@graphql-eslint/eslint-plugin 2.3.0-alpha-f7157af.0 → 2.3.2-alpha-2901045.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/README.md +1 -1
- package/docs/README.md +1 -1
- package/docs/custom-rules.md +3 -3
- package/docs/rules/alphabetize.md +6 -1
- package/docs/rules/avoid-duplicate-fields.md +6 -1
- package/docs/rules/avoid-operation-name-prefix.md +5 -1
- package/docs/rules/avoid-scalar-result-type-on-mutation.md +6 -1
- package/docs/rules/avoid-typename-prefix.md +6 -1
- package/docs/rules/description-style.md +6 -1
- package/docs/rules/executable-definitions.md +6 -1
- package/docs/rules/fields-on-correct-type.md +6 -1
- package/docs/rules/fragments-on-composite-type.md +6 -1
- package/docs/rules/input-name.md +6 -1
- package/docs/rules/known-argument-names.md +6 -1
- package/docs/rules/known-directives.md +6 -1
- package/docs/rules/known-fragment-names.md +6 -1
- package/docs/rules/known-type-names.md +6 -1
- package/docs/rules/lone-anonymous-operation.md +6 -1
- package/docs/rules/lone-schema-definition.md +6 -1
- package/docs/rules/match-document-filename.md +6 -1
- package/docs/rules/naming-convention.md +6 -1
- package/docs/rules/no-anonymous-operations.md +6 -1
- package/docs/rules/no-case-insensitive-enum-values-duplicates.md +5 -1
- package/docs/rules/no-deprecated.md +6 -1
- package/docs/rules/no-fragment-cycles.md +6 -1
- package/docs/rules/no-hashtag-description.md +6 -1
- package/docs/rules/no-operation-name-suffix.md +5 -1
- package/docs/rules/no-undefined-variables.md +6 -1
- package/docs/rules/no-unreachable-types.md +6 -1
- package/docs/rules/no-unused-fields.md +6 -1
- package/docs/rules/no-unused-fragments.md +6 -1
- package/docs/rules/no-unused-variables.md +6 -1
- package/docs/rules/one-field-subscriptions.md +6 -1
- package/docs/rules/overlapping-fields-can-be-merged.md +6 -1
- package/docs/rules/possible-fragment-spread.md +6 -1
- package/docs/rules/possible-type-extension.md +6 -1
- package/docs/rules/provided-required-arguments.md +6 -1
- package/docs/rules/require-deprecation-date.md +6 -1
- package/docs/rules/require-deprecation-reason.md +6 -1
- package/docs/rules/require-description.md +6 -1
- package/docs/rules/require-field-of-type-query-in-mutation-result.md +6 -1
- package/docs/rules/require-id-when-available.md +6 -1
- package/docs/rules/scalar-leafs.md +6 -1
- package/docs/rules/selection-set-depth.md +6 -1
- package/docs/rules/strict-id-in-types.md +6 -1
- package/docs/rules/unique-argument-names.md +6 -1
- package/docs/rules/unique-directive-names-per-location.md +6 -1
- package/docs/rules/unique-directive-names.md +6 -1
- package/docs/rules/unique-enum-value-names.md +6 -1
- package/docs/rules/unique-field-definition-names.md +6 -1
- package/docs/rules/unique-fragment-name.md +6 -1
- package/docs/rules/unique-input-field-names.md +6 -1
- package/docs/rules/unique-operation-name.md +6 -1
- package/docs/rules/unique-operation-types.md +6 -1
- package/docs/rules/unique-type-names.md +6 -1
- package/docs/rules/unique-variable-names.md +6 -1
- package/docs/rules/value-literals-of-correct-type.md +6 -1
- package/docs/rules/variables-are-input-types.md +6 -1
- package/docs/rules/variables-in-allowed-position.md +6 -1
- package/index.js +167 -55
- package/index.mjs +167 -55
- package/package.json +1 -1
- package/testkit.d.ts +5 -3
- package/types.d.ts +2 -0
- package/utils.d.ts +4 -0
@@ -43,4 +43,9 @@ fragment AllUserFields on User {
|
|
43
43
|
fragment UserFields on User {
|
44
44
|
id
|
45
45
|
}
|
46
|
-
```
|
46
|
+
```
|
47
|
+
|
48
|
+
## Resources
|
49
|
+
|
50
|
+
- [Rule source](../../packages/plugin/src/rules/unique-fragment-name.ts)
|
51
|
+
- [Test source](../../packages/plugin/tests/unique-fragment-name.spec.ts)
|
@@ -9,4 +9,9 @@
|
|
9
9
|
|
10
10
|
A GraphQL input object value is only valid if all supplied fields are uniquely named.
|
11
11
|
|
12
|
-
> This rule is a wrapper around a `graphql-js` validation function. [You can find its source code here](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/UniqueInputFieldNamesRule.ts).
|
12
|
+
> This rule is a wrapper around a `graphql-js` validation function. [You can find its source code here](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/UniqueInputFieldNamesRule.ts).
|
13
|
+
|
14
|
+
## Resources
|
15
|
+
|
16
|
+
- [Rule source](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/UniqueInputFieldNamesRule.ts)
|
17
|
+
- [Test source](https://github.com/graphql/graphql-js/tree/main/src/validation/__tests__/UniqueInputFieldNamesRule-test.ts)
|
@@ -9,4 +9,9 @@
|
|
9
9
|
|
10
10
|
A GraphQL document is only valid if it has only one type per operation.
|
11
11
|
|
12
|
-
> This rule is a wrapper around a `graphql-js` validation function. [You can find its source code here](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/UniqueOperationTypesRule.ts).
|
12
|
+
> This rule is a wrapper around a `graphql-js` validation function. [You can find its source code here](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/UniqueOperationTypesRule.ts).
|
13
|
+
|
14
|
+
## Resources
|
15
|
+
|
16
|
+
- [Rule source](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/UniqueOperationTypesRule.ts)
|
17
|
+
- [Test source](https://github.com/graphql/graphql-js/tree/main/src/validation/__tests__/UniqueOperationTypesRule-test.ts)
|
@@ -9,4 +9,9 @@
|
|
9
9
|
|
10
10
|
A GraphQL document is only valid if all defined types have unique names.
|
11
11
|
|
12
|
-
> This rule is a wrapper around a `graphql-js` validation function. [You can find its source code here](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/UniqueTypeNamesRule.ts).
|
12
|
+
> This rule is a wrapper around a `graphql-js` validation function. [You can find its source code here](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/UniqueTypeNamesRule.ts).
|
13
|
+
|
14
|
+
## Resources
|
15
|
+
|
16
|
+
- [Rule source](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/UniqueTypeNamesRule.ts)
|
17
|
+
- [Test source](https://github.com/graphql/graphql-js/tree/main/src/validation/__tests__/UniqueTypeNamesRule-test.ts)
|
@@ -9,4 +9,9 @@
|
|
9
9
|
|
10
10
|
A GraphQL operation is only valid if all its variables are uniquely named.
|
11
11
|
|
12
|
-
> This rule is a wrapper around a `graphql-js` validation function. [You can find its source code here](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/UniqueVariableNamesRule.ts).
|
12
|
+
> This rule is a wrapper around a `graphql-js` validation function. [You can find its source code here](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/UniqueVariableNamesRule.ts).
|
13
|
+
|
14
|
+
## Resources
|
15
|
+
|
16
|
+
- [Rule source](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/UniqueVariableNamesRule.ts)
|
17
|
+
- [Test source](https://github.com/graphql/graphql-js/tree/main/src/validation/__tests__/UniqueVariableNamesRule-test.ts)
|
@@ -9,4 +9,9 @@
|
|
9
9
|
|
10
10
|
A GraphQL document is only valid if all value literals are of the type expected at their position.
|
11
11
|
|
12
|
-
> This rule is a wrapper around a `graphql-js` validation function. [You can find its source code here](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/ValuesOfCorrectTypeRule.ts).
|
12
|
+
> This rule is a wrapper around a `graphql-js` validation function. [You can find its source code here](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/ValuesOfCorrectTypeRule.ts).
|
13
|
+
|
14
|
+
## Resources
|
15
|
+
|
16
|
+
- [Rule source](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/ValuesOfCorrectTypeRule.ts)
|
17
|
+
- [Test source](https://github.com/graphql/graphql-js/tree/main/src/validation/__tests__/ValuesOfCorrectTypeRule-test.ts)
|
@@ -9,4 +9,9 @@
|
|
9
9
|
|
10
10
|
A GraphQL operation is only valid if all the variables it defines are of input types (scalar, enum, or input object).
|
11
11
|
|
12
|
-
> This rule is a wrapper around a `graphql-js` validation function. [You can find its source code here](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/VariablesAreInputTypesRule.ts).
|
12
|
+
> This rule is a wrapper around a `graphql-js` validation function. [You can find its source code here](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/VariablesAreInputTypesRule.ts).
|
13
|
+
|
14
|
+
## Resources
|
15
|
+
|
16
|
+
- [Rule source](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/VariablesAreInputTypesRule.ts)
|
17
|
+
- [Test source](https://github.com/graphql/graphql-js/tree/main/src/validation/__tests__/VariablesAreInputTypesRule-test.ts)
|
@@ -9,4 +9,9 @@
|
|
9
9
|
|
10
10
|
Variables passed to field arguments conform to type.
|
11
11
|
|
12
|
-
> This rule is a wrapper around a `graphql-js` validation function. [You can find its source code here](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/VariablesInAllowedPositionRule.ts).
|
12
|
+
> This rule is a wrapper around a `graphql-js` validation function. [You can find its source code here](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/VariablesInAllowedPositionRule.ts).
|
13
|
+
|
14
|
+
## Resources
|
15
|
+
|
16
|
+
- [Rule source](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/VariablesInAllowedPositionRule.ts)
|
17
|
+
- [Test source](https://github.com/graphql/graphql-js/tree/main/src/validation/__tests__/VariablesInAllowedPositionRule-test.ts)
|
package/index.js
CHANGED
@@ -15,6 +15,8 @@ const depthLimit = _interopDefault(require('graphql-depth-limit'));
|
|
15
15
|
const graphqlTagPluck = require('@graphql-tools/graphql-tag-pluck');
|
16
16
|
const graphqlConfig$1 = require('graphql-config');
|
17
17
|
const codeFileLoader = require('@graphql-tools/code-file-loader');
|
18
|
+
const eslint = require('eslint');
|
19
|
+
const codeFrame = require('@babel/code-frame');
|
18
20
|
|
19
21
|
/*
|
20
22
|
* 🚨 IMPORTANT! Do not manually modify this file. Run: `yarn generate-configs`
|
@@ -242,6 +244,24 @@ const convertCase = (style, str) => {
|
|
242
244
|
return lowerCase(str).replace(/ /g, '-');
|
243
245
|
}
|
244
246
|
};
|
247
|
+
function getLocation(loc, fieldName = '', offset) {
|
248
|
+
const { start } = loc;
|
249
|
+
/*
|
250
|
+
* ESLint has 0-based column number
|
251
|
+
* https://eslint.org/docs/developer-guide/working-with-rules#contextreport
|
252
|
+
*/
|
253
|
+
const { offsetStart = 1, offsetEnd = 1 } = offset !== null && offset !== void 0 ? offset : {};
|
254
|
+
return {
|
255
|
+
start: {
|
256
|
+
line: start.line,
|
257
|
+
column: start.column - offsetStart,
|
258
|
+
},
|
259
|
+
end: {
|
260
|
+
line: start.line,
|
261
|
+
column: start.column - offsetEnd + fieldName.length,
|
262
|
+
},
|
263
|
+
};
|
264
|
+
}
|
245
265
|
|
246
266
|
function extractRuleName(stack) {
|
247
267
|
const match = (stack || '').match(/validation[/\\\\]rules[/\\\\](.*?)\.js:/) || [];
|
@@ -292,6 +312,7 @@ const validationToRule = (name, ruleName, docs, getDocumentNode) => {
|
|
292
312
|
meta: {
|
293
313
|
docs: {
|
294
314
|
...docs,
|
315
|
+
graphQLJSRuleName: ruleName,
|
295
316
|
category: 'Validation',
|
296
317
|
recommended: true,
|
297
318
|
requiresSchema,
|
@@ -591,7 +612,7 @@ const rule = {
|
|
591
612
|
],
|
592
613
|
},
|
593
614
|
messages: {
|
594
|
-
[ALPHABETIZE]: '"{{ currName }}" should be before "{{ prevName }}"
|
615
|
+
[ALPHABETIZE]: '"{{ currName }}" should be before "{{ prevName }}"',
|
595
616
|
},
|
596
617
|
schema: {
|
597
618
|
type: 'array',
|
@@ -648,19 +669,9 @@ const rule = {
|
|
648
669
|
for (const node of nodes) {
|
649
670
|
const currName = node.name.value;
|
650
671
|
if (prevName && prevName > currName) {
|
651
|
-
const { start, end } = node.name.loc;
|
652
672
|
const isVariableNode = node.kind === graphql.Kind.VARIABLE;
|
653
673
|
context.report({
|
654
|
-
loc: {
|
655
|
-
start: {
|
656
|
-
line: start.line,
|
657
|
-
column: start.column - (isVariableNode ? 2 : 1),
|
658
|
-
},
|
659
|
-
end: {
|
660
|
-
line: end.line,
|
661
|
-
column: end.column,
|
662
|
-
},
|
663
|
-
},
|
674
|
+
loc: getLocation(node.loc, node.name.value, { offsetEnd: isVariableNode ? 0 : 1 }),
|
664
675
|
messageId: ALPHABETIZE,
|
665
676
|
data: isVariableNode
|
666
677
|
? {
|
@@ -790,6 +801,7 @@ const rule$1 = {
|
|
790
801
|
messages: {
|
791
802
|
[AVOID_DUPLICATE_FIELDS]: `{{ type }} "{{ fieldName }}" defined multiple times.`,
|
792
803
|
},
|
804
|
+
schema: [],
|
793
805
|
},
|
794
806
|
create(context) {
|
795
807
|
return {
|
@@ -909,15 +921,16 @@ const rule$2 = {
|
|
909
921
|
const testKeyword = caseSensitive ? keyword : keyword.toLowerCase();
|
910
922
|
const testName = caseSensitive ? node.name.value : node.name.value.toLowerCase();
|
911
923
|
if (testName.startsWith(testKeyword)) {
|
924
|
+
const { start } = node.name.loc;
|
912
925
|
context.report({
|
913
926
|
loc: {
|
914
927
|
start: {
|
915
|
-
line:
|
916
|
-
column:
|
928
|
+
line: start.line,
|
929
|
+
column: start.column - 1,
|
917
930
|
},
|
918
931
|
end: {
|
919
|
-
line:
|
920
|
-
column:
|
932
|
+
line: start.line,
|
933
|
+
column: start.column - 1 + testKeyword.length,
|
921
934
|
},
|
922
935
|
},
|
923
936
|
data: {
|
@@ -960,6 +973,7 @@ const rule$3 = {
|
|
960
973
|
},
|
961
974
|
],
|
962
975
|
},
|
976
|
+
schema: [],
|
963
977
|
},
|
964
978
|
create(context) {
|
965
979
|
const schema = requireGraphQLSchemaFromContext('avoid-scalar-result-type-on-mutation', context);
|
@@ -1015,22 +1029,33 @@ const rule$4 = {
|
|
1015
1029
|
messages: {
|
1016
1030
|
[AVOID_TYPENAME_PREFIX]: `Field "{{ fieldName }}" starts with the name of the parent type "{{ typeName }}"`,
|
1017
1031
|
},
|
1032
|
+
schema: [],
|
1018
1033
|
},
|
1019
1034
|
create(context) {
|
1020
1035
|
return {
|
1021
1036
|
'ObjectTypeDefinition, ObjectTypeExtension, InterfaceTypeDefinition, InterfaceTypeExtension'(node) {
|
1022
1037
|
const typeName = node.name.value;
|
1023
|
-
const lowerTypeName =
|
1038
|
+
const lowerTypeName = typeName.toLowerCase();
|
1024
1039
|
for (const field of node.fields) {
|
1025
|
-
const fieldName = field.name.value
|
1026
|
-
if (fieldName
|
1040
|
+
const fieldName = field.name.value;
|
1041
|
+
if (fieldName.toLowerCase().startsWith(lowerTypeName)) {
|
1042
|
+
const { start } = field.loc;
|
1027
1043
|
context.report({
|
1028
|
-
node: field.name,
|
1029
1044
|
data: {
|
1030
1045
|
fieldName,
|
1031
1046
|
typeName,
|
1032
1047
|
},
|
1033
1048
|
messageId: AVOID_TYPENAME_PREFIX,
|
1049
|
+
loc: {
|
1050
|
+
start: {
|
1051
|
+
line: start.line,
|
1052
|
+
column: start.column - 1,
|
1053
|
+
},
|
1054
|
+
end: {
|
1055
|
+
line: start.line,
|
1056
|
+
column: start.column - 1 + lowerTypeName.length,
|
1057
|
+
},
|
1058
|
+
},
|
1034
1059
|
});
|
1035
1060
|
}
|
1036
1061
|
}
|
@@ -1358,7 +1383,8 @@ const rule$7 = {
|
|
1358
1383
|
var _a;
|
1359
1384
|
if (options.fileExtension && options.fileExtension !== fileExtension) {
|
1360
1385
|
context.report({
|
1361
|
-
|
1386
|
+
// Report on first character
|
1387
|
+
loc: { column: 0, line: 1 },
|
1362
1388
|
messageId: MATCH_EXTENSION,
|
1363
1389
|
data: {
|
1364
1390
|
fileExtension,
|
@@ -1390,7 +1416,8 @@ const rule$7 = {
|
|
1390
1416
|
const filenameWithExtension = filename + expectedExtension;
|
1391
1417
|
if (expectedFilename !== filenameWithExtension) {
|
1392
1418
|
context.report({
|
1393
|
-
|
1419
|
+
// Report on first character
|
1420
|
+
loc: { column: 0, line: 1 },
|
1394
1421
|
messageId: MATCH_STYLE,
|
1395
1422
|
data: {
|
1396
1423
|
expectedFilename,
|
@@ -1728,20 +1755,24 @@ const rule$9 = {
|
|
1728
1755
|
messages: {
|
1729
1756
|
[NO_ANONYMOUS_OPERATIONS]: `Anonymous GraphQL operations are forbidden. Please make sure to name your {{ operation }}!`,
|
1730
1757
|
},
|
1758
|
+
schema: [],
|
1731
1759
|
},
|
1732
1760
|
create(context) {
|
1733
1761
|
return {
|
1734
1762
|
OperationDefinition(node) {
|
1735
|
-
|
1763
|
+
var _a;
|
1764
|
+
const isAnonymous = (((_a = node.name) === null || _a === void 0 ? void 0 : _a.value) || '').length === 0;
|
1765
|
+
if (isAnonymous) {
|
1766
|
+
const { start } = node.loc;
|
1736
1767
|
context.report({
|
1737
1768
|
loc: {
|
1738
1769
|
start: {
|
1739
|
-
column:
|
1740
|
-
line:
|
1770
|
+
column: start.column - 1,
|
1771
|
+
line: start.line,
|
1741
1772
|
},
|
1742
1773
|
end: {
|
1743
|
-
column:
|
1744
|
-
line:
|
1774
|
+
column: start.column - 1 + node.operation.length,
|
1775
|
+
line: start.line,
|
1745
1776
|
},
|
1746
1777
|
},
|
1747
1778
|
data: {
|
@@ -1791,6 +1822,7 @@ const rule$a = {
|
|
1791
1822
|
messages: {
|
1792
1823
|
[ERROR_MESSAGE_ID]: `Case-insensitive enum values duplicates are not allowed! Found: "{{ found }}"`,
|
1793
1824
|
},
|
1825
|
+
schema: [],
|
1794
1826
|
},
|
1795
1827
|
create(context) {
|
1796
1828
|
return {
|
@@ -1885,6 +1917,7 @@ const rule$b = {
|
|
1885
1917
|
messages: {
|
1886
1918
|
[NO_DEPRECATED]: `This {{ type }} is marked as deprecated in your GraphQL schema {{ reason }}`,
|
1887
1919
|
},
|
1920
|
+
schema: [],
|
1888
1921
|
},
|
1889
1922
|
create(context) {
|
1890
1923
|
return {
|
@@ -1971,6 +2004,7 @@ const rule$c = {
|
|
1971
2004
|
],
|
1972
2005
|
},
|
1973
2006
|
type: 'suggestion',
|
2007
|
+
schema: [],
|
1974
2008
|
},
|
1975
2009
|
create(context) {
|
1976
2010
|
return {
|
@@ -2031,15 +2065,28 @@ const rule$d = {
|
|
2031
2065
|
messages: {
|
2032
2066
|
[NO_OPERATION_NAME_SUFFIX]: `Unnecessary "{{ invalidSuffix }}" suffix in your operation name!`,
|
2033
2067
|
},
|
2068
|
+
schema: [],
|
2034
2069
|
},
|
2035
2070
|
create(context) {
|
2036
2071
|
return {
|
2037
2072
|
'OperationDefinition, FragmentDefinition'(node) {
|
2038
|
-
|
2039
|
-
|
2040
|
-
|
2073
|
+
var _a;
|
2074
|
+
const name = ((_a = node.name) === null || _a === void 0 ? void 0 : _a.value) || '';
|
2075
|
+
if (name.length > 0) {
|
2076
|
+
const invalidSuffix = 'operation' in node ? node.operation : 'fragment';
|
2077
|
+
if (name.toLowerCase().endsWith(invalidSuffix)) {
|
2078
|
+
const { start, end } = node.name.loc;
|
2041
2079
|
context.report({
|
2042
|
-
|
2080
|
+
loc: {
|
2081
|
+
start: {
|
2082
|
+
column: start.column - 1 + name.length - invalidSuffix.length,
|
2083
|
+
line: start.line,
|
2084
|
+
},
|
2085
|
+
end: {
|
2086
|
+
column: end.column - 1 + name.length,
|
2087
|
+
line: end.line,
|
2088
|
+
},
|
2089
|
+
},
|
2043
2090
|
data: {
|
2044
2091
|
invalidSuffix,
|
2045
2092
|
},
|
@@ -2096,6 +2143,7 @@ const rule$e = {
|
|
2096
2143
|
},
|
2097
2144
|
fixable: 'code',
|
2098
2145
|
type: 'suggestion',
|
2146
|
+
schema: [],
|
2099
2147
|
},
|
2100
2148
|
create(context) {
|
2101
2149
|
const reachableTypes = requireReachableTypesFromContext(RULE_NAME, context);
|
@@ -2187,6 +2235,7 @@ const rule$f = {
|
|
2187
2235
|
},
|
2188
2236
|
fixable: 'code',
|
2189
2237
|
type: 'suggestion',
|
2238
|
+
schema: [],
|
2190
2239
|
},
|
2191
2240
|
create(context) {
|
2192
2241
|
const usedFields = requireUsedFieldsFromContext(RULE_NAME$1, context);
|
@@ -2452,6 +2501,7 @@ const rule$h = {
|
|
2452
2501
|
],
|
2453
2502
|
},
|
2454
2503
|
type: 'suggestion',
|
2504
|
+
schema: [],
|
2455
2505
|
},
|
2456
2506
|
create(context) {
|
2457
2507
|
return {
|
@@ -2488,15 +2538,18 @@ const DESCRIBABLE_NODES = [
|
|
2488
2538
|
function verifyRule(context, node) {
|
2489
2539
|
if (node) {
|
2490
2540
|
if (!node.description || !node.description.value || node.description.value.trim().length === 0) {
|
2541
|
+
const { start, end } = ('name' in node ? node.name : node).loc;
|
2491
2542
|
context.report({
|
2492
2543
|
loc: {
|
2493
2544
|
start: {
|
2494
|
-
line:
|
2495
|
-
column:
|
2545
|
+
line: start.line,
|
2546
|
+
column: start.column - 1,
|
2496
2547
|
},
|
2497
2548
|
end: {
|
2498
|
-
line:
|
2499
|
-
column:
|
2549
|
+
line: end.line,
|
2550
|
+
column:
|
2551
|
+
// node.name don't exist on SchemaDefinition
|
2552
|
+
'name' in node ? end.column - 1 + node.name.value.length : end.column,
|
2500
2553
|
},
|
2501
2554
|
},
|
2502
2555
|
messageId: REQUIRE_DESCRIPTION_ERROR,
|
@@ -2610,6 +2663,7 @@ const rule$j = {
|
|
2610
2663
|
},
|
2611
2664
|
],
|
2612
2665
|
},
|
2666
|
+
schema: [],
|
2613
2667
|
},
|
2614
2668
|
create(context) {
|
2615
2669
|
const schema = requireGraphQLSchemaFromContext(RULE_NAME$2, context);
|
@@ -3146,11 +3200,7 @@ const rule$m = {
|
|
3146
3200
|
const RULE_NAME$3 = 'unique-fragment-name';
|
3147
3201
|
const UNIQUE_FRAGMENT_NAME = 'UNIQUE_FRAGMENT_NAME';
|
3148
3202
|
const checkNode = (context, node, ruleName, messageId) => {
|
3149
|
-
|
3150
|
-
const documentName = (_a = node.name) === null || _a === void 0 ? void 0 : _a.value;
|
3151
|
-
if (!documentName) {
|
3152
|
-
return;
|
3153
|
-
}
|
3203
|
+
const documentName = node.name.value;
|
3154
3204
|
const siblings = requireSiblingsOperations(ruleName, context);
|
3155
3205
|
const siblingDocuments = node.kind === graphql.Kind.FRAGMENT_DEFINITION ? siblings.getFragment(documentName) : siblings.getOperation(documentName);
|
3156
3206
|
const filepath = context.getFilename();
|
@@ -3161,7 +3211,6 @@ const checkNode = (context, node, ruleName, messageId) => {
|
|
3161
3211
|
return isSameName && !isSamePath;
|
3162
3212
|
});
|
3163
3213
|
if (conflictingDocuments.length > 0) {
|
3164
|
-
const { start, end } = node.name.loc;
|
3165
3214
|
context.report({
|
3166
3215
|
messageId,
|
3167
3216
|
data: {
|
@@ -3170,16 +3219,7 @@ const checkNode = (context, node, ruleName, messageId) => {
|
|
3170
3219
|
.map(f => `\t${path.relative(process.cwd(), getOnDiskFilepath(f.filePath))}`)
|
3171
3220
|
.join('\n'),
|
3172
3221
|
},
|
3173
|
-
loc:
|
3174
|
-
start: {
|
3175
|
-
line: start.line,
|
3176
|
-
column: start.column - 1,
|
3177
|
-
},
|
3178
|
-
end: {
|
3179
|
-
line: end.line,
|
3180
|
-
column: end.column - 1,
|
3181
|
-
},
|
3182
|
-
},
|
3222
|
+
loc: getLocation(node.name.loc, documentName),
|
3183
3223
|
});
|
3184
3224
|
}
|
3185
3225
|
};
|
@@ -3229,6 +3269,7 @@ const rule$n = {
|
|
3229
3269
|
messages: {
|
3230
3270
|
[UNIQUE_FRAGMENT_NAME]: 'Fragment named "{{ documentName }}" already defined in:\n{{ summary }}',
|
3231
3271
|
},
|
3272
|
+
schema: [],
|
3232
3273
|
},
|
3233
3274
|
create(context) {
|
3234
3275
|
return {
|
@@ -3291,10 +3332,11 @@ const rule$o = {
|
|
3291
3332
|
messages: {
|
3292
3333
|
[UNIQUE_OPERATION_NAME]: 'Operation named "{{ documentName }}" already defined in:\n{{ summary }}',
|
3293
3334
|
},
|
3335
|
+
schema: [],
|
3294
3336
|
},
|
3295
3337
|
create(context) {
|
3296
3338
|
return {
|
3297
|
-
OperationDefinition(node) {
|
3339
|
+
'OperationDefinition[name!=undefined]'(node) {
|
3298
3340
|
checkNode(context, node, RULE_NAME$4, UNIQUE_OPERATION_NAME);
|
3299
3341
|
},
|
3300
3342
|
};
|
@@ -3724,23 +3766,93 @@ function parseForESLint(code, options = {}) {
|
|
3724
3766
|
}
|
3725
3767
|
}
|
3726
3768
|
|
3727
|
-
class GraphQLRuleTester extends
|
3769
|
+
class GraphQLRuleTester extends eslint.RuleTester {
|
3728
3770
|
constructor(parserOptions = {}) {
|
3729
|
-
|
3771
|
+
const config = {
|
3730
3772
|
parser: require.resolve('@graphql-eslint/eslint-plugin'),
|
3731
3773
|
parserOptions: {
|
3732
3774
|
...parserOptions,
|
3733
3775
|
skipGraphQLConfig: true,
|
3734
3776
|
},
|
3735
|
-
}
|
3777
|
+
};
|
3778
|
+
super(config);
|
3779
|
+
this.config = config;
|
3736
3780
|
}
|
3737
3781
|
fromMockFile(path$1) {
|
3738
3782
|
return fs.readFileSync(path.resolve(__dirname, `../tests/mocks/${path$1}`), 'utf-8');
|
3739
3783
|
}
|
3740
3784
|
runGraphQLTests(name, rule, tests) {
|
3741
3785
|
super.run(name, rule, tests);
|
3786
|
+
// Skip snapshot testing if `expect` variable is not defined
|
3787
|
+
if (typeof expect === 'undefined') {
|
3788
|
+
return;
|
3789
|
+
}
|
3790
|
+
const linter = new eslint.Linter();
|
3791
|
+
linter.defineRule(name, rule);
|
3792
|
+
for (const testCase of tests.invalid) {
|
3793
|
+
const verifyConfig = getVerifyConfig(name, this.config, testCase);
|
3794
|
+
defineParser(linter, verifyConfig.parser);
|
3795
|
+
const { code, filename } = testCase;
|
3796
|
+
const messages = linter.verify(code, verifyConfig, { filename });
|
3797
|
+
for (const message of messages) {
|
3798
|
+
if (message.fatal) {
|
3799
|
+
throw new Error(message.message);
|
3800
|
+
}
|
3801
|
+
const messageForSnapshot = visualizeEslintMessage(code, message);
|
3802
|
+
// eslint-disable-next-line no-undef
|
3803
|
+
expect(messageForSnapshot).toMatchSnapshot();
|
3804
|
+
}
|
3805
|
+
}
|
3806
|
+
}
|
3807
|
+
}
|
3808
|
+
function getVerifyConfig(ruleId, testerConfig, testCase) {
|
3809
|
+
const { options, parserOptions, parser = testerConfig.parser } = testCase;
|
3810
|
+
return {
|
3811
|
+
...testerConfig,
|
3812
|
+
parser,
|
3813
|
+
parserOptions: {
|
3814
|
+
...testerConfig.parserOptions,
|
3815
|
+
...parserOptions,
|
3816
|
+
},
|
3817
|
+
rules: {
|
3818
|
+
[ruleId]: ['error', ...(Array.isArray(options) ? options : [])],
|
3819
|
+
},
|
3820
|
+
};
|
3821
|
+
}
|
3822
|
+
const parsers = new WeakMap();
|
3823
|
+
function defineParser(linter, parser) {
|
3824
|
+
if (!parser) {
|
3825
|
+
return;
|
3826
|
+
}
|
3827
|
+
if (!parsers.has(linter)) {
|
3828
|
+
parsers.set(linter, new Set());
|
3829
|
+
}
|
3830
|
+
const defined = parsers.get(linter);
|
3831
|
+
if (!defined.has(parser)) {
|
3832
|
+
defined.add(parser);
|
3833
|
+
linter.defineParser(parser, require(parser));
|
3742
3834
|
}
|
3743
3835
|
}
|
3836
|
+
function visualizeEslintMessage(text, result) {
|
3837
|
+
const { line, column, endLine, endColumn, message } = result;
|
3838
|
+
const location = {
|
3839
|
+
start: {
|
3840
|
+
line,
|
3841
|
+
column,
|
3842
|
+
},
|
3843
|
+
};
|
3844
|
+
if (typeof endLine === 'number' && typeof endColumn === 'number') {
|
3845
|
+
location.end = {
|
3846
|
+
line: endLine,
|
3847
|
+
column: endColumn,
|
3848
|
+
};
|
3849
|
+
}
|
3850
|
+
return codeFrame.codeFrameColumns(text, location, {
|
3851
|
+
linesAbove: Number.POSITIVE_INFINITY,
|
3852
|
+
linesBelow: Number.POSITIVE_INFINITY,
|
3853
|
+
message,
|
3854
|
+
});
|
3855
|
+
}
|
3744
3856
|
|
3745
3857
|
exports.GraphQLRuleTester = GraphQLRuleTester;
|
3746
3858
|
exports.configs = configs;
|