Skip to content

Commit

Permalink
backport[v16]: Enable passing values configuration to GraphQLEnumType…
Browse files Browse the repository at this point in the history
… as a thunk (#4122)
  • Loading branch information
benjie authored Jun 21, 2024
1 parent 29144f7 commit 6a1614c
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 9 deletions.
25 changes: 25 additions & 0 deletions src/type/__tests__/enumType-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ const ComplexEnum = new GraphQLEnumType({
},
});

const ThunkValuesEnum = new GraphQLEnumType({
name: 'ThunkValues',
values: () => ({
A: { value: 'a' },
B: { value: 'b' },
}),
});

const QueryType = new GraphQLObjectType({
name: 'Query',
fields: {
Expand Down Expand Up @@ -84,6 +92,15 @@ const QueryType = new GraphQLObjectType({
return fromEnum;
},
},
thunkValuesString: {
type: GraphQLString,
args: {
fromEnum: { type: ThunkValuesEnum },
},
resolve(_source, { fromEnum }) {
return fromEnum;
},
},
},
});

Expand Down Expand Up @@ -400,6 +417,14 @@ describe('Type System: Enum Values', () => {
});
});

it('may have values specified via a callback', () => {
const result = executeQuery('{ thunkValuesString(fromEnum: B) }');

expect(result).to.deep.equal({
data: { thunkValuesString: 'b' },
});
});

it('can be introspected without error', () => {
expect(() => introspectionFromSchema(schema)).to.not.throw();
});
Expand Down
34 changes: 25 additions & 9 deletions src/type/definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1372,9 +1372,12 @@ export class GraphQLEnumType /* <T> */ {
astNode: Maybe<EnumTypeDefinitionNode>;
extensionASTNodes: ReadonlyArray<EnumTypeExtensionNode>;

private _values: ReadonlyArray<GraphQLEnumValue /* <T> */>;
private _valueLookup: ReadonlyMap<any /* T */, GraphQLEnumValue>;
private _nameLookup: ObjMap<GraphQLEnumValue>;
private _values:
| ReadonlyArray<GraphQLEnumValue /* <T> */>
| (() => GraphQLEnumValueConfigMap);

private _valueLookup: ReadonlyMap<any /* T */, GraphQLEnumValue> | null;
private _nameLookup: ObjMap<GraphQLEnumValue> | null;

constructor(config: Readonly<GraphQLEnumTypeConfig /* <T> */>) {
this.name = assertName(config.name);
Expand All @@ -1383,26 +1386,38 @@ export class GraphQLEnumType /* <T> */ {
this.astNode = config.astNode;
this.extensionASTNodes = config.extensionASTNodes ?? [];

this._values = defineEnumValues(this.name, config.values);
this._valueLookup = new Map(
this._values.map((enumValue) => [enumValue.value, enumValue]),
);
this._nameLookup = keyMap(this._values, (value) => value.name);
this._values =
typeof config.values === 'function'
? config.values
: defineEnumValues(this.name, config.values);
this._valueLookup = null;
this._nameLookup = null;
}

get [Symbol.toStringTag]() {
return 'GraphQLEnumType';
}

getValues(): ReadonlyArray<GraphQLEnumValue /* <T> */> {
if (typeof this._values === 'function') {
this._values = defineEnumValues(this.name, this._values());
}
return this._values;
}

getValue(name: string): Maybe<GraphQLEnumValue> {
if (this._nameLookup === null) {
this._nameLookup = keyMap(this.getValues(), (value) => value.name);
}
return this._nameLookup[name];
}

serialize(outputValue: unknown /* T */): Maybe<string> {
if (this._valueLookup === null) {
this._valueLookup = new Map(
this.getValues().map((enumValue) => [enumValue.value, enumValue]),
);
}
const enumValue = this._valueLookup.get(outputValue);
if (enumValue === undefined) {
throw new GraphQLError(
Expand Down Expand Up @@ -1527,13 +1542,14 @@ function defineEnumValues(
export interface GraphQLEnumTypeConfig {
name: string;
description?: Maybe<string>;
values: GraphQLEnumValueConfigMap /* <T> */;
values: ThunkObjMap<GraphQLEnumValueConfig /* <T> */>;
extensions?: Maybe<Readonly<GraphQLEnumTypeExtensions>>;
astNode?: Maybe<EnumTypeDefinitionNode>;
extensionASTNodes?: Maybe<ReadonlyArray<EnumTypeExtensionNode>>;
}

interface GraphQLEnumTypeNormalizedConfig extends GraphQLEnumTypeConfig {
values: ObjMap<GraphQLEnumValueConfig /* <T> */>;
extensions: Readonly<GraphQLEnumTypeExtensions>;
extensionASTNodes: ReadonlyArray<EnumTypeExtensionNode>;
}
Expand Down

0 comments on commit 6a1614c

Please sign in to comment.