UNPKG

@graphql-inspector/core

Version:

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

325 lines (324 loc) • 12.1 kB
import { isInterfaceType, isNonNullType, } from 'graphql'; import { safeChangeForField } from '../../utils/graphql.js'; import { ChangeType, CriticalityLevel, } from './change.js'; function buildFieldRemovedMessage(args) { return `Field '${args.removedFieldName}' ${args.isRemovedFieldDeprecated ? '(deprecated) ' : ''}was removed from ${args.typeType} '${args.typeName}'`; } export function fieldRemovedFromMeta(args) { return { type: ChangeType.FieldRemoved, criticality: { level: CriticalityLevel.Breaking, reason: args.meta.isRemovedFieldDeprecated ? `Removing a deprecated field is a breaking change. Before removing it, you may want to look at the field's usage to see the impact of removing the field.` : `Removing a field is a breaking change. It is preferable to deprecate the field before removing it.`, }, message: buildFieldRemovedMessage(args.meta), meta: args.meta, path: [args.meta.typeName, args.meta.removedFieldName].join('.'), }; } export function fieldRemoved(type, field) { const entity = isInterfaceType(type) ? 'interface' : 'object type'; return fieldRemovedFromMeta({ type: ChangeType.FieldRemoved, meta: { typeName: type.name, removedFieldName: field.name, isRemovedFieldDeprecated: field.deprecationReason != null, typeType: entity, }, }); } function buildFieldAddedMessage(args) { return `Field '${args.addedFieldName}' was added to ${args.typeType} '${args.typeName}'`; } export function fieldAddedFromMeta(args) { return { type: ChangeType.FieldAdded, criticality: { level: CriticalityLevel.NonBreaking, }, message: buildFieldAddedMessage(args.meta), meta: args.meta, path: [args.meta.typeName, args.meta.addedFieldName].join('.'), }; } export function fieldAdded(type, field) { const entity = isInterfaceType(type) ? 'interface' : 'object type'; return fieldAddedFromMeta({ type: ChangeType.FieldAdded, meta: { typeName: type.name, addedFieldName: field.name, typeType: entity, }, }); } function buildFieldDescriptionChangedMessage(args) { return `Field '${args.typeName}.${args.fieldName}' description changed from '${args.oldDescription}' to '${args.newDescription}'`; } export function fieldDescriptionChangedFromMeta(args) { return { type: ChangeType.FieldDescriptionChanged, criticality: { level: CriticalityLevel.NonBreaking, }, message: buildFieldDescriptionChangedMessage(args.meta), meta: args.meta, path: [args.meta.typeName, args.meta.fieldName].join('.'), }; } export function fieldDescriptionChanged(type, oldField, newField) { return fieldDescriptionChangedFromMeta({ type: ChangeType.FieldDescriptionChanged, meta: { fieldName: oldField.name, typeName: type.name, oldDescription: oldField.description ?? '', newDescription: newField.description ?? '', }, }); } function buildFieldDescriptionAddedMessage(args) { return `Field '${args.typeName}.${args.fieldName}' has description '${args.addedDescription}'`; } export function fieldDescriptionAddedFromMeta(args) { return { type: ChangeType.FieldDescriptionAdded, criticality: { level: CriticalityLevel.NonBreaking, }, message: buildFieldDescriptionAddedMessage(args.meta), meta: args.meta, path: [args.meta.typeName, args.meta.fieldName].join('.'), }; } export function fieldDescriptionAdded(type, field) { return fieldDescriptionAddedFromMeta({ type: ChangeType.FieldDescriptionAdded, meta: { typeName: type.name, fieldName: field.name, addedDescription: field.description ?? '', }, }); } function buildFieldDescriptionRemovedMessage(args) { return `Description was removed from field '${args.typeName}.${args.fieldName}'`; } export function fieldDescriptionRemovedFromMeta(args) { return { type: ChangeType.FieldDescriptionRemoved, criticality: { level: CriticalityLevel.NonBreaking, }, message: buildFieldDescriptionRemovedMessage(args.meta), meta: args.meta, path: [args.meta.typeName, args.meta.fieldName].join('.'), }; } export function fieldDescriptionRemoved(type, field) { return fieldDescriptionRemovedFromMeta({ type: ChangeType.FieldDescriptionRemoved, meta: { typeName: type.name, fieldName: field.name, }, }); } function buildFieldDeprecatedAddedMessage(args) { return `Field '${args.typeName}.${args.fieldName}' is deprecated`; } export function fieldDeprecationAddedFromMeta(args) { return { type: ChangeType.FieldDeprecationAdded, criticality: { level: CriticalityLevel.NonBreaking, }, message: buildFieldDeprecatedAddedMessage(args.meta), meta: args.meta, path: [args.meta.typeName, args.meta.fieldName].join('.'), }; } export function fieldDeprecationAdded(type, field) { return fieldDeprecationAddedFromMeta({ type: ChangeType.FieldDeprecationAdded, meta: { typeName: type.name, fieldName: field.name, }, }); } export function fieldDeprecationRemovedFromMeta(args) { return { type: ChangeType.FieldDeprecationRemoved, criticality: { level: CriticalityLevel.Dangerous, }, message: `Field '${args.meta.typeName}.${args.meta.fieldName}' is no longer deprecated`, meta: args.meta, path: [args.meta.typeName, args.meta.fieldName].join('.'), }; } export function fieldDeprecationRemoved(type, field) { return fieldDeprecationRemovedFromMeta({ type: ChangeType.FieldDeprecationRemoved, meta: { fieldName: field.name, typeName: type.name, }, }); } function buildFieldDeprecationReasonChangedMessage(args) { return `Deprecation reason on field '${args.typeName}.${args.fieldName}' has changed from '${args.oldDeprecationReason}' to '${args.newDeprecationReason}'`; } export function fieldDeprecationReasonChangedFromMeta(args) { return { type: ChangeType.FieldDeprecationReasonChanged, criticality: { level: CriticalityLevel.NonBreaking, }, message: buildFieldDeprecationReasonChangedMessage(args.meta), meta: args.meta, path: [args.meta.typeName, args.meta.fieldName].join('.'), }; } export function fieldDeprecationReasonChanged(type, oldField, newField) { return fieldDeprecationReasonChangedFromMeta({ type: ChangeType.FieldDeprecationReasonChanged, meta: { fieldName: newField.name, typeName: type.name, newDeprecationReason: newField.deprecationReason ?? '', oldDeprecationReason: oldField.deprecationReason ?? '', }, }); } function buildFieldDeprecationReasonAddedMessage(args) { return `Field '${args.typeName}.${args.fieldName}' has deprecation reason '${args.addedDeprecationReason}'`; } export function fieldDeprecationReasonAddedFromMeta(args) { return { type: ChangeType.FieldDeprecationReasonAdded, criticality: { level: CriticalityLevel.NonBreaking, }, message: buildFieldDeprecationReasonAddedMessage(args.meta), meta: args.meta, path: [args.meta.typeName, args.meta.fieldName].join('.'), }; } export function fieldDeprecationReasonAdded(type, field) { return fieldDeprecationReasonAddedFromMeta({ type: ChangeType.FieldDeprecationReasonAdded, meta: { typeName: type.name, fieldName: field.name, addedDeprecationReason: field.deprecationReason ?? '', }, }); } export function fieldDeprecationReasonRemovedFromMeta(args) { return { type: ChangeType.FieldDeprecationReasonRemoved, criticality: { level: CriticalityLevel.NonBreaking, }, message: `Deprecation reason was removed from field '${args.meta.typeName}.${args.meta.fieldName}'`, meta: args.meta, path: [args.meta.typeName, args.meta.fieldName].join('.'), }; } export function fieldDeprecationReasonRemoved(type, field) { return fieldDeprecationReasonRemovedFromMeta({ type: ChangeType.FieldDeprecationReasonRemoved, meta: { typeName: type.name, fieldName: field.name, }, }); } function buildFieldTypeChangedMessage(args) { return `Field '${args.meta.typeName}.${args.meta.fieldName}' changed type from '${args.meta.oldFieldType}' to '${args.meta.newFieldType}'`; } export function fieldTypeChangedFromMeta(args) { return { type: ChangeType.FieldTypeChanged, criticality: { level: args.meta.isSafeFieldTypeChange ? CriticalityLevel.NonBreaking : CriticalityLevel.Breaking, }, message: buildFieldTypeChangedMessage(args), meta: args.meta, path: [args.meta.typeName, args.meta.fieldName].join('.'), }; } export function fieldTypeChanged(type, oldField, newField) { return fieldTypeChangedFromMeta({ type: ChangeType.FieldTypeChanged, meta: { typeName: type.name, fieldName: oldField.name, oldFieldType: oldField.type.toString(), newFieldType: newField.type.toString(), isSafeFieldTypeChange: safeChangeForField(oldField.type, newField.type), }, }); } function buildFieldArgumentAddedMessage(args) { return `Argument '${args.addedArgumentName}: ${args.addedArgumentType}'${args.hasDefaultValue ? ' (with default value) ' : ' '}added to field '${args.typeName}.${args.fieldName}'`; } export function fieldArgumentAddedFromMeta(args) { return { type: ChangeType.FieldArgumentAdded, criticality: { level: args.meta.isAddedFieldArgumentBreaking ? CriticalityLevel.Breaking : CriticalityLevel.Dangerous, }, message: buildFieldArgumentAddedMessage(args.meta), meta: args.meta, path: [args.meta.typeName, args.meta.fieldName, args.meta.addedArgumentName].join('.'), }; } export function fieldArgumentAdded(type, field, arg) { const isBreaking = isNonNullType(arg.type) && typeof arg.defaultValue === 'undefined'; return fieldArgumentAddedFromMeta({ type: ChangeType.FieldArgumentAdded, meta: { typeName: type.name, fieldName: field.name, addedArgumentName: arg.name, addedArgumentType: arg.type.toString(), hasDefaultValue: arg.defaultValue != null, isAddedFieldArgumentBreaking: isBreaking, }, }); } function buildFieldArgumentRemovedMessage(args) { return `Argument '${args.meta.removedFieldArgumentName}: ${args.meta.removedFieldType}' was removed from field '${args.meta.typeName}.${args.meta.fieldName}'`; } export function fieldArgumentRemovedFromMeta(args) { return { type: ChangeType.FieldArgumentRemoved, criticality: { level: CriticalityLevel.Breaking, }, message: buildFieldArgumentRemovedMessage(args), meta: args.meta, path: [args.meta.typeName, args.meta.fieldName, args.meta.removedFieldArgumentName].join('.'), }; } export function fieldArgumentRemoved(type, field, arg) { return fieldArgumentRemovedFromMeta({ type: ChangeType.FieldArgumentRemoved, meta: { typeName: type.name, fieldName: field.name, removedFieldArgumentName: arg.name, removedFieldType: arg.type.toString(), }, }); }