123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462 |
- local path = (...):gsub('%.[^%.]+$', '')
- local types = require(path .. '.types')
- local util = require(path .. '.util')
- local __Schema, __Directive, __DirectiveLocation, __Type, __Field, __InputValue,__EnumValue, __TypeKind
- local function resolveArgs(field)
- local function transformArg(arg, name)
- if arg.__type then
- return { kind = arg, name = name }
- elseif arg.name then
- return arg
- else
- local result = { name = name }
- for k, v in pairs(arg) do
- result[k] = v
- end
- return result
- end
- end
- return util.values(util.map(field.arguments or {}, transformArg))
- end
- __Schema = types.object({
- name = '__Schema',
- description = util.trim [[
- A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all available types
- and directives on the server, as well as the entry points for query and mutation operations.
- ]],
- fields = function()
- return {
- types = {
- description = 'A list of all types supported by this server.',
- kind = types.nonNull(types.list(types.nonNull(__Type))),
- resolve = function(schema)
- return util.values(schema:getTypeMap())
- end
- },
- queryType = {
- description = 'The type that query operations will be rooted at.',
- kind = __Type.nonNull,
- resolve = function(schema)
- return schema:getQueryType()
- end
- },
- mutationType = {
- description = 'If this server supports mutation, the type that mutation operations will be rooted at.',
- kind = __Type,
- resolve = function(schema)
- return schema:getMutationType()
- end
- },
- directives = {
- description = 'A list of all directives supported by this server.',
- kind = types.nonNull(types.list(types.nonNull(__Directive))),
- resolve = function(schema)
- return schema.directives
- end
- },
- subscriptionType = {
- description = 'If this server supports subscriptions, the type that subscription operations will be rooted at.',
- kind = __Type,
- resolve = function(schema)
- return schema:getSubscriptionType()
- end
- }
- }
- end
- })
- __Directive = types.object({
- name = '__Directive',
- description = util.trim [[
- A Directive provides a way to describe alternate runtime execution and type validation behavior
- in a GraphQL document.
- In some cases, you need to provide options to alter GraphQL’s execution
- behavior in ways field arguments will not suffice, such as conditionally including or skipping a
- field. Directives provide this by describing additional information to the executor.
- ]],
- fields = function()
- return {
- name = types.nonNull(types.string),
- description = types.string,
- locations = {
- kind = types.nonNull(types.list(types.nonNull(
- __DirectiveLocation
- ))),
- resolve = function(directive)
- local res = {}
- if directive.onQuery then table.insert(res, 'QUERY') end
- if directive.onMutation then table.insert(res, 'MUTATION') end
- if directive.onField then table.insert(res, 'FIELD') end
- if directive.onFragmentDefinition then table.insert(res, 'FRAGMENT_DEFINITION') end
- if directive.onFragmentSpread then table.insert(res, 'FRAGMENT_SPREAD') end
- if directive.onInlineFragment then table.insert(res, 'INLINE_FRAGMENT') end
- return res
- end
- },
- args = {
- kind = types.nonNull(types.list(types.nonNull(__InputValue))),
- resolve = resolveArgs
- }
- }
- end
- })
- __DirectiveLocation = types.enum({
- name = '__DirectiveLocation',
- description = util.trim [[
- A Directive can be adjacent to many parts of the GraphQL language, a __DirectiveLocation
- describes one such possible adjacencies.
- ]],
- values = {
- QUERY = {
- value = 'QUERY',
- description = 'Location adjacent to a query operation.'
- },
- MUTATION = {
- value = 'MUTATION',
- description = 'Location adjacent to a mutation operation.'
- },
- FIELD = {
- value = 'FIELD',
- description = 'Location adjacent to a field.'
- },
- FRAGMENT_DEFINITION = {
- value = 'FRAGMENT_DEFINITION',
- description = 'Location adjacent to a fragment definition.'
- },
- FRAGMENT_SPREAD = {
- value = 'FRAGMENT_SPREAD',
- description = 'Location adjacent to a fragment spread.'
- },
- INLINE_FRAGMENT = {
- value = 'INLINE_FRAGMENT',
- description = 'Location adjacent to an inline fragment.'
- }
- }
- })
- __Type = types.object({
- name = '__Type',
- description = util.trim [[
- The fundamental unit of any GraphQL Schema is the type. There are
- many kinds of types in GraphQL as represented by the `__TypeKind` enum.
- Depending on the kind of a type, certain fields describe
- information about that type. Scalar types provide no information
- beyond a name and description, while Enum types provide their values.
- Object and Interface types provide the fields they describe. Abstract
- types, Union and Interface, provide the Object types possible
- at runtime. List and NonNull types compose other types.
- ]],
- fields = function()
- return {
- name = types.string,
- description = types.string,
- kind = {
- kind = __TypeKind.nonNull,
- resolve = function(kind)
- if kind.__type == 'Scalar' then
- return 'SCALAR'
- elseif kind.__type == 'Object' then
- return 'OBJECT'
- elseif kind.__type == 'Interface' then
- return 'INTERFACE'
- elseif kind.__type == 'Union' then
- return 'UNION'
- elseif kind.__type == 'Enum' then
- return 'ENUM'
- elseif kind.__type == 'InputObject' then
- return 'INPUT_OBJECT'
- elseif kind.__type == 'List' then
- return 'LIST'
- elseif kind.__type == 'NonNull' then
- return 'NON_NULL'
- end
- error('Unknown type ' .. kind)
- end
- },
- fields = {
- kind = types.list(types.nonNull(__Field)),
- arguments = {
- includeDeprecated = {
- kind = types.boolean,
- defaultValue = false
- }
- },
- resolve = function(kind, arguments)
- if kind.__type == 'Object' or kind.__type == 'Interface' then
- return util.filter(util.values(kind.fields), function(field)
- return arguments.includeDeprecated or field.deprecationReason == nil
- end)
- end
- return nil
- end
- },
- interfaces = {
- kind = types.list(types.nonNull(__Type)),
- resolve = function(kind)
- if kind.__type == 'Object' then
- return kind.interfaces
- end
- end
- },
- possibleTypes = {
- kind = types.list(types.nonNull(__Type)),
- resolve = function(kind, arguments, context)
- if kind.__type == 'Interface' or kind.__type == 'Union' then
- return context.schema:getPossibleTypes(kind)
- end
- end
- },
- enumValues = {
- kind = types.list(types.nonNull(__EnumValue)),
- arguments = {
- includeDeprecated = { kind = types.boolean, defaultValue = false }
- },
- resolve = function(kind, arguments)
- if kind.__type == 'Enum' then
- return util.filter(util.values(kind.values), function(value)
- return arguments.includeDeprecated or not value.deprecationReason
- end)
- end
- end
- },
- inputFields = {
- kind = types.list(types.nonNull(__InputValue)),
- resolve = function(kind)
- if kind.__type == 'InputObject' then
- return util.values(kind.fields)
- end
- end
- },
- ofType = {
- kind = __Type
- }
- }
- end
- })
- __Field = types.object({
- name = '__Field',
- description = util.trim [[
- Object and Interface types are described by a list of Fields, each of
- which has a name, potentially a list of arguments, and a return type.
- ]],
- fields = function()
- return {
- name = types.string.nonNull,
- description = types.string,
- args = {
- kind = types.nonNull(types.list(types.nonNull(__InputValue))),
- resolve = resolveArgs
- },
- type = {
- kind = __Type.nonNull,
- resolve = function(field)
- return field.kind
- end
- },
- isDeprecated = {
- kind = types.boolean.nonNull,
- resolve = function(field)
- return field.deprecationReason ~= nil
- end
- },
- deprecationReason = types.string
- }
- end
- })
- __InputValue = types.object({
- name = '__InputValue',
- description = util.trim [[
- Arguments provided to Fields or Directives and the input fields of an
- InputObject are represented as Input Values which describe their type
- and optionally a default value.
- ]],
- fields = function()
- return {
- name = types.string.nonNull,
- description = types.string,
- type = {
- kind = types.nonNull(__Type),
- resolve = function(field)
- return field.kind
- end
- },
- defaultValue = {
- kind = types.string,
- description = 'A GraphQL-formatted string representing the default value for this input value.',
- resolve = function(inputVal)
- return inputVal.defaultValue and tostring(inputVal.defaultValue) -- TODO improve serialization a lot
- end
- }
- }
- end
- })
- __EnumValue = types.object({
- name = '__EnumValue',
- description = util.trim [[
- One possible value for a given Enum. Enum values are unique values, not
- a placeholder for a string or numeric value. However an Enum value is
- returned in a JSON response as a string.
- ]],
- fields = function()
- return {
- name = types.string.nonNull,
- description = types.string,
- isDeprecated = {
- kind = types.boolean.nonNull,
- resolve = function(enumValue) return enumValue.deprecationReason ~= nil end
- },
- deprecationReason = types.string
- }
- end
- })
- __TypeKind = types.enum({
- name = '__TypeKind',
- description = 'An enum describing what kind of type a given `__Type` is.',
- values = {
- SCALAR = {
- value = 'SCALAR',
- description = 'Indicates this type is a scalar.'
- },
- OBJECT = {
- value = 'OBJECT',
- description = 'Indicates this type is an object. `fields` and `interfaces` are valid fields.'
- },
- INTERFACE = {
- value = 'INTERFACE',
- description = 'Indicates this type is an interface. `fields` and `possibleTypes` are valid fields.'
- },
- UNION = {
- value = 'UNION',
- description = 'Indicates this type is a union. `possibleTypes` is a valid field.'
- },
- ENUM = {
- value = 'ENUM',
- description = 'Indicates this type is an enum. `enumValues` is a valid field.'
- },
- INPUT_OBJECT = {
- value = 'INPUT_OBJECT',
- description = 'Indicates this type is an input object. `inputFields` is a valid field.'
- },
- LIST = {
- value = 'LIST',
- description = 'Indicates this type is a list. `ofType` is a valid field.'
- },
- NON_NULL = {
- value = 'NON_NULL',
- description = 'Indicates this type is a non-null. `ofType` is a valid field.'
- }
- }
- })
- local Schema = {
- name = '__schema',
- kind = __Schema.nonNull,
- description = 'Access the current type schema of this server.',
- arguments = {},
- resolve = function(_, _, info)
- return info.schema
- end
- }
- local Type = {
- name = '__type',
- kind = __Type,
- description = 'Request the type information of a single type.',
- arguments = {
- name = types.string.nonNull
- },
- resolve = function(_, arguments, info)
- return info.schema:getType(arguments.name)
- end
- }
- local TypeName = {
- name = '__typename',
- kind = types.string.nonNull,
- description = 'The name of the current Object type at runtime.',
- arguments = {},
- resolve = function(_, _, info)
- return info.parentType.name
- end
- }
- return {
- __Schema = __Schema,
- __Directive = __Directive,
- __DirectiveLocation = __DirectiveLocation,
- __Type = __Type,
- __Field = __Field,
- __EnumValue = __EnumValue,
- __TypeKind = __TypeKind,
- Schema = Schema,
- Type = Type,
- TypeName = TypeName,
- fieldMap = {
- __schema = Schema,
- __type = Type,
- __typename = TypeName
- }
- }
|