diff --git a/.changeset/config.json b/.changeset/config.json index abf430e6f9e..b2f1f7d26bd 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -8,6 +8,7 @@ "ignore": [ "website", "example-*", + "dev-test*", "@graphql-codegen/client-preset-swc-plugin", "example-apollo-client-swc-plugin", "example-react-nextjs-swr" diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index efe67b8af93..c7dd48cb48a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -4,6 +4,7 @@ on: push: branches: - master + pull_request: branches: - master @@ -137,10 +138,10 @@ jobs: strategy: matrix: os: [ubuntu-latest] # remove windows to speed up the tests - node_version: [20, 22, 24] + node_version: [22, 24] graphql_version: [15, 16] include: - - node-version: 20 + - node-version: 22 os: windows-latest graphql_version: 16 steps: diff --git a/.prettierignore b/.prettierignore index d58d3ea2879..33860628e5b 100644 --- a/.prettierignore +++ b/.prettierignore @@ -34,3 +34,7 @@ packages/presets/swc-plugin/tests/fixtures # Ignore intentional error files packages/graphql-codegen-cli/tests/test-files/schema-dir/error-schema.graphql packages/graphql-codegen-cli/tests/test-files/error-document.graphql + +# Ignore dev-tests with no prettier requirement +dev-test/test-schema/flow-types.flow.js +dev-test-apollo-tooling/src/__generated__/ diff --git a/dev-test-apollo-tooling/README.md b/dev-test-apollo-tooling/README.md new file mode 100644 index 00000000000..0e0fb858580 --- /dev/null +++ b/dev-test-apollo-tooling/README.md @@ -0,0 +1,23 @@ +The `dev-test-apollo-tooling` package is an example of migrating from Apollo tooling to GraphQL +Codegen. It attempts to generate output as close as possible to Apollo tooling’s output. Note: +**this package is a work in progress** and currently requires a patch to `near-operation-file`. We +will fix this package soon. + +How to run this package: + +1. Make sure you have the correct Yarn version installed (check the root package.json, + `packageManager` entry). Otherwise, you might run into unexplained bugs. +2. In the monorepo root, run: + +yarn clean && yarn install && yarn build + +3. Patch `near-operation-file` manually (the automatic patch doesn’t always work). In the monorepo + root, run: + +yarn postinstall + +4. Go to the `dev-test-apollo-tooling` directory and run: + +cd dev-test-apollo-tooling yarn install yarn start + +This will generate type files in `dev-test-apollo-tooling/src/__generated__/*`. diff --git a/dev-test-apollo-tooling/cli/index.ts b/dev-test-apollo-tooling/cli/index.ts new file mode 100644 index 00000000000..a82483dcf50 --- /dev/null +++ b/dev-test-apollo-tooling/cli/index.ts @@ -0,0 +1,83 @@ +#!/usr/bin/env ts-node +import { generate } from '@graphql-codegen/cli'; +import type { Types } from '@graphql-codegen/plugin-helpers'; + +export const GENERATED = '__generated__'; +export const GLOBAL_TYPES_FILE = 'globalTypes.ts'; +export const TS_GENERATED_FILE_HEADER = `\ +/* tslint:disable */ +/* eslint-disable */ +// @generated +// This file was automatically generated and should not be edited. +`; + +/** + * The following GraphQL Codegen config matches as closely as possible + * to the old apollo-tooling codegen + * @see https://github.com/apollographql/apollo-tooling/issues/2053 + * */ +const GRAPHQL_CODEGEN_CONFIG = { + useTypeImports: true, + namingConvention: 'keep', // Keeps naming as-is + avoidOptionals: false, // Allow '?' on variables fields + nonOptionalTypename: true, // Forces `__typename` on all selection sets + skipTypeNameForRoot: true, // Don't generate __typename for root types + omitOperationSuffix: true, // Don't add 'Query', 'Mutation' or 'Subscription' suffixes to operation result types + fragmentSuffix: '', // Don't add 'Fragment' suffix to fragment result types + extractAllFieldsToTypesCompact: true, // Extracts all fields to separate types (similar to apollo-codegen behavior) + printFieldsOnNewLines: true, // Prints each field on a new line (similar to apollo-codegen behavior) + enumType: 'native', + generateOperationTypes: true, +}; + +export const main = async () => { + const cwd = process.cwd(); + + const localSchemaFilePath = `${cwd}/schema.graphql`; + + const includes = ['src']; + + const generatePaths: { [scanPath: string]: Types.ConfiguredOutput } = {}; + + // Prepare the required structure for GraphQL Codegen + // eslint-disable-next-line unicorn/no-array-for-each + includes.forEach((include: string) => { + generatePaths[include] = { + preset: 'near-operation-file', // This preset tells the codegen to generate multiple files instead of one + presetConfig: { + extension: '.ts', + folder: GENERATED, // Output folder for generated files + }, + plugins: [ + 'typescript-operations', + { + add: { + content: TS_GENERATED_FILE_HEADER, + }, + }, + ], + }; + }); + + await generate({ + schema: localSchemaFilePath, + documents: [ + ...includes.map((include: any) => `${include}/**/*.{js,jsx,ts,tsx}`), + `!**/${GENERATED}/**`, + ], + config: GRAPHQL_CODEGEN_CONFIG, + generates: generatePaths, + silent: false, + overwrite: true, + debug: false, + verbose: false, + }); +}; + +if (import.meta.url === process.argv[1] || import.meta.url === `file://${process.argv[1]}`) { + main().catch(e => { + // eslint-disable-next-line no-console + console.error(e); + process.exit(1); + }); +} diff --git a/dev-test-apollo-tooling/package.json b/dev-test-apollo-tooling/package.json new file mode 100644 index 00000000000..a38219fb00b --- /dev/null +++ b/dev-test-apollo-tooling/package.json @@ -0,0 +1,31 @@ +{ + "name": "dev-test-apollo-tooling", + "version": "0.0.1", + "type": "module", + "description": "A setup which mimics Apollo tooling generation as close as possible", + "private": true, + "files": [ + "cli" + ], + "scripts": { + "start": "tsx cli/index.ts", + "start:debug": "NODE_OPTIONS='--trace-warnings' tsx cli/index.ts", + "start:verbose": "DEBUG='*' tsx cli/index.ts", + "test": "vitest --no-watch" + }, + "dependencies": { + "@apollo/client": "3.13.8", + "@graphql-codegen/cli": "*", + "@graphql-codegen/plugin-helpers": "*", + "@graphql-codegen/typed-document-node": "*", + "@graphql-codegen/typescript-operations": "*", + "@graphql-codegen/visitor-plugin-common": "*" + }, + "devDependencies": { + "@types/node": "^25.0.3", + "tsx": "4.7.0", + "typescript": "^5.9.3", + "vitest": "4.0.4" + }, + "sideEffects": false +} diff --git a/dev-test-apollo-tooling/schema.graphql b/dev-test-apollo-tooling/schema.graphql new file mode 100644 index 00000000000..d5c1acd821f --- /dev/null +++ b/dev-test-apollo-tooling/schema.graphql @@ -0,0 +1,356 @@ +schema + @link(url: "https://specs.apollo.dev/link/v1.0") + @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/tag/v0.3") { + query: Query +} + +directive @join__graph(name: String!, url: String!) on ENUM_VALUE + +directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE + +directive @join__field( + graph: join__Graph + requires: join__FieldSet + provides: join__FieldSet + type: String + external: Boolean + override: String + usedOverridden: Boolean + overrideLabel: String +) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + +directive @join__implements( + graph: join__Graph! + interface: String! +) repeatable on OBJECT | INTERFACE + +directive @join__type( + graph: join__Graph! + key: join__FieldSet + extension: Boolean! = false + resolvable: Boolean! = true + isInterfaceObject: Boolean! = false +) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + +directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on UNION + +directive @link( + url: String + as: String + for: link__Purpose + import: [link__Import] +) repeatable on SCHEMA + +directive @tag( + name: String! +) repeatable on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION | SCHEMA + +scalar join__FieldSet + +scalar link__Import + +enum link__Purpose { + EXECUTION +} + +enum join__Graph { + SUPER_USER_MANAGER + @join__graph(name: "super_user_management", url: "http://i.am.not.used.example.com") + GRAPHQL_MAIN__SHARD__BASE + @join__graph(name: "graphql_main__shard__base", url: "http://i.am.not.used.example.com") + GRAPHQL_MAIN__SHARD__INTERNAL_TESTING + @join__graph( + name: "graphql_main__shard__internal_testing" + url: "http://i.am.not.used.example.com" + ) +} + +type Query { + superUser: SuperUser! @join__field(graph: GRAPHQL_MAIN__SHARD__BASE) + organization(id: String!): Organization @join__field(graph: GRAPHQL_MAIN__SHARD__BASE) +} + +enum UserManagerRoleType @join__type(graph: SUPER_USER_MANAGER) { + ROLE_TYPE_1 @join__enumValue(graph: SUPER_USER_MANAGER) + + ROLE_TYPE_2 @join__enumValue(graph: SUPER_USER_MANAGER) + + ROLE_TYPE_3 @join__enumValue(graph: SUPER_USER_MANAGER) +} + +type UserManager @join__type(graph: SUPER_USER_MANAGER) { + fooUser: User! + + roleType: UserManagerRoleType! +} + +type User { + id: ID! + profilePhoto: UserProfilePhoto @join__field(graph: GRAPHQL_MAIN__SHARD__BASE) +} + +type AdminUser { + id: ID! + profilePhoto: UserProfilePhoto @join__field(graph: GRAPHQL_MAIN__SHARD__BASE) +} + +type UserProfilePhoto @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) { + id: ID! + photoUrl: UserPhotoUrl +} + +type UserPhotoUrl @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) { + url(size: UserPhotoSize!): String +} + +enum UserPhotoSize + @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) + @join__type(graph: GRAPHQL_MAIN__SHARD__INTERNAL_TESTING) { + SQUARE_300 + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__BASE) + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__INTERNAL_TESTING) +} + +type SuperUser @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) { + groupFromAlias(alias: String!): SuperUserGroup! +} + +type SuperUserGroup + @join__type(graph: SUPER_USER_MANAGER, key: "id") + @join__type(graph: GRAPHQL_MAIN__SHARD__BASE, key: "id") { + id: ID! + + managers(onlyPublic: Boolean! = false): [UserManager!] @join__field(graph: SUPER_USER_MANAGER) +} + +# Schema definitions for Duplicates.ts examples + +interface ConfigTypeDefinition @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) { + identifier: String! +} + +type ConfigActionId implements ConfigTypeDefinition + @join__implements(graph: GRAPHQL_MAIN__SHARD__BASE, interface: "ConfigTypeDefinition") + @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) { + identifier: String! +} + +type ConfigString implements ConfigTypeDefinition + @join__implements(graph: GRAPHQL_MAIN__SHARD__BASE, interface: "ConfigTypeDefinition") + @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) { + identifier: String! + supportedHtmlTags: [String!] +} + +type ConfigEnum implements ConfigTypeDefinition + @join__implements(graph: GRAPHQL_MAIN__SHARD__BASE, interface: "ConfigTypeDefinition") + @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) { + identifier: String! + values: [String!]! +} + +type ConfigIconResource implements ConfigTypeDefinition + @join__implements(graph: GRAPHQL_MAIN__SHARD__BASE, interface: "ConfigTypeDefinition") + @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) { + identifier: String! + parameters: [ConfigParameterDefinition!]! +} + +type ConfigIllustrationResource implements ConfigTypeDefinition + @join__implements(graph: GRAPHQL_MAIN__SHARD__BASE, interface: "ConfigTypeDefinition") + @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) { + identifier: String! + parameters: [ConfigParameterDefinition!]! +} + +type ConfigStruct implements ConfigTypeDefinition + @join__implements(graph: GRAPHQL_MAIN__SHARD__BASE, interface: "ConfigTypeDefinition") + @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) { + identifier: String! + parameters: [ConfigParameterDefinition!]! +} + +type ConfigParameterDefinition @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) { + name: String! + typeId: String! + isRequired: Boolean! + defaultValue: String +} + +type Organization implements Node + @join__implements(graph: GRAPHQL_MAIN__SHARD__BASE, interface: "Node") + @join__type(graph: GRAPHQL_MAIN__SHARD__BASE, key: "id") { + id: ID! + internalOrgData: InternalOrgData @join__field(graph: GRAPHQL_MAIN__SHARD__BASE) +} + +type InternalOrgData @join__type(graph: GRAPHQL_MAIN__SHARD__BASE, key: "id") { + id: ID! + processableFeedback( + first: Int + after: String + sortBy: ProcessableFeedbackSortBy + sortOrder: ProcessableFeedbackSortOrder + scoreFilter: [Int] + ): FeedbackConnection @join__field(graph: GRAPHQL_MAIN__SHARD__BASE) +} + +enum ProcessableFeedbackSortBy + @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) + @join__type(graph: GRAPHQL_MAIN__SHARD__INTERNAL_TESTING) { + OPTION_1 + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__BASE) + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__INTERNAL_TESTING) + OPTION_2 + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__BASE) + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__INTERNAL_TESTING) + OPTION_3 + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__BASE) + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__INTERNAL_TESTING) + OPTION_4 + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__BASE) + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__INTERNAL_TESTING) +} + +enum ProcessableFeedbackSortOrder + @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) + @join__type(graph: GRAPHQL_MAIN__SHARD__INTERNAL_TESTING) { + ASC + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__BASE) + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__INTERNAL_TESTING) + DESC + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__BASE) + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__INTERNAL_TESTING) +} + +type FeedbackConnection @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) { + edges: [FeedbackEdge] + pageInfo: PageInfo! + totalCount: Int +} + +type FeedbackEdge @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) { + cursor: String! + node: Feedback +} + +type Feedback implements Node + @join__implements(graph: GRAPHQL_MAIN__SHARD__BASE, interface: "Node") + @join__type(graph: GRAPHQL_MAIN__SHARD__BASE, key: "id") { + id: ID! + orgMemberThread: Thread @join__field(graph: GRAPHQL_MAIN__SHARD__BASE) +} + +type Thread implements Node + @join__implements(graph: GRAPHQL_MAIN__SHARD__BASE, interface: "Node") + @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) { + id: ID! + posts(after: String, first: Int): ThreadPostConnection + @join__field(graph: GRAPHQL_MAIN__SHARD__BASE) +} + +type ThreadPostConnection @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) { + edges: [ThreadPostEdge] + pageInfo: PageInfo! +} + +type ThreadPostEdge @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) { + cursor: String! + node: ThreadPost +} + +type ThreadPost @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) { + id: ID! + creator: ThreadPostCreator + text: String + createdAt: DateTime +} + +union ThreadPostCreator + @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) + @join__unionMember(graph: GRAPHQL_MAIN__SHARD__BASE, member: "OrgMember") + @join__unionMember(graph: GRAPHQL_MAIN__SHARD__BASE, member: "EndUser") = + | OrgMember + | EndUser + +type OrgMember @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) { + id: ID! + fullName: String + avatar: OrgMemberAvatar +} + +type EndUser @join__type(graph: GRAPHQL_MAIN__SHARD__BASE, key: "id") { + id: ID! + fullName: String + avatar: EndUserAvatar +} + +type OrgMemberAvatar implements Photo & Node + @join__implements(graph: GRAPHQL_MAIN__SHARD__BASE, interface: "Photo") + @join__implements(graph: GRAPHQL_MAIN__SHARD__BASE, interface: "Node") + @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) { + id: ID! + imageUrl: OrgMemberImageUrl +} + +type OrgMemberImageUrl @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) { + url(size: OrgMemberImageSize!): String +} + +enum OrgMemberImageSize + @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) + @join__type(graph: GRAPHQL_MAIN__SHARD__INTERNAL_TESTING) { + LARGE + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__BASE) + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__INTERNAL_TESTING) + MEDIUM + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__BASE) + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__INTERNAL_TESTING) + SMALL + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__BASE) + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__INTERNAL_TESTING) +} + +type EndUserAvatar implements Photo & Node + @join__implements(graph: GRAPHQL_MAIN__SHARD__BASE, interface: "Photo") + @join__implements(graph: GRAPHQL_MAIN__SHARD__BASE, interface: "Node") + @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) { + id: ID! + imageUrl: EndUserImageUrl +} + +type EndUserImageUrl @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) { + url(size: EndUserImageSize!): String +} + +enum EndUserImageSize + @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) + @join__type(graph: GRAPHQL_MAIN__SHARD__INTERNAL_TESTING) { + LARGE + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__BASE) + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__INTERNAL_TESTING) + MEDIUM + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__BASE) + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__INTERNAL_TESTING) + SMALL + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__BASE) + @join__enumValue(graph: GRAPHQL_MAIN__SHARD__INTERNAL_TESTING) +} + +interface Photo { + id: ID! +} + +interface Node { + id: ID! +} + +type PageInfo { + hasNextPage: Boolean! + hasPreviousPage: Boolean! + startCursor: String + endCursor: String +} + +scalar DateTime diff --git a/dev-test-apollo-tooling/src/Component.ts b/dev-test-apollo-tooling/src/Component.ts new file mode 100644 index 00000000000..af327d906f8 --- /dev/null +++ b/dev-test-apollo-tooling/src/Component.ts @@ -0,0 +1,26 @@ +/** + * This file tests generating enum from external fragement from another file. + * Check that `UserManagerRoleType` enum is generated in `__generated__/Component.ts` + */ + +import { gql, useQuery } from '@apollo/client'; +import Helper from './Helper'; + +export const getFooQuery = gql` + ${Helper.fragments.query} + query GetFoo($alias: String!, $collectionId: String!) { + superUser { + groupFromAlias(alias: $alias) { + managers(onlyPublic: true) { + ...HelperFields + } + } + } + } +`; + +const Component = () => { + useQuery(getFooQuery, {}); +}; + +export default Component; diff --git a/dev-test-apollo-tooling/src/Duplicates.ts b/dev-test-apollo-tooling/src/Duplicates.ts new file mode 100644 index 00000000000..61ad20e71ae --- /dev/null +++ b/dev-test-apollo-tooling/src/Duplicates.ts @@ -0,0 +1,82 @@ +/** + * This file tests handing duplicates when using extractAllFieldsToTypesCompact: true + * Check the `__generated__/Duplicates.ts` file: it should not contain any duplicate names. + */ + +import { gql } from '@apollo/client'; + +export const getTypeDefinitionsFragment = gql` + fragment ConfigTypeDefinitions on ConfigTypeDefinition { + __typename + ... on ConfigActionId { + identifier + } + ... on ConfigString { + identifier + supportedHtmlTags + } + ... on ConfigEnum { + identifier + values + } + } +`; + +export const GET_FEEDBACK_DATA = gql` + query GetFeedbackData( + $organizationId: String! + $first: Int + $after: String + $scoreFilter: [Int] + $sortBy: ProcessableFeedbackSortBy + $sortOrder: ProcessableFeedbackSortOrder + ) { + organization(id: $organizationId) { + internalOrgData { + processableFeedback( + first: $first + after: $after + sortBy: $sortBy + sortOrder: $sortOrder + scoreFilter: $scoreFilter + ) { + edges { + node { + id + orgMemberThread { + id + posts(first: 1, after: "") { + edges { + node { + creator { + __typename + ... on OrgMember { + id + fullName + avatar { + imageUrl { + url(size: SMALL) + } + } + } + ... on EndUser { + id + fullName + avatar { + imageUrl { + url(size: SMALL) + } + } + } + } + } + } + } + } + } + } + } + } + } + } +`; diff --git a/dev-test-apollo-tooling/src/Helper.ts b/dev-test-apollo-tooling/src/Helper.ts new file mode 100644 index 00000000000..c562fc0eb0a --- /dev/null +++ b/dev-test-apollo-tooling/src/Helper.ts @@ -0,0 +1,27 @@ +import { gql } from '@apollo/client'; + +const getHelperFieldsFragment = gql` + fragment HelperFields on UserManager { + roleType + fooUser { + profilePhoto { + photoUrl { + url(size: SQUARE_300) + } + } + } + } +`; + +export const helperPropsFromFragment = (fragment: any) => ({ + profilePhotoUrl: fragment.fooUser.profilePhoto?.photoUrl.url, + roleType: fragment.roleType, +}); + +const Helper = { fragments: { query: {} } }; + +Helper.fragments = { + query: getHelperFieldsFragment, +}; + +export default Helper; diff --git a/dev-test-apollo-tooling/src/__generated__/Component.ts b/dev-test-apollo-tooling/src/__generated__/Component.ts new file mode 100644 index 00000000000..678db425463 --- /dev/null +++ b/dev-test-apollo-tooling/src/__generated__/Component.ts @@ -0,0 +1,52 @@ +/* tslint:disable */ +/* eslint-disable */ +// @generated +// This file was automatically generated and should not be edited. + +type Exact = { [K in keyof T]: T[K] }; +export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; +export enum UserManagerRoleType { + ROLE_TYPE_1 = 'ROLE_TYPE_1', + ROLE_TYPE_2 = 'ROLE_TYPE_2', + ROLE_TYPE_3 = 'ROLE_TYPE_3', +} + +export type GetFoo_superUser_groupFromAlias_managers_fooUser_profilePhoto_photoUrl = { + __typename: 'UserPhotoUrl'; + url: string | null; +}; + +export type GetFoo_superUser_groupFromAlias_managers_fooUser_profilePhoto = { + __typename: 'UserProfilePhoto'; + photoUrl: GetFoo_superUser_groupFromAlias_managers_fooUser_profilePhoto_photoUrl | null; +}; + +export type GetFoo_superUser_groupFromAlias_managers_fooUser = { + __typename: 'User'; + profilePhoto: GetFoo_superUser_groupFromAlias_managers_fooUser_profilePhoto | null; +}; + +export type GetFoo_superUser_groupFromAlias_managers = { + __typename: 'UserManager'; + roleType: UserManagerRoleType; + fooUser: GetFoo_superUser_groupFromAlias_managers_fooUser; +}; + +export type GetFoo_superUser_groupFromAlias = { + __typename: 'SuperUserGroup'; + managers: Array | null; +}; + +export type GetFoo_superUser = { + __typename: 'SuperUser'; + groupFromAlias: GetFoo_superUser_groupFromAlias; +}; + +export type GetFoo = { + superUser: GetFoo_superUser; +}; + +export type GetFooVariables = Exact<{ + alias: string; + collectionId: string; +}>; diff --git a/dev-test-apollo-tooling/src/__generated__/Duplicates.ts b/dev-test-apollo-tooling/src/__generated__/Duplicates.ts new file mode 100644 index 00000000000..dfcdf289c91 --- /dev/null +++ b/dev-test-apollo-tooling/src/__generated__/Duplicates.ts @@ -0,0 +1,161 @@ +/* tslint:disable */ +/* eslint-disable */ +// @generated +// This file was automatically generated and should not be edited. + +type Exact = { [K in keyof T]: T[K] }; +export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; +export enum ProcessableFeedbackSortBy { + OPTION_1 = 'OPTION_1', + OPTION_2 = 'OPTION_2', + OPTION_3 = 'OPTION_3', + OPTION_4 = 'OPTION_4', +} + +export enum ProcessableFeedbackSortOrder { + ASC = 'ASC', + DESC = 'DESC', +} + +export type ConfigTypeDefinitions_ConfigActionId = { + __typename: 'ConfigActionId'; + identifier: string; +}; + +export type ConfigTypeDefinitions_ConfigEnum = { + __typename: 'ConfigEnum'; + identifier: string; + values: Array; +}; + +export type ConfigTypeDefinitions_ConfigIconResource = { + __typename: 'ConfigIconResource'; +}; + +export type ConfigTypeDefinitions_ConfigIllustrationResource = { + __typename: 'ConfigIllustrationResource'; +}; + +export type ConfigTypeDefinitions_ConfigString = { + __typename: 'ConfigString'; + identifier: string; + supportedHtmlTags: Array | null; +}; + +export type ConfigTypeDefinitions_ConfigStruct = { + __typename: 'ConfigStruct'; +}; + +export type ConfigTypeDefinitions = + | ConfigTypeDefinitions_ConfigActionId + | ConfigTypeDefinitions_ConfigEnum + | ConfigTypeDefinitions_ConfigIconResource + | ConfigTypeDefinitions_ConfigIllustrationResource + | ConfigTypeDefinitions_ConfigString + | ConfigTypeDefinitions_ConfigStruct; + +export type GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node_orgMemberThread_posts_edges_node_creator_avatar_imageUrl = + { + __typename: 'EndUserImageUrl'; + url: string | null; + }; + +export type GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node_orgMemberThread_posts_edges_node_creator_avatar = + { + __typename: 'EndUserAvatar'; + imageUrl: GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node_orgMemberThread_posts_edges_node_creator_avatar_imageUrl | null; + }; + +export type GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node_orgMemberThread_posts_edges_node_creator_OrgMember_avatar_imageUrl = + { + __typename: 'OrgMemberImageUrl'; + url: string | null; + }; + +export type GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node_orgMemberThread_posts_edges_node_creator_OrgMember_avatar = + { + __typename: 'OrgMemberAvatar'; + imageUrl: GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node_orgMemberThread_posts_edges_node_creator_OrgMember_avatar_imageUrl | null; + }; + +export type GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node_orgMemberThread_posts_edges_node_creator_EndUser = + { + __typename: 'EndUser'; + id: string; + fullName: string | null; + avatar: GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node_orgMemberThread_posts_edges_node_creator_avatar | null; + }; + +export type GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node_orgMemberThread_posts_edges_node_creator_OrgMember = + { + __typename: 'OrgMember'; + id: string; + fullName: string | null; + avatar: GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node_orgMemberThread_posts_edges_node_creator_OrgMember_avatar | null; + }; + +export type GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node_orgMemberThread_posts_edges_node_creator = + + | GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node_orgMemberThread_posts_edges_node_creator_EndUser + | GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node_orgMemberThread_posts_edges_node_creator_OrgMember; + +export type GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node_orgMemberThread_posts_edges_node = + { + __typename: 'ThreadPost'; + creator: GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node_orgMemberThread_posts_edges_node_creator | null; + }; + +export type GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node_orgMemberThread_posts_edges = { + __typename: 'ThreadPostEdge'; + node: GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node_orgMemberThread_posts_edges_node | null; +}; + +export type GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node_orgMemberThread_posts = { + __typename: 'ThreadPostConnection'; + edges: Array | null; +}; + +export type GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node_orgMemberThread = { + __typename: 'Thread'; + id: string; + posts: GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node_orgMemberThread_posts | null; +}; + +export type GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node = { + __typename: 'Feedback'; + id: string; + orgMemberThread: GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node_orgMemberThread | null; +}; + +export type GetFeedbackData_organization_internalOrgData_processableFeedback_edges = { + __typename: 'FeedbackEdge'; + node: GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node | null; +}; + +export type GetFeedbackData_organization_internalOrgData_processableFeedback = { + __typename: 'FeedbackConnection'; + edges: Array | null; +}; + +export type GetFeedbackData_organization_internalOrgData = { + __typename: 'InternalOrgData'; + processableFeedback: GetFeedbackData_organization_internalOrgData_processableFeedback | null; +}; + +export type GetFeedbackData_organization = { + __typename: 'Organization'; + internalOrgData: GetFeedbackData_organization_internalOrgData | null; +}; + +export type GetFeedbackData = { + organization: GetFeedbackData_organization | null; +}; + +export type GetFeedbackDataVariables = Exact<{ + organizationId: string; + first?: number | null | undefined; + after?: string | null | undefined; + scoreFilter?: Array | number | null | undefined; + sortBy?: ProcessableFeedbackSortBy | null | undefined; + sortOrder?: ProcessableFeedbackSortOrder | null | undefined; +}>; diff --git a/dev-test-apollo-tooling/src/__generated__/Helper.ts b/dev-test-apollo-tooling/src/__generated__/Helper.ts new file mode 100644 index 00000000000..7bdc34ff9b2 --- /dev/null +++ b/dev-test-apollo-tooling/src/__generated__/Helper.ts @@ -0,0 +1,32 @@ +/* tslint:disable */ +/* eslint-disable */ +// @generated +// This file was automatically generated and should not be edited. + +export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; +export enum UserManagerRoleType { + ROLE_TYPE_1 = 'ROLE_TYPE_1', + ROLE_TYPE_2 = 'ROLE_TYPE_2', + ROLE_TYPE_3 = 'ROLE_TYPE_3', +} + +export type HelperFields_fooUser_profilePhoto_photoUrl = { + __typename: 'UserPhotoUrl'; + url: string | null; +}; + +export type HelperFields_fooUser_profilePhoto = { + __typename: 'UserProfilePhoto'; + photoUrl: HelperFields_fooUser_profilePhoto_photoUrl | null; +}; + +export type HelperFields_fooUser = { + __typename: 'User'; + profilePhoto: HelperFields_fooUser_profilePhoto | null; +}; + +export type HelperFields = { + __typename: 'UserManager'; + roleType: UserManagerRoleType; + fooUser: HelperFields_fooUser; +}; diff --git a/dev-test-apollo-tooling/tests/Component.test.ts b/dev-test-apollo-tooling/tests/Component.test.ts new file mode 100644 index 00000000000..0de36414f05 --- /dev/null +++ b/dev-test-apollo-tooling/tests/Component.test.ts @@ -0,0 +1,20 @@ +import { readFileSync } from 'node:fs'; +import { dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { describe, expect, it } from 'vitest'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); + +describe('Component.ts', () => { + it('UserManagerRoleType enum should be exported', () => { + const fileContent = readFileSync(join(__dirname, '../src/__generated__/Component.ts'), 'utf-8'); + + expect(fileContent).toMatch(/export enum UserManagerRoleType/); + }); + + it('UserManagerRoleType should be referenced without any prefix', () => { + const fileContent = readFileSync(join(__dirname, '../src/__generated__/Component.ts'), 'utf-8'); + + expect(fileContent).toMatch(/roleType:\s*UserManagerRoleType;/); + }); +}); diff --git a/dev-test-apollo-tooling/tests/Duplicates.test.ts b/dev-test-apollo-tooling/tests/Duplicates.test.ts new file mode 100644 index 00000000000..e9d87b32318 --- /dev/null +++ b/dev-test-apollo-tooling/tests/Duplicates.test.ts @@ -0,0 +1,37 @@ +import { readFileSync } from 'node:fs'; +import { dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { describe, expect, it } from 'vitest'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); + +describe('Duplicates.ts', () => { + it('ConfigTypeDefinitions types should be exported', () => { + const fileContent = readFileSync( + join(__dirname, '../src/__generated__/Duplicates.ts'), + 'utf-8', + ); + + expect(fileContent).toMatch(/export type ConfigTypeDefinitions_ConfigActionId\s*=/); + expect(fileContent).toMatch(/export type ConfigTypeDefinitions_ConfigEnum\s*=/); + expect(fileContent).toMatch(/export type ConfigTypeDefinitions_ConfigIconResource\s*=/); + expect(fileContent).toMatch(/export type ConfigTypeDefinitions\s*=/); + }); + + it('GetFeedbackData creator union type exports should exist', () => { + const fileContent = readFileSync( + join(__dirname, '../src/__generated__/Duplicates.ts'), + 'utf-8', + ); + + expect(fileContent).toMatch( + /export type GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node_orgMemberThread_posts_edges_node_creator\s*=/, + ); + expect(fileContent).toMatch( + /export type GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node_orgMemberThread_posts_edges_node_creator_EndUser\s*=/, + ); + expect(fileContent).toMatch( + /export type GetFeedbackData_organization_internalOrgData_processableFeedback_edges_node_orgMemberThread_posts_edges_node_creator_OrgMember\s*=/, + ); + }); +}); diff --git a/dev-test-apollo-tooling/tsconfig.json b/dev-test-apollo-tooling/tsconfig.json new file mode 100644 index 00000000000..39e2b63b53d --- /dev/null +++ b/dev-test-apollo-tooling/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "verbatimModuleSyntax": true, + "esModuleInterop": true, + "resolveJsonModule": true, + "strict": true + } +} diff --git a/dev-test-apollo-tooling/vitest.config.ts b/dev-test-apollo-tooling/vitest.config.ts new file mode 100644 index 00000000000..98426e79914 --- /dev/null +++ b/dev-test-apollo-tooling/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject, mergeConfig } from 'vitest/config'; +import { sharedConfig } from '../vitest.config.js'; + +export default mergeConfig( + sharedConfig, + defineProject({ + test: { + name: 'dev-test-apollo-tooling', + include: ['tests/**/*.spec.ts', 'tests/**/*.test.ts'], + }, + }), +); diff --git a/dev-test/codegen.ts b/dev-test/codegen.ts index 0e8fa26cc2b..61779fd7c46 100644 --- a/dev-test/codegen.ts +++ b/dev-test/codegen.ts @@ -40,7 +40,6 @@ const config: CodegenConfig = { { add: { content: 'declare namespace GraphQL {' } }, { add: { placement: 'append', content: '}' } }, 'typescript', - 'typescript-operations', ], }, './dev-test/test-schema/env.types.ts': { @@ -68,65 +67,65 @@ const config: CodegenConfig = { './dev-test/githunt/typed-document-nodes.ts': { schema: './dev-test/githunt/schema.json', documents: './dev-test/githunt/**/*.graphql', - plugins: ['typescript', 'typescript-operations', 'typed-document-node'], + plugins: ['typescript-operations', 'typed-document-node'], }, './dev-test/githunt/types.ts': { schema: './dev-test/githunt/schema.json', documents: './dev-test/githunt/**/*.graphql', - plugins: ['typescript', 'typescript-operations'], + plugins: ['typescript-operations'], }, './dev-test/githunt/types.preResolveTypes.ts': { schema: './dev-test/githunt/schema.json', documents: './dev-test/githunt/**/*.graphql', config: { preResolveTypes: true }, - plugins: ['typescript', 'typescript-operations'], + plugins: ['typescript-operations'], }, './dev-test/githunt/types.onlyEnums.ts': { schema: './dev-test/githunt/schema.json', documents: './dev-test/githunt/**/*.graphql', - config: { onlyEnums: true }, - plugins: ['typescript'], + config: { generateOperationTypes: false }, + plugins: ['typescript-operations'], }, './dev-test/githunt/types.preResolveTypes.onlyOperationTypes.ts': { schema: './dev-test/githunt/schema.json', documents: './dev-test/githunt/**/*.graphql', - config: { preResolveTypes: true, onlyOperationTypes: true }, - plugins: ['typescript', 'typescript-operations'], + config: { preResolveTypes: true }, + plugins: ['typescript-operations'], }, './dev-test/githunt/types.flatten.preResolveTypes.ts': { schema: './dev-test/githunt/schema.json', documents: './dev-test/githunt/**/*.graphql', config: { preResolveTypes: true, flattenGeneratedTypes: true }, - plugins: ['typescript', 'typescript-operations'], + plugins: ['typescript-operations'], }, './dev-test/githunt/types.enumsAsTypes.ts': { schema: './dev-test/githunt/schema.json', documents: './dev-test/githunt/**/*.graphql', - config: { enumsAsTypes: true }, - plugins: ['typescript', 'typescript-operations'], + config: { enumType: 'string-literal' }, + plugins: ['typescript-operations'], }, './dev-test/githunt/types.d.ts': { schema: './dev-test/githunt/schema.json', documents: './dev-test/githunt/**/*.graphql', - config: { enumsAsTypes: true }, - plugins: ['typescript', 'typescript-operations'], + config: {}, + plugins: ['typescript-operations'], }, './dev-test/githunt/types.avoidOptionals.ts': { schema: './dev-test/githunt/schema.json', documents: './dev-test/githunt/**/*.graphql', config: { avoidOptionals: true }, - plugins: ['typescript', 'typescript-operations'], + plugins: ['typescript-operations'], }, './dev-test/githunt/types.immutableTypes.ts': { schema: './dev-test/githunt/schema.json', documents: './dev-test/githunt/**/*.graphql', config: { immutableTypes: true }, - plugins: ['typescript', 'typescript-operations'], + plugins: ['typescript-operations'], }, './dev-test/star-wars/types.ts': { schema: './dev-test/star-wars/schema.json', documents: './dev-test/star-wars/**/*.graphql', - plugins: ['typescript', 'typescript-operations'], + plugins: ['typescript-operations'], }, './dev-test/star-wars/types.excludeQueryAlpha.ts': { schema: './dev-test/star-wars/schema.json', @@ -134,7 +133,7 @@ const config: CodegenConfig = { './dev-test/star-wars/**/*.graphql', '!./dev-test/star-wars/**/ExcludeQueryAlpha.graphql', ], - plugins: ['typescript', 'typescript-operations'], + plugins: ['typescript-operations'], }, './dev-test/star-wars/types.excludeQueryBeta.ts': { schema: './dev-test/star-wars/schema.json', @@ -142,13 +141,13 @@ const config: CodegenConfig = { './dev-test/star-wars/**/*.graphql', '!./dev-test/star-wars/**/ExcludeQueryBeta.graphql', ], - plugins: ['typescript', 'typescript-operations'], + plugins: ['typescript-operations'], }, './dev-test/star-wars/types.preResolveTypes.ts': { schema: './dev-test/star-wars/schema.json', documents: './dev-test/star-wars/**/*.graphql', config: { preResolveTypes: true }, - plugins: ['typescript', 'typescript-operations'], + plugins: ['typescript-operations'], }, './dev-test/star-wars/types.OnlyEnums.ts': { schema: './dev-test/star-wars/schema.json', @@ -159,25 +158,25 @@ const config: CodegenConfig = { './dev-test/star-wars/types.preResolveTypes.onlyOperationTypes.ts': { schema: './dev-test/star-wars/schema.json', documents: './dev-test/star-wars/**/*.graphql', - config: { preResolveTypes: true, onlyOperationTypes: true }, - plugins: ['typescript', 'typescript-operations'], + config: { preResolveTypes: true }, + plugins: ['typescript-operations'], }, './dev-test/test-schema/types.preResolveTypes.ts': { schema: './dev-test/test-schema/schema.graphql', documents: ['query test { testArr1 testArr2 testArr3 }'], config: { preResolveTypes: true }, - plugins: ['typescript', 'typescript-operations'], + plugins: ['typescript-operations'], }, './dev-test/test-schema/types.preResolveTypes.onlyOperationTypes.ts': { schema: './dev-test/test-schema/schema.graphql', documents: ['query test { testArr1 testArr2 testArr3 }'], - config: { preResolveTypes: true, onlyOperationTypes: true }, - plugins: ['typescript', 'typescript-operations'], + config: { preResolveTypes: true }, + plugins: ['typescript-operations'], }, './dev-test/star-wars/types.d.ts': { schema: './dev-test/star-wars/schema.json', - config: { enumsAsTypes: true }, - plugins: ['typescript', 'typescript-operations'], + config: { enumType: 'string-literal' }, + plugins: ['typescript-operations'], }, './dev-test/modules/': { schema: './dev-test/modules/*/types/*.graphql', @@ -188,25 +187,25 @@ const config: CodegenConfig = { './dev-test/star-wars/types.globallyAvailable.d.ts': { schema: './dev-test/star-wars/schema.json', documents: './dev-test/star-wars/**/*.graphql', - config: { enumsAsTypes: true, noExport: true }, - plugins: ['typescript', 'typescript-operations'], + config: { noExport: true }, + plugins: ['typescript-operations'], }, './dev-test/star-wars/types.avoidOptionals.ts': { schema: './dev-test/star-wars/schema.json', documents: './dev-test/star-wars/**/*.graphql', config: { avoidOptionals: true }, - plugins: ['typescript', 'typescript-operations'], + plugins: ['typescript-operations'], }, './dev-test/star-wars/types.immutableTypes.ts': { schema: './dev-test/star-wars/schema.json', documents: './dev-test/star-wars/**/*.graphql', config: { immutableTypes: true }, - plugins: ['typescript', 'typescript-operations'], + plugins: ['typescript-operations'], }, './dev-test/star-wars/types.skipSchema.ts': { schema: './dev-test/star-wars/schema.json', documents: './dev-test/star-wars/**/*.graphql', - plugins: ['typescript', 'typescript-operations'], + plugins: ['typescript-operations'], }, './dev-test/gql-tag-operations/gql/': { schema: './dev-test/gql-tag-operations/schema.graphql', @@ -233,7 +232,7 @@ const config: CodegenConfig = { './dev-test/test-null-value/result.d.ts': { schema: './dev-test/test-null-value/schema.graphql', documents: ['./dev-test/test-null-value/query.ts'], - plugins: ['typescript', 'typescript-operations'], + plugins: ['typescript-operations'], config: { // The combination of these two flags caused the following issue: // https://github.com/dotansimha/graphql-code-generator/pull/9709 @@ -273,6 +272,40 @@ const config: CodegenConfig = { plugins: ['typescript-operations'], }, // #endregion + + // 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'], + plugins: ['typescript-operations'], + config: { + generateOperationTypes: false, + }, + }, + './dev-test/standalone-operations/import-schema-types/_types.generated.ts': { + schema: './dev-test/standalone-operations/schema.graphql', + documents: ['./dev-test/standalone-operations/import-schema-types/*.graphql'], + plugins: ['typescript-operations'], + config: { + importSchemaTypesFrom: + './dev-test/standalone-operations/import-schema-types/_base.generated.ts', + }, + }, + + // 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', + }, + }, }, }; diff --git a/dev-test/external-documents/app/types.generated.ts b/dev-test/external-documents/app/types.generated.ts index fc9a2a812b2..0a4e99d4f5e 100644 --- a/dev-test/external-documents/app/types.generated.ts +++ b/dev-test/external-documents/app/types.generated.ts @@ -1,8 +1,13 @@ +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ +export type Incremental = + | T + | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; +export type UserRole = 'ADMIN' | 'CUSTOMER'; + export type UserQueryVariables = Exact<{ - id: Scalars['ID']['input']; + id: string | number; }>; -export type UserQuery = { - __typename?: 'Query'; - user?: { __typename?: 'User'; id: string; name: string; role: UserRole } | null; -}; +export type UserQuery = { user: { id: string; name: string; role: UserRole } | null }; diff --git a/dev-test/githunt/typed-document-nodes.ts b/dev-test/githunt/typed-document-nodes.ts index c9c007657a3..81f92bdfb56 100644 --- a/dev-test/githunt/typed-document-nodes.ts +++ b/dev-test/githunt/typed-document-nodes.ts @@ -1,220 +1,59 @@ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A comment about an entry, submitted by a user */ -export type Comment = { - __typename?: 'Comment'; - /** The text of the comment */ - content: Scalars['String']['output']; - /** A timestamp of when the comment was posted */ - createdAt: Scalars['Float']['output']; - /** The SQL ID of this entry */ - id: Scalars['Int']['output']; - /** The GitHub user who posted the comment */ - postedBy: User; - /** The repository which this comment is about */ - repoName: Scalars['String']['output']; -}; - -/** Information about a GitHub repository submitted to GitHunt */ -export type Entry = { - __typename?: 'Entry'; - /** The number of comments posted about this repository */ - commentCount: Scalars['Int']['output']; - /** Comments posted about this repository */ - comments: Array>; - /** A timestamp of when the entry was submitted */ - createdAt: Scalars['Float']['output']; - /** The hot score of this repository */ - hotScore: Scalars['Float']['output']; - /** The SQL ID of this entry */ - id: Scalars['Int']['output']; - /** The GitHub user who submitted this entry */ - postedBy: User; - /** Information about the repository from GitHub */ - repository: Repository; - /** The score of this repository, upvotes - downvotes */ - score: Scalars['Int']['output']; - /** XXX to be changed */ - vote: Vote; -}; - -/** Information about a GitHub repository submitted to GitHunt */ -export type EntryCommentsArgs = { - limit?: InputMaybe; - offset?: InputMaybe; -}; /** A list of options for the sort order of the feed */ -export enum FeedType { +export type FeedType = /** Sort by a combination of freshness and score, using Reddit's algorithm */ - Hot = 'HOT', + | 'HOT' /** Newest entries first */ - New = 'NEW', + | 'NEW' /** Highest score entries first */ - Top = 'TOP', -} - -export type Mutation = { - __typename?: 'Mutation'; - /** Comment on a repository, returns the new comment */ - submitComment?: Maybe; - /** Submit a new repository, returns the new submission */ - submitRepository?: Maybe; - /** Vote on a repository submission, returns the submission that was voted on */ - vote?: Maybe; -}; - -export type MutationSubmitCommentArgs = { - commentContent: Scalars['String']['input']; - repoFullName: Scalars['String']['input']; -}; - -export type MutationSubmitRepositoryArgs = { - repoFullName: Scalars['String']['input']; -}; - -export type MutationVoteArgs = { - repoFullName: Scalars['String']['input']; - type: VoteType; -}; - -export type Query = { - __typename?: 'Query'; - /** Return the currently logged in user, or null if nobody is logged in */ - currentUser?: Maybe; - /** A single entry */ - entry?: Maybe; - /** A feed of repository submissions */ - feed?: Maybe>>; -}; - -export type QueryEntryArgs = { - repoFullName: Scalars['String']['input']; -}; - -export type QueryFeedArgs = { - limit?: InputMaybe; - offset?: InputMaybe; - type: FeedType; -}; - -/** - * A repository object from the GitHub API. This uses the exact field names returned by the - * GitHub API for simplicity, even though the convention for GraphQL is usually to camel case. - */ -export type Repository = { - __typename?: 'Repository'; - /** The description of the repository */ - description?: Maybe; - /** The full name of the repository with the username, e.g. apollostack/GitHunt-API */ - full_name: Scalars['String']['output']; - /** The link to the repository on GitHub */ - html_url: Scalars['String']['output']; - /** Just the name of the repository, e.g. GitHunt-API */ - name: Scalars['String']['output']; - /** The number of open issues on this repository on GitHub */ - open_issues_count?: Maybe; - /** The owner of this repository on GitHub, e.g. apollostack */ - owner?: Maybe; - /** The number of people who have starred this repository on GitHub */ - stargazers_count: Scalars['Int']['output']; -}; - -export type Subscription = { - __typename?: 'Subscription'; - /** Subscription fires on every comment added */ - commentAdded?: Maybe; -}; - -export type SubscriptionCommentAddedArgs = { - repoFullName: Scalars['String']['input']; -}; - -/** A user object from the GitHub API. This uses the exact field names returned from the GitHub API. */ -export type User = { - __typename?: 'User'; - /** The URL to a directly embeddable image for this user's avatar */ - avatar_url: Scalars['String']['output']; - /** The URL of this user's GitHub page */ - html_url: Scalars['String']['output']; - /** The name of the user, e.g. apollostack */ - login: Scalars['String']['output']; -}; - -/** XXX to be removed */ -export type Vote = { - __typename?: 'Vote'; - vote_value: Scalars['Int']['output']; -}; + | 'TOP'; /** The type of vote to record, when submitting a vote */ -export enum VoteType { - Cancel = 'CANCEL', - Down = 'DOWN', - Up = 'UP', -} +export type VoteType = 'CANCEL' | 'DOWN' | 'UP'; export type OnCommentAddedSubscriptionVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; }>; export type OnCommentAddedSubscription = { - __typename?: 'Subscription'; - commentAdded?: { - __typename?: 'Comment'; + commentAdded: { id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; } | null; }; export type CommentQueryVariables = Exact<{ - repoFullName: Scalars['String']['input']; - limit?: InputMaybe; - offset?: InputMaybe; + repoFullName: string; + limit?: number | null | undefined; + offset?: number | null | undefined; }>; export type CommentQuery = { - __typename?: 'Query'; - currentUser?: { __typename?: 'User'; login: string; html_url: string } | null; - entry?: { - __typename?: 'Entry'; + currentUser: { login: string; html_url: string } | null; + entry: { id: number; createdAt: number; commentCount: number; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; comments: Array<{ - __typename?: 'Comment'; id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; } | null>; repository: { - __typename?: 'Repository'; - description?: string | null; - open_issues_count?: number | null; + description: string | null; + open_issues_count: number | null; stargazers_count: number; full_name: string; html_url: string; @@ -223,124 +62,100 @@ export type CommentQuery = { }; export type CommentsPageCommentFragment = { - __typename?: 'Comment'; id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; }; export type CurrentUserForProfileQueryVariables = Exact<{ [key: string]: never }>; export type CurrentUserForProfileQuery = { - __typename?: 'Query'; - currentUser?: { __typename?: 'User'; login: string; avatar_url: string } | null; + currentUser: { login: string; avatar_url: string } | null; }; export type FeedEntryFragment = { - __typename?: 'Entry'; id: number; commentCount: number; score: number; createdAt: number; repository: { - __typename?: 'Repository'; full_name: string; html_url: string; - description?: string | null; + description: string | null; stargazers_count: number; - open_issues_count?: number | null; - owner?: { __typename?: 'User'; avatar_url: string } | null; + open_issues_count: number | null; + owner: { avatar_url: string } | null; }; - vote: { __typename?: 'Vote'; vote_value: number }; - postedBy: { __typename?: 'User'; html_url: string; login: string }; + vote: { vote_value: number }; + postedBy: { html_url: string; login: string }; }; export type FeedQueryVariables = Exact<{ type: FeedType; - offset?: InputMaybe; - limit?: InputMaybe; + offset?: number | null | undefined; + limit?: number | null | undefined; }>; export type FeedQuery = { - __typename?: 'Query'; - currentUser?: { __typename?: 'User'; login: string } | null; - feed?: Array<{ - __typename?: 'Entry'; + currentUser: { login: string } | null; + feed: Array<{ id: number; commentCount: number; score: number; createdAt: number; repository: { - __typename?: 'Repository'; full_name: string; html_url: string; - description?: string | null; + description: string | null; stargazers_count: number; - open_issues_count?: number | null; - owner?: { __typename?: 'User'; avatar_url: string } | null; + open_issues_count: number | null; + owner: { avatar_url: string } | null; }; - vote: { __typename?: 'Vote'; vote_value: number }; - postedBy: { __typename?: 'User'; html_url: string; login: string }; + vote: { vote_value: number }; + postedBy: { html_url: string; login: string }; } | null> | null; }; export type SubmitRepositoryMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; }>; -export type SubmitRepositoryMutation = { - __typename?: 'Mutation'; - submitRepository?: { __typename?: 'Entry'; createdAt: number } | null; -}; +export type SubmitRepositoryMutation = { submitRepository: { createdAt: number } | null }; export type RepoInfoFragment = { - __typename?: 'Entry'; createdAt: number; repository: { - __typename?: 'Repository'; - description?: string | null; + description: string | null; stargazers_count: number; - open_issues_count?: number | null; + open_issues_count: number | null; }; - postedBy: { __typename?: 'User'; html_url: string; login: string }; + postedBy: { html_url: string; login: string }; }; export type SubmitCommentMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; - commentContent: Scalars['String']['input']; + repoFullName: string; + commentContent: string; }>; export type SubmitCommentMutation = { - __typename?: 'Mutation'; - submitComment?: { - __typename?: 'Comment'; + submitComment: { id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; } | null; }; -export type VoteButtonsFragment = { - __typename?: 'Entry'; - score: number; - vote: { __typename?: 'Vote'; vote_value: number }; -}; +export type VoteButtonsFragment = { score: number; vote: { vote_value: number } }; export type VoteMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; type: VoteType; }>; export type VoteMutation = { - __typename?: 'Mutation'; - vote?: { - __typename?: 'Entry'; - score: number; - id: number; - vote: { __typename?: 'Vote'; vote_value: number }; - } | null; + vote: { score: number; id: number; vote: { vote_value: number } } | null; }; export const CommentsPageCommentFragmentDoc = { diff --git a/dev-test/githunt/types.avoidOptionals.ts b/dev-test/githunt/types.avoidOptionals.ts index a4e3d208f51..4b7921b4d98 100644 --- a/dev-test/githunt/types.avoidOptionals.ts +++ b/dev-test/githunt/types.avoidOptionals.ts @@ -1,216 +1,54 @@ -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A comment about an entry, submitted by a user */ -export type Comment = { - __typename?: 'Comment'; - /** The text of the comment */ - content: Scalars['String']['output']; - /** A timestamp of when the comment was posted */ - createdAt: Scalars['Float']['output']; - /** The SQL ID of this entry */ - id: Scalars['Int']['output']; - /** The GitHub user who posted the comment */ - postedBy: User; - /** The repository which this comment is about */ - repoName: Scalars['String']['output']; -}; - -/** Information about a GitHub repository submitted to GitHunt */ -export type Entry = { - __typename?: 'Entry'; - /** The number of comments posted about this repository */ - commentCount: Scalars['Int']['output']; - /** Comments posted about this repository */ - comments: Array>; - /** A timestamp of when the entry was submitted */ - createdAt: Scalars['Float']['output']; - /** The hot score of this repository */ - hotScore: Scalars['Float']['output']; - /** The SQL ID of this entry */ - id: Scalars['Int']['output']; - /** The GitHub user who submitted this entry */ - postedBy: User; - /** Information about the repository from GitHub */ - repository: Repository; - /** The score of this repository, upvotes - downvotes */ - score: Scalars['Int']['output']; - /** XXX to be changed */ - vote: Vote; -}; - -/** Information about a GitHub repository submitted to GitHunt */ -export type EntryCommentsArgs = { - limit: InputMaybe; - offset: InputMaybe; -}; - /** A list of options for the sort order of the feed */ -export enum FeedType { +export type FeedType = /** Sort by a combination of freshness and score, using Reddit's algorithm */ - Hot = 'HOT', + | 'HOT' /** Newest entries first */ - New = 'NEW', + | 'NEW' /** Highest score entries first */ - Top = 'TOP', -} - -export type Mutation = { - __typename?: 'Mutation'; - /** Comment on a repository, returns the new comment */ - submitComment: Maybe; - /** Submit a new repository, returns the new submission */ - submitRepository: Maybe; - /** Vote on a repository submission, returns the submission that was voted on */ - vote: Maybe; -}; - -export type MutationSubmitCommentArgs = { - commentContent: Scalars['String']['input']; - repoFullName: Scalars['String']['input']; -}; - -export type MutationSubmitRepositoryArgs = { - repoFullName: Scalars['String']['input']; -}; - -export type MutationVoteArgs = { - repoFullName: Scalars['String']['input']; - type: VoteType; -}; - -export type Query = { - __typename?: 'Query'; - /** Return the currently logged in user, or null if nobody is logged in */ - currentUser: Maybe; - /** A single entry */ - entry: Maybe; - /** A feed of repository submissions */ - feed: Maybe>>; -}; - -export type QueryEntryArgs = { - repoFullName: Scalars['String']['input']; -}; - -export type QueryFeedArgs = { - limit: InputMaybe; - offset: InputMaybe; - type: FeedType; -}; - -/** - * A repository object from the GitHub API. This uses the exact field names returned by the - * GitHub API for simplicity, even though the convention for GraphQL is usually to camel case. - */ -export type Repository = { - __typename?: 'Repository'; - /** The description of the repository */ - description: Maybe; - /** The full name of the repository with the username, e.g. apollostack/GitHunt-API */ - full_name: Scalars['String']['output']; - /** The link to the repository on GitHub */ - html_url: Scalars['String']['output']; - /** Just the name of the repository, e.g. GitHunt-API */ - name: Scalars['String']['output']; - /** The number of open issues on this repository on GitHub */ - open_issues_count: Maybe; - /** The owner of this repository on GitHub, e.g. apollostack */ - owner: Maybe; - /** The number of people who have starred this repository on GitHub */ - stargazers_count: Scalars['Int']['output']; -}; - -export type Subscription = { - __typename?: 'Subscription'; - /** Subscription fires on every comment added */ - commentAdded: Maybe; -}; - -export type SubscriptionCommentAddedArgs = { - repoFullName: Scalars['String']['input']; -}; - -/** A user object from the GitHub API. This uses the exact field names returned from the GitHub API. */ -export type User = { - __typename?: 'User'; - /** The URL to a directly embeddable image for this user's avatar */ - avatar_url: Scalars['String']['output']; - /** The URL of this user's GitHub page */ - html_url: Scalars['String']['output']; - /** The name of the user, e.g. apollostack */ - login: Scalars['String']['output']; -}; - -/** XXX to be removed */ -export type Vote = { - __typename?: 'Vote'; - vote_value: Scalars['Int']['output']; -}; + | 'TOP'; /** The type of vote to record, when submitting a vote */ -export enum VoteType { - Cancel = 'CANCEL', - Down = 'DOWN', - Up = 'UP', -} +export type VoteType = 'CANCEL' | 'DOWN' | 'UP'; export type OnCommentAddedSubscriptionVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; }>; export type OnCommentAddedSubscription = { - __typename?: 'Subscription'; commentAdded: { - __typename?: 'Comment'; id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; } | null; }; export type CommentQueryVariables = Exact<{ - repoFullName: Scalars['String']['input']; - limit: InputMaybe; - offset: InputMaybe; + repoFullName: string; + limit: number | null | undefined; + offset: number | null | undefined; }>; export type CommentQuery = { - __typename?: 'Query'; - currentUser: { __typename?: 'User'; login: string; html_url: string } | null; + currentUser: { login: string; html_url: string } | null; entry: { - __typename?: 'Entry'; id: number; createdAt: number; commentCount: number; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; comments: Array<{ - __typename?: 'Comment'; id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; } | null>; repository: { - __typename?: 'Repository'; description: string | null; open_issues_count: number | null; stargazers_count: number; @@ -221,122 +59,98 @@ export type CommentQuery = { }; export type CommentsPageCommentFragment = { - __typename?: 'Comment'; id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; }; export type CurrentUserForProfileQueryVariables = Exact<{ [key: string]: never }>; export type CurrentUserForProfileQuery = { - __typename?: 'Query'; - currentUser: { __typename?: 'User'; login: string; avatar_url: string } | null; + currentUser: { login: string; avatar_url: string } | null; }; export type FeedEntryFragment = { - __typename?: 'Entry'; id: number; commentCount: number; score: number; createdAt: number; repository: { - __typename?: 'Repository'; full_name: string; html_url: string; description: string | null; stargazers_count: number; open_issues_count: number | null; - owner: { __typename?: 'User'; avatar_url: string } | null; + owner: { avatar_url: string } | null; }; - vote: { __typename?: 'Vote'; vote_value: number }; - postedBy: { __typename?: 'User'; html_url: string; login: string }; + vote: { vote_value: number }; + postedBy: { html_url: string; login: string }; }; export type FeedQueryVariables = Exact<{ type: FeedType; - offset: InputMaybe; - limit: InputMaybe; + offset: number | null | undefined; + limit: number | null | undefined; }>; export type FeedQuery = { - __typename?: 'Query'; - currentUser: { __typename?: 'User'; login: string } | null; + currentUser: { login: string } | null; feed: Array<{ - __typename?: 'Entry'; id: number; commentCount: number; score: number; createdAt: number; repository: { - __typename?: 'Repository'; full_name: string; html_url: string; description: string | null; stargazers_count: number; open_issues_count: number | null; - owner: { __typename?: 'User'; avatar_url: string } | null; + owner: { avatar_url: string } | null; }; - vote: { __typename?: 'Vote'; vote_value: number }; - postedBy: { __typename?: 'User'; html_url: string; login: string }; + vote: { vote_value: number }; + postedBy: { html_url: string; login: string }; } | null> | null; }; export type SubmitRepositoryMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; }>; -export type SubmitRepositoryMutation = { - __typename?: 'Mutation'; - submitRepository: { __typename?: 'Entry'; createdAt: number } | null; -}; +export type SubmitRepositoryMutation = { submitRepository: { createdAt: number } | null }; export type RepoInfoFragment = { - __typename?: 'Entry'; createdAt: number; repository: { - __typename?: 'Repository'; description: string | null; stargazers_count: number; open_issues_count: number | null; }; - postedBy: { __typename?: 'User'; html_url: string; login: string }; + postedBy: { html_url: string; login: string }; }; export type SubmitCommentMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; - commentContent: Scalars['String']['input']; + repoFullName: string; + commentContent: string; }>; export type SubmitCommentMutation = { - __typename?: 'Mutation'; submitComment: { - __typename?: 'Comment'; id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; } | null; }; -export type VoteButtonsFragment = { - __typename?: 'Entry'; - score: number; - vote: { __typename?: 'Vote'; vote_value: number }; -}; +export type VoteButtonsFragment = { score: number; vote: { vote_value: number } }; export type VoteMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; type: VoteType; }>; export type VoteMutation = { - __typename?: 'Mutation'; - vote: { - __typename?: 'Entry'; - score: number; - id: number; - vote: { __typename?: 'Vote'; vote_value: number }; - } | null; + vote: { score: number; id: number; vote: { vote_value: number } } | null; }; diff --git a/dev-test/githunt/types.d.ts b/dev-test/githunt/types.d.ts index ff7ed78627a..fe2ef34a356 100644 --- a/dev-test/githunt/types.d.ts +++ b/dev-test/githunt/types.d.ts @@ -1,67 +1,9 @@ -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A comment about an entry, submitted by a user */ -export type Comment = { - __typename?: 'Comment'; - /** The text of the comment */ - content: Scalars['String']['output']; - /** A timestamp of when the comment was posted */ - createdAt: Scalars['Float']['output']; - /** The SQL ID of this entry */ - id: Scalars['Int']['output']; - /** The GitHub user who posted the comment */ - postedBy: User; - /** The repository which this comment is about */ - repoName: Scalars['String']['output']; -}; - -/** Information about a GitHub repository submitted to GitHunt */ -export type Entry = { - __typename?: 'Entry'; - /** The number of comments posted about this repository */ - commentCount: Scalars['Int']['output']; - /** Comments posted about this repository */ - comments: Array>; - /** A timestamp of when the entry was submitted */ - createdAt: Scalars['Float']['output']; - /** The hot score of this repository */ - hotScore: Scalars['Float']['output']; - /** The SQL ID of this entry */ - id: Scalars['Int']['output']; - /** The GitHub user who submitted this entry */ - postedBy: User; - /** Information about the repository from GitHub */ - repository: Repository; - /** The score of this repository, upvotes - downvotes */ - score: Scalars['Int']['output']; - /** XXX to be changed */ - vote: Vote; -}; - -/** Information about a GitHub repository submitted to GitHunt */ -export type EntryCommentsArgs = { - limit?: InputMaybe; - offset?: InputMaybe; -}; - /** A list of options for the sort order of the feed */ export type FeedType = /** Sort by a combination of freshness and score, using Reddit's algorithm */ @@ -71,143 +13,44 @@ export type FeedType = /** Highest score entries first */ | 'TOP'; -export type Mutation = { - __typename?: 'Mutation'; - /** Comment on a repository, returns the new comment */ - submitComment?: Maybe; - /** Submit a new repository, returns the new submission */ - submitRepository?: Maybe; - /** Vote on a repository submission, returns the submission that was voted on */ - vote?: Maybe; -}; - -export type MutationSubmitCommentArgs = { - commentContent: Scalars['String']['input']; - repoFullName: Scalars['String']['input']; -}; - -export type MutationSubmitRepositoryArgs = { - repoFullName: Scalars['String']['input']; -}; - -export type MutationVoteArgs = { - repoFullName: Scalars['String']['input']; - type: VoteType; -}; - -export type Query = { - __typename?: 'Query'; - /** Return the currently logged in user, or null if nobody is logged in */ - currentUser?: Maybe; - /** A single entry */ - entry?: Maybe; - /** A feed of repository submissions */ - feed?: Maybe>>; -}; - -export type QueryEntryArgs = { - repoFullName: Scalars['String']['input']; -}; - -export type QueryFeedArgs = { - limit?: InputMaybe; - offset?: InputMaybe; - type: FeedType; -}; - -/** - * A repository object from the GitHub API. This uses the exact field names returned by the - * GitHub API for simplicity, even though the convention for GraphQL is usually to camel case. - */ -export type Repository = { - __typename?: 'Repository'; - /** The description of the repository */ - description?: Maybe; - /** The full name of the repository with the username, e.g. apollostack/GitHunt-API */ - full_name: Scalars['String']['output']; - /** The link to the repository on GitHub */ - html_url: Scalars['String']['output']; - /** Just the name of the repository, e.g. GitHunt-API */ - name: Scalars['String']['output']; - /** The number of open issues on this repository on GitHub */ - open_issues_count?: Maybe; - /** The owner of this repository on GitHub, e.g. apollostack */ - owner?: Maybe; - /** The number of people who have starred this repository on GitHub */ - stargazers_count: Scalars['Int']['output']; -}; - -export type Subscription = { - __typename?: 'Subscription'; - /** Subscription fires on every comment added */ - commentAdded?: Maybe; -}; - -export type SubscriptionCommentAddedArgs = { - repoFullName: Scalars['String']['input']; -}; - -/** A user object from the GitHub API. This uses the exact field names returned from the GitHub API. */ -export type User = { - __typename?: 'User'; - /** The URL to a directly embeddable image for this user's avatar */ - avatar_url: Scalars['String']['output']; - /** The URL of this user's GitHub page */ - html_url: Scalars['String']['output']; - /** The name of the user, e.g. apollostack */ - login: Scalars['String']['output']; -}; - -/** XXX to be removed */ -export type Vote = { - __typename?: 'Vote'; - vote_value: Scalars['Int']['output']; -}; - /** The type of vote to record, when submitting a vote */ export type VoteType = 'CANCEL' | 'DOWN' | 'UP'; export type OnCommentAddedSubscriptionVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; }>; export type OnCommentAddedSubscription = { - __typename?: 'Subscription'; - commentAdded?: { - __typename?: 'Comment'; + commentAdded: { id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; } | null; }; export type CommentQueryVariables = Exact<{ - repoFullName: Scalars['String']['input']; - limit?: InputMaybe; - offset?: InputMaybe; + repoFullName: string; + limit?: number | null | undefined; + offset?: number | null | undefined; }>; export type CommentQuery = { - __typename?: 'Query'; - currentUser?: { __typename?: 'User'; login: string; html_url: string } | null; - entry?: { - __typename?: 'Entry'; + currentUser: { login: string; html_url: string } | null; + entry: { id: number; createdAt: number; commentCount: number; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; comments: Array<{ - __typename?: 'Comment'; id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; } | null>; repository: { - __typename?: 'Repository'; - description?: string | null; - open_issues_count?: number | null; + description: string | null; + open_issues_count: number | null; stargazers_count: number; full_name: string; html_url: string; @@ -216,122 +59,98 @@ export type CommentQuery = { }; export type CommentsPageCommentFragment = { - __typename?: 'Comment'; id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; }; export type CurrentUserForProfileQueryVariables = Exact<{ [key: string]: never }>; export type CurrentUserForProfileQuery = { - __typename?: 'Query'; - currentUser?: { __typename?: 'User'; login: string; avatar_url: string } | null; + currentUser: { login: string; avatar_url: string } | null; }; export type FeedEntryFragment = { - __typename?: 'Entry'; id: number; commentCount: number; score: number; createdAt: number; repository: { - __typename?: 'Repository'; full_name: string; html_url: string; - description?: string | null; + description: string | null; stargazers_count: number; - open_issues_count?: number | null; - owner?: { __typename?: 'User'; avatar_url: string } | null; + open_issues_count: number | null; + owner: { avatar_url: string } | null; }; - vote: { __typename?: 'Vote'; vote_value: number }; - postedBy: { __typename?: 'User'; html_url: string; login: string }; + vote: { vote_value: number }; + postedBy: { html_url: string; login: string }; }; export type FeedQueryVariables = Exact<{ type: FeedType; - offset?: InputMaybe; - limit?: InputMaybe; + offset?: number | null | undefined; + limit?: number | null | undefined; }>; export type FeedQuery = { - __typename?: 'Query'; - currentUser?: { __typename?: 'User'; login: string } | null; - feed?: Array<{ - __typename?: 'Entry'; + currentUser: { login: string } | null; + feed: Array<{ id: number; commentCount: number; score: number; createdAt: number; repository: { - __typename?: 'Repository'; full_name: string; html_url: string; - description?: string | null; + description: string | null; stargazers_count: number; - open_issues_count?: number | null; - owner?: { __typename?: 'User'; avatar_url: string } | null; + open_issues_count: number | null; + owner: { avatar_url: string } | null; }; - vote: { __typename?: 'Vote'; vote_value: number }; - postedBy: { __typename?: 'User'; html_url: string; login: string }; + vote: { vote_value: number }; + postedBy: { html_url: string; login: string }; } | null> | null; }; export type SubmitRepositoryMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; }>; -export type SubmitRepositoryMutation = { - __typename?: 'Mutation'; - submitRepository?: { __typename?: 'Entry'; createdAt: number } | null; -}; +export type SubmitRepositoryMutation = { submitRepository: { createdAt: number } | null }; export type RepoInfoFragment = { - __typename?: 'Entry'; createdAt: number; repository: { - __typename?: 'Repository'; - description?: string | null; + description: string | null; stargazers_count: number; - open_issues_count?: number | null; + open_issues_count: number | null; }; - postedBy: { __typename?: 'User'; html_url: string; login: string }; + postedBy: { html_url: string; login: string }; }; export type SubmitCommentMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; - commentContent: Scalars['String']['input']; + repoFullName: string; + commentContent: string; }>; export type SubmitCommentMutation = { - __typename?: 'Mutation'; - submitComment?: { - __typename?: 'Comment'; + submitComment: { id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; } | null; }; -export type VoteButtonsFragment = { - __typename?: 'Entry'; - score: number; - vote: { __typename?: 'Vote'; vote_value: number }; -}; +export type VoteButtonsFragment = { score: number; vote: { vote_value: number } }; export type VoteMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; type: VoteType; }>; export type VoteMutation = { - __typename?: 'Mutation'; - vote?: { - __typename?: 'Entry'; - score: number; - id: number; - vote: { __typename?: 'Vote'; vote_value: number }; - } | null; + vote: { score: number; id: number; vote: { vote_value: number } } | null; }; diff --git a/dev-test/githunt/types.enumsAsTypes.ts b/dev-test/githunt/types.enumsAsTypes.ts index ff7ed78627a..fe2ef34a356 100644 --- a/dev-test/githunt/types.enumsAsTypes.ts +++ b/dev-test/githunt/types.enumsAsTypes.ts @@ -1,67 +1,9 @@ -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A comment about an entry, submitted by a user */ -export type Comment = { - __typename?: 'Comment'; - /** The text of the comment */ - content: Scalars['String']['output']; - /** A timestamp of when the comment was posted */ - createdAt: Scalars['Float']['output']; - /** The SQL ID of this entry */ - id: Scalars['Int']['output']; - /** The GitHub user who posted the comment */ - postedBy: User; - /** The repository which this comment is about */ - repoName: Scalars['String']['output']; -}; - -/** Information about a GitHub repository submitted to GitHunt */ -export type Entry = { - __typename?: 'Entry'; - /** The number of comments posted about this repository */ - commentCount: Scalars['Int']['output']; - /** Comments posted about this repository */ - comments: Array>; - /** A timestamp of when the entry was submitted */ - createdAt: Scalars['Float']['output']; - /** The hot score of this repository */ - hotScore: Scalars['Float']['output']; - /** The SQL ID of this entry */ - id: Scalars['Int']['output']; - /** The GitHub user who submitted this entry */ - postedBy: User; - /** Information about the repository from GitHub */ - repository: Repository; - /** The score of this repository, upvotes - downvotes */ - score: Scalars['Int']['output']; - /** XXX to be changed */ - vote: Vote; -}; - -/** Information about a GitHub repository submitted to GitHunt */ -export type EntryCommentsArgs = { - limit?: InputMaybe; - offset?: InputMaybe; -}; - /** A list of options for the sort order of the feed */ export type FeedType = /** Sort by a combination of freshness and score, using Reddit's algorithm */ @@ -71,143 +13,44 @@ export type FeedType = /** Highest score entries first */ | 'TOP'; -export type Mutation = { - __typename?: 'Mutation'; - /** Comment on a repository, returns the new comment */ - submitComment?: Maybe; - /** Submit a new repository, returns the new submission */ - submitRepository?: Maybe; - /** Vote on a repository submission, returns the submission that was voted on */ - vote?: Maybe; -}; - -export type MutationSubmitCommentArgs = { - commentContent: Scalars['String']['input']; - repoFullName: Scalars['String']['input']; -}; - -export type MutationSubmitRepositoryArgs = { - repoFullName: Scalars['String']['input']; -}; - -export type MutationVoteArgs = { - repoFullName: Scalars['String']['input']; - type: VoteType; -}; - -export type Query = { - __typename?: 'Query'; - /** Return the currently logged in user, or null if nobody is logged in */ - currentUser?: Maybe; - /** A single entry */ - entry?: Maybe; - /** A feed of repository submissions */ - feed?: Maybe>>; -}; - -export type QueryEntryArgs = { - repoFullName: Scalars['String']['input']; -}; - -export type QueryFeedArgs = { - limit?: InputMaybe; - offset?: InputMaybe; - type: FeedType; -}; - -/** - * A repository object from the GitHub API. This uses the exact field names returned by the - * GitHub API for simplicity, even though the convention for GraphQL is usually to camel case. - */ -export type Repository = { - __typename?: 'Repository'; - /** The description of the repository */ - description?: Maybe; - /** The full name of the repository with the username, e.g. apollostack/GitHunt-API */ - full_name: Scalars['String']['output']; - /** The link to the repository on GitHub */ - html_url: Scalars['String']['output']; - /** Just the name of the repository, e.g. GitHunt-API */ - name: Scalars['String']['output']; - /** The number of open issues on this repository on GitHub */ - open_issues_count?: Maybe; - /** The owner of this repository on GitHub, e.g. apollostack */ - owner?: Maybe; - /** The number of people who have starred this repository on GitHub */ - stargazers_count: Scalars['Int']['output']; -}; - -export type Subscription = { - __typename?: 'Subscription'; - /** Subscription fires on every comment added */ - commentAdded?: Maybe; -}; - -export type SubscriptionCommentAddedArgs = { - repoFullName: Scalars['String']['input']; -}; - -/** A user object from the GitHub API. This uses the exact field names returned from the GitHub API. */ -export type User = { - __typename?: 'User'; - /** The URL to a directly embeddable image for this user's avatar */ - avatar_url: Scalars['String']['output']; - /** The URL of this user's GitHub page */ - html_url: Scalars['String']['output']; - /** The name of the user, e.g. apollostack */ - login: Scalars['String']['output']; -}; - -/** XXX to be removed */ -export type Vote = { - __typename?: 'Vote'; - vote_value: Scalars['Int']['output']; -}; - /** The type of vote to record, when submitting a vote */ export type VoteType = 'CANCEL' | 'DOWN' | 'UP'; export type OnCommentAddedSubscriptionVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; }>; export type OnCommentAddedSubscription = { - __typename?: 'Subscription'; - commentAdded?: { - __typename?: 'Comment'; + commentAdded: { id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; } | null; }; export type CommentQueryVariables = Exact<{ - repoFullName: Scalars['String']['input']; - limit?: InputMaybe; - offset?: InputMaybe; + repoFullName: string; + limit?: number | null | undefined; + offset?: number | null | undefined; }>; export type CommentQuery = { - __typename?: 'Query'; - currentUser?: { __typename?: 'User'; login: string; html_url: string } | null; - entry?: { - __typename?: 'Entry'; + currentUser: { login: string; html_url: string } | null; + entry: { id: number; createdAt: number; commentCount: number; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; comments: Array<{ - __typename?: 'Comment'; id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; } | null>; repository: { - __typename?: 'Repository'; - description?: string | null; - open_issues_count?: number | null; + description: string | null; + open_issues_count: number | null; stargazers_count: number; full_name: string; html_url: string; @@ -216,122 +59,98 @@ export type CommentQuery = { }; export type CommentsPageCommentFragment = { - __typename?: 'Comment'; id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; }; export type CurrentUserForProfileQueryVariables = Exact<{ [key: string]: never }>; export type CurrentUserForProfileQuery = { - __typename?: 'Query'; - currentUser?: { __typename?: 'User'; login: string; avatar_url: string } | null; + currentUser: { login: string; avatar_url: string } | null; }; export type FeedEntryFragment = { - __typename?: 'Entry'; id: number; commentCount: number; score: number; createdAt: number; repository: { - __typename?: 'Repository'; full_name: string; html_url: string; - description?: string | null; + description: string | null; stargazers_count: number; - open_issues_count?: number | null; - owner?: { __typename?: 'User'; avatar_url: string } | null; + open_issues_count: number | null; + owner: { avatar_url: string } | null; }; - vote: { __typename?: 'Vote'; vote_value: number }; - postedBy: { __typename?: 'User'; html_url: string; login: string }; + vote: { vote_value: number }; + postedBy: { html_url: string; login: string }; }; export type FeedQueryVariables = Exact<{ type: FeedType; - offset?: InputMaybe; - limit?: InputMaybe; + offset?: number | null | undefined; + limit?: number | null | undefined; }>; export type FeedQuery = { - __typename?: 'Query'; - currentUser?: { __typename?: 'User'; login: string } | null; - feed?: Array<{ - __typename?: 'Entry'; + currentUser: { login: string } | null; + feed: Array<{ id: number; commentCount: number; score: number; createdAt: number; repository: { - __typename?: 'Repository'; full_name: string; html_url: string; - description?: string | null; + description: string | null; stargazers_count: number; - open_issues_count?: number | null; - owner?: { __typename?: 'User'; avatar_url: string } | null; + open_issues_count: number | null; + owner: { avatar_url: string } | null; }; - vote: { __typename?: 'Vote'; vote_value: number }; - postedBy: { __typename?: 'User'; html_url: string; login: string }; + vote: { vote_value: number }; + postedBy: { html_url: string; login: string }; } | null> | null; }; export type SubmitRepositoryMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; }>; -export type SubmitRepositoryMutation = { - __typename?: 'Mutation'; - submitRepository?: { __typename?: 'Entry'; createdAt: number } | null; -}; +export type SubmitRepositoryMutation = { submitRepository: { createdAt: number } | null }; export type RepoInfoFragment = { - __typename?: 'Entry'; createdAt: number; repository: { - __typename?: 'Repository'; - description?: string | null; + description: string | null; stargazers_count: number; - open_issues_count?: number | null; + open_issues_count: number | null; }; - postedBy: { __typename?: 'User'; html_url: string; login: string }; + postedBy: { html_url: string; login: string }; }; export type SubmitCommentMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; - commentContent: Scalars['String']['input']; + repoFullName: string; + commentContent: string; }>; export type SubmitCommentMutation = { - __typename?: 'Mutation'; - submitComment?: { - __typename?: 'Comment'; + submitComment: { id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; } | null; }; -export type VoteButtonsFragment = { - __typename?: 'Entry'; - score: number; - vote: { __typename?: 'Vote'; vote_value: number }; -}; +export type VoteButtonsFragment = { score: number; vote: { vote_value: number } }; export type VoteMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; type: VoteType; }>; export type VoteMutation = { - __typename?: 'Mutation'; - vote?: { - __typename?: 'Entry'; - score: number; - id: number; - vote: { __typename?: 'Vote'; vote_value: number }; - } | null; + vote: { score: number; id: number; vote: { vote_value: number } } | null; }; diff --git a/dev-test/githunt/types.flatten.preResolveTypes.ts b/dev-test/githunt/types.flatten.preResolveTypes.ts index 7e27c6e0c65..69fac9b9cef 100644 --- a/dev-test/githunt/types.flatten.preResolveTypes.ts +++ b/dev-test/githunt/types.flatten.preResolveTypes.ts @@ -1,220 +1,58 @@ -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A comment about an entry, submitted by a user */ -export type Comment = { - __typename?: 'Comment'; - /** The text of the comment */ - content: Scalars['String']['output']; - /** A timestamp of when the comment was posted */ - createdAt: Scalars['Float']['output']; - /** The SQL ID of this entry */ - id: Scalars['Int']['output']; - /** The GitHub user who posted the comment */ - postedBy: User; - /** The repository which this comment is about */ - repoName: Scalars['String']['output']; -}; - -/** Information about a GitHub repository submitted to GitHunt */ -export type Entry = { - __typename?: 'Entry'; - /** The number of comments posted about this repository */ - commentCount: Scalars['Int']['output']; - /** Comments posted about this repository */ - comments: Array>; - /** A timestamp of when the entry was submitted */ - createdAt: Scalars['Float']['output']; - /** The hot score of this repository */ - hotScore: Scalars['Float']['output']; - /** The SQL ID of this entry */ - id: Scalars['Int']['output']; - /** The GitHub user who submitted this entry */ - postedBy: User; - /** Information about the repository from GitHub */ - repository: Repository; - /** The score of this repository, upvotes - downvotes */ - score: Scalars['Int']['output']; - /** XXX to be changed */ - vote: Vote; -}; - -/** Information about a GitHub repository submitted to GitHunt */ -export type EntryCommentsArgs = { - limit?: InputMaybe; - offset?: InputMaybe; -}; - /** A list of options for the sort order of the feed */ -export enum FeedType { +export type FeedType = /** Sort by a combination of freshness and score, using Reddit's algorithm */ - Hot = 'HOT', + | 'HOT' /** Newest entries first */ - New = 'NEW', + | 'NEW' /** Highest score entries first */ - Top = 'TOP', -} - -export type Mutation = { - __typename?: 'Mutation'; - /** Comment on a repository, returns the new comment */ - submitComment?: Maybe; - /** Submit a new repository, returns the new submission */ - submitRepository?: Maybe; - /** Vote on a repository submission, returns the submission that was voted on */ - vote?: Maybe; -}; - -export type MutationSubmitCommentArgs = { - commentContent: Scalars['String']['input']; - repoFullName: Scalars['String']['input']; -}; - -export type MutationSubmitRepositoryArgs = { - repoFullName: Scalars['String']['input']; -}; - -export type MutationVoteArgs = { - repoFullName: Scalars['String']['input']; - type: VoteType; -}; - -export type Query = { - __typename?: 'Query'; - /** Return the currently logged in user, or null if nobody is logged in */ - currentUser?: Maybe; - /** A single entry */ - entry?: Maybe; - /** A feed of repository submissions */ - feed?: Maybe>>; -}; - -export type QueryEntryArgs = { - repoFullName: Scalars['String']['input']; -}; - -export type QueryFeedArgs = { - limit?: InputMaybe; - offset?: InputMaybe; - type: FeedType; -}; - -/** - * A repository object from the GitHub API. This uses the exact field names returned by the - * GitHub API for simplicity, even though the convention for GraphQL is usually to camel case. - */ -export type Repository = { - __typename?: 'Repository'; - /** The description of the repository */ - description?: Maybe; - /** The full name of the repository with the username, e.g. apollostack/GitHunt-API */ - full_name: Scalars['String']['output']; - /** The link to the repository on GitHub */ - html_url: Scalars['String']['output']; - /** Just the name of the repository, e.g. GitHunt-API */ - name: Scalars['String']['output']; - /** The number of open issues on this repository on GitHub */ - open_issues_count?: Maybe; - /** The owner of this repository on GitHub, e.g. apollostack */ - owner?: Maybe; - /** The number of people who have starred this repository on GitHub */ - stargazers_count: Scalars['Int']['output']; -}; - -export type Subscription = { - __typename?: 'Subscription'; - /** Subscription fires on every comment added */ - commentAdded?: Maybe; -}; - -export type SubscriptionCommentAddedArgs = { - repoFullName: Scalars['String']['input']; -}; - -/** A user object from the GitHub API. This uses the exact field names returned from the GitHub API. */ -export type User = { - __typename?: 'User'; - /** The URL to a directly embeddable image for this user's avatar */ - avatar_url: Scalars['String']['output']; - /** The URL of this user's GitHub page */ - html_url: Scalars['String']['output']; - /** The name of the user, e.g. apollostack */ - login: Scalars['String']['output']; -}; - -/** XXX to be removed */ -export type Vote = { - __typename?: 'Vote'; - vote_value: Scalars['Int']['output']; -}; + | 'TOP'; /** The type of vote to record, when submitting a vote */ -export enum VoteType { - Cancel = 'CANCEL', - Down = 'DOWN', - Up = 'UP', -} +export type VoteType = 'CANCEL' | 'DOWN' | 'UP'; export type OnCommentAddedSubscriptionVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; }>; export type OnCommentAddedSubscription = { - __typename?: 'Subscription'; - commentAdded?: { - __typename?: 'Comment'; + commentAdded: { id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; } | null; }; export type CommentQueryVariables = Exact<{ - repoFullName: Scalars['String']['input']; - limit?: InputMaybe; - offset?: InputMaybe; + repoFullName: string; + limit?: number | null | undefined; + offset?: number | null | undefined; }>; export type CommentQuery = { - __typename?: 'Query'; - currentUser?: { __typename?: 'User'; login: string; html_url: string } | null; - entry?: { - __typename?: 'Entry'; + currentUser: { login: string; html_url: string } | null; + entry: { id: number; createdAt: number; commentCount: number; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; comments: Array<{ - __typename?: 'Comment'; id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; } | null>; repository: { - __typename?: 'Repository'; full_name: string; html_url: string; - description?: string | null; - open_issues_count?: number | null; + description: string | null; + open_issues_count: number | null; stargazers_count: number; }; } | null; @@ -223,75 +61,60 @@ export type CommentQuery = { export type CurrentUserForProfileQueryVariables = Exact<{ [key: string]: never }>; export type CurrentUserForProfileQuery = { - __typename?: 'Query'; - currentUser?: { __typename?: 'User'; login: string; avatar_url: string } | null; + currentUser: { login: string; avatar_url: string } | null; }; export type FeedQueryVariables = Exact<{ type: FeedType; - offset?: InputMaybe; - limit?: InputMaybe; + offset?: number | null | undefined; + limit?: number | null | undefined; }>; export type FeedQuery = { - __typename?: 'Query'; - currentUser?: { __typename?: 'User'; login: string } | null; - feed?: Array<{ - __typename?: 'Entry'; + currentUser: { login: string } | null; + feed: Array<{ id: number; commentCount: number; score: number; createdAt: number; repository: { - __typename?: 'Repository'; full_name: string; html_url: string; - description?: string | null; + description: string | null; stargazers_count: number; - open_issues_count?: number | null; - owner?: { __typename?: 'User'; avatar_url: string } | null; + open_issues_count: number | null; + owner: { avatar_url: string } | null; }; - vote: { __typename?: 'Vote'; vote_value: number }; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + vote: { vote_value: number }; + postedBy: { login: string; html_url: string }; } | null> | null; }; export type SubmitRepositoryMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; }>; -export type SubmitRepositoryMutation = { - __typename?: 'Mutation'; - submitRepository?: { __typename?: 'Entry'; createdAt: number } | null; -}; +export type SubmitRepositoryMutation = { submitRepository: { createdAt: number } | null }; export type SubmitCommentMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; - commentContent: Scalars['String']['input']; + repoFullName: string; + commentContent: string; }>; export type SubmitCommentMutation = { - __typename?: 'Mutation'; - submitComment?: { - __typename?: 'Comment'; + submitComment: { id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; } | null; }; export type VoteMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; type: VoteType; }>; export type VoteMutation = { - __typename?: 'Mutation'; - vote?: { - __typename?: 'Entry'; - score: number; - id: number; - vote: { __typename?: 'Vote'; vote_value: number }; - } | null; + vote: { score: number; id: number; vote: { vote_value: number } } | null; }; diff --git a/dev-test/githunt/types.immutableTypes.ts b/dev-test/githunt/types.immutableTypes.ts index 37dedae5fc1..076ac9ee412 100644 --- a/dev-test/githunt/types.immutableTypes.ts +++ b/dev-test/githunt/types.immutableTypes.ts @@ -1,234 +1,56 @@ -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A comment about an entry, submitted by a user */ -export type Comment = { - readonly __typename?: 'Comment'; - /** The text of the comment */ - readonly content: Scalars['String']['output']; - /** A timestamp of when the comment was posted */ - readonly createdAt: Scalars['Float']['output']; - /** The SQL ID of this entry */ - readonly id: Scalars['Int']['output']; - /** The GitHub user who posted the comment */ - readonly postedBy: User; - /** The repository which this comment is about */ - readonly repoName: Scalars['String']['output']; -}; - -/** Information about a GitHub repository submitted to GitHunt */ -export type Entry = { - readonly __typename?: 'Entry'; - /** The number of comments posted about this repository */ - readonly commentCount: Scalars['Int']['output']; - /** Comments posted about this repository */ - readonly comments: ReadonlyArray>; - /** A timestamp of when the entry was submitted */ - readonly createdAt: Scalars['Float']['output']; - /** The hot score of this repository */ - readonly hotScore: Scalars['Float']['output']; - /** The SQL ID of this entry */ - readonly id: Scalars['Int']['output']; - /** The GitHub user who submitted this entry */ - readonly postedBy: User; - /** Information about the repository from GitHub */ - readonly repository: Repository; - /** The score of this repository, upvotes - downvotes */ - readonly score: Scalars['Int']['output']; - /** XXX to be changed */ - readonly vote: Vote; -}; - -/** Information about a GitHub repository submitted to GitHunt */ -export type EntryCommentsArgs = { - limit?: InputMaybe; - offset?: InputMaybe; -}; - /** A list of options for the sort order of the feed */ -export enum FeedType { +export type FeedType = /** Sort by a combination of freshness and score, using Reddit's algorithm */ - Hot = 'HOT', + | 'HOT' /** Newest entries first */ - New = 'NEW', + | 'NEW' /** Highest score entries first */ - Top = 'TOP', -} - -export type Mutation = { - readonly __typename?: 'Mutation'; - /** Comment on a repository, returns the new comment */ - readonly submitComment?: Maybe; - /** Submit a new repository, returns the new submission */ - readonly submitRepository?: Maybe; - /** Vote on a repository submission, returns the submission that was voted on */ - readonly vote?: Maybe; -}; - -export type MutationSubmitCommentArgs = { - commentContent: Scalars['String']['input']; - repoFullName: Scalars['String']['input']; -}; - -export type MutationSubmitRepositoryArgs = { - repoFullName: Scalars['String']['input']; -}; - -export type MutationVoteArgs = { - repoFullName: Scalars['String']['input']; - type: VoteType; -}; - -export type Query = { - readonly __typename?: 'Query'; - /** Return the currently logged in user, or null if nobody is logged in */ - readonly currentUser?: Maybe; - /** A single entry */ - readonly entry?: Maybe; - /** A feed of repository submissions */ - readonly feed?: Maybe>>; -}; - -export type QueryEntryArgs = { - repoFullName: Scalars['String']['input']; -}; - -export type QueryFeedArgs = { - limit?: InputMaybe; - offset?: InputMaybe; - type: FeedType; -}; - -/** - * A repository object from the GitHub API. This uses the exact field names returned by the - * GitHub API for simplicity, even though the convention for GraphQL is usually to camel case. - */ -export type Repository = { - readonly __typename?: 'Repository'; - /** The description of the repository */ - readonly description?: Maybe; - /** The full name of the repository with the username, e.g. apollostack/GitHunt-API */ - readonly full_name: Scalars['String']['output']; - /** The link to the repository on GitHub */ - readonly html_url: Scalars['String']['output']; - /** Just the name of the repository, e.g. GitHunt-API */ - readonly name: Scalars['String']['output']; - /** The number of open issues on this repository on GitHub */ - readonly open_issues_count?: Maybe; - /** The owner of this repository on GitHub, e.g. apollostack */ - readonly owner?: Maybe; - /** The number of people who have starred this repository on GitHub */ - readonly stargazers_count: Scalars['Int']['output']; -}; - -export type Subscription = { - readonly __typename?: 'Subscription'; - /** Subscription fires on every comment added */ - readonly commentAdded?: Maybe; -}; - -export type SubscriptionCommentAddedArgs = { - repoFullName: Scalars['String']['input']; -}; - -/** A user object from the GitHub API. This uses the exact field names returned from the GitHub API. */ -export type User = { - readonly __typename?: 'User'; - /** The URL to a directly embeddable image for this user's avatar */ - readonly avatar_url: Scalars['String']['output']; - /** The URL of this user's GitHub page */ - readonly html_url: Scalars['String']['output']; - /** The name of the user, e.g. apollostack */ - readonly login: Scalars['String']['output']; -}; - -/** XXX to be removed */ -export type Vote = { - readonly __typename?: 'Vote'; - readonly vote_value: Scalars['Int']['output']; -}; + | 'TOP'; /** The type of vote to record, when submitting a vote */ -export enum VoteType { - Cancel = 'CANCEL', - Down = 'DOWN', - Up = 'UP', -} +export type VoteType = 'CANCEL' | 'DOWN' | 'UP'; export type OnCommentAddedSubscriptionVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; }>; export type OnCommentAddedSubscription = { - readonly __typename?: 'Subscription'; - readonly commentAdded?: { - readonly __typename?: 'Comment'; + readonly commentAdded: { readonly id: number; readonly createdAt: number; readonly content: string; - readonly postedBy: { - readonly __typename?: 'User'; - readonly login: string; - readonly html_url: string; - }; + readonly postedBy: { readonly login: string; readonly html_url: string }; } | null; }; export type CommentQueryVariables = Exact<{ - repoFullName: Scalars['String']['input']; - limit?: InputMaybe; - offset?: InputMaybe; + repoFullName: string; + limit?: number | null | undefined; + offset?: number | null | undefined; }>; export type CommentQuery = { - readonly __typename?: 'Query'; - readonly currentUser?: { - readonly __typename?: 'User'; - readonly login: string; - readonly html_url: string; - } | null; - readonly entry?: { - readonly __typename?: 'Entry'; + readonly currentUser: { readonly login: string; readonly html_url: string } | null; + readonly entry: { readonly id: number; readonly createdAt: number; readonly commentCount: number; - readonly postedBy: { - readonly __typename?: 'User'; - readonly login: string; - readonly html_url: string; - }; + readonly postedBy: { readonly login: string; readonly html_url: string }; readonly comments: ReadonlyArray<{ - readonly __typename?: 'Comment'; readonly id: number; readonly createdAt: number; readonly content: string; - readonly postedBy: { - readonly __typename?: 'User'; - readonly login: string; - readonly html_url: string; - }; + readonly postedBy: { readonly login: string; readonly html_url: string }; } | null>; readonly repository: { - readonly __typename?: 'Repository'; - readonly description?: string | null; - readonly open_issues_count?: number | null; + readonly description: string | null; + readonly open_issues_count: number | null; readonly stargazers_count: number; readonly full_name: string; readonly html_url: string; @@ -237,146 +59,107 @@ export type CommentQuery = { }; export type CommentsPageCommentFragment = { - readonly __typename?: 'Comment'; readonly id: number; readonly createdAt: number; readonly content: string; - readonly postedBy: { - readonly __typename?: 'User'; - readonly login: string; - readonly html_url: string; - }; + readonly postedBy: { readonly login: string; readonly html_url: string }; }; export type CurrentUserForProfileQueryVariables = Exact<{ [key: string]: never }>; export type CurrentUserForProfileQuery = { - readonly __typename?: 'Query'; - readonly currentUser?: { - readonly __typename?: 'User'; - readonly login: string; - readonly avatar_url: string; - } | null; + readonly currentUser: { readonly login: string; readonly avatar_url: string } | null; }; export type FeedEntryFragment = { - readonly __typename?: 'Entry'; readonly id: number; readonly commentCount: number; readonly score: number; readonly createdAt: number; readonly repository: { - readonly __typename?: 'Repository'; readonly full_name: string; readonly html_url: string; - readonly description?: string | null; + readonly description: string | null; readonly stargazers_count: number; - readonly open_issues_count?: number | null; - readonly owner?: { readonly __typename?: 'User'; readonly avatar_url: string } | null; - }; - readonly vote: { readonly __typename?: 'Vote'; readonly vote_value: number }; - readonly postedBy: { - readonly __typename?: 'User'; - readonly html_url: string; - readonly login: string; + readonly open_issues_count: number | null; + readonly owner: { readonly avatar_url: string } | null; }; + readonly vote: { readonly vote_value: number }; + readonly postedBy: { readonly html_url: string; readonly login: string }; }; export type FeedQueryVariables = Exact<{ type: FeedType; - offset?: InputMaybe; - limit?: InputMaybe; + offset?: number | null | undefined; + limit?: number | null | undefined; }>; export type FeedQuery = { - readonly __typename?: 'Query'; - readonly currentUser?: { readonly __typename?: 'User'; readonly login: string } | null; - readonly feed?: ReadonlyArray<{ - readonly __typename?: 'Entry'; + readonly currentUser: { readonly login: string } | null; + readonly feed: ReadonlyArray<{ readonly id: number; readonly commentCount: number; readonly score: number; readonly createdAt: number; readonly repository: { - readonly __typename?: 'Repository'; readonly full_name: string; readonly html_url: string; - readonly description?: string | null; + readonly description: string | null; readonly stargazers_count: number; - readonly open_issues_count?: number | null; - readonly owner?: { readonly __typename?: 'User'; readonly avatar_url: string } | null; - }; - readonly vote: { readonly __typename?: 'Vote'; readonly vote_value: number }; - readonly postedBy: { - readonly __typename?: 'User'; - readonly html_url: string; - readonly login: string; + readonly open_issues_count: number | null; + readonly owner: { readonly avatar_url: string } | null; }; + readonly vote: { readonly vote_value: number }; + readonly postedBy: { readonly html_url: string; readonly login: string }; } | null> | null; }; export type SubmitRepositoryMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; }>; export type SubmitRepositoryMutation = { - readonly __typename?: 'Mutation'; - readonly submitRepository?: { readonly __typename?: 'Entry'; readonly createdAt: number } | null; + readonly submitRepository: { readonly createdAt: number } | null; }; export type RepoInfoFragment = { - readonly __typename?: 'Entry'; readonly createdAt: number; readonly repository: { - readonly __typename?: 'Repository'; - readonly description?: string | null; + readonly description: string | null; readonly stargazers_count: number; - readonly open_issues_count?: number | null; - }; - readonly postedBy: { - readonly __typename?: 'User'; - readonly html_url: string; - readonly login: string; + readonly open_issues_count: number | null; }; + readonly postedBy: { readonly html_url: string; readonly login: string }; }; export type SubmitCommentMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; - commentContent: Scalars['String']['input']; + repoFullName: string; + commentContent: string; }>; export type SubmitCommentMutation = { - readonly __typename?: 'Mutation'; - readonly submitComment?: { - readonly __typename?: 'Comment'; + readonly submitComment: { readonly id: number; readonly createdAt: number; readonly content: string; - readonly postedBy: { - readonly __typename?: 'User'; - readonly login: string; - readonly html_url: string; - }; + readonly postedBy: { readonly login: string; readonly html_url: string }; } | null; }; export type VoteButtonsFragment = { - readonly __typename?: 'Entry'; readonly score: number; - readonly vote: { readonly __typename?: 'Vote'; readonly vote_value: number }; + readonly vote: { readonly vote_value: number }; }; export type VoteMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; type: VoteType; }>; export type VoteMutation = { - readonly __typename?: 'Mutation'; - readonly vote?: { - readonly __typename?: 'Entry'; + readonly vote: { readonly score: number; readonly id: number; - readonly vote: { readonly __typename?: 'Vote'; readonly vote_value: number }; + readonly vote: { readonly vote_value: number }; } | null; }; diff --git a/dev-test/githunt/types.onlyEnums.ts b/dev-test/githunt/types.onlyEnums.ts index 941573d8a76..1bd6a5f0fcd 100644 --- a/dev-test/githunt/types.onlyEnums.ts +++ b/dev-test/githunt/types.onlyEnums.ts @@ -1,16 +1,11 @@ /** A list of options for the sort order of the feed */ -export enum FeedType { +export type FeedType = /** Sort by a combination of freshness and score, using Reddit's algorithm */ - Hot = 'HOT', + | 'HOT' /** Newest entries first */ - New = 'NEW', + | 'NEW' /** Highest score entries first */ - Top = 'TOP', -} + | 'TOP'; /** The type of vote to record, when submitting a vote */ -export enum VoteType { - Cancel = 'CANCEL', - Down = 'DOWN', - Up = 'UP', -} +export type VoteType = 'CANCEL' | 'DOWN' | 'UP'; diff --git a/dev-test/githunt/types.preResolveTypes.onlyOperationTypes.ts b/dev-test/githunt/types.preResolveTypes.onlyOperationTypes.ts index fafa495e046..fe2ef34a356 100644 --- a/dev-test/githunt/types.preResolveTypes.onlyOperationTypes.ts +++ b/dev-test/githunt/types.preResolveTypes.onlyOperationTypes.ts @@ -1,81 +1,56 @@ -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - /** A list of options for the sort order of the feed */ -export enum FeedType { +export type FeedType = /** Sort by a combination of freshness and score, using Reddit's algorithm */ - Hot = 'HOT', + | 'HOT' /** Newest entries first */ - New = 'NEW', + | 'NEW' /** Highest score entries first */ - Top = 'TOP', -} + | 'TOP'; /** The type of vote to record, when submitting a vote */ -export enum VoteType { - Cancel = 'CANCEL', - Down = 'DOWN', - Up = 'UP', -} +export type VoteType = 'CANCEL' | 'DOWN' | 'UP'; export type OnCommentAddedSubscriptionVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; }>; export type OnCommentAddedSubscription = { - __typename?: 'Subscription'; - commentAdded?: { - __typename?: 'Comment'; + commentAdded: { id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; } | null; }; export type CommentQueryVariables = Exact<{ - repoFullName: Scalars['String']['input']; - limit?: InputMaybe; - offset?: InputMaybe; + repoFullName: string; + limit?: number | null | undefined; + offset?: number | null | undefined; }>; export type CommentQuery = { - __typename?: 'Query'; - currentUser?: { __typename?: 'User'; login: string; html_url: string } | null; - entry?: { - __typename?: 'Entry'; + currentUser: { login: string; html_url: string } | null; + entry: { id: number; createdAt: number; commentCount: number; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; comments: Array<{ - __typename?: 'Comment'; id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; } | null>; repository: { - __typename?: 'Repository'; - description?: string | null; - open_issues_count?: number | null; + description: string | null; + open_issues_count: number | null; stargazers_count: number; full_name: string; html_url: string; @@ -84,122 +59,98 @@ export type CommentQuery = { }; export type CommentsPageCommentFragment = { - __typename?: 'Comment'; id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; }; export type CurrentUserForProfileQueryVariables = Exact<{ [key: string]: never }>; export type CurrentUserForProfileQuery = { - __typename?: 'Query'; - currentUser?: { __typename?: 'User'; login: string; avatar_url: string } | null; + currentUser: { login: string; avatar_url: string } | null; }; export type FeedEntryFragment = { - __typename?: 'Entry'; id: number; commentCount: number; score: number; createdAt: number; repository: { - __typename?: 'Repository'; full_name: string; html_url: string; - description?: string | null; + description: string | null; stargazers_count: number; - open_issues_count?: number | null; - owner?: { __typename?: 'User'; avatar_url: string } | null; + open_issues_count: number | null; + owner: { avatar_url: string } | null; }; - vote: { __typename?: 'Vote'; vote_value: number }; - postedBy: { __typename?: 'User'; html_url: string; login: string }; + vote: { vote_value: number }; + postedBy: { html_url: string; login: string }; }; export type FeedQueryVariables = Exact<{ type: FeedType; - offset?: InputMaybe; - limit?: InputMaybe; + offset?: number | null | undefined; + limit?: number | null | undefined; }>; export type FeedQuery = { - __typename?: 'Query'; - currentUser?: { __typename?: 'User'; login: string } | null; - feed?: Array<{ - __typename?: 'Entry'; + currentUser: { login: string } | null; + feed: Array<{ id: number; commentCount: number; score: number; createdAt: number; repository: { - __typename?: 'Repository'; full_name: string; html_url: string; - description?: string | null; + description: string | null; stargazers_count: number; - open_issues_count?: number | null; - owner?: { __typename?: 'User'; avatar_url: string } | null; + open_issues_count: number | null; + owner: { avatar_url: string } | null; }; - vote: { __typename?: 'Vote'; vote_value: number }; - postedBy: { __typename?: 'User'; html_url: string; login: string }; + vote: { vote_value: number }; + postedBy: { html_url: string; login: string }; } | null> | null; }; export type SubmitRepositoryMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; }>; -export type SubmitRepositoryMutation = { - __typename?: 'Mutation'; - submitRepository?: { __typename?: 'Entry'; createdAt: number } | null; -}; +export type SubmitRepositoryMutation = { submitRepository: { createdAt: number } | null }; export type RepoInfoFragment = { - __typename?: 'Entry'; createdAt: number; repository: { - __typename?: 'Repository'; - description?: string | null; + description: string | null; stargazers_count: number; - open_issues_count?: number | null; + open_issues_count: number | null; }; - postedBy: { __typename?: 'User'; html_url: string; login: string }; + postedBy: { html_url: string; login: string }; }; export type SubmitCommentMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; - commentContent: Scalars['String']['input']; + repoFullName: string; + commentContent: string; }>; export type SubmitCommentMutation = { - __typename?: 'Mutation'; - submitComment?: { - __typename?: 'Comment'; + submitComment: { id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; } | null; }; -export type VoteButtonsFragment = { - __typename?: 'Entry'; - score: number; - vote: { __typename?: 'Vote'; vote_value: number }; -}; +export type VoteButtonsFragment = { score: number; vote: { vote_value: number } }; export type VoteMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; type: VoteType; }>; export type VoteMutation = { - __typename?: 'Mutation'; - vote?: { - __typename?: 'Entry'; - score: number; - id: number; - vote: { __typename?: 'Vote'; vote_value: number }; - } | null; + vote: { score: number; id: number; vote: { vote_value: number } } | null; }; diff --git a/dev-test/githunt/types.preResolveTypes.ts b/dev-test/githunt/types.preResolveTypes.ts index 057f9f78ccd..fe2ef34a356 100644 --- a/dev-test/githunt/types.preResolveTypes.ts +++ b/dev-test/githunt/types.preResolveTypes.ts @@ -1,218 +1,56 @@ -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A comment about an entry, submitted by a user */ -export type Comment = { - __typename?: 'Comment'; - /** The text of the comment */ - content: Scalars['String']['output']; - /** A timestamp of when the comment was posted */ - createdAt: Scalars['Float']['output']; - /** The SQL ID of this entry */ - id: Scalars['Int']['output']; - /** The GitHub user who posted the comment */ - postedBy: User; - /** The repository which this comment is about */ - repoName: Scalars['String']['output']; -}; - -/** Information about a GitHub repository submitted to GitHunt */ -export type Entry = { - __typename?: 'Entry'; - /** The number of comments posted about this repository */ - commentCount: Scalars['Int']['output']; - /** Comments posted about this repository */ - comments: Array>; - /** A timestamp of when the entry was submitted */ - createdAt: Scalars['Float']['output']; - /** The hot score of this repository */ - hotScore: Scalars['Float']['output']; - /** The SQL ID of this entry */ - id: Scalars['Int']['output']; - /** The GitHub user who submitted this entry */ - postedBy: User; - /** Information about the repository from GitHub */ - repository: Repository; - /** The score of this repository, upvotes - downvotes */ - score: Scalars['Int']['output']; - /** XXX to be changed */ - vote: Vote; -}; - -/** Information about a GitHub repository submitted to GitHunt */ -export type EntryCommentsArgs = { - limit?: InputMaybe; - offset?: InputMaybe; -}; - /** A list of options for the sort order of the feed */ -export enum FeedType { +export type FeedType = /** Sort by a combination of freshness and score, using Reddit's algorithm */ - Hot = 'HOT', + | 'HOT' /** Newest entries first */ - New = 'NEW', + | 'NEW' /** Highest score entries first */ - Top = 'TOP', -} - -export type Mutation = { - __typename?: 'Mutation'; - /** Comment on a repository, returns the new comment */ - submitComment?: Maybe; - /** Submit a new repository, returns the new submission */ - submitRepository?: Maybe; - /** Vote on a repository submission, returns the submission that was voted on */ - vote?: Maybe; -}; - -export type MutationSubmitCommentArgs = { - commentContent: Scalars['String']['input']; - repoFullName: Scalars['String']['input']; -}; - -export type MutationSubmitRepositoryArgs = { - repoFullName: Scalars['String']['input']; -}; - -export type MutationVoteArgs = { - repoFullName: Scalars['String']['input']; - type: VoteType; -}; - -export type Query = { - __typename?: 'Query'; - /** Return the currently logged in user, or null if nobody is logged in */ - currentUser?: Maybe; - /** A single entry */ - entry?: Maybe; - /** A feed of repository submissions */ - feed?: Maybe>>; -}; - -export type QueryEntryArgs = { - repoFullName: Scalars['String']['input']; -}; - -export type QueryFeedArgs = { - limit?: InputMaybe; - offset?: InputMaybe; - type: FeedType; -}; - -/** - * A repository object from the GitHub API. This uses the exact field names returned by the - * GitHub API for simplicity, even though the convention for GraphQL is usually to camel case. - */ -export type Repository = { - __typename?: 'Repository'; - /** The description of the repository */ - description?: Maybe; - /** The full name of the repository with the username, e.g. apollostack/GitHunt-API */ - full_name: Scalars['String']['output']; - /** The link to the repository on GitHub */ - html_url: Scalars['String']['output']; - /** Just the name of the repository, e.g. GitHunt-API */ - name: Scalars['String']['output']; - /** The number of open issues on this repository on GitHub */ - open_issues_count?: Maybe; - /** The owner of this repository on GitHub, e.g. apollostack */ - owner?: Maybe; - /** The number of people who have starred this repository on GitHub */ - stargazers_count: Scalars['Int']['output']; -}; - -export type Subscription = { - __typename?: 'Subscription'; - /** Subscription fires on every comment added */ - commentAdded?: Maybe; -}; - -export type SubscriptionCommentAddedArgs = { - repoFullName: Scalars['String']['input']; -}; - -/** A user object from the GitHub API. This uses the exact field names returned from the GitHub API. */ -export type User = { - __typename?: 'User'; - /** The URL to a directly embeddable image for this user's avatar */ - avatar_url: Scalars['String']['output']; - /** The URL of this user's GitHub page */ - html_url: Scalars['String']['output']; - /** The name of the user, e.g. apollostack */ - login: Scalars['String']['output']; -}; - -/** XXX to be removed */ -export type Vote = { - __typename?: 'Vote'; - vote_value: Scalars['Int']['output']; -}; + | 'TOP'; /** The type of vote to record, when submitting a vote */ -export enum VoteType { - Cancel = 'CANCEL', - Down = 'DOWN', - Up = 'UP', -} +export type VoteType = 'CANCEL' | 'DOWN' | 'UP'; export type OnCommentAddedSubscriptionVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; }>; export type OnCommentAddedSubscription = { - __typename?: 'Subscription'; - commentAdded?: { - __typename?: 'Comment'; + commentAdded: { id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; } | null; }; export type CommentQueryVariables = Exact<{ - repoFullName: Scalars['String']['input']; - limit?: InputMaybe; - offset?: InputMaybe; + repoFullName: string; + limit?: number | null | undefined; + offset?: number | null | undefined; }>; export type CommentQuery = { - __typename?: 'Query'; - currentUser?: { __typename?: 'User'; login: string; html_url: string } | null; - entry?: { - __typename?: 'Entry'; + currentUser: { login: string; html_url: string } | null; + entry: { id: number; createdAt: number; commentCount: number; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; comments: Array<{ - __typename?: 'Comment'; id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; } | null>; repository: { - __typename?: 'Repository'; - description?: string | null; - open_issues_count?: number | null; + description: string | null; + open_issues_count: number | null; stargazers_count: number; full_name: string; html_url: string; @@ -221,122 +59,98 @@ export type CommentQuery = { }; export type CommentsPageCommentFragment = { - __typename?: 'Comment'; id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; }; export type CurrentUserForProfileQueryVariables = Exact<{ [key: string]: never }>; export type CurrentUserForProfileQuery = { - __typename?: 'Query'; - currentUser?: { __typename?: 'User'; login: string; avatar_url: string } | null; + currentUser: { login: string; avatar_url: string } | null; }; export type FeedEntryFragment = { - __typename?: 'Entry'; id: number; commentCount: number; score: number; createdAt: number; repository: { - __typename?: 'Repository'; full_name: string; html_url: string; - description?: string | null; + description: string | null; stargazers_count: number; - open_issues_count?: number | null; - owner?: { __typename?: 'User'; avatar_url: string } | null; + open_issues_count: number | null; + owner: { avatar_url: string } | null; }; - vote: { __typename?: 'Vote'; vote_value: number }; - postedBy: { __typename?: 'User'; html_url: string; login: string }; + vote: { vote_value: number }; + postedBy: { html_url: string; login: string }; }; export type FeedQueryVariables = Exact<{ type: FeedType; - offset?: InputMaybe; - limit?: InputMaybe; + offset?: number | null | undefined; + limit?: number | null | undefined; }>; export type FeedQuery = { - __typename?: 'Query'; - currentUser?: { __typename?: 'User'; login: string } | null; - feed?: Array<{ - __typename?: 'Entry'; + currentUser: { login: string } | null; + feed: Array<{ id: number; commentCount: number; score: number; createdAt: number; repository: { - __typename?: 'Repository'; full_name: string; html_url: string; - description?: string | null; + description: string | null; stargazers_count: number; - open_issues_count?: number | null; - owner?: { __typename?: 'User'; avatar_url: string } | null; + open_issues_count: number | null; + owner: { avatar_url: string } | null; }; - vote: { __typename?: 'Vote'; vote_value: number }; - postedBy: { __typename?: 'User'; html_url: string; login: string }; + vote: { vote_value: number }; + postedBy: { html_url: string; login: string }; } | null> | null; }; export type SubmitRepositoryMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; }>; -export type SubmitRepositoryMutation = { - __typename?: 'Mutation'; - submitRepository?: { __typename?: 'Entry'; createdAt: number } | null; -}; +export type SubmitRepositoryMutation = { submitRepository: { createdAt: number } | null }; export type RepoInfoFragment = { - __typename?: 'Entry'; createdAt: number; repository: { - __typename?: 'Repository'; - description?: string | null; + description: string | null; stargazers_count: number; - open_issues_count?: number | null; + open_issues_count: number | null; }; - postedBy: { __typename?: 'User'; html_url: string; login: string }; + postedBy: { html_url: string; login: string }; }; export type SubmitCommentMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; - commentContent: Scalars['String']['input']; + repoFullName: string; + commentContent: string; }>; export type SubmitCommentMutation = { - __typename?: 'Mutation'; - submitComment?: { - __typename?: 'Comment'; + submitComment: { id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; } | null; }; -export type VoteButtonsFragment = { - __typename?: 'Entry'; - score: number; - vote: { __typename?: 'Vote'; vote_value: number }; -}; +export type VoteButtonsFragment = { score: number; vote: { vote_value: number } }; export type VoteMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; type: VoteType; }>; export type VoteMutation = { - __typename?: 'Mutation'; - vote?: { - __typename?: 'Entry'; - score: number; - id: number; - vote: { __typename?: 'Vote'; vote_value: number }; - } | null; + vote: { score: number; id: number; vote: { vote_value: number } } | null; }; diff --git a/dev-test/githunt/types.ts b/dev-test/githunt/types.ts index 057f9f78ccd..fe2ef34a356 100644 --- a/dev-test/githunt/types.ts +++ b/dev-test/githunt/types.ts @@ -1,218 +1,56 @@ -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A comment about an entry, submitted by a user */ -export type Comment = { - __typename?: 'Comment'; - /** The text of the comment */ - content: Scalars['String']['output']; - /** A timestamp of when the comment was posted */ - createdAt: Scalars['Float']['output']; - /** The SQL ID of this entry */ - id: Scalars['Int']['output']; - /** The GitHub user who posted the comment */ - postedBy: User; - /** The repository which this comment is about */ - repoName: Scalars['String']['output']; -}; - -/** Information about a GitHub repository submitted to GitHunt */ -export type Entry = { - __typename?: 'Entry'; - /** The number of comments posted about this repository */ - commentCount: Scalars['Int']['output']; - /** Comments posted about this repository */ - comments: Array>; - /** A timestamp of when the entry was submitted */ - createdAt: Scalars['Float']['output']; - /** The hot score of this repository */ - hotScore: Scalars['Float']['output']; - /** The SQL ID of this entry */ - id: Scalars['Int']['output']; - /** The GitHub user who submitted this entry */ - postedBy: User; - /** Information about the repository from GitHub */ - repository: Repository; - /** The score of this repository, upvotes - downvotes */ - score: Scalars['Int']['output']; - /** XXX to be changed */ - vote: Vote; -}; - -/** Information about a GitHub repository submitted to GitHunt */ -export type EntryCommentsArgs = { - limit?: InputMaybe; - offset?: InputMaybe; -}; - /** A list of options for the sort order of the feed */ -export enum FeedType { +export type FeedType = /** Sort by a combination of freshness and score, using Reddit's algorithm */ - Hot = 'HOT', + | 'HOT' /** Newest entries first */ - New = 'NEW', + | 'NEW' /** Highest score entries first */ - Top = 'TOP', -} - -export type Mutation = { - __typename?: 'Mutation'; - /** Comment on a repository, returns the new comment */ - submitComment?: Maybe; - /** Submit a new repository, returns the new submission */ - submitRepository?: Maybe; - /** Vote on a repository submission, returns the submission that was voted on */ - vote?: Maybe; -}; - -export type MutationSubmitCommentArgs = { - commentContent: Scalars['String']['input']; - repoFullName: Scalars['String']['input']; -}; - -export type MutationSubmitRepositoryArgs = { - repoFullName: Scalars['String']['input']; -}; - -export type MutationVoteArgs = { - repoFullName: Scalars['String']['input']; - type: VoteType; -}; - -export type Query = { - __typename?: 'Query'; - /** Return the currently logged in user, or null if nobody is logged in */ - currentUser?: Maybe; - /** A single entry */ - entry?: Maybe; - /** A feed of repository submissions */ - feed?: Maybe>>; -}; - -export type QueryEntryArgs = { - repoFullName: Scalars['String']['input']; -}; - -export type QueryFeedArgs = { - limit?: InputMaybe; - offset?: InputMaybe; - type: FeedType; -}; - -/** - * A repository object from the GitHub API. This uses the exact field names returned by the - * GitHub API for simplicity, even though the convention for GraphQL is usually to camel case. - */ -export type Repository = { - __typename?: 'Repository'; - /** The description of the repository */ - description?: Maybe; - /** The full name of the repository with the username, e.g. apollostack/GitHunt-API */ - full_name: Scalars['String']['output']; - /** The link to the repository on GitHub */ - html_url: Scalars['String']['output']; - /** Just the name of the repository, e.g. GitHunt-API */ - name: Scalars['String']['output']; - /** The number of open issues on this repository on GitHub */ - open_issues_count?: Maybe; - /** The owner of this repository on GitHub, e.g. apollostack */ - owner?: Maybe; - /** The number of people who have starred this repository on GitHub */ - stargazers_count: Scalars['Int']['output']; -}; - -export type Subscription = { - __typename?: 'Subscription'; - /** Subscription fires on every comment added */ - commentAdded?: Maybe; -}; - -export type SubscriptionCommentAddedArgs = { - repoFullName: Scalars['String']['input']; -}; - -/** A user object from the GitHub API. This uses the exact field names returned from the GitHub API. */ -export type User = { - __typename?: 'User'; - /** The URL to a directly embeddable image for this user's avatar */ - avatar_url: Scalars['String']['output']; - /** The URL of this user's GitHub page */ - html_url: Scalars['String']['output']; - /** The name of the user, e.g. apollostack */ - login: Scalars['String']['output']; -}; - -/** XXX to be removed */ -export type Vote = { - __typename?: 'Vote'; - vote_value: Scalars['Int']['output']; -}; + | 'TOP'; /** The type of vote to record, when submitting a vote */ -export enum VoteType { - Cancel = 'CANCEL', - Down = 'DOWN', - Up = 'UP', -} +export type VoteType = 'CANCEL' | 'DOWN' | 'UP'; export type OnCommentAddedSubscriptionVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; }>; export type OnCommentAddedSubscription = { - __typename?: 'Subscription'; - commentAdded?: { - __typename?: 'Comment'; + commentAdded: { id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; } | null; }; export type CommentQueryVariables = Exact<{ - repoFullName: Scalars['String']['input']; - limit?: InputMaybe; - offset?: InputMaybe; + repoFullName: string; + limit?: number | null | undefined; + offset?: number | null | undefined; }>; export type CommentQuery = { - __typename?: 'Query'; - currentUser?: { __typename?: 'User'; login: string; html_url: string } | null; - entry?: { - __typename?: 'Entry'; + currentUser: { login: string; html_url: string } | null; + entry: { id: number; createdAt: number; commentCount: number; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; comments: Array<{ - __typename?: 'Comment'; id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; } | null>; repository: { - __typename?: 'Repository'; - description?: string | null; - open_issues_count?: number | null; + description: string | null; + open_issues_count: number | null; stargazers_count: number; full_name: string; html_url: string; @@ -221,122 +59,98 @@ export type CommentQuery = { }; export type CommentsPageCommentFragment = { - __typename?: 'Comment'; id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; }; export type CurrentUserForProfileQueryVariables = Exact<{ [key: string]: never }>; export type CurrentUserForProfileQuery = { - __typename?: 'Query'; - currentUser?: { __typename?: 'User'; login: string; avatar_url: string } | null; + currentUser: { login: string; avatar_url: string } | null; }; export type FeedEntryFragment = { - __typename?: 'Entry'; id: number; commentCount: number; score: number; createdAt: number; repository: { - __typename?: 'Repository'; full_name: string; html_url: string; - description?: string | null; + description: string | null; stargazers_count: number; - open_issues_count?: number | null; - owner?: { __typename?: 'User'; avatar_url: string } | null; + open_issues_count: number | null; + owner: { avatar_url: string } | null; }; - vote: { __typename?: 'Vote'; vote_value: number }; - postedBy: { __typename?: 'User'; html_url: string; login: string }; + vote: { vote_value: number }; + postedBy: { html_url: string; login: string }; }; export type FeedQueryVariables = Exact<{ type: FeedType; - offset?: InputMaybe; - limit?: InputMaybe; + offset?: number | null | undefined; + limit?: number | null | undefined; }>; export type FeedQuery = { - __typename?: 'Query'; - currentUser?: { __typename?: 'User'; login: string } | null; - feed?: Array<{ - __typename?: 'Entry'; + currentUser: { login: string } | null; + feed: Array<{ id: number; commentCount: number; score: number; createdAt: number; repository: { - __typename?: 'Repository'; full_name: string; html_url: string; - description?: string | null; + description: string | null; stargazers_count: number; - open_issues_count?: number | null; - owner?: { __typename?: 'User'; avatar_url: string } | null; + open_issues_count: number | null; + owner: { avatar_url: string } | null; }; - vote: { __typename?: 'Vote'; vote_value: number }; - postedBy: { __typename?: 'User'; html_url: string; login: string }; + vote: { vote_value: number }; + postedBy: { html_url: string; login: string }; } | null> | null; }; export type SubmitRepositoryMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; }>; -export type SubmitRepositoryMutation = { - __typename?: 'Mutation'; - submitRepository?: { __typename?: 'Entry'; createdAt: number } | null; -}; +export type SubmitRepositoryMutation = { submitRepository: { createdAt: number } | null }; export type RepoInfoFragment = { - __typename?: 'Entry'; createdAt: number; repository: { - __typename?: 'Repository'; - description?: string | null; + description: string | null; stargazers_count: number; - open_issues_count?: number | null; + open_issues_count: number | null; }; - postedBy: { __typename?: 'User'; html_url: string; login: string }; + postedBy: { html_url: string; login: string }; }; export type SubmitCommentMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; - commentContent: Scalars['String']['input']; + repoFullName: string; + commentContent: string; }>; export type SubmitCommentMutation = { - __typename?: 'Mutation'; - submitComment?: { - __typename?: 'Comment'; + submitComment: { id: number; createdAt: number; content: string; - postedBy: { __typename?: 'User'; login: string; html_url: string }; + postedBy: { login: string; html_url: string }; } | null; }; -export type VoteButtonsFragment = { - __typename?: 'Entry'; - score: number; - vote: { __typename?: 'Vote'; vote_value: number }; -}; +export type VoteButtonsFragment = { score: number; vote: { vote_value: number } }; export type VoteMutationVariables = Exact<{ - repoFullName: Scalars['String']['input']; + repoFullName: string; type: VoteType; }>; export type VoteMutation = { - __typename?: 'Mutation'; - vote?: { - __typename?: 'Entry'; - score: number; - id: number; - vote: { __typename?: 'Vote'; vote_value: number }; - } | null; + vote: { score: number; id: number; vote: { vote_value: number } } | null; }; diff --git a/dev-test/gql-tag-operations-masking/gql/graphql.ts b/dev-test/gql-tag-operations-masking/gql/graphql.ts index fe63c39880c..d442a0136d9 100644 --- a/dev-test/gql-tag-operations-masking/gql/graphql.ts +++ b/dev-test/gql-tag-operations-masking/gql/graphql.ts @@ -1,139 +1,31 @@ -/* eslint-disable */ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; -export type Maybe = T | null; -export type InputMaybe = T | null | undefined; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/* eslint-disable */ +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; - Date: { input: any; output: any }; - Url: { input: any; output: any }; -}; - -export type Meta = { - __typename?: 'Meta'; - count?: Maybe; -}; - -export type Mutation = { - __typename?: 'Mutation'; - createTweet?: Maybe; - deleteTweet?: Maybe; - markTweetRead?: Maybe; -}; - -export type MutationCreateTweetArgs = { - body?: InputMaybe; -}; - -export type MutationDeleteTweetArgs = { - id: Scalars['ID']['input']; -}; - -export type MutationMarkTweetReadArgs = { - id: Scalars['ID']['input']; -}; - -export type Notification = { - __typename?: 'Notification'; - date?: Maybe; - id?: Maybe; - type?: Maybe; -}; - -export type Query = { - __typename?: 'Query'; - Notifications?: Maybe>>; - NotificationsMeta?: Maybe; - Tweet?: Maybe; - Tweets?: Maybe>; - TweetsMeta?: Maybe; - User?: Maybe; -}; - -export type QueryNotificationsArgs = { - limit?: InputMaybe; -}; - -export type QueryTweetArgs = { - id: Scalars['ID']['input']; -}; - -export type QueryTweetsArgs = { - limit?: InputMaybe; - skip?: InputMaybe; - sort_field?: InputMaybe; - sort_order?: InputMaybe; -}; - -export type QueryUserArgs = { - id: Scalars['ID']['input']; -}; - -export type Stat = { - __typename?: 'Stat'; - likes?: Maybe; - responses?: Maybe; - retweets?: Maybe; - views?: Maybe; -}; - -export type Tweet = { - __typename?: 'Tweet'; - Stats?: Maybe; - author: User; - body: Scalars['String']['output']; - date?: Maybe; - id: Scalars['ID']['output']; -}; - -export type User = { - __typename?: 'User'; - avatar_url?: Maybe; - first_name?: Maybe; - full_name?: Maybe; - id: Scalars['ID']['output']; - last_name?: Maybe; - /** @deprecated Field no longer supported */ - name?: Maybe; - username?: Maybe; -}; -export type TweetFragmentFragment = ({ __typename?: 'Tweet'; id: string; body: string } & { +export type TweetFragmentFragment = ({ id: string; body: string } & { ' $fragmentRefs'?: { TweetAuthorFragmentFragment: TweetAuthorFragmentFragment }; }) & { ' $fragmentName'?: 'TweetFragmentFragment' }; export type TweetAuthorFragmentFragment = { - __typename?: 'Tweet'; id: string; - author: { __typename?: 'User'; id: string; username?: string | null }; + author: { id: string; username: string | null }; } & { ' $fragmentName'?: 'TweetAuthorFragmentFragment' }; export type TweetsFragmentFragment = { - __typename?: 'Query'; - Tweets?: Array< - { __typename?: 'Tweet'; id: string } & { - ' $fragmentRefs'?: { TweetFragmentFragment: TweetFragmentFragment }; - } + Tweets: Array< + { id: string } & { ' $fragmentRefs'?: { TweetFragmentFragment: TweetFragmentFragment } } > | null; } & { ' $fragmentName'?: 'TweetsFragmentFragment' }; export type TweetAppQueryQueryVariables = Exact<{ [key: string]: never }>; -export type TweetAppQueryQuery = { __typename?: 'Query' } & { +export type TweetAppQueryQuery = { ' $fragmentRefs'?: { TweetsFragmentFragment: TweetsFragmentFragment }; }; diff --git a/dev-test/gql-tag-operations-urql/gql/graphql.ts b/dev-test/gql-tag-operations-urql/gql/graphql.ts index b1f670a60f3..fb143deb0cb 100644 --- a/dev-test/gql-tag-operations-urql/gql/graphql.ts +++ b/dev-test/gql-tag-operations-urql/gql/graphql.ts @@ -1,135 +1,25 @@ -/* eslint-disable */ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; -export type Maybe = T | null; -export type InputMaybe = T | null | undefined; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/* eslint-disable */ +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; - Date: { input: any; output: any }; - Url: { input: any; output: any }; -}; - -export type Meta = { - __typename?: 'Meta'; - count?: Maybe; -}; - -export type Mutation = { - __typename?: 'Mutation'; - createTweet?: Maybe; - deleteTweet?: Maybe; - markTweetRead?: Maybe; -}; - -export type MutationCreateTweetArgs = { - body?: InputMaybe; -}; - -export type MutationDeleteTweetArgs = { - id: Scalars['ID']['input']; -}; - -export type MutationMarkTweetReadArgs = { - id: Scalars['ID']['input']; -}; - -export type Notification = { - __typename?: 'Notification'; - date?: Maybe; - id?: Maybe; - type?: Maybe; -}; - -export type Query = { - __typename?: 'Query'; - Notifications?: Maybe>>; - NotificationsMeta?: Maybe; - Tweet?: Maybe; - Tweets?: Maybe>>; - TweetsMeta?: Maybe; - User?: Maybe; -}; - -export type QueryNotificationsArgs = { - limit?: InputMaybe; -}; - -export type QueryTweetArgs = { - id: Scalars['ID']['input']; -}; - -export type QueryTweetsArgs = { - limit?: InputMaybe; - skip?: InputMaybe; - sort_field?: InputMaybe; - sort_order?: InputMaybe; -}; - -export type QueryUserArgs = { - id: Scalars['ID']['input']; -}; - -export type Stat = { - __typename?: 'Stat'; - likes?: Maybe; - responses?: Maybe; - retweets?: Maybe; - views?: Maybe; -}; - -export type Tweet = { - __typename?: 'Tweet'; - Author?: Maybe; - Stats?: Maybe; - body?: Maybe; - date?: Maybe; - id: Scalars['ID']['output']; -}; - -export type User = { - __typename?: 'User'; - avatar_url?: Maybe; - first_name?: Maybe; - full_name?: Maybe; - id: Scalars['ID']['output']; - last_name?: Maybe; - /** @deprecated Field no longer supported */ - name?: Maybe; - username?: Maybe; -}; export type FooQueryVariables = Exact<{ [key: string]: never }>; -export type FooQuery = { - __typename?: 'Query'; - Tweets?: Array<{ __typename?: 'Tweet'; id: string } | null> | null; -}; +export type FooQuery = { Tweets: Array<{ id: string } | null> | null }; -export type LelFragment = { __typename?: 'Tweet'; id: string; body?: string | null } & { +export type LelFragment = { id: string; body: string | null } & { ' $fragmentName'?: 'LelFragment'; }; export type BarQueryVariables = Exact<{ [key: string]: never }>; export type BarQuery = { - __typename?: 'Query'; - Tweets?: Array< - ({ __typename?: 'Tweet' } & { ' $fragmentRefs'?: { LelFragment: LelFragment } }) | null - > | null; + Tweets: Array<{ ' $fragmentRefs'?: { LelFragment: LelFragment } } | null> | null; }; export const LelFragmentDoc = { diff --git a/dev-test/gql-tag-operations/gql/gql.ts b/dev-test/gql-tag-operations/gql/gql.ts index fc9ac53a8f3..097e2d716e5 100644 --- a/dev-test/gql-tag-operations/gql/gql.ts +++ b/dev-test/gql-tag-operations/gql/gql.ts @@ -15,12 +15,12 @@ import * as types from './graphql.js'; */ type Documents = { '\n query Foo {\n Tweets {\n id\n }\n }\n': typeof types.FooDocument; - '\n fragment Lel on Tweet {\n id\n body\n }\n': typeof types.LelFragmentDoc; + '\n fragment Lel on Tweet {\n id\n body\n date\n }\n': typeof types.LelFragmentDoc; '\n query Bar {\n Tweets {\n ...Lel\n }\n }\n': typeof types.BarDocument; }; const documents: Documents = { '\n query Foo {\n Tweets {\n id\n }\n }\n': types.FooDocument, - '\n fragment Lel on Tweet {\n id\n body\n }\n': types.LelFragmentDoc, + '\n fragment Lel on Tweet {\n id\n body\n date\n }\n': types.LelFragmentDoc, '\n query Bar {\n Tweets {\n ...Lel\n }\n }\n': types.BarDocument, }; @@ -48,8 +48,8 @@ export function graphql( * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ export function graphql( - source: '\n fragment Lel on Tweet {\n id\n body\n }\n', -): (typeof documents)['\n fragment Lel on Tweet {\n id\n body\n }\n']; + source: '\n fragment Lel on Tweet {\n id\n body\n date\n }\n', +): (typeof documents)['\n fragment Lel on Tweet {\n id\n body\n date\n }\n']; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/dev-test/gql-tag-operations/gql/graphql.ts b/dev-test/gql-tag-operations/gql/graphql.ts index b1f670a60f3..148be727022 100644 --- a/dev-test/gql-tag-operations/gql/graphql.ts +++ b/dev-test/gql-tag-operations/gql/graphql.ts @@ -1,135 +1,25 @@ -/* eslint-disable */ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; -export type Maybe = T | null; -export type InputMaybe = T | null | undefined; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/* eslint-disable */ +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; - Date: { input: any; output: any }; - Url: { input: any; output: any }; -}; - -export type Meta = { - __typename?: 'Meta'; - count?: Maybe; -}; - -export type Mutation = { - __typename?: 'Mutation'; - createTweet?: Maybe; - deleteTweet?: Maybe; - markTweetRead?: Maybe; -}; - -export type MutationCreateTweetArgs = { - body?: InputMaybe; -}; - -export type MutationDeleteTweetArgs = { - id: Scalars['ID']['input']; -}; - -export type MutationMarkTweetReadArgs = { - id: Scalars['ID']['input']; -}; - -export type Notification = { - __typename?: 'Notification'; - date?: Maybe; - id?: Maybe; - type?: Maybe; -}; - -export type Query = { - __typename?: 'Query'; - Notifications?: Maybe>>; - NotificationsMeta?: Maybe; - Tweet?: Maybe; - Tweets?: Maybe>>; - TweetsMeta?: Maybe; - User?: Maybe; -}; - -export type QueryNotificationsArgs = { - limit?: InputMaybe; -}; - -export type QueryTweetArgs = { - id: Scalars['ID']['input']; -}; - -export type QueryTweetsArgs = { - limit?: InputMaybe; - skip?: InputMaybe; - sort_field?: InputMaybe; - sort_order?: InputMaybe; -}; - -export type QueryUserArgs = { - id: Scalars['ID']['input']; -}; - -export type Stat = { - __typename?: 'Stat'; - likes?: Maybe; - responses?: Maybe; - retweets?: Maybe; - views?: Maybe; -}; - -export type Tweet = { - __typename?: 'Tweet'; - Author?: Maybe; - Stats?: Maybe; - body?: Maybe; - date?: Maybe; - id: Scalars['ID']['output']; -}; - -export type User = { - __typename?: 'User'; - avatar_url?: Maybe; - first_name?: Maybe; - full_name?: Maybe; - id: Scalars['ID']['output']; - last_name?: Maybe; - /** @deprecated Field no longer supported */ - name?: Maybe; - username?: Maybe; -}; export type FooQueryVariables = Exact<{ [key: string]: never }>; -export type FooQuery = { - __typename?: 'Query'; - Tweets?: Array<{ __typename?: 'Tweet'; id: string } | null> | null; -}; +export type FooQuery = { Tweets: Array<{ id: string } | null> | null }; -export type LelFragment = { __typename?: 'Tweet'; id: string; body?: string | null } & { +export type LelFragment = { id: string; body: string | null; date: unknown } & { ' $fragmentName'?: 'LelFragment'; }; export type BarQueryVariables = Exact<{ [key: string]: never }>; export type BarQuery = { - __typename?: 'Query'; - Tweets?: Array< - ({ __typename?: 'Tweet' } & { ' $fragmentRefs'?: { LelFragment: LelFragment } }) | null - > | null; + Tweets: Array<{ ' $fragmentRefs'?: { LelFragment: LelFragment } } | null> | null; }; export const LelFragmentDoc = { @@ -144,6 +34,7 @@ export const LelFragmentDoc = { selections: [ { kind: 'Field', name: { kind: 'Name', value: 'id' } }, { kind: 'Field', name: { kind: 'Name', value: 'body' } }, + { kind: 'Field', name: { kind: 'Name', value: 'date' } }, ], }, }, @@ -202,6 +93,7 @@ export const BarDocument = { selections: [ { kind: 'Field', name: { kind: 'Name', value: 'id' } }, { kind: 'Field', name: { kind: 'Name', value: 'body' } }, + { kind: 'Field', name: { kind: 'Name', value: 'date' } }, ], }, }, diff --git a/dev-test/gql-tag-operations/graphql/gql.ts b/dev-test/gql-tag-operations/graphql/gql.ts index fc9ac53a8f3..097e2d716e5 100644 --- a/dev-test/gql-tag-operations/graphql/gql.ts +++ b/dev-test/gql-tag-operations/graphql/gql.ts @@ -15,12 +15,12 @@ import * as types from './graphql.js'; */ type Documents = { '\n query Foo {\n Tweets {\n id\n }\n }\n': typeof types.FooDocument; - '\n fragment Lel on Tweet {\n id\n body\n }\n': typeof types.LelFragmentDoc; + '\n fragment Lel on Tweet {\n id\n body\n date\n }\n': typeof types.LelFragmentDoc; '\n query Bar {\n Tweets {\n ...Lel\n }\n }\n': typeof types.BarDocument; }; const documents: Documents = { '\n query Foo {\n Tweets {\n id\n }\n }\n': types.FooDocument, - '\n fragment Lel on Tweet {\n id\n body\n }\n': types.LelFragmentDoc, + '\n fragment Lel on Tweet {\n id\n body\n date\n }\n': types.LelFragmentDoc, '\n query Bar {\n Tweets {\n ...Lel\n }\n }\n': types.BarDocument, }; @@ -48,8 +48,8 @@ export function graphql( * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ export function graphql( - source: '\n fragment Lel on Tweet {\n id\n body\n }\n', -): (typeof documents)['\n fragment Lel on Tweet {\n id\n body\n }\n']; + source: '\n fragment Lel on Tweet {\n id\n body\n date\n }\n', +): (typeof documents)['\n fragment Lel on Tweet {\n id\n body\n date\n }\n']; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/dev-test/gql-tag-operations/graphql/graphql.ts b/dev-test/gql-tag-operations/graphql/graphql.ts index b1f670a60f3..148be727022 100644 --- a/dev-test/gql-tag-operations/graphql/graphql.ts +++ b/dev-test/gql-tag-operations/graphql/graphql.ts @@ -1,135 +1,25 @@ -/* eslint-disable */ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; -export type Maybe = T | null; -export type InputMaybe = T | null | undefined; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/* eslint-disable */ +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; - Date: { input: any; output: any }; - Url: { input: any; output: any }; -}; - -export type Meta = { - __typename?: 'Meta'; - count?: Maybe; -}; - -export type Mutation = { - __typename?: 'Mutation'; - createTweet?: Maybe; - deleteTweet?: Maybe; - markTweetRead?: Maybe; -}; - -export type MutationCreateTweetArgs = { - body?: InputMaybe; -}; - -export type MutationDeleteTweetArgs = { - id: Scalars['ID']['input']; -}; - -export type MutationMarkTweetReadArgs = { - id: Scalars['ID']['input']; -}; - -export type Notification = { - __typename?: 'Notification'; - date?: Maybe; - id?: Maybe; - type?: Maybe; -}; - -export type Query = { - __typename?: 'Query'; - Notifications?: Maybe>>; - NotificationsMeta?: Maybe; - Tweet?: Maybe; - Tweets?: Maybe>>; - TweetsMeta?: Maybe; - User?: Maybe; -}; - -export type QueryNotificationsArgs = { - limit?: InputMaybe; -}; - -export type QueryTweetArgs = { - id: Scalars['ID']['input']; -}; - -export type QueryTweetsArgs = { - limit?: InputMaybe; - skip?: InputMaybe; - sort_field?: InputMaybe; - sort_order?: InputMaybe; -}; - -export type QueryUserArgs = { - id: Scalars['ID']['input']; -}; - -export type Stat = { - __typename?: 'Stat'; - likes?: Maybe; - responses?: Maybe; - retweets?: Maybe; - views?: Maybe; -}; - -export type Tweet = { - __typename?: 'Tweet'; - Author?: Maybe; - Stats?: Maybe; - body?: Maybe; - date?: Maybe; - id: Scalars['ID']['output']; -}; - -export type User = { - __typename?: 'User'; - avatar_url?: Maybe; - first_name?: Maybe; - full_name?: Maybe; - id: Scalars['ID']['output']; - last_name?: Maybe; - /** @deprecated Field no longer supported */ - name?: Maybe; - username?: Maybe; -}; export type FooQueryVariables = Exact<{ [key: string]: never }>; -export type FooQuery = { - __typename?: 'Query'; - Tweets?: Array<{ __typename?: 'Tweet'; id: string } | null> | null; -}; +export type FooQuery = { Tweets: Array<{ id: string } | null> | null }; -export type LelFragment = { __typename?: 'Tweet'; id: string; body?: string | null } & { +export type LelFragment = { id: string; body: string | null; date: unknown } & { ' $fragmentName'?: 'LelFragment'; }; export type BarQueryVariables = Exact<{ [key: string]: never }>; export type BarQuery = { - __typename?: 'Query'; - Tweets?: Array< - ({ __typename?: 'Tweet' } & { ' $fragmentRefs'?: { LelFragment: LelFragment } }) | null - > | null; + Tweets: Array<{ ' $fragmentRefs'?: { LelFragment: LelFragment } } | null> | null; }; export const LelFragmentDoc = { @@ -144,6 +34,7 @@ export const LelFragmentDoc = { selections: [ { kind: 'Field', name: { kind: 'Name', value: 'id' } }, { kind: 'Field', name: { kind: 'Name', value: 'body' } }, + { kind: 'Field', name: { kind: 'Name', value: 'date' } }, ], }, }, @@ -202,6 +93,7 @@ export const BarDocument = { selections: [ { kind: 'Field', name: { kind: 'Name', value: 'id' } }, { kind: 'Field', name: { kind: 'Name', value: 'body' } }, + { kind: 'Field', name: { kind: 'Name', value: 'date' } }, ], }, }, diff --git a/dev-test/gql-tag-operations/src/index.ts b/dev-test/gql-tag-operations/src/index.ts index 884fce3543a..b11086cdac7 100644 --- a/dev-test/gql-tag-operations/src/index.ts +++ b/dev-test/gql-tag-operations/src/index.ts @@ -14,6 +14,7 @@ const LelFragment = graphql(/* GraphQL */ ` fragment Lel on Tweet { id body + date } `); diff --git a/dev-test/modules/types.ts b/dev-test/modules/types.ts index 9686d9c2ff2..44edaa1b576 100644 --- a/dev-test/modules/types.ts +++ b/dev-test/modules/types.ts @@ -2,15 +2,6 @@ import { GraphQLResolveInfo } from 'graphql'; export type Maybe = T | null; export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; -export type Incremental = - | T - | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; export type Omit = Pick>; export type RequireFields = Omit & { [P in K]-?: NonNullable }; /** All built-in and custom scalars, mapped to their actual values */ diff --git a/dev-test/standalone-operations/import-schema-types/_base.generated.ts b/dev-test/standalone-operations/import-schema-types/_base.generated.ts new file mode 100644 index 00000000000..f0dd411ab38 --- /dev/null +++ b/dev-test/standalone-operations/import-schema-types/_base.generated.ts @@ -0,0 +1,12 @@ +/** UserRole Description */ +export type UserRole = + /** UserRole ADMIN */ + | '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 new file mode 100644 index 00000000000..3f88552ad29 --- /dev/null +++ b/dev-test/standalone-operations/import-schema-types/_types.generated.ts @@ -0,0 +1,20 @@ +import type * as Types from './_base.generated.js'; + +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ +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/import-schema-types/query.graphql b/dev-test/standalone-operations/import-schema-types/query.graphql new file mode 100644 index 00000000000..ddf5351bc36 --- /dev/null +++ b/dev-test/standalone-operations/import-schema-types/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/dev-test/standalone-operations/schema.graphql b/dev-test/standalone-operations/schema.graphql new file mode 100644 index 00000000000..0f7ac081d36 --- /dev/null +++ b/dev-test/standalone-operations/schema.graphql @@ -0,0 +1,29 @@ +type Query { + user(id: ID!, role: UserRole): User + users(input: UsersInput!): [User!]! +} + +type User { + id: ID! + name: String! + role: UserRole! +} + +"UserRole Description" +enum UserRole { + "UserRole ADMIN" + ADMIN + "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..3f88552ad29 --- /dev/null +++ b/dev-test/standalone-operations/with-typescript-plugin/_types.generated.ts @@ -0,0 +1,20 @@ +import type * as Types from './_base.generated.js'; + +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ +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/dev-test/star-wars/types.avoidOptionals.ts b/dev-test/star-wars/types.avoidOptionals.ts index 9f902a4cf66..f99a9a941d7 100644 --- a/dev-test/star-wars/types.avoidOptionals.ts +++ b/dev-test/star-wars/types.avoidOptionals.ts @@ -1,247 +1,33 @@ -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A character from the Star Wars universe */ -export type Character = { - /** The movies this character appears in */ - appearsIn: Array>; - /** The friends of the character, or an empty list if they have none */ - friends: Maybe>>; - /** The friends of the character exposed as a connection with edges */ - friendsConnection: FriendsConnection; - /** The ID of the character */ - id: Scalars['ID']['output']; - /** The name of the character */ - name: Scalars['String']['output']; -}; - -/** A character from the Star Wars universe */ -export type CharacterFriendsConnectionArgs = { - after: InputMaybe; - first: InputMaybe; -}; - /** The input object sent when passing a color */ export type ColorInput = { - blue: Scalars['Int']['input']; - green: Scalars['Int']['input']; - red: Scalars['Int']['input']; -}; - -/** An autonomous mechanical character in the Star Wars universe */ -export type Droid = Character & { - __typename?: 'Droid'; - /** The movies this droid appears in */ - appearsIn: Array>; - /** This droid's friends, or an empty list if they have none */ - friends: Maybe>>; - /** The friends of the droid exposed as a connection with edges */ - friendsConnection: FriendsConnection; - /** The ID of the droid */ - id: Scalars['ID']['output']; - /** What others call this droid */ - name: Scalars['String']['output']; - /** This droid's primary function */ - primaryFunction: Maybe; -}; - -/** An autonomous mechanical character in the Star Wars universe */ -export type DroidFriendsConnectionArgs = { - after: InputMaybe; - first: InputMaybe; + blue: number; + green: number; + red: number; }; /** The episodes in the Star Wars trilogy */ -export enum Episode { +export type Episode = /** Star Wars Episode V: The Empire Strikes Back, released in 1980. */ - Empire = 'EMPIRE', + | 'EMPIRE' /** Star Wars Episode VI: Return of the Jedi, released in 1983. */ - Jedi = 'JEDI', + | 'JEDI' /** Star Wars Episode IV: A New Hope, released in 1977. */ - Newhope = 'NEWHOPE', -} - -/** A connection object for a character's friends */ -export type FriendsConnection = { - __typename?: 'FriendsConnection'; - /** The edges for each of the character's friends. */ - edges: Maybe>>; - /** A list of the friends, as a convenience when edges are not needed. */ - friends: Maybe>>; - /** Information for paginating this connection */ - pageInfo: PageInfo; - /** The total number of friends */ - totalCount: Maybe; -}; - -/** An edge object for a character's friends */ -export type FriendsEdge = { - __typename?: 'FriendsEdge'; - /** A cursor used for pagination */ - cursor: Scalars['ID']['output']; - /** The character represented by this friendship edge */ - node: Maybe; -}; - -/** A humanoid creature from the Star Wars universe */ -export type Human = Character & { - __typename?: 'Human'; - /** The movies this human appears in */ - appearsIn: Array>; - /** This human's friends, or an empty list if they have none */ - friends: Maybe>>; - /** The friends of the human exposed as a connection with edges */ - friendsConnection: FriendsConnection; - /** Height in the preferred unit, default is meters */ - height: Maybe; - /** The home planet of the human, or null if unknown */ - homePlanet: Maybe; - /** The ID of the human */ - id: Scalars['ID']['output']; - /** Mass in kilograms, or null if unknown */ - mass: Maybe; - /** What this human calls themselves */ - name: Scalars['String']['output']; - /** A list of starships this person has piloted, or an empty list if none */ - starships: Maybe>>; -}; - -/** A humanoid creature from the Star Wars universe */ -export type HumanFriendsConnectionArgs = { - after: InputMaybe; - first: InputMaybe; -}; - -/** A humanoid creature from the Star Wars universe */ -export type HumanHeightArgs = { - unit?: InputMaybe; -}; - -/** Units of height */ -export enum LengthUnit { - /** Primarily used in the United States */ - Foot = 'FOOT', - /** The standard unit around the world */ - Meter = 'METER', -} - -/** The mutation type, represents all updates we can make to our data */ -export type Mutation = { - __typename?: 'Mutation'; - createReview: Maybe; -}; - -/** The mutation type, represents all updates we can make to our data */ -export type MutationCreateReviewArgs = { - episode: InputMaybe; - review: ReviewInput; -}; - -/** Information for paginating this connection */ -export type PageInfo = { - __typename?: 'PageInfo'; - endCursor: Maybe; - hasNextPage: Scalars['Boolean']['output']; - startCursor: Maybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type Query = { - __typename?: 'Query'; - character: Maybe; - droid: Maybe; - hero: Maybe; - human: Maybe; - reviews: Maybe>>; - search: Maybe>>; - starship: Maybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryCharacterArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryDroidArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryHeroArgs = { - episode: InputMaybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryHumanArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryReviewsArgs = { - episode: Episode; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QuerySearchArgs = { - text: InputMaybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryStarshipArgs = { - id: Scalars['ID']['input']; -}; - -/** Represents a review for a movie */ -export type Review = { - __typename?: 'Review'; - /** Comment about the movie */ - commentary: Maybe; - /** The number of stars this review gave, 1-5 */ - stars: Scalars['Int']['output']; -}; + | 'NEWHOPE'; /** The input object sent when someone is creating a new review */ export type ReviewInput = { /** Comment about the movie, optional */ - commentary: InputMaybe; + commentary: string | null | undefined; /** Favorite color, optional */ - favoriteColor: InputMaybe; + favoriteColor: ColorInput | null | undefined; /** 0-5 stars */ - stars: Scalars['Int']['input']; -}; - -export type SearchResult = Droid | Human | Starship; - -export type Starship = { - __typename?: 'Starship'; - /** The ID of the starship */ - id: Scalars['ID']['output']; - /** Length of the starship, along the longest axis */ - length: Maybe; - /** The name of the starship */ - name: Scalars['String']['output']; -}; - -export type StarshipLengthArgs = { - unit?: InputMaybe; + stars: number; }; export type CreateReviewForEpisodeMutationVariables = Exact<{ @@ -250,178 +36,127 @@ export type CreateReviewForEpisodeMutationVariables = Exact<{ }>; export type CreateReviewForEpisodeMutation = { - __typename?: 'Mutation'; - createReview: { __typename?: 'Review'; stars: number; commentary: string | null } | null; + createReview: { stars: number; commentary: string | null } | null; }; export type ExcludeQueryAlphaQueryVariables = Exact<{ - episode: InputMaybe; + episode: Episode | null | undefined; }>; -export type ExcludeQueryAlphaQuery = { - __typename?: 'Query'; - hero: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; -}; +export type ExcludeQueryAlphaQuery = { hero: { name: string } | { name: string } | null }; export type ExcludeQueryBetaQueryVariables = Exact<{ - episode: InputMaybe; + episode: Episode | null | undefined; }>; -export type ExcludeQueryBetaQuery = { - __typename?: 'Query'; - hero: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; -}; +export type ExcludeQueryBetaQuery = { hero: { name: string } | { name: string } | null }; export type HeroAndFriendsNamesQueryVariables = Exact<{ - episode: InputMaybe; + episode: Episode | null | undefined; }>; export type HeroAndFriendsNamesQuery = { - __typename?: 'Query'; hero: - | { - __typename?: 'Droid'; - name: string; - friends: Array< - { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null - > | null; - } - | { - __typename?: 'Human'; - name: string; - friends: Array< - { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null - > | null; - } + | { name: string; friends: Array<{ name: string } | { name: string } | null> | null } + | { name: string; friends: Array<{ name: string } | { name: string } | null> | null } | null; }; export type HeroAppearsInQueryVariables = Exact<{ [key: string]: never }>; export type HeroAppearsInQuery = { - __typename?: 'Query'; hero: - | { __typename?: 'Droid'; name: string; appearsIn: Array } - | { __typename?: 'Human'; name: string; appearsIn: Array } + | { name: string; appearsIn: Array } + | { name: string; appearsIn: Array } | null; }; export type HeroDetailsQueryVariables = Exact<{ - episode: InputMaybe; + episode: Episode | null | undefined; }>; export type HeroDetailsQuery = { - __typename?: 'Query'; hero: - | { __typename?: 'Droid'; primaryFunction: string | null; name: string } - | { __typename?: 'Human'; height: number | null; name: string } + | { primaryFunction: string | null; name: string } + | { height: number | null; name: string } | null; }; -type HeroDetails_Droid_Fragment = { - __typename?: 'Droid'; - primaryFunction: string | null; - name: string; -}; +type HeroDetails_Droid_Fragment = { primaryFunction: string | null; name: string }; -type HeroDetails_Human_Fragment = { __typename?: 'Human'; height: number | null; name: string }; +type HeroDetails_Human_Fragment = { height: number | null; name: string }; export type HeroDetailsFragment = HeroDetails_Droid_Fragment | HeroDetails_Human_Fragment; export type HeroDetailsWithFragmentQueryVariables = Exact<{ - episode: InputMaybe; + episode: Episode | null | undefined; }>; export type HeroDetailsWithFragmentQuery = { - __typename?: 'Query'; hero: - | { __typename?: 'Droid'; primaryFunction: string | null; name: string } - | { __typename?: 'Human'; height: number | null; name: string } + | { primaryFunction: string | null; name: string } + | { height: number | null; name: string } | null; }; export type HeroNameQueryVariables = Exact<{ - episode: InputMaybe; + episode: Episode | null | undefined; }>; -export type HeroNameQuery = { - __typename?: 'Query'; - hero: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; -}; +export type HeroNameQuery = { hero: { name: string } | { name: string } | null }; export type HeroNameConditionalInclusionQueryVariables = Exact<{ - episode: InputMaybe; - includeName: Scalars['Boolean']['input']; + episode: Episode | null | undefined; + includeName: boolean; }>; export type HeroNameConditionalInclusionQuery = { - __typename?: 'Query'; - hero: { __typename?: 'Droid'; name?: string } | { __typename?: 'Human'; name?: string } | null; + hero: { name?: string } | { name?: string } | null; }; export type HeroNameConditionalExclusionQueryVariables = Exact<{ - episode: InputMaybe; - skipName: Scalars['Boolean']['input']; + episode: Episode | null | undefined; + skipName: boolean; }>; export type HeroNameConditionalExclusionQuery = { - __typename?: 'Query'; - hero: { __typename?: 'Droid'; name?: string } | { __typename?: 'Human'; name?: string } | null; + hero: { name?: string } | { name?: string } | null; }; export type HeroParentTypeDependentFieldQueryVariables = Exact<{ - episode: InputMaybe; + episode: Episode | null | undefined; }>; export type HeroParentTypeDependentFieldQuery = { - __typename?: 'Query'; hero: | { - __typename?: 'Droid'; name: string; - friends: Array< - | { __typename?: 'Droid'; name: string } - | { __typename?: 'Human'; height: number | null; name: string } - | null - > | null; + friends: Array<{ name: string } | { height: number | null; name: string } | null> | null; } | { - __typename?: 'Human'; name: string; - friends: Array< - | { __typename?: 'Droid'; name: string } - | { __typename?: 'Human'; height: number | null; name: string } - | null - > | null; + friends: Array<{ name: string } | { height: number | null; name: string } | null> | null; } | null; }; export type HeroTypeDependentAliasedFieldQueryVariables = Exact<{ - episode: InputMaybe; + episode: Episode | null | undefined; }>; export type HeroTypeDependentAliasedFieldQuery = { - __typename?: 'Query'; - hero: - | { __typename?: 'Droid'; property: string | null } - | { __typename?: 'Human'; property: string | null } - | null; + hero: { property: string | null } | { property: string | null } | null; }; -export type HumanFieldsFragment = { __typename?: 'Human'; name: string; mass: number | null }; +export type HumanFieldsFragment = { name: string; mass: number | null }; export type HumanWithNullHeightQueryVariables = Exact<{ [key: string]: never }>; -export type HumanWithNullHeightQuery = { - __typename?: 'Query'; - human: { __typename?: 'Human'; name: string; mass: number | null } | null; -}; +export type HumanWithNullHeightQuery = { human: { name: string; mass: number | null } | null }; export type TwoHeroesQueryVariables = Exact<{ [key: string]: never }>; export type TwoHeroesQuery = { - __typename?: 'Query'; - r2: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; - luke: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; + r2: { name: string } | { name: string } | null; + luke: { name: string } | { name: string } | null; }; diff --git a/dev-test/star-wars/types.d.ts b/dev-test/star-wars/types.d.ts index 3cf2a972200..5190be1aab1 100644 --- a/dev-test/star-wars/types.d.ts +++ b/dev-test/star-wars/types.d.ts @@ -1,243 +1,4 @@ -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A character from the Star Wars universe */ -export type Character = { - /** The movies this character appears in */ - appearsIn: Array>; - /** The friends of the character, or an empty list if they have none */ - friends?: Maybe>>; - /** The friends of the character exposed as a connection with edges */ - friendsConnection: FriendsConnection; - /** The ID of the character */ - id: Scalars['ID']['output']; - /** The name of the character */ - name: Scalars['String']['output']; -}; - -/** A character from the Star Wars universe */ -export type CharacterFriendsConnectionArgs = { - after?: InputMaybe; - first?: InputMaybe; -}; - -/** The input object sent when passing a color */ -export type ColorInput = { - blue: Scalars['Int']['input']; - green: Scalars['Int']['input']; - red: Scalars['Int']['input']; -}; - -/** An autonomous mechanical character in the Star Wars universe */ -export type Droid = Character & { - __typename?: 'Droid'; - /** The movies this droid appears in */ - appearsIn: Array>; - /** This droid's friends, or an empty list if they have none */ - friends?: Maybe>>; - /** The friends of the droid exposed as a connection with edges */ - friendsConnection: FriendsConnection; - /** The ID of the droid */ - id: Scalars['ID']['output']; - /** What others call this droid */ - name: Scalars['String']['output']; - /** This droid's primary function */ - primaryFunction?: Maybe; -}; - -/** An autonomous mechanical character in the Star Wars universe */ -export type DroidFriendsConnectionArgs = { - after?: InputMaybe; - first?: InputMaybe; -}; - -/** The episodes in the Star Wars trilogy */ -export type Episode = - /** Star Wars Episode V: The Empire Strikes Back, released in 1980. */ - | 'EMPIRE' - /** Star Wars Episode VI: Return of the Jedi, released in 1983. */ - | 'JEDI' - /** Star Wars Episode IV: A New Hope, released in 1977. */ - | 'NEWHOPE'; - -/** A connection object for a character's friends */ -export type FriendsConnection = { - __typename?: 'FriendsConnection'; - /** The edges for each of the character's friends. */ - edges?: Maybe>>; - /** A list of the friends, as a convenience when edges are not needed. */ - friends?: Maybe>>; - /** Information for paginating this connection */ - pageInfo: PageInfo; - /** The total number of friends */ - totalCount?: Maybe; -}; - -/** An edge object for a character's friends */ -export type FriendsEdge = { - __typename?: 'FriendsEdge'; - /** A cursor used for pagination */ - cursor: Scalars['ID']['output']; - /** The character represented by this friendship edge */ - node?: Maybe; -}; - -/** A humanoid creature from the Star Wars universe */ -export type Human = Character & { - __typename?: 'Human'; - /** The movies this human appears in */ - appearsIn: Array>; - /** This human's friends, or an empty list if they have none */ - friends?: Maybe>>; - /** The friends of the human exposed as a connection with edges */ - friendsConnection: FriendsConnection; - /** Height in the preferred unit, default is meters */ - height?: Maybe; - /** The home planet of the human, or null if unknown */ - homePlanet?: Maybe; - /** The ID of the human */ - id: Scalars['ID']['output']; - /** Mass in kilograms, or null if unknown */ - mass?: Maybe; - /** What this human calls themselves */ - name: Scalars['String']['output']; - /** A list of starships this person has piloted, or an empty list if none */ - starships?: Maybe>>; -}; - -/** A humanoid creature from the Star Wars universe */ -export type HumanFriendsConnectionArgs = { - after?: InputMaybe; - first?: InputMaybe; -}; - -/** A humanoid creature from the Star Wars universe */ -export type HumanHeightArgs = { - unit?: InputMaybe; -}; - -/** Units of height */ -export type LengthUnit = - /** Primarily used in the United States */ - | 'FOOT' - /** The standard unit around the world */ - | 'METER'; - -/** The mutation type, represents all updates we can make to our data */ -export type Mutation = { - __typename?: 'Mutation'; - createReview?: Maybe; -}; - -/** The mutation type, represents all updates we can make to our data */ -export type MutationCreateReviewArgs = { - episode?: InputMaybe; - review: ReviewInput; -}; - -/** Information for paginating this connection */ -export type PageInfo = { - __typename?: 'PageInfo'; - endCursor?: Maybe; - hasNextPage: Scalars['Boolean']['output']; - startCursor?: Maybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type Query = { - __typename?: 'Query'; - character?: Maybe; - droid?: Maybe; - hero?: Maybe; - human?: Maybe; - reviews?: Maybe>>; - search?: Maybe>>; - starship?: Maybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryCharacterArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryDroidArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryHeroArgs = { - episode?: InputMaybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryHumanArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryReviewsArgs = { - episode: Episode; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QuerySearchArgs = { - text?: InputMaybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryStarshipArgs = { - id: Scalars['ID']['input']; -}; - -/** Represents a review for a movie */ -export type Review = { - __typename?: 'Review'; - /** Comment about the movie */ - commentary?: Maybe; - /** The number of stars this review gave, 1-5 */ - stars: Scalars['Int']['output']; -}; - -/** The input object sent when someone is creating a new review */ -export type ReviewInput = { - /** Comment about the movie, optional */ - commentary?: InputMaybe; - /** Favorite color, optional */ - favoriteColor?: InputMaybe; - /** 0-5 stars */ - stars: Scalars['Int']['input']; -}; - -export type SearchResult = Droid | Human | Starship; - -export type Starship = { - __typename?: 'Starship'; - /** The ID of the starship */ - id: Scalars['ID']['output']; - /** Length of the starship, along the longest axis */ - length?: Maybe; - /** The name of the starship */ - name: Scalars['String']['output']; -}; - -export type StarshipLengthArgs = { - unit?: InputMaybe; -}; diff --git a/dev-test/star-wars/types.excludeQueryAlpha.ts b/dev-test/star-wars/types.excludeQueryAlpha.ts index 58688ef48c7..58e75ed1035 100644 --- a/dev-test/star-wars/types.excludeQueryAlpha.ts +++ b/dev-test/star-wars/types.excludeQueryAlpha.ts @@ -1,247 +1,33 @@ -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A character from the Star Wars universe */ -export type Character = { - /** The movies this character appears in */ - appearsIn: Array>; - /** The friends of the character, or an empty list if they have none */ - friends?: Maybe>>; - /** The friends of the character exposed as a connection with edges */ - friendsConnection: FriendsConnection; - /** The ID of the character */ - id: Scalars['ID']['output']; - /** The name of the character */ - name: Scalars['String']['output']; -}; - -/** A character from the Star Wars universe */ -export type CharacterFriendsConnectionArgs = { - after?: InputMaybe; - first?: InputMaybe; -}; - /** The input object sent when passing a color */ export type ColorInput = { - blue: Scalars['Int']['input']; - green: Scalars['Int']['input']; - red: Scalars['Int']['input']; -}; - -/** An autonomous mechanical character in the Star Wars universe */ -export type Droid = Character & { - __typename?: 'Droid'; - /** The movies this droid appears in */ - appearsIn: Array>; - /** This droid's friends, or an empty list if they have none */ - friends?: Maybe>>; - /** The friends of the droid exposed as a connection with edges */ - friendsConnection: FriendsConnection; - /** The ID of the droid */ - id: Scalars['ID']['output']; - /** What others call this droid */ - name: Scalars['String']['output']; - /** This droid's primary function */ - primaryFunction?: Maybe; -}; - -/** An autonomous mechanical character in the Star Wars universe */ -export type DroidFriendsConnectionArgs = { - after?: InputMaybe; - first?: InputMaybe; + blue: number; + green: number; + red: number; }; /** The episodes in the Star Wars trilogy */ -export enum Episode { +export type Episode = /** Star Wars Episode V: The Empire Strikes Back, released in 1980. */ - Empire = 'EMPIRE', + | 'EMPIRE' /** Star Wars Episode VI: Return of the Jedi, released in 1983. */ - Jedi = 'JEDI', + | 'JEDI' /** Star Wars Episode IV: A New Hope, released in 1977. */ - Newhope = 'NEWHOPE', -} - -/** A connection object for a character's friends */ -export type FriendsConnection = { - __typename?: 'FriendsConnection'; - /** The edges for each of the character's friends. */ - edges?: Maybe>>; - /** A list of the friends, as a convenience when edges are not needed. */ - friends?: Maybe>>; - /** Information for paginating this connection */ - pageInfo: PageInfo; - /** The total number of friends */ - totalCount?: Maybe; -}; - -/** An edge object for a character's friends */ -export type FriendsEdge = { - __typename?: 'FriendsEdge'; - /** A cursor used for pagination */ - cursor: Scalars['ID']['output']; - /** The character represented by this friendship edge */ - node?: Maybe; -}; - -/** A humanoid creature from the Star Wars universe */ -export type Human = Character & { - __typename?: 'Human'; - /** The movies this human appears in */ - appearsIn: Array>; - /** This human's friends, or an empty list if they have none */ - friends?: Maybe>>; - /** The friends of the human exposed as a connection with edges */ - friendsConnection: FriendsConnection; - /** Height in the preferred unit, default is meters */ - height?: Maybe; - /** The home planet of the human, or null if unknown */ - homePlanet?: Maybe; - /** The ID of the human */ - id: Scalars['ID']['output']; - /** Mass in kilograms, or null if unknown */ - mass?: Maybe; - /** What this human calls themselves */ - name: Scalars['String']['output']; - /** A list of starships this person has piloted, or an empty list if none */ - starships?: Maybe>>; -}; - -/** A humanoid creature from the Star Wars universe */ -export type HumanFriendsConnectionArgs = { - after?: InputMaybe; - first?: InputMaybe; -}; - -/** A humanoid creature from the Star Wars universe */ -export type HumanHeightArgs = { - unit?: InputMaybe; -}; - -/** Units of height */ -export enum LengthUnit { - /** Primarily used in the United States */ - Foot = 'FOOT', - /** The standard unit around the world */ - Meter = 'METER', -} - -/** The mutation type, represents all updates we can make to our data */ -export type Mutation = { - __typename?: 'Mutation'; - createReview?: Maybe; -}; - -/** The mutation type, represents all updates we can make to our data */ -export type MutationCreateReviewArgs = { - episode?: InputMaybe; - review: ReviewInput; -}; - -/** Information for paginating this connection */ -export type PageInfo = { - __typename?: 'PageInfo'; - endCursor?: Maybe; - hasNextPage: Scalars['Boolean']['output']; - startCursor?: Maybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type Query = { - __typename?: 'Query'; - character?: Maybe; - droid?: Maybe; - hero?: Maybe; - human?: Maybe; - reviews?: Maybe>>; - search?: Maybe>>; - starship?: Maybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryCharacterArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryDroidArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryHeroArgs = { - episode?: InputMaybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryHumanArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryReviewsArgs = { - episode: Episode; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QuerySearchArgs = { - text?: InputMaybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryStarshipArgs = { - id: Scalars['ID']['input']; -}; - -/** Represents a review for a movie */ -export type Review = { - __typename?: 'Review'; - /** Comment about the movie */ - commentary?: Maybe; - /** The number of stars this review gave, 1-5 */ - stars: Scalars['Int']['output']; -}; + | 'NEWHOPE'; /** The input object sent when someone is creating a new review */ export type ReviewInput = { /** Comment about the movie, optional */ - commentary?: InputMaybe; + commentary?: string | null | undefined; /** Favorite color, optional */ - favoriteColor?: InputMaybe; + favoriteColor?: ColorInput | null | undefined; /** 0-5 stars */ - stars: Scalars['Int']['input']; -}; - -export type SearchResult = Droid | Human | Starship; - -export type Starship = { - __typename?: 'Starship'; - /** The ID of the starship */ - id: Scalars['ID']['output']; - /** Length of the starship, along the longest axis */ - length?: Maybe; - /** The name of the starship */ - name: Scalars['String']['output']; -}; - -export type StarshipLengthArgs = { - unit?: InputMaybe; + stars: number; }; export type CreateReviewForEpisodeMutationVariables = Exact<{ @@ -250,169 +36,121 @@ export type CreateReviewForEpisodeMutationVariables = Exact<{ }>; export type CreateReviewForEpisodeMutation = { - __typename?: 'Mutation'; - createReview?: { __typename?: 'Review'; stars: number; commentary?: string | null } | null; + createReview: { stars: number; commentary: string | null } | null; }; export type ExcludeQueryBetaQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; -export type ExcludeQueryBetaQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; -}; +export type ExcludeQueryBetaQuery = { hero: { name: string } | { name: string } | null }; export type HeroAndFriendsNamesQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroAndFriendsNamesQuery = { - __typename?: 'Query'; - hero?: - | { - __typename?: 'Droid'; - name: string; - friends?: Array< - { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null - > | null; - } - | { - __typename?: 'Human'; - name: string; - friends?: Array< - { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null - > | null; - } + hero: + | { name: string; friends: Array<{ name: string } | { name: string } | null> | null } + | { name: string; friends: Array<{ name: string } | { name: string } | null> | null } | null; }; export type HeroAppearsInQueryVariables = Exact<{ [key: string]: never }>; export type HeroAppearsInQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; name: string; appearsIn: Array } - | { __typename?: 'Human'; name: string; appearsIn: Array } + hero: + | { name: string; appearsIn: Array } + | { name: string; appearsIn: Array } | null; }; export type HeroDetailsQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroDetailsQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; primaryFunction?: string | null; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } + hero: + | { primaryFunction: string | null; name: string } + | { height: number | null; name: string } | null; }; -type HeroDetails_Droid_Fragment = { - __typename?: 'Droid'; - primaryFunction?: string | null; - name: string; -}; +type HeroDetails_Droid_Fragment = { primaryFunction: string | null; name: string }; -type HeroDetails_Human_Fragment = { __typename?: 'Human'; height?: number | null; name: string }; +type HeroDetails_Human_Fragment = { height: number | null; name: string }; export type HeroDetailsFragment = HeroDetails_Droid_Fragment | HeroDetails_Human_Fragment; export type HeroDetailsWithFragmentQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroDetailsWithFragmentQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; primaryFunction?: string | null; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } + hero: + | { primaryFunction: string | null; name: string } + | { height: number | null; name: string } | null; }; export type HeroNameQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; -export type HeroNameQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; -}; +export type HeroNameQuery = { hero: { name: string } | { name: string } | null }; export type HeroNameConditionalInclusionQueryVariables = Exact<{ - episode?: InputMaybe; - includeName: Scalars['Boolean']['input']; + episode?: Episode | null | undefined; + includeName: boolean; }>; export type HeroNameConditionalInclusionQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name?: string } | { __typename?: 'Human'; name?: string } | null; + hero: { name?: string } | { name?: string } | null; }; export type HeroNameConditionalExclusionQueryVariables = Exact<{ - episode?: InputMaybe; - skipName: Scalars['Boolean']['input']; + episode?: Episode | null | undefined; + skipName: boolean; }>; export type HeroNameConditionalExclusionQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name?: string } | { __typename?: 'Human'; name?: string } | null; + hero: { name?: string } | { name?: string } | null; }; export type HeroParentTypeDependentFieldQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroParentTypeDependentFieldQuery = { - __typename?: 'Query'; - hero?: + hero: | { - __typename?: 'Droid'; name: string; - friends?: Array< - | { __typename?: 'Droid'; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } - | null - > | null; + friends: Array<{ name: string } | { height: number | null; name: string } | null> | null; } | { - __typename?: 'Human'; name: string; - friends?: Array< - | { __typename?: 'Droid'; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } - | null - > | null; + friends: Array<{ name: string } | { height: number | null; name: string } | null> | null; } | null; }; export type HeroTypeDependentAliasedFieldQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroTypeDependentAliasedFieldQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; property?: string | null } - | { __typename?: 'Human'; property?: string | null } - | null; + hero: { property: string | null } | { property: string | null } | null; }; -export type HumanFieldsFragment = { __typename?: 'Human'; name: string; mass?: number | null }; +export type HumanFieldsFragment = { name: string; mass: number | null }; export type HumanWithNullHeightQueryVariables = Exact<{ [key: string]: never }>; -export type HumanWithNullHeightQuery = { - __typename?: 'Query'; - human?: { __typename?: 'Human'; name: string; mass?: number | null } | null; -}; +export type HumanWithNullHeightQuery = { human: { name: string; mass: number | null } | null }; export type TwoHeroesQueryVariables = Exact<{ [key: string]: never }>; export type TwoHeroesQuery = { - __typename?: 'Query'; - r2?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; - luke?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; + r2: { name: string } | { name: string } | null; + luke: { name: string } | { name: string } | null; }; diff --git a/dev-test/star-wars/types.excludeQueryBeta.ts b/dev-test/star-wars/types.excludeQueryBeta.ts index 43677ef773d..43847b69a88 100644 --- a/dev-test/star-wars/types.excludeQueryBeta.ts +++ b/dev-test/star-wars/types.excludeQueryBeta.ts @@ -1,247 +1,33 @@ -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A character from the Star Wars universe */ -export type Character = { - /** The movies this character appears in */ - appearsIn: Array>; - /** The friends of the character, or an empty list if they have none */ - friends?: Maybe>>; - /** The friends of the character exposed as a connection with edges */ - friendsConnection: FriendsConnection; - /** The ID of the character */ - id: Scalars['ID']['output']; - /** The name of the character */ - name: Scalars['String']['output']; -}; - -/** A character from the Star Wars universe */ -export type CharacterFriendsConnectionArgs = { - after?: InputMaybe; - first?: InputMaybe; -}; - /** The input object sent when passing a color */ export type ColorInput = { - blue: Scalars['Int']['input']; - green: Scalars['Int']['input']; - red: Scalars['Int']['input']; -}; - -/** An autonomous mechanical character in the Star Wars universe */ -export type Droid = Character & { - __typename?: 'Droid'; - /** The movies this droid appears in */ - appearsIn: Array>; - /** This droid's friends, or an empty list if they have none */ - friends?: Maybe>>; - /** The friends of the droid exposed as a connection with edges */ - friendsConnection: FriendsConnection; - /** The ID of the droid */ - id: Scalars['ID']['output']; - /** What others call this droid */ - name: Scalars['String']['output']; - /** This droid's primary function */ - primaryFunction?: Maybe; -}; - -/** An autonomous mechanical character in the Star Wars universe */ -export type DroidFriendsConnectionArgs = { - after?: InputMaybe; - first?: InputMaybe; + blue: number; + green: number; + red: number; }; /** The episodes in the Star Wars trilogy */ -export enum Episode { +export type Episode = /** Star Wars Episode V: The Empire Strikes Back, released in 1980. */ - Empire = 'EMPIRE', + | 'EMPIRE' /** Star Wars Episode VI: Return of the Jedi, released in 1983. */ - Jedi = 'JEDI', + | 'JEDI' /** Star Wars Episode IV: A New Hope, released in 1977. */ - Newhope = 'NEWHOPE', -} - -/** A connection object for a character's friends */ -export type FriendsConnection = { - __typename?: 'FriendsConnection'; - /** The edges for each of the character's friends. */ - edges?: Maybe>>; - /** A list of the friends, as a convenience when edges are not needed. */ - friends?: Maybe>>; - /** Information for paginating this connection */ - pageInfo: PageInfo; - /** The total number of friends */ - totalCount?: Maybe; -}; - -/** An edge object for a character's friends */ -export type FriendsEdge = { - __typename?: 'FriendsEdge'; - /** A cursor used for pagination */ - cursor: Scalars['ID']['output']; - /** The character represented by this friendship edge */ - node?: Maybe; -}; - -/** A humanoid creature from the Star Wars universe */ -export type Human = Character & { - __typename?: 'Human'; - /** The movies this human appears in */ - appearsIn: Array>; - /** This human's friends, or an empty list if they have none */ - friends?: Maybe>>; - /** The friends of the human exposed as a connection with edges */ - friendsConnection: FriendsConnection; - /** Height in the preferred unit, default is meters */ - height?: Maybe; - /** The home planet of the human, or null if unknown */ - homePlanet?: Maybe; - /** The ID of the human */ - id: Scalars['ID']['output']; - /** Mass in kilograms, or null if unknown */ - mass?: Maybe; - /** What this human calls themselves */ - name: Scalars['String']['output']; - /** A list of starships this person has piloted, or an empty list if none */ - starships?: Maybe>>; -}; - -/** A humanoid creature from the Star Wars universe */ -export type HumanFriendsConnectionArgs = { - after?: InputMaybe; - first?: InputMaybe; -}; - -/** A humanoid creature from the Star Wars universe */ -export type HumanHeightArgs = { - unit?: InputMaybe; -}; - -/** Units of height */ -export enum LengthUnit { - /** Primarily used in the United States */ - Foot = 'FOOT', - /** The standard unit around the world */ - Meter = 'METER', -} - -/** The mutation type, represents all updates we can make to our data */ -export type Mutation = { - __typename?: 'Mutation'; - createReview?: Maybe; -}; - -/** The mutation type, represents all updates we can make to our data */ -export type MutationCreateReviewArgs = { - episode?: InputMaybe; - review: ReviewInput; -}; - -/** Information for paginating this connection */ -export type PageInfo = { - __typename?: 'PageInfo'; - endCursor?: Maybe; - hasNextPage: Scalars['Boolean']['output']; - startCursor?: Maybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type Query = { - __typename?: 'Query'; - character?: Maybe; - droid?: Maybe; - hero?: Maybe; - human?: Maybe; - reviews?: Maybe>>; - search?: Maybe>>; - starship?: Maybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryCharacterArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryDroidArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryHeroArgs = { - episode?: InputMaybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryHumanArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryReviewsArgs = { - episode: Episode; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QuerySearchArgs = { - text?: InputMaybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryStarshipArgs = { - id: Scalars['ID']['input']; -}; - -/** Represents a review for a movie */ -export type Review = { - __typename?: 'Review'; - /** Comment about the movie */ - commentary?: Maybe; - /** The number of stars this review gave, 1-5 */ - stars: Scalars['Int']['output']; -}; + | 'NEWHOPE'; /** The input object sent when someone is creating a new review */ export type ReviewInput = { /** Comment about the movie, optional */ - commentary?: InputMaybe; + commentary?: string | null | undefined; /** Favorite color, optional */ - favoriteColor?: InputMaybe; + favoriteColor?: ColorInput | null | undefined; /** 0-5 stars */ - stars: Scalars['Int']['input']; -}; - -export type SearchResult = Droid | Human | Starship; - -export type Starship = { - __typename?: 'Starship'; - /** The ID of the starship */ - id: Scalars['ID']['output']; - /** Length of the starship, along the longest axis */ - length?: Maybe; - /** The name of the starship */ - name: Scalars['String']['output']; -}; - -export type StarshipLengthArgs = { - unit?: InputMaybe; + stars: number; }; export type CreateReviewForEpisodeMutationVariables = Exact<{ @@ -250,169 +36,121 @@ export type CreateReviewForEpisodeMutationVariables = Exact<{ }>; export type CreateReviewForEpisodeMutation = { - __typename?: 'Mutation'; - createReview?: { __typename?: 'Review'; stars: number; commentary?: string | null } | null; + createReview: { stars: number; commentary: string | null } | null; }; export type ExcludeQueryAlphaQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; -export type ExcludeQueryAlphaQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; -}; +export type ExcludeQueryAlphaQuery = { hero: { name: string } | { name: string } | null }; export type HeroAndFriendsNamesQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroAndFriendsNamesQuery = { - __typename?: 'Query'; - hero?: - | { - __typename?: 'Droid'; - name: string; - friends?: Array< - { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null - > | null; - } - | { - __typename?: 'Human'; - name: string; - friends?: Array< - { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null - > | null; - } + hero: + | { name: string; friends: Array<{ name: string } | { name: string } | null> | null } + | { name: string; friends: Array<{ name: string } | { name: string } | null> | null } | null; }; export type HeroAppearsInQueryVariables = Exact<{ [key: string]: never }>; export type HeroAppearsInQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; name: string; appearsIn: Array } - | { __typename?: 'Human'; name: string; appearsIn: Array } + hero: + | { name: string; appearsIn: Array } + | { name: string; appearsIn: Array } | null; }; export type HeroDetailsQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroDetailsQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; primaryFunction?: string | null; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } + hero: + | { primaryFunction: string | null; name: string } + | { height: number | null; name: string } | null; }; -type HeroDetails_Droid_Fragment = { - __typename?: 'Droid'; - primaryFunction?: string | null; - name: string; -}; +type HeroDetails_Droid_Fragment = { primaryFunction: string | null; name: string }; -type HeroDetails_Human_Fragment = { __typename?: 'Human'; height?: number | null; name: string }; +type HeroDetails_Human_Fragment = { height: number | null; name: string }; export type HeroDetailsFragment = HeroDetails_Droid_Fragment | HeroDetails_Human_Fragment; export type HeroDetailsWithFragmentQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroDetailsWithFragmentQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; primaryFunction?: string | null; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } + hero: + | { primaryFunction: string | null; name: string } + | { height: number | null; name: string } | null; }; export type HeroNameQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; -export type HeroNameQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; -}; +export type HeroNameQuery = { hero: { name: string } | { name: string } | null }; export type HeroNameConditionalInclusionQueryVariables = Exact<{ - episode?: InputMaybe; - includeName: Scalars['Boolean']['input']; + episode?: Episode | null | undefined; + includeName: boolean; }>; export type HeroNameConditionalInclusionQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name?: string } | { __typename?: 'Human'; name?: string } | null; + hero: { name?: string } | { name?: string } | null; }; export type HeroNameConditionalExclusionQueryVariables = Exact<{ - episode?: InputMaybe; - skipName: Scalars['Boolean']['input']; + episode?: Episode | null | undefined; + skipName: boolean; }>; export type HeroNameConditionalExclusionQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name?: string } | { __typename?: 'Human'; name?: string } | null; + hero: { name?: string } | { name?: string } | null; }; export type HeroParentTypeDependentFieldQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroParentTypeDependentFieldQuery = { - __typename?: 'Query'; - hero?: + hero: | { - __typename?: 'Droid'; name: string; - friends?: Array< - | { __typename?: 'Droid'; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } - | null - > | null; + friends: Array<{ name: string } | { height: number | null; name: string } | null> | null; } | { - __typename?: 'Human'; name: string; - friends?: Array< - | { __typename?: 'Droid'; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } - | null - > | null; + friends: Array<{ name: string } | { height: number | null; name: string } | null> | null; } | null; }; export type HeroTypeDependentAliasedFieldQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroTypeDependentAliasedFieldQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; property?: string | null } - | { __typename?: 'Human'; property?: string | null } - | null; + hero: { property: string | null } | { property: string | null } | null; }; -export type HumanFieldsFragment = { __typename?: 'Human'; name: string; mass?: number | null }; +export type HumanFieldsFragment = { name: string; mass: number | null }; export type HumanWithNullHeightQueryVariables = Exact<{ [key: string]: never }>; -export type HumanWithNullHeightQuery = { - __typename?: 'Query'; - human?: { __typename?: 'Human'; name: string; mass?: number | null } | null; -}; +export type HumanWithNullHeightQuery = { human: { name: string; mass: number | null } | null }; export type TwoHeroesQueryVariables = Exact<{ [key: string]: never }>; export type TwoHeroesQuery = { - __typename?: 'Query'; - r2?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; - luke?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; + r2: { name: string } | { name: string } | null; + luke: { name: string } | { name: string } | null; }; diff --git a/dev-test/star-wars/types.globallyAvailable.d.ts b/dev-test/star-wars/types.globallyAvailable.d.ts index 4bc089978b1..bf3ce6677cd 100644 --- a/dev-test/star-wars/types.globallyAvailable.d.ts +++ b/dev-test/star-wars/types.globallyAvailable.d.ts @@ -1,69 +1,14 @@ -type Maybe = T | null; -type InputMaybe = Maybe; +/** Internal type. DO NOT USE DIRECTLY. */ type Exact = { [K in keyof T]: T[K] }; -type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -type MakeEmpty = { [_ in K]?: never }; -type Incremental = +/** Internal type. DO NOT USE DIRECTLY. */ +export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** All built-in and custom scalars, mapped to their actual values */ -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 }; -}; - -/** A character from the Star Wars universe */ -type Character = { - /** The movies this character appears in */ - appearsIn: Array>; - /** The friends of the character, or an empty list if they have none */ - friends?: Maybe>>; - /** The friends of the character exposed as a connection with edges */ - friendsConnection: FriendsConnection; - /** The ID of the character */ - id: Scalars['ID']['output']; - /** The name of the character */ - name: Scalars['String']['output']; -}; - -/** A character from the Star Wars universe */ -type CharacterFriendsConnectionArgs = { - after?: InputMaybe; - first?: InputMaybe; -}; - /** The input object sent when passing a color */ type ColorInput = { - blue: Scalars['Int']['input']; - green: Scalars['Int']['input']; - red: Scalars['Int']['input']; -}; - -/** An autonomous mechanical character in the Star Wars universe */ -type Droid = Character & { - __typename?: 'Droid'; - /** The movies this droid appears in */ - appearsIn: Array>; - /** This droid's friends, or an empty list if they have none */ - friends?: Maybe>>; - /** The friends of the droid exposed as a connection with edges */ - friendsConnection: FriendsConnection; - /** The ID of the droid */ - id: Scalars['ID']['output']; - /** What others call this droid */ - name: Scalars['String']['output']; - /** This droid's primary function */ - primaryFunction?: Maybe; -}; - -/** An autonomous mechanical character in the Star Wars universe */ -type DroidFriendsConnectionArgs = { - after?: InputMaybe; - first?: InputMaybe; + blue: number; + green: number; + red: number; }; /** The episodes in the Star Wars trilogy */ @@ -75,169 +20,14 @@ type Episode = /** Star Wars Episode IV: A New Hope, released in 1977. */ | 'NEWHOPE'; -/** A connection object for a character's friends */ -type FriendsConnection = { - __typename?: 'FriendsConnection'; - /** The edges for each of the character's friends. */ - edges?: Maybe>>; - /** A list of the friends, as a convenience when edges are not needed. */ - friends?: Maybe>>; - /** Information for paginating this connection */ - pageInfo: PageInfo; - /** The total number of friends */ - totalCount?: Maybe; -}; - -/** An edge object for a character's friends */ -type FriendsEdge = { - __typename?: 'FriendsEdge'; - /** A cursor used for pagination */ - cursor: Scalars['ID']['output']; - /** The character represented by this friendship edge */ - node?: Maybe; -}; - -/** A humanoid creature from the Star Wars universe */ -type Human = Character & { - __typename?: 'Human'; - /** The movies this human appears in */ - appearsIn: Array>; - /** This human's friends, or an empty list if they have none */ - friends?: Maybe>>; - /** The friends of the human exposed as a connection with edges */ - friendsConnection: FriendsConnection; - /** Height in the preferred unit, default is meters */ - height?: Maybe; - /** The home planet of the human, or null if unknown */ - homePlanet?: Maybe; - /** The ID of the human */ - id: Scalars['ID']['output']; - /** Mass in kilograms, or null if unknown */ - mass?: Maybe; - /** What this human calls themselves */ - name: Scalars['String']['output']; - /** A list of starships this person has piloted, or an empty list if none */ - starships?: Maybe>>; -}; - -/** A humanoid creature from the Star Wars universe */ -type HumanFriendsConnectionArgs = { - after?: InputMaybe; - first?: InputMaybe; -}; - -/** A humanoid creature from the Star Wars universe */ -type HumanHeightArgs = { - unit?: InputMaybe; -}; - -/** Units of height */ -type LengthUnit = - /** Primarily used in the United States */ - | 'FOOT' - /** The standard unit around the world */ - | 'METER'; - -/** The mutation type, represents all updates we can make to our data */ -type Mutation = { - __typename?: 'Mutation'; - createReview?: Maybe; -}; - -/** The mutation type, represents all updates we can make to our data */ -type MutationCreateReviewArgs = { - episode?: InputMaybe; - review: ReviewInput; -}; - -/** Information for paginating this connection */ -type PageInfo = { - __typename?: 'PageInfo'; - endCursor?: Maybe; - hasNextPage: Scalars['Boolean']['output']; - startCursor?: Maybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -type Query = { - __typename?: 'Query'; - character?: Maybe; - droid?: Maybe; - hero?: Maybe; - human?: Maybe; - reviews?: Maybe>>; - search?: Maybe>>; - starship?: Maybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -type QueryCharacterArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -type QueryDroidArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -type QueryHeroArgs = { - episode?: InputMaybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -type QueryHumanArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -type QueryReviewsArgs = { - episode: Episode; -}; - -/** The query type, represents all of the entry points into our object graph */ -type QuerySearchArgs = { - text?: InputMaybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -type QueryStarshipArgs = { - id: Scalars['ID']['input']; -}; - -/** Represents a review for a movie */ -type Review = { - __typename?: 'Review'; - /** Comment about the movie */ - commentary?: Maybe; - /** The number of stars this review gave, 1-5 */ - stars: Scalars['Int']['output']; -}; - /** The input object sent when someone is creating a new review */ type ReviewInput = { /** Comment about the movie, optional */ - commentary?: InputMaybe; + commentary?: string | null | undefined; /** Favorite color, optional */ - favoriteColor?: InputMaybe; + favoriteColor?: ColorInput | null | undefined; /** 0-5 stars */ - stars: Scalars['Int']['input']; -}; - -type SearchResult = Droid | Human | Starship; - -type Starship = { - __typename?: 'Starship'; - /** The ID of the starship */ - id: Scalars['ID']['output']; - /** Length of the starship, along the longest axis */ - length?: Maybe; - /** The name of the starship */ - name: Scalars['String']['output']; -}; - -type StarshipLengthArgs = { - unit?: InputMaybe; + stars: number; }; type CreateReviewForEpisodeMutationVariables = Exact<{ @@ -246,178 +36,123 @@ type CreateReviewForEpisodeMutationVariables = Exact<{ }>; type CreateReviewForEpisodeMutation = { - __typename?: 'Mutation'; - createReview?: { __typename?: 'Review'; stars: number; commentary?: string | null } | null; + createReview: { stars: number; commentary: string | null } | null; }; type ExcludeQueryAlphaQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; -type ExcludeQueryAlphaQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; -}; +type ExcludeQueryAlphaQuery = { hero: { name: string } | { name: string } | null }; type ExcludeQueryBetaQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; -type ExcludeQueryBetaQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; -}; +type ExcludeQueryBetaQuery = { hero: { name: string } | { name: string } | null }; type HeroAndFriendsNamesQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; type HeroAndFriendsNamesQuery = { - __typename?: 'Query'; - hero?: - | { - __typename?: 'Droid'; - name: string; - friends?: Array< - { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null - > | null; - } - | { - __typename?: 'Human'; - name: string; - friends?: Array< - { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null - > | null; - } + hero: + | { name: string; friends: Array<{ name: string } | { name: string } | null> | null } + | { name: string; friends: Array<{ name: string } | { name: string } | null> | null } | null; }; type HeroAppearsInQueryVariables = Exact<{ [key: string]: never }>; type HeroAppearsInQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; name: string; appearsIn: Array } - | { __typename?: 'Human'; name: string; appearsIn: Array } + hero: + | { name: string; appearsIn: Array } + | { name: string; appearsIn: Array } | null; }; type HeroDetailsQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; type HeroDetailsQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; primaryFunction?: string | null; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } + hero: + | { primaryFunction: string | null; name: string } + | { height: number | null; name: string } | null; }; -type HeroDetails_Droid_Fragment = { - __typename?: 'Droid'; - primaryFunction?: string | null; - name: string; -}; +type HeroDetails_Droid_Fragment = { primaryFunction: string | null; name: string }; -type HeroDetails_Human_Fragment = { __typename?: 'Human'; height?: number | null; name: string }; +type HeroDetails_Human_Fragment = { height: number | null; name: string }; type HeroDetailsFragment = HeroDetails_Droid_Fragment | HeroDetails_Human_Fragment; type HeroDetailsWithFragmentQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; type HeroDetailsWithFragmentQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; primaryFunction?: string | null; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } + hero: + | { primaryFunction: string | null; name: string } + | { height: number | null; name: string } | null; }; type HeroNameQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; -type HeroNameQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; -}; +type HeroNameQuery = { hero: { name: string } | { name: string } | null }; type HeroNameConditionalInclusionQueryVariables = Exact<{ - episode?: InputMaybe; - includeName: Scalars['Boolean']['input']; + episode?: Episode | null | undefined; + includeName: boolean; }>; -type HeroNameConditionalInclusionQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name?: string } | { __typename?: 'Human'; name?: string } | null; -}; +type HeroNameConditionalInclusionQuery = { hero: { name?: string } | { name?: string } | null }; type HeroNameConditionalExclusionQueryVariables = Exact<{ - episode?: InputMaybe; - skipName: Scalars['Boolean']['input']; + episode?: Episode | null | undefined; + skipName: boolean; }>; -type HeroNameConditionalExclusionQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name?: string } | { __typename?: 'Human'; name?: string } | null; -}; +type HeroNameConditionalExclusionQuery = { hero: { name?: string } | { name?: string } | null }; type HeroParentTypeDependentFieldQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; type HeroParentTypeDependentFieldQuery = { - __typename?: 'Query'; - hero?: + hero: | { - __typename?: 'Droid'; name: string; - friends?: Array< - | { __typename?: 'Droid'; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } - | null - > | null; + friends: Array<{ name: string } | { height: number | null; name: string } | null> | null; } | { - __typename?: 'Human'; name: string; - friends?: Array< - | { __typename?: 'Droid'; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } - | null - > | null; + friends: Array<{ name: string } | { height: number | null; name: string } | null> | null; } | null; }; type HeroTypeDependentAliasedFieldQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; type HeroTypeDependentAliasedFieldQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; property?: string | null } - | { __typename?: 'Human'; property?: string | null } - | null; + hero: { property: string | null } | { property: string | null } | null; }; -type HumanFieldsFragment = { __typename?: 'Human'; name: string; mass?: number | null }; +type HumanFieldsFragment = { name: string; mass: number | null }; type HumanWithNullHeightQueryVariables = Exact<{ [key: string]: never }>; -type HumanWithNullHeightQuery = { - __typename?: 'Query'; - human?: { __typename?: 'Human'; name: string; mass?: number | null } | null; -}; +type HumanWithNullHeightQuery = { human: { name: string; mass: number | null } | null }; type TwoHeroesQueryVariables = Exact<{ [key: string]: never }>; type TwoHeroesQuery = { - __typename?: 'Query'; - r2?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; - luke?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; + r2: { name: string } | { name: string } | null; + luke: { name: string } | { name: string } | null; }; diff --git a/dev-test/star-wars/types.immutableTypes.ts b/dev-test/star-wars/types.immutableTypes.ts index eb4f1283e16..fafd0e5ccea 100644 --- a/dev-test/star-wars/types.immutableTypes.ts +++ b/dev-test/star-wars/types.immutableTypes.ts @@ -1,247 +1,33 @@ -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A character from the Star Wars universe */ -export type Character = { - /** The movies this character appears in */ - readonly appearsIn: ReadonlyArray>; - /** The friends of the character, or an empty list if they have none */ - readonly friends?: Maybe>>; - /** The friends of the character exposed as a connection with edges */ - readonly friendsConnection: FriendsConnection; - /** The ID of the character */ - readonly id: Scalars['ID']['output']; - /** The name of the character */ - readonly name: Scalars['String']['output']; -}; - -/** A character from the Star Wars universe */ -export type CharacterFriendsConnectionArgs = { - after?: InputMaybe; - first?: InputMaybe; -}; - /** The input object sent when passing a color */ export type ColorInput = { - readonly blue: Scalars['Int']['input']; - readonly green: Scalars['Int']['input']; - readonly red: Scalars['Int']['input']; -}; - -/** An autonomous mechanical character in the Star Wars universe */ -export type Droid = Character & { - readonly __typename?: 'Droid'; - /** The movies this droid appears in */ - readonly appearsIn: ReadonlyArray>; - /** This droid's friends, or an empty list if they have none */ - readonly friends?: Maybe>>; - /** The friends of the droid exposed as a connection with edges */ - readonly friendsConnection: FriendsConnection; - /** The ID of the droid */ - readonly id: Scalars['ID']['output']; - /** What others call this droid */ - readonly name: Scalars['String']['output']; - /** This droid's primary function */ - readonly primaryFunction?: Maybe; -}; - -/** An autonomous mechanical character in the Star Wars universe */ -export type DroidFriendsConnectionArgs = { - after?: InputMaybe; - first?: InputMaybe; + readonly blue: number; + readonly green: number; + readonly red: number; }; /** The episodes in the Star Wars trilogy */ -export enum Episode { +export type Episode = /** Star Wars Episode V: The Empire Strikes Back, released in 1980. */ - Empire = 'EMPIRE', + | 'EMPIRE' /** Star Wars Episode VI: Return of the Jedi, released in 1983. */ - Jedi = 'JEDI', + | 'JEDI' /** Star Wars Episode IV: A New Hope, released in 1977. */ - Newhope = 'NEWHOPE', -} - -/** A connection object for a character's friends */ -export type FriendsConnection = { - readonly __typename?: 'FriendsConnection'; - /** The edges for each of the character's friends. */ - readonly edges?: Maybe>>; - /** A list of the friends, as a convenience when edges are not needed. */ - readonly friends?: Maybe>>; - /** Information for paginating this connection */ - readonly pageInfo: PageInfo; - /** The total number of friends */ - readonly totalCount?: Maybe; -}; - -/** An edge object for a character's friends */ -export type FriendsEdge = { - readonly __typename?: 'FriendsEdge'; - /** A cursor used for pagination */ - readonly cursor: Scalars['ID']['output']; - /** The character represented by this friendship edge */ - readonly node?: Maybe; -}; - -/** A humanoid creature from the Star Wars universe */ -export type Human = Character & { - readonly __typename?: 'Human'; - /** The movies this human appears in */ - readonly appearsIn: ReadonlyArray>; - /** This human's friends, or an empty list if they have none */ - readonly friends?: Maybe>>; - /** The friends of the human exposed as a connection with edges */ - readonly friendsConnection: FriendsConnection; - /** Height in the preferred unit, default is meters */ - readonly height?: Maybe; - /** The home planet of the human, or null if unknown */ - readonly homePlanet?: Maybe; - /** The ID of the human */ - readonly id: Scalars['ID']['output']; - /** Mass in kilograms, or null if unknown */ - readonly mass?: Maybe; - /** What this human calls themselves */ - readonly name: Scalars['String']['output']; - /** A list of starships this person has piloted, or an empty list if none */ - readonly starships?: Maybe>>; -}; - -/** A humanoid creature from the Star Wars universe */ -export type HumanFriendsConnectionArgs = { - after?: InputMaybe; - first?: InputMaybe; -}; - -/** A humanoid creature from the Star Wars universe */ -export type HumanHeightArgs = { - unit?: InputMaybe; -}; - -/** Units of height */ -export enum LengthUnit { - /** Primarily used in the United States */ - Foot = 'FOOT', - /** The standard unit around the world */ - Meter = 'METER', -} - -/** The mutation type, represents all updates we can make to our data */ -export type Mutation = { - readonly __typename?: 'Mutation'; - readonly createReview?: Maybe; -}; - -/** The mutation type, represents all updates we can make to our data */ -export type MutationCreateReviewArgs = { - episode?: InputMaybe; - review: ReviewInput; -}; - -/** Information for paginating this connection */ -export type PageInfo = { - readonly __typename?: 'PageInfo'; - readonly endCursor?: Maybe; - readonly hasNextPage: Scalars['Boolean']['output']; - readonly startCursor?: Maybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type Query = { - readonly __typename?: 'Query'; - readonly character?: Maybe; - readonly droid?: Maybe; - readonly hero?: Maybe; - readonly human?: Maybe; - readonly reviews?: Maybe>>; - readonly search?: Maybe>>; - readonly starship?: Maybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryCharacterArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryDroidArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryHeroArgs = { - episode?: InputMaybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryHumanArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryReviewsArgs = { - episode: Episode; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QuerySearchArgs = { - text?: InputMaybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryStarshipArgs = { - id: Scalars['ID']['input']; -}; - -/** Represents a review for a movie */ -export type Review = { - readonly __typename?: 'Review'; - /** Comment about the movie */ - readonly commentary?: Maybe; - /** The number of stars this review gave, 1-5 */ - readonly stars: Scalars['Int']['output']; -}; + | 'NEWHOPE'; /** The input object sent when someone is creating a new review */ export type ReviewInput = { /** Comment about the movie, optional */ - readonly commentary?: InputMaybe; + readonly commentary?: string | null | undefined; /** Favorite color, optional */ - readonly favoriteColor?: InputMaybe; + readonly favoriteColor?: ColorInput | null | undefined; /** 0-5 stars */ - readonly stars: Scalars['Int']['input']; -}; - -export type SearchResult = Droid | Human | Starship; - -export type Starship = { - readonly __typename?: 'Starship'; - /** The ID of the starship */ - readonly id: Scalars['ID']['output']; - /** Length of the starship, along the longest axis */ - readonly length?: Maybe; - /** The name of the starship */ - readonly name: Scalars['String']['output']; -}; - -export type StarshipLengthArgs = { - unit?: InputMaybe; + readonly stars: number; }; export type CreateReviewForEpisodeMutationVariables = Exact<{ @@ -250,61 +36,41 @@ export type CreateReviewForEpisodeMutationVariables = Exact<{ }>; export type CreateReviewForEpisodeMutation = { - readonly __typename?: 'Mutation'; - readonly createReview?: { - readonly __typename?: 'Review'; - readonly stars: number; - readonly commentary?: string | null; - } | null; + readonly createReview: { readonly stars: number; readonly commentary: string | null } | null; }; export type ExcludeQueryAlphaQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type ExcludeQueryAlphaQuery = { - readonly __typename?: 'Query'; - readonly hero?: - | { readonly __typename?: 'Droid'; readonly name: string } - | { readonly __typename?: 'Human'; readonly name: string } - | null; + readonly hero: { readonly name: string } | { readonly name: string } | null; }; export type ExcludeQueryBetaQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type ExcludeQueryBetaQuery = { - readonly __typename?: 'Query'; - readonly hero?: - | { readonly __typename?: 'Droid'; readonly name: string } - | { readonly __typename?: 'Human'; readonly name: string } - | null; + readonly hero: { readonly name: string } | { readonly name: string } | null; }; export type HeroAndFriendsNamesQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroAndFriendsNamesQuery = { - readonly __typename?: 'Query'; - readonly hero?: + readonly hero: | { - readonly __typename?: 'Droid'; readonly name: string; - readonly friends?: ReadonlyArray< - | { readonly __typename?: 'Droid'; readonly name: string } - | { readonly __typename?: 'Human'; readonly name: string } - | null + readonly friends: ReadonlyArray< + { readonly name: string } | { readonly name: string } | null > | null; } | { - readonly __typename?: 'Human'; readonly name: string; - readonly friends?: ReadonlyArray< - | { readonly __typename?: 'Droid'; readonly name: string } - | { readonly __typename?: 'Human'; readonly name: string } - | null + readonly friends: ReadonlyArray< + { readonly name: string } | { readonly name: string } | null > | null; } | null; @@ -313,135 +79,88 @@ export type HeroAndFriendsNamesQuery = { export type HeroAppearsInQueryVariables = Exact<{ [key: string]: never }>; export type HeroAppearsInQuery = { - readonly __typename?: 'Query'; - readonly hero?: - | { - readonly __typename?: 'Droid'; - readonly name: string; - readonly appearsIn: ReadonlyArray; - } - | { - readonly __typename?: 'Human'; - readonly name: string; - readonly appearsIn: ReadonlyArray; - } + readonly hero: + | { readonly name: string; readonly appearsIn: ReadonlyArray } + | { readonly name: string; readonly appearsIn: ReadonlyArray } | null; }; export type HeroDetailsQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroDetailsQuery = { - readonly __typename?: 'Query'; - readonly hero?: - | { - readonly __typename?: 'Droid'; - readonly primaryFunction?: string | null; - readonly name: string; - } - | { readonly __typename?: 'Human'; readonly height?: number | null; readonly name: string } + readonly hero: + | { readonly primaryFunction: string | null; readonly name: string } + | { readonly height: number | null; readonly name: string } | null; }; type HeroDetails_Droid_Fragment = { - readonly __typename?: 'Droid'; - readonly primaryFunction?: string | null; + readonly primaryFunction: string | null; readonly name: string; }; -type HeroDetails_Human_Fragment = { - readonly __typename?: 'Human'; - readonly height?: number | null; - readonly name: string; -}; +type HeroDetails_Human_Fragment = { readonly height: number | null; readonly name: string }; export type HeroDetailsFragment = HeroDetails_Droid_Fragment | HeroDetails_Human_Fragment; export type HeroDetailsWithFragmentQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroDetailsWithFragmentQuery = { - readonly __typename?: 'Query'; - readonly hero?: - | { - readonly __typename?: 'Droid'; - readonly primaryFunction?: string | null; - readonly name: string; - } - | { readonly __typename?: 'Human'; readonly height?: number | null; readonly name: string } + readonly hero: + | { readonly primaryFunction: string | null; readonly name: string } + | { readonly height: number | null; readonly name: string } | null; }; export type HeroNameQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroNameQuery = { - readonly __typename?: 'Query'; - readonly hero?: - | { readonly __typename?: 'Droid'; readonly name: string } - | { readonly __typename?: 'Human'; readonly name: string } - | null; + readonly hero: { readonly name: string } | { readonly name: string } | null; }; export type HeroNameConditionalInclusionQueryVariables = Exact<{ - episode?: InputMaybe; - includeName: Scalars['Boolean']['input']; + episode?: Episode | null | undefined; + includeName: boolean; }>; export type HeroNameConditionalInclusionQuery = { - readonly __typename?: 'Query'; - readonly hero?: - | { readonly __typename?: 'Droid'; readonly name?: string } - | { readonly __typename?: 'Human'; readonly name?: string } - | null; + readonly hero: { readonly name?: string } | { readonly name?: string } | null; }; export type HeroNameConditionalExclusionQueryVariables = Exact<{ - episode?: InputMaybe; - skipName: Scalars['Boolean']['input']; + episode?: Episode | null | undefined; + skipName: boolean; }>; export type HeroNameConditionalExclusionQuery = { - readonly __typename?: 'Query'; - readonly hero?: - | { readonly __typename?: 'Droid'; readonly name?: string } - | { readonly __typename?: 'Human'; readonly name?: string } - | null; + readonly hero: { readonly name?: string } | { readonly name?: string } | null; }; export type HeroParentTypeDependentFieldQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroParentTypeDependentFieldQuery = { - readonly __typename?: 'Query'; - readonly hero?: + readonly hero: | { - readonly __typename?: 'Droid'; readonly name: string; - readonly friends?: ReadonlyArray< - | { readonly __typename?: 'Droid'; readonly name: string } - | { - readonly __typename?: 'Human'; - readonly height?: number | null; - readonly name: string; - } + readonly friends: ReadonlyArray< + | { readonly name: string } + | { readonly height: number | null; readonly name: string } | null > | null; } | { - readonly __typename?: 'Human'; readonly name: string; - readonly friends?: ReadonlyArray< - | { readonly __typename?: 'Droid'; readonly name: string } - | { - readonly __typename?: 'Human'; - readonly height?: number | null; - readonly name: string; - } + readonly friends: ReadonlyArray< + | { readonly name: string } + | { readonly height: number | null; readonly name: string } | null > | null; } @@ -449,44 +168,24 @@ export type HeroParentTypeDependentFieldQuery = { }; export type HeroTypeDependentAliasedFieldQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroTypeDependentAliasedFieldQuery = { - readonly __typename?: 'Query'; - readonly hero?: - | { readonly __typename?: 'Droid'; readonly property?: string | null } - | { readonly __typename?: 'Human'; readonly property?: string | null } - | null; + readonly hero: { readonly property: string | null } | { readonly property: string | null } | null; }; -export type HumanFieldsFragment = { - readonly __typename?: 'Human'; - readonly name: string; - readonly mass?: number | null; -}; +export type HumanFieldsFragment = { readonly name: string; readonly mass: number | null }; export type HumanWithNullHeightQueryVariables = Exact<{ [key: string]: never }>; export type HumanWithNullHeightQuery = { - readonly __typename?: 'Query'; - readonly human?: { - readonly __typename?: 'Human'; - readonly name: string; - readonly mass?: number | null; - } | null; + readonly human: { readonly name: string; readonly mass: number | null } | null; }; export type TwoHeroesQueryVariables = Exact<{ [key: string]: never }>; export type TwoHeroesQuery = { - readonly __typename?: 'Query'; - readonly r2?: - | { readonly __typename?: 'Droid'; readonly name: string } - | { readonly __typename?: 'Human'; readonly name: string } - | null; - readonly luke?: - | { readonly __typename?: 'Droid'; readonly name: string } - | { readonly __typename?: 'Human'; readonly name: string } - | null; + readonly r2: { readonly name: string } | { readonly name: string } | null; + readonly luke: { readonly name: string } | { readonly name: string } | null; }; diff --git a/dev-test/star-wars/types.preResolveTypes.onlyOperationTypes.ts b/dev-test/star-wars/types.preResolveTypes.onlyOperationTypes.ts index 8a7dfa7c6ae..09384a92091 100644 --- a/dev-test/star-wars/types.preResolveTypes.onlyOperationTypes.ts +++ b/dev-test/star-wars/types.preResolveTypes.onlyOperationTypes.ts @@ -1,56 +1,33 @@ -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - /** The input object sent when passing a color */ export type ColorInput = { - blue: Scalars['Int']['input']; - green: Scalars['Int']['input']; - red: Scalars['Int']['input']; + blue: number; + green: number; + red: number; }; /** The episodes in the Star Wars trilogy */ -export enum Episode { +export type Episode = /** Star Wars Episode V: The Empire Strikes Back, released in 1980. */ - Empire = 'EMPIRE', + | 'EMPIRE' /** Star Wars Episode VI: Return of the Jedi, released in 1983. */ - Jedi = 'JEDI', + | 'JEDI' /** Star Wars Episode IV: A New Hope, released in 1977. */ - Newhope = 'NEWHOPE', -} - -/** Units of height */ -export enum LengthUnit { - /** Primarily used in the United States */ - Foot = 'FOOT', - /** The standard unit around the world */ - Meter = 'METER', -} + | 'NEWHOPE'; /** The input object sent when someone is creating a new review */ export type ReviewInput = { /** Comment about the movie, optional */ - commentary?: InputMaybe; + commentary?: string | null | undefined; /** Favorite color, optional */ - favoriteColor?: InputMaybe; + favoriteColor?: ColorInput | null | undefined; /** 0-5 stars */ - stars: Scalars['Int']['input']; + stars: number; }; export type CreateReviewForEpisodeMutationVariables = Exact<{ @@ -59,178 +36,127 @@ export type CreateReviewForEpisodeMutationVariables = Exact<{ }>; export type CreateReviewForEpisodeMutation = { - __typename?: 'Mutation'; - createReview?: { __typename?: 'Review'; stars: number; commentary?: string | null } | null; + createReview: { stars: number; commentary: string | null } | null; }; export type ExcludeQueryAlphaQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; -export type ExcludeQueryAlphaQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; -}; +export type ExcludeQueryAlphaQuery = { hero: { name: string } | { name: string } | null }; export type ExcludeQueryBetaQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; -export type ExcludeQueryBetaQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; -}; +export type ExcludeQueryBetaQuery = { hero: { name: string } | { name: string } | null }; export type HeroAndFriendsNamesQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroAndFriendsNamesQuery = { - __typename?: 'Query'; - hero?: - | { - __typename?: 'Droid'; - name: string; - friends?: Array< - { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null - > | null; - } - | { - __typename?: 'Human'; - name: string; - friends?: Array< - { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null - > | null; - } + hero: + | { name: string; friends: Array<{ name: string } | { name: string } | null> | null } + | { name: string; friends: Array<{ name: string } | { name: string } | null> | null } | null; }; export type HeroAppearsInQueryVariables = Exact<{ [key: string]: never }>; export type HeroAppearsInQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; name: string; appearsIn: Array } - | { __typename?: 'Human'; name: string; appearsIn: Array } + hero: + | { name: string; appearsIn: Array } + | { name: string; appearsIn: Array } | null; }; export type HeroDetailsQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroDetailsQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; primaryFunction?: string | null; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } + hero: + | { primaryFunction: string | null; name: string } + | { height: number | null; name: string } | null; }; -type HeroDetails_Droid_Fragment = { - __typename?: 'Droid'; - primaryFunction?: string | null; - name: string; -}; +type HeroDetails_Droid_Fragment = { primaryFunction: string | null; name: string }; -type HeroDetails_Human_Fragment = { __typename?: 'Human'; height?: number | null; name: string }; +type HeroDetails_Human_Fragment = { height: number | null; name: string }; export type HeroDetailsFragment = HeroDetails_Droid_Fragment | HeroDetails_Human_Fragment; export type HeroDetailsWithFragmentQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroDetailsWithFragmentQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; primaryFunction?: string | null; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } + hero: + | { primaryFunction: string | null; name: string } + | { height: number | null; name: string } | null; }; export type HeroNameQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; -export type HeroNameQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; -}; +export type HeroNameQuery = { hero: { name: string } | { name: string } | null }; export type HeroNameConditionalInclusionQueryVariables = Exact<{ - episode?: InputMaybe; - includeName: Scalars['Boolean']['input']; + episode?: Episode | null | undefined; + includeName: boolean; }>; export type HeroNameConditionalInclusionQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name?: string } | { __typename?: 'Human'; name?: string } | null; + hero: { name?: string } | { name?: string } | null; }; export type HeroNameConditionalExclusionQueryVariables = Exact<{ - episode?: InputMaybe; - skipName: Scalars['Boolean']['input']; + episode?: Episode | null | undefined; + skipName: boolean; }>; export type HeroNameConditionalExclusionQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name?: string } | { __typename?: 'Human'; name?: string } | null; + hero: { name?: string } | { name?: string } | null; }; export type HeroParentTypeDependentFieldQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroParentTypeDependentFieldQuery = { - __typename?: 'Query'; - hero?: + hero: | { - __typename?: 'Droid'; name: string; - friends?: Array< - | { __typename?: 'Droid'; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } - | null - > | null; + friends: Array<{ name: string } | { height: number | null; name: string } | null> | null; } | { - __typename?: 'Human'; name: string; - friends?: Array< - | { __typename?: 'Droid'; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } - | null - > | null; + friends: Array<{ name: string } | { height: number | null; name: string } | null> | null; } | null; }; export type HeroTypeDependentAliasedFieldQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroTypeDependentAliasedFieldQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; property?: string | null } - | { __typename?: 'Human'; property?: string | null } - | null; + hero: { property: string | null } | { property: string | null } | null; }; -export type HumanFieldsFragment = { __typename?: 'Human'; name: string; mass?: number | null }; +export type HumanFieldsFragment = { name: string; mass: number | null }; export type HumanWithNullHeightQueryVariables = Exact<{ [key: string]: never }>; -export type HumanWithNullHeightQuery = { - __typename?: 'Query'; - human?: { __typename?: 'Human'; name: string; mass?: number | null } | null; -}; +export type HumanWithNullHeightQuery = { human: { name: string; mass: number | null } | null }; export type TwoHeroesQueryVariables = Exact<{ [key: string]: never }>; export type TwoHeroesQuery = { - __typename?: 'Query'; - r2?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; - luke?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; + r2: { name: string } | { name: string } | null; + luke: { name: string } | { name: string } | null; }; diff --git a/dev-test/star-wars/types.preResolveTypes.ts b/dev-test/star-wars/types.preResolveTypes.ts index 48c07f03464..09384a92091 100644 --- a/dev-test/star-wars/types.preResolveTypes.ts +++ b/dev-test/star-wars/types.preResolveTypes.ts @@ -1,247 +1,33 @@ -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A character from the Star Wars universe */ -export type Character = { - /** The movies this character appears in */ - appearsIn: Array>; - /** The friends of the character, or an empty list if they have none */ - friends?: Maybe>>; - /** The friends of the character exposed as a connection with edges */ - friendsConnection: FriendsConnection; - /** The ID of the character */ - id: Scalars['ID']['output']; - /** The name of the character */ - name: Scalars['String']['output']; -}; - -/** A character from the Star Wars universe */ -export type CharacterFriendsConnectionArgs = { - after?: InputMaybe; - first?: InputMaybe; -}; - /** The input object sent when passing a color */ export type ColorInput = { - blue: Scalars['Int']['input']; - green: Scalars['Int']['input']; - red: Scalars['Int']['input']; -}; - -/** An autonomous mechanical character in the Star Wars universe */ -export type Droid = Character & { - __typename?: 'Droid'; - /** The movies this droid appears in */ - appearsIn: Array>; - /** This droid's friends, or an empty list if they have none */ - friends?: Maybe>>; - /** The friends of the droid exposed as a connection with edges */ - friendsConnection: FriendsConnection; - /** The ID of the droid */ - id: Scalars['ID']['output']; - /** What others call this droid */ - name: Scalars['String']['output']; - /** This droid's primary function */ - primaryFunction?: Maybe; -}; - -/** An autonomous mechanical character in the Star Wars universe */ -export type DroidFriendsConnectionArgs = { - after?: InputMaybe; - first?: InputMaybe; + blue: number; + green: number; + red: number; }; /** The episodes in the Star Wars trilogy */ -export enum Episode { +export type Episode = /** Star Wars Episode V: The Empire Strikes Back, released in 1980. */ - Empire = 'EMPIRE', + | 'EMPIRE' /** Star Wars Episode VI: Return of the Jedi, released in 1983. */ - Jedi = 'JEDI', + | 'JEDI' /** Star Wars Episode IV: A New Hope, released in 1977. */ - Newhope = 'NEWHOPE', -} - -/** A connection object for a character's friends */ -export type FriendsConnection = { - __typename?: 'FriendsConnection'; - /** The edges for each of the character's friends. */ - edges?: Maybe>>; - /** A list of the friends, as a convenience when edges are not needed. */ - friends?: Maybe>>; - /** Information for paginating this connection */ - pageInfo: PageInfo; - /** The total number of friends */ - totalCount?: Maybe; -}; - -/** An edge object for a character's friends */ -export type FriendsEdge = { - __typename?: 'FriendsEdge'; - /** A cursor used for pagination */ - cursor: Scalars['ID']['output']; - /** The character represented by this friendship edge */ - node?: Maybe; -}; - -/** A humanoid creature from the Star Wars universe */ -export type Human = Character & { - __typename?: 'Human'; - /** The movies this human appears in */ - appearsIn: Array>; - /** This human's friends, or an empty list if they have none */ - friends?: Maybe>>; - /** The friends of the human exposed as a connection with edges */ - friendsConnection: FriendsConnection; - /** Height in the preferred unit, default is meters */ - height?: Maybe; - /** The home planet of the human, or null if unknown */ - homePlanet?: Maybe; - /** The ID of the human */ - id: Scalars['ID']['output']; - /** Mass in kilograms, or null if unknown */ - mass?: Maybe; - /** What this human calls themselves */ - name: Scalars['String']['output']; - /** A list of starships this person has piloted, or an empty list if none */ - starships?: Maybe>>; -}; - -/** A humanoid creature from the Star Wars universe */ -export type HumanFriendsConnectionArgs = { - after?: InputMaybe; - first?: InputMaybe; -}; - -/** A humanoid creature from the Star Wars universe */ -export type HumanHeightArgs = { - unit?: InputMaybe; -}; - -/** Units of height */ -export enum LengthUnit { - /** Primarily used in the United States */ - Foot = 'FOOT', - /** The standard unit around the world */ - Meter = 'METER', -} - -/** The mutation type, represents all updates we can make to our data */ -export type Mutation = { - __typename?: 'Mutation'; - createReview?: Maybe; -}; - -/** The mutation type, represents all updates we can make to our data */ -export type MutationCreateReviewArgs = { - episode?: InputMaybe; - review: ReviewInput; -}; - -/** Information for paginating this connection */ -export type PageInfo = { - __typename?: 'PageInfo'; - endCursor?: Maybe; - hasNextPage: Scalars['Boolean']['output']; - startCursor?: Maybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type Query = { - __typename?: 'Query'; - character?: Maybe; - droid?: Maybe; - hero?: Maybe; - human?: Maybe; - reviews?: Maybe>>; - search?: Maybe>>; - starship?: Maybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryCharacterArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryDroidArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryHeroArgs = { - episode?: InputMaybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryHumanArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryReviewsArgs = { - episode: Episode; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QuerySearchArgs = { - text?: InputMaybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryStarshipArgs = { - id: Scalars['ID']['input']; -}; - -/** Represents a review for a movie */ -export type Review = { - __typename?: 'Review'; - /** Comment about the movie */ - commentary?: Maybe; - /** The number of stars this review gave, 1-5 */ - stars: Scalars['Int']['output']; -}; + | 'NEWHOPE'; /** The input object sent when someone is creating a new review */ export type ReviewInput = { /** Comment about the movie, optional */ - commentary?: InputMaybe; + commentary?: string | null | undefined; /** Favorite color, optional */ - favoriteColor?: InputMaybe; + favoriteColor?: ColorInput | null | undefined; /** 0-5 stars */ - stars: Scalars['Int']['input']; -}; - -export type SearchResult = Droid | Human | Starship; - -export type Starship = { - __typename?: 'Starship'; - /** The ID of the starship */ - id: Scalars['ID']['output']; - /** Length of the starship, along the longest axis */ - length?: Maybe; - /** The name of the starship */ - name: Scalars['String']['output']; -}; - -export type StarshipLengthArgs = { - unit?: InputMaybe; + stars: number; }; export type CreateReviewForEpisodeMutationVariables = Exact<{ @@ -250,178 +36,127 @@ export type CreateReviewForEpisodeMutationVariables = Exact<{ }>; export type CreateReviewForEpisodeMutation = { - __typename?: 'Mutation'; - createReview?: { __typename?: 'Review'; stars: number; commentary?: string | null } | null; + createReview: { stars: number; commentary: string | null } | null; }; export type ExcludeQueryAlphaQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; -export type ExcludeQueryAlphaQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; -}; +export type ExcludeQueryAlphaQuery = { hero: { name: string } | { name: string } | null }; export type ExcludeQueryBetaQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; -export type ExcludeQueryBetaQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; -}; +export type ExcludeQueryBetaQuery = { hero: { name: string } | { name: string } | null }; export type HeroAndFriendsNamesQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroAndFriendsNamesQuery = { - __typename?: 'Query'; - hero?: - | { - __typename?: 'Droid'; - name: string; - friends?: Array< - { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null - > | null; - } - | { - __typename?: 'Human'; - name: string; - friends?: Array< - { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null - > | null; - } + hero: + | { name: string; friends: Array<{ name: string } | { name: string } | null> | null } + | { name: string; friends: Array<{ name: string } | { name: string } | null> | null } | null; }; export type HeroAppearsInQueryVariables = Exact<{ [key: string]: never }>; export type HeroAppearsInQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; name: string; appearsIn: Array } - | { __typename?: 'Human'; name: string; appearsIn: Array } + hero: + | { name: string; appearsIn: Array } + | { name: string; appearsIn: Array } | null; }; export type HeroDetailsQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroDetailsQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; primaryFunction?: string | null; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } + hero: + | { primaryFunction: string | null; name: string } + | { height: number | null; name: string } | null; }; -type HeroDetails_Droid_Fragment = { - __typename?: 'Droid'; - primaryFunction?: string | null; - name: string; -}; +type HeroDetails_Droid_Fragment = { primaryFunction: string | null; name: string }; -type HeroDetails_Human_Fragment = { __typename?: 'Human'; height?: number | null; name: string }; +type HeroDetails_Human_Fragment = { height: number | null; name: string }; export type HeroDetailsFragment = HeroDetails_Droid_Fragment | HeroDetails_Human_Fragment; export type HeroDetailsWithFragmentQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroDetailsWithFragmentQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; primaryFunction?: string | null; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } + hero: + | { primaryFunction: string | null; name: string } + | { height: number | null; name: string } | null; }; export type HeroNameQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; -export type HeroNameQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; -}; +export type HeroNameQuery = { hero: { name: string } | { name: string } | null }; export type HeroNameConditionalInclusionQueryVariables = Exact<{ - episode?: InputMaybe; - includeName: Scalars['Boolean']['input']; + episode?: Episode | null | undefined; + includeName: boolean; }>; export type HeroNameConditionalInclusionQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name?: string } | { __typename?: 'Human'; name?: string } | null; + hero: { name?: string } | { name?: string } | null; }; export type HeroNameConditionalExclusionQueryVariables = Exact<{ - episode?: InputMaybe; - skipName: Scalars['Boolean']['input']; + episode?: Episode | null | undefined; + skipName: boolean; }>; export type HeroNameConditionalExclusionQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name?: string } | { __typename?: 'Human'; name?: string } | null; + hero: { name?: string } | { name?: string } | null; }; export type HeroParentTypeDependentFieldQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroParentTypeDependentFieldQuery = { - __typename?: 'Query'; - hero?: + hero: | { - __typename?: 'Droid'; name: string; - friends?: Array< - | { __typename?: 'Droid'; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } - | null - > | null; + friends: Array<{ name: string } | { height: number | null; name: string } | null> | null; } | { - __typename?: 'Human'; name: string; - friends?: Array< - | { __typename?: 'Droid'; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } - | null - > | null; + friends: Array<{ name: string } | { height: number | null; name: string } | null> | null; } | null; }; export type HeroTypeDependentAliasedFieldQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroTypeDependentAliasedFieldQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; property?: string | null } - | { __typename?: 'Human'; property?: string | null } - | null; + hero: { property: string | null } | { property: string | null } | null; }; -export type HumanFieldsFragment = { __typename?: 'Human'; name: string; mass?: number | null }; +export type HumanFieldsFragment = { name: string; mass: number | null }; export type HumanWithNullHeightQueryVariables = Exact<{ [key: string]: never }>; -export type HumanWithNullHeightQuery = { - __typename?: 'Query'; - human?: { __typename?: 'Human'; name: string; mass?: number | null } | null; -}; +export type HumanWithNullHeightQuery = { human: { name: string; mass: number | null } | null }; export type TwoHeroesQueryVariables = Exact<{ [key: string]: never }>; export type TwoHeroesQuery = { - __typename?: 'Query'; - r2?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; - luke?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; + r2: { name: string } | { name: string } | null; + luke: { name: string } | { name: string } | null; }; diff --git a/dev-test/star-wars/types.skipSchema.ts b/dev-test/star-wars/types.skipSchema.ts index 48c07f03464..09384a92091 100644 --- a/dev-test/star-wars/types.skipSchema.ts +++ b/dev-test/star-wars/types.skipSchema.ts @@ -1,247 +1,33 @@ -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A character from the Star Wars universe */ -export type Character = { - /** The movies this character appears in */ - appearsIn: Array>; - /** The friends of the character, or an empty list if they have none */ - friends?: Maybe>>; - /** The friends of the character exposed as a connection with edges */ - friendsConnection: FriendsConnection; - /** The ID of the character */ - id: Scalars['ID']['output']; - /** The name of the character */ - name: Scalars['String']['output']; -}; - -/** A character from the Star Wars universe */ -export type CharacterFriendsConnectionArgs = { - after?: InputMaybe; - first?: InputMaybe; -}; - /** The input object sent when passing a color */ export type ColorInput = { - blue: Scalars['Int']['input']; - green: Scalars['Int']['input']; - red: Scalars['Int']['input']; -}; - -/** An autonomous mechanical character in the Star Wars universe */ -export type Droid = Character & { - __typename?: 'Droid'; - /** The movies this droid appears in */ - appearsIn: Array>; - /** This droid's friends, or an empty list if they have none */ - friends?: Maybe>>; - /** The friends of the droid exposed as a connection with edges */ - friendsConnection: FriendsConnection; - /** The ID of the droid */ - id: Scalars['ID']['output']; - /** What others call this droid */ - name: Scalars['String']['output']; - /** This droid's primary function */ - primaryFunction?: Maybe; -}; - -/** An autonomous mechanical character in the Star Wars universe */ -export type DroidFriendsConnectionArgs = { - after?: InputMaybe; - first?: InputMaybe; + blue: number; + green: number; + red: number; }; /** The episodes in the Star Wars trilogy */ -export enum Episode { +export type Episode = /** Star Wars Episode V: The Empire Strikes Back, released in 1980. */ - Empire = 'EMPIRE', + | 'EMPIRE' /** Star Wars Episode VI: Return of the Jedi, released in 1983. */ - Jedi = 'JEDI', + | 'JEDI' /** Star Wars Episode IV: A New Hope, released in 1977. */ - Newhope = 'NEWHOPE', -} - -/** A connection object for a character's friends */ -export type FriendsConnection = { - __typename?: 'FriendsConnection'; - /** The edges for each of the character's friends. */ - edges?: Maybe>>; - /** A list of the friends, as a convenience when edges are not needed. */ - friends?: Maybe>>; - /** Information for paginating this connection */ - pageInfo: PageInfo; - /** The total number of friends */ - totalCount?: Maybe; -}; - -/** An edge object for a character's friends */ -export type FriendsEdge = { - __typename?: 'FriendsEdge'; - /** A cursor used for pagination */ - cursor: Scalars['ID']['output']; - /** The character represented by this friendship edge */ - node?: Maybe; -}; - -/** A humanoid creature from the Star Wars universe */ -export type Human = Character & { - __typename?: 'Human'; - /** The movies this human appears in */ - appearsIn: Array>; - /** This human's friends, or an empty list if they have none */ - friends?: Maybe>>; - /** The friends of the human exposed as a connection with edges */ - friendsConnection: FriendsConnection; - /** Height in the preferred unit, default is meters */ - height?: Maybe; - /** The home planet of the human, or null if unknown */ - homePlanet?: Maybe; - /** The ID of the human */ - id: Scalars['ID']['output']; - /** Mass in kilograms, or null if unknown */ - mass?: Maybe; - /** What this human calls themselves */ - name: Scalars['String']['output']; - /** A list of starships this person has piloted, or an empty list if none */ - starships?: Maybe>>; -}; - -/** A humanoid creature from the Star Wars universe */ -export type HumanFriendsConnectionArgs = { - after?: InputMaybe; - first?: InputMaybe; -}; - -/** A humanoid creature from the Star Wars universe */ -export type HumanHeightArgs = { - unit?: InputMaybe; -}; - -/** Units of height */ -export enum LengthUnit { - /** Primarily used in the United States */ - Foot = 'FOOT', - /** The standard unit around the world */ - Meter = 'METER', -} - -/** The mutation type, represents all updates we can make to our data */ -export type Mutation = { - __typename?: 'Mutation'; - createReview?: Maybe; -}; - -/** The mutation type, represents all updates we can make to our data */ -export type MutationCreateReviewArgs = { - episode?: InputMaybe; - review: ReviewInput; -}; - -/** Information for paginating this connection */ -export type PageInfo = { - __typename?: 'PageInfo'; - endCursor?: Maybe; - hasNextPage: Scalars['Boolean']['output']; - startCursor?: Maybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type Query = { - __typename?: 'Query'; - character?: Maybe; - droid?: Maybe; - hero?: Maybe; - human?: Maybe; - reviews?: Maybe>>; - search?: Maybe>>; - starship?: Maybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryCharacterArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryDroidArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryHeroArgs = { - episode?: InputMaybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryHumanArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryReviewsArgs = { - episode: Episode; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QuerySearchArgs = { - text?: InputMaybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryStarshipArgs = { - id: Scalars['ID']['input']; -}; - -/** Represents a review for a movie */ -export type Review = { - __typename?: 'Review'; - /** Comment about the movie */ - commentary?: Maybe; - /** The number of stars this review gave, 1-5 */ - stars: Scalars['Int']['output']; -}; + | 'NEWHOPE'; /** The input object sent when someone is creating a new review */ export type ReviewInput = { /** Comment about the movie, optional */ - commentary?: InputMaybe; + commentary?: string | null | undefined; /** Favorite color, optional */ - favoriteColor?: InputMaybe; + favoriteColor?: ColorInput | null | undefined; /** 0-5 stars */ - stars: Scalars['Int']['input']; -}; - -export type SearchResult = Droid | Human | Starship; - -export type Starship = { - __typename?: 'Starship'; - /** The ID of the starship */ - id: Scalars['ID']['output']; - /** Length of the starship, along the longest axis */ - length?: Maybe; - /** The name of the starship */ - name: Scalars['String']['output']; -}; - -export type StarshipLengthArgs = { - unit?: InputMaybe; + stars: number; }; export type CreateReviewForEpisodeMutationVariables = Exact<{ @@ -250,178 +36,127 @@ export type CreateReviewForEpisodeMutationVariables = Exact<{ }>; export type CreateReviewForEpisodeMutation = { - __typename?: 'Mutation'; - createReview?: { __typename?: 'Review'; stars: number; commentary?: string | null } | null; + createReview: { stars: number; commentary: string | null } | null; }; export type ExcludeQueryAlphaQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; -export type ExcludeQueryAlphaQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; -}; +export type ExcludeQueryAlphaQuery = { hero: { name: string } | { name: string } | null }; export type ExcludeQueryBetaQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; -export type ExcludeQueryBetaQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; -}; +export type ExcludeQueryBetaQuery = { hero: { name: string } | { name: string } | null }; export type HeroAndFriendsNamesQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroAndFriendsNamesQuery = { - __typename?: 'Query'; - hero?: - | { - __typename?: 'Droid'; - name: string; - friends?: Array< - { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null - > | null; - } - | { - __typename?: 'Human'; - name: string; - friends?: Array< - { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null - > | null; - } + hero: + | { name: string; friends: Array<{ name: string } | { name: string } | null> | null } + | { name: string; friends: Array<{ name: string } | { name: string } | null> | null } | null; }; export type HeroAppearsInQueryVariables = Exact<{ [key: string]: never }>; export type HeroAppearsInQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; name: string; appearsIn: Array } - | { __typename?: 'Human'; name: string; appearsIn: Array } + hero: + | { name: string; appearsIn: Array } + | { name: string; appearsIn: Array } | null; }; export type HeroDetailsQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroDetailsQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; primaryFunction?: string | null; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } + hero: + | { primaryFunction: string | null; name: string } + | { height: number | null; name: string } | null; }; -type HeroDetails_Droid_Fragment = { - __typename?: 'Droid'; - primaryFunction?: string | null; - name: string; -}; +type HeroDetails_Droid_Fragment = { primaryFunction: string | null; name: string }; -type HeroDetails_Human_Fragment = { __typename?: 'Human'; height?: number | null; name: string }; +type HeroDetails_Human_Fragment = { height: number | null; name: string }; export type HeroDetailsFragment = HeroDetails_Droid_Fragment | HeroDetails_Human_Fragment; export type HeroDetailsWithFragmentQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroDetailsWithFragmentQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; primaryFunction?: string | null; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } + hero: + | { primaryFunction: string | null; name: string } + | { height: number | null; name: string } | null; }; export type HeroNameQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; -export type HeroNameQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; -}; +export type HeroNameQuery = { hero: { name: string } | { name: string } | null }; export type HeroNameConditionalInclusionQueryVariables = Exact<{ - episode?: InputMaybe; - includeName: Scalars['Boolean']['input']; + episode?: Episode | null | undefined; + includeName: boolean; }>; export type HeroNameConditionalInclusionQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name?: string } | { __typename?: 'Human'; name?: string } | null; + hero: { name?: string } | { name?: string } | null; }; export type HeroNameConditionalExclusionQueryVariables = Exact<{ - episode?: InputMaybe; - skipName: Scalars['Boolean']['input']; + episode?: Episode | null | undefined; + skipName: boolean; }>; export type HeroNameConditionalExclusionQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name?: string } | { __typename?: 'Human'; name?: string } | null; + hero: { name?: string } | { name?: string } | null; }; export type HeroParentTypeDependentFieldQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroParentTypeDependentFieldQuery = { - __typename?: 'Query'; - hero?: + hero: | { - __typename?: 'Droid'; name: string; - friends?: Array< - | { __typename?: 'Droid'; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } - | null - > | null; + friends: Array<{ name: string } | { height: number | null; name: string } | null> | null; } | { - __typename?: 'Human'; name: string; - friends?: Array< - | { __typename?: 'Droid'; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } - | null - > | null; + friends: Array<{ name: string } | { height: number | null; name: string } | null> | null; } | null; }; export type HeroTypeDependentAliasedFieldQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroTypeDependentAliasedFieldQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; property?: string | null } - | { __typename?: 'Human'; property?: string | null } - | null; + hero: { property: string | null } | { property: string | null } | null; }; -export type HumanFieldsFragment = { __typename?: 'Human'; name: string; mass?: number | null }; +export type HumanFieldsFragment = { name: string; mass: number | null }; export type HumanWithNullHeightQueryVariables = Exact<{ [key: string]: never }>; -export type HumanWithNullHeightQuery = { - __typename?: 'Query'; - human?: { __typename?: 'Human'; name: string; mass?: number | null } | null; -}; +export type HumanWithNullHeightQuery = { human: { name: string; mass: number | null } | null }; export type TwoHeroesQueryVariables = Exact<{ [key: string]: never }>; export type TwoHeroesQuery = { - __typename?: 'Query'; - r2?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; - luke?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; + r2: { name: string } | { name: string } | null; + luke: { name: string } | { name: string } | null; }; diff --git a/dev-test/star-wars/types.ts b/dev-test/star-wars/types.ts index 48c07f03464..09384a92091 100644 --- a/dev-test/star-wars/types.ts +++ b/dev-test/star-wars/types.ts @@ -1,247 +1,33 @@ -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A character from the Star Wars universe */ -export type Character = { - /** The movies this character appears in */ - appearsIn: Array>; - /** The friends of the character, or an empty list if they have none */ - friends?: Maybe>>; - /** The friends of the character exposed as a connection with edges */ - friendsConnection: FriendsConnection; - /** The ID of the character */ - id: Scalars['ID']['output']; - /** The name of the character */ - name: Scalars['String']['output']; -}; - -/** A character from the Star Wars universe */ -export type CharacterFriendsConnectionArgs = { - after?: InputMaybe; - first?: InputMaybe; -}; - /** The input object sent when passing a color */ export type ColorInput = { - blue: Scalars['Int']['input']; - green: Scalars['Int']['input']; - red: Scalars['Int']['input']; -}; - -/** An autonomous mechanical character in the Star Wars universe */ -export type Droid = Character & { - __typename?: 'Droid'; - /** The movies this droid appears in */ - appearsIn: Array>; - /** This droid's friends, or an empty list if they have none */ - friends?: Maybe>>; - /** The friends of the droid exposed as a connection with edges */ - friendsConnection: FriendsConnection; - /** The ID of the droid */ - id: Scalars['ID']['output']; - /** What others call this droid */ - name: Scalars['String']['output']; - /** This droid's primary function */ - primaryFunction?: Maybe; -}; - -/** An autonomous mechanical character in the Star Wars universe */ -export type DroidFriendsConnectionArgs = { - after?: InputMaybe; - first?: InputMaybe; + blue: number; + green: number; + red: number; }; /** The episodes in the Star Wars trilogy */ -export enum Episode { +export type Episode = /** Star Wars Episode V: The Empire Strikes Back, released in 1980. */ - Empire = 'EMPIRE', + | 'EMPIRE' /** Star Wars Episode VI: Return of the Jedi, released in 1983. */ - Jedi = 'JEDI', + | 'JEDI' /** Star Wars Episode IV: A New Hope, released in 1977. */ - Newhope = 'NEWHOPE', -} - -/** A connection object for a character's friends */ -export type FriendsConnection = { - __typename?: 'FriendsConnection'; - /** The edges for each of the character's friends. */ - edges?: Maybe>>; - /** A list of the friends, as a convenience when edges are not needed. */ - friends?: Maybe>>; - /** Information for paginating this connection */ - pageInfo: PageInfo; - /** The total number of friends */ - totalCount?: Maybe; -}; - -/** An edge object for a character's friends */ -export type FriendsEdge = { - __typename?: 'FriendsEdge'; - /** A cursor used for pagination */ - cursor: Scalars['ID']['output']; - /** The character represented by this friendship edge */ - node?: Maybe; -}; - -/** A humanoid creature from the Star Wars universe */ -export type Human = Character & { - __typename?: 'Human'; - /** The movies this human appears in */ - appearsIn: Array>; - /** This human's friends, or an empty list if they have none */ - friends?: Maybe>>; - /** The friends of the human exposed as a connection with edges */ - friendsConnection: FriendsConnection; - /** Height in the preferred unit, default is meters */ - height?: Maybe; - /** The home planet of the human, or null if unknown */ - homePlanet?: Maybe; - /** The ID of the human */ - id: Scalars['ID']['output']; - /** Mass in kilograms, or null if unknown */ - mass?: Maybe; - /** What this human calls themselves */ - name: Scalars['String']['output']; - /** A list of starships this person has piloted, or an empty list if none */ - starships?: Maybe>>; -}; - -/** A humanoid creature from the Star Wars universe */ -export type HumanFriendsConnectionArgs = { - after?: InputMaybe; - first?: InputMaybe; -}; - -/** A humanoid creature from the Star Wars universe */ -export type HumanHeightArgs = { - unit?: InputMaybe; -}; - -/** Units of height */ -export enum LengthUnit { - /** Primarily used in the United States */ - Foot = 'FOOT', - /** The standard unit around the world */ - Meter = 'METER', -} - -/** The mutation type, represents all updates we can make to our data */ -export type Mutation = { - __typename?: 'Mutation'; - createReview?: Maybe; -}; - -/** The mutation type, represents all updates we can make to our data */ -export type MutationCreateReviewArgs = { - episode?: InputMaybe; - review: ReviewInput; -}; - -/** Information for paginating this connection */ -export type PageInfo = { - __typename?: 'PageInfo'; - endCursor?: Maybe; - hasNextPage: Scalars['Boolean']['output']; - startCursor?: Maybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type Query = { - __typename?: 'Query'; - character?: Maybe; - droid?: Maybe; - hero?: Maybe; - human?: Maybe; - reviews?: Maybe>>; - search?: Maybe>>; - starship?: Maybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryCharacterArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryDroidArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryHeroArgs = { - episode?: InputMaybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryHumanArgs = { - id: Scalars['ID']['input']; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryReviewsArgs = { - episode: Episode; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QuerySearchArgs = { - text?: InputMaybe; -}; - -/** The query type, represents all of the entry points into our object graph */ -export type QueryStarshipArgs = { - id: Scalars['ID']['input']; -}; - -/** Represents a review for a movie */ -export type Review = { - __typename?: 'Review'; - /** Comment about the movie */ - commentary?: Maybe; - /** The number of stars this review gave, 1-5 */ - stars: Scalars['Int']['output']; -}; + | 'NEWHOPE'; /** The input object sent when someone is creating a new review */ export type ReviewInput = { /** Comment about the movie, optional */ - commentary?: InputMaybe; + commentary?: string | null | undefined; /** Favorite color, optional */ - favoriteColor?: InputMaybe; + favoriteColor?: ColorInput | null | undefined; /** 0-5 stars */ - stars: Scalars['Int']['input']; -}; - -export type SearchResult = Droid | Human | Starship; - -export type Starship = { - __typename?: 'Starship'; - /** The ID of the starship */ - id: Scalars['ID']['output']; - /** Length of the starship, along the longest axis */ - length?: Maybe; - /** The name of the starship */ - name: Scalars['String']['output']; -}; - -export type StarshipLengthArgs = { - unit?: InputMaybe; + stars: number; }; export type CreateReviewForEpisodeMutationVariables = Exact<{ @@ -250,178 +36,127 @@ export type CreateReviewForEpisodeMutationVariables = Exact<{ }>; export type CreateReviewForEpisodeMutation = { - __typename?: 'Mutation'; - createReview?: { __typename?: 'Review'; stars: number; commentary?: string | null } | null; + createReview: { stars: number; commentary: string | null } | null; }; export type ExcludeQueryAlphaQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; -export type ExcludeQueryAlphaQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; -}; +export type ExcludeQueryAlphaQuery = { hero: { name: string } | { name: string } | null }; export type ExcludeQueryBetaQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; -export type ExcludeQueryBetaQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; -}; +export type ExcludeQueryBetaQuery = { hero: { name: string } | { name: string } | null }; export type HeroAndFriendsNamesQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroAndFriendsNamesQuery = { - __typename?: 'Query'; - hero?: - | { - __typename?: 'Droid'; - name: string; - friends?: Array< - { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null - > | null; - } - | { - __typename?: 'Human'; - name: string; - friends?: Array< - { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null - > | null; - } + hero: + | { name: string; friends: Array<{ name: string } | { name: string } | null> | null } + | { name: string; friends: Array<{ name: string } | { name: string } | null> | null } | null; }; export type HeroAppearsInQueryVariables = Exact<{ [key: string]: never }>; export type HeroAppearsInQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; name: string; appearsIn: Array } - | { __typename?: 'Human'; name: string; appearsIn: Array } + hero: + | { name: string; appearsIn: Array } + | { name: string; appearsIn: Array } | null; }; export type HeroDetailsQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroDetailsQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; primaryFunction?: string | null; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } + hero: + | { primaryFunction: string | null; name: string } + | { height: number | null; name: string } | null; }; -type HeroDetails_Droid_Fragment = { - __typename?: 'Droid'; - primaryFunction?: string | null; - name: string; -}; +type HeroDetails_Droid_Fragment = { primaryFunction: string | null; name: string }; -type HeroDetails_Human_Fragment = { __typename?: 'Human'; height?: number | null; name: string }; +type HeroDetails_Human_Fragment = { height: number | null; name: string }; export type HeroDetailsFragment = HeroDetails_Droid_Fragment | HeroDetails_Human_Fragment; export type HeroDetailsWithFragmentQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroDetailsWithFragmentQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; primaryFunction?: string | null; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } + hero: + | { primaryFunction: string | null; name: string } + | { height: number | null; name: string } | null; }; export type HeroNameQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; -export type HeroNameQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; -}; +export type HeroNameQuery = { hero: { name: string } | { name: string } | null }; export type HeroNameConditionalInclusionQueryVariables = Exact<{ - episode?: InputMaybe; - includeName: Scalars['Boolean']['input']; + episode?: Episode | null | undefined; + includeName: boolean; }>; export type HeroNameConditionalInclusionQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name?: string } | { __typename?: 'Human'; name?: string } | null; + hero: { name?: string } | { name?: string } | null; }; export type HeroNameConditionalExclusionQueryVariables = Exact<{ - episode?: InputMaybe; - skipName: Scalars['Boolean']['input']; + episode?: Episode | null | undefined; + skipName: boolean; }>; export type HeroNameConditionalExclusionQuery = { - __typename?: 'Query'; - hero?: { __typename?: 'Droid'; name?: string } | { __typename?: 'Human'; name?: string } | null; + hero: { name?: string } | { name?: string } | null; }; export type HeroParentTypeDependentFieldQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroParentTypeDependentFieldQuery = { - __typename?: 'Query'; - hero?: + hero: | { - __typename?: 'Droid'; name: string; - friends?: Array< - | { __typename?: 'Droid'; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } - | null - > | null; + friends: Array<{ name: string } | { height: number | null; name: string } | null> | null; } | { - __typename?: 'Human'; name: string; - friends?: Array< - | { __typename?: 'Droid'; name: string } - | { __typename?: 'Human'; height?: number | null; name: string } - | null - > | null; + friends: Array<{ name: string } | { height: number | null; name: string } | null> | null; } | null; }; export type HeroTypeDependentAliasedFieldQueryVariables = Exact<{ - episode?: InputMaybe; + episode?: Episode | null | undefined; }>; export type HeroTypeDependentAliasedFieldQuery = { - __typename?: 'Query'; - hero?: - | { __typename?: 'Droid'; property?: string | null } - | { __typename?: 'Human'; property?: string | null } - | null; + hero: { property: string | null } | { property: string | null } | null; }; -export type HumanFieldsFragment = { __typename?: 'Human'; name: string; mass?: number | null }; +export type HumanFieldsFragment = { name: string; mass: number | null }; export type HumanWithNullHeightQueryVariables = Exact<{ [key: string]: never }>; -export type HumanWithNullHeightQuery = { - __typename?: 'Query'; - human?: { __typename?: 'Human'; name: string; mass?: number | null } | null; -}; +export type HumanWithNullHeightQuery = { human: { name: string; mass: number | null } | null }; export type TwoHeroesQueryVariables = Exact<{ [key: string]: never }>; export type TwoHeroesQuery = { - __typename?: 'Query'; - r2?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; - luke?: { __typename?: 'Droid'; name: string } | { __typename?: 'Human'; name: string } | null; + r2: { name: string } | { name: string } | null; + luke: { name: string } | { name: string } | null; }; diff --git a/dev-test/subpath-import/result.d.ts b/dev-test/subpath-import/result.d.ts index eadc3a20514..57fea3fbf7e 100644 --- a/dev-test/subpath-import/result.d.ts +++ b/dev-test/subpath-import/result.d.ts @@ -5,15 +5,6 @@ import { GraphQLResolveInfo } from 'graphql'; export type Maybe = T | null; export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; -export type Incremental = - | T - | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; export type EnumResolverSignature = { [key in keyof T]?: AllowedValues }; export type RequireFields = Omit & { [P in K]-?: NonNullable }; /** All built-in and custom scalars, mapped to their actual values */ diff --git a/dev-test/test-federation/generated/types.ts b/dev-test/test-federation/generated/types.ts index e9f0817821f..bedeb91f77d 100644 --- a/dev-test/test-federation/generated/types.ts +++ b/dev-test/test-federation/generated/types.ts @@ -2,15 +2,6 @@ import { GraphQLResolveInfo, GraphQLScalarType, GraphQLScalarTypeConfig } from ' export type Maybe = T | null | undefined; export type InputMaybe = T | null | undefined; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; -export type Incremental = - | T - | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { ID: { input: string; output: string }; diff --git a/dev-test/test-null-value/result.d.ts b/dev-test/test-null-value/result.d.ts index 8b97092ed9b..fe5efedc5ff 100644 --- a/dev-test/test-null-value/result.d.ts +++ b/dev-test/test-null-value/result.d.ts @@ -1,56 +1,13 @@ -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 BaseCartLine = { - id: Scalars['String']['output']; - quantity: Scalars['Int']['output']; -}; - -export type BaseCartLineConnection = { - id: Scalars['String']['output']; - nodes: Array; -}; - -export type Cart = { - id: Scalars['String']['output']; - lines: BaseCartLineConnection; -}; - -export type CartLine = BaseCartLine & { - id: Scalars['String']['output']; - quantity: Scalars['Int']['output']; -}; - -export type ComponentizableCartLine = BaseCartLine & { - id: Scalars['String']['output']; - quantity: Scalars['Int']['output']; -}; - -export type QueryRoot = { - cart?: Maybe; -}; - export type CartLineFragment = { id: string; quantity: number }; export type TestQueryVariables = Exact<{ [key: string]: never }>; export type TestQuery = { - cart?: { lines: { nodes: Array<{ id: string; quantity: number }> } } | null; + cart: { lines: { nodes: Array<{ id: string; quantity: number }> } } | null; }; diff --git a/dev-test/test-schema/env.types.ts b/dev-test/test-schema/env.types.ts index 16b18213fcd..535aed9beef 100644 --- a/dev-test/test-schema/env.types.ts +++ b/dev-test/test-schema/env.types.ts @@ -1,14 +1,5 @@ export type Maybe = T | null; export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; -export type Incremental = - | T - | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { ID: { input: string; output: string }; diff --git a/dev-test/test-schema/flow-types.flow.js b/dev-test/test-schema/flow-types.flow.js index f8ac067469a..4b3cd55f7e0 100644 --- a/dev-test/test-schema/flow-types.flow.js +++ b/dev-test/test-schema/flow-types.flow.js @@ -1,8 +1,7 @@ // @flow import { type GraphQLResolveInfo } from 'graphql'; -export type $RequireFields = $Diff & - $ObjMapi(k: Key) => $NonMaybeType<$ElementType>>; +export type $RequireFields = $Diff & $ObjMapi(k: Key) => $NonMaybeType<$ElementType>>; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = {| ID: string, @@ -18,6 +17,7 @@ export type Query = {| userById?: ?User, |}; + export type QueryUserByIdArgs = {| id: $ElementType, |}; @@ -33,21 +33,21 @@ export type Resolver = ( parent: Parent, args: Args, context: Context, - info: GraphQLResolveInfo, + info: GraphQLResolveInfo ) => Promise | Result; export type SubscriptionSubscribeFn = ( parent: Parent, args: Args, context: Context, - info: GraphQLResolveInfo, + info: GraphQLResolveInfo ) => AsyncIterator | Promise>; export type SubscriptionResolveFn = ( parent: Parent, args: Args, context: Context, - info: GraphQLResolveInfo, + info: GraphQLResolveInfo ) => Result | Promise; export interface SubscriptionSubscriberObject { @@ -71,14 +71,10 @@ export type SubscriptionResolver = ( parent: Parent, context: Context, - info: GraphQLResolveInfo, + info: GraphQLResolveInfo ) => ?Types | Promise; -export type IsTypeOfResolverFn = ( - obj: T, - context: Context, - info: GraphQLResolveInfo, -) => boolean | Promise; +export type IsTypeOfResolverFn = (obj: T, context: Context, info: GraphQLResolveInfo) => boolean | Promise; export type NextResolverFn = () => Promise; @@ -87,7 +83,7 @@ export type DirectiveResolverFn Result | Promise; export type ResolverTypeWrapper = Promise | T; @@ -110,23 +106,12 @@ export type ResolversParentTypes = { User: User, }; -export type QueryResolvers< - ContextType = any, - ParentType = $ElementType, -> = { +export type QueryResolvers> = { allUsers?: Resolver>, ParentType, ContextType>, - userById?: Resolver< - ?$ElementType, - ParentType, - ContextType, - $RequireFields, - >, + userById?: Resolver, ParentType, ContextType, $RequireFields>, }; -export type UserResolvers< - ContextType = any, - ParentType = $ElementType, -> = { +export type UserResolvers> = { email?: Resolver<$ElementType, ParentType, ContextType>, id?: Resolver<$ElementType, ParentType, ContextType>, name?: Resolver<$ElementType, ParentType, ContextType>, @@ -137,3 +122,4 @@ export type Resolvers = { Query?: QueryResolvers, User?: UserResolvers, }; + diff --git a/dev-test/test-schema/resolvers-federation.ts b/dev-test/test-schema/resolvers-federation.ts index 7f0a0d6503f..8ef6a8ac231 100644 --- a/dev-test/test-schema/resolvers-federation.ts +++ b/dev-test/test-schema/resolvers-federation.ts @@ -2,15 +2,6 @@ import { GraphQLResolveInfo } from 'graphql'; export type Maybe = T | null; export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; -export type Incremental = - | T - | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { ID: { input: string; output: string }; @@ -18,7 +9,7 @@ export type Scalars = { Boolean: { input: boolean; output: boolean }; Int: { input: number; output: number }; Float: { input: number; output: number }; - _FieldSet: { input: any; output: any }; + _FieldSet: { input: unknown; output: unknown }; }; export type Address = { diff --git a/dev-test/test-schema/resolvers-root.ts b/dev-test/test-schema/resolvers-root.ts index 7cbcd79c1bb..a64be22359e 100644 --- a/dev-test/test-schema/resolvers-root.ts +++ b/dev-test/test-schema/resolvers-root.ts @@ -2,15 +2,6 @@ import { GraphQLResolveInfo } from 'graphql'; export type Maybe = T | null; export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; -export type Incremental = - | T - | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; export type RequireFields = Omit & { [P in K]-?: NonNullable }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { diff --git a/dev-test/test-schema/resolvers-stitching.ts b/dev-test/test-schema/resolvers-stitching.ts index 645f4f0feca..7ee5fcd8dd3 100644 --- a/dev-test/test-schema/resolvers-stitching.ts +++ b/dev-test/test-schema/resolvers-stitching.ts @@ -2,15 +2,6 @@ import { FieldNode, GraphQLResolveInfo, SelectionSetNode } from 'graphql'; export type Maybe = T | null; export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; -export type Incremental = - | T - | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; export type RequireFields = Omit & { [P in K]-?: NonNullable }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { diff --git a/dev-test/test-schema/resolvers-types.ts b/dev-test/test-schema/resolvers-types.ts index bfad048bbe9..9792914540d 100644 --- a/dev-test/test-schema/resolvers-types.ts +++ b/dev-test/test-schema/resolvers-types.ts @@ -2,15 +2,6 @@ import { GraphQLResolveInfo } from 'graphql'; export type Maybe = T | null; export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; -export type Incremental = - | T - | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; export type RequireFields = Omit & { [P in K]-?: NonNullable }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { diff --git a/dev-test/test-schema/types.preResolveTypes.onlyOperationTypes.ts b/dev-test/test-schema/types.preResolveTypes.onlyOperationTypes.ts index dff81900611..bdbf325176c 100644 --- a/dev-test/test-schema/types.preResolveTypes.onlyOperationTypes.ts +++ b/dev-test/test-schema/types.preResolveTypes.onlyOperationTypes.ts @@ -1,28 +1,13 @@ -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 TestQueryVariables = Exact<{ [key: string]: never }>; export type TestQuery = { - __typename?: 'Query'; - testArr1?: Array | null; + testArr1: Array | null; testArr2: Array; testArr3: Array; }; diff --git a/dev-test/test-schema/types.preResolveTypes.ts b/dev-test/test-schema/types.preResolveTypes.ts index 4d0ee75aa17..bdbf325176c 100644 --- a/dev-test/test-schema/types.preResolveTypes.ts +++ b/dev-test/test-schema/types.preResolveTypes.ts @@ -1,53 +1,13 @@ -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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'; - allUsers: Array>; - /** - * Generates a new answer for th - * guessing game - */ - answer: Array; - testArr1?: Maybe>>; - testArr2: Array>; - testArr3: Array; - userById?: Maybe; -}; - -export type QueryUserByIdArgs = { - id: Scalars['Int']['input']; -}; - -export type User = { - __typename?: 'User'; - email: Scalars['String']['output']; - id: Scalars['Int']['output']; - name: Scalars['String']['output']; -}; - export type TestQueryVariables = Exact<{ [key: string]: never }>; export type TestQuery = { - __typename?: 'Query'; - testArr1?: Array | null; + testArr1: Array | null; testArr2: Array; testArr3: Array; }; diff --git a/dev-test/test-schema/typings.avoidOptionals.ts b/dev-test/test-schema/typings.avoidOptionals.ts index 855268c0ff4..2387065b40d 100644 --- a/dev-test/test-schema/typings.avoidOptionals.ts +++ b/dev-test/test-schema/typings.avoidOptionals.ts @@ -1,14 +1,5 @@ export type Maybe = T | null; export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; -export type Incremental = - | T - | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { ID: { input: string; output: string }; diff --git a/dev-test/test-schema/typings.enum.ts b/dev-test/test-schema/typings.enum.ts index 7fe50ed4a55..bf4be12bece 100644 --- a/dev-test/test-schema/typings.enum.ts +++ b/dev-test/test-schema/typings.enum.ts @@ -1,14 +1,5 @@ export type Maybe = T | null; export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; -export type Incremental = - | T - | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { ID: { input: string; output: string }; diff --git a/dev-test/test-schema/typings.immutableTypes.ts b/dev-test/test-schema/typings.immutableTypes.ts index 24c3af3f281..dc7757718f3 100644 --- a/dev-test/test-schema/typings.immutableTypes.ts +++ b/dev-test/test-schema/typings.immutableTypes.ts @@ -1,14 +1,5 @@ export type Maybe = T | null; export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; -export type Incremental = - | T - | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { ID: { input: string; output: string }; diff --git a/dev-test/test-schema/typings.ts b/dev-test/test-schema/typings.ts index 0833c36242b..053a74746d7 100644 --- a/dev-test/test-schema/typings.ts +++ b/dev-test/test-schema/typings.ts @@ -2,15 +2,6 @@ import { GraphQLResolveInfo } from 'graphql'; export type Maybe = T | null; export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; -export type Incremental = - | T - | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; export type RequireFields = Omit & { [P in K]-?: NonNullable }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { diff --git a/dev-test/test-schema/typings.wrapped.ts b/dev-test/test-schema/typings.wrapped.ts index bdacb9bc37b..f9aaf485327 100644 --- a/dev-test/test-schema/typings.wrapped.ts +++ b/dev-test/test-schema/typings.wrapped.ts @@ -1,17 +1,6 @@ declare namespace GraphQL { export type Maybe = T | null; export type InputMaybe = Maybe; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { - [SubKey in K]?: Maybe; - }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { - [_ in K]?: never; - }; - export type Incremental = - | T - | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { ID: { input: string; output: string }; diff --git a/examples/persisted-documents-string-mode/package.json b/examples/persisted-documents-string-mode/package.json index e785cccd4e4..b43035937f8 100644 --- a/examples/persisted-documents-string-mode/package.json +++ b/examples/persisted-documents-string-mode/package.json @@ -16,7 +16,7 @@ "@babel/core": "7.29.0", "@babel/preset-env": "7.29.2", "@babel/preset-typescript": "7.28.5", - "@graphql-codegen/cli": "6.3.1", + "@graphql-codegen/cli": "7.0.0", "@graphql-typed-document-node/core": "3.2.0" }, "bob": false diff --git a/examples/persisted-documents-string-mode/src/gql/graphql.ts b/examples/persisted-documents-string-mode/src/gql/graphql.ts index 46fcc1d38b5..c6b1307f0cc 100644 --- a/examples/persisted-documents-string-mode/src/gql/graphql.ts +++ b/examples/persisted-documents-string-mode/src/gql/graphql.ts @@ -1,43 +1,16 @@ -/* eslint-disable */ import { DocumentTypeDecoration } from '@graphql-typed-document-node/core'; -export type Maybe = T | null; -export type InputMaybe = T | null | undefined; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/* eslint-disable */ +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 Mutation = { - __typename?: 'Mutation'; - echo: Scalars['String']['output']; -}; - -export type MutationEchoArgs = { - message: Scalars['String']['input']; -}; - -export type Query = { - __typename?: 'Query'; - hello: Scalars['String']['output']; -}; export type HelloQueryQueryVariables = Exact<{ [key: string]: never }>; -export type HelloQueryQuery = { __typename?: 'Query'; hello: string }; +export type HelloQueryQuery = { hello: string }; export class TypedDocumentString extends String @@ -64,5 +37,5 @@ export const HelloQueryDocument = new TypedDocumentString( hello } `, - { hash: '86f01e23de1c770cabbc35b2d87f2e5fd7557b6f' }, + { hash: 'sha256:4c3f5d98b02279859b4c0c4efdba9553ac7acf89b9b0785eb24be68d5a67e6e8' }, ) as unknown as TypedDocumentString; diff --git a/examples/persisted-documents-string-mode/src/gql/persisted-documents.json b/examples/persisted-documents-string-mode/src/gql/persisted-documents.json index c9ef75fe915..61c91812c4e 100644 --- a/examples/persisted-documents-string-mode/src/gql/persisted-documents.json +++ b/examples/persisted-documents-string-mode/src/gql/persisted-documents.json @@ -1,3 +1,3 @@ { - "86f01e23de1c770cabbc35b2d87f2e5fd7557b6f": "query HelloQuery { hello }" + "sha256:4c3f5d98b02279859b4c0c4efdba9553ac7acf89b9b0785eb24be68d5a67e6e8": "query HelloQuery { hello }" } diff --git a/examples/persisted-documents/package.json b/examples/persisted-documents/package.json index 386a8c39ec8..4d04c472b39 100644 --- a/examples/persisted-documents/package.json +++ b/examples/persisted-documents/package.json @@ -16,7 +16,7 @@ "@babel/core": "7.29.0", "@babel/preset-env": "7.29.2", "@babel/preset-typescript": "7.28.5", - "@graphql-codegen/cli": "6.3.1", + "@graphql-codegen/cli": "7.0.0", "@graphql-typed-document-node/core": "3.2.0" }, "bob": false diff --git a/examples/persisted-documents/src/gql/graphql.ts b/examples/persisted-documents/src/gql/graphql.ts index 542b1e50ce4..e7c3b9ffd4e 100644 --- a/examples/persisted-documents/src/gql/graphql.ts +++ b/examples/persisted-documents/src/gql/graphql.ts @@ -1,46 +1,19 @@ -/* eslint-disable */ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; -export type Maybe = T | null; -export type InputMaybe = T | null | undefined; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/* eslint-disable */ +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 Mutation = { - __typename?: 'Mutation'; - echo: Scalars['String']['output']; -}; - -export type MutationEchoArgs = { - message: Scalars['String']['input']; -}; - -export type Query = { - __typename?: 'Query'; - hello: Scalars['String']['output']; -}; export type HelloQueryQueryVariables = Exact<{ [key: string]: never }>; -export type HelloQueryQuery = { __typename?: 'Query'; hello: string }; +export type HelloQueryQuery = { hello: string }; export const HelloQueryDocument = { - __meta__: { hash: '86f01e23de1c770cabbc35b2d87f2e5fd7557b6f' }, + __meta__: { hash: 'sha256:4c3f5d98b02279859b4c0c4efdba9553ac7acf89b9b0785eb24be68d5a67e6e8' }, kind: 'Document', definitions: [ { diff --git a/examples/persisted-documents/src/gql/persisted-documents.json b/examples/persisted-documents/src/gql/persisted-documents.json index c9ef75fe915..61c91812c4e 100644 --- a/examples/persisted-documents/src/gql/persisted-documents.json +++ b/examples/persisted-documents/src/gql/persisted-documents.json @@ -1,3 +1,3 @@ { - "86f01e23de1c770cabbc35b2d87f2e5fd7557b6f": "query HelloQuery { hello }" + "sha256:4c3f5d98b02279859b4c0c4efdba9553ac7acf89b9b0785eb24be68d5a67e6e8": "query HelloQuery { hello }" } diff --git a/examples/programmatic-typescript/package.json b/examples/programmatic-typescript/package.json index 1100f08fbef..69111438f01 100644 --- a/examples/programmatic-typescript/package.json +++ b/examples/programmatic-typescript/package.json @@ -10,12 +10,12 @@ "test:end2end": "exit 0" }, "dependencies": { - "@graphql-codegen/core": "5.0.2", - "@graphql-codegen/plugin-helpers": "6.3.0", - "@graphql-codegen/typed-document-node": "6.1.8", - "@graphql-codegen/typescript": "5.0.10", - "@graphql-codegen/typescript-operations": "5.1.0", - "@graphql-codegen/typescript-resolvers": "5.1.8", + "@graphql-codegen/core": "6.0.0", + "@graphql-codegen/plugin-helpers": "7.0.0", + "@graphql-codegen/typed-document-node": "7.0.0", + "@graphql-codegen/typescript": "6.0.0", + "@graphql-codegen/typescript-operations": "6.0.0", + "@graphql-codegen/typescript-resolvers": "6.0.0", "@graphql-tools/graphql-file-loader": "^8.1.12", "@graphql-tools/load": "8.1.10", "@graphql-tools/schema": "10.0.33", diff --git a/examples/react/apollo-client-defer/codegen.ts b/examples/react/apollo-client-defer/codegen.ts index e679ef78f6e..dea41622933 100644 --- a/examples/react/apollo-client-defer/codegen.ts +++ b/examples/react/apollo-client-defer/codegen.ts @@ -6,6 +6,10 @@ const config: CodegenConfig = { generates: { './src/gql/': { preset: 'client', + config: { + skipTypeNameForRoot: true, + nonOptionalTypename: true, + }, }, }, hooks: { afterAllFileWrite: ['prettier --write'] }, diff --git a/examples/react/apollo-client-defer/package.json b/examples/react/apollo-client-defer/package.json index 7fb5179c4f8..8818c24d1ac 100644 --- a/examples/react/apollo-client-defer/package.json +++ b/examples/react/apollo-client-defer/package.json @@ -20,7 +20,7 @@ "react-dom": "^19.0.0" }, "devDependencies": { - "@graphql-codegen/cli": "^6.3.1", + "@graphql-codegen/cli": "^7.0.0", "@types/node": "^24.0.0", "@types/react": "^19.0.0", "@types/react-dom": "^19.0.0", diff --git a/examples/react/apollo-client-defer/src/gql/graphql.ts b/examples/react/apollo-client-defer/src/gql/graphql.ts index d914da266cd..fd811a03a35 100644 --- a/examples/react/apollo-client-defer/src/gql/graphql.ts +++ b/examples/react/apollo-client-defer/src/gql/graphql.ts @@ -1,55 +1,23 @@ -/* eslint-disable */ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; -export type Maybe = T | null; -export type InputMaybe = T | null | undefined; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/* eslint-disable */ +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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'; - alphabet: Array; - /** A field that resolves fast. */ - fastField: Scalars['String']['output']; - /** - * A field that resolves slowly. - * Maybe you want to @defer this field ;) - */ - slowField: Scalars['String']['output']; -}; - -export type QuerySlowFieldArgs = { - waitFor?: Scalars['Int']['input']; -}; -export type SlowFieldFragmentFragment = { __typename?: 'Query'; slowField: string } & { +export type SlowFieldFragmentFragment = { slowField: string } & { ' $fragmentName'?: 'SlowFieldFragmentFragment'; }; export type SlowAndFastFieldWithDeferQueryVariables = Exact<{ [key: string]: never }>; -export type SlowAndFastFieldWithDeferQuery = { __typename?: 'Query'; fastField: string } & ( - | { __typename?: 'Query'; inlinedSlowField: string } - | { __typename?: 'Query'; inlinedSlowField?: never } -) & - ({ __typename?: 'Query' } & { - ' $fragmentRefs'?: { SlowFieldFragmentFragment: Incremental }; - }); +export type SlowAndFastFieldWithDeferQuery = { fastField: string } & ( + | { inlinedSlowField: string } + | { inlinedSlowField?: never } +) & { ' $fragmentRefs'?: { SlowFieldFragmentFragment: Incremental } }; export const SlowFieldFragmentFragmentDoc = { kind: 'Document', diff --git a/examples/react/apollo-client-swc-plugin/package.json b/examples/react/apollo-client-swc-plugin/package.json index 7caaa19594c..5cd59dc09b9 100644 --- a/examples/react/apollo-client-swc-plugin/package.json +++ b/examples/react/apollo-client-swc-plugin/package.json @@ -15,7 +15,7 @@ "react-dom": "19.2.5" }, "devDependencies": { - "@graphql-codegen/cli": "^6.3.1", + "@graphql-codegen/cli": "^7.0.0", "@graphql-codegen/client-preset-swc-plugin": "0.2.0", "@types/react": "19.2.14", "@types/react-dom": "19.2.3", diff --git a/examples/react/apollo-client/codegen.ts b/examples/react/apollo-client/codegen.ts index f2aa8f0746b..c0bd3435ce5 100644 --- a/examples/react/apollo-client/codegen.ts +++ b/examples/react/apollo-client/codegen.ts @@ -6,6 +6,10 @@ const config: CodegenConfig = { generates: { './src/gql/': { preset: 'client', + config: { + skipTypeNameForRoot: true, + nonOptionalTypename: true, + }, }, }, hooks: { afterAllFileWrite: ['prettier --write'] }, diff --git a/examples/react/apollo-client/package.json b/examples/react/apollo-client/package.json index fef2864526d..2935eb56e65 100644 --- a/examples/react/apollo-client/package.json +++ b/examples/react/apollo-client/package.json @@ -17,7 +17,7 @@ "react-dom": "^19.0.0" }, "devDependencies": { - "@graphql-codegen/cli": "^6.3.1", + "@graphql-codegen/cli": "^7.0.0", "@types/node": "^24.0.0", "@types/react": "^19.0.0", "@types/react-dom": "^19.0.0", diff --git a/examples/react/apollo-client/src/gql/graphql.ts b/examples/react/apollo-client/src/gql/graphql.ts index 798c9d481c2..a9b41a154c3 100644 --- a/examples/react/apollo-client/src/gql/graphql.ts +++ b/examples/react/apollo-client/src/gql/graphql.ts @@ -1,1308 +1,35 @@ -/* eslint-disable */ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; -export type Maybe = T | null; -export type InputMaybe = T | null | undefined; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/* eslint-disable */ +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A single film. */ -export type Film = Node & { - __typename?: 'Film'; - characterConnection?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The name of the director of this film. */ - director?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** The episode number of this film. */ - episodeID?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The opening paragraphs at the beginning of this film. */ - openingCrawl?: Maybe; - planetConnection?: Maybe; - /** The name(s) of the producer(s) of this film. */ - producers?: Maybe>>; - /** The ISO 8601 date format of film release at original creator country. */ - releaseDate?: Maybe; - speciesConnection?: Maybe; - starshipConnection?: Maybe; - /** The title of this film. */ - title?: Maybe; - vehicleConnection?: Maybe; -}; - -/** A single film. */ -export type FilmCharacterConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmPlanetConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmSpeciesConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmStarshipConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmVehicleConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type FilmCharactersConnection = { - __typename?: 'FilmCharactersConnection'; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - characters?: Maybe>>; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmCharactersEdge = { - __typename?: 'FilmCharactersEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmPlanetsConnection = { - __typename?: 'FilmPlanetsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - planets?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmPlanetsEdge = { - __typename?: 'FilmPlanetsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmSpeciesConnection = { - __typename?: 'FilmSpeciesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - species?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmSpeciesEdge = { - __typename?: 'FilmSpeciesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmStarshipsConnection = { - __typename?: 'FilmStarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmStarshipsEdge = { - __typename?: 'FilmStarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmVehiclesConnection = { - __typename?: 'FilmVehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type FilmVehiclesEdge = { - __typename?: 'FilmVehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmsConnection = { - __typename?: 'FilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmsEdge = { - __typename?: 'FilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** An object with an ID */ -export type Node = { - /** The id of the object. */ - id: Scalars['ID']['output']; -}; - -/** Information about pagination in a connection. */ -export type PageInfo = { - __typename?: 'PageInfo'; - /** When paginating forwards, the cursor to continue. */ - endCursor?: Maybe; - /** When paginating forwards, are there more items? */ - hasNextPage: Scalars['Boolean']['output']; - /** When paginating backwards, are there more items? */ - hasPreviousPage: Scalars['Boolean']['output']; - /** When paginating backwards, the cursor to continue. */ - startCursor?: Maybe; -}; - -/** A connection to a list of items. */ -export type PeopleConnection = { - __typename?: 'PeopleConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - people?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PeopleEdge = { - __typename?: 'PeopleEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type Person = Node & { - __typename?: 'Person'; - /** - * The birth year of the person, using the in-universe standard of BBY or ABY - - * Before the Battle of Yavin or After the Battle of Yavin. The Battle of Yavin is - * a battle that occurs at the end of Star Wars episode IV: A New Hope. - */ - birthYear?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** - * The eye color of this person. Will be "unknown" if not known or "n/a" if the - * person does not have an eye. - */ - eyeColor?: Maybe; - filmConnection?: Maybe; - /** - * The gender of this person. Either "Male", "Female" or "unknown", - * "n/a" if the person does not have a gender. - */ - gender?: Maybe; - /** - * The hair color of this person. Will be "unknown" if not known or "n/a" if the - * person does not have hair. - */ - hairColor?: Maybe; - /** The height of the person in centimeters. */ - height?: Maybe; - /** A planet that this person was born on or inhabits. */ - homeworld?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The mass of the person in kilograms. */ - mass?: Maybe; - /** The name of this person. */ - name?: Maybe; - /** The skin color of this person. */ - skinColor?: Maybe; - /** The species that this person belongs to, or null if unknown. */ - species?: Maybe; - starshipConnection?: Maybe; - vehicleConnection?: Maybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonStarshipConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonVehicleConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type PersonFilmsConnection = { - __typename?: 'PersonFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PersonFilmsEdge = { - __typename?: 'PersonFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PersonStarshipsConnection = { - __typename?: 'PersonStarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PersonStarshipsEdge = { - __typename?: 'PersonStarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PersonVehiclesConnection = { - __typename?: 'PersonVehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type PersonVehiclesEdge = { - __typename?: 'PersonVehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type Planet = Node & { - __typename?: 'Planet'; - /** The climates of this planet. */ - climates?: Maybe>>; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The diameter of this planet in kilometers. */ - diameter?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** - * A number denoting the gravity of this planet, where "1" is normal or 1 standard - * G. "2" is twice or 2 standard Gs. "0.5" is half or 0.5 standard Gs. - */ - gravity?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The name of this planet. */ - name?: Maybe; - /** - * The number of standard days it takes for this planet to complete a single orbit - * of its local star. - */ - orbitalPeriod?: Maybe; - /** The average population of sentient beings inhabiting this planet. */ - population?: Maybe; - residentConnection?: Maybe; - /** - * The number of standard hours it takes for this planet to complete a single - * rotation on its axis. - */ - rotationPeriod?: Maybe; - /** - * The percentage of the planet surface that is naturally occurring water or bodies - * of water. - */ - surfaceWater?: Maybe; - /** The terrains of this planet. */ - terrains?: Maybe>>; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type PlanetFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type PlanetResidentConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type PlanetFilmsConnection = { - __typename?: 'PlanetFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetFilmsEdge = { - __typename?: 'PlanetFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PlanetResidentsConnection = { - __typename?: 'PlanetResidentsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - residents?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetResidentsEdge = { - __typename?: 'PlanetResidentsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PlanetsConnection = { - __typename?: 'PlanetsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - planets?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetsEdge = { - __typename?: 'PlanetsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -export type Root = { - __typename?: 'Root'; - allFilms?: Maybe; - allPeople?: Maybe; - allPlanets?: Maybe; - allSpecies?: Maybe; - allStarships?: Maybe; - allVehicles?: Maybe; - film?: Maybe; - /** Fetches an object given its ID */ - node?: Maybe; - person?: Maybe; - planet?: Maybe; - species?: Maybe; - starship?: Maybe; - vehicle?: Maybe; -}; - -export type RootAllFilmsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllPeopleArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllPlanetsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllSpeciesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllStarshipsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllVehiclesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootFilmArgs = { - filmID?: InputMaybe; - id?: InputMaybe; -}; - -export type RootNodeArgs = { - id: Scalars['ID']['input']; -}; - -export type RootPersonArgs = { - id?: InputMaybe; - personID?: InputMaybe; -}; - -export type RootPlanetArgs = { - id?: InputMaybe; - planetID?: InputMaybe; -}; - -export type RootSpeciesArgs = { - id?: InputMaybe; - speciesID?: InputMaybe; -}; - -export type RootStarshipArgs = { - id?: InputMaybe; - starshipID?: InputMaybe; -}; - -export type RootVehicleArgs = { - id?: InputMaybe; - vehicleID?: InputMaybe; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type Species = Node & { - __typename?: 'Species'; - /** The average height of this species in centimeters. */ - averageHeight?: Maybe; - /** The average lifespan of this species in years, null if unknown. */ - averageLifespan?: Maybe; - /** The classification of this species, such as "mammal" or "reptile". */ - classification?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The designation of this species, such as "sentient". */ - designation?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** - * Common eye colors for this species, null if this species does not typically - * have eyes. - */ - eyeColors?: Maybe>>; - filmConnection?: Maybe; - /** - * Common hair colors for this species, null if this species does not typically - * have hair. - */ - hairColors?: Maybe>>; - /** A planet that this species originates from. */ - homeworld?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The language commonly spoken by this species. */ - language?: Maybe; - /** The name of this species. */ - name?: Maybe; - personConnection?: Maybe; - /** - * Common skin colors for this species, null if this species does not typically - * have skin. - */ - skinColors?: Maybe>>; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type SpeciesFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type SpeciesPersonConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type SpeciesConnection = { - __typename?: 'SpeciesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - species?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesEdge = { - __typename?: 'SpeciesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type SpeciesFilmsConnection = { - __typename?: 'SpeciesFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesFilmsEdge = { - __typename?: 'SpeciesFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type SpeciesPeopleConnection = { - __typename?: 'SpeciesPeopleConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - people?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesPeopleEdge = { - __typename?: 'SpeciesPeopleEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type Starship = Node & { - __typename?: 'Starship'; - /** - * The Maximum number of Megalights this starship can travel in a standard hour. - * A "Megalight" is a standard unit of distance and has never been defined before - * within the Star Wars universe. This figure is only really useful for measuring - * the difference in speed of starships. We can assume it is similar to AU, the - * distance between our Sun (Sol) and Earth. - */ - MGLT?: Maybe; - /** The maximum number of kilograms that this starship can transport. */ - cargoCapacity?: Maybe; - /** - * The maximum length of time that this starship can provide consumables for its - * entire crew without having to resupply. - */ - consumables?: Maybe; - /** The cost of this starship new, in galactic credits. */ - costInCredits?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The number of personnel needed to run or pilot this starship. */ - crew?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** The class of this starships hyperdrive. */ - hyperdriveRating?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The length of this starship in meters. */ - length?: Maybe; - /** The manufacturers of this starship. */ - manufacturers?: Maybe>>; - /** - * The maximum speed of this starship in atmosphere. null if this starship is - * incapable of atmosphering flight. - */ - maxAtmospheringSpeed?: Maybe; - /** - * The model or official name of this starship. Such as "T-65 X-wing" or "DS-1 - * Orbital Battle Station". - */ - model?: Maybe; - /** The name of this starship. The common name, such as "Death Star". */ - name?: Maybe; - /** The number of non-essential people this starship can transport. */ - passengers?: Maybe; - pilotConnection?: Maybe; - /** - * The class of this starship, such as "Starfighter" or "Deep Space Mobile - * Battlestation" - */ - starshipClass?: Maybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type StarshipFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type StarshipPilotConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type StarshipFilmsConnection = { - __typename?: 'StarshipFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipFilmsEdge = { - __typename?: 'StarshipFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type StarshipPilotsConnection = { - __typename?: 'StarshipPilotsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - pilots?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipPilotsEdge = { - __typename?: 'StarshipPilotsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type StarshipsConnection = { - __typename?: 'StarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipsEdge = { - __typename?: 'StarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type Vehicle = Node & { - __typename?: 'Vehicle'; - /** The maximum number of kilograms that this vehicle can transport. */ - cargoCapacity?: Maybe; - /** - * The maximum length of time that this vehicle can provide consumables for its - * entire crew without having to resupply. - */ - consumables?: Maybe; - /** The cost of this vehicle new, in Galactic Credits. */ - costInCredits?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The number of personnel needed to run or pilot this vehicle. */ - crew?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The length of this vehicle in meters. */ - length?: Maybe; - /** The manufacturers of this vehicle. */ - manufacturers?: Maybe>>; - /** The maximum speed of this vehicle in atmosphere. */ - maxAtmospheringSpeed?: Maybe; - /** - * The model or official name of this vehicle. Such as "All-Terrain Attack - * Transport". - */ - model?: Maybe; - /** - * The name of this vehicle. The common name, such as "Sand Crawler" or "Speeder - * bike". - */ - name?: Maybe; - /** The number of non-essential people this vehicle can transport. */ - passengers?: Maybe; - pilotConnection?: Maybe; - /** The class of this vehicle, such as "Wheeled" or "Repulsorcraft". */ - vehicleClass?: Maybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type VehicleFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type VehiclePilotConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type VehicleFilmsConnection = { - __typename?: 'VehicleFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type VehicleFilmsEdge = { - __typename?: 'VehicleFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type VehiclePilotsConnection = { - __typename?: 'VehiclePilotsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - pilots?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type VehiclePilotsEdge = { - __typename?: 'VehiclePilotsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type VehiclesConnection = { - __typename?: 'VehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type VehiclesEdge = { - __typename?: 'VehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; export type AllFilmsWithVariablesQueryQueryVariables = Exact<{ - first: Scalars['Int']['input']; + first: number; }>; export type AllFilmsWithVariablesQueryQuery = { - __typename?: 'Root'; - allFilms?: { - __typename?: 'FilmsConnection'; - edges?: Array<{ - __typename?: 'FilmsEdge'; - node?: - | ({ __typename?: 'Film' } & { ' $fragmentRefs'?: { FilmItemFragment: FilmItemFragment } }) + allFilms: { + __typename: 'FilmsConnection'; + edges: Array<{ + __typename: 'FilmsEdge'; + node: + | ({ __typename: 'Film' } & { ' $fragmentRefs'?: { FilmItemFragment: FilmItemFragment } }) | null; } | null> | null; } | null; }; export type FilmItemFragment = { - __typename?: 'Film'; + __typename: 'Film'; id: string; - title?: string | null; - releaseDate?: string | null; - producers?: Array | null; + title: string | null; + releaseDate: string | null; + producers: Array | null; } & { ' $fragmentName'?: 'FilmItemFragment' }; export const FilmItemFragmentDoc = { diff --git a/examples/react/http-executor/package.json b/examples/react/http-executor/package.json index f3451e7a0a2..a9b04685f84 100644 --- a/examples/react/http-executor/package.json +++ b/examples/react/http-executor/package.json @@ -16,7 +16,7 @@ "react-dom": "^19.0.0" }, "devDependencies": { - "@graphql-codegen/cli": "^6.3.1", + "@graphql-codegen/cli": "^7.0.0", "@types/node": "^24.0.0", "@types/react": "^19.0.0", "@types/react-dom": "^19.0.0", diff --git a/examples/react/http-executor/src/gql/graphql.ts b/examples/react/http-executor/src/gql/graphql.ts index 798c9d481c2..41ca140746c 100644 --- a/examples/react/http-executor/src/gql/graphql.ts +++ b/examples/react/http-executor/src/gql/graphql.ts @@ -1,1308 +1,30 @@ -/* eslint-disable */ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; -export type Maybe = T | null; -export type InputMaybe = T | null | undefined; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/* eslint-disable */ +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A single film. */ -export type Film = Node & { - __typename?: 'Film'; - characterConnection?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The name of the director of this film. */ - director?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** The episode number of this film. */ - episodeID?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The opening paragraphs at the beginning of this film. */ - openingCrawl?: Maybe; - planetConnection?: Maybe; - /** The name(s) of the producer(s) of this film. */ - producers?: Maybe>>; - /** The ISO 8601 date format of film release at original creator country. */ - releaseDate?: Maybe; - speciesConnection?: Maybe; - starshipConnection?: Maybe; - /** The title of this film. */ - title?: Maybe; - vehicleConnection?: Maybe; -}; - -/** A single film. */ -export type FilmCharacterConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmPlanetConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmSpeciesConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmStarshipConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmVehicleConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type FilmCharactersConnection = { - __typename?: 'FilmCharactersConnection'; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - characters?: Maybe>>; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmCharactersEdge = { - __typename?: 'FilmCharactersEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmPlanetsConnection = { - __typename?: 'FilmPlanetsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - planets?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmPlanetsEdge = { - __typename?: 'FilmPlanetsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmSpeciesConnection = { - __typename?: 'FilmSpeciesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - species?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmSpeciesEdge = { - __typename?: 'FilmSpeciesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmStarshipsConnection = { - __typename?: 'FilmStarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmStarshipsEdge = { - __typename?: 'FilmStarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmVehiclesConnection = { - __typename?: 'FilmVehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type FilmVehiclesEdge = { - __typename?: 'FilmVehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmsConnection = { - __typename?: 'FilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmsEdge = { - __typename?: 'FilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** An object with an ID */ -export type Node = { - /** The id of the object. */ - id: Scalars['ID']['output']; -}; - -/** Information about pagination in a connection. */ -export type PageInfo = { - __typename?: 'PageInfo'; - /** When paginating forwards, the cursor to continue. */ - endCursor?: Maybe; - /** When paginating forwards, are there more items? */ - hasNextPage: Scalars['Boolean']['output']; - /** When paginating backwards, are there more items? */ - hasPreviousPage: Scalars['Boolean']['output']; - /** When paginating backwards, the cursor to continue. */ - startCursor?: Maybe; -}; - -/** A connection to a list of items. */ -export type PeopleConnection = { - __typename?: 'PeopleConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - people?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PeopleEdge = { - __typename?: 'PeopleEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type Person = Node & { - __typename?: 'Person'; - /** - * The birth year of the person, using the in-universe standard of BBY or ABY - - * Before the Battle of Yavin or After the Battle of Yavin. The Battle of Yavin is - * a battle that occurs at the end of Star Wars episode IV: A New Hope. - */ - birthYear?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** - * The eye color of this person. Will be "unknown" if not known or "n/a" if the - * person does not have an eye. - */ - eyeColor?: Maybe; - filmConnection?: Maybe; - /** - * The gender of this person. Either "Male", "Female" or "unknown", - * "n/a" if the person does not have a gender. - */ - gender?: Maybe; - /** - * The hair color of this person. Will be "unknown" if not known or "n/a" if the - * person does not have hair. - */ - hairColor?: Maybe; - /** The height of the person in centimeters. */ - height?: Maybe; - /** A planet that this person was born on or inhabits. */ - homeworld?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The mass of the person in kilograms. */ - mass?: Maybe; - /** The name of this person. */ - name?: Maybe; - /** The skin color of this person. */ - skinColor?: Maybe; - /** The species that this person belongs to, or null if unknown. */ - species?: Maybe; - starshipConnection?: Maybe; - vehicleConnection?: Maybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonStarshipConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonVehicleConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type PersonFilmsConnection = { - __typename?: 'PersonFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PersonFilmsEdge = { - __typename?: 'PersonFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PersonStarshipsConnection = { - __typename?: 'PersonStarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PersonStarshipsEdge = { - __typename?: 'PersonStarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PersonVehiclesConnection = { - __typename?: 'PersonVehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type PersonVehiclesEdge = { - __typename?: 'PersonVehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type Planet = Node & { - __typename?: 'Planet'; - /** The climates of this planet. */ - climates?: Maybe>>; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The diameter of this planet in kilometers. */ - diameter?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** - * A number denoting the gravity of this planet, where "1" is normal or 1 standard - * G. "2" is twice or 2 standard Gs. "0.5" is half or 0.5 standard Gs. - */ - gravity?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The name of this planet. */ - name?: Maybe; - /** - * The number of standard days it takes for this planet to complete a single orbit - * of its local star. - */ - orbitalPeriod?: Maybe; - /** The average population of sentient beings inhabiting this planet. */ - population?: Maybe; - residentConnection?: Maybe; - /** - * The number of standard hours it takes for this planet to complete a single - * rotation on its axis. - */ - rotationPeriod?: Maybe; - /** - * The percentage of the planet surface that is naturally occurring water or bodies - * of water. - */ - surfaceWater?: Maybe; - /** The terrains of this planet. */ - terrains?: Maybe>>; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type PlanetFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type PlanetResidentConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type PlanetFilmsConnection = { - __typename?: 'PlanetFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetFilmsEdge = { - __typename?: 'PlanetFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PlanetResidentsConnection = { - __typename?: 'PlanetResidentsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - residents?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetResidentsEdge = { - __typename?: 'PlanetResidentsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PlanetsConnection = { - __typename?: 'PlanetsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - planets?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetsEdge = { - __typename?: 'PlanetsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -export type Root = { - __typename?: 'Root'; - allFilms?: Maybe; - allPeople?: Maybe; - allPlanets?: Maybe; - allSpecies?: Maybe; - allStarships?: Maybe; - allVehicles?: Maybe; - film?: Maybe; - /** Fetches an object given its ID */ - node?: Maybe; - person?: Maybe; - planet?: Maybe; - species?: Maybe; - starship?: Maybe; - vehicle?: Maybe; -}; - -export type RootAllFilmsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllPeopleArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllPlanetsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllSpeciesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllStarshipsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllVehiclesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootFilmArgs = { - filmID?: InputMaybe; - id?: InputMaybe; -}; - -export type RootNodeArgs = { - id: Scalars['ID']['input']; -}; - -export type RootPersonArgs = { - id?: InputMaybe; - personID?: InputMaybe; -}; - -export type RootPlanetArgs = { - id?: InputMaybe; - planetID?: InputMaybe; -}; - -export type RootSpeciesArgs = { - id?: InputMaybe; - speciesID?: InputMaybe; -}; - -export type RootStarshipArgs = { - id?: InputMaybe; - starshipID?: InputMaybe; -}; - -export type RootVehicleArgs = { - id?: InputMaybe; - vehicleID?: InputMaybe; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type Species = Node & { - __typename?: 'Species'; - /** The average height of this species in centimeters. */ - averageHeight?: Maybe; - /** The average lifespan of this species in years, null if unknown. */ - averageLifespan?: Maybe; - /** The classification of this species, such as "mammal" or "reptile". */ - classification?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The designation of this species, such as "sentient". */ - designation?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** - * Common eye colors for this species, null if this species does not typically - * have eyes. - */ - eyeColors?: Maybe>>; - filmConnection?: Maybe; - /** - * Common hair colors for this species, null if this species does not typically - * have hair. - */ - hairColors?: Maybe>>; - /** A planet that this species originates from. */ - homeworld?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The language commonly spoken by this species. */ - language?: Maybe; - /** The name of this species. */ - name?: Maybe; - personConnection?: Maybe; - /** - * Common skin colors for this species, null if this species does not typically - * have skin. - */ - skinColors?: Maybe>>; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type SpeciesFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type SpeciesPersonConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type SpeciesConnection = { - __typename?: 'SpeciesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - species?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesEdge = { - __typename?: 'SpeciesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type SpeciesFilmsConnection = { - __typename?: 'SpeciesFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesFilmsEdge = { - __typename?: 'SpeciesFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type SpeciesPeopleConnection = { - __typename?: 'SpeciesPeopleConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - people?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesPeopleEdge = { - __typename?: 'SpeciesPeopleEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type Starship = Node & { - __typename?: 'Starship'; - /** - * The Maximum number of Megalights this starship can travel in a standard hour. - * A "Megalight" is a standard unit of distance and has never been defined before - * within the Star Wars universe. This figure is only really useful for measuring - * the difference in speed of starships. We can assume it is similar to AU, the - * distance between our Sun (Sol) and Earth. - */ - MGLT?: Maybe; - /** The maximum number of kilograms that this starship can transport. */ - cargoCapacity?: Maybe; - /** - * The maximum length of time that this starship can provide consumables for its - * entire crew without having to resupply. - */ - consumables?: Maybe; - /** The cost of this starship new, in galactic credits. */ - costInCredits?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The number of personnel needed to run or pilot this starship. */ - crew?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** The class of this starships hyperdrive. */ - hyperdriveRating?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The length of this starship in meters. */ - length?: Maybe; - /** The manufacturers of this starship. */ - manufacturers?: Maybe>>; - /** - * The maximum speed of this starship in atmosphere. null if this starship is - * incapable of atmosphering flight. - */ - maxAtmospheringSpeed?: Maybe; - /** - * The model or official name of this starship. Such as "T-65 X-wing" or "DS-1 - * Orbital Battle Station". - */ - model?: Maybe; - /** The name of this starship. The common name, such as "Death Star". */ - name?: Maybe; - /** The number of non-essential people this starship can transport. */ - passengers?: Maybe; - pilotConnection?: Maybe; - /** - * The class of this starship, such as "Starfighter" or "Deep Space Mobile - * Battlestation" - */ - starshipClass?: Maybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type StarshipFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type StarshipPilotConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type StarshipFilmsConnection = { - __typename?: 'StarshipFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipFilmsEdge = { - __typename?: 'StarshipFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type StarshipPilotsConnection = { - __typename?: 'StarshipPilotsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - pilots?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipPilotsEdge = { - __typename?: 'StarshipPilotsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type StarshipsConnection = { - __typename?: 'StarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipsEdge = { - __typename?: 'StarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type Vehicle = Node & { - __typename?: 'Vehicle'; - /** The maximum number of kilograms that this vehicle can transport. */ - cargoCapacity?: Maybe; - /** - * The maximum length of time that this vehicle can provide consumables for its - * entire crew without having to resupply. - */ - consumables?: Maybe; - /** The cost of this vehicle new, in Galactic Credits. */ - costInCredits?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The number of personnel needed to run or pilot this vehicle. */ - crew?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The length of this vehicle in meters. */ - length?: Maybe; - /** The manufacturers of this vehicle. */ - manufacturers?: Maybe>>; - /** The maximum speed of this vehicle in atmosphere. */ - maxAtmospheringSpeed?: Maybe; - /** - * The model or official name of this vehicle. Such as "All-Terrain Attack - * Transport". - */ - model?: Maybe; - /** - * The name of this vehicle. The common name, such as "Sand Crawler" or "Speeder - * bike". - */ - name?: Maybe; - /** The number of non-essential people this vehicle can transport. */ - passengers?: Maybe; - pilotConnection?: Maybe; - /** The class of this vehicle, such as "Wheeled" or "Repulsorcraft". */ - vehicleClass?: Maybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type VehicleFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type VehiclePilotConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type VehicleFilmsConnection = { - __typename?: 'VehicleFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type VehicleFilmsEdge = { - __typename?: 'VehicleFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type VehiclePilotsConnection = { - __typename?: 'VehiclePilotsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - pilots?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type VehiclePilotsEdge = { - __typename?: 'VehiclePilotsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type VehiclesConnection = { - __typename?: 'VehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type VehiclesEdge = { - __typename?: 'VehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; export type AllFilmsWithVariablesQueryQueryVariables = Exact<{ - first: Scalars['Int']['input']; + first: number; }>; export type AllFilmsWithVariablesQueryQuery = { - __typename?: 'Root'; - allFilms?: { - __typename?: 'FilmsConnection'; - edges?: Array<{ - __typename?: 'FilmsEdge'; - node?: - | ({ __typename?: 'Film' } & { ' $fragmentRefs'?: { FilmItemFragment: FilmItemFragment } }) - | null; + allFilms: { + edges: Array<{ + node: { ' $fragmentRefs'?: { FilmItemFragment: FilmItemFragment } } | null; } | null> | null; } | null; }; export type FilmItemFragment = { - __typename?: 'Film'; id: string; - title?: string | null; - releaseDate?: string | null; - producers?: Array | null; + title: string | null; + releaseDate: string | null; + producers: Array | null; } & { ' $fragmentName'?: 'FilmItemFragment' }; export const FilmItemFragmentDoc = { diff --git a/examples/react/nextjs-swr/package.json b/examples/react/nextjs-swr/package.json index ec100b732c4..4db9d638c32 100644 --- a/examples/react/nextjs-swr/package.json +++ b/examples/react/nextjs-swr/package.json @@ -19,9 +19,9 @@ "swr": "^2.0.0" }, "devDependencies": { - "@graphql-codegen/cli": "^6.3.1", + "@graphql-codegen/cli": "^7.0.0", "@graphql-codegen/client-preset-swc-plugin": "0.2.0", - "@graphql-codegen/schema-ast": "5.0.2", + "@graphql-codegen/schema-ast": "6.0.0", "@types/node": "^24.0.0", "@types/react": "^19.0.0", "@types/react-dom": "^19.0.0", diff --git a/examples/react/tanstack-react-query/package.json b/examples/react/tanstack-react-query/package.json index 169dc6c81f9..e90b0c516bc 100644 --- a/examples/react/tanstack-react-query/package.json +++ b/examples/react/tanstack-react-query/package.json @@ -16,7 +16,7 @@ "react-dom": "^19.0.0" }, "devDependencies": { - "@graphql-codegen/cli": "^6.3.1", + "@graphql-codegen/cli": "^7.0.0", "@types/node": "^24.0.0", "@types/react": "^19.0.0", "@types/react-dom": "^19.0.0", diff --git a/examples/react/tanstack-react-query/src/gql/graphql.ts b/examples/react/tanstack-react-query/src/gql/graphql.ts index 09de7d3df15..d51ee811183 100644 --- a/examples/react/tanstack-react-query/src/gql/graphql.ts +++ b/examples/react/tanstack-react-query/src/gql/graphql.ts @@ -1,1308 +1,30 @@ -/* eslint-disable */ import { DocumentTypeDecoration } from '@graphql-typed-document-node/core'; -export type Maybe = T | null; -export type InputMaybe = T | null | undefined; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/* eslint-disable */ +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A single film. */ -export type Film = Node & { - __typename?: 'Film'; - characterConnection?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The name of the director of this film. */ - director?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** The episode number of this film. */ - episodeID?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The opening paragraphs at the beginning of this film. */ - openingCrawl?: Maybe; - planetConnection?: Maybe; - /** The name(s) of the producer(s) of this film. */ - producers?: Maybe>>; - /** The ISO 8601 date format of film release at original creator country. */ - releaseDate?: Maybe; - speciesConnection?: Maybe; - starshipConnection?: Maybe; - /** The title of this film. */ - title?: Maybe; - vehicleConnection?: Maybe; -}; - -/** A single film. */ -export type FilmCharacterConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmPlanetConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmSpeciesConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmStarshipConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmVehicleConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type FilmCharactersConnection = { - __typename?: 'FilmCharactersConnection'; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - characters?: Maybe>>; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmCharactersEdge = { - __typename?: 'FilmCharactersEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmPlanetsConnection = { - __typename?: 'FilmPlanetsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - planets?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmPlanetsEdge = { - __typename?: 'FilmPlanetsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmSpeciesConnection = { - __typename?: 'FilmSpeciesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - species?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmSpeciesEdge = { - __typename?: 'FilmSpeciesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmStarshipsConnection = { - __typename?: 'FilmStarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmStarshipsEdge = { - __typename?: 'FilmStarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmVehiclesConnection = { - __typename?: 'FilmVehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type FilmVehiclesEdge = { - __typename?: 'FilmVehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmsConnection = { - __typename?: 'FilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmsEdge = { - __typename?: 'FilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** An object with an ID */ -export type Node = { - /** The id of the object. */ - id: Scalars['ID']['output']; -}; - -/** Information about pagination in a connection. */ -export type PageInfo = { - __typename?: 'PageInfo'; - /** When paginating forwards, the cursor to continue. */ - endCursor?: Maybe; - /** When paginating forwards, are there more items? */ - hasNextPage: Scalars['Boolean']['output']; - /** When paginating backwards, are there more items? */ - hasPreviousPage: Scalars['Boolean']['output']; - /** When paginating backwards, the cursor to continue. */ - startCursor?: Maybe; -}; - -/** A connection to a list of items. */ -export type PeopleConnection = { - __typename?: 'PeopleConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - people?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PeopleEdge = { - __typename?: 'PeopleEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type Person = Node & { - __typename?: 'Person'; - /** - * The birth year of the person, using the in-universe standard of BBY or ABY - - * Before the Battle of Yavin or After the Battle of Yavin. The Battle of Yavin is - * a battle that occurs at the end of Star Wars episode IV: A New Hope. - */ - birthYear?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** - * The eye color of this person. Will be "unknown" if not known or "n/a" if the - * person does not have an eye. - */ - eyeColor?: Maybe; - filmConnection?: Maybe; - /** - * The gender of this person. Either "Male", "Female" or "unknown", - * "n/a" if the person does not have a gender. - */ - gender?: Maybe; - /** - * The hair color of this person. Will be "unknown" if not known or "n/a" if the - * person does not have hair. - */ - hairColor?: Maybe; - /** The height of the person in centimeters. */ - height?: Maybe; - /** A planet that this person was born on or inhabits. */ - homeworld?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The mass of the person in kilograms. */ - mass?: Maybe; - /** The name of this person. */ - name?: Maybe; - /** The skin color of this person. */ - skinColor?: Maybe; - /** The species that this person belongs to, or null if unknown. */ - species?: Maybe; - starshipConnection?: Maybe; - vehicleConnection?: Maybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonStarshipConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonVehicleConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type PersonFilmsConnection = { - __typename?: 'PersonFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PersonFilmsEdge = { - __typename?: 'PersonFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PersonStarshipsConnection = { - __typename?: 'PersonStarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PersonStarshipsEdge = { - __typename?: 'PersonStarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PersonVehiclesConnection = { - __typename?: 'PersonVehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type PersonVehiclesEdge = { - __typename?: 'PersonVehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type Planet = Node & { - __typename?: 'Planet'; - /** The climates of this planet. */ - climates?: Maybe>>; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The diameter of this planet in kilometers. */ - diameter?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** - * A number denoting the gravity of this planet, where "1" is normal or 1 standard - * G. "2" is twice or 2 standard Gs. "0.5" is half or 0.5 standard Gs. - */ - gravity?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The name of this planet. */ - name?: Maybe; - /** - * The number of standard days it takes for this planet to complete a single orbit - * of its local star. - */ - orbitalPeriod?: Maybe; - /** The average population of sentient beings inhabiting this planet. */ - population?: Maybe; - residentConnection?: Maybe; - /** - * The number of standard hours it takes for this planet to complete a single - * rotation on its axis. - */ - rotationPeriod?: Maybe; - /** - * The percentage of the planet surface that is naturally occurring water or bodies - * of water. - */ - surfaceWater?: Maybe; - /** The terrains of this planet. */ - terrains?: Maybe>>; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type PlanetFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type PlanetResidentConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type PlanetFilmsConnection = { - __typename?: 'PlanetFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetFilmsEdge = { - __typename?: 'PlanetFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PlanetResidentsConnection = { - __typename?: 'PlanetResidentsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - residents?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetResidentsEdge = { - __typename?: 'PlanetResidentsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PlanetsConnection = { - __typename?: 'PlanetsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - planets?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetsEdge = { - __typename?: 'PlanetsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -export type Root = { - __typename?: 'Root'; - allFilms?: Maybe; - allPeople?: Maybe; - allPlanets?: Maybe; - allSpecies?: Maybe; - allStarships?: Maybe; - allVehicles?: Maybe; - film?: Maybe; - /** Fetches an object given its ID */ - node?: Maybe; - person?: Maybe; - planet?: Maybe; - species?: Maybe; - starship?: Maybe; - vehicle?: Maybe; -}; - -export type RootAllFilmsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllPeopleArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllPlanetsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllSpeciesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllStarshipsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllVehiclesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootFilmArgs = { - filmID?: InputMaybe; - id?: InputMaybe; -}; - -export type RootNodeArgs = { - id: Scalars['ID']['input']; -}; - -export type RootPersonArgs = { - id?: InputMaybe; - personID?: InputMaybe; -}; - -export type RootPlanetArgs = { - id?: InputMaybe; - planetID?: InputMaybe; -}; - -export type RootSpeciesArgs = { - id?: InputMaybe; - speciesID?: InputMaybe; -}; - -export type RootStarshipArgs = { - id?: InputMaybe; - starshipID?: InputMaybe; -}; - -export type RootVehicleArgs = { - id?: InputMaybe; - vehicleID?: InputMaybe; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type Species = Node & { - __typename?: 'Species'; - /** The average height of this species in centimeters. */ - averageHeight?: Maybe; - /** The average lifespan of this species in years, null if unknown. */ - averageLifespan?: Maybe; - /** The classification of this species, such as "mammal" or "reptile". */ - classification?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The designation of this species, such as "sentient". */ - designation?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** - * Common eye colors for this species, null if this species does not typically - * have eyes. - */ - eyeColors?: Maybe>>; - filmConnection?: Maybe; - /** - * Common hair colors for this species, null if this species does not typically - * have hair. - */ - hairColors?: Maybe>>; - /** A planet that this species originates from. */ - homeworld?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The language commonly spoken by this species. */ - language?: Maybe; - /** The name of this species. */ - name?: Maybe; - personConnection?: Maybe; - /** - * Common skin colors for this species, null if this species does not typically - * have skin. - */ - skinColors?: Maybe>>; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type SpeciesFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type SpeciesPersonConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type SpeciesConnection = { - __typename?: 'SpeciesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - species?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesEdge = { - __typename?: 'SpeciesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type SpeciesFilmsConnection = { - __typename?: 'SpeciesFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesFilmsEdge = { - __typename?: 'SpeciesFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type SpeciesPeopleConnection = { - __typename?: 'SpeciesPeopleConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - people?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesPeopleEdge = { - __typename?: 'SpeciesPeopleEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type Starship = Node & { - __typename?: 'Starship'; - /** - * The Maximum number of Megalights this starship can travel in a standard hour. - * A "Megalight" is a standard unit of distance and has never been defined before - * within the Star Wars universe. This figure is only really useful for measuring - * the difference in speed of starships. We can assume it is similar to AU, the - * distance between our Sun (Sol) and Earth. - */ - MGLT?: Maybe; - /** The maximum number of kilograms that this starship can transport. */ - cargoCapacity?: Maybe; - /** - * The maximum length of time that this starship can provide consumables for its - * entire crew without having to resupply. - */ - consumables?: Maybe; - /** The cost of this starship new, in galactic credits. */ - costInCredits?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The number of personnel needed to run or pilot this starship. */ - crew?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** The class of this starships hyperdrive. */ - hyperdriveRating?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The length of this starship in meters. */ - length?: Maybe; - /** The manufacturers of this starship. */ - manufacturers?: Maybe>>; - /** - * The maximum speed of this starship in atmosphere. null if this starship is - * incapable of atmosphering flight. - */ - maxAtmospheringSpeed?: Maybe; - /** - * The model or official name of this starship. Such as "T-65 X-wing" or "DS-1 - * Orbital Battle Station". - */ - model?: Maybe; - /** The name of this starship. The common name, such as "Death Star". */ - name?: Maybe; - /** The number of non-essential people this starship can transport. */ - passengers?: Maybe; - pilotConnection?: Maybe; - /** - * The class of this starship, such as "Starfighter" or "Deep Space Mobile - * Battlestation" - */ - starshipClass?: Maybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type StarshipFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type StarshipPilotConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type StarshipFilmsConnection = { - __typename?: 'StarshipFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipFilmsEdge = { - __typename?: 'StarshipFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type StarshipPilotsConnection = { - __typename?: 'StarshipPilotsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - pilots?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipPilotsEdge = { - __typename?: 'StarshipPilotsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type StarshipsConnection = { - __typename?: 'StarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipsEdge = { - __typename?: 'StarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type Vehicle = Node & { - __typename?: 'Vehicle'; - /** The maximum number of kilograms that this vehicle can transport. */ - cargoCapacity?: Maybe; - /** - * The maximum length of time that this vehicle can provide consumables for its - * entire crew without having to resupply. - */ - consumables?: Maybe; - /** The cost of this vehicle new, in Galactic Credits. */ - costInCredits?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The number of personnel needed to run or pilot this vehicle. */ - crew?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The length of this vehicle in meters. */ - length?: Maybe; - /** The manufacturers of this vehicle. */ - manufacturers?: Maybe>>; - /** The maximum speed of this vehicle in atmosphere. */ - maxAtmospheringSpeed?: Maybe; - /** - * The model or official name of this vehicle. Such as "All-Terrain Attack - * Transport". - */ - model?: Maybe; - /** - * The name of this vehicle. The common name, such as "Sand Crawler" or "Speeder - * bike". - */ - name?: Maybe; - /** The number of non-essential people this vehicle can transport. */ - passengers?: Maybe; - pilotConnection?: Maybe; - /** The class of this vehicle, such as "Wheeled" or "Repulsorcraft". */ - vehicleClass?: Maybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type VehicleFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type VehiclePilotConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type VehicleFilmsConnection = { - __typename?: 'VehicleFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type VehicleFilmsEdge = { - __typename?: 'VehicleFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type VehiclePilotsConnection = { - __typename?: 'VehiclePilotsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - pilots?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type VehiclePilotsEdge = { - __typename?: 'VehiclePilotsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type VehiclesConnection = { - __typename?: 'VehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type VehiclesEdge = { - __typename?: 'VehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; export type AllFilmsWithVariablesQueryQueryVariables = Exact<{ - first: Scalars['Int']['input']; + first: number; }>; export type AllFilmsWithVariablesQueryQuery = { - __typename?: 'Root'; - allFilms?: { - __typename?: 'FilmsConnection'; - edges?: Array<{ - __typename?: 'FilmsEdge'; - node?: - | ({ __typename?: 'Film' } & { ' $fragmentRefs'?: { FilmItemFragment: FilmItemFragment } }) - | null; + allFilms: { + edges: Array<{ + node: { ' $fragmentRefs'?: { FilmItemFragment: FilmItemFragment } } | null; } | null> | null; } | null; }; export type FilmItemFragment = { - __typename?: 'Film'; id: string; - title?: string | null; - releaseDate?: string | null; - producers?: Array | null; + title: string | null; + releaseDate: string | null; + producers: Array | null; } & { ' $fragmentName'?: 'FilmItemFragment' }; export class TypedDocumentString diff --git a/examples/react/urql/package.json b/examples/react/urql/package.json index 0590d08c7a9..13fb1aaaae1 100644 --- a/examples/react/urql/package.json +++ b/examples/react/urql/package.json @@ -16,7 +16,7 @@ "urql": "^3.0.0" }, "devDependencies": { - "@graphql-codegen/cli": "^6.3.1", + "@graphql-codegen/cli": "^7.0.0", "@types/react": "^19.0.0", "@types/react-dom": "^19.0.0", "@vitejs/plugin-react": "^6.0.0", diff --git a/examples/react/urql/src/gql/graphql.ts b/examples/react/urql/src/gql/graphql.ts index b47ef43d310..a37bc092fd7 100644 --- a/examples/react/urql/src/gql/graphql.ts +++ b/examples/react/urql/src/gql/graphql.ts @@ -1,1308 +1,30 @@ -/* eslint-disable */ import { DocumentTypeDecoration } from '@graphql-typed-document-node/core'; -export type Maybe = T | null; -export type InputMaybe = T | null | undefined; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/* eslint-disable */ +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A single film. */ -export type Film = Node & { - __typename?: 'Film'; - characterConnection?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The name of the director of this film. */ - director?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** The episode number of this film. */ - episodeID?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The opening paragraphs at the beginning of this film. */ - openingCrawl?: Maybe; - planetConnection?: Maybe; - /** The name(s) of the producer(s) of this film. */ - producers?: Maybe>>; - /** The ISO 8601 date format of film release at original creator country. */ - releaseDate?: Maybe; - speciesConnection?: Maybe; - starshipConnection?: Maybe; - /** The title of this film. */ - title?: Maybe; - vehicleConnection?: Maybe; -}; - -/** A single film. */ -export type FilmCharacterConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmPlanetConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmSpeciesConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmStarshipConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmVehicleConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type FilmCharactersConnection = { - __typename?: 'FilmCharactersConnection'; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - characters?: Maybe>>; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmCharactersEdge = { - __typename?: 'FilmCharactersEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmPlanetsConnection = { - __typename?: 'FilmPlanetsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - planets?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmPlanetsEdge = { - __typename?: 'FilmPlanetsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmSpeciesConnection = { - __typename?: 'FilmSpeciesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - species?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmSpeciesEdge = { - __typename?: 'FilmSpeciesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmStarshipsConnection = { - __typename?: 'FilmStarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmStarshipsEdge = { - __typename?: 'FilmStarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmVehiclesConnection = { - __typename?: 'FilmVehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type FilmVehiclesEdge = { - __typename?: 'FilmVehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmsConnection = { - __typename?: 'FilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmsEdge = { - __typename?: 'FilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** An object with an ID */ -export type Node = { - /** The id of the object. */ - id: Scalars['ID']['output']; -}; - -/** Information about pagination in a connection. */ -export type PageInfo = { - __typename?: 'PageInfo'; - /** When paginating forwards, the cursor to continue. */ - endCursor?: Maybe; - /** When paginating forwards, are there more items? */ - hasNextPage: Scalars['Boolean']['output']; - /** When paginating backwards, are there more items? */ - hasPreviousPage: Scalars['Boolean']['output']; - /** When paginating backwards, the cursor to continue. */ - startCursor?: Maybe; -}; - -/** A connection to a list of items. */ -export type PeopleConnection = { - __typename?: 'PeopleConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - people?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PeopleEdge = { - __typename?: 'PeopleEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type Person = Node & { - __typename?: 'Person'; - /** - * The birth year of the person, using the in-universe standard of BBY or ABY - - * Before the Battle of Yavin or After the Battle of Yavin. The Battle of Yavin is - * a battle that occurs at the end of Star Wars episode IV: A New Hope. - */ - birthYear?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** - * The eye color of this person. Will be "unknown" if not known or "n/a" if the - * person does not have an eye. - */ - eyeColor?: Maybe; - filmConnection?: Maybe; - /** - * The gender of this person. Either "Male", "Female" or "unknown", - * "n/a" if the person does not have a gender. - */ - gender?: Maybe; - /** - * The hair color of this person. Will be "unknown" if not known or "n/a" if the - * person does not have hair. - */ - hairColor?: Maybe; - /** The height of the person in centimeters. */ - height?: Maybe; - /** A planet that this person was born on or inhabits. */ - homeworld?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The mass of the person in kilograms. */ - mass?: Maybe; - /** The name of this person. */ - name?: Maybe; - /** The skin color of this person. */ - skinColor?: Maybe; - /** The species that this person belongs to, or null if unknown. */ - species?: Maybe; - starshipConnection?: Maybe; - vehicleConnection?: Maybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonStarshipConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonVehicleConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type PersonFilmsConnection = { - __typename?: 'PersonFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PersonFilmsEdge = { - __typename?: 'PersonFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PersonStarshipsConnection = { - __typename?: 'PersonStarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PersonStarshipsEdge = { - __typename?: 'PersonStarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PersonVehiclesConnection = { - __typename?: 'PersonVehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type PersonVehiclesEdge = { - __typename?: 'PersonVehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type Planet = Node & { - __typename?: 'Planet'; - /** The climates of this planet. */ - climates?: Maybe>>; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The diameter of this planet in kilometers. */ - diameter?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** - * A number denoting the gravity of this planet, where "1" is normal or 1 standard - * G. "2" is twice or 2 standard Gs. "0.5" is half or 0.5 standard Gs. - */ - gravity?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The name of this planet. */ - name?: Maybe; - /** - * The number of standard days it takes for this planet to complete a single orbit - * of its local star. - */ - orbitalPeriod?: Maybe; - /** The average population of sentient beings inhabiting this planet. */ - population?: Maybe; - residentConnection?: Maybe; - /** - * The number of standard hours it takes for this planet to complete a single - * rotation on its axis. - */ - rotationPeriod?: Maybe; - /** - * The percentage of the planet surface that is naturally occurring water or bodies - * of water. - */ - surfaceWater?: Maybe; - /** The terrains of this planet. */ - terrains?: Maybe>>; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type PlanetFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type PlanetResidentConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type PlanetFilmsConnection = { - __typename?: 'PlanetFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetFilmsEdge = { - __typename?: 'PlanetFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PlanetResidentsConnection = { - __typename?: 'PlanetResidentsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - residents?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetResidentsEdge = { - __typename?: 'PlanetResidentsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PlanetsConnection = { - __typename?: 'PlanetsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - planets?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetsEdge = { - __typename?: 'PlanetsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -export type Root = { - __typename?: 'Root'; - allFilms?: Maybe; - allPeople?: Maybe; - allPlanets?: Maybe; - allSpecies?: Maybe; - allStarships?: Maybe; - allVehicles?: Maybe; - film?: Maybe; - /** Fetches an object given its ID */ - node?: Maybe; - person?: Maybe; - planet?: Maybe; - species?: Maybe; - starship?: Maybe; - vehicle?: Maybe; -}; - -export type RootAllFilmsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllPeopleArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllPlanetsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllSpeciesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllStarshipsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllVehiclesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootFilmArgs = { - filmID?: InputMaybe; - id?: InputMaybe; -}; - -export type RootNodeArgs = { - id: Scalars['ID']['input']; -}; - -export type RootPersonArgs = { - id?: InputMaybe; - personID?: InputMaybe; -}; - -export type RootPlanetArgs = { - id?: InputMaybe; - planetID?: InputMaybe; -}; - -export type RootSpeciesArgs = { - id?: InputMaybe; - speciesID?: InputMaybe; -}; - -export type RootStarshipArgs = { - id?: InputMaybe; - starshipID?: InputMaybe; -}; - -export type RootVehicleArgs = { - id?: InputMaybe; - vehicleID?: InputMaybe; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type Species = Node & { - __typename?: 'Species'; - /** The average height of this species in centimeters. */ - averageHeight?: Maybe; - /** The average lifespan of this species in years, null if unknown. */ - averageLifespan?: Maybe; - /** The classification of this species, such as "mammal" or "reptile". */ - classification?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The designation of this species, such as "sentient". */ - designation?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** - * Common eye colors for this species, null if this species does not typically - * have eyes. - */ - eyeColors?: Maybe>>; - filmConnection?: Maybe; - /** - * Common hair colors for this species, null if this species does not typically - * have hair. - */ - hairColors?: Maybe>>; - /** A planet that this species originates from. */ - homeworld?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The language commonly spoken by this species. */ - language?: Maybe; - /** The name of this species. */ - name?: Maybe; - personConnection?: Maybe; - /** - * Common skin colors for this species, null if this species does not typically - * have skin. - */ - skinColors?: Maybe>>; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type SpeciesFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type SpeciesPersonConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type SpeciesConnection = { - __typename?: 'SpeciesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - species?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesEdge = { - __typename?: 'SpeciesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type SpeciesFilmsConnection = { - __typename?: 'SpeciesFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesFilmsEdge = { - __typename?: 'SpeciesFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type SpeciesPeopleConnection = { - __typename?: 'SpeciesPeopleConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - people?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesPeopleEdge = { - __typename?: 'SpeciesPeopleEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type Starship = Node & { - __typename?: 'Starship'; - /** - * The Maximum number of Megalights this starship can travel in a standard hour. - * A "Megalight" is a standard unit of distance and has never been defined before - * within the Star Wars universe. This figure is only really useful for measuring - * the difference in speed of starships. We can assume it is similar to AU, the - * distance between our Sun (Sol) and Earth. - */ - MGLT?: Maybe; - /** The maximum number of kilograms that this starship can transport. */ - cargoCapacity?: Maybe; - /** - * The maximum length of time that this starship can provide consumables for its - * entire crew without having to resupply. - */ - consumables?: Maybe; - /** The cost of this starship new, in galactic credits. */ - costInCredits?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The number of personnel needed to run or pilot this starship. */ - crew?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** The class of this starships hyperdrive. */ - hyperdriveRating?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The length of this starship in meters. */ - length?: Maybe; - /** The manufacturers of this starship. */ - manufacturers?: Maybe>>; - /** - * The maximum speed of this starship in atmosphere. null if this starship is - * incapable of atmosphering flight. - */ - maxAtmospheringSpeed?: Maybe; - /** - * The model or official name of this starship. Such as "T-65 X-wing" or "DS-1 - * Orbital Battle Station". - */ - model?: Maybe; - /** The name of this starship. The common name, such as "Death Star". */ - name?: Maybe; - /** The number of non-essential people this starship can transport. */ - passengers?: Maybe; - pilotConnection?: Maybe; - /** - * The class of this starship, such as "Starfighter" or "Deep Space Mobile - * Battlestation" - */ - starshipClass?: Maybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type StarshipFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type StarshipPilotConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type StarshipFilmsConnection = { - __typename?: 'StarshipFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipFilmsEdge = { - __typename?: 'StarshipFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type StarshipPilotsConnection = { - __typename?: 'StarshipPilotsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - pilots?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipPilotsEdge = { - __typename?: 'StarshipPilotsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type StarshipsConnection = { - __typename?: 'StarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipsEdge = { - __typename?: 'StarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type Vehicle = Node & { - __typename?: 'Vehicle'; - /** The maximum number of kilograms that this vehicle can transport. */ - cargoCapacity?: Maybe; - /** - * The maximum length of time that this vehicle can provide consumables for its - * entire crew without having to resupply. - */ - consumables?: Maybe; - /** The cost of this vehicle new, in Galactic Credits. */ - costInCredits?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The number of personnel needed to run or pilot this vehicle. */ - crew?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The length of this vehicle in meters. */ - length?: Maybe; - /** The manufacturers of this vehicle. */ - manufacturers?: Maybe>>; - /** The maximum speed of this vehicle in atmosphere. */ - maxAtmospheringSpeed?: Maybe; - /** - * The model or official name of this vehicle. Such as "All-Terrain Attack - * Transport". - */ - model?: Maybe; - /** - * The name of this vehicle. The common name, such as "Sand Crawler" or "Speeder - * bike". - */ - name?: Maybe; - /** The number of non-essential people this vehicle can transport. */ - passengers?: Maybe; - pilotConnection?: Maybe; - /** The class of this vehicle, such as "Wheeled" or "Repulsorcraft". */ - vehicleClass?: Maybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type VehicleFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type VehiclePilotConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type VehicleFilmsConnection = { - __typename?: 'VehicleFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type VehicleFilmsEdge = { - __typename?: 'VehicleFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type VehiclePilotsConnection = { - __typename?: 'VehiclePilotsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - pilots?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type VehiclePilotsEdge = { - __typename?: 'VehiclePilotsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type VehiclesConnection = { - __typename?: 'VehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type VehiclesEdge = { - __typename?: 'VehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; export type AllFilmsWithVariablesQuery199QueryVariables = Exact<{ - first: Scalars['Int']['input']; + first: number; }>; export type AllFilmsWithVariablesQuery199Query = { - __typename?: 'Root'; - allFilms?: { - __typename?: 'FilmsConnection'; - edges?: Array<{ - __typename?: 'FilmsEdge'; - node?: - | ({ __typename?: 'Film' } & { ' $fragmentRefs'?: { FilmItemFragment: FilmItemFragment } }) - | null; + allFilms: { + edges: Array<{ + node: { ' $fragmentRefs'?: { FilmItemFragment: FilmItemFragment } } | null; } | null> | null; } | null; }; export type FilmItemFragment = { - __typename?: 'Film'; id: string; - title?: string | null; - releaseDate?: string | null; - producers?: Array | null; + title: string | null; + releaseDate: string | null; + producers: Array | null; } & { ' $fragmentName'?: 'FilmItemFragment' }; export class TypedDocumentString diff --git a/examples/typescript-esm/package.json b/examples/typescript-esm/package.json index c268728b3fb..bb26dd3f4f6 100644 --- a/examples/typescript-esm/package.json +++ b/examples/typescript-esm/package.json @@ -14,7 +14,7 @@ "graphql": "16.13.2" }, "devDependencies": { - "@graphql-codegen/cli": "6.3.1" + "@graphql-codegen/cli": "7.0.0" }, "bob": false } diff --git a/examples/typescript-esm/src/gql/graphql.ts b/examples/typescript-esm/src/gql/graphql.ts index ba6773932bd..4b3afeee756 100644 --- a/examples/typescript-esm/src/gql/graphql.ts +++ b/examples/typescript-esm/src/gql/graphql.ts @@ -1,1317 +1,31 @@ -/* eslint-disable */ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; -export type Maybe = T | null; -export type InputMaybe = T | null | undefined; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/* eslint-disable */ +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A single film. */ -export type Film = Node & { - __typename?: 'Film'; - characterConnection?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The name of the director of this film. */ - director?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** The episode number of this film. */ - episodeID?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The opening paragraphs at the beginning of this film. */ - openingCrawl?: Maybe; - planetConnection?: Maybe; - /** The name(s) of the producer(s) of this film. */ - producers?: Maybe>>; - /** The ISO 8601 date format of film release at original creator country. */ - releaseDate?: Maybe; - speciesConnection?: Maybe; - starshipConnection?: Maybe; - /** The title of this film. */ - title?: Maybe; - vehicleConnection?: Maybe; -}; - -/** A single film. */ -export type FilmCharacterConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmPlanetConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmSpeciesConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmStarshipConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmVehicleConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type FilmCharactersConnection = { - __typename?: 'FilmCharactersConnection'; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - characters?: Maybe>>; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmCharactersEdge = { - __typename?: 'FilmCharactersEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmPlanetsConnection = { - __typename?: 'FilmPlanetsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - planets?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmPlanetsEdge = { - __typename?: 'FilmPlanetsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmSpeciesConnection = { - __typename?: 'FilmSpeciesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - species?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmSpeciesEdge = { - __typename?: 'FilmSpeciesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmStarshipsConnection = { - __typename?: 'FilmStarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmStarshipsEdge = { - __typename?: 'FilmStarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmVehiclesConnection = { - __typename?: 'FilmVehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type FilmVehiclesEdge = { - __typename?: 'FilmVehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmsConnection = { - __typename?: 'FilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmsEdge = { - __typename?: 'FilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** An object with an ID */ -export type Node = { - /** The id of the object. */ - id: Scalars['ID']['output']; -}; - -/** Information about pagination in a connection. */ -export type PageInfo = { - __typename?: 'PageInfo'; - /** When paginating forwards, the cursor to continue. */ - endCursor?: Maybe; - /** When paginating forwards, are there more items? */ - hasNextPage: Scalars['Boolean']['output']; - /** When paginating backwards, are there more items? */ - hasPreviousPage: Scalars['Boolean']['output']; - /** When paginating backwards, the cursor to continue. */ - startCursor?: Maybe; -}; - -/** A connection to a list of items. */ -export type PeopleConnection = { - __typename?: 'PeopleConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - people?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PeopleEdge = { - __typename?: 'PeopleEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type Person = Node & { - __typename?: 'Person'; - /** - * The birth year of the person, using the in-universe standard of BBY or ABY - - * Before the Battle of Yavin or After the Battle of Yavin. The Battle of Yavin is - * a battle that occurs at the end of Star Wars episode IV: A New Hope. - */ - birthYear?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** - * The eye color of this person. Will be "unknown" if not known or "n/a" if the - * person does not have an eye. - */ - eyeColor?: Maybe; - filmConnection?: Maybe; - /** - * The gender of this person. Either "Male", "Female" or "unknown", - * "n/a" if the person does not have a gender. - */ - gender?: Maybe; - /** - * The hair color of this person. Will be "unknown" if not known or "n/a" if the - * person does not have hair. - */ - hairColor?: Maybe; - /** The height of the person in centimeters. */ - height?: Maybe; - /** A planet that this person was born on or inhabits. */ - homeworld?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The mass of the person in kilograms. */ - mass?: Maybe; - /** The name of this person. */ - name?: Maybe; - /** The skin color of this person. */ - skinColor?: Maybe; - /** The species that this person belongs to, or null if unknown. */ - species?: Maybe; - starshipConnection?: Maybe; - vehicleConnection?: Maybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonStarshipConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonVehicleConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type PersonFilmsConnection = { - __typename?: 'PersonFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PersonFilmsEdge = { - __typename?: 'PersonFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PersonStarshipsConnection = { - __typename?: 'PersonStarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PersonStarshipsEdge = { - __typename?: 'PersonStarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PersonVehiclesConnection = { - __typename?: 'PersonVehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type PersonVehiclesEdge = { - __typename?: 'PersonVehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type Planet = Node & { - __typename?: 'Planet'; - /** The climates of this planet. */ - climates?: Maybe>>; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The diameter of this planet in kilometers. */ - diameter?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** - * A number denoting the gravity of this planet, where "1" is normal or 1 standard - * G. "2" is twice or 2 standard Gs. "0.5" is half or 0.5 standard Gs. - */ - gravity?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The name of this planet. */ - name?: Maybe; - /** - * The number of standard days it takes for this planet to complete a single orbit - * of its local star. - */ - orbitalPeriod?: Maybe; - /** The average population of sentient beings inhabiting this planet. */ - population?: Maybe; - residentConnection?: Maybe; - /** - * The number of standard hours it takes for this planet to complete a single - * rotation on its axis. - */ - rotationPeriod?: Maybe; - /** - * The percentage of the planet surface that is naturally occurring water or bodies - * of water. - */ - surfaceWater?: Maybe; - /** The terrains of this planet. */ - terrains?: Maybe>>; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type PlanetFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type PlanetResidentConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type PlanetFilmsConnection = { - __typename?: 'PlanetFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetFilmsEdge = { - __typename?: 'PlanetFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PlanetResidentsConnection = { - __typename?: 'PlanetResidentsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - residents?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetResidentsEdge = { - __typename?: 'PlanetResidentsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PlanetsConnection = { - __typename?: 'PlanetsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - planets?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetsEdge = { - __typename?: 'PlanetsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -export type Root = { - __typename?: 'Root'; - allFilms?: Maybe; - allPeople?: Maybe; - allPlanets?: Maybe; - allSpecies?: Maybe; - allStarships?: Maybe; - allVehicles?: Maybe; - film?: Maybe; - /** Fetches an object given its ID */ - node?: Maybe; - person?: Maybe; - planet?: Maybe; - species?: Maybe; - starship?: Maybe; - vehicle?: Maybe; -}; - -export type RootAllFilmsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllPeopleArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllPlanetsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllSpeciesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllStarshipsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllVehiclesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootFilmArgs = { - filmID?: InputMaybe; - id?: InputMaybe; -}; - -export type RootNodeArgs = { - id: Scalars['ID']['input']; -}; - -export type RootPersonArgs = { - id?: InputMaybe; - personID?: InputMaybe; -}; - -export type RootPlanetArgs = { - id?: InputMaybe; - planetID?: InputMaybe; -}; - -export type RootSpeciesArgs = { - id?: InputMaybe; - speciesID?: InputMaybe; -}; - -export type RootStarshipArgs = { - id?: InputMaybe; - starshipID?: InputMaybe; -}; - -export type RootVehicleArgs = { - id?: InputMaybe; - vehicleID?: InputMaybe; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type Species = Node & { - __typename?: 'Species'; - /** The average height of this species in centimeters. */ - averageHeight?: Maybe; - /** The average lifespan of this species in years, null if unknown. */ - averageLifespan?: Maybe; - /** The classification of this species, such as "mammal" or "reptile". */ - classification?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The designation of this species, such as "sentient". */ - designation?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** - * Common eye colors for this species, null if this species does not typically - * have eyes. - */ - eyeColors?: Maybe>>; - filmConnection?: Maybe; - /** - * Common hair colors for this species, null if this species does not typically - * have hair. - */ - hairColors?: Maybe>>; - /** A planet that this species originates from. */ - homeworld?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The language commonly spoken by this species. */ - language?: Maybe; - /** The name of this species. */ - name?: Maybe; - personConnection?: Maybe; - /** - * Common skin colors for this species, null if this species does not typically - * have skin. - */ - skinColors?: Maybe>>; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type SpeciesFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type SpeciesPersonConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type SpeciesConnection = { - __typename?: 'SpeciesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - species?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesEdge = { - __typename?: 'SpeciesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type SpeciesFilmsConnection = { - __typename?: 'SpeciesFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesFilmsEdge = { - __typename?: 'SpeciesFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type SpeciesPeopleConnection = { - __typename?: 'SpeciesPeopleConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - people?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesPeopleEdge = { - __typename?: 'SpeciesPeopleEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type Starship = Node & { - __typename?: 'Starship'; - /** - * The Maximum number of Megalights this starship can travel in a standard hour. - * A "Megalight" is a standard unit of distance and has never been defined before - * within the Star Wars universe. This figure is only really useful for measuring - * the difference in speed of starships. We can assume it is similar to AU, the - * distance between our Sun (Sol) and Earth. - */ - MGLT?: Maybe; - /** The maximum number of kilograms that this starship can transport. */ - cargoCapacity?: Maybe; - /** - * The maximum length of time that this starship can provide consumables for its - * entire crew without having to resupply. - */ - consumables?: Maybe; - /** The cost of this starship new, in galactic credits. */ - costInCredits?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The number of personnel needed to run or pilot this starship. */ - crew?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** The class of this starships hyperdrive. */ - hyperdriveRating?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The length of this starship in meters. */ - length?: Maybe; - /** The manufacturers of this starship. */ - manufacturers?: Maybe>>; - /** - * The maximum speed of this starship in atmosphere. null if this starship is - * incapable of atmosphering flight. - */ - maxAtmospheringSpeed?: Maybe; - /** - * The model or official name of this starship. Such as "T-65 X-wing" or "DS-1 - * Orbital Battle Station". - */ - model?: Maybe; - /** The name of this starship. The common name, such as "Death Star". */ - name?: Maybe; - /** The number of non-essential people this starship can transport. */ - passengers?: Maybe; - pilotConnection?: Maybe; - /** - * The class of this starship, such as "Starfighter" or "Deep Space Mobile - * Battlestation" - */ - starshipClass?: Maybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type StarshipFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type StarshipPilotConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type StarshipFilmsConnection = { - __typename?: 'StarshipFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipFilmsEdge = { - __typename?: 'StarshipFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type StarshipPilotsConnection = { - __typename?: 'StarshipPilotsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - pilots?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipPilotsEdge = { - __typename?: 'StarshipPilotsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type StarshipsConnection = { - __typename?: 'StarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipsEdge = { - __typename?: 'StarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type Vehicle = Node & { - __typename?: 'Vehicle'; - /** The maximum number of kilograms that this vehicle can transport. */ - cargoCapacity?: Maybe; - /** - * The maximum length of time that this vehicle can provide consumables for its - * entire crew without having to resupply. - */ - consumables?: Maybe; - /** The cost of this vehicle new, in Galactic Credits. */ - costInCredits?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The number of personnel needed to run or pilot this vehicle. */ - crew?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The length of this vehicle in meters. */ - length?: Maybe; - /** The manufacturers of this vehicle. */ - manufacturers?: Maybe>>; - /** The maximum speed of this vehicle in atmosphere. */ - maxAtmospheringSpeed?: Maybe; - /** - * The model or official name of this vehicle. Such as "All-Terrain Attack - * Transport". - */ - model?: Maybe; - /** - * The name of this vehicle. The common name, such as "Sand Crawler" or "Speeder - * bike". - */ - name?: Maybe; - /** The number of non-essential people this vehicle can transport. */ - passengers?: Maybe; - pilotConnection?: Maybe; - /** The class of this vehicle, such as "Wheeled" or "Repulsorcraft". */ - vehicleClass?: Maybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type VehicleFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type VehiclePilotConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type VehicleFilmsConnection = { - __typename?: 'VehicleFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type VehicleFilmsEdge = { - __typename?: 'VehicleFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type VehiclePilotsConnection = { - __typename?: 'VehiclePilotsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - pilots?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type VehiclePilotsEdge = { - __typename?: 'VehiclePilotsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type VehiclesConnection = { - __typename?: 'VehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type VehiclesEdge = { - __typename?: 'VehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; export type AllPeopleQueryQueryVariables = Exact<{ [key: string]: never }>; export type AllPeopleQueryQuery = { - __typename?: 'Root'; - allPeople?: { - __typename?: 'PeopleConnection'; - edges?: Array<{ - __typename?: 'PeopleEdge'; - node?: { - __typename?: 'Person'; - name?: string | null; - homeworld?: { __typename?: 'Planet'; name?: string | null } | null; - } | null; + allPeople: { + edges: Array<{ + node: { name: string | null; homeworld: { name: string | null } | null } | null; } | null> | null; } | null; }; export type AllPeopleWithVariablesQueryQueryVariables = Exact<{ - first: Scalars['Int']['input']; + first: number; }>; export type AllPeopleWithVariablesQueryQuery = { - __typename?: 'Root'; - allPeople?: { - __typename?: 'PeopleConnection'; - edges?: Array<{ - __typename?: 'PeopleEdge'; - node?: { - __typename?: 'Person'; - name?: string | null; - homeworld?: { __typename?: 'Planet'; name?: string | null } | null; - } | null; + allPeople: { + edges: Array<{ + node: { name: string | null; homeworld: { name: string | null } | null } | null; } | null> | null; } | null; }; diff --git a/examples/typescript-graphql-request/package.json b/examples/typescript-graphql-request/package.json index a5addf4704b..98e7dc956de 100644 --- a/examples/typescript-graphql-request/package.json +++ b/examples/typescript-graphql-request/package.json @@ -15,7 +15,7 @@ "graphql-yoga": "5.21.0" }, "devDependencies": { - "@graphql-codegen/cli": "6.3.1" + "@graphql-codegen/cli": "7.0.0" }, "bob": false } diff --git a/examples/typescript-graphql-request/src/gql/graphql.ts b/examples/typescript-graphql-request/src/gql/graphql.ts index ead1c8a5561..9aa9bc5e476 100644 --- a/examples/typescript-graphql-request/src/gql/graphql.ts +++ b/examples/typescript-graphql-request/src/gql/graphql.ts @@ -1,1317 +1,31 @@ -/* eslint-disable */ import { DocumentTypeDecoration } from '@graphql-typed-document-node/core'; -export type Maybe = T | null; -export type InputMaybe = T | null | undefined; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/* eslint-disable */ +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A single film. */ -export type Film = Node & { - __typename?: 'Film'; - characterConnection?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The name of the director of this film. */ - director?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** The episode number of this film. */ - episodeID?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The opening paragraphs at the beginning of this film. */ - openingCrawl?: Maybe; - planetConnection?: Maybe; - /** The name(s) of the producer(s) of this film. */ - producers?: Maybe>>; - /** The ISO 8601 date format of film release at original creator country. */ - releaseDate?: Maybe; - speciesConnection?: Maybe; - starshipConnection?: Maybe; - /** The title of this film. */ - title?: Maybe; - vehicleConnection?: Maybe; -}; - -/** A single film. */ -export type FilmCharacterConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmPlanetConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmSpeciesConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmStarshipConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmVehicleConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type FilmCharactersConnection = { - __typename?: 'FilmCharactersConnection'; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - characters?: Maybe>>; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmCharactersEdge = { - __typename?: 'FilmCharactersEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmPlanetsConnection = { - __typename?: 'FilmPlanetsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - planets?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmPlanetsEdge = { - __typename?: 'FilmPlanetsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmSpeciesConnection = { - __typename?: 'FilmSpeciesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - species?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmSpeciesEdge = { - __typename?: 'FilmSpeciesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmStarshipsConnection = { - __typename?: 'FilmStarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmStarshipsEdge = { - __typename?: 'FilmStarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmVehiclesConnection = { - __typename?: 'FilmVehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type FilmVehiclesEdge = { - __typename?: 'FilmVehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmsConnection = { - __typename?: 'FilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmsEdge = { - __typename?: 'FilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** An object with an ID */ -export type Node = { - /** The id of the object. */ - id: Scalars['ID']['output']; -}; - -/** Information about pagination in a connection. */ -export type PageInfo = { - __typename?: 'PageInfo'; - /** When paginating forwards, the cursor to continue. */ - endCursor?: Maybe; - /** When paginating forwards, are there more items? */ - hasNextPage: Scalars['Boolean']['output']; - /** When paginating backwards, are there more items? */ - hasPreviousPage: Scalars['Boolean']['output']; - /** When paginating backwards, the cursor to continue. */ - startCursor?: Maybe; -}; - -/** A connection to a list of items. */ -export type PeopleConnection = { - __typename?: 'PeopleConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - people?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PeopleEdge = { - __typename?: 'PeopleEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type Person = Node & { - __typename?: 'Person'; - /** - * The birth year of the person, using the in-universe standard of BBY or ABY - - * Before the Battle of Yavin or After the Battle of Yavin. The Battle of Yavin is - * a battle that occurs at the end of Star Wars episode IV: A New Hope. - */ - birthYear?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** - * The eye color of this person. Will be "unknown" if not known or "n/a" if the - * person does not have an eye. - */ - eyeColor?: Maybe; - filmConnection?: Maybe; - /** - * The gender of this person. Either "Male", "Female" or "unknown", - * "n/a" if the person does not have a gender. - */ - gender?: Maybe; - /** - * The hair color of this person. Will be "unknown" if not known or "n/a" if the - * person does not have hair. - */ - hairColor?: Maybe; - /** The height of the person in centimeters. */ - height?: Maybe; - /** A planet that this person was born on or inhabits. */ - homeworld?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The mass of the person in kilograms. */ - mass?: Maybe; - /** The name of this person. */ - name?: Maybe; - /** The skin color of this person. */ - skinColor?: Maybe; - /** The species that this person belongs to, or null if unknown. */ - species?: Maybe; - starshipConnection?: Maybe; - vehicleConnection?: Maybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonStarshipConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonVehicleConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type PersonFilmsConnection = { - __typename?: 'PersonFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PersonFilmsEdge = { - __typename?: 'PersonFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PersonStarshipsConnection = { - __typename?: 'PersonStarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PersonStarshipsEdge = { - __typename?: 'PersonStarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PersonVehiclesConnection = { - __typename?: 'PersonVehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type PersonVehiclesEdge = { - __typename?: 'PersonVehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type Planet = Node & { - __typename?: 'Planet'; - /** The climates of this planet. */ - climates?: Maybe>>; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The diameter of this planet in kilometers. */ - diameter?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** - * A number denoting the gravity of this planet, where "1" is normal or 1 standard - * G. "2" is twice or 2 standard Gs. "0.5" is half or 0.5 standard Gs. - */ - gravity?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The name of this planet. */ - name?: Maybe; - /** - * The number of standard days it takes for this planet to complete a single orbit - * of its local star. - */ - orbitalPeriod?: Maybe; - /** The average population of sentient beings inhabiting this planet. */ - population?: Maybe; - residentConnection?: Maybe; - /** - * The number of standard hours it takes for this planet to complete a single - * rotation on its axis. - */ - rotationPeriod?: Maybe; - /** - * The percentage of the planet surface that is naturally occurring water or bodies - * of water. - */ - surfaceWater?: Maybe; - /** The terrains of this planet. */ - terrains?: Maybe>>; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type PlanetFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type PlanetResidentConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type PlanetFilmsConnection = { - __typename?: 'PlanetFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetFilmsEdge = { - __typename?: 'PlanetFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PlanetResidentsConnection = { - __typename?: 'PlanetResidentsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - residents?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetResidentsEdge = { - __typename?: 'PlanetResidentsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PlanetsConnection = { - __typename?: 'PlanetsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - planets?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetsEdge = { - __typename?: 'PlanetsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -export type Root = { - __typename?: 'Root'; - allFilms?: Maybe; - allPeople?: Maybe; - allPlanets?: Maybe; - allSpecies?: Maybe; - allStarships?: Maybe; - allVehicles?: Maybe; - film?: Maybe; - /** Fetches an object given its ID */ - node?: Maybe; - person?: Maybe; - planet?: Maybe; - species?: Maybe; - starship?: Maybe; - vehicle?: Maybe; -}; - -export type RootAllFilmsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllPeopleArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllPlanetsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllSpeciesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllStarshipsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllVehiclesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootFilmArgs = { - filmID?: InputMaybe; - id?: InputMaybe; -}; - -export type RootNodeArgs = { - id: Scalars['ID']['input']; -}; - -export type RootPersonArgs = { - id?: InputMaybe; - personID?: InputMaybe; -}; - -export type RootPlanetArgs = { - id?: InputMaybe; - planetID?: InputMaybe; -}; - -export type RootSpeciesArgs = { - id?: InputMaybe; - speciesID?: InputMaybe; -}; - -export type RootStarshipArgs = { - id?: InputMaybe; - starshipID?: InputMaybe; -}; - -export type RootVehicleArgs = { - id?: InputMaybe; - vehicleID?: InputMaybe; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type Species = Node & { - __typename?: 'Species'; - /** The average height of this species in centimeters. */ - averageHeight?: Maybe; - /** The average lifespan of this species in years, null if unknown. */ - averageLifespan?: Maybe; - /** The classification of this species, such as "mammal" or "reptile". */ - classification?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The designation of this species, such as "sentient". */ - designation?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** - * Common eye colors for this species, null if this species does not typically - * have eyes. - */ - eyeColors?: Maybe>>; - filmConnection?: Maybe; - /** - * Common hair colors for this species, null if this species does not typically - * have hair. - */ - hairColors?: Maybe>>; - /** A planet that this species originates from. */ - homeworld?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The language commonly spoken by this species. */ - language?: Maybe; - /** The name of this species. */ - name?: Maybe; - personConnection?: Maybe; - /** - * Common skin colors for this species, null if this species does not typically - * have skin. - */ - skinColors?: Maybe>>; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type SpeciesFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type SpeciesPersonConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type SpeciesConnection = { - __typename?: 'SpeciesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - species?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesEdge = { - __typename?: 'SpeciesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type SpeciesFilmsConnection = { - __typename?: 'SpeciesFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesFilmsEdge = { - __typename?: 'SpeciesFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type SpeciesPeopleConnection = { - __typename?: 'SpeciesPeopleConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - people?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesPeopleEdge = { - __typename?: 'SpeciesPeopleEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type Starship = Node & { - __typename?: 'Starship'; - /** - * The Maximum number of Megalights this starship can travel in a standard hour. - * A "Megalight" is a standard unit of distance and has never been defined before - * within the Star Wars universe. This figure is only really useful for measuring - * the difference in speed of starships. We can assume it is similar to AU, the - * distance between our Sun (Sol) and Earth. - */ - MGLT?: Maybe; - /** The maximum number of kilograms that this starship can transport. */ - cargoCapacity?: Maybe; - /** - * The maximum length of time that this starship can provide consumables for its - * entire crew without having to resupply. - */ - consumables?: Maybe; - /** The cost of this starship new, in galactic credits. */ - costInCredits?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The number of personnel needed to run or pilot this starship. */ - crew?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** The class of this starships hyperdrive. */ - hyperdriveRating?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The length of this starship in meters. */ - length?: Maybe; - /** The manufacturers of this starship. */ - manufacturers?: Maybe>>; - /** - * The maximum speed of this starship in atmosphere. null if this starship is - * incapable of atmosphering flight. - */ - maxAtmospheringSpeed?: Maybe; - /** - * The model or official name of this starship. Such as "T-65 X-wing" or "DS-1 - * Orbital Battle Station". - */ - model?: Maybe; - /** The name of this starship. The common name, such as "Death Star". */ - name?: Maybe; - /** The number of non-essential people this starship can transport. */ - passengers?: Maybe; - pilotConnection?: Maybe; - /** - * The class of this starship, such as "Starfighter" or "Deep Space Mobile - * Battlestation" - */ - starshipClass?: Maybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type StarshipFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type StarshipPilotConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type StarshipFilmsConnection = { - __typename?: 'StarshipFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipFilmsEdge = { - __typename?: 'StarshipFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type StarshipPilotsConnection = { - __typename?: 'StarshipPilotsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - pilots?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipPilotsEdge = { - __typename?: 'StarshipPilotsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type StarshipsConnection = { - __typename?: 'StarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipsEdge = { - __typename?: 'StarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type Vehicle = Node & { - __typename?: 'Vehicle'; - /** The maximum number of kilograms that this vehicle can transport. */ - cargoCapacity?: Maybe; - /** - * The maximum length of time that this vehicle can provide consumables for its - * entire crew without having to resupply. - */ - consumables?: Maybe; - /** The cost of this vehicle new, in Galactic Credits. */ - costInCredits?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The number of personnel needed to run or pilot this vehicle. */ - crew?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The length of this vehicle in meters. */ - length?: Maybe; - /** The manufacturers of this vehicle. */ - manufacturers?: Maybe>>; - /** The maximum speed of this vehicle in atmosphere. */ - maxAtmospheringSpeed?: Maybe; - /** - * The model or official name of this vehicle. Such as "All-Terrain Attack - * Transport". - */ - model?: Maybe; - /** - * The name of this vehicle. The common name, such as "Sand Crawler" or "Speeder - * bike". - */ - name?: Maybe; - /** The number of non-essential people this vehicle can transport. */ - passengers?: Maybe; - pilotConnection?: Maybe; - /** The class of this vehicle, such as "Wheeled" or "Repulsorcraft". */ - vehicleClass?: Maybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type VehicleFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type VehiclePilotConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type VehicleFilmsConnection = { - __typename?: 'VehicleFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type VehicleFilmsEdge = { - __typename?: 'VehicleFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type VehiclePilotsConnection = { - __typename?: 'VehiclePilotsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - pilots?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type VehiclePilotsEdge = { - __typename?: 'VehiclePilotsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type VehiclesConnection = { - __typename?: 'VehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type VehiclesEdge = { - __typename?: 'VehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; export type AllPeopleQueryQueryVariables = Exact<{ [key: string]: never }>; export type AllPeopleQueryQuery = { - __typename?: 'Root'; - allPeople?: { - __typename?: 'PeopleConnection'; - edges?: Array<{ - __typename?: 'PeopleEdge'; - node?: { - __typename?: 'Person'; - name?: string | null; - homeworld?: { __typename?: 'Planet'; name?: string | null } | null; - } | null; + allPeople: { + edges: Array<{ + node: { name: string | null; homeworld: { name: string | null } | null } | null; } | null> | null; } | null; }; export type AllPeopleWithVariablesQueryQueryVariables = Exact<{ - first: Scalars['Int']['input']; + first: number; }>; export type AllPeopleWithVariablesQueryQuery = { - __typename?: 'Root'; - allPeople?: { - __typename?: 'PeopleConnection'; - edges?: Array<{ - __typename?: 'PeopleEdge'; - node?: { - __typename?: 'Person'; - name?: string | null; - homeworld?: { __typename?: 'Planet'; name?: string | null } | null; - } | null; + allPeople: { + edges: Array<{ + node: { name: string | null; homeworld: { name: string | null } | null } | null; } | null> | null; } | null; }; diff --git a/examples/typescript-resolvers/package.json b/examples/typescript-resolvers/package.json index 8c777c41735..e5d2def2240 100644 --- a/examples/typescript-resolvers/package.json +++ b/examples/typescript-resolvers/package.json @@ -15,9 +15,9 @@ "graphql-yoga": "5.21.0" }, "devDependencies": { - "@graphql-codegen/cli": "6.3.1", - "@graphql-codegen/typescript": "5.0.10", - "@graphql-codegen/typescript-resolvers": "5.1.8" + "@graphql-codegen/cli": "7.0.0", + "@graphql-codegen/typescript": "6.0.0", + "@graphql-codegen/typescript-resolvers": "6.0.0" }, "bob": false } diff --git a/examples/typescript-resolvers/src/type-defs.d.ts b/examples/typescript-resolvers/src/type-defs.d.ts index 485086d8856..3a73816d3ec 100644 --- a/examples/typescript-resolvers/src/type-defs.d.ts +++ b/examples/typescript-resolvers/src/type-defs.d.ts @@ -2,15 +2,6 @@ import { GraphQLResolveInfo } from 'graphql'; export type Maybe = T | null; export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; -export type Incremental = - | T - | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; export type RequireFields = Omit & { [P in K]-?: NonNullable }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { diff --git a/examples/vite/vite-react-cts/package.json b/examples/vite/vite-react-cts/package.json index 7c3268027b1..bc712188d97 100644 --- a/examples/vite/vite-react-cts/package.json +++ b/examples/vite/vite-react-cts/package.json @@ -21,7 +21,7 @@ "vite": "^8.0.0" }, "devDependencies": { - "@graphql-codegen/cli": "6.3.1", + "@graphql-codegen/cli": "7.0.0", "@types/react": "^19.0.0", "@types/react-dom": "^19.0.0", "cypress": "15.14.2", diff --git a/examples/vite/vite-react-cts/src/gql/graphql.ts b/examples/vite/vite-react-cts/src/gql/graphql.ts index bcc0af509d1..c1f9f07008d 100644 --- a/examples/vite/vite-react-cts/src/gql/graphql.ts +++ b/examples/vite/vite-react-cts/src/gql/graphql.ts @@ -1,1306 +1,28 @@ -/* eslint-disable */ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; -export type Maybe = T | null; -export type InputMaybe = T | null | undefined; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/* eslint-disable */ +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A single film. */ -export type Film = Node & { - __typename?: 'Film'; - characterConnection?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The name of the director of this film. */ - director?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** The episode number of this film. */ - episodeID?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The opening paragraphs at the beginning of this film. */ - openingCrawl?: Maybe; - planetConnection?: Maybe; - /** The name(s) of the producer(s) of this film. */ - producers?: Maybe>>; - /** The ISO 8601 date format of film release at original creator country. */ - releaseDate?: Maybe; - speciesConnection?: Maybe; - starshipConnection?: Maybe; - /** The title of this film. */ - title?: Maybe; - vehicleConnection?: Maybe; -}; - -/** A single film. */ -export type FilmCharacterConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmPlanetConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmSpeciesConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmStarshipConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmVehicleConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type FilmCharactersConnection = { - __typename?: 'FilmCharactersConnection'; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - characters?: Maybe>>; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmCharactersEdge = { - __typename?: 'FilmCharactersEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmPlanetsConnection = { - __typename?: 'FilmPlanetsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - planets?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmPlanetsEdge = { - __typename?: 'FilmPlanetsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmSpeciesConnection = { - __typename?: 'FilmSpeciesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - species?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmSpeciesEdge = { - __typename?: 'FilmSpeciesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmStarshipsConnection = { - __typename?: 'FilmStarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmStarshipsEdge = { - __typename?: 'FilmStarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmVehiclesConnection = { - __typename?: 'FilmVehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type FilmVehiclesEdge = { - __typename?: 'FilmVehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmsConnection = { - __typename?: 'FilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmsEdge = { - __typename?: 'FilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** An object with an ID */ -export type Node = { - /** The id of the object. */ - id: Scalars['ID']['output']; -}; - -/** Information about pagination in a connection. */ -export type PageInfo = { - __typename?: 'PageInfo'; - /** When paginating forwards, the cursor to continue. */ - endCursor?: Maybe; - /** When paginating forwards, are there more items? */ - hasNextPage: Scalars['Boolean']['output']; - /** When paginating backwards, are there more items? */ - hasPreviousPage: Scalars['Boolean']['output']; - /** When paginating backwards, the cursor to continue. */ - startCursor?: Maybe; -}; - -/** A connection to a list of items. */ -export type PeopleConnection = { - __typename?: 'PeopleConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - people?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PeopleEdge = { - __typename?: 'PeopleEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type Person = Node & { - __typename?: 'Person'; - /** - * The birth year of the person, using the in-universe standard of BBY or ABY - - * Before the Battle of Yavin or After the Battle of Yavin. The Battle of Yavin is - * a battle that occurs at the end of Star Wars episode IV: A New Hope. - */ - birthYear?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** - * The eye color of this person. Will be "unknown" if not known or "n/a" if the - * person does not have an eye. - */ - eyeColor?: Maybe; - filmConnection?: Maybe; - /** - * The gender of this person. Either "Male", "Female" or "unknown", - * "n/a" if the person does not have a gender. - */ - gender?: Maybe; - /** - * The hair color of this person. Will be "unknown" if not known or "n/a" if the - * person does not have hair. - */ - hairColor?: Maybe; - /** The height of the person in centimeters. */ - height?: Maybe; - /** A planet that this person was born on or inhabits. */ - homeworld?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The mass of the person in kilograms. */ - mass?: Maybe; - /** The name of this person. */ - name?: Maybe; - /** The skin color of this person. */ - skinColor?: Maybe; - /** The species that this person belongs to, or null if unknown. */ - species?: Maybe; - starshipConnection?: Maybe; - vehicleConnection?: Maybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonStarshipConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonVehicleConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type PersonFilmsConnection = { - __typename?: 'PersonFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PersonFilmsEdge = { - __typename?: 'PersonFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PersonStarshipsConnection = { - __typename?: 'PersonStarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PersonStarshipsEdge = { - __typename?: 'PersonStarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PersonVehiclesConnection = { - __typename?: 'PersonVehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type PersonVehiclesEdge = { - __typename?: 'PersonVehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type Planet = Node & { - __typename?: 'Planet'; - /** The climates of this planet. */ - climates?: Maybe>>; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The diameter of this planet in kilometers. */ - diameter?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** - * A number denoting the gravity of this planet, where "1" is normal or 1 standard - * G. "2" is twice or 2 standard Gs. "0.5" is half or 0.5 standard Gs. - */ - gravity?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The name of this planet. */ - name?: Maybe; - /** - * The number of standard days it takes for this planet to complete a single orbit - * of its local star. - */ - orbitalPeriod?: Maybe; - /** The average population of sentient beings inhabiting this planet. */ - population?: Maybe; - residentConnection?: Maybe; - /** - * The number of standard hours it takes for this planet to complete a single - * rotation on its axis. - */ - rotationPeriod?: Maybe; - /** - * The percentage of the planet surface that is naturally occurring water or bodies - * of water. - */ - surfaceWater?: Maybe; - /** The terrains of this planet. */ - terrains?: Maybe>>; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type PlanetFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type PlanetResidentConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type PlanetFilmsConnection = { - __typename?: 'PlanetFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetFilmsEdge = { - __typename?: 'PlanetFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PlanetResidentsConnection = { - __typename?: 'PlanetResidentsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - residents?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetResidentsEdge = { - __typename?: 'PlanetResidentsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PlanetsConnection = { - __typename?: 'PlanetsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - planets?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetsEdge = { - __typename?: 'PlanetsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -export type Root = { - __typename?: 'Root'; - allFilms?: Maybe; - allPeople?: Maybe; - allPlanets?: Maybe; - allSpecies?: Maybe; - allStarships?: Maybe; - allVehicles?: Maybe; - film?: Maybe; - /** Fetches an object given its ID */ - node?: Maybe; - person?: Maybe; - planet?: Maybe; - species?: Maybe; - starship?: Maybe; - vehicle?: Maybe; -}; - -export type RootAllFilmsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllPeopleArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllPlanetsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllSpeciesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllStarshipsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllVehiclesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootFilmArgs = { - filmID?: InputMaybe; - id?: InputMaybe; -}; - -export type RootNodeArgs = { - id: Scalars['ID']['input']; -}; - -export type RootPersonArgs = { - id?: InputMaybe; - personID?: InputMaybe; -}; - -export type RootPlanetArgs = { - id?: InputMaybe; - planetID?: InputMaybe; -}; - -export type RootSpeciesArgs = { - id?: InputMaybe; - speciesID?: InputMaybe; -}; - -export type RootStarshipArgs = { - id?: InputMaybe; - starshipID?: InputMaybe; -}; - -export type RootVehicleArgs = { - id?: InputMaybe; - vehicleID?: InputMaybe; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type Species = Node & { - __typename?: 'Species'; - /** The average height of this species in centimeters. */ - averageHeight?: Maybe; - /** The average lifespan of this species in years, null if unknown. */ - averageLifespan?: Maybe; - /** The classification of this species, such as "mammal" or "reptile". */ - classification?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The designation of this species, such as "sentient". */ - designation?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** - * Common eye colors for this species, null if this species does not typically - * have eyes. - */ - eyeColors?: Maybe>>; - filmConnection?: Maybe; - /** - * Common hair colors for this species, null if this species does not typically - * have hair. - */ - hairColors?: Maybe>>; - /** A planet that this species originates from. */ - homeworld?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The language commonly spoken by this species. */ - language?: Maybe; - /** The name of this species. */ - name?: Maybe; - personConnection?: Maybe; - /** - * Common skin colors for this species, null if this species does not typically - * have skin. - */ - skinColors?: Maybe>>; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type SpeciesFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type SpeciesPersonConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type SpeciesConnection = { - __typename?: 'SpeciesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - species?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesEdge = { - __typename?: 'SpeciesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type SpeciesFilmsConnection = { - __typename?: 'SpeciesFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesFilmsEdge = { - __typename?: 'SpeciesFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type SpeciesPeopleConnection = { - __typename?: 'SpeciesPeopleConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - people?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesPeopleEdge = { - __typename?: 'SpeciesPeopleEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type Starship = Node & { - __typename?: 'Starship'; - /** - * The Maximum number of Megalights this starship can travel in a standard hour. - * A "Megalight" is a standard unit of distance and has never been defined before - * within the Star Wars universe. This figure is only really useful for measuring - * the difference in speed of starships. We can assume it is similar to AU, the - * distance between our Sun (Sol) and Earth. - */ - MGLT?: Maybe; - /** The maximum number of kilograms that this starship can transport. */ - cargoCapacity?: Maybe; - /** - * The maximum length of time that this starship can provide consumables for its - * entire crew without having to resupply. - */ - consumables?: Maybe; - /** The cost of this starship new, in galactic credits. */ - costInCredits?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The number of personnel needed to run or pilot this starship. */ - crew?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** The class of this starships hyperdrive. */ - hyperdriveRating?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The length of this starship in meters. */ - length?: Maybe; - /** The manufacturers of this starship. */ - manufacturers?: Maybe>>; - /** - * The maximum speed of this starship in atmosphere. null if this starship is - * incapable of atmosphering flight. - */ - maxAtmospheringSpeed?: Maybe; - /** - * The model or official name of this starship. Such as "T-65 X-wing" or "DS-1 - * Orbital Battle Station". - */ - model?: Maybe; - /** The name of this starship. The common name, such as "Death Star". */ - name?: Maybe; - /** The number of non-essential people this starship can transport. */ - passengers?: Maybe; - pilotConnection?: Maybe; - /** - * The class of this starship, such as "Starfighter" or "Deep Space Mobile - * Battlestation" - */ - starshipClass?: Maybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type StarshipFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type StarshipPilotConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type StarshipFilmsConnection = { - __typename?: 'StarshipFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipFilmsEdge = { - __typename?: 'StarshipFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type StarshipPilotsConnection = { - __typename?: 'StarshipPilotsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - pilots?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipPilotsEdge = { - __typename?: 'StarshipPilotsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type StarshipsConnection = { - __typename?: 'StarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipsEdge = { - __typename?: 'StarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type Vehicle = Node & { - __typename?: 'Vehicle'; - /** The maximum number of kilograms that this vehicle can transport. */ - cargoCapacity?: Maybe; - /** - * The maximum length of time that this vehicle can provide consumables for its - * entire crew without having to resupply. - */ - consumables?: Maybe; - /** The cost of this vehicle new, in Galactic Credits. */ - costInCredits?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The number of personnel needed to run or pilot this vehicle. */ - crew?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The length of this vehicle in meters. */ - length?: Maybe; - /** The manufacturers of this vehicle. */ - manufacturers?: Maybe>>; - /** The maximum speed of this vehicle in atmosphere. */ - maxAtmospheringSpeed?: Maybe; - /** - * The model or official name of this vehicle. Such as "All-Terrain Attack - * Transport". - */ - model?: Maybe; - /** - * The name of this vehicle. The common name, such as "Sand Crawler" or "Speeder - * bike". - */ - name?: Maybe; - /** The number of non-essential people this vehicle can transport. */ - passengers?: Maybe; - pilotConnection?: Maybe; - /** The class of this vehicle, such as "Wheeled" or "Repulsorcraft". */ - vehicleClass?: Maybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type VehicleFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type VehiclePilotConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type VehicleFilmsConnection = { - __typename?: 'VehicleFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type VehicleFilmsEdge = { - __typename?: 'VehicleFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type VehiclePilotsConnection = { - __typename?: 'VehiclePilotsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - pilots?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type VehiclePilotsEdge = { - __typename?: 'VehiclePilotsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type VehiclesConnection = { - __typename?: 'VehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type VehiclesEdge = { - __typename?: 'VehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; export type FilmItemFragment = { - __typename?: 'Film'; id: string; - title?: string | null; - releaseDate?: string | null; - producers?: Array | null; + title: string | null; + releaseDate: string | null; + producers: Array | null; } & { ' $fragmentName'?: 'FilmItemFragment' }; export type AllFilmsWithVariablesQueryQueryVariables = Exact<{ - first: Scalars['Int']['input']; + first: number; }>; export type AllFilmsWithVariablesQueryQuery = { - __typename?: 'Root'; - allFilms?: { - __typename?: 'FilmsConnection'; - edges?: Array<{ - __typename?: 'FilmsEdge'; - node?: - | ({ __typename?: 'Film' } & { ' $fragmentRefs'?: { FilmItemFragment: FilmItemFragment } }) - | null; + allFilms: { + edges: Array<{ + node: { ' $fragmentRefs'?: { FilmItemFragment: FilmItemFragment } } | null; } | null> | null; } | null; }; diff --git a/examples/vite/vite-react-mts/package.json b/examples/vite/vite-react-mts/package.json index 034a03627a5..f6a14ef1699 100644 --- a/examples/vite/vite-react-mts/package.json +++ b/examples/vite/vite-react-mts/package.json @@ -21,7 +21,7 @@ "vite": "^8.0.0" }, "devDependencies": { - "@graphql-codegen/cli": "6.3.1", + "@graphql-codegen/cli": "7.0.0", "@types/react": "^19.0.0", "@types/react-dom": "^19.0.0", "cypress": "15.14.2", diff --git a/examples/vite/vite-react-mts/src/gql/graphql.ts b/examples/vite/vite-react-mts/src/gql/graphql.ts index bcc0af509d1..c1f9f07008d 100644 --- a/examples/vite/vite-react-mts/src/gql/graphql.ts +++ b/examples/vite/vite-react-mts/src/gql/graphql.ts @@ -1,1306 +1,28 @@ -/* eslint-disable */ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; -export type Maybe = T | null; -export type InputMaybe = T | null | undefined; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/* eslint-disable */ +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A single film. */ -export type Film = Node & { - __typename?: 'Film'; - characterConnection?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The name of the director of this film. */ - director?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** The episode number of this film. */ - episodeID?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The opening paragraphs at the beginning of this film. */ - openingCrawl?: Maybe; - planetConnection?: Maybe; - /** The name(s) of the producer(s) of this film. */ - producers?: Maybe>>; - /** The ISO 8601 date format of film release at original creator country. */ - releaseDate?: Maybe; - speciesConnection?: Maybe; - starshipConnection?: Maybe; - /** The title of this film. */ - title?: Maybe; - vehicleConnection?: Maybe; -}; - -/** A single film. */ -export type FilmCharacterConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmPlanetConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmSpeciesConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmStarshipConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmVehicleConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type FilmCharactersConnection = { - __typename?: 'FilmCharactersConnection'; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - characters?: Maybe>>; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmCharactersEdge = { - __typename?: 'FilmCharactersEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmPlanetsConnection = { - __typename?: 'FilmPlanetsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - planets?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmPlanetsEdge = { - __typename?: 'FilmPlanetsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmSpeciesConnection = { - __typename?: 'FilmSpeciesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - species?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmSpeciesEdge = { - __typename?: 'FilmSpeciesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmStarshipsConnection = { - __typename?: 'FilmStarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmStarshipsEdge = { - __typename?: 'FilmStarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmVehiclesConnection = { - __typename?: 'FilmVehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type FilmVehiclesEdge = { - __typename?: 'FilmVehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmsConnection = { - __typename?: 'FilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmsEdge = { - __typename?: 'FilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** An object with an ID */ -export type Node = { - /** The id of the object. */ - id: Scalars['ID']['output']; -}; - -/** Information about pagination in a connection. */ -export type PageInfo = { - __typename?: 'PageInfo'; - /** When paginating forwards, the cursor to continue. */ - endCursor?: Maybe; - /** When paginating forwards, are there more items? */ - hasNextPage: Scalars['Boolean']['output']; - /** When paginating backwards, are there more items? */ - hasPreviousPage: Scalars['Boolean']['output']; - /** When paginating backwards, the cursor to continue. */ - startCursor?: Maybe; -}; - -/** A connection to a list of items. */ -export type PeopleConnection = { - __typename?: 'PeopleConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - people?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PeopleEdge = { - __typename?: 'PeopleEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type Person = Node & { - __typename?: 'Person'; - /** - * The birth year of the person, using the in-universe standard of BBY or ABY - - * Before the Battle of Yavin or After the Battle of Yavin. The Battle of Yavin is - * a battle that occurs at the end of Star Wars episode IV: A New Hope. - */ - birthYear?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** - * The eye color of this person. Will be "unknown" if not known or "n/a" if the - * person does not have an eye. - */ - eyeColor?: Maybe; - filmConnection?: Maybe; - /** - * The gender of this person. Either "Male", "Female" or "unknown", - * "n/a" if the person does not have a gender. - */ - gender?: Maybe; - /** - * The hair color of this person. Will be "unknown" if not known or "n/a" if the - * person does not have hair. - */ - hairColor?: Maybe; - /** The height of the person in centimeters. */ - height?: Maybe; - /** A planet that this person was born on or inhabits. */ - homeworld?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The mass of the person in kilograms. */ - mass?: Maybe; - /** The name of this person. */ - name?: Maybe; - /** The skin color of this person. */ - skinColor?: Maybe; - /** The species that this person belongs to, or null if unknown. */ - species?: Maybe; - starshipConnection?: Maybe; - vehicleConnection?: Maybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonStarshipConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonVehicleConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type PersonFilmsConnection = { - __typename?: 'PersonFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PersonFilmsEdge = { - __typename?: 'PersonFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PersonStarshipsConnection = { - __typename?: 'PersonStarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PersonStarshipsEdge = { - __typename?: 'PersonStarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PersonVehiclesConnection = { - __typename?: 'PersonVehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type PersonVehiclesEdge = { - __typename?: 'PersonVehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type Planet = Node & { - __typename?: 'Planet'; - /** The climates of this planet. */ - climates?: Maybe>>; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The diameter of this planet in kilometers. */ - diameter?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** - * A number denoting the gravity of this planet, where "1" is normal or 1 standard - * G. "2" is twice or 2 standard Gs. "0.5" is half or 0.5 standard Gs. - */ - gravity?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The name of this planet. */ - name?: Maybe; - /** - * The number of standard days it takes for this planet to complete a single orbit - * of its local star. - */ - orbitalPeriod?: Maybe; - /** The average population of sentient beings inhabiting this planet. */ - population?: Maybe; - residentConnection?: Maybe; - /** - * The number of standard hours it takes for this planet to complete a single - * rotation on its axis. - */ - rotationPeriod?: Maybe; - /** - * The percentage of the planet surface that is naturally occurring water or bodies - * of water. - */ - surfaceWater?: Maybe; - /** The terrains of this planet. */ - terrains?: Maybe>>; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type PlanetFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type PlanetResidentConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type PlanetFilmsConnection = { - __typename?: 'PlanetFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetFilmsEdge = { - __typename?: 'PlanetFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PlanetResidentsConnection = { - __typename?: 'PlanetResidentsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - residents?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetResidentsEdge = { - __typename?: 'PlanetResidentsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PlanetsConnection = { - __typename?: 'PlanetsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - planets?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetsEdge = { - __typename?: 'PlanetsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -export type Root = { - __typename?: 'Root'; - allFilms?: Maybe; - allPeople?: Maybe; - allPlanets?: Maybe; - allSpecies?: Maybe; - allStarships?: Maybe; - allVehicles?: Maybe; - film?: Maybe; - /** Fetches an object given its ID */ - node?: Maybe; - person?: Maybe; - planet?: Maybe; - species?: Maybe; - starship?: Maybe; - vehicle?: Maybe; -}; - -export type RootAllFilmsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllPeopleArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllPlanetsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllSpeciesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllStarshipsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllVehiclesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootFilmArgs = { - filmID?: InputMaybe; - id?: InputMaybe; -}; - -export type RootNodeArgs = { - id: Scalars['ID']['input']; -}; - -export type RootPersonArgs = { - id?: InputMaybe; - personID?: InputMaybe; -}; - -export type RootPlanetArgs = { - id?: InputMaybe; - planetID?: InputMaybe; -}; - -export type RootSpeciesArgs = { - id?: InputMaybe; - speciesID?: InputMaybe; -}; - -export type RootStarshipArgs = { - id?: InputMaybe; - starshipID?: InputMaybe; -}; - -export type RootVehicleArgs = { - id?: InputMaybe; - vehicleID?: InputMaybe; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type Species = Node & { - __typename?: 'Species'; - /** The average height of this species in centimeters. */ - averageHeight?: Maybe; - /** The average lifespan of this species in years, null if unknown. */ - averageLifespan?: Maybe; - /** The classification of this species, such as "mammal" or "reptile". */ - classification?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The designation of this species, such as "sentient". */ - designation?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** - * Common eye colors for this species, null if this species does not typically - * have eyes. - */ - eyeColors?: Maybe>>; - filmConnection?: Maybe; - /** - * Common hair colors for this species, null if this species does not typically - * have hair. - */ - hairColors?: Maybe>>; - /** A planet that this species originates from. */ - homeworld?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The language commonly spoken by this species. */ - language?: Maybe; - /** The name of this species. */ - name?: Maybe; - personConnection?: Maybe; - /** - * Common skin colors for this species, null if this species does not typically - * have skin. - */ - skinColors?: Maybe>>; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type SpeciesFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type SpeciesPersonConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type SpeciesConnection = { - __typename?: 'SpeciesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - species?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesEdge = { - __typename?: 'SpeciesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type SpeciesFilmsConnection = { - __typename?: 'SpeciesFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesFilmsEdge = { - __typename?: 'SpeciesFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type SpeciesPeopleConnection = { - __typename?: 'SpeciesPeopleConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - people?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesPeopleEdge = { - __typename?: 'SpeciesPeopleEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type Starship = Node & { - __typename?: 'Starship'; - /** - * The Maximum number of Megalights this starship can travel in a standard hour. - * A "Megalight" is a standard unit of distance and has never been defined before - * within the Star Wars universe. This figure is only really useful for measuring - * the difference in speed of starships. We can assume it is similar to AU, the - * distance between our Sun (Sol) and Earth. - */ - MGLT?: Maybe; - /** The maximum number of kilograms that this starship can transport. */ - cargoCapacity?: Maybe; - /** - * The maximum length of time that this starship can provide consumables for its - * entire crew without having to resupply. - */ - consumables?: Maybe; - /** The cost of this starship new, in galactic credits. */ - costInCredits?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The number of personnel needed to run or pilot this starship. */ - crew?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** The class of this starships hyperdrive. */ - hyperdriveRating?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The length of this starship in meters. */ - length?: Maybe; - /** The manufacturers of this starship. */ - manufacturers?: Maybe>>; - /** - * The maximum speed of this starship in atmosphere. null if this starship is - * incapable of atmosphering flight. - */ - maxAtmospheringSpeed?: Maybe; - /** - * The model or official name of this starship. Such as "T-65 X-wing" or "DS-1 - * Orbital Battle Station". - */ - model?: Maybe; - /** The name of this starship. The common name, such as "Death Star". */ - name?: Maybe; - /** The number of non-essential people this starship can transport. */ - passengers?: Maybe; - pilotConnection?: Maybe; - /** - * The class of this starship, such as "Starfighter" or "Deep Space Mobile - * Battlestation" - */ - starshipClass?: Maybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type StarshipFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type StarshipPilotConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type StarshipFilmsConnection = { - __typename?: 'StarshipFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipFilmsEdge = { - __typename?: 'StarshipFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type StarshipPilotsConnection = { - __typename?: 'StarshipPilotsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - pilots?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipPilotsEdge = { - __typename?: 'StarshipPilotsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type StarshipsConnection = { - __typename?: 'StarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipsEdge = { - __typename?: 'StarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type Vehicle = Node & { - __typename?: 'Vehicle'; - /** The maximum number of kilograms that this vehicle can transport. */ - cargoCapacity?: Maybe; - /** - * The maximum length of time that this vehicle can provide consumables for its - * entire crew without having to resupply. - */ - consumables?: Maybe; - /** The cost of this vehicle new, in Galactic Credits. */ - costInCredits?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The number of personnel needed to run or pilot this vehicle. */ - crew?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The length of this vehicle in meters. */ - length?: Maybe; - /** The manufacturers of this vehicle. */ - manufacturers?: Maybe>>; - /** The maximum speed of this vehicle in atmosphere. */ - maxAtmospheringSpeed?: Maybe; - /** - * The model or official name of this vehicle. Such as "All-Terrain Attack - * Transport". - */ - model?: Maybe; - /** - * The name of this vehicle. The common name, such as "Sand Crawler" or "Speeder - * bike". - */ - name?: Maybe; - /** The number of non-essential people this vehicle can transport. */ - passengers?: Maybe; - pilotConnection?: Maybe; - /** The class of this vehicle, such as "Wheeled" or "Repulsorcraft". */ - vehicleClass?: Maybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type VehicleFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type VehiclePilotConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type VehicleFilmsConnection = { - __typename?: 'VehicleFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type VehicleFilmsEdge = { - __typename?: 'VehicleFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type VehiclePilotsConnection = { - __typename?: 'VehiclePilotsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - pilots?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type VehiclePilotsEdge = { - __typename?: 'VehiclePilotsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type VehiclesConnection = { - __typename?: 'VehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type VehiclesEdge = { - __typename?: 'VehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; export type FilmItemFragment = { - __typename?: 'Film'; id: string; - title?: string | null; - releaseDate?: string | null; - producers?: Array | null; + title: string | null; + releaseDate: string | null; + producers: Array | null; } & { ' $fragmentName'?: 'FilmItemFragment' }; export type AllFilmsWithVariablesQueryQueryVariables = Exact<{ - first: Scalars['Int']['input']; + first: number; }>; export type AllFilmsWithVariablesQueryQuery = { - __typename?: 'Root'; - allFilms?: { - __typename?: 'FilmsConnection'; - edges?: Array<{ - __typename?: 'FilmsEdge'; - node?: - | ({ __typename?: 'Film' } & { ' $fragmentRefs'?: { FilmItemFragment: FilmItemFragment } }) - | null; + allFilms: { + edges: Array<{ + node: { ' $fragmentRefs'?: { FilmItemFragment: FilmItemFragment } } | null; } | null> | null; } | null; }; diff --git a/examples/vite/vite-react-ts/package.json b/examples/vite/vite-react-ts/package.json index dfb246dc779..886d554a29f 100644 --- a/examples/vite/vite-react-ts/package.json +++ b/examples/vite/vite-react-ts/package.json @@ -21,7 +21,7 @@ "vite": "^8.0.0" }, "devDependencies": { - "@graphql-codegen/cli": "6.3.1", + "@graphql-codegen/cli": "7.0.0", "@types/react": "^19.0.0", "@types/react-dom": "^19.0.0", "cypress": "15.14.2", diff --git a/examples/vite/vite-react-ts/src/gql/graphql.ts b/examples/vite/vite-react-ts/src/gql/graphql.ts index bcc0af509d1..c1f9f07008d 100644 --- a/examples/vite/vite-react-ts/src/gql/graphql.ts +++ b/examples/vite/vite-react-ts/src/gql/graphql.ts @@ -1,1306 +1,28 @@ -/* eslint-disable */ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; -export type Maybe = T | null; -export type InputMaybe = T | null | undefined; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/* eslint-disable */ +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A single film. */ -export type Film = Node & { - __typename?: 'Film'; - characterConnection?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The name of the director of this film. */ - director?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** The episode number of this film. */ - episodeID?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The opening paragraphs at the beginning of this film. */ - openingCrawl?: Maybe; - planetConnection?: Maybe; - /** The name(s) of the producer(s) of this film. */ - producers?: Maybe>>; - /** The ISO 8601 date format of film release at original creator country. */ - releaseDate?: Maybe; - speciesConnection?: Maybe; - starshipConnection?: Maybe; - /** The title of this film. */ - title?: Maybe; - vehicleConnection?: Maybe; -}; - -/** A single film. */ -export type FilmCharacterConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmPlanetConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmSpeciesConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmStarshipConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmVehicleConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type FilmCharactersConnection = { - __typename?: 'FilmCharactersConnection'; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - characters?: Maybe>>; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmCharactersEdge = { - __typename?: 'FilmCharactersEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmPlanetsConnection = { - __typename?: 'FilmPlanetsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - planets?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmPlanetsEdge = { - __typename?: 'FilmPlanetsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmSpeciesConnection = { - __typename?: 'FilmSpeciesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - species?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmSpeciesEdge = { - __typename?: 'FilmSpeciesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmStarshipsConnection = { - __typename?: 'FilmStarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmStarshipsEdge = { - __typename?: 'FilmStarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmVehiclesConnection = { - __typename?: 'FilmVehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type FilmVehiclesEdge = { - __typename?: 'FilmVehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmsConnection = { - __typename?: 'FilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmsEdge = { - __typename?: 'FilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** An object with an ID */ -export type Node = { - /** The id of the object. */ - id: Scalars['ID']['output']; -}; - -/** Information about pagination in a connection. */ -export type PageInfo = { - __typename?: 'PageInfo'; - /** When paginating forwards, the cursor to continue. */ - endCursor?: Maybe; - /** When paginating forwards, are there more items? */ - hasNextPage: Scalars['Boolean']['output']; - /** When paginating backwards, are there more items? */ - hasPreviousPage: Scalars['Boolean']['output']; - /** When paginating backwards, the cursor to continue. */ - startCursor?: Maybe; -}; - -/** A connection to a list of items. */ -export type PeopleConnection = { - __typename?: 'PeopleConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - people?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PeopleEdge = { - __typename?: 'PeopleEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type Person = Node & { - __typename?: 'Person'; - /** - * The birth year of the person, using the in-universe standard of BBY or ABY - - * Before the Battle of Yavin or After the Battle of Yavin. The Battle of Yavin is - * a battle that occurs at the end of Star Wars episode IV: A New Hope. - */ - birthYear?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** - * The eye color of this person. Will be "unknown" if not known or "n/a" if the - * person does not have an eye. - */ - eyeColor?: Maybe; - filmConnection?: Maybe; - /** - * The gender of this person. Either "Male", "Female" or "unknown", - * "n/a" if the person does not have a gender. - */ - gender?: Maybe; - /** - * The hair color of this person. Will be "unknown" if not known or "n/a" if the - * person does not have hair. - */ - hairColor?: Maybe; - /** The height of the person in centimeters. */ - height?: Maybe; - /** A planet that this person was born on or inhabits. */ - homeworld?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The mass of the person in kilograms. */ - mass?: Maybe; - /** The name of this person. */ - name?: Maybe; - /** The skin color of this person. */ - skinColor?: Maybe; - /** The species that this person belongs to, or null if unknown. */ - species?: Maybe; - starshipConnection?: Maybe; - vehicleConnection?: Maybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonStarshipConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonVehicleConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type PersonFilmsConnection = { - __typename?: 'PersonFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PersonFilmsEdge = { - __typename?: 'PersonFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PersonStarshipsConnection = { - __typename?: 'PersonStarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PersonStarshipsEdge = { - __typename?: 'PersonStarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PersonVehiclesConnection = { - __typename?: 'PersonVehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type PersonVehiclesEdge = { - __typename?: 'PersonVehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type Planet = Node & { - __typename?: 'Planet'; - /** The climates of this planet. */ - climates?: Maybe>>; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The diameter of this planet in kilometers. */ - diameter?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** - * A number denoting the gravity of this planet, where "1" is normal or 1 standard - * G. "2" is twice or 2 standard Gs. "0.5" is half or 0.5 standard Gs. - */ - gravity?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The name of this planet. */ - name?: Maybe; - /** - * The number of standard days it takes for this planet to complete a single orbit - * of its local star. - */ - orbitalPeriod?: Maybe; - /** The average population of sentient beings inhabiting this planet. */ - population?: Maybe; - residentConnection?: Maybe; - /** - * The number of standard hours it takes for this planet to complete a single - * rotation on its axis. - */ - rotationPeriod?: Maybe; - /** - * The percentage of the planet surface that is naturally occurring water or bodies - * of water. - */ - surfaceWater?: Maybe; - /** The terrains of this planet. */ - terrains?: Maybe>>; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type PlanetFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type PlanetResidentConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type PlanetFilmsConnection = { - __typename?: 'PlanetFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetFilmsEdge = { - __typename?: 'PlanetFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PlanetResidentsConnection = { - __typename?: 'PlanetResidentsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - residents?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetResidentsEdge = { - __typename?: 'PlanetResidentsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PlanetsConnection = { - __typename?: 'PlanetsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - planets?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetsEdge = { - __typename?: 'PlanetsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -export type Root = { - __typename?: 'Root'; - allFilms?: Maybe; - allPeople?: Maybe; - allPlanets?: Maybe; - allSpecies?: Maybe; - allStarships?: Maybe; - allVehicles?: Maybe; - film?: Maybe; - /** Fetches an object given its ID */ - node?: Maybe; - person?: Maybe; - planet?: Maybe; - species?: Maybe; - starship?: Maybe; - vehicle?: Maybe; -}; - -export type RootAllFilmsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllPeopleArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllPlanetsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllSpeciesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllStarshipsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllVehiclesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootFilmArgs = { - filmID?: InputMaybe; - id?: InputMaybe; -}; - -export type RootNodeArgs = { - id: Scalars['ID']['input']; -}; - -export type RootPersonArgs = { - id?: InputMaybe; - personID?: InputMaybe; -}; - -export type RootPlanetArgs = { - id?: InputMaybe; - planetID?: InputMaybe; -}; - -export type RootSpeciesArgs = { - id?: InputMaybe; - speciesID?: InputMaybe; -}; - -export type RootStarshipArgs = { - id?: InputMaybe; - starshipID?: InputMaybe; -}; - -export type RootVehicleArgs = { - id?: InputMaybe; - vehicleID?: InputMaybe; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type Species = Node & { - __typename?: 'Species'; - /** The average height of this species in centimeters. */ - averageHeight?: Maybe; - /** The average lifespan of this species in years, null if unknown. */ - averageLifespan?: Maybe; - /** The classification of this species, such as "mammal" or "reptile". */ - classification?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The designation of this species, such as "sentient". */ - designation?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** - * Common eye colors for this species, null if this species does not typically - * have eyes. - */ - eyeColors?: Maybe>>; - filmConnection?: Maybe; - /** - * Common hair colors for this species, null if this species does not typically - * have hair. - */ - hairColors?: Maybe>>; - /** A planet that this species originates from. */ - homeworld?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The language commonly spoken by this species. */ - language?: Maybe; - /** The name of this species. */ - name?: Maybe; - personConnection?: Maybe; - /** - * Common skin colors for this species, null if this species does not typically - * have skin. - */ - skinColors?: Maybe>>; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type SpeciesFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type SpeciesPersonConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type SpeciesConnection = { - __typename?: 'SpeciesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - species?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesEdge = { - __typename?: 'SpeciesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type SpeciesFilmsConnection = { - __typename?: 'SpeciesFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesFilmsEdge = { - __typename?: 'SpeciesFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type SpeciesPeopleConnection = { - __typename?: 'SpeciesPeopleConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - people?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesPeopleEdge = { - __typename?: 'SpeciesPeopleEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type Starship = Node & { - __typename?: 'Starship'; - /** - * The Maximum number of Megalights this starship can travel in a standard hour. - * A "Megalight" is a standard unit of distance and has never been defined before - * within the Star Wars universe. This figure is only really useful for measuring - * the difference in speed of starships. We can assume it is similar to AU, the - * distance between our Sun (Sol) and Earth. - */ - MGLT?: Maybe; - /** The maximum number of kilograms that this starship can transport. */ - cargoCapacity?: Maybe; - /** - * The maximum length of time that this starship can provide consumables for its - * entire crew without having to resupply. - */ - consumables?: Maybe; - /** The cost of this starship new, in galactic credits. */ - costInCredits?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The number of personnel needed to run or pilot this starship. */ - crew?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** The class of this starships hyperdrive. */ - hyperdriveRating?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The length of this starship in meters. */ - length?: Maybe; - /** The manufacturers of this starship. */ - manufacturers?: Maybe>>; - /** - * The maximum speed of this starship in atmosphere. null if this starship is - * incapable of atmosphering flight. - */ - maxAtmospheringSpeed?: Maybe; - /** - * The model or official name of this starship. Such as "T-65 X-wing" or "DS-1 - * Orbital Battle Station". - */ - model?: Maybe; - /** The name of this starship. The common name, such as "Death Star". */ - name?: Maybe; - /** The number of non-essential people this starship can transport. */ - passengers?: Maybe; - pilotConnection?: Maybe; - /** - * The class of this starship, such as "Starfighter" or "Deep Space Mobile - * Battlestation" - */ - starshipClass?: Maybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type StarshipFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type StarshipPilotConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type StarshipFilmsConnection = { - __typename?: 'StarshipFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipFilmsEdge = { - __typename?: 'StarshipFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type StarshipPilotsConnection = { - __typename?: 'StarshipPilotsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - pilots?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipPilotsEdge = { - __typename?: 'StarshipPilotsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type StarshipsConnection = { - __typename?: 'StarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipsEdge = { - __typename?: 'StarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type Vehicle = Node & { - __typename?: 'Vehicle'; - /** The maximum number of kilograms that this vehicle can transport. */ - cargoCapacity?: Maybe; - /** - * The maximum length of time that this vehicle can provide consumables for its - * entire crew without having to resupply. - */ - consumables?: Maybe; - /** The cost of this vehicle new, in Galactic Credits. */ - costInCredits?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The number of personnel needed to run or pilot this vehicle. */ - crew?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The length of this vehicle in meters. */ - length?: Maybe; - /** The manufacturers of this vehicle. */ - manufacturers?: Maybe>>; - /** The maximum speed of this vehicle in atmosphere. */ - maxAtmospheringSpeed?: Maybe; - /** - * The model or official name of this vehicle. Such as "All-Terrain Attack - * Transport". - */ - model?: Maybe; - /** - * The name of this vehicle. The common name, such as "Sand Crawler" or "Speeder - * bike". - */ - name?: Maybe; - /** The number of non-essential people this vehicle can transport. */ - passengers?: Maybe; - pilotConnection?: Maybe; - /** The class of this vehicle, such as "Wheeled" or "Repulsorcraft". */ - vehicleClass?: Maybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type VehicleFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type VehiclePilotConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type VehicleFilmsConnection = { - __typename?: 'VehicleFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type VehicleFilmsEdge = { - __typename?: 'VehicleFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type VehiclePilotsConnection = { - __typename?: 'VehiclePilotsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - pilots?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type VehiclePilotsEdge = { - __typename?: 'VehiclePilotsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type VehiclesConnection = { - __typename?: 'VehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type VehiclesEdge = { - __typename?: 'VehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; export type FilmItemFragment = { - __typename?: 'Film'; id: string; - title?: string | null; - releaseDate?: string | null; - producers?: Array | null; + title: string | null; + releaseDate: string | null; + producers: Array | null; } & { ' $fragmentName'?: 'FilmItemFragment' }; export type AllFilmsWithVariablesQueryQueryVariables = Exact<{ - first: Scalars['Int']['input']; + first: number; }>; export type AllFilmsWithVariablesQueryQuery = { - __typename?: 'Root'; - allFilms?: { - __typename?: 'FilmsConnection'; - edges?: Array<{ - __typename?: 'FilmsEdge'; - node?: - | ({ __typename?: 'Film' } & { ' $fragmentRefs'?: { FilmItemFragment: FilmItemFragment } }) - | null; + allFilms: { + edges: Array<{ + node: { ' $fragmentRefs'?: { FilmItemFragment: FilmItemFragment } } | null; } | null> | null; } | null; }; diff --git a/examples/vue/apollo-composable/package.json b/examples/vue/apollo-composable/package.json index df0afeb9114..f62fb4b81ed 100644 --- a/examples/vue/apollo-composable/package.json +++ b/examples/vue/apollo-composable/package.json @@ -17,7 +17,7 @@ "vue": "^3.2.37" }, "devDependencies": { - "@graphql-codegen/cli": "^6.3.1", + "@graphql-codegen/cli": "^7.0.0", "@vitejs/plugin-vue": "^6.0.0", "cypress": "15.14.2", "serve": "14.2.6", diff --git a/examples/vue/apollo-composable/src/gql/graphql.ts b/examples/vue/apollo-composable/src/gql/graphql.ts index ba3e733af05..32b8b38e8d3 100644 --- a/examples/vue/apollo-composable/src/gql/graphql.ts +++ b/examples/vue/apollo-composable/src/gql/graphql.ts @@ -1,1308 +1,30 @@ -/* eslint-disable */ import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; -export type Maybe = T | null; -export type InputMaybe = T | null | undefined; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/* eslint-disable */ +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A single film. */ -export type Film = Node & { - __typename?: 'Film'; - characterConnection?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The name of the director of this film. */ - director?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** The episode number of this film. */ - episodeID?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The opening paragraphs at the beginning of this film. */ - openingCrawl?: Maybe; - planetConnection?: Maybe; - /** The name(s) of the producer(s) of this film. */ - producers?: Maybe>>; - /** The ISO 8601 date format of film release at original creator country. */ - releaseDate?: Maybe; - speciesConnection?: Maybe; - starshipConnection?: Maybe; - /** The title of this film. */ - title?: Maybe; - vehicleConnection?: Maybe; -}; - -/** A single film. */ -export type FilmCharacterConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmPlanetConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmSpeciesConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmStarshipConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmVehicleConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type FilmCharactersConnection = { - __typename?: 'FilmCharactersConnection'; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - characters?: Maybe>>; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmCharactersEdge = { - __typename?: 'FilmCharactersEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmPlanetsConnection = { - __typename?: 'FilmPlanetsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - planets?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmPlanetsEdge = { - __typename?: 'FilmPlanetsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmSpeciesConnection = { - __typename?: 'FilmSpeciesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - species?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmSpeciesEdge = { - __typename?: 'FilmSpeciesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmStarshipsConnection = { - __typename?: 'FilmStarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmStarshipsEdge = { - __typename?: 'FilmStarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmVehiclesConnection = { - __typename?: 'FilmVehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type FilmVehiclesEdge = { - __typename?: 'FilmVehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmsConnection = { - __typename?: 'FilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmsEdge = { - __typename?: 'FilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** An object with an ID */ -export type Node = { - /** The id of the object. */ - id: Scalars['ID']['output']; -}; - -/** Information about pagination in a connection. */ -export type PageInfo = { - __typename?: 'PageInfo'; - /** When paginating forwards, the cursor to continue. */ - endCursor?: Maybe; - /** When paginating forwards, are there more items? */ - hasNextPage: Scalars['Boolean']['output']; - /** When paginating backwards, are there more items? */ - hasPreviousPage: Scalars['Boolean']['output']; - /** When paginating backwards, the cursor to continue. */ - startCursor?: Maybe; -}; - -/** A connection to a list of items. */ -export type PeopleConnection = { - __typename?: 'PeopleConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - people?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PeopleEdge = { - __typename?: 'PeopleEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type Person = Node & { - __typename?: 'Person'; - /** - * The birth year of the person, using the in-universe standard of BBY or ABY - - * Before the Battle of Yavin or After the Battle of Yavin. The Battle of Yavin is - * a battle that occurs at the end of Star Wars episode IV: A New Hope. - */ - birthYear?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** - * The eye color of this person. Will be "unknown" if not known or "n/a" if the - * person does not have an eye. - */ - eyeColor?: Maybe; - filmConnection?: Maybe; - /** - * The gender of this person. Either "Male", "Female" or "unknown", - * "n/a" if the person does not have a gender. - */ - gender?: Maybe; - /** - * The hair color of this person. Will be "unknown" if not known or "n/a" if the - * person does not have hair. - */ - hairColor?: Maybe; - /** The height of the person in centimeters. */ - height?: Maybe; - /** A planet that this person was born on or inhabits. */ - homeworld?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The mass of the person in kilograms. */ - mass?: Maybe; - /** The name of this person. */ - name?: Maybe; - /** The skin color of this person. */ - skinColor?: Maybe; - /** The species that this person belongs to, or null if unknown. */ - species?: Maybe; - starshipConnection?: Maybe; - vehicleConnection?: Maybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonStarshipConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonVehicleConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type PersonFilmsConnection = { - __typename?: 'PersonFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PersonFilmsEdge = { - __typename?: 'PersonFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PersonStarshipsConnection = { - __typename?: 'PersonStarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PersonStarshipsEdge = { - __typename?: 'PersonStarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PersonVehiclesConnection = { - __typename?: 'PersonVehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type PersonVehiclesEdge = { - __typename?: 'PersonVehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type Planet = Node & { - __typename?: 'Planet'; - /** The climates of this planet. */ - climates?: Maybe>>; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The diameter of this planet in kilometers. */ - diameter?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** - * A number denoting the gravity of this planet, where "1" is normal or 1 standard - * G. "2" is twice or 2 standard Gs. "0.5" is half or 0.5 standard Gs. - */ - gravity?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The name of this planet. */ - name?: Maybe; - /** - * The number of standard days it takes for this planet to complete a single orbit - * of its local star. - */ - orbitalPeriod?: Maybe; - /** The average population of sentient beings inhabiting this planet. */ - population?: Maybe; - residentConnection?: Maybe; - /** - * The number of standard hours it takes for this planet to complete a single - * rotation on its axis. - */ - rotationPeriod?: Maybe; - /** - * The percentage of the planet surface that is naturally occurring water or bodies - * of water. - */ - surfaceWater?: Maybe; - /** The terrains of this planet. */ - terrains?: Maybe>>; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type PlanetFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type PlanetResidentConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type PlanetFilmsConnection = { - __typename?: 'PlanetFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetFilmsEdge = { - __typename?: 'PlanetFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PlanetResidentsConnection = { - __typename?: 'PlanetResidentsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - residents?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetResidentsEdge = { - __typename?: 'PlanetResidentsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PlanetsConnection = { - __typename?: 'PlanetsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - planets?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetsEdge = { - __typename?: 'PlanetsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -export type Root = { - __typename?: 'Root'; - allFilms?: Maybe; - allPeople?: Maybe; - allPlanets?: Maybe; - allSpecies?: Maybe; - allStarships?: Maybe; - allVehicles?: Maybe; - film?: Maybe; - /** Fetches an object given its ID */ - node?: Maybe; - person?: Maybe; - planet?: Maybe; - species?: Maybe; - starship?: Maybe; - vehicle?: Maybe; -}; - -export type RootAllFilmsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllPeopleArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllPlanetsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllSpeciesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllStarshipsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllVehiclesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootFilmArgs = { - filmID?: InputMaybe; - id?: InputMaybe; -}; - -export type RootNodeArgs = { - id: Scalars['ID']['input']; -}; - -export type RootPersonArgs = { - id?: InputMaybe; - personID?: InputMaybe; -}; - -export type RootPlanetArgs = { - id?: InputMaybe; - planetID?: InputMaybe; -}; - -export type RootSpeciesArgs = { - id?: InputMaybe; - speciesID?: InputMaybe; -}; - -export type RootStarshipArgs = { - id?: InputMaybe; - starshipID?: InputMaybe; -}; - -export type RootVehicleArgs = { - id?: InputMaybe; - vehicleID?: InputMaybe; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type Species = Node & { - __typename?: 'Species'; - /** The average height of this species in centimeters. */ - averageHeight?: Maybe; - /** The average lifespan of this species in years, null if unknown. */ - averageLifespan?: Maybe; - /** The classification of this species, such as "mammal" or "reptile". */ - classification?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The designation of this species, such as "sentient". */ - designation?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** - * Common eye colors for this species, null if this species does not typically - * have eyes. - */ - eyeColors?: Maybe>>; - filmConnection?: Maybe; - /** - * Common hair colors for this species, null if this species does not typically - * have hair. - */ - hairColors?: Maybe>>; - /** A planet that this species originates from. */ - homeworld?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The language commonly spoken by this species. */ - language?: Maybe; - /** The name of this species. */ - name?: Maybe; - personConnection?: Maybe; - /** - * Common skin colors for this species, null if this species does not typically - * have skin. - */ - skinColors?: Maybe>>; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type SpeciesFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type SpeciesPersonConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type SpeciesConnection = { - __typename?: 'SpeciesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - species?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesEdge = { - __typename?: 'SpeciesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type SpeciesFilmsConnection = { - __typename?: 'SpeciesFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesFilmsEdge = { - __typename?: 'SpeciesFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type SpeciesPeopleConnection = { - __typename?: 'SpeciesPeopleConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - people?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesPeopleEdge = { - __typename?: 'SpeciesPeopleEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type Starship = Node & { - __typename?: 'Starship'; - /** - * The Maximum number of Megalights this starship can travel in a standard hour. - * A "Megalight" is a standard unit of distance and has never been defined before - * within the Star Wars universe. This figure is only really useful for measuring - * the difference in speed of starships. We can assume it is similar to AU, the - * distance between our Sun (Sol) and Earth. - */ - MGLT?: Maybe; - /** The maximum number of kilograms that this starship can transport. */ - cargoCapacity?: Maybe; - /** - * The maximum length of time that this starship can provide consumables for its - * entire crew without having to resupply. - */ - consumables?: Maybe; - /** The cost of this starship new, in galactic credits. */ - costInCredits?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The number of personnel needed to run or pilot this starship. */ - crew?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** The class of this starships hyperdrive. */ - hyperdriveRating?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The length of this starship in meters. */ - length?: Maybe; - /** The manufacturers of this starship. */ - manufacturers?: Maybe>>; - /** - * The maximum speed of this starship in atmosphere. null if this starship is - * incapable of atmosphering flight. - */ - maxAtmospheringSpeed?: Maybe; - /** - * The model or official name of this starship. Such as "T-65 X-wing" or "DS-1 - * Orbital Battle Station". - */ - model?: Maybe; - /** The name of this starship. The common name, such as "Death Star". */ - name?: Maybe; - /** The number of non-essential people this starship can transport. */ - passengers?: Maybe; - pilotConnection?: Maybe; - /** - * The class of this starship, such as "Starfighter" or "Deep Space Mobile - * Battlestation" - */ - starshipClass?: Maybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type StarshipFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type StarshipPilotConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type StarshipFilmsConnection = { - __typename?: 'StarshipFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipFilmsEdge = { - __typename?: 'StarshipFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type StarshipPilotsConnection = { - __typename?: 'StarshipPilotsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - pilots?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipPilotsEdge = { - __typename?: 'StarshipPilotsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type StarshipsConnection = { - __typename?: 'StarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipsEdge = { - __typename?: 'StarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type Vehicle = Node & { - __typename?: 'Vehicle'; - /** The maximum number of kilograms that this vehicle can transport. */ - cargoCapacity?: Maybe; - /** - * The maximum length of time that this vehicle can provide consumables for its - * entire crew without having to resupply. - */ - consumables?: Maybe; - /** The cost of this vehicle new, in Galactic Credits. */ - costInCredits?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The number of personnel needed to run or pilot this vehicle. */ - crew?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The length of this vehicle in meters. */ - length?: Maybe; - /** The manufacturers of this vehicle. */ - manufacturers?: Maybe>>; - /** The maximum speed of this vehicle in atmosphere. */ - maxAtmospheringSpeed?: Maybe; - /** - * The model or official name of this vehicle. Such as "All-Terrain Attack - * Transport". - */ - model?: Maybe; - /** - * The name of this vehicle. The common name, such as "Sand Crawler" or "Speeder - * bike". - */ - name?: Maybe; - /** The number of non-essential people this vehicle can transport. */ - passengers?: Maybe; - pilotConnection?: Maybe; - /** The class of this vehicle, such as "Wheeled" or "Repulsorcraft". */ - vehicleClass?: Maybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type VehicleFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type VehiclePilotConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type VehicleFilmsConnection = { - __typename?: 'VehicleFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type VehicleFilmsEdge = { - __typename?: 'VehicleFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type VehiclePilotsConnection = { - __typename?: 'VehiclePilotsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - pilots?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type VehiclePilotsEdge = { - __typename?: 'VehiclePilotsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type VehiclesConnection = { - __typename?: 'VehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type VehiclesEdge = { - __typename?: 'VehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; export type AllFilmsWithVariablesQueryQueryVariables = Exact<{ - first: Scalars['Int']['input']; + first: number; }>; export type AllFilmsWithVariablesQueryQuery = { - __typename?: 'Root'; - allFilms?: { - __typename?: 'FilmsConnection'; - edges?: Array<{ - __typename?: 'FilmsEdge'; - node?: - | ({ __typename?: 'Film' } & { ' $fragmentRefs'?: { FilmItemFragment: FilmItemFragment } }) - | null; + allFilms: { + edges: Array<{ + node: { ' $fragmentRefs'?: { FilmItemFragment: FilmItemFragment } } | null; } | null> | null; } | null; }; export type FilmItemFragment = { - __typename?: 'Film'; id: string; - title?: string | null; - releaseDate?: string | null; - producers?: Array | null; + title: string | null; + releaseDate: string | null; + producers: Array | null; } & { ' $fragmentName'?: 'FilmItemFragment' }; export const FilmItemFragmentDoc = { diff --git a/examples/vue/urql/package.json b/examples/vue/urql/package.json index 70a67cb94f3..2515bfac755 100644 --- a/examples/vue/urql/package.json +++ b/examples/vue/urql/package.json @@ -16,7 +16,7 @@ "vue": "^3.2.45" }, "devDependencies": { - "@graphql-codegen/cli": "^6.3.1", + "@graphql-codegen/cli": "^7.0.0", "@vitejs/plugin-vue": "^6.0.0", "cypress": "15.14.2", "serve": "14.2.6", diff --git a/examples/vue/urql/src/gql/graphql.ts b/examples/vue/urql/src/gql/graphql.ts index ba3e733af05..32b8b38e8d3 100644 --- a/examples/vue/urql/src/gql/graphql.ts +++ b/examples/vue/urql/src/gql/graphql.ts @@ -1,1308 +1,30 @@ -/* eslint-disable */ import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; -export type Maybe = T | null; -export type InputMaybe = T | null | undefined; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/* eslint-disable */ +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A single film. */ -export type Film = Node & { - __typename?: 'Film'; - characterConnection?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The name of the director of this film. */ - director?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** The episode number of this film. */ - episodeID?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The opening paragraphs at the beginning of this film. */ - openingCrawl?: Maybe; - planetConnection?: Maybe; - /** The name(s) of the producer(s) of this film. */ - producers?: Maybe>>; - /** The ISO 8601 date format of film release at original creator country. */ - releaseDate?: Maybe; - speciesConnection?: Maybe; - starshipConnection?: Maybe; - /** The title of this film. */ - title?: Maybe; - vehicleConnection?: Maybe; -}; - -/** A single film. */ -export type FilmCharacterConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmPlanetConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmSpeciesConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmStarshipConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmVehicleConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type FilmCharactersConnection = { - __typename?: 'FilmCharactersConnection'; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - characters?: Maybe>>; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmCharactersEdge = { - __typename?: 'FilmCharactersEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmPlanetsConnection = { - __typename?: 'FilmPlanetsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - planets?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmPlanetsEdge = { - __typename?: 'FilmPlanetsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmSpeciesConnection = { - __typename?: 'FilmSpeciesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - species?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmSpeciesEdge = { - __typename?: 'FilmSpeciesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmStarshipsConnection = { - __typename?: 'FilmStarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmStarshipsEdge = { - __typename?: 'FilmStarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmVehiclesConnection = { - __typename?: 'FilmVehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type FilmVehiclesEdge = { - __typename?: 'FilmVehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmsConnection = { - __typename?: 'FilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmsEdge = { - __typename?: 'FilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** An object with an ID */ -export type Node = { - /** The id of the object. */ - id: Scalars['ID']['output']; -}; - -/** Information about pagination in a connection. */ -export type PageInfo = { - __typename?: 'PageInfo'; - /** When paginating forwards, the cursor to continue. */ - endCursor?: Maybe; - /** When paginating forwards, are there more items? */ - hasNextPage: Scalars['Boolean']['output']; - /** When paginating backwards, are there more items? */ - hasPreviousPage: Scalars['Boolean']['output']; - /** When paginating backwards, the cursor to continue. */ - startCursor?: Maybe; -}; - -/** A connection to a list of items. */ -export type PeopleConnection = { - __typename?: 'PeopleConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - people?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PeopleEdge = { - __typename?: 'PeopleEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type Person = Node & { - __typename?: 'Person'; - /** - * The birth year of the person, using the in-universe standard of BBY or ABY - - * Before the Battle of Yavin or After the Battle of Yavin. The Battle of Yavin is - * a battle that occurs at the end of Star Wars episode IV: A New Hope. - */ - birthYear?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** - * The eye color of this person. Will be "unknown" if not known or "n/a" if the - * person does not have an eye. - */ - eyeColor?: Maybe; - filmConnection?: Maybe; - /** - * The gender of this person. Either "Male", "Female" or "unknown", - * "n/a" if the person does not have a gender. - */ - gender?: Maybe; - /** - * The hair color of this person. Will be "unknown" if not known or "n/a" if the - * person does not have hair. - */ - hairColor?: Maybe; - /** The height of the person in centimeters. */ - height?: Maybe; - /** A planet that this person was born on or inhabits. */ - homeworld?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The mass of the person in kilograms. */ - mass?: Maybe; - /** The name of this person. */ - name?: Maybe; - /** The skin color of this person. */ - skinColor?: Maybe; - /** The species that this person belongs to, or null if unknown. */ - species?: Maybe; - starshipConnection?: Maybe; - vehicleConnection?: Maybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonStarshipConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonVehicleConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type PersonFilmsConnection = { - __typename?: 'PersonFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PersonFilmsEdge = { - __typename?: 'PersonFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PersonStarshipsConnection = { - __typename?: 'PersonStarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PersonStarshipsEdge = { - __typename?: 'PersonStarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PersonVehiclesConnection = { - __typename?: 'PersonVehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type PersonVehiclesEdge = { - __typename?: 'PersonVehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type Planet = Node & { - __typename?: 'Planet'; - /** The climates of this planet. */ - climates?: Maybe>>; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The diameter of this planet in kilometers. */ - diameter?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** - * A number denoting the gravity of this planet, where "1" is normal or 1 standard - * G. "2" is twice or 2 standard Gs. "0.5" is half or 0.5 standard Gs. - */ - gravity?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The name of this planet. */ - name?: Maybe; - /** - * The number of standard days it takes for this planet to complete a single orbit - * of its local star. - */ - orbitalPeriod?: Maybe; - /** The average population of sentient beings inhabiting this planet. */ - population?: Maybe; - residentConnection?: Maybe; - /** - * The number of standard hours it takes for this planet to complete a single - * rotation on its axis. - */ - rotationPeriod?: Maybe; - /** - * The percentage of the planet surface that is naturally occurring water or bodies - * of water. - */ - surfaceWater?: Maybe; - /** The terrains of this planet. */ - terrains?: Maybe>>; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type PlanetFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type PlanetResidentConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type PlanetFilmsConnection = { - __typename?: 'PlanetFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetFilmsEdge = { - __typename?: 'PlanetFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PlanetResidentsConnection = { - __typename?: 'PlanetResidentsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - residents?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetResidentsEdge = { - __typename?: 'PlanetResidentsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PlanetsConnection = { - __typename?: 'PlanetsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - planets?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetsEdge = { - __typename?: 'PlanetsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -export type Root = { - __typename?: 'Root'; - allFilms?: Maybe; - allPeople?: Maybe; - allPlanets?: Maybe; - allSpecies?: Maybe; - allStarships?: Maybe; - allVehicles?: Maybe; - film?: Maybe; - /** Fetches an object given its ID */ - node?: Maybe; - person?: Maybe; - planet?: Maybe; - species?: Maybe; - starship?: Maybe; - vehicle?: Maybe; -}; - -export type RootAllFilmsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllPeopleArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllPlanetsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllSpeciesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllStarshipsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllVehiclesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootFilmArgs = { - filmID?: InputMaybe; - id?: InputMaybe; -}; - -export type RootNodeArgs = { - id: Scalars['ID']['input']; -}; - -export type RootPersonArgs = { - id?: InputMaybe; - personID?: InputMaybe; -}; - -export type RootPlanetArgs = { - id?: InputMaybe; - planetID?: InputMaybe; -}; - -export type RootSpeciesArgs = { - id?: InputMaybe; - speciesID?: InputMaybe; -}; - -export type RootStarshipArgs = { - id?: InputMaybe; - starshipID?: InputMaybe; -}; - -export type RootVehicleArgs = { - id?: InputMaybe; - vehicleID?: InputMaybe; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type Species = Node & { - __typename?: 'Species'; - /** The average height of this species in centimeters. */ - averageHeight?: Maybe; - /** The average lifespan of this species in years, null if unknown. */ - averageLifespan?: Maybe; - /** The classification of this species, such as "mammal" or "reptile". */ - classification?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The designation of this species, such as "sentient". */ - designation?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** - * Common eye colors for this species, null if this species does not typically - * have eyes. - */ - eyeColors?: Maybe>>; - filmConnection?: Maybe; - /** - * Common hair colors for this species, null if this species does not typically - * have hair. - */ - hairColors?: Maybe>>; - /** A planet that this species originates from. */ - homeworld?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The language commonly spoken by this species. */ - language?: Maybe; - /** The name of this species. */ - name?: Maybe; - personConnection?: Maybe; - /** - * Common skin colors for this species, null if this species does not typically - * have skin. - */ - skinColors?: Maybe>>; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type SpeciesFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type SpeciesPersonConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type SpeciesConnection = { - __typename?: 'SpeciesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - species?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesEdge = { - __typename?: 'SpeciesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type SpeciesFilmsConnection = { - __typename?: 'SpeciesFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesFilmsEdge = { - __typename?: 'SpeciesFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type SpeciesPeopleConnection = { - __typename?: 'SpeciesPeopleConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - people?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesPeopleEdge = { - __typename?: 'SpeciesPeopleEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type Starship = Node & { - __typename?: 'Starship'; - /** - * The Maximum number of Megalights this starship can travel in a standard hour. - * A "Megalight" is a standard unit of distance and has never been defined before - * within the Star Wars universe. This figure is only really useful for measuring - * the difference in speed of starships. We can assume it is similar to AU, the - * distance between our Sun (Sol) and Earth. - */ - MGLT?: Maybe; - /** The maximum number of kilograms that this starship can transport. */ - cargoCapacity?: Maybe; - /** - * The maximum length of time that this starship can provide consumables for its - * entire crew without having to resupply. - */ - consumables?: Maybe; - /** The cost of this starship new, in galactic credits. */ - costInCredits?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The number of personnel needed to run or pilot this starship. */ - crew?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** The class of this starships hyperdrive. */ - hyperdriveRating?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The length of this starship in meters. */ - length?: Maybe; - /** The manufacturers of this starship. */ - manufacturers?: Maybe>>; - /** - * The maximum speed of this starship in atmosphere. null if this starship is - * incapable of atmosphering flight. - */ - maxAtmospheringSpeed?: Maybe; - /** - * The model or official name of this starship. Such as "T-65 X-wing" or "DS-1 - * Orbital Battle Station". - */ - model?: Maybe; - /** The name of this starship. The common name, such as "Death Star". */ - name?: Maybe; - /** The number of non-essential people this starship can transport. */ - passengers?: Maybe; - pilotConnection?: Maybe; - /** - * The class of this starship, such as "Starfighter" or "Deep Space Mobile - * Battlestation" - */ - starshipClass?: Maybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type StarshipFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type StarshipPilotConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type StarshipFilmsConnection = { - __typename?: 'StarshipFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipFilmsEdge = { - __typename?: 'StarshipFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type StarshipPilotsConnection = { - __typename?: 'StarshipPilotsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - pilots?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipPilotsEdge = { - __typename?: 'StarshipPilotsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type StarshipsConnection = { - __typename?: 'StarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipsEdge = { - __typename?: 'StarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type Vehicle = Node & { - __typename?: 'Vehicle'; - /** The maximum number of kilograms that this vehicle can transport. */ - cargoCapacity?: Maybe; - /** - * The maximum length of time that this vehicle can provide consumables for its - * entire crew without having to resupply. - */ - consumables?: Maybe; - /** The cost of this vehicle new, in Galactic Credits. */ - costInCredits?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The number of personnel needed to run or pilot this vehicle. */ - crew?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The length of this vehicle in meters. */ - length?: Maybe; - /** The manufacturers of this vehicle. */ - manufacturers?: Maybe>>; - /** The maximum speed of this vehicle in atmosphere. */ - maxAtmospheringSpeed?: Maybe; - /** - * The model or official name of this vehicle. Such as "All-Terrain Attack - * Transport". - */ - model?: Maybe; - /** - * The name of this vehicle. The common name, such as "Sand Crawler" or "Speeder - * bike". - */ - name?: Maybe; - /** The number of non-essential people this vehicle can transport. */ - passengers?: Maybe; - pilotConnection?: Maybe; - /** The class of this vehicle, such as "Wheeled" or "Repulsorcraft". */ - vehicleClass?: Maybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type VehicleFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type VehiclePilotConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type VehicleFilmsConnection = { - __typename?: 'VehicleFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type VehicleFilmsEdge = { - __typename?: 'VehicleFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type VehiclePilotsConnection = { - __typename?: 'VehiclePilotsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - pilots?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type VehiclePilotsEdge = { - __typename?: 'VehiclePilotsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type VehiclesConnection = { - __typename?: 'VehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type VehiclesEdge = { - __typename?: 'VehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; export type AllFilmsWithVariablesQueryQueryVariables = Exact<{ - first: Scalars['Int']['input']; + first: number; }>; export type AllFilmsWithVariablesQueryQuery = { - __typename?: 'Root'; - allFilms?: { - __typename?: 'FilmsConnection'; - edges?: Array<{ - __typename?: 'FilmsEdge'; - node?: - | ({ __typename?: 'Film' } & { ' $fragmentRefs'?: { FilmItemFragment: FilmItemFragment } }) - | null; + allFilms: { + edges: Array<{ + node: { ' $fragmentRefs'?: { FilmItemFragment: FilmItemFragment } } | null; } | null> | null; } | null; }; export type FilmItemFragment = { - __typename?: 'Film'; id: string; - title?: string | null; - releaseDate?: string | null; - producers?: Array | null; + title: string | null; + releaseDate: string | null; + producers: Array | null; } & { ' $fragmentName'?: 'FilmItemFragment' }; export const FilmItemFragmentDoc = { diff --git a/examples/vue/villus/package.json b/examples/vue/villus/package.json index 842a4df9636..3fd0ff5ade0 100644 --- a/examples/vue/villus/package.json +++ b/examples/vue/villus/package.json @@ -16,7 +16,7 @@ "vue": "^3.2.37" }, "devDependencies": { - "@graphql-codegen/cli": "^6.3.1", + "@graphql-codegen/cli": "^7.0.0", "@vitejs/plugin-vue": "^6.0.0", "cypress": "15.14.2", "serve": "14.2.6", diff --git a/examples/vue/villus/src/gql/graphql.ts b/examples/vue/villus/src/gql/graphql.ts index ba3e733af05..32b8b38e8d3 100644 --- a/examples/vue/villus/src/gql/graphql.ts +++ b/examples/vue/villus/src/gql/graphql.ts @@ -1,1308 +1,30 @@ -/* eslint-disable */ import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; -export type Maybe = T | null; -export type InputMaybe = T | null | undefined; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/* eslint-disable */ +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 }; -}; - -/** A single film. */ -export type Film = Node & { - __typename?: 'Film'; - characterConnection?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The name of the director of this film. */ - director?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** The episode number of this film. */ - episodeID?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The opening paragraphs at the beginning of this film. */ - openingCrawl?: Maybe; - planetConnection?: Maybe; - /** The name(s) of the producer(s) of this film. */ - producers?: Maybe>>; - /** The ISO 8601 date format of film release at original creator country. */ - releaseDate?: Maybe; - speciesConnection?: Maybe; - starshipConnection?: Maybe; - /** The title of this film. */ - title?: Maybe; - vehicleConnection?: Maybe; -}; - -/** A single film. */ -export type FilmCharacterConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmPlanetConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmSpeciesConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmStarshipConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single film. */ -export type FilmVehicleConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type FilmCharactersConnection = { - __typename?: 'FilmCharactersConnection'; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - characters?: Maybe>>; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmCharactersEdge = { - __typename?: 'FilmCharactersEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmPlanetsConnection = { - __typename?: 'FilmPlanetsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - planets?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmPlanetsEdge = { - __typename?: 'FilmPlanetsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmSpeciesConnection = { - __typename?: 'FilmSpeciesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - species?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmSpeciesEdge = { - __typename?: 'FilmSpeciesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmStarshipsConnection = { - __typename?: 'FilmStarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmStarshipsEdge = { - __typename?: 'FilmStarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmVehiclesConnection = { - __typename?: 'FilmVehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type FilmVehiclesEdge = { - __typename?: 'FilmVehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type FilmsConnection = { - __typename?: 'FilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type FilmsEdge = { - __typename?: 'FilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** An object with an ID */ -export type Node = { - /** The id of the object. */ - id: Scalars['ID']['output']; -}; - -/** Information about pagination in a connection. */ -export type PageInfo = { - __typename?: 'PageInfo'; - /** When paginating forwards, the cursor to continue. */ - endCursor?: Maybe; - /** When paginating forwards, are there more items? */ - hasNextPage: Scalars['Boolean']['output']; - /** When paginating backwards, are there more items? */ - hasPreviousPage: Scalars['Boolean']['output']; - /** When paginating backwards, the cursor to continue. */ - startCursor?: Maybe; -}; - -/** A connection to a list of items. */ -export type PeopleConnection = { - __typename?: 'PeopleConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - people?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PeopleEdge = { - __typename?: 'PeopleEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type Person = Node & { - __typename?: 'Person'; - /** - * The birth year of the person, using the in-universe standard of BBY or ABY - - * Before the Battle of Yavin or After the Battle of Yavin. The Battle of Yavin is - * a battle that occurs at the end of Star Wars episode IV: A New Hope. - */ - birthYear?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** - * The eye color of this person. Will be "unknown" if not known or "n/a" if the - * person does not have an eye. - */ - eyeColor?: Maybe; - filmConnection?: Maybe; - /** - * The gender of this person. Either "Male", "Female" or "unknown", - * "n/a" if the person does not have a gender. - */ - gender?: Maybe; - /** - * The hair color of this person. Will be "unknown" if not known or "n/a" if the - * person does not have hair. - */ - hairColor?: Maybe; - /** The height of the person in centimeters. */ - height?: Maybe; - /** A planet that this person was born on or inhabits. */ - homeworld?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The mass of the person in kilograms. */ - mass?: Maybe; - /** The name of this person. */ - name?: Maybe; - /** The skin color of this person. */ - skinColor?: Maybe; - /** The species that this person belongs to, or null if unknown. */ - species?: Maybe; - starshipConnection?: Maybe; - vehicleConnection?: Maybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonStarshipConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** An individual person or character within the Star Wars universe. */ -export type PersonVehicleConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type PersonFilmsConnection = { - __typename?: 'PersonFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PersonFilmsEdge = { - __typename?: 'PersonFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PersonStarshipsConnection = { - __typename?: 'PersonStarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PersonStarshipsEdge = { - __typename?: 'PersonStarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PersonVehiclesConnection = { - __typename?: 'PersonVehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type PersonVehiclesEdge = { - __typename?: 'PersonVehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type Planet = Node & { - __typename?: 'Planet'; - /** The climates of this planet. */ - climates?: Maybe>>; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The diameter of this planet in kilometers. */ - diameter?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** - * A number denoting the gravity of this planet, where "1" is normal or 1 standard - * G. "2" is twice or 2 standard Gs. "0.5" is half or 0.5 standard Gs. - */ - gravity?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The name of this planet. */ - name?: Maybe; - /** - * The number of standard days it takes for this planet to complete a single orbit - * of its local star. - */ - orbitalPeriod?: Maybe; - /** The average population of sentient beings inhabiting this planet. */ - population?: Maybe; - residentConnection?: Maybe; - /** - * The number of standard hours it takes for this planet to complete a single - * rotation on its axis. - */ - rotationPeriod?: Maybe; - /** - * The percentage of the planet surface that is naturally occurring water or bodies - * of water. - */ - surfaceWater?: Maybe; - /** The terrains of this planet. */ - terrains?: Maybe>>; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type PlanetFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** - * A large mass, planet or planetoid in the Star Wars Universe, at the time of - * 0 ABY. - */ -export type PlanetResidentConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type PlanetFilmsConnection = { - __typename?: 'PlanetFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetFilmsEdge = { - __typename?: 'PlanetFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PlanetResidentsConnection = { - __typename?: 'PlanetResidentsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - residents?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetResidentsEdge = { - __typename?: 'PlanetResidentsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type PlanetsConnection = { - __typename?: 'PlanetsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - planets?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type PlanetsEdge = { - __typename?: 'PlanetsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -export type Root = { - __typename?: 'Root'; - allFilms?: Maybe; - allPeople?: Maybe; - allPlanets?: Maybe; - allSpecies?: Maybe; - allStarships?: Maybe; - allVehicles?: Maybe; - film?: Maybe; - /** Fetches an object given its ID */ - node?: Maybe; - person?: Maybe; - planet?: Maybe; - species?: Maybe; - starship?: Maybe; - vehicle?: Maybe; -}; - -export type RootAllFilmsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllPeopleArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllPlanetsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllSpeciesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllStarshipsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootAllVehiclesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -export type RootFilmArgs = { - filmID?: InputMaybe; - id?: InputMaybe; -}; - -export type RootNodeArgs = { - id: Scalars['ID']['input']; -}; - -export type RootPersonArgs = { - id?: InputMaybe; - personID?: InputMaybe; -}; - -export type RootPlanetArgs = { - id?: InputMaybe; - planetID?: InputMaybe; -}; - -export type RootSpeciesArgs = { - id?: InputMaybe; - speciesID?: InputMaybe; -}; - -export type RootStarshipArgs = { - id?: InputMaybe; - starshipID?: InputMaybe; -}; - -export type RootVehicleArgs = { - id?: InputMaybe; - vehicleID?: InputMaybe; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type Species = Node & { - __typename?: 'Species'; - /** The average height of this species in centimeters. */ - averageHeight?: Maybe; - /** The average lifespan of this species in years, null if unknown. */ - averageLifespan?: Maybe; - /** The classification of this species, such as "mammal" or "reptile". */ - classification?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The designation of this species, such as "sentient". */ - designation?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - /** - * Common eye colors for this species, null if this species does not typically - * have eyes. - */ - eyeColors?: Maybe>>; - filmConnection?: Maybe; - /** - * Common hair colors for this species, null if this species does not typically - * have hair. - */ - hairColors?: Maybe>>; - /** A planet that this species originates from. */ - homeworld?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The language commonly spoken by this species. */ - language?: Maybe; - /** The name of this species. */ - name?: Maybe; - personConnection?: Maybe; - /** - * Common skin colors for this species, null if this species does not typically - * have skin. - */ - skinColors?: Maybe>>; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type SpeciesFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A type of person or character within the Star Wars Universe. */ -export type SpeciesPersonConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type SpeciesConnection = { - __typename?: 'SpeciesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - species?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesEdge = { - __typename?: 'SpeciesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type SpeciesFilmsConnection = { - __typename?: 'SpeciesFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesFilmsEdge = { - __typename?: 'SpeciesFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type SpeciesPeopleConnection = { - __typename?: 'SpeciesPeopleConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - people?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type SpeciesPeopleEdge = { - __typename?: 'SpeciesPeopleEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type Starship = Node & { - __typename?: 'Starship'; - /** - * The Maximum number of Megalights this starship can travel in a standard hour. - * A "Megalight" is a standard unit of distance and has never been defined before - * within the Star Wars universe. This figure is only really useful for measuring - * the difference in speed of starships. We can assume it is similar to AU, the - * distance between our Sun (Sol) and Earth. - */ - MGLT?: Maybe; - /** The maximum number of kilograms that this starship can transport. */ - cargoCapacity?: Maybe; - /** - * The maximum length of time that this starship can provide consumables for its - * entire crew without having to resupply. - */ - consumables?: Maybe; - /** The cost of this starship new, in galactic credits. */ - costInCredits?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The number of personnel needed to run or pilot this starship. */ - crew?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** The class of this starships hyperdrive. */ - hyperdriveRating?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The length of this starship in meters. */ - length?: Maybe; - /** The manufacturers of this starship. */ - manufacturers?: Maybe>>; - /** - * The maximum speed of this starship in atmosphere. null if this starship is - * incapable of atmosphering flight. - */ - maxAtmospheringSpeed?: Maybe; - /** - * The model or official name of this starship. Such as "T-65 X-wing" or "DS-1 - * Orbital Battle Station". - */ - model?: Maybe; - /** The name of this starship. The common name, such as "Death Star". */ - name?: Maybe; - /** The number of non-essential people this starship can transport. */ - passengers?: Maybe; - pilotConnection?: Maybe; - /** - * The class of this starship, such as "Starfighter" or "Deep Space Mobile - * Battlestation" - */ - starshipClass?: Maybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type StarshipFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single transport craft that has hyperdrive capability. */ -export type StarshipPilotConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type StarshipFilmsConnection = { - __typename?: 'StarshipFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipFilmsEdge = { - __typename?: 'StarshipFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type StarshipPilotsConnection = { - __typename?: 'StarshipPilotsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - pilots?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipPilotsEdge = { - __typename?: 'StarshipPilotsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type StarshipsConnection = { - __typename?: 'StarshipsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - starships?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type StarshipsEdge = { - __typename?: 'StarshipsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type Vehicle = Node & { - __typename?: 'Vehicle'; - /** The maximum number of kilograms that this vehicle can transport. */ - cargoCapacity?: Maybe; - /** - * The maximum length of time that this vehicle can provide consumables for its - * entire crew without having to resupply. - */ - consumables?: Maybe; - /** The cost of this vehicle new, in Galactic Credits. */ - costInCredits?: Maybe; - /** The ISO 8601 date format of the time that this resource was created. */ - created?: Maybe; - /** The number of personnel needed to run or pilot this vehicle. */ - crew?: Maybe; - /** The ISO 8601 date format of the time that this resource was edited. */ - edited?: Maybe; - filmConnection?: Maybe; - /** The ID of an object */ - id: Scalars['ID']['output']; - /** The length of this vehicle in meters. */ - length?: Maybe; - /** The manufacturers of this vehicle. */ - manufacturers?: Maybe>>; - /** The maximum speed of this vehicle in atmosphere. */ - maxAtmospheringSpeed?: Maybe; - /** - * The model or official name of this vehicle. Such as "All-Terrain Attack - * Transport". - */ - model?: Maybe; - /** - * The name of this vehicle. The common name, such as "Sand Crawler" or "Speeder - * bike". - */ - name?: Maybe; - /** The number of non-essential people this vehicle can transport. */ - passengers?: Maybe; - pilotConnection?: Maybe; - /** The class of this vehicle, such as "Wheeled" or "Repulsorcraft". */ - vehicleClass?: Maybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type VehicleFilmConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A single transport craft that does not have hyperdrive capability */ -export type VehiclePilotConnectionArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - -/** A connection to a list of items. */ -export type VehicleFilmsConnection = { - __typename?: 'VehicleFilmsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - films?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type VehicleFilmsEdge = { - __typename?: 'VehicleFilmsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type VehiclePilotsConnection = { - __typename?: 'VehiclePilotsConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - pilots?: Maybe>>; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; -}; - -/** An edge in a connection. */ -export type VehiclePilotsEdge = { - __typename?: 'VehiclePilotsEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; - -/** A connection to a list of items. */ -export type VehiclesConnection = { - __typename?: 'VehiclesConnection'; - /** A list of edges. */ - edges?: Maybe>>; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - /** - * A count of the total number of objects in this connection, ignoring pagination. - * This allows a client to fetch the first five objects by passing "5" as the - * argument to "first", then fetch the total count so it could display "5 of 83", - * for example. - */ - totalCount?: Maybe; - /** - * A list of all of the objects returned in the connection. This is a convenience - * field provided for quickly exploring the API; rather than querying for - * "{ edges { node } }" when no edge data is needed, this field can be be used - * instead. Note that when clients like Relay need to fetch the "cursor" field on - * the edge to enable efficient pagination, this shortcut cannot be used, and the - * full "{ edges { node } }" version should be used instead. - */ - vehicles?: Maybe>>; -}; - -/** An edge in a connection. */ -export type VehiclesEdge = { - __typename?: 'VehiclesEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node?: Maybe; -}; export type AllFilmsWithVariablesQueryQueryVariables = Exact<{ - first: Scalars['Int']['input']; + first: number; }>; export type AllFilmsWithVariablesQueryQuery = { - __typename?: 'Root'; - allFilms?: { - __typename?: 'FilmsConnection'; - edges?: Array<{ - __typename?: 'FilmsEdge'; - node?: - | ({ __typename?: 'Film' } & { ' $fragmentRefs'?: { FilmItemFragment: FilmItemFragment } }) - | null; + allFilms: { + edges: Array<{ + node: { ' $fragmentRefs'?: { FilmItemFragment: FilmItemFragment } } | null; } | null> | null; } | null; }; export type FilmItemFragment = { - __typename?: 'Film'; id: string; - title?: string | null; - releaseDate?: string | null; - producers?: Array | null; + title: string | null; + releaseDate: string | null; + producers: Array | null; } & { ' $fragmentName'?: 'FilmItemFragment' }; export const FilmItemFragmentDoc = { diff --git a/examples/yoga-tests/package.json b/examples/yoga-tests/package.json index 341c08a140f..b0787544ad6 100644 --- a/examples/yoga-tests/package.json +++ b/examples/yoga-tests/package.json @@ -15,7 +15,7 @@ "@babel/core": "7.29.0", "@babel/preset-env": "7.29.2", "@babel/preset-typescript": "7.28.5", - "@graphql-codegen/cli": "6.3.1", + "@graphql-codegen/cli": "7.0.0", "@graphql-typed-document-node/core": "3.2.0" }, "bob": false diff --git a/examples/yoga-tests/src/gql/graphql.ts b/examples/yoga-tests/src/gql/graphql.ts index d7443c95ea4..299a5f4e2bc 100644 --- a/examples/yoga-tests/src/gql/graphql.ts +++ b/examples/yoga-tests/src/gql/graphql.ts @@ -1,49 +1,22 @@ -/* eslint-disable */ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; -export type Maybe = T | null; -export type InputMaybe = T | null | undefined; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { - [_ in K]?: never; -}; +/* eslint-disable */ +/** Internal type. DO NOT USE DIRECTLY. */ +type Exact = { [K in keyof T]: T[K] }; +/** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = | T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 Mutation = { - __typename?: 'Mutation'; - echo: Scalars['String']['output']; -}; - -export type MutationEchoArgs = { - message: Scalars['String']['input']; -}; - -export type Query = { - __typename?: 'Query'; - hello: Scalars['String']['output']; -}; export type HelloQueryQueryVariables = Exact<{ [key: string]: never }>; -export type HelloQueryQuery = { __typename?: 'Query'; hello: string }; +export type HelloQueryQuery = { hello: string }; export type EchoMutationMutationVariables = Exact<{ - message: Scalars['String']['input']; + message: string; }>; -export type EchoMutationMutation = { __typename?: 'Mutation'; echo: string }; +export type EchoMutationMutation = { echo: string }; export const HelloQueryDocument = { kind: 'Document', diff --git a/package.json b/package.json index 40bc5a71ce2..d0bab60e50f 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "packages/plugins/other/*", "packages/presets/*", "website", - "examples/**/*" + "examples/**/*", + "dev-test-apollo-tooling" ], "packageManager": "yarn@1.22.22", "engines": { @@ -93,6 +94,7 @@ "**/*.{js,jsx,cjs,mjs,ts,tsx,graphql,gql,yml,yaml,json,md}": [ "prettier --write" ], + "**/__generated__/**": [], "yarn.lock": [ "npx yarn-deduplicate" ] diff --git a/packages/graphql-codegen-cli/CHANGELOG.md b/packages/graphql-codegen-cli/CHANGELOG.md index 7014a5de5ed..6da49d0158d 100644 --- a/packages/graphql-codegen-cli/CHANGELOG.md +++ b/packages/graphql-codegen-cli/CHANGELOG.md @@ -1,5 +1,123 @@ # @graphql-codegen/cli +## 7.0.0 + +### Major Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Update deps to latest, some + only support ESM + + Node 20 support is dropped in this release. Node 22 comes with `require()` support for ESM, which + means it's easier to integrate ES modules into applications. Therefore, it is safe to start using + ESM-only packages. + + If you are a user, please upgrade to Node 22. If you are a lib maintainer and see ESM vs CJS + issues when running Jest tests, try using Vitest. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Drop Node 20 support + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Set `noSilentErrors: true` + by default + + When multiple files match documents pattern, and there are syntax errors in some but not others, + then the operations with errors are not included in the loaded documents list by default + (`noSilentErrors: false`). This is annoying for users as there is no feedback loop during + development. + + `noSilentErrors: true` is used as the default for Codegen users to make the feedback loop faster. + It can still overriden in Codegen Config if desired. + +### Patch Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - dependencies updates: + - Updated dependency + [`@inquirer/prompts@^8.3.2` ↗︎](https://www.npmjs.com/package/@inquirer/prompts/v/8.3.2) (from + `^7.8.2`, in `dependencies`) + - Updated dependency [`chalk@^5.6.0` ↗︎](https://www.npmjs.com/package/chalk/v/5.6.0) (from + `^4.1.0`, in `dependencies`) + - Updated dependency [`debounce@^3.0.0` ↗︎](https://www.npmjs.com/package/debounce/v/3.0.0) (from + `^2.0.0`, in `dependencies`) + - Updated dependency + [`detect-indent@^7.0.0` ↗︎](https://www.npmjs.com/package/detect-indent/v/7.0.0) (from `^6.0.0`, + in `dependencies`) + - Updated dependency [`listr2@^10.2.1` ↗︎](https://www.npmjs.com/package/listr2/v/10.2.1) (from + `^9.0.0`, in `dependencies`) + - Updated dependency [`log-symbols@^7.0.0` ↗︎](https://www.npmjs.com/package/log-symbols/v/7.0.0) + (from `^4.0.0`, in `dependencies`) + - Updated dependency [`ts-log@^3.0.0` ↗︎](https://www.npmjs.com/package/ts-log/v/3.0.0) (from + `^2.2.3`, in `dependencies`) + - Updated dependency [`yargs@^18.0.0` ↗︎](https://www.npmjs.com/package/yargs/v/18.0.0) (from + `^17.0.0`, in `dependencies`) + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - dependencies updates: + - Updated dependency [`chalk@^5.6.0` ↗︎](https://www.npmjs.com/package/chalk/v/5.6.0) (from + `^4.1.0`, in `dependencies`) + - Updated dependency [`debounce@^3.0.0` ↗︎](https://www.npmjs.com/package/debounce/v/3.0.0) (from + `^2.0.0`, in `dependencies`) + - Updated dependency + [`detect-indent@^7.0.0` ↗︎](https://www.npmjs.com/package/detect-indent/v/7.0.0) (from `^6.0.0`, + in `dependencies`) + - Updated dependency [`listr2@^10.2.1` ↗︎](https://www.npmjs.com/package/listr2/v/10.2.1) (from + `^9.0.0`, in `dependencies`) + - Updated dependency [`log-symbols@^7.0.0` ↗︎](https://www.npmjs.com/package/log-symbols/v/7.0.0) + (from `^4.0.0`, in `dependencies`) + - Updated dependency [`ts-log@^3.0.0` ↗︎](https://www.npmjs.com/package/ts-log/v/3.0.0) (from + `^2.2.3`, in `dependencies`) + - Updated dependency [`yargs@^18.0.0` ↗︎](https://www.npmjs.com/package/yargs/v/18.0.0) (from + `^17.0.0`, in `dependencies`) + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - dependencies updates: + - Updated dependency + [`@inquirer/prompts@^8.3.2` ↗︎](https://www.npmjs.com/package/@inquirer/prompts/v/8.3.2) (from + `^7.8.2`, in `dependencies`) + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Use ESM for CLI instead of CJS; + + For backwards compatibility; `graphql-codegen-esm` is reserved, and also `graphql-codegen-cjs` is + added for users who want to use CJS. + + So the commands are; + - `graphql-codegen` - ESM version, default + - `graphql-codegen-esm` - ESM version, same as above, but reserved for backwards compatibility + - `graphql-codegen-cjs` - CJS version, for users who want to use CJS, but not recommended for new + users. Will be removed in the future. + - `gql-gen` - ESM version, same as `graphql-codegen` + - `graphql-code-generator` - ESM version, same as `graphql-codegen` and `gql-gen` + +- Updated dependencies + [[`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29)]: + - @graphql-codegen/client-preset@6.0.0 + - @graphql-codegen/plugin-helpers@7.0.0 + - @graphql-codegen/core@6.0.0 + ## 6.3.1 ### Patch Changes diff --git a/packages/graphql-codegen-cli/package.json b/packages/graphql-codegen-cli/package.json index fb95b79efea..e7a58a3724a 100644 --- a/packages/graphql-codegen-cli/package.json +++ b/packages/graphql-codegen-cli/package.json @@ -1,6 +1,6 @@ { "name": "@graphql-codegen/cli", - "version": "6.3.1", + "version": "7.0.0", "type": "module", "repository": { "type": "git", @@ -17,10 +17,11 @@ "node": ">=16" }, "bin": { - "gql-gen": "dist/cjs/bin.js", - "graphql-codegen": "dist/cjs/bin.js", - "graphql-code-generator": "dist/cjs/bin.js", - "graphql-codegen-esm": "dist/esm/bin.js" + "gql-gen": "dist/esm/bin.js", + "graphql-codegen": "dist/esm/bin.js", + "graphql-code-generator": "dist/esm/bin.js", + "graphql-codegen-esm": "dist/esm/bin.js", + "graphql-codegen-cjs": "dist/cjs/bin.js" }, "main": "dist/cjs/index.js", "module": "dist/esm/index.js", @@ -76,9 +77,9 @@ "@babel/generator": "^7.18.13", "@babel/template": "^7.18.10", "@babel/types": "^7.18.13", - "@graphql-codegen/client-preset": "^5.3.0", - "@graphql-codegen/core": "^5.0.2", - "@graphql-codegen/plugin-helpers": "^6.3.0", + "@graphql-codegen/client-preset": "^6.0.0", + "@graphql-codegen/core": "^6.0.0", + "@graphql-codegen/plugin-helpers": "^7.0.0", "@graphql-tools/apollo-engine-loader": "^8.0.28", "@graphql-tools/code-file-loader": "^8.1.28", "@graphql-tools/git-loader": "^8.0.32", @@ -89,34 +90,34 @@ "@graphql-tools/merge": "^9.0.6", "@graphql-tools/url-loader": "^9.0.6", "@graphql-tools/utils": "^11.0.0", - "@inquirer/prompts": "^7.8.2", + "@inquirer/prompts": "^8.3.2", "@whatwg-node/fetch": "^0.10.0", - "chalk": "^4.1.0", + "chalk": "^5.6.0", "cosmiconfig": "^9.0.0", - "debounce": "^2.0.0", - "detect-indent": "^6.0.0", + "debounce": "^3.0.0", + "detect-indent": "^7.0.0", "graphql-config": "^5.1.6", "is-glob": "^4.0.1", "jiti": "^2.3.0", "json-to-pretty-yaml": "^1.2.2", - "listr2": "^9.0.0", - "log-symbols": "^4.0.0", + "listr2": "^10.2.1", + "log-symbols": "^7.0.0", "micromatch": "^4.0.5", "shell-quote": "^1.7.3", "string-env-interpolation": "^1.0.1", - "ts-log": "^2.2.3", + "ts-log": "^3.0.0", "tslib": "^2.4.0", "yaml": "^2.3.1", - "yargs": "^17.0.0" + "yargs": "^18.0.0" }, "devDependencies": { + "@inquirer/testing": "3.3.2", "@parcel/watcher": "^2.1.0", "@types/is-glob": "4.0.4", "@types/js-yaml": "4.0.9", "@types/micromatch": "^4.0.2", "@types/shell-quote": "1.7.5", - "bdd-stdin": "0.2.0", - "change-case-all": "1.0.15", + "change-case-all": "2.1.0", "js-yaml": "4.1.1", "make-dir": "5.1.0", "prettier": "3.8.3" diff --git a/packages/graphql-codegen-cli/src/config.ts b/packages/graphql-codegen-cli/src/config.ts index e04547b1ad0..845c5274cc4 100644 --- a/packages/graphql-codegen-cli/src/config.ts +++ b/packages/graphql-codegen-cli/src/config.ts @@ -418,6 +418,7 @@ export class CodegenContext { } const config = { + noSilentErrors: true, // When a `documents` pattern matches multiple files e.g. `*` exists in filename like `src/something.*.ts`, and some files fail but some pass syntax error check, the failed files will silently fail if `noSilentErrors: false`. So, `noSilentErrors: true` is turned on by default to help users detect errors faster. ...extraConfig, ...this.config, }; diff --git a/packages/graphql-codegen-cli/src/init/index.ts b/packages/graphql-codegen-cli/src/init/index.ts index 53ce1b85a1a..6abcfa28b3b 100644 --- a/packages/graphql-codegen-cli/src/init/index.ts +++ b/packages/graphql-codegen-cli/src/init/index.ts @@ -15,7 +15,7 @@ export async function init() { Answer few questions and we will setup everything for you. `); - const possibleTargets = await guessTargets(); + const possibleTargets = guessTargets(); const answers = await getAnswers(possibleTargets); // define config diff --git a/packages/graphql-codegen-cli/src/init/targets.ts b/packages/graphql-codegen-cli/src/init/targets.ts index 1c536dd895f..8d4f3e87ea7 100644 --- a/packages/graphql-codegen-cli/src/init/targets.ts +++ b/packages/graphql-codegen-cli/src/init/targets.ts @@ -2,7 +2,7 @@ import { readFileSync } from 'fs'; import { resolve } from 'path'; import { Tags } from './types.js'; -export async function guessTargets(): Promise> { +export function guessTargets(): Record { const pkg = JSON.parse(readFileSync(resolve(process.cwd(), 'package.json'), 'utf8')); const dependencies = Object.keys({ ...pkg.dependencies, diff --git a/packages/graphql-codegen-cli/tests/__snapshots__/init.spec.ts.snap b/packages/graphql-codegen-cli/tests/__snapshots__/init.spec.ts.snap deleted file mode 100644 index 0782ac6737f..00000000000 --- a/packages/graphql-codegen-cli/tests/__snapshots__/init.spec.ts.snap +++ /dev/null @@ -1,134 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`init > custom setup 1`] = ` -" -import type { CodegenConfig } from '@graphql-codegen/cli'; - -const config: CodegenConfig = { - overwrite: true, - schema: "http://localhost:4000", - documents: "graphql/*.ts", - generates: { - "src/gql/": { - preset: "client", - plugins: [] - }, - "./graphql.schema.json": { - plugins: ["introspection"] - } - } -}; - -export default config; -" -`; - -exports[`init > plugins suggestions for client-side setup > should use angular related plugins when @angular/core is found 1`] = ` -" -import type { CodegenConfig } from '@graphql-codegen/cli'; - -const config: CodegenConfig = { - overwrite: true, - schema: "http://localhost:4000", - documents: "src/**/*.ts", - generates: { - "src/generated/graphql.ts": { - plugins: ["typescript-apollo-angular"] - } - } -}; - -export default config; -" -`; - -exports[`init > plugins suggestions for client-side setup > should use react related plugins when react is found 1`] = ` -" -import type { CodegenConfig } from '@graphql-codegen/cli'; - -const config: CodegenConfig = { - overwrite: true, - schema: "http://localhost:4000", - documents: "src/**/*.tsx", - generates: { - "src/gql/": { - preset: "client", - plugins: [] - } - } -}; - -export default config; -" -`; - -exports[`init > plugins suggestions for client-side setup > should use stencil related plugins when @stencil/core is found 1`] = ` -" -import type { CodegenConfig } from '@graphql-codegen/cli'; - -const config: CodegenConfig = { - overwrite: true, - schema: "http://localhost:4000", - documents: "src/**/*.graphql", - generates: { - "src/generated/graphql.tsx": { - plugins: ["typescript", "typescript-operations", "typescript-stencil-apollo"] - } - } -}; - -export default config; -" -`; - -exports[`init > plugins suggestions non client-side setup > should use typescript related plugins when typescript is found (node) 1`] = ` -" -import type { CodegenConfig } from '@graphql-codegen/cli'; - -const config: CodegenConfig = { - overwrite: true, - schema: "http://localhost:4000", - generates: { - "src/generated/graphql.ts": { - plugins: ["typescript", "typescript-resolvers"] - } - } -}; - -export default config; -" -`; - -exports[`init > should have few default values for Angular 1`] = ` -" -import type { CodegenConfig } from '@graphql-codegen/cli'; - -const config: CodegenConfig = { - overwrite: true, - schema: "http://localhost:4000", - documents: "src/**/*.tsx", - generates: { - "src/gql/": { - preset: "client", - plugins: [] - } - } -}; - -export default config; -" -`; - -exports[`init > should have few default values for React 1`] = ` -"overwrite: true -schema: "./schema.ts" -documents: "graphql/**/*.graphql" -generates: - graphql/index.ts: - preset: "client" - plugins: [] - ./graphql.schema.json: - plugins: - - "introspection" -" -`; diff --git a/packages/graphql-codegen-cli/tests/codegen.spec.ts b/packages/graphql-codegen-cli/tests/codegen.spec.ts index 1108cbbb6a1..a761f837647 100644 --- a/packages/graphql-codegen-cli/tests/codegen.spec.ts +++ b/packages/graphql-codegen-cli/tests/codegen.spec.ts @@ -774,7 +774,7 @@ describe('Codegen Executor', () => { Boolean: { input: boolean; output: boolean; } Int: { input: number; output: number; } Float: { input: number; output: number; } - UniqueID: { input: any; output: any; } + UniqueID: { input: unknown; output: unknown; } };`); }); }); diff --git a/packages/graphql-codegen-cli/tests/generate-and-save.spec.ts b/packages/graphql-codegen-cli/tests/generate-and-save.spec.ts index 137ce27ea52..1c4154b2b2f 100644 --- a/packages/graphql-codegen-cli/tests/generate-and-save.spec.ts +++ b/packages/graphql-codegen-cli/tests/generate-and-save.spec.ts @@ -333,6 +333,40 @@ describe('generate-and-save', () => { } }); + test('Document syntax error - when `*` is used in documents filename pattern, and some failed but some passed, should report error by default (noSilentErrors: true)', async () => { + expect.assertions(6); + outputErrorSpy.mockImplementation(() => true); + try { + await generate( + { + verbose: true, + schema: './tests/test-files/schema-dir/schema.ts', + documents: './tests/test-files/error-document-error-keyword.graphql.*.ts', // Should find `error-document-error-keyword.graphql.1.ts` (failed) and `error-document-error-keyword.graphql.2.ts` (passed) + generates: { + 'src/gql/': { + preset: 'client-preset', + }, + }, + }, + false, + ); + } catch { + // Note: cannot use toMatchInlineSnapshot here because spacing in the snapshot gets formatted by prettier. + expect(outputErrorSpy.mock.calls[0][0]).toContain( + '[FAILED] Failed to load documents from ./tests/test-files/error-document-error-keyword.graphql.*.ts,!src/gql/:', + ); + expect(outputErrorSpy.mock.calls[0][0]).toContain( + '[FAILED] Syntax Error: Unexpected Name "qu".', + ); + expect(outputErrorSpy.mock.calls[0][0]).toContain( + `[FAILED] ${process.cwd()}/tests/test-files/error-document-error-keyword.graphql.1.ts:2:3`, + ); + expect(outputErrorSpy.mock.calls[0][0]).toContain('[FAILED] 2 | qu ery Test {'); + expect(outputErrorSpy.mock.calls[0][0]).toContain('[FAILED] | ^'); + expect(outputErrorSpy.mock.calls[0][0]).toContain('[FAILED] 3 | user {'); + } + }); + test('No documents found - should throw error by default', async () => { expect.assertions(1); outputErrorSpy.mockImplementation(() => true); diff --git a/packages/graphql-codegen-cli/tests/init.spec.ts b/packages/graphql-codegen-cli/tests/init.spec.ts index 738bae293f1..31850c57789 100644 --- a/packages/graphql-codegen-cli/tests/init.spec.ts +++ b/packages/graphql-codegen-cli/tests/init.spec.ts @@ -1,6 +1,6 @@ import { resolve } from 'path'; -import bddStdin from 'bdd-stdin'; import { fs, vol } from 'memfs'; +import { screen } from '@inquirer/testing/vitest'; import { bold } from '../src/init/helpers.js'; import { init } from '../src/init/index.js'; import { getApplicationTypeChoices, getPluginChoices } from '../src/init/questions.js'; @@ -12,11 +12,7 @@ vi.mock('../src/utils/get-latest-version.ts', () => { }); vi.mock('fs', () => require('./__mocks__/fs.cjs')); -const { version } = require('../package.json'); - -const SELECT = ' '; // checkbox -const ENTER = '\n'; -// const DOWN = bddStdin.keys.down; +const version = '888.888.888'; // Mocked CLI version, not important const packageJson = { withAngular: JSON.stringify({ @@ -87,45 +83,45 @@ describe('init', () => { }); describe('guessTargets()', () => { - it('should guess angular projects', async () => { + it('should guess angular projects', () => { vol.fromJSON({ ['package.json']: packageJson.withAngular }, process.cwd()); - const targets = await guessTargets(); + const targets = guessTargets(); expect(targets.Angular).toEqual(true); }); - it('should guess typescript projects', async () => { + it('should guess typescript projects', () => { vol.fromJSON({ ['package.json']: packageJson.withTypescript }, process.cwd()); - const targets = await guessTargets(); + const targets = guessTargets(); expect(targets.TypeScript).toEqual(true); }); - it('should guess react projects', async () => { + it('should guess react projects', () => { vol.fromJSON({ ['package.json']: packageJson.withReact }, process.cwd()); - const targets = await guessTargets(); + const targets = guessTargets(); expect(targets.React).toEqual(true); }); - it('should guess stencil projects', async () => { + it('should guess stencil projects', () => { vol.fromJSON({ ['package.json']: packageJson.withStencil }, process.cwd()); - const targets = await guessTargets(); + const targets = guessTargets(); expect(targets.Stencil).toEqual(true); }); - it('should guess flow projects', async () => { + it('should guess flow projects', () => { vol.fromJSON({ ['package.json']: packageJson.withFlow }, process.cwd()); - const targets = await guessTargets(); + const targets = guessTargets(); expect(targets.Flow).toEqual(true); }); - it('should guess vue projects', async () => { + it('should guess vue projects', () => { vol.fromJSON({ ['package.json']: packageJson.withVue }, process.cwd()); - const targets = await guessTargets(); + const targets = guessTargets(); expect(targets.Vue).toEqual(true); }); - it('should guess graphql-request projects', async () => { + it('should guess graphql-request projects', () => { vol.fromJSON({ ['package.json']: packageJson.withGraphqlRequest }, process.cwd()); - const targets = await guessTargets(); + const targets = guessTargets(); expect(targets.graphqlRequest).toEqual(true); }); }); @@ -134,100 +130,398 @@ describe('init', () => { it('should use angular related plugins when @angular/core is found', async () => { vol.fromJSON({ ['package.json']: packageJson.withAngular }, process.cwd()); const writeFileSpy = vi.spyOn(fs, 'writeFileSync'); - // silent - vi.spyOn(console, 'log').mockImplementation(() => {}); - - useInputs({ - onTarget: [ENTER], // confirm target - onSchema: [ENTER], // use default - onDocuments: [ENTER], - onPlugins: [ENTER], // use selected packages - onOutput: [ENTER], // use default output path - onIntrospection: ['n', ENTER], // no introspection, - onConfig: [ENTER], // use default config path - onScript: ['graphql', ENTER], // use custom npm script - }); - - await init(); + const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); // silent + + const result = init(); + + // targets + expect(screen.getScreen()).toMatchInlineSnapshot(` + "? What type of application are you building? + Backend - API or server + ❯ Application built with Angular + Application built with React + Application built with Stencil + Application built with Vue + Application using graphql-request + Application built with other framework or vanilla JS + + ↑↓ navigate • ⏎ select" + `); + screen.keypress('enter'); + await screen.next(); + + // schema + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? Where is your schema?: (path or url) (http://localhost:4000)"`, + ); + screen.keypress('enter'); + await screen.next(); + + // documents + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? Where are your operations and fragments?: (src/**/*.ts)"`, + ); + screen.keypress('enter'); + await screen.next(); + + // plugins + expect(screen.getScreen()).toMatchInlineSnapshot(` + "? Pick plugins: + ❯◯ Introspection Fragment Matcher (for Apollo Client) + ◉ TypeScript Apollo Angular (typed GQL services) + + ↑↓ navigate • space select • a all • i invert • ⏎ submit" + `); + screen.keypress('enter'); + await screen.next(); + + // output + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? Where to write the output: (src/generated/graphql.ts)"`, + ); + screen.keypress('enter'); + await screen.next(); + + // introspection + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? Do you want to generate an introspection file? (y/N)"`, + ); + screen.keypress('n'); + screen.keypress('enter'); + await screen.next(); + + // config + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? How to name the config file? (codegen.ts)"`, + ); + screen.keypress('enter'); + await screen.next(); + + // script + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? What script in package.json should run the codegen? (codegen)"`, + ); + screen.keypress('enter'); + await result; + + expect(await screen.getFullOutput()).toMatchInlineSnapshot( + ` + "✔ What type of application are you building? Application built with Angular + ✔ Where is your schema?: (path or url) http://localhost:4000 + ✔ Where are your operations and fragments?: src/**/*.ts + ✔ Pick plugins: TypeScript Apollo Angular (typed GQL services) + ✔ Where to write the output: src/generated/graphql.ts + ✔ Do you want to generate an introspection file? No + ✔ How to name the config file? codegen.ts + ✔ What script in package.json should run the codegen? codegen" + `, + ); + + expect(logSpy.mock.calls[2][0]).toContain(`Config file generated at ${bold('codegen.ts')}`); expect(writeFileSpy).toHaveBeenCalledTimes(2); const pkg = JSON.parse(writeFileSpy.mock.calls[1][1] as string); + expect(pkg).toMatchInlineSnapshot(` + { + "dependencies": { + "@angular/core": "x.x.x", + }, + "devDependencies": { + "@graphql-codegen/cli": "1.0.0", + "@graphql-codegen/typescript-apollo-angular": "1.0.0", + }, + "scripts": { + "codegen": "graphql-codegen --config codegen.ts", + }, + "version": "888.888.888", + } + `); + + const configFile = writeFileSpy.mock.calls[0][0] as string; const config = writeFileSpy.mock.calls[0][1] as string; - - expect(config).toMatchSnapshot(); - - // expected plugins - expect(pkg.devDependencies).toEqual({ - '@graphql-codegen/cli': '1.0.0', - '@graphql-codegen/typescript-apollo-angular': '1.0.0', - }); + expect(config).toMatchInlineSnapshot(` + " + import type { CodegenConfig } from '@graphql-codegen/cli'; + + const config: CodegenConfig = { + overwrite: true, + schema: "http://localhost:4000", + documents: "src/**/*.ts", + generates: { + "src/generated/graphql.ts": { + plugins: ["typescript-apollo-angular"] + } + } + }; + + export default config; + " + `); + expect(configFile).toEqual(resolve(process.cwd(), 'codegen.ts')); }); it('should use react related plugins when react is found', async () => { vol.fromJSON({ ['package.json']: packageJson.withReact }, process.cwd()); const writeFileSpy = vi.spyOn(fs, 'writeFileSync'); - // silent - vi.spyOn(console, 'log').mockImplementation(() => {}); - - useInputs({ - onTarget: [ENTER], // confirm react target - onSchema: [ENTER], // use default - onDocuments: [ENTER], - onOutput: [ENTER], // use default output path - onIntrospection: ['n', ENTER], // no introspection, - onConfig: [ENTER], // use default config path - onScript: ['graphql', ENTER], // use custom npm script - }); - - await init(); + const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); + + const result = init(); + + // targets + expect(screen.getScreen()).toMatchInlineSnapshot(` + "? What type of application are you building? + Backend - API or server + Application built with Angular + ❯ Application built with React + Application built with Stencil + Application built with Vue + Application using graphql-request + Application built with other framework or vanilla JS + + ↑↓ navigate • ⏎ select" + `); + screen.keypress('enter'); + await screen.next(); + + // schema + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? Where is your schema?: (path or url) (http://localhost:4000)"`, + ); + screen.keypress('enter'); + await screen.next(); + + // documents + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? Where are your operations and fragments?: (src/**/*.tsx)"`, + ); + screen.keypress('enter'); + await screen.next(); + + // output + expect(screen.getScreen()).toMatchInlineSnapshot(`"? Where to write the output: (src/gql/)"`); + screen.keypress('enter'); + await screen.next(); + + // introspection + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? Do you want to generate an introspection file? (y/N)"`, + ); + screen.keypress('enter'); + await screen.next(); + + // config + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? How to name the config file? (codegen.ts)"`, + ); + screen.keypress('enter'); + await screen.next(); + + // script + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? What script in package.json should run the codegen? (codegen)"`, + ); + screen.keypress('enter'); + await result; + + expect(await screen.getFullOutput()).toMatchInlineSnapshot( + ` + "✔ What type of application are you building? Application built with React + ✔ Where is your schema?: (path or url) http://localhost:4000 + ✔ Where are your operations and fragments?: src/**/*.tsx + ✔ Where to write the output: src/gql/ + ✔ Do you want to generate an introspection file? No + ✔ How to name the config file? codegen.ts + ✔ What script in package.json should run the codegen? codegen" + `, + ); + + expect(logSpy.mock.calls[2][0]).toContain(`Config file generated at codegen.ts`); expect(writeFileSpy).toHaveBeenCalledTimes(2); const pkg = JSON.parse(writeFileSpy.mock.calls[1][1] as string); + expect(pkg).toMatchInlineSnapshot(` + { + "dependencies": { + "react": "x.x.x", + }, + "devDependencies": { + "@graphql-codegen/cli": "1.0.0", + "@graphql-codegen/client-preset": "1.0.0", + }, + "scripts": { + "codegen": "graphql-codegen --config codegen.ts", + }, + "version": "888.888.888", + } + `); + + const configFile = writeFileSpy.mock.calls[0][0] as string; const config = writeFileSpy.mock.calls[0][1] as string; - - expect(config).toMatchSnapshot(); - - // expected plugins - expect(pkg.devDependencies).toHaveProperty('@graphql-codegen/cli'); - expect(pkg.devDependencies).toHaveProperty('@graphql-codegen/client-preset'); - // should not have other plugins - expect(Object.keys(pkg.devDependencies)).toHaveLength(2); + expect(configFile).toEqual(resolve(process.cwd(), 'codegen.ts')); + expect(config).toMatchInlineSnapshot(` + " + import type { CodegenConfig } from '@graphql-codegen/cli'; + + const config: CodegenConfig = { + overwrite: true, + schema: "http://localhost:4000", + documents: "src/**/*.tsx", + generates: { + "src/gql/": { + preset: "client", + plugins: [] + } + } + }; + + export default config; + " + `); }); it('should use stencil related plugins when @stencil/core is found', async () => { vol.fromJSON({ ['package.json']: packageJson.withStencil }, process.cwd()); const writeFileSpy = vi.spyOn(fs, 'writeFileSync'); - // silent - vi.spyOn(console, 'log').mockImplementation(() => {}); - - useInputs({ - onTarget: [ENTER], // confirm stencil target - onSchema: [ENTER], // use default - onDocuments: [ENTER], - onPlugins: [ENTER], // use selected packages - onOutput: [ENTER], // use default output path - onIntrospection: ['n', ENTER], // no introspection, - onConfig: [ENTER], // use default config path - onScript: ['graphql', ENTER], // use custom npm script - }); - - await init(); + const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); // silent + + const result = init(); + + // targets + expect(screen.getScreen()).toMatchInlineSnapshot(` + "? What type of application are you building? + Backend - API or server + Application built with Angular + Application built with React + ❯ Application built with Stencil + Application built with Vue + Application using graphql-request + Application built with other framework or vanilla JS + + ↑↓ navigate • ⏎ select" + `); + screen.keypress('enter'); + await screen.next(); + + // schema + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? Where is your schema?: (path or url) (http://localhost:4000)"`, + ); + screen.keypress('enter'); + await screen.next(); + + // documents + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? Where are your operations and fragments?: (src/**/*.graphql)"`, + ); + screen.keypress('enter'); + await screen.next(); + + // plugins + expect(screen.getScreen()).toMatchInlineSnapshot( + ` + "? Pick plugins: + ❯◉ TypeScript (required by other typescript plugins) + ◉ TypeScript Operations (operations and fragments) + ◉ TypeScript Stencil Apollo (typed components) + ◯ TypeScript GraphQL files modules (declarations for .graphql files) + ◯ TypeScript GraphQL document nodes (embedded GraphQL document) + ◯ Introspection Fragment Matcher (for Apollo Client) + ◯ Urql Introspection (for Urql Client) + + ↑↓ navigate • space select • a all • i invert • ⏎ submit" + `, + ); + screen.keypress('enter'); + await screen.next(); + + // output + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? Where to write the output: (src/generated/graphql.tsx)"`, + ); + screen.keypress('enter'); + await screen.next(); + + // introspection + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? Do you want to generate an introspection file? (y/N)"`, + ); + screen.keypress('n'); + screen.keypress('enter'); + await screen.next(); + + // config + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? How to name the config file? (codegen.ts)"`, + ); + screen.keypress('enter'); + await screen.next(); + + // script + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? What script in package.json should run the codegen? (codegen)"`, + ); + screen.keypress('enter'); + await result; + + expect(await screen.getFullOutput()).toMatchInlineSnapshot( + ` + "✔ What type of application are you building? Application built with Stencil + ✔ Where is your schema?: (path or url) http://localhost:4000 + ✔ Where are your operations and fragments?: src/**/*.graphql + ✔ Pick plugins: TypeScript (required by other typescript plugins), TypeScript Operations (operations and fragments), TypeScript Stencil Apollo (typed components) + ✔ Where to write the output: src/generated/graphql.tsx + ✔ Do you want to generate an introspection file? No + ✔ How to name the config file? codegen.ts + ✔ What script in package.json should run the codegen? codegen" + `, + ); + + expect(logSpy.mock.calls[2][0]).toContain(`Config file generated at codegen.ts`); expect(writeFileSpy).toHaveBeenCalledTimes(2); const pkg = JSON.parse(writeFileSpy.mock.calls[1][1] as string); + expect(pkg).toMatchInlineSnapshot(` + { + "dependencies": { + "@stencil/core": "x.x.x", + }, + "devDependencies": { + "@graphql-codegen/cli": "1.0.0", + "@graphql-codegen/typescript": "1.0.0", + "@graphql-codegen/typescript-operations": "1.0.0", + "@graphql-codegen/typescript-stencil-apollo": "1.0.0", + }, + "scripts": { + "codegen": "graphql-codegen --config codegen.ts", + }, + "version": "888.888.888", + } + `); + + const configFile = writeFileSpy.mock.calls[0][0] as string; const config = writeFileSpy.mock.calls[0][1] as string; - - expect(config).toMatchSnapshot(); - - // expected plugins - expect(pkg.devDependencies).toHaveProperty('@graphql-codegen/typescript'); - expect(pkg.devDependencies).toHaveProperty('@graphql-codegen/typescript-operations'); - expect(pkg.devDependencies).toHaveProperty('@graphql-codegen/typescript-stencil-apollo'); - // should not have other plugins - expect(Object.keys(pkg.devDependencies)).toHaveLength(4); + expect(configFile).toEqual(resolve(process.cwd(), 'codegen.ts')); + expect(config).toMatchInlineSnapshot(` + " + import type { CodegenConfig } from '@graphql-codegen/cli'; + + const config: CodegenConfig = { + overwrite: true, + schema: "http://localhost:4000", + documents: "src/**/*.graphql", + generates: { + "src/generated/graphql.tsx": { + plugins: ["typescript", "typescript-operations", "typescript-stencil-apollo"] + } + } + }; + + export default config; + " + `); }); }); @@ -235,144 +529,275 @@ describe('init', () => { it('should use typescript related plugins when typescript is found (node)', async () => { vol.fromJSON({ ['package.json']: packageJson.withTypescript }, process.cwd()); const writeFileSpy = vi.spyOn(fs, 'writeFileSync'); - // silent - vi.spyOn(console, 'log').mockImplementation(() => {}); - - useInputs({ - onTarget: [SELECT, ENTER], // confirm api target - onSchema: [ENTER], // use default - onPlugins: [ENTER], // use selected packages - onOutput: [ENTER], // use default output path - onIntrospection: ['n', ENTER], // no introspection, - onConfig: [ENTER], // use default config path - onScript: ['graphql', ENTER], // use custom npm script - }); - - await init(); + const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); // silent + + const result = init(); + + // targets + expect(screen.getScreen()).toMatchInlineSnapshot(` + "? What type of application are you building? + ❯ Backend - API or server + Application built with Angular + Application built with React + Application built with Stencil + Application built with Vue + Application using graphql-request + Application built with other framework or vanilla JS + + ↑↓ navigate • ⏎ select" + `); + screen.keypress('enter'); + await screen.next(); + + // schema + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? Where is your schema?: (path or url) (http://localhost:4000)"`, + ); + screen.keypress('enter'); + await screen.next(); + + // documents + expect(screen.getScreen()).toMatchInlineSnapshot( + ` + "? Pick plugins: + ❯◉ TypeScript (required by other typescript plugins) + ◉ TypeScript Resolvers (strongly typed resolve functions) + ◯ TypeScript MongoDB (typed MongoDB objects) + ◯ TypeScript GraphQL document nodes (embedded GraphQL document) + + ↑↓ navigate • space select • a all • i invert • ⏎ submit" + `, + ); + screen.keypress('enter'); + await screen.next(); + + // output + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? Where to write the output: (src/generated/graphql.ts)"`, + ); + screen.keypress('enter'); + await screen.next(); + + // introspection + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? Do you want to generate an introspection file? (y/N)"`, + ); + screen.keypress('n'); + screen.keypress('enter'); + await screen.next(); + + // config + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? How to name the config file? (codegen.ts)"`, + ); + screen.keypress('enter'); + await screen.next(); + + // script + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? What script in package.json should run the codegen? (codegen)"`, + ); + screen.keypress('enter'); + + await result; + + expect(await screen.getFullOutput()).toMatchInlineSnapshot( + ` + "✔ What type of application are you building? Backend - API or server + ✔ Where is your schema?: (path or url) http://localhost:4000 + ✔ Pick plugins: TypeScript (required by other typescript plugins), TypeScript Resolvers (strongly typed resolve functions) + ✔ Where to write the output: src/generated/graphql.ts + ✔ Do you want to generate an introspection file? No + ✔ How to name the config file? codegen.ts + ✔ What script in package.json should run the codegen? codegen" + `, + ); + + expect(logSpy.mock.calls[2][0]).toContain(`Config file generated at codegen.ts`); expect(writeFileSpy).toHaveBeenCalledTimes(2); const pkg = JSON.parse(writeFileSpy.mock.calls[1][1] as string); + expect(pkg).toMatchInlineSnapshot(` + { + "devDependencies": { + "@graphql-codegen/cli": "1.0.0", + "@graphql-codegen/typescript": "1.0.0", + "@graphql-codegen/typescript-resolvers": "1.0.0", + "typescript": "x.x.x", + }, + "scripts": { + "codegen": "graphql-codegen --config codegen.ts", + }, + "version": "888.888.888", + } + `); + + const configFile = writeFileSpy.mock.calls[0][0] as string; const config = writeFileSpy.mock.calls[0][1] as string; - - expect(config).toMatchSnapshot(); - - // expected plugins - expect(pkg.devDependencies).toHaveProperty('@graphql-codegen/typescript'); - expect(pkg.devDependencies).toHaveProperty('@graphql-codegen/typescript-resolvers'); - // should not have other plugins - expect(Object.keys(pkg.devDependencies)).toHaveLength(4); // 3 - because we have typescript package in devDeps - }); - }); - - it('should have few default values for Angular', async () => { - vol.fromJSON({ ['package.json']: packageJson.withReact }, process.cwd()); - const writeFileSpy = vi.spyOn(fs, 'writeFileSync'); - const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); - const defaults = { - config: 'codegen.ts', - }; - - useInputs({ - onTarget: [ENTER], // confirm angular target - onSchema: [ENTER], // use default - onDocuments: [ENTER], - onOutput: [ENTER], // use default output path - onIntrospection: [ENTER], // no introspection, - onConfig: [ENTER], // use default config path - onScript: ['graphql', ENTER], // use custom npm script + expect(configFile).toEqual(resolve(process.cwd(), 'codegen.ts')); + expect(config).toMatchInlineSnapshot(` + " + import type { CodegenConfig } from '@graphql-codegen/cli'; + + const config: CodegenConfig = { + overwrite: true, + schema: "http://localhost:4000", + generates: { + "src/generated/graphql.ts": { + plugins: ["typescript", "typescript-resolvers"] + } + } + }; + + export default config; + " + `); }); - - await init(); - - const configFile = writeFileSpy.mock.calls[0][0] as string; - const config = writeFileSpy.mock.calls[0][1] as string; - const pkg = JSON.parse(writeFileSpy.mock.calls[1][1] as string); - - expect(pkg.scripts.graphql).toEqual(`graphql-codegen --config codegen.ts`); - expect(configFile).toEqual(resolve(process.cwd(), defaults.config)); - expect(config).toMatchSnapshot(); - expect(logSpy.mock.calls[2][0]).toContain(`Config file generated at ${bold(defaults.config)}`); - }); - - it('should have few default values for React', async () => { - vol.fromJSON({ ['package.json']: packageJson.withReact }, process.cwd()); - const writeFileSpy = vi.spyOn(fs, 'writeFileSync'); - const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); - const options = { - script: 'graphql', - schema: './schema.ts', - documents: 'graphql/**/*.graphql', - output: 'graphql/index.ts', - config: 'app-codegen.yml', - }; - - useInputs({ - onTarget: [ENTER], // confirm target - onSchema: [options.schema, ENTER], // use default - onDocuments: [options.documents, ENTER], - onOutput: [options.output, ENTER], // use default output path - onIntrospection: ['y', ENTER], // with introspection, - onConfig: [options.config, ENTER], // use default config path - onScript: [options.script, ENTER], // use custom npm script - }); - - await init(); - - const configFile = writeFileSpy.mock.calls[0][0] as string; - const config = writeFileSpy.mock.calls[0][1] as string; - const pkg = JSON.parse(writeFileSpy.mock.calls[1][1] as string); - - expect(pkg.scripts[options.script]).toEqual(`graphql-codegen --config ${options.config}`); - expect(configFile).toEqual(resolve(process.cwd(), options.config)); - expect(config).toMatchSnapshot(); - expect(logSpy.mock.calls[2][0]).toContain(`Config file generated at ${bold(options.config)}`); }); it('custom setup', async () => { vol.fromJSON({ ['package.json']: packageJson.withReact }, process.cwd()); - - const { init } = await import('../src/init/index.js'); const writeFileSpy = vi.spyOn(fs, 'writeFileSync'); - const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); - const documents = 'graphql/*.ts'; - const script = 'generate:types'; - - useInputs({ - onTarget: [ENTER], // confirm target - onSchema: [ENTER], // use default - onDocuments: [documents, ENTER], - onOutput: [ENTER], // use default output path - onIntrospection: ['y', ENTER], // no introspection, - onConfig: [ENTER], // use default config path - onScript: [script, ENTER], // use custom npm script - }); + const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); // silent + + const result = init(); + + // targets + expect(screen.getScreen()).toMatchInlineSnapshot(` + "? What type of application are you building? + Backend - API or server + Application built with Angular + ❯ Application built with React + Application built with Stencil + Application built with Vue + Application using graphql-request + Application built with other framework or vanilla JS + + ↑↓ navigate • ⏎ select" + `); + screen.keypress('enter'); + await screen.next(); + + // schema + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? Where is your schema?: (path or url) (http://localhost:4000)"`, + ); + screen.type('./schema.ts'); + screen.keypress('enter'); + await screen.next(); + + // documents + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? Where are your operations and fragments?: (src/**/*.tsx)"`, + ); + screen.type('graphql/*.ts'); + screen.keypress('enter'); + await screen.next(); + + // output + expect(screen.getScreen()).toMatchInlineSnapshot(`"? Where to write the output: (src/gql/)"`); + screen.type('graphql/index.ts'); + screen.keypress('enter'); + await screen.next(); + + // introspection + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? Do you want to generate an introspection file? (y/N)"`, + ); + screen.type('y'); + screen.keypress('enter'); + await screen.next(); - await init(); + // config + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? How to name the config file? (codegen.ts)"`, + ); + screen.type('app-codegen.yml'); + screen.keypress('enter'); + await screen.next(); + + // script + expect(screen.getScreen()).toMatchInlineSnapshot( + `"? What script in package.json should run the codegen? (codegen)"`, + ); + screen.type('generate:types'); + screen.keypress('enter'); + await result; + + expect(await screen.getFullOutput()).toMatchInlineSnapshot( + ` + "✔ What type of application are you building? Application built with React + ✔ Where is your schema?: (path or url) ./schema.ts + ✔ Where are your operations and fragments?: graphql/*.ts + ✔ Where to write the output: graphql/index.ts + ✔ Do you want to generate an introspection file? Yes + ✔ How to name the config file? app-codegen.yml + ✔ What script in package.json should run the codegen? generate:types" + `, + ); + + await result; expect(writeFileSpy).toHaveBeenCalledTimes(2); const pkg = JSON.parse(writeFileSpy.mock.calls[1][1] as string); - const config = writeFileSpy.mock.calls[0][1] as string; + expect(pkg).toMatchInlineSnapshot(` + { + "dependencies": { + "react": "x.x.x", + }, + "devDependencies": { + "@graphql-codegen/cli": "1.0.0", + "@graphql-codegen/client-preset": "1.0.0", + "@graphql-codegen/introspection": "1.0.0", + }, + "scripts": { + "generate:types": "graphql-codegen --config app-codegen.yml", + }, + "version": "888.888.888", + } + `); - // config - expect(config).toMatchSnapshot(); - - // script name should match what we provided - expect(pkg.scripts[script]).toEqual('graphql-codegen --config codegen.ts'); - // expected plugins - expect(pkg.devDependencies).toHaveProperty('@graphql-codegen/introspection'); - // should not have these plugins - expect(pkg.devDependencies).not.toHaveProperty('@graphql-codegen/typescript-resolvers'); + const configFile = writeFileSpy.mock.calls[0][0] as string; + const config = writeFileSpy.mock.calls[0][1] as string; + expect(configFile).toEqual(resolve(process.cwd(), 'app-codegen.yml')); + expect(config).toMatchInlineSnapshot(` + "overwrite: true + schema: "./schema.ts" + documents: "graphql/*.ts" + generates: + graphql/index.ts: + preset: "client" + plugins: [] + ./graphql.schema.json: + plugins: + - "introspection" + " + `); // logs const welcomeMsg = logSpy.mock.calls[0][0]; const doneMsg = logSpy.mock.calls[2][0]; + expect(welcomeMsg).toMatchInlineSnapshot(` + " + Welcome to GraphQL Code Generator! + Answer few questions and we will setup everything for you. + " + `); + expect(doneMsg).toMatchInlineSnapshot(` + " + Config file generated at app-codegen.yml + + $ npm install + + To install the plugins. - expect(welcomeMsg).toContain(`Welcome to ${bold('GraphQL Code Generator')}`); - expect(doneMsg).toContain(`Config file generated at ${bold('codegen.ts')}`); - expect(doneMsg).toContain(bold('$ npm install')); - expect(doneMsg).toContain(bold(`$ npm run ${script}`)); + $ npm run generate:types + + To run GraphQL Code Generator. + " + `); }); describe('plugin choices', () => { @@ -505,27 +930,3 @@ describe('init', () => { }); }); }); - -function useInputs(inputs: { - onTarget: string[]; - onSchema: string[]; - onDocuments?: string[]; - onPlugins?: string[]; - onOutput: string[]; - onIntrospection: string[]; - onConfig: string[]; - onScript: string[]; -}) { - bddStdin( - [].concat( - inputs.onTarget, - inputs.onSchema, - inputs.onDocuments || [], - inputs.onPlugins || [], - inputs.onOutput, - inputs.onIntrospection, - inputs.onConfig, - inputs.onScript, - ), - ); -} diff --git a/packages/graphql-codegen-cli/tests/test-files/error-document-error-keyword.graphql.1.ts b/packages/graphql-codegen-cli/tests/test-files/error-document-error-keyword.graphql.1.ts new file mode 100644 index 00000000000..a19d025d60d --- /dev/null +++ b/packages/graphql-codegen-cli/tests/test-files/error-document-error-keyword.graphql.1.ts @@ -0,0 +1,7 @@ +const query1 = /* GraphQL */ ` + qu ery Test { + user { + one: a + } + } +`; diff --git a/packages/graphql-codegen-cli/tests/test-files/error-document-error-keyword.graphql.2.ts b/packages/graphql-codegen-cli/tests/test-files/error-document-error-keyword.graphql.2.ts new file mode 100644 index 00000000000..70f42047e4b --- /dev/null +++ b/packages/graphql-codegen-cli/tests/test-files/error-document-error-keyword.graphql.2.ts @@ -0,0 +1,7 @@ +const query2 = /* GraphQL */ ` + query Test2 { + user { + two: a + } + } +`; diff --git a/packages/graphql-codegen-core/CHANGELOG.md b/packages/graphql-codegen-core/CHANGELOG.md index eb5a5a1807f..ca854d78a68 100644 --- a/packages/graphql-codegen-core/CHANGELOG.md +++ b/packages/graphql-codegen-core/CHANGELOG.md @@ -1,5 +1,22 @@ # @graphql-codegen/core +## 6.0.0 + +### Major Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Drop Node 20 support + +### Patch Changes + +- Updated dependencies + [[`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29)]: + - @graphql-codegen/plugin-helpers@7.0.0 + ## 5.0.2 ### Patch Changes diff --git a/packages/graphql-codegen-core/package.json b/packages/graphql-codegen-core/package.json index c8953f1afd3..9e6cd40ad53 100644 --- a/packages/graphql-codegen-core/package.json +++ b/packages/graphql-codegen-core/package.json @@ -1,6 +1,6 @@ { "name": "@graphql-codegen/core", - "version": "5.0.2", + "version": "6.0.0", "type": "module", "repository": { "type": "git", @@ -61,7 +61,7 @@ "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" }, "dependencies": { - "@graphql-codegen/plugin-helpers": "^6.3.0", + "@graphql-codegen/plugin-helpers": "^7.0.0", "@graphql-tools/schema": "^10.0.0", "@graphql-tools/utils": "^11.0.0", "tslib": "^2.8.0" diff --git a/packages/plugins/other/add/CHANGELOG.md b/packages/plugins/other/add/CHANGELOG.md index a913c0672d4..5e6e4dd9f07 100644 --- a/packages/plugins/other/add/CHANGELOG.md +++ b/packages/plugins/other/add/CHANGELOG.md @@ -1,5 +1,22 @@ # @graphql-codegen/add +## 7.0.0 + +### Major Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Drop Node 20 support + +### Patch Changes + +- Updated dependencies + [[`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29)]: + - @graphql-codegen/plugin-helpers@7.0.0 + ## 6.0.1 ### Patch Changes diff --git a/packages/plugins/other/add/package.json b/packages/plugins/other/add/package.json index 322b3345e6c..6116f70511c 100644 --- a/packages/plugins/other/add/package.json +++ b/packages/plugins/other/add/package.json @@ -1,6 +1,6 @@ { "name": "@graphql-codegen/add", - "version": "6.0.1", + "version": "7.0.0", "type": "module", "description": "GraphQL Code Generator plugin for adding custom content to your output file", "repository": { @@ -39,7 +39,7 @@ "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" }, "dependencies": { - "@graphql-codegen/plugin-helpers": "^6.3.0", + "@graphql-codegen/plugin-helpers": "^7.0.0", "tslib": "^2.8.0" }, "publishConfig": { diff --git a/packages/plugins/other/fragment-matcher/CHANGELOG.md b/packages/plugins/other/fragment-matcher/CHANGELOG.md index b41e4d1cb93..08456bd4e5b 100644 --- a/packages/plugins/other/fragment-matcher/CHANGELOG.md +++ b/packages/plugins/other/fragment-matcher/CHANGELOG.md @@ -1,5 +1,22 @@ # @graphql-codegen/fragment-matcher +## 7.0.0 + +### Major Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Drop Node 20 support + +### Patch Changes + +- Updated dependencies + [[`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29)]: + - @graphql-codegen/plugin-helpers@7.0.0 + ## 6.0.1 ### Patch Changes diff --git a/packages/plugins/other/fragment-matcher/package.json b/packages/plugins/other/fragment-matcher/package.json index ffb2d0b7f74..7eb75d8a1f9 100644 --- a/packages/plugins/other/fragment-matcher/package.json +++ b/packages/plugins/other/fragment-matcher/package.json @@ -1,6 +1,6 @@ { "name": "@graphql-codegen/fragment-matcher", - "version": "6.0.1", + "version": "7.0.0", "type": "module", "description": "graphql-code-generate plugin for generating fragments matcher introspection file", "repository": { @@ -40,7 +40,7 @@ "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" }, "dependencies": { - "@graphql-codegen/plugin-helpers": "^6.3.0", + "@graphql-codegen/plugin-helpers": "^7.0.0", "tslib": "^2.8.0" }, "publishConfig": { diff --git a/packages/plugins/other/introspection/CHANGELOG.md b/packages/plugins/other/introspection/CHANGELOG.md index f5980c11d5c..dcfc324d711 100644 --- a/packages/plugins/other/introspection/CHANGELOG.md +++ b/packages/plugins/other/introspection/CHANGELOG.md @@ -1,5 +1,43 @@ # @graphql-codegen/introspection +## 6.0.0 + +### Major Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Drop Node 20 support + +### Patch Changes + +- Updated dependencies + [[`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29)]: + - @graphql-codegen/plugin-helpers@7.0.0 + - @graphql-codegen/visitor-plugin-common@7.0.0 + ## 5.0.2 ### Patch Changes diff --git a/packages/plugins/other/introspection/package.json b/packages/plugins/other/introspection/package.json index fcca536509d..812b7f124ac 100644 --- a/packages/plugins/other/introspection/package.json +++ b/packages/plugins/other/introspection/package.json @@ -1,6 +1,6 @@ { "name": "@graphql-codegen/introspection", - "version": "5.0.2", + "version": "6.0.0", "type": "module", "description": "GraphQL Code Generator plugin for generating an introspection JSON file for a GraphQLSchema", "repository": { @@ -40,8 +40,8 @@ "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" }, "dependencies": { - "@graphql-codegen/plugin-helpers": "^6.3.0", - "@graphql-codegen/visitor-plugin-common": "^6.3.0", + "@graphql-codegen/plugin-helpers": "^7.0.0", + "@graphql-codegen/visitor-plugin-common": "^7.0.0", "tslib": "^2.8.0" }, "publishConfig": { diff --git a/packages/plugins/other/schema-ast/CHANGELOG.md b/packages/plugins/other/schema-ast/CHANGELOG.md index 3025f122d76..a0f0ff2c187 100644 --- a/packages/plugins/other/schema-ast/CHANGELOG.md +++ b/packages/plugins/other/schema-ast/CHANGELOG.md @@ -1,5 +1,22 @@ # @graphql-codegen/schema-ast +## 6.0.0 + +### Major Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Drop Node 20 support + +### Patch Changes + +- Updated dependencies + [[`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29)]: + - @graphql-codegen/plugin-helpers@7.0.0 + ## 5.0.2 ### Patch Changes diff --git a/packages/plugins/other/schema-ast/package.json b/packages/plugins/other/schema-ast/package.json index bb636892d3a..576d735fe62 100644 --- a/packages/plugins/other/schema-ast/package.json +++ b/packages/plugins/other/schema-ast/package.json @@ -1,6 +1,6 @@ { "name": "@graphql-codegen/schema-ast", - "version": "5.0.2", + "version": "6.0.0", "type": "module", "description": "GraphQL Code Generator plugin for generating a .graphql file from a given schema", "repository": { @@ -40,7 +40,7 @@ "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" }, "dependencies": { - "@graphql-codegen/plugin-helpers": "^6.3.0", + "@graphql-codegen/plugin-helpers": "^7.0.0", "@graphql-tools/utils": "^11.0.0", "tslib": "^2.8.0" }, diff --git a/packages/plugins/other/time/CHANGELOG.md b/packages/plugins/other/time/CHANGELOG.md index f383358b09a..6a9e2a73454 100644 --- a/packages/plugins/other/time/CHANGELOG.md +++ b/packages/plugins/other/time/CHANGELOG.md @@ -1,75 +1,127 @@ # @graphql-codegen/time +## 7.0.0 + +### Major Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Drop Node 20 support + +### Patch Changes + +- Updated dependencies + [[`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29)]: + - @graphql-codegen/plugin-helpers@7.0.0 + ## 6.0.0 ### Major Changes -- [#10218](https://github.com/dotansimha/graphql-code-generator/pull/10218) [`140298a`](https://github.com/dotansimha/graphql-code-generator/commit/140298a33b257a0b7958e361971b5bc97bbc01c2) Thanks [@eddeee888](https://github.com/eddeee888)! - Drop Node 18 support +- [#10218](https://github.com/dotansimha/graphql-code-generator/pull/10218) + [`140298a`](https://github.com/dotansimha/graphql-code-generator/commit/140298a33b257a0b7958e361971b5bc97bbc01c2) + Thanks [@eddeee888](https://github.com/eddeee888)! - Drop Node 18 support ### Patch Changes -- Updated dependencies [[`140298a`](https://github.com/dotansimha/graphql-code-generator/commit/140298a33b257a0b7958e361971b5bc97bbc01c2), [`140298a`](https://github.com/dotansimha/graphql-code-generator/commit/140298a33b257a0b7958e361971b5bc97bbc01c2), [`140298a`](https://github.com/dotansimha/graphql-code-generator/commit/140298a33b257a0b7958e361971b5bc97bbc01c2), [`140298a`](https://github.com/dotansimha/graphql-code-generator/commit/140298a33b257a0b7958e361971b5bc97bbc01c2), [`140298a`](https://github.com/dotansimha/graphql-code-generator/commit/140298a33b257a0b7958e361971b5bc97bbc01c2), [`140298a`](https://github.com/dotansimha/graphql-code-generator/commit/140298a33b257a0b7958e361971b5bc97bbc01c2), [`140298a`](https://github.com/dotansimha/graphql-code-generator/commit/140298a33b257a0b7958e361971b5bc97bbc01c2), [`140298a`](https://github.com/dotansimha/graphql-code-generator/commit/140298a33b257a0b7958e361971b5bc97bbc01c2), [`140298a`](https://github.com/dotansimha/graphql-code-generator/commit/140298a33b257a0b7958e361971b5bc97bbc01c2)]: +- Updated dependencies + [[`140298a`](https://github.com/dotansimha/graphql-code-generator/commit/140298a33b257a0b7958e361971b5bc97bbc01c2), + [`140298a`](https://github.com/dotansimha/graphql-code-generator/commit/140298a33b257a0b7958e361971b5bc97bbc01c2), + [`140298a`](https://github.com/dotansimha/graphql-code-generator/commit/140298a33b257a0b7958e361971b5bc97bbc01c2), + [`140298a`](https://github.com/dotansimha/graphql-code-generator/commit/140298a33b257a0b7958e361971b5bc97bbc01c2), + [`140298a`](https://github.com/dotansimha/graphql-code-generator/commit/140298a33b257a0b7958e361971b5bc97bbc01c2), + [`140298a`](https://github.com/dotansimha/graphql-code-generator/commit/140298a33b257a0b7958e361971b5bc97bbc01c2), + [`140298a`](https://github.com/dotansimha/graphql-code-generator/commit/140298a33b257a0b7958e361971b5bc97bbc01c2), + [`140298a`](https://github.com/dotansimha/graphql-code-generator/commit/140298a33b257a0b7958e361971b5bc97bbc01c2), + [`140298a`](https://github.com/dotansimha/graphql-code-generator/commit/140298a33b257a0b7958e361971b5bc97bbc01c2)]: - @graphql-codegen/plugin-helpers@6.0.0 ## 5.0.1 ### Patch Changes -- [#9881](https://github.com/dotansimha/graphql-code-generator/pull/9881) [`68ea5d4`](https://github.com/dotansimha/graphql-code-generator/commit/68ea5d4d18969840c34e42bf4f8237e849af7aab) Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates: - - Updated dependency [`moment@~2.30.0` ↗︎](https://www.npmjs.com/package/moment/v/2.30.0) (from `~2.29.1`, in `dependencies`) +- [#9881](https://github.com/dotansimha/graphql-code-generator/pull/9881) + [`68ea5d4`](https://github.com/dotansimha/graphql-code-generator/commit/68ea5d4d18969840c34e42bf4f8237e849af7aab) + Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates: + - Updated dependency [`moment@~2.30.0` ↗︎](https://www.npmjs.com/package/moment/v/2.30.0) (from + `~2.29.1`, in `dependencies`) ## 5.0.0 ### Major Changes -- [`bb66c2a31`](https://github.com/dotansimha/graphql-code-generator/commit/bb66c2a31985c1375912ccd6b2b02933f313c9c0) Thanks [@n1ru4l](https://github.com/n1ru4l)! - Require Node.js `>= 16`. Drop support for Node.js 14 +- [`bb66c2a31`](https://github.com/dotansimha/graphql-code-generator/commit/bb66c2a31985c1375912ccd6b2b02933f313c9c0) + Thanks [@n1ru4l](https://github.com/n1ru4l)! - Require Node.js `>= 16`. Drop support for Node.js + 14 ### Patch Changes -- Updated dependencies [[`4d9ea1a5a`](https://github.com/dotansimha/graphql-code-generator/commit/4d9ea1a5a94cd3458c1bd868ce1ab1cb806257f2), [`f46803a8c`](https://github.com/dotansimha/graphql-code-generator/commit/f46803a8c70840280529a52acbb111c865712af2), [`63827fabe`](https://github.com/dotansimha/graphql-code-generator/commit/63827fabede76b2380d40392aba2a3ccb099f0c4), [`bb66c2a31`](https://github.com/dotansimha/graphql-code-generator/commit/bb66c2a31985c1375912ccd6b2b02933f313c9c0)]: +- Updated dependencies + [[`4d9ea1a5a`](https://github.com/dotansimha/graphql-code-generator/commit/4d9ea1a5a94cd3458c1bd868ce1ab1cb806257f2), + [`f46803a8c`](https://github.com/dotansimha/graphql-code-generator/commit/f46803a8c70840280529a52acbb111c865712af2), + [`63827fabe`](https://github.com/dotansimha/graphql-code-generator/commit/63827fabede76b2380d40392aba2a3ccb099f0c4), + [`bb66c2a31`](https://github.com/dotansimha/graphql-code-generator/commit/bb66c2a31985c1375912ccd6b2b02933f313c9c0)]: - @graphql-codegen/plugin-helpers@5.0.0 ## 4.0.0 ### Major Changes -- [#8885](https://github.com/dotansimha/graphql-code-generator/pull/8885) [`fd0b0c813`](https://github.com/dotansimha/graphql-code-generator/commit/fd0b0c813015cae4f6f6bda5f4c5515e544eb76d) Thanks [@n1ru4l](https://github.com/n1ru4l)! - drop Node.js 12 support +- [#8885](https://github.com/dotansimha/graphql-code-generator/pull/8885) + [`fd0b0c813`](https://github.com/dotansimha/graphql-code-generator/commit/fd0b0c813015cae4f6f6bda5f4c5515e544eb76d) + Thanks [@n1ru4l](https://github.com/n1ru4l)! - drop Node.js 12 support ### Patch Changes -- Updated dependencies [[`fc79b65d4`](https://github.com/dotansimha/graphql-code-generator/commit/fc79b65d4914fd25ae6bd5d58ebc7ded573a08a5), [`fd0b0c813`](https://github.com/dotansimha/graphql-code-generator/commit/fd0b0c813015cae4f6f6bda5f4c5515e544eb76d)]: +- Updated dependencies + [[`fc79b65d4`](https://github.com/dotansimha/graphql-code-generator/commit/fc79b65d4914fd25ae6bd5d58ebc7ded573a08a5), + [`fd0b0c813`](https://github.com/dotansimha/graphql-code-generator/commit/fd0b0c813015cae4f6f6bda5f4c5515e544eb76d)]: - @graphql-codegen/plugin-helpers@4.0.0 ## 3.2.3 ### Patch Changes -- [`46f75304a`](https://github.com/dotansimha/graphql-code-generator/commit/46f75304a69a13e8b5f58303f65c81b30a2ad96a) Thanks [@saihaj](https://github.com/saihaj)! - fix the version of `@graphql-codegen/plugin-helpers@3.1.1` +- [`46f75304a`](https://github.com/dotansimha/graphql-code-generator/commit/46f75304a69a13e8b5f58303f65c81b30a2ad96a) + Thanks [@saihaj](https://github.com/saihaj)! - fix the version of + `@graphql-codegen/plugin-helpers@3.1.1` -- Updated dependencies [[`307a5d350`](https://github.com/dotansimha/graphql-code-generator/commit/307a5d350643dd065d228b04ef3b4bd70cac0e81)]: +- Updated dependencies + [[`307a5d350`](https://github.com/dotansimha/graphql-code-generator/commit/307a5d350643dd065d228b04ef3b4bd70cac0e81)]: - @graphql-codegen/plugin-helpers@3.1.1 ## 3.2.2 ### Patch Changes -- Updated dependencies [[`a6c2097f4`](https://github.com/dotansimha/graphql-code-generator/commit/a6c2097f4789c0cce4296ce349790ce29943ed22), [`f79a00e8a`](https://github.com/dotansimha/graphql-code-generator/commit/f79a00e8ae073eab426ca08795c924e716123482), [`c802a0c0b`](https://github.com/dotansimha/graphql-code-generator/commit/c802a0c0b775cfabc5ace3e7fb6655540c6c4d84)]: +- Updated dependencies + [[`a6c2097f4`](https://github.com/dotansimha/graphql-code-generator/commit/a6c2097f4789c0cce4296ce349790ce29943ed22), + [`f79a00e8a`](https://github.com/dotansimha/graphql-code-generator/commit/f79a00e8ae073eab426ca08795c924e716123482), + [`c802a0c0b`](https://github.com/dotansimha/graphql-code-generator/commit/c802a0c0b775cfabc5ace3e7fb6655540c6c4d84)]: - @graphql-codegen/plugin-helpers@3.0.0 ## 3.2.1 ### Patch Changes -- [#8189](https://github.com/dotansimha/graphql-code-generator/pull/8189) [`b408f8238`](https://github.com/dotansimha/graphql-code-generator/commit/b408f8238c00bbb4cd448501093856c06cfde50f) Thanks [@n1ru4l](https://github.com/n1ru4l)! - Fix CommonJS TypeScript resolution with `moduleResolution` `node16` or `nodenext` +- [#8189](https://github.com/dotansimha/graphql-code-generator/pull/8189) + [`b408f8238`](https://github.com/dotansimha/graphql-code-generator/commit/b408f8238c00bbb4cd448501093856c06cfde50f) + Thanks [@n1ru4l](https://github.com/n1ru4l)! - Fix CommonJS TypeScript resolution with + `moduleResolution` `node16` or `nodenext` -- Updated dependencies [[`b408f8238`](https://github.com/dotansimha/graphql-code-generator/commit/b408f8238c00bbb4cd448501093856c06cfde50f)]: +- Updated dependencies + [[`b408f8238`](https://github.com/dotansimha/graphql-code-generator/commit/b408f8238c00bbb4cd448501093856c06cfde50f)]: - @graphql-codegen/plugin-helpers@2.6.2 ## 3.2.0 ### Minor Changes -- d84afec09: Support TypeScript ESM modules (`"module": "node16"` and `"moduleResolution": "node16"`). +- d84afec09: Support TypeScript ESM modules (`"module": "node16"` and + `"moduleResolution": "node16"`). [More information on the TypeScript Release Notes.](https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#ecmascript-module-support-in-node-js) @@ -110,7 +162,8 @@ ‼️ ‼️ ‼️ Please note ‼️ ‼️ ‼️: - This is a breaking change since Node 10 is no longer supported in `graphql-tools`, and also no longer supported for Codegen packages. + This is a breaking change since Node 10 is no longer supported in `graphql-tools`, and also no + longer supported for Codegen packages. ### Patch Changes @@ -130,7 +183,8 @@ ### Patch Changes - 1d7c6432: Bump all packages to allow "^" in deps and fix compatibility issues -- 1d7c6432: Bump versions of @graphql-tools/ packages to fix issues with loading schemas and SDL comments +- 1d7c6432: Bump versions of @graphql-tools/ packages to fix issues with loading schemas and SDL + comments - Updated dependencies [1d7c6432] - Updated dependencies [1d7c6432] - @graphql-codegen/plugin-helpers@1.17.8 @@ -143,7 +197,8 @@ ## Migration Notes - This only effects developers who used to override the `format`. You now need to specify it with a key! + This only effects developers who used to override the `format`. You now need to specify it with a + key! #### Before diff --git a/packages/plugins/other/time/package.json b/packages/plugins/other/time/package.json index ff3490625ba..b684370091f 100644 --- a/packages/plugins/other/time/package.json +++ b/packages/plugins/other/time/package.json @@ -1,6 +1,6 @@ { "name": "@graphql-codegen/time", - "version": "6.0.0", + "version": "7.0.0", "type": "module", "description": "GraphQL Code Generator plugin for adding the current time for an output file", "repository": { @@ -39,7 +39,7 @@ "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" }, "dependencies": { - "@graphql-codegen/plugin-helpers": "^6.0.0", + "@graphql-codegen/plugin-helpers": "^7.0.0", "moment": "~2.30.0" }, "devDependencies": { diff --git a/packages/plugins/other/visitor-plugin-common/CHANGELOG.md b/packages/plugins/other/visitor-plugin-common/CHANGELOG.md index 2998032680d..05efd1cee28 100644 --- a/packages/plugins/other/visitor-plugin-common/CHANGELOG.md +++ b/packages/plugins/other/visitor-plugin-common/CHANGELOG.md @@ -1,5 +1,204 @@ # @graphql-codegen/visitor-plugin-common +## 7.0.0 + +### Major Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Fix nullable field optionality in operations + + Previously, a nullable Result field is generated as optional (marked by `?` TypeScript modifier) + by default. This is not correct, because generally at runtime such field can only be `null`, and + not `undefined` (both missing from the object OR `undefined`). The only exceptions are when fields + are deferred (using `@defer` directive) or marked as conditional (using `@skip` or `@include`). + + Now, a nullable Result field cannot be optional unless the exceptions are met. This also limits + `avoidOptionals` to only target Variables input, since some users may want to force explicit + `null` when providing operation variables. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: visitors' config option are + moved based on their use case + - addTypename/skipTypename: is only a types-visitor concern. This is moved to types-visitor from + base-visitor + - nonOptionalTypename: is a documents-visitor and types-visitor concern. Moved from base-visitor + there + - extractAllFieldsToTypes: is a documents-visitor concern. Moved from base-visitor there + - enumPrefix and enumSuffix: need to be in base-visitor as all 3 types of visitors need this to + correctly sync the enum type names. This is moved to base visitor + - ignoreEnumValuesFromSchema: is a documents-visitor and types-visitor concern. Moved from + base-visitor there. + - globalNamespace: is a documents-visitor concern. Moved from base-visitor there + + Refactors + - documents-visitor no longer extends types-visitor _option types_ as they have two distinct + usages now. The types now extend base-visitor types. This is now consistent with + documents-visitor extending base-visitor + - Classes now handle config parsing and types at the same level e.g. if typescript-operations + plugin parses configOne, then the types for configOne must be in that class, rather than in + base-documents-visitor + + Note: These visitors are rolled up into one type for simplicity + - base-visitor: includes `base-visitor` + - documents-visitor: includes `base-documents-visitor` and `typescript-operations` visitor + - types-visitor: includes `base-types-visitor` and `typescript` visitor + - resolvers-visitor: includes `base-resolvers-visitor` and `typescript-resolvers` visitor + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: make `unknown` instead of + `any` the default custom scalar type + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Update deps to latest, some + only support ESM + + Node 20 support is dropped in this release. Node 22 comes with `require()` support for ESM, which + means it's easier to integrate ES modules into applications. Therefore, it is safe to start using + ESM-only packages. + + If you are a user, please upgrade to Node 22. If you are a lib maintainer and see ESM vs CJS + issues when running Jest tests, try using Vitest. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Drop Node 20 support + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: + `@graphql-codegen/visitor-plugin-common`'s `base-types-visitor` no longer has `getNodeComment` or + `buildEnumValuesBlock` method. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Operation plugin and Client + Preset no longer generates optional `__typename` for result type + + `__typenam` should not be in the request unless: + - explicitly requested by the user + - automatically injected into the request by clients, such as Apollo Clients. + + Note: Apollo Client users can still use `nonOptionalTypename: true` and + `skipTypeNameForRoot: true` to ensure generated types match the runtime behaviour. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Remove unused utility types + from `typescript` plugin as they were previously used for `typescript-operations` plugin: + - `MakeOptional` + - `MakeMaybe` + - `MakeEmpty` + - `Incremental` + + BREAKING CHANGE: Remove `getRootTypeNames` function because it's available in + `@graphql-utils/tools` and not used anywhere + +### Minor Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Add support for declarationKind for + typescript-operations + - Input: can only be `type` or `interface` + - Variables: no support. It must always be `type` because it's an alias e.g. + `Variables = Exact<{ something: type }>` + - Result: can only be `type` or `interface` + - Note: when `extractAllFieldsToTypes:true` or `extractAllFieldsToTypesCompact:true`, Results + are used as type alias, so they are forced to be `type`. There is a console warning for users. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Add importSchemaTypesFrom support + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Adding config option + extractAllFieldsToTypesCompact, which renders nested types names with field names only (without + types) + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Add generateOperationTypes to + typescript-operations to allow omitting operation types such as Variables, + Query/Mutation/Subscription selection set, and Fragment types + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Fixing 2 bugs: 1) including enums from + external fragments; 2) extractAllFieldsToTypesCompact does not create duplicates + +### Patch Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - dependencies updates: + - Updated dependency [`auto-bind@^5.0.0` ↗︎](https://www.npmjs.com/package/auto-bind/v/5.0.0) (from + `~4.0.0`, in `dependencies`) + - Updated dependency + [`change-case-all@^2.1.0` ↗︎](https://www.npmjs.com/package/change-case-all/v/2.1.0) (from + `1.0.15`, in `dependencies`) + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - dependencies updates: + - Updated dependency [`auto-bind@^5.0.0` ↗︎](https://www.npmjs.com/package/auto-bind/v/5.0.0) (from + `~4.0.0`, in `dependencies`) + - Updated dependency + [`change-case-all@^2.1.0` ↗︎](https://www.npmjs.com/package/change-case-all/v/2.1.0) (from + `1.0.15`, in `dependencies`) + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Improve `namespacedImportName` usability by + setting a default when `importSchemaTypesFrom` is set + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Add `printTypeScriptMaybeType` to handle + printing TS types, as there are special cases like `any` and `unknown` + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Fix isNativeNamedType to handle types from + remote schemas correctly + + Previously, we assumed that if a name type does note have `astNode`, it is a native named type + because it is not declared in user's schema. + + However, this is a wrong assumption because remote schemas do not have `astNode`. This causes all + user declared types are wrongly recognised as native types e.g. Input + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Ensure Input and Variables use the same input + scalars default e.g. `ID` can take `string | number` + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Fix namingConvention not being applied + consistently + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Abstract how enum imports are generated into + visitor-plugin-common package + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Fix namingConvention not being applied + consistently in imports, Variables, Input and Result + +- Updated dependencies + [[`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29)]: + - @graphql-codegen/plugin-helpers@7.0.0 + ## 6.3.0 ### Minor Changes @@ -791,8 +990,8 @@ ``` The `RefType` generic is used to reference back to `ResolversTypes` and `ResolversParentTypes` in - some cases such as field returning a Union. - 2. `resolversNonOptionalTypename` also affects `ResolversInterfaceTypes` + some cases such as field returning a Union. 2. `resolversNonOptionalTypename` also affects + `ResolversInterfaceTypes` Using the schema above, if we use `resolversNonOptionalTypename` option: diff --git a/packages/plugins/other/visitor-plugin-common/package.json b/packages/plugins/other/visitor-plugin-common/package.json index f2c8e2e8f3a..33a9df0e37a 100644 --- a/packages/plugins/other/visitor-plugin-common/package.json +++ b/packages/plugins/other/visitor-plugin-common/package.json @@ -1,6 +1,6 @@ { "name": "@graphql-codegen/visitor-plugin-common", - "version": "6.3.0", + "version": "7.0.0", "type": "module", "repository": { "type": "git", @@ -39,12 +39,12 @@ "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" }, "dependencies": { - "@graphql-codegen/plugin-helpers": "^6.3.0", + "@graphql-codegen/plugin-helpers": "^7.0.0", "@graphql-tools/optimize": "^2.0.0", "@graphql-tools/relay-operation-optimizer": "^7.1.1", "@graphql-tools/utils": "^11.0.0", - "auto-bind": "~4.0.0", - "change-case-all": "1.0.15", + "auto-bind": "^5.0.0", + "change-case-all": "^2.1.0", "dependency-graph": "^1.0.0", "graphql-tag": "^2.11.0", "parse-filepath": "^1.0.2", 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 a7972d6fb96..32e2313bcb5 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 @@ -7,9 +7,19 @@ import { OperationTypeNode, VariableDefinitionNode, } from 'graphql'; -import { ParsedTypesConfig, RawTypesConfig } from './base-types-visitor.js'; -import { BaseVisitor } from './base-visitor.js'; -import { DEFAULT_SCALARS } from './scalars.js'; +import { BaseVisitor, type ParsedConfig, type RawConfig } from './base-visitor.js'; +import { + NormalizedOperationAvoidOptionalsConfig, + normalizeOperationAvoidOptionals, + type OperationAvoidOptionalsConfig, +} from './operation-avoid-optionals.js'; +import { + normalizeOperationDeclarationKind, + type NormalizedOperationDeclarationKindConfig, + type OperationDeclarationKind, + type OperationDeclarationKindConfig, +} from './operation-declaration-kinds.js'; +import { DEFAULT_INPUT_SCALARS } from './scalars.js'; import { SelectionSetToObject } from './selection-set-to-object.js'; import { CustomDirectivesConfig, NormalizedScalarsMap } from './types.js'; import { @@ -20,51 +30,69 @@ import { } from './utils.js'; import { OperationVariablesToObject } from './variables-to-object.js'; -function getRootType(operation: OperationTypeNode, schema: GraphQLSchema) { - switch (operation) { - case 'query': - return schema.getQueryType(); - case 'mutation': - return schema.getMutationType(); - case 'subscription': - return schema.getSubscriptionType(); - } - throw new Error(`Unknown operation type: ${operation}`); -} - -export interface ParsedDocumentsConfig extends ParsedTypesConfig { - addTypename: boolean; - preResolveTypes: boolean; +export interface ParsedDocumentsConfig extends ParsedConfig { extractAllFieldsToTypes: boolean; - globalNamespace: boolean; + extractAllFieldsToTypesCompact: boolean; operationResultSuffix: string; dedupeOperationSuffix: boolean; omitOperationSuffix: boolean; - namespacedImportName: string | null; exportFragmentSpreadSubTypes: boolean; skipTypeNameForRoot: boolean; + nonOptionalTypename: boolean; + globalNamespace: boolean; experimentalFragmentVariables: boolean; mergeFragmentTypes: boolean; customDirectives: CustomDirectivesConfig; + generateOperationTypes: boolean; + importSchemaTypesFrom: string; + namespacedImportName: string | null; + declarationKind: NormalizedOperationDeclarationKindConfig; + avoidOptionals: NormalizedOperationAvoidOptionalsConfig; } -export interface RawDocumentsConfig extends RawTypesConfig { +export interface RawDocumentsConfig extends RawConfig { /** - * @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. + * @description This will cause the generator to avoid using TypeScript optionals (`?`) on types, + * so the following definition: `type A { myField: String }` will output `myField: Maybe` + * instead of `myField?: Maybe`. + * @default false * * @exampleMarkdown + * ## Override all definition types + * * ```ts filename="codegen.ts" * import type { CodegenConfig } from '@graphql-codegen/cli'; * * const config: CodegenConfig = { * // ... * generates: { - * 'path/to/file': { - * // plugins... + * 'path/to/file.ts': { + * plugins: ['typescript-operations'], * config: { - * preResolveTypes: false + * avoidOptionals: true + * }, + * }, + * }, + * }; + * export default config; + * ``` + * + * ## Override only specific definition types + * + * ```ts filename="codegen.ts" + * import type { CodegenConfig } from '@graphql-codegen/cli'; + * + * const config: CodegenConfig = { + * // ... + * generates: { + * 'path/to/file.ts': { + * plugins: ['typescript-operations'], + * config: { + * avoidOptionals: { + * variableValue: true, + * inputValue: true, + * defaultValue: true, + * } * }, * }, * }, @@ -72,7 +100,7 @@ export interface RawDocumentsConfig extends RawTypesConfig { * export default config; * ``` */ - preResolveTypes?: boolean; + avoidOptionals?: boolean | OperationAvoidOptionalsConfig; /** * @default false * @description Avoid adding `__typename` for root types. This is ignored when a selection explicitly specifies `__typename`. @@ -96,6 +124,30 @@ export interface RawDocumentsConfig extends RawTypesConfig { * ``` */ skipTypeNameForRoot?: boolean; + /** + * @default false + * @description Automatically adds `__typename` field to the generated types, even when they are not specified + * in the selection set, and makes it non-optional + * + * @exampleMarkdown + * ```ts filename="codegen.ts" + * import type { CodegenConfig } from '@graphql-codegen/cli'; + * + * const config: CodegenConfig = { + * // ... + * generates: { + * 'path/to/file': { + * // plugins... + * config: { + * nonOptionalTypename: true + * }, + * }, + * }, + * }; + * export default config; + * ``` + */ + nonOptionalTypename?: boolean; /** * @default false * @description Puts all generated code under `global` namespace. Useful for Stencil integration. @@ -150,9 +202,27 @@ export interface RawDocumentsConfig extends RawTypesConfig { */ mergeFragmentTypes?: boolean; - // The following are internal, and used by presets /** - * @ignore + * @description Prefixes all GraphQL related generated types with that value, as namespaces import. + * You can use this feature to allow separation of plugins to different files (See `importSchemaTypesFrom`) + * @default 'Types' (if `importSchemaTypesFrom` is set) + * @exampleMarkdown + * ```ts filename="codegen.ts" + * import type { CodegenConfig } from '@graphql-codegen/cli'; + * const config: CodegenConfig = { + * // ... + * generates: { + * 'path/to/file.ts': { + * plugins: ['typescript-operations'], + * config: { + * importSchemaTypesFrom: './path/to/shared-types.ts', + * namespacedImportName: 'Types' + * }, + * }, + * }, + * }; + * export default config; + * ``` */ namespacedImportName?: string; @@ -180,6 +250,118 @@ export interface RawDocumentsConfig extends RawTypesConfig { * ``` */ customDirectives?: CustomDirectivesConfig; + + /** + * @description Whether to generate operation types such as Variables, Query/Mutation/Subscription selection set, and Fragment types + * This can be used with `importSchemaTypesFrom` to generate shared used Enums and Input. + * @default true + * @exampleMarkdown + * ```ts filename="codegen.ts" + * import type { CodegenConfig } from '@graphql-codegen/cli'; + * + * const config: CodegenConfig = { + * // ... + * generates: { + * 'path/to/file.ts': { + * plugins: ['typescript-operations'], + * config: { + * generateOperationTypes: false, + * }, + * }, + * }, + * }; + * export default config; + * ``` + */ + generateOperationTypes?: boolean; + + /** + * @description The absolute (prefixed with `~`) or relative path from `cwd` to the shared used Enums and Input (See `generateOperationTypes`). + * @default true + * @exampleMarkdown + * ```ts filename="codegen.ts" + * import type { CodegenConfig } from '@graphql-codegen/cli'; + * + * const config: CodegenConfig = { + * // ... + * generates: { + * 'path/to/file.ts': { + * plugins: ['typescript-operations'], + * config: { + * importSchemaTypesFrom: './path/to/shared-types.ts', // relative + * importSchemaTypesFrom: '~@my-org/package' // absolute + * }, + * }, + * }, + * }; + * export default config; + * ``` + */ + importSchemaTypesFrom?: string; + /** + * @default false + * @description Extract all field types to their own types, instead of inlining them. + * This helps to reduce type duplication, and makes type errors more readable. + * It can also significantly reduce the size of the generated code, the generation time, + * and the typechecking time. + */ + extractAllFieldsToTypes?: boolean; + /** + * @default false + * @description Generates type names using only field names, omitting GraphQL type names. + * This matches the naming convention used by Apollo Tooling. + * For example, instead of `Query_company_Company_office_Office_location_Location`, + * it generates `Query_company_office_location`. + * + * When this option is enabled, `extractAllFieldsToTypes` is automatically enabled as well. + */ + extractAllFieldsToTypesCompact?: boolean; + /** + * @description Overrides the default output for various GraphQL types. + * @default 'type' + * @exampleMarkdown + * ## Override all declarations + * + * ```ts filename="codegen.ts" + * import type { CodegenConfig } from '@graphql-codegen/cli'; + * + * const config: CodegenConfig = { + * // ... + * generates: { + * 'path/to/file': { + * // plugins... + * config: { + * declarationKind: 'interface' + * }, + * }, + * }, + * }; + * export default config; + * ``` + * + * ## Override only specific declarations + * + * ```ts filename="codegen.ts" + * import type { CodegenConfig } from '@graphql-codegen/cli'; + * + * const config: CodegenConfig = { + * // ... + * generates: { + * 'path/to/file': { + * // plugins... + * config: { + * declarationKind: { + * input: 'interface', + * result: 'type' + * } + * }, + * }, + * }, + * }; + * export default config; + * ``` + */ + declarationKind?: OperationDeclarationKind | OperationDeclarationKindConfig; } export class BaseDocumentsVisitor< @@ -195,25 +377,49 @@ export class BaseDocumentsVisitor< rawConfig: TRawConfig, additionalConfig: TPluginConfig, protected _schema: GraphQLSchema, - defaultScalars: NormalizedScalarsMap = DEFAULT_SCALARS, + defaultScalars: NormalizedScalarsMap = DEFAULT_INPUT_SCALARS, ) { + const importSchemaTypesFrom = getConfigValue(rawConfig.importSchemaTypesFrom, ''); + const extractAllFieldsToTypes = + getConfigValue(rawConfig.extractAllFieldsToTypes, false) || + getConfigValue(rawConfig.extractAllFieldsToTypesCompact, false); + const declarationKind = normalizeOperationDeclarationKind( + getConfigValue(rawConfig.declarationKind, 'type'), + ); + if (extractAllFieldsToTypes && declarationKind.result === 'interface') { + // eslint-disable-next-line no-console + console.warn( + "`declarationKind.result` has been set to `'type'` because `extractAllFieldsToTypes` or `extractAllFieldsToTypesCompact` is true", + ); + declarationKind.result = 'type'; + } + super(rawConfig, { + avoidOptionals: normalizeOperationAvoidOptionals( + getConfigValue(rawConfig.avoidOptionals, false), + ), 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), - namespacedImportName: getConfigValue(rawConfig.namespacedImportName, null), + nonOptionalTypename: getConfigValue(rawConfig.nonOptionalTypename, false), experimentalFragmentVariables: getConfigValue(rawConfig.experimentalFragmentVariables, false), - addTypename: !rawConfig.skipTypename, globalNamespace: !!rawConfig.globalNamespace, operationResultSuffix: getConfigValue(rawConfig.operationResultSuffix, ''), scalars: buildScalarsFromConfig(_schema, rawConfig, defaultScalars), - customDirectives: getConfigValue(rawConfig.customDirectives, { - apolloUnmask: false, - }), + customDirectives: getConfigValue(rawConfig.customDirectives, { apolloUnmask: false }), + generateOperationTypes: getConfigValue(rawConfig.generateOperationTypes, true), + importSchemaTypesFrom, + namespacedImportName: getConfigValue( + rawConfig.namespacedImportName, + importSchemaTypesFrom ? 'Types' : null, + ), + extractAllFieldsToTypes, + extractAllFieldsToTypesCompact: getConfigValue( + rawConfig.extractAllFieldsToTypesCompact, + false, + ), + declarationKind, ...((additionalConfig || {}) as any), }); @@ -245,10 +451,6 @@ export class BaseDocumentsVisitor< return this._schema; } - public get addTypename(): boolean { - return this._parsedConfig.addTypename; - } - private handleAnonymousOperation(node: OperationDefinitionNode): string { const name = node.name?.value; @@ -268,6 +470,10 @@ export class BaseDocumentsVisitor< } FragmentDefinition(node: FragmentDefinitionNode): string { + if (!this.config.generateOperationTypes) { + return null; + } + const fragmentRootType = this._schema.getType(node.typeCondition.name.value); const selectionSet = this._selectionSetToObject.createNext(fragmentRootType, node.selectionSet); const fragmentSuffix = this.getFragmentSuffix(node); @@ -300,7 +506,11 @@ export class BaseDocumentsVisitor< return variablesBlock; } - OperationDefinition(node: OperationDefinitionNode): string { + OperationDefinition(node: OperationDefinitionNode): string | null { + if (!this.config.generateOperationTypes) { + return null; + } + const name = this.handleAnonymousOperation(node); const operationRootType = getRootType(node.operation, this._schema); @@ -323,22 +533,30 @@ export class BaseDocumentsVisitor< }), ); - const operationResult = new DeclarationBlock(this._declarationBlockConfig) - .export() - .asKind('type') - .withName( - this.convertName(name, { - suffix: operationTypeSuffix + this._parsedConfig.operationResultSuffix, - }), - ) - .withContent(selectionSetObjects.mergedTypeString).string; + const operationResultName = this.convertName(name, { + suffix: operationTypeSuffix + this._parsedConfig.operationResultSuffix, + }); + + // When extractAllFieldsToTypes creates a root type with the same name as the operation result, + // we only need the extracted type and can skip the alias to avoid duplicates + const shouldSkipOperationResult = + this._parsedConfig.extractAllFieldsToTypesCompact && + operationResultName === selectionSetObjects.mergedTypeString; + + const operationResult = shouldSkipOperationResult + ? '' + : new DeclarationBlock(this._declarationBlockConfig) + .export() + .asKind(this.config.declarationKind.result) + .withName(operationResultName) + .withContent(selectionSetObjects.mergedTypeString).string; const operationVariables = new DeclarationBlock({ ...this._declarationBlockConfig, blockTransformer: t => this.applyVariablesWrapper(t, operationType), }) .export() - .asKind('type') + .asKind('type') // Variables must always be `'type'` because it is an alias of `Exact` .withName( this.convertName(name, { suffix: operationTypeSuffix + 'Variables', @@ -351,7 +569,7 @@ export class BaseDocumentsVisitor< i => new DeclarationBlock(this._declarationBlockConfig) .export() - .asKind('type') + .asKind('type') // dependentTypes must always be `'type'` because they are alias types .withName(i.name) .withContent(i.content).string, ) @@ -366,3 +584,15 @@ export class BaseDocumentsVisitor< .join('\n\n'); } } + +function getRootType(operation: OperationTypeNode, schema: GraphQLSchema) { + switch (operation) { + case 'query': + return schema.getQueryType(); + case 'mutation': + return schema.getMutationType(); + case 'subscription': + return schema.getSubscriptionType(); + } + throw new Error(`Unknown operation type: ${operation}`); +} diff --git a/packages/plugins/other/visitor-plugin-common/src/base-resolvers-visitor.ts b/packages/plugins/other/visitor-plugin-common/src/base-resolvers-visitor.ts index ddd3dae132f..f39d58b0e04 100644 --- a/packages/plugins/other/visitor-plugin-common/src/base-resolvers-visitor.ts +++ b/packages/plugins/other/visitor-plugin-common/src/base-resolvers-visitor.ts @@ -79,8 +79,6 @@ export interface ParsedResolversConfig extends ParsedConfig { enumValues: ParsedEnumValuesMap; resolverTypeWrapperSignature: string; federation: boolean; - enumPrefix: boolean; - enumSuffix: boolean; optionalResolveType: boolean; immutableTypes: boolean; namespacedImportName: string; @@ -522,59 +520,7 @@ export interface RawResolversConfig extends RawConfig { * @description Supports Apollo Federation */ federation?: boolean; - /** - * @default true - * @description Allow you to disable prefixing for generated enums, works in combination with `typesPrefix`. - * - * @exampleMarkdown - * ## Disable enum prefixes - * - * ```ts filename="codegen.ts" - * import type { CodegenConfig } from '@graphql-codegen/cli'; - * - * const config: CodegenConfig = { - * // ... - * generates: { - * 'path/to/file': { - * plugins: ['typescript', 'typescript-resolver'], - * config: { - * typesPrefix: 'I', - * enumPrefix: false - * }, - * }, - * }, - * }; - * export default config; - * ``` - */ - enumPrefix?: boolean; - /** - * @default true - * @description Allow you to disable suffixing for generated enums, works in combination with `typesSuffix`. - * - * @exampleMarkdown - * ## Disable enum suffixes - * - * ```ts filename="codegen.ts" - * import type { CodegenConfig } from '@graphql-codegen/cli'; - * - * const config: CodegenConfig = { - * // ... - * generates: { - * 'path/to/file': { - * plugins: ['typescript', 'typescript-resolver'], - * config: { - * typesSuffix: 'I', - * enumSuffix: false - * }, - * }, - * }, - * }; - * export default config; - * ``` - */ - enumSuffix?: boolean; /** * @description Configures behavior for custom directives from various GraphQL libraries. * @exampleMarkdown @@ -811,17 +757,11 @@ export class BaseResolversVisitor< super(rawConfig, { immutableTypes: getConfigValue(rawConfig.immutableTypes, false), optionalResolveType: getConfigValue(rawConfig.optionalResolveType, false), - enumPrefix: getConfigValue(rawConfig.enumPrefix, true), - enumSuffix: getConfigValue(rawConfig.enumSuffix, true), federation: getConfigValue(rawConfig.federation, false), resolverTypeWrapperSignature: getConfigValue( rawConfig.resolverTypeWrapperSignature, 'Promise | T', ), - enumValues: parseEnumValues({ - schema: _schema, - mapOrStr: rawConfig.enumValues, - }), addUnderscoreToArgsType: getConfigValue(rawConfig.addUnderscoreToArgsType, false), addInterfaceFieldResolverTypes: getConfigValue( rawConfig.addInterfaceFieldResolverTypes, @@ -855,6 +795,20 @@ export class BaseResolversVisitor< ...additionalConfig, } as TPluginConfig); + this.config.enumValues = parseEnumValues({ + schema: _schema, + mapOrStr: rawConfig.enumValues, + naming: { + convert: this.config.convert, + options: { + typesPrefix: this.config.typesPrefix, + typesSuffix: this.config.typesSuffix, + useTypesPrefix: this.config.enumPrefix, + useTypesSuffix: this.config.enumSuffix, + }, + }, + }); + autoBind(this); this._federation = new ApolloFederation({ enabled: this.config.federation, @@ -1021,10 +975,7 @@ export class BaseResolversVisitor< if (isEnumType(schemaType) && this.config.enumValues[typeName]) { const isExternalFile = !!this.config.enumValues[typeName].sourceFile; prev[typeName] = isExternalFile - ? this.convertName(this.config.enumValues[typeName].typeIdentifier, { - useTypesPrefix: false, - useTypesSuffix: false, - }) + ? this.config.enumValues[typeName].typeIdentifierConverted : this.config.enumValues[typeName].sourceIdentifier; } else if (hasDefaultMapper && !hasPlaceholder(this.config.defaultMapper.type)) { prev[typeName] = applyWrapper(this.config.defaultMapper.type); @@ -1482,7 +1433,7 @@ export class BaseResolversVisitor< : false; const existsFromEnums = !!Object.keys(this.config.enumValues) .map(key => this.config.enumValues[key]) - .find(o => o.sourceFile === source && o.typeIdentifier === identifier); + .find(o => o.sourceFile === source && o.typeIdentifierConverted === identifier); return exists || existsFromEnums; } diff --git a/packages/plugins/other/visitor-plugin-common/src/base-types-visitor.ts b/packages/plugins/other/visitor-plugin-common/src/base-types-visitor.ts index 58f7031796d..69b7319ccec 100644 --- a/packages/plugins/other/visitor-plugin-common/src/base-types-visitor.ts +++ b/packages/plugins/other/visitor-plugin-common/src/base-types-visitor.ts @@ -2,9 +2,7 @@ import { DirectiveDefinitionNode, DirectiveNode, EnumTypeDefinitionNode, - EnumValueDefinitionNode, FieldDefinitionNode, - GraphQLEnumType, GraphQLSchema, InputObjectTypeDefinitionNode, InputValueDefinitionNode, @@ -19,11 +17,13 @@ import { UnionTypeDefinitionNode, } from 'graphql'; import { BaseVisitor, ParsedConfig, RawConfig } from './base-visitor.js'; +import { buildEnumValuesBlock } from './convert-schema-enum-to-declaration-block-string.js'; import { normalizeDeclarationKind } from './declaration-kinds.js'; import { parseEnumValues } from './enum-values.js'; +import { buildTypeImport, getEnumsImports } from './imports.js'; import { transformDirectiveArgumentAndInputFieldMappings } from './mappers.js'; import { DEFAULT_SCALARS } from './scalars.js'; -import { +import type { DeclarationKind, DeclarationKindConfig, DirectiveArgumentAndInputFieldMappings, @@ -37,6 +37,7 @@ import { DeclarationBlock, DeclarationBlockConfig, getConfigValue, + getNodeComment, indent, isOneOfInputObjectType, transformComment, @@ -46,18 +47,18 @@ import { OperationVariablesToObject } from './variables-to-object.js'; export interface ParsedTypesConfig extends ParsedConfig { enumValues: ParsedEnumValuesMap; + ignoreEnumValuesFromSchema: boolean; declarationKind: DeclarationKindConfig; addUnderscoreToArgsType: boolean; onlyEnums: boolean; onlyOperationTypes: boolean; - enumPrefix: boolean; - enumSuffix: boolean; fieldWrapperValue: string; wrapFieldDefinitions: boolean; entireFieldWrapperValue: string; wrapEntireDefinitions: boolean; - ignoreEnumValuesFromSchema: boolean; directiveArgumentAndInputFieldMappings: ParsedDirectiveArgumentAndInputFieldMappings; + addTypename: boolean; + nonOptionalTypename: boolean; } export interface RawTypesConfig extends RawConfig { @@ -154,29 +155,11 @@ export interface RawTypesConfig extends RawConfig { */ enumValues?: EnumValuesMap; /** - * @description Overrides the default output for various GraphQL elements. + * @description This will cause the generator to ignore enum values defined in GraphQLSchema + * @default false * * @exampleMarkdown - * ## Override all declarations - * - * ```ts filename="codegen.ts" - * import type { CodegenConfig } from '@graphql-codegen/cli'; - * - * const config: CodegenConfig = { - * // ... - * generates: { - * 'path/to/file': { - * // plugins... - * config: { - * declarationKind: 'interface' - * }, - * }, - * }, - * }; - * export default config; - * ``` - * - * ## Override only specific declarations + * ## Ignore enum values from schema * * ```ts filename="codegen.ts" * import type { CodegenConfig } from '@graphql-codegen/cli'; @@ -187,10 +170,7 @@ export interface RawTypesConfig extends RawConfig { * 'path/to/file': { * // plugins... * config: { - * declarationKind: { - * type: 'interface', - * input: 'interface' - * } + * ignoreEnumValuesFromSchema: true, * }, * }, * }, @@ -198,13 +178,12 @@ export interface RawTypesConfig extends RawConfig { * export default config; * ``` */ - declarationKind?: DeclarationKind | DeclarationKindConfig; + ignoreEnumValuesFromSchema?: boolean; /** - * @default true - * @description Allow you to disable prefixing for generated enums, works in combination with `typesPrefix`. + * @description Overrides the default output for various GraphQL elements. * * @exampleMarkdown - * ## Disable enum prefixes + * ## Override all declarations * * ```ts filename="codegen.ts" * import type { CodegenConfig } from '@graphql-codegen/cli'; @@ -215,22 +194,15 @@ export interface RawTypesConfig extends RawConfig { * 'path/to/file': { * // plugins... * config: { - * typesPrefix: 'I', - * enumPrefix: false + * declarationKind: 'interface' * }, * }, * }, * }; * export default config; * ``` - */ - enumPrefix?: boolean; - /** - * @default true - * @description Allow you to disable suffixing for generated enums, works in combination with `typesSuffix`. * - * @exampleMarkdown - * ## Disable enum suffixes + * ## Override only specific declarations * * ```ts filename="codegen.ts" * import type { CodegenConfig } from '@graphql-codegen/cli'; @@ -241,8 +213,10 @@ export interface RawTypesConfig extends RawConfig { * 'path/to/file': { * // plugins... * config: { - * typesSuffix: 'I', - * enumSuffix: false + * declarationKind: { + * type: 'interface', + * input: 'interface' + * } * }, * }, * }, @@ -250,7 +224,7 @@ export interface RawTypesConfig extends RawConfig { * export default config; * ``` */ - enumSuffix?: boolean; + declarationKind?: DeclarationKind | DeclarationKindConfig; /** * @description Allow you to add wrapper for field type, use T as the generic value. Make sure to set `wrapFieldDefinitions` to `true` in order to make this flag work. * @default T @@ -353,31 +327,6 @@ export interface RawTypesConfig extends RawConfig { * ``` */ onlyOperationTypes?: boolean; - /** - * @description This will cause the generator to ignore enum values defined in GraphQLSchema - * @default false - * - * @exampleMarkdown - * ## Ignore enum values from schema - * - * ```ts filename="codegen.ts" - * import type { CodegenConfig } from '@graphql-codegen/cli'; - * - * const config: CodegenConfig = { - * // ... - * generates: { - * 'path/to/file': { - * // plugins... - * config: { - * ignoreEnumValuesFromSchema: true, - * }, - * }, - * }, - * }; - * export default config; - * ``` - */ - ignoreEnumValuesFromSchema?: boolean; /** * @name wrapEntireFieldDefinitions * @type boolean @@ -491,10 +440,55 @@ export interface RawTypesConfig extends RawConfig { * ``` */ directiveArgumentAndInputFieldMappingTypeSuffix?: string; + /** + * @default false + * @description Does not add `__typename` to the generated types, unless it was specified in the selection set. + * + * @exampleMarkdown + * ```ts filename="codegen.ts" + * import type { CodegenConfig } from '@graphql-codegen/cli'; + * + * const config: CodegenConfig = { + * // ... + * generates: { + * 'path/to/file': { + * // plugins... + * config: { + * skipTypename: true + * }, + * }, + * }, + * }; + * export default config; + * ``` + */ + skipTypename?: boolean; + /** + * @default false + * @description Automatically adds `__typename` field to the generated types, even when they are not specified + * in the selection set, and makes it non-optional + * + * @exampleMarkdown + * ```ts filename="codegen.ts" + * import type { CodegenConfig } from '@graphql-codegen/cli'; + * + * const config: CodegenConfig = { + * // ... + * generates: { + * 'path/to/file': { + * // plugins... + * config: { + * nonOptionalTypename: true + * }, + * }, + * }, + * }; + * export default config; + * ``` + */ + nonOptionalTypename?: boolean; } -const onlyUnderscoresPattern = /^_+$/; - export class BaseTypesVisitor< TRawConfig extends RawTypesConfig = RawTypesConfig, TPluginConfig extends ParsedTypesConfig = ParsedTypesConfig, @@ -508,30 +502,40 @@ export class BaseTypesVisitor< defaultScalars: NormalizedScalarsMap = DEFAULT_SCALARS, ) { super(rawConfig, { - enumPrefix: getConfigValue(rawConfig.enumPrefix, true), - enumSuffix: getConfigValue(rawConfig.enumSuffix, true), onlyEnums: getConfigValue(rawConfig.onlyEnums, false), onlyOperationTypes: getConfigValue(rawConfig.onlyOperationTypes, false), addUnderscoreToArgsType: getConfigValue(rawConfig.addUnderscoreToArgsType, false), - enumValues: parseEnumValues({ - schema: _schema, - mapOrStr: rawConfig.enumValues, - ignoreEnumValuesFromSchema: rawConfig.ignoreEnumValuesFromSchema, - }), + ignoreEnumValuesFromSchema: getConfigValue(rawConfig.ignoreEnumValuesFromSchema, false), declarationKind: normalizeDeclarationKind(rawConfig.declarationKind), scalars: buildScalarsFromConfig(_schema, rawConfig, defaultScalars), fieldWrapperValue: getConfigValue(rawConfig.fieldWrapperValue, 'T'), wrapFieldDefinitions: getConfigValue(rawConfig.wrapFieldDefinitions, false), entireFieldWrapperValue: getConfigValue(rawConfig.entireFieldWrapperValue, 'T'), wrapEntireDefinitions: getConfigValue(rawConfig.wrapEntireFieldDefinitions, false), - ignoreEnumValuesFromSchema: getConfigValue(rawConfig.ignoreEnumValuesFromSchema, false), directiveArgumentAndInputFieldMappings: transformDirectiveArgumentAndInputFieldMappings( rawConfig.directiveArgumentAndInputFieldMappings ?? {}, rawConfig.directiveArgumentAndInputFieldMappingTypeSuffix, ), + addTypename: !rawConfig.skipTypename, + nonOptionalTypename: getConfigValue(rawConfig.nonOptionalTypename, false), ...additionalConfig, }); + this.config.enumValues = parseEnumValues({ + schema: _schema, + mapOrStr: rawConfig.enumValues, + ignoreEnumValuesFromSchema: this.config.ignoreEnumValuesFromSchema, + naming: { + convert: this.config.convert, + options: { + typesPrefix: this.config.typesPrefix, + typesSuffix: this.config.typesSuffix, + useTypesPrefix: this.config.enumPrefix, + useTypesSuffix: this.config.enumSuffix, + }, + }, + }); + // Note: Missing directive mappers but not a problem since always overriden by implementors this._argumentsTransformer = new OperationVariablesToObject(this.scalars, this.convertName); } @@ -564,21 +568,23 @@ export class BaseTypesVisitor< if (mappedValue.input.isExternal) { res.push( - this._buildTypeImport( - mappedValue.input.import, - mappedValue.input.source, - mappedValue.input.default, - ), + buildTypeImport({ + identifier: mappedValue.input.import, + source: mappedValue.input.source, + asDefault: mappedValue.input.default, + useTypeImports: this.config.useTypeImports, + }), ); } if (mappedValue.output.isExternal) { res.push( - this._buildTypeImport( - mappedValue.output.import, - mappedValue.output.source, - mappedValue.output.default, - ), + buildTypeImport({ + identifier: mappedValue.output.import, + source: mappedValue.output.source, + asDefault: mappedValue.output.default, + useTypeImports: this.config.useTypeImports, + }), ); } @@ -592,7 +598,12 @@ export class BaseTypesVisitor< const mappedValue = this.config.directiveArgumentAndInputFieldMappings[directive]; if (mappedValue.isExternal) { - return this._buildTypeImport(mappedValue.import, mappedValue.source, mappedValue.default); + return buildTypeImport({ + identifier: mappedValue.import, + source: mappedValue.source, + asDefault: mappedValue.default, + useTypeImports: this.config.useTypeImports, + }); } return null; @@ -723,7 +734,7 @@ export class BaseTypesVisitor< const typeString = node.type as any as string; const { type } = this._parsedConfig.declarationKind; - const comment = this.getNodeComment(node); + const comment = getNodeComment(node); return comment + indent(`${node.name.value}: ${typeString}${this.getPunctuation(type)}`); } @@ -858,60 +869,11 @@ export class BaseTypesVisitor< return ''; } - protected _buildTypeImport(identifier: string, source: string, asDefault = false): string { - const { useTypeImports } = this.config; - if (asDefault) { - if (useTypeImports) { - return `import type { default as ${identifier} } from '${source}';`; - } - return `import ${identifier} from '${source}';`; - } - return `import${useTypeImports ? ' type' : ''} { ${identifier} } from '${source}';`; - } - - protected handleEnumValueMapper( - typeIdentifier: string, - importIdentifier: string | null, - sourceIdentifier: string | null, - sourceFile: string | null, - ): string[] { - if (importIdentifier !== sourceIdentifier) { - // use namespace import to dereference nested enum - // { enumValues: { MyEnum: './my-file#NS.NestedEnum' } } - return [ - this._buildTypeImport(importIdentifier || sourceIdentifier, sourceFile), - `import ${typeIdentifier} = ${sourceIdentifier};`, - ]; - } - if (sourceIdentifier !== typeIdentifier) { - return [this._buildTypeImport(`${sourceIdentifier} as ${typeIdentifier}`, sourceFile)]; - } - return [this._buildTypeImport(importIdentifier || sourceIdentifier, sourceFile)]; - } - public getEnumsImports(): string[] { - return Object.keys(this.config.enumValues) - .flatMap(enumName => { - const mappedValue = this.config.enumValues[enumName]; - - if (mappedValue.sourceFile) { - if (mappedValue.isDefault) { - return [ - this._buildTypeImport(mappedValue.typeIdentifier, mappedValue.sourceFile, true), - ]; - } - - return this.handleEnumValueMapper( - mappedValue.typeIdentifier, - mappedValue.importIdentifier, - mappedValue.sourceIdentifier, - mappedValue.sourceFile, - ); - } - - return []; - }) - .filter(Boolean); + return getEnumsImports({ + enumValues: this.config.enumValues, + useTypeImports: this.config.useTypeImports, + }); } EnumTypeDefinition(node: EnumTypeDefinitionNode): string { @@ -932,7 +894,25 @@ export class BaseTypesVisitor< }), ) .withComment(node.description.value) - .withBlock(this.buildEnumValuesBlock(enumName, node.values)).string; + .withBlock( + buildEnumValuesBlock({ + typeName: enumName, + values: node.values, + schema: this._schema, + naming: { + convert: this.config.convert, + options: { + typesPrefix: this.config.typesPrefix, + useTypesPrefix: this.config.enumPrefix, + typesSuffix: this.config.typesSuffix, + useTypesSuffix: this.config.enumSuffix, + }, + }, + ignoreEnumValuesFromSchema: this.config.ignoreEnumValuesFromSchema, + declarationBlockConfig: this._declarationBlockConfig, + enumValues: this.config.enumValues, + }), + ).string; } protected makeValidEnumIdentifier(identifier: string): string { @@ -942,48 +922,6 @@ export class BaseTypesVisitor< return identifier; } - protected buildEnumValuesBlock( - typeName: string, - values: ReadonlyArray, - ): string { - const schemaEnumType: GraphQLEnumType | undefined = this._schema - ? (this._schema.getType(typeName) as GraphQLEnumType) - : undefined; - - return values - .map(enumOption => { - const optionName = this.makeValidEnumIdentifier( - this.convertName(enumOption, { - useTypesPrefix: false, - // We can only strip out the underscores if the value contains other - // characters. Otherwise we'll generate syntactically invalid code. - transformUnderscore: !onlyUnderscoresPattern.test(enumOption.name.value), - }), - ); - const comment = this.getNodeComment(enumOption); - const schemaEnumValue = - schemaEnumType && !this.config.ignoreEnumValuesFromSchema - ? schemaEnumType.getValue(enumOption.name.value).value - : undefined; - let enumValue: string | number = - typeof schemaEnumValue === 'undefined' ? enumOption.name.value : schemaEnumValue; - - if (typeof this.config.enumValues[typeName]?.mappedValues?.[enumValue] !== 'undefined') { - enumValue = this.config.enumValues[typeName].mappedValues[enumValue]; - } - - return ( - comment + - indent( - `${optionName}${ - this._declarationBlockConfig.enumNameValueSeparator - } ${wrapWithSingleQuotes(enumValue, typeof schemaEnumValue !== 'undefined')}`, - ) - ); - }) - .join(',\n'); - } - DirectiveDefinition(_node: DirectiveDefinitionNode): string { return ''; } @@ -1059,7 +997,7 @@ export class BaseTypesVisitor< return this._getScalar(typeAsString, isVisitingInputType ? 'input' : 'output'); } if (this.config.enumValues[typeAsString]) { - return this.config.enumValues[typeAsString].typeIdentifier; + return this.config.enumValues[typeAsString].typeIdentifierConverted; } const schemaType = this._schema.getType(typeAsString); @@ -1100,30 +1038,6 @@ export class BaseTypesVisitor< return null; } - getNodeComment( - node: FieldDefinitionNode | EnumValueDefinitionNode | InputValueDefinitionNode, - ): string { - let commentText = node.description?.value; - const deprecationDirective = node.directives.find(v => v.name.value === 'deprecated'); - if (deprecationDirective) { - const deprecationReason = this.getDeprecationReason(deprecationDirective); - commentText = `${commentText ? `${commentText}\n` : ''}@deprecated ${deprecationReason}`; - } - const comment = transformComment(commentText, 1); - return comment; - } - - protected getDeprecationReason(directive: DirectiveNode): string | void { - if (directive.name.value === 'deprecated') { - let reason = 'Field no longer supported'; - const deprecatedReason = directive.arguments[0]; - if (deprecatedReason && deprecatedReason.value.kind === Kind.STRING) { - reason = deprecatedReason.value.value; - } - return reason; - } - } - protected wrapWithListType(str: string): string { return `Array<${str}>`; } diff --git a/packages/plugins/other/visitor-plugin-common/src/base-visitor.ts b/packages/plugins/other/visitor-plugin-common/src/base-visitor.ts index 16caee72a4d..bae5f1b8a07 100644 --- a/packages/plugins/other/visitor-plugin-common/src/base-visitor.ts +++ b/packages/plugins/other/visitor-plugin-common/src/base-visitor.ts @@ -13,7 +13,7 @@ import { ParsedScalarsMap, ScalarsMap, } from './types.js'; -import { DeclarationBlockConfig } from './utils.js'; +import { DeclarationBlockConfig, getConfigValue } from './utils.js'; export interface BaseVisitorConvertOptions { useTypesPrefix?: boolean; @@ -27,9 +27,8 @@ export interface ParsedConfig { convert: ConvertFn; typesPrefix: string; typesSuffix: string; - addTypename: boolean; - nonOptionalTypename: boolean; - extractAllFieldsToTypes: boolean; + enumPrefix: boolean; + enumSuffix: boolean; externalFragments: LoadedFragment[]; fragmentImports: ImportDeclaration[]; immutableTypes: boolean; @@ -71,7 +70,7 @@ export interface RawConfig { strictScalars?: boolean; /** * @description Allows you to override the type that unknown scalars will have. - * @default any + * @default unknown * * @exampleMarkdown * ```ts filename="codegen.ts" @@ -83,7 +82,7 @@ export interface RawConfig { * 'path/to/file': { * // plugins... * config: { - * defaultScalarType: 'unknown' + * defaultScalarType: 'any' * }, * }, * }, @@ -261,10 +260,12 @@ export interface RawConfig { */ typesSuffix?: string; /** - * @default false - * @description Does not add `__typename` to the generated types, unless it was specified in the selection set. + * @default true + * @description Allow you to disable prefixing for generated enums, works in combination with `typesPrefix`. * * @exampleMarkdown + * ## Disable enum prefixes + * * ```ts filename="codegen.ts" * import type { CodegenConfig } from '@graphql-codegen/cli'; * @@ -274,7 +275,8 @@ export interface RawConfig { * 'path/to/file': { * // plugins... * config: { - * skipTypename: true + * typesPrefix: 'I', + * enumPrefix: false * }, * }, * }, @@ -282,13 +284,14 @@ export interface RawConfig { * export default config; * ``` */ - skipTypename?: boolean; + enumPrefix?: boolean; /** - * @default false - * @description Automatically adds `__typename` field to the generated types, even when they are not specified - * in the selection set, and makes it non-optional + * @default true + * @description Allow you to disable suffixing for generated enums, works in combination with `typesSuffix`. * * @exampleMarkdown + * ## Disable enum suffixes + * * ```ts filename="codegen.ts" * import type { CodegenConfig } from '@graphql-codegen/cli'; * @@ -298,7 +301,8 @@ export interface RawConfig { * 'path/to/file': { * // plugins... * config: { - * nonOptionalTypename: true + * typesSuffix: 'I', + * enumSuffix: false * }, * }, * }, @@ -306,7 +310,7 @@ export interface RawConfig { * export default config; * ``` */ - nonOptionalTypename?: boolean; + enumSuffix?: boolean; /** * @name useTypeImports * @type boolean @@ -343,10 +347,6 @@ export interface RawConfig { * @ignore */ fragmentImports?: ImportDeclaration[]; - /** - * @ignore - */ - globalNamespace?: boolean; /** * @ignore */ @@ -374,15 +374,6 @@ export interface RawConfig { */ importExtension?: '' | `.${string}`; - /** - * @default false - * @description Extract all field types to their own types, instead of inlining them. - * This helps to reduce type duplication, and makes type errors more readable. - * It can also significantly reduce the size of the generated code, the generation time, - * and the typechecking time. - */ - extractAllFieldsToTypes?: boolean; - /** * @default false * @description If you prefer to have each field in generated types printed on a new line, set this to true. @@ -416,16 +407,18 @@ export class BaseVisitor< convert: convertFactory(rawConfig), typesPrefix: rawConfig.typesPrefix || '', typesSuffix: rawConfig.typesSuffix || '', + enumPrefix: getConfigValue(rawConfig.enumPrefix, true), + enumSuffix: getConfigValue(rawConfig.enumSuffix, true), externalFragments: rawConfig.externalFragments || [], fragmentImports: rawConfig.fragmentImports || [], - addTypename: !rawConfig.skipTypename, - nonOptionalTypename: !!rawConfig.nonOptionalTypename, useTypeImports: !!rawConfig.useTypeImports, allowEnumStringTypes: !!rawConfig.allowEnumStringTypes, inlineFragmentTypes: rawConfig.inlineFragmentTypes ?? 'inline', - emitLegacyCommonJSImports: rawConfig.emitLegacyCommonJSImports ?? true, + emitLegacyCommonJSImports: + rawConfig.emitLegacyCommonJSImports === undefined + ? true + : !!rawConfig.emitLegacyCommonJSImports, importExtension, - extractAllFieldsToTypes: rawConfig.extractAllFieldsToTypes ?? false, printFieldsOnNewLines: rawConfig.printFieldsOnNewLines ?? false, includeExternalFragments: rawConfig.includeExternalFragments ?? false, ...((additionalConfig || {}) as any), diff --git a/packages/plugins/other/visitor-plugin-common/src/convert-schema-enum-to-declaration-block-string.ts b/packages/plugins/other/visitor-plugin-common/src/convert-schema-enum-to-declaration-block-string.ts new file mode 100644 index 00000000000..3b24a5e36e7 --- /dev/null +++ b/packages/plugins/other/visitor-plugin-common/src/convert-schema-enum-to-declaration-block-string.ts @@ -0,0 +1,244 @@ +import type { + EnumTypeDefinitionNode, + EnumValueDefinitionNode, + GraphQLEnumType, + GraphQLSchema, +} from 'graphql'; +import { convertName } from './naming.js'; +import type { ConvertFn, ParsedEnumValuesMap } from './types.js'; +import { + DeclarationBlock, + getNodeComment, + indent, + transformComment, + wrapWithSingleQuotes, + type DeclarationBlockConfig, +} from './utils.js'; + +export interface ConvertSchemaEnumToDeclarationBlockString { + schema: GraphQLSchema; + node: EnumTypeDefinitionNode; + enumName: string; + enumValues: ParsedEnumValuesMap; + futureProofEnums: boolean; + ignoreEnumValuesFromSchema: boolean; + naming: { + convert: ConvertFn; + options: { + typesPrefix: string; + typesSuffix: string; + useTypesPrefix?: boolean; + useTypesSuffix?: boolean; + }; + }; + + outputType: 'string-literal' | 'native-numeric' | 'const' | 'native-const' | 'native'; + declarationBlockConfig: DeclarationBlockConfig; +} + +export const convertSchemaEnumToDeclarationBlockString = ({ + schema, + node, + enumName, + enumValues, + futureProofEnums, + ignoreEnumValuesFromSchema, + outputType, + declarationBlockConfig, + naming, +}: ConvertSchemaEnumToDeclarationBlockString): string => { + if (enumValues[enumName]?.sourceFile) { + return `export { ${enumValues[enumName].typeIdentifierConverted} };\n`; + } + + const getValueFromConfig = (enumValue: string | number) => { + if (typeof enumValues[enumName]?.mappedValues?.[enumValue] !== 'undefined') { + return enumValues[enumName].mappedValues[enumValue]; + } + return null; + }; + + const withFutureAddedValue = [ + futureProofEnums ? [indent('| ' + wrapWithSingleQuotes('%future added value'))] : [], + ]; + + const enumTypeName = convertName({ + convert: () => naming.convert(node), + options: naming.options, + }); + + if (outputType === 'string-literal') { + return new DeclarationBlock(declarationBlockConfig) + .export() + .asKind('type') + .withComment(node.description?.value) + .withName(enumTypeName) + .withContent( + '\n' + + node.values + .map(enumOption => { + const name = enumOption.name.value; + const enumValue: string | number = getValueFromConfig(name) ?? name; + const comment = transformComment(enumOption.description?.value, 1); + + return comment + indent('| ' + wrapWithSingleQuotes(enumValue)); + }) + .concat(...withFutureAddedValue) + .join('\n'), + ).string; + } + + if (outputType === 'native-numeric') { + return new DeclarationBlock(declarationBlockConfig) + .export() + .withComment(node.description?.value) + .withName(enumTypeName) + .asKind('enum') + .withBlock( + node.values + .map((enumOption, i) => { + const valueFromConfig = getValueFromConfig(enumOption.name.value); + const enumValue: string | number = valueFromConfig ?? i; + const comment = transformComment(enumOption.description?.value, 1); + const optionName = makeValidEnumIdentifier( + convertName({ + options: { + typesPrefix: naming.options.typesPrefix, + typesSuffix: naming.options.typesSuffix, + useTypesPrefix: false, + }, + convert: () => naming.convert(enumOption, { transformUnderscore: true }), + }), + ); + return comment + indent(optionName) + ` = ${enumValue}`; + }) + .concat(...withFutureAddedValue) + .join(',\n'), + ).string; + } + + if (outputType === 'const') { + const typeName = `export type ${enumTypeName} = typeof ${enumTypeName}[keyof typeof ${enumTypeName}];`; + const enumAsConst = new DeclarationBlock({ + ...declarationBlockConfig, + blockTransformer: block => { + return block + ' as const'; + }, + }) + .export() + .asKind('const') + .withName(enumTypeName) + .withComment(node.description?.value) + .withBlock( + node.values + .map(enumOption => { + const optionName = makeValidEnumIdentifier( + convertName({ + options: { + typesPrefix: naming.options.typesPrefix, + typesSuffix: naming.options.typesPrefix, + }, + convert: () => + naming.convert(enumOption, { + transformUnderscore: true, + }), + }), + ); + const comment = transformComment(enumOption.description?.value, 1); + const name = enumOption.name.value; + const enumValue: string | number = getValueFromConfig(name) ?? name; + + return comment + indent(`${optionName}: ${wrapWithSingleQuotes(enumValue)}`); + }) + .join(',\n'), + ).string; + + return [enumAsConst, typeName].join('\n'); + } + + return new DeclarationBlock(declarationBlockConfig) + .export() + .asKind(outputType === 'native-const' ? 'const enum' : 'enum') + .withName(enumTypeName) + .withComment(node.description?.value) + .withBlock( + buildEnumValuesBlock({ + typeName: enumName, + values: node.values, + schema, + naming, + ignoreEnumValuesFromSchema, + declarationBlockConfig, + enumValues, + }), + ).string; +}; + +export const buildEnumValuesBlock = ({ + typeName, + values, + schema, + naming, + ignoreEnumValuesFromSchema, + declarationBlockConfig, + enumValues, +}: Pick< + ConvertSchemaEnumToDeclarationBlockString, + 'schema' | 'naming' | 'ignoreEnumValuesFromSchema' | 'declarationBlockConfig' | 'enumValues' +> & { + typeName: string; + values: ReadonlyArray; +}): string => { + const schemaEnumType: GraphQLEnumType | undefined = schema + ? (schema.getType(typeName) as GraphQLEnumType) + : undefined; + + return values + .map(enumOption => { + const onlyUnderscoresPattern = /^_+$/; + const optionName = makeValidEnumIdentifier( + convertName({ + options: { + useTypesPrefix: false, + typesPrefix: naming.options.typesPrefix, + typesSuffix: naming.options.typesSuffix, + }, + convert: () => + naming.convert(enumOption, { + // We can only strip out the underscores if the value contains other + // characters. Otherwise we'll generate syntactically invalid code. + transformUnderscore: !onlyUnderscoresPattern.test(enumOption.name.value), + }), + }), + ); + const comment = getNodeComment(enumOption); + const schemaEnumValue = + schemaEnumType && !ignoreEnumValuesFromSchema + ? schemaEnumType.getValue(enumOption.name.value).value + : undefined; + let enumValue: string | number = + typeof schemaEnumValue === 'undefined' ? enumOption.name.value : schemaEnumValue; + + if (typeof enumValues[typeName]?.mappedValues?.[enumValue] !== 'undefined') { + enumValue = enumValues[typeName].mappedValues[enumValue]; + } + + return ( + comment + + indent( + `${optionName}${declarationBlockConfig.enumNameValueSeparator} ${wrapWithSingleQuotes( + enumValue, + typeof schemaEnumValue !== 'undefined', + )}`, + ) + ); + }) + .join(',\n'); +}; + +const makeValidEnumIdentifier = (identifier: string): string => { + if (/^[0-9]/.exec(identifier)) { + return wrapWithSingleQuotes(identifier, true); + } + return identifier; +}; diff --git a/packages/plugins/other/visitor-plugin-common/src/enum-values.ts b/packages/plugins/other/visitor-plugin-common/src/enum-values.ts index 740bf3649ce..6d87a956789 100644 --- a/packages/plugins/other/visitor-plugin-common/src/enum-values.ts +++ b/packages/plugins/other/visitor-plugin-common/src/enum-values.ts @@ -1,6 +1,7 @@ import { GraphQLEnumType, GraphQLSchema, isEnumType } from 'graphql'; import { parseMapper } from './mappers.js'; -import { EnumValuesMap, ParsedEnumValuesMap } from './types.js'; +import { convertName } from './naming.js'; +import type { ConvertFn, EnumValuesMap, ParsedEnumValuesMap } from './types.js'; function escapeString(str: string) { return str.replace(/\\/g, '\\\\').replace(/\n/g, '\\n').replace(/'/g, "\\'"); @@ -10,10 +11,20 @@ export function parseEnumValues({ schema, mapOrStr = {}, ignoreEnumValuesFromSchema, + naming, }: { schema: GraphQLSchema; mapOrStr: EnumValuesMap; ignoreEnumValuesFromSchema?: boolean; + naming: { + convert: ConvertFn; + options: { + typesPrefix: string; + typesSuffix: string; + useTypesPrefix?: boolean; + useTypesSuffix?: boolean; + }; + }; }): ParsedEnumValuesMap { const allTypes = schema.getTypeMap(); const allEnums = Object.keys(allTypes).filter(t => isEnumType(allTypes[t])); @@ -43,7 +54,7 @@ export function parseEnumValues({ ); } - return Object.keys(mapOrStr).reduce((prev, gqlIdentifier) => { + return Object.keys(mapOrStr).reduce((prev, gqlIdentifier) => { const pointer = mapOrStr[gqlIdentifier]; if (typeof pointer === 'string') { @@ -54,6 +65,10 @@ export function parseEnumValues({ [gqlIdentifier]: { isDefault: mapper.isExternal && mapper.default, typeIdentifier: gqlIdentifier, + typeIdentifierConverted: convertName({ + convert: () => naming.convert(gqlIdentifier), + options: naming.options, + }), sourceFile: mapper.isExternal ? mapper.source : null, sourceIdentifier: mapper.type, importIdentifier: mapper.isExternal ? mapper.import : null, @@ -67,6 +82,10 @@ export function parseEnumValues({ [gqlIdentifier]: { isDefault: false, typeIdentifier: gqlIdentifier, + typeIdentifierConverted: convertName({ + convert: () => naming.convert(gqlIdentifier), + options: naming.options, + }), sourceFile: null, sourceIdentifier: null, importIdentifier: null, @@ -78,24 +97,28 @@ export function parseEnumValues({ `Invalid "enumValues" configuration \n Enum "${gqlIdentifier}": expected string or object (with enum values mapping)`, ); - }, {} as ParsedEnumValuesMap); + }, {}); } if (typeof mapOrStr === 'string') { return allEnums .filter(enumName => !enumName.startsWith('__')) - .reduce((prev, enumName) => { + .reduce((prev, enumName) => { return { ...prev, [enumName]: { isDefault: false, typeIdentifier: enumName, + typeIdentifierConverted: convertName({ + convert: () => naming.convert(enumName), + options: naming.options, + }), sourceFile: mapOrStr, sourceIdentifier: enumName, importIdentifier: enumName, mappedValues: null, }, }; - }, {} as ParsedEnumValuesMap); + }, {}); } return {}; diff --git a/packages/plugins/other/visitor-plugin-common/src/graphql-type-utils.ts b/packages/plugins/other/visitor-plugin-common/src/graphql-type-utils.ts new file mode 100644 index 00000000000..52a43513c03 --- /dev/null +++ b/packages/plugins/other/visitor-plugin-common/src/graphql-type-utils.ts @@ -0,0 +1,12 @@ +import { isIntrospectionType, isSpecifiedScalarType, type GraphQLNamedType } from 'graphql'; + +export const isNativeNamedType = (namedType: GraphQLNamedType): boolean => { + // "Native" NamedType in this context means the following: + // 1. introspection types i.e. with `__` prefixes + // 2. base scalars e.g. Boolean, Int, etc. + if (isSpecifiedScalarType(namedType) || isIntrospectionType(namedType)) { + return true; + } + + return false; +}; diff --git a/packages/plugins/other/visitor-plugin-common/src/imports.ts b/packages/plugins/other/visitor-plugin-common/src/imports.ts index 7287975cedf..8ac5fc27254 100644 --- a/packages/plugins/other/visitor-plugin-common/src/imports.ts +++ b/packages/plugins/other/visitor-plugin-common/src/imports.ts @@ -1,6 +1,7 @@ import { dirname, isAbsolute, join, relative, resolve } from 'path'; import parse from 'parse-filepath'; import { normalizeImportExtension } from '@graphql-codegen/plugin-helpers'; +import type { ParsedEnumValuesMap } from './types'; export type ImportDeclaration = { outputPath: string; @@ -105,3 +106,102 @@ export function clearExtension(path: string): string { export function fixLocalFilePath(path: string): string { return path.startsWith('..') ? path : `./${path}`; } + +export function getEnumsImports({ + enumValues, + useTypeImports, +}: { + enumValues: ParsedEnumValuesMap; + useTypeImports: boolean; +}): string[] { + function handleEnumValueMapper({ + typeIdentifierConverted, + importIdentifier, + sourceIdentifier, + sourceFile, + useTypeImports, + }: { + typeIdentifierConverted: string; + importIdentifier: string | null; + sourceIdentifier: string | null; + sourceFile: string | null; + useTypeImports: boolean; + }): string[] { + if (importIdentifier !== sourceIdentifier) { + // use namespace import to dereference nested enum + // { enumValues: { MyEnum: './my-file#NS.NestedEnum' } } + return [ + buildTypeImport({ + identifier: importIdentifier || sourceIdentifier, + source: sourceFile, + useTypeImports, + }), + `import ${typeIdentifierConverted} = ${sourceIdentifier};`, + ]; + } + if (sourceIdentifier !== typeIdentifierConverted) { + return [ + buildTypeImport({ + identifier: `${sourceIdentifier} as ${typeIdentifierConverted}`, + source: sourceFile, + useTypeImports, + }), + ]; + } + return [ + buildTypeImport({ + identifier: importIdentifier || sourceIdentifier, + source: sourceFile, + useTypeImports, + }), + ]; + } + + return Object.keys(enumValues) + .flatMap(enumName => { + const mappedValue = enumValues[enumName]; + if (mappedValue.sourceFile) { + if (mappedValue.isDefault) { + return [ + buildTypeImport({ + identifier: mappedValue.typeIdentifierConverted, + source: mappedValue.sourceFile, + asDefault: true, + useTypeImports, + }), + ]; + } + + return handleEnumValueMapper({ + typeIdentifierConverted: mappedValue.typeIdentifierConverted, + importIdentifier: mappedValue.importIdentifier, + sourceIdentifier: mappedValue.sourceIdentifier, + sourceFile: mappedValue.sourceFile, + useTypeImports, + }); + } + + return []; + }) + .filter(Boolean); +} + +export function buildTypeImport({ + identifier, + source, + useTypeImports, + asDefault = false, +}: { + identifier: string; + source: string; + useTypeImports: boolean; + asDefault?: boolean; +}): string { + if (asDefault) { + if (useTypeImports) { + return `import type { default as ${identifier} } from '${source}';`; + } + return `import ${identifier} from '${source}';`; + } + return `import${useTypeImports ? ' type' : ''} { ${identifier} } from '${source}';`; +} diff --git a/packages/plugins/other/visitor-plugin-common/src/index.ts b/packages/plugins/other/visitor-plugin-common/src/index.ts index a196546db4f..b0a07031317 100644 --- a/packages/plugins/other/visitor-plugin-common/src/index.ts +++ b/packages/plugins/other/visitor-plugin-common/src/index.ts @@ -9,6 +9,8 @@ export * from './enum-values.js'; export * from './imports.js'; export * from './mappers.js'; export * from './naming.js'; +export * from './operation-avoid-optionals.js'; +export * from './operation-declaration-kinds.js'; export * from './optimize-operations.js'; export * from './scalars.js'; export * from './selection-set-processor/base.js'; @@ -17,3 +19,5 @@ export * from './selection-set-to-object.js'; export * from './types.js'; export * from './utils.js'; export * from './variables-to-object.js'; +export * from './convert-schema-enum-to-declaration-block-string.js'; +export * from './graphql-type-utils.js'; diff --git a/packages/plugins/other/visitor-plugin-common/src/naming.ts b/packages/plugins/other/visitor-plugin-common/src/naming.ts index e4cef23c60c..19b053bf217 100644 --- a/packages/plugins/other/visitor-plugin-common/src/naming.ts +++ b/packages/plugins/other/visitor-plugin-common/src/naming.ts @@ -2,7 +2,7 @@ import { pascalCase } from 'change-case-all'; import { ASTNode } from 'graphql'; import { resolveExternalModuleAndFn } from '@graphql-codegen/plugin-helpers'; import { ConvertFn, ConvertOptions, NamingConvention, NamingConventionMap } from './types.js'; -import { convertNameParts, getConfigValue } from './utils.js'; +import { getConfigValue } from './utils.js'; function getKind(node: ASTNode | string): keyof NamingConventionMap { if (typeof node === 'string') { @@ -61,6 +61,21 @@ function getName(node: ASTNode | string): string | undefined { } export function convertFactory(config: { namingConvention?: NamingConvention }): ConvertFn { + function convertNameParts( + str: string, + func: (str: string) => string, + removeUnderscore = false, + ): string { + if (removeUnderscore) { + return func(str); + } + + return str + .split('_') + .map(s => func(s)) + .join('_'); + } + function resolveConventionName( type: keyof NamingConventionMap, ): (str: string, opts?: ConvertOptions) => string { @@ -130,3 +145,35 @@ export function convertFactory(config: { namingConvention?: NamingConvention }): return resolveConventionName(kind)(str, opts); }; } + +export const convertName = ({ + convert, + options, +}: { + options: { + typesPrefix: string; + useTypesPrefix?: boolean; + typesSuffix: string; + useTypesSuffix?: boolean; + }; + convert: () => string; +}): string => { + const useTypesPrefix = + typeof options.useTypesPrefix === 'boolean' ? options.useTypesPrefix : true; + const useTypesSuffix = + typeof options.useTypesSuffix === 'boolean' ? options.useTypesSuffix : true; + + let convertedName = ''; + + if (useTypesPrefix) { + convertedName += options.typesPrefix; + } + + convertedName += convert(); + + if (useTypesSuffix) { + convertedName += options.typesSuffix; + } + + return convertedName; +}; diff --git a/packages/plugins/other/visitor-plugin-common/src/operation-avoid-optionals.ts b/packages/plugins/other/visitor-plugin-common/src/operation-avoid-optionals.ts new file mode 100644 index 00000000000..6afbf647ce5 --- /dev/null +++ b/packages/plugins/other/visitor-plugin-common/src/operation-avoid-optionals.ts @@ -0,0 +1,29 @@ +export interface OperationAvoidOptionalsConfig { + variableValue?: boolean; + inputValue?: boolean; + defaultValue?: boolean; +} +export type NormalizedOperationAvoidOptionalsConfig = Required; + +export const normalizeOperationAvoidOptionals = ( + avoidOptionals: boolean | OperationAvoidOptionalsConfig, +): NormalizedOperationAvoidOptionalsConfig => { + const defaultAvoidOptionals: NormalizedOperationAvoidOptionalsConfig = { + variableValue: false, + inputValue: false, + defaultValue: false, + }; + + if (typeof avoidOptionals === 'boolean') { + return { + variableValue: avoidOptionals, + inputValue: avoidOptionals, + defaultValue: avoidOptionals, + }; + } + + return { + ...defaultAvoidOptionals, + ...avoidOptionals, + }; +}; diff --git a/packages/plugins/other/visitor-plugin-common/src/operation-declaration-kinds.ts b/packages/plugins/other/visitor-plugin-common/src/operation-declaration-kinds.ts new file mode 100644 index 00000000000..c5aed4ae3bf --- /dev/null +++ b/packages/plugins/other/visitor-plugin-common/src/operation-declaration-kinds.ts @@ -0,0 +1,29 @@ +export type OperationDeclarationKind = 'type' | 'interface'; + +export type OperationDeclarationKindConfig = { + input?: OperationDeclarationKind; + result?: OperationDeclarationKind; // Query, Mutation, Subscription +}; + +export type NormalizedOperationDeclarationKindConfig = Required; + +const DEFAULT_OPERATION_DECLARATION_KINDS: NormalizedOperationDeclarationKindConfig = { + input: 'type', + result: 'type', +}; + +export function normalizeOperationDeclarationKind( + declarationKind: OperationDeclarationKind | OperationDeclarationKindConfig, +): NormalizedOperationDeclarationKindConfig { + if (typeof declarationKind === 'string') { + return { + input: declarationKind, + result: declarationKind, + }; + } + + return { + ...DEFAULT_OPERATION_DECLARATION_KINDS, + ...declarationKind, + }; +} diff --git a/packages/plugins/other/visitor-plugin-common/src/scalars.ts b/packages/plugins/other/visitor-plugin-common/src/scalars.ts index e58f82790ed..eb1b6bfa11e 100644 --- a/packages/plugins/other/visitor-plugin-common/src/scalars.ts +++ b/packages/plugins/other/visitor-plugin-common/src/scalars.ts @@ -22,3 +22,26 @@ export const DEFAULT_SCALARS: NormalizedScalarsMap = { output: 'number', }, }; + +export const DEFAULT_INPUT_SCALARS: NormalizedScalarsMap = { + ID: { + input: 'string | number', + output: 'string', + }, + String: { + input: 'string', + output: 'string', + }, + Boolean: { + input: 'boolean', + output: 'boolean', + }, + Int: { + input: 'number', + output: 'number', + }, + Float: { + input: 'number', + output: 'number', + }, +}; diff --git a/packages/plugins/other/visitor-plugin-common/src/selection-set-processor/base.ts b/packages/plugins/other/visitor-plugin-common/src/selection-set-processor/base.ts index 379665a3b02..5a86ca303f8 100644 --- a/packages/plugins/other/visitor-plugin-common/src/selection-set-processor/base.ts +++ b/packages/plugins/other/visitor-plugin-common/src/selection-set-processor/base.ts @@ -5,7 +5,7 @@ import { GraphQLOutputType, Location, } from 'graphql'; -import { AvoidOptionalsConfig, ConvertNameFn, NormalizedScalarsMap } from '../types.js'; +import { ConvertNameFn, NormalizedScalarsMap } from '../types.js'; export type PrimitiveField = { isConditional: boolean; fieldName: string }; export type PrimitiveAliasedFields = { @@ -25,17 +25,11 @@ export type ProcessResult = null | Array; export type SelectionSetProcessorConfig = { namespacedImportName: string | null; convertName: ConvertNameFn; - enumPrefix: boolean | null; - enumSuffix: boolean | null; + enumPrefix: boolean; + enumSuffix: boolean; scalars: NormalizedScalarsMap; - formatNamedField( - name: string, - type?: GraphQLOutputType | GraphQLNamedType | null, - isConditional?: boolean, - isOptional?: boolean, - ): string; + formatNamedField(params: { name: string; isOptional?: boolean }): string; wrapTypeWithModifiers(baseType: string, type: GraphQLOutputType | GraphQLNamedType): string; - avoidOptionals?: AvoidOptionalsConfig | boolean; printFieldsOnNewLines?: boolean; }; diff --git a/packages/plugins/other/visitor-plugin-common/src/selection-set-processor/pre-resolve-types.ts b/packages/plugins/other/visitor-plugin-common/src/selection-set-processor/pre-resolve-types.ts index 75410d76f59..aaf720996b2 100644 --- a/packages/plugins/other/visitor-plugin-common/src/selection-set-processor/pre-resolve-types.ts +++ b/packages/plugins/other/visitor-plugin-common/src/selection-set-processor/pre-resolve-types.ts @@ -1,5 +1,5 @@ -import { GraphQLInterfaceType, GraphQLObjectType, isEnumType, isNonNullType } from 'graphql'; -import { getBaseType, removeNonNullWrapper } from '@graphql-codegen/plugin-helpers'; +import { GraphQLInterfaceType, GraphQLObjectType, isEnumType } from 'graphql'; +import { getBaseType } from '@graphql-codegen/plugin-helpers'; import { BaseSelectionSetProcessor, LinkField, @@ -34,15 +34,10 @@ export class PreResolveTypesProcessor extends BaseSelectionSetProcessor { if (aliasedField.fieldName === '__typename') { - const name = this.config.formatNamedField(aliasedField.alias, null); + const name = this.config.formatNamedField({ name: aliasedField.alias }); return { name, type: `'${schemaType.name}'`, @@ -101,12 +96,10 @@ export class PreResolveTypesProcessor extends BaseSelectionSetProcessor; + selectionNodes: Array; + fragmentDirectives: DirectiveNode[]; +}; + +/** + * @description EnrichedFieldNode are field nodes enriched with Codegen metadata for subsequent processing + */ +type EnrichedFieldNode = FieldNode & { + /** + * A field node may implicitly inherit fragment directives from parents + * For example, if the field's parent is marked with `@skip`, the field is implicitly marked with `@skip` as well + */ fragmentDirectives?: DirectiveNode[]; }; @@ -67,8 +78,17 @@ interface DependentType { isUnionType?: boolean; } -type CollectedFragmentNode = (SelectionNode | FragmentSpreadUsage | DirectiveNode) & - FragmentDirectives; +/** + * Each grouped TypeName has an array of nodes. + * These are collected when parsing the selection set, + * then turned into TypeScript strings + */ +type GroupedTypeNameNode = + | EnrichedFieldNode + | FragmentSpreadNode + | InlineFragmentNode + | FragmentSpreadUsage + | DirectiveNode; type GroupedStringifiedTypes = Record>; const operationTypes: string[] = ['Query', 'Mutation', 'Subscription']; @@ -82,14 +102,22 @@ const metadataFieldMap: Record> = { __type: TypeMetaFieldDef, }; -export class SelectionSetToObject { +export class SelectionSetToObject< + Config extends ParsedDocumentsConfig = ParsedDocumentsConfig, + SelectionSetProcessorConfig extends BaseSelectionSetProcessorConfig = + BaseSelectionSetProcessorConfig, +> { protected _primitiveFields: PrimitiveField[] = []; protected _primitiveAliasedFields: PrimitiveAliasedFields[] = []; protected _linksFields: LinkField[] = []; protected _queriedForTypename = false; + // Enables resolving conflicting type names in extractAllFieldsToTypesCompact mode: + // key === GetFoo_user <-- full field name + // value === User <-- last field type + protected _seenFieldNames: Map = new Map(); constructor( - protected _processor: BaseSelectionSetProcessor, + protected _processor: BaseSelectionSetProcessor, protected _scalars: NormalizedScalarsMap, protected _schema: GraphQLSchema, protected _convertName: ConvertNameFn, @@ -106,7 +134,7 @@ export class SelectionSetToObject, - types: Map>, - ) { + nodes: Array, + types: Map>, + ): void { if (isListType(parentType) || isNonNullType(parentType)) { return this._collectInlineFragments(parentType.ofType as GraphQLNamedType, nodes, types); } @@ -144,9 +174,9 @@ export class SelectionSetToObject ({ + const fieldsWithFragmentDirectives: EnrichedFieldNode[] = fields.map(field => ({ ...field, - fragmentDirectives: field.fragmentDirectives || directives, + fragmentDirectives: directives, })); if (isObjectType(typeOnSchema)) { @@ -245,27 +275,6 @@ export class SelectionSetToObject { + if (originalNode.kind === Kind.FIELD) { + return { + ...originalNode, + fragmentDirectives: [...spread.directives], + } satisfies EnrichedFieldNode; + } + return originalNode; + }); + selectionNodesByTypeName[possibleType.name].push({ fragmentName: spread.name.value, typeName: usage, onType: fragmentSpreadObject.onType, - selectionNodes: [...fragmentSpreadObject.node.selectionSet.selections], + selectionNodes: fragmentSelectionNodes, fragmentDirectives: [...spread.directives], }); } @@ -310,52 +331,125 @@ export class SelectionSetToObject, parentSchemaType?: GraphQLObjectType, - ): Map> { - const selectionNodesByTypeName = new Map>(); + ): { + selectionNodesByTypeName: Map>; + selectionNodesByTypeNameConditional: Array>>; + } { + const result: ReturnType = { + selectionNodesByTypeName: new Map>(), + selectionNodesByTypeNameConditional: [], + }; + const inlineFragmentSelections: InlineFragmentNode[] = []; + /** + * Inline fragments marked with `@skip`, `@include` or `@defer` + */ + const inlineFragmentConditionalSelections: InlineFragmentNode[] = []; const fieldNodes: FieldNode[] = []; const fragmentSpreads: FragmentSpreadNode[] = []; + /** + * Fragment spreads marked with `@skip` or `@include` or `@defer` + */ + const fragmentSpreadsConditionalSelections: FragmentSpreadNode[] = []; + for (const selection of selections) { switch (selection.kind) { case Kind.FIELD: fieldNodes.push(selection); break; case Kind.INLINE_FRAGMENT: + if ( + hasConditionalDirectives(selection.directives) || + hasIncrementalDeliveryDirectives(selection.directives) + ) { + inlineFragmentConditionalSelections.push(selection); + break; + } inlineFragmentSelections.push(selection); break; case Kind.FRAGMENT_SPREAD: + if ( + hasConditionalDirectives(selection.directives) || + hasIncrementalDeliveryDirectives(selection.directives) + ) { + fragmentSpreadsConditionalSelections.push(selection); + break; + } fragmentSpreads.push(selection); break; } } + // 1. Merge all selection sets that are mergable into one object. This includes: + // - field + // - field with conditional directives + // - inline fragment without conditional/incremental directives + // - fragment spreads without conditional/incremental directives + + // Turn field nodes into one inline fragments to simplify collecting fields from selections using _collectInlineFragments if (fieldNodes.length) { - inlineFragmentSelections.push( - this._createInlineFragmentForFieldNodes( - parentSchemaType ?? this._parentSchemaType, - fieldNodes, - ), - ); + inlineFragmentSelections.push({ + kind: Kind.INLINE_FRAGMENT, + typeCondition: { + kind: Kind.NAMED_TYPE, + name: { + kind: Kind.NAME, + value: (parentSchemaType ?? this._parentSchemaType).name, + }, + }, + directives: [], + selectionSet: { + kind: Kind.SELECTION_SET, + selections: fieldNodes, + }, + }); } - this._collectInlineFragments( parentSchemaType ?? this._parentSchemaType, inlineFragmentSelections, - selectionNodesByTypeName, + result.selectionNodesByTypeName, ); - const fragmentsUsage = this.buildFragmentSpreadsUsage(fragmentSpreads); + // Add fragment spreads into selection nodes so it becomes part of the base selection + const fragmentSpreadsUsage = this.buildFragmentSpreadsUsage(fragmentSpreads); - for (const [typeName, records] of Object.entries(fragmentsUsage)) { - this._appendToTypeMap(selectionNodesByTypeName, typeName, records); + for (const [typeName, records] of Object.entries(fragmentSpreadsUsage)) { + this._appendToTypeMap(result.selectionNodesByTypeName, typeName, records); } - return selectionNodesByTypeName; + // 2. Push conditional inline fragments into the result.selectionNodesByTypeNameConditional + // This is treated differently from result.selectionNodesByTypeName + // because fields in result.selectionNodesByTypeNameConditional are optional + for (const inlineFragmentConditionalSelection of inlineFragmentConditionalSelections) { + const selectionNodes = new Map>(); + this._collectInlineFragments( + parentSchemaType ?? this._parentSchemaType, + [inlineFragmentConditionalSelection], + selectionNodes, + ); + result.selectionNodesByTypeNameConditional.push(selectionNodes); + } + + // 3. Push conditional FragmentSpreadUsage into the result.selectionNodesByTypeNameConditional + // This is important to track because fields in a conditional Fragment Spread are optional + for (const fragmentSpreadsConditionalSelection of fragmentSpreadsConditionalSelections) { + const conditionalFragmentSpreadsUsage = this.buildFragmentSpreadsUsage([ + fragmentSpreadsConditionalSelection, + ]); + + for (const [typeName, records] of Object.entries(conditionalFragmentSpreadsUsage)) { + const selectionNodes = new Map>(); + this._appendToTypeMap(selectionNodes, typeName, records); + result.selectionNodesByTypeNameConditional.push(selectionNodes); + } + } + + return result; } - private _appendToTypeMap( - types: Map>, + private _appendToTypeMap( + types: Map>, typeName: string, - nodes: Array, + nodes: Array, ): void { if (!types.has(typeName)) { types.set(typeName, []); @@ -375,15 +469,27 @@ export class SelectionSetToObject((prev, type) => { const typeName = type.name; const schemaType = this._schema.getType(typeName); @@ -394,75 +500,116 @@ export class SelectionSetToObject( - (acc, node) => { - if ( - 'fragmentDirectives' in node && - hasIncrementalDeliveryDirectives(node.fragmentDirectives) - ) { - acc.incrementalNodes.push(node); - } else { - acc.selectionNodes.push(node); - } - return acc; - }, - { selectionNodes: [], incrementalNodes: [], fragmentSpreads: [] }, - ); + const collectGrouped = ( + selectionNodes: GroupedTypeNameNode[], + ): { hasTransformedSelectionSet: boolean } => { + const { fields, dependentTypes: subDependentTypes } = this.buildSelectionSet( + schemaType, + selectionNodes, + { + parentFieldName: this.buildParentFieldName(typeName, parentName), + }, + ); + const transformedSet = this.selectionSetStringFromFields(fields); - const { fields, dependentTypes: subDependentTypes } = this.buildSelectionSet( - schemaType, - selectionNodes, - { - parentFieldName: this.buildParentFieldName(typeName, parentName), - }, - ); - const transformedSet = this.selectionSetStringFromFields(fields); + if (transformedSet) { + prev[typeName].push(transformedSet); + } + dependentTypes.push(...subDependentTypes); - if (transformedSet) { - prev[typeName].push(transformedSet); - } - dependentTypes.push(...subDependentTypes); - if (!transformedSet && !fragmentSpreads.length) { + return { + hasTransformedSelectionSet: !!transformedSet, + }; + }; + + const { hasTransformedSelectionSet } = collectGrouped( + selectionNodesByTypeName.get(typeName) || [], + ); + if (!hasTransformedSelectionSet) { mustAddEmptyObject = true; } - for (const incrementalNode of incrementalNodes) { - if (this._config.inlineFragmentTypes === 'mask' && 'fragmentName' in incrementalNode) { - const { fields: incrementalFields, dependentTypes: incrementalDependentTypes } = - this.buildSelectionSet(schemaType, [incrementalNode], { - unsetTypes: true, - parentFieldName: parentName, - }); - const incrementalSet = this.selectionSetStringFromFields(incrementalFields); - prev[typeName].push(incrementalSet); - dependentTypes.push(...incrementalDependentTypes); - - continue; + for (const conditionalNodes of selectionNodesByTypeNameConditional) { + const selectionNodes = (conditionalNodes.get(typeName) || []).filter( + (node): node is EnrichedFieldNode | FragmentSpreadUsage => 'fragmentDirectives' in node, + ); + + let conditionalDirectivesFound = false; + let incrementalDirectivesFound = false; + for (const selectionNode of selectionNodes) { + if (hasConditionalDirectives(selectionNode.fragmentDirectives)) { + conditionalDirectivesFound = true; + } + if (hasIncrementalDeliveryDirectives(selectionNode.fragmentDirectives)) { + incrementalDirectivesFound = true; + } + } + + if (conditionalDirectivesFound) { + // When a FragmentSpreadUsage is marked as conditional, + // it should just be treated like an Inline Fragment + // i.e. every field in the fragment's selection set should be optional + const flattenedSelectionNodes = selectionNodes.reduce( + (prev, node) => { + if ('kind' in node) { + prev.push(node); + return prev; + } + + // When a node is a FragmentSpreadUsage, + // We just "inline" all the field in its selection set. Note: each field has fragmentDirectives which should contain `@skip` or `@inlcude` + // So, `buildSelectionSet` function below can correctly make said fields optional + for (const fragmentSpreadUsageSelectionNode of node.selectionNodes) { + prev.push(fragmentSpreadUsageSelectionNode); + } + return prev; + }, + [], + ); + + collectGrouped(flattenedSelectionNodes); + } + + if (incrementalDirectivesFound) { + for (const incrementalNode of selectionNodes) { + // 1. fragment masking + if ( + this._config.inlineFragmentTypes === 'mask' && + 'fragmentName' in incrementalNode + ) { + const { fields: incrementalFields, dependentTypes: incrementalDependentTypes } = + this.buildSelectionSet(schemaType, [incrementalNode], { + unsetTypes: true, + parentFieldName: parentName, + }); + const incrementalSet = this.selectionSetStringFromFields(incrementalFields); + prev[typeName].push(incrementalSet); + dependentTypes.push(...incrementalDependentTypes); + + continue; + } + + // 2. @defer + const { fields: initialFields, dependentTypes: initialDependentTypes } = + this.buildSelectionSet(schemaType, [incrementalNode], { + parentFieldName: parentName, + }); + + const { fields: subsequentFields, dependentTypes: subsequentDependentTypes } = + this.buildSelectionSet(schemaType, [incrementalNode], { + unsetTypes: true, + parentFieldName: parentName, + }); + + const initialSet = this.selectionSetStringFromFields(initialFields); + const subsequentSet = this.selectionSetStringFromFields(subsequentFields); + dependentTypes.push(...initialDependentTypes, ...subsequentDependentTypes); + + prev[typeName].push({ union: [initialSet, subsequentSet] }); + } } - const { fields: initialFields, dependentTypes: initialDependentTypes } = - this.buildSelectionSet(schemaType, [incrementalNode], { - parentFieldName: parentName, - }); - - const { fields: subsequentFields, dependentTypes: subsequentDependentTypes } = - this.buildSelectionSet(schemaType, [incrementalNode], { - unsetTypes: true, - parentFieldName: parentName, - }); - - const initialSet = this.selectionSetStringFromFields(initialFields); - const subsequentSet = this.selectionSetStringFromFields(subsequentFields); - dependentTypes.push(...initialDependentTypes, ...subsequentDependentTypes); - prev[typeName].push({ union: [initialSet, subsequentSet] }); } return prev; @@ -470,6 +617,7 @@ export class SelectionSetToObject, + selectionNodes: Array, options: { unsetTypes?: boolean; parentFieldName?: string }, ) { - const primitiveFields = new Map(); - const primitiveAliasFields = new Map(); + const primitiveFields = new Map(); + const primitiveAliasFields = new Map(); const linkFieldSelectionSets = new Map< string, { selectedFieldType: GraphQLOutputType; - field: FieldNode; + field: EnrichedFieldNode; } >(); let requireTypename = false; @@ -608,7 +753,7 @@ export class SelectionSetToObject = null; @@ -650,8 +795,8 @@ export class SelectionSetToObject objectType.name === parentSchemaType.name)) ) { // also process fields from fragment that apply for this parentType - const flatten = this.flattenSelectionSet(selectionNode.selectionNodes, parentSchemaType); - const typeNodes = flatten.get(parentSchemaType.name) ?? []; + const { selectionNodesByTypeName } = this.flattenSelectionSet( + selectionNode.selectionNodes, + parentSchemaType, + ); + const typeNodes = selectionNodesByTypeName.get(parentSchemaType.name) ?? []; selectionNodes.push(...typeNodes); for (const iinterface of parentSchemaType.getInterfaces()) { - const typeNodes = flatten.get(iinterface.name) ?? []; + const typeNodes = selectionNodesByTypeName.get(iinterface.name) ?? []; selectionNodes.push(...typeNodes); } } @@ -718,7 +866,7 @@ export class SelectionSetToObject ({ - isConditional: hasConditionalDirectives(field), + isConditional: + hasConditionalDirectives(field.directives) || + hasConditionalDirectives(field.fragmentDirectives), fieldName: field.name.value, })), options.unsetTypes, @@ -779,7 +926,9 @@ export class SelectionSetToObject ({ alias: field.alias.value, fieldName: field.name.value, - isConditional: hasConditionalDirectives(field), + isConditional: + hasConditionalDirectives(field.directives) || + hasConditionalDirectives(field.fragmentDirectives), })), options.unsetTypes, ), @@ -821,24 +970,26 @@ export class SelectionSetToObject { const relevant = grouped[typeName].filter(Boolean); return relevant.map(objDefinition => { - const name = fieldName ? `${fieldName}_${typeName}` : typeName; + // In extractAllFieldsToTypesCompact mode, we still need to keep the final concrete type name for union/interface types + // to distinguish between different implementations, but we skip it for simple object types + const hasMultipleTypes = Object.keys(grouped).length > 1; + let name: string; + if (fieldName) { + if (this._config.extractAllFieldsToTypesCompact && !hasMultipleTypes) { + name = fieldName; + } else { + name = `${fieldName}_${typeName}`; + } + } else { + name = typeName; + } return { name, content: @@ -966,15 +1129,17 @@ export class SelectionSetToObject 1; + const subTypes: DependentType[] = Object.keys(grouped).flatMap(typeName => { const possibleFields = grouped[typeName].filter(Boolean); - const declarationName = this.buildFragmentTypeName(fragmentName, fragmentSuffix, typeName); + // In extractAllFieldsToTypesCompact mode, pass typeName only when there are multiple types + const declarationName = + this._config.extractAllFieldsToTypesCompact && !hasMultipleTypes + ? this.buildFragmentTypeName(fragmentName, fragmentSuffix) + : this.buildFragmentTypeName(fragmentName, fragmentSuffix, typeName); if (possibleFields.length === 0) { - if (!this._config.addTypename) { - return [{ name: declarationName, content: this.getEmptyObjectType() }]; - } - return []; } @@ -1052,19 +1217,43 @@ export class SelectionSetToObject; -}; - export interface ResolversNonOptionalTypenameConfig { unionMember?: boolean; interfaceImplementingType?: boolean; diff --git a/packages/plugins/other/visitor-plugin-common/src/utils.ts b/packages/plugins/other/visitor-plugin-common/src/utils.ts index 81f74bbc24a..a3e4f6c2303 100644 --- a/packages/plugins/other/visitor-plugin-common/src/utils.ts +++ b/packages/plugins/other/visitor-plugin-common/src/utils.ts @@ -1,5 +1,7 @@ import { DirectiveNode, + EnumValueDefinitionNode, + FieldDefinitionNode, FieldNode, FragmentSpreadNode, GraphQLInputObjectType, @@ -9,6 +11,7 @@ import { GraphQLScalarType, GraphQLSchema, InlineFragmentNode, + InputValueDefinitionNode, isAbstractType, isInputObjectType, isListType, @@ -26,13 +29,7 @@ import { import { RawConfig } from './base-visitor.js'; import { parseMapper } from './mappers.js'; import { DEFAULT_SCALARS } from './scalars.js'; -import { - FragmentDirectives, - LoadedFragment, - NormalizedScalarsMap, - ParsedScalarsMap, - ScalarsMap, -} from './types.js'; +import { LoadedFragment, NormalizedScalarsMap, ParsedScalarsMap, ScalarsMap } from './types.js'; export const getConfigValue = (value: T, defaultValue: T): T => { if (value === null || value === undefined) { @@ -269,26 +266,11 @@ export function getBaseTypeNode(typeNode: TypeNode): NamedTypeNode { return typeNode; } -export function convertNameParts( - str: string, - func: (str: string) => string, - removeUnderscore = false, -): string { - if (removeUnderscore) { - return func(str); - } - - return str - .split('_') - .map(s => func(s)) - .join('_'); -} - export function buildScalarsFromConfig( schema: GraphQLSchema | undefined, config: RawConfig, defaultScalarsMapping: NormalizedScalarsMap = DEFAULT_SCALARS, - defaultScalarType = 'any', + defaultScalarType = 'unknown', ): ParsedScalarsMap { return buildScalars( schema, @@ -302,7 +284,7 @@ export function buildScalars( schema: GraphQLSchema | undefined, scalarsMapping: ScalarsMap, defaultScalarsMapping: NormalizedScalarsMap = DEFAULT_SCALARS, - defaultScalarType: string | null = 'any', + defaultScalarType: string | null = 'unknown', ): ParsedScalarsMap { const result: ParsedScalarsMap = {}; @@ -446,13 +428,6 @@ function isStringValueNode(node: any): node is StringValueNode { return node && typeof node === 'object' && node.kind === Kind.STRING; } -// will be removed on next release because tools already has it -export function getRootTypeNames(schema: GraphQLSchema): string[] { - return [schema.getQueryType(), schema.getMutationType(), schema.getSubscriptionType()] - .filter(t => t) - .map(t => t.name); -} - export function stripMapperTypeInterpolation(identifier: string): string { return identifier.trim().replace(/<{.*}>/, ''); } @@ -512,7 +487,7 @@ export const getFieldNodeNameValue = (node: FieldNode): string => { }; export function separateSelectionSet(selections: ReadonlyArray): { - fields: (FieldNode & FragmentDirectives)[]; + fields: FieldNode[]; spreads: FragmentSpreadNode[]; inlines: InlineFragmentNode[]; } { @@ -540,12 +515,20 @@ export function getPossibleTypes( return []; } -export function hasConditionalDirectives(field: FieldNode): boolean { +/** + * Check if any of the directives are conditional i.e. `@skip` and `@include` + */ +export function hasConditionalDirectives(directives: readonly DirectiveNode[] = []): boolean { const CONDITIONAL_DIRECTIVES = ['skip', 'include']; - return field.directives?.some(directive => CONDITIONAL_DIRECTIVES.includes(directive.name.value)); + return directives.some(directive => CONDITIONAL_DIRECTIVES.includes(directive.name.value)); } -export function hasIncrementalDeliveryDirectives(directives: DirectiveNode[]): boolean { +/** + * Check if any of the directives are incremental i.e. `@defer` + */ +export function hasIncrementalDeliveryDirectives( + directives: readonly DirectiveNode[] = [], +): boolean { const INCREMENTAL_DELIVERY_DIRECTIVES = ['defer']; return directives?.some(directive => INCREMENTAL_DELIVERY_DIRECTIVES.includes(directive.name.value), @@ -721,3 +704,55 @@ export const getFieldNames = ({ } return fieldNames; }; + +export const getNodeComment = ( + node: FieldDefinitionNode | EnumValueDefinitionNode | InputValueDefinitionNode, +): string => { + let commentText = node.description?.value; + const deprecationDirective = node.directives.find(v => v.name.value === 'deprecated'); + if (deprecationDirective) { + const deprecationReason = getDeprecationReason(deprecationDirective); + commentText = `${commentText ? `${commentText}\n` : ''}@deprecated ${deprecationReason}`; + } + const comment = transformComment(commentText, 1); + return comment; +}; + +const getDeprecationReason = (directive: DirectiveNode): string | void => { + if (directive.name.value === 'deprecated') { + let reason = 'Field no longer supported'; + const deprecatedReason = directive.arguments[0]; + if (deprecatedReason && deprecatedReason.value.kind === Kind.STRING) { + reason = deprecatedReason.value.value; + } + return reason; + } +}; + +/** + * @description Utility function to print a TypeScript type that is `Maybe`. + * We need this since some TypeScript types have special handling. + * e.g. `unknown | null | undefined` is treated as `unknown` + * + * Note: we currently have two types of handling nullable: `Maybe` or `T | null | undefined` + * This function only handles the latter case at the moment, but could be extended if needed. + * + * @param {Object} params + * @param {string} params.type - The TypeScript type e.g. `any`, `unknown`, `string`, `Something` + * @param {string} params.pattern - The pattern of the Maybe type. This is usually `T | null | undefined` or `T | null` + * @returns {string} The TypeScript type as string + */ +export const printTypeScriptMaybeType = ({ + type, + pattern, +}: { + type: string; + pattern: string; +}): string => { + if (type === 'any' || type === 'unknown') { + return type; + } + + const nullableSuffix = pattern.replace('T', ''); + return type.endsWith(nullableSuffix) ? type : `${type}${nullableSuffix}`; +}; diff --git a/packages/plugins/other/visitor-plugin-common/src/variables-to-object.ts b/packages/plugins/other/visitor-plugin-common/src/variables-to-object.ts index 74b68a0ca7f..ca4b6ee09b3 100644 --- a/packages/plugins/other/visitor-plugin-common/src/variables-to-object.ts +++ b/packages/plugins/other/visitor-plugin-common/src/variables-to-object.ts @@ -109,7 +109,8 @@ export class OperationVariablesToObject { typeValue = this.getScalar(typeName); } else if (this._enumValues[typeName]?.sourceFile) { typeValue = - this._enumValues[typeName].typeIdentifier || this._enumValues[typeName].sourceIdentifier; + this._enumValues[typeName].typeIdentifierConverted || + this._enumValues[typeName].sourceIdentifier; } else { typeValue = `${prefix}${this._convertName(baseType, { useTypesPrefix: this._enumNames.includes(typeName) ? this._enumPrefix : true, diff --git a/packages/plugins/other/visitor-plugin-common/tests/enum-values.spec.ts b/packages/plugins/other/visitor-plugin-common/tests/enum-values.spec.ts index 91aecaf1489..c982666b064 100644 --- a/packages/plugins/other/visitor-plugin-common/tests/enum-values.spec.ts +++ b/packages/plugins/other/visitor-plugin-common/tests/enum-values.spec.ts @@ -1,5 +1,6 @@ import { buildSchema, GraphQLEnumType, GraphQLObjectType, GraphQLSchema } from 'graphql'; import { parseEnumValues } from '../src/enum-values.js'; +import { convertFactory } from '../src/naming.js'; describe('enumValues', () => { const schema = buildSchema(/* GraphQL */ ` @@ -20,12 +21,20 @@ describe('enumValues', () => { mapOrStr: { Test: `my-file#SomeNamespace.ETest`, }, + naming: { + convert: convertFactory({}), + options: { + typesPrefix: '', + typesSuffix: '', + }, + }, }); expect(result).toEqual({ Test: { isDefault: false, typeIdentifier: 'Test', + typeIdentifierConverted: 'Test', sourceFile: 'my-file', sourceIdentifier: 'SomeNamespace.ETest', importIdentifier: 'SomeNamespace', @@ -40,12 +49,20 @@ describe('enumValues', () => { mapOrStr: { Test: `my-file#ETest`, }, + naming: { + convert: convertFactory({}), + options: { + typesPrefix: '', + typesSuffix: '', + }, + }, }); expect(result).toEqual({ Test: { isDefault: false, typeIdentifier: 'Test', + typeIdentifierConverted: 'Test', sourceFile: 'my-file', sourceIdentifier: 'ETest', importIdentifier: 'ETest', @@ -60,12 +77,20 @@ describe('enumValues', () => { mapOrStr: { Test: `my-file#ETest as Something`, }, + naming: { + convert: convertFactory({}), + options: { + typesPrefix: '', + typesSuffix: '', + }, + }, }); expect(result).toEqual({ Test: { isDefault: false, typeIdentifier: 'Test', + typeIdentifierConverted: 'Test', sourceFile: 'my-file', sourceIdentifier: 'Something', importIdentifier: 'ETest as Something', @@ -106,12 +131,20 @@ describe('enumValues', () => { schema: schemaWithEnumValues, mapOrStr: {}, ignoreEnumValuesFromSchema: false, + naming: { + convert: convertFactory({}), + options: { + typesPrefix: '', + typesSuffix: '', + }, + }, }); expect(result).toEqual({ Test: { isDefault: false, typeIdentifier: 'Test', + typeIdentifierConverted: 'Test', sourceFile: null, importIdentifier: null, sourceIdentifier: null, @@ -130,22 +163,16 @@ describe('enumValues', () => { schema: schemaWithEnumValues, mapOrStr: {}, ignoreEnumValuesFromSchema: true, - }); - - expect(result).not.toEqual({ - Test: { - isDefault: false, - typeIdentifier: 'Test', - sourceFile: null, - importIdentifier: null, - sourceIdentifier: null, - mappedValues: { - A: 'a', - B: 'b', - C: 'c', + naming: { + convert: convertFactory({}), + options: { + typesPrefix: '', + typesSuffix: '', }, }, }); + + expect(result).toEqual({}); }); const schemaWithNonStringEnumValues = new GraphQLSchema({ @@ -180,20 +207,27 @@ describe('enumValues', () => { schema: schemaWithNonStringEnumValues, mapOrStr: {}, ignoreEnumValuesFromSchema: false, + naming: { + convert: convertFactory({}), + options: { + typesPrefix: '', + typesSuffix: '', + }, + }, }); - expect(result).not.toEqual({ + expect(result).toEqual({ Test: { isDefault: false, typeIdentifier: 'Test', + typeIdentifierConverted: 'Test', sourceFile: null, importIdentifier: null, sourceIdentifier: null, mappedValues: { - A: '1', - B: 'true', - C: 'null', - D: 'undefined', + A: 1, + B: true, + C: null, }, }, }); diff --git a/packages/plugins/typescript/document-nodes/CHANGELOG.md b/packages/plugins/typescript/document-nodes/CHANGELOG.md index 3f5898f18a2..e75cb4a86bf 100644 --- a/packages/plugins/typescript/document-nodes/CHANGELOG.md +++ b/packages/plugins/typescript/document-nodes/CHANGELOG.md @@ -1,5 +1,66 @@ # @graphql-codegen/typescript-document-nodes +## 6.0.0 + +### Major Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Update deps to latest, some + only support ESM + + Node 20 support is dropped in this release. Node 22 comes with `require()` support for ESM, which + means it's easier to integrate ES modules into applications. Therefore, it is safe to start using + ESM-only packages. + + If you are a user, please upgrade to Node 22. If you are a lib maintainer and see ESM vs CJS + issues when running Jest tests, try using Vitest. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Drop Node 20 support + +### Patch Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - dependencies updates: + - Updated dependency [`auto-bind@^5.0.0` ↗︎](https://www.npmjs.com/package/auto-bind/v/5.0.0) (from + `~4.0.0`, in `dependencies`) + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - dependencies updates: + - Updated dependency [`auto-bind@^5.0.0` ↗︎](https://www.npmjs.com/package/auto-bind/v/5.0.0) (from + `~4.0.0`, in `dependencies`) +- Updated dependencies + [[`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29)]: + - @graphql-codegen/plugin-helpers@7.0.0 + - @graphql-codegen/visitor-plugin-common@7.0.0 + ## 5.0.10 ### Patch Changes diff --git a/packages/plugins/typescript/document-nodes/package.json b/packages/plugins/typescript/document-nodes/package.json index 75c06cf5033..3dddebad8da 100644 --- a/packages/plugins/typescript/document-nodes/package.json +++ b/packages/plugins/typescript/document-nodes/package.json @@ -1,6 +1,6 @@ { "name": "@graphql-codegen/typescript-document-nodes", - "version": "5.0.10", + "version": "6.0.0", "type": "module", "description": "GraphQL Code Generator plugin for generating TypeScript modules with embedded GraphQL document nodes", "repository": { @@ -40,9 +40,9 @@ "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" }, "dependencies": { - "@graphql-codegen/plugin-helpers": "^6.3.0", - "@graphql-codegen/visitor-plugin-common": "^6.3.0", - "auto-bind": "~4.0.0", + "@graphql-codegen/plugin-helpers": "^7.0.0", + "@graphql-codegen/visitor-plugin-common": "^7.0.0", + "auto-bind": "^5.0.0", "tslib": "^2.8.0" }, "publishConfig": { diff --git a/packages/plugins/typescript/gql-tag-operations/CHANGELOG.md b/packages/plugins/typescript/gql-tag-operations/CHANGELOG.md index dd5584aa9a6..be6bf10c5fb 100644 --- a/packages/plugins/typescript/gql-tag-operations/CHANGELOG.md +++ b/packages/plugins/typescript/gql-tag-operations/CHANGELOG.md @@ -1,5 +1,66 @@ # @graphql-codegen/gql-tag-operations +## 6.0.0 + +### Major Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Update deps to latest, some + only support ESM + + Node 20 support is dropped in this release. Node 22 comes with `require()` support for ESM, which + means it's easier to integrate ES modules into applications. Therefore, it is safe to start using + ESM-only packages. + + If you are a user, please upgrade to Node 22. If you are a lib maintainer and see ESM vs CJS + issues when running Jest tests, try using Vitest. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Drop Node 20 support + +### Patch Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - dependencies updates: + - Updated dependency [`auto-bind@^5.0.0` ↗︎](https://www.npmjs.com/package/auto-bind/v/5.0.0) (from + `~4.0.0`, in `dependencies`) + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - dependencies updates: + - Updated dependency [`auto-bind@^5.0.0` ↗︎](https://www.npmjs.com/package/auto-bind/v/5.0.0) (from + `~4.0.0`, in `dependencies`) +- Updated dependencies + [[`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29)]: + - @graphql-codegen/plugin-helpers@7.0.0 + - @graphql-codegen/visitor-plugin-common@7.0.0 + ## 5.2.0 ### Minor Changes diff --git a/packages/plugins/typescript/gql-tag-operations/package.json b/packages/plugins/typescript/gql-tag-operations/package.json index c6b24dc0aa1..702f7a769b3 100644 --- a/packages/plugins/typescript/gql-tag-operations/package.json +++ b/packages/plugins/typescript/gql-tag-operations/package.json @@ -1,6 +1,6 @@ { "name": "@graphql-codegen/gql-tag-operations", - "version": "5.2.0", + "version": "6.0.0", "type": "module", "description": "GraphQL Code Generator plugin for generating a typed gql tag function", "repository": { @@ -40,10 +40,10 @@ "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" }, "dependencies": { - "@graphql-codegen/plugin-helpers": "^6.3.0", - "@graphql-codegen/visitor-plugin-common": "^6.3.0", + "@graphql-codegen/plugin-helpers": "^7.0.0", + "@graphql-codegen/visitor-plugin-common": "^7.0.0", "@graphql-tools/utils": "^11.0.0", - "auto-bind": "~4.0.0", + "auto-bind": "^5.0.0", "tslib": "^2.8.0" }, "publishConfig": { diff --git a/packages/plugins/typescript/operations/CHANGELOG.md b/packages/plugins/typescript/operations/CHANGELOG.md index 8ae17ff9e78..d54c7ac1fb6 100644 --- a/packages/plugins/typescript/operations/CHANGELOG.md +++ b/packages/plugins/typescript/operations/CHANGELOG.md @@ -1,5 +1,291 @@ # @graphql-codegen/typescript-operations +## 6.0.0 + +### Major Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Fix nullable field optionality in operations + + Previously, a nullable Result field is generated as optional (marked by `?` TypeScript modifier) + by default. This is not correct, because generally at runtime such field can only be `null`, and + not `undefined` (both missing from the object OR `undefined`). The only exceptions are when fields + are deferred (using `@defer` directive) or marked as conditional (using `@skip` or `@include`). + + Now, a nullable Result field cannot be optional unless the exceptions are met. This also limits + `avoidOptionals` to only target Variables input, since some users may want to force explicit + `null` when providing operation variables. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: visitors' config option are + moved based on their use case + - addTypename/skipTypename: is only a types-visitor concern. This is moved to types-visitor from + base-visitor + - nonOptionalTypename: is a documents-visitor and types-visitor concern. Moved from base-visitor + there + - extractAllFieldsToTypes: is a documents-visitor concern. Moved from base-visitor there + - enumPrefix and enumSuffix: need to be in base-visitor as all 3 types of visitors need this to + correctly sync the enum type names. This is moved to base visitor + - ignoreEnumValuesFromSchema: is a documents-visitor and types-visitor concern. Moved from + base-visitor there. + - globalNamespace: is a documents-visitor concern. Moved from base-visitor there + + Refactors + - documents-visitor no longer extends types-visitor _option types_ as they have two distinct + usages now. The types now extend base-visitor types. This is now consistent with + documents-visitor extending base-visitor + - Classes now handle config parsing and types at the same level e.g. if typescript-operations + plugin parses configOne, then the types for configOne must be in that class, rather than in + base-documents-visitor + + Note: These visitors are rolled up into one type for simplicity + - base-visitor: includes `base-visitor` + - documents-visitor: includes `base-documents-visitor` and `typescript-operations` visitor + - types-visitor: includes `base-types-visitor` and `typescript` visitor + - resolvers-visitor: includes `base-resolvers-visitor` and `typescript-resolvers` visitor + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: typescript-operations plugin + now generates enum if it is used in operation. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Conditionally generate input types and output + enums into target file + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: make `unknown` instead of + `any` the default custom scalar type + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Update deps to latest, some + only support ESM + + Node 20 support is dropped in this release. Node 22 comes with `require()` support for ESM, which + means it's easier to integrate ES modules into applications. Therefore, it is safe to start using + ESM-only packages. + + If you are a user, please upgrade to Node 22. If you are a lib maintainer and see ESM vs CJS + issues when running Jest tests, try using Vitest. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Drop Node 20 support + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Decouple + `typescript-operations` plugin from `typescript` plugin + + Previously, `TypeScriptOperationVariablesToObject` from `typescript-operations` was extending from + `typescript` plugin. This made it (1) very hard to read, as we need to jump from base class <-> + typescript class <-> typescript-operations class to understand the flow and (2) very hard to + evolve the two independently (which is the point of this work). + + Since there's not much shared logic anyways, it's simpler to extend the `typescript-operations` + class from the base class directly. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - The `typescript-operations` plugin no longer + generates InputMaybe and Scalars types; it now uses native Typescript types instead. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: `typescript` plugin no + longer generates `Exact` utility type. Instead, `typescript-operations` generates said utility + type for every file it creates. This is because it is used _only_ for `Variables`, so we only need + to generate it once for every generated operation file. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Operation plugin and Client + Preset no longer generates optional `__typename` for result type + + `__typenam` should not be in the request unless: + - explicitly requested by the user + - automatically injected into the request by clients, such as Apollo Clients. + + Note: Apollo Client users can still use `nonOptionalTypename: true` and + `skipTypeNameForRoot: true` to ensure generated types match the runtime behaviour. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Integrate new typescript-operations into + client-preset + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: config.avoidOptionals now + only supports object, inputValue, defaultValue + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: rename avoidOptionals.object + to avoidOptionals.variableValue + +### Minor Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Add support for declarationKind for + typescript-operations + - Input: can only be `type` or `interface` + - Variables: no support. It must always be `type` because it's an alias e.g. + `Variables = Exact<{ something: type }>` + - Result: can only be `type` or `interface` + - Note: when `extractAllFieldsToTypes:true` or `extractAllFieldsToTypesCompact:true`, Results + are used as type alias, so they are forced to be `type`. There is a console warning for users. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Add importSchemaTypesFrom support + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Add generateOperationTypes to + typescript-operations to allow omitting operation types such as Variables, + Query/Mutation/Subscription selection set, and Fragment types + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Fixing 2 bugs: 1) including enums from + external fragments; 2) extractAllFieldsToTypesCompact does not create duplicates + +### Patch Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - dependencies updates: + - Updated dependency [`auto-bind@^5.0.0` ↗︎](https://www.npmjs.com/package/auto-bind/v/5.0.0) (from + `~4.0.0`, in `dependencies`) + - Added dependency + [`@graphql-codegen/schema-ast@^5.0.1` ↗︎](https://www.npmjs.com/package/@graphql-codegen/schema-ast/v/5.0.1) + (to `dependencies`) + - Removed dependency + [`@graphql-codegen/typescript@^5.0.10` ↗︎](https://www.npmjs.com/package/@graphql-codegen/typescript/v/5.0.10) + (from `dependencies`) + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - dependencies updates: + - Added dependency + [`@graphql-codegen/schema-ast@^5.0.0` ↗︎](https://www.npmjs.com/package/@graphql-codegen/schema-ast/v/5.0.0) + (to `dependencies`) + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - dependencies updates: + - Removed dependency + [`@graphql-codegen/typescript@^5.0.7` ↗︎](https://www.npmjs.com/package/@graphql-codegen/typescript/v/5.0.7) + (from `dependencies`) + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - dependencies updates: + - Updated dependency [`auto-bind@^5.0.0` ↗︎](https://www.npmjs.com/package/auto-bind/v/5.0.0) (from + `~4.0.0`, in `dependencies`) + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Improve `namespacedImportName` usability by + setting a default when `importSchemaTypesFrom` is set + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Add internal utility type warning to deter + usage + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Add `printTypeScriptMaybeType` to handle + printing TS types, as there are special cases like `any` and `unknown` + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Re-implement inputMaybeValue + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Only generate `Exact` utility type at the top + if it is used + + `Exact` utility is only used to wrap variables types for operations (queries, mutations and + subscriptions) if they exist in the document. `Exact` is never used when there are _only_ + fragments. + + This is important to conditionally generate as users may use very strict tsconfig that will fail + compiling if there are unused types. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Fix external custom scalars not getting + imported + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Ensure Input and Variables use the same input + scalars default e.g. `ID` can take `string | number` + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Fix `@skip` and `@include` not applying + conditional modifiers correctly when used on inline fragment + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Abstract how enum imports are generated into + visitor-plugin-common package + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Fix `@skip` and `@include` not applying + conditional modifiers correctly when used on fragment sread, and `@defer` fragments + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Fix importing issue of Input when + importSchemaTypesFrom is used + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Fix namingConvention not being applied + consistently in imports, Variables, Input and Result + +- Updated dependencies + [[`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29)]: + - @graphql-codegen/plugin-helpers@7.0.0 + - @graphql-codegen/visitor-plugin-common@7.0.0 + - @graphql-codegen/schema-ast@6.0.0 + ## 5.1.0 ### Minor Changes diff --git a/packages/plugins/typescript/operations/package.json b/packages/plugins/typescript/operations/package.json index 437c8049e46..c27678f81d4 100644 --- a/packages/plugins/typescript/operations/package.json +++ b/packages/plugins/typescript/operations/package.json @@ -1,6 +1,6 @@ { "name": "@graphql-codegen/typescript-operations", - "version": "5.1.0", + "version": "6.0.0", "type": "module", "description": "GraphQL Code Generator plugin for generating TypeScript types for GraphQL queries, mutations, subscriptions and fragments", "repository": { @@ -46,10 +46,10 @@ } }, "dependencies": { - "@graphql-codegen/plugin-helpers": "^6.3.0", - "@graphql-codegen/typescript": "^5.0.10", - "@graphql-codegen/visitor-plugin-common": "^6.3.0", - "auto-bind": "~4.0.0", + "@graphql-codegen/plugin-helpers": "^7.0.0", + "@graphql-codegen/schema-ast": "^6.0.0", + "@graphql-codegen/visitor-plugin-common": "^7.0.0", + "auto-bind": "^5.0.0", "tslib": "^2.8.0" }, "devDependencies": { diff --git a/packages/plugins/typescript/operations/src/config.ts b/packages/plugins/typescript/operations/src/config.ts index ec83928eecc..eb2db30ad27 100644 --- a/packages/plugins/typescript/operations/src/config.ts +++ b/packages/plugins/typescript/operations/src/config.ts @@ -1,10 +1,12 @@ -import { AvoidOptionalsConfig, RawDocumentsConfig } from '@graphql-codegen/visitor-plugin-common'; +import { + RawDocumentsConfig, + type ConvertSchemaEnumToDeclarationBlockString, + type EnumValuesMap, +} from '@graphql-codegen/visitor-plugin-common'; /** * @description This plugin generates TypeScript types based on your GraphQLSchema _and_ your GraphQL operations and fragments. * It generates types for your GraphQL documents: Query, Mutation, Subscription and Fragment. - * - * Note: In most configurations, this plugin requires you to use `typescript as well, because it depends on its base types. */ export interface TypeScriptDocumentsPluginConfig extends RawDocumentsConfig { /** @@ -23,7 +25,7 @@ export interface TypeScriptDocumentsPluginConfig extends RawDocumentsConfig { * // ... * generates: { * 'path/to/file.ts': { - * plugins: ['typescript'], + * plugins: ['typescript-operations'], * config: { * arrayInputCoercion: false * }, @@ -34,57 +36,6 @@ export interface TypeScriptDocumentsPluginConfig extends RawDocumentsConfig { * ``` */ arrayInputCoercion?: boolean; - /** - * @description This will cause the generator to avoid using TypeScript optionals (`?`) on types, - * so the following definition: `type A { myField: String }` will output `myField: Maybe` - * instead of `myField?: Maybe`. - * @default false - * - * @exampleMarkdown - * ## Override all definition types - * - * ```ts filename="codegen.ts" - * import type { CodegenConfig } from '@graphql-codegen/cli'; - * - * const config: CodegenConfig = { - * // ... - * generates: { - * 'path/to/file.ts': { - * plugins: ['typescript'], - * config: { - * avoidOptionals: true - * }, - * }, - * }, - * }; - * export default config; - * ``` - * - * ## Override only specific definition types - * - * ```ts filename="codegen.ts" - * import type { CodegenConfig } from '@graphql-codegen/cli'; - * - * const config: CodegenConfig = { - * // ... - * generates: { - * 'path/to/file.ts': { - * plugins: ['typescript'], - * config: { - * avoidOptionals: { - * field: true - * inputValue: true - * object: true - * defaultValue: true - * } - * }, - * }, - * }, - * }; - * export default config; - * ``` - */ - avoidOptionals?: boolean | AvoidOptionalsConfig; /** * @description Generates immutable types by adding `readonly` to properties and uses `ReadonlyArray`. * @default false @@ -97,7 +48,7 @@ export interface TypeScriptDocumentsPluginConfig extends RawDocumentsConfig { * // ... * generates: { * 'path/to/file.ts': { - * plugins: ['typescript'], + * plugins: ['typescript-operations'], * config: { * immutableTypes: true * }, @@ -120,7 +71,7 @@ export interface TypeScriptDocumentsPluginConfig extends RawDocumentsConfig { * // ... * generates: { * 'path/to/file.ts': { - * plugins: ['typescript', 'typescript-operations'], + * plugins: ['typescript-operations'], * config: { * flattenGeneratedTypes: true * }, @@ -144,7 +95,7 @@ export interface TypeScriptDocumentsPluginConfig extends RawDocumentsConfig { * // ... * generates: { * 'path/to/file.ts': { - * plugins: ['typescript', 'typescript-operations'], + * plugins: ['typescript-operations'], * config: { * flattenGeneratedTypes: true, * flattenGeneratedTypesIncludeFragments: true @@ -170,7 +121,7 @@ export interface TypeScriptDocumentsPluginConfig extends RawDocumentsConfig { * // ... * generates: { * 'path/to/file.ts': { - * plugins: ['typescript'], + * plugins: ['typescript-operations'], * config: { * noExport: true * }, @@ -181,7 +132,6 @@ export interface TypeScriptDocumentsPluginConfig extends RawDocumentsConfig { * ``` */ noExport?: boolean; - globalNamespace?: boolean; /** * @name addOperationExport * @type boolean @@ -202,23 +152,19 @@ export interface TypeScriptDocumentsPluginConfig extends RawDocumentsConfig { * const config: CodegenConfig = { * // ... * generates: { - * "./typings/api.ts": { - * "plugins": [ - * "typescript" - * ] - * }, - * "./": { + * "./": { * "preset": "near-operation-file", * "presetConfig": { - * "baseTypesPath": "./typings/api.ts", - * "extension": ".gql.d.ts" + * "baseTypesPath": "./typings/api.ts", + * "extension": ".gql.d.ts" * }, * "plugins": [ - * "@graphql-codegen/typescript-operations" + * "typescript-operations" * ], * "config": { - * "addOperationExport": true + * "addOperationExport": true * } + * } * } * }; * export default config; @@ -226,11 +172,13 @@ export interface TypeScriptDocumentsPluginConfig extends RawDocumentsConfig { */ addOperationExport?: boolean; /** - * @description Allow to override the type value of `Maybe`. + * @description Allows overriding the type value of nullable fields to match GraphQL client's runtime behaviour. * @default T | null * * @exampleMarkdown * ## Allow undefined + * By default, a GraphQL server will return either the expected type or `null` for a nullable field. + * `maybeValue` option could be used to change this behaviour if your GraphQL client does something different such as returning `undefined`. * ```ts filename="codegen.ts" * import type { CodegenConfig } from '@graphql-codegen/cli'; * @@ -238,7 +186,7 @@ export interface TypeScriptDocumentsPluginConfig extends RawDocumentsConfig { * // ... * generates: { * 'path/to/file.ts': { - * plugins: ['typescript'], + * plugins: ['typescript-operations'], * config: { * maybeValue: 'T | null | undefined' * }, @@ -247,26 +195,38 @@ export interface TypeScriptDocumentsPluginConfig extends RawDocumentsConfig { * }; * export default config; * ``` + */ + maybeValue?: string; + + /** + * @description Allows overriding the type of Input and Variables nullable types. + * @default T | null | undefined + * + * @exampleMarkdown + * ## Disallow `undefined` + * Disallowing `undefined` is useful if you want to force explicit null to be passed in as Variables to the server. Use `inputMaybeValue: 'T | null'` with `avoidOptionals.inputValue: true` to achieve this. * - * ## Allow `null` in resolvers: * ```ts filename="codegen.ts" - * import type { CodegenConfig } from '@graphql-codegen/cli'; + * import type { CodegenConfig } from '@graphql-codegen/cli' * - * const config: CodegenConfig = { - * // ... - * generates: { - * 'path/to/file.ts': { - * plugins: ['typescript'], - * config: { - * maybeValue: 'T extends PromiseLike ? Promise : T | null' - * }, - * }, - * }, - * }; - * export default config; + * const config: CodegenConfig = { + * // ... + * generates: { + * 'path/to/file.ts': { + * plugins: ['typescript-operations'], + * config: { + * avoidOptionals: { + * inputValue: true, + * }, + * inputMaybeValue: 'T | null' + * } + * } + * } + * } + * export default config * ``` */ - maybeValue?: string; + inputMaybeValue?: string; /** * @description Adds undefined as a possible type for query variables @@ -280,7 +240,7 @@ export interface TypeScriptDocumentsPluginConfig extends RawDocumentsConfig { * // ... * generates: { * 'path/to/file.ts': { - * plugins: ['typescript'], + * plugins: ['typescript-operations'], * config: { * allowUndefinedQueryVariables: true * }, @@ -321,7 +281,7 @@ export interface TypeScriptDocumentsPluginConfig extends RawDocumentsConfig { * // ... * generates: { * 'path/to/file.ts': { - * plugins: ['typescript', 'typescript-operations'], + * plugins: ['typescript-operations'], * config: { * nullability: { * errorHandlingClient: true @@ -336,4 +296,146 @@ export interface TypeScriptDocumentsPluginConfig extends RawDocumentsConfig { nullability?: { errorHandlingClient: boolean; }; + + /** + * @description Controls the enum output type. Options: `string-literal` | `native-numeric` | `const` | `native-const` | `native`; + * @default `string-literal` + * + * @exampleMarkdown + * ```ts filename="codegen.ts" + * import type { CodegenConfig } from '@graphql-codegen/cli' + * + * const config: CodegenConfig = { + * // ... + * generates: { + * 'path/to/file.ts': { + * plugins: ['typescript-operations'], + * config: { + * enumType: 'string-literal', + * } + * } + * } + * } + * export default config + * ``` + */ + enumType?: ConvertSchemaEnumToDeclarationBlockString['outputType']; + + /** + * @description Overrides the default value of enum values declared in your GraphQL schema. + * You can also map the entire enum to an external type by providing a string that of `module#type`. + * + * @exampleMarkdown + * ## With Custom Values + * ```ts filename="codegen.ts" + * import type { CodegenConfig } from '@graphql-codegen/cli'; + * + * const config: CodegenConfig = { + * // ... + * generates: { + * 'path/to/file': { + * // plugins... + * config: { + * enumValues: { + * MyEnum: { + * A: 'foo' + * } + * } + * }, + * }, + * }, + * }; + * export default config; + * ``` + * + * ## With External Enum + * ```ts filename="codegen.ts" + * import type { CodegenConfig } from '@graphql-codegen/cli'; + * + * const config: CodegenConfig = { + * // ... + * generates: { + * 'path/to/file': { + * // plugins... + * config: { + * enumValues: { + * MyEnum: './my-file#MyCustomEnum', + * } + * }, + * }, + * }, + * }; + * export default config; + * ``` + * + * ## Import All Enums from a file + * ```ts filename="codegen.ts" + * import type { CodegenConfig } from '@graphql-codegen/cli'; + * + * const config: CodegenConfig = { + * // ... + * generates: { + * 'path/to/file': { + * // plugins... + * config: { + * enumValues: { + * MyEnum: './my-file', + * } + * }, + * }, + * }, + * }; + * export default config; + * ``` + */ + enumValues?: EnumValuesMap; + /** + * @description This will cause the generator to ignore enum values defined in GraphQLSchema + * @default false + * + * @exampleMarkdown + * ## Ignore enum values from schema + * + * ```ts filename="codegen.ts" + * import type { CodegenConfig } from '@graphql-codegen/cli'; + * + * const config: CodegenConfig = { + * // ... + * generates: { + * 'path/to/file': { + * // plugins... + * config: { + * ignoreEnumValuesFromSchema: true, + * }, + * }, + * }, + * }; + * export default config; + * ``` + */ + ignoreEnumValuesFromSchema?: boolean; + /** + * @description This option controls whether or not a catch-all entry is added to enum type definitions for values that may be added in the future. + * This is useful if you are using `relay`. + * @default false + * + * @exampleMarkdown + * ```ts filename="codegen.ts" + * import type { CodegenConfig } from '@graphql-codegen/cli' + * + * const config: CodegenConfig = { + * // ... + * generates: { + * 'path/to/file.ts': { + * plugins: ['typescript-operations'], + * config: { + * futureProofEnums: true + * } + * } + * } + * } + * export default config + * ``` + */ + futureProofEnums?: boolean; } diff --git a/packages/plugins/typescript/operations/src/index.ts b/packages/plugins/typescript/operations/src/index.ts index d047ea252be..2a3da5d0802 100644 --- a/packages/plugins/typescript/operations/src/index.ts +++ b/packages/plugins/typescript/operations/src/index.ts @@ -1,19 +1,14 @@ -import { concatAST, FragmentDefinitionNode, GraphQLSchema, Kind, type DocumentNode } from 'graphql'; +import { concatAST, GraphQLSchema, type DocumentNode } from 'graphql'; import { oldVisit, PluginFunction, Types } from '@graphql-codegen/plugin-helpers'; -import { LoadedFragment, optimizeOperations } from '@graphql-codegen/visitor-plugin-common'; +import { transformSchemaAST } from '@graphql-codegen/schema-ast'; +import { optimizeOperations } from '@graphql-codegen/visitor-plugin-common'; import { TypeScriptDocumentsPluginConfig } from './config.js'; import { TypeScriptDocumentsVisitor } from './visitor.js'; -export { TypeScriptDocumentsPluginConfig } from './config.js'; - export const plugin: PluginFunction< TypeScriptDocumentsPluginConfig, Types.ComplexPluginOutput -> = async ( - inputSchema: GraphQLSchema, - rawDocuments: Types.DocumentFile[], - config: TypeScriptDocumentsPluginConfig, -) => { +> = async (inputSchema, rawDocuments, config, { outputFile }) => { const schema = config.nullability?.errorHandlingClient ? await semanticToStrict(inputSchema) : inputSchema; @@ -57,43 +52,37 @@ export const plugin: PluginFunction< // For Fragment types to resolve correctly, we must get read all docs (`standard` and `external`) // Fragment types are usually (but not always) in `external` files in certain setup, like a monorepo. const allDocumentsAST = concatAST(parsedDocuments.all.documentNodes); - const allFragments: LoadedFragment[] = [ - ...( - allDocumentsAST.definitions.filter( - d => d.kind === Kind.FRAGMENT_DEFINITION, - ) as FragmentDefinitionNode[] - ).map(fragmentDef => ({ - node: fragmentDef, - name: fragmentDef.name.value, - onType: fragmentDef.typeCondition.name.value, - isExternal: false, - })), - ...(config.externalFragments || []), - ]; - - const visitor = new TypeScriptDocumentsVisitor(schema, config, allFragments); + const visitor = new TypeScriptDocumentsVisitor(schema, config, allDocumentsAST, outputFile); // We only visit `standard` documents to generate types. // `external` documents are included as references for typechecking and completeness i.e. only used for reading purposes, no writing. const documentsToVisitAST = concatAST(parsedDocuments.standard.documentNodes); - const visitorResult = oldVisit(documentsToVisitAST, { + const operationsResult = oldVisit(documentsToVisitAST, { leave: visitor, }); - let content = visitorResult.definitions.join('\n'); + const operationsDefinitions = operationsResult.definitions; if (config.addOperationExport) { - const exportConsts = []; - for (const d of allDocumentsAST.definitions) { if ('name' in d) { - exportConsts.push(`export declare const ${d.name.value}: import("graphql").DocumentNode;`); + operationsDefinitions.push( + `export declare const ${d.name.value}: import("graphql").DocumentNode;`, + ); } } - - content = visitorResult.definitions.concat(exportConsts).join('\n'); } + const schemaTypes = oldVisit(transformSchemaAST(schema, config).ast, { leave: visitor }); + + // IMPORTANT: when a visitor leaves a node with no transformation logic, + // It will leave the node as an object. + // Here, we filter in nodes that have been turned into strings, i.e. they have been transformed + // This way, we do not have to explicitly declare a method for every node type to convert them to null + const schemaTypesDefinitions = schemaTypes.definitions.filter(def => typeof def === 'string'); + + let content = [...schemaTypesDefinitions, ...operationsDefinitions].join('\n'); + if (config.globalNamespace) { content = ` declare global { @@ -102,12 +91,20 @@ export const plugin: PluginFunction< } return { - prepend: [...visitor.getImports(), ...visitor.getGlobalDeclarations(visitor.config.noExport)], + prepend: [ + ...visitor.getImports(), + ...visitor.getExternalSchemaTypeImports(), + ...visitor.getEnumsImports(), + ...visitor.getScalarsImports(), + ...visitor.getGlobalDeclarations(visitor.config.noExport), + visitor.getExactUtilityType(), + visitor.getIncrementalUtilityType(), + ], content, }; }; -export { TypeScriptDocumentsVisitor }; +export { TypeScriptDocumentsVisitor, type TypeScriptDocumentsPluginConfig }; const semanticToStrict = async (schema: GraphQLSchema): Promise => { try { diff --git a/packages/plugins/typescript/operations/src/ts-operation-variables-to-object.ts b/packages/plugins/typescript/operations/src/ts-operation-variables-to-object.ts index 4448bfc28e6..58decf2307d 100644 --- a/packages/plugins/typescript/operations/src/ts-operation-variables-to-object.ts +++ b/packages/plugins/typescript/operations/src/ts-operation-variables-to-object.ts @@ -1,6 +1,51 @@ -import { TypeScriptOperationVariablesToObject as TSOperationVariablesToObject } from '@graphql-codegen/typescript'; +import { Kind, TypeNode } from 'graphql'; +import { + ConvertNameFn, + DEFAULT_INPUT_SCALARS, + NormalizedScalarsMap, + OperationVariablesToObject, + ParsedEnumValuesMap, + printTypeScriptMaybeType, + type NormalizedOperationAvoidOptionalsConfig, +} from '@graphql-codegen/visitor-plugin-common'; + +export class TypeScriptOperationVariablesToObject extends OperationVariablesToObject { + constructor( + private _config: { + avoidOptionals: NormalizedOperationAvoidOptionalsConfig; + immutableTypes: boolean; + inputMaybeValue: string; + }, + _scalars: NormalizedScalarsMap, + _convertName: ConvertNameFn, + _namespacedImportName: string | null, + _enumNames: string[], + _enumPrefix: boolean, + _enumSuffix: boolean, + _enumValues: ParsedEnumValuesMap, + _applyCoercion: boolean, + ) { + super( + _scalars, + _convertName, + _namespacedImportName, + _enumNames, + _enumPrefix, + _enumSuffix, + _enumValues, + _applyCoercion, + {}, + ); + } + + protected formatFieldString( + fieldName: string, + isNonNullType: boolean, + hasDefaultValue: boolean, + ): string { + return `${fieldName}${this.getAvoidOption(isNonNullType, hasDefaultValue) ? '?' : ''}`; + } -export class TypeScriptOperationVariablesToObject extends TSOperationVariablesToObject { protected formatTypeString( fieldType: string, _isNonNullType: boolean, @@ -8,4 +53,58 @@ export class TypeScriptOperationVariablesToObject extends TSOperationVariablesTo ): string { return fieldType; } + + protected clearOptional(str: string): string { + const maybeSuffix = this._config.inputMaybeValue.replace('T', ''); // e.g. turns `T | null | undefined` to ` | null | undefined` + + if (str.endsWith(maybeSuffix)) { + return (str = str.substring(0, str.length - maybeSuffix.length)); + } + + return str; + } + + protected getAvoidOption(isNonNullType: boolean, hasDefaultValue: boolean): boolean { + const options = this._config.avoidOptionals; + return ( + ((options.variableValue || !options.defaultValue) && hasDefaultValue) || + (!options.variableValue && !isNonNullType) + ); + } + + protected getScalar(name: string): string { + return this._scalars[name]?.input ?? DEFAULT_INPUT_SCALARS[name].input ?? 'unknown'; + } + + protected getPunctuation(): string { + return ';'; + } + + public wrapAstTypeWithModifiers( + baseType: string, + typeNode: TypeNode, + applyCoercion = false, + ): string { + if (typeNode.kind === Kind.NON_NULL_TYPE) { + const type = this.wrapAstTypeWithModifiers(baseType, typeNode.type, applyCoercion); + + return this.clearOptional(type); + } + if (typeNode.kind === Kind.LIST_TYPE) { + const innerType = this.wrapAstTypeWithModifiers(baseType, typeNode.type, applyCoercion); + const listInputCoercionExtension = applyCoercion ? ` | ${innerType}` : ''; + + return this.wrapMaybe( + `${this._config.immutableTypes ? 'ReadonlyArray' : 'Array'}<${innerType}>${listInputCoercionExtension}`, + ); + } + return this.wrapMaybe(baseType); + } + + protected wrapMaybe(type: string): string { + return printTypeScriptMaybeType({ + type, + pattern: this._config.inputMaybeValue, + }); + } } diff --git a/packages/plugins/typescript/operations/src/ts-selection-set-processor.ts b/packages/plugins/typescript/operations/src/ts-selection-set-processor.ts index cc51e60750c..4c752909315 100644 --- a/packages/plugins/typescript/operations/src/ts-selection-set-processor.ts +++ b/packages/plugins/typescript/operations/src/ts-selection-set-processor.ts @@ -41,18 +41,9 @@ export class TypeScriptSelectionSetProcessor extends BaseSelectionSetProcessor; + export class TypeScriptDocumentsVisitor extends BaseDocumentsVisitor< TypeScriptDocumentsPluginConfig, TypeScriptDocumentsParsedConfig > { + protected _usedSchemaTypes: UsedSchemaTypes = {}; + protected _needsExactUtilityType: boolean = false; + private _outputPath: string; + constructor( schema: GraphQLSchema, config: TypeScriptDocumentsPluginConfig, - allFragments: LoadedFragment[], + documentNode: DocumentNode, + outputPath: string, ) { super( config, { arrayInputCoercion: getConfigValue(config.arrayInputCoercion, true), noExport: getConfigValue(config.noExport, false), - 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'), + ignoreEnumValuesFromSchema: getConfigValue(config.ignoreEnumValuesFromSchema, false), + futureProofEnums: getConfigValue(config.futureProofEnums, false), + maybeValue: getConfigValue(config.maybeValue, 'T | null'), + inputMaybeValue: getConfigValue(config.inputMaybeValue, 'T | null | undefined'), } as TypeScriptDocumentsParsedConfig, schema, ); + this.config.enumValues = parseEnumValues({ + schema, + mapOrStr: config.enumValues, + ignoreEnumValuesFromSchema: config.ignoreEnumValuesFromSchema, + naming: { + convert: this.config.convert, + options: { + typesPrefix: this.config.typesPrefix, + typesSuffix: this.config.typesSuffix, + useTypesPrefix: this.config.enumPrefix, + useTypesSuffix: this.config.enumSuffix, + }, + }, + }); + + this._outputPath = outputPath; autoBind(this); - const preResolveTypes = getConfigValue(config.preResolveTypes, true); - const defaultMaybeValue = 'T | null'; - const maybeValue = getConfigValue(config.maybeValue, defaultMaybeValue); + const allFragments: LoadedFragment[] = [ + ...( + documentNode.definitions.filter( + d => d.kind === Kind.FRAGMENT_DEFINITION, + ) as FragmentDefinitionNode[] + ).map(fragmentDef => ({ + node: fragmentDef, + name: fragmentDef.name.value, + onType: fragmentDef.typeCondition.name.value, + isExternal: false, + })), + ...(config.externalFragments || []), + ]; - 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}>`; + // Create a combined document that includes operations, internal and external fragments for enum collection + const documentWithAllFragments: DocumentNode = { + ...documentNode, + definitions: [ + ...documentNode.definitions.filter(d => d.kind !== Kind.FRAGMENT_DEFINITION), + ...allFragments.map(f => f.node), + ], }; - const formatNamedField = ( - name: string, - type: GraphQLOutputType | GraphQLNamedType | null, - isConditional = false, - isOptional = false, - ): string => { - const optional = - isOptional || - isConditional || - (!this.config.avoidOptionals.field && !!type && !isNonNullType(type)); - return (this.config.immutableTypes ? `readonly ${name}` : name) + (optional ? '?' : ''); - }; + this._usedSchemaTypes = this.collectUsedSchemaTypesToGenerate({ + schema, + documentNode: documentWithAllFragments, + }); const processorConfig: SelectionSetProcessorConfig = { namespacedImportName: this.config.namespacedImportName, @@ -94,22 +158,28 @@ export class TypeScriptDocumentsVisitor extends BaseDocumentsVisitor< enumPrefix: this.config.enumPrefix, enumSuffix: this.config.enumSuffix, scalars: this.scalars, - formatNamedField, - wrapTypeWithModifiers(baseType, type) { + formatNamedField: ({ name, isOptional }) => { + return (this.config.immutableTypes ? `readonly ${name}` : name) + (isOptional ? '?' : ''); + }, + wrapTypeWithModifiers: (baseType, type) => { return wrapTypeWithModifiers(baseType, type, { - wrapOptional, - wrapArray, + wrapOptional: type => + printTypeScriptMaybeType({ + type, + pattern: this.config.maybeValue, + }), + wrapArray: type => { + const listModifier = this.config.immutableTypes ? 'ReadonlyArray' : 'Array'; + return `${listModifier}<${type}>`; + }, }); }, - avoidOptionals: this.config.avoidOptionals, printFieldsOnNewLines: this.config.printFieldsOnNewLines, }; - const processor = new ( - preResolveTypes ? PreResolveTypesProcessor : TypeScriptSelectionSetProcessor - )(processorConfig); + this.setSelectionSetHandler( new SelectionSetToObject( - processor, + new PreResolveTypesProcessor(processorConfig), this.scalars, this.schema, this.convertName.bind(this), @@ -118,30 +188,205 @@ export class TypeScriptDocumentsVisitor extends BaseDocumentsVisitor< this.config, ), ); + const enumsNames = Object.keys(schema.getTypeMap()).filter(typeName => isEnumType(schema.getType(typeName)), ); this.setVariablesTransformer( new TypeScriptOperationVariablesToObject( + { + avoidOptionals: this.config.avoidOptionals, + immutableTypes: this.config.immutableTypes, + inputMaybeValue: this.config.inputMaybeValue, + }, this.scalars, this.convertName.bind(this), - this.config.avoidOptionals, - this.config.immutableTypes, this.config.namespacedImportName, enumsNames, this.config.enumPrefix, this.config.enumSuffix, this.config.enumValues, this.config.arrayInputCoercion, - undefined, - 'InputMaybe', ), ); this._declarationBlockConfig = { ignoreExport: this.config.noExport, + enumNameValueSeparator: ' =', }; } + EnumTypeDefinition(node: EnumTypeDefinitionNode): string | null { + const enumName = node.name.value; + if ( + !this._usedSchemaTypes[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({ + schema: this._schema, + node, + declarationBlockConfig: this._declarationBlockConfig, + enumName, + enumValues: this.config.enumValues, + futureProofEnums: this.config.futureProofEnums, + ignoreEnumValuesFromSchema: this.config.ignoreEnumValuesFromSchema, + outputType: this.config.enumType, + naming: { + convert: this.config.convert, + options: { + typesPrefix: this.config.typesPrefix, + typesSuffix: this.config.typesSuffix, + useTypesPrefix: this.config.enumPrefix, + useTypesSuffix: this.config.enumSuffix, + }, + }, + }); + } + + InputObjectTypeDefinition(node: InputObjectTypeDefinitionNode): string | null { + const inputTypeName = node.name.value; + if ( + !this._usedSchemaTypes[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(this.config.declarationKind.input) + .withName(this.convertName(node)) + .withComment(node.description?.value) + .withContent(`\n` + (node.fields || []).join('\n |')).string; + } + + return new DeclarationBlock(this._declarationBlockConfig) + .export() + .asKind(this.config.declarationKind.input) + .withName(this.convertName(node)) + .withComment(node.description?.value) + .withBlock((node.fields || []).join('\n')).string; + } + + InputValueDefinition( + node: InputValueDefinitionNode, + _key?: number | string, + _parent?: any, + _path?: Array, + ancestors?: Array, + ): string { + const oneOfDetails = parseOneOfInputValue({ + node, + schema: this._schema, + ancestors, + }); + + // 1. Flatten GraphQL type nodes to make it easier to turn into string + // GraphQL type nodes may have `NonNullType` type before each `ListType` or `NamedType` + // This make it a bit harder to know whether a `ListType` or `Namedtype` is nullable without looking at the node before it. + // Flattening it into an array where the nullability is in `ListType` and `NamedType` makes it easier to code, + // + // So, we recursively call `collectAndFlattenTypeNodes` to handle the following scenarios: + // - [Thing] + // - [Thing!] + // - [Thing]! + // - [Thing!]! + const typeNodes: Parameters[0]['typeNodes'] = []; + collectAndFlattenTypeNodes({ + currentTypeNode: node.type, + isPreviousNodeNonNullable: oneOfDetails.isOneOfInputValue, // If the InputValue is part of @oneOf input, we treat it as non-null (even if it must be null in the schema) + typeNodes, + }); + + // 2. Generate the type of a TypeScript field declaration + // e.g. `field?: string`, then the `string` is the `typePart` + let typePart: string = ''; + // We call `.reverse()` here to get the base type node first + for (const typeNode of typeNodes.reverse()) { + if (typeNode.type === 'NamedType') { + const usedInputType = this._usedSchemaTypes[typeNode.name]; + if (!usedInputType) { + continue; + } + + typePart = usedInputType.tsType; // If the schema is correct, when reversing typeNodes, the first node would be `NamedType`, which means we can safely set it as the base for typePart + if (!typeNode.isNonNullable) { + typePart = printTypeScriptMaybeType({ + type: typePart, + pattern: this.config.inputMaybeValue, + }); + } + continue; + } + + if (typeNode.type === 'ListType') { + typePart = `Array<${typePart}>`; + if (!typeNode.isNonNullable) { + typePart = printTypeScriptMaybeType({ + type: typePart, + pattern: this.config.inputMaybeValue, + }); + } + } + } + + const addOptionalSign = + !oneOfDetails.isOneOfInputValue && + !this.config.avoidOptionals.inputValue && + (node.type.kind !== Kind.NON_NULL_TYPE || + (!this.config.avoidOptionals.defaultValue && node.defaultValue !== undefined)); + + // 3. Generate the keyPart of the TypeScript field declaration + // e.g. `field?: string`, then the `field?` is the `keyPart` + const keyPart = `${node.name.value}${addOptionalSign ? '?' : ''}`; + + // 4. other parts of TypeScript field declaration + const commentPart = getNodeComment(node); + const readonlyPart = this.config.immutableTypes ? 'readonly ' : ''; + + const currentInputValue = commentPart + indent(`${readonlyPart}${keyPart}: ${typePart};`); + + // 5. Check if field is part of `@oneOf` input type + // If yes, we must generate a union member where the current inputValue must be provieded, and the others are not + // e.g. + // ```graphql + // input UserInput { + // byId: ID + // byEmail: String + // byLegacyId: ID + // } + // ``` + // + // Then, the generated type is: + // ```ts + // type UserInput = + // | { byId: string | number; byEmail?: never; byLegacyId?: never } + // | { byId?: never; byEmail: string; byLegacyId?: never } + // | { byId?: never; byEmail?: never; byLegacyId: string | number } + // ``` + if (oneOfDetails.isOneOfInputValue) { + const fieldParts: Array = []; + for (const fieldName of Object.keys(oneOfDetails.parentType.getFields())) { + if (fieldName === node.name.value) { + fieldParts.push(currentInputValue); + continue; + } + fieldParts.push(`${readonlyPart}${fieldName}?: never;`); + } + return indent(`{ ${fieldParts.join(' ')} }`); + } + + // If field is not part of @oneOf input type, then it's a input value, just return as-is + return currentInputValue; + } + public getImports(): Array { return !this.config.globalNamespace && (this.config.inlineFragmentTypes === 'combine' || this.config.inlineFragmentTypes === 'mask') @@ -151,17 +396,415 @@ export class TypeScriptDocumentsVisitor extends BaseDocumentsVisitor< : []; } + public getExternalSchemaTypeImports(): Array { + if (!this.config.importSchemaTypesFrom) { + return []; + } + + const hasTypesToImport = + Object.values(this._usedSchemaTypes).filter( + value => value.type === 'GraphQLEnumType' || value.type === 'GraphQLInputObjectType', // Only Enums and Inputs are stored in the shared type file (never Scalar), so we should only print import line if Enums and Inputs are used. + ).length > 0; + + if (!hasTypesToImport) { + return []; + } + + return [ + generateImportStatement({ + baseDir: process.cwd(), + baseOutputDir: '', + outputPath: this._outputPath, + importSource: { + path: this.config.importSchemaTypesFrom, + namespace: this.config.namespacedImportName, + identifiers: [], + }, + typesImport: true, + emitLegacyCommonJSImports: this.config.emitLegacyCommonJSImports, + importExtension: normalizeImportExtension({ + emitLegacyCommonJSImports: this.config.emitLegacyCommonJSImports, + importExtension: this.config.importExtension, + }), + }), + ]; + } + + public getEnumsImports(): string[] { + const usedEnumMap: ParsedEnumValuesMap = {}; + for (const [enumName, enumDetails] of Object.entries(this.config.enumValues)) { + if (this._usedSchemaTypes[enumName]) { + usedEnumMap[enumName] = enumDetails; + } + } + + return getEnumsImports({ + enumValues: usedEnumMap, + useTypeImports: this.config.useTypeImports, + }); + } + + public getScalarsImports(): string[] { + const fileType: + | 'multi-file-shared-type-file' + | 'multi-file-operation-file' + | 'single-file-operation-file' = this.config.importSchemaTypesFrom + ? 'multi-file-operation-file' + : this.config.generateOperationTypes + ? 'single-file-operation-file' + : 'multi-file-shared-type-file'; + + const imports: { + [ + source: string + ]: // `source` is where to import from e.g. './relative-import', 'package-import', '@org/package' + { + identifiers: { + [ + identifier: string + ]: // `identifier` is the name of import, this could be used for named or default imports + { asDefault: boolean }; + }; + }; + } = {}; + for (const [scalarName, parsedScalar] of Object.entries(this.config.scalars)) { + const usedScalar = this._usedSchemaTypes[scalarName]; + if (!usedScalar || usedScalar.type !== 'GraphQLScalarType') { + continue; + } + + if ( + parsedScalar.input.isExternal && + (((usedScalar.useCases.input || usedScalar.useCases.variables) && + fileType === 'single-file-operation-file') || + (usedScalar.useCases.input && fileType === 'multi-file-shared-type-file') || + (usedScalar.useCases.variables && fileType === 'multi-file-operation-file')) + ) { + imports[parsedScalar.input.source] ||= { identifiers: {} }; + imports[parsedScalar.input.source].identifiers[parsedScalar.input.import] = { + asDefault: parsedScalar.input.default, + }; + } + + if ( + parsedScalar.output.isExternal && + usedScalar.useCases.output && + (fileType === 'single-file-operation-file' || fileType === 'multi-file-operation-file') + ) { + imports[parsedScalar.output.source] ||= { identifiers: {} }; + imports[parsedScalar.output.source].identifiers[parsedScalar.output.import] = { + asDefault: parsedScalar.output.default, + }; + } + } + + return Object.entries(imports).reduce((res, [importSource, importParams]) => { + // One import statement cannot have multiple defaults. + // So: + // - split each defaults into its own statements + // - the named imports can all go together, tracked by `namedImports` + const namedImports = []; + for (const [identifier, identifierMetadata] of Object.entries(importParams.identifiers)) { + if (identifierMetadata.asDefault) { + res.push( + buildTypeImport({ + identifier, + source: importSource, + asDefault: true, + useTypeImports: this.config.useTypeImports, + }), + ); + continue; + } + + namedImports.push(identifier); + } + + if (namedImports.length > 0) { + res.push( + buildTypeImport({ + identifier: namedImports.join(', '), + source: importSource, + asDefault: false, + useTypeImports: this.config.useTypeImports, + }), + ); + } + + return res; + }, []); + } + protected getPunctuation(_declarationKind: DeclarationKind): string { return ';'; } protected applyVariablesWrapper(variablesBlock: string, operationType: string): string { - const prefix = this.config.namespacedImportName ? `${this.config.namespacedImportName}.` : ''; const extraType = this.config.allowUndefinedQueryVariables && operationType === 'Query' ? ' | undefined' : ''; + this._needsExactUtilityType = true; + return `Exact<${variablesBlock === '{}' ? `{ [key: string]: never; }` : variablesBlock}>${extraType}`; + } + + private collectInnerTypesRecursively({ + node, + usedSchemaTypes, + location, + }: { + node: GraphQLNamedInputType; + usedSchemaTypes: UsedSchemaTypes; + location: 'variables' | 'input'; // the location where the node was found. This is useful for nested input. Note: Since it starts at the variable, it first iteration is 'variables' and the rest will be `input` + }): void { + if (node instanceof GraphQLEnumType) { + if (usedSchemaTypes[node.name]) { + return; + } + + usedSchemaTypes[node.name] = { + type: 'GraphQLEnumType', + node, + tsType: this.convertName(node.name), + }; + return; + } + + if (node instanceof GraphQLScalarType) { + const scalarType = usedSchemaTypes[node.name] || { + type: 'GraphQLScalarType', + node, + tsType: + (DEFAULT_INPUT_SCALARS[node.name]?.input || + this.config.scalars?.[node.name]?.input.type) ?? + 'unknown', + useCases: { + variables: location === 'variables', + input: location === 'input', + output: false, + }, + }; + + if (scalarType.type !== 'GraphQLScalarType') { + throw new Error( + `${node.name} has been incorrectly parsed as Scalar. This should not happen.`, + ); + } + + // ensure scalar's useCases is updated to have `useCases.input:true` or `useCases.variables:true`, depending on the use case + // this is required because if the scalar has been parsed previously, it may only have `useCases.output:true`, and not `useCases.input:true` or `useCases.variables:true` + if (location === 'input') { + scalarType.useCases.input = true; + } + if (location === 'variables') { + scalarType.useCases.variables = true; + } + + usedSchemaTypes[node.name] = scalarType; + return; + } + + // GraphQLInputObjectType + if (usedSchemaTypes[node.name]) { + return; + } + usedSchemaTypes[node.name] = { + type: 'GraphQLInputObjectType', + node, + tsType: this.convertName(node.name), + }; + + const fields = node.getFields(); + for (const field of Object.values(fields)) { + const fieldType = getNamedType(field.type); + this.collectInnerTypesRecursively({ + node: fieldType, + usedSchemaTypes, + location: 'input', + }); + } + } + + /** + * @description collects schema types used in operations: + * - used Enums for Variables + * - used Scalars for Variables + * - used Input for Variables (recursively) + * + * - used Enums for Result + * - used Scalars for Result + */ + private collectUsedSchemaTypesToGenerate({ + schema, + documentNode, + }: { + schema: GraphQLSchema; + documentNode: DocumentNode; + }): UsedSchemaTypes { + const schemaTypes = schema.getTypeMap(); + + const usedSchemaTypes: UsedSchemaTypes = {}; + + // Collect input enums and input types + visit(documentNode, { + VariableDefinition: variableDefinitionNode => { + visit(variableDefinitionNode, { + NamedType: namedTypeNode => { + const foundInputType = schemaTypes[namedTypeNode.name.value]; + if ( + foundInputType && + (foundInputType instanceof GraphQLInputObjectType || + foundInputType instanceof GraphQLScalarType || + foundInputType instanceof GraphQLEnumType) && + !isNativeNamedType(foundInputType) + ) { + this.collectInnerTypesRecursively({ + node: foundInputType, + usedSchemaTypes, + location: 'variables', + }); + } + }, + }); + }, + }); + + // Collect output enums + const typeInfo = new TypeInfo(schema); + visit( + documentNode, + // AST doesn’t include field types (they are defined in the schema) - only names. + // TypeInfo is a stateful helper that tracks typing context while walking the AST + // visitWithTypeInfo wires that context into a visitor. + visitWithTypeInfo(typeInfo, { + Field: () => { + const fieldType = typeInfo.getType(); + if (fieldType) { + const namedType = getNamedType(fieldType); + + if (namedType instanceof GraphQLEnumType) { + usedSchemaTypes[namedType.name] = { + type: 'GraphQLEnumType', + node: namedType, + tsType: this.convertName(namedType.name), + }; + return; + } + + if (namedType instanceof GraphQLScalarType) { + const scalarType = usedSchemaTypes[namedType.name] || { + type: 'GraphQLScalarType', + node: namedType, + tsType: this.convertName(namedType.name), + useCases: { variables: false, input: false, output: true }, + }; + + if (scalarType.type !== 'GraphQLScalarType') { + throw new Error( + `${namedType.name} has been incorrectly parsed as Scalar. This should not happen.`, + ); + } + + // ensure scalar's useCases is updated to have `useCases.output:true` + // this is required because if the scalar has been parsed previously, it may only have `useCases.input:true` or `useCases.variables:true`, not `useCases.output:true` + scalarType.useCases.output = true; + + usedSchemaTypes[namedType.name] = scalarType; + } + } + }, + }), + ); + + return usedSchemaTypes; + } + + getExactUtilityType(): string | null { + if ( + !this.config.generateOperationTypes || // 1. If we don't generate operation types, definitely do not need `Exact` + !this._needsExactUtilityType // 2. Even if we generate operation types, we may not need `Exact` if there's no operations in the documents i.e. only fragments found + ) { + return null; + } + + return `${internalUtilityTypeWarning}type Exact = { [K in keyof T]: T[K] };`; + } + + getIncrementalUtilityType(): string | null { + if (!this.config.generateOperationTypes) { + return null; + } + + // Note: `export` here is important for 2 reasons + // 1. It is not always used in the rest of the file, so this is a safe way to avoid lint rules (in tsconfig or eslint) complaining it's not used in the current file. + // 2. In Client Preset, it is used by fragment-masking.ts, so it needs `export` + return `${internalUtilityTypeWarning}export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never };`; + } +} + +const internalUtilityTypeWarning = '/** Internal type. DO NOT USE DIRECTLY. */\n'; + +function parseOneOfInputValue({ + node, + schema, + ancestors, +}: { + node: InputValueDefinitionNode; + schema: GraphQLSchema; + ancestors?: Array; +}): + | { + isOneOfInputValue: true; + realParentDef: TypeDefinitionNode; + parentType: GraphQLInputObjectType; + } + | { isOneOfInputValue: false } { + const realParentDef = ancestors?.[ancestors.length - 1]; + if (realParentDef) { + const parentType = schema.getType(realParentDef.name.value); + if (isOneOfInputObjectType(parentType)) { + if (node.type.kind === Kind.NON_NULL_TYPE) { + throw new Error( + 'Fields on an input object type can not be non-nullable. It seems like the schema was not validated.', + ); + } + return { isOneOfInputValue: true, realParentDef, parentType }; + } + } + return { isOneOfInputValue: false }; +} + +function collectAndFlattenTypeNodes({ + currentTypeNode, + isPreviousNodeNonNullable, + typeNodes, +}: { + currentTypeNode: TypeNode; + isPreviousNodeNonNullable: boolean; + typeNodes: Array< + | { type: 'ListType'; isNonNullable: boolean } + | { type: 'NamedType'; isNonNullable: boolean; name: string } + >; +}): void { + if (currentTypeNode.kind === Kind.NON_NULL_TYPE) { + const nextTypeNode = currentTypeNode.type; + collectAndFlattenTypeNodes({ + currentTypeNode: nextTypeNode, + isPreviousNodeNonNullable: true, + typeNodes, + }); + } else if (currentTypeNode.kind === Kind.LIST_TYPE) { + typeNodes.push({ type: 'ListType', isNonNullable: isPreviousNodeNonNullable }); - return `${prefix}Exact<${ - variablesBlock === '{}' ? `{ [key: string]: never; }` : variablesBlock - }>${extraType}`; + const nextTypeNode = currentTypeNode.type; + collectAndFlattenTypeNodes({ + currentTypeNode: nextTypeNode, + isPreviousNodeNonNullable: false, + typeNodes, + }); + } else if (currentTypeNode.kind === Kind.NAMED_TYPE) { + typeNodes.push({ + type: 'NamedType', + isNonNullable: isPreviousNodeNonNullable, + name: currentTypeNode.name.value, + }); } } 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 3bdd6ab1a15..fdfa43db9b4 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 @@ -1,36 +1,26 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`TypeScript Operations Plugin > Config > should include fragment variable definitions when experimentalFragmentVariables is set 1`] = ` -"export type TextNotificationFragmentFragment = { __typename?: 'TextNotification', text?: string }; - - -export type TextNotificationFragmentFragmentVariables = Exact<{ - skip: Scalars['Boolean']['input']; -}>; -" -`; - exports[`TypeScript Operations Plugin > Issues > #2699 - Issues with multiple interfaces and unions 1`] = ` "export type GetEntityBrandDataQueryVariables = Exact<{ - gid: Scalars['ID']['input']; - brand: Scalars['ID']['input']; + gid: string | number; + brand: string | number; }>; -export type GetEntityBrandDataQuery = { __typename?: 'Query', node: - | { __typename: 'Company', active: boolean, id: string, createdAt: any, updatedAt: any, brandData?: { __typename?: 'EntityBrandData', active: boolean, browsable: boolean, title: string, alternateTitle?: string | null, description: string } | null, createdBy?: { __typename?: 'User', id: string, name: string } | null, updatedBy?: { __typename?: 'User', id: string, name: string } | null } - | { __typename: 'Theater', active: boolean, id: string, createdAt: any, updatedAt: any, brandData?: { __typename?: 'EntityBrandData', active: boolean, browsable: boolean, title: string, alternateTitle?: string | null, description: string } | null, createdBy?: { __typename?: 'User', id: string, name: string } | null, updatedBy?: { __typename?: 'User', id: string, name: string } | null } - | { __typename: 'Movie', id: string, createdAt: any, updatedAt: any, brandData?: { __typename?: 'EntityBrandData', active: boolean, browsable: boolean, title: string, alternateTitle?: string | null, description: string } | null, createdBy?: { __typename?: 'User', id: string, name: string } | null, updatedBy?: { __typename?: 'User', id: string, name: string } | null } - | { __typename: 'User', id: string, createdAt: any, updatedAt: any, brandData?: { __typename?: 'EntityBrandData', active: boolean, browsable: boolean, title: string, alternateTitle?: string | null, description: string } | null, createdBy?: { __typename?: 'User', id: string, name: string } | null, updatedBy?: { __typename?: 'User', id: string, name: string } | null } +export type GetEntityBrandDataQuery = { node: + | { __typename: 'Company', active: boolean, id: string, createdAt: unknown, updatedAt: unknown, brandData: { active: boolean, browsable: boolean, title: string, alternateTitle: string | null, description: string } | null, createdBy: { id: string, name: string } | null, updatedBy: { id: string, name: string } | null } + | { __typename: 'Theater', active: boolean, id: string, createdAt: unknown, updatedAt: unknown, brandData: { active: boolean, browsable: boolean, title: string, alternateTitle: string | null, description: string } | null, createdBy: { id: string, name: string } | null, updatedBy: { id: string, name: string } | null } + | { __typename: 'Movie', id: string, createdAt: unknown, updatedAt: unknown, brandData: { active: boolean, browsable: boolean, title: string, alternateTitle: string | null, description: string } | null, createdBy: { id: string, name: string } | null, updatedBy: { id: string, name: string } | null } + | { __typename: 'User', id: string, createdAt: unknown, updatedAt: unknown, brandData: { active: boolean, browsable: boolean, title: string, alternateTitle: string | null, description: string } | null, createdBy: { id: string, name: string } | null, updatedBy: { id: string, name: string } | null } }; -type EntityBrandData_Company_Fragment = { __typename?: 'Company', brandData?: { __typename?: 'EntityBrandData', active: boolean, browsable: boolean, title: string, alternateTitle?: string | null, description: string } | null }; +type EntityBrandData_Company_Fragment = { brandData: { active: boolean, browsable: boolean, title: string, alternateTitle: string | null, description: string } | null }; -type EntityBrandData_Theater_Fragment = { __typename?: 'Theater', brandData?: { __typename?: 'EntityBrandData', active: boolean, browsable: boolean, title: string, alternateTitle?: string | null, description: string } | null }; +type EntityBrandData_Theater_Fragment = { brandData: { active: boolean, browsable: boolean, title: string, alternateTitle: string | null, description: string } | null }; -type EntityBrandData_Movie_Fragment = { __typename?: 'Movie', brandData?: { __typename?: 'EntityBrandData', active: boolean, browsable: boolean, title: string, alternateTitle?: string | null, description: string } | null }; +type EntityBrandData_Movie_Fragment = { brandData: { active: boolean, browsable: boolean, title: string, alternateTitle: string | null, description: string } | null }; -type EntityBrandData_User_Fragment = { __typename?: 'User', brandData?: { __typename?: 'EntityBrandData', active: boolean, browsable: boolean, title: string, alternateTitle?: string | null, description: string } | null }; +type EntityBrandData_User_Fragment = { brandData: { active: boolean, browsable: boolean, title: string, alternateTitle: string | null, description: string } | null }; export type EntityBrandDataFragment = | EntityBrandData_Company_Fragment @@ -39,13 +29,13 @@ export type EntityBrandDataFragment = | EntityBrandData_User_Fragment ; -type ElementMetadata_Company_Fragment = { __typename?: 'Company', createdAt: any, updatedAt: any, createdBy?: { __typename?: 'User', id: string, name: string } | null, updatedBy?: { __typename?: 'User', id: string, name: string } | null }; +type ElementMetadata_Company_Fragment = { createdAt: unknown, updatedAt: unknown, createdBy: { id: string, name: string } | null, updatedBy: { id: string, name: string } | null }; -type ElementMetadata_Theater_Fragment = { __typename?: 'Theater', createdAt: any, updatedAt: any, createdBy?: { __typename?: 'User', id: string, name: string } | null, updatedBy?: { __typename?: 'User', id: string, name: string } | null }; +type ElementMetadata_Theater_Fragment = { createdAt: unknown, updatedAt: unknown, createdBy: { id: string, name: string } | null, updatedBy: { id: string, name: string } | null }; -type ElementMetadata_Movie_Fragment = { __typename?: 'Movie', createdAt: any, updatedAt: any, createdBy?: { __typename?: 'User', id: string, name: string } | null, updatedBy?: { __typename?: 'User', id: string, name: string } | null }; +type ElementMetadata_Movie_Fragment = { createdAt: unknown, updatedAt: unknown, createdBy: { id: string, name: string } | null, updatedBy: { id: string, name: string } | null }; -type ElementMetadata_User_Fragment = { __typename?: 'User', createdAt: any, updatedAt: any, createdBy?: { __typename?: 'User', id: string, name: string } | null, updatedBy?: { __typename?: 'User', id: string, name: string } | null }; +type ElementMetadata_User_Fragment = { createdAt: unknown, updatedAt: unknown, createdBy: { id: string, name: string } | null, updatedBy: { id: string, name: string } | null }; export type ElementMetadataFragment = | ElementMetadata_Company_Fragment @@ -56,8 +46,12 @@ export type ElementMetadataFragment = " `; -exports[`TypeScript Operations Plugin > Issues > #2916 - Missing import prefix with preResolveTypes: true and near-operation-file preset 1`] = ` -"export type UserQueryVariables = Types.Exact<{ [key: string]: never; }>; +exports[`TypeScript Operations Plugin > Issues > #2916 - Missing import prefix with near-operation-file preset 1`] = ` +"export type Department = + | 'Direction' + | 'Development'; + +export type UserQueryVariables = Exact<{ [key: string]: never; }>; export type UserQuery = { user: { id: string, username: string, email: string, dep: Types.Department } }; @@ -65,76 +59,9 @@ export type UserQuery = { user: { id: string, username: string, email: string, d `; exports[`TypeScript Operations Plugin > Issues > #3064 - fragments over interfaces causes issues with fields 1`] = ` -"type Venue_Hotel_Fragment = { __typename?: 'Hotel', id: string, gpsPosition: { __typename?: 'GPSPosition', lat: number, lng: number } }; - -type Venue_Transport_Fragment = { __typename?: 'Transport', id: string }; - -export type VenueFragment = - | Venue_Hotel_Fragment - | Venue_Transport_Fragment -; - -export type QQueryVariables = Exact<{ [key: string]: never; }>; +"type Venue_Hotel_Fragment = { id: string, gpsPosition: { lat: number, lng: number } }; - -export type QQuery = { __typename?: 'Query', hotel: { __typename?: 'Hotel', id: string, gpsPosition: { __typename?: 'GPSPosition', lat: number, lng: number } }, transport: { __typename?: 'Transport', id: string } }; -" -`; - -exports[`TypeScript Operations Plugin > Issues > #3064 - fragments over interfaces causes issues with fields 2`] = ` -"export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { [_ in K]?: never }; -export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 Venue = { - id: Scalars['String']['output']; - name: Scalars['String']['output']; -}; - -export type GpsPosition = { - __typename?: 'GPSPosition'; - lat: Scalars['Float']['output']; - lng: Scalars['Float']['output']; -}; - -export type VenueWithPosition = { - id: Scalars['String']['output']; - gpsPosition: GpsPosition; -}; - -export type Hotel = VenueWithPosition & Venue & { - __typename?: 'Hotel'; - id: Scalars['String']['output']; - gpsPosition: GpsPosition; - name: Scalars['String']['output']; -}; - -export type Transport = Venue & { - __typename?: 'Transport'; - id: Scalars['String']['output']; - name: Scalars['String']['output']; -}; - -export type Query = { - __typename?: 'Query'; - hotel: Hotel; - transport: Transport; -}; -type Venue_Hotel_Fragment = { __typename?: 'Hotel', id: string, gpsPosition: { __typename?: 'GPSPosition', lat: number, lng: number } }; - -type Venue_Transport_Fragment = { __typename?: 'Transport', id: string }; +type Venue_Transport_Fragment = { id: string }; export type VenueFragment = | Venue_Hotel_Fragment @@ -144,7 +71,7 @@ export type VenueFragment = export type QQueryVariables = Exact<{ [key: string]: never; }>; -export type QQuery = { __typename?: 'Query', hotel: { __typename?: 'Hotel', id: string, gpsPosition: { __typename?: 'GPSPosition', lat: number, lng: number } }, transport: { __typename?: 'Transport', id: string } }; +export type QQuery = { hotel: { id: string, gpsPosition: { lat: number, lng: number } }, transport: { id: string } }; function test(q: QQuery) { if (q.hotel) { const t1 = q.hotel.gpsPosition.lat @@ -156,18 +83,18 @@ 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; }>; -export type SnakeQueryQuery = { __typename?: 'Query', snake: - | { __typename?: 'Snake', name: string, features: { __typename?: 'SnakeFeatures', color: string, length: number } } - | { __typename?: 'Error' } +export type SnakeQueryQuery = { snake: + | { name: string, features: { color: string, length: number } } + | Record }; -type AnimalFragment_Bat_Fragment = { __typename?: 'Bat', features: { __typename?: 'BatFeatures', color: string, wingspan: number } }; +type AnimalFragment_Bat_Fragment = { features: { color: string, wingspan: number } }; -type AnimalFragment_Snake_Fragment = { __typename?: 'Snake', features: { __typename?: 'SnakeFeatures', color: string, length: number } }; +type AnimalFragment_Snake_Fragment = { features: { color: string, length: number } }; export type AnimalFragmentFragment = | AnimalFragment_Bat_Fragment @@ -176,33 +103,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 = ( - { __typename?: 'Query' } - & { user?: Maybe<( - { __typename?: 'User' } - & Pick - )> } -); +export type UserQueryQuery = { user: { id: string, name: string | null } | null }; -export type UserFragment = ( - { __typename?: 'User' } - & Pick -); +export type UserFragment = { id: string, name: string | null }; " `; @@ -210,13 +117,7 @@ exports[`TypeScript Operations Plugin > Selection Set > Should generate the corr "export type UserQueryQueryVariables = Exact<{ [key: string]: never; }>; -export type UserQueryQuery = ( - { __typename?: 'Query' } - & { user?: Maybe<( - { __typename?: 'User' } - & Pick - )> } -); +export type UserQueryQuery = { user: { id: string, name: string | null } | null }; " `; @@ -224,86 +125,29 @@ exports[`TypeScript Operations Plugin > Selection Set > Should generate the corr "export type UserQueryQueryVariables = Exact<{ [key: string]: never; }>; -export type UserQueryQuery = ( - { __typename?: 'Query' } - & { user?: Maybe<( - { __typename?: 'User' } - & Pick - )> } -); +export type UserQueryQuery = { user: { id: string, name: string | null } | null }; -export type UserFragment = ( - { __typename?: 'User' } - & 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 = ( - { __typename?: 'User' } - & Pick -); +"export type UserFragmentFragment = { id: string }; export type AaaQueryVariables = Exact<{ [key: string]: never; }>; -export type AaaQuery = ( - { __typename?: 'Query' } - & { user: - | ( - { __typename?: 'User' } - & Pick - ) - | { __typename?: 'Error' } - } -); -" -`; - -exports[`TypeScript Operations Plugin > Selection Set > Should generate the correct intersection for fragments when using with interfaces with same type 1`] = ` -"export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - - -export type Unnamed_1_Query = ( - { __typename?: 'Query' } - & { b?: Maybe< - | ( - { __typename?: 'A' } - & Pick - ) - | { __typename?: 'B' } - > } -); - -export type AFragment = ( - { __typename?: 'A' } - & Pick -); - -export type BFragment = ( - { __typename?: 'A' } - & Pick -); +export type AaaQuery = { user: + | { id: string } + | Record + }; " `; 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: unknown, ipv4Gateway: unknown }; + +type NetRoute_Ipv6Route_Fragment = { __typename: 'IPV6Route', ipv6Address: unknown, ipv6Gateway: unknown }; export type NetRouteFragment = | NetRoute_Ipv4Route_Fragment @@ -313,103 +157,43 @@ export type NetRouteFragment = export type QqQueryVariables = Exact<{ [key: string]: never; }>; -export type QqQuery = ( - { __typename?: 'Query' } - & { routes: Array< - | ( - { __typename: 'IPV4Route' } - & { - ipv4Address: Ipv4Route['address'], - ipv4Gateway: Ipv4Route['gateway'], - } - ) - | ( - { __typename: 'IPV6Route' } - & { - ipv6Address: Ipv6Route['address'], - ipv6Gateway: Ipv6Route['gateway'], - } - ) - > } -); +export type QqQuery = { routes: Array< + | { __typename: 'IPV4Route', ipv4Address: unknown, ipv4Gateway: unknown } + | { __typename: 'IPV6Route', ipv6Address: unknown, ipv6Gateway: unknown } + > }; " `; 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: unknown, ipv4Gateway: unknown }; + +type NetRoute_Ipv6Route_Fragment = { __typename: 'IPV6Route', ipv6Address: unknown, ipv6Gateway: unknown }; export type NetRouteFragment = | NetRoute_Ipv4Route_Fragment | NetRoute_Ipv6Route_Fragment ; -export type TestFragment = ( - { __typename?: 'IPV6Route' } - & { - ipv6Address: Ipv6Route['address'], - ipv6Gateway: Ipv6Route['gateway'], - } -); +export type TestFragment = { ipv6Address: unknown, ipv6Gateway: unknown }; export type QqQueryVariables = Exact<{ [key: string]: never; }>; -export type QqQuery = ( - { __typename?: 'Query' } - & { routes: Array< - | ( - { __typename: 'IPV4Route' } - & { - ipv4Address: Ipv4Route['address'], - ipv4Gateway: Ipv4Route['gateway'], - } - ) - | ( - { __typename: 'IPV6Route' } - & { - ipv6Address: Ipv6Route['address'], - ipv6Gateway: Ipv6Route['gateway'], - } - ) - > } -); +export type QqQuery = { routes: Array< + | { __typename: 'IPV4Route', ipv4Address: unknown, ipv4Gateway: unknown } + | { __typename: 'IPV6Route', ipv6Address: unknown, ipv6Gateway: unknown } + > }; " `; exports[`TypeScript Operations Plugin > Selection Set > Should have valid fragments intersection on different types (with usage) #2498 1`] = ` -"export type TomFragment = ( - { __typename?: 'Tom' } - & Pick -); - -export type JerryFragment = ( - { __typename?: 'Jerry' } - & Pick -); - -type User_Tom_Fragment = ( - { __typename?: 'Tom' } - & Pick -); - -type User_Jerry_Fragment = ( - { __typename?: 'Jerry' } - & Pick -); +"export type TomFragment = { id: string, foo: string }; + +export type JerryFragment = { id: string, bar: string }; + +type User_Tom_Fragment = { id: string, foo: string }; + +type User_Jerry_Fragment = { id: string, bar: string }; export type UserFragment = | User_Tom_Fragment @@ -419,357 +203,9 @@ export type UserFragment = export type UserQueryQueryVariables = Exact<{ [key: string]: never; }>; -export type UserQueryQuery = ( - { __typename?: 'Query' } - & { user?: Maybe< - | ( - { __typename?: 'Tom' } - & Pick - ) - | ( - { __typename?: 'Jerry' } - & Pick - ) - > } -); -" -`; - -exports[`TypeScript Operations Plugin > Union & Interfaces > #4216 - handle fragments against unions and interfaces with flattenGeneratedTypes 1`] = ` -"export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { [_ in K]?: never }; -export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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'; - search?: Maybe>; -}; - -export type Concept = { - id?: Maybe; -}; - -export type Dimension = Concept & { - __typename?: 'Dimension'; - id?: Maybe; -}; - -export type DimValue = { - __typename?: 'DimValue'; - dimension?: Maybe; - value: Scalars['String']['output']; -}; - -export type Searchable = Dimension | DimValue; -export type SearchPopularQueryVariables = Exact<{ [key: string]: never; }>; - - -export type SearchPopularQuery = ( - { __typename?: 'Query' } - & { search?: Maybe - ) - | ( - { __typename?: 'DimValue' } - & Pick - & { dimension?: Maybe<( - { __typename?: 'Dimension' } - & Pick - )> } - ) - >> } -); -" -`; - -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 = ( - { __typename?: 'Query' } - & { user: - | ( - { __typename?: 'User' } - & Pick - ) - | ( - { __typename?: 'Error2' } - & Pick - ) - | ( - { __typename?: 'Error3' } - & Pick - & { info?: Maybe<( - { __typename?: 'AdditionalInfo' } - & Pick - )> } - ) - } -); - -export type AdditionalInfoFragment = ( - { __typename?: 'AdditionalInfo' } - & Pick -); - -type UserResult1_User_Fragment = ( - { __typename?: 'User' } - & Pick -); - -type UserResult1_Error2_Fragment = { __typename?: 'Error2' }; - -type UserResult1_Error3_Fragment = ( - { __typename?: 'Error3' } - & { info?: Maybe<( - { __typename?: 'AdditionalInfo' } - & Pick - )> } -); - -export type UserResult1Fragment = - | UserResult1_User_Fragment - | UserResult1_Error2_Fragment - | UserResult1_Error3_Fragment -; - -type UserResult_User_Fragment = ( - { __typename?: 'User' } - & Pick -); - -type UserResult_Error2_Fragment = ( - { __typename?: 'Error2' } - & Pick -); - -type UserResult_Error3_Fragment = { __typename?: 'Error3' }; - -export type UserResultFragment = - | UserResult_User_Fragment - | UserResult_Error2_Fragment - | UserResult_Error3_Fragment -; +export type UserQueryQuery = { user: + | { 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 Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { [_ in K]?: never }; -export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 Error = { - message: Scalars['String']['output']; -}; - -export type Error1 = Error & { - __typename?: 'Error1'; - message: Scalars['String']['output']; -}; - -export type Error2 = Error & { - __typename?: 'Error2'; - message: Scalars['String']['output']; -}; - -export type Error3 = Error & { - __typename?: 'Error3'; - message: Scalars['String']['output']; - info?: Maybe; -}; - -export type AdditionalInfo = { - __typename?: 'AdditionalInfo'; - message: Scalars['String']['output']; - message2: Scalars['String']['output']; -}; - -export type User = { - __typename?: 'User'; - id: Scalars['ID']['output']; - login: Scalars['String']['output']; -}; - -export type UserResult = User | Error2 | Error3; - -export type Query = { - __typename?: 'Query'; - user: UserResult; -}; -export type UserQueryQueryVariables = Exact<{ [key: string]: never; }>; - - -export type UserQueryQuery = ( - { __typename?: 'Query' } - & { user: - | ( - { __typename?: 'User' } - & Pick - ) - | ( - { __typename?: 'Error2' } - & Pick - ) - | ( - { __typename?: 'Error3' } - & Pick - & { info?: Maybe<( - { __typename?: 'AdditionalInfo' } - & Pick - )> } - ) - } -); - - 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 Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { [_ in K]?: never }; -export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** 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 Error = { - message: Scalars['String']['output']; -}; - -export type Error1 = Error & { - __typename?: 'Error1'; - message: Scalars['String']['output']; -}; - -export type Error2 = Error & { - __typename?: 'Error2'; - message: Scalars['String']['output']; -}; - -export type Error3 = Error & { - __typename?: 'Error3'; - message: Scalars['String']['output']; - info?: Maybe; -}; - -export type AdditionalInfo = { - __typename?: 'AdditionalInfo'; - message: Scalars['String']['output']; - message2: Scalars['String']['output']; -}; - -export type User = { - __typename?: 'User'; - id: Scalars['ID']['output']; - login: Scalars['String']['output']; - test?: Maybe; - test2?: Maybe; -}; - -export type UserResult = User | Error2 | Error3; - -export type Query = { - __typename?: 'Query'; - user: UserResult; -}; -export type UserQueryQueryVariables = Exact<{ [key: string]: never; }>; - - -export type UserQueryQuery = ( - { __typename?: 'Query' } - & { user: - | ( - { __typename?: 'User' } - & Pick< - User, - | 'id' - | 'test2' - | 'login' - | 'test' - > - ) - | ( - { __typename?: 'Error2' } - & Pick - ) - | ( - { __typename?: 'Error3' } - & Pick - & { info?: Maybe<( - { __typename?: 'AdditionalInfo' } - & Pick - )> } - ) - } -); - - 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-compact-duplicates.spec.ts b/packages/plugins/typescript/operations/tests/extract-all-types-compact-duplicates.spec.ts new file mode 100644 index 00000000000..f09cd9673a7 --- /dev/null +++ b/packages/plugins/typescript/operations/tests/extract-all-types-compact-duplicates.spec.ts @@ -0,0 +1,347 @@ +import { buildSchema, parse } from 'graphql'; +import { mergeOutputs, Types } from '@graphql-codegen/plugin-helpers'; +import { validateTs } from '@graphql-codegen/testing'; +import { plugin, type TypeScriptDocumentsPluginConfig } from '../src/index.js'; + +describe('extractAllFieldsToTypesCompact: duplicate type names', () => { + const validate = async (content: Types.PluginOutput) => { + const m = mergeOutputs([content]); + validateTs(m, undefined, undefined, undefined, []); + + return m; + }; + + it('should add type suffix to disambiguate duplicate fragment type names in union types', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + typeDefinitions: [TypeDefinition!]! + } + + interface TypeDefinition { + identifier: String! + } + + type StringType implements TypeDefinition { + identifier: String! + } + + type IntType implements TypeDefinition { + identifier: String! + min: Int + max: Int + } + + type ArrayType implements TypeDefinition { + identifier: String! + elementTypeId: String! + } + + type BooleanType implements TypeDefinition { + identifier: String! + } + `); + + const document = parse(/* GraphQL */ ` + fragment TypeDefinitions on TypeDefinition { + __typename + ... on StringType { + identifier + } + ... on IntType { + identifier + min + max + } + ... on ArrayType { + identifier + elementTypeId + } + ... on BooleanType { + identifier + } + } + `); + + const config: TypeScriptDocumentsPluginConfig = { + extractAllFieldsToTypesCompact: true, + printFieldsOnNewLines: true, + nonOptionalTypename: true, + fragmentSuffix: '', + }; + + const { content } = await plugin(schema, [{ location: 'test-file.ts', document }], config, { + outputFile: '', + }); + + await validate(content); + + // Should generate unique type names with type suffixes + expect(content).toContain('type TypeDefinitions_StringType_Fragment = {'); + expect(content).toContain('type TypeDefinitions_IntType_Fragment = {'); + expect(content).toContain('type TypeDefinitions_ArrayType_Fragment = {'); + expect(content).toContain('type TypeDefinitions_BooleanType_Fragment = {'); + + // Should generate a union type referencing the unique names + expect(content).toContain('export type TypeDefinitionsFragment ='); + expect(content).toContain('| TypeDefinitions_StringType_Fragment'); + expect(content).toContain('| TypeDefinitions_IntType_Fragment'); + expect(content).toContain('| TypeDefinitions_ArrayType_Fragment'); + expect(content).toContain('| TypeDefinitions_BooleanType_Fragment'); + + // Should NOT have duplicate type declarations with the same name + const typeDeclarationRegex = /type TypeDefinitions_StringType_Fragment = \{/g; + const matches = content.match(typeDeclarationRegex); + expect(matches).toHaveLength(1); // Should appear exactly once + }); + + it('should handle nested fields with parameters in union fragments', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + typeDefinitions: [TypeDefinition!]! + } + + interface TypeDefinition { + identifier: String! + } + + type Parameter { + name: String! + } + + type StructType implements TypeDefinition { + identifier: String! + parameters: [Parameter!]! + } + + type FunctionType implements TypeDefinition { + identifier: String! + parameters: [Parameter!]! + } + `); + + const document = parse(/* GraphQL */ ` + fragment ParameterDetails on Parameter { + __typename + } + + fragment TypeDefinitions on TypeDefinition { + __typename + ... on StructType { + identifier + parameters { + ...ParameterDetails + } + } + ... on FunctionType { + identifier + parameters { + ...ParameterDetails + } + } + } + `); + + const config: TypeScriptDocumentsPluginConfig = { + extractAllFieldsToTypesCompact: true, + printFieldsOnNewLines: true, + nonOptionalTypename: true, + fragmentSuffix: '', + }; + + const { content } = await plugin(schema, [{ location: 'test-file.ts', document }], config, { + outputFile: '', + }); + + await validate(content); + + // Should generate unique names for the main types + expect(content).toContain('type TypeDefinitions_StructType_Fragment = {'); + expect(content).toContain('type TypeDefinitions_FunctionType_Fragment = {'); + + // Should generate a union type + expect(content).toContain('export type TypeDefinitionsFragment ='); + expect(content).toContain('| TypeDefinitions_StructType_Fragment'); + expect(content).toContain('| TypeDefinitions_FunctionType_Fragment'); + + // Verify there are no duplicate type declarations + const structTypeRegex = /type TypeDefinitions_StructType_Fragment = \{/g; + const structMatches = content.match(structTypeRegex); + expect(structMatches).toHaveLength(1); + + const functionTypeRegex = /type TypeDefinitions_FunctionType_Fragment = \{/g; + const functionMatches = content.match(functionTypeRegex); + expect(functionMatches).toHaveLength(1); + }); + + it('should not add type suffix when there is only one inline fragment', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user: User + } + + interface User { + id: ID! + } + + type PremiumUser implements User { + id: ID! + isPremium: Boolean! + } + `); + + const document = parse(/* GraphQL */ ` + fragment UserFragment on User { + __typename + ... on PremiumUser { + id + isPremium + } + } + `); + + const config: TypeScriptDocumentsPluginConfig = { + extractAllFieldsToTypesCompact: true, + printFieldsOnNewLines: true, + nonOptionalTypename: true, + fragmentSuffix: '', + }; + + const { content } = await plugin(schema, [{ location: 'test-file.ts', document }], config, { + outputFile: '', + }); + + await validate(content); + + // With only one inline fragment, should use the base name without type suffix + expect(content).toContain('export type UserFragmentFragment = {'); + expect(content).not.toContain('UserFragment_PremiumUser_Fragment'); + }); + + it('should handle complex union with many types', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + shapes: [Shape!]! + } + + interface Shape { + id: ID! + } + + type Circle implements Shape { + id: ID! + radius: Float! + } + + type Rectangle implements Shape { + id: ID! + width: Float! + height: Float! + } + + type Triangle implements Shape { + id: ID! + base: Float! + height: Float! + } + + type Square implements Shape { + id: ID! + side: Float! + } + + type Polygon implements Shape { + id: ID! + sides: Int! + vertices: [Float!]! + } + + type Ellipse implements Shape { + id: ID! + majorAxis: Float! + minorAxis: Float! + } + + type Pentagon implements Shape { + id: ID! + side: Float! + } + `); + + const document = parse(/* GraphQL */ ` + fragment ShapeDetails on Shape { + __typename + ... on Circle { + id + radius + } + ... on Rectangle { + id + width + height + } + ... on Triangle { + id + base + height + } + ... on Square { + id + side + } + ... on Polygon { + id + sides + vertices + } + ... on Ellipse { + id + majorAxis + minorAxis + } + ... on Pentagon { + id + side + } + } + `); + + const config: TypeScriptDocumentsPluginConfig = { + extractAllFieldsToTypesCompact: true, + printFieldsOnNewLines: true, + nonOptionalTypename: true, + fragmentSuffix: '', + }; + + const { content } = await plugin(schema, [{ location: 'test-file.ts', document }], config, { + outputFile: '', + }); + + await validate(content); + + // Verify all unique type names exist + expect(content).toContain('type ShapeDetails_Circle_Fragment'); + expect(content).toContain('type ShapeDetails_Rectangle_Fragment'); + expect(content).toContain('type ShapeDetails_Triangle_Fragment'); + expect(content).toContain('type ShapeDetails_Square_Fragment'); + expect(content).toContain('type ShapeDetails_Polygon_Fragment'); + expect(content).toContain('type ShapeDetails_Ellipse_Fragment'); + expect(content).toContain('type ShapeDetails_Pentagon_Fragment'); + + // Verify union type exists + expect(content).toContain('export type ShapeDetailsFragment ='); + + // Verify all types are in the union + expect(content).toContain('| ShapeDetails_Circle_Fragment'); + expect(content).toContain('| ShapeDetails_Rectangle_Fragment'); + expect(content).toContain('| ShapeDetails_Triangle_Fragment'); + expect(content).toContain('| ShapeDetails_Square_Fragment'); + expect(content).toContain('| ShapeDetails_Polygon_Fragment'); + expect(content).toContain('| ShapeDetails_Ellipse_Fragment'); + expect(content).toContain('| ShapeDetails_Pentagon_Fragment'); + + // Verify there are no duplicate type declarations + const circleTypeRegex = /type ShapeDetails_Circle_Fragment = \{/g; + const circleMatches = content.match(circleTypeRegex); + expect(circleMatches).toHaveLength(1); + }); +}); 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 349f2da0489..c5a514ce8d6 100644 --- a/packages/plugins/typescript/operations/tests/extract-all-types.spec.ts +++ b/packages/plugins/typescript/operations/tests/extract-all-types.spec.ts @@ -1,12 +1,11 @@ import { buildSchema, parse } from 'graphql'; import { mergeOutputs, Types } from '@graphql-codegen/plugin-helpers'; import { validateTs } from '@graphql-codegen/testing'; -import { plugin as tsPlugin } from '../../typescript/src/index.js'; -import { plugin, TypeScriptDocumentsPluginConfig } from '../src/index.js'; +import { plugin, type TypeScriptDocumentsPluginConfig } from '../src/index.js'; describe('extractAllFieldsToTypes: true', () => { - const validate = async (content: Types.PluginOutput, config: any = {}, pluginSchema) => { - const m = mergeOutputs([await tsPlugin(pluginSchema, [], config, { outputFile: '' }), content]); + const validate = async (content: Types.PluginOutput) => { + const m = mergeOutputs([content]); validateTs(m, undefined, undefined, undefined, []); return m; @@ -70,7 +69,6 @@ describe('extractAllFieldsToTypes: true', () => { it('should extract types from queries', async () => { const config: TypeScriptDocumentsPluginConfig = { - preResolveTypes: true, extractAllFieldsToTypes: true, printFieldsOnNewLines: true, nonOptionalTypename: true, @@ -86,13 +84,13 @@ describe('extractAllFieldsToTypes: true', () => { "type UserFragment_DummyUser = { __typename: 'DummyUser', id: string, - joinDate: any + joinDate: unknown }; type UserFragment_ActiveUser = { __typename: 'ActiveUser', id: string, - joinDate: any + joinDate: unknown }; export type UserFragment = @@ -103,13 +101,13 @@ describe('extractAllFieldsToTypes: true', () => { export type MeFragment_ActiveUser_parentUser_DummyUser = { __typename: 'DummyUser', id: string, - joinDate: any + joinDate: unknown }; export type MeFragment_ActiveUser_parentUser_ActiveUser = { __typename: 'ActiveUser', id: string, - joinDate: any + joinDate: unknown }; export type MeFragment_ActiveUser_parentUser = @@ -120,14 +118,14 @@ describe('extractAllFieldsToTypes: true', () => { type Me_DummyUser_Fragment = { __typename: 'DummyUser', id: string, - joinDate: any + joinDate: unknown }; type Me_ActiveUser_Fragment = { __typename: 'ActiveUser', isActive: boolean, id: string, - joinDate: any, + joinDate: unknown, parentUser: MeFragment_ActiveUser_parentUser }; @@ -139,14 +137,14 @@ describe('extractAllFieldsToTypes: true', () => { export type OverlappingFieldsMergingTestQuery_me_DummyUser = { __typename: 'DummyUser', id: string, - joinDate: any + joinDate: unknown }; export type OverlappingFieldsMergingTestQuery_me_ActiveUser = { __typename: 'ActiveUser', id: string, isActive: boolean, - joinDate: any, + joinDate: unknown, parentUser: MeFragment_ActiveUser_parentUser }; @@ -157,7 +155,7 @@ describe('extractAllFieldsToTypes: true', () => { export type OverlappingFieldsMergingTestQuery_Query = { __typename: 'Query', - me?: OverlappingFieldsMergingTestQuery_me | null + me: OverlappingFieldsMergingTestQuery_me | null }; @@ -169,14 +167,14 @@ describe('extractAllFieldsToTypes: true', () => { export type NestedOverlappingFieldsMergingTestQuery_me_DummyUser = { __typename: 'DummyUser', id: string, - joinDate: any + joinDate: unknown }; export type NestedOverlappingFieldsMergingTestQuery_me_ActiveUser = { __typename: 'ActiveUser', isActive: boolean, id: string, - joinDate: any, + joinDate: unknown, parentUser: MeFragment_ActiveUser_parentUser }; @@ -187,7 +185,7 @@ describe('extractAllFieldsToTypes: true', () => { export type NestedOverlappingFieldsMergingTestQuery_Query = { __typename: 'Query', - me?: NestedOverlappingFieldsMergingTestQuery_me | null + me: NestedOverlappingFieldsMergingTestQuery_me | null }; @@ -198,7 +196,7 @@ describe('extractAllFieldsToTypes: true', () => { " `); - await validate(content, config, dummyUserTestSchema); + await validate(content); }); const complexTestSchemaWithUnionsAndInterfaces = buildSchema(/* GraphQL */ ` @@ -389,7 +387,6 @@ describe('extractAllFieldsToTypes: true', () => { it('should extract types from multiple fragments', async () => { const config: TypeScriptDocumentsPluginConfig = { - preResolveTypes: true, extractAllFieldsToTypes: true, nonOptionalTypename: true, dedupeOperationSuffix: true, @@ -401,7 +398,13 @@ describe('extractAllFieldsToTypes: true', () => { { outputFile: '' }, ); expect(content).toMatchInlineSnapshot(` - "export type ConversationBotSolutionFragment_BotSolution_article_ArchivedArticle = { __typename: 'ArchivedArticle', id: string, htmlUrl: string, title: string, url: string }; + "export type CallType = + | 'OUTGOING' + | 'INCOMING' + | 'VOICEMAIL' + | 'UNKNOWN'; + + export type ConversationBotSolutionFragment_BotSolution_article_ArchivedArticle = { __typename: 'ArchivedArticle', id: string, htmlUrl: string, title: string, url: string }; export type ConversationBotSolutionFragment_BotSolution_originatedFrom_EmailInteraction = { __typename: 'EmailInteraction', originalEmailURLPath: string }; @@ -409,11 +412,11 @@ describe('extractAllFieldsToTypes: true', () => { export type ConversationBotSolutionFragment_BotSolution_originatedFrom_TalkInteraction = { __typename: 'TalkInteraction' }; - export type ConversationBotSolutionFragment_BotSolution_originatedFrom_NativeMessagingInteraction = { __typename: 'NativeMessagingInteraction', conversationId?: string | null }; + export type ConversationBotSolutionFragment_BotSolution_originatedFrom_NativeMessagingInteraction = { __typename: 'NativeMessagingInteraction', conversationId: string | null }; - export type ConversationBotSolutionFragment_BotSolution_originatedFrom_WhatsAppInteraction = { __typename: 'WhatsAppInteraction', conversationId?: string | null }; + export type ConversationBotSolutionFragment_BotSolution_originatedFrom_WhatsAppInteraction = { __typename: 'WhatsAppInteraction', conversationId: string | null }; - export type ConversationBotSolutionFragment_BotSolution_originatedFrom_WeChatInteraction = { __typename: 'WeChatInteraction', conversationId?: string | null }; + export type ConversationBotSolutionFragment_BotSolution_originatedFrom_WeChatInteraction = { __typename: 'WeChatInteraction', conversationId: string | null }; export type ConversationBotSolutionFragment_BotSolution_originatedFrom_NotImplementedOriginatedFrom = { __typename: 'NotImplementedOriginatedFrom' }; @@ -439,11 +442,11 @@ describe('extractAllFieldsToTypes: true', () => { export type ConversationConversationEventFragment_ConversationEvent_originatedFrom_TalkInteraction = { __typename: 'TalkInteraction' }; - export type ConversationConversationEventFragment_ConversationEvent_originatedFrom_NativeMessagingInteraction = { __typename: 'NativeMessagingInteraction', conversationId?: string | null }; + export type ConversationConversationEventFragment_ConversationEvent_originatedFrom_NativeMessagingInteraction = { __typename: 'NativeMessagingInteraction', conversationId: string | null }; - export type ConversationConversationEventFragment_ConversationEvent_originatedFrom_WhatsAppInteraction = { __typename: 'WhatsAppInteraction', conversationId?: string | null }; + export type ConversationConversationEventFragment_ConversationEvent_originatedFrom_WhatsAppInteraction = { __typename: 'WhatsAppInteraction', conversationId: string | null }; - export type ConversationConversationEventFragment_ConversationEvent_originatedFrom_WeChatInteraction = { __typename: 'WeChatInteraction', conversationId?: string | null }; + export type ConversationConversationEventFragment_ConversationEvent_originatedFrom_WeChatInteraction = { __typename: 'WeChatInteraction', conversationId: string | null }; export type ConversationConversationEventFragment_ConversationEvent_originatedFrom_NotImplementedOriginatedFrom = { __typename: 'NotImplementedOriginatedFrom' }; @@ -501,11 +504,11 @@ describe('extractAllFieldsToTypes: true', () => { type ConversationOriginatedFrom_TalkInteraction_Fragment = { __typename: 'TalkInteraction' }; - type ConversationOriginatedFrom_NativeMessagingInteraction_Fragment = { __typename: 'NativeMessagingInteraction', conversationId?: string | null }; + type ConversationOriginatedFrom_NativeMessagingInteraction_Fragment = { __typename: 'NativeMessagingInteraction', conversationId: string | null }; - type ConversationOriginatedFrom_WhatsAppInteraction_Fragment = { __typename: 'WhatsAppInteraction', conversationId?: string | null }; + type ConversationOriginatedFrom_WhatsAppInteraction_Fragment = { __typename: 'WhatsAppInteraction', conversationId: string | null }; - type ConversationOriginatedFrom_WeChatInteraction_Fragment = { __typename: 'WeChatInteraction', conversationId?: string | null }; + type ConversationOriginatedFrom_WeChatInteraction_Fragment = { __typename: 'WeChatInteraction', conversationId: string | null }; type ConversationOriginatedFrom_NotImplementedOriginatedFrom_Fragment = { __typename: 'NotImplementedOriginatedFrom' }; @@ -525,11 +528,11 @@ describe('extractAllFieldsToTypes: true', () => { export type ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom_TalkInteraction = { __typename: 'TalkInteraction', channel: string, type: CallType }; - export type ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom_NativeMessagingInteraction = { __typename: 'NativeMessagingInteraction', conversationId?: string | null }; + export type ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom_NativeMessagingInteraction = { __typename: 'NativeMessagingInteraction', conversationId: string | null }; - export type ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom_WhatsAppInteraction = { __typename: 'WhatsAppInteraction', conversationId?: string | null }; + export type ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom_WhatsAppInteraction = { __typename: 'WhatsAppInteraction', conversationId: string | null }; - export type ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom_WeChatInteraction = { __typename: 'WeChatInteraction', conversationId?: string | null }; + export type ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom_WeChatInteraction = { __typename: 'WeChatInteraction', conversationId: string | null }; export type ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom_NotImplementedOriginatedFrom = { __typename: 'NotImplementedOriginatedFrom' }; @@ -547,12 +550,11 @@ describe('extractAllFieldsToTypes: true', () => { " `); - await validate(content, config, complexTestSchemaWithUnionsAndInterfaces); + await validate(content); }); it('should extract types from multiple fragments (mergeFragmentTypes: true)', async () => { const config: TypeScriptDocumentsPluginConfig = { - preResolveTypes: true, extractAllFieldsToTypes: true, nonOptionalTypename: true, dedupeOperationSuffix: true, @@ -565,7 +567,13 @@ describe('extractAllFieldsToTypes: true', () => { { outputFile: '' }, ); expect(content).toMatchInlineSnapshot(` - "export type ConversationBotSolutionFragment_BotSolution_article_ArchivedArticle = ( + "export type CallType = + | 'OUTGOING' + | 'INCOMING' + | 'VOICEMAIL' + | 'UNKNOWN'; + + export type ConversationBotSolutionFragment_BotSolution_article_ArchivedArticle = ( { id: string, htmlUrl: string, title: string, url: string } & { __typename: 'ArchivedArticle' } ); @@ -583,7 +591,7 @@ describe('extractAllFieldsToTypes: true', () => { export type ConversationBotSolutionFragment_BotSolution_originatedFrom_TalkInteraction_NotImplementedOriginatedFrom = { __typename: 'TalkInteraction' | 'NotImplementedOriginatedFrom' }; export type ConversationBotSolutionFragment_BotSolution_originatedFrom_NativeMessagingInteraction_WhatsAppInteraction_WeChatInteraction = ( - { conversationId?: string | null } + { conversationId: string | null } & { __typename: 'NativeMessagingInteraction' | 'WhatsAppInteraction' | 'WeChatInteraction' } ); @@ -622,7 +630,7 @@ describe('extractAllFieldsToTypes: true', () => { export type ConversationConversationEventFragment_ConversationEvent_originatedFrom_TalkInteraction_NotImplementedOriginatedFrom = { __typename: 'TalkInteraction' | 'NotImplementedOriginatedFrom' }; export type ConversationConversationEventFragment_ConversationEvent_originatedFrom_NativeMessagingInteraction_WhatsAppInteraction_WeChatInteraction = ( - { conversationId?: string | null } + { conversationId: string | null } & { __typename: 'NativeMessagingInteraction' | 'WhatsAppInteraction' | 'WeChatInteraction' } ); @@ -668,7 +676,7 @@ describe('extractAllFieldsToTypes: true', () => { type ConversationOriginatedFrom_TalkInteraction_NotImplementedOriginatedFrom_Fragment = { __typename: 'TalkInteraction' | 'NotImplementedOriginatedFrom' }; type ConversationOriginatedFrom_NativeMessagingInteraction_WhatsAppInteraction_WeChatInteraction_Fragment = ( - { conversationId?: string | null } + { conversationId: string | null } & { __typename: 'NativeMessagingInteraction' | 'WhatsAppInteraction' | 'WeChatInteraction' } ); @@ -695,7 +703,7 @@ describe('extractAllFieldsToTypes: true', () => { ); export type ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom_NativeMessagingInteraction_WhatsAppInteraction_WeChatInteraction = ( - { conversationId?: string | null } + { conversationId: string | null } & { __typename: 'NativeMessagingInteraction' | 'WhatsAppInteraction' | 'WeChatInteraction' } ); @@ -716,12 +724,11 @@ describe('extractAllFieldsToTypes: true', () => { " `); - await validate(content, config, complexTestSchemaWithUnionsAndInterfaces); + await validate(content); }); it("should extract types from multiple fragments (inlineFragmentTypes: 'combine')", async () => { const config: TypeScriptDocumentsPluginConfig = { - preResolveTypes: true, extractAllFieldsToTypes: true, nonOptionalTypename: true, dedupeOperationSuffix: true, @@ -734,7 +741,13 @@ describe('extractAllFieldsToTypes: true', () => { { outputFile: '' }, ); expect(content).toMatchInlineSnapshot(` - "export type ConversationBotSolutionFragment_BotSolution_article_ArchivedArticle = { __typename: 'ArchivedArticle', id: string, htmlUrl: string, title: string, url: string }; + "export type CallType = + | 'OUTGOING' + | 'INCOMING' + | 'VOICEMAIL' + | 'UNKNOWN'; + + export type ConversationBotSolutionFragment_BotSolution_article_ArchivedArticle = { __typename: 'ArchivedArticle', id: string, htmlUrl: string, title: string, url: string }; export type ConversationBotSolutionFragment_BotSolution_originatedFrom_EmailInteraction = ( { __typename: 'EmailInteraction' } @@ -890,17 +903,17 @@ describe('extractAllFieldsToTypes: true', () => { ); type ConversationOriginatedFrom_NativeMessagingInteraction_Fragment = ( - { __typename: 'NativeMessagingInteraction', conversationId?: string | null } + { __typename: 'NativeMessagingInteraction', conversationId: string | null } & MessageEnvelopeData_NativeMessagingInteraction_Fragment ); type ConversationOriginatedFrom_WhatsAppInteraction_Fragment = ( - { __typename: 'WhatsAppInteraction', conversationId?: string | null } + { __typename: 'WhatsAppInteraction', conversationId: string | null } & MessageEnvelopeData_WhatsAppInteraction_Fragment ); type ConversationOriginatedFrom_WeChatInteraction_Fragment = ( - { __typename: 'WeChatInteraction', conversationId?: string | null } + { __typename: 'WeChatInteraction', conversationId: string | null } & MessageEnvelopeData_WeChatInteraction_Fragment ); @@ -954,12 +967,11 @@ describe('extractAllFieldsToTypes: true', () => { " `); - await validate(content, config, complexTestSchemaWithUnionsAndInterfaces); + await validate(content); }); it("should extract types from multiple fragments (inlineFragmentTypes: 'mask')", async () => { const config: TypeScriptDocumentsPluginConfig = { - preResolveTypes: true, extractAllFieldsToTypes: true, nonOptionalTypename: true, dedupeOperationSuffix: true, @@ -972,7 +984,13 @@ describe('extractAllFieldsToTypes: true', () => { { outputFile: '' }, ); expect(content).toMatchInlineSnapshot(` - "export type ConversationBotSolutionFragment_BotSolution_article_ArchivedArticle = { __typename: 'ArchivedArticle', id: string, htmlUrl: string, title: string, url: string }; + "export type CallType = + | 'OUTGOING' + | 'INCOMING' + | 'VOICEMAIL' + | 'UNKNOWN'; + + export type ConversationBotSolutionFragment_BotSolution_article_ArchivedArticle = { __typename: 'ArchivedArticle', id: string, htmlUrl: string, title: string, url: string }; export type ConversationBotSolutionFragment_BotSolution_originatedFrom_EmailInteraction = ( { __typename: 'EmailInteraction' } @@ -1127,17 +1145,17 @@ describe('extractAllFieldsToTypes: true', () => { ) & { ' $fragmentName'?: 'ConversationOriginatedFrom_TalkInteraction_Fragment' }; type ConversationOriginatedFrom_NativeMessagingInteraction_Fragment = ( - { __typename: 'NativeMessagingInteraction', conversationId?: string | null } + { __typename: 'NativeMessagingInteraction', conversationId: string | null } & { ' $fragmentRefs'?: { 'MessageEnvelopeData_NativeMessagingInteraction_Fragment': MessageEnvelopeData_NativeMessagingInteraction_Fragment } } ) & { ' $fragmentName'?: 'ConversationOriginatedFrom_NativeMessagingInteraction_Fragment' }; type ConversationOriginatedFrom_WhatsAppInteraction_Fragment = ( - { __typename: 'WhatsAppInteraction', conversationId?: string | null } + { __typename: 'WhatsAppInteraction', conversationId: string | null } & { ' $fragmentRefs'?: { 'MessageEnvelopeData_WhatsAppInteraction_Fragment': MessageEnvelopeData_WhatsAppInteraction_Fragment } } ) & { ' $fragmentName'?: 'ConversationOriginatedFrom_WhatsAppInteraction_Fragment' }; type ConversationOriginatedFrom_WeChatInteraction_Fragment = ( - { __typename: 'WeChatInteraction', conversationId?: string | null } + { __typename: 'WeChatInteraction', conversationId: string | null } & { ' $fragmentRefs'?: { 'MessageEnvelopeData_WeChatInteraction_Fragment': MessageEnvelopeData_WeChatInteraction_Fragment } } ) & { ' $fragmentName'?: 'ConversationOriginatedFrom_WeChatInteraction_Fragment' }; @@ -1190,278 +1208,9 @@ describe('extractAllFieldsToTypes: true', () => { " `); - await validate(content, config, complexTestSchemaWithUnionsAndInterfaces); + await validate(content); }); - 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 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_ConversationEvent_originatedFrom_EmailInteraction = ( - { __typename: 'EmailInteraction' } - & Pick - ); - - export type ConversationConversationEventFragment_ConversationEvent_originatedFrom_CustomChannelInteraction = ( - { __typename: 'CustomChannelInteraction' } - & Pick - ); - - export type ConversationConversationEventFragment_ConversationEvent_originatedFrom_TalkInteraction = { __typename: 'TalkInteraction' }; - - export type ConversationConversationEventFragment_ConversationEvent_originatedFrom_NativeMessagingInteraction = ( - { __typename: 'NativeMessagingInteraction' } - & Pick - ); - - export type ConversationConversationEventFragment_ConversationEvent_originatedFrom_WhatsAppInteraction = ( - { __typename: 'WhatsAppInteraction' } - & Pick - ); - - export type ConversationConversationEventFragment_ConversationEvent_originatedFrom_WeChatInteraction = ( - { __typename: 'WeChatInteraction' } - & Pick - ); - - export type ConversationConversationEventFragment_ConversationEvent_originatedFrom_NotImplementedOriginatedFrom = { __typename: 'NotImplementedOriginatedFrom' }; - - export type ConversationConversationEventFragment_ConversationEvent_originatedFrom = - | ConversationConversationEventFragment_ConversationEvent_originatedFrom_EmailInteraction - | ConversationConversationEventFragment_ConversationEvent_originatedFrom_CustomChannelInteraction - | ConversationConversationEventFragment_ConversationEvent_originatedFrom_TalkInteraction - | ConversationConversationEventFragment_ConversationEvent_originatedFrom_NativeMessagingInteraction - | ConversationConversationEventFragment_ConversationEvent_originatedFrom_WhatsAppInteraction - | ConversationConversationEventFragment_ConversationEvent_originatedFrom_WeChatInteraction - | ConversationConversationEventFragment_ConversationEvent_originatedFrom_NotImplementedOriginatedFrom - ; - - type ConversationConversationEvent_BrokenConversationEvent_Fragment = ( - { __typename: 'BrokenConversationEvent' } - & Pick - & { originatedFrom: ConversationConversationEventFragment_ConversationEvent_originatedFrom } - ); - - type ConversationConversationEvent_BotSolution_Fragment = ( - { __typename: 'BotSolution' } - & Pick - & { originatedFrom: ConversationConversationEventFragment_ConversationEvent_originatedFrom } - ); - - type ConversationConversationEvent_TalkPublicCallSummary_Fragment = ( - { __typename: 'TalkPublicCallSummary' } - & Pick - & { originatedFrom: ConversationConversationEventFragment_ConversationEvent_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); - }); it('fields with shared types and no fragments should use the shared type interface name', async () => { const nestedInterfacesSchema = buildSchema(/* GraphQL */ ` type Query { @@ -1508,7 +1257,6 @@ describe('extractAllFieldsToTypes: true', () => { `); const config: TypeScriptDocumentsPluginConfig = { - preResolveTypes: true, extractAllFieldsToTypes: true, nonOptionalTypename: true, dedupeOperationSuffix: true, @@ -1543,7 +1291,7 @@ describe('extractAllFieldsToTypes: true', () => { | GetAnimalsQuery_animals_Dog ; - export type GetAnimalsQuery_Query = { __typename: 'Query', animals?: Array | null }; + export type GetAnimalsQuery_Query = { __typename: 'Query', animals: Array | null }; export type GetAnimalsQueryVariables = Exact<{ [key: string]: never; }>; @@ -1553,7 +1301,7 @@ describe('extractAllFieldsToTypes: true', () => { " `); - await validate(content, config, nestedInterfacesSchema); + await validate(content); }); it('fragment spreads on the same interface should not force concrete parent type names (regression #10502)', async () => { @@ -1610,7 +1358,6 @@ describe('extractAllFieldsToTypes: true', () => { `); const config: TypeScriptDocumentsPluginConfig = { - preResolveTypes: true, extractAllFieldsToTypes: true, nonOptionalTypename: true, dedupeOperationSuffix: true, @@ -1628,9 +1375,9 @@ describe('extractAllFieldsToTypes: true', () => { expect(content).toMatchInlineSnapshot(` "export type GetFragmentPetFragment_Pet_home_House = { __typename: 'House', id: string }; - type GetFragmentPet_Dog_Fragment = { __typename: 'Dog', id: string, home?: GetFragmentPetFragment_Pet_home_House | null }; + type GetFragmentPet_Dog_Fragment = { __typename: 'Dog', id: string, home: GetFragmentPetFragment_Pet_home_House | null }; - type GetFragmentPet_Cat_Fragment = { __typename: 'Cat', id: string, home?: GetFragmentPetFragment_Pet_home_House | null }; + type GetFragmentPet_Cat_Fragment = { __typename: 'Cat', id: string, home: GetFragmentPetFragment_Pet_home_House | null }; export type GetFragmentPetFragment = | GetFragmentPet_Dog_Fragment @@ -1639,20 +1386,20 @@ describe('extractAllFieldsToTypes: true', () => { export type GetPetDataQuery_pet_Pet_home_House = { __typename: 'House', id: string }; - export type GetPetDataQuery_pet_Dog = { __typename: 'Dog', id: string, home?: GetPetDataQuery_pet_Pet_home_House | null }; + export type GetPetDataQuery_pet_Dog = { __typename: 'Dog', id: string, home: GetPetDataQuery_pet_Pet_home_House | null }; - export type GetPetDataQuery_pet_Cat = { __typename: 'Cat', id: string, home?: GetPetDataQuery_pet_Pet_home_House | null }; + export type GetPetDataQuery_pet_Cat = { __typename: 'Cat', id: string, home: GetPetDataQuery_pet_Pet_home_House | null }; export type GetPetDataQuery_pet = | GetPetDataQuery_pet_Dog | GetPetDataQuery_pet_Cat ; - export type GetPetDataQuery_Query = { __typename: 'Query', pet?: GetPetDataQuery_pet | null }; + export type GetPetDataQuery_Query = { __typename: 'Query', pet: GetPetDataQuery_pet | null }; export type GetPetDataQueryVariables = Exact<{ - petId: Scalars['ID']['input']; + petId: string | number; }>; @@ -1660,7 +1407,7 @@ describe('extractAllFieldsToTypes: true', () => { " `); - await validate(content, config, interfaceFragmentSchema); + await validate(content); }); // Exception case for Issue #10502 - shared schema for fragment tests @@ -1720,7 +1467,6 @@ describe('extractAllFieldsToTypes: true', () => { `); const config: TypeScriptDocumentsPluginConfig = { - preResolveTypes: true, extractAllFieldsToTypes: true, nonOptionalTypename: true, dedupeOperationSuffix: true, @@ -1752,9 +1498,9 @@ describe('extractAllFieldsToTypes: true', () => { | GetNotificationsQuery_notifications_SystemNotification_content_ImageContent ; - export type GetNotificationsQuery_notifications_AppNotification = { __typename: 'AppNotification', id: string, content?: GetNotificationsQuery_notifications_AppNotification_content | null }; + export type GetNotificationsQuery_notifications_AppNotification = { __typename: 'AppNotification', id: string, content: GetNotificationsQuery_notifications_AppNotification_content | null }; - export type GetNotificationsQuery_notifications_SystemNotification = { __typename: 'SystemNotification', id: string, content?: GetNotificationsQuery_notifications_SystemNotification_content | null }; + export type GetNotificationsQuery_notifications_SystemNotification = { __typename: 'SystemNotification', id: string, content: GetNotificationsQuery_notifications_SystemNotification_content | null }; export type GetNotificationsQuery_notifications = | GetNotificationsQuery_notifications_AppNotification @@ -1770,7 +1516,7 @@ describe('extractAllFieldsToTypes: true', () => { export type GetNotificationsQuery = GetNotificationsQuery_Query; " `); - await validate(content, config, notificationSchema); + await validate(content); }); it('named fragments should use their name and not parent type name', async () => { @@ -1798,7 +1544,6 @@ describe('extractAllFieldsToTypes: true', () => { `); const config: TypeScriptDocumentsPluginConfig = { - preResolveTypes: true, extractAllFieldsToTypes: true, nonOptionalTypename: true, dedupeOperationSuffix: true, @@ -1821,7 +1566,7 @@ describe('extractAllFieldsToTypes: true', () => { | AppNotificationFragment_AppNotification_content_ImageContent ; - export type AppNotificationFragment = { __typename: 'AppNotification', content?: AppNotificationFragment_AppNotification_content | null }; + export type AppNotificationFragment = { __typename: 'AppNotification', content: AppNotificationFragment_AppNotification_content | null }; export type SystemNotificationFragment_SystemNotification_content_TextContent = { __typename: 'TextContent', id: string }; @@ -1832,11 +1577,11 @@ describe('extractAllFieldsToTypes: true', () => { | SystemNotificationFragment_SystemNotification_content_ImageContent ; - export type SystemNotificationFragment = { __typename: 'SystemNotification', content?: SystemNotificationFragment_SystemNotification_content | null }; + export type SystemNotificationFragment = { __typename: 'SystemNotification', content: SystemNotificationFragment_SystemNotification_content | null }; - export type GetNotificationsQuery_notifications_AppNotification = { __typename: 'AppNotification', id: string, title: string, content?: AppNotificationFragment_AppNotification_content | null }; + export type GetNotificationsQuery_notifications_AppNotification = { __typename: 'AppNotification', id: string, title: string, content: AppNotificationFragment_AppNotification_content | null }; - export type GetNotificationsQuery_notifications_SystemNotification = { __typename: 'SystemNotification', id: string, title: string, content?: SystemNotificationFragment_SystemNotification_content | null }; + export type GetNotificationsQuery_notifications_SystemNotification = { __typename: 'SystemNotification', id: string, title: string, content: SystemNotificationFragment_SystemNotification_content | null }; export type GetNotificationsQuery_notifications = | GetNotificationsQuery_notifications_AppNotification @@ -1852,6 +1597,249 @@ describe('extractAllFieldsToTypes: true', () => { export type GetNotificationsQuery = GetNotificationsQuery_Query; " `); - await validate(content, config, notificationSchema); + await validate(content); + }); +}); + +describe('extractAllFieldsToTypesCompact: true', () => { + const validate = async (content: Types.PluginOutput) => { + const m = mergeOutputs([content]); + validateTs(m, undefined, undefined, undefined, []); + + return m; + }; + + const companySchema = buildSchema(/* GraphQL */ ` + type Query { + company(id: ID!): Company + } + type Company { + id: ID! + name: String! + score: Float + reviewCount: Int + office: Office + } + type Office { + id: ID! + location: Location + } + type Location { + formatted: String + } + `); + + const companyDoc = parse(/* GraphQL */ ` + query GetCompanyInfo($id: ID!) { + company(id: $id) { + id + name + score + reviewCount + office { + id + location { + formatted + } + } + } + } + `); + + it('should generate compact type names without GraphQL type names (Apollo Tooling style)', async () => { + const config: TypeScriptDocumentsPluginConfig = { + extractAllFieldsToTypesCompact: true, + nonOptionalTypename: true, + omitOperationSuffix: true, + }; + const { content } = await plugin( + companySchema, + [{ location: 'test-file.ts', document: companyDoc }], + config, + { + outputFile: '', + }, + ); + expect(content).toMatchInlineSnapshot(` + "export type GetCompanyInfo_company_office_location = { __typename: 'Location', formatted: string | null }; + + export type GetCompanyInfo_company_office = { __typename: 'Office', id: string, location: GetCompanyInfo_company_office_location | null }; + + export type GetCompanyInfo_company = { __typename: 'Company', id: string, name: string, score: number | null, reviewCount: number | null, office: GetCompanyInfo_company_office | null }; + + export type GetCompanyInfo = { __typename: 'Query', company: GetCompanyInfo_company | null }; + + + export type GetCompanyInfoVariables = Exact<{ + id: string | number; + }>; + " + `); + + await validate(content); + }); + + it('should work with unions and interfaces in compact mode', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + animals: [Animal!]! + } + interface Animal { + name: String! + owner: Person! + } + type Cat implements Animal { + name: String! + owner: Person! + } + type Dog implements Animal { + name: String! + owner: Person! + } + union Person = Trainer | Veterinarian + type Trainer { + name: String! + } + type Veterinarian { + name: String! + } + `); + + const doc = parse(/* GraphQL */ ` + query GetAnimals { + animals { + name + owner { + ... on Trainer { + name + } + ... on Veterinarian { + name + } + } + } + } + `); + + const config: TypeScriptDocumentsPluginConfig = { + extractAllFieldsToTypesCompact: true, + nonOptionalTypename: true, + omitOperationSuffix: true, + }; + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: doc }], + config, + { outputFile: '' }, + ); + + // Verify the naming follows Apollo Tooling style (field names only, no intermediate type names) + expect(content).toContain('GetAnimals_animals_owner_Trainer'); + expect(content).toContain('GetAnimals_animals_owner_Veterinarian'); + expect(content).toContain('GetAnimals_animals_owner'); + expect(content).toContain('GetAnimals_animals_Cat'); + expect(content).toContain('GetAnimals_animals_Dog'); + expect(content).toContain('GetAnimals_animals'); + + // Should NOT contain intermediate type names in the field paths (like Animal between animals and owner) + expect(content).not.toContain('GetAnimals_animals_Animal_owner'); + + await validate(content); + }); + + it('should automatically enable extractAllFieldsToTypes when extractAllFieldsToTypesCompact is true', async () => { + const config: TypeScriptDocumentsPluginConfig = { + extractAllFieldsToTypes: false, + extractAllFieldsToTypesCompact: true, + nonOptionalTypename: true, + omitOperationSuffix: true, + }; + const { content } = await plugin( + companySchema, + [{ location: 'test-file.ts', document: companyDoc }], + config, + { + outputFile: '', + }, + ); + + // When extractAllFieldsToTypesCompact is true, extractAllFieldsToTypes should be automatically enabled + // So types should be extracted, not inlined + expect(content).toContain('GetCompanyInfo_company_office_location'); + expect(content).toContain('GetCompanyInfo_company_office'); + expect(content).toContain('GetCompanyInfo_company'); + expect(content).toContain('export type GetCompanyInfo'); + + await validate(content); + }); + + it('should apply compact naming to fragments', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(id: ID!): User + } + interface User { + id: ID! + profile: Profile + } + type AdminUser implements User { + id: ID! + profile: Profile + permissions: [String!]! + } + type RegularUser implements User { + id: ID! + profile: Profile + } + type Profile { + name: String! + contact: Contact + } + type Contact { + email: String + } + `); + + const doc = parse(/* GraphQL */ ` + fragment UserProfile on User { + id + profile { + name + contact { + email + } + } + } + query GetUser($id: ID!) { + user(id: $id) { + ...UserProfile + ... on AdminUser { + permissions + } + } + } + `); + + const config: TypeScriptDocumentsPluginConfig = { + extractAllFieldsToTypesCompact: true, + nonOptionalTypename: true, + omitOperationSuffix: true, + }; + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: doc }], + config, + { outputFile: '' }, + ); + + // Fragment types should use compact naming (no intermediate type names) + expect(content).toContain('UserProfile_profile_contact'); + expect(content).toContain('UserProfile_profile'); + + // Should NOT contain type names in fragment paths + expect(content).not.toContain('UserProfile_profile_Profile_contact'); + expect(content).not.toContain('UserProfile_profile_Profile_contact_Contact'); + + await validate(content); }); }); diff --git a/packages/plugins/typescript/operations/tests/ts-documents.apolloUnmask.spec.ts b/packages/plugins/typescript/operations/tests/ts-documents.apolloUnmask.spec.ts index b26ba4dd0c7..0f7d7294a64 100644 --- a/packages/plugins/typescript/operations/tests/ts-documents.apolloUnmask.spec.ts +++ b/packages/plugins/typescript/operations/tests/ts-documents.apolloUnmask.spec.ts @@ -25,9 +25,9 @@ describe('TypeScript Operations Plugin - apolloUnmask', () => { "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_1_Query = { __typename?: 'Query', me?: { __typename?: 'User', id: string } | null }; + export type Unnamed_1_Query = { me: { id: string } | null }; - export type UserFragmentFragment = { __typename?: 'User', id: string } & { ' $fragmentName'?: 'UserFragmentFragment' }; + export type UserFragmentFragment = { id: string } & { ' $fragmentName'?: 'UserFragmentFragment' }; " `); }); @@ -53,12 +53,9 @@ describe('TypeScript Operations Plugin - apolloUnmask', () => { "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_1_Query = { __typename?: 'Query', me?: ( - { __typename?: 'User' } - & { ' $fragmentRefs'?: { 'UserFragmentFragment': UserFragmentFragment } } - ) | null }; + export type Unnamed_1_Query = { me: { ' $fragmentRefs'?: { 'UserFragmentFragment': UserFragmentFragment } } | null }; - export type UserFragmentFragment = { __typename?: 'User', id: string } & { ' $fragmentName'?: 'UserFragmentFragment' }; + export type UserFragmentFragment = { id: string } & { ' $fragmentName'?: 'UserFragmentFragment' }; " `); }); @@ -87,12 +84,9 @@ describe('TypeScript Operations Plugin - apolloUnmask', () => { "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_1_Query = { __typename?: 'Query', me?: ( - { __typename?: 'User' } - & { ' $fragmentRefs'?: { 'UserFragmentFragment': UserFragmentFragment } } - ) | null }; + export type Unnamed_1_Query = { me: { ' $fragmentRefs'?: { 'UserFragmentFragment': UserFragmentFragment } } | null }; - export type UserFragmentFragment = { __typename?: 'User', id: string } & { ' $fragmentName'?: 'UserFragmentFragment' }; + export type UserFragmentFragment = { id: string } & { ' $fragmentName'?: 'UserFragmentFragment' }; " `); }); @@ -123,14 +117,14 @@ describe('TypeScript Operations Plugin - apolloUnmask', () => { "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_1_Query = { __typename?: 'Query', me?: ( - { __typename?: 'User', id: string } + export type Unnamed_1_Query = { me: ( + { id: string } & { ' $fragmentRefs'?: { 'UserFragment2Fragment': UserFragment2Fragment } } ) | null }; - export type UserFragmentFragment = { __typename?: 'User', id: string } & { ' $fragmentName'?: 'UserFragmentFragment' }; + export type UserFragmentFragment = { id: string } & { ' $fragmentName'?: 'UserFragmentFragment' }; - export type UserFragment2Fragment = { __typename?: 'User', email: string } & { ' $fragmentName'?: 'UserFragment2Fragment' }; + export type UserFragment2Fragment = { email: string } & { ' $fragmentName'?: 'UserFragment2Fragment' }; " `); }); @@ -162,14 +156,14 @@ describe('TypeScript Operations Plugin - apolloUnmask', () => { "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_1_Query = { __typename?: 'Query', me?: ( - { __typename?: 'User', id: string, email: string } + export type Unnamed_1_Query = { me: ( + { id: string, email: string } & { ' $fragmentRefs'?: { 'UserFragment2Fragment': UserFragment2Fragment } } ) | null }; - export type UserFragmentFragment = { __typename?: 'User', id: string, email: string } & { ' $fragmentName'?: 'UserFragmentFragment' }; + export type UserFragmentFragment = { id: string, email: string } & { ' $fragmentName'?: 'UserFragmentFragment' }; - export type UserFragment2Fragment = { __typename?: 'User', email: string } & { ' $fragmentName'?: 'UserFragment2Fragment' }; + export type UserFragment2Fragment = { email: string } & { ' $fragmentName'?: 'UserFragment2Fragment' }; " `); }); diff --git a/packages/plugins/typescript/operations/tests/ts-documents.external-fragments-enum.spec.ts b/packages/plugins/typescript/operations/tests/ts-documents.external-fragments-enum.spec.ts new file mode 100644 index 00000000000..625341a79eb --- /dev/null +++ b/packages/plugins/typescript/operations/tests/ts-documents.external-fragments-enum.spec.ts @@ -0,0 +1,485 @@ +import { buildSchema, parse } from 'graphql'; +import { mergeOutputs } from '@graphql-codegen/plugin-helpers'; +import { validateTs } from '@graphql-codegen/testing'; +import { plugin } from '../src/index.js'; + +describe('TypeScript Operations Plugin - External Fragments with Enums', () => { + it('should include enum in document when enum is used in external fragment', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user: User + } + + type User { + id: ID! + name: String! + role: UserRole! + profile: UserProfile! + } + + type UserProfile { + bio: String! + } + + enum UserRole { + ADMIN + CUSTOMER + GUEST + } + `); + + // Fragment defined separately (external fragment) + const fragmentDocument = parse(/* GraphQL */ ` + fragment UserFields on User { + role + profile { + bio + } + } + `); + + // Query that uses the external fragment + const queryDocument = parse(/* GraphQL */ ` + query GetUser { + user { + id + ...UserFields + } + } + `); + + const fragmentDef = fragmentDocument.definitions[0]; + if (fragmentDef.kind !== 'FragmentDefinition') { + throw new Error('Expected fragment definition'); + } + + const result = mergeOutputs([ + await plugin( + schema, + [{ document: queryDocument }], + { + enumType: 'native', + externalFragments: [ + { + node: fragmentDef, + name: 'UserFields', + onType: 'User', + isExternal: true, + }, + ], + }, + { outputFile: '' }, + ), + ]); + + // The enum should be included in the output + expect(result).toContain('export enum UserRole'); + expect(result).toContain("Admin = 'ADMIN'"); + expect(result).toContain("Customer = 'CUSTOMER'"); + expect(result).toContain("Guest = 'GUEST'"); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('should include enum in document when enum is nested deeply in external fragment', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + organization: Organization + } + + type Organization { + id: ID! + users: [User!]! + } + + type User { + id: ID! + manager: Manager! + } + + type Manager { + id: ID! + roleType: ManagerRole! + } + + enum ManagerRole { + SENIOR + JUNIOR + LEAD + } + `); + + const fragmentDocument = parse(/* GraphQL */ ` + fragment ManagerFields on User { + manager { + id + roleType + } + } + `); + + const queryDocument = parse(/* GraphQL */ ` + query GetOrganization { + organization { + id + users { + id + ...ManagerFields + } + } + } + `); + + const fragmentDef = fragmentDocument.definitions[0]; + if (fragmentDef.kind !== 'FragmentDefinition') { + throw new Error('Expected fragment definition'); + } + + const result = mergeOutputs([ + await plugin( + schema, + [{ document: queryDocument }], + { + enumType: 'native', + externalFragments: [ + { + node: fragmentDef, + name: 'ManagerFields', + onType: 'User', + isExternal: true, + }, + ], + }, + { outputFile: '' }, + ), + ]); + + // The enum should be included even though it's nested deeply + expect(result).toContain('export enum ManagerRole'); + expect(result).toContain("Senior = 'SENIOR'"); + expect(result).toContain("Junior = 'JUNIOR'"); + expect(result).toContain("Lead = 'LEAD'"); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('should include multiple enums from multiple external fragments', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user: User + } + + type User { + id: ID! + role: UserRole! + status: UserStatus! + } + + enum UserRole { + ADMIN + CUSTOMER + } + + enum UserStatus { + ACTIVE + INACTIVE + } + `); + + const roleFragmentDocument = parse(/* GraphQL */ ` + fragment RoleFields on User { + role + } + `); + + const statusFragmentDocument = parse(/* GraphQL */ ` + fragment StatusFields on User { + status + } + `); + + const queryDocument = parse(/* GraphQL */ ` + query GetUser { + user { + id + ...RoleFields + ...StatusFields + } + } + `); + + const roleFragmentDef = roleFragmentDocument.definitions[0]; + const statusFragmentDef = statusFragmentDocument.definitions[0]; + + if ( + roleFragmentDef.kind !== 'FragmentDefinition' || + statusFragmentDef.kind !== 'FragmentDefinition' + ) { + throw new Error('Expected fragment definitions'); + } + + const result = mergeOutputs([ + await plugin( + schema, + [{ document: queryDocument }], + { + enumType: 'native', + externalFragments: [ + { + node: roleFragmentDef, + name: 'RoleFields', + onType: 'User', + isExternal: true, + }, + { + node: statusFragmentDef, + name: 'StatusFields', + onType: 'User', + isExternal: true, + }, + ], + }, + { outputFile: '' }, + ), + ]); + + // Both enums should be included + expect(result).toContain('export enum UserRole'); + expect(result).toContain("Admin = 'ADMIN'"); + expect(result).toContain("Customer = 'CUSTOMER'"); + + expect(result).toContain('export enum UserStatus'); + expect(result).toContain("Active = 'ACTIVE'"); + expect(result).toContain("Inactive = 'INACTIVE'"); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('should not duplicate enum if it appears in both query and external fragment', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user: User + admin: User + } + + type User { + id: ID! + role: UserRole! + } + + enum UserRole { + ADMIN + CUSTOMER + } + `); + + const fragmentDocument = parse(/* GraphQL */ ` + fragment UserFields on User { + role + } + `); + + const queryDocument = parse(/* GraphQL */ ` + query GetUsers { + user { + id + ...UserFields + } + admin { + id + role + } + } + `); + + const fragmentDef = fragmentDocument.definitions[0]; + if (fragmentDef.kind !== 'FragmentDefinition') { + throw new Error('Expected fragment definition'); + } + + const result = mergeOutputs([ + await plugin( + schema, + [{ document: queryDocument }], + { + enumType: 'native', + externalFragments: [ + { + node: fragmentDef, + name: 'UserFields', + onType: 'User', + isExternal: true, + }, + ], + }, + { outputFile: '' }, + ), + ]); + + // The enum should appear only once + const enumMatches = result.match(/export enum UserRole/g); + expect(enumMatches).toHaveLength(1); + + expect(result).toContain('export enum UserRole'); + expect(result).toContain("Admin = 'ADMIN'"); + expect(result).toContain("Customer = 'CUSTOMER'"); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('should handle external fragment with nested fragment spread containing enum', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user: User + } + + type User { + id: ID! + profile: UserProfile! + } + + type UserProfile { + id: ID! + visibility: Visibility! + } + + enum Visibility { + PUBLIC + PRIVATE + FRIENDS_ONLY + } + `); + + const profileFragmentDocument = parse(/* GraphQL */ ` + fragment ProfileVisibility on UserProfile { + visibility + } + `); + + const userFragmentDocument = parse(/* GraphQL */ ` + fragment UserWithProfile on User { + id + profile { + ...ProfileVisibility + } + } + `); + + const queryDocument = parse(/* GraphQL */ ` + query GetUser { + user { + ...UserWithProfile + } + } + `); + + const profileFragmentDef = profileFragmentDocument.definitions[0]; + const userFragmentDef = userFragmentDocument.definitions[0]; + + if ( + profileFragmentDef.kind !== 'FragmentDefinition' || + userFragmentDef.kind !== 'FragmentDefinition' + ) { + throw new Error('Expected fragment definitions'); + } + + const result = mergeOutputs([ + await plugin( + schema, + [{ document: queryDocument }], + { + enumType: 'native', + externalFragments: [ + { + node: profileFragmentDef, + name: 'ProfileVisibility', + onType: 'UserProfile', + isExternal: true, + }, + { + node: userFragmentDef, + name: 'UserWithProfile', + onType: 'User', + isExternal: true, + }, + ], + }, + { outputFile: '' }, + ), + ]); + + // The enum should be included even with nested fragment spreads + expect(result).toContain('export enum Visibility'); + expect(result).toContain("Public = 'PUBLIC'"); + expect(result).toContain("Private = 'PRIVATE'"); + expect(result).toContain("FriendsOnly = 'FRIENDS_ONLY'"); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('should include enum with const enum type from external fragment', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user: User + } + + type User { + id: ID! + role: UserRole! + } + + enum UserRole { + ADMIN + CUSTOMER + } + `); + + const fragmentDocument = parse(/* GraphQL */ ` + fragment UserFields on User { + role + } + `); + + const queryDocument = parse(/* GraphQL */ ` + query GetUser { + user { + id + ...UserFields + } + } + `); + + const fragmentDef = fragmentDocument.definitions[0]; + if (fragmentDef.kind !== 'FragmentDefinition') { + throw new Error('Expected fragment definition'); + } + + const result = mergeOutputs([ + await plugin( + schema, + [{ document: queryDocument }], + { + enumType: 'const', + externalFragments: [ + { + node: fragmentDef, + name: 'UserFields', + onType: 'User', + isExternal: true, + }, + ], + }, + { outputFile: '' }, + ), + ]); + + // The enum should be included as const object + expect(result).toContain('export const UserRole = {'); + expect(result).toContain("Admin: 'ADMIN'"); + expect(result).toContain("Customer: 'CUSTOMER'"); + expect(result).toContain('} as const;'); + expect(result).toContain('export type UserRole = typeof UserRole[keyof typeof UserRole];'); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); +}); diff --git a/packages/plugins/typescript/operations/tests/ts-documents.externalDocuments.spec.ts b/packages/plugins/typescript/operations/tests/ts-documents.externalDocuments.spec.ts index 3c2139335fb..f474eb86b3f 100644 --- a/packages/plugins/typescript/operations/tests/ts-documents.externalDocuments.spec.ts +++ b/packages/plugins/typescript/operations/tests/ts-documents.externalDocuments.spec.ts @@ -1,5 +1,6 @@ import { buildSchema, parse } from 'graphql'; import { mergeOutputs } from '@graphql-codegen/plugin-helpers'; +import { validateTs } from '@graphql-codegen/testing'; import { plugin } from '../src/index.js'; describe('TypeScript Operations Plugin - externalDocuments', () => { @@ -49,15 +50,17 @@ describe('TypeScript Operations Plugin - externalDocuments', () => { ]); expect(result).toMatchInlineSnapshot(` - "export type UserQueryVariables = Exact<{ [key: string]: never; }>; + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserQueryVariables = Exact<{ [key: string]: never; }>; - export type UserQuery = { __typename?: 'Query', user?: { __typename?: 'User', id: string, name: string } | null }; + export type UserQuery = { user: { id: string, name: string } | null }; " `); - // FIXME: cannot call `validateTs` until next major version - // https://github.com/dotansimha/graphql-code-generator/pull/10496/changes - // validateTs(result, undefined, undefined, undefined, undefined, true); + validateTs(result, undefined, undefined, undefined, undefined, true); }); }); diff --git a/packages/plugins/typescript/operations/tests/ts-documents.nullability.spec.ts b/packages/plugins/typescript/operations/tests/ts-documents.nullability.spec.ts index df6c18e18d3..6b89ff30494 100644 --- a/packages/plugins/typescript/operations/tests/ts-documents.nullability.spec.ts +++ b/packages/plugins/typescript/operations/tests/ts-documents.nullability.spec.ts @@ -62,11 +62,16 @@ const document = parse(/* GraphQL */ ` describe('TypeScript Operations Plugin - nullability', () => { it('converts semanticNonNull to nonNull when nullability.errorHandlingClient=true', async () => { - const result = await plugin(schema, [{ document }], { - nullability: { - errorHandlingClient: true, + const result = await plugin( + schema, + [{ document }], + { + nullability: { + errorHandlingClient: true, + }, }, - }); + { outputFile: '' }, + ); const formattedContent = await prettier.format(result.content, { parser: 'typescript', @@ -75,16 +80,14 @@ describe('TypeScript Operations Plugin - nullability', () => { "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never }>; export type Unnamed_1_Query = { - __typename?: "Query"; - me?: { - __typename?: "User"; + me: { field: string; fieldLevel0: string; - fieldLevel1?: string | null; + fieldLevel1: string | null; fieldBothLevels: string; list: Array; listLevel0: Array; - listLevel1?: Array | null; + listLevel1: Array | null; listBothLevels: Array; nonNullableList: Array; nonNullableListLevel0: Array; @@ -92,7 +95,7 @@ describe('TypeScript Operations Plugin - nullability', () => { nonNullableListBothLevels: Array; listWithNonNullableItem: Array; listWithNonNullableItemLevel0: Array; - listWithNonNullableItemLevel1?: Array | null; + listWithNonNullableItemLevel1: Array | null; listWithNonNullableItemBothLevels: Array; nonNullableListWithNonNullableItem: Array; nonNullableListWithNonNullableItemLevel0: Array; @@ -105,11 +108,16 @@ describe('TypeScript Operations Plugin - nullability', () => { }); it('does not convert nullability to nonNull when nullability.errorHandlingClient=false', async () => { - const result = await plugin(schema, [{ document }], { - nullability: { - errorHandlingClient: false, + const result = await plugin( + schema, + [{ document }], + { + nullability: { + errorHandlingClient: false, + }, }, - }); + { outputFile: '' }, + ); const formattedContent = await prettier.format(result.content, { parser: 'typescript', @@ -118,25 +126,23 @@ describe('TypeScript Operations Plugin - nullability', () => { "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never }>; export type Unnamed_1_Query = { - __typename?: "Query"; - me?: { - __typename?: "User"; - field?: string | null; - fieldLevel0?: string | null; - fieldLevel1?: string | null; - fieldBothLevels?: string | null; - list?: Array | null; - listLevel0?: Array | null; - listLevel1?: Array | null; - listBothLevels?: Array | null; + me: { + field: string | null; + fieldLevel0: string | null; + fieldLevel1: string | null; + fieldBothLevels: string | null; + list: Array | null; + listLevel0: Array | null; + listLevel1: Array | null; + listBothLevels: Array | null; nonNullableList: Array; nonNullableListLevel0: Array; nonNullableListLevel1: Array; nonNullableListBothLevels: Array; - listWithNonNullableItem?: Array | null; - listWithNonNullableItemLevel0?: Array | null; - listWithNonNullableItemLevel1?: Array | null; - listWithNonNullableItemBothLevels?: Array | null; + listWithNonNullableItem: Array | null; + listWithNonNullableItemLevel0: Array | null; + listWithNonNullableItemLevel1: Array | null; + listWithNonNullableItemBothLevels: Array | null; nonNullableListWithNonNullableItem: Array; nonNullableListWithNonNullableItemLevel0: Array; nonNullableListWithNonNullableItemLevel1: Array; diff --git a/packages/plugins/typescript/operations/tests/ts-documents.skip-include-directives.spec.ts b/packages/plugins/typescript/operations/tests/ts-documents.skip-include-directives.spec.ts new file mode 100644 index 00000000000..605758badf6 --- /dev/null +++ b/packages/plugins/typescript/operations/tests/ts-documents.skip-include-directives.spec.ts @@ -0,0 +1,947 @@ +import { buildSchema, parse } from 'graphql'; +import { plugin } from '../src/index.js'; +import { schema } from './shared/schema.js'; + +describe('TypeScript Operations Plugin - @include directives', () => { + it('should resolve optionals according to maybeValue', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user: User! + } + + type User { + name: String! + age: Int + address: String! + nicknames: [String!] + parents: [User!]! + } + `); + + const fragment = parse(/* GraphQL */ ` + query user($showProperty: Boolean!) { + user { + name + age + address @include(if: $showProperty) + nicknames @include(if: $showProperty) + parents @include(if: $showProperty) + } + } + `); + + const { content } = await plugin( + schema, + [{ location: '', document: fragment }], + { maybeValue: "T | 'specialType'" }, + { outputFile: 'graphql.ts' }, + ); + expect(content).toMatchInlineSnapshot(` + "export type UserQueryVariables = Exact<{ + showProperty: boolean; + }>; + + + export type UserQuery = { user: { name: string, age: number | 'specialType', address?: string, nicknames?: Array | 'specialType', parents?: Array } }; + " + `); + }); + + it('should add undefined as possible value according to allowUndefinedQueryVariables', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user: User! + } + + type User { + name: String! + age: Int + address: String! + nicknames: [String!] + parents: [User!]! + } + `); + + const fragment = parse(/* GraphQL */ ` + query user($showProperty: Boolean!) { + user { + name + age + address @include(if: $showProperty) + nicknames @include(if: $showProperty) + parents @include(if: $showProperty) + } + } + `); + + const { content } = await plugin( + schema, + [{ location: '', document: fragment }], + { allowUndefinedQueryVariables: true }, + { outputFile: 'graphql.ts' }, + ); + + expect(content).toMatchInlineSnapshot(` + "export type UserQueryVariables = Exact<{ + showProperty: boolean; + }> | undefined; + + + export type UserQuery = { user: { name: string, age: number | null, address?: string, nicknames?: Array | null, parents?: Array } }; + " + `); + }); + + it('#2506 - inline fragment without typeCondition specified', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user: User + } + + type User { + name: String + } + `); + + const fragment = parse(/* GraphQL */ ` + query user($withUser: Boolean! = false) { + ... @include(if: $withUser) { + user { + name + } + } + } + `); + + const { content } = await plugin( + schema, + [{ location: '', document: fragment }], + {}, + { outputFile: 'graphql.ts' }, + ); + + expect(content).toMatchInlineSnapshot(` + "export type UserQueryVariables = Exact<{ + withUser?: boolean; + }>; + + + export type UserQuery = + | { user?: { name: string | null } | null } + | Record + ; + " + `); + }); + + it('#10616 - @include on fragment with inlineFragmentTypes:combine should generate optional fragment', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user: User + } + + type User { + name: String + } + `); + + const document = parse(/* GraphQL */ ` + fragment Name on User { + name + } + query user($withName: Boolean! = false) { + user { + ...Name @include(if: $withName) + } + } + `); + + const { content } = await plugin( + schema, + [{ location: '', document }], + { inlineFragmentTypes: 'combine' }, + { outputFile: '' }, + ); + + expect(content).toMatchInlineSnapshot(` + "export type NameFragment = { name: string | null }; + + export type UserQueryVariables = Exact<{ + withName?: boolean; + }>; + + + export type UserQuery = { user: + | { name?: string | null } + | Record + | null }; + " + `); + }); + + it('fields with @include should pre resolve into optional', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user: User! + } + + type User { + name: String! + address: String! + nicknames: [String!] + parents: [User!]! + } + `); + + const fragment = parse(/* GraphQL */ ` + query user($showAddress: Boolean!) { + user { + name + address @include(if: $showAddress) + nicknames @include(if: $showNicknames) + parents @include(if: $showParents) + } + } + `); + + const { content } = await plugin( + schema, + [{ location: '', document: fragment }], + {}, + { outputFile: 'graphql.ts' }, + ); + + expect(content).toMatchInlineSnapshot(` + "export type UserQueryVariables = Exact<{ + showAddress: boolean; + }>; + + + export type UserQuery = { user: { name: string, address?: string, nicknames?: Array | null, parents?: Array } }; + " + `); + }); + + it('objects with @include should pre resolve into optional', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user: User! + } + + type User { + id: String! + name: String! + address: Address! + friends: [User!]! + moreFriends: [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 }], + {}, + { outputFile: 'graphql.ts' }, + ); + + expect(content).toMatchInlineSnapshot(` + "export type UserQueryVariables = Exact<{ + showAddress: boolean; + showName: boolean; + }>; + + + export type UserQuery = { user: { id: string, name?: string, address?: { city: string }, friends?: Array<{ id: string }> } }; + " + `); + }); + + it('optionals (?) on types should be avoided by default', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User! + } + + type User { + messages: [Message!]! + } + + type Message { + content: String! + } + `); + + const fragment = parse(/* GraphQL */ ` + query MyQuery($include: Boolean!) { + me { + messages @include(if: $include) { + content + } + } + } + `); + + const { content } = await plugin( + schema, + [{ location: '', document: fragment }], + { nonOptionalTypename: true }, + { outputFile: 'graphql.ts' }, + ); + + expect(content).toMatchInlineSnapshot(` + "export type MyQueryQueryVariables = Exact<{ + include: boolean; + }>; + + + export type MyQueryQuery = { __typename: 'Query', me: { __typename: 'User', messages?: Array<{ __typename: 'Message', content: string }> } }; + " + `); + }); + + it('inline fragment with conditional directives', 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 }], + {}, + { outputFile: 'graphql.ts' }, + ); + + expect(content).toMatchInlineSnapshot(` + "export type UserQueryVariables = Exact<{ + withUser?: boolean; + }>; + + + export type UserQuery = + | { user?: { name: string | null } | null, group?: { id: number } } + | Record + ; + " + `); + }); + + it('resolve optionals according to maybeValue and conditional directives', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user: User! + } + + type User { + name: String! + age: Int + address: String! + nicknames: [String!] + parents: [User!]! + } + `); + + const fragment = parse(/* GraphQL */ ` + query user($showProperty: Boolean!) { + user { + name + age + address @include(if: $showProperty) + nicknames @include(if: $showProperty) + parents @include(if: $showProperty) + } + } + `); + + const { content } = await plugin( + schema, + [{ location: '', document: fragment }], + { maybeValue: "T | 'specialType'" }, + { outputFile: 'graphql.ts' }, + ); + expect(content).toMatchInlineSnapshot(` + "export type UserQueryVariables = Exact<{ + showProperty: boolean; + }>; + + + export type UserQuery = { user: { name: string, age: number | 'specialType', address?: string, nicknames?: Array | 'specialType', parents?: Array } }; + " + `); + }); + + it('generates optional field when @include is used on an aliased field', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + users: [User!]! + } + + type User { + id: ID! + name: String! + } + `); + + const document = parse(/* GraphQL */ ` + query GetUsers($included: Boolean!) { + aliasedUsers: users @include(if: $included) { + id + userName: name @include(if: $included) + } + users { + id + userName: name @include(if: $included) + } + } + `); + + const { content } = await plugin( + schema, + [{ location: '', document }], + {}, + { outputFile: 'graphql.ts' }, + ); + + expect(content).toMatchInlineSnapshot(` + "export type GetUsersQueryVariables = Exact<{ + included: boolean; + }>; + + + export type GetUsersQuery = { aliasedUsers?: Array<{ id: string, userName?: string }>, users: Array<{ id: string, userName?: string }> }; + " + `); + }); + + it('generates optional object when @include is used on an inline fragment', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user: User + users: [User!]! + } + + type User { + id: ID! + name: String! + nickName: String! + age: Int! + createdAt: String! + } + `); + + const document = parse(/* GraphQL */ ` + query User($included: Boolean!) { + user { + id + ... @include(if: $included) { + name + niName: nickName + } + ... on User @include(if: $included) { + age + } + ... { + createdAt + } + } + } + query GetUsers($included: Boolean!) { + users { + id + ... @include(if: $included) { + name + niName: nickName + } + ... on User @include(if: $included) { + age + } + } + } + `); + + const { content } = await plugin( + schema, + [{ location: '', document }], + {}, + { outputFile: 'graphql.ts' }, + ); + + expect(content).toMatchInlineSnapshot(` + "export type UserQueryVariables = Exact<{ + included: boolean; + }>; + + + export type UserQuery = { user: { createdAt: string, id: string } & { name?: string, niName?: string } & { age?: number } | null }; + + export type GetUsersQueryVariables = Exact<{ + included: boolean; + }>; + + + export type GetUsersQuery = { users: Array<{ id: string } & { name?: string, niName?: string } & { age?: number }> }; + " + `); + }); + + it('generates optional object when @include is used on a fragment spread', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user: User + users: [User!]! + } + + type User { + id: ID! + name: String! + nickName: String! + age: Int! + createdAt: String! + } + `); + + const document = parse(/* GraphQL */ ` + query User($included: Boolean!) { + user { + id + ...User_Name @include(if: $included) + ...User_Age @include + ...User_CreatedAt # This is not conditional, so it should be merged with base selection set that includes the id field + } + } + query GetUsers($included: Boolean!) { + users { + id + ...User_Name @include(if: $included) + ...User_Age @include(if: $included) + ...User_CreatedAt + } + } + + fragment User_Name on User { + name + niName: nickName + } + + fragment User_Age on User { + age + } + + fragment User_CreatedAt on User { + createdAt + } + `); + + const { content } = await plugin( + schema, + [{ location: '', document }], + {}, + { outputFile: 'graphql.ts' }, + ); + + expect(content).toMatchInlineSnapshot(` + "export type UserQueryVariables = Exact<{ + included: boolean; + }>; + + + export type UserQuery = { user: { id: string, createdAt: string } & { name?: string, niName?: string } & { age?: number } | null }; + + export type GetUsersQueryVariables = Exact<{ + included: boolean; + }>; + + + export type GetUsersQuery = { users: Array<{ id: string, createdAt: string } & { name?: string, niName?: string } & { age?: number }> }; + + export type User_NameFragment = { name: string, niName: string }; + + export type User_AgeFragment = { age: number }; + + export type User_CreatedAtFragment = { createdAt: string }; + " + `); + }); +}); + +describe('TypeScript Operations Plugin - @skip directive', () => { + it('#8461 - conditional directives are ignored on fields with alias', async () => { + const testSchema = buildSchema(/* GraphQL */ ` + type User { + firstName: String! + lastName: Int! + address: Address! + } + + type Address { + postalCode: String! + } + + type Query { + viewer: User! + } + `); + + const query = parse(/* GraphQL */ ` + query UserQuery($skipFirstName: Boolean!, $skipAddress: Boolean!) { + viewer { + givenName: firstName @skip(if: $skipFirstName) + lastName + mailingAddress: address @skip(if: $skipAddress) { + postalCode + } + } + } + `); + + const { content } = await plugin( + testSchema, + [{ location: '', document: query }], + {}, + { outputFile: 'graphql.ts' }, + ); + + expect(content).toMatchInlineSnapshot(` + "export type UserQueryQueryVariables = Exact<{ + skipFirstName: boolean; + skipAddress: boolean; + }>; + + + export type UserQueryQuery = { viewer: { lastName: number, givenName?: string, mailingAddress?: { postalCode: string } } }; + " + `); + }); + + it('should include fragment variable definitions when experimentalFragmentVariables is set', async () => { + const ast = parse( + /* GraphQL */ ` + fragment TextNotificationFragment($skip: Boolean!) on TextNotification { + text @skip(if: $skip) + } + `, + // < v15 compatibility + { experimentalFragmentVariables: true, allowLegacyFragmentVariables: true } as any, + ); + const config = { experimentalFragmentVariables: true }; + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + config, + { + outputFile: '', + }, + ); + expect(content).toMatchInlineSnapshot(` + "export type TextNotificationFragmentFragment = { text?: string }; + + + export type TextNotificationFragmentFragmentVariables = Exact<{ + skip: boolean; + }>; + " + `); + }); + + it('generates optional field when @skip is used on an aliased field', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + users: [User!]! + } + + type User { + id: ID! + name: String! + } + `); + + const document = parse(/* GraphQL */ ` + query GetUsers($skipName: Boolean!) { + users { + id + userName: name @skip(if: $skipName) + } + } + `); + + const { content } = await plugin( + schema, + [{ location: '', document }], + {}, + { outputFile: 'graphql.ts' }, + ); + + expect(content).toMatchInlineSnapshot(` + "export type GetUsersQueryVariables = Exact<{ + skipName: boolean; + }>; + + + export type GetUsersQuery = { users: Array<{ id: string, userName?: string }> }; + " + `); + }); + + it('generates optional object when @skip is used on an inline fragment', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user: User + users: [User!]! + } + + type User { + id: ID! + name: String! + nickName: String! + age: Int! + createdAt: String! + } + `); + + const document = parse(/* GraphQL */ ` + query User($skip: Boolean!) { + user { + id + ... @skip(if: $skip) { + name + niName: nickName + } + ... on User @skip(if: $included) { + age + } + ... { + createdAt + } + } + } + query GetUsers($skip: Boolean!) { + users { + id + ... @skip(if: $skip) { + name + niName: nickName + } + ... on User @skip(if: $skip) { + age + } + } + } + `); + + const { content } = await plugin( + schema, + [{ location: '', document }], + {}, + { outputFile: 'graphql.ts' }, + ); + + expect(content).toMatchInlineSnapshot(` + "export type UserQueryVariables = Exact<{ + skip: boolean; + }>; + + + export type UserQuery = { user: { createdAt: string, id: string } & { name?: string, niName?: string } & { age?: number } | null }; + + export type GetUsersQueryVariables = Exact<{ + skip: boolean; + }>; + + + export type GetUsersQuery = { users: Array<{ id: string } & { name?: string, niName?: string } & { age?: number }> }; + " + `); + }); + + it('generates optional object when @skip is used on a fragment spread', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user: User + users: [User!]! + } + + type User { + id: ID! + name: String! + nickName: String! + age: Int! + createdAt: String! + } + `); + + const document = parse(/* GraphQL */ ` + query User($skip: Boolean!) { + user { + id + ...User_Name @skip(if: $skip) + ...User_Age @skip + ...User_CreatedAt # This is not conditional, so it should be merged with base selection set that includes the id field + } + } + query GetUsers($skip: Boolean!) { + users { + id + ...User_Name @skip(if: $skip) + ...User_Age @skip(if: $skip) + ...User_CreatedAt + } + } + + fragment User_Name on User { + name + niName: nickName + } + + fragment User_Age on User { + age + } + + fragment User_CreatedAt on User { + createdAt + } + `); + + const { content } = await plugin( + schema, + [{ location: '', document }], + {}, + { outputFile: 'graphql.ts' }, + ); + + expect(content).toMatchInlineSnapshot(` + "export type UserQueryVariables = Exact<{ + skip: boolean; + }>; + + + export type UserQuery = { user: { id: string, createdAt: string } & { name?: string, niName?: string } & { age?: number } | null }; + + export type GetUsersQueryVariables = Exact<{ + skip: boolean; + }>; + + + export type GetUsersQuery = { users: Array<{ id: string, createdAt: string } & { name?: string, niName?: string } & { age?: number }> }; + + export type User_NameFragment = { name: string, niName: string }; + + export type User_AgeFragment = { age: number }; + + export type User_CreatedAtFragment = { createdAt: string }; + " + `); + }); +}); + +describe('TypeScript Operations Plugin - @include and @skip with @defer', () => { + it('generates conditional object with defer fields when @skip and @include are used with defer', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user: User + users: [User!]! + } + + type User { + id: ID! + name: String! + nickName: String! + age: Int! + createdAt: String! + } + `); + + const document = parse(/* GraphQL */ ` + query UserSkip { + user { + id + ...User_Name @skip + ...User_Age @skip @defer + } + } + + query UserInclude { + user { + id + ...User_Name @include + ...User_Age @include @defer + } + } + + fragment User_Name on User { + name + niName: nickName + } + + fragment User_Age on User { + age + createdAt + } + `); + + const { content } = await plugin( + schema, + [{ location: '', document }], + {}, + { outputFile: 'graphql.ts' }, + ); + + expect(content).toMatchInlineSnapshot(` + "export type UserSkipQueryVariables = Exact<{ [key: string]: never; }>; + + + export type UserSkipQuery = { user: { id: string } & { name?: string, niName?: string } & { age?: number, createdAt?: string } & ({ age: number, createdAt: string } | { age?: never, createdAt?: never }) | null }; + + export type UserIncludeQueryVariables = Exact<{ [key: string]: never; }>; + + + export type UserIncludeQuery = { user: { id: string } & { name?: string, niName?: string } & { age?: number, createdAt?: string } & ({ age: number, createdAt: string } | { age?: never, createdAt?: never }) | null }; + + export type User_NameFragment = { name: string, niName: string }; + + export type User_AgeFragment = { age: number, createdAt: string }; + " + `); + }); +}); diff --git a/packages/plugins/typescript/operations/tests/ts-documents.spec.ts b/packages/plugins/typescript/operations/tests/ts-documents.spec.ts index 44358de8683..2708dec92c1 100644 --- a/packages/plugins/typescript/operations/tests/ts-documents.spec.ts +++ b/packages/plugins/typescript/operations/tests/ts-documents.spec.ts @@ -1,25 +1,14 @@ import { buildClientSchema, buildSchema, parse } from 'graphql'; import { mergeOutputs, Types } from '@graphql-codegen/plugin-helpers'; import { validateTs } from '@graphql-codegen/testing'; -import { plugin as tsPlugin } from '../../typescript/src/index.js'; import { plugin } from '../src/index.js'; import { schema } from './shared/schema.js'; describe('TypeScript Operations Plugin', () => { const gitHuntSchema = buildClientSchema(require('../../../../../dev-test/githunt/schema.json')); - const validate = async ( - content: Types.PluginOutput, - config: any = {}, - pluginSchema = schema, - usage = '', - suspenseErrors = [], - ) => { - const m = mergeOutputs([ - await tsPlugin(pluginSchema, [], config, { outputFile: '' }), - content, - usage, - ]); + const validate = async (content: Types.PluginOutput, usage = '', suspenseErrors = []) => { + const m = mergeOutputs([content, usage]); validateTs(m, undefined, undefined, undefined, suspenseErrors); return m; @@ -45,72 +34,15 @@ describe('TypeScript Operations Plugin', () => { } } `); - const config = { noExport: true, preResolveTypes: false }; const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + { noExport: true }, + { outputFile: '' }, ); expect(content).not.toContain('export'); - await validate(content, config); - }); - - 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).toBeSimilarStringTo(` - export type NotificationsQuery = ( - { __typename?: 'Query' } - & { notifications: Array<( - { __typename?: 'TextNotification' } - & Pick - & { textAlias: Types.TextNotification['text'] } - ) | ( - { __typename?: 'ImageNotification' } - & Pick - & { metadata: ( - { __typename?: 'ImageMetadata' } - & { created: Types.ImageMetadata['createdBy'] } - ) } - )> } - ); - `); - await validate(content, config, schema, '', [`Cannot find namespace 'Types'.`]); + await validate(content); }); it('Can merge an inline fragment with a spread', async () => { @@ -160,62 +92,20 @@ describe('TypeScript Operations Plugin', () => { testSchema, [{ location: 'test-file.ts', document: ast }], {}, - { - outputFile: '', - }, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type PostFragment = { __typename?: 'Post', id: string, comments: Array<{ __typename?: 'TextComment', text: string } | { __typename?: 'ImageComment' }> }; - - export type PostPlusFragment = { __typename?: 'Post', id: string, comments: Array<{ __typename?: 'TextComment', text: string, id: string } | { __typename?: 'ImageComment', id: string }> }; - `); - }); - - it('Should handle "namespacedImportName" and "preResolveTypes" together', async () => { - const testSchema = buildSchema(/* GraphQL */ ` - type Query { - f: E - user: User! - } - - enum E { - A - B - } - - scalar JSON + expect(content).toMatchInlineSnapshot(` + "export type PostFragment = { id: string, comments: Array< + | { text: string } + | Record + > }; - type User { - id: ID! - f: E - j: JSON - } - `); - const ast = parse(/* GraphQL */ ` - query test { - f - user { - id - f - j - } - } + export type PostPlusFragment = { id: string, comments: Array< + | { text: string, id: string } + | { id: string } + > }; + " `); - const config = { namespacedImportName: 'Types', preResolveTypes: true }; - const { content } = await plugin( - testSchema, - [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, - ); - - expect(content).toBeSimilarStringTo( - `export type TestQuery = { __typename?: 'Query', f?: Types.E | null, user: { __typename?: 'User', id: string, f?: Types.E | null, j?: any | null } };`, - ); - - await validate(content, config, schema, '', [`Cannot find namespace 'Types'.`]); }); it('Should generate the correct output when using immutableTypes config', async () => { @@ -237,186 +127,28 @@ 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: '', - }, - ); - - expect(content).toBeSimilarStringTo(` - export type notificationsquery = ( - { readonly __typename?: 'Query' } - & { readonly notifications: ReadonlyArray<( - { readonly __typename?: 'TextNotification' } - & Pick - ) | ( - { readonly __typename?: 'ImageNotification' } - & Pick - & { readonly metadata: ( - { readonly __typename?: 'ImageMetadata' } - & Pick - ) } - )> } - ); - `); - await validate(content, config); - }); - it('should include fragment variable definitions when experimentalFragmentVariables is set', async () => { - const ast = parse( - /* GraphQL */ ` - fragment TextNotificationFragment($skip: Boolean!) on TextNotification { - text @skip(if: $skip) - } - `, - // < v15 compatibility - { - experimentalFragmentVariables: true, - allowLegacyFragmentVariables: true, - } as any, - ); - const config = { experimentalFragmentVariables: true }; const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, - ); - expect(content).toMatchSnapshot(); - }); - - it('should resolve optionals according to maybeValue', async () => { - const schema = buildSchema(/* GraphQL */ ` - type Query { - user: User! - } - - type User { - name: String! - age: Int - address: String! - nicknames: [String!] - parents: [User!]! - } - `); - - const fragment = parse(/* GraphQL */ ` - query user($showProperty: Boolean!) { - user { - name - age - address @include(if: $showProperty) - nicknames @include(if: $showProperty) - parents @include(if: $showProperty) - } - } - `); - - const { content } = await plugin( - schema, - [{ location: '', document: fragment }], - { - preResolveTypes: true, - maybeValue: "T | 'specialType'", - }, - { - outputFile: 'graphql.ts', - }, - ); - expect(content).toBeSimilarStringTo(` - export type UserQuery = { __typename?: 'Query', user: { __typename?: 'User', name: string, age?: number | 'specialType', address?: string, nicknames?: Array | 'specialType', parents?: Array } }; - `); - }); - - it('should add undefined as possible value according to allowUndefinedQueryVariables', async () => { - const schema = buildSchema(/* GraphQL */ ` - type Query { - user: User! - } - - type User { - name: String! - age: Int - address: String! - nicknames: [String!] - parents: [User!]! - } - `); - - const fragment = parse(/* GraphQL */ ` - query user($showProperty: Boolean!) { - user { - name - age - address @include(if: $showProperty) - nicknames @include(if: $showProperty) - parents @include(if: $showProperty) - } - } - `); - - const { content } = await plugin( - schema, - [{ location: '', document: fragment }], { - preResolveTypes: true, - allowUndefinedQueryVariables: true, - }, - { - outputFile: 'graphql.ts', + namingConvention: 'change-case-all#lowerCase', + immutableTypes: true, }, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type UserQueryVariables = Exact<{ - showProperty: Scalars['Boolean']['input']; - }> | undefined; - `); - }); - }); + expect(content).toMatchInlineSnapshot(` + "export type notificationsqueryvariables = Exact<{ [key: string]: never; }>; - 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 - } - } + export type notificationsquery = { readonly notifications: ReadonlyArray< + | { readonly text: string, readonly id: string } + | { readonly imageUrl: string, readonly id: string, readonly metadata: { readonly createdBy: string } } + > }; + " `); - const config = { preResolveTypes: false }; - const { content } = await plugin( - testSchema, - [{ location: 'test-file.ts', document: doc }], - config, - { - outputFile: '', - }, - ); - expect(content).toContain(`Pick`); - await validate(content, config, testSchema); + await validate(content); }); }); @@ -440,40 +172,39 @@ describe('TypeScript Operations Plugin', () => { } } `); - const config = { - operationResultSuffix: 'Result', - preResolveTypes: false, - }; + const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + { operationResultSuffix: 'Result' }, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo( - `export type NotificationsQueryVariables = Exact<{ [key: string]: never; }>;`, + expect(content).toMatchInlineSnapshot( + ` + "export type NotificationsQueryVariables = Exact<{ [key: string]: never; }>; + + + export type NotificationsQueryResult = { notifications: Array< + | { text: string, id: string } + | { imageUrl: string, id: string, metadata: { createdBy: string } } + > }; + " + `, ); - expect(content).toBeSimilarStringTo(` - export type NotificationsQueryResult = ( - { __typename?: 'Query' } - & { notifications: Array<( - { __typename?: 'TextNotification' } - & Pick - ) | ( - { __typename?: 'ImageNotification' } - & Pick - & { metadata: ( - { __typename?: 'ImageMetadata' } - & Pick - ) } - )> } - ); + + expect(content).toMatchInlineSnapshot(` + "export type NotificationsQueryVariables = Exact<{ [key: string]: never; }>; + + + export type NotificationsQueryResult = { notifications: Array< + | { text: string, id: string } + | { imageUrl: string, id: string, metadata: { createdBy: string } } + > }; + " `); - await validate(content, config); + await validate(content); }); }); @@ -497,36 +228,25 @@ 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: '', - }, + { namingConvention: 'change-case-all#lowerCase' }, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type notificationsquery = ( - { __typename?: 'Query' } - & { notifications: Array<( - { __typename?: 'TextNotification' } - & Pick - ) | ( - { __typename?: 'ImageNotification' } - & Pick - & { metadata: ( - { __typename?: 'ImageMetadata' } - & Pick - ) } - )> } - ); + expect(content).toMatchInlineSnapshot(` + "export type notificationsqueryvariables = Exact<{ [key: string]: never; }>; + + + export type notificationsquery = { notifications: Array< + | { text: string, id: string } + | { imageUrl: string, id: string, metadata: { createdBy: string } } + > }; + " `); - await validate(content, config); + await validate(content); }); it('Should allow custom naming and point to the correct type - with custom prefix', async () => { @@ -549,40 +269,27 @@ 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: '', - }, + { typesPrefix: 'i', namingConvention: 'change-case-all#lowerCase' }, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo( - `export type inotificationsqueryvariables = Exact<{ [key: string]: never; }>;`, + expect(content).toMatchInlineSnapshot( + ` + "export type inotificationsqueryvariables = Exact<{ [key: string]: never; }>; + + + export type inotificationsquery = { notifications: Array< + | { text: string, id: string } + | { imageUrl: string, id: string, metadata: { createdBy: string } } + > }; + " + `, ); - expect(content).toBeSimilarStringTo(` - export type inotificationsquery = ( - { __typename?: 'Query' } - & { notifications: Array<( - { __typename?: 'TextNotification' } - & Pick - ) | ( - { __typename?: 'ImageNotification' } - & Pick - & { metadata: ( - { __typename?: 'ImageMetadata' } - & Pick - ) } - )> } - ); - `); - await validate(content, config); + + await validate(content); }); it('Test for dedupeOperationSuffix', async () => { @@ -709,33 +416,24 @@ describe('TypeScript Operations Plugin', () => { await plugin( schema, [{ location: 'test-file.ts', document: ast3 }], - { dedupeOperationSuffix: true, preResolveTypes: false }, + { dedupeOperationSuffix: true }, { outputFile: '' }, ) ).content; - expect(withUsage).toBeSimilarStringTo(` - export type MyFragment = ( - { __typename?: 'Query' } - & { notifications: Array<( - { __typename?: 'TextNotification' } - & Pick - ) | ( - { __typename?: 'ImageNotification' } - & Pick - )> } - ); - `); - expect(withUsage).toBeSimilarStringTo(` - export type NotificationsQuery = ( - { __typename?: 'Query' } - & { notifications: Array<( - { __typename?: 'TextNotification' } - & Pick - ) | ( - { __typename?: 'ImageNotification' } - & Pick - )> } - ); + expect(withUsage).toMatchInlineSnapshot(` + "export type NotificationsQueryVariables = Exact<{ [key: string]: never; }>; + + + export type NotificationsQuery = { notifications: Array< + | { id: string } + | { id: string } + > }; + + export type MyFragment = { notifications: Array< + | { id: string } + | { id: string } + > }; + " `); }); }); @@ -780,31 +478,19 @@ 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, @@ -814,7 +500,7 @@ describe('TypeScript Operations Plugin', () => { await plugin( schema, [{ location: 'test-file.ts', document: ast }], - { omitOperationSuffix: true, preResolveTypes: false }, + { omitOperationSuffix: true }, { outputFile: '' }, ) ).content, @@ -824,7 +510,7 @@ describe('TypeScript Operations Plugin', () => { await plugin( schema, [{ location: 'test-file.ts', document: ast2 }], - { omitOperationSuffix: true, preResolveTypes: false }, + { omitOperationSuffix: true }, { outputFile: '' }, ) ).content, @@ -834,7 +520,7 @@ describe('TypeScript Operations Plugin', () => { await plugin( schema, [{ location: 'test-file.ts', document: ast2 }], - { omitOperationSuffix: true, preResolveTypes: false }, + { omitOperationSuffix: true }, { outputFile: '' }, ) ).content, @@ -844,7 +530,7 @@ describe('TypeScript Operations Plugin', () => { await plugin( schema, [{ location: 'test-file.ts', document: ast2 }], - { omitOperationSuffix: false, preResolveTypes: false }, + { omitOperationSuffix: false }, { outputFile: '' }, ) ).content, @@ -854,7 +540,7 @@ describe('TypeScript Operations Plugin', () => { await plugin( schema, [{ location: 'test-file.ts', document: ast2 }], - { omitOperationSuffix: false, preResolveTypes: false }, + { omitOperationSuffix: false }, { outputFile: '' }, ) ).content, @@ -864,33 +550,24 @@ describe('TypeScript Operations Plugin', () => { await plugin( schema, [{ location: 'test-file.ts', document: ast3 }], - { omitOperationSuffix: true, preResolveTypes: false }, + { omitOperationSuffix: true }, { outputFile: '' }, ) ).content; - expect(withUsage).toBeSimilarStringTo(` - export type My = ( - { __typename?: 'Query' } - & { notifications: Array<( - { __typename?: 'TextNotification' } - & Pick - ) | ( - { __typename?: 'ImageNotification' } - & Pick - )> } - ); - `); - expect(withUsage).toBeSimilarStringTo(` - export type Notifications = ( - { __typename?: 'Query' } - & { notifications: Array<( - { __typename?: 'TextNotification' } - & Pick - ) | ( - { __typename?: 'ImageNotification' } - & Pick - )> } - ); + expect(withUsage).toMatchInlineSnapshot(` + "export type NotificationsVariables = Exact<{ [key: string]: never; }>; + + + export type Notifications = { notifications: Array< + | { id: string } + | { id: string } + > }; + + export type My = { notifications: Array< + | { id: string } + | { id: string } + > }; + " `); }); @@ -912,26 +589,24 @@ describe('TypeScript Operations Plugin', () => { } } `); - const config = { - skipTypeNameForRoot: true, - preResolveTypes: false, - }; + const { content } = await plugin( testSchema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + { skipTypeNameForRoot: true }, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo( - `export type Q1Query = { test?: Maybe<( - { __typename?: 'Test' } - & Pick - )> };`, + expect(content).toMatchInlineSnapshot( + ` + "export type Q1QueryVariables = Exact<{ [key: string]: never; }>; + + + export type Q1Query = { test: { foo: string | null } | null }; + " + `, ); - await validate(content, config, testSchema); + await validate(content); }); it('Should ignore __typename for root types with skipTypeNameForRoot = true, and with nonOptionalTypename = true', async () => { @@ -951,28 +626,28 @@ 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: '', + nonOptionalTypename: true, + skipTypeNameForRoot: true, }, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo( - `export type Q1Query = { test?: Maybe<( - { __typename: 'Test' } - & Pick - )> };`, - ); - await validate(content, config, testSchema); - }); + expect(content).toMatchInlineSnapshot( + ` + "export type Q1QueryVariables = Exact<{ [key: string]: never; }>; + + + export type Q1Query = { test: { __typename: 'Test', foo: string | null } | null }; + " + `, + ); + await validate(content); + }); it('Should ignore skipTypeNameForRoot = true when __typename is specified manually', async () => { const testSchema = buildSchema(/* GraphQL */ ` @@ -992,33 +667,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: '', + nonOptionalTypename: true, + skipTypeNameForRoot: true, }, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo( - `export type Q1Query = ( - { __typename: 'Query' } - & { test?: Maybe<( - { __typename: 'Test' } - & Pick - )> } - );`, + expect(content).toMatchInlineSnapshot( + ` + "export type Q1QueryVariables = Exact<{ [key: string]: never; }>; + + + export type Q1Query = { __typename: 'Query', test: { __typename: 'Test', foo: string | null } | null }; + " + `, ); - await validate(content, config, testSchema); + 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 and explicit field', async () => { const testSchema = buildSchema(/* GraphQL */ ` type Search { search: [SearchResult!]! @@ -1069,17 +741,12 @@ describe('TypeScript Operations Plugin', () => { } } `); - const config = { - nonOptionalTypename: false, - skipTypename: true, - }; + const { content } = await plugin( testSchema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + { nonOptionalTypename: false }, + { outputFile: '' }, ); expect(content).toContain( @@ -1096,27 +763,7 @@ export type Q2Query = { search: Array< | { __typename: 'Person', id: string, name: string } > };`, ); - await validate(content, config, testSchema); - }); - - it('Should skip __typename when skipTypename is set to true', async () => { - const ast = parse(/* GraphQL */ ` - query { - dummy - } - `); - const config = { skipTypename: true, preResolveTypes: false }; - const { content } = await plugin( - schema, - [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, - ); - - expect(content).not.toContain(`__typename`); - await validate(content, config); + await validate(content); }); it('Should add __typename when dealing with fragments', async () => { @@ -1151,28 +798,33 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; + const { content } = await plugin( testSchema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, - ); - expect(content).toBeSimilarStringTo(` - export type TestQuery = ( - { __typename?: 'Query' } - & { some?: Maybe<( - { __typename: 'A' } - & Pick - ) | ( - { __typename: 'B' } - & Pick - )> } + {}, + { outputFile: '' }, ); + expect(content).toMatchInlineSnapshot(` + "type Node_A_Fragment = { __typename: 'A', id: string }; + + type Node_B_Fragment = { __typename: 'B', id: string }; + + export type NodeFragment = + | Node_A_Fragment + | Node_B_Fragment + ; + + export type TestQueryVariables = Exact<{ [key: string]: never; }>; + + + export type TestQuery = { some: + | { __typename: 'A', id: string } + | { __typename: 'B', id: string } + | null }; + " `); - await validate(content, config, testSchema); + await validate(content); }); it('Should add aliased __typename correctly', async () => { @@ -1182,45 +834,21 @@ 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).toBeSimilarStringTo(` - export type Unnamed_1_Query = ( - { __typename?: 'Query' } - & Pick - & { type: 'Query' } - ); - `); - await validate(content, config); - }); - 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: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type Unnamed_1_Query = { __typename?: 'Query', dummy?: string | null, type: 'Query' }; + expect(content).toMatchInlineSnapshot(` + "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; + + + export type Unnamed_1_Query = { dummy: string | null, type: 'Query' }; + " `); - await validate(content, config); + await validate(content); }); it('Should add __typename as non-optional when explicitly specified', async () => { @@ -1230,22 +858,21 @@ export type Q2Query = { search: Array< dummy } `); - const config = { preResolveTypes: false }; + const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type Unnamed_1_Query = ( - { __typename: 'Query' } - & Pick - ); + expect(content).toMatchInlineSnapshot(` + "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; + + + export type Unnamed_1_Query = { __typename: 'Query', dummy: string | null }; + " `); - await validate(content, config); + await validate(content); }); it('Should add __typename as non-optional when forced', async () => { @@ -1254,75 +881,24 @@ 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).toBeSimilarStringTo(` - export type Unnamed_1_Query = ( - { __typename: 'Query' } - & Pick - ); - `); - await validate(content, config); - }); - 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: '', - }, + { nonOptionalTypename: true }, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type Unnamed_1_Query = ( - { __typename?: 'Query' } - & Pick - ); - `); - await validate(content, config); - }); + expect(content).toMatchInlineSnapshot(` + "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - it('Should add __typename as non-optional when its explictly specified, even if skipTypename is true', async () => { - const ast = parse(/* GraphQL */ ` - query { - __typename - dummy - } - `); - const config = { skipTypename: true, preResolveTypes: false }; - const { content } = await plugin( - schema, - [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, - ); - expect(content).toBeSimilarStringTo(` - export type Unnamed_1_Query = ( - { __typename: 'Query' } - & Pick - ); + export type Unnamed_1_Query = { __typename: 'Query', dummy: string | null }; + " `); - await validate(content, config); + 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 { @@ -1336,31 +912,27 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; + const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + { nonOptionalTypename: true }, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type UnionTestQuery = ( - { __typename?: 'Query' } - & { unionTest?: Maybe<( - { __typename?: 'User' } - & Pick - ) | ( - { __typename?: 'Profile' } - & Pick - )> } - ); + expect(content).toMatchInlineSnapshot(` + "export type UnionTestQueryVariables = Exact<{ [key: string]: never; }>; + + + export type UnionTestQuery = { __typename: 'Query', unionTest: + | { __typename: 'User', id: string } + | { __typename: 'Profile', age: number | null } + | null }; + " `); - await validate(content, config); + 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 { @@ -1379,32 +951,24 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; + const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + { nonOptionalTypename: true }, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type NotificationsQuery = ( - { __typename?: 'Query' } - & { notifications: Array<( - { __typename?: 'TextNotification' } - & Pick - ) | ( - { __typename?: 'ImageNotification' } - & Pick - & { metadata: ( - { __typename?: 'ImageMetadata' } - & Pick - ) } - )> } - ); + expect(content).toMatchInlineSnapshot(` + "export type NotificationsQueryVariables = Exact<{ [key: string]: never; }>; + + + export type NotificationsQuery = { __typename: 'Query', notifications: Array< + | { __typename: 'TextNotification', text: string, id: string } + | { __typename: 'ImageNotification', imageUrl: string, id: string, metadata: { __typename: 'ImageMetadata', createdBy: string } } + > }; + " `); - await validate(content, config); + await validate(content); }); it('should mark __typename as non optional in case it is included in the selection set of an interface field', async () => { const ast = parse(/* GraphQL */ ` @@ -1420,28 +984,24 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; + const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type NotificationsQuery = ( - { __typename?: 'Query' } - & { notifications: Array<( - { __typename: 'TextNotification' } - & Pick - ) | ( - { __typename: 'ImageNotification' } - & Pick - )> } - ); + expect(content).toMatchInlineSnapshot(` + "export type NotificationsQueryVariables = Exact<{ [key: string]: never; }>; + + + export type NotificationsQuery = { notifications: Array< + | { __typename: 'TextNotification', text: string } + | { __typename: 'ImageNotification', imageUrl: string } + > }; + " `); - await validate(content, config); + await validate(content); }); it('should mark __typename as non optional in case it is included in the selection set of an union field', async () => { const ast = parse(/* GraphQL */ ` @@ -1457,27 +1017,24 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; + const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - { __typename?: 'Query' } - & { unionTest?: Maybe<( - { __typename: 'User' } - & Pick - ) | ( - { __typename: 'Profile' } - & Pick - )> } - ); + expect(content).toMatchInlineSnapshot(` + "export type UnionTestQueryVariables = Exact<{ [key: string]: never; }>; + + + export type UnionTestQuery = { unionTest: + | { __typename: 'User', email: string } + | { __typename: 'Profile', firstName: string } + | null }; + " `); - await validate(content, config); + await validate(content); }); }); @@ -1488,22 +1045,28 @@ 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: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type Unnamed_1_Query = Pick; + expect(content).toMatchInlineSnapshot(` + "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; + + + export type Unnamed_1_Query = { dummy: string | null }; + " `); - expect(content).toBeSimilarStringTo(` - export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; + expect(content).toMatchInlineSnapshot(` + "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; + + + export type Unnamed_1_Query = { dummy: string | null }; + " `); - await validate(content, config); + await validate(content); }); it('Should handle unnamed documents correctly with multiple documents', async () => { @@ -1516,29 +1079,63 @@ 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: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type Unnamed_1_Query = Pick; + expect(content).toMatchInlineSnapshot(` + "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; + + + export type Unnamed_1_Query = { dummy: string | null }; + + export type Unnamed_2_QueryVariables = Exact<{ [key: string]: never; }>; + + + export type Unnamed_2_Query = { dummy: string | null }; + " `); - expect(content).toBeSimilarStringTo(` - export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; + expect(content).toMatchInlineSnapshot(` + "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; + + + export type Unnamed_1_Query = { dummy: string | null }; + + export type Unnamed_2_QueryVariables = Exact<{ [key: string]: never; }>; + + + export type Unnamed_2_Query = { dummy: string | null }; + " `); - expect(content).toBeSimilarStringTo(` - export type Unnamed_2_Query = Pick; + expect(content).toMatchInlineSnapshot(` + "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; + + + export type Unnamed_1_Query = { dummy: string | null }; + + export type Unnamed_2_QueryVariables = Exact<{ [key: string]: never; }>; + + + export type Unnamed_2_Query = { dummy: string | null }; + " `); - expect(content).toBeSimilarStringTo(` + expect(content).toMatchInlineSnapshot(` + "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; + + + export type Unnamed_1_Query = { dummy: string | null }; + export type Unnamed_2_QueryVariables = Exact<{ [key: string]: never; }>; + + + export type Unnamed_2_Query = { dummy: string | null }; + " `); - await validate(content, config); + await validate(content); }); }); @@ -1549,7 +1146,6 @@ export type Q2Query = { search: Array< test } `); - const config = { preResolveTypes: false }; try { await plugin( @@ -1559,7 +1155,7 @@ export type Q2Query = { search: Array< } `), [{ location: 'test-file.ts', document: ast }], - config, + {}, { outputFile: '' }, ); expect(true).toBeFalsy(); @@ -1608,14 +1204,12 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; + const { content } = await plugin( testSchema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); const usage = ` @@ -1630,7 +1224,7 @@ export type Q2Query = { search: Array< } `; - await validate(content, config, testSchema, usage); + await validate(content, usage); expect(mergeOutputs([content])).toMatchSnapshot(); }); @@ -1655,16 +1249,14 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; + const { content } = await plugin( testSchema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - await validate(content, config, testSchema); + await validate(content); expect(mergeOutputs([content])).toMatchSnapshot(); }); @@ -1693,16 +1285,14 @@ export type Q2Query = { search: Array< name } `); - const config = { preResolveTypes: false }; + const { content } = await plugin( testSchema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - await validate(content, config, testSchema); + await validate(content); expect(mergeOutputs([content])).toMatchSnapshot(); }); @@ -1729,16 +1319,14 @@ export type Q2Query = { search: Array< name } `); - const config = { preResolveTypes: false }; + const { content } = await plugin( testSchema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - await validate(content, config, testSchema); + await validate(content); expect(mergeOutputs([content])).toMatchSnapshot(); }); @@ -1768,19 +1356,15 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; + const { content } = await plugin( testSchema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); await validate( content, - config, - testSchema, `function test(q: AaaQuery) { console.log(q.user.__typename === 'User' ? q.user.id : null); console.log(q.user.__typename === 'Error' ? q.user.__typename : null); @@ -1831,20 +1415,16 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; + const { content } = await plugin( testSchema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); await validate( content, - config, - testSchema, ` function test(a: UserFragment) { if (a.__typename === 'Tom') { @@ -1899,14 +1479,12 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; + const { content } = await plugin( testSchema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); const usage = ` @@ -1921,7 +1499,7 @@ export type Q2Query = { search: Array< } `; - await validate(content, config, testSchema, usage); + await validate(content, usage); expect(mergeOutputs([content])).toMatchSnapshot(); }); @@ -1942,22 +1520,27 @@ export type Q2Query = { search: Array< } } `); - const config = { skipTypename: true, preResolveTypes: false }; + const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type MeQuery = { me?: Maybe<( - Pick - & { profile?: Maybe> } - )> }; + expect(content).toMatchInlineSnapshot(` + "export type Role = + | 'USER' + | 'ADMIN'; + + 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: { id: string, username: string, role: Role | null, profile: { age: number | null } | null } | null }; + " `); - await validate(content, config); + await validate(content); }); it('Should support fragment spread correctly with simple type with other fields', async () => { @@ -1976,23 +1559,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: '', - }, - ); + {}, + { outputFile: '' }, + ); + + expect(content).toMatchInlineSnapshot(` + "export type UserFieldsFragment = { id: string, profile: { age: number | null } | null }; + + export type MeQueryVariables = Exact<{ [key: string]: never; }>; - expect(content).toBeSimilarStringTo(` - 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, config); + await validate(content); }); it('Should support fragment spread correctly with multiple fragment spread', async () => { @@ -2015,45 +1599,26 @@ export type Q2Query = { search: Array< } } `); - const config = { skipTypename: false, preResolveTypes: false }; + const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type MeQuery = ( - { __typename?: 'Query' } - & { me?: Maybe<( - { __typename?: 'User' } - & Pick - & { profile?: Maybe<( - { __typename?: 'Profile' } - & Pick - )> } - )> } - ); - `); - expect(content).toBeSimilarStringTo(` - export type UserProfileFragment = ( - { __typename?: 'User' } - & { profile?: Maybe<( - { __typename?: 'Profile' } - & Pick - )> } - ); - `); - expect(content).toBeSimilarStringTo(` - export type UserFieldsFragment = ( - { __typename?: 'User' } - & Pick - ); + expect(content).toMatchInlineSnapshot(` + "export type UserFieldsFragment = { id: string }; + + export type UserProfileFragment = { profile: { age: number | null } | null }; + + export type MeQueryVariables = Exact<{ [key: string]: never; }>; + + + export type MeQuery = { me: { username: string, id: string, profile: { age: number | null } | null } | null }; + " `); - await validate(content, config); + await validate(content); }); it('Should generate the correct intersection for fragments when using with interfaces with different type', async () => { @@ -2095,39 +1660,29 @@ export type Q2Query = { search: Array< y } `); - const config = { preResolveTypes: false }; + const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type Unnamed_1_Query = ( - { __typename?: 'Query' } - & { b?: Maybe<( - { __typename?: 'A' } - & Pick - ) | ( - { __typename?: 'B' } - & Pick - )> } - ); + expect(content).toMatchInlineSnapshot(` + "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - export type AFragment = ( - { __typename?: 'A' } - & Pick - ); - export type BFragment = ( - { __typename?: 'B' } - & Pick - ); + export type Unnamed_1_Query = { b: + | { id: string, x: number } + | { id: string, y: number } + | null }; + + export type AFragment = { id: string, x: number }; + + export type BFragment = { id: string, y: number }; + " `); - await validate(content, config, schema); + await validate(content); }); it('Should generate the correct intersection for fragments when type implements 2 interfaces', async () => { @@ -2172,25 +1727,27 @@ export type Q2Query = { search: Array< bar } `); - const config = { preResolveTypes: false }; + const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, - ); - expect(content).toBeSimilarStringTo(` - export type Unnamed_1_Query = ( - { __typename?: 'Query' } - & { myType: ( - { __typename?: 'MyType' } - & Pick - ) } + {}, + { outputFile: '' }, ); + expect(content).toMatchInlineSnapshot(` + "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; + + + export type Unnamed_1_Query = { myType: { foo: string, bar: string, test: string } }; + + export type CFragment = { test: string }; + + export type AFragment = { foo: string }; + + export type BFragment = { bar: string }; + " `); - await validate(content, config, schema); + await validate(content); }); it('Should generate the correct intersection for fragments when using with interfaces with same type', async () => { @@ -2230,37 +1787,29 @@ export type Q2Query = { search: Array< x } `); - const config = { preResolveTypes: false }; + const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type Unnamed_1_Query = ( - { __typename?: 'Query' } - & { b?: Maybe<( - { __typename?: 'A' } - & Pick - ) | { __typename?: 'B' }> } - ); + expect(content).toMatchInlineSnapshot(` + "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - export type AFragment = ( - { __typename?: 'A' } - & Pick - ); - export type BFragment = ( - { __typename?: 'A' } - & Pick - ); + export type Unnamed_1_Query = { b: + | { id: string, x: number } + | Record + | null }; + + export type AFragment = { id: string }; + + 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 () => { @@ -2283,32 +1832,23 @@ export type Q2Query = { search: Array< } `); - const config = { preResolveTypes: false }; const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type NotificationsQuery = ( - { __typename?: 'Query' } - & { notifications: Array<( - { __typename?: 'TextNotification' } - & Pick - ) | ( - { __typename?: 'ImageNotification' } - & Pick - & { metadata: ( - { __typename?: 'ImageMetadata' } - & Pick - ) } - )> } - ); + expect(content).toMatchInlineSnapshot(` + "export type NotificationsQueryVariables = Exact<{ [key: string]: never; }>; + + + export type NotificationsQuery = { notifications: Array< + | { text: string, id: string } + | { imageUrl: string, id: string, metadata: { createdBy: string } } + > }; + " `); - await validate(content, config); + await validate(content); }); it('Should support union correctly when used with inline fragments', async () => { @@ -2325,29 +1865,25 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; + const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type UnionTestQuery = ( - { __typename?: 'Query' } - & { unionTest?: Maybe<( - { __typename?: 'User' } - & Pick - ) | ( - { __typename?: 'Profile' } - & Pick - )> } - ); + expect(content).toMatchInlineSnapshot(` + "export type UnionTestQueryVariables = Exact<{ [key: string]: never; }>; + + + export type UnionTestQuery = { unionTest: + | { id: string } + | { age: number | null } + | null }; + " `); - await validate(content, config); + await validate(content); }); it('Should support union correctly when used with inline fragments on types implementing common interface', async () => { @@ -2368,29 +1904,25 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; + const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type UnionTestQuery = ( - { __typename?: 'Query' } - & { mixedNotifications: Array<( - { __typename?: 'TextNotification' } - & Pick - ) | ( - { __typename?: 'ImageNotification' } - & Pick - )> } - ); + expect(content).toMatchInlineSnapshot(` + "export type UnionTestQueryVariables = Exact<{ [key: string]: never; }>; + + + export type UnionTestQuery = { mixedNotifications: Array< + | { id: string, text: string } + | { id: string, imageUrl: string } + > }; + " `); - await validate(content, config); + await validate(content); }); it('Should support union correctly when used with inline fragments on types implementing common interface and also other types', async () => { @@ -2415,32 +1947,26 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; + const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type UnionTestQuery = ( - { __typename?: 'Query' } - & { search: Array<( - { __typename?: 'TextNotification' } - & Pick - ) | ( - { __typename?: 'ImageNotification' } - & Pick - ) | ( - { __typename?: 'User' } - & Pick - )> } - ); + expect(content).toMatchInlineSnapshot(` + "export type UnionTestQueryVariables = Exact<{ [key: string]: never; }>; + + + export type UnionTestQuery = { search: Array< + | { id: string, text: string } + | { id: string, imageUrl: string } + | { id: string } + > }; + " `); - await validate(content, config); + await validate(content); }); it('Should support merging identical fragment union types', async () => { @@ -2455,37 +1981,24 @@ 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: '', - }, + { mergeFragmentTypes: true, namingConvention: 'keep' }, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type testQueryVariables = Exact<{ [key: string]: never; }>; + expect(content).toMatchInlineSnapshot(` + "export type testQueryVariables = Exact<{ [key: string]: never; }>; + - export type testQuery = ( - { notifications: Array<( - { id: string } - & { __typename?: 'TextNotification' | 'ImageNotification' } - )> } - & { __typename?: 'Query' } - ); + export type testQuery = { notifications: Array<{ id: string }> }; - export type NFragment = ( - { id: string } - & { __typename?: 'TextNotification' | 'ImageNotification' } - ); - `); - await validate(content, config); + export type NFragment = { id: string }; + " + `); + await validate(content); }); it('Should support computing correct names for merged fragment union types', async () => { @@ -2497,34 +2010,26 @@ 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: '', - }, + { mergeFragmentTypes: true, namingConvention: 'keep' }, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - type N_TextNotification_Fragment = ( - { text: string, id: string } - & { __typename?: 'TextNotification' } - ); + expect(content).toMatchInlineSnapshot(` + "type N_TextNotification_Fragment = { text: string, id: string }; - type N_ImageNotification_Fragment = ( - { id: string } - & { __typename?: 'ImageNotification' } - ); + type N_ImageNotification_Fragment = { id: string }; - export type NFragment = N_TextNotification_Fragment | N_ImageNotification_Fragment; + export type NFragment = + | N_TextNotification_Fragment + | N_ImageNotification_Fragment + ; + " `); - await validate(content, config); + await validate(content); }); it('Should support computing correct names for large merged fragment union types', async () => { @@ -2567,34 +2072,26 @@ 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: '', - }, + { mergeFragmentTypes: true, namingConvention: 'keep' }, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - type N_A_Fragment = ( - { text: string, id: string } - & { __typename?: 'A' } - ); + expect(content).toMatchInlineSnapshot(` + "type N_A_Fragment = { text: string, id: string }; - type N_zhJJUzpMTyh98zugnx0IKwiLetPNjV8KybSlmpAEUU_Fragment = ( - { id: string } - & { __typename?: 'B' | 'C' | 'D' | 'E' } - ); + type N_ZMkK3KeglIQrCEb6gIP8zgzig3OXIb4iuHrFFPW86a4_Fragment = { id: string }; - export type NFragment = N_A_Fragment | N_zhJJUzpMTyh98zugnx0IKwiLetPNjV8KybSlmpAEUU_Fragment; + export type NFragment = + | N_A_Fragment + | N_ZMkK3KeglIQrCEb6gIP8zgzig3OXIb4iuHrFFPW86a4_Fragment + ; + " `); - await validate(content, config); + await validate(content); }); it('Should not create empty types when merging fragment union types', async () => { @@ -2607,33 +2104,22 @@ 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: '', - }, + { mergeFragmentTypes: true, namingConvention: 'keep' }, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type NFragment = ( - { notifications: Array<( - { text: string } - & { __typename?: 'TextNotification' } - ) | { __typename?: 'ImageNotification' }> } - & { __typename?: 'Query' } - ); + expect(content).toMatchInlineSnapshot(` + "export type NFragment = { notifications: Array<{ text: string }> }; + " `); - await validate(content, config); + await validate(content); }); - it('Should support merging identical fragment union types with skipTypename', async () => { + it('Should support merging identical fragment union types', async () => { const ast = parse(/* GraphQL */ ` query test { notifications { @@ -2645,30 +2131,30 @@ 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: '', + mergeFragmentTypes: true, + namingConvention: 'keep', }, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type testQueryVariables = Exact<{ [key: string]: never; }>; + expect(content).toMatchInlineSnapshot(` + "export type testQueryVariables = Exact<{ [key: string]: never; }>; + export type testQuery = { notifications: Array<{ id: string }> }; + + export type NFragment = { id: string }; + " `); - await validate(content, config); + await validate(content); }); - it('Should support computing correct names for merged fragment union types with skipTypename', async () => { + it('Should support computing correct names for merged fragment union types', async () => { const ast = parse(/* GraphQL */ ` fragment N on Notifiction { id @@ -2677,29 +2163,29 @@ 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: '', + mergeFragmentTypes: true, + namingConvention: 'keep', }, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - type N_TextNotification_Fragment = { text: string, id: string }; + expect(content).toMatchInlineSnapshot(` + "type N_TextNotification_Fragment = { text: string, id: string }; - type N_ImageNotification_Fragment = { id: string }; + type N_ImageNotification_Fragment = { id: string }; - export type NFragment = N_TextNotification_Fragment | N_ImageNotification_Fragment; + export type NFragment = + | N_TextNotification_Fragment + | N_ImageNotification_Fragment + ; + " `); - await validate(content, config); + await validate(content); }); it('Ignores merging when enabled alongside inline fragment masking', async () => { @@ -2714,39 +2200,34 @@ 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: '', - }, + { mergeFragmentTypes: true, inlineFragmentTypes: 'mask' }, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type TestQueryVariables = Exact<{ [key: string]: never; }>; + expect(content).toMatchInlineSnapshot(` + "export type TestQueryVariables = Exact<{ [key: string]: never; }>; - export type TestQuery = { __typename?: 'Query', notifications: Array<( - { __typename?: 'TextNotification' } - & { ' $fragmentRefs'?: { 'N_TextNotification_Fragment': N_TextNotification_Fragment } } - ) | ( - { __typename?: 'ImageNotification' } - & { ' $fragmentRefs'?: { 'N_ImageNotification_Fragment': N_ImageNotification_Fragment } } - )> }; + export type TestQuery = { notifications: Array< + | { ' $fragmentRefs'?: { 'N_TextNotification_Fragment': N_TextNotification_Fragment } } + | { ' $fragmentRefs'?: { 'N_ImageNotification_Fragment': N_ImageNotification_Fragment } } + > }; - type N_TextNotification_Fragment = { __typename?: 'TextNotification', id: string } & { ' $fragmentName'?: 'N_TextNotification_Fragment' }; + type N_TextNotification_Fragment = { id: string } & { ' $fragmentName'?: 'N_TextNotification_Fragment' }; - type N_ImageNotification_Fragment = { __typename?: 'ImageNotification', id: string } & { ' $fragmentName'?: 'N_ImageNotification_Fragment' }; + type N_ImageNotification_Fragment = { id: string } & { ' $fragmentName'?: 'N_ImageNotification_Fragment' }; - export type NFragment = N_TextNotification_Fragment | N_ImageNotification_Fragment; - `); - await validate(content, config); + export type NFragment = + | N_TextNotification_Fragment + | N_ImageNotification_Fragment + ; + " + `); + await validate(content); }); it('Should support inline fragments', async () => { @@ -2763,23 +2244,22 @@ export type Q2Query = { search: Array< } } `); - const config = { skipTypename: true, preResolveTypes: false }; + const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type CurrentUserQuery = { me?: Maybe<( - Pick - & { profile?: Maybe> } - )> }; + expect(content).toMatchInlineSnapshot(` + "export type CurrentUserQueryVariables = Exact<{ [key: string]: never; }>; + + + export type CurrentUserQuery = { me: { username: string, id: string, profile: { age: number | null } | null } | null }; + " `); - await validate(content, config); + await validate(content); }); it('Should build a basic selection set based on basic query on GitHub schema', async () => { @@ -2799,31 +2279,29 @@ export type Q2Query = { search: Array< } } `); - const config = { skipTypename: true, preResolveTypes: false }; + const { content } = await plugin( gitHuntSchema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo( - `export type MeQueryVariables = Exact<{ - repoFullName: Scalars['String']['input']; - }>;`, + expect(content).toMatchInlineSnapshot( + ` + "export type MeQueryVariables = Exact<{ + repoFullName: string; + }>; + + + export type MeQuery = { currentUser: { login: string, html_url: string } | null, entry: { id: number, createdAt: number, postedBy: { login: string, html_url: string } } | null }; + " + `, ); - expect(content).toBeSimilarStringTo(` - export type MeQuery = { currentUser?: Maybe>, entry?: Maybe<( - Pick - & { postedBy: Pick } - )> }; - `); - await validate(content, config, gitHuntSchema); + 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 { @@ -2840,23 +2318,27 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: true }; + const { content } = await plugin( gitHuntSchema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type MeQuery = { __typename?: 'Query', currentUser?: { __typename?: 'User', login: string, html_url: string } | null, entry?: { __typename?: 'Entry', id: number, createdAt: number, postedBy: { __typename?: 'User', login: string, html_url: string } } | null }; + expect(content).toMatchInlineSnapshot(` + "export type MeQueryVariables = Exact<{ + repoFullName: string; + }>; + + + 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, config, gitHuntSchema); + 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 { @@ -2890,22 +2372,31 @@ export type Q2Query = { search: Array< info: Information } `); - const config = { preResolveTypes: true }; + const { content } = await plugin( testSchema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - const o = await validate(content, config, testSchema); - expect(o).toContain(`export enum Information_EntryType {`); - expect(o).toContain(`__typename?: 'Information_Entry', id: Information_EntryType,`); + const o = await validate(content); + expect(o).toMatchInlineSnapshot(` + "export type Information_EntryType = + | 'NAME' + | 'ADDRESS'; + + export type TestQueryVariables = Exact<{ [key: string]: never; }>; + + + export type TestQuery = { info: { entries: Array<{ id: Information_EntryType, value: string | null }> } | null }; + + export type InformationFragment = { entries: Array<{ id: Information_EntryType, value: string | null }> }; + " + `); }); - 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 { @@ -2943,30 +2434,33 @@ 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: '', - }, + { typesPrefix: 'I', enumPrefix: false }, + { outputFile: '' }, ); - const o = await validate(content, config, testSchema); - expect(o).toBeSimilarStringTo(` export type ITestQueryVariables = Exact<{ - e: Information_EntryType; - }>;`); - expect(o).toContain(`export type IQuery = {`); - expect(o).toContain(`export enum Information_EntryType {`); - expect(o).toContain(`__typename?: 'Information_Entry', id: Information_EntryType,`); + const o = await validate(content); + expect(o).toMatchInlineSnapshot(` + "export type Information_EntryType = + | 'NAME' + | 'ADDRESS'; + + export type ITestQueryVariables = Exact<{ + e: Information_EntryType; + }>; + + + export type ITestQuery = { info: { entries: Array<{ id: Information_EntryType, value: string | null }> } | null, infoArgTest: { entries: Array<{ id: Information_EntryType, value: string | null }> } | null }; + + export type IInformationFragment = { entries: Array<{ id: Information_EntryType, value: string | null }> }; + " + `); }); - 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 { @@ -3004,27 +2498,30 @@ 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: '', - }, + { typesSuffix: 'I', enumSuffix: false }, + { outputFile: '' }, ); - const o = await validate(content, config, testSchema); - expect(o).toBeSimilarStringTo(` export type TestQueryVariablesI = Exact<{ - e: Information_EntryType; - }>;`); - expect(o).toContain(`export type QueryI = {`); - expect(o).toContain(`export enum Information_EntryType {`); - expect(o).toContain(`__typename?: 'Information_Entry', id: Information_EntryType,`); + const o = await validate(content); + expect(o).toMatchInlineSnapshot(` + "export type Information_EntryType = + | 'NAME' + | 'ADDRESS'; + + export type TestQueryVariablesI = Exact<{ + e: Information_EntryType; + }>; + + + export type TestQueryI = { info: { entries: Array<{ id: Information_EntryType, value: string | null }> } | null, infoArgTest: { entries: Array<{ id: Information_EntryType, value: string | null }> } | null }; + + export type InformationFragmentI = { entries: Array<{ id: Information_EntryType, value: string | null }> }; + " + `); }); it('Should build a basic selection set based on basic query', async () => { @@ -3033,20 +2530,22 @@ 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: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type DummyQuery = Pick; + expect(content).toMatchInlineSnapshot(` + "export type DummyQueryVariables = Exact<{ [key: string]: never; }>; + + + export type DummyQuery = { dummy: string | null }; + " `); - await validate(content, config); + await validate(content); }); it('Should build a basic selection set based on basic query with field aliasing for basic scalar', async () => { @@ -3058,23 +2557,22 @@ export type Q2Query = { search: Array< } } `); - const config = { skipTypename: true, preResolveTypes: false }; + const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type DummyQuery = ( - { customName: Query['dummy'] } - & { customName2?: Maybe> } - ); + expect(content).toMatchInlineSnapshot(` + "export type DummyQueryVariables = Exact<{ [key: string]: never; }>; + + + export type DummyQuery = { customName: string | null, customName2: { age: number | null } | null }; + " `); - await validate(content, config); + await validate(content); }); it('Should build a basic selection set based on a query with inner fields', async () => { @@ -3090,23 +2588,26 @@ export type Q2Query = { search: Array< } } `); - const config = { skipTypename: true, preResolveTypes: false }; + const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type CurrentUserQuery = { me?: Maybe<( - Pick - & { profile?: Maybe> } - )> }; + expect(content).toMatchInlineSnapshot(` + "export type Role = + | 'USER' + | 'ADMIN'; + + export type CurrentUserQueryVariables = Exact<{ [key: string]: never; }>; + + + export type CurrentUserQuery = { me: { id: string, username: string, role: Role | null, profile: { age: number | null } | null } | null }; + " `); - await validate(content, config); + await validate(content); }); }); @@ -3121,23 +2622,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: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type UserFieldsFragment = ( - Pick - & { profile?: Maybe> } - ); + expect(content).toMatchInlineSnapshot(` + "export type UserFieldsFragment = { id: string, username: string, profile: { age: number | null } | null }; + " `); - await validate(content, config); + await validate(content); }); }); @@ -3154,23 +2651,22 @@ export type Q2Query = { search: Array< } } `); - const config = { skipTypename: true, preResolveTypes: false }; + const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type LoginMutation = { login?: Maybe<( - Pick - & { profile?: Maybe> } - )> }; + expect(content).toMatchInlineSnapshot(` + "export type LoginMutationVariables = Exact<{ [key: string]: never; }>; + + + export type LoginMutation = { login: { id: string, username: string, profile: { age: number | null } | null } | null }; + " `); - await validate(content, config); + await validate(content); }); it('Should detect Query correctly', async () => { @@ -3179,20 +2675,22 @@ 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: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type TestQuery = Pick; + expect(content).toMatchInlineSnapshot(` + "export type TestQueryVariables = Exact<{ [key: string]: never; }>; + + + export type TestQuery = { dummy: string | null }; + " `); - await validate(content, config); + await validate(content); }); it('Should detect Subscription correctly', async () => { @@ -3203,20 +2701,22 @@ export type Q2Query = { search: Array< } } `); - const config = { skipTypename: true, preResolveTypes: false }; + const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo(` - export type TestSubscription = { userCreated?: Maybe> }; + expect(content).toMatchInlineSnapshot(` + "export type TestSubscriptionVariables = Exact<{ [key: string]: never; }>; + + + export type TestSubscription = { userCreated: { id: string } | null }; + " `); - await validate(content, config); + await validate(content); }); it('Should handle operation variables correctly', async () => { @@ -3234,29 +2734,37 @@ export type Q2Query = { search: Array< dummy } `); - const config = { skipTypename: true }; + const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo( - `export type TestQueryQueryVariables = Exact<{ - username?: InputMaybe; - email?: InputMaybe; - password: Scalars['String']['input']; - input?: InputMaybe; + expect(content).toMatchInlineSnapshot( + ` + "export type InputType = { + t?: string | null | undefined; + }; + + export type TestQueryQueryVariables = Exact<{ + username?: string | null | undefined; + email?: string | null | undefined; + password: string; + input?: InputType | null | undefined; mandatoryInput: InputType; - testArray?: InputMaybe> | InputMaybe>; - requireString: Array> | InputMaybe; - innerRequired: Array | Scalars['String']['input']; - }>;`, + testArray?: Array | string | null | undefined; + requireString: Array | string; + innerRequired: Array | string; + }>; + + + export type TestQueryQuery = { dummy: string | null }; + " + `, ); - await validate(content, config, schema); + await validate(content); }); it('Should handle operation variables correctly when they use custom scalars', async () => { @@ -3265,22 +2773,26 @@ export type Q2Query = { search: Array< dummy } `); - const config = { skipTypename: true }; + const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo( - `export type TestQueryQueryVariables = Exact<{ - test?: InputMaybe; - }>;`, + expect(content).toMatchInlineSnapshot( + ` + "export type TestQueryQueryVariables = Exact<{ + test?: unknown; + }>; + + + export type TestQueryQuery = { dummy: string | null }; + " + `, ); - await validate(content, config); + await validate(content); }); it('Should create empty variables when there are no operation variables', async () => { @@ -3289,20 +2801,22 @@ export type Q2Query = { search: Array< dummy } `); - const config = { skipTypename: true }; + const { content } = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - config, - { - outputFile: '', - }, + {}, + { outputFile: '' }, ); - expect(content).toBeSimilarStringTo( - `export type TestQueryQueryVariables = Exact<{ [key: string]: never; }>;`, - ); - await validate(content, config); + expect(content).toMatchInlineSnapshot(` + "export type TestQueryQueryVariables = Exact<{ [key: string]: never; }>; + + + export type TestQueryQuery = { dummy: string | null }; + " + `); + await validate(content); }); it('avoid duplicates - each type name should be unique', async () => { @@ -3337,23 +2851,21 @@ export type Q2Query = { search: Array< const { content } = await plugin( testSchema, [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - }, + {}, + { outputFile: 'graphql.ts' }, ); - expect(content).toBeSimilarStringTo(` - export type SubmitMessageMutation = ( - { __typename?: 'Mutation' } - & { mutation: ( - { __typename?: 'DeleteMutation' } - & Pick - ) | ( - { __typename?: 'UpdateMutation' } - & Pick - ) } - ); + expect(content).toMatchInlineSnapshot(` + "export type SubmitMessageMutationVariables = Exact<{ + message: string; + }>; + + + export type SubmitMessageMutation = { mutation: + | { deleted: boolean } + | { updated: boolean } + }; + " `); }); @@ -3379,17 +2891,16 @@ export type Q2Query = { search: Array< const { content } = await plugin( testSchema, [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - }, + {}, + { outputFile: 'graphql.ts' }, ); - expect(content).toBeSimilarStringTo(` - export type PostQuery = ( - { __typename?: 'Query' } - & { post: { __typename: 'Post' } } - ); + expect(content).toMatchInlineSnapshot(` + "export type PostQueryVariables = Exact<{ [key: string]: never; }>; + + + export type PostQuery = { post: { __typename: 'Post' } }; + " `); }); @@ -3417,81 +2928,20 @@ export type Q2Query = { search: Array< const { content } = await plugin( testSchema, [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - }, + {}, + { outputFile: 'graphql.ts' }, ); - expect(content).toBeSimilarStringTo(` - export type InfoQuery = ( - { __typename?: 'Query' } - & { __schema: ( - { __typename?: '__Schema' } - & { queryType: ( - { __typename?: '__Type' } - & { fields?: Maybe - )>> } - ) } - ) } - );`); - }); - - it('should handle introspection types (__type)', async () => { - const testSchema = buildSchema(/* GraphQL */ ` - type Post { - title: String - } - type Query { - post: Post! - } - `); - const query = parse(/* GraphQL */ ` - query Info { - __type(name: "Post") { - name - fields { - name - type { - name - kind - } - } - } - } - `); + expect(content).toMatchInlineSnapshot(` + "export type InfoQueryVariables = Exact<{ [key: string]: never; }>; - const { content } = await plugin( - testSchema, - [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - }, - ); - expect(content).toBeSimilarStringTo(` - export type InfoQuery = ( - { __typename?: 'Query' } - & { __type?: Maybe<( - { __typename?: '__Type' } - & Pick<__Type, 'name'> - & { fields?: Maybe - & { type: ( - { __typename?: '__Type' } - & Pick<__Type, 'name' | 'kind'> - ) } - )>> } - )> } - ); + export type InfoQuery = { __schema: { queryType: { fields: Array<{ name: string }> | null } } }; + " `); }); - it('should handle introspection types (like __TypeKind)', async () => { + it('should handle introspection types (__type)', async () => { const testSchema = buildSchema(/* GraphQL */ ` type Post { title: String @@ -3515,49 +2965,20 @@ export type Q2Query = { search: Array< } `); - const coreContent = await tsPlugin( + const { content } = await plugin( testSchema, [{ location: '', document: query }], {}, - { - outputFile: 'graphql.ts', - }, + { outputFile: 'graphql.ts' }, ); - const pluginContent = await plugin( - testSchema, - [{ location: '', document: query }], - {}, - { - outputFile: 'graphql.ts', - }, - ); + expect(content).toMatchInlineSnapshot(` + "export type InfoQueryVariables = Exact<{ [key: string]: never; }>; - const content = mergeOutputs([coreContent, pluginContent]); - - expect(content).toBeSimilarStringTo(` - /** An enum describing what kind of type a given \`__Type\` is. */ - export enum __TypeKind { - /** Indicates this type is a scalar. */ - Scalar = 'SCALAR', - /** Indicates this type is an object. \`fields\` and \`interfaces\` are valid fields. */ - Object = 'OBJECT', - /** Indicates this type is an interface. \`fields\`, \`interfaces\`, and \`possibleTypes\` are valid fields. */ - Interface = 'INTERFACE', - /** Indicates this type is a union. \`possibleTypes\` is a valid field. */ - Union = 'UNION', - /** Indicates this type is an enum. \`enumValues\` is a valid field. */ - Enum = 'ENUM', - /** Indicates this type is an input object. \`inputFields\` is a valid field. */ - InputObject = 'INPUT_OBJECT', - /** Indicates this type is a list. \`ofType\` is a valid field. */ - List = 'LIST', - /** Indicates this type is a non-null. \`ofType\` is a valid field. */ - NonNull = 'NON_NULL' - } - `); - validateTs(content); + export type InfoQuery = { __type: { name: string | null, fields: Array<{ name: string, type: { name: string | null, kind: __TypeKind } }> | null } | null }; + " + `); }); it('Should generate correctly when using enums and typesPrefix', async () => { @@ -3588,25 +3009,27 @@ 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).toBeSimilarStringTo(` + expect(content).toMatchInlineSnapshot(` + "export type PREFIX_Access = + | 'Read' + | 'Write' + | 'All'; + + export type PREFIX_Filter = { + match: string; + }; + export type PREFIX_UsersQueryVariables = Exact<{ filter: PREFIX_Filter; }>; - `); - expect(content).toBeSimilarStringTo(` - export type PREFIX_UsersQuery = ( - { __typename?: 'Query' } - & { users?: Maybe - )>>> } - ); + + + export type PREFIX_UsersQuery = { users: Array<{ access: PREFIX_Access | null } | null> | null }; + " `); }); @@ -3631,15 +3054,17 @@ export type Q2Query = { search: Array< testSchema, [{ location: '', document: query }], {}, - { - outputFile: 'graphql.ts', - }, + { outputFile: 'graphql.ts' }, ); - expect(content).toBeSimilarStringTo(` - export type UsersQueryVariables = Exact<{ - reverse?: InputMaybe; + expect(content).toMatchInlineSnapshot(` + "export type UsersQueryVariables = Exact<{ + reverse?: boolean | null | undefined; }>; + + + export type UsersQuery = { users: Array<{ name: string }> }; + " `); }); }); @@ -3695,28 +3120,20 @@ export type Q2Query = { search: Array< const { content } = await plugin( schema, [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - }, - ); - expect(content).toBeSimilarStringTo(` - export type FieldQuery = ( - { __typename?: 'Query' } - & { field: ( - { __typename: 'Error1' } - & Pick - ) | ( - { __typename: 'Error2' } - & Pick - ) | ( - { __typename: 'ComplexError' } - & Pick - ) | ( - { __typename: 'FieldResultSuccess' } - & Pick - ) } + {}, + { outputFile: 'graphql.ts' }, ); + expect(content).toMatchInlineSnapshot(` + "export type FieldQueryVariables = Exact<{ [key: string]: never; }>; + + + export type FieldQuery = { field: + | { __typename: 'Error1', message: string } + | { __typename: 'Error2', message: string } + | { __typename: 'ComplexError', message: string, additionalInfo: string } + | { __typename: 'FieldResultSuccess', someValue: boolean } + }; + " `); }); @@ -3770,28 +3187,20 @@ export type Q2Query = { search: Array< const { content } = await plugin( schema, [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - }, + {}, + { outputFile: 'graphql.ts' }, ); - expect(content).toBeSimilarStringTo(` - export type FieldQuery = ( - { __typename?: 'Query' } - & { field: ( - { __typename: 'Error1' } - & Pick - ) | ( - { __typename: 'Error2' } - & Pick - ) | ( - { __typename: 'ComplexError' } - & Pick - ) | ( - { __typename?: 'FieldResultSuccess' } - & Pick - ) } - ); + expect(content).toMatchInlineSnapshot(` + "export type FieldQueryVariables = Exact<{ [key: string]: never; }>; + + + export type FieldQuery = { field: + | { __typename: 'Error1', message: string } + | { __typename: 'Error2', message: string } + | { __typename: 'ComplexError', message: string, additionalInfo: string } + | { someValue: boolean } + }; + " `); }); it('interface with same field names', async () => { @@ -3832,23 +3241,19 @@ export type Q2Query = { search: Array< const { content } = await plugin( testSchema, [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - }, + {}, + { outputFile: 'graphql.ts' }, ); - expect(content).toBeSimilarStringTo(` - export type SomethingQuery = ( - { __typename?: 'Query' } - & { node?: Maybe<( - { __typename?: 'A' } - & Pick - ) | ( - { __typename?: 'B' } - & Pick - )> } - ); + expect(content).toMatchInlineSnapshot(` + "export type SomethingQueryVariables = Exact<{ [key: string]: never; }>; + + + export type SomethingQuery = { node: + | { a: string | null } + | { a: boolean | null } + | null }; + " `); }); it('union returning single interface types', async () => { @@ -3902,30 +3307,20 @@ export type Q2Query = { search: Array< const { content } = await plugin( testSchema, [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - }, + {}, + { outputFile: 'graphql.ts' }, ); - expect(content).toBeSimilarStringTo(` - export type UserQuery = ( - { __typename?: 'Query' } - & { user?: Maybe<( - { __typename?: 'User' } - & Pick - ) | ( - { __typename?: 'Error2' } - & Pick - ) | ( - { __typename?: 'Error3' } - & Pick - & { info?: Maybe<( - { __typename?: 'AdditionalInfo' } - & Pick - )> } - )> } - ); + expect(content).toMatchInlineSnapshot(` + "export type UserQueryVariables = Exact<{ [key: string]: never; }>; + + + export type UserQuery = { user: + | { id: string, login: string } + | { message: string } + | { message: string, info: { message: string } | null } + | null }; + " `); }); @@ -3995,30 +3390,20 @@ export type Q2Query = { search: Array< const { content } = await plugin( testSchema, [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - }, + {}, + { outputFile: 'graphql.ts' }, ); - expect(content).toBeSimilarStringTo(` - export type UserQuery = ( - { __typename?: 'Query' } - & { user?: Maybe<( - { __typename?: 'User' } - & Pick - ) | ( - { __typename?: 'Error2' } - & Pick - ) | ( - { __typename?: 'Error3' } - & Pick - & { info?: Maybe<( - { __typename?: 'AdditionalInfo' } - & Pick - )> } - )> } - ); + expect(content).toMatchInlineSnapshot(` + "export type UserQueryVariables = Exact<{ [key: string]: never; }>; + + + export type UserQuery = { user: + | { id: string, login: string } + | { message: string } + | { message: string, info: { message: string, message2: string } | null } + | null }; + " `); }); @@ -4051,22 +3436,18 @@ 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, {}, testSchema); + const o = await validate(content); - expect(o).toBeSimilarStringTo(` - export type UserQueryQuery = ( - { __typename?: 'Query' } - & { user: ( - { __typename?: 'User' } - & Pick - ) } - ); + expect(o).toMatchInlineSnapshot(` + "export type UserQueryQueryVariables = Exact<{ [key: string]: never; }>; + + + export type UserQueryQuery = { user: { id: string, login: string } }; + " `); }); @@ -4101,27 +3482,21 @@ 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, {}, testSchema); - - expect(o).toBeSimilarStringTo(` - export type UserQueryQuery = ( - { __typename?: 'Query' } - & { user: ( - { __typename?: 'User' } - & Pick - ) } - );`); - - expect(o).toBeSimilarStringTo(`export type TestFragment = ( - { __typename?: 'User' } - & Pick - );`); + const o = await validate(content); + + expect(o).toMatchInlineSnapshot(` + "export type UserQueryQueryVariables = Exact<{ [key: string]: never; }>; + + + export type UserQueryQuery = { user: { id: string, login: string } }; + + export type TestFragment = { login: string }; + " + `); }); it('Should handle union selection sets with both FragmentSpreads and InlineFragments', async () => { @@ -4200,16 +3575,12 @@ 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( content, - {}, - testSchema, ` function t(q: UserQueryQuery) { if (q.user) { @@ -4229,63 +3600,55 @@ export type Q2Query = { search: Array< } }`, ); - expect(mergeOutputs([content])).toMatchSnapshot(); - expect(output).toBeSimilarStringTo(` - export type UserQueryQuery = ( - { __typename?: 'Query' } - & { user: ( - { __typename?: 'User' } - & Pick - ) | ( - { __typename?: 'Error2' } - & Pick - ) | ( - { __typename?: 'Error3' } - & Pick - & { info?: Maybe<( - { __typename?: 'AdditionalInfo' } - & Pick - )> } - ) } - );`); - - expect(output).toBeSimilarStringTo(` - export type AdditionalInfoFragment = ( - { __typename?: 'AdditionalInfo' } - & Pick - ); + expect(output).toMatchInlineSnapshot(` + "export type UserQueryQueryVariables = Exact<{ [key: string]: never; }>; - type UserResult1_User_Fragment = ( - { __typename?: 'User' } - & Pick - ); - type UserResult1_Error2_Fragment = { __typename?: 'Error2' }; + export type UserQueryQuery = { user: + | { login: string, id: string } + | { message: string } + | { message: string, info: { message2: string, message: string } | null } + }; - type UserResult1_Error3_Fragment = ( - { __typename?: 'Error3' } - & { info?: Maybe<( - { __typename?: 'AdditionalInfo' } - & Pick - )> } - ); + export type AdditionalInfoFragment = { message: string }; - export type UserResult1Fragment = UserResult1_User_Fragment | UserResult1_Error2_Fragment | UserResult1_Error3_Fragment; + type UserResult1_User_Fragment = { id: string }; - type UserResult_User_Fragment = ( - { __typename?: 'User' } - & Pick - ); + type UserResult1_Error3_Fragment = { info: { message2: string } | null }; - type UserResult_Error2_Fragment = ( - { __typename?: 'Error2' } - & Pick - ); + export type UserResult1Fragment = + | UserResult1_User_Fragment + | UserResult1_Error3_Fragment + ; + + type UserResult_User_Fragment = { id: string }; + + type UserResult_Error2_Fragment = { message: string }; - type UserResult_Error3_Fragment = { __typename?: 'Error3' }; + export type UserResultFragment = + | UserResult_User_Fragment + | UserResult_Error2_Fragment + ; - export type UserResultFragment = UserResult_User_Fragment | UserResult_Error2_Fragment | UserResult_Error3_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) + } + } + } + }" + `); }); it('Should handle union selection sets with both FragmentSpreads and InlineFragments with flattenGeneratedTypes', async () => { @@ -4361,19 +3724,15 @@ 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, - config, - testSchema, ` function t(q: UserQueryQuery) { if (q.user) { @@ -4393,26 +3752,34 @@ export type Q2Query = { search: Array< } }`, ); - expect(mergeOutputs([output])).toMatchSnapshot(); - - expect(output).toBeSimilarStringTo(` - export type UserQueryQuery = ( - { __typename?: 'Query' } - & { user: ( - { __typename?: 'User' } - & Pick - ) | ( - { __typename?: 'Error2' } - & Pick - ) | ( - { __typename?: 'Error3' } - & Pick - & { info?: Maybe<( - { __typename?: 'AdditionalInfo' } - & Pick - )> } - ) } - ); + + expect(output).toMatchInlineSnapshot(` + "export type UserQueryQueryVariables = Exact<{ [key: string]: never; }>; + + + export type UserQueryQuery = { user: + | { id: string, login: string } + | { message: string } + | { message: string, info: { message2: string, message: string } | null } + }; + + 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) + } + } + } + }" `); }); @@ -4466,72 +3833,25 @@ export type Q2Query = { search: Array< } `); - const config = { - flattenGeneratedTypes: true, - preResolveTypes: false, - }; - - const { content } = await plugin(testSchema, [{ location: '', document: query }], config, { - outputFile: 'graphql.ts', - }); - - const output = await validate(content, config, testSchema); - expect(mergeOutputs([output])).toMatchSnapshot(); - - expect(output).toBeSimilarStringTo(` - export type Maybe = T | null; - export type InputMaybe = Maybe; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; - export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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'; - search?: Maybe>; - }; - - export type Concept = { - id?: Maybe; - }; + const { content } = await plugin( + testSchema, + [{ location: '', document: query }], + { flattenGeneratedTypes: true }, + { outputFile: 'graphql.ts' }, + ); - export type Dimension = Concept & { - __typename?: 'Dimension'; - id?: Maybe; - }; + const output = await validate(content); - export type DimValue = { - __typename?: 'DimValue'; - dimension?: Maybe; - value: Scalars['String']['output']; - }; + expect(output).toMatchInlineSnapshot(` + "export type SearchPopularQueryVariables = Exact<{ [key: string]: never; }>; - export type Searchable = Dimension | DimValue; - export type SearchPopularQueryVariables = Exact<{ [key: string]: never; }>; - export type SearchPopularQuery = ( - { __typename?: 'Query' } - & { search?: Maybe - ) | ( - { __typename?: 'DimValue' } - & Pick - & { dimension?: Maybe<( - { __typename?: 'Dimension' } - & Pick - )> } - )>> } - );`); + export type SearchPopularQuery = { search: Array< + | { id: string | null } + | { value: string, dimension: { id: string | null } | null } + > | null }; + " + `); }); it('Handles fragments across files with flattenGeneratedTypes', async () => { @@ -4568,57 +3888,30 @@ 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, config, testSchema); - - expect(output).toBeSimilarStringTo(` - export type Maybe = T | null; - export type InputMaybe = Maybe; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; - export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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'; - search?: Maybe>; - }; + const output = await validate(content); - export type Dimension = { - __typename?: 'Dimension'; - id?: Maybe; - }; - export type SearchableFragmentFragment = { __typename?: 'Dimension', id?: string | null }; + expect(output).toMatchInlineSnapshot(` + "export type SearchableFragmentFragment = { id: string | null }; export type SearchPopularQueryVariables = Exact<{ [key: string]: never; }>; - export type SearchPopularQuery = { __typename?: 'Query', search?: Array<{ __typename?: 'Dimension', id?: string | null }> | null };`); + + export type SearchPopularQuery = { search: Array<{ id: string | null }> | null }; + " + `); }); it('Drops fragments with flattenGeneratedTypes', async () => { @@ -4656,56 +3949,28 @@ 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, config, testSchema); - - expect(output).toBeSimilarStringTo(` - export type Maybe = T | null; - export type InputMaybe = Maybe; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; - export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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'; - search?: Maybe>; - }; + const output = await validate(content); - export type Dimension = { - __typename?: 'Dimension'; - id?: Maybe; - }; + expect(output).toMatchInlineSnapshot(` + "export type SearchPopularQueryVariables = Exact<{ [key: string]: never; }>; - export type SearchPopularQueryVariables = Exact<{ [key: string]: never; }>; - export type SearchPopularQuery = { __typename?: 'Query', search?: Array<{ __typename?: 'Dimension', id?: string | null }> | null };`); + export type SearchPopularQuery = { search: Array<{ id: string | null }> | null }; + " + `); }); it('Should add operation name when addOperationExport is true', async () => { @@ -4733,38 +3998,26 @@ export type Q2Query = { search: Array< } `); - const config = { - addOperationExport: true, - preResolveTypes: false, - }; + const { content } = await plugin( + testSchema, + [{ location: '', document: query }], + { addOperationExport: true }, + { outputFile: 'graphql.ts' }, + ); - const { content } = await plugin(testSchema, [{ location: '', document: query }], config, { - outputFile: 'graphql.ts', - }); + expect(content).toMatchInlineSnapshot(` + "export type UserIdQueryQueryVariables = Exact<{ [key: string]: never; }>; - expect(content).toBeSimilarStringTo(` - export type UserIdQueryQueryVariables = Exact<{ [key: string]: never; }>; - export type UserIdQueryQuery = ( - { __typename?: 'Query' } - & { user: ( - { __typename?: 'User' } - & Pick - ) } - ); + export type UserIdQueryQuery = { user: { id: string } }; - export type UserLoginQueryQueryVariables = Exact<{ [key: string]: never; }>; + export type UserLoginQueryQueryVariables = Exact<{ [key: string]: never; }>; - export type UserLoginQueryQuery = ( - { __typename?: 'Query' } - & { user: ( - { __typename?: 'User' } - & Pick - ) } - ); - export declare const UserIdQuery: import("graphql").DocumentNode; - export declare const UserLoginQuery: import("graphql").DocumentNode; + export type UserLoginQueryQuery = { user: { login: string } }; + + export declare const UserIdQuery: import("graphql").DocumentNode; + export declare const UserLoginQuery: import("graphql").DocumentNode;" `); }); @@ -4848,19 +4101,15 @@ 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, - config, - testSchema, ` function t(q: UserQueryQuery) { if (q.user) { @@ -4880,26 +4129,34 @@ export type Q2Query = { search: Array< } }`, ); - expect(mergeOutputs([output])).toMatchSnapshot(); - - expect(output).toBeSimilarStringTo(` - export type UserQueryQuery = ( - { __typename?: 'Query' } - & { user: ( - { __typename?: 'User' } - & Pick - ) | ( - { __typename?: 'Error2' } - & Pick - ) | ( - { __typename?: 'Error3' } - & Pick - & { info?: Maybe<( - { __typename?: 'AdditionalInfo' } - & Pick - )> } - ) } - ); + + expect(output).toMatchInlineSnapshot(` + "export type UserQueryQueryVariables = Exact<{ [key: string]: never; }>; + + + export type UserQueryQuery = { user: + | { id: string, test2: string | null, login: string, test: string | null } + | { message: string } + | { message: string, info: { message2: string, message: string } | null } + }; + + 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) + } + } + } + }" `); }); }); @@ -4950,15 +4207,11 @@ export type Q2Query = { search: Array< testSchema, [{ location: '', document: query }], {}, - { - outputFile: 'graphql.ts', - }, + { outputFile: 'graphql.ts' }, ); await validate( content, - {}, - testSchema, ` function test (t: TestQuery) { for (const item of t.obj!.items) { @@ -4991,14 +4244,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 () => { @@ -5036,12 +4292,16 @@ export type Q2Query = { search: Array< const { content } = await plugin( testSchema, [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - }, + {}, + { outputFile: 'graphql.ts' }, ); - expect(content).toContain(`{ foo?: Maybe<{ __typename?: 'C' }> }`); + expect(content).toMatchInlineSnapshot(` + "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; + + + export type Unnamed_1_Query = { foo: Record | null }; + " + `); }); it('#5001 - incorrect output with typeSuffix', async () => { @@ -5067,13 +4327,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'); @@ -5136,18 +4395,15 @@ 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, - {}, - testSchema, `function test(q: QQuery) { if (q.hotel) { const t1 = q.hotel.gpsPosition.lat @@ -5161,7 +4417,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! @@ -5191,15 +4447,12 @@ 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 }], + { namespacedImportName: 'Types' }, + { outputFile: 'graphql.ts' }, + ); expect(content).toContain(`dep: Types.Department`); expect(content).toMatchSnapshot(); @@ -5327,17 +4580,13 @@ export type Q2Query = { search: Array< testSchema, [{ location: '', document: query }], {}, - { - outputFile: 'graphql.ts', - }, + { outputFile: 'graphql.ts' }, ); expect(mergeOutputs([content])).toMatchSnapshot(); await validate( content, - {}, - testSchema, ` function test(q: GetEntityBrandDataQuery): void { const typeName: 'Company' | 'Theater' | 'User' | 'Movie' = q.node.__typename; // just to check that those are the types we want here @@ -5394,35 +4643,28 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( testSchema, [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - }, + {}, + { outputFile: 'graphql.ts' }, ); - expect(content).toBeSimilarStringTo(` - export type TestQueryQuery = ( - { __typename?: 'Query' } - & { fooBar: Array<( - { __typename?: 'Foo' } - & Pick - ) | ( - { __typename?: 'Bar' } - & Pick - )> } - ); + expect(content).toMatchInlineSnapshot(` + "export type TestQueryQueryVariables = Exact<{ [key: string]: never; }>; - type FooBarFragment_Foo_Fragment = ( - { __typename?: 'Foo' } - & Pick - ); - type FooBarFragment_Bar_Fragment = ( - { __typename?: 'Bar' } - & Pick - ); + export type TestQueryQuery = { fooBar: Array< + | { id: string } + | { id: string } + > }; + + type FooBarFragment_Foo_Fragment = { id: string }; + + type FooBarFragment_Bar_Fragment = { id: string }; - export type FooBarFragmentFragment = FooBarFragment_Foo_Fragment | FooBarFragment_Bar_Fragment; + export type FooBarFragmentFragment = + | FooBarFragment_Foo_Fragment + | FooBarFragment_Bar_Fragment + ; + " `); }); @@ -5469,67 +4711,16 @@ function test(q: GetEntityBrandDataQuery): void { { location: '', document: productFragmentDocument }, { location: '', document: priceFragmentDocument }, ], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - }, - ); - - expect(content).toBeSimilarStringTo(` - export type ProductFragmentFragment = ( - { __typename?: 'Product' } - & Pick + {}, + { outputFile: 'graphql.ts' }, ); - export type PriceFragmentFragment = ( - { __typename?: 'Price' } - & Pick - & { item: Array - )>> } - ); - `); - }); - - it('#2506 - inline fragment without typeCondition specified', async () => { - const schema = buildSchema(/* GraphQL */ ` - type Query { - user: User - } - - type User { - name: String - } - `); + expect(content).toMatchInlineSnapshot(` + "export type ProductFragmentFragment = { id: string, title: string }; - const fragment = parse(/* GraphQL */ ` - query user($withUser: Boolean! = false) { - ... @include(if: $withUser) { - user { - name - } - } - } + export type PriceFragmentFragment = { id: string, item: Array<{ id: string, title: string } | null> }; + " `); - - const { content } = await plugin( - schema, - [{ location: '', document: fragment }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - }, - ); - - expect(content).toBeSimilarStringTo(` - export type UserQuery = ( - { __typename?: 'Query' } - & { user?: Maybe<( - { __typename?: 'User' } - & Pick - )> } - );`); }); it('#2436 - interface with field of same name but different type is correctly handled', async () => { @@ -5583,31 +4774,16 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( schema, [{ location: '', document: fragment }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - }, + {}, + { outputFile: 'graphql.ts' }, ); - expect(content).toBeSimilarStringTo(` - export type DashboardVersionFragmentFragment = ( - { __typename?: 'DashboardVersion' } - & { tiles: ( - { __typename?: 'DashboardTileFilterDetails' } - & Pick - & { md: ( - { __typename?: 'TileFilterMetadata' } - & Pick - ) } - ) | ( - { __typename?: 'DashboardTileParameterDetails' } - & Pick - & { md: ( - { __typename?: 'TileParameterMetadata' } - & Pick - ) } - ) } - ); + expect(content).toMatchInlineSnapshot(` + "export type DashboardVersionFragmentFragment = { tiles: + | { tileId: string, md: { viz: string, columnInfo: string } } + | { tileId: string, md: { viz: string, columnInfo: string } } + }; + " `); }); @@ -5661,35 +4837,20 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( schema, [{ location: '', document: fragment }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - }, + {}, + { outputFile: 'graphql.ts' }, ); - expect(content).toBeSimilarStringTo(` - export type DashboardVersionFragmentFragment = ( - { __typename?: 'DashboardVersion' } - & { tiles: ( - { __typename?: 'DashboardTileFilterDetails' } - & Pick - & { md: ( - { __typename?: 'TileFilterMetadata' } - & Pick - ) } - ) | ( - { __typename?: 'DashboardTileParameterDetails' } - & Pick - & { md: ( - { __typename?: 'TileParameterMetadata' } - & Pick - ) } - ) } - ); + expect(content).toMatchInlineSnapshot(` + "export type DashboardVersionFragmentFragment = { tiles: + | { tileId: string, md: { viz: string, columnInfo: string } } + | { tileId: string, md: { viz: string, columnInfo: string } } + }; + " `); }); - it('#3950 - Invalid output with fragments and skipTypename: true', async () => { + it('#3950 - Invalid output with fragments', async () => { const schema = buildSchema(/* GraphQL */ ` type Query { animals: [Animal!]! @@ -5732,28 +4893,18 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( schema, [{ location: '', document: query }], - { - skipTypename: true, - }, - { - outputFile: 'graphql.ts', - }, + {}, + { outputFile: 'graphql.ts' }, ); expect(content).toMatchInlineSnapshot(` - "type CatFragment_Duck_Fragment = Record; - - type CatFragment_Lion_Fragment = { id: string }; + "type CatFragment_Lion_Fragment = { id: string }; type CatFragment_Puma_Fragment = { id: string }; - type CatFragment_Wolf_Fragment = Record; - export type CatFragmentFragment = - | CatFragment_Duck_Fragment | CatFragment_Lion_Fragment | CatFragment_Puma_Fragment - | CatFragment_Wolf_Fragment ; export type KittyQueryVariables = Exact<{ [key: string]: never; }>; @@ -5768,131 +4919,53 @@ function test(q: GetEntityBrandDataQuery): void { `); }); - it('#3950 - Invalid output with fragments and skipTypename: false', async () => { + it('#2489 - Union that only covers one possible type with selection set and no typename', async () => { const schema = buildSchema(/* GraphQL */ ` - type Query { - animals: [Animal!]! - } - - interface Animal { - id: ID! - } - type Duck implements Animal { - id: ID! + type NotFoundError { + message: String! } - type Lion implements Animal { - id: ID! + type UserBannedError { + message: String! } - type Puma implements Animal { + type User { id: ID! + login: String } - type Wolf implements Animal { - id: ID! + union UserResult = NotFoundError | UserBannedError | User + + type Query { + user: UserResult! } `); const query = parse(/* GraphQL */ ` - fragment CatFragment on Animal { - ... on Lion { - id - } - ... on Puma { - id - } - } - - query kitty { - animals { - ...CatFragment + query user { + user { + ... on User { + id + login + } } } `); - const { content } = await plugin( schema, [{ location: '', document: query }], - { - skipTypename: false, - }, - { - outputFile: 'graphql.ts', - }, + {}, + { outputFile: 'graphql.ts' }, ); expect(content).toMatchInlineSnapshot(` - "type CatFragment_Duck_Fragment = { __typename?: 'Duck' }; + "export type UserQueryVariables = Exact<{ [key: string]: never; }>; - type CatFragment_Lion_Fragment = { __typename?: 'Lion', id: string }; - type CatFragment_Puma_Fragment = { __typename?: 'Puma', id: string }; - - type CatFragment_Wolf_Fragment = { __typename?: 'Wolf' }; - - export type CatFragmentFragment = - | CatFragment_Duck_Fragment - | CatFragment_Lion_Fragment - | CatFragment_Puma_Fragment - | CatFragment_Wolf_Fragment - ; - - export type KittyQueryVariables = Exact<{ [key: string]: never; }>; - - - export type KittyQuery = { __typename?: 'Query', animals: Array< - | { __typename?: 'Duck' } - | { __typename?: 'Lion', id: string } - | { __typename?: 'Puma', id: string } - | { __typename?: 'Wolf' } - > }; - " - `); - }); - - it('#2489 - Union that only covers one possible type with selection set and no typename', async () => { - const schema = buildSchema(/* GraphQL */ ` - type NotFoundError { - message: String! - } - type UserBannedError { - message: String! - } - type User { - id: ID! - login: String - } - union UserResult = NotFoundError | UserBannedError | User - - type Query { - user: UserResult! - } - `); - - const query = parse(/* GraphQL */ ` - query user { - user { - ... on User { - id - login - } - } - } - `); - const { content } = await plugin( - schema, - [{ location: '', document: query }], - { - skipTypename: true, - preResolveTypes: false, - }, - { - outputFile: 'graphql.ts', - }, - ); - - expect(content).toBeSimilarStringTo(` - export type UserQuery = { user: Pick | Record }; - `); - }); + export type UserQuery = { user: + | { id: string, login: string | null } + | Record + }; + " + `); + }); it('#4888 - Types for input Lists do not support coercion', async () => { const schema = buildSchema(/* GraphQL */ ` @@ -5916,18 +4989,26 @@ function test(q: GetEntityBrandDataQuery): void { } } `); - const config = { preResolveTypes: true }; - const { content } = await plugin(schema, [{ location: '', document: ast }], config, { - outputFile: 'graphql.ts', - }); - expect(content).toBeSimilarStringTo(` - export type UserQueryVariables = Exact<{ - testArray?: InputMaybe> | InputMaybe>; - requireString: Array> | InputMaybe; - innerRequired: Array | Scalars['String']['input']; - }>;`); - await validate(content, config); + const { content } = await plugin( + schema, + [{ location: '', document: ast }], + {}, + { outputFile: 'graphql.ts' }, + ); + + expect(content).toMatchInlineSnapshot(` + "export type UserQueryVariables = Exact<{ + testArray?: Array | string | null | undefined; + requireString: Array | string; + innerRequired: Array | string; + }>; + + + export type UserQuery = { search: Array<{ id: string }> | null }; + " + `); + await validate(content); }); it('#5352 - Prevent array input coercion if arrayInputCoercion = false', async () => { @@ -5952,18 +5033,26 @@ function test(q: GetEntityBrandDataQuery): void { } } `); - const config = { preResolveTypes: true, arrayInputCoercion: false }; - const { content } = await plugin(schema, [{ location: '', document: ast }], config, { - outputFile: 'graphql.ts', - }); - expect(content).toBeSimilarStringTo(` - export type UserQueryVariables = Exact<{ - testArray?: InputMaybe>>; - requireString: Array>; - innerRequired: Array; - }>;`); - await validate(content, config); + const { content } = await plugin( + schema, + [{ location: '', document: ast }], + { arrayInputCoercion: false }, + { outputFile: 'graphql.ts' }, + ); + + expect(content).toMatchInlineSnapshot(` + "export type UserQueryVariables = Exact<{ + testArray?: Array | null | undefined; + requireString: Array; + innerRequired: Array; + }>; + + + export type UserQuery = { search: Array<{ id: string }> | null }; + " + `); + await validate(content); }); it('#5263 - inline fragment spread on interface field results in incorrect types', async () => { @@ -6006,23 +5095,19 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( schema, [{ location: '', document }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - }, + {}, + { outputFile: 'graphql.ts' }, ); - expect(content).toBeSimilarStringTo(` - export type EntityQuery = ( - { __typename?: 'Query' } - & { entity: ( - { __typename?: 'Session' } - & Pick - ) | ( - { __typename?: 'User' } - & Pick - ) } - ); + expect(content).toMatchInlineSnapshot(` + "export type EntityQueryVariables = Exact<{ [key: string]: never; }>; + + + export type EntityQuery = { entity: + | { id: string } + | { name: string, id: string } + }; + " `); }); @@ -6060,25 +5145,16 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( schema, [{ location: '', document }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - }, + {}, + { outputFile: 'graphql.ts' }, ); - expect(content).toBeSimilarStringTo(` - export type InlineFragmentQueryQueryVariables = Exact<{ [key: string]: never; }>; - - export type InlineFragmentQueryQuery = ( - { __typename?: 'Query' } - & { user: ( - { __typename?: 'User' } - & { friends: Array<( - { __typename?: 'User' } - & Pick - )> } - ) } - ); + expect(content).toMatchInlineSnapshot(` + "export type InlineFragmentQueryQueryVariables = Exact<{ [key: string]: never; }>; + + + export type InlineFragmentQueryQuery = { user: { friends: Array<{ id: string, name: string }> } }; + " `); }); it('SpreadFragmentQuery', async () => { @@ -6108,48 +5184,20 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( schema, [{ location: '', document }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - }, + {}, + { outputFile: 'graphql.ts' }, ); - expect(content).toBeSimilarStringTo(` - export type UserFriendsIdFragmentFragment = ( - { __typename?: 'Query' } - & { user: ( - { __typename?: 'User' } - & { friends: Array<( - { __typename?: 'User' } - & Pick - )> } - ) } - ); - - export type UserFriendsNameFragmentFragment = ( - { __typename?: 'Query' } - & { user: ( - { __typename?: 'User' } - & { friends: Array<( - { __typename?: 'User' } - & Pick - )> } - ) } - ); + expect(content).toMatchInlineSnapshot(` + "export type UserFriendsIdFragmentFragment = { user: { friends: Array<{ id: string }> } }; + + export type UserFriendsNameFragmentFragment = { user: { friends: Array<{ name: string }> } }; export type SpreadFragmentQueryQueryVariables = Exact<{ [key: string]: never; }>; - export type SpreadFragmentQueryQuery = ( - { __typename?: 'Query' } - & { user: ( - { __typename?: 'User' } - & { friends: Array<( - { __typename?: 'User' } - & Pick - )> } - ) } - ); + export type SpreadFragmentQueryQuery = { user: { friends: Array<{ id: string, name: string }> } }; + " `); }); it('SpreadFragmentWithSelectionQuery', async () => { @@ -6176,37 +5224,18 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( schema, [{ location: '', document }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - }, + {}, + { outputFile: 'graphql.ts' }, ); - expect(content).toBeSimilarStringTo(` - export type UserFriendsNameFragmentFragment = ( - { __typename?: 'Query' } - & { user: ( - { __typename?: 'User' } - & { friends: Array<( - { __typename?: 'User' } - & Pick - )> } - ) } - ); + expect(content).toMatchInlineSnapshot(` + "export type UserFriendsNameFragmentFragment = { user: { friends: Array<{ name: string }> } }; export type SpreadFragmentWithSelectionQueryQueryVariables = Exact<{ [key: string]: never; }>; - export type SpreadFragmentWithSelectionQueryQuery = ( - { __typename?: 'Query' } - & { user: ( - { __typename?: 'User' } - & Pick - & { friends: Array<( - { __typename?: 'User' } - & Pick - )> } - ) } - ); + + export type SpreadFragmentWithSelectionQueryQuery = { user: { id: string, friends: Array<{ id: string, name: string }> } }; + " `); }); it('SpreadFragmentWithSelectionQuery - flatten', async () => { @@ -6233,37 +5262,18 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( schema, [{ location: '', document }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - }, + {}, + { outputFile: 'graphql.ts' }, ); - expect(content).toBeSimilarStringTo(` - export type UserFriendsNameFragmentFragment = ( - { __typename?: 'Query' } - & { user: ( - { __typename?: 'User' } - & { friends: Array<( - { __typename?: 'User' } - & Pick - )> } - ) } - ); + expect(content).toMatchInlineSnapshot(` + "export type UserFriendsNameFragmentFragment = { user: { friends: Array<{ name: string }> } }; export type SpreadFragmentWithSelectionQueryQueryVariables = Exact<{ [key: string]: never; }>; - export type SpreadFragmentWithSelectionQueryQuery = ( - { __typename?: 'Query' } - & { user: ( - { __typename?: 'User' } - & Pick - & { friends: Array<( - { __typename?: 'User' } - & Pick - )> } - ) } - ); + + export type SpreadFragmentWithSelectionQueryQuery = { user: { id: string, friends: Array<{ id: string, name: string }> } }; + " `); }); }); @@ -6328,26 +5338,17 @@ function test(q: GetEntityBrandDataQuery): void { "export type GetPeopleQueryVariables = Exact<{ [key: string]: never; }>; - export type GetPeopleQuery = { __typename?: 'Query', people: - | ( - { __typename?: 'Character' } - & { ' $fragmentRefs'?: { 'PeopleInfo_Character_Fragment': PeopleInfo_Character_Fragment } } - ) - | ( - { __typename?: 'Jedi' } - & { ' $fragmentRefs'?: { 'PeopleInfo_Jedi_Fragment': PeopleInfo_Jedi_Fragment } } - ) - | ( - { __typename?: 'Droid' } - & { ' $fragmentRefs'?: { 'PeopleInfo_Droid_Fragment': PeopleInfo_Droid_Fragment } } - ) + export type GetPeopleQuery = { people: + | { ' $fragmentRefs'?: { 'PeopleInfo_Character_Fragment': PeopleInfo_Character_Fragment } } + | { ' $fragmentRefs'?: { 'PeopleInfo_Jedi_Fragment': PeopleInfo_Jedi_Fragment } } + | { ' $fragmentRefs'?: { 'PeopleInfo_Droid_Fragment': PeopleInfo_Droid_Fragment } } }; - type PeopleInfo_Character_Fragment = { __typename?: 'Character', name?: string | null } & { ' $fragmentName'?: 'PeopleInfo_Character_Fragment' }; + type PeopleInfo_Character_Fragment = { name: string | null } & { ' $fragmentName'?: 'PeopleInfo_Character_Fragment' }; - type PeopleInfo_Jedi_Fragment = { __typename?: 'Jedi', side?: string | null } & { ' $fragmentName'?: 'PeopleInfo_Jedi_Fragment' }; + type PeopleInfo_Jedi_Fragment = { side: string | null } & { ' $fragmentName'?: 'PeopleInfo_Jedi_Fragment' }; - type PeopleInfo_Droid_Fragment = { __typename?: 'Droid', model?: string | null } & { ' $fragmentName'?: 'PeopleInfo_Droid_Fragment' }; + type PeopleInfo_Droid_Fragment = { model: string | null } & { ' $fragmentName'?: 'PeopleInfo_Droid_Fragment' }; export type PeopleInfoFragment = | PeopleInfo_Character_Fragment @@ -6358,7 +5359,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! @@ -6413,11 +5414,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(); }); @@ -6461,94 +5463,105 @@ function test(q: GetEntityBrandDataQuery): void { } `); - const config = { preResolveTypes: true }; + const { content } = await plugin( + testSchema, + [{ location: '', document: query }], + {}, + { outputFile: 'graphql.ts' }, + ); - const { content } = await plugin(testSchema, [{ location: '', document: query }], config, { - outputFile: 'graphql.ts', - }); + expect(content).toMatchInlineSnapshot(` + "export type SnakeQueryQueryVariables = Exact<{ [key: string]: never; }>; - expect(content).toMatchSnapshot(); + + export type SnakeQueryQuery = { __typename: 'Query', snake: + | { __typename: 'Snake' } + | { __typename: 'Error' } + }; + " + `); }); + }); - it('#8461 - conditional directives are ignored on fields with alias', async () => { - const testSchema = buildSchema(/* GraphQL */ ` - type User { - firstName: String! - lastName: Int! - address: Address! + describe('incremental delivery directive handling', () => { + it('should generate an union of initial and deferred fields for fragments', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Address { + street1: String! } - type Address { - postalCode: String! + type Phone { + home: String! + } + + type Employment { + title: String! + } + + type User { + name: String! + email: String! + address: Address! + phone: Phone! + employment: Employment! + widgetCount: Int! + widgetPreference: String! + clearanceLevel: String! + favoriteFood: String! + leastFavoriteFood: String! } type Query { - viewer: User! + user: User! } `); - const query = parse(/* GraphQL */ ` - query UserQuery($skipFirstName: Boolean!, $skipAddress: Boolean!) { - viewer { - givenName: firstName @skip(if: $skipFirstName) - lastName - mailingAddress: address @skip(if: $skipAddress) { - postalCode - } - } + const fragment = parse(/* GraphQL */ ` + fragment WidgetFragment on User { + widgetCount + widgetPreference } - `); - const config = { preResolveTypes: true }; + fragment FoodFragment on User { + favoriteFood + leastFavoriteFood + } - const { content } = await plugin(testSchema, [{ location: '', document: query }], config, { - outputFile: 'graphql.ts', - }); + fragment EmploymentFragment on User { + employment { + title + } + } - expect(content).toBeSimilarStringTo(` - export type UserQueryQueryVariables = Exact<{ - skipFirstName: Scalars['Boolean']['input']; - skipAddress: Scalars['Boolean']['input']; - }>; + query user { + user { + # Test inline fragment defer + ... @defer { + email + } - export type UserQueryQuery = { - __typename?: 'Query', - viewer: { - __typename?: 'User', - lastName: number, - givenName?: string, - mailingAddress?: { - __typename?: 'Address', - postalCode: string + # Test inline fragment defer with nested selection set + ... @defer { + address { + street1 + } } - } - }; - `); - }); - }); - describe('conditional directives handling', () => { - it('fields with @skip, @include should pre resolve into optional', async () => { - const schema = buildSchema(/* GraphQL */ ` - type Query { - user: User! - } + # Test named fragment defer + ...WidgetFragment @defer - type User { - name: String! - address: String! - nicknames: [String!] - parents: [User!]! - } - `); + # Test a secondary named fragment defer + ...FoodFragment @defer - const fragment = parse(/* GraphQL */ ` - query user($showAddress: Boolean!) { - user { + # Not deferred fields, fragments, selection sets, etc are left alone name - address @include(if: $showAddress) - nicknames @include(if: $showNicknames) - parents @include(if: $showParents) + phone { + home + } + ...EmploymentFragment + ... { + clearanceLevel + } } } `); @@ -6556,570 +5569,64 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( schema, [{ location: '', document: fragment }], - { - preResolveTypes: true, - }, - { - outputFile: 'graphql.ts', - }, + {}, + { outputFile: 'graphql.ts' }, ); - expect(content).toBeSimilarStringTo(` - export type UserQueryVariables = Exact<{ - showAddress: Scalars['Boolean']['input']; - }>; + expect(content).toMatchInlineSnapshot(` + "export type WidgetFragmentFragment = { widgetCount: number, widgetPreference: string }; + + export type FoodFragmentFragment = { favoriteFood: string, leastFavoriteFood: string }; + + export type EmploymentFragmentFragment = { employment: { title: string } }; - export type UserQuery = { __typename?: 'Query', user: { __typename?: 'User', name: string, address?: string, nicknames?: Array | null, parents?: Array } };`); + 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, widgetPreference: string } | { widgetCount?: never, widgetPreference?: never }) & ({ favoriteFood: string, leastFavoriteFood: string } | { favoriteFood?: never, leastFavoriteFood?: never }) }; + " + `); }); - it('objects with @skip, @include should pre resolve into optional', async () => { + it('should resolve optionals according to maybeValue together with deferred fragments', async () => { const schema = buildSchema(/* GraphQL */ ` - type Query { - user: User! + type Address { + street1: String + } + + type Phone { + home: String! + } + + type Employment { + title: String! } type User { - id: String! name: String! + email: String! address: Address! - friends: [User!]! - moreFriends: [User!]! + phone: Phone! + employment: Employment! + widgetName: String! + widgetCount: Int! + clearanceLevel: String! } - type Address { - city: String! + type Query { + user: User! } `); 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: true, - }, - { - outputFile: 'graphql.ts', - }, - ); - - expect(content).toBeSimilarStringTo(` - export type UserQueryVariables = Exact<{ - showAddress: Scalars['Boolean']['input']; - showName: Scalars['Boolean']['input']; - }>; - export type UserQuery = { __typename?: 'Query', user: { __typename?: 'User', id: string, name?: string, address?: { __typename?: 'Address', city: string }, friends?: Array<{ __typename?: 'User', id: string }> } };`); - }); - - 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).toBeSimilarStringTo(` - export type UserQueryVariables = Exact<{ - showAddress: Scalars['Boolean']['input']; - showName: Scalars['Boolean']['input']; - }>; - - export type UserQuery = ( - { __typename?: 'Query' } - & { user: ( - { __typename?: 'User' } - & MakeOptional, 'name'> - & { address?: ( - { __typename?: 'Address' } - & Pick - ), friends?: Array<( - { __typename?: 'User' } - & Pick - )> } - ) } - );`); - }); - - it('On avoidOptionals:true, fields with @skip, @include should make container resolve into MakeMaybe type', async () => { - const schema = buildSchema(/* GraphQL */ ` - type Query { - user(id: ID!): User! - } - - type User { - id: ID! - username: String! - email: String! - } - `); - - const fragment = parse(/* GraphQL */ ` - query user { - user(id: 1) { - id - username - email @skip(if: true) - } - } - `); - - const { content } = await plugin( - schema, - [{ location: '', document: fragment }], - { - avoidOptionals: true, - preResolveTypes: false, - }, - { - outputFile: 'graphql.ts', - }, - ); - - expect(content).toBeSimilarStringTo(` - export type UserQueryVariables = Exact<{ [key: string]: never; }>; - - export type UserQuery = ( - { __typename?: 'Query' } - & { user: ( - { __typename?: 'User' } - & MakeMaybe, 'email'> - ) } - ); - `); - }); - - it('Should handle "preResolveTypes" and "avoidOptionals" together', 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 = { avoidOptionals: true, preResolveTypes: true }; - const { content } = await plugin(schema, [{ location: '', document: operations }], config, { - outputFile: 'graphql.ts', - }); - - expect(content).toBeSimilarStringTo( - `export type UserQuery = { __typename?: 'Query', user: { __typename?: 'User', id: string, username: string, email: string | null } }`, - ); - }); - - it('On avoidOptionals:true, optionals (?) on types should be avoided', async () => { - const schema = buildSchema(/* GraphQL */ ` - type Query { - me: User! - } - - type User { - messages: [Message!]! - } - - type Message { - content: String! - } - `); - - const fragment = parse(/* GraphQL */ ` - query MyQuery($include: Boolean!) { - me { - messages @include(if: $include) { - content - } - } - } - `); - - const { content } = await plugin( - schema, - [{ location: '', document: fragment }], - { - avoidOptionals: true, - nonOptionalTypename: true, - preResolveTypes: false, - }, - { - outputFile: 'graphql.ts', - }, - ); - - expect(content).toBeSimilarStringTo(` - export type MyQueryQuery = ( - { __typename: 'Query' } - & { me: ( - { __typename: 'User' } - & { messages?: Array<( - { __typename: 'Message' } - & Pick - )> } - ) } - ); - `); - }); - - it('inline fragment with conditional directives and avoidOptionals', 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: true, avoidOptionals: true }, - { - outputFile: 'graphql.ts', - }, - ); - - expect(content).toBeSimilarStringTo(` - export type UserQuery = { - __typename?: 'Query', - user?: { - __typename?: 'User', - name: string | null - } | null, - group?: { - __typename?: 'Group', - id: number - } - };`); - }); - - it('resolve optionals according to maybeValue together with avoidOptionals and conditional directives', async () => { - const schema = buildSchema(/* GraphQL */ ` - type Query { - user: User! - } - - type User { - name: String! - age: Int - address: String! - nicknames: [String!] - parents: [User!]! - } - `); - - const fragment = parse(/* GraphQL */ ` - query user($showProperty: Boolean!) { - user { - name - age - address @include(if: $showProperty) - nicknames @include(if: $showProperty) - parents @include(if: $showProperty) - } - } - `); - - const { content } = await plugin( - schema, - [{ location: '', document: fragment }], - { - preResolveTypes: true, - maybeValue: "T | 'specialType'", - avoidOptionals: true, - }, - { - outputFile: 'graphql.ts', - }, - ); - expect(content).toBeSimilarStringTo(` - export type UserQuery = { __typename?: 'Query', user: { __typename?: 'User', name: string, age: number | 'specialType', address?: string, nicknames?: Array | 'specialType', parents?: Array } }; - `); - }); - - it('inline fragment with conditional directives and avoidOptionals, 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, avoidOptionals: true }, - { - outputFile: 'graphql.ts', - }, - ); - - expect(content).toBeSimilarStringTo(` - export type UserQuery = ( - { __typename?: 'Query' } - & { user?: Maybe<( - { __typename?: 'User' } - & Pick - )>, group?: ( - { __typename?: 'Group' } - & Pick - ) } - );`); - }); - }); - - describe('incremental delivery directive handling', () => { - it('should generate an union of initial and deferred fields for fragments (preResolveTypes: true)', async () => { - const schema = buildSchema(` - 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! - widgetPreference: String! - clearanceLevel: String! - favoriteFood: String! - leastFavoriteFood: String! - } - - type Query { - user: User! - } - `); - - const fragment = parse(` - fragment WidgetFragment on User { - widgetCount - widgetPreference - } - - fragment FoodFragment on User { - favoriteFood - leastFavoriteFood - } - - 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 - - # Test a secondary named fragment defer - ...FoodFragment @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).toBeSimilarStringTo(` - export type UserQueryVariables = Exact<{ [key: string]: never; }>; - export type UserQuery = { - __typename?: 'Query', - user: { - __typename?: 'User', - clearanceLevel: string, - name: string, - phone: { - __typename?: 'Phone', - home: string - }, - employment: { - __typename?: 'Employment', - title: string - } - } & ({ __typename?: 'User', email: string } - | { __typename?: 'User', email?: never }) - & ({ __typename?: 'User', address: { __typename?: 'Address', street1: string } } - | { __typename?: 'User', address?: never }) - & ({ __typename?: 'User', widgetCount: number, widgetPreference: string } - | { __typename?: 'User', widgetCount?: never, widgetPreference?: never }) - & ({ __typename?: 'User', favoriteFood: string, leastFavoriteFood: string } - | { __typename?: 'User', favoriteFood?: never, leastFavoriteFood?: never }) }; - `); - }); - - it('should generate an union of initial and deferred fields for fragments using MakeEmpty (preResolveTypes: false)', async () => { - const schema = buildSchema(` - 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(` - fragment WidgetFragment on User { - widgetCount - } - - fragment EmploymentFragment on User { - employment { - title + fragment WidgetFragment on User { + widgetName + widgetCount + } + + fragment EmploymentFragment on User { + employment { + title } } @@ -7156,208 +5663,25 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( schema, [{ location: '', document: fragment }], - { preResolveTypes: false }, + { maybeValue: "T | 'specialType'" }, { outputFile: 'graphql.ts' }, ); - expect(content).toBeSimilarStringTo(` - export type WidgetFragmentFragment = ( - { __typename?: 'User' } - & Pick - ); + expect(content).toMatchInlineSnapshot(` + "export type WidgetFragmentFragment = { widgetName: string, widgetCount: number }; - export type EmploymentFragmentFragment = ( - { __typename?: 'User' } - & { employment: ( - { __typename?: 'Employment' } - & Pick - ) } - ); + export type EmploymentFragmentFragment = { employment: { title: string } }; export type UserQueryVariables = Exact<{ [key: string]: never; }>; - export type UserQuery = ( - { __typename?: 'Query' } - & { user: ( - { __typename?: 'User' } - & Pick - & { phone: ( - { __typename?: 'Phone' } - & Pick - ), employment: ( - { __typename?: 'Employment' } - & Pick - ) } - ) & (( - { __typename?: 'User' } - & Pick - ) | ( - { __typename?: 'User' } - & MakeEmpty - )) & (( - { __typename?: 'User' } - & { address: ( - { __typename?: 'Address' } - & Pick - ) } - ) | ( - { __typename?: 'User' } - & { address?: ( - { __typename?: 'Address' } - & Pick - ) } - )) & (( - { __typename?: 'User' } - & Pick - ) | ( - { __typename?: 'User' } - & MakeEmpty - )) } - ); - `); - }); - - it('should generate an union of initial and deferred fields for fragments MakeEmpty (avoidOptionals: true)', async () => { - const schema = buildSchema(` - 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(` - 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 }], - { - avoidOptionals: true, - preResolveTypes: false, - }, - { outputFile: 'graphql.ts' }, - ); - - expect(content).toBeSimilarStringTo(` - export type WidgetFragmentFragment = ( - { __typename?: 'User' } - & Pick - ); - - export type EmploymentFragmentFragment = ( - { __typename?: 'User' } - & { employment: ( - { __typename?: 'Employment' } - & Pick - ) } - ); - - export type UserQueryVariables = Exact<{ [key: string]: never; }>; - export type UserQuery = ( - { __typename?: 'Query' } - & { user: ( - { __typename?: 'User' } - & Pick - & { phone: ( - { __typename?: 'Phone' } - & Pick - ), employment: ( - { __typename?: 'Employment' } - & Pick - ) } - ) & (( - { __typename?: 'User' } - & Pick - ) | ( - { __typename?: 'User' } - & MakeEmpty - )) & (( - { __typename?: 'User' } - & { address: ( - { __typename?: 'Address' } - & Pick - ) } - ) | ( - { __typename?: 'User' } - & { address?: ( - { __typename?: 'Address' } - & Pick - ) } - )) & (( - { __typename?: 'User' } - & Pick - ) | ( - { __typename?: 'User' } - & MakeEmpty - )) } - ); + export type UserQuery = { user: { clearanceLevel: string, name: string, phone: { home: string }, employment: { title: string } } & ({ email: string } | { email?: never }) & ({ address: { street1: string | 'specialType' } } | { address?: never }) & ({ widgetName: string, widgetCount: number } | { widgetName?: never, widgetCount?: never }) }; + " `); }); - it('should support "preResolveTypes: true" and "avoidOptionals: true" together', async () => { - const schema = buildSchema(` + it('should generate correct types with inlineFragmentTypes: "mask""', async () => { + const schema = buildSchema(/* GraphQL */ ` type Address { street1: String! } @@ -7377,7 +5701,10 @@ function test(q: GetEntityBrandDataQuery): void { phone: Phone! employment: Employment! widgetCount: Int! + widgetPreference: String! clearanceLevel: String! + favoriteFood: String! + leastFavoriteFood: String! } type Query { @@ -7385,111 +5712,15 @@ function test(q: GetEntityBrandDataQuery): void { } `); - const fragment = parse(` + const fragment = parse(/* GraphQL */ ` fragment WidgetFragment on User { widgetCount + widgetPreference } - 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 }], - { - avoidOptionals: true, - preResolveTypes: true, - }, - { outputFile: 'graphql.ts' }, - ); - - expect(content).toBeSimilarStringTo(` - export type UserQueryVariables = Exact<{ [key: string]: never; }>; - export type UserQuery = { - __typename?: 'Query', - user: { - __typename?: 'User', - clearanceLevel: string, - name: string, - phone: { __typename?: 'Phone', home: string }, - employment: { __typename?: 'Employment', title: string } - } & ({ __typename?: 'User', email: string } - | { __typename?: 'User', email?: never }) - & ({ __typename?: 'User', address: { __typename?: 'Address', street1: string } } - | { __typename?: 'User', address?: never }) - & ({ __typename?: 'User', widgetCount: number } - | { __typename?: 'User', widgetCount?: never }) - }; - `); - }); - - it('should resolve optionals according to maybeValue together with avoidOptionals and deferred fragments', async () => { - const schema = buildSchema(` - 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(` - fragment WidgetFragment on User { - widgetName - widgetCount + fragment FoodFragment on User { + favoriteFood + leastFavoriteFood } fragment EmploymentFragment on User { @@ -7515,6 +5746,9 @@ function test(q: GetEntityBrandDataQuery): void { # Test named fragment defer ...WidgetFragment @defer + # Test a secondary named fragment defer + ...FoodFragment @defer + # Not deferred fields, fragments, selection sets, etc are left alone name phone { @@ -7528,152 +5762,35 @@ function test(q: GetEntityBrandDataQuery): void { } `); - const { content } = await plugin( - schema, - [{ location: '', document: fragment }], - { - preResolveTypes: true, - maybeValue: "T | 'specialType'", - avoidOptionals: true, - }, - { outputFile: 'graphql.ts' }, - ); - - expect(content).toBeSimilarStringTo(` - export type UserQueryVariables = Exact<{ [key: string]: never; }>; - export type UserQuery = { - __typename?: 'Query', - user: { - __typename?: 'User', - clearanceLevel: string, - name: string, - phone: { __typename?: 'Phone', home: string }, - employment: { __typename?: 'Employment', title: string } - } & ({ __typename?: 'User', email: string } - | { __typename?: 'User', email?: never }) - & ({ __typename?: 'User', address: { __typename?: 'Address', street1: string | 'specialType' } } - | { __typename?: 'User', address?: never }) - & ({ __typename?: 'User', widgetName: string, widgetCount: number } - | { __typename?: 'User', widgetName?: never, widgetCount?: never }) - }; - `); - }); - - it('should generate correct types with inlineFragmentTypes: "mask""', async () => { - const schema = buildSchema(` - 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! - widgetPreference: String! - clearanceLevel: String! - favoriteFood: String! - leastFavoriteFood: String! - } - - type Query { - user: User! - } - `); - - const fragment = parse(` - fragment WidgetFragment on User { - widgetCount - widgetPreference - } - - fragment FoodFragment on User { - favoriteFood - leastFavoriteFood - } - - 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 - - # Test a secondary named fragment defer - ...FoodFragment @defer - - # Not deferred fields, fragments, selection sets, etc are left alone - name - phone { - home - } - ...EmploymentFragment - ... { - clearanceLevel - } - } - } - `); + const content = mergeOutputs([ + await plugin( + schema, + [{ location: '', document: fragment }], + { inlineFragmentTypes: 'mask' }, + { outputFile: 'graphql.ts' }, + ), + ]); - const { content } = await plugin( - schema, - [{ location: '', document: fragment }], - { preResolveTypes: true, inlineFragmentTypes: 'mask' }, - { outputFile: 'graphql.ts' }, - ); + expect(content).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type WidgetFragmentFragment = { widgetCount: number, widgetPreference: string } & { ' $fragmentName'?: 'WidgetFragmentFragment' }; - expect(content).toBeSimilarStringTo(` - export type WidgetFragmentFragment = { __typename?: 'User', widgetCount: number, widgetPreference: string } & { ' $fragmentName'?: 'WidgetFragmentFragment' }; + export type FoodFragmentFragment = { favoriteFood: string, leastFavoriteFood: string } & { ' $fragmentName'?: 'FoodFragmentFragment' }; - export type FoodFragmentFragment = { __typename?: 'User', favoriteFood: string, leastFavoriteFood: string } & { ' $fragmentName'?: 'FoodFragmentFragment' }; + export type EmploymentFragmentFragment = { employment: { title: string } } & { ' $fragmentName'?: 'EmploymentFragmentFragment' }; - export type EmploymentFragmentFragment = { __typename?: 'User', employment: { __typename?: 'Employment', title: string } } & { ' $fragmentName'?: 'EmploymentFragmentFragment' }; + export type UserQueryVariables = Exact<{ [key: string]: never; }>; - export type UserQueryVariables = Exact<{ [key: string]: never; }>; - export type UserQuery = { - __typename?: 'Query', - user: ( - { - __typename?: 'User', - clearanceLevel: string, - name: string, - phone: { __typename?: 'Phone', home: string } - } & { ' $fragmentRefs'?: { 'EmploymentFragmentFragment': EmploymentFragmentFragment } } - ) & ({ __typename?: 'User', email: string } | { __typename?: 'User', email?: never }) & ({ __typename?: 'User', address: { __typename?: 'Address', street1: string } } | { __typename?: 'User', address?: never }) & ( - { __typename?: 'User' } - & { ' $fragmentRefs'?: { 'WidgetFragmentFragment': Incremental } } - ) & ( - { __typename?: 'User' } - & { ' $fragmentRefs'?: { 'FoodFragmentFragment': Incremental } } - ) }; - `); + export type UserQuery = { user: ( + { clearanceLevel: string, name: string, phone: { home: string } } + & { ' $fragmentRefs'?: { 'EmploymentFragmentFragment': EmploymentFragmentFragment } } + ) & ({ email: string } | { email?: never }) & ({ address: { street1: string } } | { address?: never }) & { ' $fragmentRefs'?: { 'WidgetFragmentFragment': Incremental } } & { ' $fragmentRefs'?: { 'FoodFragmentFragment': Incremental } } }; + " + `); }); }); @@ -7689,22 +5806,18 @@ function test(q: GetEntityBrandDataQuery): void { const result = await plugin( schema, [{ location: 'test-file.ts', document: ast }], - { preResolveTypes: false }, + {}, { outputFile: '' }, ); - expect(result.content).toBeSimilarStringTo(` - export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - - export type Unnamed_1_Query = ( - { __typename?: 'Query' } - & { notifications: Array<( - { __typename?: 'TextNotification' } - & Pick - ) | ( - { __typename?: 'ImageNotification' } - & Pick - )> } - ); + expect(result.content).toMatchInlineSnapshot(` + "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; + + + export type Unnamed_1_Query = { notifications: Array< + | { id: string } + | { id: string } + > }; + " `); }); @@ -7726,16 +5839,14 @@ function test(q: GetEntityBrandDataQuery): void { { inlineFragmentTypes: 'combine' }, { outputFile: '' }, ); - expect(result.content).toBeSimilarStringTo(` - export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; + expect(result.content).toMatchInlineSnapshot(` + "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_1_Query = { __typename?: 'Query', me?: ( - { __typename?: 'User' } - & UserFragmentFragment - ) | null }; + export type Unnamed_1_Query = { me: UserFragmentFragment | null }; - export type UserFragmentFragment = { __typename?: 'User', id: string }; + export type UserFragmentFragment = { id: string }; + " `); }); @@ -7756,13 +5867,14 @@ function test(q: GetEntityBrandDataQuery): void { { inlineFragmentTypes: 'inline' }, { outputFile: '' }, ); - expect(result.content).toBeSimilarStringTo(` - export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; + expect(result.content).toMatchInlineSnapshot(` + "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_1_Query = { __typename?: 'Query', me?: { __typename?: 'User', id: string } | null }; + export type Unnamed_1_Query = { me: { id: string } | null }; - export type UserFragmentFragment = { __typename?: 'User', id: string }; + export type UserFragmentFragment = { id: string }; + " `); }); @@ -7783,16 +5895,14 @@ function test(q: GetEntityBrandDataQuery): void { { inlineFragmentTypes: 'mask' }, { outputFile: '' }, ); - expect(result.content).toBeSimilarStringTo(` - export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; + expect(result.content).toMatchInlineSnapshot(` + "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_1_Query = { __typename?: 'Query', me?: ( - { __typename?: 'User' } - & { ' $fragmentRefs'?: { 'UserFragmentFragment': UserFragmentFragment } } - ) | null }; + export type Unnamed_1_Query = { me: { ' $fragmentRefs'?: { 'UserFragmentFragment': UserFragmentFragment } } | null }; - export type UserFragmentFragment = { __typename?: 'User', id: string } & { ' $fragmentName'?: 'UserFragmentFragment' }; + export type UserFragmentFragment = { id: string } & { ' $fragmentName'?: 'UserFragmentFragment' }; + " `); }); }); diff --git a/packages/plugins/typescript/operations/tests/ts-documents.standalone.config.avoidOptionals.spec.ts b/packages/plugins/typescript/operations/tests/ts-documents.standalone.config.avoidOptionals.spec.ts new file mode 100644 index 00000000000..781d5636975 --- /dev/null +++ b/packages/plugins/typescript/operations/tests/ts-documents.standalone.config.avoidOptionals.spec.ts @@ -0,0 +1,482 @@ +import { buildSchema, parse } from 'graphql'; +import { mergeOutputs } from '@graphql-codegen/plugin-helpers'; +import { validateTs } from '@graphql-codegen/testing'; +import { plugin } from '../src/index.js'; + +describe('TypeScript Operations Plugin - config.avoidOptionals', () => { + it('generates optional for nullable Variables and Input by default', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(input: UserInput): User + } + + input UserInput { + id: ID! + id2: ID! = "default-id" + legacyId: ID + legacyId2: ID = "default-legacy-id" + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + nickname: String + } + + "UserRole Description" + enum UserRole { + "UserRole ADMIN" + ADMIN + "UserRole CUSTOMER" + CUSTOMER + } + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query User( + $testNullable: ID + $testNonNullable: ID! + $inputNullable: UserInput + $inputNonNullable: UserInput! + ) { + user(input: $input) { + id + name + nickname + } + } + `); + + const result = mergeOutputs([await plugin(schema, [{ document }], {}, { outputFile: '' })]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserInput = { + id: string | number; + id2?: string | number; + legacyId?: string | number | null | undefined; + legacyId2?: string | number | null | undefined; + }; + + export type UserQueryVariables = Exact<{ + testNullable?: string | number | null | undefined; + testNonNullable: string | number; + inputNullable?: UserInput | null | undefined; + inputNonNullable: UserInput; + }>; + + + export type UserQuery = { user: { id: string, name: string, nickname: string | null } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('generates non-optional Variables and Input when `avoidOptionals:true`', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(input: UserInput): User + } + + input UserInput { + id: ID! + id2: ID! = "default-id" + legacyId: ID + legacyId2: ID = "default-legacy-id" + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + nickname: String + } + + "UserRole Description" + enum UserRole { + "UserRole ADMIN" + ADMIN + "UserRole CUSTOMER" + CUSTOMER + } + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query User( + $testNullable: ID + $testNonNullable: ID! + $inputNullable: UserInput + $inputNonNullable: UserInput! + ) { + user(input: $input) { + id + name + nickname + } + } + `); + + const result = mergeOutputs([ + await plugin(schema, [{ document }], { avoidOptionals: true }, { outputFile: '' }), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserInput = { + id: string | number; + id2: string | number; + legacyId: string | number | null | undefined; + legacyId2: string | number | null | undefined; + }; + + export type UserQueryVariables = Exact<{ + testNullable: string | number | null | undefined; + testNonNullable: string | number; + inputNullable: UserInput | null | undefined; + inputNonNullable: UserInput; + }>; + + + export type UserQuery = { user: { id: string, name: string, nickname: string | null } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('generates non-optional Input when `avoidOptionals.inputValue:true`', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(input: UserInput): User + } + + input UserInput { + id: ID! + id2: ID! = "default-id" + legacyId: ID + legacyId2: ID = "default-legacy-id" + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + nickname: String + } + + "UserRole Description" + enum UserRole { + "UserRole ADMIN" + ADMIN + "UserRole CUSTOMER" + CUSTOMER + } + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query User($test: ID, $input: UserInput) { + user { + id + name + nickname + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + avoidOptionals: { + inputValue: true, + }, + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserInput = { + id: string | number; + id2: string | number; + legacyId: string | number | null | undefined; + legacyId2: string | number | null | undefined; + }; + + export type UserQueryVariables = Exact<{ + test?: string | number | null | undefined; + input?: UserInput | null | undefined; + }>; + + + export type UserQuery = { user: { id: string, name: string, nickname: string | null } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('generates non-optional Input with defaults when `avoidOptionals.defaultValue:true`', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(input: UserInput): User + } + + input UserInput { + id: ID! + id2: ID! = "default-id" + legacyId: ID + legacyId2: ID = "default-legacy-id" + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + nickname: String + } + + "UserRole Description" + enum UserRole { + "UserRole ADMIN" + ADMIN + "UserRole CUSTOMER" + CUSTOMER + } + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query User($test: ID, $input: UserInput) { + user { + id + name + nickname + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + avoidOptionals: { + defaultValue: true, + }, + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserInput = { + id: string | number; + id2: string | number; + legacyId?: string | number | null | undefined; + legacyId2?: string | number | null | undefined; + }; + + export type UserQueryVariables = Exact<{ + test?: string | number | null | undefined; + input?: UserInput | null | undefined; + }>; + + + export type UserQuery = { user: { id: string, name: string, nickname: string | null } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('generates non-optional Variable when `avoidOptionals.variableValue:true`', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(input: UserInput): User + } + + input UserInput { + id: ID! + id2: ID! = "default-id" + legacyId: ID + legacyId2: ID = "default-legacy-id" + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + nickname: String + } + + "UserRole Description" + enum UserRole { + "UserRole ADMIN" + ADMIN + "UserRole CUSTOMER" + CUSTOMER + } + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query User($test: ID, $input: UserInput) { + user { + id + name + nickname + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + avoidOptionals: { + variableValue: true, + }, + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserInput = { + id: string | number; + id2?: string | number; + legacyId?: string | number | null | undefined; + legacyId2?: string | number | null | undefined; + }; + + export type UserQueryVariables = Exact<{ + test: string | number | null | undefined; + input: UserInput | null | undefined; + }>; + + + export type UserQuery = { user: { id: string, name: string, nickname: string | null } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('generates optional Variable if there is a default value when `avoidOptionals.variableValue:true` and `avoidOptionals.defaultValue:false`', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(input: UserInput): User + } + + input UserInput { + id: ID! + id2: ID! = "default-id" + legacyId: ID + legacyId2: ID = "default-legacy-id" + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + nickname: String + } + + "UserRole Description" + enum UserRole { + "UserRole ADMIN" + ADMIN + "UserRole CUSTOMER" + CUSTOMER + } + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query User( + $test: ID # This does not have a default, so it will be non-optional (given the config) + $testWithDefault: ID = "100" # This has a default, so it will be optional (given the config) + $input: UserInput # This does not have a default, so it will be non-optional (given the config) + $inputWithDefault: UserInput = { id: "200" } # This has a default, so it will be optional (given the config) + ) { + user { + id + name + nickname + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + avoidOptionals: { + variableValue: true, + defaultValue: false, + }, + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserInput = { + id: string | number; + id2?: string | number; + legacyId?: string | number | null | undefined; + legacyId2?: string | number | null | undefined; + }; + + export type UserQueryVariables = Exact<{ + test: string | number | null | undefined; + testWithDefault?: string | number | null | undefined; + input: UserInput | null | undefined; + inputWithDefault?: UserInput | null | undefined; + }>; + + + export type UserQuery = { user: { id: string, name: string, nickname: string | null } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); +}); diff --git a/packages/plugins/typescript/operations/tests/ts-documents.standalone.config.declarationKind.spec.ts b/packages/plugins/typescript/operations/tests/ts-documents.standalone.config.declarationKind.spec.ts new file mode 100644 index 00000000000..ffe5cce9f93 --- /dev/null +++ b/packages/plugins/typescript/operations/tests/ts-documents.standalone.config.declarationKind.spec.ts @@ -0,0 +1,445 @@ +import { buildSchema, parse } from 'graphql'; +import { mergeOutputs } from '@graphql-codegen/plugin-helpers'; +import { validateTs } from '@graphql-codegen/testing'; +import { plugin } from '../src/index.js'; + +const warnSpy = vi.spyOn(console, 'warn'); + +describe('TypeScript Operations Plugin - config.declarationKind', () => { + beforeEach(() => { + warnSpy.mockReset(); + warnSpy.mockImplementation(() => {}); + }); + + it('generates interface for Input and Result when declarationKind:interface', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(id: ID!): User + } + type Mutation { + updateUser(id: ID!, changes: UpdateUserChangesInput!): User + } + type Subscription { + userUpdates(id: ID!): User + } + + input UpdateUserChangesInput { + name: String + role: UserRole + } + + type User { + id: ID! + name: String! + role: UserRole! + } + + enum UserRole { + ADMIN + CUSTOMER + } + `); + const document = parse(/* GraphQL */ ` + query User($id: ID!) { + user(id: $id) { + id + name + } + } + + mutation UpdateUser($input: UpdateUserChangesInput!) { + updateUser(id: "100", input: $input) { + id + name + } + } + + subscription UserUpdates { + userUpdates(id: "200") { + id + name + } + } + `); + + const result = mergeOutputs([ + await plugin(schema, [{ document }], { declarationKind: 'interface' }, { outputFile: '' }), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export interface UpdateUserChangesInput { + name?: string | null | undefined; + role?: UserRole | null | undefined; + } + + export type UserRole = + | 'ADMIN' + | 'CUSTOMER'; + + export type UserQueryVariables = Exact<{ + id: string | number; + }>; + + + export interface UserQuery { user: { id: string, name: string } | null } + + export type UpdateUserMutationVariables = Exact<{ + input: UpdateUserChangesInput; + }>; + + + export interface UpdateUserMutation { updateUser: { id: string, name: string } | null } + + export type UserUpdatesSubscriptionVariables = Exact<{ [key: string]: never; }>; + + + export interface UserUpdatesSubscription { userUpdates: { id: string, name: string } | null } + " + `); + expect(warnSpy).not.toHaveBeenCalled(); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('handles partial object option correctly', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(id: ID!): User + } + type Mutation { + updateUser(id: ID!, changes: UpdateUserChangesInput!): User + } + type Subscription { + userUpdates(id: ID!): User + } + + input UpdateUserChangesInput { + name: String + role: UserRole + } + + type User { + id: ID! + name: String! + role: UserRole! + } + + enum UserRole { + ADMIN + CUSTOMER + } + `); + const document = parse(/* GraphQL */ ` + query User($id: ID!) { + user(id: $id) { + id + name + } + } + + mutation UpdateUser($input: UpdateUserChangesInput!) { + updateUser(id: "100", input: $input) { + id + name + } + } + + subscription UserUpdates { + userUpdates(id: "200") { + id + name + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + declarationKind: { + result: 'interface', // `result` value is `interface`, and `input` value is `type` (default) + }, + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UpdateUserChangesInput = { + name?: string | null | undefined; + role?: UserRole | null | undefined; + }; + + export type UserRole = + | 'ADMIN' + | 'CUSTOMER'; + + export type UserQueryVariables = Exact<{ + id: string | number; + }>; + + + export interface UserQuery { user: { id: string, name: string } | null } + + export type UpdateUserMutationVariables = Exact<{ + input: UpdateUserChangesInput; + }>; + + + export interface UpdateUserMutation { updateUser: { id: string, name: string } | null } + + export type UserUpdatesSubscriptionVariables = Exact<{ [key: string]: never; }>; + + + export interface UserUpdatesSubscription { userUpdates: { id: string, name: string } | null } + " + `); + expect(warnSpy).not.toHaveBeenCalled(); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('generates type for Result when declarationKind.result:interface but extractAllFieldsToTypes:true, but warns user', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(id: ID!): User + } + type Mutation { + updateUser(id: ID!, changes: UpdateUserChangesInput!): User + } + type Subscription { + userUpdates(id: ID!): User + } + + input UpdateUserChangesInput { + name: String + role: UserRole + } + + type User { + id: ID! + name: String! + role: UserRole! + } + + enum UserRole { + ADMIN + CUSTOMER + } + `); + const document = parse(/* GraphQL */ ` + query User($id: ID!) { + user(id: $id) { + id + name + } + } + + mutation UpdateUser($input: UpdateUserChangesInput!) { + updateUser(id: "100", input: $input) { + id + name + } + } + + subscription UserUpdates { + userUpdates(id: "200") { + id + name + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + extractAllFieldsToTypes: true, + declarationKind: 'interface', + }, + { outputFile: '' }, + ), + ]); + + expect(warnSpy).toHaveBeenCalledTimes(1); + expect(warnSpy).toHaveBeenNthCalledWith( + 1, + "`declarationKind.result` has been set to `'type'` because `extractAllFieldsToTypes` or `extractAllFieldsToTypesCompact` is true", + ); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export interface UpdateUserChangesInput { + name?: string | null | undefined; + role?: UserRole | null | undefined; + } + + export type UserRole = + | 'ADMIN' + | 'CUSTOMER'; + + export type UserQuery_user_User = { id: string, name: string }; + + export type UserQuery_Query = { user: UserQuery_user_User | null }; + + + export type UserQueryVariables = Exact<{ + id: string | number; + }>; + + + export type UserQuery = UserQuery_Query; + + export type UpdateUserMutation_updateUser_User = { id: string, name: string }; + + export type UpdateUserMutation_Mutation = { updateUser: UpdateUserMutation_updateUser_User | null }; + + + export type UpdateUserMutationVariables = Exact<{ + input: UpdateUserChangesInput; + }>; + + + export type UpdateUserMutation = UpdateUserMutation_Mutation; + + export type UserUpdatesSubscription_userUpdates_User = { id: string, name: string }; + + export type UserUpdatesSubscription_Subscription = { userUpdates: UserUpdatesSubscription_userUpdates_User | null }; + + + export type UserUpdatesSubscriptionVariables = Exact<{ [key: string]: never; }>; + + + export type UserUpdatesSubscription = UserUpdatesSubscription_Subscription; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('generates type for Result when declarationKind.result:interface and extractAllFieldsToTypesCompact:true, but warns user', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(id: ID!): User + } + type Mutation { + updateUser(id: ID!, changes: UpdateUserChangesInput!): User + } + type Subscription { + userUpdates(id: ID!): User + } + + input UpdateUserChangesInput { + name: String + role: UserRole + } + + type User { + id: ID! + name: String! + role: UserRole! + } + + enum UserRole { + ADMIN + CUSTOMER + } + `); + const document = parse(/* GraphQL */ ` + query User($id: ID!) { + user(id: $id) { + id + name + } + } + + mutation UpdateUser($input: UpdateUserChangesInput!) { + updateUser(id: "100", input: $input) { + id + name + } + } + + subscription UserUpdates { + userUpdates(id: "200") { + id + name + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + extractAllFieldsToTypesCompact: true, + declarationKind: 'interface', + }, + { outputFile: '' }, + ), + ]); + + expect(warnSpy).toHaveBeenCalledTimes(1); + expect(warnSpy).toHaveBeenNthCalledWith( + 1, + "`declarationKind.result` has been set to `'type'` because `extractAllFieldsToTypes` or `extractAllFieldsToTypesCompact` is true", + ); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export interface UpdateUserChangesInput { + name?: string | null | undefined; + role?: UserRole | null | undefined; + } + + export type UserRole = + | 'ADMIN' + | 'CUSTOMER'; + + export type UserQuery_user = { id: string, name: string }; + + export type UserQuery = { user: UserQuery_user | null }; + + + export type UserQueryVariables = Exact<{ + id: string | number; + }>; + + export type UpdateUserMutation_updateUser = { id: string, name: string }; + + export type UpdateUserMutation = { updateUser: UpdateUserMutation_updateUser | null }; + + + export type UpdateUserMutationVariables = Exact<{ + input: UpdateUserChangesInput; + }>; + + export type UserUpdatesSubscription_userUpdates = { id: string, name: string }; + + export type UserUpdatesSubscription = { userUpdates: UserUpdatesSubscription_userUpdates | null }; + + + export type UserUpdatesSubscriptionVariables = Exact<{ [key: string]: never; }>; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); +}); diff --git a/packages/plugins/typescript/operations/tests/ts-documents.standalone.enum.spec.ts b/packages/plugins/typescript/operations/tests/ts-documents.standalone.enum.spec.ts new file mode 100644 index 00000000000..921f451f72d --- /dev/null +++ b/packages/plugins/typescript/operations/tests/ts-documents.standalone.enum.spec.ts @@ -0,0 +1,1756 @@ +import { buildSchema, parse } from 'graphql'; +import { mergeOutputs } from '@graphql-codegen/plugin-helpers'; +import { validateTs } from '@graphql-codegen/testing'; +import { plugin } from '../src/index.js'; + +describe('TypeScript Operations Plugin - Enum', () => { + it('does not generate enums if not used in variables and result', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + enum UserRole { + ADMIN + CUSTOMER + } + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query Me { + me { + id + } + } + `); + + const result = mergeOutputs([await plugin(schema, [{ document }], {}, { outputFile: '' })]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type MeQueryVariables = Exact<{ [key: string]: never; }>; + + + export type MeQuery = { me: { id: string } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('handles `native-numeric` enum', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + enum UserRole { + ADMIN + CUSTOMER + } + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query Me($role: UserRole!) { + me { + id + } + } + `); + + const result = mergeOutputs([ + await plugin(schema, [{ document }], { enumType: 'native-numeric' }, { outputFile: '' }), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export enum UserRole { + Admin = 0, + Customer = 1 + } + + export type MeQueryVariables = Exact<{ + role: UserRole; + }>; + + + export type MeQuery = { me: { id: string } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('handles `const` enum', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + enum UserRole { + A_B_C + X_Y_Z + _TEST + My_Value + _123 + } + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query Me($role: UserRole!) { + me { + id + } + } + `); + + const result = mergeOutputs([ + await plugin(schema, [{ document }], { enumType: 'const' }, { outputFile: '' }), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export const UserRole = { + ABC: 'A_B_C', + XYZ: 'X_Y_Z', + Test: '_TEST', + MyValue: 'My_Value', + '123': '_123' + } as const; + + export type UserRole = typeof UserRole[keyof typeof UserRole]; + export type MeQueryVariables = Exact<{ + role: UserRole; + }>; + + + export type MeQuery = { me: { id: string } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('handles `native-const` enum', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + """ + Multiline comment test + """ + enum UserRole { + ADMIN + CUSTOMER @deprecated(reason: "Enum value CUSTOMER has been deprecated.") + } + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query Me($role: UserRole!) { + me { + id + } + } + `); + + const result = mergeOutputs([ + await plugin(schema, [{ document }], { enumType: 'native-const' }, { outputFile: '' }), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + /** Multiline comment test */ + export const enum UserRole { + Admin = 'ADMIN', + /** @deprecated Enum value CUSTOMER has been deprecated. */ + Customer = 'CUSTOMER' + }; + + export type MeQueryVariables = Exact<{ + role: UserRole; + }>; + + + export type MeQuery = { me: { id: string } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('handles `native` enum', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + enum UserRole { + ADMIN + CUSTOMER + } + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query Me($role: UserRole!) { + me { + id + } + } + `); + + const result = mergeOutputs([ + await plugin(schema, [{ document }], { enumType: 'native' }, { outputFile: '' }), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export enum UserRole { + Admin = 'ADMIN', + Customer = 'CUSTOMER' + } + + export type MeQueryVariables = Exact<{ + role: UserRole; + }>; + + + export type MeQuery = { me: { id: string } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('removes underscore from enum values', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + enum UserRole { + A_B_C + X_Y_Z + _TEST + My_Value + } + + scalar DateTime + `); + + const document = parse(/* GraphQL */ ` + query Me($role: UserRole!) { + me { + id + } + } + `); + + const result = mergeOutputs([ + await plugin(schema, [{ document }], { enumType: 'native' }, { outputFile: '' }), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export enum UserRole { + ABC = 'A_B_C', + XYZ = 'X_Y_Z', + Test = '_TEST', + MyValue = 'My_Value' + } + + export type MeQueryVariables = Exact<{ + role: UserRole; + }>; + + + export type MeQuery = { me: { id: string } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('keeps underscores in enum values when the value is only underscores', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + enum UserRole { + _ + __ + _TEST + } + + scalar DateTime + `); + + const document = parse(/* GraphQL */ ` + query Me($role: UserRole!) { + me { + id + } + } + `); + + const result = mergeOutputs([ + await plugin(schema, [{ document }], { enumType: 'native' }, { outputFile: '' }), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export enum UserRole { + _ = '_', + __ = '__', + Test = '_TEST' + } + + export type MeQueryVariables = Exact<{ + role: UserRole; + }>; + + + export type MeQuery = { me: { id: string } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('adds typesPrefix to enum when enumPrefix is true', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + enum UserRole { + ADMIN + CUSTOMER + } + + scalar DateTime + `); + + const document = parse(/* GraphQL */ ` + query Me($role: UserRole!) { + me { + id + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { typesPrefix: 'I', enumPrefix: true }, + { outputFile: '' }, + ), + ]); + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type IUserRole = + | 'ADMIN' + | 'CUSTOMER'; + + export type IMeQueryVariables = Exact<{ + role: IUserRole; + }>; + + + export type IMeQuery = { me: { id: string } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('does not add typesPrefix to enum when enumPrefix is false', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + enum UserRole { + ADMIN + CUSTOMER + } + + scalar DateTime + `); + + const document = parse(/* GraphQL */ ` + query Me($role: UserRole!) { + me { + id + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { typesPrefix: 'I', enumPrefix: false }, + { outputFile: '' }, + ), + ]); + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserRole = + | 'ADMIN' + | 'CUSTOMER'; + + export type IMeQueryVariables = Exact<{ + role: UserRole; + }>; + + + export type IMeQuery = { me: { id: string } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('adds typesSuffix to enum when enumSuffix is true', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + enum UserRole { + ADMIN + CUSTOMER + } + + scalar DateTime + `); + + const document = parse(/* GraphQL */ ` + query Me($role: UserRole!) { + me { + id + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { typesSuffix: 'Z', enumSuffix: true }, + { outputFile: '' }, + ), + ]); + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserRoleZ = + | 'ADMIN' + | 'CUSTOMER'; + + export type MeQueryVariablesZ = Exact<{ + role: UserRoleZ; + }>; + + + export type MeQueryZ = { me: { id: string } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('does not add typesSuffix to enum when enumSuffix is false', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + enum UserRole { + ADMIN + CUSTOMER + } + + scalar DateTime + `); + + const document = parse(/* GraphQL */ ` + query Me($role: UserRole!) { + me { + id + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { typesSuffix: 'Z', enumSuffix: false }, + { outputFile: '' }, + ), + ]); + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserRole = + | 'ADMIN' + | 'CUSTOMER'; + + export type MeQueryVariablesZ = Exact<{ + role: UserRole; + }>; + + + export type MeQueryZ = { me: { id: string } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('keeps enum value naming convention when namingConvention.enumValues is `keep`', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + input UserRoleInput { + role: UserRole! + } + + enum UserRole { + ADMIN + CUSTOMER + } + + scalar DateTime + `); + + const document = parse(/* GraphQL */ ` + query Me($input: UserRoleInput!, $role: UserRole!) { + me { + id + role + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + namingConvention: { + typeNames: 'change-case-all#lowerCase', + enumValues: 'keep', + }, + }, + { outputFile: '' }, + ), + ]); + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type userroleinput = { + role: userrole; + }; + + export type userrole = + | 'ADMIN' + | 'CUSTOMER'; + + export type mequeryvariables = Exact<{ + input: userroleinput; + role: userrole; + }>; + + + export type mequery = { me: { id: string, role: userrole } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('uses custom enum naming convention when namingConvention.enumValues is provided and enumType is native', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + input UserRoleInput { + role: UserRole! + } + + enum UserRole { + ADMIN + CUSTOMER + } + + scalar DateTime + `); + + const document = parse(/* GraphQL */ ` + query Me($input: UserRoleInput!, $role: UserRole!) { + me { + id + role + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + enumType: 'native', + namingConvention: { + typeNames: 'keep', + enumValues: 'change-case-all#lowerCase', + }, + }, + { outputFile: '' }, + ), + ]); + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserRoleInput = { + role: UserRole; + }; + + export enum UserRole { + admin = 'ADMIN', + customer = 'CUSTOMER' + } + + export type MeQueryVariables = Exact<{ + input: UserRoleInput; + role: UserRole; + }>; + + + export type MeQuery = { me: { id: string, role: UserRole } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('does not contain "export" when noExport is set to true', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + enum UserRole { + ADMIN + CUSTOMER + } + + scalar DateTime + `); + + const document = parse(/* GraphQL */ ` + query Me($role: UserRole!) { + me { + id + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + noExport: true, + }, + { outputFile: '' }, + ), + ]); + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + type UserRole = + | 'ADMIN' + | 'CUSTOMER'; + + type MeQueryVariables = Exact<{ + role: UserRole; + }>; + + + type MeQuery = { me: { id: string } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('handles enumValues and named default import', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + input UserRoleInput { + role: UserRole! + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + enum UserRole { + ADMIN + CUSTOMER + } + + scalar DateTime + `); + + const document = parse(/* GraphQL */ ` + query Me($input: UserRoleInput!, $role: UserRole!) { + me { + id + role + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + typesPrefix: 'I', + namingConvention: { enumValues: 'change-case-all#constantCase' }, + enumValues: { + UserRole: './files#default as UserRole', // NOTE: `as UserRole` doesn't do anything here, this is here to demonstrate that it's the same as './files#default' + }, + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "import IUserRole from './files'; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type IUserRoleInput = { + role: IUserRole; + }; + + export { IUserRole }; + + export type IMeQueryVariables = Exact<{ + input: IUserRoleInput; + role: IUserRole; + }>; + + + export type IMeQuery = { me: { id: string, role: IUserRole } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('enum members should be quoted if numeric when enumType is native', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + enum UserRole { + AXB + _1X2 + _3X4 + } + + scalar DateTime + `); + + const document = parse(/* GraphQL */ ` + query Me($role: UserRole!) { + me { + id + } + } + `); + + const result = mergeOutputs([ + await plugin(schema, [{ document }], { enumType: 'native' }, { outputFile: '' }), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export enum UserRole { + Axb = 'AXB', + '1X2' = '_1X2', + '3X4' = '_3X4' + } + + export type MeQueryVariables = Exact<{ + role: UserRole; + }>; + + + export type MeQuery = { me: { id: string } | null }; + " + `); + }); +}); + +describe('TypeScript Operations Plugin - Enum `%future added value`', () => { + it('adds `%future added value` to the type when enumType is `string-literal` and futureProofEnums is true', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + enum UserRole { + ADMIN + CUSTOMER + } + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query Me($role: UserRole!) { + me { + id + } + } + `); + + const result = mergeOutputs([ + await plugin(schema, [{ document }], { futureProofEnums: true }, { outputFile: '' }), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserRole = + | 'ADMIN' + | 'CUSTOMER' + | '%future added value'; + + export type MeQueryVariables = Exact<{ + role: UserRole; + }>; + + + export type MeQuery = { me: { id: string } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); +}); + +describe('TypeScript Operations Plugin - Enum enumValues', () => { + it('handles `enumValues` with `string-literal` enum', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + input UserRoleInput { + role: UserRole! + } + + enum UserRole { + A_B_C + X_Y_Z + _TEST + My_Value + } + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query Me($input: UserRoleInput!, $role: UserRole!) { + me { + id + role + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + enumType: 'string-literal', + enumValues: { + UserRole: { + A_B_C: 0, + X_Y_Z: 'Foo', + _TEST: 'Bar', + My_Value: 1, + }, + }, + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserRoleInput = { + role: UserRole; + }; + + export type UserRole = + | 0 + | 'Foo' + | 'Bar' + | 1; + + export type MeQueryVariables = Exact<{ + input: UserRoleInput; + role: UserRole; + }>; + + + export type MeQuery = { me: { id: string, role: UserRole } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('handles `enumValues` with `const` enum', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + input UserRoleInput { + role: UserRole! + } + + enum UserRole { + A_B_C + X_Y_Z + _TEST + My_Value + } + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query Me($input: UserRoleInput!, $role: UserRole!) { + me { + id + role + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + enumType: 'const', + enumValues: { + UserRole: { + A_B_C: 0, + X_Y_Z: 'Foo', + _TEST: 'Bar', + My_Value: 1, + }, + }, + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserRoleInput = { + role: UserRole; + }; + + export const UserRole = { + ABC: 0, + XYZ: 'Foo', + Test: 'Bar', + MyValue: 1 + } as const; + + export type UserRole = typeof UserRole[keyof typeof UserRole]; + export type MeQueryVariables = Exact<{ + input: UserRoleInput; + role: UserRole; + }>; + + + export type MeQuery = { me: { id: string, role: UserRole } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('handles `enumValues` with `native` enum', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + input UserRoleInput { + role: UserRole! + } + + enum UserRole { + ADMIN + CUSTOMER + } + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query Me($input: UserRoleInput!, $role: UserRole!) { + me { + id + role + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + enumType: 'native', + enumValues: { + UserRole: { + ADMIN: 0, + CUSTOMER: 'test', + }, + }, + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserRoleInput = { + role: UserRole; + }; + + export enum UserRole { + Admin = 0, + Customer = 'test' + } + + export type MeQueryVariables = Exact<{ + input: UserRoleInput; + role: UserRole; + }>; + + + export type MeQuery = { me: { id: string, role: UserRole } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('handles `enumValues` as file import', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + input UserRoleInput { + role: UserRole! + } + + enum UserRole { + ADMIN + CUSTOMER + } + + scalar DateTime + `); + + const document = parse(/* GraphQL */ ` + query Me($input: UserRoleInput!, $role: UserRole!) { + me { + id + role + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + enumValues: { + UserRole: './my-file#MyEnum', + }, + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "import { MyEnum as UserRole } from './my-file'; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserRoleInput = { + role: UserRole; + }; + + export { UserRole }; + + export type MeQueryVariables = Exact<{ + input: UserRoleInput; + role: UserRole; + }>; + + + export type MeQuery = { me: { id: string, role: UserRole } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('does not import or export `enumValues` (as file import) if enum is not used', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + enum UserRole { + ADMIN + CUSTOMER + } + + scalar DateTime + `); + + const document = parse(/* GraphQL */ ` + query { + me { + id + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + enumValues: { + UserRole: './my-file#MyEnum', + }, + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; + + + export type Unnamed_1_Query = { me: { id: string } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('handles `enumValues` with custom imported enum from namespace with different name', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + input UserRoleInput { + role: UserRole! + } + + enum UserRole { + ADMIN + CUSTOMER + } + + scalar DateTime + `); + + const document = parse(/* GraphQL */ ` + query Me($input: UserRoleInput!, $role: UserRole!) { + me { + id + role + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + enumValues: { + UserRole: './my-file#NS.ETest', + }, + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "import { NS } from './my-file'; + import UserRole = NS.ETest; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserRoleInput = { + role: UserRole; + }; + + export { UserRole }; + + export type MeQueryVariables = Exact<{ + input: UserRoleInput; + role: UserRole; + }>; + + + export type MeQuery = { me: { id: string, role: UserRole } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('handles `enumValues` with custom imported enum from namespace with the same name', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + input UserRoleInput { + role: UserRole! + } + + enum UserRole { + ADMIN + CUSTOMER + } + + scalar DateTime + `); + + const document = parse(/* GraphQL */ ` + query Me($input: UserRoleInput!, $role: UserRole!) { + me { + id + role + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + enumValues: { + UserRole: './my-file#NS.UserRole', + }, + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "import { NS } from './my-file'; + import UserRole = NS.UserRole; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserRoleInput = { + role: UserRole; + }; + + export { UserRole }; + + export type MeQueryVariables = Exact<{ + input: UserRoleInput; + role: UserRole; + }>; + + + export type MeQuery = { me: { id: string, role: UserRole } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('handles `enumValues` from a single file', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + input UserRoleInput { + role: UserRole! + } + + enum UserRole { + ADMIN + CUSTOMER + } + + enum UserStatus { + ACTIVE + PENDING + } + + scalar DateTime + `); + + const document = parse(/* GraphQL */ ` + query Me($input: UserRoleInput!, $role: UserRole!, $status: UserStatus!) { + me { + id + role + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + enumType: 'native', + enumValues: './my-file', + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "import { UserRole } from './my-file'; + import { UserStatus } from './my-file'; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserRoleInput = { + role: UserRole; + }; + + export { UserRole }; + + export { UserStatus }; + + export type MeQueryVariables = Exact<{ + input: UserRoleInput; + role: UserRole; + status: UserStatus; + }>; + + + export type MeQuery = { me: { id: string, role: UserRole } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('handles `enumValues` from a single file when specified as string', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + me: User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + input UserRoleInput { + role: UserRole! + } + + enum UserRole { + ADMIN + CUSTOMER + } + + enum UserStatus { + ACTIVE + PENDING + } + + scalar DateTime + `); + + const document = parse(/* GraphQL */ ` + query Me($input: UserRoleInput!, $role: UserRole!, $status: UserStatus!) { + me { + id + role + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + enumType: 'native', + enumValues: { UserRole: './my-file#UserRole', UserStatus: './my-file#UserStatus2X' }, + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "import { UserRole } from './my-file'; + import { UserStatus2X as UserStatus } from './my-file'; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserRoleInput = { + role: UserRole; + }; + + export { UserRole }; + + export { UserStatus }; + + export type MeQueryVariables = Exact<{ + input: UserRoleInput; + role: UserRole; + status: UserStatus; + }>; + + + export type MeQuery = { me: { id: string, role: UserRole } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('#10471 - `enumValues` as named import from file must consider naming convention', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + license: License + } + + type License { + id: ID! + sku: LicenseSKU! + } + + enum LicenseSKU { + BASIC + ADVANCED + } + `); + + const document = parse(/* GraphQL */ ` + query License { + license { + sku + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + enumValues: { + LicenseSKU: './my-file#LicenseSku', + }, + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "import { LicenseSku } from './my-file'; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export { LicenseSku }; + + export type LicenseQueryVariables = Exact<{ [key: string]: never; }>; + + + export type LicenseQuery = { license: { sku: LicenseSku } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); +}); 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 new file mode 100644 index 00000000000..2e9f28d483a --- /dev/null +++ b/packages/plugins/typescript/operations/tests/ts-documents.standalone.import-types.spec.ts @@ -0,0 +1,655 @@ +import { buildSchema, parse } from 'graphql'; +import { mergeOutputs } from '@graphql-codegen/plugin-helpers'; +import { validateTs } from '@graphql-codegen/testing'; +import { plugin } from '../src/index.js'; + +describe('TypeScript Operations Plugin - Import Types', () => { + it('imports user-defined types externally with relative importSchemaTypesFrom correctly', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(id: ID!): User + users(input: UsersInput!): UsersResponse! + } + + type ResponseError { + error: ResponseErrorType! + } + + enum ResponseErrorType { + NOT_FOUND + INPUT_VALIDATION_ERROR + FORBIDDEN_ERROR + UNEXPECTED_ERROR + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + "UserRole Description" + enum UserRole { + "UserRole ADMIN" + ADMIN + "UserRole CUSTOMER" + CUSTOMER + } + + "UsersInput Description" + input UsersInput { + "UsersInput from" + from: DateTime + "UsersInput to" + to: DateTime + role: UserRole + } + + type UsersResponseOk { + result: [User!]! + } + union UsersResponse = UsersResponseOk | ResponseError + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query User($id: ID!) { + user(id: $id) { + id + name + role + createdAt + } + } + + query Users($input: UsersInput!) { + users(input: $input) { + ... on UsersResponseOk { + result { + id + } + } + ... on ResponseError { + error + } + } + } + + query UsersWithScalarInput($from: DateTime!, $to: DateTime, $role: UserRole) { + users(input: { from: $from, to: $to, role: $role }) { + ... on UsersResponseOk { + result { + __typename + } + } + ... on ResponseError { + __typename + } + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { importSchemaTypesFrom: './base-dir/path-to-other-file.generated.ts' }, + { outputFile: './base-dir/this-file.ts' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "import type * as Types from './path-to-other-file.generated'; + + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserQueryVariables = Exact<{ + id: string | number; + }>; + + + export type UserQuery = { user: { id: string, name: string, role: Types.UserRole, createdAt: unknown } | null }; + + export type UsersQueryVariables = Exact<{ + input: Types.UsersInput; + }>; + + + export type UsersQuery = { users: + | { result: Array<{ id: string }> } + | { error: Types.ResponseErrorType } + }; + + export type UsersWithScalarInputQueryVariables = Exact<{ + from: unknown; + to?: unknown; + role?: Types.UserRole | null | undefined; + }>; + + + export type UsersWithScalarInputQuery = { users: + | { result: Array<{ __typename: 'User' }> } + | { __typename: 'ResponseError' } + }; + " + `); + }); + + it('imports user-defined types externally with absolute importSchemaTypesFrom correctly', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(id: ID!): User + users(input: UsersInput!): UsersResponse! + } + + type ResponseError { + error: ResponseErrorType! + } + + enum ResponseErrorType { + NOT_FOUND + INPUT_VALIDATION_ERROR + FORBIDDEN_ERROR + UNEXPECTED_ERROR + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + "UserRole Description" + enum UserRole { + "UserRole ADMIN" + ADMIN + "UserRole CUSTOMER" + CUSTOMER + } + + "UsersInput Description" + input UsersInput { + "UsersInput from" + from: DateTime + "UsersInput to" + to: DateTime + role: UserRole + } + + type UsersResponseOk { + result: [User!]! + } + union UsersResponse = UsersResponseOk | ResponseError + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query User($id: ID!) { + user(id: $id) { + id + name + role + createdAt + } + } + + query Users($input: UsersInput!) { + users(input: $input) { + ... on UsersResponseOk { + result { + id + } + } + ... on ResponseError { + error + } + } + } + + query UsersWithScalarInput($from: DateTime!, $to: DateTime, $role: UserRole) { + users(input: { from: $from, to: $to, role: $role }) { + ... on UsersResponseOk { + result { + __typename + } + } + ... on ResponseError { + __typename + } + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { importSchemaTypesFrom: '~@my-company/package/types' }, + { outputFile: './base-dir/this-file.ts' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "import type * as Types from '@my-company/package/types'; + + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserQueryVariables = Exact<{ + id: string | number; + }>; + + + export type UserQuery = { user: { id: string, name: string, role: Types.UserRole, createdAt: unknown } | null }; + + export type UsersQueryVariables = Exact<{ + input: Types.UsersInput; + }>; + + + export type UsersQuery = { users: + | { result: Array<{ id: string }> } + | { error: Types.ResponseErrorType } + }; + + export type UsersWithScalarInputQueryVariables = Exact<{ + from: unknown; + to?: unknown; + role?: Types.UserRole | null | undefined; + }>; + + + export type UsersWithScalarInputQuery = { users: + | { result: Array<{ __typename: 'User' }> } + | { __typename: 'ResponseError' } + }; + " + `); + }); + + it('does not import external types if only native GraphQL types are used in Variables and Result', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(id: ID!): User + users(input: UsersInput!): UsersResponse! + } + + type ResponseError { + error: ResponseErrorType! + } + + enum ResponseErrorType { + NOT_FOUND + INPUT_VALIDATION_ERROR + FORBIDDEN_ERROR + UNEXPECTED_ERROR + } + + type User { + # Native GraphQL types + id: ID! + name: String! + isOld: Boolean! + ageInt: Int! + ageFloat: Float! + + # User-defined types + role: UserRole! + createdAt: DateTime! + } + + "UserRole Description" + enum UserRole { + "UserRole ADMIN" + ADMIN + "UserRole CUSTOMER" + CUSTOMER + } + + "UsersInput Description" + input UsersInput { + "UsersInput from" + from: DateTime + "UsersInput to" + to: DateTime + role: UserRole + } + + type UsersResponseOk { + result: [User!]! + } + union UsersResponse = UsersResponseOk | ResponseError + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query User($id: ID, $name: String, $bool: Boolean, $int: Int, $float: Float) { + user(id: $id) { + id + name + isOld + ageInt + ageFloat + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { importSchemaTypesFrom: './path-to-other-file' }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserQueryVariables = Exact<{ + id?: string | number | null | undefined; + name?: string | null | undefined; + bool?: boolean | null | undefined; + int?: number | null | undefined; + float?: number | null | undefined; + }>; + + + export type UserQuery = { user: { id: string, name: string, isOld: boolean, ageInt: number, ageFloat: number } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); +}); + +describe('TypeScript Operations Plugin - Import Types with external custom Scalars', () => { + it('imports external custom scalar in shared type file when said scalar is used in relevant Input', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(input: UserInput): User + } + + input UserInput { + id: ID! + scalar1: Scalar1 + } + + type User { + id: ID! + } + + scalar Scalar1 + `); + const document = parse(/* GraphQL */ ` + query User($input: UserInput) { + user(input: $input) { + id + } + } + `); + + const sharedTypeFileResult = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + generateOperationTypes: false, + scalars: { + Scalar1: '@org/scalars#Scalar1', + }, + }, + { outputFile: '' }, + ), + ]); + expect(sharedTypeFileResult).toMatchInlineSnapshot(` + "import { Scalar1 } from '@org/scalars'; + + + export type UserInput = { + id: string | number; + scalar1?: Scalar1 | null | undefined; + }; + " + `); + validateTs(sharedTypeFileResult, undefined, undefined, undefined, undefined, true); + + const operationFileResult = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + importSchemaTypesFrom: './path-to-other-file', + scalars: { + Scalar1: '@org/scalars#Scalar1', + }, + }, + { outputFile: '' }, + ), + ]); + expect(operationFileResult).toMatchInlineSnapshot(` + "import type * as Types from './graphql-code-generator/path-to-other-file'; + + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserQueryVariables = Exact<{ + input?: Types.UserInput | null | undefined; + }>; + + + export type UserQuery = { user: { id: string } | null }; + " + `); + validateTs(operationFileResult, undefined, undefined, undefined, undefined, true); + }); + + it('imports external custom scalar in operation file when said scalar is used in Variables', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(id: ID!): User + } + + type User { + id: ID! + scalar1: Scalar1 + } + + scalar Scalar1 + `); + const document = parse(/* GraphQL */ ` + query User($scalar1: Scalar1) { + user(id: "100") { + id + } + } + `); + + const sharedTypeFileResult = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + generateOperationTypes: false, + scalars: { + Scalar1: '@org/scalars#Scalar1', + }, + }, + { outputFile: '' }, + ), + ]); + expect(sharedTypeFileResult).toMatchInlineSnapshot(` + " + + " + `); + validateTs(sharedTypeFileResult, undefined, undefined, undefined, undefined, true); + + const operationFileResult = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + importSchemaTypesFrom: './path-to-other-file', + scalars: { + Scalar1: '@org/scalars#Scalar1', + }, + }, + { outputFile: '' }, + ), + ]); + expect(operationFileResult).toMatchInlineSnapshot(` + "import { Scalar1 } from '@org/scalars'; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserQueryVariables = Exact<{ + scalar1?: Scalar1 | null | undefined; + }>; + + + export type UserQuery = { user: { id: string } | null }; + " + `); + validateTs(operationFileResult, undefined, undefined, undefined, undefined, true); + }); + + it('imports external custom scalar in operation file when said scalar is used in Result SelectionSet', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(id: ID!): User + } + + type User { + id: ID! + scalar1: Scalar1 + } + + scalar Scalar1 + `); + const document = parse(/* GraphQL */ ` + query User { + user(id: "100") { + id + scalar1 + } + } + `); + + const sharedTypeFileResult = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + generateOperationTypes: false, + scalars: { + Scalar1: '@org/scalars#Scalar1', + }, + }, + { outputFile: '' }, + ), + ]); + expect(sharedTypeFileResult).toMatchInlineSnapshot(` + " + + " + `); + validateTs(sharedTypeFileResult, undefined, undefined, undefined, undefined, true); + + const operationFileResult = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + importSchemaTypesFrom: './path-to-other-file', + scalars: { + Scalar1: '@org/scalars#Scalar1', + }, + }, + { outputFile: '' }, + ), + ]); + expect(operationFileResult).toMatchInlineSnapshot(` + "import { Scalar1 } from '@org/scalars'; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserQueryVariables = Exact<{ [key: string]: never; }>; + + + export type UserQuery = { user: { id: string, scalar1: Scalar1 | null } | null }; + " + `); + validateTs(operationFileResult, undefined, undefined, undefined, undefined, true); + }); + + it('uses `namespacedImportName` correctly to name the import type', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(id: ID!): User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + enum UserRole { + ADMIN + CUSTOMER + } + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query User($id: ID!) { + user(id: $id) { + id + name + role + createdAt + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + importSchemaTypesFrom: './base-dir/path-to-other-file.generated.ts', + namespacedImportName: 'TypeImport', + }, + { outputFile: './base-dir/this-file.ts' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "import type * as TypeImport from './path-to-other-file.generated'; + + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserQueryVariables = Exact<{ + id: string | number; + }>; + + + export type UserQuery = { user: { id: string, name: string, role: TypeImport.UserRole, createdAt: unknown } | null }; + " + `); + }); +}); 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 new file mode 100644 index 00000000000..9654ad5955f --- /dev/null +++ b/packages/plugins/typescript/operations/tests/ts-documents.standalone.input.spec.ts @@ -0,0 +1,475 @@ +import { buildSchema, parse } from 'graphql'; +import { mergeOutputs } from '@graphql-codegen/plugin-helpers'; +import { validateTs } from '@graphql-codegen/testing'; +import { plugin } from '../src/index.js'; + +describe('TypeScript Operations Plugin - Input', () => { + it('generates nested input correctly', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + users( + input: UsersInput! + ageRange1: [Int] + ageRange2: [Int]! + ageRange3: [Int!] + ageRange4: [Int!]! + ): [User!]! + } + + type User { + id: ID! + ageRange1: [Int] + ageRange2: [Int]! + ageRange3: [Int!] + ageRange4: [Int!]! + } + + "UserRole Description" + enum UserRole { + "UserRole ADMIN" + ADMIN + "UserRole CUSTOMER" + CUSTOMER + } + + "UsersInput Description" + input UsersInput { + idNonNullable: ID! + idNullable: ID + "UsersInput from" + from: DateTime + "UsersInput to" + to: DateTime + timezone: TimeZone + role: UserRole + ageRange1: [Int] + ageRange2: [Int]! + ageRange3: [Int!] + ageRange4: [Int!]! + bestFriend: UsersBestFriendInput + nestedInput: UsersInput + } + + input UsersBestFriendInput { + name: String + } + + scalar DateTime + scalar TimeZone + `); + const document = parse(/* GraphQL */ ` + query UsersWithScalarInput( + $idNonNullable: ID! + $idNullable: ID + $inputNonNullable: UsersInput! + $inputNullable: UsersInput + $ageRange1: [Int] + $ageRange2: [Int]! + $ageRange3: [Int!] + $ageRange4: [Int!]! + ) { + users( + idNonNullable: $idNonNullable + idNullable: $idNullable + input: $inputNonNullable + ageRange1: $ageRange1 + ageRange2: $ageRange2 + ageRange3: $ageRange3 + ageRange4: $ageRange4 + ) { + ageRange1 + ageRange2 + ageRange3 + ageRange4 + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + scalars: { + DateTime: 'Date', + }, + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + /** UserRole Description */ + export type UserRole = + /** UserRole ADMIN */ + | 'ADMIN' + /** UserRole CUSTOMER */ + | 'CUSTOMER'; + + /** UsersInput Description */ + export type UsersInput = { + idNonNullable: string | number; + idNullable?: string | number | null | undefined; + /** UsersInput from */ + from?: Date | null | undefined; + /** UsersInput to */ + to?: Date | null | undefined; + timezone?: unknown; + role?: UserRole | null | undefined; + ageRange1?: Array | null | undefined; + ageRange2: Array; + ageRange3?: Array | null | undefined; + ageRange4: Array; + bestFriend?: UsersBestFriendInput | null | undefined; + nestedInput?: UsersInput | null | undefined; + }; + + export type UsersBestFriendInput = { + name?: string | null | undefined; + }; + + export type UsersWithScalarInputQueryVariables = Exact<{ + idNonNullable: string | number; + idNullable?: string | number | null | undefined; + inputNonNullable: UsersInput; + inputNullable?: UsersInput | null | undefined; + ageRange1?: Array | number | null | undefined; + ageRange2: Array | number; + ageRange3?: Array | number | null | undefined; + ageRange4: Array | number; + }>; + + + export type UsersWithScalarInputQuery = { users: Array<{ ageRange1: Array | null, ageRange2: Array, ageRange3: Array | null, ageRange4: Array }> }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('generates readonly input when immutableTypes:true', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + users(input: UsersInput!): [User!]! + } + + type User { + id: ID! + ageRange1: [Int] + ageRange2: [Int]! + ageRange3: [Int!] + ageRange4: [Int!]! + } + + "UserRole Description" + enum UserRole { + "UserRole ADMIN" + ADMIN + "UserRole CUSTOMER" + CUSTOMER + } + + "UsersInput Description" + input UsersInput { + "UsersInput from" + from: DateTime + "UsersInput to" + to: DateTime + timezone: TimeZone + role: UserRole + ageRange1: [Int] + ageRange2: [Int]! + ageRange3: [Int!] + ageRange4: [Int!]! + bestFriend: UsersBestFriendInput + nestedInput: UsersInput + } + + input UsersBestFriendInput { + name: String + } + + scalar DateTime + scalar TimeZone + `); + const document = parse(/* GraphQL */ ` + query UsersWithScalarInput($inputNonNullable: UsersInput!, $inputNullable: UsersInput) { + users(input: $inputNonNullable) { + ageRange1 + ageRange2 + ageRange3 + ageRange4 + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + scalars: { + DateTime: 'Date', + }, + immutableTypes: true, + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + /** UserRole Description */ + export type UserRole = + /** UserRole ADMIN */ + | 'ADMIN' + /** UserRole CUSTOMER */ + | 'CUSTOMER'; + + /** UsersInput Description */ + export type UsersInput = { + /** UsersInput from */ + readonly from?: Date | null | undefined; + /** UsersInput to */ + readonly to?: Date | null | undefined; + readonly timezone?: unknown; + readonly role?: UserRole | null | undefined; + readonly ageRange1?: Array | null | undefined; + readonly ageRange2: Array; + readonly ageRange3?: Array | null | undefined; + readonly ageRange4: Array; + readonly bestFriend?: UsersBestFriendInput | null | undefined; + readonly nestedInput?: UsersInput | null | undefined; + }; + + export type UsersBestFriendInput = { + readonly name?: string | null | undefined; + }; + + export type UsersWithScalarInputQueryVariables = Exact<{ + inputNonNullable: UsersInput; + inputNullable?: UsersInput | null | undefined; + }>; + + + export type UsersWithScalarInputQuery = { readonly users: ReadonlyArray<{ readonly ageRange1: ReadonlyArray | null, readonly ageRange2: ReadonlyArray, readonly ageRange3: ReadonlyArray | null, readonly ageRange4: ReadonlyArray }> }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('generates @oneOf input correctly', async () => { + const schema = buildSchema(/* GraphQL */ ` + directive @oneOf on INPUT_OBJECT + + type Query { + users(input: UsersInput!): [User!]! + } + + type User { + id: ID! + ageRange1: [Int] + ageRange2: [Int]! + ageRange3: [Int!] + ageRange4: [Int!]! + } + + "UserRole Description" + enum UserRole { + "UserRole ADMIN" + ADMIN + "UserRole CUSTOMER" + CUSTOMER + } + + "UsersInput Description" + input UsersInput @oneOf { + "UsersInput from" + from: DateTime + "UsersInput to" + to: DateTime + timezone: TimeZone + role: UserRole + ageRange1: [Int] + ageRange3: [Int!] + bestFriend: UsersBestFriendInput + nestedInput: UsersInput + } + + input UsersBestFriendInput { + name: String + } + + scalar DateTime + scalar TimeZone + `); + const document = parse(/* GraphQL */ ` + query Users($inputNonNullable: UsersInput!, $inputNullable: UsersInput) { + users(input: $inputNonNullable) { + __typename + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + scalars: { + DateTime: 'Date', + }, + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + /** UserRole Description */ + export type UserRole = + /** UserRole ADMIN */ + | 'ADMIN' + /** UserRole CUSTOMER */ + | 'CUSTOMER'; + + /** UsersInput Description */ + 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 */ + to: Date; timezone?: never; role?: never; ageRange1?: never; ageRange3?: never; bestFriend?: never; nestedInput?: never; } + | { from?: never; to?: never; timezone: unknown; role?: never; ageRange1?: never; ageRange3?: never; bestFriend?: never; nestedInput?: never; } + | { from?: never; to?: never; timezone?: never; role: UserRole; ageRange1?: never; ageRange3?: never; bestFriend?: never; nestedInput?: never; } + | { from?: never; to?: never; timezone?: never; role?: never; ageRange1: Array; ageRange3?: never; bestFriend?: never; nestedInput?: never; } + | { from?: never; to?: never; timezone?: never; role?: never; ageRange1?: never; ageRange3: Array; bestFriend?: never; nestedInput?: never; } + | { 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; }; + + export type UsersBestFriendInput = { + name?: string | null | undefined; + }; + + export type UsersQueryVariables = Exact<{ + inputNonNullable: UsersInput; + inputNullable?: UsersInput | null | undefined; + }>; + + + export type UsersQuery = { users: Array<{ __typename: 'User' }> }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('generates with custom inputMaybeValue', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(input: UserInput!): User + } + + type User { + id: ID! + } + + input UserInput { + dateRange1: [DateTime] + dateRange2: [DateTime]! + dateRange3: [DateTime!] + dateRange4: [DateTime!]! + bestFriend: UserBestFriendInput + nestedInput: UserInput + } + + input UserBestFriendInput { + name: String + bestFriendDateRange1: [DateTime] + bestFriendDateRange2: [DateTime]! + bestFriendDateRange3: [DateTime!] + bestFriendDateRange4: [DateTime!]! + } + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query Users( + $input: UserInput + $dateTime1: DateTime + $dateTime2: DateTime! + $dateTimeArray1: [DateTime] + $dateTimeArray2: [DateTime]! + $dateTimeArray3: [DateTime!] + $dateTimeArray4: [DateTime!]! + ) { + user { + __typename + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + inputMaybeValue: 'T | null', + scalars: { + DateTime: 'Date', + }, + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserInput = { + dateRange1?: Array | null; + dateRange2: Array; + dateRange3?: Array | null; + dateRange4: Array; + bestFriend?: UserBestFriendInput | null; + nestedInput?: UserInput | null; + }; + + export type UserBestFriendInput = { + name?: string | null; + bestFriendDateRange1?: Array | null; + bestFriendDateRange2: Array; + bestFriendDateRange3?: Array | null; + bestFriendDateRange4: Array; + }; + + export type UsersQueryVariables = Exact<{ + input?: UserInput | null; + dateTime1?: Date | null; + dateTime2: Date; + dateTimeArray1?: Array | Date | null; + dateTimeArray2: Array | Date; + dateTimeArray3?: Array | Date | null; + dateTimeArray4: Array | Date; + }>; + + + export type UsersQuery = { user: { __typename: 'User' } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); +}); diff --git a/packages/plugins/typescript/operations/tests/ts-documents.standalone.scalars.spec.ts b/packages/plugins/typescript/operations/tests/ts-documents.standalone.scalars.spec.ts new file mode 100644 index 00000000000..bd9caeecf20 --- /dev/null +++ b/packages/plugins/typescript/operations/tests/ts-documents.standalone.scalars.spec.ts @@ -0,0 +1,715 @@ +import { buildSchema, parse } from 'graphql'; +import { mergeOutputs } from '@graphql-codegen/plugin-helpers'; +import { validateTs } from '@graphql-codegen/testing'; +import { plugin } from '../src/index.js'; + +describe('TypeScript Operations Plugin - Default Scalar types', () => { + it('generates `unknown` as the default custom defaultScalarType', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user( + id: ID! + nonNullableDate: DateTime! + nullableDate: DateTime + dateArray1: [DateTime] + dateArray2: [DateTime]! + dateArray3: [DateTime!] + dateArray4: [DateTime!]! + input: UserInput! + ): User + } + + input UserInput { + nonNullableDate: DateTime! + nullableDate: DateTime + dateArray1: [DateTime] + dateArray2: [DateTime]! + dateArray3: [DateTime!] + dateArray4: [DateTime!]! + } + + type User { + id: ID! + nonNullableDate: DateTime! + nullableDate: DateTime + } + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query User( + $nonNullableDate: DateTime! + $nullableDate: DateTime + $dateArray1: [DateTime] + $dateArray2: [DateTime]! + $dateArray3: [DateTime!] + $dateArray4: [DateTime!]! + $input: UserInput! + ) { + user( + id: "1" + nonNullableDate: $nonNullableDate + nullableDate: $nullableDate + dateArray1: $dateArray1 + dateArray2: $dateArray2 + dateArray3: $dateArray3 + dateArray4: $dateArray4 + input: $input + ) { + id + nonNullableDate + nullableDate + } + } + `); + + const result = mergeOutputs([await plugin(schema, [{ document }], {}, { outputFile: '' })]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserInput = { + nonNullableDate: unknown; + nullableDate?: unknown; + dateArray1?: Array | null | undefined; + dateArray2: Array; + dateArray3?: Array | null | undefined; + dateArray4: Array; + }; + + export type UserQueryVariables = Exact<{ + nonNullableDate: unknown; + nullableDate?: unknown; + dateArray1?: Array | unknown | null | undefined; + dateArray2: Array | unknown; + dateArray3?: Array | unknown | null | undefined; + dateArray4: Array | unknown; + input: UserInput; + }>; + + + export type UserQuery = { user: { id: string, nonNullableDate: unknown, nullableDate: unknown } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it("generates `any` when defaultScalarType:'any'", async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user( + id: ID! + nonNullableDate: DateTime! + nullableDate: DateTime + dateArray1: [DateTime] + dateArray2: [DateTime]! + dateArray3: [DateTime!] + dateArray4: [DateTime!]! + input: UserInput! + ): User + } + + input UserInput { + nonNullableDate: DateTime! + nullableDate: DateTime + dateArray1: [DateTime] + dateArray2: [DateTime]! + dateArray3: [DateTime!] + dateArray4: [DateTime!]! + } + + type User { + id: ID! + nonNullableDate: DateTime! + nullableDate: DateTime + } + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query User( + $nonNullableDate: DateTime! + $nullableDate: DateTime + $dateArray1: [DateTime] + $dateArray2: [DateTime]! + $dateArray3: [DateTime!] + $dateArray4: [DateTime!]! + $input: UserInput! + ) { + user( + id: "1" + nonNullableDate: $nonNullableDate + nullableDate: $nullableDate + dateArray1: $dateArray1 + dateArray2: $dateArray2 + dateArray3: $dateArray3 + dateArray4: $dateArray4 + input: $input + ) { + id + nonNullableDate + nullableDate + } + } + `); + + const result = mergeOutputs([ + await plugin(schema, [{ document }], { defaultScalarType: 'any' }, { outputFile: '' }), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserInput = { + nonNullableDate: any; + nullableDate?: any; + dateArray1?: Array | null | undefined; + dateArray2: Array; + dateArray3?: Array | null | undefined; + dateArray4: Array; + }; + + export type UserQueryVariables = Exact<{ + nonNullableDate: any; + nullableDate?: any; + dateArray1?: Array | any | null | undefined; + dateArray2: Array | any; + dateArray3?: Array | any | null | undefined; + dateArray4: Array | any; + input: UserInput; + }>; + + + export type UserQuery = { user: { id: string, nonNullableDate: any, nullableDate: any } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('generates correct types when defaultScalarType is set to said types', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user( + id: ID! + nonNullableDate: DateTime! + nullableDate: DateTime + dateArray1: [DateTime] + dateArray2: [DateTime]! + dateArray3: [DateTime!] + dateArray4: [DateTime!]! + input: UserInput! + ): User + } + + input UserInput { + nonNullableDate: DateTime! + nullableDate: DateTime + dateArray1: [DateTime] + dateArray2: [DateTime]! + dateArray3: [DateTime!] + dateArray4: [DateTime!]! + } + + type User { + id: ID! + nonNullableDate: DateTime! + nullableDate: DateTime + } + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query User( + $nonNullableDate: DateTime! + $nullableDate: DateTime + $dateArray1: [DateTime] + $dateArray2: [DateTime]! + $dateArray3: [DateTime!] + $dateArray4: [DateTime!]! + $input: UserInput! + ) { + user( + id: "1" + nonNullableDate: $nonNullableDate + nullableDate: $nullableDate + dateArray1: $dateArray1 + dateArray2: $dateArray2 + dateArray3: $dateArray3 + dateArray4: $dateArray4 + input: $input + ) { + id + nonNullableDate + nullableDate + } + } + `); + + const result = mergeOutputs([ + await plugin(schema, [{ document }], { defaultScalarType: 'Date' }, { outputFile: '' }), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserInput = { + nonNullableDate: Date; + nullableDate?: Date | null | undefined; + dateArray1?: Array | null | undefined; + dateArray2: Array; + dateArray3?: Array | null | undefined; + dateArray4: Array; + }; + + export type UserQueryVariables = Exact<{ + nonNullableDate: Date; + nullableDate?: Date | null | undefined; + dateArray1?: Array | Date | null | undefined; + dateArray2: Array | Date; + dateArray3?: Array | Date | null | undefined; + dateArray4: Array | Date; + input: UserInput; + }>; + + + export type UserQuery = { user: { id: string, nonNullableDate: Date, nullableDate: Date | null } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); +}); + +describe('TypeScript Operations Plugin - Custom Scalars', () => { + it('imports external custom scalar correctly when used in Result SelectionSet', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(id: ID!): User + } + + type User { + id: ID! + scalar1: Scalar1 + scalar2: Scalar2 + scalar3: Scalar3 + scalar4: Scalar4 + scalar5: Scalar5 + scalar6: Scalar6 + scalar7: Scalar7 + unusedScalar: UnusedScalar + } + + scalar Scalar1 + scalar Scalar2 + scalar Scalar3 + scalar Scalar4 + scalar Scalar5 + scalar Scalar6 + scalar Scalar7 + scalar UnusedScalar + `); + const document = parse(/* GraphQL */ ` + query User { + user(id: "1") { + id + scalar1 + scalar2 + scalar3 + scalar4 + scalar5 + scalar6 + scalar7 + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + scalars: { + Scalar1: '../../scalars#default', + Scalar2: '../../scalars#MyScalar2', + Scalar3: '../../scalars#MyScalar3 as AliasedScalar3', + Scalar4: '@org/scalars#default', + Scalar5: '@org/scalars#MyScalar5', + Scalar6: '@org/scalars#MyScalar6 as AliasedScalar6', + Scalar7: { + input: '@org/input-output#Scalar7Input', + output: '@org/input-output#Scalar7Output', + }, + UnusedScalar: 'scalars#UnusedScalar', + }, + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "import Scalar1 from '../../scalars'; + import { MyScalar2, MyScalar3 as AliasedScalar3 } from '../../scalars'; + import Scalar4 from '@org/scalars'; + import { MyScalar5, MyScalar6 as AliasedScalar6 } from '@org/scalars'; + import { Scalar7Output } from '@org/input-output'; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserQueryVariables = Exact<{ [key: string]: never; }>; + + + export type UserQuery = { user: { id: string, scalar1: Scalar1 | null, scalar2: MyScalar2 | null, scalar3: AliasedScalar3 | null, scalar4: Scalar4 | null, scalar5: MyScalar5 | null, scalar6: AliasedScalar6 | null, scalar7: Scalar7Output | null } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('imports external custom scalar correctly when used in Input and Variables', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(input: UserInput): User + } + + type User { + id: ID! + } + + input UserInput { + scalar1: Scalar1 + scalar2: Scalar2 + scalar3: Scalar3 + } + + scalar Scalar1 + scalar Scalar2 + scalar Scalar3 + scalar Scalar4 + scalar Scalar5 + scalar Scalar6 + scalar Scalar7 + scalar UnusedScalar + `); + const document = parse(/* GraphQL */ ` + query User( + $userInput: UserInput + $scalar4: Scalar4 + $scalar5: Scalar5 + $scalar6: Scalar6 + $scalar7: Scalar7 + ) { + user { + id + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + scalars: { + Scalar1: '../../scalars#default', + Scalar2: '../../scalars#MyScalar2', + Scalar3: '../../scalars#MyScalar3 as AliasedScalar3', + Scalar4: '@org/scalars#default', + Scalar5: '@org/scalars#MyScalar5', + Scalar6: '@org/scalars#MyScalar6 as AliasedScalar6', + Scalar7: { + input: '@org/input-output#Scalar7Input', + output: '@org/input-output#Scalar7Output', + }, + UnusedScalar: 'scalars#UnusedScalar', + }, + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "import Scalar1 from '../../scalars'; + import { MyScalar2, MyScalar3 as AliasedScalar3 } from '../../scalars'; + import Scalar4 from '@org/scalars'; + import { MyScalar5, MyScalar6 as AliasedScalar6 } from '@org/scalars'; + import { Scalar7Input } from '@org/input-output'; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserInput = { + scalar1?: Scalar1 | null | undefined; + scalar2?: MyScalar2 | null | undefined; + scalar3?: AliasedScalar3 | null | undefined; + }; + + export type UserQueryVariables = Exact<{ + userInput?: UserInput | null | undefined; + scalar4?: Scalar4 | null | undefined; + scalar5?: MyScalar5 | null | undefined; + scalar6?: AliasedScalar6 | null | undefined; + scalar7?: Scalar7Input | null | undefined; + }>; + + + export type UserQuery = { user: { id: string } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('imports multiple default imports and named imports correctly by default', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(id: ID!): User + } + + type User { + id: ID! + scalar11: Scalar11 + } + + scalar Scalar1 + scalar Scalar2 + scalar Scalar3 + scalar Scalar4 + scalar Scalar5 + scalar Scalar6 + scalar Scalar7 + scalar Scalar8 + scalar Scalar9 + scalar Scalar10 + scalar Scalar11 + scalar Scalar12 + scalar UnusedScalar + `); + const document = parse(/* GraphQL */ ` + query User( + # relative imports + $scalar1: Scalar1 + $scalar1a: Scalar1 # Should only import once + $scalar2: Scalar2 + $scalar3: Scalar3 + $scalar3a: Scalar3 # Should only import once + $scalar4: Scalar4 + # module imports + $scalar5: Scalar5 + $scalar6: Scalar6 + $scalar7: Scalar7 + $scalar8: Scalar8 + $scalar9: Scalar9 + $scalar10: Scalar10 + # mix of input/output + $scalar11: Scalar11 + $scalar12: Scalar12 + ) { + user { + id + scalar11 + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + scalars: { + Scalar1: '../../scalars#default', + Scalar2: '../../scalars#default as DefaultScalar2', + Scalar3: '../../scalars#default as DefaultScalar3', + Scalar4: '../../scalars#Scalar4', + Scalar5: '../../scalars#Scalar5 as MyScalar5', + Scalar6: '@org/scalars#default', + Scalar7: '@org/scalars#default as DefaultScalar7', + Scalar8: '@org/scalars#default as DefaultScalar8', + Scalar9: '@org/scalars#Scalar9', + Scalar10: '@org/scalars#Scalar10 as MyScalar10', + Scalar11: { + input: '@org/input-output#Scalar11 as Scalar11Input', + output: '@org/input-output#Scalar11 as Scalar11Output', + }, + Scalar12: { + input: '@org/input-output#Scalar12', + output: '@org/input-output#Scalar12', + }, + UnusedScalar: 'scalars#UnusedScalar', + }, + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "import Scalar1 from '../../scalars'; + import DefaultScalar2 from '../../scalars'; + import DefaultScalar3 from '../../scalars'; + import { Scalar4, Scalar5 as MyScalar5 } from '../../scalars'; + import Scalar6 from '@org/scalars'; + import DefaultScalar7 from '@org/scalars'; + import DefaultScalar8 from '@org/scalars'; + import { Scalar9, Scalar10 as MyScalar10 } from '@org/scalars'; + import { Scalar11 as Scalar11Input, Scalar11 as Scalar11Output, Scalar12 } from '@org/input-output'; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserQueryVariables = Exact<{ + scalar1?: Scalar1 | null | undefined; + scalar1a?: Scalar1 | null | undefined; + scalar2?: DefaultScalar2 | null | undefined; + scalar3?: DefaultScalar3 | null | undefined; + scalar3a?: DefaultScalar3 | null | undefined; + scalar4?: Scalar4 | null | undefined; + scalar5?: MyScalar5 | null | undefined; + scalar6?: Scalar6 | null | undefined; + scalar7?: DefaultScalar7 | null | undefined; + scalar8?: DefaultScalar8 | null | undefined; + scalar9?: Scalar9 | null | undefined; + scalar10?: MyScalar10 | null | undefined; + scalar11?: Scalar11Input | null | undefined; + scalar12?: Scalar12 | null | undefined; + }>; + + + export type UserQuery = { user: { id: string, scalar11: Scalar11Output | null } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('imports multiple default imports and named imports correctly with useTypeImports:true', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(id: ID!): User + } + + type User { + id: ID! + scalar11: Scalar11 + } + + scalar Scalar1 + scalar Scalar2 + scalar Scalar3 + scalar Scalar4 + scalar Scalar5 + scalar Scalar6 + scalar Scalar7 + scalar Scalar8 + scalar Scalar9 + scalar Scalar10 + scalar Scalar11 + scalar Scalar12 + scalar UnusedScalar + `); + const document = parse(/* GraphQL */ ` + query User( + # relative imports + $scalar1: Scalar1 + $scalar1a: Scalar1 # Should only import once + $scalar2: Scalar2 + $scalar3: Scalar3 + $scalar3a: Scalar3 # Should only import once + $scalar4: Scalar4 + # module imports + $scalar5: Scalar5 + $scalar6: Scalar6 + $scalar7: Scalar7 + $scalar8: Scalar8 + $scalar9: Scalar9 + $scalar10: Scalar10 + # mix of input/output + $scalar11: Scalar11 + $scalar12: Scalar12 + ) { + user { + id + scalar11 + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + useTypeImports: true, + scalars: { + Scalar1: '../../scalars#default', + Scalar2: '../../scalars#default as DefaultScalar2', + Scalar3: '../../scalars#default as DefaultScalar3', + Scalar4: '../../scalars#Scalar4', + Scalar5: '../../scalars#Scalar5 as MyScalar5', + Scalar6: '@org/scalars#default', + Scalar7: '@org/scalars#default as DefaultScalar7', + Scalar8: '@org/scalars#default as DefaultScalar8', + Scalar9: '@org/scalars#Scalar9', + Scalar10: '@org/scalars#Scalar10 as MyScalar10', + Scalar11: { + input: '@org/input-output#Scalar11 as Scalar11Input', + output: '@org/input-output#Scalar11 as Scalar11Output', + }, + Scalar12: { + input: '@org/input-output#Scalar12', + output: '@org/input-output#Scalar12', + }, + UnusedScalar: 'scalars#UnusedScalar', + }, + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "import type { default as Scalar1 } from '../../scalars'; + import type { default as DefaultScalar2 } from '../../scalars'; + import type { default as DefaultScalar3 } from '../../scalars'; + import type { Scalar4, Scalar5 as MyScalar5 } from '../../scalars'; + import type { default as Scalar6 } from '@org/scalars'; + import type { default as DefaultScalar7 } from '@org/scalars'; + import type { default as DefaultScalar8 } from '@org/scalars'; + import type { Scalar9, Scalar10 as MyScalar10 } from '@org/scalars'; + import type { Scalar11 as Scalar11Input, Scalar11 as Scalar11Output, Scalar12 } from '@org/input-output'; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserQueryVariables = Exact<{ + scalar1?: Scalar1 | null | undefined; + scalar1a?: Scalar1 | null | undefined; + scalar2?: DefaultScalar2 | null | undefined; + scalar3?: DefaultScalar3 | null | undefined; + scalar3a?: DefaultScalar3 | null | undefined; + scalar4?: Scalar4 | null | undefined; + scalar5?: MyScalar5 | null | undefined; + scalar6?: Scalar6 | null | undefined; + scalar7?: DefaultScalar7 | null | undefined; + scalar8?: DefaultScalar8 | null | undefined; + scalar9?: Scalar9 | null | undefined; + scalar10?: MyScalar10 | null | undefined; + scalar11?: Scalar11Input | null | undefined; + scalar12?: Scalar12 | null | undefined; + }>; + + + export type UserQuery = { user: { id: string, scalar11: Scalar11Output | null } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); +}); diff --git a/packages/plugins/typescript/operations/tests/ts-documents.standalone.spec.ts b/packages/plugins/typescript/operations/tests/ts-documents.standalone.spec.ts new file mode 100644 index 00000000000..f0b004a2517 --- /dev/null +++ b/packages/plugins/typescript/operations/tests/ts-documents.standalone.spec.ts @@ -0,0 +1,940 @@ +import { buildSchema, parse } from 'graphql'; +import { mergeOutputs } from '@graphql-codegen/plugin-helpers'; +import { validateTs } from '@graphql-codegen/testing'; +import { plugin } from '../src/index.js'; + +describe('TypeScript Operations Plugin - Standalone', () => { + it('generates using default config', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(id: ID!): User + users(input: UsersInput!): UsersResponse! + } + + type Mutation { + makeUserAdmin(id: ID!): User! + } + + type Subscription { + userChanges(id: ID!): User! + } + + type ResponseError { + error: ResponseErrorType! + } + + enum ResponseErrorType { + NOT_FOUND + INPUT_VALIDATION_ERROR + FORBIDDEN_ERROR + UNEXPECTED_ERROR + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + nickname: String + } + + "UserRole Description" + enum UserRole { + "UserRole ADMIN" + ADMIN + "UserRole CUSTOMER" + CUSTOMER + } + + "UsersInput Description" + input UsersInput { + "UsersInput from" + from: DateTime + "UsersInput to" + to: DateTime + role: UserRole + } + + type UsersResponseOk { + result: [User!]! + } + union UsersResponse = UsersResponseOk | ResponseError + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query User($id: ID!) { + user(id: $id) { + id + name + role + createdAt + nickname + } + } + + query Users($input: UsersInput!) { + users(input: $input) { + ... on UsersResponseOk { + result { + id + } + } + ... on ResponseError { + error + } + } + } + + query UsersWithScalarInput($from: DateTime!, $to: DateTime, $role: UserRole) { + users(input: { from: $from, to: $to, role: $role }) { + ... on UsersResponseOk { + result { + __typename + } + } + ... on ResponseError { + __typename + } + } + } + + mutation MakeAdmin { + makeUserAdmin(id: "100") { + ...UserFragment + } + } + + subscription UserChanges { + makeUserAdmin(id: "100") { + ...UserFragment + } + } + + fragment UserFragment on User { + id + role + } + `); + + const result = mergeOutputs([await plugin(schema, [{ document }], {}, { outputFile: '' })]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type ResponseErrorType = + | 'NOT_FOUND' + | 'INPUT_VALIDATION_ERROR' + | 'FORBIDDEN_ERROR' + | 'UNEXPECTED_ERROR'; + + /** UserRole Description */ + export type UserRole = + /** UserRole ADMIN */ + | 'ADMIN' + /** UserRole CUSTOMER */ + | 'CUSTOMER'; + + /** UsersInput Description */ + export type UsersInput = { + /** UsersInput from */ + from?: unknown; + /** UsersInput to */ + to?: unknown; + role?: UserRole | null | undefined; + }; + + export type UserQueryVariables = Exact<{ + id: string | number; + }>; + + + export type UserQuery = { user: { id: string, name: string, role: UserRole, createdAt: unknown, nickname: string | null } | null }; + + export type UsersQueryVariables = Exact<{ + input: UsersInput; + }>; + + + export type UsersQuery = { users: + | { result: Array<{ id: string }> } + | { error: ResponseErrorType } + }; + + export type UsersWithScalarInputQueryVariables = Exact<{ + from: unknown; + to?: unknown; + role?: UserRole | null | undefined; + }>; + + + export type UsersWithScalarInputQuery = { users: + | { result: Array<{ __typename: 'User' }> } + | { __typename: 'ResponseError' } + }; + + export type MakeAdminMutationVariables = Exact<{ [key: string]: never; }>; + + + export type MakeAdminMutation = { makeUserAdmin: { id: string, role: UserRole } }; + + export type UserChangesSubscriptionVariables = Exact<{ [key: string]: never; }>; + + + export type UserChangesSubscription = Record; + + export type UserFragmentFragment = { id: string, role: UserRole }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('test generating input types enums in lists and inner field', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + users(input: UsersInput!): [User!]! + } + + type User { + id: ID! + } + + enum EnumRoot { + ENUM_A + ENUM_B + } + + enum EnumRootArray { + ENUM_C + ENUM_D + } + + enum EnumInnerArray { + ENUM_E + ENUM_F + } + + input EnumsInner { + enumsDeep: [EnumInnerArray!]! + } + + input UsersInput { + enum: EnumRoot! + enums: [EnumRootArray!]! + innerEnums: EnumsInner! + } + `); + const document = parse(/* GraphQL */ ` + query Users($input: UsersInput!) { + users(input: $input) { + id + } + } + `); + + const result = mergeOutputs([await plugin(schema, [{ document }], {}, { outputFile: '' })]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type EnumRoot = + | 'ENUM_A' + | 'ENUM_B'; + + export type EnumRootArray = + | 'ENUM_C' + | 'ENUM_D'; + + export type EnumInnerArray = + | 'ENUM_E' + | 'ENUM_F'; + + export type EnumsInner = { + enumsDeep: Array; + }; + + export type UsersInput = { + enum: EnumRoot; + enums: Array; + innerEnums: EnumsInner; + }; + + export type UsersQueryVariables = Exact<{ + input: UsersInput; + }>; + + + export type UsersQuery = { users: Array<{ id: string }> }; + " + `); + }); + + it('test generating output enums in lists and inner field', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(id: ID!): User! + } + + enum EnumRoot { + ENUM_A + ENUM_B + } + + enum EnumRootArray { + ENUM_C + ENUM_D + } + + enum EnumInnerArray { + ENUM_E + ENUM_F + } + + type EnumsInner { + enumsDeep: [EnumInnerArray!]! + } + + type User { + enum: EnumRoot! + enums: [EnumRootArray!]! + innerEnums: EnumsInner! + } + `); + const document = parse(/* GraphQL */ ` + query User($id: ID!) { + user(id: $id) { + enum + enums + innerEnums { + enumsDeep + } + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + extractAllFieldsToTypes: true, // Extracts all fields to separate types (similar to apollo-codegen behavior) + printFieldsOnNewLines: true, // Prints each field on a new line (similar to apollo-codegen behavior) + }, + { + outputFile: '', + }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type EnumRoot = + | 'ENUM_A' + | 'ENUM_B'; + + export type EnumRootArray = + | 'ENUM_C' + | 'ENUM_D'; + + export type EnumInnerArray = + | 'ENUM_E' + | 'ENUM_F'; + + export type UserQuery_user_User_innerEnums_EnumsInner = { + enumsDeep: Array + }; + + export type UserQuery_user_User = { + enum: EnumRoot, + enums: Array, + innerEnums: UserQuery_user_User_innerEnums_EnumsInner + }; + + export type UserQuery_Query = { + user: UserQuery_user_User + }; + + + export type UserQueryVariables = Exact<{ + id: string | number; + }>; + + + export type UserQuery = UserQuery_Query; + " + `); + }); + + it('test overrdiding config.scalars', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(id: ID!): User + } + + type User { + id: ID! + name: String! + } + `); + const document = parse(/* GraphQL */ ` + query User($id: ID!) { + user(id: $id) { + id + name + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { scalars: { ID: 'string | number | boolean' } }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserQueryVariables = Exact<{ + id: string | number | boolean; + }>; + + + export type UserQuery = { user: { id: string | number | boolean, name: string } | null }; + " + `); + }); + + it('test render output enum from fragment in the same document', async () => { + const schema = buildSchema(/* GraphQL */ ` + enum RoleType { + ROLE_A + ROLE_B + } + + type User { + id: ID! + name: String! + role: RoleType + pictureUrl: String + } + + type Query { + users: [User!]! + viewer: User! + } + `); + const document = parse(/* GraphQL */ ` + fragment UserBasic on User { + id + name + role + } + + query GetUsersAndViewer { + users { + ...UserBasic + } + viewer { + ...UserBasic + } + } + `); + + const result = mergeOutputs([await plugin(schema, [{ document }], {}, { outputFile: '' })]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type RoleType = + | 'ROLE_A' + | 'ROLE_B'; + + export type UserBasicFragment = { id: string, name: string, role: RoleType | null }; + + export type GetUsersAndViewerQueryVariables = Exact<{ [key: string]: never; }>; + + + export type GetUsersAndViewerQuery = { users: Array<{ id: string, name: string, role: RoleType | null }>, viewer: { id: string, name: string, role: RoleType | null } }; + " + `); + }); + + it('test render output enum from fragment in a separate document', async () => { + const schema = buildSchema(/* GraphQL */ ` + enum RoleType { + ROLE_A + ROLE_B + } + + type User { + id: ID! + name: String! + role: RoleType + pictureUrl: String + } + + type Query { + users: [User!]! + viewer: User! + } + `); + + const documentWithFragment = parse(/* GraphQL */ ` + fragment UserBasic on User { + id + name + role + } + `); + + const documentMain = parse(/* GraphQL */ ` + query GetUsersAndViewer { + users { + ...UserBasic + } + viewer { + ...UserBasic + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document: documentMain }, { document: documentWithFragment }], + {}, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type RoleType = + | 'ROLE_A' + | 'ROLE_B'; + + export type GetUsersAndViewerQueryVariables = Exact<{ [key: string]: never; }>; + + + export type GetUsersAndViewerQuery = { users: Array<{ id: string, name: string, role: RoleType | null }>, viewer: { id: string, name: string, role: RoleType | null } }; + + export type UserBasicFragment = { id: string, name: string, role: RoleType | null }; + " + `); + }); + + it('does not generate Variables, Result or Fragments when generateOperationTypes:false', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(id: ID!): User + users(input: UsersInput!): UsersResponse! + } + + type Mutation { + makeUserAdmin(id: ID!): User! + } + + type Subscription { + userChanges(id: ID!): User! + } + + type ResponseError { + error: ResponseErrorType! + } + + enum ResponseErrorType { + NOT_FOUND + INPUT_VALIDATION_ERROR + FORBIDDEN_ERROR + UNEXPECTED_ERROR + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + "UserRole Description" + enum UserRole { + "UserRole ADMIN" + ADMIN + "UserRole CUSTOMER" + CUSTOMER + } + + "UsersInput Description" + input UsersInput { + "UsersInput from" + from: DateTime + "UsersInput to" + to: DateTime + role: UserRole + } + + type UsersResponseOk { + result: [User!]! + } + union UsersResponse = UsersResponseOk | ResponseError + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query User($id: ID!) { + user(id: $id) { + id + name + role + createdAt + } + } + + query Users($input: UsersInput!) { + users(input: $input) { + ... on UsersResponseOk { + result { + ...UserFragment + } + } + ... on ResponseError { + error + } + } + } + + query UsersWithScalarInput($from: DateTime!, $to: DateTime, $role: UserRole) { + users(input: { from: $from, to: $to, role: $role }) { + ... on UsersResponseOk { + result { + __typename + } + } + ... on ResponseError { + __typename + } + } + } + + mutation MakeAdmin { + makeUserAdmin(id: "100") { + ...UserFragment + } + } + + subscription UserChanges { + makeUserAdmin(id: "100") { + ...UserFragment + } + } + + fragment UserFragment on User { + id + role + } + `); + + const result = mergeOutputs([ + await plugin(schema, [{ document }], { generateOperationTypes: false }, { outputFile: '' }), + ]); + + expect(result).toMatchInlineSnapshot(` + " + + export type ResponseErrorType = + | 'NOT_FOUND' + | 'INPUT_VALIDATION_ERROR' + | 'FORBIDDEN_ERROR' + | 'UNEXPECTED_ERROR'; + + /** UserRole Description */ + export type UserRole = + /** UserRole ADMIN */ + | 'ADMIN' + /** UserRole CUSTOMER */ + | 'CUSTOMER'; + + /** UsersInput Description */ + export type UsersInput = { + /** UsersInput from */ + from?: unknown; + /** UsersInput to */ + to?: unknown; + role?: UserRole | null | undefined; + }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('does not generate unused schema enum and input types', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(id: ID!): User + users(input: UsersInput!): UsersResponse! + } + + type Mutation { + makeUserAdmin(id: ID!): User! + } + + type Subscription { + userChanges(id: ID!): User! + } + + type ResponseError { + error: ResponseErrorType! + } + + enum ResponseErrorType { + NOT_FOUND + INPUT_VALIDATION_ERROR + FORBIDDEN_ERROR + UNEXPECTED_ERROR + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + } + + "UserRole Description" + enum UserRole { + "UserRole ADMIN" + ADMIN + "UserRole CUSTOMER" + CUSTOMER + } + + "UsersInput Description" + input UsersInput { + "UsersInput from" + from: DateTime + "UsersInput to" + to: DateTime + role: UserRole + } + + type UsersResponseOk { + result: [User!]! + } + union UsersResponse = UsersResponseOk | ResponseError + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query User { + user(id: "100") { + id + } + } + `); + + const result = mergeOutputs([ + await plugin(schema, [{ document }], { generateOperationTypes: false }, { outputFile: '' }), + ]); + + expect(result).toMatchInlineSnapshot(` + " + + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('adds __typename correctly for Apollo Client when skipTypeNameForRoot:true, nonOptionalTypename:true are used', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(id: ID!): User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + bestFriend: User + goodFriends: [User!]! + } + + enum UserRole { + ADMIN + CUSTOMER + } + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query User($id: ID!) { + user(id: $id) { + id + name + createdAt + bestFriend { + name + } + goodFriends { + id + __typename + } + } + } + `); + + const result = mergeOutputs([ + await plugin( + schema, + [{ document }], + { + skipTypeNameForRoot: true, + nonOptionalTypename: true, + }, + { outputFile: '' }, + ), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserQueryVariables = Exact<{ + id: string | number; + }>; + + + export type UserQuery = { user: { __typename: 'User', id: string, name: string, createdAt: unknown, bestFriend: { __typename: 'User', name: string } | null, goodFriends: Array<{ __typename: 'User', id: string }> } | null }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('does not generate Exact utility type if there are only fragments', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(id: ID!): User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + bestFriend: User + goodFriends: [User!]! + } + + enum UserRole { + ADMIN + CUSTOMER + } + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + fragment UserPart on User { + id + name + } + `); + + const result = mergeOutputs([await plugin(schema, [{ document }], {}, { outputFile: '' })]); + + expect(result).toMatchInlineSnapshot(` + " + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type UserPartFragment = { id: string, name: string }; + " + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); + + it('generates correctly with `globalNamespace: true`', async () => { + const schema = buildSchema(/* GraphQL */ ` + type Query { + user(id: ID!): User + } + + type User { + id: ID! + name: String! + role: UserRole! + createdAt: DateTime! + nickname: String + } + + "UserRole Description" + enum UserRole { + "UserRole ADMIN" + ADMIN + "UserRole CUSTOMER" + CUSTOMER + } + + scalar DateTime + `); + const document = parse(/* GraphQL */ ` + query User($id: ID!) { + user(id: $id) { + id + role + } + } + `); + + const result = mergeOutputs([ + await plugin(schema, [{ document }], { globalNamespace: true }, { outputFile: '' }), + ]); + + expect(result).toMatchInlineSnapshot(` + "/** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + + declare global { + /** UserRole Description */ + export type UserRole = + /** UserRole ADMIN */ + | 'ADMIN' + /** UserRole CUSTOMER */ + | 'CUSTOMER'; + + export type UserQueryVariables = Exact<{ + id: string | number; + }>; + + + export type UserQuery = { user: { id: string, role: UserRole } | null }; + + }" + `); + + validateTs(result, undefined, undefined, undefined, undefined, true); + }); +}); diff --git a/packages/plugins/typescript/resolvers/CHANGELOG.md b/packages/plugins/typescript/resolvers/CHANGELOG.md index 64be10ddc5a..d1a1d625e28 100644 --- a/packages/plugins/typescript/resolvers/CHANGELOG.md +++ b/packages/plugins/typescript/resolvers/CHANGELOG.md @@ -1,5 +1,117 @@ # @graphql-codegen/typescript-resolvers +## 6.0.0 + +### Major Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: visitors' config option are + moved based on their use case + - addTypename/skipTypename: is only a types-visitor concern. This is moved to types-visitor from + base-visitor + - nonOptionalTypename: is a documents-visitor and types-visitor concern. Moved from base-visitor + there + - extractAllFieldsToTypes: is a documents-visitor concern. Moved from base-visitor there + - enumPrefix and enumSuffix: need to be in base-visitor as all 3 types of visitors need this to + correctly sync the enum type names. This is moved to base visitor + - ignoreEnumValuesFromSchema: is a documents-visitor and types-visitor concern. Moved from + base-visitor there. + - globalNamespace: is a documents-visitor concern. Moved from base-visitor there + + Refactors + - documents-visitor no longer extends types-visitor _option types_ as they have two distinct + usages now. The types now extend base-visitor types. This is now consistent with + documents-visitor extending base-visitor + - Classes now handle config parsing and types at the same level e.g. if typescript-operations + plugin parses configOne, then the types for configOne must be in that class, rather than in + base-documents-visitor + + Note: These visitors are rolled up into one type for simplicity + - base-visitor: includes `base-visitor` + - documents-visitor: includes `base-documents-visitor` and `typescript-operations` visitor + - types-visitor: includes `base-types-visitor` and `typescript` visitor + - resolvers-visitor: includes `base-resolvers-visitor` and `typescript-resolvers` visitor + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: make `unknown` instead of + `any` the default custom scalar type + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Update deps to latest, some + only support ESM + + Node 20 support is dropped in this release. Node 22 comes with `require()` support for ESM, which + means it's easier to integrate ES modules into applications. Therefore, it is safe to start using + ESM-only packages. + + If you are a user, please upgrade to Node 22. If you are a lib maintainer and see ESM vs CJS + issues when running Jest tests, try using Vitest. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Drop Node 20 support + +### Patch Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - dependencies updates: + - Updated dependency [`auto-bind@^5.0.0` ↗︎](https://www.npmjs.com/package/auto-bind/v/5.0.0) (from + `~4.0.0`, in `dependencies`) + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - dependencies updates: + - Updated dependency [`auto-bind@^5.0.0` ↗︎](https://www.npmjs.com/package/auto-bind/v/5.0.0) (from + `~4.0.0`, in `dependencies`) + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Fix namingConvention not being applied + consistently + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Abstract how enum imports are generated into + visitor-plugin-common package + +- Updated dependencies + [[`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29)]: + - @graphql-codegen/plugin-helpers@7.0.0 + - @graphql-codegen/typescript@6.0.0 + - @graphql-codegen/visitor-plugin-common@7.0.0 + ## 5.1.8 ### Patch Changes @@ -812,8 +924,8 @@ ``` The `RefType` generic is used to reference back to `ResolversTypes` and `ResolversParentTypes` in - some cases such as field returning a Union. - 2. `resolversNonOptionalTypename` also affects `ResolversInterfaceTypes` + some cases such as field returning a Union. 2. `resolversNonOptionalTypename` also affects + `ResolversInterfaceTypes` Using the schema above, if we use `resolversNonOptionalTypename` option: diff --git a/packages/plugins/typescript/resolvers/package.json b/packages/plugins/typescript/resolvers/package.json index 1f074cd5193..0b469cc0d72 100644 --- a/packages/plugins/typescript/resolvers/package.json +++ b/packages/plugins/typescript/resolvers/package.json @@ -1,6 +1,6 @@ { "name": "@graphql-codegen/typescript-resolvers", - "version": "5.1.8", + "version": "6.0.0", "type": "module", "description": "GraphQL Code Generator plugin for generating TypeScript types for resolvers signature", "repository": { @@ -46,11 +46,11 @@ } }, "dependencies": { - "@graphql-codegen/plugin-helpers": "^6.3.0", - "@graphql-codegen/typescript": "^5.0.10", - "@graphql-codegen/visitor-plugin-common": "^6.3.0", + "@graphql-codegen/plugin-helpers": "^7.0.0", + "@graphql-codegen/typescript": "^6.0.0", + "@graphql-codegen/visitor-plugin-common": "^7.0.0", "@graphql-tools/utils": "^11.0.0", - "auto-bind": "~4.0.0", + "auto-bind": "^5.0.0", "tslib": "^2.8.0" }, "devDependencies": { diff --git a/packages/plugins/typescript/resolvers/tests/__snapshots__/ts-resolvers.spec.ts.snap b/packages/plugins/typescript/resolvers/tests/__snapshots__/ts-resolvers.spec.ts.snap index 3838c3a15da..3960c3ecb53 100644 --- a/packages/plugins/typescript/resolvers/tests/__snapshots__/ts-resolvers.spec.ts.snap +++ b/packages/plugins/typescript/resolvers/tests/__snapshots__/ts-resolvers.spec.ts.snap @@ -3,11 +3,6 @@ exports[`TypeScript Resolvers Plugin > Config > allowParentTypeOverride - should allow to have less strict resolvers by overrding parent type 1`] = ` "export type Maybe = T | null; export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { [_ in K]?: never }; -export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; import { GraphQLResolveInfo, GraphQLScalarType, GraphQLScalarTypeConfig } from 'graphql'; export type Omit = Pick>; export type RequireFields = Omit & { [P in K]-?: NonNullable }; @@ -18,7 +13,7 @@ export type Scalars = { Boolean: { input: boolean; output: boolean; } Int: { input: number; output: number; } Float: { input: number; output: number; } - MyScalar: { input: any; output: any; } + MyScalar: { input: unknown; output: unknown; } }; export type MyType = { @@ -623,11 +618,6 @@ export type DirectiveResolvers = ResolversObject<{ exports[`TypeScript Resolvers Plugin > Config > optionalInfoArgument - should allow to have optional info argument 1`] = ` "export type Maybe = T | null; export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { [_ in K]?: never }; -export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; import { GraphQLResolveInfo, GraphQLScalarType, GraphQLScalarTypeConfig } from 'graphql'; export type Omit = Pick>; export type RequireFields = Omit & { [P in K]-?: NonNullable }; @@ -638,7 +628,7 @@ export type Scalars = { Boolean: { input: boolean; output: boolean; } Int: { input: number; output: number; } Float: { input: number; output: number; } - MyScalar: { input: any; output: any; } + MyScalar: { input: unknown; output: unknown; } }; export type MyType = { diff --git a/packages/plugins/typescript/resolvers/tests/ts-resolvers.spec.ts b/packages/plugins/typescript/resolvers/tests/ts-resolvers.spec.ts index f9e5898e10f..42ba8100198 100644 --- a/packages/plugins/typescript/resolvers/tests/ts-resolvers.spec.ts +++ b/packages/plugins/typescript/resolvers/tests/ts-resolvers.spec.ts @@ -724,8 +724,8 @@ __isTypeOf?: IsTypeOfResolverFn; expect(mergedOutputs).not.toContain(`NotMapped: NotMapped;`); expect(mergedOutputs).toContain(`A: MyA;`); expect(mergedOutputs).toContain(`B: GQL_B;`); - expect(mergedOutputs).toContain(`C: C;`); - expect(mergedOutputs).toContain(`import { MyC as C } from '../enums.js';`); + expect(mergedOutputs).toContain(`C: GQL_C;`); + expect(mergedOutputs).toContain(`import { MyC as GQL_C } from '../enums.js';`); }); it('Should allow to generate optional __resolveType', async () => { @@ -2448,8 +2448,8 @@ export type ResolverFn = ( )) as Types.ComplexPluginOutput; expect(output.content).toContain( - `export type GqlAuthDirectiveArgs = {\n role?: Maybe;\n};`, - ); + `export type GqlAuthDirectiveArgs = {\n role?: Maybe;\n};`, + ); // Note: `GqlUserRole` will be imported from `@org/package` by `typescript` plugin expect(output.content).toContain( `export type GqlAuthDirectiveResolver = DirectiveResolverFn;`, ); diff --git a/packages/plugins/typescript/typed-document-node/CHANGELOG.md b/packages/plugins/typescript/typed-document-node/CHANGELOG.md index 01052a1abc6..43c0f6edc0e 100644 --- a/packages/plugins/typescript/typed-document-node/CHANGELOG.md +++ b/packages/plugins/typescript/typed-document-node/CHANGELOG.md @@ -1,5 +1,72 @@ # @graphql-codegen/typed-document-node +## 7.0.0 + +### Major Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Update deps to latest, some + only support ESM + + Node 20 support is dropped in this release. Node 22 comes with `require()` support for ESM, which + means it's easier to integrate ES modules into applications. Therefore, it is safe to start using + ESM-only packages. + + If you are a user, please upgrade to Node 22. If you are a lib maintainer and see ESM vs CJS + issues when running Jest tests, try using Vitest. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Drop Node 20 support + +### Patch Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - dependencies updates: + - Updated dependency [`auto-bind@^5.0.0` ↗︎](https://www.npmjs.com/package/auto-bind/v/5.0.0) (from + `~4.0.0`, in `dependencies`) + - Updated dependency + [`change-case-all@^2.1.0` ↗︎](https://www.npmjs.com/package/change-case-all/v/2.1.0) (from + `1.0.15`, in `dependencies`) + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - dependencies updates: + - Updated dependency + [`change-case-all@^2.1.0` ↗︎](https://www.npmjs.com/package/change-case-all/v/2.1.0) (from + `1.0.15`, in `dependencies`) + - Updated dependency [`auto-bind@^5.0.0` ↗︎](https://www.npmjs.com/package/auto-bind/v/5.0.0) (from + `~4.0.0`, in `dependencies`) +- Updated dependencies + [[`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29)]: + - @graphql-codegen/plugin-helpers@7.0.0 + - @graphql-codegen/visitor-plugin-common@7.0.0 + ## 6.1.8 ### Patch Changes diff --git a/packages/plugins/typescript/typed-document-node/package.json b/packages/plugins/typescript/typed-document-node/package.json index 0de4bca6e85..5a477d44340 100644 --- a/packages/plugins/typescript/typed-document-node/package.json +++ b/packages/plugins/typescript/typed-document-node/package.json @@ -1,6 +1,6 @@ { "name": "@graphql-codegen/typed-document-node", - "version": "6.1.8", + "version": "7.0.0", "type": "module", "description": "GraphQL Code Generator plugin for generating ready-to-use TypedDocumentNode based on GraphQL operations", "repository": { @@ -40,10 +40,10 @@ "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" }, "dependencies": { - "@graphql-codegen/plugin-helpers": "^6.3.0", - "@graphql-codegen/visitor-plugin-common": "^6.3.0", - "auto-bind": "~4.0.0", - "change-case-all": "1.0.15", + "@graphql-codegen/plugin-helpers": "^7.0.0", + "@graphql-codegen/visitor-plugin-common": "^7.0.0", + "auto-bind": "^5.0.0", + "change-case-all": "^2.1.0", "tslib": "^2.8.0" }, "publishConfig": { diff --git a/packages/plugins/typescript/typescript/CHANGELOG.md b/packages/plugins/typescript/typescript/CHANGELOG.md index cf0eb0c4bbd..5fa42f5e2a6 100644 --- a/packages/plugins/typescript/typescript/CHANGELOG.md +++ b/packages/plugins/typescript/typescript/CHANGELOG.md @@ -1,5 +1,150 @@ # @graphql-codegen/typescript +## 6.0.0 + +### Major Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: visitors' config option are + moved based on their use case + - addTypename/skipTypename: is only a types-visitor concern. This is moved to types-visitor from + base-visitor + - nonOptionalTypename: is a documents-visitor and types-visitor concern. Moved from base-visitor + there + - extractAllFieldsToTypes: is a documents-visitor concern. Moved from base-visitor there + - enumPrefix and enumSuffix: need to be in base-visitor as all 3 types of visitors need this to + correctly sync the enum type names. This is moved to base visitor + - ignoreEnumValuesFromSchema: is a documents-visitor and types-visitor concern. Moved from + base-visitor there. + - globalNamespace: is a documents-visitor concern. Moved from base-visitor there + + Refactors + - documents-visitor no longer extends types-visitor _option types_ as they have two distinct + usages now. The types now extend base-visitor types. This is now consistent with + documents-visitor extending base-visitor + - Classes now handle config parsing and types at the same level e.g. if typescript-operations + plugin parses configOne, then the types for configOne must be in that class, rather than in + base-documents-visitor + + Note: These visitors are rolled up into one type for simplicity + - base-visitor: includes `base-visitor` + - documents-visitor: includes `base-documents-visitor` and `typescript-operations` visitor + - types-visitor: includes `base-types-visitor` and `typescript` visitor + - resolvers-visitor: includes `base-resolvers-visitor` and `typescript-resolvers` visitor + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: make `unknown` instead of + `any` the default custom scalar type + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Update deps to latest, some + only support ESM + + Node 20 support is dropped in this release. Node 22 comes with `require()` support for ESM, which + means it's easier to integrate ES modules into applications. Therefore, it is safe to start using + ESM-only packages. + + If you are a user, please upgrade to Node 22. If you are a lib maintainer and see ESM vs CJS + issues when running Jest tests, try using Vitest. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Drop Node 20 support + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: `typescript` plugin no + longer generates `Exact` utility type. Instead, `typescript-operations` generates said utility + type for every file it creates. This is because it is used _only_ for `Variables`, so we only need + to generate it once for every generated operation file. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Remove unused utility types + from `typescript` plugin as they were previously used for `typescript-operations` plugin: + - `MakeOptional` + - `MakeMaybe` + - `MakeEmpty` + - `Incremental` + + BREAKING CHANGE: Remove `getRootTypeNames` function because it's available in + `@graphql-utils/tools` and not used anywhere + +### Minor Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - The `typescript-operations` plugin no longer + generates InputMaybe and Scalars types; it now uses native Typescript types instead. + +### Patch Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - dependencies updates: + - Updated dependency [`auto-bind@^5.0.0` ↗︎](https://www.npmjs.com/package/auto-bind/v/5.0.0) (from + `~4.0.0`, in `dependencies`) + - Updated dependency [`tslib@~2.6.0` ↗︎](https://www.npmjs.com/package/tslib/v/2.6.0) (from + `^2.8.0`, in `dependencies`) + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - dependencies updates: + - Updated dependency [`auto-bind@^5.0.0` ↗︎](https://www.npmjs.com/package/auto-bind/v/5.0.0) (from + `~4.0.0`, in `dependencies`) + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Extract utilities from base-type-visitor to + be shared with other plugins later: convertSchemaEnumToDeclarationBlockString, getNodeComment + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Fix namingConvention not being applied + consistently + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Abstract how enum imports are generated into + visitor-plugin-common package + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Fix namingConvention not being applied + consistently in imports, Variables, Input and Result + +- Updated dependencies + [[`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29)]: + - @graphql-codegen/plugin-helpers@7.0.0 + - @graphql-codegen/visitor-plugin-common@7.0.0 + - @graphql-codegen/schema-ast@6.0.0 + ## 5.0.10 ### Patch Changes diff --git a/packages/plugins/typescript/typescript/package.json b/packages/plugins/typescript/typescript/package.json index 00c343092d4..a04fa11ea41 100644 --- a/packages/plugins/typescript/typescript/package.json +++ b/packages/plugins/typescript/typescript/package.json @@ -1,6 +1,6 @@ { "name": "@graphql-codegen/typescript", - "version": "5.0.10", + "version": "6.0.0", "type": "module", "description": "GraphQL Code Generator plugin for generating TypeScript types", "repository": { @@ -40,11 +40,11 @@ "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" }, "dependencies": { - "@graphql-codegen/plugin-helpers": "^6.3.0", - "@graphql-codegen/schema-ast": "^5.0.2", - "@graphql-codegen/visitor-plugin-common": "^6.3.0", - "auto-bind": "~4.0.0", - "tslib": "^2.8.0" + "@graphql-codegen/plugin-helpers": "^7.0.0", + "@graphql-codegen/schema-ast": "^6.0.0", + "@graphql-codegen/visitor-plugin-common": "^7.0.0", + "auto-bind": "^5.0.0", + "tslib": "~2.6.0" }, "publishConfig": { "directory": "dist", diff --git a/packages/plugins/typescript/typescript/src/typescript-variables-to-object.ts b/packages/plugins/typescript/typescript/src/typescript-variables-to-object.ts index d5e1dbf3fe7..ad2740b17a2 100644 --- a/packages/plugins/typescript/typescript/src/typescript-variables-to-object.ts +++ b/packages/plugins/typescript/typescript/src/typescript-variables-to-object.ts @@ -36,7 +36,7 @@ export class TypeScriptOperationVariablesToObject extends OperationVariablesToOb ); } - private clearOptional(str: string): string { + protected clearOptional(str: string): string { const prefix = this._namespacedImportName ? `${this._namespacedImportName}.` : ''; const rgx = new RegExp(`^${this.wrapMaybe(`(.*?)`)}$`, 'i'); diff --git a/packages/plugins/typescript/typescript/src/visitor.ts b/packages/plugins/typescript/typescript/src/visitor.ts index 33f8cf8d8e4..06b7e6fba7e 100644 --- a/packages/plugins/typescript/typescript/src/visitor.ts +++ b/packages/plugins/typescript/typescript/src/visitor.ts @@ -15,16 +15,16 @@ import { } from 'graphql'; import { BaseTypesVisitor, + convertSchemaEnumToDeclarationBlockString, DeclarationBlock, DeclarationKind, getConfigValue, + getNodeComment, indent, isOneOfInputObjectType, normalizeAvoidOptionals, NormalizedAvoidOptionalsConfig, ParsedTypesConfig, - transformComment, - wrapWithSingleQuotes, } from '@graphql-codegen/visitor-plugin-common'; import { TypeScriptPluginConfig } from './config.js'; import { TypeScriptOperationVariablesToObject } from './typescript-variables-to-object.js'; @@ -46,12 +46,6 @@ export interface TypeScriptPluginParsedConfig extends ParsedTypesConfig { useImplementingTypes: boolean; } -export const EXACT_SIGNATURE = `type Exact = { [K in keyof T]: T[K] };`; -export const MAKE_OPTIONAL_SIGNATURE = `type MakeOptional = Omit & { [SubKey in K]?: Maybe };`; -export const MAKE_MAYBE_SIGNATURE = `type MakeMaybe = Omit & { [SubKey in K]: Maybe };`; -export const MAKE_EMPTY_SIGNATURE = `type MakeEmpty = { [_ in K]?: never };`; -export const MAKE_INCREMENTAL_SIGNATURE = `type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never };`; - export class TsVisitor< TRawConfig extends TypeScriptPluginConfig = TypeScriptPluginConfig, TParsedConfig extends TypeScriptPluginParsedConfig = TypeScriptPluginParsedConfig, @@ -161,15 +155,7 @@ export class TsVisitor< public getWrapperDefinitions(): string[] { if (this.config.onlyEnums) return []; - const definitions: string[] = [ - this.getMaybeValue(), - this.getInputMaybeValue(), - this.getExactDefinition(), - this.getMakeOptionalDefinition(), - this.getMakeMaybeDefinition(), - this.getMakeEmptyDefinition(), - this.getIncrementalDefinition(), - ]; + const definitions: string[] = [this.getMaybeValue(), this.getInputMaybeValue()]; if (this.config.wrapFieldDefinitions) { definitions.push(this.getFieldWrapperValue()); @@ -181,30 +167,6 @@ export class TsVisitor< return definitions; } - public getExactDefinition(): string { - if (this.config.onlyEnums) return ''; - - return `${this.getExportPrefix()}${EXACT_SIGNATURE}`; - } - - public getMakeOptionalDefinition(): string { - return `${this.getExportPrefix()}${MAKE_OPTIONAL_SIGNATURE}`; - } - - public getMakeMaybeDefinition(): string { - if (this.config.onlyEnums) return ''; - - return `${this.getExportPrefix()}${MAKE_MAYBE_SIGNATURE}`; - } - - public getMakeEmptyDefinition(): string { - return `${this.getExportPrefix()}${MAKE_EMPTY_SIGNATURE}`; - } - - public getIncrementalDefinition(): string { - return `${this.getExportPrefix()}${MAKE_INCREMENTAL_SIGNATURE}`; - } - public getMaybeValue(): string { return `${this.getExportPrefix()}type Maybe = ${this.config.maybeValue};`; } @@ -308,7 +270,7 @@ export class TsVisitor< const originalFieldNode = parent[key] as FieldDefinitionNode; const addOptionalSign = !this.config.avoidOptionals.field && originalFieldNode.type.kind !== Kind.NON_NULL_TYPE; - const comment = this.getNodeComment(node); + const comment = getNodeComment(node); const { type } = this.config.declarationKind; return ( @@ -334,7 +296,7 @@ export class TsVisitor< !this.config.avoidOptionals.inputValue && (originalFieldNode.type.kind !== Kind.NON_NULL_TYPE || (!this.config.avoidOptionals.defaultValue && node.defaultValue !== undefined)); - const comment = this.getNodeComment(node); + const comment = getNodeComment(node); const declarationKind = this.config.declarationKind.type; let type: string = node.type as any as string; @@ -378,116 +340,43 @@ export class TsVisitor< EnumTypeDefinition(node: EnumTypeDefinitionNode): string { const enumName = node.name.value; - // In case of mapped external enum string - if (this.config.enumValues[enumName]?.sourceFile) { - return `export { ${this.config.enumValues[enumName].typeIdentifier} };\n`; - } - - const getValueFromConfig = (enumValue: string | number) => { - if (typeof this.config.enumValues[enumName]?.mappedValues?.[enumValue] !== 'undefined') { - return this.config.enumValues[enumName].mappedValues[enumValue]; + const outputType = ((): Parameters< + typeof convertSchemaEnumToDeclarationBlockString + >[0]['outputType'] => { + if (this.config.enumsAsTypes) { + return 'string-literal'; } - return null; - }; - - const withFutureAddedValue = [ - this.config.futureProofEnums - ? [indent('| ' + wrapWithSingleQuotes('%future added value'))] - : [], - ]; - const enumTypeName = this.convertName(node, { - useTypesPrefix: this.config.enumPrefix, - useTypesSuffix: this.config.enumSuffix, - }); + if (this.config.numericEnums) { + return 'native-numeric'; + } - if (this.config.enumsAsTypes) { - return new DeclarationBlock(this._declarationBlockConfig) - .export() - .asKind('type') - .withComment(node.description?.value) - .withName(enumTypeName) - .withContent( - '\n' + - node.values - .map(enumOption => { - const name = enumOption.name.value; - const enumValue: string | number = getValueFromConfig(name) ?? name; - const comment = transformComment(enumOption.description?.value, 1); - - return comment + indent('| ' + wrapWithSingleQuotes(enumValue)); - }) - .concat(...withFutureAddedValue) - .join('\n'), - ).string; - } + if (this.config.enumsAsConst) { + return 'const'; + } - if (this.config.numericEnums) { - const block = new DeclarationBlock(this._declarationBlockConfig) - .export() - .withComment(node.description?.value) - .withName(enumTypeName) - .asKind('enum') - .withBlock( - node.values - .map((enumOption, i) => { - const valueFromConfig = getValueFromConfig(enumOption.name.value); - const enumValue: string | number = valueFromConfig ?? i; - const comment = transformComment(enumOption.description?.value, 1); - const optionName = this.makeValidEnumIdentifier( - this.convertName(enumOption, { - useTypesPrefix: false, - transformUnderscore: true, - }), - ); - return comment + indent(optionName) + ` = ${enumValue}`; - }) - .concat(...withFutureAddedValue) - .join(',\n'), - ).string; - - return block; - } + return this.config.constEnums ? 'native-const' : 'native'; + })(); - if (this.config.enumsAsConst) { - const typeName = `export type ${enumTypeName} = typeof ${enumTypeName}[keyof typeof ${enumTypeName}];`; - const enumAsConst = new DeclarationBlock({ - ...this._declarationBlockConfig, - blockTransformer: block => { - return block + ' as const'; + return convertSchemaEnumToDeclarationBlockString({ + schema: this._schema, + node, + declarationBlockConfig: this._declarationBlockConfig, + enumName, + enumValues: this.config.enumValues, + futureProofEnums: this.config.futureProofEnums, + ignoreEnumValuesFromSchema: this.config.ignoreEnumValuesFromSchema, + outputType, + naming: { + convert: this.config.convert, + options: { + typesPrefix: this.config.typesPrefix, + typesSuffix: this.config.typesSuffix, + useTypesPrefix: this.config.enumPrefix, + useTypesSuffix: this.config.enumSuffix, }, - }) - .export() - .asKind('const') - .withName(enumTypeName) - .withComment(node.description?.value) - .withBlock( - node.values - .map(enumOption => { - const optionName = this.makeValidEnumIdentifier( - this.convertName(enumOption, { - useTypesPrefix: false, - transformUnderscore: true, - }), - ); - const comment = transformComment(enumOption.description?.value, 1); - const name = enumOption.name.value; - const enumValue: string | number = getValueFromConfig(name) ?? name; - - return comment + indent(`${optionName}: ${wrapWithSingleQuotes(enumValue)}`); - }) - .join(',\n'), - ).string; - - return [enumAsConst, typeName].join('\n'); - } - - return new DeclarationBlock(this._declarationBlockConfig) - .export() - .asKind(this.config.constEnums ? 'const enum' : 'enum') - .withName(enumTypeName) - .withComment(node.description?.value) - .withBlock(this.buildEnumValuesBlock(enumName, node.values)).string; + }, + }); } protected getPunctuation(_declarationKind: DeclarationKind): string { diff --git a/packages/plugins/typescript/typescript/tests/typescript.spec.ts b/packages/plugins/typescript/typescript/tests/typescript.spec.ts index a19a185f624..4417d547e46 100644 --- a/packages/plugins/typescript/typescript/tests/typescript.spec.ts +++ b/packages/plugins/typescript/typescript/tests/typescript.spec.ts @@ -29,7 +29,7 @@ describe('TypeScript', () => { Int: { input: number; output: number; } Float: { input: number; output: number; } /** My custom scalar */ - A: { input: any; output: any; } + A: { input: unknown; output: unknown; } }; `); }); @@ -354,12 +354,12 @@ describe('TypeScript', () => { expect(result.content).not.toBeSimilarStringTo(`/** My custom scalar */`); expect(result.content).toBeSimilarStringTo(` 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; } - A: { input: any; output: any; } + 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; } + A: { input: unknown; output: unknown; } }; `); }); @@ -905,13 +905,13 @@ describe('TypeScript', () => { typesPrefix: 'I', namingConvention: { enumValues: 'change-case-all#constantCase' }, enumValues: { - MyEnum: './files#default as MyEnum', + MyEnum: './files#default as MyEnum', // NOTE: `as MyEnum` doesn't do anything, this is here to demonstrate that it's the same as './files#default' }, }, { outputFile: '' }, )) as Types.ComplexPluginOutput; - expect(result.prepend[0]).toBe(`import MyEnum from './files';`); + expect(result.prepend[0]).toBe(`import IMyEnum from './files';`); }); it('#4834 - enum members should be quoted if numeric', async () => { @@ -958,14 +958,21 @@ describe('TypeScript', () => { { outputFile: '' }, )) as Types.ComplexPluginOutput; + expect(result.prepend).toMatchInlineSnapshot(` + [ + "import { MyEnum as IMyEnum } from './files';", + "export type Maybe = T | null;", + "export type InputMaybe = Maybe;", + ] + `); expect(result.content).toBeSimilarStringTo(`export type ITest = { __typename?: 'Test'; - t?: Maybe; + t?: Maybe; test?: Maybe; };`); expect(result.content).toBeSimilarStringTo(`export type ITestTestArgs = { - a?: InputMaybe; + a?: InputMaybe; };`); }); @@ -997,9 +1004,9 @@ describe('TypeScript', () => { }, { outputFile: '' }, )) as Types.ComplexPluginOutput; - expect(result.prepend).toContain(`import { MyEnum } from './files';`); + expect(result.prepend).toContain(`import { MyEnum as GQL_MyEnum } from './files';`); expect(result.content).toContain(`enum GQL_OtherEnum {`); - expect(result.content).toContain(`a?: Maybe;`); + expect(result.content).toContain(`a?: Maybe;`); expect(result.content).toContain(`b?: Maybe`); }); @@ -2193,7 +2200,7 @@ describe('TypeScript', () => { Boolean: { input: boolean; output: boolean; } Int: { input: number; output: number; } Float: { input: number; output: number; } - MyScalar: { input: any; output: any; } + MyScalar: { input: unknown; output: unknown; } };`); expect(result.content).toBeSimilarStringTo(` @@ -2322,7 +2329,7 @@ describe('TypeScript', () => { const result = (await plugin( schema, [], - { defaultScalarType: 'unknown' }, + { defaultScalarType: 'any' }, { outputFile: '' }, )) as Types.ComplexPluginOutput; @@ -2333,7 +2340,7 @@ describe('TypeScript', () => { Boolean: { input: boolean; output: boolean; } Int: { input: number; output: number; } Float: { input: number; output: number; } - MyScalar: { input: unknown; output: unknown; } + MyScalar: { input: any; output: any; } };`); expect(result.content).toBeSimilarStringTo(` diff --git a/packages/presets/client/CHANGELOG.md b/packages/presets/client/CHANGELOG.md index 79755222b00..2cec84c2bc1 100644 --- a/packages/presets/client/CHANGELOG.md +++ b/packages/presets/client/CHANGELOG.md @@ -1,5 +1,162 @@ # @graphql-codegen/client-preset +## 6.0.0 + +### Major Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Fix nullable field optionality in operations + + Previously, a nullable Result field is generated as optional (marked by `?` TypeScript modifier) + by default. This is not correct, because generally at runtime such field can only be `null`, and + not `undefined` (both missing from the object OR `undefined`). The only exceptions are when fields + are deferred (using `@defer` directive) or marked as conditional (using `@skip` or `@include`). + + Now, a nullable Result field cannot be optional unless the exceptions are met. This also limits + `avoidOptionals` to only target Variables input, since some users may want to force explicit + `null` when providing operation variables. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Conditionally generate input types and output + enums into target file + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: make `unknown` instead of + `any` the default custom scalar type + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Update deps to latest, some + only support ESM + + Node 20 support is dropped in this release. Node 22 comes with `require()` support for ESM, which + means it's easier to integrate ES modules into applications. Therefore, it is safe to start using + ESM-only packages. + + If you are a user, please upgrade to Node 22. If you are a lib maintainer and see ESM vs CJS + issues when running Jest tests, try using Vitest. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Drop Node 20 support + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: `typescript` plugin no + longer generates `Exact` utility type. Instead, `typescript-operations` generates said utility + type for every file it creates. This is because it is used _only_ for `Variables`, so we only need + to generate it once for every generated operation file. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Operation plugin and Client + Preset no longer generates optional `__typename` for result type + + `__typenam` should not be in the request unless: + - explicitly requested by the user + - automatically injected into the request by clients, such as Apollo Clients. + + Note: Apollo Client users can still use `nonOptionalTypename: true` and + `skipTypeNameForRoot: true` to ensure generated types match the runtime behaviour. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGES: The default hashing + algorithm is now sha256 instead of sha1. Generated sha256 format also follows the standard + outlined in + https://github.com/graphql/graphql-over-http/blob/52d56fb36d51c17e08a920510a23bdc2f6a720be/spec/Appendix%20A%20--%20Persisted%20Documents.md#sha256-hex-document-identifier + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Integrate new typescript-operations into + client-preset + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: config.avoidOptionals now + only supports object, inputValue, defaultValue + +### Patch Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - dependencies updates: + - Removed dependency + [`@graphql-codegen/typescript@^5.0.8` ↗︎](https://www.npmjs.com/package/@graphql-codegen/typescript/v/5.0.8) + (from `dependencies`) + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Remove @graphql-codegen/typescript from + client-preset dep as the preset no longer uses the plugin. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - Abstract how enum imports are generated into + visitor-plugin-common package + +- Updated dependencies + [[`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29)]: + - @graphql-codegen/gql-tag-operations@6.0.0 + - @graphql-codegen/plugin-helpers@7.0.0 + - @graphql-codegen/typed-document-node@7.0.0 + - @graphql-codegen/typescript@6.0.0 + - @graphql-codegen/typescript-operations@6.0.0 + - @graphql-codegen/visitor-plugin-common@7.0.0 + - @graphql-codegen/add@7.0.0 + ## 5.3.0 ### Minor Changes diff --git a/packages/presets/client/package.json b/packages/presets/client/package.json index 9134d54d97f..dedf7b864fc 100644 --- a/packages/presets/client/package.json +++ b/packages/presets/client/package.json @@ -1,6 +1,6 @@ { "name": "@graphql-codegen/client-preset", - "version": "5.3.0", + "version": "6.0.0", "type": "module", "description": "GraphQL Code Generator preset for client.", "repository": { @@ -48,13 +48,13 @@ "dependencies": { "@babel/helper-plugin-utils": "^7.20.2", "@babel/template": "^7.20.7", - "@graphql-codegen/add": "^6.0.1", - "@graphql-codegen/gql-tag-operations": "5.2.0", - "@graphql-codegen/plugin-helpers": "^6.3.0", - "@graphql-codegen/typed-document-node": "^6.1.8", - "@graphql-codegen/typescript": "^5.0.10", - "@graphql-codegen/typescript-operations": "^5.1.0", - "@graphql-codegen/visitor-plugin-common": "^6.3.0", + "@graphql-codegen/add": "^7.0.0", + "@graphql-codegen/gql-tag-operations": "6.0.0", + "@graphql-codegen/plugin-helpers": "^7.0.0", + "@graphql-codegen/typed-document-node": "^7.0.0", + "@graphql-codegen/typescript": "^6.0.0", + "@graphql-codegen/typescript-operations": "^6.0.0", + "@graphql-codegen/visitor-plugin-common": "^7.0.0", "@graphql-tools/documents": "^1.0.0", "@graphql-tools/utils": "^11.0.0", "@graphql-typed-document-node/core": "3.2.0", diff --git a/packages/presets/client/src/index.ts b/packages/presets/client/src/index.ts index 41f06df349e..41161425b91 100644 --- a/packages/presets/client/src/index.ts +++ b/packages/presets/client/src/index.ts @@ -7,7 +7,6 @@ import { type Types, } from '@graphql-codegen/plugin-helpers'; import * as typedDocumentNodePlugin from '@graphql-codegen/typed-document-node'; -import * as typescriptPlugin from '@graphql-codegen/typescript'; import * as typescriptOperationPlugin from '@graphql-codegen/typescript-operations'; import { ClientSideBaseVisitor, DocumentMode } from '@graphql-codegen/visitor-plugin-common'; import * as fragmentMaskingPlugin from './fragment-masking-plugin.js'; @@ -95,7 +94,7 @@ export type ClientPresetConfig = { * The algorithm parameter is typed with known algorithms and as a string rather than a union because it solely depends on Crypto's algorithms supported * by the version of OpenSSL on the platform. * - * @default `sha1` + * @default `sha256` */ hashAlgorithm?: 'sha1' | 'sha256' | (string & {}) | ((operation: string) => string); }; @@ -138,18 +137,14 @@ export const preset: Types.OutputPreset = { strictScalars: options.config.strictScalars, namingConvention: options.config.namingConvention, useTypeImports: options.config.useTypeImports, - skipTypename: options.config.skipTypename, arrayInputCoercion: options.config.arrayInputCoercion, - enumsAsTypes: options.config.enumsAsTypes, - enumsAsConst: options.config.enumsAsConst, + enumType: options.config.enumType, enumValues: options.config.enumValues, futureProofEnums: options.config.futureProofEnums, nonOptionalTypename: options.config.nonOptionalTypename, avoidOptionals: options.config.avoidOptionals, documentMode: options.config.documentMode, skipTypeNameForRoot: options.config.skipTypeNameForRoot, - onlyOperationTypes: options.config.onlyOperationTypes, - onlyEnums: options.config.onlyEnums, customDirectives: options.config.customDirectives, immutableTypes: options.config.immutableTypes, }; @@ -184,7 +179,7 @@ export const preset: Types.OutputPreset = { hashAlgorithm: (typeof options.presetConfig.persistedDocuments === 'object' && options.presetConfig.persistedDocuments.hashAlgorithm) || - 'sha1', + 'sha256', } : null; @@ -202,7 +197,6 @@ export const preset: Types.OutputPreset = { const pluginMap = { ...options.pluginMap, [`add`]: addPlugin, - [`typescript`]: typescriptPlugin, [`typescript-operations`]: typescriptOperationPlugin, [`typed-document-node`]: { ...typedDocumentNodePlugin, @@ -236,11 +230,6 @@ export const preset: Types.OutputPreset = { const plugins: Array = [ { [`add`]: { content: `/* eslint-disable */` } }, - { - [`typescript`]: { - inputMaybeValue: 'T | null | undefined', - }, - }, { [`typescript-operations`]: {} }, { [`typed-document-node`]: { diff --git a/packages/presets/client/src/persisted-documents.ts b/packages/presets/client/src/persisted-documents.ts index 1fdb21a2563..356fb02d6de 100644 --- a/packages/presets/client/src/persisted-documents.ts +++ b/packages/presets/client/src/persisted-documents.ts @@ -7,6 +7,8 @@ const CONNECTION_DIRECTIVE_NAME = 'connection'; /** * This function generates a hash from a document node. + * When `sha256` algorithm is used, the hash should be prefixed with `sha256:` + * https://github.com/graphql/graphql-over-http/blob/52d56fb36d51c17e08a920510a23bdc2f6a720be/spec/Appendix%20A%20--%20Persisted%20Documents.md#sha256-hex-document-identifier */ export function generateDocumentHash( operation: string, @@ -17,7 +19,10 @@ export function generateDocumentHash( } const shasum = crypto.createHash(algorithm); shasum.update(operation); - return shasum.digest('hex'); + + const algorithmPrefix = algorithm === 'sha256' ? 'sha256:' : ''; + + return algorithmPrefix + shasum.digest('hex'); } /** diff --git a/packages/presets/client/tests/client-preset.enum.spec.ts b/packages/presets/client/tests/client-preset.enum.spec.ts new file mode 100644 index 00000000000..028e5164e37 --- /dev/null +++ b/packages/presets/client/tests/client-preset.enum.spec.ts @@ -0,0 +1,218 @@ +import { executeCodegen } from '@graphql-codegen/cli'; +import { preset } from '../src/index.js'; + +describe('client-preset - Enum', () => { + it('does not generate enum if not used in operations', async () => { + const { result } = await executeCodegen({ + schema: [ + /* GraphQL */ ` + enum Color { + RED + BLUE + } + `, + ], + + generates: { + 'out1/': { + preset, + }, + }, + }); + + const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); + expect(graphqlFile.content).toMatchInlineSnapshot(` + "/* eslint-disable */ + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never };" + `); + }); + + it('generates enum if used in operation Variables', async () => { + const { result } = await executeCodegen({ + schema: [ + /* GraphQL */ ` + type Query { + shape(shape: Shape): ShapeObj! + } + + enum Color { + RED + BLUE + } + + enum Shape { + ROUND + SQUARE + } + + type ShapeObj { + id: ID! + shape: Shape! + } + `, + ], + documents: /* GraphQL */ ` + query Shape($shape: Shape) { + shape(shape: $shape) { + id + } + } + `, + + generates: { + 'out1/': { + preset, + }, + }, + }); + + const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); + expect(graphqlFile.content).toMatchInlineSnapshot(` + "/* eslint-disable */ + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; + export type Shape = + | 'ROUND' + | 'SQUARE'; + + export type ShapeQueryVariables = Exact<{ + shape?: Shape | null | undefined; + }>; + + + export type ShapeQuery = { shape: { id: string } }; + + + export const ShapeDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Shape"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"shape"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Shape"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"shape"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"shape"},"value":{"kind":"Variable","name":{"kind":"Name","value":"shape"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]} as unknown as DocumentNode;" + `); + }); + + it('generates enum if used in operation Result', async () => { + const { result } = await executeCodegen({ + schema: [ + /* GraphQL */ ` + type Query { + shape(shape: Shape): ShapeObj! + } + + enum Color { + RED + BLUE + } + + enum Shape { + ROUND + SQUARE + } + + type ShapeObj { + id: ID! + shape: Shape! + } + `, + ], + documents: /* GraphQL */ ` + query Shape { + shape { + id + shape + } + } + `, + + generates: { + 'out1/': { + preset, + }, + }, + }); + + const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); + expect(graphqlFile.content).toMatchInlineSnapshot(` + "/* eslint-disable */ + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; + export type Shape = + | 'ROUND' + | 'SQUARE'; + + export type ShapeQueryVariables = Exact<{ [key: string]: never; }>; + + + export type ShapeQuery = { shape: { id: string, shape: Shape } }; + + + export const ShapeDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Shape"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"shape"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"shape"}}]}}]}}]} as unknown as DocumentNode;" + `); + }); + + it('supports config.enumType=const', async () => { + const { result } = await executeCodegen({ + schema: [ + /* GraphQL */ ` + type Query { + shape(shape: Shape): ShapeObj! + } + + enum Shape { + ROUND + SQUARE + } + + type ShapeObj { + id: ID! + shape: Shape! + } + `, + ], + documents: /* GraphQL */ ` + query Shape($shape: Shape) { + shape(shape: $shape) { + id + } + } + `, + + generates: { + 'out1/': { + preset, + config: { + enumType: 'const', + }, + }, + }, + }); + + const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); + expect(graphqlFile.content).toMatchInlineSnapshot(` + "/* eslint-disable */ + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; + export const Shape = { + Round: 'ROUND', + Square: 'SQUARE' + } as const; + + export type Shape = typeof Shape[keyof typeof Shape]; + export type ShapeQueryVariables = Exact<{ + shape?: Shape | null | undefined; + }>; + + + export type ShapeQuery = { shape: { id: string } }; + + + export const ShapeDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Shape"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"shape"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Shape"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"shape"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"shape"},"value":{"kind":"Variable","name":{"kind":"Name","value":"shape"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]} as unknown as DocumentNode;" + `); + }); +}); diff --git a/packages/presets/client/tests/client-preset.nullability.spec.ts b/packages/presets/client/tests/client-preset.nullability.spec.ts index acfe41d125f..3d081a1d731 100644 --- a/packages/presets/client/tests/client-preset.nullability.spec.ts +++ b/packages/presets/client/tests/client-preset.nullability.spec.ts @@ -85,16 +85,14 @@ describe('client-preset - nullability', () => { expect(formattedContent).toBeSimilarStringTo(` export type TestQuery = { - __typename?: "Query"; - me?: { - __typename?: "User"; + me: { field: string; fieldLevel0: string; - fieldLevel1?: string | null; + fieldLevel1: string | null; fieldBothLevels: string; list: Array; listLevel0: Array; - listLevel1?: Array | null; + listLevel1: Array | null; listBothLevels: Array; nonNullableList: Array; nonNullableListLevel0: Array; @@ -102,7 +100,7 @@ describe('client-preset - nullability', () => { nonNullableListBothLevels: Array; listWithNonNullableItem: Array; listWithNonNullableItemLevel0: Array; - listWithNonNullableItemLevel1?: Array | null; + listWithNonNullableItemLevel1: Array | null; listWithNonNullableItemBothLevels: Array; nonNullableListWithNonNullableItem: Array; nonNullableListWithNonNullableItemLevel0: Array; @@ -136,25 +134,23 @@ describe('client-preset - nullability', () => { expect(formattedContent).toBeSimilarStringTo(` export type TestQuery = { - __typename?: "Query"; - me?: { - __typename?: "User"; - field?: string | null; - fieldLevel0?: string | null; - fieldLevel1?: string | null; - fieldBothLevels?: string | null; - list?: Array | null; - listLevel0?: Array | null; - listLevel1?: Array | null; - listBothLevels?: Array | null; + me: { + field: string | null; + fieldLevel0: string | null; + fieldLevel1: string | null; + fieldBothLevels: string | null; + list: Array | null; + listLevel0: Array | null; + listLevel1: Array | null; + listBothLevels: Array | null; nonNullableList: Array; nonNullableListLevel0: Array; nonNullableListLevel1: Array; nonNullableListBothLevels: Array; - listWithNonNullableItem?: Array | null; - listWithNonNullableItemLevel0?: Array | null; - listWithNonNullableItemLevel1?: Array | null; - listWithNonNullableItemBothLevels?: Array | null; + listWithNonNullableItem: Array | null; + listWithNonNullableItemLevel0: Array | null; + listWithNonNullableItemLevel1: Array | null; + listWithNonNullableItemBothLevels: Array | null; nonNullableListWithNonNullableItem: Array; nonNullableListWithNonNullableItemLevel0: Array; nonNullableListWithNonNullableItemLevel1: Array; diff --git a/packages/presets/client/tests/client-preset.spec.ts b/packages/presets/client/tests/client-preset.spec.ts index ff77f35dee9..9f132b6f4e2 100644 --- a/packages/presets/client/tests/client-preset.spec.ts +++ b/packages/presets/client/tests/client-preset.spec.ts @@ -362,41 +362,22 @@ export * from "./gql";`); const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); expect(graphqlFile.content).toMatchInlineSnapshot(` "/* eslint-disable */ - import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; - export type Maybe = T | null; - export type InputMaybe = T | null | undefined; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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'; - a?: Maybe; - b?: Maybe; - c?: Maybe; - }; - + import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; export type AQueryVariables = Exact<{ [key: string]: never; }>; - export type AQuery = { __typename?: 'Query', a?: string | null }; + export type AQuery = { a: string | null }; export type BQueryVariables = Exact<{ [key: string]: never; }>; - export type BQuery = { __typename?: 'Query', b?: string | null }; + export type BQuery = { b: string | null }; - export type CFragment = { __typename?: 'Query', c?: string | null } & { ' $fragmentName'?: 'CFragment' }; + export type CFragment = { c: string | null } & { ' $fragmentName'?: 'CFragment' }; export const CFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"C"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Query"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"c"}}]}}]} as unknown as DocumentNode; export const ADocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"A"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"a"}}]}}]} as unknown as DocumentNode; @@ -498,48 +479,27 @@ export * from "./gql";`); const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); expect(graphqlFile.content).toMatchInlineSnapshot(` "/* eslint-disable */ - import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; - export type Maybe = T | null; - export type InputMaybe = T | null | undefined; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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'; - a?: Maybe; - b?: Maybe; - c?: Maybe; - }; - + import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; export type AQueryVariables = Exact<{ [key: string]: never; }>; - export type AQuery = { __typename: 'Query', a?: string | null }; + export type AQuery = { __typename: 'Query', a: string | null }; export type BQueryVariables = Exact<{ [key: string]: never; }>; - export type BQuery = { __typename: 'Query', b?: string | null }; + export type BQuery = { __typename: 'Query', b: string | null }; - export type CFragment = { __typename: 'Query', c?: string | null } & { ' $fragmentName'?: 'CFragment' }; + export type CFragment = { __typename: 'Query', c: string | null } & { ' $fragmentName'?: 'CFragment' }; export const CFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"C"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Query"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"c"}}]}}]} as unknown as DocumentNode; export const ADocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"A"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"a"}}]}}]} as unknown as DocumentNode; export const BDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"B"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"b"}}]}}]} as unknown as DocumentNode;" `); - - expect(graphqlFile.content).toContain("__typename: 'Query';"); }); it('supports Apollo fragment masking', async () => { @@ -587,44 +547,20 @@ export * from "./gql";`); const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); expect(graphqlFile.content).toMatchInlineSnapshot(` "/* eslint-disable */ - import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; - export type Maybe = T | null; - export type InputMaybe = T | null | undefined; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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'; - me?: Maybe; - }; - - export type User = { - __typename?: 'User'; - age: Scalars['Int']['output']; - id: Scalars['ID']['output']; - name: Scalars['String']['output']; - }; - + import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; export type MeQueryVariables = Exact<{ [key: string]: never; }>; - export type MeQuery = { __typename?: 'Query', unmasked?: { __typename?: 'User', id: string, name: string, age: number } | null, masked?: ( - { __typename?: 'User', id: string } + export type MeQuery = { unmasked: { id: string, name: string, age: number } | null, masked: ( + { id: string } & { ' $fragmentRefs'?: { 'User_MeFragment': User_MeFragment } } ) | null }; - export type User_MeFragment = { __typename?: 'User', name: string, age: number } & { ' $fragmentName'?: 'User_MeFragment' }; + export type User_MeFragment = { name: string, age: number } & { ' $fragmentName'?: 'User_MeFragment' }; export const User_MeFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"User_Me"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"age"}}]}}]} as unknown as DocumentNode; export const MeDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Me"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","alias":{"kind":"Name","value":"unmasked"},"name":{"kind":"Name","value":"me"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"User_Me"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"unmask"}}]}]}},{"kind":"Field","alias":{"kind":"Name","value":"masked"},"name":{"kind":"Name","value":"me"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"User_Me"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"User_Me"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"age"}}]}}]} as unknown as DocumentNode;" @@ -704,32 +640,15 @@ export * from "./gql";`); const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); expect(graphqlFile.content).toMatchInlineSnapshot(` "/* eslint-disable */ - import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; - export type Maybe = T | null; - export type InputMaybe = T | null | undefined; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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'; - a?: Maybe; - }; - + import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; export type AQueryVariables = Exact<{ [key: string]: never; }>; - export type AQuery = { __typename?: 'Query', a?: string | null }; + export type AQuery = { a: string | null }; export const ADocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"a"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"a"}}]}}]} as unknown as DocumentNode;" @@ -1561,39 +1480,20 @@ export * from "./gql.cjs";`); const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); expect(graphqlFile.content).toMatchInlineSnapshot(` "/* eslint-disable */ - import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; - export type Maybe = T | null; - export type InputMaybe = T | null | undefined; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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'; - a?: Maybe; - b?: Maybe; - c?: Maybe; - }; - + import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; export type BbbQueryVariables = Exact<{ [key: string]: never; }>; - export type BbbQuery = { __typename?: 'Query', b?: string | null }; + export type BbbQuery = { b: string | null }; export type AaaQueryVariables = Exact<{ [key: string]: never; }>; - export type AaaQuery = { __typename?: 'Query', a?: string | null }; + export type AaaQuery = { a: string | null }; export const BbbDocument = {"__meta__":{"cacheKeys":["bbb"]},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"bbb"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"b"}}]}}]} as unknown as DocumentNode; @@ -1633,53 +1533,34 @@ export * from "./gql.cjs";`); expect(persistedDocuments.content).toMatchInlineSnapshot(` "{ - "b61b879c1eb0040bce65d70c8adfb1ae9360f52f": "query A { a }", - "c3ea9f3f937d47d72c70055ea55c7cf88a35e608": "query B { b }" + "sha256:7d0eedabb966107835cf307a0ebaf93b5d2cb8c30228611ffe3d27a53c211a0c": "query A { a }", + "sha256:a62a11aa72041e38d8c12ef77e1e7c208d9605db60bb5abb1717e8af98e4b410": "query B { b }" }" `); const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); expect(graphqlFile.content).toMatchInlineSnapshot(` "/* eslint-disable */ - import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; - export type Maybe = T | null; - export type InputMaybe = T | null | undefined; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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'; - a?: Maybe; - b?: Maybe; - c?: Maybe; - }; - + import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; export type AQueryVariables = Exact<{ [key: string]: never; }>; - export type AQuery = { __typename?: 'Query', a?: string | null }; + export type AQuery = { a: string | null }; export type BQueryVariables = Exact<{ [key: string]: never; }>; - export type BQuery = { __typename?: 'Query', b?: string | null }; + export type BQuery = { b: string | null }; - export type CFragment = { __typename?: 'Query', c?: string | null } & { ' $fragmentName'?: 'CFragment' }; + export type CFragment = { c: string | null } & { ' $fragmentName'?: 'CFragment' }; export const CFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"C"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Query"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"c"}}]}}]} as unknown as DocumentNode; - export const ADocument = {"__meta__":{"hash":"b61b879c1eb0040bce65d70c8adfb1ae9360f52f"},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"A"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"a"}}]}}]} as unknown as DocumentNode; - export const BDocument = {"__meta__":{"hash":"c3ea9f3f937d47d72c70055ea55c7cf88a35e608"},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"B"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"b"}}]}}]} as unknown as DocumentNode;" + export const ADocument = {"__meta__":{"hash":"sha256:7d0eedabb966107835cf307a0ebaf93b5d2cb8c30228611ffe3d27a53c211a0c"},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"A"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"a"}}]}}]} as unknown as DocumentNode; + export const BDocument = {"__meta__":{"hash":"sha256:a62a11aa72041e38d8c12ef77e1e7c208d9605db60bb5abb1717e8af98e4b410"},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"B"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"b"}}]}}]} as unknown as DocumentNode;" `); }); @@ -1716,53 +1597,34 @@ export * from "./gql.cjs";`); expect(persistedDocuments.content).toMatchInlineSnapshot(` "{ - "b61b879c1eb0040bce65d70c8adfb1ae9360f52f": "query A { a }", - "c3ea9f3f937d47d72c70055ea55c7cf88a35e608": "query B { b }" + "sha256:7d0eedabb966107835cf307a0ebaf93b5d2cb8c30228611ffe3d27a53c211a0c": "query A { a }", + "sha256:a62a11aa72041e38d8c12ef77e1e7c208d9605db60bb5abb1717e8af98e4b410": "query B { b }" }" `); const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); expect(graphqlFile.content).toMatchInlineSnapshot(` "/* eslint-disable */ - import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; - export type Maybe = T | null; - export type InputMaybe = T | null | undefined; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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'; - a?: Maybe; - b?: Maybe; - c?: Maybe; - }; - + import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; export type AQueryVariables = Exact<{ [key: string]: never; }>; - export type AQuery = { __typename?: 'Query', a?: string | null }; + export type AQuery = { a: string | null }; export type BQueryVariables = Exact<{ [key: string]: never; }>; - export type BQuery = { __typename?: 'Query', b?: string | null }; + export type BQuery = { b: string | null }; - export type CFragment = { __typename?: 'Query', c?: string | null } & { ' $fragmentName'?: 'CFragment' }; + export type CFragment = { c: string | null } & { ' $fragmentName'?: 'CFragment' }; export const CFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"C"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Query"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"c"}}]}}]} as unknown as DocumentNode; - export const ADocument = {"__meta__":{"hash":"b61b879c1eb0040bce65d70c8adfb1ae9360f52f"}} as unknown as DocumentNode; - export const BDocument = {"__meta__":{"hash":"c3ea9f3f937d47d72c70055ea55c7cf88a35e608"}} as unknown as DocumentNode;" + export const ADocument = {"__meta__":{"hash":"sha256:7d0eedabb966107835cf307a0ebaf93b5d2cb8c30228611ffe3d27a53c211a0c"}} as unknown as DocumentNode; + export const BDocument = {"__meta__":{"hash":"sha256:a62a11aa72041e38d8c12ef77e1e7c208d9605db60bb5abb1717e8af98e4b410"}} as unknown as DocumentNode;" `); }); @@ -1799,53 +1661,34 @@ export * from "./gql.cjs";`); expect(persistedDocuments.content).toMatchInlineSnapshot(` "{ - "b61b879c1eb0040bce65d70c8adfb1ae9360f52f": "query A { a }", - "c3ea9f3f937d47d72c70055ea55c7cf88a35e608": "query B { b }" + "sha256:7d0eedabb966107835cf307a0ebaf93b5d2cb8c30228611ffe3d27a53c211a0c": "query A { a }", + "sha256:a62a11aa72041e38d8c12ef77e1e7c208d9605db60bb5abb1717e8af98e4b410": "query B { b }" }" `); const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); expect(graphqlFile.content).toMatchInlineSnapshot(` "/* eslint-disable */ - import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; - export type Maybe = T | null; - export type InputMaybe = T | null | undefined; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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'; - a?: Maybe; - b?: Maybe; - c?: Maybe; - }; - + import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; export type AQueryVariables = Exact<{ [key: string]: never; }>; - export type AQuery = { __typename?: 'Query', a?: string | null }; + export type AQuery = { a: string | null }; export type BQueryVariables = Exact<{ [key: string]: never; }>; - export type BQuery = { __typename?: 'Query', b?: string | null }; + export type BQuery = { b: string | null }; - export type CFragment = { __typename?: 'Query', c?: string | null } & { ' $fragmentName'?: 'CFragment' }; + export type CFragment = { c: string | null } & { ' $fragmentName'?: 'CFragment' }; export const CFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"C"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Query"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"c"}}]}}]} as unknown as DocumentNode; - export const ADocument = {"__meta__":{"custom_property_name":"b61b879c1eb0040bce65d70c8adfb1ae9360f52f"},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"A"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"a"}}]}}]} as unknown as DocumentNode; - export const BDocument = {"__meta__":{"custom_property_name":"c3ea9f3f937d47d72c70055ea55c7cf88a35e608"},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"B"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"b"}}]}}]} as unknown as DocumentNode;" + export const ADocument = {"__meta__":{"custom_property_name":"sha256:7d0eedabb966107835cf307a0ebaf93b5d2cb8c30228611ffe3d27a53c211a0c"},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"A"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"a"}}]}}]} as unknown as DocumentNode; + export const BDocument = {"__meta__":{"custom_property_name":"sha256:a62a11aa72041e38d8c12ef77e1e7c208d9605db60bb5abb1717e8af98e4b410"},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"B"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"b"}}]}}]} as unknown as DocumentNode;" `); }); @@ -1890,43 +1733,24 @@ export * from "./gql.cjs";`); const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); expect(graphqlFile.content).toMatchInlineSnapshot(` "/* eslint-disable */ - import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; - export type Maybe = T | null; - export type InputMaybe = T | null | undefined; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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'; - a?: Maybe; - b?: Maybe; - c?: Maybe; - }; - + import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; export type AaaQueryVariables = Exact<{ [key: string]: never; }>; - export type AaaQuery = { __typename?: 'Query', a?: string | null }; + export type AaaQuery = { a: string | null }; export type BbbQueryVariables = Exact<{ [key: string]: never; }>; - export type BbbQuery = { __typename?: 'Query', b?: string | null }; + export type BbbQuery = { b: string | null }; - export const AaaDocument = {"__meta__":{"cacheKeys":["aaa"],"hash":"682f60dea844320c05fcb4fb6c4118015902c9a8"},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"aaa"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"a"}}]}}]} as unknown as DocumentNode; - export const BbbDocument = {"__meta__":{"cacheKeys":["bbb"],"hash":"2a8e0849914b13ebc13b112ba5a502678d757511"},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"bbb"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"b"}}]}}]} as unknown as DocumentNode;" + export const AaaDocument = {"__meta__":{"cacheKeys":["aaa"],"hash":"sha256:a3728239db824c94acc4e31d248e0f05d527606cc8a1bdc4c31307564cd713a1"},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"aaa"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"a"}}]}}]} as unknown as DocumentNode; + export const BbbDocument = {"__meta__":{"cacheKeys":["bbb"],"hash":"sha256:a8badf5c61adc3e65b5c8602e35a138657025aba92b30ece37dab989e7b1264b"},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"bbb"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"b"}}]}}]} as unknown as DocumentNode;" `); }); @@ -1963,53 +1787,34 @@ export * from "./gql.cjs";`); expect(persistedDocuments.content).toMatchInlineSnapshot(` "{ - "7d0eedabb966107835cf307a0ebaf93b5d2cb8c30228611ffe3d27a53c211a0c": "query A { a }", - "a62a11aa72041e38d8c12ef77e1e7c208d9605db60bb5abb1717e8af98e4b410": "query B { b }" + "sha256:7d0eedabb966107835cf307a0ebaf93b5d2cb8c30228611ffe3d27a53c211a0c": "query A { a }", + "sha256:a62a11aa72041e38d8c12ef77e1e7c208d9605db60bb5abb1717e8af98e4b410": "query B { b }" }" `); const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); expect(graphqlFile.content).toMatchInlineSnapshot(` "/* eslint-disable */ - import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; - export type Maybe = T | null; - export type InputMaybe = T | null | undefined; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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'; - a?: Maybe; - b?: Maybe; - c?: Maybe; - }; - + import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; export type AQueryVariables = Exact<{ [key: string]: never; }>; - export type AQuery = { __typename?: 'Query', a?: string | null }; + export type AQuery = { a: string | null }; export type BQueryVariables = Exact<{ [key: string]: never; }>; - export type BQuery = { __typename?: 'Query', b?: string | null }; + export type BQuery = { b: string | null }; - export type CFragment = { __typename?: 'Query', c?: string | null } & { ' $fragmentName'?: 'CFragment' }; + export type CFragment = { c: string | null } & { ' $fragmentName'?: 'CFragment' }; export const CFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"C"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Query"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"c"}}]}}]} as unknown as DocumentNode; - export const ADocument = {"__meta__":{"hash":"7d0eedabb966107835cf307a0ebaf93b5d2cb8c30228611ffe3d27a53c211a0c"},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"A"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"a"}}]}}]} as unknown as DocumentNode; - export const BDocument = {"__meta__":{"hash":"a62a11aa72041e38d8c12ef77e1e7c208d9605db60bb5abb1717e8af98e4b410"},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"B"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"b"}}]}}]} as unknown as DocumentNode;" + export const ADocument = {"__meta__":{"hash":"sha256:7d0eedabb966107835cf307a0ebaf93b5d2cb8c30228611ffe3d27a53c211a0c"},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"A"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"a"}}]}}]} as unknown as DocumentNode; + export const BDocument = {"__meta__":{"hash":"sha256:a62a11aa72041e38d8c12ef77e1e7c208d9605db60bb5abb1717e8af98e4b410"},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"B"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"b"}}]}}]} as unknown as DocumentNode;" `); }); @@ -2058,41 +1863,22 @@ export * from "./gql.cjs";`); const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); expect(graphqlFile.content).toMatchInlineSnapshot(` "/* eslint-disable */ - import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; - export type Maybe = T | null; - export type InputMaybe = T | null | undefined; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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'; - a?: Maybe; - b?: Maybe; - c?: Maybe; - }; - + import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; export type AQueryVariables = Exact<{ [key: string]: never; }>; - export type AQuery = { __typename?: 'Query', a?: string | null }; + export type AQuery = { a: string | null }; export type BQueryVariables = Exact<{ [key: string]: never; }>; - export type BQuery = { __typename?: 'Query', b?: string | null }; + export type BQuery = { b: string | null }; - export type CFragment = { __typename?: 'Query', c?: string | null } & { ' $fragmentName'?: 'CFragment' }; + export type CFragment = { c: string | null } & { ' $fragmentName'?: 'CFragment' }; export const CFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"C"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Query"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"c"}}]}}]} as unknown as DocumentNode; export const ADocument = {"__meta__":{"hash":"queryA{a}"},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"A"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"a"}}]}}]} as unknown as DocumentNode; @@ -2146,41 +1932,22 @@ export * from "./gql.cjs";`); const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); expect(graphqlFile.content).toMatchInlineSnapshot(` "/* eslint-disable */ - import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; - export type Maybe = T | null; - export type InputMaybe = T | null | undefined; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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'; - a?: Maybe; - b?: Maybe; - c?: Maybe; - }; - + import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; export type AQueryVariables = Exact<{ [key: string]: never; }>; - export type AQuery = { __typename?: 'Query', a?: string | null }; + export type AQuery = { a: string | null }; export type BQueryVariables = Exact<{ [key: string]: never; }>; - export type BQuery = { __typename?: 'Query', b?: string | null }; + export type BQuery = { b: string | null }; - export type CFragment = { __typename?: 'Query', c?: string | null } & { ' $fragmentName'?: 'CFragment' }; + export type CFragment = { c: string | null } & { ' $fragmentName'?: 'CFragment' }; export const CFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"C"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Query"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"c"}}]}}]} as unknown as DocumentNode; export const ADocument = {"__meta__":{"hash":"7d0eedabb966107835cf307a0ebaf93b5d2cb8c30228611ffe3d27a53c211a0c"},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"A"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"a"}}]}}]} as unknown as DocumentNode; @@ -2234,41 +2001,22 @@ export * from "./gql.cjs";`); const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); expect(graphqlFile.content).toMatchInlineSnapshot(` "/* eslint-disable */ - import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; - export type Maybe = T | null; - export type InputMaybe = T | null | undefined; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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'; - a?: Maybe; - b?: Maybe; - c?: Maybe; - }; - + import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; export type AQueryVariables = Exact<{ [key: string]: never; }>; - export type AQuery = { __typename?: 'Query', a?: string | null }; + export type AQuery = { a: string | null }; export type BQueryVariables = Exact<{ [key: string]: never; }>; - export type BQuery = { __typename?: 'Query', b?: string | null }; + export type BQuery = { b: string | null }; - export type CFragment = { __typename?: 'Query', c?: string | null } & { ' $fragmentName'?: 'CFragment' }; + export type CFragment = { c: string | null } & { ' $fragmentName'?: 'CFragment' }; export const CFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"C"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Query"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"c"}}]}}]} as unknown as DocumentNode; export const ADocument = {"__meta__":{"hash":"a82d8b22f2bf805563146dc8ad80b2eb054845441539e3a5a69d1f534bb5bc0bd4f9470053b9f61b6aa1966cfc2f67406258102e5ee3a356a5d171506f3ede50"},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"A"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"a"}}]}}]} as unknown as DocumentNode; @@ -2326,50 +2074,24 @@ export * from "./gql.cjs";`); const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); expect(graphqlFile.content).toMatchInlineSnapshot(` "/* eslint-disable */ - import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; - export type Maybe = T | null; - export type InputMaybe = T | null | undefined; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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 A = { - __typename?: 'A'; - a: A; - b: Scalars['String']['output']; - }; - - export type Query = { - __typename?: 'Query'; - a: A; - }; - + import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; export type AbFragment = ( - { __typename?: 'A', b: string } + { b: string } & { ' $fragmentRefs'?: { 'AcFragment': AcFragment;'AaFragment': AaFragment } } ) & { ' $fragmentName'?: 'AbFragment' }; - export type AaFragment = { __typename?: 'A', b: string } & { ' $fragmentName'?: 'AaFragment' }; + export type AaFragment = { b: string } & { ' $fragmentName'?: 'AaFragment' }; export type OiQueryVariables = Exact<{ [key: string]: never; }>; - export type OiQuery = { __typename?: 'Query', a: ( - { __typename?: 'A' } - & { ' $fragmentRefs'?: { 'AbFragment': AbFragment;'AcFragment': AcFragment } } - ) }; + export type OiQuery = { a: { ' $fragmentRefs'?: { 'AbFragment': AbFragment;'AcFragment': AcFragment } } }; - export type AcFragment = { __typename?: 'A', b: string } & { ' $fragmentName'?: 'AcFragment' }; + export type AcFragment = { b: string } & { ' $fragmentName'?: 'AcFragment' }; export const AcFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AC"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"A"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"b"}}]}}]} as unknown as DocumentNode; export const AaFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AA"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"A"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"b"}}]}}]} as unknown as DocumentNode; @@ -2378,6 +2100,89 @@ export * from "./gql.cjs";`); `); }); + it('correctly handle fragment references with explicit __typename', async () => { + const { result } = await executeCodegen({ + schema: /* GraphQL */ ` + type Query { + a: A! + } + + type A { + b: String! + a: A! + } + `, + documents: [ + /* GraphQL */ ` + fragment AC on A { + __typename + b + } + `, + /* GraphQL */ ` + fragment AA on A { + __typename + b + } + `, + /* GraphQL */ ` + fragment AB on A { + __typename + b + ...AC + ...AA + } + `, + /* GraphQL */ ` + query OI { + __typename + a { + __typename + ...AB + ...AC + } + } + `, + ], + generates: { + 'out1/': { + preset, + plugins: [], + }, + }, + }); + const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); + expect(graphqlFile.content).toMatchInlineSnapshot(` + "/* eslint-disable */ + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; + export type AcFragment = { __typename: 'A', b: string } & { ' $fragmentName'?: 'AcFragment' }; + + export type AaFragment = { __typename: 'A', b: string } & { ' $fragmentName'?: 'AaFragment' }; + + export type AbFragment = ( + { __typename: 'A', b: string } + & { ' $fragmentRefs'?: { 'AcFragment': AcFragment;'AaFragment': AaFragment } } + ) & { ' $fragmentName'?: 'AbFragment' }; + + export type OiQueryVariables = Exact<{ [key: string]: never; }>; + + + export type OiQuery = { __typename: 'Query', a: ( + { __typename: 'A' } + & { ' $fragmentRefs'?: { 'AbFragment': AbFragment;'AcFragment': AcFragment } } + ) }; + + export const AcFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AC"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"A"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"Field","name":{"kind":"Name","value":"b"}}]}}]} as unknown as DocumentNode; + export const AaFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AA"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"A"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"Field","name":{"kind":"Name","value":"b"}}]}}]} as unknown as DocumentNode; + export const AbFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AB"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"A"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"Field","name":{"kind":"Name","value":"b"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AC"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AA"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AC"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"A"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"Field","name":{"kind":"Name","value":"b"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AA"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"A"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"Field","name":{"kind":"Name","value":"b"}}]}}]} as unknown as DocumentNode; + export const OiDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"OI"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"Field","name":{"kind":"Name","value":"a"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AB"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AC"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AC"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"A"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"Field","name":{"kind":"Name","value":"b"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AA"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"A"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"Field","name":{"kind":"Name","value":"b"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AB"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"A"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"Field","name":{"kind":"Name","value":"b"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AC"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AA"}}]}}]} as unknown as DocumentNode;" + `); + }); + describe('handles @defer directive', () => { it('generates correct types and metadata', async () => { const { result } = await executeCodegen({ @@ -2405,59 +2210,32 @@ export * from "./gql.cjs";`); const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); expect(graphqlFile.content).toMatchInlineSnapshot(` "/* eslint-disable */ - import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; - export type Maybe = T | null; - export type InputMaybe = T | null | undefined; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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 Foo = { - __typename?: 'Foo'; - id?: Maybe; - value?: Maybe; - }; - - export type Query = { - __typename?: 'Query'; - foo?: Maybe; - foos?: Maybe>>; - }; - + import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; export type FooQueryVariables = Exact<{ [key: string]: never; }>; - export type FooQuery = { __typename?: 'Query', foo?: { __typename?: 'Foo' } & ( - { __typename?: 'Foo' } - & { ' $fragmentRefs'?: { 'FooFragment': Incremental } } - ) | null }; + export type FooQuery = { foo: + | { ' $fragmentRefs'?: { 'FooFragment': Incremental } } + | Record + | null }; export type FoosQueryVariables = Exact<{ [key: string]: never; }>; - export type FoosQuery = { __typename?: 'Query', foos?: Array<{ __typename?: 'Foo' } & ( - { __typename?: 'Foo' } - & { ' $fragmentRefs'?: { 'FooFragment': Incremental } } - ) | null> | null }; + export type FoosQuery = { foos: Array< + | { ' $fragmentRefs'?: { 'FooFragment': Incremental } } + | Record + | null> | null }; - export type FooFragment = { __typename?: 'Foo', value?: string | null } & { ' $fragmentName'?: 'FooFragment' }; + export type FooFragment = { value: string | null } & { ' $fragmentName'?: 'FooFragment' }; - export type FooFragment = { __typename?: 'Foo', id?: string | null } & ({ __typename?: 'Foo', value?: string | null } | { __typename?: 'Foo', value?: never }) & { ' $fragmentName'?: 'FooFragment' }; + export type FooFragment = { id: string | null } & ({ value: string | null } | { value?: never }) & { ' $fragmentName'?: 'FooFragment' }; - export type FooNestedFragment = { __typename?: 'Foo', id?: string | null } & ( - { __typename?: 'Foo' } - & { ' $fragmentRefs'?: { 'FooFragment': Incremental } } - ) & { ' $fragmentName'?: 'FooNestedFragment' }; + export type FooNestedFragment = { id: string | null } & { ' $fragmentRefs'?: { 'FooFragment': Incremental } } & { ' $fragmentName'?: 'FooNestedFragment' }; export const FooFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Foo"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Foo"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"value"}}]}}]} as unknown as DocumentNode; export const FooFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"foo"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Foo"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Foo"}},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"defer"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"value"}}]}}]}}]} as unknown as DocumentNode; @@ -2496,65 +2274,38 @@ export * from "./gql.cjs";`); const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); expect(graphqlFile.content).toMatchInlineSnapshot(` "/* eslint-disable */ - import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; - export type Maybe = T | null; - export type InputMaybe = T | null | undefined; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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 Foo = { - __typename?: 'Foo'; - id?: Maybe; - value?: Maybe; - }; - - export type Query = { - __typename?: 'Query'; - foo?: Maybe; - foos?: Maybe>>; - }; - + import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; export type FooQueryVariables = Exact<{ [key: string]: never; }>; - export type FooQuery = { __typename?: 'Query', foo?: { __typename?: 'Foo' } & ( - { __typename?: 'Foo' } - & { ' $fragmentRefs'?: { 'FooFragment': Incremental } } - ) | null }; + export type FooQuery = { foo: + | { ' $fragmentRefs'?: { 'FooFragment': Incremental } } + | Record + | null }; export type FoosQueryVariables = Exact<{ [key: string]: never; }>; - export type FoosQuery = { __typename?: 'Query', foos?: Array<{ __typename?: 'Foo' } & ( - { __typename?: 'Foo' } - & { ' $fragmentRefs'?: { 'FooFragment': Incremental } } - ) | null> | null }; + export type FoosQuery = { foos: Array< + | { ' $fragmentRefs'?: { 'FooFragment': Incremental } } + | Record + | null> | null }; - export type FooFragment = { __typename?: 'Foo', value?: string | null } & { ' $fragmentName'?: 'FooFragment' }; + export type FooFragment = { value: string | null } & { ' $fragmentName'?: 'FooFragment' }; - export type FooFragment = { __typename?: 'Foo', id?: string | null } & ({ __typename?: 'Foo', value?: string | null } | { __typename?: 'Foo', value?: never }) & { ' $fragmentName'?: 'FooFragment' }; + export type FooFragment = { id: string | null } & ({ value: string | null } | { value?: never }) & { ' $fragmentName'?: 'FooFragment' }; - export type FooNestedFragment = { __typename?: 'Foo', id?: string | null } & ( - { __typename?: 'Foo' } - & { ' $fragmentRefs'?: { 'FooFragment': Incremental } } - ) & { ' $fragmentName'?: 'FooNestedFragment' }; + export type FooNestedFragment = { id: string | null } & { ' $fragmentRefs'?: { 'FooFragment': Incremental } } & { ' $fragmentName'?: 'FooNestedFragment' }; export const FooFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Foo"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Foo"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"value"}}]}}]} as unknown as DocumentNode; export const FooFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"foo"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Foo"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Foo"}},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"defer"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"value"}}]}}]}}]} as unknown as DocumentNode; export const FooNestedFragmentDoc = {"__meta__":{"deferredFields":{"foo":["id"]}},"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"fooNested"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Foo"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"foo"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"defer"}}]}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"foo"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Foo"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Foo"}},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"defer"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"value"}}]}}]}}]} as unknown as DocumentNode; - export const FooDocument = {"__meta__":{"hash":"39c47d2da0fb0e6867abbe2ec942d9858f2d76c7","deferredFields":{"Foo":["value"]}},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Foo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"foo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Foo"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"defer"}}]}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Foo"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Foo"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"value"}}]}}]} as unknown as DocumentNode; - export const FoosDocument = {"__meta__":{"hash":"8aba765173b2302b9857334e9959d97a2168dbc8","deferredFields":{"Foo":["value"]}},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Foos"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"foos"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Foo"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"defer"}}]}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Foo"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Foo"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"value"}}]}}]} as unknown as DocumentNode;" + export const FooDocument = {"__meta__":{"hash":"sha256:07e5ff4a0a8921816acb51a2e854243b3a43554586f1e0a0d0b53f06126bccb6","deferredFields":{"Foo":["value"]}},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Foo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"foo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Foo"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"defer"}}]}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Foo"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Foo"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"value"}}]}}]} as unknown as DocumentNode; + export const FoosDocument = {"__meta__":{"hash":"sha256:f467ac02b2476a740fba9d4fb05ecf4d3660d4d073e3ab45ed274ea65865c30a","deferredFields":{"Foo":["value"]}},"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Foos"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"foos"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Foo"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"defer"}}]}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Foo"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Foo"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"value"}}]}}]} as unknown as DocumentNode;" `); }); @@ -2587,59 +2338,32 @@ export * from "./gql.cjs";`); const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); expect(graphqlFile.content).toMatchInlineSnapshot(` "/* eslint-disable */ - import { DocumentTypeDecoration } from '@graphql-typed-document-node/core'; - export type Maybe = T | null; - export type InputMaybe = T | null | undefined; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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 Foo = { - __typename?: 'Foo'; - id?: Maybe; - value?: Maybe; - }; - - export type Query = { - __typename?: 'Query'; - foo?: Maybe; - foos?: Maybe>>; - }; - + import { DocumentTypeDecoration } from '@graphql-typed-document-node/core'; export type FooQueryVariables = Exact<{ [key: string]: never; }>; - export type FooQuery = { __typename?: 'Query', foo?: { __typename?: 'Foo' } & ( - { __typename?: 'Foo' } - & { ' $fragmentRefs'?: { 'FooFragment': Incremental } } - ) | null }; + export type FooQuery = { foo: + | { ' $fragmentRefs'?: { 'FooFragment': Incremental } } + | Record + | null }; export type FoosQueryVariables = Exact<{ [key: string]: never; }>; - export type FoosQuery = { __typename?: 'Query', foos?: Array<{ __typename?: 'Foo' } & ( - { __typename?: 'Foo' } - & { ' $fragmentRefs'?: { 'FooFragment': Incremental } } - ) | null> | null }; + export type FoosQuery = { foos: Array< + | { ' $fragmentRefs'?: { 'FooFragment': Incremental } } + | Record + | null> | null }; - export type FooFragment = { __typename?: 'Foo', value?: string | null } & { ' $fragmentName'?: 'FooFragment' }; + export type FooFragment = { value: string | null } & { ' $fragmentName'?: 'FooFragment' }; - export type FooFragment = { __typename?: 'Foo', id?: string | null } & ({ __typename?: 'Foo', value?: string | null } | { __typename?: 'Foo', value?: never }) & { ' $fragmentName'?: 'FooFragment' }; + export type FooFragment = { id: string | null } & ({ value: string | null } | { value?: never }) & { ' $fragmentName'?: 'FooFragment' }; - export type FooNestedFragment = { __typename?: 'Foo', id?: string | null } & ( - { __typename?: 'Foo' } - & { ' $fragmentRefs'?: { 'FooFragment': Incremental } } - ) & { ' $fragmentName'?: 'FooNestedFragment' }; + export type FooNestedFragment = { id: string | null } & { ' $fragmentRefs'?: { 'FooFragment': Incremental } } & { ' $fragmentName'?: 'FooNestedFragment' }; export class TypedDocumentString extends String @@ -2751,59 +2475,32 @@ export * from "./gql.cjs";`); const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); expect(graphqlFile.content).toMatchInlineSnapshot(` "/* eslint-disable */ - import { DocumentTypeDecoration } from '@graphql-typed-document-node/core'; - export type Maybe = T | null; - export type InputMaybe = T | null | undefined; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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 Foo = { - __typename?: 'Foo'; - id?: Maybe; - value?: Maybe; - }; - - export type Query = { - __typename?: 'Query'; - foo?: Maybe; - foos?: Maybe>>; - }; - + import { DocumentTypeDecoration } from '@graphql-typed-document-node/core'; export type FooQueryVariables = Exact<{ [key: string]: never; }>; - export type FooQuery = { __typename?: 'Query', foo?: { __typename?: 'Foo' } & ( - { __typename?: 'Foo' } - & { ' $fragmentRefs'?: { 'FooFragment': Incremental } } - ) | null }; + export type FooQuery = { foo: + | { ' $fragmentRefs'?: { 'FooFragment': Incremental } } + | Record + | null }; export type FoosQueryVariables = Exact<{ [key: string]: never; }>; - export type FoosQuery = { __typename?: 'Query', foos?: Array<{ __typename?: 'Foo' } & ( - { __typename?: 'Foo' } - & { ' $fragmentRefs'?: { 'FooFragment': Incremental } } - ) | null> | null }; + export type FoosQuery = { foos: Array< + | { ' $fragmentRefs'?: { 'FooFragment': Incremental } } + | Record + | null> | null }; - export type FooFragment = { __typename?: 'Foo', value?: string | null } & { ' $fragmentName'?: 'FooFragment' }; + export type FooFragment = { value: string | null } & { ' $fragmentName'?: 'FooFragment' }; - export type FooFragment = { __typename?: 'Foo', id?: string | null } & ({ __typename?: 'Foo', value?: string | null } | { __typename?: 'Foo', value?: never }) & { ' $fragmentName'?: 'FooFragment' }; + export type FooFragment = { id: string | null } & ({ value: string | null } | { value?: never }) & { ' $fragmentName'?: 'FooFragment' }; - export type FooNestedFragment = { __typename?: 'Foo', id?: string | null } & ( - { __typename?: 'Foo' } - & { ' $fragmentRefs'?: { 'FooFragment': Incremental } } - ) & { ' $fragmentName'?: 'FooNestedFragment' }; + export type FooNestedFragment = { id: string | null } & { ' $fragmentRefs'?: { 'FooFragment': Incremental } } & { ' $fragmentName'?: 'FooNestedFragment' }; export class TypedDocumentString extends String @@ -2864,7 +2561,7 @@ export * from "./gql.cjs";`); ... on Foo @defer { value } - }\`, {"hash":"2687841b00fe0b3b4fd0dfa2e943f80936594f58","deferredFields":{"Foo":["value"]}}) as unknown as TypedDocumentString; + }\`, {"hash":"sha256:7d1874b8f21095f92812369eeb5557f9eff46319f70d6f69a4cb11eba6c3b215","deferredFields":{"Foo":["value"]}}) as unknown as TypedDocumentString; export const FoosDocument = new TypedDocumentString(\` query Foos { foos { @@ -2879,7 +2576,7 @@ export * from "./gql.cjs";`); ... on Foo @defer { value } - }\`, {"hash":"8db613cc1f12f64dbde9cd6fef167fd12246330d","deferredFields":{"Foo":["value"]}}) as unknown as TypedDocumentString;" + }\`, {"hash":"sha256:3daba53c1f6375961bee04d12a5e3528532479e152c01462918f3c11187ba0aa","deferredFields":{"Foo":["value"]}}) as unknown as TypedDocumentString;" `); }); }); @@ -2913,51 +2610,22 @@ export * from "./gql.cjs";`); const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); expect(graphqlFile.content).toMatchInlineSnapshot(` "/* eslint-disable */ - import { DocumentTypeDecoration } from '@graphql-typed-document-node/core'; - export type Maybe = T | null; - export type InputMaybe = T | null | undefined; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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 Foo = { - __typename?: 'Foo'; - value?: Maybe; - }; - - export type Query = { - __typename?: 'Query'; - foo?: Maybe; - foos?: Maybe>>; - }; - + import { DocumentTypeDecoration } from '@graphql-typed-document-node/core'; export type FooQueryVariables = Exact<{ [key: string]: never; }>; - export type FooQuery = { __typename?: 'Query', foo?: ( - { __typename?: 'Foo' } - & { ' $fragmentRefs'?: { 'FooFragment': FooFragment } } - ) | null }; + export type FooQuery = { foo: { ' $fragmentRefs'?: { 'FooFragment': FooFragment } } | null }; export type FoosQueryVariables = Exact<{ [key: string]: never; }>; - export type FoosQuery = { __typename?: 'Query', foos?: Array<( - { __typename?: 'Foo' } - & { ' $fragmentRefs'?: { 'FooFragment': FooFragment } } - ) | null> | null }; + export type FoosQuery = { foos: Array<{ ' $fragmentRefs'?: { 'FooFragment': FooFragment } } | null> | null }; - export type FooFragment = { __typename?: 'Foo', value?: string | null } & { ' $fragmentName'?: 'FooFragment' }; + export type FooFragment = { value: string | null } & { ' $fragmentName'?: 'FooFragment' }; export class TypedDocumentString extends String @@ -3208,55 +2876,17 @@ export * from "./gql.cjs";`); }); const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); - expect(graphqlFile.content).toBeSimilarStringTo(` - /* eslint-disable */ - import { DocumentTypeDecoration } from '@graphql-typed-document-node/core'; - export type Maybe = T | null; - export type InputMaybe = T | null | undefined; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; + expect(graphqlFile.content).toMatchInlineSnapshot(` + "/* eslint-disable */ + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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 Mutation = { - __typename?: 'Mutation'; - createRegion?: Maybe; - }; - - - export type MutationCreateRegionArgs = { - regionDescription: Scalars['String']['input']; - }; - - export type Query = { - __typename?: 'Query'; - regions?: Maybe>>; - }; - - export type Region = { - __typename?: 'Region'; - regionDescription: Scalars['String']['output']; - regionId: Scalars['Int']['output']; - }; - - export type Subscription = { - __typename?: 'Subscription'; - onRegionCreated: Region; - }; - + import { DocumentTypeDecoration } from '@graphql-typed-document-node/core'; export type OnRegionCreatedSubscriptionVariables = Exact<{ [key: string]: never; }>; - export type OnRegionCreatedSubscription = { __typename?: 'Subscription', onRegionCreated: { __typename: 'Region', regionId: number, regionDescription: string } }; + export type OnRegionCreatedSubscription = { onRegionCreated: { __typename: 'Region', regionId: number, regionDescription: string } }; export class TypedDocumentString extends String @@ -3285,127 +2915,11 @@ export * from "./gql.cjs";`); regionDescription } } - \`) as unknown as TypedDocumentString; + \`) as unknown as TypedDocumentString;" `); }); }); - it('support enumsAsConst option', async () => { - const { result } = await executeCodegen({ - schema: [ - /* GraphQL */ ` - type Query { - thing: Thing - } - type Thing { - color: Color! - } - enum Color { - RED - BLUE - } - `, - ], - documents: path.join(__dirname, 'fixtures/enum.ts'), - generates: { - 'out1/': { - preset, - config: { - enumsAsConst: true, - }, - }, - }, - }); - const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); - expect(graphqlFile.content).toBeSimilarStringTo(` - /* eslint-disable */ - import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; - export type Maybe = T | null; - export type InputMaybe = T | null | undefined; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; - export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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 const Color = { - Blue: 'BLUE', - Red: 'RED' - } as const; - - export type Color = typeof Color[keyof typeof Color]; - export type Query = { - __typename?: 'Query'; - thing?: Maybe; - }; - - export type Thing = { - __typename?: 'Thing'; - color: Color; - }; - - export type FavoriteColorQueryVariables = Exact<{ [key: string]: never; }>; - - - export type FavoriteColorQuery = { __typename?: 'Query', thing?: { __typename?: 'Thing', color: Color } | null }; - - - export const FavoriteColorDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FavoriteColor"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"thing"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"color"}}]}}]}}]} as unknown as DocumentNode; - `); - }); - - it('support enumValues option', async () => { - const { result } = await executeCodegen({ - schema: [ - /* GraphQL */ ` - enum Color { - RED - BLUE - } - `, - ], - generates: { - 'out1/': { - preset, - config: { - enumValues: { - Color: './fixtures/with-enum-values#MyColor', - }, - }, - }, - }, - }); - - const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); - expect(graphqlFile.content).toBeSimilarStringTo(`/* eslint-disable */ - import { MyColor as Color } from './fixtures/with-enum-values'; - export type Maybe = T | null; - export type InputMaybe = T | null | undefined; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; - export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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 { Color };`); - }); - it('supports immutableTypes', async () => { const { result } = await executeCodegen({ schema: [ @@ -3443,44 +2957,15 @@ export * from "./gql.cjs";`); const graphqlFile = result.find(file => file.filename === 'out1/graphql.ts'); expect(graphqlFile.content).toMatchInlineSnapshot(` "/* eslint-disable */ - import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; - export type Maybe = T | null; - export type InputMaybe = T | null | undefined; - export type Exact = { [K in keyof T]: T[K] }; - export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; - export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; - export type MakeEmpty = { [_ in K]?: never }; + /** Internal type. DO NOT USE DIRECTLY. */ + type Exact = { [K in keyof T]: T[K] }; + /** Internal type. DO NOT USE DIRECTLY. */ export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** 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 = { - readonly __typename?: 'Query'; - readonly user?: Maybe; - }; - - - export type QueryUserArgs = { - id: Scalars['ID']['input']; - }; - - export type User = { - readonly __typename?: 'User'; - readonly friends: ReadonlyArray; - readonly id: Scalars['ID']['output']; - readonly name: Scalars['String']['output']; - }; - + import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; export type Test_UserQueryVariables = Exact<{ [key: string]: never; }>; - export type Test_UserQuery = { readonly __typename?: 'Query', readonly user?: { readonly __typename?: 'User', readonly id: string, readonly name: string } | null }; + export type Test_UserQuery = { readonly user: { readonly id: string, readonly name: string } | null }; export const Test_UserDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Test_User"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"StringValue","value":"user-001","block":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]} as unknown as DocumentNode;" diff --git a/packages/presets/graphql-modules/CHANGELOG.md b/packages/presets/graphql-modules/CHANGELOG.md index 4a22985fd59..dfc7fc937dc 100644 --- a/packages/presets/graphql-modules/CHANGELOG.md +++ b/packages/presets/graphql-modules/CHANGELOG.md @@ -1,5 +1,68 @@ # @graphql-codegen/graphql-modules-preset +## 6.0.0 + +### Major Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Update deps to latest, some + only support ESM + + Node 20 support is dropped in this release. Node 22 comes with `require()` support for ESM, which + means it's easier to integrate ES modules into applications. Therefore, it is safe to start using + ESM-only packages. + + If you are a user, please upgrade to Node 22. If you are a lib maintainer and see ESM vs CJS + issues when running Jest tests, try using Vitest. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Drop Node 20 support + +### Patch Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - dependencies updates: + - Updated dependency + [`change-case-all@^2.1.0` ↗︎](https://www.npmjs.com/package/change-case-all/v/2.1.0) (from + `1.0.15`, in `dependencies`) + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - dependencies updates: + - Updated dependency + [`change-case-all@^2.1.0` ↗︎](https://www.npmjs.com/package/change-case-all/v/2.1.0) (from + `1.0.15`, in `dependencies`) +- Updated dependencies + [[`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29)]: + - @graphql-codegen/plugin-helpers@7.0.0 + - @graphql-codegen/visitor-plugin-common@7.0.0 + ## 5.1.5 ### Patch Changes diff --git a/packages/presets/graphql-modules/package.json b/packages/presets/graphql-modules/package.json index 6d63e140309..928dcea694e 100644 --- a/packages/presets/graphql-modules/package.json +++ b/packages/presets/graphql-modules/package.json @@ -1,6 +1,6 @@ { "name": "@graphql-codegen/graphql-modules-preset", - "version": "5.1.5", + "version": "6.0.0", "type": "module", "description": "GraphQL Code Generator preset for modularized schema", "repository": { @@ -39,10 +39,10 @@ "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" }, "dependencies": { - "@graphql-codegen/plugin-helpers": "^6.3.0", - "@graphql-codegen/visitor-plugin-common": "^6.3.0", + "@graphql-codegen/plugin-helpers": "^7.0.0", + "@graphql-codegen/visitor-plugin-common": "^7.0.0", "@graphql-tools/utils": "^11.0.0", - "change-case-all": "1.0.15", + "change-case-all": "^2.1.0", "parse-filepath": "^1.0.2", "tslib": "^2.8.0" }, diff --git a/packages/utils/graphql-codegen-testing/CHANGELOG.md b/packages/utils/graphql-codegen-testing/CHANGELOG.md index 7ce7c566e31..3180e4a6a4f 100644 --- a/packages/utils/graphql-codegen-testing/CHANGELOG.md +++ b/packages/utils/graphql-codegen-testing/CHANGELOG.md @@ -1,5 +1,22 @@ # @graphql-codegen/testing +## 5.0.0 + +### Major Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Drop Node 20 support + +### Patch Changes + +- Updated dependencies + [[`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29), + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29)]: + - @graphql-codegen/plugin-helpers@7.0.0 + ## 4.0.5 ### Patch Changes diff --git a/packages/utils/graphql-codegen-testing/package.json b/packages/utils/graphql-codegen-testing/package.json index abdfce009b5..ac82feebb9b 100644 --- a/packages/utils/graphql-codegen-testing/package.json +++ b/packages/utils/graphql-codegen-testing/package.json @@ -1,6 +1,6 @@ { "name": "@graphql-codegen/testing", - "version": "4.0.5", + "version": "5.0.0", "type": "module", "description": "GraphQL Codegen Testing Utils", "repository": "git@github.com:dotansimha/graphql-code-generator.git", @@ -41,7 +41,7 @@ "typescript": ">=3.0.0" }, "dependencies": { - "@graphql-codegen/plugin-helpers": "^6.3.0", + "@graphql-codegen/plugin-helpers": "^7.0.0", "common-tags": "^1.8.0", "graphql-helix": "1.13.0", "lz-string": "^1.4.4", diff --git a/packages/utils/plugins-helpers/CHANGELOG.md b/packages/utils/plugins-helpers/CHANGELOG.md index df4dcdee0b7..62afefc98e8 100644 --- a/packages/utils/plugins-helpers/CHANGELOG.md +++ b/packages/utils/plugins-helpers/CHANGELOG.md @@ -1,5 +1,41 @@ # @graphql-codegen/plugin-helpers +## 7.0.0 + +### Major Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Update deps to latest, some + only support ESM + + Node 20 support is dropped in this release. Node 22 comes with `require()` support for ESM, which + means it's easier to integrate ES modules into applications. Therefore, it is safe to start using + ESM-only packages. + + If you are a user, please upgrade to Node 22. If you are a lib maintainer and see ESM vs CJS + issues when running Jest tests, try using Vitest. + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - BREAKING CHANGE: Drop Node 20 support + +### Patch Changes + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - dependencies updates: + - Updated dependency + [`change-case-all@^2.1.0` ↗︎](https://www.npmjs.com/package/change-case-all/v/2.1.0) (from + `1.0.15`, in `dependencies`) + +- [#10496](https://github.com/dotansimha/graphql-code-generator/pull/10496) + [`afaace6`](https://github.com/dotansimha/graphql-code-generator/commit/afaace6bb1467793ea8fcda01a6a793e844e0c29) + Thanks [@eddeee888](https://github.com/eddeee888)! - dependencies updates: + - Updated dependency + [`change-case-all@^2.1.0` ↗︎](https://www.npmjs.com/package/change-case-all/v/2.1.0) (from + `1.0.15`, in `dependencies`) + ## 6.3.0 ### Minor Changes diff --git a/packages/utils/plugins-helpers/package.json b/packages/utils/plugins-helpers/package.json index b9a62ac646c..50650df5250 100644 --- a/packages/utils/plugins-helpers/package.json +++ b/packages/utils/plugins-helpers/package.json @@ -1,6 +1,6 @@ { "name": "@graphql-codegen/plugin-helpers", - "version": "6.3.0", + "version": "7.0.0", "type": "module", "description": "GraphQL Code Generator common utils and types", "repository": { @@ -41,7 +41,7 @@ }, "dependencies": { "@graphql-tools/utils": "^11.0.0", - "change-case-all": "1.0.15", + "change-case-all": "^2.1.0", "common-tags": "1.8.2", "import-from": "4.0.0", "tslib": "^2.8.0" diff --git a/tsconfig.spec.json b/tsconfig.spec.json index 633551e9fd7..82d75080116 100644 --- a/tsconfig.spec.json +++ b/tsconfig.spec.json @@ -2,6 +2,8 @@ "extends": "./tsconfig.json", "compilerOptions": { "rootDir": ".", + "module": "nodenext", + "moduleResolution": "nodenext", "composite": true, "types": ["vitest/globals"] }, diff --git a/website/package.json b/website/package.json index 2544e618361..1fc920d3cd6 100644 --- a/website/package.json +++ b/website/package.json @@ -11,20 +11,20 @@ "start": "next start" }, "dependencies": { - "@graphql-codegen/add": "6.0.1", + "@graphql-codegen/add": "7.0.0", "@graphql-codegen/c-sharp": "6.0.1", "@graphql-codegen/c-sharp-operations": "4.0.1", - "@graphql-codegen/cli": "6.3.1", - "@graphql-codegen/client-preset": "5.3.0", - "@graphql-codegen/core": "5.0.2", + "@graphql-codegen/cli": "7.0.0", + "@graphql-codegen/client-preset": "6.0.0", + "@graphql-codegen/core": "6.0.0", "@graphql-codegen/flow": "3.0.1", "@graphql-codegen/flow-operations": "3.0.2", "@graphql-codegen/flow-resolvers": "3.0.2", "@graphql-codegen/flutter-freezed": "^5.0.0", - "@graphql-codegen/fragment-matcher": "6.0.1", + "@graphql-codegen/fragment-matcher": "7.0.0", "@graphql-codegen/hasura-allow-list": "4.0.1", "@graphql-codegen/import-types-preset": "4.0.1", - "@graphql-codegen/introspection": "5.0.2", + "@graphql-codegen/introspection": "6.0.0", "@graphql-codegen/java": "5.0.1", "@graphql-codegen/java-apollo-android": "4.0.1", "@graphql-codegen/java-resolvers": "4.0.1", @@ -32,10 +32,10 @@ "@graphql-codegen/kotlin": "4.0.1", "@graphql-codegen/named-operations-object": "4.0.1", "@graphql-codegen/near-operation-file-preset": "5.1.0", - "@graphql-codegen/schema-ast": "5.0.2", - "@graphql-codegen/time": "6.0.0", - "@graphql-codegen/typed-document-node": "6.1.8", - "@graphql-codegen/typescript": "5.0.10", + "@graphql-codegen/schema-ast": "6.0.0", + "@graphql-codegen/time": "7.0.0", + "@graphql-codegen/typed-document-node": "7.0.0", + "@graphql-codegen/typescript": "6.0.0", "@graphql-codegen/typescript-apollo-angular": "5.0.1", "@graphql-codegen/typescript-apollo-client-helpers": "4.0.1", "@graphql-codegen/typescript-generic-sdk": "5.0.1", @@ -44,10 +44,10 @@ "@graphql-codegen/typescript-mongodb": "4.0.2", "@graphql-codegen/typescript-msw": "4.0.1", "@graphql-codegen/typescript-nhost": "1.0.1", - "@graphql-codegen/typescript-operations": "5.1.0", + "@graphql-codegen/typescript-operations": "6.0.0", "@graphql-codegen/typescript-react-apollo": "4.4.2", "@graphql-codegen/typescript-react-query": "4.1.0", - "@graphql-codegen/typescript-resolvers": "5.1.8", + "@graphql-codegen/typescript-resolvers": "6.0.0", "@graphql-codegen/typescript-rtk-query": "4.0.1", "@graphql-codegen/typescript-stencil-apollo": "4.0.1", "@graphql-codegen/typescript-type-graphql": "3.0.1", diff --git a/website/src/pages/docs/migration/apollo-tooling.mdx b/website/src/pages/docs/migration/apollo-tooling.mdx index 8bf23cd91cf..cfa85304eb2 100644 --- a/website/src/pages/docs/migration/apollo-tooling.mdx +++ b/website/src/pages/docs/migration/apollo-tooling.mdx @@ -16,11 +16,6 @@ This guide explains how to replace it with [GraphQL Code Generator](https://the-guild.dev/graphql/codegen), which is actively maintained, more flexible, and supports a broader range of use cases. - - This setup is available in the next major version of `graphql-code-generator` and - `graphql-code-generator-community`. - - ## Installation Remove Apollo Tooling and install GraphQL Code Generator: diff --git a/website/src/pages/docs/migration/operations-and-client-preset-from-5-0.mdx b/website/src/pages/docs/migration/operations-and-client-preset-from-5-0.mdx index bfb081dc08c..9a596336966 100644 --- a/website/src/pages/docs/migration/operations-and-client-preset-from-5-0.mdx +++ b/website/src/pages/docs/migration/operations-and-client-preset-from-5-0.mdx @@ -16,11 +16,6 @@ import { Callout } from '@theguild/components' # Migrating to `typescript-operations` and `client-preset` v6.0 - - This major version has not been released yet. You can find upcoming changes and alpha releases in - the [feature branch](https://github.com/dotansimha/graphql-code-generator/pull/10496). - - ## What's new? `typescript-operations` and `client-preset` v6.0 come with a major overhaul of type generation and @@ -32,7 +27,8 @@ config to improve developer experience. For the most important changes, read the [Breaking changes](#breaking-changes) section. -For a full list of changes, see the CHANGELOG. +For a full list of changes, see the +[release notes](https://github.com/dotansimha/graphql-code-generator/releases/tag/release-1777556900878). ## Installation diff --git a/website/src/pages/plugins/presets/preset-client.mdx b/website/src/pages/plugins/presets/preset-client.mdx index 82ab461934a..9c3f4ba5dc8 100644 --- a/website/src/pages/plugins/presets/preset-client.mdx +++ b/website/src/pages/plugins/presets/preset-client.mdx @@ -48,53 +48,44 @@ For step-by-step instructions, please [refer to our dedicated guide](/docs/guide The `client` preset allows the following `config` options: -- [`scalars`](/plugins/typescript/typescript#scalars): Extends or overrides the built-in scalars and - custom GraphQL scalars to a custom type. -- [`defaultScalarType`](/plugins/typescript/typescript#defaultscalartype): Allows you to override - the type that unknown `scalars` will have. Defaults to `any`. -- [`strictScalars`](/plugins/typescript/typescript#strictscalars): If `scalars` are found in the - schema that are not defined in scalars an error will be thrown during codegen. -- [`namingConvention`](/plugins/typescript/typescript#namingconvention): Available case functions in - `change-case-all` are `camelCase`, `capitalCase`, `constantCase`, `dotCase`, `headerCase`, - `noCase`, `paramCase`, `pascalCase`, `pathCase`, `sentenceCase`, `snakeCase`, `lowerCase`, - `localeLowerCase`, `lowerCaseFirst`, `spongeCase`, `titleCase`, `upperCase`, `localeUpperCase` and - `upperCaseFirst`. -- [`useTypeImports`](/plugins/typescript/typescript#usetypeimports): Will use `import type {}` - rather than `import {}` when importing only types. This gives compatibility with TypeScript's +- [`scalars`](/plugins/typescript/typescript-operations#scalars): Extends or overrides the built-in + scalars and custom GraphQL scalars to a custom type. +- [`defaultScalarType`](/plugins/typescript/typescript-operations#defaultscalartype): Allows you to + override the type that unknown `scalars` will have. Defaults to `unknown`. +- [`strictScalars`](/plugins/typescript/typescript-operations#strictscalars): If `scalars` are found + in the schema that are not defined in scalars an error will be thrown during codegen. +- [`namingConvention`](/plugins/typescript/typescript-operations#namingconvention): Available case + functions in `change-case-all` are `camelCase`, `capitalCase`, `constantCase`, `dotCase`, + `headerCase`, `noCase`, `paramCase`, `pascalCase`, `pathCase`, `sentenceCase`, `snakeCase`, + `lowerCase`, `localeLowerCase`, `lowerCaseFirst`, `spongeCase`, `titleCase`, `upperCase`, + `localeUpperCase` and `upperCaseFirst`. +- [`useTypeImports`](/plugins/typescript/typescript-operations#usetypeimports): Will use + `import type {}` rather than `import {}` when importing only types. This gives compatibility with + TypeScript's [`"importsNotUsedAsValues": "error"`](https://www.typescriptlang.org/tsconfig#importsNotUsedAsValues) option. -- [`immutableTypes`](/plugins/typescript/typescript#immutabletypes): Generates immutable types by - adding `readonly` to properties and `ReadonlyArray` for lists. -- [`skipTypename`](/plugins/typescript/typescript#skiptypename): Does not add `__typename` to the - generated types, unless it was specified in the selection set. +- [`immutableTypes`](/plugins/typescript/typescript-operations#immutabletypes): Generates immutable + types by adding `readonly` to properties and `ReadonlyArray` for lists. - [`arrayInputCoercion`](/plugins/typescript/typescript-operations#arrayinputcoercion): The [GraphQL spec](https://spec.graphql.org/draft/#sel-FAHjBJFCAACE_Gh7d) allows arrays and a single primitive value for list input. This allows to deactivate that behavior to only accept arrays instead of single values. -- [`enumsAsTypes`](/plugins/typescript/typescript#enumsastypes): Generates enum as TypeScript string - union `type` instead of an `enum`. Useful if you wish to generate `.d.ts` declaration file instead - of `.ts`, or if you want to avoid using TypeScript enums due to bundle size concerns. -- [`enumsAsConst`](/plugins/typescript/typescript#enumsasconst): Generates enum as TypeScript const - assertions instead of enum. This can even be used to enable enum-like patterns in plain JavaScript - code if you choose not to use TypeScript’s enum construct. -- [`enumValues`](/plugins/typescript/typescript#enumvalues): Overrides the default value of enum - values declared in your GraphQL schema. You can also map the entire enum to an external type by - providing a string that of module#type. -- [`futureProofEnums`](/plugins/typescript/typescript#futureproofenums): Adds a catch-all entry to - enum type definitions for values that may be added in the future. -- [`nonOptionalTypename`](/plugins/typescript/typescript#nonoptionaltypename): Automatically adds - `__typename` field to the generated types, even when they are not specified in the selection set, - and makes it non-optional. -- [`avoidOptionals`](/plugins/typescript/typescript#avoidoptionals): This will cause the generator - to avoid using TypeScript optionals (`?`) on types. +- [`enumType`](/plugins/typescript/typescript-operations#enumtype): Changes how TypeScript enums are + generated. +- [`enumValues`](/plugins/typescript/typescript-operations#enumvalues): Overrides the default value + of enum values declared in your GraphQL schema. You can also map the entire enum to an external + type by providing a string that of module#type. +- [`futureProofEnums`](/plugins/typescript/typescript-operations#futureproofenums): Adds a catch-all + entry to enum type definitions for values that may be added in the future. +- [`avoidOptionals`](/plugins/typescript/typescript-operations#avoidoptionals): This will cause the + generator to avoid using TypeScript optionals (`?`) on types. - [`documentMode`](#documentmode): Allows you to control how the documents are generated. +- [`nonOptionalTypename`](/plugins/typescript/typescript-operations#nonoptionaltypename): + Automatically adds `__typename` field to the generated types, even when they are not specified in + the selection set, and makes it non-optional. - [`skipTypeNameForRoot`](/plugins/typescript/typescript-operations#skiptypenameforroot): Avoid adding `__typename` for root types. This is ignored when a selection explicitly specifies `__typename`. -- [`onlyOperationTypes`](/plugins/typescript/typescript#onlyoperationtypes): This will cause the - generator to emit types required for operations only i.e. only enums and scalars. -- [`onlyEnums`](/plugins/typescript/typescript#onlyenums): This will cause the generator to emit - types for enums only. - [`customDirectives`](/plugins/typescript/typescript-operations#customdirectives): Configures behavior for use with custom directives from various GraphQL libraries, such as Apollo Client's [@unmask](https://www.apollographql.com/docs/react/data/directives#unmask). @@ -557,7 +548,7 @@ console.log(await response.json()) ### Hashing algorithm -To override the default hash algorithm of sha1 set `persistedDocuments.hashAlgorithm` +To override the default hash algorithm of sha256 set `persistedDocuments.hashAlgorithm` ```ts filename="codegen.ts" {10-12} import { type CodegenConfig } from '@graphql-codegen/cli' @@ -570,7 +561,7 @@ const config: CodegenConfig = { preset: 'client', presetConfig: { persistedDocuments: { - hashAlgorithm: 'sha256' + hashAlgorithm: 'sha1' } } } diff --git a/yarn.lock b/yarn.lock index 019c825e75b..451e7e7ead1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -20,10 +20,10 @@ package-manager-detector "^1.3.0" tinyexec "^1.0.1" -"@apollo/client@^3.7.10": - version "3.14.1" - resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.14.1.tgz#98931c8feea4a50c89c32ec0c8ffd04ccaa9416f" - integrity sha512-SgGX6E23JsZhUdG2anxiyHvEvvN6CUaI4ZfMsndZFeuHPXL3H0IsaiNAhLITSISbeyeYd+CBd9oERXQDdjXWZw== +"@apollo/client@3.13.8", "@apollo/client@^3.7.10": + version "3.13.8" + resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.13.8.tgz#ef1d49a5b134c69a55e3f137164a8e323aef4e2a" + integrity sha512-YM9lQpm0VfVco4DSyKooHS/fDTiKQcCHfxr7i3iL6a0kP/jNO5+4NFK6vtRDxaYisd5BrwOZHLJpPBnvRVpKPg== dependencies: "@graphql-typed-document-node/core" "^3.1.1" "@wry/caches" "^1.0.0" @@ -1437,86 +1437,171 @@ "@whatwg-node/promise-helpers" "^1.0.0" tslib "^2.5.0" +"@esbuild/aix-ppc64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz#d1bc06aedb6936b3b6d313bf809a5a40387d2b7f" + integrity sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA== + "@esbuild/aix-ppc64@0.27.3": version "0.27.3" resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz#815b39267f9bffd3407ea6c376ac32946e24f8d2" integrity sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg== +"@esbuild/android-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz#7ad65a36cfdb7e0d429c353e00f680d737c2aed4" + integrity sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA== + "@esbuild/android-arm64@0.27.3": version "0.27.3" resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz#19b882408829ad8e12b10aff2840711b2da361e8" integrity sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg== +"@esbuild/android-arm@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.12.tgz#b0c26536f37776162ca8bde25e42040c203f2824" + integrity sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w== + "@esbuild/android-arm@0.27.3": version "0.27.3" resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.27.3.tgz#90be58de27915efa27b767fcbdb37a4470627d7b" integrity sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA== +"@esbuild/android-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.12.tgz#cb13e2211282012194d89bf3bfe7721273473b3d" + integrity sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew== + "@esbuild/android-x64@0.27.3": version "0.27.3" resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.27.3.tgz#d7dcc976f16e01a9aaa2f9b938fbec7389f895ac" integrity sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ== +"@esbuild/darwin-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz#cbee41e988020d4b516e9d9e44dd29200996275e" + integrity sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g== + "@esbuild/darwin-arm64@0.27.3": version "0.27.3" resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz#9f6cac72b3a8532298a6a4493ed639a8988e8abd" integrity sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg== +"@esbuild/darwin-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz#e37d9633246d52aecf491ee916ece709f9d5f4cd" + integrity sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A== + "@esbuild/darwin-x64@0.27.3": version "0.27.3" resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz#ac61d645faa37fd650340f1866b0812e1fb14d6a" integrity sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg== +"@esbuild/freebsd-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz#1ee4d8b682ed363b08af74d1ea2b2b4dbba76487" + integrity sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA== + "@esbuild/freebsd-arm64@0.27.3": version "0.27.3" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz#b8625689d73cf1830fe58c39051acdc12474ea1b" integrity sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w== +"@esbuild/freebsd-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz#37a693553d42ff77cd7126764b535fb6cc28a11c" + integrity sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg== + "@esbuild/freebsd-x64@0.27.3": version "0.27.3" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz#07be7dd3c9d42fe0eccd2ab9f9ded780bc53bead" integrity sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA== +"@esbuild/linux-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz#be9b145985ec6c57470e0e051d887b09dddb2d4b" + integrity sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA== + "@esbuild/linux-arm64@0.27.3": version "0.27.3" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz#bf31918fe5c798586460d2b3d6c46ed2c01ca0b6" integrity sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg== +"@esbuild/linux-arm@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz#207ecd982a8db95f7b5279207d0ff2331acf5eef" + integrity sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w== + "@esbuild/linux-arm@0.27.3": version "0.27.3" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz#28493ee46abec1dc3f500223cd9f8d2df08f9d11" integrity sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw== +"@esbuild/linux-ia32@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz#d0d86b5ca1562523dc284a6723293a52d5860601" + integrity sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA== + "@esbuild/linux-ia32@0.27.3": version "0.27.3" resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz#750752a8b30b43647402561eea764d0a41d0ee29" integrity sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg== +"@esbuild/linux-loong64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz#9a37f87fec4b8408e682b528391fa22afd952299" + integrity sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA== + "@esbuild/linux-loong64@0.27.3": version "0.27.3" resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz#a5a92813a04e71198c50f05adfaf18fc1e95b9ed" integrity sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA== +"@esbuild/linux-mips64el@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz#4ddebd4e6eeba20b509d8e74c8e30d8ace0b89ec" + integrity sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w== + "@esbuild/linux-mips64el@0.27.3": version "0.27.3" resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz#deb45d7fd2d2161eadf1fbc593637ed766d50bb1" integrity sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw== +"@esbuild/linux-ppc64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz#adb67dadb73656849f63cd522f5ecb351dd8dee8" + integrity sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg== + "@esbuild/linux-ppc64@0.27.3": version "0.27.3" resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz#6f39ae0b8c4d3d2d61a65b26df79f6e12a1c3d78" integrity sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA== +"@esbuild/linux-riscv64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz#11bc0698bf0a2abf8727f1c7ace2112612c15adf" + integrity sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg== + "@esbuild/linux-riscv64@0.27.3": version "0.27.3" resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz#4c5c19c3916612ec8e3915187030b9df0b955c1d" integrity sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ== +"@esbuild/linux-s390x@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz#e86fb8ffba7c5c92ba91fc3b27ed5a70196c3cc8" + integrity sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg== + "@esbuild/linux-s390x@0.27.3": version "0.27.3" resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz#9ed17b3198fa08ad5ccaa9e74f6c0aff7ad0156d" integrity sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw== +"@esbuild/linux-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz#5f37cfdc705aea687dfe5dfbec086a05acfe9c78" + integrity sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg== + "@esbuild/linux-x64@0.27.3": version "0.27.3" resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz#12383dcbf71b7cf6513e58b4b08d95a710bf52a5" @@ -1527,6 +1612,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz#dd0cb2fa543205fcd931df44f4786bfcce6df7d7" integrity sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA== +"@esbuild/netbsd-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz#29da566a75324e0d0dd7e47519ba2f7ef168657b" + integrity sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA== + "@esbuild/netbsd-x64@0.27.3": version "0.27.3" resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz#028ad1807a8e03e155153b2d025b506c3787354b" @@ -1537,6 +1627,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz#e3c16ff3490c9b59b969fffca87f350ffc0e2af5" integrity sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw== +"@esbuild/openbsd-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz#306c0acbdb5a99c95be98bdd1d47c916e7dc3ff0" + integrity sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw== + "@esbuild/openbsd-x64@0.27.3": version "0.27.3" resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz#c5a4693fcb03d1cbecbf8b422422468dfc0d2a8b" @@ -1547,27 +1642,54 @@ resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz#082082444f12db564a0775a41e1991c0e125055e" integrity sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g== +"@esbuild/sunos-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz#0933eaab9af8b9b2c930236f62aae3fc593faf30" + integrity sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA== + "@esbuild/sunos-x64@0.27.3": version "0.27.3" resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz#5ab036c53f929e8405c4e96e865a424160a1b537" integrity sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA== +"@esbuild/win32-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz#773bdbaa1971b36db2f6560088639ccd1e6773ae" + integrity sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A== + "@esbuild/win32-arm64@0.27.3": version "0.27.3" resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz#38de700ef4b960a0045370c171794526e589862e" integrity sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA== +"@esbuild/win32-ia32@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz#000516cad06354cc84a73f0943a4aa690ef6fd67" + integrity sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ== + "@esbuild/win32-ia32@0.27.3": version "0.27.3" resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz#451b93dc03ec5d4f38619e6cd64d9f9eff06f55c" integrity sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q== +"@esbuild/win32-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz#c57c8afbb4054a3ab8317591a0b7320360b444ae" + integrity sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA== + "@esbuild/win32-x64@0.27.3": version "0.27.3" resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz#0eaf705c941a218a43dba8e09f1df1d6cd2f1f17" integrity sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA== -"@eslint-community/eslint-utils@^4.1.2", "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0", "@eslint-community/eslint-utils@^4.4.1", "@eslint-community/eslint-utils@^4.8.0", "@eslint-community/eslint-utils@^4.9.1": +"@eslint-community/eslint-utils@^4.1.2", "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0", "@eslint-community/eslint-utils@^4.4.1": + version "4.4.1" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz#d1145bf2c20132d6400495d6df4bf59362fd9d56" + integrity sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA== + dependencies: + eslint-visitor-keys "^3.4.3" + +"@eslint-community/eslint-utils@^4.8.0", "@eslint-community/eslint-utils@^4.9.1": version "4.9.1" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz#4e90af67bc51ddee6cdef5284edf572ec376b595" integrity sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ== @@ -2775,63 +2897,60 @@ resolved "https://registry.yarnpkg.com/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz#a81ffb00e69267cd0a1d626eaedb8a8430b2b2f8" integrity sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw== -"@inquirer/ansi@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@inquirer/ansi/-/ansi-1.0.2.tgz#674a4c4d81ad460695cb2a1fc69d78cd187f337e" - integrity sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ== - -"@inquirer/checkbox@^4.3.2": - version "4.3.2" - resolved "https://registry.yarnpkg.com/@inquirer/checkbox/-/checkbox-4.3.2.tgz#e1483e6519d6ffef97281a54d2a5baa0d81b3f3b" - integrity sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA== - dependencies: - "@inquirer/ansi" "^1.0.2" - "@inquirer/core" "^10.3.2" - "@inquirer/figures" "^1.0.15" - "@inquirer/type" "^3.0.10" - yoctocolors-cjs "^2.1.3" - -"@inquirer/confirm@^5.1.21": - version "5.1.21" - resolved "https://registry.yarnpkg.com/@inquirer/confirm/-/confirm-5.1.21.tgz#610c4acd7797d94890a6e2dde2c98eb1e891dd12" - integrity sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ== - dependencies: - "@inquirer/core" "^10.3.2" - "@inquirer/type" "^3.0.10" - -"@inquirer/core@^10.3.2": - version "10.3.2" - resolved "https://registry.yarnpkg.com/@inquirer/core/-/core-10.3.2.tgz#535979ff3ff4fe1e7cc4f83e2320504c743b7e20" - integrity sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A== - dependencies: - "@inquirer/ansi" "^1.0.2" - "@inquirer/figures" "^1.0.15" - "@inquirer/type" "^3.0.10" +"@inquirer/ansi@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@inquirer/ansi/-/ansi-2.0.4.tgz#c767aba4e224297c17108820e2401d9def117172" + integrity sha512-DpcZrQObd7S0R/U3bFdkcT5ebRwbTTC4D3tCc1vsJizmgPLxNJBo+AAFmrZwe8zk30P2QzgzGWZ3Q9uJwWuhIg== + +"@inquirer/checkbox@^5.1.2": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@inquirer/checkbox/-/checkbox-5.1.2.tgz#8cc30b3f16625b1f29425ce68fd7b65d03759807" + integrity sha512-PubpMPO2nJgMufkoB3P2wwxNXEMUXnBIKi/ACzDUYfaoPuM7gSTmuxJeMscoLVEsR4qqrCMf5p0SiYGWnVJ8kw== + dependencies: + "@inquirer/ansi" "^2.0.4" + "@inquirer/core" "^11.1.7" + "@inquirer/figures" "^2.0.4" + "@inquirer/type" "^4.0.4" + +"@inquirer/confirm@^6.0.10": + version "6.0.10" + resolved "https://registry.yarnpkg.com/@inquirer/confirm/-/confirm-6.0.10.tgz#96366b834273421233f3eae1a55b47cd19e75228" + integrity sha512-tiNyA73pgpQ0FQ7axqtoLUe4GDYjNCDcVsbgcA5anvwg2z6i+suEngLKKJrWKJolT//GFPZHwN30binDIHgSgQ== + dependencies: + "@inquirer/core" "^11.1.7" + "@inquirer/type" "^4.0.4" + +"@inquirer/core@^11.1.7": + version "11.1.7" + resolved "https://registry.yarnpkg.com/@inquirer/core/-/core-11.1.7.tgz#053041e54dc35d0043a9280d94f58da0e3a7b716" + integrity sha512-1BiBNDk9btIwYIzNZpkikIHXWeNzNncJePPqwDyVMhXhD1ebqbpn1mKGctpoqAbzywZfdG0O4tvmsGIcOevAPQ== + dependencies: + "@inquirer/ansi" "^2.0.4" + "@inquirer/figures" "^2.0.4" + "@inquirer/type" "^4.0.4" cli-width "^4.1.0" - mute-stream "^2.0.0" + fast-wrap-ansi "^0.2.0" + mute-stream "^3.0.0" signal-exit "^4.1.0" - wrap-ansi "^6.2.0" - yoctocolors-cjs "^2.1.3" -"@inquirer/editor@^4.2.23": - version "4.2.23" - resolved "https://registry.yarnpkg.com/@inquirer/editor/-/editor-4.2.23.tgz#fe046a3bfdae931262de98c1052437d794322e0b" - integrity sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ== +"@inquirer/editor@^5.0.10": + version "5.0.10" + resolved "https://registry.yarnpkg.com/@inquirer/editor/-/editor-5.0.10.tgz#5e019f4b8e7f3049391b366074cf566c909f912f" + integrity sha512-VJx4XyaKea7t8hEApTw5dxeIyMtWXre2OiyJcICCRZI4hkoHsMoCnl/KbUnJJExLbH9csLLHMVR144ZhFE1CwA== dependencies: - "@inquirer/core" "^10.3.2" - "@inquirer/external-editor" "^1.0.3" - "@inquirer/type" "^3.0.10" + "@inquirer/core" "^11.1.7" + "@inquirer/external-editor" "^2.0.4" + "@inquirer/type" "^4.0.4" -"@inquirer/expand@^4.0.23": - version "4.0.23" - resolved "https://registry.yarnpkg.com/@inquirer/expand/-/expand-4.0.23.tgz#a38b5f32226d75717c370bdfed792313b92bdc05" - integrity sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew== +"@inquirer/expand@^5.0.10": + version "5.0.10" + resolved "https://registry.yarnpkg.com/@inquirer/expand/-/expand-5.0.10.tgz#0c24970db9cf5ed3327ea0e9ce06e82103731992" + integrity sha512-fC0UHJPXsTRvY2fObiwuQYaAnHrp3aDqfwKUJSdfpgv18QUG054ezGbaRNStk/BKD5IPijeMKWej8VV8O5Q/eQ== dependencies: - "@inquirer/core" "^10.3.2" - "@inquirer/type" "^3.0.10" - yoctocolors-cjs "^2.1.3" + "@inquirer/core" "^11.1.7" + "@inquirer/type" "^4.0.4" -"@inquirer/external-editor@^1.0.2", "@inquirer/external-editor@^1.0.3": +"@inquirer/external-editor@^1.0.2": version "1.0.3" resolved "https://registry.yarnpkg.com/@inquirer/external-editor/-/external-editor-1.0.3.tgz#c23988291ee676290fdab3fd306e64010a6d13b8" integrity sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA== @@ -2839,86 +2958,100 @@ chardet "^2.1.1" iconv-lite "^0.7.0" -"@inquirer/figures@^1.0.15": - version "1.0.15" - resolved "https://registry.yarnpkg.com/@inquirer/figures/-/figures-1.0.15.tgz#dbb49ed80df11df74268023b496ac5d9acd22b3a" - integrity sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g== +"@inquirer/external-editor@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@inquirer/external-editor/-/external-editor-2.0.4.tgz#1178821c52014bf70bbadd664ee6fedc37a40b5c" + integrity sha512-Prenuv9C1PHj2Itx0BcAOVBTonz02Hc2Nd2DbU67PdGUaqn0nPCnV34oDyyoaZHnmfRxkpuhh/u51ThkrO+RdA== + dependencies: + chardet "^2.1.1" + iconv-lite "^0.7.2" -"@inquirer/input@^4.3.1": - version "4.3.1" - resolved "https://registry.yarnpkg.com/@inquirer/input/-/input-4.3.1.tgz#778683b4c4c4d95d05d4b05c4a854964b73565b4" - integrity sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g== +"@inquirer/figures@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@inquirer/figures/-/figures-2.0.4.tgz#154986941a00db8b8171d1ed0d1df566972ed173" + integrity sha512-eLBsjlS7rPS3WEhmOmh1znQ5IsQrxWzxWDxO51e4urv+iVrSnIHbq4zqJIOiyNdYLa+BVjwOtdetcQx1lWPpiQ== + +"@inquirer/input@^5.0.10": + version "5.0.10" + resolved "https://registry.yarnpkg.com/@inquirer/input/-/input-5.0.10.tgz#0a18347e8f16d4cb01e1d801f1ca8fcca26006dc" + integrity sha512-nvZ6qEVeX/zVtZ1dY2hTGDQpVGD3R7MYPLODPgKO8Y+RAqxkrP3i/3NwF3fZpLdaMiNuK0z2NaYIx9tPwiSegQ== dependencies: - "@inquirer/core" "^10.3.2" - "@inquirer/type" "^3.0.10" + "@inquirer/core" "^11.1.7" + "@inquirer/type" "^4.0.4" -"@inquirer/number@^3.0.23": - version "3.0.23" - resolved "https://registry.yarnpkg.com/@inquirer/number/-/number-3.0.23.tgz#3fdec2540d642093fd7526818fd8d4bdc7335094" - integrity sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg== - dependencies: - "@inquirer/core" "^10.3.2" - "@inquirer/type" "^3.0.10" - -"@inquirer/password@^4.0.23": - version "4.0.23" - resolved "https://registry.yarnpkg.com/@inquirer/password/-/password-4.0.23.tgz#b9f5187c8c92fd7aa9eceb9d8f2ead0d7e7b000d" - integrity sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA== - dependencies: - "@inquirer/ansi" "^1.0.2" - "@inquirer/core" "^10.3.2" - "@inquirer/type" "^3.0.10" - -"@inquirer/prompts@^7.8.2": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@inquirer/prompts/-/prompts-7.10.1.tgz#e1436c0484cf04c22548c74e2cd239e989d5f847" - integrity sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg== - dependencies: - "@inquirer/checkbox" "^4.3.2" - "@inquirer/confirm" "^5.1.21" - "@inquirer/editor" "^4.2.23" - "@inquirer/expand" "^4.0.23" - "@inquirer/input" "^4.3.1" - "@inquirer/number" "^3.0.23" - "@inquirer/password" "^4.0.23" - "@inquirer/rawlist" "^4.1.11" - "@inquirer/search" "^3.2.2" - "@inquirer/select" "^4.4.2" - -"@inquirer/rawlist@^4.1.11": - version "4.1.11" - resolved "https://registry.yarnpkg.com/@inquirer/rawlist/-/rawlist-4.1.11.tgz#313c8c3ffccb7d41e990c606465726b4a898a033" - integrity sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw== - dependencies: - "@inquirer/core" "^10.3.2" - "@inquirer/type" "^3.0.10" - yoctocolors-cjs "^2.1.3" - -"@inquirer/search@^3.2.2": - version "3.2.2" - resolved "https://registry.yarnpkg.com/@inquirer/search/-/search-3.2.2.tgz#4cc6fd574dcd434e4399badc37c742c3fd534ac8" - integrity sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA== +"@inquirer/number@^4.0.10": + version "4.0.10" + resolved "https://registry.yarnpkg.com/@inquirer/number/-/number-4.0.10.tgz#e8d3a3f218c8795c0aade0cb1821df8a0f4682b4" + integrity sha512-Ht8OQstxiS3APMGjHV0aYAjRAysidWdwurWEo2i8yI5xbhOBWqizT0+MU1S2GCcuhIBg+3SgWVjEoXgfhY+XaA== dependencies: - "@inquirer/core" "^10.3.2" - "@inquirer/figures" "^1.0.15" - "@inquirer/type" "^3.0.10" - yoctocolors-cjs "^2.1.3" + "@inquirer/core" "^11.1.7" + "@inquirer/type" "^4.0.4" -"@inquirer/select@^4.4.2": - version "4.4.2" - resolved "https://registry.yarnpkg.com/@inquirer/select/-/select-4.4.2.tgz#2ac8fca960913f18f1d1b35323ed8fcd27d89323" - integrity sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w== +"@inquirer/password@^5.0.10": + version "5.0.10" + resolved "https://registry.yarnpkg.com/@inquirer/password/-/password-5.0.10.tgz#53cc6613ac2cb18b018f83d0731c73783ba3c353" + integrity sha512-QbNyvIE8q2GTqKLYSsA8ATG+eETo+m31DSR0+AU7x3d2FhaTWzqQek80dj3JGTo743kQc6mhBR0erMjYw5jQ0A== dependencies: - "@inquirer/ansi" "^1.0.2" - "@inquirer/core" "^10.3.2" - "@inquirer/figures" "^1.0.15" - "@inquirer/type" "^3.0.10" - yoctocolors-cjs "^2.1.3" + "@inquirer/ansi" "^2.0.4" + "@inquirer/core" "^11.1.7" + "@inquirer/type" "^4.0.4" -"@inquirer/type@^3.0.10": - version "3.0.10" - resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-3.0.10.tgz#11ed564ec78432a200ea2601a212d24af8150d50" - integrity sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA== +"@inquirer/prompts@^8.3.2": + version "8.3.2" + resolved "https://registry.yarnpkg.com/@inquirer/prompts/-/prompts-8.3.2.tgz#7d2464b53011a5fbd5cc6f22b365a61c60104a2a" + integrity sha512-yFroiSj2iiBFlm59amdTvAcQFvWS6ph5oKESls/uqPBect7rTU2GbjyZO2DqxMGuIwVA8z0P4K6ViPcd/cp+0w== + dependencies: + "@inquirer/checkbox" "^5.1.2" + "@inquirer/confirm" "^6.0.10" + "@inquirer/editor" "^5.0.10" + "@inquirer/expand" "^5.0.10" + "@inquirer/input" "^5.0.10" + "@inquirer/number" "^4.0.10" + "@inquirer/password" "^5.0.10" + "@inquirer/rawlist" "^5.2.6" + "@inquirer/search" "^4.1.6" + "@inquirer/select" "^5.1.2" + +"@inquirer/rawlist@^5.2.6": + version "5.2.6" + resolved "https://registry.yarnpkg.com/@inquirer/rawlist/-/rawlist-5.2.6.tgz#fcc00c80e2d4597ba6010eb72e373690c6c82241" + integrity sha512-jfw0MLJ5TilNsa9zlJ6nmRM0ZFVZhhTICt4/6CU2Dv1ndY7l3sqqo1gIYZyMMDw0LvE1u1nzJNisfHEhJIxq5w== + dependencies: + "@inquirer/core" "^11.1.7" + "@inquirer/type" "^4.0.4" + +"@inquirer/search@^4.1.6": + version "4.1.6" + resolved "https://registry.yarnpkg.com/@inquirer/search/-/search-4.1.6.tgz#399b87074af1e7a2c8d6924fe6bd90b993f40f41" + integrity sha512-3/6kTRae98hhDevENScy7cdFEuURnSpM3JbBNg8yfXLw88HgTOl+neUuy/l9W0No5NzGsLVydhBzTIxZP7yChQ== + dependencies: + "@inquirer/core" "^11.1.7" + "@inquirer/figures" "^2.0.4" + "@inquirer/type" "^4.0.4" + +"@inquirer/select@^5.1.2": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@inquirer/select/-/select-5.1.2.tgz#d40f6af6fe86dbdbd97587a76ba3101274fb5208" + integrity sha512-kTK8YIkHV+f02y7bWCh7E0u2/11lul5WepVTclr3UMBtBr05PgcZNWfMa7FY57ihpQFQH/spLMHTcr0rXy50tA== + dependencies: + "@inquirer/ansi" "^2.0.4" + "@inquirer/core" "^11.1.7" + "@inquirer/figures" "^2.0.4" + "@inquirer/type" "^4.0.4" + +"@inquirer/testing@3.3.2": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@inquirer/testing/-/testing-3.3.2.tgz#8f111529276ba88bd99d81133d1b2aa374818c3b" + integrity sha512-kR5fSmr6eV0sz6bonnDrW8PDdVC2D15Ftv0Y4+y081fidr+4XhruPezz5/GqUHYRCvQXcBG8w1UhWGIU0zy+Vg== + dependencies: + "@inquirer/type" "^4.0.4" + "@xterm/headless" "^6.0.0" + mute-stream "^3.0.0" + +"@inquirer/type@^4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-4.0.4.tgz#ef66cf0ee6af7d240d5aa462dd7697be010a1837" + integrity sha512-PamArxO3cFJZoOzspzo6cxVlLeIftyBsZw/S9bKY5DzxqJVZgjoj1oP8d0rskKtp7sZxBycsoer1g6UeJV1BBA== "@internationalized/date@^3.12.1": version "3.12.1" @@ -4049,130 +4182,130 @@ resolved "https://registry.yarnpkg.com/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.7.tgz#0414869467f0e471a6515d4f506c85fde867e022" integrity sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA== -"@rollup/rollup-android-arm-eabi@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.2.tgz#a19c645c375158cd5c50a344106f0fa18eb821c4" - integrity sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw== - -"@rollup/rollup-android-arm64@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.2.tgz#1af19aa9d3ad6d00df2681f59cfcb8bf7499576b" - integrity sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg== - -"@rollup/rollup-darwin-arm64@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.2.tgz#3b8463e03ba2a393453fea70e7d907379c27b649" - integrity sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA== - -"@rollup/rollup-darwin-x64@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.2.tgz#28da23d69fe117f5f0ff330a8549e51bd09f1b6a" - integrity sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g== - -"@rollup/rollup-freebsd-arm64@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.2.tgz#94bacac3190f621de1355922b599f3817786044c" - integrity sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw== - -"@rollup/rollup-freebsd-x64@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.2.tgz#8a0094f533b9fda160b5c90ad9e0c78fca341788" - integrity sha512-LU+TPda3mAE2QB0/Hp5VyeKJivpC6+tlOXd1VMoXV/YFMvk/MNk5iXeBfB4MQGRWyOYVJ01625vjkr0Az98OJQ== - -"@rollup/rollup-linux-arm-gnueabihf@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.2.tgz#3b7e901a555c7245c87f7440979bee0a1ec882bb" - integrity sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg== - -"@rollup/rollup-linux-arm-musleabihf@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.2.tgz#ee9a09b72e8ad764cfd6188b32ff1de528ff7ebe" - integrity sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw== - -"@rollup/rollup-linux-arm64-gnu@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.2.tgz#ba483f4aca9be141171d086dbd01ada6ab03b58d" - integrity sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg== - -"@rollup/rollup-linux-arm64-musl@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.2.tgz#17b595b790e6df68e91c5d02526fc832a985ce4f" - integrity sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA== - -"@rollup/rollup-linux-loong64-gnu@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.2.tgz#551718714075a2bfb36a2813c466e3a0e9d56abf" - integrity sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A== - -"@rollup/rollup-linux-loong64-musl@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.2.tgz#ba156ed1243447a3d710972001d5dcfe3827ff3d" - integrity sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q== - -"@rollup/rollup-linux-ppc64-gnu@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.2.tgz#6a957a709b86ac62ef68e597ac03dbd4336782b1" - integrity sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw== - -"@rollup/rollup-linux-ppc64-musl@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.2.tgz#ca4176b4ad53f3edee3b4bfa6f9ef48ff38f167b" - integrity sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ== - -"@rollup/rollup-linux-riscv64-gnu@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.2.tgz#4e6b08f72ebeafdb41f3ec433bd228ba8573473b" - integrity sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A== - -"@rollup/rollup-linux-riscv64-musl@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.2.tgz#a0b8b8580c7680c8086cb3226527e5472253b895" - integrity sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ== - -"@rollup/rollup-linux-s390x-gnu@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.2.tgz#79fe15b92ce0bae2b609cf26dd158cd3e2b73634" - integrity sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA== - -"@rollup/rollup-linux-x64-gnu@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.2.tgz#6aa8302fa45fd3cbbc510ccd223c9c37bf67e53f" - integrity sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ== - -"@rollup/rollup-linux-x64-musl@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.2.tgz#0c1a5e9799f80c47a66f2c3a5f1a280f38356047" - integrity sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw== - -"@rollup/rollup-openbsd-x64@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.2.tgz#5f07c863e74fd428794f1dc5749f321b661d1f17" - integrity sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg== - -"@rollup/rollup-openharmony-arm64@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.2.tgz#8e0d71324be0f423428b12b25a2eb8ea8e0a7833" - integrity sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q== - -"@rollup/rollup-win32-arm64-msvc@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.2.tgz#a553fdf90a785ace6d7501eed6241c468b088999" - integrity sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ== - -"@rollup/rollup-win32-ia32-msvc@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.2.tgz#0fb04f0a88027fbfd323e25a446debce4773868c" - integrity sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg== - -"@rollup/rollup-win32-x64-gnu@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.2.tgz#aaa9e36dbdc0f0e397e5966dcce1b4285354ede2" - integrity sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA== - -"@rollup/rollup-win32-x64-msvc@4.60.2": - version "4.60.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.2.tgz#3418dcf1388f2abd6b0ccc08fe1ef205ae76d696" - integrity sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA== +"@rollup/rollup-android-arm-eabi@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.1.tgz#043f145716234529052ef9e1ce1d847ffbe9e674" + integrity sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA== + +"@rollup/rollup-android-arm64@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.1.tgz#023e1bd146e7519087dfd9e8b29e4cf9f8ecd35c" + integrity sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA== + +"@rollup/rollup-darwin-arm64@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.1.tgz#55ccb5487c02419954c57a7a80602885d616e1ee" + integrity sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw== + +"@rollup/rollup-darwin-x64@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.1.tgz#254b65404b14488c83225e88b8819376ad71a784" + integrity sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew== + +"@rollup/rollup-freebsd-arm64@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.1.tgz#6377ff38c052c76fcaffb7b2728d3172fe676fe6" + integrity sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w== + +"@rollup/rollup-freebsd-x64@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.1.tgz#ba3902309d088eaf7139b916f09b7140b28b406d" + integrity sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g== + +"@rollup/rollup-linux-arm-gnueabihf@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.1.tgz#e011b9a14638267e53b446286e838dbdaf53f167" + integrity sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g== + +"@rollup/rollup-linux-arm-musleabihf@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.1.tgz#0bce9ce9a009490abd28fd922dd97ed521311afe" + integrity sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg== + +"@rollup/rollup-linux-arm64-gnu@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.1.tgz#6f6cfbbf324fbb4ceff213abdf7f322fd45d25ff" + integrity sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ== + +"@rollup/rollup-linux-arm64-musl@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.1.tgz#f7cb3eecaea9c151ef77342af05f38ae924bf795" + integrity sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA== + +"@rollup/rollup-linux-loong64-gnu@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.1.tgz#499bfac6bb669fd88bb664357bf6be996a28b92f" + integrity sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ== + +"@rollup/rollup-linux-loong64-musl@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.1.tgz#127dfac08764764396bbe04453c545d38a3ab518" + integrity sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw== + +"@rollup/rollup-linux-ppc64-gnu@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.1.tgz#6a72f4d95852aac18326c5bf708393e8f3a41b70" + integrity sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw== + +"@rollup/rollup-linux-ppc64-musl@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.1.tgz#ba8674666b00d6f9066cb9a5771a8430c34d2de6" + integrity sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg== + +"@rollup/rollup-linux-riscv64-gnu@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.1.tgz#17cc38b2a71e302547cad29bcf78d0db2618c922" + integrity sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg== + +"@rollup/rollup-linux-riscv64-musl@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.1.tgz#e36a41e2d8bd247331bd5cfc13b8c951d33454a2" + integrity sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg== + +"@rollup/rollup-linux-s390x-gnu@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.1.tgz#1687265f1f4bdea0726c761a58c2db9933609d68" + integrity sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ== + +"@rollup/rollup-linux-x64-gnu@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.1.tgz#56a6a0d9076f2a05a976031493b24a20ddcc0e77" + integrity sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg== + +"@rollup/rollup-linux-x64-musl@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.1.tgz#bc240ebb5b9fd8d41ca8a80cb458452e8c187e0f" + integrity sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w== + +"@rollup/rollup-openbsd-x64@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.1.tgz#6f80d48a006c4b2ffa7724e95a3e33f6975872af" + integrity sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw== + +"@rollup/rollup-openharmony-arm64@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.1.tgz#8f6db6f70d0a48abd833b263cd6dd3e7199c4c0e" + integrity sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA== + +"@rollup/rollup-win32-arm64-msvc@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.1.tgz#b68989bfa815d0b3d4e302ecd90bda744438b177" + integrity sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g== + +"@rollup/rollup-win32-ia32-msvc@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.1.tgz#c098e45338c50f22f1b288476354f025b746285b" + integrity sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg== + +"@rollup/rollup-win32-x64-gnu@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.1.tgz#2c9e15be155b79d05999953b1737b2903842e903" + integrity sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg== + +"@rollup/rollup-win32-x64-msvc@4.60.1": + version "4.60.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.1.tgz#23b860113e9f87eea015d1fa3a4240a52b42fcd4" + integrity sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ== "@rtsao/scc@^1.1.0": version "1.1.0" @@ -4264,7 +4397,7 @@ resolved "https://registry.yarnpkg.com/@speed-highlight/core/-/core-1.2.15.tgz#88c45609a2b5c2293a2e1935417c507f98f39d0b" integrity sha512-BMq1K3DsElxDWawkX6eLg9+CKJrTVGCBAWVuHXVUV2u0s2711qiChLSId6ikYPfxhdYocLNt3wWwSvDiTvFabw== -"@standard-schema/spec@^1.1.0": +"@standard-schema/spec@^1.0.0", "@standard-schema/spec@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@standard-schema/spec/-/spec-1.1.0.tgz#a79b55dbaf8604812f52d140b2c9ab41bc150bb8" integrity sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w== @@ -4908,7 +5041,14 @@ dependencies: "@types/unist" "*" -"@types/node@*", "@types/node@24.12.2", "@types/node@^24.0.0": +"@types/node@*", "@types/node@^25.0.3": + version "25.0.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-25.0.9.tgz#81ce3579ddf67cae812a9d49c8a0ab90c82e7782" + integrity sha512-/rpCXHlCWeqClNBwUhDcusJxXYDjZTyE8v5oTO7WbL8eij2nKhUeU89/6xgjU7N4/Vh3He0BtyhJdQbDyhiXAw== + dependencies: + undici-types "~7.16.0" + +"@types/node@24.12.2", "@types/node@^24.0.0": version "24.12.2" resolved "https://registry.yarnpkg.com/@types/node/-/node-24.12.2.tgz#353cb161dbf1785ea25e8829ba7ec574c5c629ac" integrity sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g== @@ -5368,6 +5508,18 @@ dependencies: "@rolldown/pluginutils" "1.0.0-rc.13" +"@vitest/expect@4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-4.0.4.tgz#ba98573c19f568ce8ad0377ebbb5689883a2f053" + integrity sha512-0ioMscWJtfpyH7+P82sGpAi3Si30OVV73jD+tEqXm5+rIx9LgnfdaOn45uaFkKOncABi/PHL00Yn0oW/wK4cXw== + dependencies: + "@standard-schema/spec" "^1.0.0" + "@types/chai" "^5.2.2" + "@vitest/spy" "4.0.4" + "@vitest/utils" "4.0.4" + chai "^6.0.1" + tinyrainbow "^3.0.3" + "@vitest/expect@4.1.5": version "4.1.5" resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-4.1.5.tgz#5caab19535cfb04fbc37087c5608d46e74dc9292" @@ -5380,6 +5532,15 @@ chai "^6.2.2" tinyrainbow "^3.1.0" +"@vitest/mocker@4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@vitest/mocker/-/mocker-4.0.4.tgz#d3366047e1f075874d35d40218e49266dfa2e561" + integrity sha512-UTtKgpjWj+pvn3lUM55nSg34098obGhSHH+KlJcXesky8b5wCUgg7s60epxrS6yAG8slZ9W8T9jGWg4PisMf5Q== + dependencies: + "@vitest/spy" "4.0.4" + estree-walker "^3.0.3" + magic-string "^0.30.19" + "@vitest/mocker@4.1.5": version "4.1.5" resolved "https://registry.yarnpkg.com/@vitest/mocker/-/mocker-4.1.5.tgz#9d5791733e4866cfb8af2d48ca371b127e7d2e93" @@ -5389,6 +5550,13 @@ estree-walker "^3.0.3" magic-string "^0.30.21" +"@vitest/pretty-format@4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-4.0.4.tgz#19ffa9fb35853554e272799b68743717dc2ec1b7" + integrity sha512-lHI2rbyrLVSd1TiHGJYyEtbOBo2SDndIsN3qY4o4xe2pBxoJLD6IICghNCvD7P+BFin6jeyHXiUICXqgl6vEaQ== + dependencies: + tinyrainbow "^3.0.3" + "@vitest/pretty-format@4.1.5": version "4.1.5" resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-4.1.5.tgz#4c13d77a77e2931e44db95522ed5700bcf0570d4" @@ -5396,6 +5564,14 @@ dependencies: tinyrainbow "^3.1.0" +"@vitest/runner@4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-4.0.4.tgz#ca0eb9de67bdfe6c6cb0841a23f47474af92dbf9" + integrity sha512-99EDqiCkncCmvIZj3qJXBZbyoQ35ghOwVWNnQ5nj0Hnsv4Qm40HmrMJrceewjLVvsxV/JSU4qyx2CGcfMBmXJw== + dependencies: + "@vitest/utils" "4.0.4" + pathe "^2.0.3" + "@vitest/runner@4.1.5": version "4.1.5" resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-4.1.5.tgz#a14dd2d2f48603f906dd52304a10c7fc623bb1de" @@ -5404,6 +5580,15 @@ "@vitest/utils" "4.1.5" pathe "^2.0.3" +"@vitest/snapshot@4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-4.0.4.tgz#ea90222f94da640481c8809e87597171b049c727" + integrity sha512-XICqf5Gi4648FGoBIeRgnHWSNDp+7R5tpclGosFaUUFzY6SfcpsfHNMnC7oDu/iOLBxYfxVzaQpylEvpgii3zw== + dependencies: + "@vitest/pretty-format" "4.0.4" + magic-string "^0.30.19" + pathe "^2.0.3" + "@vitest/snapshot@4.1.5": version "4.1.5" resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-4.1.5.tgz#d07970d1448190ee5a258db6ab79c65b8018c13b" @@ -5414,11 +5599,24 @@ magic-string "^0.30.21" pathe "^2.0.3" +"@vitest/spy@4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-4.0.4.tgz#b20b8736cdfd1774e38bceeadac1936d9b7653bf" + integrity sha512-G9L13AFyYECo40QG7E07EdYnZZYCKMTSp83p9W8Vwed0IyCG1GnpDLxObkx8uOGPXfDpdeVf24P1Yka8/q1s9g== + "@vitest/spy@4.1.5": version "4.1.5" resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-4.1.5.tgz#fa7858ffab746fa9ac29496e626f5a0caf9a5a7f" integrity sha512-2lNOsh6+R2Idnf1TCZqSwYlKN2E/iDlD8sgU59kYVl+OMDmvldO1VDk39smRfpUNwYpNRVn3w4YfuC7KfbBnkQ== +"@vitest/utils@4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-4.0.4.tgz#90d355d0f21596a06eca83f84783a29467513d6a" + integrity sha512-4bJLmSvZLyVbNsYFRpPYdJViG9jZyRvMZ35IF4ymXbRZoS+ycYghmwTGiscTXduUg2lgKK7POWIyXJNute1hjw== + dependencies: + "@vitest/pretty-format" "4.0.4" + tinyrainbow "^3.0.3" + "@vitest/utils@4.1.5": version "4.1.5" resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-4.1.5.tgz#20d6a6ae651a0dd33f945548921698d49701fa43" @@ -5635,6 +5833,11 @@ resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.9.10.tgz#a0ad5a26fe8aa996310870726e1704977f769dee" integrity sha512-A9gOqLdi6cV4ibazAjcQufGj0B1y/vDqYrcuP6d/6x8P27gRS8643Dj9o1dEKtB6O7fwxb2FgBmJS2mX7gpvdw== +"@xterm/headless@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@xterm/headless/-/headless-6.0.0.tgz#a839dee397c49834bb220fa5951d60f4b7f0aa11" + integrity sha512-5Yj1QINYCyzrZtf8OFIHi47iQtI+0qYFPHmouEfG8dHNxbZ9Tb9YGSuLcsEwj9Z+OL75GJqPyJbyoFer80a2Hw== + "@yarnpkg/lockfile@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" @@ -5948,6 +6151,11 @@ at-least-node@^1.0.0: resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== +auto-bind@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/auto-bind/-/auto-bind-5.0.1.tgz#50d8e63ea5a1dddcb5e5e36451c1a8266ffbb2ae" + integrity sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg== + auto-bind@~4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/auto-bind/-/auto-bind-4.0.0.tgz#e3589fc6c2da8f7ca43ba9f84fa52a744fc997fb" @@ -6092,13 +6300,6 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" -bdd-stdin@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/bdd-stdin/-/bdd-stdin-0.2.0.tgz#04e66aa480e0e0df861e288a4062fb8557db2441" - integrity sha512-PH3Xlt0JkiIgxknpZrW4Ato1ZPkMSp1JdfKnKiDDWVMVntoKJhyTwSV9Hk0K0gTMhsaQJMFCcyazg3EsXt+9jg== - dependencies: - mock-stdin "0.3.0" - better-path-resolve@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/better-path-resolve/-/better-path-resolve-1.0.0.tgz#13a35a1104cdd48a7b74bf8758f96a1ee613f99d" @@ -6356,7 +6557,7 @@ ccount@^2.0.0: resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5" integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== -chai@^6.2.2: +chai@^6.0.1, chai@^6.2.2: version "6.2.2" resolved "https://registry.yarnpkg.com/chai/-/chai-6.2.2.tgz#ae41b52c9aca87734505362717f3255facda360e" integrity sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg== @@ -6368,7 +6569,7 @@ chalk-template@0.4.0: dependencies: chalk "^4.1.2" -chalk@5.0.1, chalk@^5.0.0, chalk@^5.0.1: +chalk@5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.0.1.tgz#ca57d71e82bb534a296df63bbacc4a1c22b2a4b6" integrity sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w== @@ -6381,6 +6582,11 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" +chalk@^5.0.0, chalk@^5.0.1, chalk@^5.6.0: + version "5.6.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.6.2.tgz#b1238b6e23ea337af71c7f8a295db5af0c158aea" + integrity sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA== + change-case-all@1.0.14: version "1.0.14" resolved "https://registry.yarnpkg.com/change-case-all/-/change-case-all-1.0.14.tgz#bac04da08ad143278d0ac3dda7eccd39280bfba1" @@ -6413,6 +6619,16 @@ change-case-all@1.0.15: upper-case "^2.0.2" upper-case-first "^2.0.2" +change-case-all@2.1.0, change-case-all@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/change-case-all/-/change-case-all-2.1.0.tgz#c838988531bba9fa9e4db124f2d3f53a9607acc1" + integrity sha512-v6b0WWWkZUMHVuYk82l+WROgkUm4qEN2w5hKRNWtEOYwWqUGoi8C6xH0l1RLF1EoWqDFK6MFclmN3od6ws3/uw== + dependencies: + change-case "^5.2.0" + sponge-case "^2.0.2" + swap-case "^3.0.2" + title-case "^3.0.3" + change-case@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/change-case/-/change-case-4.1.2.tgz#fedfc5f136045e2398c0410ee441f95704641e12" @@ -6431,6 +6647,11 @@ change-case@^4.1.2: snake-case "^3.0.4" tslib "^2.0.3" +change-case@^5.2.0: + version "5.4.4" + resolved "https://registry.yarnpkg.com/change-case/-/change-case-5.4.4.tgz#0d52b507d8fb8f204343432381d1a6d7bff97a02" + integrity sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w== + character-entities-html4@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-2.1.0.tgz#1f1adb940c971a4b22ba39ddca6b618dc6e56b2b" @@ -6544,7 +6765,7 @@ cli-table3@0.6.1: optionalDependencies: colors "1.4.0" -cli-truncate@^5.0.0: +cli-truncate@^5.0.0, cli-truncate@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-5.2.0.tgz#c8e72aaca8339c773d128c36e0a17c6315b694eb" integrity sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw== @@ -6598,6 +6819,15 @@ cliui@^8.0.1: strip-ansi "^6.0.1" wrap-ansi "^7.0.0" +cliui@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-9.0.1.tgz#6f7890f386f6f1f79953adc1f78dec46fcc2d291" + integrity sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w== + dependencies: + string-width "^7.2.0" + strip-ansi "^7.1.0" + wrap-ansi "^9.0.0" + clsx@2.1.1, clsx@^2.0.0, clsx@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999" @@ -7264,10 +7494,10 @@ debounce@^1.2.1: resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== -debounce@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/debounce/-/debounce-2.2.0.tgz#f895fa2fbdb579a0f0d3dcf5dde19657e50eaad5" - integrity sha512-Xks6RUDLZFdz8LIdR6q0MTH44k7FikOmnh5xkSjMig6ch45afc8sjTjRQf3P6ax8dMgcQrYO/AR2RGWURrruqw== +debounce@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/debounce/-/debounce-3.0.0.tgz#7633adff3bcd92cdfe13370c2f46e87bdb946a1b" + integrity sha512-64byRbF0/AirwbuHqB3/ZpMG9/nckDa6ZA0yd6UnaQNwbbemCOwvz2sL5sjXLHhZHADyiwLm0M5qMhltUUx+TA== debug@2.6.9: version "2.6.9" @@ -7372,6 +7602,11 @@ detect-indent@^6.0.0: resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6" integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA== +detect-indent@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-7.0.2.tgz#16c516bf75d4b2f759f68214554996d467c8d648" + integrity sha512-y+8xyqdGLL+6sh0tVeHcfP/QDd8gUgbasolJJpY7NgeQGSZ739bDtSiaiDgtoicy+mtYB81dKLxO9xRhCyIB3A== + detect-libc@^2.0.3, detect-libc@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.1.2.tgz#689c5dcdc1900ef5583a4cb9f6d7b473742074ad" @@ -7655,6 +7890,11 @@ es-iterator-helpers@^1.2.1: iterator.prototype "^1.1.5" math-intrinsics "^1.1.0" +es-module-lexer@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.7.0.tgz#9159601561880a85f2734560a9099b2c31e5372a" + integrity sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA== + es-module-lexer@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-2.1.0.tgz#1dfcbb5ea3bbfb63f28e1fc3676c3676d1c9624c" @@ -7745,6 +7985,35 @@ esbuild@0.27.3, esbuild@^0.27.0, esbuild@~0.27.0: "@esbuild/win32-ia32" "0.27.3" "@esbuild/win32-x64" "0.27.3" +esbuild@~0.19.10: + version "0.19.12" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.19.12.tgz#dc82ee5dc79e82f5a5c3b4323a2a641827db3e04" + integrity sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg== + optionalDependencies: + "@esbuild/aix-ppc64" "0.19.12" + "@esbuild/android-arm" "0.19.12" + "@esbuild/android-arm64" "0.19.12" + "@esbuild/android-x64" "0.19.12" + "@esbuild/darwin-arm64" "0.19.12" + "@esbuild/darwin-x64" "0.19.12" + "@esbuild/freebsd-arm64" "0.19.12" + "@esbuild/freebsd-x64" "0.19.12" + "@esbuild/linux-arm" "0.19.12" + "@esbuild/linux-arm64" "0.19.12" + "@esbuild/linux-ia32" "0.19.12" + "@esbuild/linux-loong64" "0.19.12" + "@esbuild/linux-mips64el" "0.19.12" + "@esbuild/linux-ppc64" "0.19.12" + "@esbuild/linux-riscv64" "0.19.12" + "@esbuild/linux-s390x" "0.19.12" + "@esbuild/linux-x64" "0.19.12" + "@esbuild/netbsd-x64" "0.19.12" + "@esbuild/openbsd-x64" "0.19.12" + "@esbuild/sunos-x64" "0.19.12" + "@esbuild/win32-arm64" "0.19.12" + "@esbuild/win32-ia32" "0.19.12" + "@esbuild/win32-x64" "0.19.12" + escalade@^3.1.1, escalade@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" @@ -8280,7 +8549,7 @@ eventemitter2@6.4.7: resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.7.tgz#a7f6c4d7abf28a14c1ef3442f21cb306a054271d" integrity sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg== -eventemitter3@^5.0.1: +eventemitter3@^5.0.1, eventemitter3@^5.0.4: version "5.0.4" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.4.tgz#a86d66170433712dde814707ac52b5271ceb1feb" integrity sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw== @@ -8352,7 +8621,7 @@ executable@^4.1.1: dependencies: pify "^2.2.0" -expect-type@^1.3.0: +expect-type@^1.2.2, expect-type@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/expect-type/-/expect-type-1.3.0.tgz#0d58ed361877a31bbc4dd6cf71bbfef7faf6bd68" integrity sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA== @@ -8416,11 +8685,30 @@ fast-levenshtein@^2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== +fast-string-truncated-width@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz#23afe0da67d752ca0727538f1e6967759728ce49" + integrity sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g== + +fast-string-width@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/fast-string-width/-/fast-string-width-3.0.2.tgz#16dbabb491ce5585b5ecb675b65c165d71688eeb" + integrity sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg== + dependencies: + fast-string-truncated-width "^3.0.2" + fast-uri@^3.0.1: version "3.1.0" resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.0.tgz#66eecff6c764c0df9b762e62ca7edcfb53b4edfa" integrity sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA== +fast-wrap-ansi@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/fast-wrap-ansi/-/fast-wrap-ansi-0.2.0.tgz#c0ae3f3982d061c3d657ec927196fbb47e22fe64" + integrity sha512-rLV8JHxTyhVmFYhBJuMujcrHqOT2cnO5Zxj37qROj23CP39GXubJRBUFF0z8KFK77Uc0SukZUf7JZhsVEQ6n8w== + dependencies: + fast-string-width "^3.0.2" + fast-xml-builder@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/fast-xml-builder/-/fast-xml-builder-1.1.5.tgz#50188e1452a5fa095f415d3e63dcac0a1dbcbf11" @@ -8785,10 +9073,10 @@ get-symbol-description@^1.1.0: es-errors "^1.3.0" get-intrinsic "^1.2.6" -get-tsconfig@^4.10.0, get-tsconfig@^4.7.5, get-tsconfig@^4.8.1: - version "4.14.0" - resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.14.0.tgz#985d85c52a9903864280ccc2448d413fbf1efed8" - integrity sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA== +get-tsconfig@^4.10.0, get-tsconfig@^4.7.2, get-tsconfig@^4.7.5, get-tsconfig@^4.8.1: + version "4.13.0" + resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.13.0.tgz#fcdd991e6d22ab9a600f00e91c318707a5d9a0d7" + integrity sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ== dependencies: resolve-pkg-maps "^1.0.0" @@ -9357,7 +9645,7 @@ iconv-lite@0.6: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" -iconv-lite@^0.7.0: +iconv-lite@^0.7.0, iconv-lite@^0.7.2: version "0.7.2" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.7.2.tgz#d0bdeac3f12b4835b7359c2ad89c422a4d1cc72e" integrity sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw== @@ -9833,6 +10121,11 @@ is-unicode-supported@^0.1.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== +is-unicode-supported@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz#09f0ab0de6d3744d48d265ebb98f65d11f2a9b3a" + integrity sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ== + is-upper-case@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-upper-case/-/is-upper-case-2.0.2.tgz#f1105ced1fe4de906a5f39553e7d3803fd804649" @@ -10325,7 +10618,18 @@ lint-staged@16.4.0: tinyexec "^1.0.4" yaml "^2.8.2" -listr2@^9.0.0, listr2@^9.0.5: +listr2@^10.2.1: + version "10.2.1" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-10.2.1.tgz#fb44e1e9e5f8b15ab817296d45149d295c47bee9" + integrity sha512-7I5knELsJKTUjXG+A6BkKAiGkW1i25fNa/xlUl9hFtk15WbE9jndA89xu5FzQKrY5llajE1hfZZFMILXkDHk/Q== + dependencies: + cli-truncate "^5.2.0" + eventemitter3 "^5.0.4" + log-update "^6.1.0" + rfdc "^1.4.1" + wrap-ansi "^10.0.0" + +listr2@^9.0.5: version "9.0.5" resolved "https://registry.yarnpkg.com/listr2/-/listr2-9.0.5.tgz#92df7c4416a6da630eb9ef46da469b70de97b316" integrity sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g== @@ -10456,6 +10760,14 @@ log-symbols@^4.0.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" +log-symbols@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-7.0.1.tgz#f52e68037d96f589fc572ff2193dc424d48c195b" + integrity sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg== + dependencies: + is-unicode-supported "^2.0.0" + yoctocolors "^2.1.1" + log-update@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/log-update/-/log-update-6.1.0.tgz#1a04ff38166f94647ae1af562f4bd6a15b1b7cd4" @@ -10515,7 +10827,7 @@ lz-string@*, lz-string@^1.4.4: resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941" integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ== -magic-string@^0.30.11, magic-string@^0.30.17, magic-string@^0.30.21: +magic-string@^0.30.11, magic-string@^0.30.17, magic-string@^0.30.19, magic-string@^0.30.21: version "0.30.21" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.21.tgz#56763ec09a0fa8091df27879fd94d19078c00d91" integrity sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ== @@ -11360,11 +11672,6 @@ mlly@^1.7.4, mlly@^1.8.2: pkg-types "^1.3.1" ufo "^1.6.3" -mock-stdin@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/mock-stdin/-/mock-stdin-0.3.0.tgz#f40d2a513a114e6d547480625b5ef5190744bd4d" - integrity sha512-RgODIm+s+lEFH+BUlJbLFm2m7oeuNQNFyUU3Bvviqp14bhPJZhzIv4ovN3pdejqK/GyNqdKENLKxR55rDPDnXw== - moment@~2.30.0: version "2.30.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae" @@ -11395,10 +11702,10 @@ muggle-string@^0.4.1: resolved "https://registry.yarnpkg.com/muggle-string/-/muggle-string-0.4.1.tgz#3b366bd43b32f809dc20659534dd30e7c8a0d328" integrity sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ== -mute-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-2.0.0.tgz#a5446fc0c512b71c83c44d908d5c7b7b4c493b2b" - integrity sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA== +mute-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-3.0.0.tgz#cd8014dd2acb72e1e91bb67c74f0019e620ba2d1" + integrity sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw== mvdan-sh@^0.10.1: version "0.10.1" @@ -12367,10 +12674,19 @@ postcss@8.4.31: picocolors "^1.0.0" source-map-js "^1.0.2" -postcss@^8.4.4, postcss@^8.4.47, postcss@^8.5.10: - version "8.5.12" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.12.tgz#cd0c0f667f7cb0521e2313234ea6e707a9ec1ddb" - integrity sha512-W62t/Se6rA0Az3DfCL0AqJwXuKwBeYg6nOaIgzP+xZ7N5BFCI7DYi1qs6ygUYT6rvfi6t9k65UMLJC+PHZpDAA== +postcss@^8.4.4, postcss@^8.4.47, postcss@^8.5.6: + version "8.5.9" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.9.tgz#f6ee9e0b94f0f19c97d2f172bfbd7fc71fe1cca4" + integrity sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw== + dependencies: + nanoid "^3.3.11" + picocolors "^1.1.1" + source-map-js "^1.2.1" + +postcss@^8.5.10: + version "8.5.10" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.10.tgz#8992d8c30acf3f12169e7c09514a12fed7e48356" + integrity sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ== dependencies: nanoid "^3.3.11" picocolors "^1.1.1" @@ -13222,38 +13538,38 @@ rolldown@1.0.0-rc.17: "@rolldown/binding-win32-arm64-msvc" "1.0.0-rc.17" "@rolldown/binding-win32-x64-msvc" "1.0.0-rc.17" -rollup@^4.34.8: - version "4.60.2" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.60.2.tgz#ac23fe4bd530304cef9fa61e639d7098b6762cf4" - integrity sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ== +rollup@^4.34.8, rollup@^4.43.0: + version "4.60.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.60.1.tgz#b4aa2bcb3a5e1437b5fad40d43fe42d4bde7a42d" + integrity sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w== dependencies: "@types/estree" "1.0.8" optionalDependencies: - "@rollup/rollup-android-arm-eabi" "4.60.2" - "@rollup/rollup-android-arm64" "4.60.2" - "@rollup/rollup-darwin-arm64" "4.60.2" - "@rollup/rollup-darwin-x64" "4.60.2" - "@rollup/rollup-freebsd-arm64" "4.60.2" - "@rollup/rollup-freebsd-x64" "4.60.2" - "@rollup/rollup-linux-arm-gnueabihf" "4.60.2" - "@rollup/rollup-linux-arm-musleabihf" "4.60.2" - "@rollup/rollup-linux-arm64-gnu" "4.60.2" - "@rollup/rollup-linux-arm64-musl" "4.60.2" - "@rollup/rollup-linux-loong64-gnu" "4.60.2" - "@rollup/rollup-linux-loong64-musl" "4.60.2" - "@rollup/rollup-linux-ppc64-gnu" "4.60.2" - "@rollup/rollup-linux-ppc64-musl" "4.60.2" - "@rollup/rollup-linux-riscv64-gnu" "4.60.2" - "@rollup/rollup-linux-riscv64-musl" "4.60.2" - "@rollup/rollup-linux-s390x-gnu" "4.60.2" - "@rollup/rollup-linux-x64-gnu" "4.60.2" - "@rollup/rollup-linux-x64-musl" "4.60.2" - "@rollup/rollup-openbsd-x64" "4.60.2" - "@rollup/rollup-openharmony-arm64" "4.60.2" - "@rollup/rollup-win32-arm64-msvc" "4.60.2" - "@rollup/rollup-win32-ia32-msvc" "4.60.2" - "@rollup/rollup-win32-x64-gnu" "4.60.2" - "@rollup/rollup-win32-x64-msvc" "4.60.2" + "@rollup/rollup-android-arm-eabi" "4.60.1" + "@rollup/rollup-android-arm64" "4.60.1" + "@rollup/rollup-darwin-arm64" "4.60.1" + "@rollup/rollup-darwin-x64" "4.60.1" + "@rollup/rollup-freebsd-arm64" "4.60.1" + "@rollup/rollup-freebsd-x64" "4.60.1" + "@rollup/rollup-linux-arm-gnueabihf" "4.60.1" + "@rollup/rollup-linux-arm-musleabihf" "4.60.1" + "@rollup/rollup-linux-arm64-gnu" "4.60.1" + "@rollup/rollup-linux-arm64-musl" "4.60.1" + "@rollup/rollup-linux-loong64-gnu" "4.60.1" + "@rollup/rollup-linux-loong64-musl" "4.60.1" + "@rollup/rollup-linux-ppc64-gnu" "4.60.1" + "@rollup/rollup-linux-ppc64-musl" "4.60.1" + "@rollup/rollup-linux-riscv64-gnu" "4.60.1" + "@rollup/rollup-linux-riscv64-musl" "4.60.1" + "@rollup/rollup-linux-s390x-gnu" "4.60.1" + "@rollup/rollup-linux-x64-gnu" "4.60.1" + "@rollup/rollup-linux-x64-musl" "4.60.1" + "@rollup/rollup-openbsd-x64" "4.60.1" + "@rollup/rollup-openharmony-arm64" "4.60.1" + "@rollup/rollup-win32-arm64-msvc" "4.60.1" + "@rollup/rollup-win32-ia32-msvc" "4.60.1" + "@rollup/rollup-win32-x64-gnu" "4.60.1" + "@rollup/rollup-win32-x64-msvc" "4.60.1" fsevents "~2.3.2" roughjs@^4.6.6: @@ -13742,6 +14058,11 @@ sponge-case@^1.0.1: dependencies: tslib "^2.0.3" +sponge-case@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/sponge-case/-/sponge-case-2.0.3.tgz#9e004d04332c307e4895b79eeb6c1f3da86eb203" + integrity sha512-i4h9ZGRfxV6Xw3mpZSFOfbXjf0cQcYmssGWutgNIfFZ2VM+YIWfD71N/kjjwK6X/AAHzBr+rciEcn/L34S8TGw== + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -13798,6 +14119,11 @@ static-eval@2.1.1: dependencies: escodegen "^2.1.0" +std-env@^3.9.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.10.0.tgz#d810b27e3a073047b2b5e40034881f5ea6f9c83b" + integrity sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg== + std-env@^4.0.0-rc.1: version "4.1.0" resolved "https://registry.yarnpkg.com/std-env/-/std-env-4.1.0.tgz#45899abc590d86d682e87f0acd1033a75084cd3f" @@ -13867,7 +14193,7 @@ string-width@^6.0.0: emoji-regex "^10.2.1" strip-ansi "^7.0.1" -string-width@^7.0.0: +string-width@^7.0.0, string-width@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-7.2.0.tgz#b5bb8e2165ce275d4d43476dd2700ad9091db6dc" integrity sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ== @@ -14130,6 +14456,11 @@ swap-case@^2.0.2: dependencies: tslib "^2.0.3" +swap-case@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/swap-case/-/swap-case-3.0.3.tgz#363883b0e8a2837c24d2e0eccb6bdff92e32d711" + integrity sha512-6p4op8wE9CQv7uDFzulI6YXUw4lD9n4oQierdbFThEKVWVQcbQcUjdP27W8XE7V4QnWmnq9jueSHceyyQnqQVA== + swr@^2.0.0: version "2.4.1" resolved "https://registry.yarnpkg.com/swr/-/swr-2.4.1.tgz#c9e48abff6bf4b04846342e2f1f6be108a078cf6" @@ -14289,7 +14620,7 @@ tinyglobby@^0.2.11, tinyglobby@^0.2.12, tinyglobby@^0.2.13, tinyglobby@^0.2.15, fdir "^6.5.0" picomatch "^4.0.4" -tinyrainbow@^3.1.0: +tinyrainbow@^3.0.3, tinyrainbow@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/tinyrainbow/-/tinyrainbow-3.1.0.tgz#1d8a623893f95cf0a2ddb9e5d11150e191409421" integrity sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw== @@ -14398,10 +14729,10 @@ ts-invariant@^0.10.3: dependencies: tslib "^2.1.0" -ts-log@^2.2.3: - version "2.2.7" - resolved "https://registry.yarnpkg.com/ts-log/-/ts-log-2.2.7.tgz#4f4512144898b77c9984e91587076fcb8518688e" - integrity sha512-320x5Ggei84AxzlXp91QkIGSw5wgaLT6GeAH0KsqDmRZdVWW2OiSeVvElVoatk3f7nicwXlElXsoFkARiGE2yg== +ts-log@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ts-log/-/ts-log-3.0.0.tgz#74a84ca54ebeea02d6a6d052d21a8c47889c119a" + integrity sha512-dOh2B+XwtPsIt+bOy0krUiGGO9fbqUCrR4nkNNir/EObVmEJYd4q6KkfF2Ni8/QG1Lji3JwX8TrTa7LHftPWsA== ts-node@10.9.2, ts-node@^10.9.1: version "10.9.2" @@ -14485,6 +14816,16 @@ tsx@4.21.0: optionalDependencies: fsevents "~2.3.3" +tsx@4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/tsx/-/tsx-4.7.0.tgz#1689cfe7dda495ca1f9a66d4cad79cb57b9f6f4a" + integrity sha512-I+t79RYPlEYlHn9a+KzwrvEwhJg35h/1zHsLC2JXvhC2mdynMv6Zxzvhv5EMV6VF5qJlLlkSnMVvdZV3PSIGcg== + dependencies: + esbuild "~0.19.10" + get-tsconfig "^4.7.2" + optionalDependencies: + fsevents "~2.3.3" + tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" @@ -14601,7 +14942,7 @@ typescript-json-schema@0.56.0: typescript "~4.9.5" yargs "^17.1.1" -typescript@6.0.3, typescript@^5, typescript@^6.0.0, typescript@~4.9.5: +typescript@6.0.3, typescript@^5, typescript@^5.9.3, typescript@^6.0.0, typescript@~4.9.5: version "6.0.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-6.0.3.tgz#90251dc007916e972786cb94d74d15b185577d21" integrity sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw== @@ -15103,6 +15444,20 @@ villus@^3.0.0: resolved "https://registry.yarnpkg.com/villus/-/villus-3.5.2.tgz#19ef1d87cbd3f55a84765f64e3fb7bb797eae36f" integrity sha512-Tn6zAXVigaY91lTgWuT5WecAwfxRjTX5ezwRU1e2A/sD3yRi3v0tnVgRQJ7EjaMSNrbY+iXWHMVCGhof1llSvQ== +"vite@^6.0.0 || ^7.0.0": + version "7.3.2" + resolved "https://registry.yarnpkg.com/vite/-/vite-7.3.2.tgz#cb041794d4c1395e28baea98198fd6e8f4b96b5c" + integrity sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg== + dependencies: + esbuild "^0.27.0" + fdir "^6.5.0" + picomatch "^4.0.3" + postcss "^8.5.6" + rollup "^4.43.0" + tinyglobby "^0.2.15" + optionalDependencies: + fsevents "~2.3.3" + "vite@^6.0.0 || ^7.0.0 || ^8.0.0", vite@^8.0.0: version "8.0.10" resolved "https://registry.yarnpkg.com/vite/-/vite-8.0.10.tgz#fb31868526ec874101fac084172a2cdc6776319b" @@ -15116,6 +15471,32 @@ villus@^3.0.0: optionalDependencies: fsevents "~2.3.3" +vitest@4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/vitest/-/vitest-4.0.4.tgz#92f8ed44110292c80efadc03bb6fa735ebefa414" + integrity sha512-hV31h0/bGbtmDQc0KqaxsTO1v4ZQeF8ojDFuy4sZhFadwAqqvJA0LDw68QUocctI5EDpFMql/jVWKuPYHIf2Ew== + dependencies: + "@vitest/expect" "4.0.4" + "@vitest/mocker" "4.0.4" + "@vitest/pretty-format" "4.0.4" + "@vitest/runner" "4.0.4" + "@vitest/snapshot" "4.0.4" + "@vitest/spy" "4.0.4" + "@vitest/utils" "4.0.4" + debug "^4.4.3" + es-module-lexer "^1.7.0" + expect-type "^1.2.2" + magic-string "^0.30.19" + pathe "^2.0.3" + picomatch "^4.0.3" + std-env "^3.9.0" + tinybench "^2.9.0" + tinyexec "^0.3.2" + tinyglobby "^0.2.15" + tinyrainbow "^3.0.3" + vite "^6.0.0 || ^7.0.0" + why-is-node-running "^2.3.0" + vitest@4.1.5: version "4.1.5" resolved "https://registry.yarnpkg.com/vitest/-/vitest-4.1.5.tgz#cda189c0cd9dd1c920be477c0f371b64ec14782a" @@ -15410,6 +15791,15 @@ wrangler@4.86.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-10.0.0.tgz#b83ddcc14dbc5596f1b07e153bf6f863c1acbb57" + integrity sha512-SGcvg80f0wUy2/fXES19feHMz8E0JoXv2uNgHOu4Dgi2OrCy1lqwFYEJz1BLbDI0exjPMe/ZdzZ/YpGECBG/aQ== + dependencies: + ansi-styles "^6.2.3" + string-width "^8.2.0" + strip-ansi "^7.1.2" + wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" @@ -15512,6 +15902,11 @@ yargs-parser@^21.1.1: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== +yargs-parser@^22.0.0: + version "22.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-22.0.0.tgz#87b82094051b0567717346ecd00fd14804b357c8" + integrity sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw== + yargs@^15.3.1: version "15.4.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" @@ -15529,7 +15924,7 @@ yargs@^15.3.1: y18n "^4.0.0" yargs-parser "^18.1.2" -yargs@^17.0.0, yargs@^17.1.1, yargs@^17.6.2: +yargs@^17.1.1, yargs@^17.6.2: version "17.7.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== @@ -15542,6 +15937,18 @@ yargs@^17.0.0, yargs@^17.1.1, yargs@^17.6.2: y18n "^5.0.5" yargs-parser "^21.1.1" +yargs@^18.0.0: + version "18.0.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-18.0.0.tgz#6c84259806273a746b09f579087b68a3c2d25bd1" + integrity sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg== + dependencies: + cliui "^9.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + string-width "^7.2.0" + y18n "^5.0.5" + yargs-parser "^22.0.0" + yauzl@^2.10.0: version "2.10.0" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" @@ -15565,10 +15972,10 @@ yocto-queue@^1.0.0, yocto-queue@^1.1.1: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.2.2.tgz#3e09c95d3f1aa89a58c114c99223edf639152c00" integrity sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ== -yoctocolors-cjs@^2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz#7e4964ea8ec422b7a40ac917d3a344cfd2304baa" - integrity sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw== +yoctocolors@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yoctocolors/-/yoctocolors-2.1.2.tgz#d795f54d173494e7d8db93150cec0ed7f678c83a" + integrity sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug== youch-core@^0.3.3: version "0.3.3"