UNPKG

@graphql-inspector/cli

Version:

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

290 lines (289 loc) • 15 kB
"use strict"; 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; }