export function toInspectorChange()

in controlplane/src/core/services/SchemaUsageTrafficInspector.ts [196:326]


export function toInspectorChange(change: SchemaDiff, schemaCheckId: string): InspectorSchemaChange | null {
  const path = change.path.split('.');

  switch (change.changeType) {
    // Not inspectable yet
    case ChangeType.SchemaMutationTypeChanged:
    case ChangeType.SchemaQueryTypeChanged:
    case ChangeType.SchemaSubscriptionTypeChanged:
    case ChangeType.DirectiveRemoved:
    case ChangeType.DirectiveArgumentAdded:
    case ChangeType.DirectiveArgumentRemoved:
    case ChangeType.DirectiveArgumentDefaultValueChanged:
    case ChangeType.DirectiveArgumentTypeChanged:
    case ChangeType.DirectiveLocationRemoved: {
      // We cannot inspect these changes. We want to return null instead of throwing an error.
      // This is so that other changes that we can in fact inspect are not skipped over in the schema check.
      return null;
    }

    // Safe to ignore
    case ChangeType.DirectiveAdded:
    case ChangeType.FieldArgumentDescriptionChanged:
    case ChangeType.FieldArgumentDefaultChanged:
    case ChangeType.DirectiveDescriptionChanged:
    case ChangeType.DirectiveArgumentDescriptionChanged:
    case ChangeType.DirectiveLocationAdded:
    case ChangeType.EnumValueDescriptionChanged:
    case ChangeType.EnumValueDeprecationReasonChanged:
    case ChangeType.EnumValueDeprecationReasonAdded:
    case ChangeType.EnumValueDeprecationReasonRemoved:
    case ChangeType.FieldDescriptionChanged:
    case ChangeType.FieldDescriptionAdded:
    case ChangeType.FieldDescriptionRemoved:
    case ChangeType.FieldDeprecationAdded:
    case ChangeType.FieldDeprecationRemoved:
    case ChangeType.FieldDeprecationReasonChanged:
    case ChangeType.FieldDeprecationReasonAdded:
    case ChangeType.FieldDeprecationReasonRemoved:
    case ChangeType.InputFieldDescriptionAdded:
    case ChangeType.InputFieldDescriptionRemoved:
    case ChangeType.InputFieldDescriptionChanged:
    case ChangeType.InputFieldDefaultValueChanged:
    case ChangeType.TypeDescriptionChanged:
    case ChangeType.TypeDescriptionRemoved:
    case ChangeType.TypeDescriptionAdded:
    case ChangeType.TypeAdded:
    case ChangeType.FieldAdded:
    case ChangeType.UnionMemberAdded:
    case ChangeType.DirectiveUsageUnionMemberAdded:
    case ChangeType.DirectiveUsageUnionMemberRemoved:
    case ChangeType.DirectiveUsageEnumAdded:
    case ChangeType.DirectiveUsageEnumRemoved:
    case ChangeType.DirectiveUsageEnumValueAdded:
    case ChangeType.DirectiveUsageEnumValueRemoved:
    case ChangeType.DirectiveUsageInputObjectAdded:
    case ChangeType.DirectiveUsageInputObjectRemoved:
    case ChangeType.DirectiveUsageFieldAdded:
    case ChangeType.DirectiveUsageFieldRemoved:
    case ChangeType.DirectiveUsageScalarAdded:
    case ChangeType.DirectiveUsageScalarRemoved:
    case ChangeType.DirectiveUsageObjectAdded:
    case ChangeType.DirectiveUsageObjectRemoved:
    case ChangeType.DirectiveUsageInterfaceAdded:
    case ChangeType.DirectiveUsageInterfaceRemoved:
    case ChangeType.DirectiveUsageArgumentDefinitionAdded:
    case ChangeType.DirectiveUsageArgumentDefinitionRemoved:
    case ChangeType.DirectiveUsageSchemaAdded:
    case ChangeType.DirectiveUsageSchemaRemoved:
    case ChangeType.DirectiveUsageFieldDefinitionAdded:
    case ChangeType.DirectiveUsageFieldDefinitionRemoved:
    case ChangeType.DirectiveUsageInputFieldDefinitionAdded:
    case ChangeType.DirectiveUsageInputFieldDefinitionRemoved: {
      return null;
    }
    // 1. When a type is removed we know the exact type name e.g. 'Engineer'. We have no field name.
    // 2. When an interface type is removed or added we know the interface 'RoleType'. We have no field name.
    case ChangeType.TypeRemoved:
    case ChangeType.TypeKindChanged:
    case ChangeType.ObjectTypeInterfaceAdded:
    case ChangeType.ObjectTypeInterfaceRemoved: {
      return {
        schemaChangeId: schemaCheckId,
        typeName: path[0],
      };
    }
    // 1. When a field is removed we know the exact type and field name e.g. 'Engineer.name'
    // 2. When a field type has changed in a breaking way, we know the exact type name and field name e.g. 'Engineer.name'
    case ChangeType.FieldRemoved:
    case ChangeType.FieldTypeChanged: {
      return {
        schemaChangeId: schemaCheckId,
        typeName: path[0],
        fieldName: path[1],
      };
    }
    // 1. When an enum value is added or removed, we only know the affected type. This is fine because any change to an enum value is breaking.
    // 2. When a union member is removed, we only know the affected parent type. We use namedType to check for the usage of the union member.
    case ChangeType.UnionMemberRemoved:
    case ChangeType.EnumValueAdded:
    case ChangeType.EnumValueRemoved: {
      return {
        schemaChangeId: schemaCheckId,
        namedType: path[0],
      };
    }
    // 1. When the type of input field has changed, we know the exact type name and field name e.g. 'MyInput.name'
    case ChangeType.InputFieldTypeChanged:
    case ChangeType.InputFieldRemoved:
    case ChangeType.InputFieldAdded: {
      return {
        schemaChangeId: schemaCheckId,
        fieldName: path[1],
        typeName: path[0],
        isInput: true,
      };
    }
    // 1. When an argument has changed, we know the exact path to the argument e.g. 'Query.engineer.id'
    // and the type name e.g. 'Query'
    case ChangeType.FieldArgumentRemoved:
    case ChangeType.FieldArgumentAdded: // Only when a required argument is added
    case ChangeType.FieldArgumentTypeChanged: {
      return {
        schemaChangeId: schemaCheckId,
        path: path.slice(1), // The path to the updated argument e.g. 'engineer.name' of the type names
        typeName: path[0], // Enclosing type e.g. 'Query' or 'Engineer' when the argument is on a field of type Engineer
        isArgument: true,
      };
    }
  }
  // no return to enforce that all cases are handled
}