@graphql-inspector/core 3.2.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +70 -68
- package/index.mjs +70 -68
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -696,6 +696,70 @@ function changesInUnion(oldUnion, newUnion, addChange) {
|
|
|
696
696
|
});
|
|
697
697
|
}
|
|
698
698
|
|
|
699
|
+
function compareTwoStrings(str1, str2) {
|
|
700
|
+
if (!str1.length && !str2.length)
|
|
701
|
+
return 1;
|
|
702
|
+
if (!str1.length || !str2.length)
|
|
703
|
+
return 0;
|
|
704
|
+
if (str1.toUpperCase() === str2.toUpperCase())
|
|
705
|
+
return 1;
|
|
706
|
+
if (str1.length === 1 && str2.length === 1)
|
|
707
|
+
return 0;
|
|
708
|
+
const pairs1 = wordLetterPairs(str1);
|
|
709
|
+
const pairs2 = wordLetterPairs(str2);
|
|
710
|
+
const union = pairs1.length + pairs2.length;
|
|
711
|
+
let intersection = 0;
|
|
712
|
+
pairs1.forEach((pair1) => {
|
|
713
|
+
for (let i = 0, pair2; (pair2 = pairs2[i]); i++) {
|
|
714
|
+
if (pair1 !== pair2)
|
|
715
|
+
continue;
|
|
716
|
+
intersection++;
|
|
717
|
+
pairs2.splice(i, 1);
|
|
718
|
+
break;
|
|
719
|
+
}
|
|
720
|
+
});
|
|
721
|
+
return (intersection * 2) / union;
|
|
722
|
+
}
|
|
723
|
+
function findBestMatch(mainString, targetStrings) {
|
|
724
|
+
if (!areArgsValid(mainString, targetStrings))
|
|
725
|
+
throw new Error('Bad arguments: First argument should be a string, second should be an array of strings');
|
|
726
|
+
const ratings = targetStrings.map((target) => ({
|
|
727
|
+
target,
|
|
728
|
+
rating: compareTwoStrings(mainString, target.value),
|
|
729
|
+
}));
|
|
730
|
+
const bestMatch = Array.from(ratings).sort((a, b) => b.rating - a.rating)[0];
|
|
731
|
+
return { ratings, bestMatch };
|
|
732
|
+
}
|
|
733
|
+
function flattenDeep(arr) {
|
|
734
|
+
return Array.isArray(arr)
|
|
735
|
+
? arr.reduce((a, b) => a.concat(flattenDeep(b)), [])
|
|
736
|
+
: [arr];
|
|
737
|
+
}
|
|
738
|
+
function areArgsValid(mainString, targetStrings) {
|
|
739
|
+
if (typeof mainString !== 'string')
|
|
740
|
+
return false;
|
|
741
|
+
if (!Array.isArray(targetStrings))
|
|
742
|
+
return false;
|
|
743
|
+
if (!targetStrings.length)
|
|
744
|
+
return false;
|
|
745
|
+
if (targetStrings.find((s) => typeof s.value !== 'string'))
|
|
746
|
+
return false;
|
|
747
|
+
return true;
|
|
748
|
+
}
|
|
749
|
+
function letterPairs(str) {
|
|
750
|
+
const pairs = [];
|
|
751
|
+
for (let i = 0, max = str.length - 1; i < max; i++)
|
|
752
|
+
pairs[i] = str.substring(i, i + 2);
|
|
753
|
+
return pairs;
|
|
754
|
+
}
|
|
755
|
+
function wordLetterPairs(str) {
|
|
756
|
+
const pairs = str.toUpperCase().split(' ').map(letterPairs);
|
|
757
|
+
return flattenDeep(pairs);
|
|
758
|
+
}
|
|
759
|
+
function safeString(obj) {
|
|
760
|
+
return inspect(obj).replace(/\[Object\: null prototype\] /g, '').replace(/(^')|('$)/g, '');
|
|
761
|
+
}
|
|
762
|
+
|
|
699
763
|
function inputFieldRemoved(input, field) {
|
|
700
764
|
return {
|
|
701
765
|
criticality: {
|
|
@@ -756,10 +820,10 @@ function inputFieldDefaultValueChanged(input, oldField, newField) {
|
|
|
756
820
|
return {
|
|
757
821
|
criticality: {
|
|
758
822
|
level: exports.CriticalityLevel.Dangerous,
|
|
759
|
-
reason: 'Changing the default value for an argument may change the runtime
|
|
823
|
+
reason: 'Changing the default value for an argument may change the runtime behavior of a field if it was never provided.',
|
|
760
824
|
},
|
|
761
825
|
type: exports.ChangeType.InputFieldDefaultValueChanged,
|
|
762
|
-
message: `Input field '${input.name}.${oldField.name}' default value changed from '${oldField.defaultValue}' to '${newField.defaultValue}'`,
|
|
826
|
+
message: `Input field '${input.name}.${oldField.name}' default value changed from '${safeString(oldField.defaultValue)}' to '${safeString(newField.defaultValue)}'`,
|
|
763
827
|
path: [input.name, oldField.name].join('.'),
|
|
764
828
|
};
|
|
765
829
|
}
|
|
@@ -965,8 +1029,10 @@ function fieldTypeChanged(type, oldField, newField) {
|
|
|
965
1029
|
};
|
|
966
1030
|
}
|
|
967
1031
|
function fieldArgumentAdded(type, field, arg) {
|
|
1032
|
+
const isBreaking = graphql.isNonNullType(arg.type) && typeof arg.defaultValue === 'undefined';
|
|
1033
|
+
const defaultValueMsg = typeof arg.defaultValue !== 'undefined' ? ' (with default value) ' : ' ';
|
|
968
1034
|
return {
|
|
969
|
-
criticality:
|
|
1035
|
+
criticality: isBreaking
|
|
970
1036
|
? {
|
|
971
1037
|
level: exports.CriticalityLevel.Breaking,
|
|
972
1038
|
reason: `Adding a required argument to an existing field is a breaking change because it will cause existing uses of this field to error.`,
|
|
@@ -976,7 +1042,7 @@ function fieldArgumentAdded(type, field, arg) {
|
|
|
976
1042
|
reason: `Adding a new argument to an existing field may involve a change in resolve function logic that potentially may cause some side effects.`,
|
|
977
1043
|
},
|
|
978
1044
|
type: exports.ChangeType.FieldArgumentAdded,
|
|
979
|
-
message: `Argument '${arg.name}: ${arg.type}'
|
|
1045
|
+
message: `Argument '${arg.name}: ${arg.type}'${defaultValueMsg}added to field '${type.name}.${field.name}'`,
|
|
980
1046
|
path: [type.name, field.name, arg.name].join('.'),
|
|
981
1047
|
};
|
|
982
1048
|
}
|
|
@@ -992,70 +1058,6 @@ function fieldArgumentRemoved(type, field, arg) {
|
|
|
992
1058
|
};
|
|
993
1059
|
}
|
|
994
1060
|
|
|
995
|
-
function compareTwoStrings(str1, str2) {
|
|
996
|
-
if (!str1.length && !str2.length)
|
|
997
|
-
return 1;
|
|
998
|
-
if (!str1.length || !str2.length)
|
|
999
|
-
return 0;
|
|
1000
|
-
if (str1.toUpperCase() === str2.toUpperCase())
|
|
1001
|
-
return 1;
|
|
1002
|
-
if (str1.length === 1 && str2.length === 1)
|
|
1003
|
-
return 0;
|
|
1004
|
-
const pairs1 = wordLetterPairs(str1);
|
|
1005
|
-
const pairs2 = wordLetterPairs(str2);
|
|
1006
|
-
const union = pairs1.length + pairs2.length;
|
|
1007
|
-
let intersection = 0;
|
|
1008
|
-
pairs1.forEach((pair1) => {
|
|
1009
|
-
for (let i = 0, pair2; (pair2 = pairs2[i]); i++) {
|
|
1010
|
-
if (pair1 !== pair2)
|
|
1011
|
-
continue;
|
|
1012
|
-
intersection++;
|
|
1013
|
-
pairs2.splice(i, 1);
|
|
1014
|
-
break;
|
|
1015
|
-
}
|
|
1016
|
-
});
|
|
1017
|
-
return (intersection * 2) / union;
|
|
1018
|
-
}
|
|
1019
|
-
function findBestMatch(mainString, targetStrings) {
|
|
1020
|
-
if (!areArgsValid(mainString, targetStrings))
|
|
1021
|
-
throw new Error('Bad arguments: First argument should be a string, second should be an array of strings');
|
|
1022
|
-
const ratings = targetStrings.map((target) => ({
|
|
1023
|
-
target,
|
|
1024
|
-
rating: compareTwoStrings(mainString, target.value),
|
|
1025
|
-
}));
|
|
1026
|
-
const bestMatch = Array.from(ratings).sort((a, b) => b.rating - a.rating)[0];
|
|
1027
|
-
return { ratings, bestMatch };
|
|
1028
|
-
}
|
|
1029
|
-
function flattenDeep(arr) {
|
|
1030
|
-
return Array.isArray(arr)
|
|
1031
|
-
? arr.reduce((a, b) => a.concat(flattenDeep(b)), [])
|
|
1032
|
-
: [arr];
|
|
1033
|
-
}
|
|
1034
|
-
function areArgsValid(mainString, targetStrings) {
|
|
1035
|
-
if (typeof mainString !== 'string')
|
|
1036
|
-
return false;
|
|
1037
|
-
if (!Array.isArray(targetStrings))
|
|
1038
|
-
return false;
|
|
1039
|
-
if (!targetStrings.length)
|
|
1040
|
-
return false;
|
|
1041
|
-
if (targetStrings.find((s) => typeof s.value !== 'string'))
|
|
1042
|
-
return false;
|
|
1043
|
-
return true;
|
|
1044
|
-
}
|
|
1045
|
-
function letterPairs(str) {
|
|
1046
|
-
const pairs = [];
|
|
1047
|
-
for (let i = 0, max = str.length - 1; i < max; i++)
|
|
1048
|
-
pairs[i] = str.substring(i, i + 2);
|
|
1049
|
-
return pairs;
|
|
1050
|
-
}
|
|
1051
|
-
function wordLetterPairs(str) {
|
|
1052
|
-
const pairs = str.toUpperCase().split(' ').map(letterPairs);
|
|
1053
|
-
return flattenDeep(pairs);
|
|
1054
|
-
}
|
|
1055
|
-
function safeString(obj) {
|
|
1056
|
-
return inspect(obj).replace(/\[Object\: null prototype\] /g, '');
|
|
1057
|
-
}
|
|
1058
|
-
|
|
1059
1061
|
function fieldArgumentDescriptionChanged(type, field, oldArg, newArg) {
|
|
1060
1062
|
return {
|
|
1061
1063
|
criticality: {
|
package/index.mjs
CHANGED
|
@@ -692,6 +692,70 @@ function changesInUnion(oldUnion, newUnion, addChange) {
|
|
|
692
692
|
});
|
|
693
693
|
}
|
|
694
694
|
|
|
695
|
+
function compareTwoStrings(str1, str2) {
|
|
696
|
+
if (!str1.length && !str2.length)
|
|
697
|
+
return 1;
|
|
698
|
+
if (!str1.length || !str2.length)
|
|
699
|
+
return 0;
|
|
700
|
+
if (str1.toUpperCase() === str2.toUpperCase())
|
|
701
|
+
return 1;
|
|
702
|
+
if (str1.length === 1 && str2.length === 1)
|
|
703
|
+
return 0;
|
|
704
|
+
const pairs1 = wordLetterPairs(str1);
|
|
705
|
+
const pairs2 = wordLetterPairs(str2);
|
|
706
|
+
const union = pairs1.length + pairs2.length;
|
|
707
|
+
let intersection = 0;
|
|
708
|
+
pairs1.forEach((pair1) => {
|
|
709
|
+
for (let i = 0, pair2; (pair2 = pairs2[i]); i++) {
|
|
710
|
+
if (pair1 !== pair2)
|
|
711
|
+
continue;
|
|
712
|
+
intersection++;
|
|
713
|
+
pairs2.splice(i, 1);
|
|
714
|
+
break;
|
|
715
|
+
}
|
|
716
|
+
});
|
|
717
|
+
return (intersection * 2) / union;
|
|
718
|
+
}
|
|
719
|
+
function findBestMatch(mainString, targetStrings) {
|
|
720
|
+
if (!areArgsValid(mainString, targetStrings))
|
|
721
|
+
throw new Error('Bad arguments: First argument should be a string, second should be an array of strings');
|
|
722
|
+
const ratings = targetStrings.map((target) => ({
|
|
723
|
+
target,
|
|
724
|
+
rating: compareTwoStrings(mainString, target.value),
|
|
725
|
+
}));
|
|
726
|
+
const bestMatch = Array.from(ratings).sort((a, b) => b.rating - a.rating)[0];
|
|
727
|
+
return { ratings, bestMatch };
|
|
728
|
+
}
|
|
729
|
+
function flattenDeep(arr) {
|
|
730
|
+
return Array.isArray(arr)
|
|
731
|
+
? arr.reduce((a, b) => a.concat(flattenDeep(b)), [])
|
|
732
|
+
: [arr];
|
|
733
|
+
}
|
|
734
|
+
function areArgsValid(mainString, targetStrings) {
|
|
735
|
+
if (typeof mainString !== 'string')
|
|
736
|
+
return false;
|
|
737
|
+
if (!Array.isArray(targetStrings))
|
|
738
|
+
return false;
|
|
739
|
+
if (!targetStrings.length)
|
|
740
|
+
return false;
|
|
741
|
+
if (targetStrings.find((s) => typeof s.value !== 'string'))
|
|
742
|
+
return false;
|
|
743
|
+
return true;
|
|
744
|
+
}
|
|
745
|
+
function letterPairs(str) {
|
|
746
|
+
const pairs = [];
|
|
747
|
+
for (let i = 0, max = str.length - 1; i < max; i++)
|
|
748
|
+
pairs[i] = str.substring(i, i + 2);
|
|
749
|
+
return pairs;
|
|
750
|
+
}
|
|
751
|
+
function wordLetterPairs(str) {
|
|
752
|
+
const pairs = str.toUpperCase().split(' ').map(letterPairs);
|
|
753
|
+
return flattenDeep(pairs);
|
|
754
|
+
}
|
|
755
|
+
function safeString(obj) {
|
|
756
|
+
return inspect(obj).replace(/\[Object\: null prototype\] /g, '').replace(/(^')|('$)/g, '');
|
|
757
|
+
}
|
|
758
|
+
|
|
695
759
|
function inputFieldRemoved(input, field) {
|
|
696
760
|
return {
|
|
697
761
|
criticality: {
|
|
@@ -752,10 +816,10 @@ function inputFieldDefaultValueChanged(input, oldField, newField) {
|
|
|
752
816
|
return {
|
|
753
817
|
criticality: {
|
|
754
818
|
level: CriticalityLevel.Dangerous,
|
|
755
|
-
reason: 'Changing the default value for an argument may change the runtime
|
|
819
|
+
reason: 'Changing the default value for an argument may change the runtime behavior of a field if it was never provided.',
|
|
756
820
|
},
|
|
757
821
|
type: ChangeType.InputFieldDefaultValueChanged,
|
|
758
|
-
message: `Input field '${input.name}.${oldField.name}' default value changed from '${oldField.defaultValue}' to '${newField.defaultValue}'`,
|
|
822
|
+
message: `Input field '${input.name}.${oldField.name}' default value changed from '${safeString(oldField.defaultValue)}' to '${safeString(newField.defaultValue)}'`,
|
|
759
823
|
path: [input.name, oldField.name].join('.'),
|
|
760
824
|
};
|
|
761
825
|
}
|
|
@@ -961,8 +1025,10 @@ function fieldTypeChanged(type, oldField, newField) {
|
|
|
961
1025
|
};
|
|
962
1026
|
}
|
|
963
1027
|
function fieldArgumentAdded(type, field, arg) {
|
|
1028
|
+
const isBreaking = isNonNullType(arg.type) && typeof arg.defaultValue === 'undefined';
|
|
1029
|
+
const defaultValueMsg = typeof arg.defaultValue !== 'undefined' ? ' (with default value) ' : ' ';
|
|
964
1030
|
return {
|
|
965
|
-
criticality:
|
|
1031
|
+
criticality: isBreaking
|
|
966
1032
|
? {
|
|
967
1033
|
level: CriticalityLevel.Breaking,
|
|
968
1034
|
reason: `Adding a required argument to an existing field is a breaking change because it will cause existing uses of this field to error.`,
|
|
@@ -972,7 +1038,7 @@ function fieldArgumentAdded(type, field, arg) {
|
|
|
972
1038
|
reason: `Adding a new argument to an existing field may involve a change in resolve function logic that potentially may cause some side effects.`,
|
|
973
1039
|
},
|
|
974
1040
|
type: ChangeType.FieldArgumentAdded,
|
|
975
|
-
message: `Argument '${arg.name}: ${arg.type}'
|
|
1041
|
+
message: `Argument '${arg.name}: ${arg.type}'${defaultValueMsg}added to field '${type.name}.${field.name}'`,
|
|
976
1042
|
path: [type.name, field.name, arg.name].join('.'),
|
|
977
1043
|
};
|
|
978
1044
|
}
|
|
@@ -988,70 +1054,6 @@ function fieldArgumentRemoved(type, field, arg) {
|
|
|
988
1054
|
};
|
|
989
1055
|
}
|
|
990
1056
|
|
|
991
|
-
function compareTwoStrings(str1, str2) {
|
|
992
|
-
if (!str1.length && !str2.length)
|
|
993
|
-
return 1;
|
|
994
|
-
if (!str1.length || !str2.length)
|
|
995
|
-
return 0;
|
|
996
|
-
if (str1.toUpperCase() === str2.toUpperCase())
|
|
997
|
-
return 1;
|
|
998
|
-
if (str1.length === 1 && str2.length === 1)
|
|
999
|
-
return 0;
|
|
1000
|
-
const pairs1 = wordLetterPairs(str1);
|
|
1001
|
-
const pairs2 = wordLetterPairs(str2);
|
|
1002
|
-
const union = pairs1.length + pairs2.length;
|
|
1003
|
-
let intersection = 0;
|
|
1004
|
-
pairs1.forEach((pair1) => {
|
|
1005
|
-
for (let i = 0, pair2; (pair2 = pairs2[i]); i++) {
|
|
1006
|
-
if (pair1 !== pair2)
|
|
1007
|
-
continue;
|
|
1008
|
-
intersection++;
|
|
1009
|
-
pairs2.splice(i, 1);
|
|
1010
|
-
break;
|
|
1011
|
-
}
|
|
1012
|
-
});
|
|
1013
|
-
return (intersection * 2) / union;
|
|
1014
|
-
}
|
|
1015
|
-
function findBestMatch(mainString, targetStrings) {
|
|
1016
|
-
if (!areArgsValid(mainString, targetStrings))
|
|
1017
|
-
throw new Error('Bad arguments: First argument should be a string, second should be an array of strings');
|
|
1018
|
-
const ratings = targetStrings.map((target) => ({
|
|
1019
|
-
target,
|
|
1020
|
-
rating: compareTwoStrings(mainString, target.value),
|
|
1021
|
-
}));
|
|
1022
|
-
const bestMatch = Array.from(ratings).sort((a, b) => b.rating - a.rating)[0];
|
|
1023
|
-
return { ratings, bestMatch };
|
|
1024
|
-
}
|
|
1025
|
-
function flattenDeep(arr) {
|
|
1026
|
-
return Array.isArray(arr)
|
|
1027
|
-
? arr.reduce((a, b) => a.concat(flattenDeep(b)), [])
|
|
1028
|
-
: [arr];
|
|
1029
|
-
}
|
|
1030
|
-
function areArgsValid(mainString, targetStrings) {
|
|
1031
|
-
if (typeof mainString !== 'string')
|
|
1032
|
-
return false;
|
|
1033
|
-
if (!Array.isArray(targetStrings))
|
|
1034
|
-
return false;
|
|
1035
|
-
if (!targetStrings.length)
|
|
1036
|
-
return false;
|
|
1037
|
-
if (targetStrings.find((s) => typeof s.value !== 'string'))
|
|
1038
|
-
return false;
|
|
1039
|
-
return true;
|
|
1040
|
-
}
|
|
1041
|
-
function letterPairs(str) {
|
|
1042
|
-
const pairs = [];
|
|
1043
|
-
for (let i = 0, max = str.length - 1; i < max; i++)
|
|
1044
|
-
pairs[i] = str.substring(i, i + 2);
|
|
1045
|
-
return pairs;
|
|
1046
|
-
}
|
|
1047
|
-
function wordLetterPairs(str) {
|
|
1048
|
-
const pairs = str.toUpperCase().split(' ').map(letterPairs);
|
|
1049
|
-
return flattenDeep(pairs);
|
|
1050
|
-
}
|
|
1051
|
-
function safeString(obj) {
|
|
1052
|
-
return inspect(obj).replace(/\[Object\: null prototype\] /g, '');
|
|
1053
|
-
}
|
|
1054
|
-
|
|
1055
1057
|
function fieldArgumentDescriptionChanged(type, field, oldArg, newArg) {
|
|
1056
1058
|
return {
|
|
1057
1059
|
criticality: {
|
package/package.json
CHANGED