Skip to content

Commit 480613c

Browse files
committed
introduce internal getVariableSignature utility
extracted from my fragment arguments scratch branch
1 parent 5c7d4d1 commit 480613c

File tree

2 files changed

+77
-16
lines changed

2 files changed

+77
-16
lines changed

src/execution/values.ts

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ import { Kind } from '../language/kinds.js';
1414
import { print } from '../language/printer.js';
1515

1616
import type { GraphQLField } from '../type/definition.js';
17-
import { isInputType, isNonNullType } from '../type/definition.js';
17+
import { isNonNullType } from '../type/definition.js';
1818
import type { GraphQLDirective } from '../type/directives.js';
1919
import type { GraphQLSchema } from '../type/schema.js';
2020

2121
import { coerceInputValue } from '../utilities/coerceInputValue.js';
22-
import { typeFromAST } from '../utilities/typeFromAST.js';
22+
import { getVariableSignature } from '../utilities/getVariableSignature.js';
2323
import { valueFromAST } from '../utilities/valueFromAST.js';
2424

2525
type CoercedVariableValues =
@@ -76,24 +76,16 @@ function coerceVariableValues(
7676
): { [variable: string]: unknown } {
7777
const coercedValues: { [variable: string]: unknown } = {};
7878
for (const varDefNode of varDefNodes) {
79-
const varName = varDefNode.variable.name.value;
80-
const varType = typeFromAST(schema, varDefNode.type);
81-
if (!isInputType(varType)) {
82-
// Must use input types for variables. This should be caught during
83-
// validation, however is checked again here for safety.
84-
const varTypeStr = print(varDefNode.type);
85-
onError(
86-
new GraphQLError(
87-
`Variable "$${varName}" expected value of type "${varTypeStr}" which cannot be used as an input type.`,
88-
{ nodes: varDefNode.type },
89-
),
90-
);
79+
const varSignature = getVariableSignature(schema, varDefNode);
80+
if (varSignature instanceof GraphQLError) {
81+
onError(varSignature);
9182
continue;
9283
}
9384

85+
const { name: varName, type: varType } = varSignature;
9486
if (!Object.hasOwn(inputs, varName)) {
95-
if (varDefNode.defaultValue) {
96-
coercedValues[varName] = valueFromAST(varDefNode.defaultValue, varType);
87+
if (varSignature.hasDefaultValue) {
88+
coercedValues[varName] = varSignature.getDefaultValue();
9789
} else if (isNonNullType(varType)) {
9890
const varTypeStr = inspect(varType);
9991
onError(

src/utilities/getVariableSignature.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { GraphQLError } from '../error/GraphQLError.js';
2+
3+
import { print } from '../language/printer.js';
4+
5+
import type { GraphQLInputType, GraphQLSchema } from '../type/index.js';
6+
import { isInputType } from '../type/index.js';
7+
8+
import type { ConstValueNode, VariableDefinitionNode } from '../index.js';
9+
10+
import { typeFromAST } from './typeFromAST.js';
11+
import { valueFromAST } from './valueFromAST.js';
12+
13+
/**
14+
* A GraphQLVariableSignature is required to coerce a variable value.
15+
*
16+
* @internal
17+
* */
18+
export class GraphQLVariableSignature {
19+
name: string;
20+
type: GraphQLInputType;
21+
hasDefaultValue: boolean;
22+
_defaultValue: unknown;
23+
24+
constructor(
25+
name: string,
26+
type: GraphQLInputType,
27+
defaultValueNode: ConstValueNode | undefined,
28+
) {
29+
this.name = name;
30+
this.type = type;
31+
if (defaultValueNode) {
32+
this.hasDefaultValue = true;
33+
this._defaultValue = () => valueFromAST(defaultValueNode, type);
34+
} else {
35+
this.hasDefaultValue = false;
36+
}
37+
}
38+
39+
getDefaultValue(): unknown {
40+
if (typeof this._defaultValue === 'function') {
41+
this._defaultValue = this._defaultValue();
42+
}
43+
return this._defaultValue;
44+
}
45+
}
46+
47+
export function getVariableSignature(
48+
schema: GraphQLSchema,
49+
varDefNode: VariableDefinitionNode,
50+
): GraphQLVariableSignature | GraphQLError {
51+
const varName = varDefNode.variable.name.value;
52+
const varType = typeFromAST(schema, varDefNode.type);
53+
54+
if (!isInputType(varType)) {
55+
// Must use input types for variables. This should be caught during
56+
// validation, however is checked again here for safety.
57+
const varTypeStr = print(varDefNode.type);
58+
return new GraphQLError(
59+
`Variable "$${varName}" expected value of type "${varTypeStr}" which cannot be used as an input type.`,
60+
{ nodes: varDefNode.type },
61+
);
62+
}
63+
64+
return new GraphQLVariableSignature(
65+
varName,
66+
varType,
67+
varDefNode.defaultValue,
68+
);
69+
}

0 commit comments

Comments
 (0)