diff --git a/.changeset/shy-rabbits-juggle.md b/.changeset/shy-rabbits-juggle.md new file mode 100644 index 00000000000..5cc6bd7d85b --- /dev/null +++ b/.changeset/shy-rabbits-juggle.md @@ -0,0 +1,5 @@ +--- +"@graphql-codegen/client-preset": patch +--- + +The client preset now allows the use of the `enumsAsConst` config option diff --git a/packages/presets/client/src/index.ts b/packages/presets/client/src/index.ts index 7bf2cbeaea9..5c59cc281a6 100644 --- a/packages/presets/client/src/index.ts +++ b/packages/presets/client/src/index.ts @@ -127,6 +127,7 @@ export const preset: Types.OutputPreset = { skipTypename: options.config.skipTypename, arrayInputCoercion: options.config.arrayInputCoercion, enumsAsTypes: options.config.enumsAsTypes, + enumsAsConst: options.config.enumsAsConst, futureProofEnums: options.config.futureProofEnums, dedupeFragments: options.config.dedupeFragments, nonOptionalTypename: options.config.nonOptionalTypename, diff --git a/packages/presets/client/tests/client-preset.spec.ts b/packages/presets/client/tests/client-preset.spec.ts index 82cb20abbd1..49ca2d43997 100644 --- a/packages/presets/client/tests/client-preset.spec.ts +++ b/packages/presets/client/tests/client-preset.spec.ts @@ -2748,4 +2748,76 @@ export * from "./gql.js";`); `); }); }); + + 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 = 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 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; + `); + }); }); diff --git a/packages/presets/client/tests/fixtures/enum.ts b/packages/presets/client/tests/fixtures/enum.ts new file mode 100644 index 00000000000..6430bc9c1d5 --- /dev/null +++ b/packages/presets/client/tests/fixtures/enum.ts @@ -0,0 +1,12 @@ +/* eslint-disable @typescript-eslint/ban-ts-comment */ +//@ts-ignore +import gql from 'gql-tag'; + +//@ts-ignore +const A = gql(/* GraphQL */ ` + query FavoriteColor { + thing { + color + } + } +`); diff --git a/website/src/pages/docs/guides/react-vue.mdx b/website/src/pages/docs/guides/react-vue.mdx index 9513a56c78d..70bb45bcdb8 100644 --- a/website/src/pages/docs/guides/react-vue.mdx +++ b/website/src/pages/docs/guides/react-vue.mdx @@ -508,6 +508,7 @@ The `client` preset allows the following `config` options: - [`skipTypename`](/plugins/typescript/typescript#skiptypename): Does not add `__typename` to the generated types, unless it was specified in the selection set. - [`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. - [`dedupeFragments`](/plugins/typescript/typescript#dedupefragments): Removes fragment duplicates for reducing data transfer. It is done by removing sub-fragments imports from fragment definition. - [`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. diff --git a/website/src/pages/plugins/presets/preset-client.mdx b/website/src/pages/plugins/presets/preset-client.mdx index bfc97f03095..55c8e57bc62 100644 --- a/website/src/pages/plugins/presets/preset-client.mdx +++ b/website/src/pages/plugins/presets/preset-client.mdx @@ -52,6 +52,7 @@ The `client` preset allows the following `config` options: - [`skipTypename`](/plugins/typescript/typescript#skiptypename): Does not add `__typename` to the generated types, unless it was specified in the selection set. - [`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. - [`futureProofEnums`](/plugins/typescript/typescript#futureproofenums): Adds a catch-all entry to enum type definitions for values that may be added in the future. - [`dedupeFragments`](/plugins/typescript/typescript#dedupefragments): Removes fragment duplicates for reducing data transfer. It is done by removing sub-fragments imports from fragment definition. - [`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.