swc/crates/swc_bundler/tests/.cache/deno/f61b66c032f511a7681d30d9aef6d0f2d2857c29.ts
2021-11-09 20:42:49 +09:00

127 lines
3.8 KiB
TypeScript

// Loaded from https://deno.land/x/graphql_deno@v15.0.0/lib/validation/rules/PossibleTypeExtensionsRule.js
import inspect from '../../jsutils/inspect.js';
import invariant from '../../jsutils/invariant.js';
import didYouMean from '../../jsutils/didYouMean.js';
import suggestionList from '../../jsutils/suggestionList.js';
import { GraphQLError } from '../../error/GraphQLError.js';
import { Kind } from '../../language/kinds.js';
import { isTypeDefinitionNode } from '../../language/predicates.js';
import { isScalarType, isObjectType, isInterfaceType, isUnionType, isEnumType, isInputObjectType } from '../../type/definition.js';
/**
* Possible type extension
*
* A type extension is only valid if the type is defined and has the same kind.
*/
export function PossibleTypeExtensionsRule(context) {
const schema = context.getSchema();
const definedTypes = Object.create(null);
for (const def of context.getDocument().definitions) {
if (isTypeDefinitionNode(def)) {
definedTypes[def.name.value] = def;
}
}
return {
ScalarTypeExtension: checkExtension,
ObjectTypeExtension: checkExtension,
InterfaceTypeExtension: checkExtension,
UnionTypeExtension: checkExtension,
EnumTypeExtension: checkExtension,
InputObjectTypeExtension: checkExtension
};
function checkExtension(node) {
const typeName = node.name.value;
const defNode = definedTypes[typeName];
const existingType = schema?.getType(typeName);
let expectedKind;
if (defNode) {
expectedKind = defKindToExtKind[defNode.kind];
} else if (existingType) {
expectedKind = typeToExtKind(existingType);
}
if (expectedKind) {
if (expectedKind !== node.kind) {
const kindStr = extensionKindToTypeName(node.kind);
context.reportError(new GraphQLError(`Cannot extend non-${kindStr} type "${typeName}".`, defNode ? [defNode, node] : node));
}
} else {
let allTypeNames = Object.keys(definedTypes);
if (schema) {
allTypeNames = allTypeNames.concat(Object.keys(schema.getTypeMap()));
}
const suggestedTypes = suggestionList(typeName, allTypeNames);
context.reportError(new GraphQLError(`Cannot extend type "${typeName}" because it is not defined.` + didYouMean(suggestedTypes), node.name));
}
}
}
const defKindToExtKind = {
[Kind.SCALAR_TYPE_DEFINITION]: Kind.SCALAR_TYPE_EXTENSION,
[Kind.OBJECT_TYPE_DEFINITION]: Kind.OBJECT_TYPE_EXTENSION,
[Kind.INTERFACE_TYPE_DEFINITION]: Kind.INTERFACE_TYPE_EXTENSION,
[Kind.UNION_TYPE_DEFINITION]: Kind.UNION_TYPE_EXTENSION,
[Kind.ENUM_TYPE_DEFINITION]: Kind.ENUM_TYPE_EXTENSION,
[Kind.INPUT_OBJECT_TYPE_DEFINITION]: Kind.INPUT_OBJECT_TYPE_EXTENSION
};
function typeToExtKind(type) {
if (isScalarType(type)) {
return Kind.SCALAR_TYPE_EXTENSION;
}
if (isObjectType(type)) {
return Kind.OBJECT_TYPE_EXTENSION;
}
if (isInterfaceType(type)) {
return Kind.INTERFACE_TYPE_EXTENSION;
}
if (isUnionType(type)) {
return Kind.UNION_TYPE_EXTENSION;
}
if (isEnumType(type)) {
return Kind.ENUM_TYPE_EXTENSION;
}
if (isInputObjectType(type)) {
return Kind.INPUT_OBJECT_TYPE_EXTENSION;
} // Not reachable. All possible types have been considered.
invariant(false, 'Unexpected type: ' + inspect(type));
}
function extensionKindToTypeName(kind) {
switch (kind) {
case Kind.SCALAR_TYPE_EXTENSION:
return 'scalar';
case Kind.OBJECT_TYPE_EXTENSION:
return 'object';
case Kind.INTERFACE_TYPE_EXTENSION:
return 'interface';
case Kind.UNION_TYPE_EXTENSION:
return 'union';
case Kind.ENUM_TYPE_EXTENSION:
return 'enum';
case Kind.INPUT_OBJECT_TYPE_EXTENSION:
return 'input object';
} // Not reachable. All possible types have been considered.
invariant(false, 'Unexpected kind: ' + inspect(kind));
}