Idea: "Field.isScalar()" helper
GavinRay97 opened this issue · 2 comments
I have this which I use to find whether a Field of an Object node is a scalar or not:
export const isScalar = (doc: DocumentApi, field: FieldDefinitionApi) => {
const baseScalars = ['ID', 'Int', 'Float', 'String', 'Boolean']
const customScalars = doc.getAllScalarTypes().map((s) => s.getName())
const allScalars = [...baseScalars, ...customScalars]
return allScalars.some((scalar) =>
field.getTypename().includes(scalar)
)
}
And I use something similar to this pretty often, I was curious whether there might be interest in adding it as a native operation =)
Following up on this, I have been trying for days to figure out a way to test if a type node is a scalar without needing the context of the DocumentApi
in the function.
Is this possible @vadistic?
This works below in raw graphql.js
for GraphQLInputType
but I can't seem to figure it out for TypeNode
. Not sure if this is possible.
Maybe the other solution is to expose the context of the root document
to the mixins so that they can refer back to the schema that they exist in?
const rootQueryType = schema.getQueryType()
const fields = rootQueryType?.getFields()
const forms = Object.keys(fields).map((fieldName) => {
console.log('fieldname', fieldName)
const field = fields[fieldName]
const args = field.args
console.log('field.type', field.type)
for (let arg of args) {
const nullableType = getNullableType(arg.type)
console.log('arg.name:', arg.name)
console.log('arg.type:', arg.type)
console.log('getNullableType(arg.type):', nullableType)
console.log('isScalar:', isScalarType(nullableType))
}
})
Finally realized why I was having so much trouble with writing this functionality in myself.
I hadn't quite realized that the concepts for working with GraphQL schemas inside of graphql.js
are divided into two sub-types.
- The
Document
type, from/graphql/language/ast
, for representing just AST nodes - The
GraphQLSchema
type, from/graphql/graphql
, for the actual schema itself
The type names that are used between each of them aren't very different either, IE, GraphQLObjectType
vs ObjectTypeDefinition
etc.
So I figured out that this is the shortest/easiest way to tell whether a node is a scalar type or not, but it won't map to the existing library code well because it requires isScalar()
which requires a GraphQLSchema
and not a Document
🙁
import { isScalarType, GraphQLSchema } from 'graphql'
import { DocumentApi, TypeApi } from 'graphql-extra'
let cachedSchema: GraphQLSchema
function isScalar(doc: DocumentApi, type: TypeApi) {
if (!cachedSchema) cachedSchema = doc.toSchema()
const schemaType = cachedSchema.getType(type.getTypename())
return isScalarType(schemaType)
}
If there's a way to store the result of document.toSchema()
on the global DocumentApi
instance when created after addSDL()
, and then provide the value of GraphQLSchema
to context of instance of graphql-extra/src/api/type.ts
then it would work but that's a bit beyond my comprehension.