UNPKG

@graphql-inspector/cli

Version:

Tooling for GraphQL. Compare GraphQL Schemas, check documents, find breaking changes, find similar types.

110 lines (109 loc) 4.43 kB
import { Kind } from 'graphql'; import { ChangeType } from '@graphql-inspector/core'; import { ChangedCoordinateKindMismatchError, ChangedCoordinateNotFoundError, ChangePathMissingError, DeletedCoordinateNotFound, ValueMismatchError, } from './errors.js'; export function findNamedNode(nodes, name) { return nodes?.find(value => value.name.value === name); } export function deleteNamedNode(nodes, name) { if (nodes) { const idx = nodes.findIndex(value => value.name.value === name); return idx >= 0 ? nodes.toSpliced(idx, 1) : nodes; } } export function parentPath(path) { const lastDividerIndex = path.lastIndexOf('.'); return lastDividerIndex === -1 ? path : path.substring(0, lastDividerIndex); } const isAdditionChange = (change) => { switch (change.type) { case ChangeType.DirectiveAdded: case ChangeType.DirectiveArgumentAdded: case ChangeType.DirectiveLocationAdded: case ChangeType.EnumValueAdded: case ChangeType.EnumValueDeprecationReasonAdded: case ChangeType.FieldAdded: case ChangeType.FieldArgumentAdded: case ChangeType.FieldDeprecationAdded: case ChangeType.FieldDeprecationReasonAdded: case ChangeType.FieldDescriptionAdded: case ChangeType.InputFieldAdded: case ChangeType.InputFieldDescriptionAdded: case ChangeType.ObjectTypeInterfaceAdded: case ChangeType.TypeDescriptionAdded: case ChangeType.TypeAdded: case ChangeType.UnionMemberAdded: case ChangeType.DirectiveUsageArgumentAdded: case ChangeType.DirectiveUsageArgumentDefinitionAdded: case ChangeType.DirectiveUsageEnumAdded: case ChangeType.DirectiveUsageEnumValueAdded: case ChangeType.DirectiveUsageFieldAdded: case ChangeType.DirectiveUsageFieldDefinitionAdded: case ChangeType.DirectiveUsageInputFieldDefinitionAdded: case ChangeType.DirectiveUsageInputObjectAdded: case ChangeType.DirectiveUsageInterfaceAdded: case ChangeType.DirectiveUsageObjectAdded: case ChangeType.DirectiveUsageScalarAdded: case ChangeType.DirectiveUsageSchemaAdded: case ChangeType.DirectiveUsageUnionMemberAdded: return true; default: return false; } }; export function debugPrintChange(change, nodeByPath) { if (isAdditionChange(change)) { console.debug(`"${change.path}" is being added to the schema.`); } else { const changedNode = (change.path && nodeByPath.get(change.path)) || false; if (changedNode) { console.debug(`"${change.path}" has a change: [${change.type}] "${change.message}"`); } else { console.debug(`The "${change.type}" change to "${change.path}" cannot be applied. That coordinate does not exist in the schema.`); } } } export function assertValueMatch(change, expectedKind, expected, actual, config) { if (expected !== actual) { config.onError(new ValueMismatchError(expectedKind, expected, actual), change); } } /** * Handles verifying the change object has a path, that the node exists in the * nodeByPath Map, and that the found node is the expected Kind. */ export function getChangedNodeOfKind(change, nodeByPath, kind, config) { if (kind === Kind.DIRECTIVE) { throw new Error('Directives cannot be found using this method.'); } if (!change.path) { config.onError(new ChangePathMissingError(change), change); return; } const existing = nodeByPath.get(change.path); if (!existing) { config.onError(new ChangedCoordinateNotFoundError(kind, undefined), change); return; } if (existing.kind !== kind) { config.onError(new ChangedCoordinateKindMismatchError(kind, existing.kind), change); } return existing; } export function getDeletedNodeOfKind(change, nodeByPath, kind, config) { if (!change.path) { config.onError(new ChangePathMissingError(change), change); return; } const existing = nodeByPath.get(change.path); if (!existing) { config.onError(new DeletedCoordinateNotFound(change.path, change.type), change); return; } if (existing.kind !== kind) { config.onError(new ChangedCoordinateKindMismatchError(kind, existing.kind), change); return; } return existing; }