@graphql-inspector/cli
Version:
Tooling for GraphQL. Compare GraphQL Schemas, check documents, find breaking changes, find similar types.
119 lines (118 loc) • 4.95 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.findNamedNode = findNamedNode;
exports.deleteNamedNode = deleteNamedNode;
exports.parentPath = parentPath;
exports.debugPrintChange = debugPrintChange;
exports.assertValueMatch = assertValueMatch;
exports.getChangedNodeOfKind = getChangedNodeOfKind;
exports.getDeletedNodeOfKind = getDeletedNodeOfKind;
const graphql_1 = require("graphql");
const core_1 = require("@graphql-inspector/core");
const errors_js_1 = require("./errors.js");
function findNamedNode(nodes, name) {
return nodes?.find(value => value.name.value === name);
}
function deleteNamedNode(nodes, name) {
if (nodes) {
const idx = nodes.findIndex(value => value.name.value === name);
return idx >= 0 ? nodes.toSpliced(idx, 1) : nodes;
}
}
function parentPath(path) {
const lastDividerIndex = path.lastIndexOf('.');
return lastDividerIndex === -1 ? path : path.substring(0, lastDividerIndex);
}
const isAdditionChange = (change) => {
switch (change.type) {
case core_1.ChangeType.DirectiveAdded:
case core_1.ChangeType.DirectiveArgumentAdded:
case core_1.ChangeType.DirectiveLocationAdded:
case core_1.ChangeType.EnumValueAdded:
case core_1.ChangeType.EnumValueDeprecationReasonAdded:
case core_1.ChangeType.FieldAdded:
case core_1.ChangeType.FieldArgumentAdded:
case core_1.ChangeType.FieldDeprecationAdded:
case core_1.ChangeType.FieldDeprecationReasonAdded:
case core_1.ChangeType.FieldDescriptionAdded:
case core_1.ChangeType.InputFieldAdded:
case core_1.ChangeType.InputFieldDescriptionAdded:
case core_1.ChangeType.ObjectTypeInterfaceAdded:
case core_1.ChangeType.TypeDescriptionAdded:
case core_1.ChangeType.TypeAdded:
case core_1.ChangeType.UnionMemberAdded:
case core_1.ChangeType.DirectiveUsageArgumentAdded:
case core_1.ChangeType.DirectiveUsageArgumentDefinitionAdded:
case core_1.ChangeType.DirectiveUsageEnumAdded:
case core_1.ChangeType.DirectiveUsageEnumValueAdded:
case core_1.ChangeType.DirectiveUsageFieldAdded:
case core_1.ChangeType.DirectiveUsageFieldDefinitionAdded:
case core_1.ChangeType.DirectiveUsageInputFieldDefinitionAdded:
case core_1.ChangeType.DirectiveUsageInputObjectAdded:
case core_1.ChangeType.DirectiveUsageInterfaceAdded:
case core_1.ChangeType.DirectiveUsageObjectAdded:
case core_1.ChangeType.DirectiveUsageScalarAdded:
case core_1.ChangeType.DirectiveUsageSchemaAdded:
case core_1.ChangeType.DirectiveUsageUnionMemberAdded:
return true;
default:
return false;
}
};
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.`);
}
}
}
function assertValueMatch(change, expectedKind, expected, actual, config) {
if (expected !== actual) {
config.onError(new errors_js_1.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.
*/
function getChangedNodeOfKind(change, nodeByPath, kind, config) {
if (kind === graphql_1.Kind.DIRECTIVE) {
throw new Error('Directives cannot be found using this method.');
}
if (!change.path) {
config.onError(new errors_js_1.ChangePathMissingError(change), change);
return;
}
const existing = nodeByPath.get(change.path);
if (!existing) {
config.onError(new errors_js_1.ChangedCoordinateNotFoundError(kind, undefined), change);
return;
}
if (existing.kind !== kind) {
config.onError(new errors_js_1.ChangedCoordinateKindMismatchError(kind, existing.kind), change);
}
return existing;
}
function getDeletedNodeOfKind(change, nodeByPath, kind, config) {
if (!change.path) {
config.onError(new errors_js_1.ChangePathMissingError(change), change);
return;
}
const existing = nodeByPath.get(change.path);
if (!existing) {
config.onError(new errors_js_1.DeletedCoordinateNotFound(change.path, change.type), change);
return;
}
if (existing.kind !== kind) {
config.onError(new errors_js_1.ChangedCoordinateKindMismatchError(kind, existing.kind), change);
return;
}
return existing;
}