UNPKG

@graphql-inspector/core

Version:

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

590 lines (589 loc) • 26.4 kB
import { Kind, } from 'graphql'; import { ChangeType, CriticalityLevel, } from './change.js'; function addedSpecialDirective(directiveName, forceReturn) { if (directiveName === 'deprecated') { return CriticalityLevel.NonBreaking; } if (directiveName === 'oneOf') { return CriticalityLevel.Breaking; } return forceReturn; } function removedSpecialDirective(directiveName, forceReturn) { if (directiveName === 'deprecated') { return CriticalityLevel.NonBreaking; } if (directiveName === 'oneOf') { return 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}'`; } export function directiveUsageArgumentDefinitionAddedFromMeta(args) { return { criticality: { level: addedSpecialDirective(args.meta.addedDirectiveName, CriticalityLevel.Dangerous), reason: `Directive '${args.meta.addedDirectiveName}' was added to argument '${args.meta.argumentName}'`, }, type: 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}'`; } export function directiveUsageArgumentDefinitionRemovedFromMeta(args) { return { criticality: { level: removedSpecialDirective(args.meta.removedDirectiveName, CriticalityLevel.Dangerous), reason: `Directive '${args.meta.removedDirectiveName}' was removed from argument '${args.meta.argumentName}'`, }, type: 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}'`; } export function directiveUsageInputObjectAddedFromMeta(args) { return { criticality: { level: addedSpecialDirective(args.meta.addedDirectiveName, CriticalityLevel.Dangerous), reason: `Directive '${args.meta.addedDirectiveName}' was added to input object '${args.meta.inputObjectName}'`, }, type: 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}'`; } export function directiveUsageInputObjectRemovedFromMeta(args) { return { criticality: { level: removedSpecialDirective(args.meta.removedDirectiveName, CriticalityLevel.Dangerous), reason: `Directive '${args.meta.removedDirectiveName}' was removed from input object '${args.meta.inputObjectName}'`, }, type: 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}'`; } export function directiveUsageInterfaceAddedFromMeta(args) { return { criticality: { level: addedSpecialDirective(args.meta.addedDirectiveName, CriticalityLevel.Dangerous), reason: `Directive '${args.meta.addedDirectiveName}' was added to interface '${args.meta.interfaceName}'`, }, type: 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}'`; } export function directiveUsageInterfaceRemovedFromMeta(args) { return { criticality: { level: removedSpecialDirective(args.meta.removedDirectiveName, CriticalityLevel.Dangerous), reason: `Directive '${args.meta.removedDirectiveName}' was removed from interface '${args.meta.interfaceName}'`, }, type: 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}'`; } export function directiveUsageInputFieldDefinitionAddedFromMeta(args) { return { criticality: { level: addedSpecialDirective(args.meta.addedDirectiveName, CriticalityLevel.Dangerous), reason: `Directive '${args.meta.addedDirectiveName}' was added to input field '${args.meta.inputFieldName}'`, }, type: 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}'`; } export function directiveUsageInputFieldDefinitionRemovedFromMeta(args) { return { criticality: { level: removedSpecialDirective(args.meta.removedDirectiveName, CriticalityLevel.Dangerous), reason: `Directive '${args.meta.removedDirectiveName}' was removed from input field '${args.meta.inputFieldName}'`, }, type: 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}'`; } export function directiveUsageObjectAddedFromMeta(args) { return { criticality: { level: addedSpecialDirective(args.meta.addedDirectiveName, CriticalityLevel.Dangerous), reason: `Directive '${args.meta.addedDirectiveName}' was added to object '${args.meta.objectName}'`, }, type: 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}'`; } export function directiveUsageObjectRemovedFromMeta(args) { return { criticality: { level: removedSpecialDirective(args.meta.removedDirectiveName, CriticalityLevel.Dangerous), reason: `Directive '${args.meta.removedDirectiveName}' was removed from object '${args.meta.objectName}'`, }, type: 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}'`; } export function directiveUsageEnumAddedFromMeta(args) { return { criticality: { level: addedSpecialDirective(args.meta.addedDirectiveName, CriticalityLevel.Dangerous), reason: `Directive '${args.meta.addedDirectiveName}' was added to enum '${args.meta.enumName}'`, }, type: 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}'`; } export function directiveUsageEnumRemovedFromMeta(args) { return { criticality: { level: removedSpecialDirective(args.meta.removedDirectiveName, CriticalityLevel.Dangerous), reason: `Directive '${args.meta.removedDirectiveName}' was removed from enum '${args.meta.enumName}'`, }, type: ChangeType.DirectiveUsageEnumRemoved, message: buildDirectiveUsageEnumRemovedMessage(args.meta), path: [args.meta.enumName, args.meta.removedDirectiveName].join('.'), meta: args.meta, }; } function buildDirectiveUsageFieldDefinitionAddedMessage(args) { return `Directive '${args.addedDirectiveName}' was added to field '${args.typeName}.${args.fieldName}'`; } export function directiveUsageFieldDefinitionAddedFromMeta(args) { return { criticality: { level: addedSpecialDirective(args.meta.addedDirectiveName, CriticalityLevel.Dangerous), reason: `Directive '${args.meta.addedDirectiveName}' was added to field '${args.meta.fieldName}'`, }, type: ChangeType.DirectiveUsageFieldDefinitionAdded, message: buildDirectiveUsageFieldDefinitionAddedMessage(args.meta), path: [args.meta.typeName, args.meta.fieldName, args.meta.addedDirectiveName].join('.'), meta: args.meta, }; } function buildDirectiveUsageFieldDefinitionRemovedMessage(args) { return `Directive '${args.removedDirectiveName}' was removed from field '${args.typeName}.${args.fieldName}'`; } export function directiveUsageFieldDefinitionRemovedFromMeta(args) { return { criticality: { level: removedSpecialDirective(args.meta.removedDirectiveName, CriticalityLevel.Dangerous), reason: `Directive '${args.meta.removedDirectiveName}' was removed from field '${args.meta.fieldName}'`, }, type: 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}'`; } export function directiveUsageEnumValueAddedFromMeta(args) { return { criticality: { level: addedSpecialDirective(args.meta.addedDirectiveName, CriticalityLevel.Dangerous), reason: `Directive '${args.meta.addedDirectiveName}' was added to enum value '${args.meta.enumName}.${args.meta.enumValueName}'`, }, type: 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}'`; } export function directiveUsageEnumValueRemovedFromMeta(args) { return { criticality: { level: removedSpecialDirective(args.meta.removedDirectiveName, CriticalityLevel.Dangerous), reason: `Directive '${args.meta.removedDirectiveName}' was removed from enum value '${args.meta.enumName}.${args.meta.enumValueName}'`, }, type: 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}'`; } export function directiveUsageSchemaAddedFromMeta(args) { return { criticality: { level: addedSpecialDirective(args.meta.addedDirectiveName, CriticalityLevel.Dangerous), reason: `Directive '${args.meta.addedDirectiveName}' was added to schema '${args.meta.schemaTypeName}'`, }, type: ChangeType.DirectiveUsageSchemaAdded, message: buildDirectiveUsageSchemaAddedMessage(args.meta), path: [args.meta.schemaTypeName, args.meta.addedDirectiveName].join('.'), meta: args.meta, }; } function buildDirectiveUsageSchemaRemovedMessage(args) { return `Directive '${args.removedDirectiveName}' was removed from schema '${args.schemaTypeName}'`; } export function directiveUsageSchemaRemovedFromMeta(args) { return { criticality: { level: removedSpecialDirective(args.meta.removedDirectiveName, CriticalityLevel.Dangerous), reason: `Directive '${args.meta.removedDirectiveName}' was removed from schema '${args.meta.schemaTypeName}'`, }, type: ChangeType.DirectiveUsageSchemaRemoved, message: buildDirectiveUsageSchemaRemovedMessage(args.meta), path: [args.meta.schemaTypeName, args.meta.removedDirectiveName].join('.'), meta: args.meta, }; } function buildDirectiveUsageScalarAddedMessage(args) { return `Directive '${args.addedDirectiveName}' was added to scalar '${args.scalarName}'`; } export function directiveUsageScalarAddedFromMeta(args) { return { criticality: { level: addedSpecialDirective(args.meta.addedDirectiveName, CriticalityLevel.Dangerous), reason: `Directive '${args.meta.addedDirectiveName}' was added to scalar '${args.meta.scalarName}'`, }, type: 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}'`; } export function directiveUsageScalarRemovedFromMeta(args) { return { criticality: { level: removedSpecialDirective(args.meta.removedDirectiveName, CriticalityLevel.Dangerous), reason: `Directive '${args.meta.removedDirectiveName}' was removed from scalar '${args.meta.scalarName}'`, }, type: 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}'`; } export function directiveUsageUnionMemberAddedFromMeta(args) { return { criticality: { level: addedSpecialDirective(args.meta.addedDirectiveName, CriticalityLevel.Dangerous), reason: `Directive '${args.meta.addedDirectiveName}' was added to union member '${args.meta.unionName}.${args.meta.addedUnionMemberTypeName}'`, }, type: 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}'`; } export function directiveUsageUnionMemberRemovedFromMeta(args) { return { criticality: { level: removedSpecialDirective(args.meta.removedDirectiveName, CriticalityLevel.Dangerous), reason: `Directive '${args.meta.removedDirectiveName}' was removed from union member '${args.meta.unionName}.${args.meta.removedUnionMemberTypeName}'`, }, type: ChangeType.DirectiveUsageUnionMemberRemoved, message: buildDirectiveUsageUnionMemberRemovedMessage(args.meta), path: [args.meta.unionName, args.meta.removedDirectiveName].join('.'), meta: args.meta, }; } export function directiveUsageAdded(kind, directive, payload) { if (isOfKind(kind, Kind.ARGUMENT, payload)) { return directiveUsageArgumentDefinitionAddedFromMeta({ type: ChangeType.DirectiveUsageArgumentDefinitionAdded, meta: { addedDirectiveName: directive.name.value, argumentName: payload.argument.name, fieldName: payload.field.name, typeName: payload.type.name, }, }); } if (isOfKind(kind, Kind.INPUT_VALUE_DEFINITION, payload)) { return directiveUsageInputFieldDefinitionAddedFromMeta({ type: ChangeType.DirectiveUsageInputFieldDefinitionAdded, meta: { addedDirectiveName: directive.name.value, inputFieldName: payload.field.name, inputObjectName: payload.type.name, }, }); } if (isOfKind(kind, Kind.INPUT_OBJECT_TYPE_DEFINITION, payload)) { return directiveUsageInputObjectAddedFromMeta({ type: ChangeType.DirectiveUsageInputObjectAdded, meta: { addedDirectiveName: directive.name.value, addedInputFieldName: directive.name.value, addedInputFieldType: payload.name, inputObjectName: payload.name, isAddedInputFieldTypeNullable: kind === Kind.INPUT_VALUE_DEFINITION, }, }); } if (isOfKind(kind, Kind.INTERFACE_TYPE_DEFINITION, payload)) { return directiveUsageInterfaceAddedFromMeta({ type: ChangeType.DirectiveUsageInterfaceAdded, meta: { addedDirectiveName: directive.name.value, interfaceName: payload.name, }, }); } if (isOfKind(kind, Kind.OBJECT, payload)) { return directiveUsageObjectAddedFromMeta({ type: ChangeType.DirectiveUsageObjectAdded, meta: { objectName: payload.name, addedDirectiveName: directive.name.value, }, }); } if (isOfKind(kind, Kind.ENUM_TYPE_DEFINITION, payload)) { return directiveUsageEnumAddedFromMeta({ type: ChangeType.DirectiveUsageEnumAdded, meta: { enumName: payload.name, addedDirectiveName: directive.name.value, }, }); } if (isOfKind(kind, Kind.FIELD_DEFINITION, payload)) { return directiveUsageFieldDefinitionAddedFromMeta({ type: ChangeType.DirectiveUsageFieldDefinitionAdded, meta: { addedDirectiveName: directive.name.value, fieldName: payload.field.name, typeName: payload.parentType.name, }, }); } if (isOfKind(kind, Kind.UNION_TYPE_DEFINITION, payload)) { return directiveUsageUnionMemberAddedFromMeta({ type: ChangeType.DirectiveUsageUnionMemberAdded, meta: { addedDirectiveName: directive.name.value, addedUnionMemberTypeName: payload.name, unionName: payload.name, }, }); } if (isOfKind(kind, Kind.ENUM_VALUE_DEFINITION, payload)) { return directiveUsageEnumValueAddedFromMeta({ type: ChangeType.DirectiveUsageEnumValueAdded, meta: { enumName: payload.type.name, enumValueName: payload.value.name, addedDirectiveName: directive.name.value, }, }); } if (isOfKind(kind, Kind.SCHEMA_DEFINITION, payload)) { return directiveUsageSchemaAddedFromMeta({ type: ChangeType.DirectiveUsageSchemaAdded, meta: { addedDirectiveName: directive.name.value, schemaTypeName: payload.getQueryType()?.name || '', }, }); } if (isOfKind(kind, Kind.SCALAR_TYPE_DEFINITION, payload)) { return directiveUsageScalarAddedFromMeta({ type: ChangeType.DirectiveUsageScalarAdded, meta: { scalarName: payload.name, addedDirectiveName: directive.name.value, }, }); } return {}; } export function directiveUsageRemoved(kind, directive, payload) { if (isOfKind(kind, Kind.ARGUMENT, payload)) { return directiveUsageArgumentDefinitionRemovedFromMeta({ type: ChangeType.DirectiveUsageArgumentDefinitionRemoved, meta: { removedDirectiveName: directive.name.value, argumentName: payload.argument.name, fieldName: payload.field.name, typeName: payload.type.name, }, }); } if (isOfKind(kind, Kind.INPUT_VALUE_DEFINITION, payload)) { return directiveUsageInputFieldDefinitionRemovedFromMeta({ type: ChangeType.DirectiveUsageInputFieldDefinitionRemoved, meta: { removedDirectiveName: directive.name.value, inputFieldName: payload.field.name, inputObjectName: payload.type.name, }, }); } if (isOfKind(kind, Kind.INPUT_OBJECT_TYPE_DEFINITION, payload)) { return directiveUsageInputObjectRemovedFromMeta({ type: ChangeType.DirectiveUsageInputObjectRemoved, meta: { removedDirectiveName: directive.name.value, removedInputFieldName: directive.name.value, removedInputFieldType: payload.name, inputObjectName: payload.name, isRemovedInputFieldTypeNullable: kind === Kind.INPUT_VALUE_DEFINITION, }, }); } if (isOfKind(kind, Kind.INTERFACE_TYPE_DEFINITION, payload)) { return directiveUsageInterfaceRemovedFromMeta({ type: ChangeType.DirectiveUsageInterfaceRemoved, meta: { removedDirectiveName: directive.name.value, interfaceName: payload.name, }, }); } if (isOfKind(kind, Kind.OBJECT, payload)) { return directiveUsageObjectRemovedFromMeta({ type: ChangeType.DirectiveUsageObjectRemoved, meta: { objectName: payload.name, removedDirectiveName: directive.name.value, }, }); } if (isOfKind(kind, Kind.ENUM_TYPE_DEFINITION, payload)) { return directiveUsageEnumRemovedFromMeta({ type: ChangeType.DirectiveUsageEnumRemoved, meta: { enumName: payload.name, removedDirectiveName: directive.name.value, }, }); } if (isOfKind(kind, Kind.FIELD_DEFINITION, payload)) { return directiveUsageFieldDefinitionRemovedFromMeta({ type: ChangeType.DirectiveUsageFieldDefinitionRemoved, meta: { removedDirectiveName: directive.name.value, fieldName: payload.field.name, typeName: payload.parentType.name, }, }); } if (isOfKind(kind, Kind.UNION_TYPE_DEFINITION, payload)) { return directiveUsageUnionMemberRemovedFromMeta({ type: ChangeType.DirectiveUsageUnionMemberRemoved, meta: { removedDirectiveName: directive.name.value, removedUnionMemberTypeName: payload.name, unionName: payload.name, }, }); } if (isOfKind(kind, Kind.ENUM_VALUE_DEFINITION, payload)) { return directiveUsageEnumValueRemovedFromMeta({ type: ChangeType.DirectiveUsageEnumValueRemoved, meta: { enumName: payload.type.name, enumValueName: payload.value.name, removedDirectiveName: directive.name.value, }, }); } if (isOfKind(kind, Kind.SCHEMA_DEFINITION, payload)) { return directiveUsageSchemaRemovedFromMeta({ type: ChangeType.DirectiveUsageSchemaRemoved, meta: { removedDirectiveName: directive.name.value, schemaTypeName: payload.getQueryType()?.name || '', }, }); } if (isOfKind(kind, Kind.SCALAR_TYPE_DEFINITION, payload)) { return directiveUsageScalarRemovedFromMeta({ type: ChangeType.DirectiveUsageScalarRemoved, meta: { scalarName: payload.name, removedDirectiveName: directive.name.value, }, }); } return {}; } function isOfKind(kind, expectedKind, _value) { return kind === expectedKind; }