@graphql-inspector/cli
Version:
Tooling for GraphQL. Compare GraphQL Schemas, check documents, find breaking changes, find similar types.
290 lines (289 loc) • 15 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.directiveAdded = directiveAdded;
exports.directiveRemoved = directiveRemoved;
exports.directiveArgumentAdded = directiveArgumentAdded;
exports.directiveArgumentRemoved = directiveArgumentRemoved;
exports.directiveLocationAdded = directiveLocationAdded;
exports.directiveLocationRemoved = directiveLocationRemoved;
exports.directiveDescriptionChanged = directiveDescriptionChanged;
exports.directiveArgumentDefaultValueChanged = directiveArgumentDefaultValueChanged;
exports.directiveArgumentDescriptionChanged = directiveArgumentDescriptionChanged;
exports.directiveArgumentTypeChanged = directiveArgumentTypeChanged;
exports.directiveRepeatableAdded = directiveRepeatableAdded;
exports.directiveRepeatableRemoved = directiveRepeatableRemoved;
const graphql_1 = require("graphql");
const errors_js_1 = require("../errors.js");
const node_templates_js_1 = require("../node-templates.js");
const utils_js_1 = require("../utils.js");
function directiveAdded(change, nodeByPath, config, _context) {
if (change.path === undefined) {
config.onError(new errors_js_1.ChangePathMissingError(change), change);
return;
}
const changedNode = nodeByPath.get(change.path);
if (!changedNode) {
const node = {
kind: graphql_1.Kind.DIRECTIVE_DEFINITION,
name: (0, node_templates_js_1.nameNode)(change.meta.addedDirectiveName),
repeatable: change.meta.addedDirectiveRepeatable,
locations: change.meta.addedDirectiveLocations.map(l => (0, node_templates_js_1.nameNode)(l)),
description: change.meta.addedDirectiveDescription
? (0, node_templates_js_1.stringNode)(change.meta.addedDirectiveDescription)
: undefined,
};
nodeByPath.set(change.path, node);
return;
}
if (changedNode.kind !== graphql_1.Kind.DIRECTIVE_DEFINITION) {
config.onError(new errors_js_1.ChangedCoordinateKindMismatchError(graphql_1.Kind.DIRECTIVE_DEFINITION, changedNode.kind), change);
return;
}
// eslint-disable-next-line eqeqeq
if (change.meta.addedDirectiveRepeatable != changedNode.repeatable) {
config.onError(new errors_js_1.ValueMismatchError(changedNode.kind, `repeatable=${change.meta.addedDirectiveRepeatable}`, `repeatable=${changedNode.repeatable}`), change);
return;
}
if (change.meta.addedDirectiveLocations.join('|') !==
changedNode.locations.map(l => l.value).join('|')) {
config.onError(new errors_js_1.ValueMismatchError(changedNode.kind, `locations=${change.meta.addedDirectiveLocations.join('|')}`, `locations=${changedNode.locations.map(l => l.value).join('|')}`), change);
return;
}
config.onError(new errors_js_1.AddedCoordinateAlreadyExistsError(change.path, change.type), change);
}
function directiveRemoved(change, nodeByPath, config, _context) {
const existing = (0, utils_js_1.getDeletedNodeOfKind)(change, nodeByPath, graphql_1.Kind.DIRECTIVE_DEFINITION, config);
if (existing) {
nodeByPath.delete(change.path);
}
}
function directiveArgumentAdded(change, nodeByPath, config, _context) {
if (!change.path) {
config.onError(new errors_js_1.ChangePathMissingError(change), change);
return;
}
const directiveNode = nodeByPath.get(change.path);
if (!directiveNode) {
config.onError(new errors_js_1.AddedAttributeCoordinateNotFoundError(change.path, change.type, change.meta.addedDirectiveArgumentName), change);
return;
}
if (directiveNode.kind !== graphql_1.Kind.DIRECTIVE_DEFINITION) {
config.onError(new errors_js_1.ChangedCoordinateKindMismatchError(graphql_1.Kind.DIRECTIVE_DEFINITION, directiveNode.kind), change);
return;
}
const existingArg = (0, utils_js_1.findNamedNode)(directiveNode.arguments, change.meta.addedDirectiveArgumentName);
if (!existingArg) {
const node = {
kind: graphql_1.Kind.INPUT_VALUE_DEFINITION,
name: (0, node_templates_js_1.nameNode)(change.meta.addedDirectiveArgumentName),
type: (0, graphql_1.parseType)(change.meta.addedDirectiveArgumentType),
};
directiveNode.arguments = [
...(directiveNode.arguments ?? []),
node,
];
nodeByPath.set(`${change.path}.${change.meta.addedDirectiveArgumentName}`, node);
return;
}
const existingType = (0, graphql_1.print)(existingArg.type);
if (existingType !== change.meta.addedDirectiveArgumentType) {
config.onError(new errors_js_1.ValueMismatchError(existingArg.kind, `type=${change.meta.addedDirectiveArgumentType}`, `type=${existingType}`), change);
}
const existingDefaultValue = existingArg.defaultValue
? (0, graphql_1.print)(existingArg.defaultValue)
: undefined;
if (change.meta.addedDirectiveDefaultValue !== existingDefaultValue) {
config.onError(new errors_js_1.ValueMismatchError(existingArg.kind, `defaultValue=${change.meta.addedDirectiveDefaultValue}`, `defaultValue=${existingDefaultValue}`), change);
}
config.onError(new errors_js_1.AddedAttributeAlreadyExistsError(change.path, change.type, 'arguments', change.meta.addedDirectiveArgumentName), change);
}
function directiveArgumentRemoved(change, nodeByPath, config, _context) {
if (!change.path) {
config.onError(new errors_js_1.ChangePathMissingError(change), change);
return;
}
const argNode = (0, utils_js_1.getDeletedNodeOfKind)(change, nodeByPath, graphql_1.Kind.INPUT_VALUE_DEFINITION, config);
if (argNode) {
const directiveNode = nodeByPath.get((0, utils_js_1.parentPath)(change.path));
if (!directiveNode) {
config.onError(new errors_js_1.DeletedAncestorCoordinateNotFoundError(change.path, change.type, change.meta.removedDirectiveArgumentName), change);
return;
}
if (directiveNode.kind !== graphql_1.Kind.DIRECTIVE_DEFINITION) {
config.onError(new errors_js_1.ChangedCoordinateKindMismatchError(graphql_1.Kind.DIRECTIVE_DEFINITION, directiveNode.kind), change);
return;
}
directiveNode.arguments =
(0, utils_js_1.deleteNamedNode)(directiveNode.arguments, change.meta.removedDirectiveArgumentName);
}
}
function directiveLocationAdded(change, nodeByPath, config, _context) {
if (!change.path) {
config.onError(new errors_js_1.ChangePathMissingError(change), change);
return;
}
const changedNode = nodeByPath.get(change.path);
if (!changedNode) {
config.onError(new errors_js_1.ChangedAncestorCoordinateNotFoundError(change.path, change.type, change.meta.addedDirectiveLocation), change);
return;
}
if (changedNode.kind !== graphql_1.Kind.DIRECTIVE_DEFINITION) {
config.onError(new errors_js_1.ChangedCoordinateKindMismatchError(graphql_1.Kind.DIRECTIVE_DEFINITION, changedNode.kind), change);
return;
}
if (changedNode.locations.some(l => l.value === change.meta.addedDirectiveLocation)) {
config.onError(new errors_js_1.AddedAttributeAlreadyExistsError(change.path, change.type, 'locations', change.meta.addedDirectiveLocation), change);
return;
}
changedNode.locations = [
...changedNode.locations,
(0, node_templates_js_1.nameNode)(change.meta.addedDirectiveLocation),
];
}
function directiveLocationRemoved(change, nodeByPath, config, _context) {
if (!change.path) {
config.onError(new errors_js_1.ChangePathMissingError(change), change);
return;
}
const changedNode = nodeByPath.get(change.path);
if (!changedNode) {
config.onError(new errors_js_1.DeletedAncestorCoordinateNotFoundError(change.path, change.type, change.meta.removedDirectiveLocation), change);
return;
}
if (changedNode.kind !== graphql_1.Kind.DIRECTIVE_DEFINITION) {
config.onError(new errors_js_1.ChangedCoordinateKindMismatchError(graphql_1.Kind.DIRECTIVE_DEFINITION, changedNode.kind), change);
return;
}
const existing = changedNode.locations.findIndex(l => l.value === change.meta.removedDirectiveLocation);
if (existing >= 0) {
changedNode.locations = changedNode.locations.toSpliced(existing, 1);
}
else {
config.onError(new errors_js_1.DeletedAttributeNotFoundError(change.path, change.type, 'locations', change.meta.removedDirectiveLocation), change);
}
}
function directiveDescriptionChanged(change, nodeByPath, config, _context) {
if (!change.path) {
config.onError(new errors_js_1.ChangePathMissingError(change), change);
return;
}
const directiveNode = nodeByPath.get(change.path);
if (!directiveNode) {
config.onError(new errors_js_1.ChangedAncestorCoordinateNotFoundError(change.path, change.type, change.meta.newDirectiveDescription), change);
return;
}
if (directiveNode.kind !== graphql_1.Kind.DIRECTIVE_DEFINITION) {
config.onError(new errors_js_1.ChangedCoordinateKindMismatchError(graphql_1.Kind.DIRECTIVE_DEFINITION, directiveNode.kind), change);
return;
}
if ((directiveNode.description?.value ?? null) !== change.meta.oldDirectiveDescription) {
config.onError(new errors_js_1.ValueMismatchError(graphql_1.Kind.STRING, change.meta.oldDirectiveDescription, directiveNode.description?.value), change);
}
directiveNode.description = change.meta.newDirectiveDescription
? (0, node_templates_js_1.stringNode)(change.meta.newDirectiveDescription)
: undefined;
}
function directiveArgumentDefaultValueChanged(change, nodeByPath, config, _context) {
if (!change.path) {
config.onError(new errors_js_1.ChangePathMissingError(change), change);
return;
}
const argumentNode = nodeByPath.get(change.path);
if (!argumentNode) {
config.onError(new errors_js_1.ChangedAncestorCoordinateNotFoundError(change.path, change.type, change.meta.newDirectiveArgumentDefaultValue ?? null), change);
return;
}
if (argumentNode.kind !== graphql_1.Kind.INPUT_VALUE_DEFINITION) {
config.onError(new errors_js_1.ChangedCoordinateKindMismatchError(graphql_1.Kind.INPUT_VALUE_DEFINITION, argumentNode.kind), change);
return;
}
if ((argumentNode.defaultValue && (0, graphql_1.print)(argumentNode.defaultValue)) ===
change.meta.oldDirectiveArgumentDefaultValue) {
argumentNode.defaultValue = change.meta
.newDirectiveArgumentDefaultValue
? (0, graphql_1.parseConstValue)(change.meta.newDirectiveArgumentDefaultValue)
: undefined;
}
else {
config.onError(new errors_js_1.ValueMismatchError(graphql_1.Kind.INPUT_VALUE_DEFINITION, change.meta.oldDirectiveArgumentDefaultValue, argumentNode.defaultValue && (0, graphql_1.print)(argumentNode.defaultValue)), change);
}
}
function directiveArgumentDescriptionChanged(change, nodeByPath, config, _context) {
if (!change.path) {
config.onError(new errors_js_1.ChangePathMissingError(change), change);
return;
}
const argumentNode = nodeByPath.get(change.path);
if (!argumentNode) {
config.onError(new errors_js_1.ChangedAncestorCoordinateNotFoundError(change.path, change.type, change.meta.newDirectiveArgumentDescription), change);
return;
}
if (argumentNode.kind !== graphql_1.Kind.INPUT_VALUE_DEFINITION) {
config.onError(new errors_js_1.ChangedCoordinateKindMismatchError(graphql_1.Kind.INPUT_VALUE_DEFINITION, argumentNode.kind), change);
return;
}
if ((argumentNode.description?.value ?? null) !== change.meta.oldDirectiveArgumentDescription) {
config.onError(new errors_js_1.ValueMismatchError(graphql_1.Kind.STRING, change.meta.oldDirectiveArgumentDescription ?? undefined, argumentNode.description?.value), change);
}
argumentNode.description = change.meta
.newDirectiveArgumentDescription
? (0, node_templates_js_1.stringNode)(change.meta.newDirectiveArgumentDescription)
: undefined;
}
function directiveArgumentTypeChanged(change, nodeByPath, config, _context) {
if (!change.path) {
config.onError(new errors_js_1.ChangePathMissingError(change), change);
return;
}
const argumentNode = nodeByPath.get(change.path);
if (!argumentNode) {
config.onError(new errors_js_1.ChangedAncestorCoordinateNotFoundError(change.path, change.type, change.meta.newDirectiveArgumentType), change);
return;
}
if (argumentNode.kind !== graphql_1.Kind.INPUT_VALUE_DEFINITION) {
config.onError(new errors_js_1.ChangedCoordinateKindMismatchError(graphql_1.Kind.INPUT_VALUE_DEFINITION, argumentNode.kind), change);
return;
}
if ((0, graphql_1.print)(argumentNode.type) !== change.meta.oldDirectiveArgumentType) {
config.onError(new errors_js_1.ValueMismatchError(graphql_1.Kind.STRING, change.meta.oldDirectiveArgumentType, (0, graphql_1.print)(argumentNode.type)), change);
}
argumentNode.type = (0, graphql_1.parseType)(change.meta.newDirectiveArgumentType);
}
function directiveRepeatableAdded(change, nodeByPath, config, _context) {
if (!change.path) {
config.onError(new errors_js_1.ChangePathMissingError(change), change);
return;
}
const directiveNode = nodeByPath.get(change.path);
if (!directiveNode) {
config.onError(new errors_js_1.ChangedAncestorCoordinateNotFoundError(change.path, change.type, true), change);
return;
}
if (directiveNode.kind !== graphql_1.Kind.DIRECTIVE_DEFINITION) {
config.onError(new errors_js_1.ChangedCoordinateKindMismatchError(graphql_1.Kind.DIRECTIVE_DEFINITION, directiveNode.kind), change);
return;
}
if (directiveNode.repeatable !== false) {
config.onError(new errors_js_1.ValueMismatchError(graphql_1.Kind.BOOLEAN, String(directiveNode.repeatable), 'false'), change);
}
directiveNode.repeatable = true;
}
function directiveRepeatableRemoved(change, nodeByPath, config, _context) {
if (!change.path) {
config.onError(new errors_js_1.ChangePathMissingError(change), change);
return;
}
const directiveNode = nodeByPath.get(change.path);
if (!directiveNode) {
config.onError(new errors_js_1.DeletedAncestorCoordinateNotFoundError(change.path, change.type, true), change);
return;
}
if (directiveNode.kind !== graphql_1.Kind.DIRECTIVE_DEFINITION) {
config.onError(new errors_js_1.ChangedCoordinateKindMismatchError(graphql_1.Kind.DIRECTIVE_DEFINITION, directiveNode.kind), change);
return;
}
if (directiveNode.repeatable !== true) {
config.onError(new errors_js_1.ValueMismatchError(graphql_1.Kind.BOOLEAN, String(directiveNode.repeatable), 'true'), change);
}
directiveNode.repeatable = false;
}