A tool for generating code based on a GraphQL schema and GraphQL operations (query/mutation/subscription), with flexible support for custom plugins.
#9151 b7dacb21f
Thanks @eddeee888! - Add watchPattern
config option for generates
sections.
By default, watch
mode automatically watches all GraphQL schema and document files. This means when a change is detected, Codegen CLI is run.
A user may want to run Codegen CLI when non-schema and non-document files are changed. Each generates
section now has a watchPattern
option to allow more file patterns to be added to the list of patterns to watch.
In the example below, mappers are exported from schema.mappers.ts
files. We want to re-run Codegen if the content of *.mappers.ts
files change because they change the generated types file. To solve this, we can add mapper file patterns to watch using the glob pattern used for schema and document files.
// codegen.ts
const config: CodegenConfig = {
schema: 'src/schema/**/*.graphql',
generates: {
'src/schema/types.ts': {
plugins: ['typescript', 'typescript-resolvers'],
config: {
mappers: {
User: './user/schema.mappers#UserMapper',
Book: './book/schema.mappers#BookMapper',
},
}
watchPattern: 'src/schema/**/*.mappers.ts', // Watches mapper files in `watch` mode. Use an array for multiple patterns e.g. `['src/*.pattern1.ts','src/*.pattern2.ts']`
},
},
};
Then, run Codegen CLI in watch
mode:
yarn graphql-codegen --watch
Now, updating *.mappers.ts
files re-runs Codegen! 🎉
Note: watchPattern
is only used in watch
mode i.e. running CLI with --watch
flag.
b7dacb21f
, f104619ac
]:
#9146 9f4d9c5a4
Thanks @eddeee888! - [typescript-resolvers] Add resolversNonOptionalTypename
config option.
This is extending on ResolversUnionTypes
implemented in https://github.com/dotansimha/graphql-code-generator/pull/9069
resolversNonOptionalTypename
adds non-optional __typename
to union members of ResolversUnionTypes
, without affecting the union members' base intefaces.
A common use case for non-optional __typename
of union members is using it as the common field to work out the final schema type. This makes implementing the union's __resolveType
very simple as we can use __typename
to decide which union member the resolved object is. Without this, we have to check the existence of field/s on the incoming object which could be verbose.
For example, consider this schema:
type Query {
book(id: ID!): BookPayload!
}
type Book {
id: ID!
isbn: String!
}
type BookResult {
node: Book
}
type PayloadError {
message: String!
}
union BookPayload = BookResult | PayloadError
With optional __typename
: We need to check existence of certain fields to resolve type in the union resolver:
// Query/book.ts
export const book = async () => {
try {
const book = await fetchBook();
// 1. No `__typename` in resolver results...
return {
node: book,
};
} catch (e) {
return {
message: 'Failed to fetch book',
};
}
};
// BookPayload.ts
export const BookPayload = {
__resolveType: parent => {
// 2. ... means more checks in `__resolveType`
if ('message' in parent) {
return 'PayloadError';
}
return 'BookResult';
},
};
With non-optional __typename
: Resolvers declare the type. This which gives us better TypeScript support in resolvers and simplify __resolveType
implementation:
// Query/book.ts
export const book = async () => {
try {
const book = await fetchBook();
// 1. `__typename` is declared in resolver results...
return {
__typename: 'BookResult', // 1a. this also types `node` for us 🎉
node: book,
};
} catch (e) {
return {
__typename: 'PayloadError',
message: 'Failed to fetch book',
};
}
};
// BookPayload.ts
export const BookPayload = {
__resolveType: parent => parent.__typename, // 2. ... means a very simple check in `__resolveType`
};
Using resolversNonOptionalTypename
: add it into typescript-resolvers
plugin config:
// codegen.ts
const config: CodegenConfig = {
schema: 'src/schema/**/*.graphql',
generates: {
'src/schema/types.ts': {
plugins: ['typescript', 'typescript-resolvers'],
config: {
resolversNonOptionalTypename: true, // Or `resolversNonOptionalTypename: { unionMember: true }`
},
},
},
};
#9206 e56790104
Thanks @eddeee888! - Fix ResolversUnionTypes
being used in ResolversParentTypes
Previously, objects with mappable fields are converted to Omit format that references its own type group or ResolversTypes
or ResolversParentTypes
e.g.
export type ResolversTypes = {
Book: ResolverTypeWrapper<BookMapper>;
BookPayload: ResolversTypes['BookResult'] | ResolversTypes['StandardError'];
// Note: `result` on the next line references `ResolversTypes["Book"]`
BookResult: ResolverTypeWrapper<Omit<BookResult, 'result'> & { result?: Maybe<ResolversTypes['Book']> }>;
StandardError: ResolverTypeWrapper<StandardError>;
};
export type ResolversParentTypes = {
Book: BookMapper;
BookPayload: ResolversParentTypes['BookResult'] | ResolversParentTypes['StandardError'];
// Note: `result` on the next line references `ResolversParentTypes["Book"]`
BookResult: Omit<BookResult, 'result'> & { result?: Maybe<ResolversParentTypes['Book']> };
StandardError: StandardError;
};
In https://github.com/dotansimha/graphql-code-generator/pull/9069, we extracted resolver union types to its own group:
export type ResolversUnionTypes = {
// Note: `result` on the next line references `ResolversTypes["Book"]` which is only correct for the `ResolversTypes` case
BookPayload: (Omit<BookResult, 'result'> & { result?: Maybe<ResolversTypes['Book']> }) | StandardError;
};
export type ResolversTypes = {
Book: ResolverTypeWrapper<BookMapper>;
BookPayload: ResolverTypeWrapper<ResolversUnionTypes['BookPayload']>;
BookResult: ResolverTypeWrapper<Omit<BookResult, 'result'> & { result?: Maybe<ResolversTypes['Book']> }>;
StandardError: ResolverTypeWrapper<StandardError>;
};
export type ResolversParentTypes = {
Book: BookMapper;
BookPayload: ResolversUnionTypes['BookPayload'];
BookResult: Omit<BookResult, 'result'> & { result?: Maybe<ResolversParentTypes['Book']> };
StandardError: StandardError;
};
This change creates an extra ResolversUnionParentTypes
that is referenced by ResolversParentTypes
to ensure backwards compatibility:
export type ResolversUnionTypes = {
BookPayload: (Omit<BookResult, 'result'> & { result?: Maybe<ResolversParentTypes['Book']> }) | StandardError;
};
// ... and the reference is changed in ResolversParentTypes:
export type ResolversParentTypes = {
// ... other fields
BookPayload: ResolversUnionParentTypes['BookPayload'];
};
#9194 acb647e4e
Thanks @dstaley! - Don't emit import statements for unused fragments
Updated dependencies [b7dacb21f
, f104619ac
]:
e56790104
, b7dacb21f
, f104619ac
, acb647e4e
, 9f4d9c5a4
]:
2256c8b5d
Thanks @beerose! - Add TypedDocumentNode
string alternative that doesn't require GraphQL AST on the client. This change requires @graphql-typed-document-node/core
in version 3.2.0
or higher.e56790104
, b7dacb21f
, f104619ac
, acb647e4e
, 9f4d9c5a4
]:
e56790104
, b7dacb21f
, f104619ac
, 92d86b009
, acb647e4e
, 9f4d9c5a4
]:
#9146 9f4d9c5a4
Thanks @eddeee888! - [typescript-resolvers] Add resolversNonOptionalTypename
config option.
This is extending on ResolversUnionTypes
implemented in https://github.com/dotansimha/graphql-code-generator/pull/9069
resolversNonOptionalTypename
adds non-optional __typename
to union members of ResolversUnionTypes
, without affecting the union members' base intefaces.
A common use case for non-optional __typename
of union members is using it as the common field to work out the final schema type. This makes implementing the union's __resolveType
very simple as we can use __typename
to decide which union member the resolved object is. Without this, we have to check the existence of field/s on the incoming object which could be verbose.
For example, consider this schema:
type Query {
book(id: ID!): BookPayload!
}
type Book {
id: ID!
isbn: String!
}
type BookResult {
node: Book
}
type PayloadError {
message: String!
}
union BookPayload = BookResult | PayloadError
With optional __typename
: We need to check existence of certain fields to resolve type in the union resolver:
// Query/book.ts
export const book = async () => {
try {
const book = await fetchBook();
// 1. No `__typename` in resolver results...
return {
node: book,
};
} catch (e) {
return {
message: 'Failed to fetch book',
};
}
};
// BookPayload.ts
export const BookPayload = {
__resolveType: parent => {
// 2. ... means more checks in `__resolveType`
if ('message' in parent) {
return 'PayloadError';
}
return 'BookResult';
},
};
With non-optional __typename
: Resolvers declare the type. This which gives us better TypeScript support in resolvers and simplify __resolveType
implementation:
// Query/book.ts
export const book = async () => {
try {
const book = await fetchBook();
// 1. `__typename` is declared in resolver results...
return {
__typename: 'BookResult', // 1a. this also types `node` for us 🎉
node: book,
};
} catch (e) {
return {
__typename: 'PayloadError',
message: 'Failed to fetch book',
};
}
};
// BookPayload.ts
export const BookPayload = {
__resolveType: parent => parent.__typename, // 2. ... means a very simple check in `__resolveType`
};
Using resolversNonOptionalTypename
: add it into typescript-resolvers
plugin config:
// codegen.ts
const config: CodegenConfig = {
schema: 'src/schema/**/*.graphql',
generates: {
'src/schema/types.ts': {
plugins: ['typescript', 'typescript-resolvers'],
config: {
resolversNonOptionalTypename: true, // Or `resolversNonOptionalTypename: { unionMember: true }`
},
},
},
};
#9206 e56790104
Thanks @eddeee888! - Fix ResolversUnionTypes
being used in ResolversParentTypes
Previously, objects with mappable fields are converted to Omit format that references its own type group or ResolversTypes
or ResolversParentTypes
e.g.
export type ResolversTypes = {
Book: ResolverTypeWrapper<BookMapper>;
BookPayload: ResolversTypes['BookResult'] | ResolversTypes['StandardError'];
// Note: `result` on the next line references `ResolversTypes["Book"]`
BookResult: ResolverTypeWrapper<Omit<BookResult, 'result'> & { result?: Maybe<ResolversTypes['Book']> }>;
StandardError: ResolverTypeWrapper<StandardError>;
};
export type ResolversParentTypes = {
Book: BookMapper;
BookPayload: ResolversParentTypes['BookResult'] | ResolversParentTypes['StandardError'];
// Note: `result` on the next line references `ResolversParentTypes["Book"]`
BookResult: Omit<BookResult, 'result'> & { result?: Maybe<ResolversParentTypes['Book']> };
StandardError: StandardError;
};
In https://github.com/dotansimha/graphql-code-generator/pull/9069, we extracted resolver union types to its own group:
export type ResolversUnionTypes = {
// Note: `result` on the next line references `ResolversTypes["Book"]` which is only correct for the `ResolversTypes` case
BookPayload: (Omit<BookResult, 'result'> & { result?: Maybe<ResolversTypes['Book']> }) | StandardError;
};
export type ResolversTypes = {
Book: ResolverTypeWrapper<BookMapper>;
BookPayload: ResolverTypeWrapper<ResolversUnionTypes['BookPayload']>;
BookResult: ResolverTypeWrapper<Omit<BookResult, 'result'> & { result?: Maybe<ResolversTypes['Book']> }>;
StandardError: ResolverTypeWrapper<StandardError>;
};
export type ResolversParentTypes = {
Book: BookMapper;
BookPayload: ResolversUnionTypes['BookPayload'];
BookResult: Omit<BookResult, 'result'> & { result?: Maybe<ResolversParentTypes['Book']> };
StandardError: StandardError;
};
This change creates an extra ResolversUnionParentTypes
that is referenced by ResolversParentTypes
to ensure backwards compatibility:
export type ResolversUnionTypes = {
BookPayload: (Omit<BookResult, 'result'> & { result?: Maybe<ResolversParentTypes['Book']> }) | StandardError;
};
// ... and the reference is changed in ResolversParentTypes:
export type ResolversParentTypes = {
// ... other fields
BookPayload: ResolversUnionParentTypes['BookPayload'];
};
f104619ac
Thanks @saihaj! - Resolve issue with nesting fields in @provides
directive being prevented
Updated dependencies [e56790104
, b7dacb21f
, f104619ac
, 92d86b009
, acb647e4e
, 9f4d9c5a4
]:
2256c8b5d
Thanks @beerose! - Add TypedDocumentNode
string alternative that doesn't require GraphQL AST on the client. This change requires @graphql-typed-document-node/core
in version 3.2.0
or higher.e56790104
, b7dacb21f
, f104619ac
, acb647e4e
, 9f4d9c5a4
]:
#9150 92d86b009
Thanks @rliljest! - Properly escape enum identifiers when enumsAsConst is used
Updated dependencies [e56790104
, b7dacb21f
, f104619ac
, acb647e4e
, 9f4d9c5a4
]:
2256c8b5d
Thanks @beerose! - Add TypedDocumentNode
string alternative that doesn't require GraphQL AST on the client. This change requires @graphql-typed-document-node/core
in version 3.2.0
or higher.2256c8b5d
Thanks @beerose! - dependencies updates:
@graphql-typed-document-node/[email protected]
↗︎ (from 3.1.2
, in dependencies
)e56790104
, b7dacb21f
, f104619ac
, 92d86b009
, 2256c8b5d
, acb647e4e
, 9f4d9c5a4
]:
e56790104
, b7dacb21f
, f104619ac
, acb647e4e
, 9f4d9c5a4
]:
#9228 a5ec5af36
Thanks @eddeee888! - Add complex test cases for resolvers tests
Updated dependencies [b7dacb21f
, f104619ac
]:
#9151 b7dacb21f
Thanks @eddeee888! - Add watchPattern
config option for generates
sections.
By default, watch
mode automatically watches all GraphQL schema and document files. This means when a change is detected, Codegen CLI is run.
A user may want to run Codegen CLI when non-schema and non-document files are changed. Each generates
section now has a watchPattern
option to allow more file patterns to be added to the list of patterns to watch.
In the example below, mappers are exported from schema.mappers.ts
files. We want to re-run Codegen if the content of *.mappers.ts
files change because they change the generated types file. To solve this, we can add mapper file patterns to watch using the glob pattern used for schema and document files.
// codegen.ts
const config: CodegenConfig = {
schema: 'src/schema/**/*.graphql',
generates: {
'src/schema/types.ts': {
plugins: ['typescript', 'typescript-resolvers'],
config: {
mappers: {
User: './user/schema.mappers#UserMapper',
Book: './book/schema.mappers#BookMapper',
},
}
watchPattern: 'src/schema/**/*.mappers.ts', // Watches mapper files in `watch` mode. Use an array for multiple patterns e.g. `['src/*.pattern1.ts','src/*.pattern2.ts']`
},
},
};
Then, run Codegen CLI in watch
mode:
yarn graphql-codegen --watch
Now, updating *.mappers.ts
files re-runs Codegen! 🎉
Note: watchPattern
is only used in watch
mode i.e. running CLI with --watch
flag.
a34cef35b
, a34cef35b
]:
#9086 a34cef35b
Thanks @beerose! - dependencies updates:
graphql-config@^4.5.0
↗︎ (from ^4.4.0
, in dependencies
)jiti@^1.17.1
↗︎ (to dependencies
)cosmiconfig-typescript-loader@^4.3.0
↗︎ (from dependencies
)ts-node@^10.9.1
↗︎ (from dependencies
)#9086 a34cef35b
Thanks @beerose! - Support codegen.ts
in ESM projects
#9110 ba0610bbd
Thanks @gilgardosh! - Custom mappers with placeholder will apply omit
#9069 4b49f6fbe
Thanks @eddeee888! - Extract union types to ResolversUnionTypes
#8895 b343626c9
Thanks @benkroeger! - Preserve .js extension when importDocumentNodeExternallyFrom and emitLegacyCommonJSImports is false
ba0610bbd
, 4b49f6fbe
, b343626c9
]:
ba0610bbd
, 4b49f6fbe
, b343626c9
]:
ba0610bbd
, 4b49f6fbe
, b343626c9
]:
#9110 ba0610bbd
Thanks @gilgardosh! - Custom mappers with placeholder will apply omit
#9069 4b49f6fbe
Thanks @eddeee888! - Extract union types to ResolversUnionTypes
Updated dependencies [ba0610bbd
, 4b49f6fbe
, b343626c9
]:
ba0610bbd
, 4b49f6fbe
, b343626c9
]:
ba0610bbd
, 4b49f6fbe
, b343626c9
]:
9430c3811
Thanks @renovate! - dependencies updates:
@graphql-typed-document-node/[email protected]
↗︎ (from 3.1.1
, in dependencies
)ba0610bbd
, 4b49f6fbe
, b343626c9
]:
ba0610bbd
, 4b49f6fbe
, b343626c9
]:
f7313f7ca
, f7313f7ca
]:
288ed0977
, 288ed0977
]:
288ed0977
Thanks @saihaj! - dependencies updates:
@parcel/watcher@^2.1.0
↗︎ (to dependencies
)chokidar@^3.5.2
↗︎ (from dependencies
)#8893 a118c307a
Thanks @n1ru4l! - It is no longer mandatory to declare an empty plugins array when using a preset
#8723 a3309e63e
Thanks @kazekyo! - Introduce a new feature called DocumentTransform.
DocumentTransform is a functionality that allows you to modify documents
before they are processed by plugins. You can use functions passed to the documentTransforms
option to make changes to GraphQL documents.
To use this feature, you can write documentTransforms
as follows:
import type { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = {
schema: 'https://localhost:4000/graphql',
documents: ['src/**/*.tsx'],
generates: {
'./src/gql/': {
preset: 'client',
documentTransforms: [
{
transform: ({ documents }) => {
// Make some changes to the documents
return documents;
},
},
],
},
},
};
export default config;
For instance, to remove a @localOnlyDirective
directive from documents
, you can write the following code:
import type { CodegenConfig } from '@graphql-codegen/cli';
import { visit } from 'graphql';
const config: CodegenConfig = {
schema: 'https://localhost:4000/graphql',
documents: ['src/**/*.tsx'],
generates: {
'./src/gql/': {
preset: 'client',
documentTransforms: [
{
transform: ({ documents }) => {
return documents.map(documentFile => {
documentFile.document = visit(documentFile.document, {
Directive: {
leave(node) {
if (node.name.value === 'localOnlyDirective') return null;
},
},
});
return documentFile;
});
},
},
],
},
},
};
export default config;
DocumentTransform can also be specified by file name. You can create a custom file for a specific transformation and pass it to documentTransforms
.
Let's create the document transform as a file:
module.exports = {
transform: ({ documents }) => {
// Make some changes to the documents
return documents;
},
};
Then, you can specify the file name as follows:
import type { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = {
schema: 'https://localhost:4000/graphql',
documents: ['src/**/*.tsx'],
generates: {
'./src/gql/': {
preset: 'client',
documentTransforms: ['./my-document-transform.js'],
},
},
};
export default config;
4c422ccf6
Thanks @renovate! - dependencies updates:
@whatwg-node/fetch@^0.8.0
↗︎ (from ^0.6.0
, in dependencies
)8206b268d
, 8206b268d
, a118c307a
, a3309e63e
]:
#8723 a3309e63e
Thanks @kazekyo! - Introduce a new feature called DocumentTransform.
DocumentTransform is a functionality that allows you to modify documents
before they are processed by plugins. You can use functions passed to the documentTransforms
option to make changes to GraphQL documents.
To use this feature, you can write documentTransforms
as follows:
import type { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = {
schema: 'https://localhost:4000/graphql',
documents: ['src/**/*.tsx'],
generates: {
'./src/gql/': {
preset: 'client',
documentTransforms: [
{
transform: ({ documents }) => {
// Make some changes to the documents
return documents;
},
},
],
},
},
};
export default config;
For instance, to remove a @localOnlyDirective
directive from documents
, you can write the following code:
import type { CodegenConfig } from '@graphql-codegen/cli';
import { visit } from 'graphql';
const config: CodegenConfig = {
schema: 'https://localhost:4000/graphql',
documents: ['src/**/*.tsx'],
generates: {
'./src/gql/': {
preset: 'client',
documentTransforms: [
{
transform: ({ documents }) => {
return documents.map(documentFile => {
documentFile.document = visit(documentFile.document, {
Directive: {
leave(node) {
if (node.name.value === 'localOnlyDirective') return null;
},
},
});
return documentFile;
});
},
},
],
},
},
};
export default config;
DocumentTransform can also be specified by file name. You can create a custom file for a specific transformation and pass it to documentTransforms
.
Let's create the document transform as a file:
module.exports = {
transform: ({ documents }) => {
// Make some changes to the documents
return documents;
},
};
Then, you can specify the file name as follows:
import type { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = {
schema: 'https://localhost:4000/graphql',
documents: ['src/**/*.tsx'],
generates: {
'./src/gql/': {
preset: 'client',
documentTransforms: ['./my-document-transform.js'],
},
},
};
export default config;
8206b268d
Thanks @renovate! - dependencies updates:
tslib@~2.5.0
↗︎ (from ~2.4.0
, in dependencies
)8206b268d
, a118c307a
, a3309e63e
]:
b13aa7449
Thanks @KGAdamCook! - Updated customResolveInfo to use the correct importType for external imports8206b268d
Thanks @renovate! - dependencies updates:
tslib@~2.5.0
↗︎ (from ~2.4.0
, in dependencies
)8206b268d
, 8206b268d
, 8206b268d
, a118c307a
, 6b6fe3cbc
, a3309e63e
]:
#8893 a118c307a
Thanks @n1ru4l! - It is no longer mandatory to declare an empty plugins array when using a preset
#8723 a3309e63e
Thanks @kazekyo! - Introduce a new feature called DocumentTransform.
DocumentTransform is a functionality that allows you to modify documents
before they are processed by plugins. You can use functions passed to the documentTransforms
option to make changes to GraphQL documents.
To use this feature, you can write documentTransforms
as follows:
import type { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = {
schema: 'https://localhost:4000/graphql',
documents: ['src/**/*.tsx'],
generates: {
'./src/gql/': {
preset: 'client',
documentTransforms: [
{
transform: ({ documents }) => {
// Make some changes to the documents
return documents;
},
},
],
},
},
};
export default config;
For instance, to remove a @localOnlyDirective
directive from documents
, you can write the following code:
import type { CodegenConfig } from '@graphql-codegen/cli';
import { visit } from 'graphql';
const config: CodegenConfig = {
schema: 'https://localhost:4000/graphql',
documents: ['src/**/*.tsx'],
generates: {
'./src/gql/': {
preset: 'client',
documentTransforms: [
{
transform: ({ documents }) => {
return documents.map(documentFile => {
documentFile.document = visit(documentFile.document, {
Directive: {
leave(node) {
if (node.name.value === 'localOnlyDirective') return null;
},
},
});
return documentFile;
});
},
},
],
},
},
};
export default config;
DocumentTransform can also be specified by file name. You can create a custom file for a specific transformation and pass it to documentTransforms
.
Let's create the document transform as a file:
module.exports = {
transform: ({ documents }) => {
// Make some changes to the documents
return documents;
},
};
Then, you can specify the file name as follows:
import type { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = {
schema: 'https://localhost:4000/graphql',
documents: ['src/**/*.tsx'],
generates: {
'./src/gql/': {
preset: 'client',
documentTransforms: ['./my-document-transform.js'],
},
},
};
export default config;
#8879 8206b268d
Thanks @renovate! - dependencies updates:
tslib@~2.5.0
↗︎ (from ~2.4.0
, in dependencies
)#8995 fe2e9c7a5
Thanks @charpeni! - Use gqlTagName
for generated examples
#8971 6b6fe3cbc
Thanks @n1ru4l! - Allow passing fragment documents to APIs like Apollos readFragment
Updated dependencies [8206b268d
, 8206b268d
, 8206b268d
, 8206b268d
, 8206b268d
, 8206b268d
, 8206b268d
, a118c307a
, fe2e9c7a5
, 6b6fe3cbc
, 6b6fe3cbc
, a3309e63e
]:
#8893 a118c307a
Thanks @n1ru4l! - It is no longer mandatory to declare an empty plugins array when using a preset
#8723 a3309e63e
Thanks @kazekyo! - Introduce a new feature called DocumentTransform.
DocumentTransform is a functionality that allows you to modify documents
before they are processed by plugins. You can use functions passed to the documentTransforms
option to make changes to GraphQL documents.
To use this feature, you can write documentTransforms
as follows:
import type { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = {
schema: 'https://localhost:4000/graphql',
documents: ['src/**/*.tsx'],
generates: {
'./src/gql/': {
preset: 'client',
documentTransforms: [
{
transform: ({ documents }) => {
// Make some changes to the documents
return documents;
},
},
],
},
},
};
export default config;
For instance, to remove a @localOnlyDirective
directive from documents
, you can write the following code:
import type { CodegenConfig } from '@graphql-codegen/cli';
import { visit } from 'graphql';
const config: CodegenConfig = {
schema: 'https://localhost:4000/graphql',
documents: ['src/**/*.tsx'],
generates: {
'./src/gql/': {
preset: 'client',
documentTransforms: [
{
transform: ({ documents }) => {
return documents.map(documentFile => {
documentFile.document = visit(documentFile.document, {
Directive: {
leave(node) {
if (node.name.value === 'localOnlyDirective') return null;
},
},
});
return documentFile;
});
},
},
],
},
},
};
export default config;
DocumentTransform can also be specified by file name. You can create a custom file for a specific transformation and pass it to documentTransforms
.
Let's create the document transform as a file:
module.exports = {
transform: ({ documents }) => {
// Make some changes to the documents
return documents;
},
};
Then, you can specify the file name as follows:
import type { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = {
schema: 'https://localhost:4000/graphql',
documents: ['src/**/*.tsx'],
generates: {
'./src/gql/': {
preset: 'client',
documentTransforms: ['./my-document-transform.js'],
},
},
};
export default config;
8206b268d
Thanks @renovate! - dependencies updates:
tslib@~2.5.0
↗︎ (from ~2.4.0
, in dependencies
)8206b268d
, 8206b268d
, 8206b268d
, 8206b268d
, 8206b268d
, 8206b268d
, 8206b268d
, a118c307a
, fe2e9c7a5
, 6b6fe3cbc
, 6b6fe3cbc
, a3309e63e
]:
#8723 a3309e63e
Thanks @kazekyo! - Introduce a new feature called DocumentTransform.
DocumentTransform is a functionality that allows you to modify documents
before they are processed by plugins. You can use functions passed to the documentTransforms
option to make changes to GraphQL documents.
To use this feature, you can write documentTransforms
as follows:
import type { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = {
schema: 'https://localhost:4000/graphql',
documents: ['src/**/*.tsx'],
generates: {
'./src/gql/': {
preset: 'client',
documentTransforms: [
{
transform: ({ documents }) => {
// Make some changes to the documents
return documents;
},
},
],
},
},
};
export default config;
For instance, to remove a @localOnlyDirective
directive from documents
, you can write the following code:
import type { CodegenConfig } from '@graphql-codegen/cli';
import { visit } from 'graphql';
const config: CodegenConfig = {
schema: 'https://localhost:4000/graphql',
documents: ['src/**/*.tsx'],
generates: {
'./src/gql/': {
preset: 'client',
documentTransforms: [
{
transform: ({ documents }) => {
return documents.map(documentFile => {
documentFile.document = visit(documentFile.document, {
Directive: {
leave(node) {
if (node.name.value === 'localOnlyDirective') return null;
},
},
});
return documentFile;
});
},
},
],
},
},
};
export default config;
DocumentTransform can also be specified by file name. You can create a custom file for a specific transformation and pass it to documentTransforms
.
Let's create the document transform as a file:
module.exports = {
transform: ({ documents }) => {
// Make some changes to the documents
return documents;
},
};
Then, you can specify the file name as follows:
import type { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = {
schema: 'https://localhost:4000/graphql',
documents: ['src/**/*.tsx'],
generates: {
'./src/gql/': {
preset: 'client',
documentTransforms: ['./my-document-transform.js'],
},
},
};
export default config;
8206b268d
Thanks @renovate! - dependencies updates:
tslib@~2.5.0
↗︎ (from ~2.4.0
, in dependencies
)8206b268d
, 8206b268d
, a118c307a
, 6b6fe3cbc
, a3309e63e
]:
#8893 a118c307a
Thanks @n1ru4l! - mark plugins
in config optional
#8723 a3309e63e
Thanks @kazekyo! - Introduce a new feature called DocumentTransform.
DocumentTransform is a functionality that allows you to modify documents
before they are processed by plugins. You can use functions passed to the documentTransforms
option to make changes to GraphQL documents.
To use this feature, you can write documentTransforms
as follows:
import type { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = {
schema: 'https://localhost:4000/graphql',
documents: ['src/**/*.tsx'],
generates: {
'./src/gql/': {
preset: 'client',
documentTransforms: [
{
transform: ({ documents }) => {
// Make some changes to the documents
return documents;
},
},
],
},
},
};
export default config;
For instance, to remove a @localOnlyDirective
directive from documents
, you can write the following code:
import type { CodegenConfig } from '@graphql-codegen/cli';
import { visit } from 'graphql';
const config: CodegenConfig = {
schema: 'https://localhost:4000/graphql',
documents: ['src/**/*.tsx'],
generates: {
'./src/gql/': {
preset: 'client',
documentTransforms: [
{
transform: ({ documents }) => {
return documents.map(documentFile => {
documentFile.document = visit(documentFile.document, {
Directive: {
leave(node) {
if (node.name.value === 'localOnlyDirective') return null;
},
},
});
return documentFile;
});
},
},
],
},
},
};
export default config;
DocumentTransform can also be specified by file name. You can create a custom file for a specific transformation and pass it to documentTransforms
.
Let's create the document transform as a file:
module.exports = {
transform: ({ documents }) => {
// Make some changes to the documents
return documents;
},
};
Then, you can specify the file name as follows:
import type { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = {
schema: 'https://localhost:4000/graphql',
documents: ['src/**/*.tsx'],
generates: {
'./src/gql/': {
preset: 'client',
documentTransforms: ['./my-document-transform.js'],
},
},
};
export default config;
8206b268d
Thanks @renovate! - dependencies updates:
tslib@~2.5.0
↗︎ (from ~2.4.0
, in dependencies
)4c422ccf6
, a118c307a
, a3309e63e
]:
8206b268d
Thanks @renovate! - dependencies updates:
tslib@~2.5.0
↗︎ (from ~2.4.0
, in dependencies
)8206b268d
, a118c307a
, a3309e63e
]:
8206b268d
Thanks @renovate! - dependencies updates:
tslib@~2.5.0
↗︎ (from ~2.4.0
, in dependencies
)8206b268d
, a118c307a
, a3309e63e
]:
8206b268d
Thanks @renovate! - dependencies updates:
tslib@~2.5.0
↗︎ (from ~2.4.0
, in dependencies
)8206b268d
, 8206b268d
, a118c307a
, 6b6fe3cbc
, a3309e63e
]:
8206b268d
Thanks @renovate! - dependencies updates:
tslib@~2.5.0
↗︎ (from ~2.4.0
, in dependencies
)8206b268d
, a118c307a
, a3309e63e
]:
#8879 8206b268d
Thanks @renovate! - dependencies updates:
tslib@~2.5.0
↗︎ (from ~2.4.0
, in dependencies
)#8971 6b6fe3cbc
Thanks @n1ru4l! - Always inline referenced fragments within their document. This prevents issues with duplicated fragments or missing fragments.
Updated dependencies [8206b268d
, a118c307a
, a3309e63e
]:
8206b268d
Thanks @renovate! - dependencies updates:
tslib@~2.5.0
↗︎ (from ~2.4.0
, in dependencies
)8206b268d
, 8206b268d
, a118c307a
, 6b6fe3cbc
, a3309e63e
]:
#8879 8206b268d
Thanks @renovate! - dependencies updates:
tslib@~2.5.0
↗︎ (from ~2.4.0
, in dependencies
)#8995 fe2e9c7a5
Thanks @charpeni! - Use gqlTagName
for generated examples
Updated dependencies [8206b268d
, 8206b268d
, a118c307a
, 6b6fe3cbc
, a3309e63e
]:
8206b268d
Thanks @renovate! - dependencies updates:
tslib@~2.5.0
↗︎ (from ~2.4.0
, in dependencies
)8206b268d
, 8206b268d
, 8206b268d
, a118c307a
, 6b6fe3cbc
, a3309e63e
]:
#8879 8206b268d
Thanks @renovate! - dependencies updates:
tslib@~2.5.0
↗︎ (from ~2.4.0
, in dependencies
)#8971 6b6fe3cbc
Thanks @n1ru4l! - Allow passing fragment documents to APIs like Apollos readFragment
Updated dependencies [8206b268d
, 8206b268d
, a118c307a
, 6b6fe3cbc
, a3309e63e
]:
8206b268d
Thanks @renovate! - dependencies updates:
tslib@~2.5.0
↗︎ (from ~2.4.0
, in dependencies
)8206b268d
, 8206b268d
, 8206b268d
, a118c307a
, 6b6fe3cbc
, a3309e63e
]:
8206b268d
Thanks @renovate! - dependencies updates:
tslib@~2.5.0
↗︎ (from ~2.4.0
, in dependencies
)8206b268d
, a118c307a
, a3309e63e
]:
321d5112e
, fd0b0c813
]:
#8883 321d5112e
Thanks @Solo-steven! - Fix PluckConfig overwrite problem.
Updated dependencies [fc79b65d4
, fd0b0c813
]:
Updated dependencies [fc79b65d4
, fd0b0c813
]:
fc79b65d4
, fd0b0c813
]:
fc79b65d4
, fd0b0c813
]:
fc79b65d4
, fd0b0c813
]:
fc79b65d4
, fd0b0c813
]:
fc79b65d4
, fd0b0c813
]:
Updated dependencies [fc79b65d4
, fd0b0c813
]:
fc79b65d4
, fd0b0c813
]:
fc79b65d4
, fd0b0c813
]:
fc79b65d4
, fd0b0c813
]:
Updated dependencies [fc79b65d4
, fd0b0c813
]:
fc79b65d4
, fd0b0c813
]:
fc79b65d4
, fd0b0c813
]:
#8885 fd0b0c813
Thanks @n1ru4l! - dependencies updates:
@babel/helper-plugin-utils@^7.20.2
↗︎ (from ^7.14.5
, in dependencies
)@babel/template@^7.20.7
↗︎ (from ^7.15.4
, in dependencies
)Updated dependencies [fc79b65d4
, fd0b0c813
]:
Updated dependencies [fc79b65d4
, fd0b0c813
]:
Updated dependencies [fc79b65d4
, fd0b0c813
]:
fc79b65d4
, fd0b0c813
]:
4fa0a566e
Thanks @renovate! - dependencies updates:
[email protected]
↗︎ (from 13.2.9
, in dependencies
)e4d073b16
, 884d25c4e
, e4d073b16
]:
#8865 e4d073b16
Thanks @n1ru4l! - dependencies updates:
@graphql-codegen/core@^2.6.8
↗︎ (from 2.6.8
, in dependencies
)@graphql-tools/load@^7.8.0
↗︎ (from 7.8.0
, in dependencies
)cosmiconfig-typescript-loader@^4.3.0
↗︎ (from 4.3.0
, in dependencies
)graphql-config@^4.4.0
↗︎ (from 4.4.0
, in dependencies
)ts-node@^10.9.1
↗︎ (to dependencies
)ts-node@>=10
↗︎ (from peerDependencies
)#8865 e4d073b16
Thanks @n1ru4l! - move ts-node from peer dependencies to dependencies
a98198524
Thanks @charle692! - Fix issue where visitor-plugin-common emitted ESM imports for Operations when emitLegacyCommonJSImports is truea98198524
]:
a98198524
]:
a98198524
]:
a98198524
]:
a98198524
]:
a98198524
]:
#8757 4f290aa72
Thanks @n1ru4l! - Add support for persisted documents.
You can now generate and embed a persisted documents hash for the executable documents.
/** codegen.ts */
import { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = {
schema: 'https://swapi-graphql.netlify.app/.netlify/functions/index',
documents: ['src/**/*.tsx'],
ignoreNoDocuments: true, // for better experience with the watcher
generates: {
'./src/gql/': {
preset: 'client',
plugins: [],
presetConfig: {
persistedDocuments: true,
},
},
},
};
export default config;
This will generate ./src/gql/persisted-documents.json
(dictionary of hashes with their operation string).
In addition to that each generated document node will have a __meta__.hash
property.
import { gql } from './gql.js';
const allFilmsWithVariablesQueryDocument = graphql(/* GraphQL */ `
query allFilmsWithVariablesQuery($first: Int!) {
allFilms(first: $first) {
edges {
node {
...FilmItem
}
}
}
}
`);
console.log((allFilmsWithVariablesQueryDocument as any)['__meta__']['hash']);
#8757 4f290aa72
Thanks @n1ru4l! - Add support for embedding metadata in the document AST.
It is now possible to embed metadata (e.g. for your GraphQL client within the emitted code).
/** codegen.ts */
import { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = {
schema: 'https://swapi-graphql.netlify.app/.netlify/functions/index',
documents: ['src/**/*.tsx'],
ignoreNoDocuments: true, // for better experience with the watcher
generates: {
'./src/gql/': {
preset: 'client',
plugins: [],
presetConfig: {
onExecutableDocumentNode(documentNode) {
return {
operation: documentNode.definitions[0].operation,
name: documentNode.definitions[0].name.value,
};
},
},
},
},
};
export default config;
You can then access the metadata via the __meta__
property on the document node.
import { gql } from './gql.js';
const allFilmsWithVariablesQueryDocument = graphql(/* GraphQL */ `
query allFilmsWithVariablesQuery($first: Int!) {
allFilms(first: $first) {
edges {
node {
...FilmItem
}
}
}
}
`);
console.log((allFilmsWithVariablesQueryDocument as any)['__meta__']);
4f290aa72
Thanks @n1ru4l! - dependencies updates:
@graphql-tools/documents@^0.1.0
↗︎ (to dependencies
)a98198524
]:
a98198524
]:
4774247e9
, fe12b4826
]:
#8770 4774247e9
Thanks @renovate! - dependencies updates:
[email protected]
↗︎ (from 4.3.6
, in dependencies
)#8790 fe12b4826
Thanks @renovate! - dependencies updates:
@whatwg-node/fetch@^0.6.0
↗︎ (from ^0.5.0
, in dependencies
)902451601
Thanks @shmax! - remove extra asterisk and add missing semicolon in generated output#8796 902451601
Thanks @shmax! - remove extra asterisk and add missing semicolon in generated output
Updated dependencies [902451601
]:
#8796 902451601
Thanks @shmax! - remove extra asterisk and add missing semicolon in generated output
Updated dependencies [902451601
]:
ad5d83313
]:
ad5d83313
Thanks @louisscruz! - add ts-node as a peerDependencyeb454d06c
]:
2a33fc774
Thanks @ElvisUpUp! - change the client-preset generated templateeb454d06c
]:
eb454d06c
]:
eb454d06c
]:
eb454d06c
]:
eb454d06c
]:
eb454d06c
, 2a33fc774
]:
eb454d06c
]: