Description
In graphql-compose-connection I use Enum type
for storing avaliable sortings for connections, so values represent complex objects with function, eg:
var ConnectionSortUserEnum = new GraphQLEnumType({
name: 'ConnectionSortUserEnum',
values: {
AGE_ID_DESC: {
uniqueFields: ['age', '_id'],
sortValue: { age: -1, _id: 1 },
directionFilter: (cursorData, filter, isBefore) => {
// some code for extending filter with data obtained from `before` or `after` cursors
return filter;
},
},
...someOtherSorts
}
});
With such Enum
graphql server starts and works perfectly (example).
But throws error when I try to build introspection graphql(Schema, introspectionQuery)
or run printSchema(Schema)
:
[11:33:10] Starting 'buildSchema'...
ERROR introspecting schema: [
{
"path": [
"__schema",
"types",
1,
"fields",
21,
"args",
5,
"defaultValue"
],
"originalError": {}
}
]
Error
at invariant (invariant.js:19:11)
at astFromValue (astFromValue.js:112:3)
at astFromValue.js:123:22
at Array.forEach (native)
at astFromValue (astFromValue.js:117:23)
at printInputValue (schemaPrinter.js:180:44)
at Array.map (native)
at printArgs (schemaPrinter.js:174:39)
at schemaPrinter.js:155:28
at Array.map (native)
at printFields (schemaPrinter.js:154:17)
at printObject (schemaPrinter.js:121:65)
at printType (schemaPrinter.js:100:12)
at Array.map (native)
at printFilteredSchema (schemaPrinter.js:72:87)
at printSchema (schemaPrinter.js:37:10)
According to astFromValue.js#L116 it accepts only string
values for Enums
:
// JavaScript strings can be Enum values or String values. Use the
// GraphQLType to differentiate if possible.
if (typeof _value === 'string') {
if (type instanceof GraphQLEnumType &&
/^[_a-zA-Z][_a-zA-Z0-9]*$/.test(_value)) {
return ({ kind: ENUM, value: _value }: EnumValue);
}
// Use JSON stringify, which uses the same string encoding as GraphQL,
// then remove the quotes.
return ({
kind: STRING,
value: JSON.stringify(_value).slice(1, -1)
}: StringValue);
}
- But in graphql specification https://facebook.github.io/graphql/#sec-Enums I did not found explicit requirement that enum value must be
string
. - Also in
flow-type
definitions value hasany
type:
export type GraphQLEnumValueConfig/* <T> */ = {
value?: any/* T */;
deprecationReason?: ?string;
description?: ?string;
}
So, according to concept of Enum ...
- client gets only
names
from enum - enum values can be defined only on server (and client does not know anything about internal enum value)
... I think, that if developer define complex value for enum, so it expects that get it in args
for resolve
function. And astFromValue
should not deeply extract AST for enum's value
it should stops on enum's name
.
I don't know enough FB internals requirements for ENUMs, so can not provide correct PR for this problem. @leebyron please consider this issue, as soon as possible, because it blocking me.
PS. Passing to enum's value arrow functions, provides for me awesome ability to customise logic in resolve
methods - https://github.com/nodkz/graphql-compose-connection/blob/master/src/resolvers/connectionResolver.js#L207