Skip to content

rename serialize and parseValue methods #4241

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 17, 2024
Merged
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
4 changes: 2 additions & 2 deletions integrationTests/ts/kitchenSink-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { Kind } from 'graphql/language';
// Test subset of public APIs with "exactOptionalPropertyTypes" flag enabled
new GraphQLScalarType({
name: 'SomeScalar',
serialize: undefined,
parseValue: undefined,
coerceOutputValue: undefined,
coerceInputValue: undefined,
coerceInputLiteral: undefined,
});

Expand Down
6 changes: 3 additions & 3 deletions src/execution/__tests__/executor-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1258,10 +1258,10 @@ describe('Execute: Handles basic execution tasks', () => {
expect(asyncResult).to.deep.equal(result);
});

it('fails when serialize of custom scalar does not return a value', () => {
it('fails when coerceOutputValue of custom scalar does not return a value', () => {
const customScalar = new GraphQLScalarType({
name: 'CustomScalar',
serialize() {
coerceOutputValue() {
/* returns nothing */
},
});
Expand All @@ -1283,7 +1283,7 @@ describe('Execute: Handles basic execution tasks', () => {
errors: [
{
message:
'Expected `CustomScalar.serialize("CUSTOM_VALUE")` to return non-nullable value, returned: undefined',
'Expected `CustomScalar.coerceOutputValue("CUSTOM_VALUE")` to return non-nullable value, returned: undefined',
locations: [{ line: 1, column: 3 }],
path: ['customScalar'],
},
Expand Down
24 changes: 12 additions & 12 deletions src/execution/__tests__/variables-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const TestFaultyScalarGraphQLError = new GraphQLError(

const TestFaultyScalar = new GraphQLScalarType({
name: 'FaultyScalar',
parseValue() {
coerceInputValue() {
throw TestFaultyScalarGraphQLError;
},
coerceInputLiteral() {
Expand All @@ -54,13 +54,13 @@ const TestFaultyScalar = new GraphQLScalarType({

const TestComplexScalar = new GraphQLScalarType({
name: 'ComplexScalar',
parseValue(value) {
expect(value).to.equal('SerializedValue');
return 'DeserializedValue';
coerceInputValue(value) {
expect(value).to.equal('ExternalValue');
return 'InternalValue';
},
coerceInputLiteral(ast) {
expect(ast).to.include({ kind: 'StringValue', value: 'SerializedValue' });
return 'DeserializedValue';
expect(ast).to.include({ kind: 'StringValue', value: 'ExternalValue' });
return 'InternalValue';
},
});

Expand Down Expand Up @@ -284,13 +284,13 @@ describe('Execute: Handles inputs', () => {
it('properly runs coerceInputLiteral on complex scalar types', () => {
const result = executeQuery(`
{
fieldWithObjectInput(input: {c: "foo", d: "SerializedValue"})
fieldWithObjectInput(input: {c: "foo", d: "ExternalValue"})
}
`);

expect(result).to.deep.equal({
data: {
fieldWithObjectInput: '{ c: "foo", d: "DeserializedValue" }',
fieldWithObjectInput: '{ c: "foo", d: "InternalValue" }',
},
});
});
Expand Down Expand Up @@ -447,25 +447,25 @@ describe('Execute: Handles inputs', () => {
});

it('executes with complex scalar input', () => {
const params = { input: { c: 'foo', d: 'SerializedValue' } };
const params = { input: { c: 'foo', d: 'ExternalValue' } };
const result = executeQuery(doc, params);

expect(result).to.deep.equal({
data: {
fieldWithObjectInput: '{ c: "foo", d: "DeserializedValue" }',
fieldWithObjectInput: '{ c: "foo", d: "InternalValue" }',
},
});
});

it('errors on faulty scalar type input', () => {
const params = { input: { c: 'foo', e: 'SerializedValue' } };
const params = { input: { c: 'foo', e: 'ExternalValue' } };
const result = executeQuery(doc, params);

expectJSON(result).toDeepEqual({
errors: [
{
message:
'Variable "$input" got invalid value "SerializedValue" at "input.e"; FaultyScalarErrorMessage',
'Variable "$input" got invalid value "ExternalValue" at "input.e"; FaultyScalarErrorMessage',
locations: [{ line: 2, column: 16 }],
extensions: { code: 'FaultyScalarErrorExtensionCode' },
},
Expand Down
18 changes: 9 additions & 9 deletions src/execution/execute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,7 @@ function toNodes(fieldDetailsList: FieldDetailsList): ReadonlyArray<FieldNode> {
* Implements the "Executing fields" section of the spec
* In particular, this function figures out the value that the field returns by
* calling its resolve function, then calls completeValue to complete promises,
* serialize scalars, or execute the sub-selection-set for objects.
* coercing scalars, or execute the sub-selection-set for objects.
*/
function executeField(
exeContext: ExecutionContext,
Expand Down Expand Up @@ -937,7 +937,7 @@ function handleFieldError(
* for the inner type on each item in the list.
*
* If the field type is a Scalar or Enum, ensures the completed value is a legal
* value of the type by calling the `serialize` method of GraphQL type
* value of the type by calling the `coerceOutputValue` method of GraphQL type
* definition.
*
* If the field is an abstract type, determine the runtime type of the value
Expand Down Expand Up @@ -1001,8 +1001,8 @@ function completeValue(
);
}

// If field type is a leaf type, Scalar or Enum, serialize to a valid value,
// returning null if serialization is not possible.
// If field type is a leaf type, Scalar or Enum, coerce to a valid value,
// returning null if coercion is not possible.
if (isLeafType(returnType)) {
return [completeLeafValue(returnType, result), undefined];
}
Expand Down Expand Up @@ -1571,14 +1571,14 @@ function completeLeafValue(
returnType: GraphQLLeafType,
result: unknown,
): unknown {
const serializedResult = returnType.serialize(result);
if (serializedResult == null) {
const coerced = returnType.coerceOutputValue(result);
if (coerced == null) {
throw new Error(
`Expected \`${inspect(returnType)}.serialize(${inspect(result)})\` to ` +
`return non-nullable value, returned: ${inspect(serializedResult)}`,
`Expected \`${inspect(returnType)}.coerceOutputValue(${inspect(result)})\` to ` +
`return non-nullable value, returned: ${inspect(coerced)}`,
);
}
return serializedResult;
return coerced;
}

/**
Expand Down
3 changes: 2 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,9 @@ export type {
GraphQLUnionTypeExtensions,
GraphQLScalarSerializer,
GraphQLScalarValueParser,
/* @deprecated in favor of GraphQLScalarInputLiteralCoercer, will be removed in v18 */
GraphQLScalarLiteralParser,
GraphQLScalarOutputValueCoercer,
GraphQLScalarInputValueCoercer,
GraphQLScalarInputLiteralCoercer,
GraphQLDefaultValueUsage,
} from './type/index.js';
Expand Down
36 changes: 34 additions & 2 deletions src/type/__tests__/definition-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ describe('Type System: Scalars', () => {
serialize: someScalar.serialize,
parseValue: someScalar.parseValue,
parseLiteral: someScalar.parseLiteral,
coerceOutputValue: someScalar.coerceOutputValue,
coerceInputValue: someScalar.coerceInputValue,
coerceInputLiteral: undefined,
valueToLiteral: undefined,
extensions: {},
Expand All @@ -76,6 +78,8 @@ describe('Type System: Scalars', () => {
serialize: passThroughFunc,
parseValue: passThroughFunc,
parseLiteral: passThroughFunc,
coerceOutputValue: passThroughFunc,
coerceInputValue: passThroughFunc,
coerceInputLiteral: passThroughFunc,
valueToLiteral: passThroughFunc,
extensions: { someExtension: 'extension' },
Expand All @@ -95,6 +99,8 @@ describe('Type System: Scalars', () => {
serialize: passThroughFunc,
parseValue: passThroughFunc,
parseLiteral: passThroughFunc,
coerceOutputValue: passThroughFunc,
coerceInputValue: passThroughFunc,
coerceInputLiteral: passThroughFunc,
valueToLiteral: passThroughFunc,
extensions: { [test]: 'extension' },
Expand All @@ -110,6 +116,8 @@ describe('Type System: Scalars', () => {

expect(scalar.serialize).to.equal(identityFunc);
expect(scalar.parseValue).to.equal(identityFunc);
expect(scalar.coerceOutputValue).to.equal(identityFunc);
expect(scalar.coerceInputValue).to.equal(identityFunc);
expect(scalar.parseLiteral).to.be.a('function');
/* default will be provided in v18 when parseLiteral is removed */
// expect(scalar.coerceInputLiteral).to.be.a('function');
Expand Down Expand Up @@ -143,15 +151,15 @@ describe('Type System: Scalars', () => {
);
});

it('rejects a Scalar type defining coerceInputLiteral but not parseValue', () => {
it('rejects a Scalar type defining coerceInputLiteral but not coerceInputValue', () => {
expect(
() =>
new GraphQLScalarType({
name: 'SomeScalar',
coerceInputLiteral: passThroughFunc,
}),
).to.throw(
'SomeScalar must provide both "parseValue" and "coerceInputLiteral" functions.',
'SomeScalar must provide both "coerceInputValue" and "coerceInputLiteral" functions.',
);
});
});
Expand Down Expand Up @@ -644,6 +652,30 @@ describe('Type System: Enums', () => {
expect(someEnum.toConfig()).to.deep.equal(someEnumConfig);
});

it('can be coerced to an output value via serialize() method', () => {
const someEnum = new GraphQLEnumType({
name: 'SomeEnum',
values: {
FOO: {
value: 'foo',
},
},
});
expect(someEnum.serialize('foo')).to.equal('FOO');
});

it('can be coerced to an input value via parseValue() method', () => {
const someEnum = new GraphQLEnumType({
name: 'SomeEnum',
values: {
FOO: {
value: 'foo',
},
},
});
expect(someEnum.parseValue('FOO')).to.equal('foo');
});

it('defines an enum type with deprecated value', () => {
const EnumTypeWithDeprecatedValue = new GraphQLEnumType({
name: 'EnumWithDeprecatedValue',
Expand Down
Loading
Loading