@graphql-inspector/patch
Version:
Applies changes output from @graphql-inspect/diff
97 lines (96 loc) • 4.1 kB
JavaScript
import { isTypeDefinitionNode, Kind } from 'graphql';
import { AddedCoordinateAlreadyExistsError, ChangedAncestorCoordinateNotFoundError, ChangedCoordinateKindMismatchError, ChangePathMissingError, DeletedAncestorCoordinateNotFoundError, DeletedCoordinateNotFound, ValueMismatchError, } from '../errors.js';
import { nameNode, stringNode } from '../node-templates.js';
export function typeAdded(change, nodeByPath, config, _context) {
if (!change.path) {
config.onError(new ChangePathMissingError(change), change);
return;
}
const existing = nodeByPath.get(change.path);
if (existing) {
config.onError(new AddedCoordinateAlreadyExistsError(change.path, change.type), change);
return;
}
const node = {
name: nameNode(change.meta.addedTypeName),
kind: change.meta.addedTypeKind,
};
nodeByPath.set(change.path, node);
}
export function typeRemoved(change, nodeByPath, config, _context) {
if (!change.path) {
config.onError(new ChangePathMissingError(change), change);
return;
}
const removedNode = nodeByPath.get(change.path);
if (!removedNode) {
config.onError(new DeletedCoordinateNotFound(change.path, change.type), change);
return;
}
if (!isTypeDefinitionNode(removedNode)) {
config.onError(new DeletedCoordinateNotFound(change.path, change.type), change);
return;
}
// delete the reference to the removed field.
for (const key of nodeByPath.keys()) {
if (key.startsWith(change.path)) {
nodeByPath.delete(key);
}
}
}
export function typeDescriptionAdded(change, nodeByPath, config, _context) {
if (!change.path) {
config.onError(new ChangePathMissingError(change), change);
return;
}
const typeNode = nodeByPath.get(change.path);
if (!typeNode) {
config.onError(new ChangedAncestorCoordinateNotFoundError(change.path, change.type, change.meta.addedTypeDescription), change);
return;
}
if (!isTypeDefinitionNode(typeNode)) {
config.onError(new ChangedCoordinateKindMismatchError(Kind.OBJECT_TYPE_DEFINITION, typeNode.kind), change);
return;
}
typeNode.description = change.meta.addedTypeDescription
? stringNode(change.meta.addedTypeDescription)
: undefined;
}
export function typeDescriptionChanged(change, nodeByPath, config, _context) {
if (!change.path) {
config.onError(new ChangePathMissingError(change), change);
return;
}
const typeNode = nodeByPath.get(change.path);
if (!typeNode) {
config.onError(new ChangedAncestorCoordinateNotFoundError(change.path, change.type, change.meta.newTypeDescription), change);
return;
}
if (!isTypeDefinitionNode(typeNode)) {
config.onError(new ChangedCoordinateKindMismatchError(Kind.OBJECT_TYPE_DEFINITION, typeNode.kind), change);
return;
}
if (typeNode.description?.value !== change.meta.oldTypeDescription) {
config.onError(new ValueMismatchError(Kind.STRING, change.meta.oldTypeDescription, typeNode.description?.value), change);
}
typeNode.description = stringNode(change.meta.newTypeDescription);
}
export function typeDescriptionRemoved(change, nodeByPath, config, _context) {
if (!change.path) {
config.onError(new ChangePathMissingError(change), change);
return;
}
const typeNode = nodeByPath.get(change.path);
if (!typeNode) {
config.onError(new DeletedAncestorCoordinateNotFoundError(change.path, change.type, change.meta.removedTypeDescription), change);
return;
}
if (!isTypeDefinitionNode(typeNode)) {
config.onError(new ChangedCoordinateKindMismatchError(Kind.OBJECT_TYPE_DEFINITION, typeNode.kind), change);
return;
}
if (typeNode.description?.value !== change.meta.removedTypeDescription) {
config.onError(new ValueMismatchError(Kind.STRING, change.meta.removedTypeDescription, typeNode.description?.value), change);
}
typeNode.description = undefined;
}