diff --git a/.changeset/@graphql-codegen_cli-10496-dependencies.md b/.changeset/@graphql-codegen_cli-10496-dependencies.md new file mode 100644 index 00000000000..886bea55e86 --- /dev/null +++ b/.changeset/@graphql-codegen_cli-10496-dependencies.md @@ -0,0 +1,12 @@ +--- +"@graphql-codegen/cli": patch +--- +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`) diff --git a/.changeset/@graphql-codegen_cli-10650-dependencies.md b/.changeset/@graphql-codegen_cli-10650-dependencies.md new file mode 100644 index 00000000000..0b9986b071b --- /dev/null +++ b/.changeset/@graphql-codegen_cli-10650-dependencies.md @@ -0,0 +1,11 @@ +--- +"@graphql-codegen/cli": patch +--- +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`) diff --git a/.changeset/@graphql-codegen_cli-10651-dependencies.md b/.changeset/@graphql-codegen_cli-10651-dependencies.md new file mode 100644 index 00000000000..635d380e7bc --- /dev/null +++ b/.changeset/@graphql-codegen_cli-10651-dependencies.md @@ -0,0 +1,5 @@ +--- +"@graphql-codegen/cli": patch +--- +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`) diff --git a/.changeset/@graphql-codegen_client-preset-10608-dependencies.md b/.changeset/@graphql-codegen_client-preset-10608-dependencies.md new file mode 100644 index 00000000000..d3a31ec2973 --- /dev/null +++ b/.changeset/@graphql-codegen_client-preset-10608-dependencies.md @@ -0,0 +1,5 @@ +--- +"@graphql-codegen/client-preset": patch +--- +dependencies updates: + - Removed dependency [`@graphql-codegen/typescript@^5.0.8` ↗︎](https://www.npmjs.com/package/@graphql-codegen/typescript/v/5.0.8) (from `dependencies`) diff --git a/.changeset/@graphql-codegen_gql-tag-operations-10496-dependencies.md b/.changeset/@graphql-codegen_gql-tag-operations-10496-dependencies.md new file mode 100644 index 00000000000..e3e963598c8 --- /dev/null +++ b/.changeset/@graphql-codegen_gql-tag-operations-10496-dependencies.md @@ -0,0 +1,5 @@ +--- +"@graphql-codegen/gql-tag-operations": patch +--- +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`) diff --git a/.changeset/@graphql-codegen_gql-tag-operations-10650-dependencies.md b/.changeset/@graphql-codegen_gql-tag-operations-10650-dependencies.md new file mode 100644 index 00000000000..e3e963598c8 --- /dev/null +++ b/.changeset/@graphql-codegen_gql-tag-operations-10650-dependencies.md @@ -0,0 +1,5 @@ +--- +"@graphql-codegen/gql-tag-operations": patch +--- +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`) diff --git a/.changeset/@graphql-codegen_graphql-modules-preset-10496-dependencies.md b/.changeset/@graphql-codegen_graphql-modules-preset-10496-dependencies.md new file mode 100644 index 00000000000..25df99c250f --- /dev/null +++ b/.changeset/@graphql-codegen_graphql-modules-preset-10496-dependencies.md @@ -0,0 +1,5 @@ +--- +"@graphql-codegen/graphql-modules-preset": patch +--- +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`) diff --git a/.changeset/@graphql-codegen_graphql-modules-preset-10650-dependencies.md b/.changeset/@graphql-codegen_graphql-modules-preset-10650-dependencies.md new file mode 100644 index 00000000000..25df99c250f --- /dev/null +++ b/.changeset/@graphql-codegen_graphql-modules-preset-10650-dependencies.md @@ -0,0 +1,5 @@ +--- +"@graphql-codegen/graphql-modules-preset": patch +--- +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`) diff --git a/.changeset/@graphql-codegen_plugin-helpers-10496-dependencies.md b/.changeset/@graphql-codegen_plugin-helpers-10496-dependencies.md new file mode 100644 index 00000000000..692a0ed9378 --- /dev/null +++ b/.changeset/@graphql-codegen_plugin-helpers-10496-dependencies.md @@ -0,0 +1,5 @@ +--- +"@graphql-codegen/plugin-helpers": patch +--- +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`) diff --git a/.changeset/@graphql-codegen_plugin-helpers-10650-dependencies.md b/.changeset/@graphql-codegen_plugin-helpers-10650-dependencies.md new file mode 100644 index 00000000000..692a0ed9378 --- /dev/null +++ b/.changeset/@graphql-codegen_plugin-helpers-10650-dependencies.md @@ -0,0 +1,5 @@ +--- +"@graphql-codegen/plugin-helpers": patch +--- +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`) diff --git a/.changeset/@graphql-codegen_typed-document-node-10496-dependencies.md b/.changeset/@graphql-codegen_typed-document-node-10496-dependencies.md new file mode 100644 index 00000000000..03198289844 --- /dev/null +++ b/.changeset/@graphql-codegen_typed-document-node-10496-dependencies.md @@ -0,0 +1,6 @@ +--- +"@graphql-codegen/typed-document-node": patch +--- +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`) diff --git a/.changeset/@graphql-codegen_typed-document-node-10650-dependencies.md b/.changeset/@graphql-codegen_typed-document-node-10650-dependencies.md new file mode 100644 index 00000000000..52788e4aeeb --- /dev/null +++ b/.changeset/@graphql-codegen_typed-document-node-10650-dependencies.md @@ -0,0 +1,6 @@ +--- +"@graphql-codegen/typed-document-node": patch +--- +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`) diff --git a/.changeset/@graphql-codegen_typescript-10496-dependencies.md b/.changeset/@graphql-codegen_typescript-10496-dependencies.md new file mode 100644 index 00000000000..f0a25772c39 --- /dev/null +++ b/.changeset/@graphql-codegen_typescript-10496-dependencies.md @@ -0,0 +1,6 @@ +--- +"@graphql-codegen/typescript": patch +--- +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`) diff --git a/.changeset/@graphql-codegen_typescript-10650-dependencies.md b/.changeset/@graphql-codegen_typescript-10650-dependencies.md new file mode 100644 index 00000000000..e7efcd336f4 --- /dev/null +++ b/.changeset/@graphql-codegen_typescript-10650-dependencies.md @@ -0,0 +1,5 @@ +--- +"@graphql-codegen/typescript": patch +--- +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`) diff --git a/.changeset/@graphql-codegen_typescript-document-nodes-10496-dependencies.md b/.changeset/@graphql-codegen_typescript-document-nodes-10496-dependencies.md new file mode 100644 index 00000000000..72924f13846 --- /dev/null +++ b/.changeset/@graphql-codegen_typescript-document-nodes-10496-dependencies.md @@ -0,0 +1,5 @@ +--- +"@graphql-codegen/typescript-document-nodes": patch +--- +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`) diff --git a/.changeset/@graphql-codegen_typescript-document-nodes-10650-dependencies.md b/.changeset/@graphql-codegen_typescript-document-nodes-10650-dependencies.md new file mode 100644 index 00000000000..72924f13846 --- /dev/null +++ b/.changeset/@graphql-codegen_typescript-document-nodes-10650-dependencies.md @@ -0,0 +1,5 @@ +--- +"@graphql-codegen/typescript-document-nodes": patch +--- +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`) diff --git a/.changeset/@graphql-codegen_typescript-operations-10496-dependencies.md b/.changeset/@graphql-codegen_typescript-operations-10496-dependencies.md new file mode 100644 index 00000000000..fd8fb574d9b --- /dev/null +++ b/.changeset/@graphql-codegen_typescript-operations-10496-dependencies.md @@ -0,0 +1,7 @@ +--- +"@graphql-codegen/typescript-operations": patch +--- +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`) diff --git a/.changeset/@graphql-codegen_typescript-operations-10563-dependencies.md b/.changeset/@graphql-codegen_typescript-operations-10563-dependencies.md new file mode 100644 index 00000000000..e66f900bbf7 --- /dev/null +++ b/.changeset/@graphql-codegen_typescript-operations-10563-dependencies.md @@ -0,0 +1,5 @@ +--- +"@graphql-codegen/typescript-operations": patch +--- +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`) diff --git a/.changeset/@graphql-codegen_typescript-operations-10572-dependencies.md b/.changeset/@graphql-codegen_typescript-operations-10572-dependencies.md new file mode 100644 index 00000000000..81018bf6546 --- /dev/null +++ b/.changeset/@graphql-codegen_typescript-operations-10572-dependencies.md @@ -0,0 +1,5 @@ +--- +"@graphql-codegen/typescript-operations": patch +--- +dependencies updates: + - Removed dependency [`@graphql-codegen/typescript@^5.0.7` ↗︎](https://www.npmjs.com/package/@graphql-codegen/typescript/v/5.0.7) (from `dependencies`) diff --git a/.changeset/@graphql-codegen_typescript-operations-10650-dependencies.md b/.changeset/@graphql-codegen_typescript-operations-10650-dependencies.md new file mode 100644 index 00000000000..b710cf54928 --- /dev/null +++ b/.changeset/@graphql-codegen_typescript-operations-10650-dependencies.md @@ -0,0 +1,5 @@ +--- +"@graphql-codegen/typescript-operations": patch +--- +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`) diff --git a/.changeset/@graphql-codegen_typescript-resolvers-10496-dependencies.md b/.changeset/@graphql-codegen_typescript-resolvers-10496-dependencies.md new file mode 100644 index 00000000000..f779c89b2d9 --- /dev/null +++ b/.changeset/@graphql-codegen_typescript-resolvers-10496-dependencies.md @@ -0,0 +1,5 @@ +--- +"@graphql-codegen/typescript-resolvers": patch +--- +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`) diff --git a/.changeset/@graphql-codegen_typescript-resolvers-10650-dependencies.md b/.changeset/@graphql-codegen_typescript-resolvers-10650-dependencies.md new file mode 100644 index 00000000000..f779c89b2d9 --- /dev/null +++ b/.changeset/@graphql-codegen_typescript-resolvers-10650-dependencies.md @@ -0,0 +1,5 @@ +--- +"@graphql-codegen/typescript-resolvers": patch +--- +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`) diff --git a/.changeset/@graphql-codegen_visitor-plugin-common-10496-dependencies.md b/.changeset/@graphql-codegen_visitor-plugin-common-10496-dependencies.md new file mode 100644 index 00000000000..c38bdfe56b8 --- /dev/null +++ b/.changeset/@graphql-codegen_visitor-plugin-common-10496-dependencies.md @@ -0,0 +1,6 @@ +--- +"@graphql-codegen/visitor-plugin-common": patch +--- +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`) diff --git a/.changeset/@graphql-codegen_visitor-plugin-common-10650-dependencies.md b/.changeset/@graphql-codegen_visitor-plugin-common-10650-dependencies.md new file mode 100644 index 00000000000..c38bdfe56b8 --- /dev/null +++ b/.changeset/@graphql-codegen_visitor-plugin-common-10650-dependencies.md @@ -0,0 +1,6 @@ +--- +"@graphql-codegen/visitor-plugin-common": patch +--- +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`) diff --git a/.changeset/beige-pets-talk.md b/.changeset/beige-pets-talk.md new file mode 100644 index 00000000000..0265c6618ff --- /dev/null +++ b/.changeset/beige-pets-talk.md @@ -0,0 +1,11 @@ +--- +'@graphql-codegen/visitor-plugin-common': minor +'@graphql-codegen/typescript-operations': minor +--- + +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. diff --git a/.changeset/big-taxes-hunt.md b/.changeset/big-taxes-hunt.md new file mode 100644 index 00000000000..d4d9998152a --- /dev/null +++ b/.changeset/big-taxes-hunt.md @@ -0,0 +1,6 @@ +--- +'@graphql-codegen/visitor-plugin-common': patch +'@graphql-codegen/typescript-operations': patch +--- + +Improve `namespacedImportName` usability by setting a default when `importSchemaTypesFrom` is set diff --git a/.changeset/breezy-games-enter.md b/.changeset/breezy-games-enter.md new file mode 100644 index 00000000000..9befb0d91ae --- /dev/null +++ b/.changeset/breezy-games-enter.md @@ -0,0 +1,11 @@ +--- +'@graphql-codegen/visitor-plugin-common': major +'@graphql-codegen/typescript-operations': major +'@graphql-codegen/client-preset': major +--- + +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. diff --git a/.changeset/brown-things-jump.md b/.changeset/brown-things-jump.md new file mode 100644 index 00000000000..115b47b37f1 --- /dev/null +++ b/.changeset/brown-things-jump.md @@ -0,0 +1,27 @@ +--- +'@graphql-codegen/visitor-plugin-common': major +'@graphql-codegen/typescript-operations': major +'@graphql-codegen/typescript': major +'@graphql-codegen/typescript-resolvers': major +--- + +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 diff --git a/.changeset/clever-loops-crash.md b/.changeset/clever-loops-crash.md new file mode 100644 index 00000000000..c28b7d69057 --- /dev/null +++ b/.changeset/clever-loops-crash.md @@ -0,0 +1,6 @@ +--- +'@graphql-codegen/visitor-plugin-common': minor +'@graphql-codegen/typescript-operations': minor +--- + +Add importSchemaTypesFrom support 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/.changeset/curly-trees-lead.md b/.changeset/curly-trees-lead.md new file mode 100644 index 00000000000..e6aab78bdca --- /dev/null +++ b/.changeset/curly-trees-lead.md @@ -0,0 +1,5 @@ +--- +'@graphql-codegen/typescript-operations': major +--- + +BREAKING CHANGE: typescript-operations plugin now generates enum if it is used in operation. diff --git a/.changeset/every-queens-sin.md b/.changeset/every-queens-sin.md new file mode 100644 index 00000000000..cda139690b5 --- /dev/null +++ b/.changeset/every-queens-sin.md @@ -0,0 +1,6 @@ +--- +'@graphql-codegen/typescript-operations': major +'@graphql-codegen/client-preset': major +--- + +Conditionally generate input types and output enums into target file diff --git a/.changeset/every-rooms-camp.md b/.changeset/every-rooms-camp.md new file mode 100644 index 00000000000..89938d2d564 --- /dev/null +++ b/.changeset/every-rooms-camp.md @@ -0,0 +1,9 @@ +--- +'@graphql-codegen/visitor-plugin-common': major +'@graphql-codegen/typescript-operations': major +'@graphql-codegen/typescript': major +'@graphql-codegen/typescript-resolvers': major +'@graphql-codegen/client-preset': major +--- + +BREAKING CHANGE: make `unknown` instead of `any` the default custom scalar type diff --git a/.changeset/five-cases-sniff.md b/.changeset/five-cases-sniff.md new file mode 100644 index 00000000000..148366947bc --- /dev/null +++ b/.changeset/five-cases-sniff.md @@ -0,0 +1,5 @@ +--- +'@graphql-codegen/visitor-plugin-common': minor +--- + +Adding config option extractAllFieldsToTypesCompact, which renders nested types names with field names only (without types) diff --git a/.changeset/flat-paths-boil.md b/.changeset/flat-paths-boil.md new file mode 100644 index 00000000000..7a02df893a0 --- /dev/null +++ b/.changeset/flat-paths-boil.md @@ -0,0 +1,5 @@ +--- +'@graphql-codegen/typescript-operations': patch +--- + +Add internal utility type warning to deter usage diff --git a/.changeset/free-fans-dance.md b/.changeset/free-fans-dance.md new file mode 100644 index 00000000000..0dbbfd76c20 --- /dev/null +++ b/.changeset/free-fans-dance.md @@ -0,0 +1,6 @@ +--- +'@graphql-codegen/visitor-plugin-common': patch +'@graphql-codegen/typescript-operations': patch +--- + +Add `printTypeScriptMaybeType` to handle printing TS types, as there are special cases like `any` and `unknown` diff --git a/.changeset/fuzzy-poets-doubt.md b/.changeset/fuzzy-poets-doubt.md new file mode 100644 index 00000000000..8a8e0a30bc7 --- /dev/null +++ b/.changeset/fuzzy-poets-doubt.md @@ -0,0 +1,5 @@ +--- +'@graphql-codegen/typescript-operations': patch +--- + +Re-implement inputMaybeValue diff --git a/.changeset/hot-toys-leave.md b/.changeset/hot-toys-leave.md new file mode 100644 index 00000000000..95a20947acc --- /dev/null +++ b/.changeset/hot-toys-leave.md @@ -0,0 +1,21 @@ +--- +'@graphql-codegen/typed-document-node': major +'@graphql-codegen/gql-tag-operations': major +'@graphql-codegen/visitor-plugin-common': major +'@graphql-codegen/typescript-document-nodes': major +'@graphql-codegen/typescript-operations': major +'@graphql-codegen/typescript': major +'@graphql-codegen/typescript-resolvers': major +'@graphql-codegen/graphql-modules-preset': major +'@graphql-codegen/plugin-helpers': major +'@graphql-codegen/cli': major +'@graphql-codegen/client-preset': major +--- + +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. diff --git a/.changeset/huge-hounds-arrive.md b/.changeset/huge-hounds-arrive.md new file mode 100644 index 00000000000..97f7c348bda --- /dev/null +++ b/.changeset/huge-hounds-arrive.md @@ -0,0 +1,22 @@ +--- +'@graphql-codegen/visitor-plugin-common': major +'@graphql-codegen/typescript-operations': major +'@graphql-codegen/typescript': major +'@graphql-codegen/typescript-resolvers': major +'@graphql-codegen/cli': major +'@graphql-codegen/client-preset': major +'@graphql-codegen/core': major +'@graphql-codegen/add': major +'@graphql-codegen/fragment-matcher': major +'@graphql-codegen/introspection': major +'@graphql-codegen/schema-ast': major +'@graphql-codegen/time': major +'@graphql-codegen/typescript-document-nodes': major +'@graphql-codegen/gql-tag-operations': major +'@graphql-codegen/typed-document-node': major +'@graphql-codegen/graphql-modules-preset': major +'@graphql-codegen/testing': major +'@graphql-codegen/plugin-helpers': major +--- + +BREAKING CHANGE: Drop Node 20 support diff --git a/.changeset/khaki-clubs-say.md b/.changeset/khaki-clubs-say.md new file mode 100644 index 00000000000..0bbae4c9c99 --- /dev/null +++ b/.changeset/khaki-clubs-say.md @@ -0,0 +1,9 @@ +--- +'@graphql-codegen/typescript-operations': patch +--- + +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. diff --git a/.changeset/khaki-spies-admire.md b/.changeset/khaki-spies-admire.md new file mode 100644 index 00000000000..efda9226e8a --- /dev/null +++ b/.changeset/khaki-spies-admire.md @@ -0,0 +1,9 @@ +--- +'@graphql-codegen/typescript-operations': major +--- + +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. diff --git a/.changeset/khaki-turtles-juggle.md b/.changeset/khaki-turtles-juggle.md new file mode 100644 index 00000000000..bb0e0614a6a --- /dev/null +++ b/.changeset/khaki-turtles-juggle.md @@ -0,0 +1,6 @@ +--- +'@graphql-codegen/typescript-operations': major +'@graphql-codegen/typescript': minor +--- + +The `typescript-operations` plugin no longer generates InputMaybe and Scalars types; it now uses native Typescript types instead. diff --git a/.changeset/lovely-sloths-kiss.md b/.changeset/lovely-sloths-kiss.md new file mode 100644 index 00000000000..3005f29b02b --- /dev/null +++ b/.changeset/lovely-sloths-kiss.md @@ -0,0 +1,7 @@ +--- +'@graphql-codegen/typescript-operations': major +'@graphql-codegen/typescript': major +'@graphql-codegen/client-preset': major +--- + +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. diff --git a/.changeset/new-foxes-bake.md b/.changeset/new-foxes-bake.md new file mode 100644 index 00000000000..c3355eb01a1 --- /dev/null +++ b/.changeset/new-foxes-bake.md @@ -0,0 +1,9 @@ +--- +'@graphql-codegen/visitor-plugin-common': patch +--- + +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 diff --git a/.changeset/proud-cougars-hear.md b/.changeset/proud-cougars-hear.md new file mode 100644 index 00000000000..f02764b32ff --- /dev/null +++ b/.changeset/proud-cougars-hear.md @@ -0,0 +1,5 @@ +--- +'@graphql-codegen/visitor-plugin-common': major +--- + +BREAKING CHANGE: `@graphql-codegen/visitor-plugin-common`'s `base-types-visitor` no longer has `getNodeComment` or `buildEnumValuesBlock` method. diff --git a/.changeset/proud-dingos-trade.md b/.changeset/proud-dingos-trade.md new file mode 100644 index 00000000000..22576b3959f --- /dev/null +++ b/.changeset/proud-dingos-trade.md @@ -0,0 +1,5 @@ +--- +'@graphql-codegen/typescript-operations': patch +--- + +Fix external custom scalars not getting imported diff --git a/.changeset/proud-jobs-decide.md b/.changeset/proud-jobs-decide.md new file mode 100644 index 00000000000..dd7d919643d --- /dev/null +++ b/.changeset/proud-jobs-decide.md @@ -0,0 +1,6 @@ +--- +'@graphql-codegen/visitor-plugin-common': minor +'@graphql-codegen/typescript-operations': minor +--- + +Add generateOperationTypes to typescript-operations to allow omitting operation types such as Variables, Query/Mutation/Subscription selection set, and Fragment types diff --git a/.changeset/real-numbers-fall.md b/.changeset/real-numbers-fall.md new file mode 100644 index 00000000000..12c0cedbf52 --- /dev/null +++ b/.changeset/real-numbers-fall.md @@ -0,0 +1,14 @@ +--- +'@graphql-codegen/visitor-plugin-common': major +'@graphql-codegen/typescript-operations': major +'@graphql-codegen/client-preset': major +--- + +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. diff --git a/.changeset/sad-rules-sell.md b/.changeset/sad-rules-sell.md new file mode 100644 index 00000000000..d5725fe05bf --- /dev/null +++ b/.changeset/sad-rules-sell.md @@ -0,0 +1,5 @@ +--- +'@graphql-codegen/client-preset': major +--- + +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 diff --git a/.changeset/salty-guests-retire.md b/.changeset/salty-guests-retire.md new file mode 100644 index 00000000000..78587b447ad --- /dev/null +++ b/.changeset/salty-guests-retire.md @@ -0,0 +1,6 @@ +--- +'@graphql-codegen/typescript-operations': major +'@graphql-codegen/client-preset': major +--- + +Integrate new typescript-operations into client-preset diff --git a/.changeset/seven-wombats-tie.md b/.changeset/seven-wombats-tie.md new file mode 100644 index 00000000000..4291aa63ff0 --- /dev/null +++ b/.changeset/seven-wombats-tie.md @@ -0,0 +1,5 @@ +--- +'@graphql-codegen/client-preset': patch +--- + +Remove @graphql-codegen/typescript from client-preset dep as the preset no longer uses the plugin. diff --git a/.changeset/silly-kiwis-sip.md b/.changeset/silly-kiwis-sip.md new file mode 100644 index 00000000000..31295846e7e --- /dev/null +++ b/.changeset/silly-kiwis-sip.md @@ -0,0 +1,5 @@ +--- +'@graphql-codegen/typescript': patch +--- + +Extract utilities from base-type-visitor to be shared with other plugins later: convertSchemaEnumToDeclarationBlockString, getNodeComment diff --git a/.changeset/slow-sheep-rush.md b/.changeset/slow-sheep-rush.md new file mode 100644 index 00000000000..5caab3f24ed --- /dev/null +++ b/.changeset/slow-sheep-rush.md @@ -0,0 +1,9 @@ +--- +'@graphql-codegen/cli': major +--- + +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. \ No newline at end of file diff --git a/.changeset/stale-regions-bow.md b/.changeset/stale-regions-bow.md new file mode 100644 index 00000000000..612da8f1e04 --- /dev/null +++ b/.changeset/stale-regions-bow.md @@ -0,0 +1,6 @@ +--- +'@graphql-codegen/visitor-plugin-common': patch +'@graphql-codegen/typescript-operations': patch +--- + +Ensure Input and Variables use the same input scalars default e.g. `ID` can take `string | number` diff --git a/.changeset/tasty-waves-trade.md b/.changeset/tasty-waves-trade.md new file mode 100644 index 00000000000..4a7facf07e3 --- /dev/null +++ b/.changeset/tasty-waves-trade.md @@ -0,0 +1,7 @@ +--- +'@graphql-codegen/visitor-plugin-common': patch +'@graphql-codegen/typescript': patch +'@graphql-codegen/typescript-resolvers': patch +--- + +Fix namingConvention not being applied consistently diff --git a/.changeset/tender-snakes-hang.md b/.changeset/tender-snakes-hang.md new file mode 100644 index 00000000000..244560ae0ba --- /dev/null +++ b/.changeset/tender-snakes-hang.md @@ -0,0 +1,5 @@ +--- +'@graphql-codegen/typescript-operations': patch +--- + +Fix `@skip` and `@include` not applying conditional modifiers correctly when used on inline fragment diff --git a/.changeset/tidy-jobs-unite.md b/.changeset/tidy-jobs-unite.md new file mode 100644 index 00000000000..c4eb57e9cd1 --- /dev/null +++ b/.changeset/tidy-jobs-unite.md @@ -0,0 +1,9 @@ +--- +'@graphql-codegen/visitor-plugin-common': patch +'@graphql-codegen/typescript-operations': patch +'@graphql-codegen/typescript': patch +'@graphql-codegen/typescript-resolvers': patch +'@graphql-codegen/client-preset': patch +--- + +Abstract how enum imports are generated into visitor-plugin-common package diff --git a/.changeset/tiny-baboons-fry.md b/.changeset/tiny-baboons-fry.md new file mode 100644 index 00000000000..7ffa62adc80 --- /dev/null +++ b/.changeset/tiny-baboons-fry.md @@ -0,0 +1,5 @@ +--- +'@graphql-codegen/typescript-operations': patch +--- + +Fix `@skip` and `@include` not applying conditional modifiers correctly when used on fragment sread, and `@defer` fragments diff --git a/.changeset/twelve-trams-pump.md b/.changeset/twelve-trams-pump.md new file mode 100644 index 00000000000..6ec52b480bf --- /dev/null +++ b/.changeset/twelve-trams-pump.md @@ -0,0 +1,13 @@ +--- +'@graphql-codegen/visitor-plugin-common': major +'@graphql-codegen/typescript': major +--- + +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 diff --git a/.changeset/twenty-buckets-brush.md b/.changeset/twenty-buckets-brush.md new file mode 100644 index 00000000000..92cda5aef3d --- /dev/null +++ b/.changeset/twenty-buckets-brush.md @@ -0,0 +1,5 @@ +--- +'@graphql-codegen/typescript-operations': patch +--- + +Fix importing issue of Input when importSchemaTypesFrom is used diff --git a/.changeset/upset-bars-call.md b/.changeset/upset-bars-call.md new file mode 100644 index 00000000000..1b09fb593e8 --- /dev/null +++ b/.changeset/upset-bars-call.md @@ -0,0 +1,6 @@ +--- +'@graphql-codegen/typescript-operations': minor +'@graphql-codegen/visitor-plugin-common': minor +--- + +Fixing 2 bugs: 1) including enums from external fragments; 2) extractAllFieldsToTypesCompact does not create duplicates diff --git a/.changeset/wacky-books-post.md b/.changeset/wacky-books-post.md new file mode 100644 index 00000000000..47fca5fee43 --- /dev/null +++ b/.changeset/wacky-books-post.md @@ -0,0 +1,14 @@ +--- +'@graphql-codegen/cli': patch +--- + +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` diff --git a/.changeset/whole-eagles-switch.md b/.changeset/whole-eagles-switch.md new file mode 100644 index 00000000000..0eb3ed44429 --- /dev/null +++ b/.changeset/whole-eagles-switch.md @@ -0,0 +1,7 @@ +--- +'@graphql-codegen/visitor-plugin-common': patch +'@graphql-codegen/typescript-operations': patch +'@graphql-codegen/typescript': patch +--- + +Fix namingConvention not being applied consistently in imports, Variables, Input and Result diff --git a/.changeset/wise-poets-float.md b/.changeset/wise-poets-float.md new file mode 100644 index 00000000000..9fb2acb4d2a --- /dev/null +++ b/.changeset/wise-poets-float.md @@ -0,0 +1,6 @@ +--- +'@graphql-codegen/typescript-operations': major +'@graphql-codegen/client-preset': major +--- + +BREAKING CHANGE: config.avoidOptionals now only supports object, inputValue, defaultValue diff --git a/.changeset/yellow-cups-crash.md b/.changeset/yellow-cups-crash.md new file mode 100644 index 00000000000..0aa8b16743f --- /dev/null +++ b/.changeset/yellow-cups-crash.md @@ -0,0 +1,5 @@ +--- +'@graphql-codegen/typescript-operations': major +--- + +BREAKING CHANGE: rename avoidOptionals.object to avoidOptionals.variableValue diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1fbe24c817d..7e621065b7c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -4,9 +4,11 @@ on: push: branches: - master + - master-next # FIXME:eddeee888 Remove once done pull_request: branches: - master + - master-next # FIXME:eddeee888 Remove once released concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -137,10 +139,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/.github/workflows/pr.yml b/.github/workflows/pr.yml index 4d05c7f9de2..102e5f252b2 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -3,6 +3,7 @@ on: pull_request: branches: - master + - master-next # FIXME:eddeee888 Remove once done concurrency: group: ${{ github.workflow }}-${{ github.ref }} 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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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 293f1fbb277..d1344cde659 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": { @@ -94,6 +95,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/package.json b/packages/graphql-codegen-cli/package.json index 83b7bdaf053..60b1261577e 100644 --- a/packages/graphql-codegen-cli/package.json +++ b/packages/graphql-codegen-cli/package.json @@ -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", @@ -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.2" 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 8a692a9fb2a..0f9dcecde3f 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/plugins/other/visitor-plugin-common/package.json b/packages/plugins/other/visitor-plugin-common/package.json index f2c8e2e8f3a..3f3928b00d7 100644 --- a/packages/plugins/other/visitor-plugin-common/package.json +++ b/packages/plugins/other/visitor-plugin-common/package.json @@ -43,8 +43,8 @@ "@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/package.json b/packages/plugins/typescript/document-nodes/package.json index 75c06cf5033..6dab78a0867 100644 --- a/packages/plugins/typescript/document-nodes/package.json +++ b/packages/plugins/typescript/document-nodes/package.json @@ -42,7 +42,7 @@ "dependencies": { "@graphql-codegen/plugin-helpers": "^6.3.0", "@graphql-codegen/visitor-plugin-common": "^6.3.0", - "auto-bind": "~4.0.0", + "auto-bind": "^5.0.0", "tslib": "^2.8.0" }, "publishConfig": { diff --git a/packages/plugins/typescript/gql-tag-operations/package.json b/packages/plugins/typescript/gql-tag-operations/package.json index c6b24dc0aa1..c1b549dde47 100644 --- a/packages/plugins/typescript/gql-tag-operations/package.json +++ b/packages/plugins/typescript/gql-tag-operations/package.json @@ -43,7 +43,7 @@ "@graphql-codegen/plugin-helpers": "^6.3.0", "@graphql-codegen/visitor-plugin-common": "^6.3.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/package.json b/packages/plugins/typescript/operations/package.json index 437c8049e46..ef2bbc1bf13 100644 --- a/packages/plugins/typescript/operations/package.json +++ b/packages/plugins/typescript/operations/package.json @@ -47,9 +47,9 @@ }, "dependencies": { "@graphql-codegen/plugin-helpers": "^6.3.0", - "@graphql-codegen/typescript": "^5.0.10", + "@graphql-codegen/schema-ast": "^5.0.1", "@graphql-codegen/visitor-plugin-common": "^6.3.0", - "auto-bind": "~4.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/package.json b/packages/plugins/typescript/resolvers/package.json index 1f074cd5193..3b1c91623a6 100644 --- a/packages/plugins/typescript/resolvers/package.json +++ b/packages/plugins/typescript/resolvers/package.json @@ -50,7 +50,7 @@ "@graphql-codegen/typescript": "^5.0.10", "@graphql-codegen/visitor-plugin-common": "^6.3.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/package.json b/packages/plugins/typescript/typed-document-node/package.json index 0de4bca6e85..72b15d6de47 100644 --- a/packages/plugins/typescript/typed-document-node/package.json +++ b/packages/plugins/typescript/typed-document-node/package.json @@ -42,8 +42,8 @@ "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", + "auto-bind": "^5.0.0", + "change-case-all": "^2.1.0", "tslib": "^2.8.0" }, "publishConfig": { diff --git a/packages/plugins/typescript/typescript/package.json b/packages/plugins/typescript/typescript/package.json index 00c343092d4..9e224ee64ff 100644 --- a/packages/plugins/typescript/typescript/package.json +++ b/packages/plugins/typescript/typescript/package.json @@ -43,8 +43,8 @@ "@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" + "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/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/package.json b/packages/presets/graphql-modules/package.json index 6d63e140309..b5c686bdf43 100644 --- a/packages/presets/graphql-modules/package.json +++ b/packages/presets/graphql-modules/package.json @@ -42,7 +42,7 @@ "@graphql-codegen/plugin-helpers": "^6.3.0", "@graphql-codegen/visitor-plugin-common": "^6.3.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/plugins-helpers/package.json b/packages/utils/plugins-helpers/package.json index 3506e830e64..b6b54b0b94c 100644 --- a/packages/utils/plugins-helpers/package.json +++ b/packages/utils/plugins-helpers/package.json @@ -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/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 70e9963c646..21b0f202188 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== @@ -2767,63 +2889,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/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@^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/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== @@ -2831,86 +2950,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== "@isaacs/cliui@^8.0.2": version "8.0.2" @@ -4268,7 +4401,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== @@ -4910,7 +5043,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== @@ -5370,6 +5510,18 @@ dependencies: "@rolldown/pluginutils" "1.0.0-rc.2" +"@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.4": version "4.1.4" resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-4.1.4.tgz#1507e51c53969723c99e8a7f054aa12cfa7c1a4d" @@ -5382,6 +5534,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.4": version "4.1.4" resolved "https://registry.yarnpkg.com/@vitest/mocker/-/mocker-4.1.4.tgz#5d22e99d8dbacf2f77f7a4c30a6e17eece7f25ef" @@ -5391,6 +5552,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.4": version "4.1.4" resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-4.1.4.tgz#0ee79cd2ef8321330dabb8cc57ba9bce237e7183" @@ -5398,6 +5566,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.4": version "4.1.4" resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-4.1.4.tgz#8f884f265efabfdd8a5ee393cfe622a01ec849c2" @@ -5406,6 +5582,15 @@ "@vitest/utils" "4.1.4" 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.4": version "4.1.4" resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-4.1.4.tgz#600c04ee1c598d4e6ce219afae684ff21c3e187d" @@ -5416,11 +5601,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.4": version "4.1.4" resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-4.1.4.tgz#b955fcef98bcc746e7fc61d17d4725b43b33fa6d" integrity sha512-XxNdAsKW7C+FLydqFJLb5KhJtl3PGCMmYwFRfhvIgxJvLSXhhVI1zM8f1qD3Zg7RCjTSzDVyct6sghs9UEgBEQ== +"@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.4": version "4.1.4" resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-4.1.4.tgz#9518fb0ad0903ae455e82e063fa18e7558aa6065" @@ -5637,6 +5835,11 @@ resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.9.9.tgz#665b1cf4e5962d248bb4d032b5e020626f634503" integrity sha512-qycIHAucxy/LXAYIjmLmtQ8q9GPnMbnjG1KXhWm9o5sCr6pOYDATkMPiTNa6/v8eELyqOQ2FsEqeoFYmgv/gJg== +"@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" @@ -5963,6 +6166,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" @@ -6107,13 +6315,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" @@ -6371,7 +6572,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== @@ -6383,7 +6584,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== @@ -6396,6 +6597,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" @@ -6428,6 +6634,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" @@ -6446,6 +6662,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" @@ -6579,7 +6800,7 @@ cli-truncate@^2.1.0: slice-ansi "^3.0.0" string-width "^4.2.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== @@ -6633,6 +6854,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" @@ -7302,10 +7532,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" @@ -7410,6 +7640,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" @@ -7693,6 +7928,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.0.0" resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-2.0.0.tgz#f657cd7a9448dcdda9c070a3cb75e5dc1e85f5b1" @@ -7783,6 +8023,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" @@ -8318,7 +8587,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== @@ -8390,7 +8659,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== @@ -8454,11 +8723,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.4: version "1.1.4" resolved "https://registry.yarnpkg.com/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz#0c407a1d9d5996336c0cd76f7ff785cac6413017" @@ -8829,10 +9117,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.13.7" - resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.13.7.tgz#b9d8b199b06033ceeea1a93df7ea5765415089bc" - integrity sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q== +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" @@ -9406,7 +9694,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== @@ -9887,6 +10175,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" @@ -10379,6 +10672,17 @@ lint-staged@16.4.0: tinyexec "^1.0.4" yaml "^2.8.2" +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@^3.8.3: version "3.14.0" resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.14.0.tgz#23101cc62e1375fd5836b248276d1d2b51fdbe9e" @@ -10393,7 +10697,7 @@ listr2@^3.8.3: through "^2.3.8" wrap-ansi "^7.0.0" -listr2@^9.0.0, listr2@^9.0.5: +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== @@ -10524,6 +10828,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@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" @@ -10593,7 +10905,7 @@ 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== @@ -11438,11 +11750,6 @@ mlly@^1.7.4, mlly@^1.8.0: 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" @@ -11473,10 +11780,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" @@ -12452,7 +12759,7 @@ 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.8: +postcss@^8.4.4, postcss@^8.4.47, postcss@^8.5.6, postcss@^8.5.8: version "8.5.9" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.9.tgz#f6ee9e0b94f0f19c97d2f172bfbd7fc71fe1cca4" integrity sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw== @@ -13288,7 +13595,7 @@ rolldown@1.0.0-rc.15: "@rolldown/binding-win32-arm64-msvc" "1.0.0-rc.15" "@rolldown/binding-win32-x64-msvc" "1.0.0-rc.15" -rollup@^4.34.8: +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== @@ -13826,6 +14133,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" @@ -13882,6 +14194,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.0.0" resolved "https://registry.yarnpkg.com/std-env/-/std-env-4.0.0.tgz#ba3dc31c3a46bc5ba21138aa20a6a4ceb5bb9b7e" @@ -13951,7 +14268,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== @@ -14214,6 +14531,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" @@ -14378,7 +14700,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== @@ -14487,10 +14809,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" @@ -14579,6 +14901,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" @@ -14700,7 +15032,7 @@ typescript-json-schema@0.56.0: typescript "~4.9.5" yargs "^17.1.1" -typescript@6.0.2, typescript@^5, typescript@^6.0.0, typescript@~4.9.5: +typescript@6.0.2, typescript@^5, typescript@^5.9.3, typescript@^6.0.0, typescript@~4.9.5: version "6.0.2" resolved "https://registry.yarnpkg.com/typescript/-/typescript-6.0.2.tgz#0b1bfb15f68c64b97032f3d78abbf98bdbba501f" integrity sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ== @@ -15211,6 +15543,20 @@ vite-tsconfig-paths@6.1.1: globrex "^0.1.2" tsconfck "^3.0.3" +"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.8" resolved "https://registry.yarnpkg.com/vite/-/vite-8.0.8.tgz#4e26a9bba77c4b27a00b6b10100a7dab48d546a3" @@ -15224,6 +15570,32 @@ vite-tsconfig-paths@6.1.1: 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.4: version "4.1.4" resolved "https://registry.yarnpkg.com/vitest/-/vitest-4.1.4.tgz#330a3798ce307f88d3eea373e61a5f14da8f3bb1" @@ -15518,6 +15890,15 @@ wrangler@4.81.1: 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" @@ -15620,6 +16001,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" @@ -15637,7 +16023,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== @@ -15650,6 +16036,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" @@ -15673,10 +16071,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"