UNPKG

@graphql-inspector/core

Version:

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

876 lines (875 loc) • 43.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.directiveUsageArgumentDefinitionAddedFromMeta = directiveUsageArgumentDefinitionAddedFromMeta; exports.directiveUsageArgumentDefinitionRemovedFromMeta = directiveUsageArgumentDefinitionRemovedFromMeta; exports.directiveUsageInputObjectAddedFromMeta = directiveUsageInputObjectAddedFromMeta; exports.directiveUsageInputObjectRemovedFromMeta = directiveUsageInputObjectRemovedFromMeta; exports.directiveUsageInterfaceAddedFromMeta = directiveUsageInterfaceAddedFromMeta; exports.directiveUsageInterfaceRemovedFromMeta = directiveUsageInterfaceRemovedFromMeta; exports.directiveUsageInputFieldDefinitionAddedFromMeta = directiveUsageInputFieldDefinitionAddedFromMeta; exports.directiveUsageInputFieldDefinitionRemovedFromMeta = directiveUsageInputFieldDefinitionRemovedFromMeta; exports.directiveUsageObjectAddedFromMeta = directiveUsageObjectAddedFromMeta; exports.directiveUsageObjectRemovedFromMeta = directiveUsageObjectRemovedFromMeta; exports.directiveUsageEnumAddedFromMeta = directiveUsageEnumAddedFromMeta; exports.directiveUsageEnumRemovedFromMeta = directiveUsageEnumRemovedFromMeta; exports.directiveUsageFieldAddedFromMeta = directiveUsageFieldAddedFromMeta; exports.directiveUsageFieldDefinitionAddedFromMeta = directiveUsageFieldDefinitionAddedFromMeta; exports.directiveUsageFieldRemovedFromMeta = directiveUsageFieldRemovedFromMeta; exports.directiveUsageFieldDefinitionRemovedFromMeta = directiveUsageFieldDefinitionRemovedFromMeta; exports.directiveUsageEnumValueAddedFromMeta = directiveUsageEnumValueAddedFromMeta; exports.directiveUsageEnumValueRemovedFromMeta = directiveUsageEnumValueRemovedFromMeta; exports.directiveUsageSchemaAddedFromMeta = directiveUsageSchemaAddedFromMeta; exports.directiveUsageSchemaRemovedFromMeta = directiveUsageSchemaRemovedFromMeta; exports.directiveUsageScalarAddedFromMeta = directiveUsageScalarAddedFromMeta; exports.directiveUsageScalarRemovedFromMeta = directiveUsageScalarRemovedFromMeta; exports.directiveUsageUnionMemberAddedFromMeta = directiveUsageUnionMemberAddedFromMeta; exports.directiveUsageUnionMemberRemovedFromMeta = directiveUsageUnionMemberRemovedFromMeta; exports.directiveUsageAdded = directiveUsageAdded; exports.directiveUsageRemoved = directiveUsageRemoved; exports.directiveUsageArgumentAddedFromMeta = directiveUsageArgumentAddedFromMeta; exports.directiveUsageArgumentRemovedFromMeta = directiveUsageArgumentRemovedFromMeta; exports.directiveUsageChanged = directiveUsageChanged; const graphql_1 = require("graphql"); const compare_js_1 = require("../../utils/compare.js"); const change_js_1 = require("./change.js"); function addedSpecialDirective(directiveName, forceReturn) { if (directiveName === 'deprecated') { return change_js_1.CriticalityLevel.NonBreaking; } if (directiveName === 'oneOf') { return change_js_1.CriticalityLevel.Breaking; } return forceReturn; } function removedSpecialDirective(directiveName, forceReturn) { if (directiveName === 'deprecated') { return change_js_1.CriticalityLevel.NonBreaking; } if (directiveName === 'oneOf') { return change_js_1.CriticalityLevel.NonBreaking; } return forceReturn; } function buildDirectiveUsageArgumentDefinitionAddedMessage(args) { return `Directive '${args.addedDirectiveName}' was added to argument '${args.argumentName}' of field '${args.fieldName}' in type '${args.typeName}'`; } function directiveUsageArgumentDefinitionAddedFromMeta(args) { return { criticality: { level: args.meta.addedToNewType ? change_js_1.CriticalityLevel.NonBreaking : addedSpecialDirective(args.meta.addedDirectiveName, change_js_1.CriticalityLevel.Dangerous), reason: `Directive '${args.meta.addedDirectiveName}' was added to argument '${args.meta.argumentName}'`, }, type: change_js_1.ChangeType.DirectiveUsageArgumentDefinitionAdded, message: buildDirectiveUsageArgumentDefinitionAddedMessage(args.meta), path: [ args.meta.typeName, args.meta.fieldName, args.meta.argumentName, `@${args.meta.addedDirectiveName}`, ].join('.'), meta: args.meta, }; } function buildDirectiveUsageArgumentDefinitionRemovedMessage(args) { return `Directive '${args.removedDirectiveName}' was removed from argument '${args.argumentName}' of field '${args.fieldName}' in type '${args.typeName}'`; } function directiveUsageArgumentDefinitionRemovedFromMeta(args) { return { criticality: { level: removedSpecialDirective(args.meta.removedDirectiveName, change_js_1.CriticalityLevel.Dangerous), reason: `Directive '${args.meta.removedDirectiveName}' was removed from argument '${args.meta.argumentName}'`, }, type: change_js_1.ChangeType.DirectiveUsageArgumentDefinitionRemoved, message: buildDirectiveUsageArgumentDefinitionRemovedMessage(args.meta), path: [ args.meta.typeName, args.meta.fieldName, args.meta.argumentName, `@${args.meta.removedDirectiveName}`, ].join('.'), meta: args.meta, }; } function buildDirectiveUsageInputObjectAddedMessage(args) { return `Directive '${args.addedDirectiveName}' was added to input object '${args.inputObjectName}'`; } function directiveUsageInputObjectAddedFromMeta(args) { return { criticality: { level: args.meta.addedToNewType ? change_js_1.CriticalityLevel.NonBreaking : addedSpecialDirective(args.meta.addedDirectiveName, change_js_1.CriticalityLevel.Dangerous), reason: `Directive '${args.meta.addedDirectiveName}' was added to input object '${args.meta.inputObjectName}'`, }, type: change_js_1.ChangeType.DirectiveUsageInputObjectAdded, message: buildDirectiveUsageInputObjectAddedMessage(args.meta), path: [args.meta.inputObjectName, `@${args.meta.addedDirectiveName}`].join('.'), meta: args.meta, }; } function buildDirectiveUsageInputObjectRemovedMessage(args) { return `Directive '${args.removedDirectiveName}' was removed from input object '${args.inputObjectName}'`; } function directiveUsageInputObjectRemovedFromMeta(args) { return { criticality: { level: removedSpecialDirective(args.meta.removedDirectiveName, change_js_1.CriticalityLevel.Dangerous), reason: `Directive '${args.meta.removedDirectiveName}' was removed from input object '${args.meta.inputObjectName}'`, }, type: change_js_1.ChangeType.DirectiveUsageInputObjectRemoved, message: buildDirectiveUsageInputObjectRemovedMessage(args.meta), path: [args.meta.inputObjectName, `@${args.meta.removedDirectiveName}`].join('.'), meta: args.meta, }; } function buildDirectiveUsageInterfaceAddedMessage(args) { return `Directive '${args.addedDirectiveName}' was added to interface '${args.interfaceName}'`; } function directiveUsageInterfaceAddedFromMeta(args) { return { criticality: { level: args.meta.addedToNewType ? change_js_1.CriticalityLevel.NonBreaking : addedSpecialDirective(args.meta.addedDirectiveName, change_js_1.CriticalityLevel.Dangerous), reason: `Directive '${args.meta.addedDirectiveName}' was added to interface '${args.meta.interfaceName}'`, }, type: change_js_1.ChangeType.DirectiveUsageInterfaceAdded, message: buildDirectiveUsageInterfaceAddedMessage(args.meta), path: [args.meta.interfaceName, `@${args.meta.addedDirectiveName}`].join('.'), meta: args.meta, }; } function buildDirectiveUsageInterfaceRemovedMessage(args) { return `Directive '${args.removedDirectiveName}' was removed from interface '${args.interfaceName}'`; } function directiveUsageInterfaceRemovedFromMeta(args) { return { criticality: { level: removedSpecialDirective(args.meta.removedDirectiveName, change_js_1.CriticalityLevel.Dangerous), reason: `Directive '${args.meta.removedDirectiveName}' was removed from interface '${args.meta.interfaceName}'`, }, type: change_js_1.ChangeType.DirectiveUsageInterfaceRemoved, message: buildDirectiveUsageInterfaceRemovedMessage(args.meta), path: [args.meta.interfaceName, `@${args.meta.removedDirectiveName}`].join('.'), meta: args.meta, }; } function buildDirectiveUsageInputFieldDefinitionAddedMessage(args) { return `Directive '${args.addedDirectiveName}' was added to input field '${args.inputFieldName}' in input object '${args.inputObjectName}'`; } function directiveUsageInputFieldDefinitionAddedFromMeta(args) { return { criticality: { level: args.meta.addedToNewType ? change_js_1.CriticalityLevel.NonBreaking : addedSpecialDirective(args.meta.addedDirectiveName, change_js_1.CriticalityLevel.Dangerous), reason: `Directive '${args.meta.addedDirectiveName}' was added to input field '${args.meta.inputFieldName}'`, }, type: change_js_1.ChangeType.DirectiveUsageInputFieldDefinitionAdded, message: buildDirectiveUsageInputFieldDefinitionAddedMessage(args.meta), path: [ args.meta.inputObjectName, args.meta.inputFieldName, `@${args.meta.addedDirectiveName}`, ].join('.'), meta: args.meta, }; } function buildDirectiveUsageInputFieldDefinitionRemovedMessage(args) { return `Directive '${args.removedDirectiveName}' was removed from input field '${args.inputFieldName}' in input object '${args.inputObjectName}'`; } function directiveUsageInputFieldDefinitionRemovedFromMeta(args) { return { criticality: { level: removedSpecialDirective(args.meta.removedDirectiveName, change_js_1.CriticalityLevel.Dangerous), reason: `Directive '${args.meta.removedDirectiveName}' was removed from input field '${args.meta.inputFieldName}'`, }, type: change_js_1.ChangeType.DirectiveUsageInputFieldDefinitionRemoved, message: buildDirectiveUsageInputFieldDefinitionRemovedMessage(args.meta), path: [ args.meta.inputObjectName, args.meta.inputFieldName, `@${args.meta.removedDirectiveName}`, ].join('.'), meta: args.meta, }; } function buildDirectiveUsageObjectAddedMessage(args) { return `Directive '${args.addedDirectiveName}' was added to object '${args.objectName}'`; } function directiveUsageObjectAddedFromMeta(args) { return { criticality: { level: args.meta.addedToNewType ? change_js_1.CriticalityLevel.NonBreaking : addedSpecialDirective(args.meta.addedDirectiveName, change_js_1.CriticalityLevel.Dangerous), reason: `Directive '${args.meta.addedDirectiveName}' was added to object '${args.meta.objectName}'`, }, type: change_js_1.ChangeType.DirectiveUsageObjectAdded, message: buildDirectiveUsageObjectAddedMessage(args.meta), path: [args.meta.objectName, `@${args.meta.addedDirectiveName}`].join('.'), meta: args.meta, }; } function buildDirectiveUsageObjectRemovedMessage(args) { return `Directive '${args.removedDirectiveName}' was removed from object '${args.objectName}'`; } function directiveUsageObjectRemovedFromMeta(args) { return { criticality: { level: removedSpecialDirective(args.meta.removedDirectiveName, change_js_1.CriticalityLevel.Dangerous), reason: `Directive '${args.meta.removedDirectiveName}' was removed from object '${args.meta.objectName}'`, }, type: change_js_1.ChangeType.DirectiveUsageObjectRemoved, message: buildDirectiveUsageObjectRemovedMessage(args.meta), path: [args.meta.objectName, `@${args.meta.removedDirectiveName}`].join('.'), meta: args.meta, }; } function buildDirectiveUsageEnumAddedMessage(args) { return `Directive '${args.addedDirectiveName}' was added to enum '${args.enumName}'`; } function directiveUsageEnumAddedFromMeta(args) { return { criticality: { level: args.meta.addedToNewType ? change_js_1.CriticalityLevel.NonBreaking : addedSpecialDirective(args.meta.addedDirectiveName, change_js_1.CriticalityLevel.Dangerous), reason: `Directive '${args.meta.addedDirectiveName}' was added to enum '${args.meta.enumName}'`, }, type: change_js_1.ChangeType.DirectiveUsageEnumAdded, message: buildDirectiveUsageEnumAddedMessage(args.meta), path: [args.meta.enumName, `@${args.meta.addedDirectiveName}`].join('.'), meta: args.meta, }; } function buildDirectiveUsageEnumRemovedMessage(args) { return `Directive '${args.removedDirectiveName}' was removed from enum '${args.enumName}'`; } function directiveUsageEnumRemovedFromMeta(args) { return { criticality: { level: removedSpecialDirective(args.meta.removedDirectiveName, change_js_1.CriticalityLevel.Dangerous), reason: `Directive '${args.meta.removedDirectiveName}' was removed from enum '${args.meta.enumName}'`, }, type: change_js_1.ChangeType.DirectiveUsageEnumRemoved, message: buildDirectiveUsageEnumRemovedMessage(args.meta), path: [args.meta.enumName, `@${args.meta.removedDirectiveName}`].join('.'), meta: args.meta, }; } function buildDirectiveUsageFieldAddedMessage(args) { return `Directive '${args.addedDirectiveName}' was added to field '${args.typeName}.${args.fieldName}'`; } function directiveUsageFieldAddedFromMeta(args) { return { criticality: { level: addedSpecialDirective(args.meta.addedDirectiveName, change_js_1.CriticalityLevel.Dangerous), reason: `Directive '${args.meta.addedDirectiveName}' was added to field '${args.meta.fieldName}'`, }, type: change_js_1.ChangeType.DirectiveUsageFieldAdded, message: buildDirectiveUsageFieldAddedMessage(args.meta), path: [args.meta.typeName, args.meta.fieldName, args.meta.addedDirectiveName].join('.'), meta: args.meta, }; } function buildDirectiveUsageFieldDefinitionAddedMessage(args) { return `Directive '${args.addedDirectiveName}' was added to field '${args.typeName}.${args.fieldName}'`; } function directiveUsageFieldDefinitionAddedFromMeta(args) { return { criticality: { level: args.meta.addedToNewType ? change_js_1.CriticalityLevel.NonBreaking : addedSpecialDirective(args.meta.addedDirectiveName, change_js_1.CriticalityLevel.Dangerous), reason: `Directive '${args.meta.addedDirectiveName}' was added to field '${args.meta.fieldName}'`, }, type: change_js_1.ChangeType.DirectiveUsageFieldDefinitionAdded, message: buildDirectiveUsageFieldDefinitionAddedMessage(args.meta), path: [args.meta.typeName, args.meta.fieldName, `@${args.meta.addedDirectiveName}`].join('.'), meta: args.meta, }; } function buildDirectiveUsageFieldRemovedMessage(args) { return `Directive '${args.removedDirectiveName}' was removed from field '${args.typeName}.${args.fieldName}'`; } function directiveUsageFieldRemovedFromMeta(args) { return { criticality: { level: removedSpecialDirective(args.meta.removedDirectiveName, change_js_1.CriticalityLevel.Dangerous), reason: `Directive '${args.meta.removedDirectiveName}' was removed from field '${args.meta.fieldName}'`, }, type: change_js_1.ChangeType.DirectiveUsageFieldRemoved, message: buildDirectiveUsageFieldRemovedMessage(args.meta), path: [args.meta.typeName, args.meta.fieldName, args.meta.removedDirectiveName].join('.'), meta: args.meta, }; } function buildDirectiveUsageFieldDefinitionRemovedMessage(args) { return `Directive '${args.removedDirectiveName}' was removed from field '${args.typeName}.${args.fieldName}'`; } function directiveUsageFieldDefinitionRemovedFromMeta(args) { return { criticality: { level: removedSpecialDirective(args.meta.removedDirectiveName, change_js_1.CriticalityLevel.Dangerous), reason: `Directive '${args.meta.removedDirectiveName}' was removed from field '${args.meta.fieldName}'`, }, type: change_js_1.ChangeType.DirectiveUsageFieldDefinitionRemoved, message: buildDirectiveUsageFieldDefinitionRemovedMessage(args.meta), path: [args.meta.typeName, args.meta.fieldName, `@${args.meta.removedDirectiveName}`].join('.'), meta: args.meta, }; } function buildDirectiveUsageEnumValueAddedMessage(args) { return `Directive '${args.addedDirectiveName}' was added to enum value '${args.enumName}.${args.enumValueName}'`; } function directiveUsageEnumValueAddedFromMeta(args) { return { criticality: { level: args.meta.addedToNewType ? change_js_1.CriticalityLevel.NonBreaking : addedSpecialDirective(args.meta.addedDirectiveName, change_js_1.CriticalityLevel.Dangerous), reason: `Directive '${args.meta.addedDirectiveName}' was added to enum value '${args.meta.enumName}.${args.meta.enumValueName}'`, }, type: change_js_1.ChangeType.DirectiveUsageEnumValueAdded, message: buildDirectiveUsageEnumValueAddedMessage(args.meta), path: [args.meta.enumName, args.meta.enumValueName, `@${args.meta.addedDirectiveName}`].join('.'), meta: args.meta, }; } function buildDirectiveUsageEnumValueRemovedMessage(args) { return `Directive '${args.removedDirectiveName}' was removed from enum value '${args.enumName}.${args.enumValueName}'`; } function directiveUsageEnumValueRemovedFromMeta(args) { return { criticality: { level: removedSpecialDirective(args.meta.removedDirectiveName, change_js_1.CriticalityLevel.Dangerous), reason: `Directive '${args.meta.removedDirectiveName}' was removed from enum value '${args.meta.enumName}.${args.meta.enumValueName}'`, }, type: change_js_1.ChangeType.DirectiveUsageEnumValueRemoved, message: buildDirectiveUsageEnumValueRemovedMessage(args.meta), path: [args.meta.enumName, args.meta.enumValueName, `@${args.meta.removedDirectiveName}`].join('.'), meta: args.meta, }; } function buildDirectiveUsageSchemaAddedMessage(args) { return `Directive '${args.addedDirectiveName}' was added to schema '${args.schemaTypeName}'`; } function directiveUsageSchemaAddedFromMeta(args) { return { criticality: { level: args.meta.addedToNewType ? change_js_1.CriticalityLevel.NonBreaking : addedSpecialDirective(args.meta.addedDirectiveName, change_js_1.CriticalityLevel.Dangerous), reason: `Directive '${args.meta.addedDirectiveName}' was added to schema '${args.meta.schemaTypeName}'`, }, type: change_js_1.ChangeType.DirectiveUsageSchemaAdded, message: buildDirectiveUsageSchemaAddedMessage(args.meta), path: `.@${args.meta.addedDirectiveName}`, meta: args.meta, }; } function buildDirectiveUsageSchemaRemovedMessage(args) { return `Directive '${args.removedDirectiveName}' was removed from schema '${args.schemaTypeName}'`; } function directiveUsageSchemaRemovedFromMeta(args) { return { criticality: { level: removedSpecialDirective(args.meta.removedDirectiveName, change_js_1.CriticalityLevel.Dangerous), reason: `Directive '${args.meta.removedDirectiveName}' was removed from schema '${args.meta.schemaTypeName}'`, }, type: change_js_1.ChangeType.DirectiveUsageSchemaRemoved, message: buildDirectiveUsageSchemaRemovedMessage(args.meta), path: `.@${args.meta.removedDirectiveName}`, meta: args.meta, }; } function buildDirectiveUsageScalarAddedMessage(args) { return `Directive '${args.addedDirectiveName}' was added to scalar '${args.scalarName}'`; } function directiveUsageScalarAddedFromMeta(args) { return { criticality: { level: args.meta.addedToNewType ? change_js_1.CriticalityLevel.NonBreaking : addedSpecialDirective(args.meta.addedDirectiveName, change_js_1.CriticalityLevel.Dangerous), reason: `Directive '${args.meta.addedDirectiveName}' was added to scalar '${args.meta.scalarName}'`, }, type: change_js_1.ChangeType.DirectiveUsageScalarAdded, message: buildDirectiveUsageScalarAddedMessage(args.meta), path: [args.meta.scalarName, `@${args.meta.addedDirectiveName}`].join('.'), meta: args.meta, }; } function buildDirectiveUsageScalarRemovedMessage(args) { return `Directive '${args.removedDirectiveName}' was removed from scalar '${args.scalarName}'`; } function directiveUsageScalarRemovedFromMeta(args) { return { criticality: { level: removedSpecialDirective(args.meta.removedDirectiveName, change_js_1.CriticalityLevel.Dangerous), reason: `Directive '${args.meta.removedDirectiveName}' was removed from scalar '${args.meta.scalarName}'`, }, type: change_js_1.ChangeType.DirectiveUsageScalarRemoved, message: buildDirectiveUsageScalarRemovedMessage(args.meta), path: [args.meta.scalarName, `@${args.meta.removedDirectiveName}`].join('.'), meta: args.meta, }; } function buildDirectiveUsageUnionMemberAddedMessage(args) { return `Directive '${args.addedDirectiveName}' was added to union member '${args.unionName}'`; } function directiveUsageUnionMemberAddedFromMeta(args) { return { criticality: { level: args.meta.addedToNewType ? change_js_1.CriticalityLevel.NonBreaking : addedSpecialDirective(args.meta.addedDirectiveName, change_js_1.CriticalityLevel.Dangerous), reason: `Directive '${args.meta.addedDirectiveName}' was added to union member '${args.meta.unionName}.${args.meta.addedUnionMemberTypeName}'`, }, type: change_js_1.ChangeType.DirectiveUsageUnionMemberAdded, message: buildDirectiveUsageUnionMemberAddedMessage(args.meta), path: [args.meta.unionName, `@${args.meta.addedDirectiveName}`].join('.'), meta: args.meta, }; } function buildDirectiveUsageUnionMemberRemovedMessage(args) { return `Directive '${args.removedDirectiveName}' was removed from union member '${args.unionName}'`; } function directiveUsageUnionMemberRemovedFromMeta(args) { return { criticality: { level: removedSpecialDirective(args.meta.removedDirectiveName, change_js_1.CriticalityLevel.Dangerous), reason: `Directive '${args.meta.removedDirectiveName}' was removed from union member '${args.meta.unionName}.${args.meta.removedUnionMemberTypeName}'`, }, type: change_js_1.ChangeType.DirectiveUsageUnionMemberRemoved, message: buildDirectiveUsageUnionMemberRemovedMessage(args.meta), path: [args.meta.unionName, `@${args.meta.removedDirectiveName}`].join('.'), meta: args.meta, }; } function directiveUsageAdded(kind, directive, payload, addedToNewType) { if (isOfKind(kind, graphql_1.Kind.ARGUMENT, payload)) { return directiveUsageArgumentDefinitionAddedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageArgumentDefinitionAdded, meta: { addedDirectiveName: directive.name.value, argumentName: payload.argument.name, fieldName: payload.field.name, typeName: payload.type.name, addedToNewType, directiveRepeatedTimes: directiveRepeatTimes(payload.argument.astNode?.directives ?? [], directive), }, }); } if (isOfKind(kind, graphql_1.Kind.INPUT_VALUE_DEFINITION, payload)) { return directiveUsageInputFieldDefinitionAddedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageInputFieldDefinitionAdded, meta: { addedDirectiveName: directive.name.value, inputFieldName: payload.field.name, inputFieldType: payload.field.type.toString(), inputObjectName: payload.type.name, addedToNewType, directiveRepeatedTimes: directiveRepeatTimes(payload.field.astNode?.directives ?? [], directive), }, }); } if (isOfKind(kind, graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION, payload)) { return directiveUsageInputObjectAddedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageInputObjectAdded, meta: { addedDirectiveName: directive.name.value, addedInputFieldName: directive.name.value, addedInputFieldType: payload.name, inputObjectName: payload.name, isAddedInputFieldTypeNullable: kind === graphql_1.Kind.INPUT_VALUE_DEFINITION, addedToNewType, directiveRepeatedTimes: directiveRepeatTimes(payload.astNode?.directives ?? [], directive), }, }); } if (isOfKind(kind, graphql_1.Kind.INTERFACE_TYPE_DEFINITION, payload)) { return directiveUsageInterfaceAddedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageInterfaceAdded, meta: { addedDirectiveName: directive.name.value, interfaceName: payload.name, addedToNewType, directiveRepeatedTimes: directiveRepeatTimes(payload.astNode?.directives ?? [], directive), }, }); } if (isOfKind(kind, graphql_1.Kind.OBJECT, payload)) { return directiveUsageObjectAddedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageObjectAdded, meta: { objectName: payload.name, addedDirectiveName: directive.name.value, addedToNewType, directiveRepeatedTimes: directiveRepeatTimes(payload.astNode?.directives ?? [], directive), }, }); } if (isOfKind(kind, graphql_1.Kind.ENUM_TYPE_DEFINITION, payload)) { return directiveUsageEnumAddedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageEnumAdded, meta: { enumName: payload.name, addedDirectiveName: directive.name.value, addedToNewType, directiveRepeatedTimes: directiveRepeatTimes(payload.astNode?.directives ?? [], directive), }, }); } if (isOfKind(kind, graphql_1.Kind.FIELD, payload)) { return directiveUsageFieldAddedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageFieldAdded, meta: { addedDirectiveName: directive.name.value, fieldName: payload.field.name, typeName: payload.parentType.name, directiveRepeatedTimes: directiveRepeatTimes(payload.field.astNode?.directives ?? [], directive), }, }); } if (isOfKind(kind, graphql_1.Kind.FIELD_DEFINITION, payload)) { return directiveUsageFieldDefinitionAddedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageFieldDefinitionAdded, meta: { addedDirectiveName: directive.name.value, fieldName: payload.field.name, typeName: payload.parentType.name, addedToNewType, directiveRepeatedTimes: directiveRepeatTimes(payload.field.astNode?.directives ?? [], directive), }, }); } if (isOfKind(kind, graphql_1.Kind.UNION_TYPE_DEFINITION, payload)) { return directiveUsageUnionMemberAddedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageUnionMemberAdded, meta: { addedDirectiveName: directive.name.value, addedUnionMemberTypeName: payload.name, unionName: payload.name, addedToNewType, directiveRepeatedTimes: directiveRepeatTimes(payload.astNode?.directives ?? [], directive), }, }); } if (isOfKind(kind, graphql_1.Kind.ENUM_VALUE_DEFINITION, payload)) { return directiveUsageEnumValueAddedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageEnumValueAdded, meta: { enumName: payload.type.name, enumValueName: payload.value.name, addedDirectiveName: directive.name.value, addedToNewType, directiveRepeatedTimes: directiveRepeatTimes(payload.value.astNode?.directives ?? [], directive), }, }); } if (isOfKind(kind, graphql_1.Kind.SCHEMA_DEFINITION, payload)) { return directiveUsageSchemaAddedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageSchemaAdded, meta: { addedDirectiveName: directive.name.value, schemaTypeName: payload.getQueryType()?.name || '', addedToNewType, directiveRepeatedTimes: directiveRepeatTimes(payload.astNode?.directives ?? [], directive), }, }); } if (isOfKind(kind, graphql_1.Kind.SCALAR_TYPE_DEFINITION, payload)) { return directiveUsageScalarAddedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageScalarAdded, meta: { scalarName: payload.name, addedDirectiveName: directive.name.value, addedToNewType, directiveRepeatedTimes: directiveRepeatTimes(payload.astNode?.directives ?? [], directive), }, }); } return {}; } /** * Counts the number of times a directive with the same name * exists in the directives array before the passed directive. * * This is important for repeatable directives because it * determines which instance of the directive usage the change applies to. */ function directiveRepeatTimes(directives, directive) { const name = directive.name.value; let repeats = 0; for (const d of directives) { if (d.name.value === name) { repeats += 1; } if (d === directive) { return repeats; } } return 0; } function directiveUsageRemoved(kind, directive, payload) { if (isOfKind(kind, graphql_1.Kind.ARGUMENT, payload)) { return directiveUsageArgumentDefinitionRemovedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageArgumentDefinitionRemoved, meta: { removedDirectiveName: directive.name.value, argumentName: payload.argument.name, fieldName: payload.field.name, typeName: payload.type.name, directiveRepeatedTimes: directiveRepeatTimes(payload.argument.astNode?.directives ?? [], directive), }, }); } if (isOfKind(kind, graphql_1.Kind.INPUT_VALUE_DEFINITION, payload)) { return directiveUsageInputFieldDefinitionRemovedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageInputFieldDefinitionRemoved, meta: { removedDirectiveName: directive.name.value, inputFieldName: payload.field.name, inputObjectName: payload.type.name, directiveRepeatedTimes: directiveRepeatTimes(payload.field.astNode?.directives ?? [], directive), }, }); } if (isOfKind(kind, graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION, payload)) { return directiveUsageInputObjectRemovedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageInputObjectRemoved, meta: { removedDirectiveName: directive.name.value, removedInputFieldName: directive.name.value, removedInputFieldType: payload.name, inputObjectName: payload.name, isRemovedInputFieldTypeNullable: kind === graphql_1.Kind.INPUT_VALUE_DEFINITION, directiveRepeatedTimes: directiveRepeatTimes(payload.astNode?.directives ?? [], directive), }, }); } if (isOfKind(kind, graphql_1.Kind.INTERFACE_TYPE_DEFINITION, payload)) { return directiveUsageInterfaceRemovedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageInterfaceRemoved, meta: { removedDirectiveName: directive.name.value, interfaceName: payload.name, directiveRepeatedTimes: directiveRepeatTimes(payload.astNode?.directives ?? [], directive), }, }); } if (isOfKind(kind, graphql_1.Kind.OBJECT, payload)) { return directiveUsageObjectRemovedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageObjectRemoved, meta: { objectName: payload.name, removedDirectiveName: directive.name.value, directiveRepeatedTimes: directiveRepeatTimes(payload.astNode?.directives ?? [], directive), }, }); } if (isOfKind(kind, graphql_1.Kind.ENUM_TYPE_DEFINITION, payload)) { return directiveUsageEnumRemovedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageEnumRemoved, meta: { enumName: payload.name, removedDirectiveName: directive.name.value, directiveRepeatedTimes: directiveRepeatTimes(payload.astNode?.directives ?? [], directive), }, }); } if (isOfKind(kind, graphql_1.Kind.FIELD, payload)) { return directiveUsageFieldRemovedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageFieldRemoved, meta: { removedDirectiveName: directive.name.value, fieldName: payload.field.name, typeName: payload.parentType.name, directiveRepeatedTimes: directiveRepeatTimes(payload.field.astNode?.directives ?? [], directive), }, }); } if (isOfKind(kind, graphql_1.Kind.FIELD_DEFINITION, payload)) { return directiveUsageFieldDefinitionRemovedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageFieldDefinitionRemoved, meta: { removedDirectiveName: directive.name.value, fieldName: payload.field.name, typeName: payload.parentType.name, directiveRepeatedTimes: directiveRepeatTimes(payload.field.astNode?.directives ?? [], directive), }, }); } if (isOfKind(kind, graphql_1.Kind.UNION_TYPE_DEFINITION, payload)) { return directiveUsageUnionMemberRemovedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageUnionMemberRemoved, meta: { removedDirectiveName: directive.name.value, removedUnionMemberTypeName: payload.name, unionName: payload.name, directiveRepeatedTimes: directiveRepeatTimes(payload.astNode?.directives ?? [], directive), }, }); } if (isOfKind(kind, graphql_1.Kind.ENUM_VALUE_DEFINITION, payload)) { return directiveUsageEnumValueRemovedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageEnumValueRemoved, meta: { enumName: payload.type.name, enumValueName: payload.value.name, removedDirectiveName: directive.name.value, directiveRepeatedTimes: directiveRepeatTimes(payload.value.astNode?.directives ?? [], directive), }, }); } if (isOfKind(kind, graphql_1.Kind.SCHEMA_DEFINITION, payload)) { return directiveUsageSchemaRemovedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageSchemaRemoved, meta: { removedDirectiveName: directive.name.value, schemaTypeName: payload.getQueryType()?.name || '', directiveRepeatedTimes: directiveRepeatTimes(payload.astNode?.directives ?? [], directive), }, }); } if (isOfKind(kind, graphql_1.Kind.SCALAR_TYPE_DEFINITION, payload)) { return directiveUsageScalarRemovedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageScalarRemoved, meta: { scalarName: payload.name, removedDirectiveName: directive.name.value, directiveRepeatedTimes: directiveRepeatTimes(payload.astNode?.directives ?? [], directive), }, }); } return {}; } function isOfKind(kind, expectedKind, _value) { return kind === expectedKind; } function directiveUsageArgumentAddedFromMeta(args) { return { type: change_js_1.ChangeType.DirectiveUsageArgumentAdded, criticality: { level: change_js_1.CriticalityLevel.NonBreaking, }, message: `Argument '${args.meta.addedArgumentName}' was added to '@${args.meta.directiveName}'`, path: [ /** If the type is missing then this must be a directive on a schema */ args.meta.parentTypeName ?? '', args.meta.parentFieldName ?? args.meta.parentEnumValueName, args.meta.parentArgumentName, `@${args.meta.directiveName}`, args.meta.addedArgumentName, ] .filter(p => p !== null) .join('.'), meta: args.meta, }; } function directiveUsageArgumentRemovedFromMeta(args) { return { type: change_js_1.ChangeType.DirectiveUsageArgumentRemoved, criticality: { level: change_js_1.CriticalityLevel.Dangerous, reason: `Changing an argument on a directive can change runtime behavior.`, }, message: `Argument '${args.meta.removedArgumentName}' was removed from '@${args.meta.directiveName}'`, path: [ /** If the type is missing then this must be a directive on a schema */ args.meta.parentTypeName ?? '', args.meta.parentFieldName ?? args.meta.parentEnumValueName, args.meta.parentArgumentName, `@${args.meta.directiveName}`, args.meta.removedArgumentName, ] .filter(a => a !== null) .join('.'), meta: args.meta, }; } function directiveUsageChanged(oldDirective, newDirective, addChange, parentType, parentField, parentArgument, parentEnumValue) { (0, compare_js_1.compareLists)(oldDirective?.arguments || [], newDirective.arguments || [], { onAdded(argument) { addChange(directiveUsageArgumentAddedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageArgumentAdded, meta: { addedArgumentName: argument.name.value, addedArgumentValue: (0, graphql_1.print)(argument.value), oldArgumentValue: null, directiveName: newDirective.name.value, parentTypeName: parentType?.name ?? null, parentFieldName: parentField?.name ?? null, parentArgumentName: parentArgument?.name ?? null, parentEnumValueName: parentEnumValue?.name ?? null, directiveRepeatedTimes: // @todo should this lastly fall back to the GraphQLSchema? directiveRepeatTimes((parentEnumValue || parentArgument || parentField || parentType)?.astNode ?.directives ?? [], newDirective), }, })); }, /** Treat a mutual change as a removal then addition. */ onMutual(argument) { if (argument.oldVersion && (0, graphql_1.print)(argument.oldVersion.value) === (0, graphql_1.print)(argument.newVersion.value)) { return; } if (argument.oldVersion) { addChange(directiveUsageArgumentRemovedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageArgumentRemoved, meta: { removedArgumentName: argument.oldVersion.name.value, directiveName: newDirective.name.value, parentTypeName: parentType?.name ?? null, parentFieldName: parentField?.name ?? null, parentArgumentName: parentArgument?.name ?? null, parentEnumValueName: parentEnumValue?.name ?? null, directiveRepeatedTimes: // @todo should this lastly fall back to the GraphQLSchema? directiveRepeatTimes((parentEnumValue || parentArgument || parentField || parentType)?.astNode ?.directives ?? [], newDirective), }, })); } addChange(directiveUsageArgumentAddedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageArgumentAdded, meta: { addedArgumentName: argument.newVersion.name.value, addedArgumentValue: (0, graphql_1.print)(argument.newVersion.value), oldArgumentValue: (argument.oldVersion?.value && (0, graphql_1.print)(argument.oldVersion.value)) ?? null, directiveName: newDirective.name.value, parentTypeName: parentType?.name ?? null, parentFieldName: parentField?.name ?? null, parentArgumentName: parentArgument?.name ?? null, parentEnumValueName: parentEnumValue?.name ?? null, directiveRepeatedTimes: // @todo should this lastly fall back to the GraphQLSchema? directiveRepeatTimes((parentEnumValue || parentArgument || parentField || parentType)?.astNode ?.directives ?? [], newDirective), }, })); }, onRemoved(argument) { addChange(directiveUsageArgumentRemovedFromMeta({ type: change_js_1.ChangeType.DirectiveUsageArgumentRemoved, meta: { removedArgumentName: argument.name.value, directiveName: newDirective.name.value, parentTypeName: parentType?.name ?? null, parentFieldName: parentField?.name ?? null, parentArgumentName: parentArgument?.name ?? null, parentEnumValueName: parentEnumValue?.name ?? null, directiveRepeatedTimes: // @todo should this lastly fall back to the GraphQLSchema? directiveRepeatTimes((parentEnumValue || parentArgument || parentField || parentType)?.astNode ?.directives ?? [], newDirective), }, })); }, }); }