Files
30-seconds-of-code/node_modules/@gatsbyjs/relay-compiler/lib/GraphQLSchemaUtils.js
2019-08-20 15:52:05 +02:00

194 lines
5.9 KiB
JavaScript

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
* @format
*/
'use strict';
var invariant = require("fbjs/lib/invariant");
var nullthrows = require("./nullthrowsOSS");
var _require = require("graphql"),
assertAbstractType = _require.assertAbstractType,
getNamedType = _require.getNamedType,
getNullableType = _require.getNullableType,
isType = _require.isType,
print = _require.print,
typeFromAST = _require.typeFromAST,
GraphQLInterfaceType = _require.GraphQLInterfaceType,
GraphQLList = _require.GraphQLList,
GraphQLObjectType = _require.GraphQLObjectType,
GraphQLSchema = _require.GraphQLSchema,
GraphQLUnionType = _require.GraphQLUnionType;
var ID = 'id';
var ID_TYPE = 'ID';
/**
* Determine if the given type may implement the named type:
* - it is the named type
* - it implements the named interface
* - it is an abstract type and *some* of its concrete types may
* implement the named type
*/
function mayImplement(schema, type, typeName) {
var unmodifiedType = getRawType(type);
return unmodifiedType.toString() === typeName || implementsInterface(unmodifiedType, typeName) || isAbstractType(unmodifiedType) && hasConcreteTypeThatImplements(schema, unmodifiedType, typeName);
}
function canHaveSelections(type) {
return type instanceof GraphQLObjectType || type instanceof GraphQLInterfaceType;
}
/**
* Implements duck typing that checks whether a type has an id field of the ID
* type. This is approximating what we can hopefully do with the __id proposal
* a bit more cleanly.
*
* https://github.com/graphql/graphql-future/blob/master/01%20-%20__id.md
*/
function hasID(schema, type) {
var unmodifiedType = getRawType(type);
!(unmodifiedType instanceof GraphQLObjectType || unmodifiedType instanceof GraphQLInterfaceType) ? process.env.NODE_ENV !== "production" ? invariant(false, 'GraphQLSchemaUtils.hasID(): Expected a concrete type or interface, ' + 'got type `%s`.', type) : invariant(false) : void 0;
var idType = schema.getType(ID_TYPE);
var idField = unmodifiedType.getFields()[ID];
return idField && getRawType(idField.type) === idType;
}
/**
* Determine if a type is abstract (not concrete).
*
* Note: This is used in place of the `graphql` version of the function in order
* to not break `instanceof` checks with Jest. This version also unwraps
* non-null/list wrapper types.
*/
function isAbstractType(type) {
var rawType = getRawType(type);
return rawType instanceof GraphQLInterfaceType || rawType instanceof GraphQLUnionType;
}
function isUnionType(type) {
return type instanceof GraphQLUnionType;
}
/**
* Get the unmodified type, with list/null wrappers removed.
*/
function getRawType(type) {
return nullthrows(getNamedType(type));
}
/**
* Gets the non-list type, removing the list wrapper if present.
*/
function getSingularType(type) {
var unmodifiedType = type;
while (unmodifiedType instanceof GraphQLList) {
unmodifiedType = unmodifiedType.ofType;
}
return unmodifiedType;
}
/**
* @public
*/
function implementsInterface(type, interfaceName) {
return getInterfaces(type).some(function (interfaceType) {
return interfaceType.toString() === interfaceName;
});
}
/**
* @private
*/
function hasConcreteTypeThatImplements(schema, type, interfaceName) {
return isAbstractType(type) && getConcreteTypes(schema, type).some(function (concreteType) {
return implementsInterface(concreteType, interfaceName);
});
}
/**
* @private
*/
function getConcreteTypes(schema, type) {
return schema.getPossibleTypes(assertAbstractType(type));
}
/**
* @private
*/
function getInterfaces(type) {
if (type instanceof GraphQLObjectType) {
return type.getInterfaces();
}
return [];
}
/**
* @public
*
* Determine if an AST node contains a fragment/operation definition.
*/
function isExecutableDefinitionAST(ast) {
return ast.kind === 'FragmentDefinition' || ast.kind === 'OperationDefinition';
}
/**
* @public
*
* Determine if an AST node contains a schema definition.
*/
function isSchemaDefinitionAST(ast) {
return ast.kind === 'SchemaDefinition' || ast.kind === 'ScalarTypeDefinition' || ast.kind === 'ObjectTypeDefinition' || ast.kind === 'InterfaceTypeDefinition' || ast.kind === 'UnionTypeDefinition' || ast.kind === 'EnumTypeDefinition' || ast.kind === 'InputObjectTypeDefinition' || ast.kind === 'DirectiveDefinition' || ast.kind === 'ScalarTypeExtension' || ast.kind === 'ObjectTypeExtension' || ast.kind === 'InterfaceTypeExtension' || ast.kind === 'UnionTypeExtension' || ast.kind === 'EnumTypeExtension' || ast.kind === 'InputObjectTypeExtension';
}
function assertTypeWithFields(type) {
!(type instanceof GraphQLObjectType || type instanceof GraphQLInterfaceType) ? process.env.NODE_ENV !== "production" ? invariant(false, 'GraphQLSchemaUtils: Expected type `%s` to be an object or interface type.', type) : invariant(false) : void 0;
return type;
}
/**
* Helper for calling `typeFromAST()` with a clear warning when the type does
* not exist. This enables the pattern `assertXXXType(getTypeFromAST(...))`,
* emitting distinct errors for unknown types vs types of the wrong category.
*/
function getTypeFromAST(schema, ast) {
var type = typeFromAST(schema, ast);
!isType(type) ? process.env.NODE_ENV !== "production" ? invariant(false, 'GraphQLSchemaUtils: Unknown type `%s`.', print(ast)) : invariant(false) : void 0;
return type;
}
module.exports = {
assertTypeWithFields: assertTypeWithFields,
canHaveSelections: canHaveSelections,
getNullableType: getNullableType,
getRawType: getRawType,
getSingularType: getSingularType,
getTypeFromAST: getTypeFromAST,
hasID: hasID,
implementsInterface: implementsInterface,
isAbstractType: isAbstractType,
isUnionType: isUnionType,
isExecutableDefinitionAST: isExecutableDefinitionAST,
isSchemaDefinitionAST: isSchemaDefinitionAST,
mayImplement: mayImplement
};