@graphql-eslint/eslint-plugin 3.8.0-alpha-2d2b247.0 â 3.8.0-alpha-fb12b01.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/docs/rules/alphabetize.md +0 -2
- package/docs/rules/match-document-filename.md +2 -1
- package/index.js +62 -72
- package/index.mjs +62 -72
- package/package.json +1 -2
- package/rules/alphabetize.d.ts +1 -1
- package/rules/index.d.ts +7 -1
- package/rules/match-document-filename.d.ts +2 -1
- package/rules/require-description.d.ts +1 -1
- package/testkit.d.ts +1 -0
@@ -1,7 +1,5 @@
|
|
1
1
|
# `alphabetize`
|
2
2
|
|
3
|
-
đ§ The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#--fix) can automatically fix some of the problems reported by this rule.
|
4
|
-
|
5
3
|
- Category: `Schema & Operations`
|
6
4
|
- Rule name: `@graphql-eslint/alphabetize`
|
7
5
|
- Requires GraphQL Schema: `false` [âšī¸](../../README.md#extended-linting-rules-with-graphql-schema)
|
@@ -131,7 +131,7 @@ The schema defines the following additional types:
|
|
131
131
|
|
132
132
|
## `asString` (enum)
|
133
133
|
|
134
|
-
One of: `camelCase`, `PascalCase`, `snake_case`, `UPPER_CASE`, `kebab-case`
|
134
|
+
One of: `camelCase`, `PascalCase`, `snake_case`, `UPPER_CASE`, `kebab-case`, `matchDocumentStyle`
|
135
135
|
|
136
136
|
## `asObject` (object)
|
137
137
|
|
@@ -146,6 +146,7 @@ This element must be one of the following enum values:
|
|
146
146
|
- `snake_case`
|
147
147
|
- `UPPER_CASE`
|
148
148
|
- `kebab-case`
|
149
|
+
- `matchDocumentStyle`
|
149
150
|
|
150
151
|
### `suffix` (string)
|
151
152
|
|
package/index.js
CHANGED
@@ -17,7 +17,6 @@ const graphqlConfig = require('graphql-config');
|
|
17
17
|
const codeFileLoader = require('@graphql-tools/code-file-loader');
|
18
18
|
const eslint = require('eslint');
|
19
19
|
const codeFrame = require('@babel/code-frame');
|
20
|
-
const dedent = _interopDefault(require('dedent'));
|
21
20
|
|
22
21
|
const base = {
|
23
22
|
parser: '@graphql-eslint/eslint-plugin',
|
@@ -689,10 +688,9 @@ const argumentsEnum = [
|
|
689
688
|
const rule = {
|
690
689
|
meta: {
|
691
690
|
type: 'suggestion',
|
692
|
-
fixable: 'code',
|
693
691
|
docs: {
|
694
692
|
category: ['Schema', 'Operations'],
|
695
|
-
description:
|
693
|
+
description: 'Enforce arrange in alphabetical order for type fields, enum values, input object fields, operation selections and more.',
|
696
694
|
url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/alphabetize.md',
|
697
695
|
examples: [
|
698
696
|
{
|
@@ -850,56 +848,24 @@ const rule = {
|
|
850
848
|
},
|
851
849
|
create(context) {
|
852
850
|
var _a, _b, _c, _d, _e;
|
853
|
-
const sourceCode = context.getSourceCode();
|
854
|
-
function isNodeAndCommentOnSameLine(node, comment) {
|
855
|
-
return node.loc.end.line === comment.loc.start.line;
|
856
|
-
}
|
857
|
-
function getBeforeComments(node) {
|
858
|
-
const commentsBefore = sourceCode.getCommentsBefore(node);
|
859
|
-
if (commentsBefore.length === 0) {
|
860
|
-
return [];
|
861
|
-
}
|
862
|
-
const tokenBefore = sourceCode.getTokenBefore(node);
|
863
|
-
if (tokenBefore) {
|
864
|
-
return commentsBefore.filter(comment => !isNodeAndCommentOnSameLine(tokenBefore, comment));
|
865
|
-
}
|
866
|
-
return commentsBefore;
|
867
|
-
}
|
868
|
-
function getRangeWithComments(node) {
|
869
|
-
const [firstBeforeComment] = getBeforeComments(node);
|
870
|
-
const [firstAfterComment] = sourceCode.getCommentsAfter(node);
|
871
|
-
const from = firstBeforeComment || node;
|
872
|
-
const to = firstAfterComment && isNodeAndCommentOnSameLine(node, firstAfterComment) ? firstAfterComment : node;
|
873
|
-
return [from.range[0], to.range[1]];
|
874
|
-
}
|
875
851
|
function checkNodes(nodes) {
|
876
|
-
|
877
|
-
for (
|
878
|
-
const
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
852
|
+
let prevName = null;
|
853
|
+
for (const node of nodes) {
|
854
|
+
const currName = node.name.value;
|
855
|
+
if (prevName && prevName > currName) {
|
856
|
+
const isVariableNode = node.kind === graphql.Kind.VARIABLE;
|
857
|
+
context.report({
|
858
|
+
loc: getLocation(node.loc, node.name.value, { offsetEnd: isVariableNode ? 0 : 1 }),
|
859
|
+
messageId: ALPHABETIZE,
|
860
|
+
data: isVariableNode
|
861
|
+
? {
|
862
|
+
currName: `$${currName}`,
|
863
|
+
prevName: `$${prevName}`,
|
864
|
+
}
|
865
|
+
: { currName, prevName },
|
866
|
+
});
|
885
867
|
}
|
886
|
-
|
887
|
-
context.report({
|
888
|
-
loc: getLocation(currNode.name.loc, currName, { offsetStart: isVariableNode ? 2 : 1 }),
|
889
|
-
messageId: ALPHABETIZE,
|
890
|
-
data: isVariableNode
|
891
|
-
? {
|
892
|
-
currName: `$${currName}`,
|
893
|
-
prevName: `$${prevName}`,
|
894
|
-
}
|
895
|
-
: { currName, prevName },
|
896
|
-
*fix(fixer) {
|
897
|
-
const prevRange = getRangeWithComments(prevNode);
|
898
|
-
const currRange = getRangeWithComments(currNode);
|
899
|
-
yield fixer.replaceTextRange(prevRange, sourceCode.getText({ range: currRange }));
|
900
|
-
yield fixer.replaceTextRange(currRange, sourceCode.getText({ range: prevRange }));
|
901
|
-
},
|
902
|
-
});
|
868
|
+
prevName = currName;
|
903
869
|
}
|
904
870
|
}
|
905
871
|
const opts = context.options[0];
|
@@ -1132,7 +1098,7 @@ const rule$2 = {
|
|
1132
1098
|
const MATCH_EXTENSION = 'MATCH_EXTENSION';
|
1133
1099
|
const MATCH_STYLE = 'MATCH_STYLE';
|
1134
1100
|
const ACCEPTED_EXTENSIONS = ['.gql', '.graphql'];
|
1135
|
-
const CASE_STYLES = ['camelCase', 'PascalCase', 'snake_case', 'UPPER_CASE', 'kebab-case'];
|
1101
|
+
const CASE_STYLES = ['camelCase', 'PascalCase', 'snake_case', 'UPPER_CASE', 'kebab-case', 'matchDocumentStyle'];
|
1136
1102
|
const schemaOption = {
|
1137
1103
|
oneOf: [{ $ref: '#/definitions/asString' }, { $ref: '#/definitions/asObject' }],
|
1138
1104
|
};
|
@@ -1306,7 +1272,14 @@ const rule$3 = {
|
|
1306
1272
|
option = { style: option };
|
1307
1273
|
}
|
1308
1274
|
const expectedExtension = options.fileExtension || fileExtension;
|
1309
|
-
|
1275
|
+
let expectedFilename;
|
1276
|
+
if (option.style) {
|
1277
|
+
expectedFilename = option.style === 'matchDocumentStyle' ? docName : convertCase(option.style, docName);
|
1278
|
+
}
|
1279
|
+
else {
|
1280
|
+
expectedFilename = filename;
|
1281
|
+
}
|
1282
|
+
expectedFilename += (option.suffix || '') + expectedExtension;
|
1310
1283
|
const filenameWithExtension = filename + expectedExtension;
|
1311
1284
|
if (expectedFilename !== filenameWithExtension) {
|
1312
1285
|
context.report({
|
@@ -2662,12 +2635,40 @@ const rule$g = {
|
|
2662
2635
|
const RULE_ID$2 = 'require-description';
|
2663
2636
|
const ALLOWED_KINDS$1 = [
|
2664
2637
|
...TYPES_KINDS,
|
2638
|
+
graphql.Kind.DIRECTIVE_DEFINITION,
|
2665
2639
|
graphql.Kind.FIELD_DEFINITION,
|
2666
2640
|
graphql.Kind.INPUT_VALUE_DEFINITION,
|
2667
2641
|
graphql.Kind.ENUM_VALUE_DEFINITION,
|
2668
|
-
graphql.Kind.DIRECTIVE_DEFINITION,
|
2669
2642
|
graphql.Kind.OPERATION_DEFINITION,
|
2670
2643
|
];
|
2644
|
+
function getNodeName(node) {
|
2645
|
+
const DisplayNodeNameMap = {
|
2646
|
+
[graphql.Kind.OBJECT_TYPE_DEFINITION]: 'type',
|
2647
|
+
[graphql.Kind.INTERFACE_TYPE_DEFINITION]: 'interface',
|
2648
|
+
[graphql.Kind.ENUM_TYPE_DEFINITION]: 'enum',
|
2649
|
+
[graphql.Kind.SCALAR_TYPE_DEFINITION]: 'scalar',
|
2650
|
+
[graphql.Kind.INPUT_OBJECT_TYPE_DEFINITION]: 'input',
|
2651
|
+
[graphql.Kind.UNION_TYPE_DEFINITION]: 'union',
|
2652
|
+
[graphql.Kind.DIRECTIVE_DEFINITION]: 'directive',
|
2653
|
+
};
|
2654
|
+
switch (node.kind) {
|
2655
|
+
case graphql.Kind.OBJECT_TYPE_DEFINITION:
|
2656
|
+
case graphql.Kind.INTERFACE_TYPE_DEFINITION:
|
2657
|
+
case graphql.Kind.ENUM_TYPE_DEFINITION:
|
2658
|
+
case graphql.Kind.SCALAR_TYPE_DEFINITION:
|
2659
|
+
case graphql.Kind.INPUT_OBJECT_TYPE_DEFINITION:
|
2660
|
+
case graphql.Kind.UNION_TYPE_DEFINITION:
|
2661
|
+
return `${DisplayNodeNameMap[node.kind]} ${node.name.value}`;
|
2662
|
+
case graphql.Kind.DIRECTIVE_DEFINITION:
|
2663
|
+
return `${DisplayNodeNameMap[node.kind]} @${node.name.value}`;
|
2664
|
+
case graphql.Kind.FIELD_DEFINITION:
|
2665
|
+
case graphql.Kind.INPUT_VALUE_DEFINITION:
|
2666
|
+
case graphql.Kind.ENUM_VALUE_DEFINITION:
|
2667
|
+
return `${node.parent.name.value}.${node.name.value}`;
|
2668
|
+
case graphql.Kind.OPERATION_DEFINITION:
|
2669
|
+
return node.name ? `${node.operation} ${node.name.value}` : node.operation;
|
2670
|
+
}
|
2671
|
+
}
|
2671
2672
|
const rule$h = {
|
2672
2673
|
meta: {
|
2673
2674
|
docs: {
|
@@ -2720,7 +2721,7 @@ const rule$h = {
|
|
2720
2721
|
},
|
2721
2722
|
type: 'suggestion',
|
2722
2723
|
messages: {
|
2723
|
-
[RULE_ID$2]: 'Description is required for
|
2724
|
+
[RULE_ID$2]: 'Description is required for `{{ nodeName }}`.',
|
2724
2725
|
},
|
2725
2726
|
schema: {
|
2726
2727
|
type: 'array',
|
@@ -2782,7 +2783,7 @@ const rule$h = {
|
|
2782
2783
|
loc: isOperation ? getLocation(node.loc, node.operation) : getLocation(node.name.loc, node.name.value),
|
2783
2784
|
messageId: RULE_ID$2,
|
2784
2785
|
data: {
|
2785
|
-
|
2786
|
+
nodeName: getNodeName(node),
|
2786
2787
|
},
|
2787
2788
|
});
|
2788
2789
|
}
|
@@ -4009,30 +4010,19 @@ class GraphQLRuleTester extends eslint.RuleTester {
|
|
4009
4010
|
}
|
4010
4011
|
const linter = new eslint.Linter();
|
4011
4012
|
linter.defineRule(name, rule);
|
4012
|
-
const hasOnlyTest = tests.invalid.some(t => t.only);
|
4013
4013
|
for (const testCase of tests.invalid) {
|
4014
|
-
const { only, code, filename } = testCase;
|
4015
|
-
if (hasOnlyTest && !only) {
|
4016
|
-
continue;
|
4017
|
-
}
|
4018
4014
|
const verifyConfig = getVerifyConfig(name, this.config, testCase);
|
4019
4015
|
defineParser(linter, verifyConfig.parser);
|
4016
|
+
const { code, filename } = testCase;
|
4020
4017
|
const messages = linter.verify(code, verifyConfig, { filename });
|
4021
|
-
const
|
4022
|
-
for (const [index, message] of messages.entries()) {
|
4018
|
+
for (const message of messages) {
|
4023
4019
|
if (message.fatal) {
|
4024
4020
|
throw new Error(message.message);
|
4025
4021
|
}
|
4026
|
-
messageForSnapshot
|
4027
|
-
|
4028
|
-
|
4029
|
-
const { fixed, output } = linter.verifyAndFix(code, verifyConfig, { filename });
|
4030
|
-
if (fixed) {
|
4031
|
-
messageForSnapshot.push('Autofix output', dedent(output));
|
4032
|
-
}
|
4022
|
+
const messageForSnapshot = visualizeEslintMessage(code, message);
|
4023
|
+
// eslint-disable-next-line no-undef
|
4024
|
+
expect(messageForSnapshot).toMatchSnapshot();
|
4033
4025
|
}
|
4034
|
-
// eslint-disable-next-line no-undef
|
4035
|
-
expect(messageForSnapshot.join('\n\n')).toMatchSnapshot();
|
4036
4026
|
}
|
4037
4027
|
}
|
4038
4028
|
}
|
package/index.mjs
CHANGED
@@ -11,7 +11,6 @@ import { loadConfigSync, GraphQLConfig } from 'graphql-config';
|
|
11
11
|
import { CodeFileLoader } from '@graphql-tools/code-file-loader';
|
12
12
|
import { RuleTester, Linter } from 'eslint';
|
13
13
|
import { codeFrameColumns } from '@babel/code-frame';
|
14
|
-
import dedent from 'dedent';
|
15
14
|
|
16
15
|
const base = {
|
17
16
|
parser: '@graphql-eslint/eslint-plugin',
|
@@ -683,10 +682,9 @@ const argumentsEnum = [
|
|
683
682
|
const rule = {
|
684
683
|
meta: {
|
685
684
|
type: 'suggestion',
|
686
|
-
fixable: 'code',
|
687
685
|
docs: {
|
688
686
|
category: ['Schema', 'Operations'],
|
689
|
-
description:
|
687
|
+
description: 'Enforce arrange in alphabetical order for type fields, enum values, input object fields, operation selections and more.',
|
690
688
|
url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/alphabetize.md',
|
691
689
|
examples: [
|
692
690
|
{
|
@@ -844,56 +842,24 @@ const rule = {
|
|
844
842
|
},
|
845
843
|
create(context) {
|
846
844
|
var _a, _b, _c, _d, _e;
|
847
|
-
const sourceCode = context.getSourceCode();
|
848
|
-
function isNodeAndCommentOnSameLine(node, comment) {
|
849
|
-
return node.loc.end.line === comment.loc.start.line;
|
850
|
-
}
|
851
|
-
function getBeforeComments(node) {
|
852
|
-
const commentsBefore = sourceCode.getCommentsBefore(node);
|
853
|
-
if (commentsBefore.length === 0) {
|
854
|
-
return [];
|
855
|
-
}
|
856
|
-
const tokenBefore = sourceCode.getTokenBefore(node);
|
857
|
-
if (tokenBefore) {
|
858
|
-
return commentsBefore.filter(comment => !isNodeAndCommentOnSameLine(tokenBefore, comment));
|
859
|
-
}
|
860
|
-
return commentsBefore;
|
861
|
-
}
|
862
|
-
function getRangeWithComments(node) {
|
863
|
-
const [firstBeforeComment] = getBeforeComments(node);
|
864
|
-
const [firstAfterComment] = sourceCode.getCommentsAfter(node);
|
865
|
-
const from = firstBeforeComment || node;
|
866
|
-
const to = firstAfterComment && isNodeAndCommentOnSameLine(node, firstAfterComment) ? firstAfterComment : node;
|
867
|
-
return [from.range[0], to.range[1]];
|
868
|
-
}
|
869
845
|
function checkNodes(nodes) {
|
870
|
-
|
871
|
-
for (
|
872
|
-
const
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
846
|
+
let prevName = null;
|
847
|
+
for (const node of nodes) {
|
848
|
+
const currName = node.name.value;
|
849
|
+
if (prevName && prevName > currName) {
|
850
|
+
const isVariableNode = node.kind === Kind.VARIABLE;
|
851
|
+
context.report({
|
852
|
+
loc: getLocation(node.loc, node.name.value, { offsetEnd: isVariableNode ? 0 : 1 }),
|
853
|
+
messageId: ALPHABETIZE,
|
854
|
+
data: isVariableNode
|
855
|
+
? {
|
856
|
+
currName: `$${currName}`,
|
857
|
+
prevName: `$${prevName}`,
|
858
|
+
}
|
859
|
+
: { currName, prevName },
|
860
|
+
});
|
879
861
|
}
|
880
|
-
|
881
|
-
context.report({
|
882
|
-
loc: getLocation(currNode.name.loc, currName, { offsetStart: isVariableNode ? 2 : 1 }),
|
883
|
-
messageId: ALPHABETIZE,
|
884
|
-
data: isVariableNode
|
885
|
-
? {
|
886
|
-
currName: `$${currName}`,
|
887
|
-
prevName: `$${prevName}`,
|
888
|
-
}
|
889
|
-
: { currName, prevName },
|
890
|
-
*fix(fixer) {
|
891
|
-
const prevRange = getRangeWithComments(prevNode);
|
892
|
-
const currRange = getRangeWithComments(currNode);
|
893
|
-
yield fixer.replaceTextRange(prevRange, sourceCode.getText({ range: currRange }));
|
894
|
-
yield fixer.replaceTextRange(currRange, sourceCode.getText({ range: prevRange }));
|
895
|
-
},
|
896
|
-
});
|
862
|
+
prevName = currName;
|
897
863
|
}
|
898
864
|
}
|
899
865
|
const opts = context.options[0];
|
@@ -1126,7 +1092,7 @@ const rule$2 = {
|
|
1126
1092
|
const MATCH_EXTENSION = 'MATCH_EXTENSION';
|
1127
1093
|
const MATCH_STYLE = 'MATCH_STYLE';
|
1128
1094
|
const ACCEPTED_EXTENSIONS = ['.gql', '.graphql'];
|
1129
|
-
const CASE_STYLES = ['camelCase', 'PascalCase', 'snake_case', 'UPPER_CASE', 'kebab-case'];
|
1095
|
+
const CASE_STYLES = ['camelCase', 'PascalCase', 'snake_case', 'UPPER_CASE', 'kebab-case', 'matchDocumentStyle'];
|
1130
1096
|
const schemaOption = {
|
1131
1097
|
oneOf: [{ $ref: '#/definitions/asString' }, { $ref: '#/definitions/asObject' }],
|
1132
1098
|
};
|
@@ -1300,7 +1266,14 @@ const rule$3 = {
|
|
1300
1266
|
option = { style: option };
|
1301
1267
|
}
|
1302
1268
|
const expectedExtension = options.fileExtension || fileExtension;
|
1303
|
-
|
1269
|
+
let expectedFilename;
|
1270
|
+
if (option.style) {
|
1271
|
+
expectedFilename = option.style === 'matchDocumentStyle' ? docName : convertCase(option.style, docName);
|
1272
|
+
}
|
1273
|
+
else {
|
1274
|
+
expectedFilename = filename;
|
1275
|
+
}
|
1276
|
+
expectedFilename += (option.suffix || '') + expectedExtension;
|
1304
1277
|
const filenameWithExtension = filename + expectedExtension;
|
1305
1278
|
if (expectedFilename !== filenameWithExtension) {
|
1306
1279
|
context.report({
|
@@ -2656,12 +2629,40 @@ const rule$g = {
|
|
2656
2629
|
const RULE_ID$2 = 'require-description';
|
2657
2630
|
const ALLOWED_KINDS$1 = [
|
2658
2631
|
...TYPES_KINDS,
|
2632
|
+
Kind.DIRECTIVE_DEFINITION,
|
2659
2633
|
Kind.FIELD_DEFINITION,
|
2660
2634
|
Kind.INPUT_VALUE_DEFINITION,
|
2661
2635
|
Kind.ENUM_VALUE_DEFINITION,
|
2662
|
-
Kind.DIRECTIVE_DEFINITION,
|
2663
2636
|
Kind.OPERATION_DEFINITION,
|
2664
2637
|
];
|
2638
|
+
function getNodeName(node) {
|
2639
|
+
const DisplayNodeNameMap = {
|
2640
|
+
[Kind.OBJECT_TYPE_DEFINITION]: 'type',
|
2641
|
+
[Kind.INTERFACE_TYPE_DEFINITION]: 'interface',
|
2642
|
+
[Kind.ENUM_TYPE_DEFINITION]: 'enum',
|
2643
|
+
[Kind.SCALAR_TYPE_DEFINITION]: 'scalar',
|
2644
|
+
[Kind.INPUT_OBJECT_TYPE_DEFINITION]: 'input',
|
2645
|
+
[Kind.UNION_TYPE_DEFINITION]: 'union',
|
2646
|
+
[Kind.DIRECTIVE_DEFINITION]: 'directive',
|
2647
|
+
};
|
2648
|
+
switch (node.kind) {
|
2649
|
+
case Kind.OBJECT_TYPE_DEFINITION:
|
2650
|
+
case Kind.INTERFACE_TYPE_DEFINITION:
|
2651
|
+
case Kind.ENUM_TYPE_DEFINITION:
|
2652
|
+
case Kind.SCALAR_TYPE_DEFINITION:
|
2653
|
+
case Kind.INPUT_OBJECT_TYPE_DEFINITION:
|
2654
|
+
case Kind.UNION_TYPE_DEFINITION:
|
2655
|
+
return `${DisplayNodeNameMap[node.kind]} ${node.name.value}`;
|
2656
|
+
case Kind.DIRECTIVE_DEFINITION:
|
2657
|
+
return `${DisplayNodeNameMap[node.kind]} @${node.name.value}`;
|
2658
|
+
case Kind.FIELD_DEFINITION:
|
2659
|
+
case Kind.INPUT_VALUE_DEFINITION:
|
2660
|
+
case Kind.ENUM_VALUE_DEFINITION:
|
2661
|
+
return `${node.parent.name.value}.${node.name.value}`;
|
2662
|
+
case Kind.OPERATION_DEFINITION:
|
2663
|
+
return node.name ? `${node.operation} ${node.name.value}` : node.operation;
|
2664
|
+
}
|
2665
|
+
}
|
2665
2666
|
const rule$h = {
|
2666
2667
|
meta: {
|
2667
2668
|
docs: {
|
@@ -2714,7 +2715,7 @@ const rule$h = {
|
|
2714
2715
|
},
|
2715
2716
|
type: 'suggestion',
|
2716
2717
|
messages: {
|
2717
|
-
[RULE_ID$2]: 'Description is required for
|
2718
|
+
[RULE_ID$2]: 'Description is required for `{{ nodeName }}`.',
|
2718
2719
|
},
|
2719
2720
|
schema: {
|
2720
2721
|
type: 'array',
|
@@ -2776,7 +2777,7 @@ const rule$h = {
|
|
2776
2777
|
loc: isOperation ? getLocation(node.loc, node.operation) : getLocation(node.name.loc, node.name.value),
|
2777
2778
|
messageId: RULE_ID$2,
|
2778
2779
|
data: {
|
2779
|
-
|
2780
|
+
nodeName: getNodeName(node),
|
2780
2781
|
},
|
2781
2782
|
});
|
2782
2783
|
}
|
@@ -4003,30 +4004,19 @@ class GraphQLRuleTester extends RuleTester {
|
|
4003
4004
|
}
|
4004
4005
|
const linter = new Linter();
|
4005
4006
|
linter.defineRule(name, rule);
|
4006
|
-
const hasOnlyTest = tests.invalid.some(t => t.only);
|
4007
4007
|
for (const testCase of tests.invalid) {
|
4008
|
-
const { only, code, filename } = testCase;
|
4009
|
-
if (hasOnlyTest && !only) {
|
4010
|
-
continue;
|
4011
|
-
}
|
4012
4008
|
const verifyConfig = getVerifyConfig(name, this.config, testCase);
|
4013
4009
|
defineParser(linter, verifyConfig.parser);
|
4010
|
+
const { code, filename } = testCase;
|
4014
4011
|
const messages = linter.verify(code, verifyConfig, { filename });
|
4015
|
-
const
|
4016
|
-
for (const [index, message] of messages.entries()) {
|
4012
|
+
for (const message of messages) {
|
4017
4013
|
if (message.fatal) {
|
4018
4014
|
throw new Error(message.message);
|
4019
4015
|
}
|
4020
|
-
messageForSnapshot
|
4021
|
-
|
4022
|
-
|
4023
|
-
const { fixed, output } = linter.verifyAndFix(code, verifyConfig, { filename });
|
4024
|
-
if (fixed) {
|
4025
|
-
messageForSnapshot.push('Autofix output', dedent(output));
|
4026
|
-
}
|
4016
|
+
const messageForSnapshot = visualizeEslintMessage(code, message);
|
4017
|
+
// eslint-disable-next-line no-undef
|
4018
|
+
expect(messageForSnapshot).toMatchSnapshot();
|
4027
4019
|
}
|
4028
|
-
// eslint-disable-next-line no-undef
|
4029
|
-
expect(messageForSnapshot.join('\n\n')).toMatchSnapshot();
|
4030
4020
|
}
|
4031
4021
|
}
|
4032
4022
|
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@graphql-eslint/eslint-plugin",
|
3
|
-
"version": "3.8.0-alpha-
|
3
|
+
"version": "3.8.0-alpha-fb12b01.0",
|
4
4
|
"description": "GraphQL plugin for ESLint",
|
5
5
|
"sideEffects": false,
|
6
6
|
"peerDependencies": {
|
@@ -12,7 +12,6 @@
|
|
12
12
|
"@graphql-tools/graphql-tag-pluck": "7.1.5",
|
13
13
|
"@graphql-tools/utils": "8.6.1",
|
14
14
|
"chalk": "4.1.2",
|
15
|
-
"dedent": "0.7.0",
|
16
15
|
"graphql-config": "4.1.0",
|
17
16
|
"graphql-depth-limit": "1.1.0",
|
18
17
|
"lodash.lowercase": "4.3.0"
|
package/rules/alphabetize.d.ts
CHANGED
@@ -4,7 +4,7 @@ declare const valuesEnum: ['EnumTypeDefinition'];
|
|
4
4
|
declare const selectionsEnum: ('OperationDefinition' | 'FragmentDefinition')[];
|
5
5
|
declare const variablesEnum: ['OperationDefinition'];
|
6
6
|
declare const argumentsEnum: ('FieldDefinition' | 'Field' | 'DirectiveDefinition' | 'Directive')[];
|
7
|
-
|
7
|
+
declare type AlphabetizeConfig = {
|
8
8
|
fields?: typeof fieldsEnum;
|
9
9
|
values?: typeof valuesEnum;
|
10
10
|
selections?: typeof selectionsEnum;
|
package/rules/index.d.ts
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
export declare const rules: {
|
2
|
-
alphabetize: import("..").GraphQLESLintRule<[
|
2
|
+
alphabetize: import("..").GraphQLESLintRule<[{
|
3
|
+
fields?: ("ObjectTypeDefinition" | "InterfaceTypeDefinition" | "InputObjectTypeDefinition")[];
|
4
|
+
values?: ["EnumTypeDefinition"];
|
5
|
+
selections?: ("OperationDefinition" | "FragmentDefinition")[];
|
6
|
+
variables?: ["OperationDefinition"];
|
7
|
+
arguments?: ("Field" | "Directive" | "FieldDefinition" | "DirectiveDefinition")[];
|
8
|
+
}], false>;
|
3
9
|
'description-style': import("..").GraphQLESLintRule<[{
|
4
10
|
style: "block" | "inline";
|
5
11
|
}], false>;
|
@@ -1,5 +1,6 @@
|
|
1
|
-
import { CaseStyle } from '../utils';
|
1
|
+
import { CaseStyle as _CaseStyle } from '../utils';
|
2
2
|
import { GraphQLESLintRule } from '../types';
|
3
|
+
declare type CaseStyle = _CaseStyle | 'matchDocumentStyle';
|
3
4
|
declare const ACCEPTED_EXTENSIONS: ['.gql', '.graphql'];
|
4
5
|
declare type PropertySchema = {
|
5
6
|
style?: CaseStyle;
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { Kind } from 'graphql';
|
2
2
|
import { GraphQLESLintRule } from '../types';
|
3
|
-
declare const ALLOWED_KINDS: readonly [Kind.OBJECT_TYPE_DEFINITION, Kind.INTERFACE_TYPE_DEFINITION, Kind.ENUM_TYPE_DEFINITION, Kind.SCALAR_TYPE_DEFINITION, Kind.INPUT_OBJECT_TYPE_DEFINITION, Kind.UNION_TYPE_DEFINITION, Kind.
|
3
|
+
declare const ALLOWED_KINDS: readonly [Kind.OBJECT_TYPE_DEFINITION, Kind.INTERFACE_TYPE_DEFINITION, Kind.ENUM_TYPE_DEFINITION, Kind.SCALAR_TYPE_DEFINITION, Kind.INPUT_OBJECT_TYPE_DEFINITION, Kind.UNION_TYPE_DEFINITION, Kind.DIRECTIVE_DEFINITION, Kind.FIELD_DEFINITION, Kind.INPUT_VALUE_DEFINITION, Kind.ENUM_VALUE_DEFINITION, Kind.OPERATION_DEFINITION];
|
4
4
|
declare type AllowedKind = typeof ALLOWED_KINDS[number];
|
5
5
|
export declare type RequireDescriptionRuleConfig = {
|
6
6
|
types?: boolean;
|
package/testkit.d.ts
CHANGED
@@ -6,6 +6,7 @@ export declare type GraphQLESLintRuleListener<WithTypeInfo extends boolean = fal
|
|
6
6
|
[K in keyof ASTKindToNode]?: (node: GraphQLESTreeNode<ASTKindToNode[K], WithTypeInfo>) => void;
|
7
7
|
} & Record<string, any>;
|
8
8
|
export declare type GraphQLValidTestCase<Options> = Omit<RuleTester.ValidTestCase, 'options' | 'parserOptions'> & {
|
9
|
+
name?: string;
|
9
10
|
options?: Options;
|
10
11
|
parserOptions?: ParserOptions;
|
11
12
|
};
|