mirror of
https://github.com/retailcrm/graphql-php.git
synced 2025-02-06 07:49:24 +03:00
some functions converted over
This commit is contained in:
parent
7aebf2dbf7
commit
3811181f49
@ -5,8 +5,19 @@
|
||||
|
||||
namespace GraphQL\Utils;
|
||||
|
||||
use GraphQL\Type\Definition\EnumType;
|
||||
use GraphQL\Type\Definition\InputObjectType;
|
||||
use GraphQL\Type\Definition\InterfaceType;
|
||||
use GraphQL\Type\Definition\ListOfType;
|
||||
use GraphQL\Type\Definition\NonNull;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\ScalarType;
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Definition\UnionType;
|
||||
use GraphQL\Type\Schema;
|
||||
|
||||
class FindBreakingChanges {
|
||||
class FindBreakingChanges
|
||||
{
|
||||
|
||||
const BREAKING_CHANGE_FIELD_CHANGED = 'FIELD_CHANGED_KIND';
|
||||
const BREAKING_CHANGE_FIELD_REMOVED = 'FIELD_REMOVED';
|
||||
@ -26,6 +37,24 @@ class FindBreakingChanges {
|
||||
TYPE_ADDED_TO_UNION: 'TYPE_ADDED_TO_UNION',
|
||||
};*/
|
||||
|
||||
/**
|
||||
* Given two schemas, returns an Array containing descriptions of all the types
|
||||
* of potentially dangerous changes covered by the other functions down below.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function findDangerousChanges(
|
||||
Schema $oldSchema, Schema $newSchema
|
||||
)
|
||||
{
|
||||
return [
|
||||
/* ...findArgChanges(oldSchema, newSchema).dangerousChanges,
|
||||
...findValuesAddedToEnums(oldSchema, newSchema),
|
||||
...findTypesAddedToUnions(oldSchema, newSchema)
|
||||
*/
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Given two schemas, returns an Array containing descriptions of all the types
|
||||
* of breaking changes covered by the other functions down below.
|
||||
@ -34,7 +63,8 @@ class FindBreakingChanges {
|
||||
*/
|
||||
public function findBreakingChanges(
|
||||
$oldSchema, $newSchema
|
||||
) {
|
||||
)
|
||||
{
|
||||
return [
|
||||
/*...findRemovedTypes(oldSchema, newSchema),
|
||||
...findTypesThatChangedKind(oldSchema, newSchema),
|
||||
@ -47,43 +77,35 @@ class FindBreakingChanges {
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Given two schemas, returns an Array containing descriptions of all the types
|
||||
* of potentially dangerous changes covered by the other functions down below.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function findDangerousChanges(
|
||||
$oldSchema, $newSchema
|
||||
) {
|
||||
return [
|
||||
/* ...findArgChanges(oldSchema, newSchema).dangerousChanges,
|
||||
...findValuesAddedToEnums(oldSchema, newSchema),
|
||||
...findTypesAddedToUnions(oldSchema, newSchema)
|
||||
*/
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Given two schemas, returns an Array containing descriptions of any breaking
|
||||
* changes in the newSchema related to removing an entire type.
|
||||
*/
|
||||
public function findRemovedTypes(
|
||||
$oldSchema, $newSchema
|
||||
) {
|
||||
/*const oldTypeMap = oldSchema.getTypeMap();
|
||||
const newTypeMap = newSchema.getTypeMap();
|
||||
Schema $oldSchema, Schema $newSchema
|
||||
)
|
||||
{
|
||||
$oldTypeMap = $oldSchema->getTypeMap();
|
||||
$newTypeMap = $newSchema->getTypeMap();
|
||||
|
||||
const breakingChanges = [];
|
||||
Object.keys(oldTypeMap).forEach(typeName => {
|
||||
$breakingChanges = [];
|
||||
foreach ($oldTypeMap as $typeName => $typeDefinition) {
|
||||
if (!isset($newTypeMap[$typeName])) {
|
||||
$breakingChanges[] =
|
||||
['type' => self::BREAKING_CHANGE_TYPE_REMOVED, 'description' => "${$typeName} was removed."];
|
||||
}
|
||||
}
|
||||
|
||||
/*Object.keys(oldTypeMap).forEach(typeName => {
|
||||
if (!newTypeMap[typeName]) {
|
||||
breakingChanges.push({
|
||||
type: BreakingChangeType.TYPE_REMOVED,
|
||||
description: `${typeName} was removed.`,
|
||||
});
|
||||
}
|
||||
});
|
||||
return breakingChanges;*/
|
||||
});*/
|
||||
|
||||
return $breakingChanges;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -91,12 +113,29 @@ class FindBreakingChanges {
|
||||
* changes in the newSchema related to changing the type of a type.
|
||||
*/
|
||||
public function findTypesThatChangedKind(
|
||||
$oldSchema, $newSchema
|
||||
) {
|
||||
/*const oldTypeMap = oldSchema.getTypeMap();
|
||||
const newTypeMap = newSchema.getTypeMap();
|
||||
Schema $oldSchema, Schema $newSchema
|
||||
)
|
||||
{
|
||||
$oldTypeMap = $oldSchema->getTypeMap();
|
||||
$newTypeMap = $newSchema->getTypeMap();
|
||||
|
||||
const breakingChanges = [];
|
||||
$breakingChanges = [];
|
||||
foreach ($oldTypeMap as $typeName => $typeDefinition) {
|
||||
if (!isset($newTypeMap[$typeName])) {
|
||||
continue;
|
||||
}
|
||||
$newTypeDefinition = $newTypeMap[$typeName];
|
||||
if (!($typeDefinition instanceof $newTypeDefinition)) {
|
||||
$oldTypeKindName = self::typeKindName($typeDefinition);
|
||||
$newTypeKindName = self::typeKindName($newTypeDefinition);
|
||||
$breakingChanges[] = [
|
||||
'type' => self::BREAKING_CHANGE_TYPE_CHANGED,
|
||||
'description' => "${$typeName} changed from ${oldTypeKindName} to ${newTypeKindName}."
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Object.keys(oldTypeMap).forEach(typeName => {
|
||||
if (!newTypeMap[typeName]) {
|
||||
return;
|
||||
@ -110,9 +149,9 @@ class FindBreakingChanges {
|
||||
`${typeKindName(oldType)} to ${typeKindName(newType)}.`
|
||||
});
|
||||
}
|
||||
});
|
||||
return breakingChanges;
|
||||
*/
|
||||
});*/
|
||||
|
||||
return $breakingChanges;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -122,14 +161,77 @@ class FindBreakingChanges {
|
||||
* argument's default value).
|
||||
*/
|
||||
public function findArgChanges(
|
||||
$oldSchema, $newSchema
|
||||
) {
|
||||
/* const oldTypeMap = oldSchema.getTypeMap();
|
||||
const newTypeMap = newSchema.getTypeMap();
|
||||
Schema $oldSchema, Schema $newSchema
|
||||
)
|
||||
{
|
||||
$oldTypeMap = $oldSchema->getTypeMap();
|
||||
$newTypeMap = $newSchema->getTypeMap();
|
||||
|
||||
const breakingChanges = [];
|
||||
const dangerousChanges = [];
|
||||
$breakingChanges = [];
|
||||
$dangerousChanges = [];
|
||||
foreach ($oldTypeMap as $oldTypeName => $oldTypeDefinition) {
|
||||
$newTypeDefinition = isset($newTypeMap[$oldTypeName]) ? $newTypeMap[$oldTypeName] : null;
|
||||
if (!($oldTypeDefinition instanceof ObjectType || $oldTypeDefinition instanceof InterfaceType) ||
|
||||
!($newTypeDefinition instanceof $oldTypeDefinition)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$oldTypeFields = $oldTypeDefinition->getFields();
|
||||
$newTypeFields = $newTypeDefinition->getFields();
|
||||
|
||||
foreach ($oldTypeFields as $fieldName => $fieldDefinition) {
|
||||
if (!isset($newTypeFields[$fieldName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($fieldDefinition->args as $oldArgName => $oldArgDef) {
|
||||
$newArgs = $newTypeFields[$fieldName]->args;
|
||||
$newArgDef = Utils::find(
|
||||
$newArgs, function ($arg) use ($oldArgDef) {
|
||||
return $arg->name === $oldArgDef->name;
|
||||
}
|
||||
);
|
||||
if (!$newArgDef) {
|
||||
$breakingChanges[] = [
|
||||
'type' => self::BREAKING_CHANGE_ARG_REMOVED,
|
||||
'description' => "${$oldTypeName}->${$fieldName} arg ${oldArgName} was removed"
|
||||
];
|
||||
} else {
|
||||
$isSafe = self::isChangeSafeForInputObjectFieldOrFieldArg($oldArgDef->getType(), $newArgDef->getType());
|
||||
if (!$isSafe) {
|
||||
$oldArgType = $oldArgDef->getType();
|
||||
$newArgType = $newArgDef->getType();
|
||||
$breakingChanges[] = [
|
||||
'type' => self::BREAKING_CHANGE_ARG_CHANGED,
|
||||
'description' => "${oldTypeName}->${fieldName} arg ${oldArgName} has changed type from ${oldArgType} to ${newArgType}"
|
||||
];
|
||||
} elseif ($oldArgDef->defaultValueExists() && $oldArgDef->defaultValue !== $newArgDef->defaultValue) {
|
||||
$dangerousChanges[] = []; // TODO
|
||||
}
|
||||
}
|
||||
// Check if a non-null arg was added to the field
|
||||
foreach ($newTypeFields[$fieldName]->args as $newArgName => $newArgDef) {
|
||||
$oldArgs = $oldTypeFields[$fieldName]->args;
|
||||
$oldArgDef = Utils::find(
|
||||
$oldArgs, function ($arg) use ($newArgDef) {
|
||||
return $arg->name === $newArgDef->name;
|
||||
}
|
||||
);
|
||||
|
||||
if (!$oldArgDef && $newArgDef->getType() instanceof NonNull) {
|
||||
$newTypeName = $newTypeDefinition->name;
|
||||
$breakingChanges[] = [
|
||||
'type' => self::BREAKING_CHANGE_NON_NULL_ARG_ADDED,
|
||||
'description' => "A non-null arg ${$newArgName} on ${newTypeName}->${fieldName} was added."
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ['breakingChanges' => $breakingChanges, 'dangerousChanges' => $dangerousChanges];
|
||||
/*
|
||||
Object.keys(oldTypeMap).forEach(typeName => {
|
||||
const oldType = oldTypeMap[typeName];
|
||||
const newType = newTypeMap[typeName];
|
||||
@ -207,26 +309,29 @@ class FindBreakingChanges {
|
||||
};*/
|
||||
}
|
||||
|
||||
private static function typeKindName($type) {
|
||||
/* if (type instanceof GraphQLScalarType) {
|
||||
/**
|
||||
* @param Type $type
|
||||
* @return string
|
||||
*
|
||||
* @throws \TypeError
|
||||
*/
|
||||
private static function typeKindName(Type $type)
|
||||
{
|
||||
if ($type instanceof ScalarType) {
|
||||
return 'a Scalar type';
|
||||
}
|
||||
if (type instanceof GraphQLObjectType) {
|
||||
} elseif($type instanceof ObjectType) {
|
||||
return 'an Object type';
|
||||
}
|
||||
if (type instanceof GraphQLInterfaceType) {
|
||||
} elseif ($type instanceof InterfaceType) {
|
||||
return 'an Interface type';
|
||||
}
|
||||
if (type instanceof GraphQLUnionType) {
|
||||
} elseif ($type instanceof UnionType) {
|
||||
return 'a Union type';
|
||||
}
|
||||
if (type instanceof GraphQLEnumType) {
|
||||
} elseif ($type instanceof EnumType) {
|
||||
return 'an Enum type';
|
||||
}
|
||||
if (type instanceof GraphQLInputObjectType) {
|
||||
} elseif ($type instanceof InputObjectType) {
|
||||
return 'an Input type';
|
||||
}
|
||||
throw new TypeError('Unknown type ' + type.constructor.name);*/
|
||||
|
||||
throw new \TypeError('unknown type ' . $type->name);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -236,8 +341,9 @@ class FindBreakingChanges {
|
||||
* a non-null field is added to an input type.
|
||||
*/
|
||||
public static function findFieldsThatChangedType(
|
||||
$oldSchema, $newSchema
|
||||
) {
|
||||
Schema $oldSchema, Schema $newSchema
|
||||
)
|
||||
{
|
||||
/*return [
|
||||
...findFieldsThatChangedTypeOnObjectOrInterfaceTypes(oldSchema, newSchema),
|
||||
...findFieldsThatChangedTypeOnInputObjectTypes(oldSchema, newSchema),
|
||||
@ -246,7 +352,8 @@ class FindBreakingChanges {
|
||||
|
||||
private static function findFieldsThatChangedTypeOnObjectOrInterfaceTypes(
|
||||
$oldSchema, $newSchema
|
||||
) {
|
||||
)
|
||||
{
|
||||
/*const oldTypeMap = oldSchema.getTypeMap();
|
||||
const newTypeMap = newSchema.getTypeMap();
|
||||
|
||||
@ -296,8 +403,9 @@ class FindBreakingChanges {
|
||||
}
|
||||
|
||||
public static function findFieldsThatChangedTypeOnInputObjectTypes(
|
||||
$oldSchema, $newSchema
|
||||
) {
|
||||
Schema $oldSchema, Schema $newSchema
|
||||
)
|
||||
{
|
||||
/* const oldTypeMap = oldSchema.getTypeMap();
|
||||
const newTypeMap = newSchema.getTypeMap();
|
||||
|
||||
@ -360,8 +468,31 @@ class FindBreakingChanges {
|
||||
}
|
||||
|
||||
private static function isChangeSafeForObjectOrInterfaceField(
|
||||
$oldType, $newType
|
||||
) {
|
||||
Type $oldType, Type $newType
|
||||
)
|
||||
{
|
||||
if (self::isNamedType($oldType)) {
|
||||
// if they're both named types, see if their names are equivalent
|
||||
return (self::isNamedType($newType) && $oldType->name === $newType->name)
|
||||
// moving from nullable to non-null of the same underlying type is safe
|
||||
|| ($newType instanceof NonNull
|
||||
&& self::isChangeSafeForObjectOrInterfaceField(
|
||||
$oldType, $newType->getWrappedType()
|
||||
));
|
||||
} elseif ($oldType instanceof ListOfType) {
|
||||
// if they're both lists, make sure the underlying types are compatible
|
||||
return ($newType instanceof ListOfType &&
|
||||
self::isChangeSafeForObjectOrInterfaceField($oldType->getWrappedType(), $newType->getWrappedType())) ||
|
||||
// moving from nullable to non-null of the same underlying type is safe
|
||||
($newType instanceof NonNull &&
|
||||
self::isChangeSafeForObjectOrInterfaceField($oldType, $newType->getWrappedType()));
|
||||
} elseif ($oldType instanceof NonNull) {
|
||||
// if they're both non-null, make sure the underlying types are compatible
|
||||
return $newType instanceof NonNull &&
|
||||
self::isChangeSafeForObjectOrInterfaceField($oldType->getWrappedType(), $newType->getWrappedType());
|
||||
}
|
||||
|
||||
return false;
|
||||
/*if (isNamedType(oldType)) {
|
||||
return (
|
||||
// if they're both named types, see if their names are equivalent
|
||||
@ -404,8 +535,9 @@ class FindBreakingChanges {
|
||||
}
|
||||
|
||||
private static function isChangeSafeForInputObjectFieldOrFieldArg(
|
||||
$oldType, $newType
|
||||
) {
|
||||
Schema $oldSchema, Schema $newSchema
|
||||
)
|
||||
{
|
||||
/* if (isNamedType(oldType)) {
|
||||
// if they're both named types, see if their names are equivalent
|
||||
return isNamedType(newType) && oldType.name === newType.name;
|
||||
@ -443,8 +575,9 @@ class FindBreakingChanges {
|
||||
* changes in the newSchema related to removing types from a union type.
|
||||
*/
|
||||
public static function findTypesRemovedFromUnions(
|
||||
$oldSchema, $newSchema
|
||||
) {
|
||||
Schema $oldSchema, Schema $newSchema
|
||||
)
|
||||
{
|
||||
/* const oldTypeMap = oldSchema.getTypeMap();
|
||||
const newTypeMap = newSchema.getTypeMap();
|
||||
|
||||
@ -477,8 +610,9 @@ class FindBreakingChanges {
|
||||
* changes in the newSchema related to adding types to a union type.
|
||||
*/
|
||||
public static function findTypesAddedToUnions(
|
||||
$oldSchema, $newSchema
|
||||
) {
|
||||
Schema $oldSchema, Schema $newSchema
|
||||
)
|
||||
{
|
||||
/* const oldTypeMap = oldSchema.getTypeMap();
|
||||
const newTypeMap = newSchema.getTypeMap();
|
||||
|
||||
@ -511,8 +645,9 @@ class FindBreakingChanges {
|
||||
* changes in the newSchema related to removing values from an enum type.
|
||||
*/
|
||||
public static function findValuesRemovedFromEnums(
|
||||
$oldSchema, $newSchema
|
||||
) {
|
||||
Schema $oldSchema, Schema $newSchema
|
||||
)
|
||||
{
|
||||
/* const oldTypeMap = oldSchema.getTypeMap();
|
||||
const newTypeMap = newSchema.getTypeMap();
|
||||
|
||||
@ -545,8 +680,9 @@ class FindBreakingChanges {
|
||||
* changes in the newSchema related to adding values to an enum type.
|
||||
*/
|
||||
public static function findValuesAddedToEnums(
|
||||
$oldSchema, $newSchema
|
||||
) {
|
||||
Schema $oldSchema, Schema $newSchema
|
||||
)
|
||||
{
|
||||
/* const oldTypeMap = oldSchema.getTypeMap();
|
||||
const newTypeMap = newSchema.getTypeMap();
|
||||
|
||||
@ -576,8 +712,9 @@ class FindBreakingChanges {
|
||||
}
|
||||
|
||||
public static function findInterfacesRemovedFromObjectTypes(
|
||||
$oldSchema, $newSchema
|
||||
) {
|
||||
Schema $oldSchema, Schema $newSchema
|
||||
)
|
||||
{
|
||||
/* const oldTypeMap = oldSchema.getTypeMap();
|
||||
const newTypeMap = newSchema.getTypeMap();
|
||||
const breakingChanges = [];
|
||||
@ -606,4 +743,21 @@ class FindBreakingChanges {
|
||||
});
|
||||
return breakingChanges;*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Type $type
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function isNamedType(Type $type)
|
||||
{
|
||||
return (
|
||||
$type instanceof ScalarType ||
|
||||
$type instanceof ObjectType ||
|
||||
$type instanceof InterfaceType ||
|
||||
$type instanceof UnionType ||
|
||||
$type instanceof EnumType ||
|
||||
$type instanceof InputObjectType
|
||||
);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user