Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/codegenscalartype-input-output.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@graphql-codegen/visitor-plugin-common': minor
---

Support an object form for the `codegenScalarType` scalar extension.

A scalar's `extensions.codegenScalarType` can now be either a string (applied to both the `input` and `output` types, as before) or `{ input, output }` to map the two positions independently — matching what the `scalars` config option already accepts. This lets schema-first scalar libraries declare a stricter parsed/input type than the accepted resolver-return/output type directly from the schema, instead of collapsing both into one type.
7 changes: 5 additions & 2 deletions packages/plugins/other/visitor-plugin-common/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -366,14 +366,17 @@ export function buildScalars(
};
}
} else if (scalarType.extensions?.codegenScalarType) {
const normalizedScalar = normalizeScalarType(
scalarType.extensions.codegenScalarType as string | { input: string; output: string },
);
result[name] = {
input: {
isExternal: false,
type: scalarType.extensions.codegenScalarType as string,
type: normalizedScalar.input,
},
output: {
isExternal: false,
type: scalarType.extensions.codegenScalarType as string,
type: normalizedScalar.output,
},
};
} else if (!defaultScalarsMapping[name]) {
Expand Down
35 changes: 34 additions & 1 deletion packages/plugins/typescript/typescript/tests/typescript.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { buildSchema, GraphQLEnumType, GraphQLObjectType, GraphQLSchema, parse } from 'graphql';
import {
buildSchema,
GraphQLEnumType,
GraphQLObjectType,
GraphQLScalarType,
GraphQLSchema,
parse,
} from 'graphql';
import { mergeOutputs, Types } from '@graphql-codegen/plugin-helpers';
import { validateTs } from '@graphql-codegen/testing';
import { plugin } from '../src/index.js';
Expand All @@ -12,6 +19,32 @@ describe('TypeScript', () => {
expect(result.prepend).toBeSimilarStringTo('export type Maybe<T> =');
});

describe('codegenScalarType extension', () => {
const schemaWithScalarExtension = (codegenScalarType: unknown) =>
new GraphQLSchema({
query: new GraphQLObjectType({
name: 'Query',
fields: {
a: {
type: new GraphQLScalarType({ name: 'MyScalar', extensions: { codegenScalarType } }),
},
},
}),
});

it('maps a string codegenScalarType to both input and output', async () => {
const schema = schemaWithScalarExtension('MyType');
const result = await plugin(schema, [], {}, { outputFile: '' });
expect(result.content).toBeSimilarStringTo(`MyScalar: { input: MyType; output: MyType; }`);
});

it('maps an object codegenScalarType to distinct input and output', async () => {
const schema = schemaWithScalarExtension({ input: 'MyInput', output: 'MyOutput' });
const result = await plugin(schema, [], {}, { outputFile: '' });
expect(result.content).toBeSimilarStringTo(`MyScalar: { input: MyInput; output: MyOutput; }`);
});
});

describe('description to comment', () => {
it('Should include a description for Scalars type', async () => {
const schema = buildSchema(/* GraphQL */ `
Expand Down