@graphql-eslint/eslint-plugin 3.0.0-alpha-5388f29.0 → 3.0.0-alpha-580615a.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 +69 -60
- package/configs/all.d.ts +9 -1
- package/configs/index.d.ts +9 -1
- package/docs/README.md +1 -0
- package/docs/custom-rules.md +36 -36
- package/docs/rules/naming-convention.md +25 -25
- package/docs/rules/no-root-type.md +56 -0
- package/docs/rules/require-description.md +35 -6
- package/estree-parser/converter.d.ts +2 -3
- package/index.js +196 -70
- package/index.mjs +197 -71
- package/package.json +9 -8
- package/rules/alphabetize.d.ts +5 -5
- package/rules/index.d.ts +18 -3
- package/rules/no-root-type.d.ts +7 -0
- package/rules/require-description.d.ts +10 -5
- package/utils.d.ts +3 -3
package/index.mjs
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { Kind,
|
1
|
+
import { Kind, validate, isScalarType, TokenKind, isNonNullType, isListType, isObjectType as isObjectType$1, visit, visitWithTypeInfo, GraphQLObjectType, GraphQLInterfaceType, TypeInfo, isInterfaceType, Source, GraphQLError } from 'graphql';
|
2
2
|
import { validateSDL } from 'graphql/validation/validate';
|
3
3
|
import { processImport, parseImportLine } from '@graphql-tools/import';
|
4
4
|
import { statSync, existsSync, readFileSync } from 'fs';
|
@@ -112,10 +112,11 @@ const allConfig = {
|
|
112
112
|
'@graphql-eslint/match-document-filename': 'error',
|
113
113
|
'@graphql-eslint/no-deprecated': 'error',
|
114
114
|
'@graphql-eslint/no-hashtag-description': 'error',
|
115
|
+
'@graphql-eslint/no-root-type': ['error', { disallow: ['subscription'] }],
|
115
116
|
'@graphql-eslint/no-unreachable-types': 'error',
|
116
117
|
'@graphql-eslint/no-unused-fields': 'error',
|
117
118
|
'@graphql-eslint/require-deprecation-date': 'error',
|
118
|
-
'@graphql-eslint/require-description': 'error',
|
119
|
+
'@graphql-eslint/require-description': ['error', { types: true, overrides: { DirectiveDefinition: true } }],
|
119
120
|
'@graphql-eslint/require-field-of-type-query-in-mutation-result': 'error',
|
120
121
|
'@graphql-eslint/require-id-when-available': 'error',
|
121
122
|
'@graphql-eslint/selection-set-depth': 'error',
|
@@ -170,7 +171,7 @@ function getLexer(source) {
|
|
170
171
|
throw new Error(`Unsupported GraphQL version! Please make sure to use GraphQL v14 or newer!`);
|
171
172
|
}
|
172
173
|
function extractTokens(source) {
|
173
|
-
const lexer = getLexer(
|
174
|
+
const lexer = getLexer(source);
|
174
175
|
const tokens = [];
|
175
176
|
let token = lexer.advance();
|
176
177
|
while (token && token.kind !== '<EOF>') {
|
@@ -539,11 +540,23 @@ const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-de
|
|
539
540
|
}));
|
540
541
|
|
541
542
|
const ALPHABETIZE = 'ALPHABETIZE';
|
542
|
-
const fieldsEnum = [
|
543
|
+
const fieldsEnum = [
|
544
|
+
Kind.OBJECT_TYPE_DEFINITION,
|
545
|
+
Kind.INTERFACE_TYPE_DEFINITION,
|
546
|
+
Kind.INPUT_OBJECT_TYPE_DEFINITION,
|
547
|
+
];
|
543
548
|
const valuesEnum = [Kind.ENUM_TYPE_DEFINITION];
|
544
|
-
const selectionsEnum = [
|
549
|
+
const selectionsEnum = [
|
550
|
+
Kind.OPERATION_DEFINITION,
|
551
|
+
Kind.FRAGMENT_DEFINITION,
|
552
|
+
];
|
545
553
|
const variablesEnum = [Kind.OPERATION_DEFINITION];
|
546
|
-
const argumentsEnum = [
|
554
|
+
const argumentsEnum = [
|
555
|
+
Kind.FIELD_DEFINITION,
|
556
|
+
Kind.FIELD,
|
557
|
+
Kind.DIRECTIVE_DEFINITION,
|
558
|
+
Kind.DIRECTIVE,
|
559
|
+
];
|
547
560
|
const rule = {
|
548
561
|
meta: {
|
549
562
|
type: 'suggestion',
|
@@ -1576,11 +1589,11 @@ const rule$8 = {
|
|
1576
1589
|
properties: {
|
1577
1590
|
types: {
|
1578
1591
|
...schemaOption$1,
|
1579
|
-
description: `Includes:\n\n${TYPES_KINDS.map(kind => `-
|
1592
|
+
description: `Includes:\n\n${TYPES_KINDS.map(kind => `- [${kind}](https://spec.graphql.org/October2021/#${kind})`).join('\n')}`,
|
1580
1593
|
},
|
1581
1594
|
fields: {
|
1582
1595
|
...schemaOption$1,
|
1583
|
-
description: `Includes:\n\n${FIELDS_KINDS.map(kind => `-
|
1596
|
+
description: `Includes:\n\n${FIELDS_KINDS.map(kind => `- [${kind}](https://spec.graphql.org/October2021/#${kind})`).join('\n')}`,
|
1584
1597
|
},
|
1585
1598
|
allowLeadingUnderscore: {
|
1586
1599
|
type: 'boolean',
|
@@ -1596,7 +1609,7 @@ const rule$8 = {
|
|
1596
1609
|
description: [
|
1597
1610
|
'May contain the following `ASTNode` names:',
|
1598
1611
|
'',
|
1599
|
-
...ALLOWED_KINDS.map(kind => `-
|
1612
|
+
...ALLOWED_KINDS.map(kind => `- [${kind}](https://spec.graphql.org/October2021/#${kind})`),
|
1600
1613
|
'',
|
1601
1614
|
"> It's also possible to use a [`selector`](https://eslint.org/docs/developer-guide/selectors) that starts with `ASTNode` name",
|
1602
1615
|
'>',
|
@@ -1879,7 +1892,7 @@ const rule$b = {
|
|
1879
1892
|
requireGraphQLSchemaFromContext('no-deprecated', context);
|
1880
1893
|
const typeInfo = node.typeInfo();
|
1881
1894
|
if (typeInfo && typeInfo.enumValue) {
|
1882
|
-
if (typeInfo.enumValue.
|
1895
|
+
if (typeInfo.enumValue.deprecationReason) {
|
1883
1896
|
const enumValueName = node.value;
|
1884
1897
|
context.report({
|
1885
1898
|
loc: getLocation(node.loc, enumValueName),
|
@@ -1896,7 +1909,7 @@ const rule$b = {
|
|
1896
1909
|
requireGraphQLSchemaFromContext('no-deprecated', context);
|
1897
1910
|
const typeInfo = node.typeInfo();
|
1898
1911
|
if (typeInfo && typeInfo.fieldDef) {
|
1899
|
-
if (typeInfo.fieldDef.
|
1912
|
+
if (typeInfo.fieldDef.deprecationReason) {
|
1900
1913
|
const fieldName = node.name.value;
|
1901
1914
|
context.report({
|
1902
1915
|
loc: getLocation(node.loc, fieldName),
|
@@ -2053,9 +2066,100 @@ const rule$d = {
|
|
2053
2066
|
},
|
2054
2067
|
};
|
2055
2068
|
|
2069
|
+
const ROOT_TYPES = ['query', 'mutation', 'subscription'];
|
2070
|
+
const rule$e = {
|
2071
|
+
meta: {
|
2072
|
+
type: 'suggestion',
|
2073
|
+
docs: {
|
2074
|
+
category: 'Validation',
|
2075
|
+
description: 'Disallow using root types for `read-only` or `write-only` schemas.',
|
2076
|
+
url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-root-type.md',
|
2077
|
+
requiresSchema: true,
|
2078
|
+
examples: [
|
2079
|
+
{
|
2080
|
+
title: 'Incorrect (`read-only` schema)',
|
2081
|
+
usage: [{ disallow: ['mutation', 'subscription'] }],
|
2082
|
+
code: /* GraphQL */ `
|
2083
|
+
type Mutation {
|
2084
|
+
createUser(input: CreateUserInput!): User!
|
2085
|
+
}
|
2086
|
+
`,
|
2087
|
+
},
|
2088
|
+
{
|
2089
|
+
title: 'Incorrect (`write-only` schema)',
|
2090
|
+
usage: [{ disallow: ['query'] }],
|
2091
|
+
code: /* GraphQL */ `
|
2092
|
+
type Query {
|
2093
|
+
users: [User!]!
|
2094
|
+
}
|
2095
|
+
`,
|
2096
|
+
},
|
2097
|
+
{
|
2098
|
+
title: 'Correct (`read-only` schema)',
|
2099
|
+
usage: [{ disallow: ['mutation', 'subscription'] }],
|
2100
|
+
code: /* GraphQL */ `
|
2101
|
+
type Query {
|
2102
|
+
users: [User!]!
|
2103
|
+
}
|
2104
|
+
`,
|
2105
|
+
},
|
2106
|
+
],
|
2107
|
+
optionsForConfig: [{ disallow: ['subscription'] }],
|
2108
|
+
},
|
2109
|
+
schema: {
|
2110
|
+
type: 'array',
|
2111
|
+
minItems: 1,
|
2112
|
+
maxItems: 1,
|
2113
|
+
items: {
|
2114
|
+
type: 'object',
|
2115
|
+
additionalProperties: false,
|
2116
|
+
required: ['disallow'],
|
2117
|
+
properties: {
|
2118
|
+
disallow: {
|
2119
|
+
type: 'array',
|
2120
|
+
uniqueItems: true,
|
2121
|
+
minItems: 1,
|
2122
|
+
items: {
|
2123
|
+
enum: ROOT_TYPES,
|
2124
|
+
},
|
2125
|
+
},
|
2126
|
+
},
|
2127
|
+
},
|
2128
|
+
},
|
2129
|
+
},
|
2130
|
+
create(context) {
|
2131
|
+
const schema = requireGraphQLSchemaFromContext('no-root-type', context);
|
2132
|
+
const disallow = new Set(context.options[0].disallow);
|
2133
|
+
const rootTypeNames = [
|
2134
|
+
disallow.has('query') && schema.getQueryType(),
|
2135
|
+
disallow.has('mutation') && schema.getMutationType(),
|
2136
|
+
disallow.has('subscription') && schema.getSubscriptionType(),
|
2137
|
+
]
|
2138
|
+
.filter(Boolean)
|
2139
|
+
.map(type => type.name);
|
2140
|
+
if (rootTypeNames.length === 0) {
|
2141
|
+
return {};
|
2142
|
+
}
|
2143
|
+
const selector = [
|
2144
|
+
`:matches(${Kind.OBJECT_TYPE_DEFINITION}, ${Kind.OBJECT_TYPE_EXTENSION})`,
|
2145
|
+
'>',
|
2146
|
+
`${Kind.NAME}[value=/^(${rootTypeNames.join('|')})$/]`,
|
2147
|
+
].join(' ');
|
2148
|
+
return {
|
2149
|
+
[selector](node) {
|
2150
|
+
const typeName = node.value;
|
2151
|
+
context.report({
|
2152
|
+
loc: getLocation(node.loc, typeName),
|
2153
|
+
message: `Root type "${typeName}" is forbidden`,
|
2154
|
+
});
|
2155
|
+
},
|
2156
|
+
};
|
2157
|
+
},
|
2158
|
+
};
|
2159
|
+
|
2056
2160
|
const UNREACHABLE_TYPE = 'UNREACHABLE_TYPE';
|
2057
2161
|
const RULE_NAME = 'no-unreachable-types';
|
2058
|
-
const rule$
|
2162
|
+
const rule$f = {
|
2059
2163
|
meta: {
|
2060
2164
|
messages: {
|
2061
2165
|
[UNREACHABLE_TYPE]: `Type "{{ typeName }}" is unreachable`,
|
@@ -2131,7 +2235,7 @@ const rule$e = {
|
|
2131
2235
|
|
2132
2236
|
const UNUSED_FIELD = 'UNUSED_FIELD';
|
2133
2237
|
const RULE_NAME$1 = 'no-unused-fields';
|
2134
|
-
const rule$
|
2238
|
+
const rule$g = {
|
2135
2239
|
meta: {
|
2136
2240
|
messages: {
|
2137
2241
|
[UNUSED_FIELD]: `Field "{{fieldName}}" is unused`,
|
@@ -2320,7 +2424,7 @@ const MESSAGE_REQUIRE_DATE = 'MESSAGE_REQUIRE_DATE';
|
|
2320
2424
|
const MESSAGE_INVALID_FORMAT = 'MESSAGE_INVALID_FORMAT';
|
2321
2425
|
const MESSAGE_INVALID_DATE = 'MESSAGE_INVALID_DATE';
|
2322
2426
|
const MESSAGE_CAN_BE_REMOVED = 'MESSAGE_CAN_BE_REMOVED';
|
2323
|
-
const rule$
|
2427
|
+
const rule$h = {
|
2324
2428
|
meta: {
|
2325
2429
|
type: 'suggestion',
|
2326
2430
|
docs: {
|
@@ -2423,7 +2527,7 @@ const rule$g = {
|
|
2423
2527
|
},
|
2424
2528
|
};
|
2425
2529
|
|
2426
|
-
const rule$
|
2530
|
+
const rule$i = {
|
2427
2531
|
meta: {
|
2428
2532
|
docs: {
|
2429
2533
|
description: `Require all deprecation directives to specify a reason.`,
|
@@ -2478,41 +2582,23 @@ const rule$h = {
|
|
2478
2582
|
};
|
2479
2583
|
|
2480
2584
|
const REQUIRE_DESCRIPTION_ERROR = 'REQUIRE_DESCRIPTION_ERROR';
|
2481
|
-
const
|
2482
|
-
|
2483
|
-
Kind.OBJECT_TYPE_DEFINITION,
|
2585
|
+
const ALLOWED_KINDS$1 = [
|
2586
|
+
...TYPES_KINDS,
|
2484
2587
|
Kind.FIELD_DEFINITION,
|
2485
2588
|
Kind.INPUT_VALUE_DEFINITION,
|
2486
|
-
Kind.INTERFACE_TYPE_DEFINITION,
|
2487
|
-
Kind.UNION_TYPE_DEFINITION,
|
2488
|
-
Kind.ENUM_TYPE_DEFINITION,
|
2489
2589
|
Kind.ENUM_VALUE_DEFINITION,
|
2490
|
-
Kind.INPUT_OBJECT_TYPE_DEFINITION,
|
2491
2590
|
Kind.DIRECTIVE_DEFINITION,
|
2492
2591
|
];
|
2493
|
-
|
2494
|
-
if (node) {
|
2495
|
-
if (!node.description || !node.description.value || node.description.value.trim().length === 0) {
|
2496
|
-
context.report({
|
2497
|
-
loc: getLocation(('name' in node ? node.name : node).loc, 'name' in node ? node.name.value : 'schema'),
|
2498
|
-
messageId: REQUIRE_DESCRIPTION_ERROR,
|
2499
|
-
data: {
|
2500
|
-
nodeType: node.kind,
|
2501
|
-
},
|
2502
|
-
});
|
2503
|
-
}
|
2504
|
-
}
|
2505
|
-
}
|
2506
|
-
const rule$i = {
|
2592
|
+
const rule$j = {
|
2507
2593
|
meta: {
|
2508
2594
|
docs: {
|
2509
2595
|
category: 'Best Practices',
|
2510
|
-
description:
|
2511
|
-
url:
|
2596
|
+
description: 'Enforce descriptions in your type definitions.',
|
2597
|
+
url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/require-description.md',
|
2512
2598
|
examples: [
|
2513
2599
|
{
|
2514
2600
|
title: 'Incorrect',
|
2515
|
-
usage: [{
|
2601
|
+
usage: [{ types: true, overrides: { FieldDefinition: true } }],
|
2516
2602
|
code: /* GraphQL */ `
|
2517
2603
|
type someTypeName {
|
2518
2604
|
name: String
|
@@ -2521,7 +2607,7 @@ const rule$i = {
|
|
2521
2607
|
},
|
2522
2608
|
{
|
2523
2609
|
title: 'Correct',
|
2524
|
-
usage: [{
|
2610
|
+
usage: [{ types: true, overrides: { FieldDefinition: true } }],
|
2525
2611
|
code: /* GraphQL */ `
|
2526
2612
|
"""
|
2527
2613
|
Some type description
|
@@ -2535,40 +2621,74 @@ const rule$i = {
|
|
2535
2621
|
`,
|
2536
2622
|
},
|
2537
2623
|
],
|
2624
|
+
optionsForConfig: [
|
2625
|
+
{
|
2626
|
+
types: true,
|
2627
|
+
overrides: {
|
2628
|
+
[Kind.DIRECTIVE_DEFINITION]: true,
|
2629
|
+
},
|
2630
|
+
},
|
2631
|
+
],
|
2538
2632
|
},
|
2539
2633
|
type: 'suggestion',
|
2540
2634
|
messages: {
|
2541
|
-
[REQUIRE_DESCRIPTION_ERROR]:
|
2635
|
+
[REQUIRE_DESCRIPTION_ERROR]: 'Description is required for nodes of type "{{ nodeType }}"',
|
2542
2636
|
},
|
2543
2637
|
schema: {
|
2544
2638
|
type: 'array',
|
2545
|
-
additionalItems: false,
|
2546
2639
|
minItems: 1,
|
2547
2640
|
maxItems: 1,
|
2548
2641
|
items: {
|
2549
2642
|
type: 'object',
|
2550
|
-
|
2643
|
+
additionalProperties: false,
|
2644
|
+
minProperties: 1,
|
2551
2645
|
properties: {
|
2552
|
-
|
2553
|
-
type: '
|
2554
|
-
|
2555
|
-
|
2556
|
-
|
2557
|
-
|
2558
|
-
|
2559
|
-
|
2646
|
+
types: {
|
2647
|
+
type: 'boolean',
|
2648
|
+
description: `Includes:\n\n${TYPES_KINDS.map(kind => `- [${kind}](https://spec.graphql.org/October2021/#${kind})`).join('\n')}`,
|
2649
|
+
},
|
2650
|
+
overrides: {
|
2651
|
+
type: 'object',
|
2652
|
+
description: 'Configuration for precise `ASTNode`',
|
2653
|
+
additionalProperties: false,
|
2654
|
+
properties: Object.fromEntries(ALLOWED_KINDS$1.map(kind => [kind, { type: 'boolean' }])),
|
2560
2655
|
},
|
2561
2656
|
},
|
2562
2657
|
},
|
2563
2658
|
},
|
2564
2659
|
},
|
2565
2660
|
create(context) {
|
2566
|
-
|
2661
|
+
const { types, overrides = {} } = context.options[0];
|
2662
|
+
const kinds = new Set(types ? TYPES_KINDS : []);
|
2663
|
+
for (const [kind, isEnabled] of Object.entries(overrides)) {
|
2664
|
+
if (isEnabled) {
|
2665
|
+
kinds.add(kind);
|
2666
|
+
}
|
2667
|
+
else {
|
2668
|
+
kinds.delete(kind);
|
2669
|
+
}
|
2670
|
+
}
|
2671
|
+
const selector = [...kinds].join(',');
|
2672
|
+
return {
|
2673
|
+
[selector](node) {
|
2674
|
+
var _a;
|
2675
|
+
const description = ((_a = node.description) === null || _a === void 0 ? void 0 : _a.value) || '';
|
2676
|
+
if (description.trim().length === 0) {
|
2677
|
+
context.report({
|
2678
|
+
loc: getLocation(node.name.loc, node.name.value),
|
2679
|
+
messageId: REQUIRE_DESCRIPTION_ERROR,
|
2680
|
+
data: {
|
2681
|
+
nodeType: node.kind,
|
2682
|
+
},
|
2683
|
+
});
|
2684
|
+
}
|
2685
|
+
},
|
2686
|
+
};
|
2567
2687
|
},
|
2568
2688
|
};
|
2569
2689
|
|
2570
2690
|
const RULE_NAME$2 = 'require-field-of-type-query-in-mutation-result';
|
2571
|
-
const rule$
|
2691
|
+
const rule$k = {
|
2572
2692
|
meta: {
|
2573
2693
|
type: 'suggestion',
|
2574
2694
|
docs: {
|
@@ -2736,7 +2856,7 @@ const convertNode = (typeInfo) => (node, key, parent) => {
|
|
2736
2856
|
|
2737
2857
|
const REQUIRE_ID_WHEN_AVAILABLE = 'REQUIRE_ID_WHEN_AVAILABLE';
|
2738
2858
|
const DEFAULT_ID_FIELD_NAME = 'id';
|
2739
|
-
const rule$
|
2859
|
+
const rule$l = {
|
2740
2860
|
meta: {
|
2741
2861
|
type: 'suggestion',
|
2742
2862
|
docs: {
|
@@ -2872,7 +2992,7 @@ const rule$k = {
|
|
2872
2992
|
},
|
2873
2993
|
};
|
2874
2994
|
|
2875
|
-
const rule$
|
2995
|
+
const rule$m = {
|
2876
2996
|
meta: {
|
2877
2997
|
docs: {
|
2878
2998
|
category: 'Best Practices',
|
@@ -2994,7 +3114,7 @@ const shouldIgnoreNode = ({ node, exceptions }) => {
|
|
2994
3114
|
}
|
2995
3115
|
return false;
|
2996
3116
|
};
|
2997
|
-
const rule$
|
3117
|
+
const rule$n = {
|
2998
3118
|
meta: {
|
2999
3119
|
type: 'suggestion',
|
3000
3120
|
docs: {
|
@@ -3171,7 +3291,7 @@ const checkNode = (context, node, ruleName, messageId) => {
|
|
3171
3291
|
});
|
3172
3292
|
}
|
3173
3293
|
};
|
3174
|
-
const rule$
|
3294
|
+
const rule$o = {
|
3175
3295
|
meta: {
|
3176
3296
|
type: 'suggestion',
|
3177
3297
|
docs: {
|
@@ -3230,7 +3350,7 @@ const rule$n = {
|
|
3230
3350
|
|
3231
3351
|
const RULE_NAME$4 = 'unique-operation-name';
|
3232
3352
|
const UNIQUE_OPERATION_NAME = 'UNIQUE_OPERATION_NAME';
|
3233
|
-
const rule$
|
3353
|
+
const rule$p = {
|
3234
3354
|
meta: {
|
3235
3355
|
type: 'suggestion',
|
3236
3356
|
docs: {
|
@@ -3310,17 +3430,18 @@ const rules = {
|
|
3310
3430
|
'no-deprecated': rule$b,
|
3311
3431
|
'no-hashtag-description': rule$c,
|
3312
3432
|
'no-operation-name-suffix': rule$d,
|
3313
|
-
'no-
|
3314
|
-
'no-
|
3315
|
-
'
|
3316
|
-
'require-deprecation-
|
3317
|
-
'require-
|
3318
|
-
'require-
|
3319
|
-
'require-
|
3320
|
-
'
|
3321
|
-
'
|
3322
|
-
'
|
3323
|
-
'unique-
|
3433
|
+
'no-root-type': rule$e,
|
3434
|
+
'no-unreachable-types': rule$f,
|
3435
|
+
'no-unused-fields': rule$g,
|
3436
|
+
'require-deprecation-date': rule$h,
|
3437
|
+
'require-deprecation-reason': rule$i,
|
3438
|
+
'require-description': rule$j,
|
3439
|
+
'require-field-of-type-query-in-mutation-result': rule$k,
|
3440
|
+
'require-id-when-available': rule$l,
|
3441
|
+
'selection-set-depth': rule$m,
|
3442
|
+
'strict-id-in-types': rule$n,
|
3443
|
+
'unique-fragment-name': rule$o,
|
3444
|
+
'unique-operation-name': rule$p,
|
3324
3445
|
};
|
3325
3446
|
|
3326
3447
|
const RELEVANT_KEYWORDS = ['gql', 'graphql', '/* GraphQL */'];
|
@@ -3623,7 +3744,12 @@ function getReachableTypes(schema) {
|
|
3623
3744
|
Directive: collect,
|
3624
3745
|
NamedType: collect,
|
3625
3746
|
};
|
3626
|
-
for (const type of [
|
3747
|
+
for (const type of [
|
3748
|
+
schema,
|
3749
|
+
schema.getQueryType(),
|
3750
|
+
schema.getMutationType(),
|
3751
|
+
schema.getSubscriptionType(),
|
3752
|
+
]) {
|
3627
3753
|
if (type) {
|
3628
3754
|
visit(type.astNode, visitor);
|
3629
3755
|
}
|
@@ -3682,7 +3808,7 @@ function parseForESLint(code, options = {}) {
|
|
3682
3808
|
noLocation: false,
|
3683
3809
|
});
|
3684
3810
|
const { rootTree, comments } = convertToESTree(graphqlAst.document, schema ? new TypeInfo(schema) : null);
|
3685
|
-
const tokens = extractTokens(code);
|
3811
|
+
const tokens = extractTokens(new Source(code, filePath));
|
3686
3812
|
return {
|
3687
3813
|
services: parserServices,
|
3688
3814
|
parserServices,
|
package/package.json
CHANGED
@@ -1,18 +1,19 @@
|
|
1
1
|
{
|
2
2
|
"name": "@graphql-eslint/eslint-plugin",
|
3
|
-
"version": "3.0.0-alpha-
|
3
|
+
"version": "3.0.0-alpha-580615a.0",
|
4
4
|
"sideEffects": false,
|
5
5
|
"peerDependencies": {
|
6
|
-
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0"
|
6
|
+
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
|
7
7
|
},
|
8
8
|
"dependencies": {
|
9
|
-
"@
|
10
|
-
"@graphql-tools/
|
11
|
-
"@graphql-tools/
|
12
|
-
"@graphql-tools/
|
13
|
-
"graphql-
|
9
|
+
"@babel/code-frame": "7.16.0",
|
10
|
+
"@graphql-tools/code-file-loader": "7.2.2",
|
11
|
+
"@graphql-tools/graphql-tag-pluck": "7.1.3",
|
12
|
+
"@graphql-tools/import": "6.6.1",
|
13
|
+
"@graphql-tools/utils": "8.5.3",
|
14
|
+
"graphql-config": "4.1.0",
|
14
15
|
"graphql-depth-limit": "1.1.0",
|
15
|
-
"lodash.lowercase": "
|
16
|
+
"lodash.lowercase": "4.3.0"
|
16
17
|
},
|
17
18
|
"repository": "https://github.com/dotansimha/graphql-eslint",
|
18
19
|
"author": "Dotan Simha <dotansimha@gmail.com>",
|
package/rules/alphabetize.d.ts
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
import { GraphQLESLintRule } from '../types';
|
2
|
-
declare const fieldsEnum: (
|
3
|
-
declare const valuesEnum:
|
4
|
-
declare const selectionsEnum: (
|
5
|
-
declare const variablesEnum:
|
6
|
-
declare const argumentsEnum: (
|
2
|
+
declare const fieldsEnum: ('ObjectTypeDefinition' | 'InterfaceTypeDefinition' | 'InputObjectTypeDefinition')[];
|
3
|
+
declare const valuesEnum: ['EnumTypeDefinition'];
|
4
|
+
declare const selectionsEnum: ('OperationDefinition' | 'FragmentDefinition')[];
|
5
|
+
declare const variablesEnum: ['OperationDefinition'];
|
6
|
+
declare const argumentsEnum: ('FieldDefinition' | 'Field' | 'DirectiveDefinition' | 'Directive')[];
|
7
7
|
declare type AlphabetizeConfig = [
|
8
8
|
{
|
9
9
|
fields?: typeof fieldsEnum;
|
package/rules/index.d.ts
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
export declare const rules: {
|
2
2
|
alphabetize: import("..").GraphQLESLintRule<[{
|
3
3
|
fields?: ("ObjectTypeDefinition" | "InterfaceTypeDefinition" | "InputObjectTypeDefinition")[];
|
4
|
-
values?: "EnumTypeDefinition"
|
4
|
+
values?: ["EnumTypeDefinition"];
|
5
5
|
selections?: ("OperationDefinition" | "FragmentDefinition")[];
|
6
|
-
variables?: "OperationDefinition"
|
6
|
+
variables?: ["OperationDefinition"];
|
7
7
|
arguments?: ("Field" | "Directive" | "FieldDefinition" | "DirectiveDefinition")[];
|
8
8
|
}], false>;
|
9
9
|
'avoid-duplicate-fields': import("..").GraphQLESLintRule<any[], false>;
|
@@ -161,6 +161,9 @@ export declare const rules: {
|
|
161
161
|
'no-deprecated': import("..").GraphQLESLintRule<[], true>;
|
162
162
|
'no-hashtag-description': import("..").GraphQLESLintRule<any[], false>;
|
163
163
|
'no-operation-name-suffix': import("..").GraphQLESLintRule<any[], false>;
|
164
|
+
'no-root-type': import("..").GraphQLESLintRule<[{
|
165
|
+
disallow: ("query" | "mutation" | "subscription")[];
|
166
|
+
}], false>;
|
164
167
|
'no-unreachable-types': import("..").GraphQLESLintRule<any[], false>;
|
165
168
|
'no-unused-fields': import("..").GraphQLESLintRule<any[], false>;
|
166
169
|
'require-deprecation-date': import("..").GraphQLESLintRule<[{
|
@@ -168,7 +171,19 @@ export declare const rules: {
|
|
168
171
|
}], false>;
|
169
172
|
'require-deprecation-reason': import("..").GraphQLESLintRule<any[], false>;
|
170
173
|
'require-description': import("..").GraphQLESLintRule<[{
|
171
|
-
|
174
|
+
types?: boolean;
|
175
|
+
overrides?: {
|
176
|
+
ScalarTypeDefinition?: boolean;
|
177
|
+
ObjectTypeDefinition?: boolean;
|
178
|
+
FieldDefinition?: boolean;
|
179
|
+
InputValueDefinition?: boolean;
|
180
|
+
InterfaceTypeDefinition?: boolean;
|
181
|
+
UnionTypeDefinition?: boolean;
|
182
|
+
EnumTypeDefinition?: boolean;
|
183
|
+
EnumValueDefinition?: boolean;
|
184
|
+
InputObjectTypeDefinition?: boolean;
|
185
|
+
DirectiveDefinition?: boolean;
|
186
|
+
};
|
172
187
|
}], false>;
|
173
188
|
'require-field-of-type-query-in-mutation-result': import("..").GraphQLESLintRule<any[], false>;
|
174
189
|
'require-id-when-available': import("..").GraphQLESLintRule<[{
|
@@ -0,0 +1,7 @@
|
|
1
|
+
import { GraphQLESLintRule } from '../types';
|
2
|
+
declare const ROOT_TYPES: ('query' | 'mutation' | 'subscription')[];
|
3
|
+
declare type NoRootTypeConfig = {
|
4
|
+
disallow: typeof ROOT_TYPES;
|
5
|
+
};
|
6
|
+
declare const rule: GraphQLESLintRule<[NoRootTypeConfig]>;
|
7
|
+
export default rule;
|
@@ -1,7 +1,12 @@
|
|
1
|
+
import { Kind } from 'graphql';
|
1
2
|
import { GraphQLESLintRule } from '../types';
|
2
|
-
declare const
|
3
|
-
declare type
|
4
|
-
|
5
|
-
|
6
|
-
|
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.FIELD_DEFINITION, Kind.INPUT_VALUE_DEFINITION, Kind.ENUM_VALUE_DEFINITION, Kind.DIRECTIVE_DEFINITION];
|
4
|
+
declare type AllowedKind = typeof ALLOWED_KINDS[number];
|
5
|
+
declare type RequireDescriptionRuleConfig = {
|
6
|
+
types?: boolean;
|
7
|
+
overrides?: {
|
8
|
+
[key in AllowedKind]?: boolean;
|
9
|
+
};
|
10
|
+
};
|
11
|
+
declare const rule: GraphQLESLintRule<[RequireDescriptionRuleConfig]>;
|
7
12
|
export default rule;
|
package/utils.d.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { GraphQLSchema } from 'graphql';
|
1
|
+
import { GraphQLSchema, Source, Kind } from 'graphql';
|
2
2
|
import { AST } from 'eslint';
|
3
3
|
import { Source as LoaderSource } from '@graphql-tools/utils';
|
4
4
|
import { GraphQLESLintRuleContext } from './types';
|
@@ -8,7 +8,7 @@ export declare function requireSiblingsOperations(ruleName: string, context: Gra
|
|
8
8
|
export declare function requireGraphQLSchemaFromContext(ruleName: string, context: GraphQLESLintRuleContext): GraphQLSchema | never;
|
9
9
|
export declare function requireReachableTypesFromContext(ruleName: string, context: GraphQLESLintRuleContext): ReachableTypes | never;
|
10
10
|
export declare function requireUsedFieldsFromContext(ruleName: string, context: GraphQLESLintRuleContext): UsedFields | never;
|
11
|
-
export declare function extractTokens(source:
|
11
|
+
export declare function extractTokens(source: Source): AST.Token[];
|
12
12
|
export declare const normalizePath: (path: string) => string;
|
13
13
|
/**
|
14
14
|
* https://github.com/prettier/eslint-plugin-prettier/blob/76bd45ece6d56eb52f75db6b4a1efdd2efb56392/eslint-plugin-prettier.js#L71
|
@@ -19,7 +19,7 @@ export declare const normalizePath: (path: string) => string;
|
|
19
19
|
export declare const getOnDiskFilepath: (filepath: string) => string;
|
20
20
|
export declare const getTypeName: (node: any) => any;
|
21
21
|
export declare const loaderCache: Record<string, LoaderSource[]>;
|
22
|
-
export declare const TYPES_KINDS:
|
22
|
+
export declare const TYPES_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];
|
23
23
|
export declare enum CaseStyle {
|
24
24
|
camelCase = "camelCase",
|
25
25
|
pascalCase = "PascalCase",
|