@graphql-eslint/eslint-plugin 4.0.0-alpha.10 → 4.0.0-alpha.11
Sign up to get free protection for your applications and to get access to all the features.
- package/cjs/index.d.cts +4 -2
- package/cjs/meta.js +1 -1
- package/cjs/rules/index.d.cts +4 -2
- package/cjs/rules/no-unused-fields/index.d.cts +24 -3
- package/cjs/rules/no-unused-fields/index.js +118 -8
- package/esm/index.d.ts +4 -2
- package/esm/meta.js +1 -1
- package/esm/rules/index.d.ts +4 -2
- package/esm/rules/no-unused-fields/index.d.ts +24 -3
- package/esm/rules/no-unused-fields/index.js +118 -8
- package/index.browser.js +186 -76
- package/package.json +1 -1
package/cjs/index.d.cts
CHANGED
@@ -48,10 +48,10 @@ declare const _default: {
|
|
48
48
|
};
|
49
49
|
rules: {
|
50
50
|
alphabetize: GraphQLESLintRule<{
|
51
|
+
values?: boolean | undefined;
|
51
52
|
definitions?: boolean | undefined;
|
52
53
|
selections?: ("OperationDefinition" | "FragmentDefinition")[] | undefined;
|
53
54
|
arguments?: ("Field" | "Directive" | "FieldDefinition" | "DirectiveDefinition")[] | undefined;
|
54
|
-
values?: boolean | undefined;
|
55
55
|
fields?: ("ObjectTypeDefinition" | "InterfaceTypeDefinition" | "InputObjectTypeDefinition")[] | undefined;
|
56
56
|
variables?: boolean | undefined;
|
57
57
|
groups?: string[] | undefined;
|
@@ -117,7 +117,9 @@ declare const _default: {
|
|
117
117
|
'no-scalar-result-type-on-mutation': GraphQLESLintRule;
|
118
118
|
'no-typename-prefix': GraphQLESLintRule;
|
119
119
|
'no-unreachable-types': GraphQLESLintRule;
|
120
|
-
'no-unused-fields': GraphQLESLintRule
|
120
|
+
'no-unused-fields': GraphQLESLintRule<{
|
121
|
+
ignoredFieldSelectors?: string[] | undefined;
|
122
|
+
}[]>;
|
121
123
|
'relay-arguments': GraphQLESLintRule<{
|
122
124
|
includeBoth: boolean;
|
123
125
|
}[], true>;
|
package/cjs/meta.js
CHANGED
package/cjs/rules/index.d.cts
CHANGED
@@ -12,10 +12,10 @@ import 'json-schema-to-ts';
|
|
12
12
|
|
13
13
|
declare const rules: {
|
14
14
|
alphabetize: GraphQLESLintRule<{
|
15
|
+
values?: boolean | undefined;
|
15
16
|
definitions?: boolean | undefined;
|
16
17
|
selections?: ("OperationDefinition" | "FragmentDefinition")[] | undefined;
|
17
18
|
arguments?: ("Field" | "Directive" | "FieldDefinition" | "DirectiveDefinition")[] | undefined;
|
18
|
-
values?: boolean | undefined;
|
19
19
|
fields?: ("ObjectTypeDefinition" | "InterfaceTypeDefinition" | "InputObjectTypeDefinition")[] | undefined;
|
20
20
|
variables?: boolean | undefined;
|
21
21
|
groups?: string[] | undefined;
|
@@ -81,7 +81,9 @@ declare const rules: {
|
|
81
81
|
'no-scalar-result-type-on-mutation': GraphQLESLintRule;
|
82
82
|
'no-typename-prefix': GraphQLESLintRule;
|
83
83
|
'no-unreachable-types': GraphQLESLintRule;
|
84
|
-
'no-unused-fields': GraphQLESLintRule
|
84
|
+
'no-unused-fields': GraphQLESLintRule<{
|
85
|
+
ignoredFieldSelectors?: string[] | undefined;
|
86
|
+
}[]>;
|
85
87
|
'relay-arguments': GraphQLESLintRule<{
|
86
88
|
includeBoth: boolean;
|
87
89
|
}[], true>;
|
@@ -1,13 +1,34 @@
|
|
1
|
+
import { FromSchema } from 'json-schema-to-ts';
|
1
2
|
import { GraphQLESLintRule } from '../../types.cjs';
|
2
3
|
import 'eslint';
|
3
4
|
import 'estree';
|
4
5
|
import 'graphql';
|
5
6
|
import 'graphql-config';
|
6
|
-
import 'json-schema-to-ts';
|
7
7
|
import '../../estree-converter/types.cjs';
|
8
8
|
import '../../siblings.cjs';
|
9
9
|
import '@graphql-tools/utils';
|
10
10
|
|
11
|
-
declare const
|
11
|
+
declare const schema: {
|
12
|
+
readonly type: "array";
|
13
|
+
readonly maxItems: 1;
|
14
|
+
readonly items: {
|
15
|
+
readonly type: "object";
|
16
|
+
readonly additionalProperties: false;
|
17
|
+
readonly properties: {
|
18
|
+
readonly ignoredFieldSelectors: {
|
19
|
+
readonly type: "array";
|
20
|
+
readonly uniqueItems: true;
|
21
|
+
readonly minItems: 1;
|
22
|
+
readonly description: string;
|
23
|
+
readonly items: {
|
24
|
+
readonly type: "string";
|
25
|
+
readonly pattern: "^\\[(.+)]$";
|
26
|
+
};
|
27
|
+
};
|
28
|
+
};
|
29
|
+
};
|
30
|
+
};
|
31
|
+
type RuleOptions = FromSchema<typeof schema>;
|
32
|
+
declare const rule: GraphQLESLintRule<RuleOptions>;
|
12
33
|
|
13
|
-
export { rule };
|
34
|
+
export { type RuleOptions, rule };
|
@@ -2,12 +2,105 @@
|
|
2
2
|
var _graphql = require('graphql');
|
3
3
|
var _cachejs = require('../../cache.js');
|
4
4
|
var _utilsjs = require('../../utils.js');
|
5
|
-
const RULE_ID = "no-unused-fields",
|
6
|
-
|
7
|
-
|
5
|
+
const RULE_ID = "no-unused-fields", RELAY_SCHEMA = (
|
6
|
+
/* GraphQL */
|
7
|
+
`
|
8
|
+
# Root Query Type
|
9
|
+
type Query {
|
10
|
+
user: User
|
11
|
+
}
|
12
|
+
|
13
|
+
# User Type
|
14
|
+
type User {
|
15
|
+
id: ID!
|
16
|
+
name: String!
|
17
|
+
friends(first: Int, after: String): FriendConnection!
|
18
|
+
}
|
19
|
+
|
20
|
+
# FriendConnection Type (Relay Connection)
|
21
|
+
type FriendConnection {
|
22
|
+
edges: [FriendEdge]
|
23
|
+
pageInfo: PageInfo!
|
24
|
+
}
|
25
|
+
|
26
|
+
# FriendEdge Type
|
27
|
+
type FriendEdge {
|
28
|
+
cursor: String!
|
29
|
+
node: Friend!
|
30
|
+
}
|
31
|
+
|
32
|
+
# Friend Type
|
33
|
+
type Friend {
|
34
|
+
id: ID!
|
35
|
+
name: String!
|
36
|
+
}
|
37
|
+
|
38
|
+
# PageInfo Type (Relay Pagination)
|
39
|
+
type PageInfo {
|
40
|
+
hasPreviousPage: Boolean!
|
41
|
+
hasNextPage: Boolean!
|
42
|
+
startCursor: String
|
43
|
+
endCursor: String
|
44
|
+
}
|
45
|
+
`
|
46
|
+
), RELAY_QUERY = (
|
47
|
+
/* GraphQL */
|
48
|
+
`
|
49
|
+
query {
|
50
|
+
user {
|
51
|
+
id
|
52
|
+
name
|
53
|
+
friends(first: 10) {
|
54
|
+
edges {
|
55
|
+
node {
|
56
|
+
id
|
57
|
+
name
|
58
|
+
}
|
59
|
+
}
|
60
|
+
}
|
61
|
+
}
|
62
|
+
}
|
63
|
+
`
|
64
|
+
), RELAY_DEFAULT_IGNORED_FIELD_SELECTORS = [
|
65
|
+
"[parent.name.value=PageInfo][name.value=/(endCursor|startCursor|hasNextPage|hasPreviousPage)/]",
|
66
|
+
"[parent.name.value=/Edge$/][name.value=cursor]",
|
67
|
+
"[parent.name.value=/Connection$/][name.value=pageInfo]"
|
68
|
+
], schema = {
|
69
|
+
type: "array",
|
70
|
+
maxItems: 1,
|
71
|
+
items: {
|
72
|
+
type: "object",
|
73
|
+
additionalProperties: !1,
|
74
|
+
properties: {
|
75
|
+
ignoredFieldSelectors: {
|
76
|
+
type: "array",
|
77
|
+
uniqueItems: !0,
|
78
|
+
minItems: 1,
|
79
|
+
description: [
|
80
|
+
"Fields that will be ignored and are allowed to be unused.",
|
81
|
+
"",
|
82
|
+
"E.g. The following selector will ignore all the relay pagination fields for every connection exposed in the schema:",
|
83
|
+
"```json",
|
84
|
+
JSON.stringify(RELAY_DEFAULT_IGNORED_FIELD_SELECTORS, null, 2),
|
85
|
+
"```",
|
86
|
+
"",
|
87
|
+
"> These fields are defined by ESLint [`selectors`](https://eslint.org/docs/developer-guide/selectors).",
|
88
|
+
"> Paste or drop code into the editor in [ASTExplorer](https://astexplorer.net) and inspect the generated AST to compose your selector."
|
89
|
+
].join(`
|
90
|
+
`),
|
91
|
+
items: {
|
92
|
+
type: "string",
|
93
|
+
pattern: "^\\[(.+)]$"
|
94
|
+
}
|
95
|
+
}
|
96
|
+
}
|
97
|
+
}
|
98
|
+
}, usedFieldsCache = new (0, _cachejs.ModuleCache)();
|
99
|
+
function getUsedFields(schema2, operations) {
|
100
|
+
const cachedValue = usedFieldsCache.get(schema2);
|
8
101
|
if (process.env.NODE_ENV !== "test" && cachedValue)
|
9
102
|
return cachedValue;
|
10
|
-
const usedFields = /* @__PURE__ */ Object.create(null), typeInfo = new (0, _graphql.TypeInfo)(
|
103
|
+
const usedFields = /* @__PURE__ */ Object.create(null), typeInfo = new (0, _graphql.TypeInfo)(schema2), visitor = _graphql.visitWithTypeInfo.call(void 0, typeInfo, {
|
11
104
|
Field(node) {
|
12
105
|
if (!typeInfo.getFieldDef())
|
13
106
|
return !1;
|
@@ -17,7 +110,7 @@ function getUsedFields(schema, operations) {
|
|
17
110
|
}), allDocuments = [...operations.getOperations(), ...operations.getFragments()];
|
18
111
|
for (const { document } of allDocuments)
|
19
112
|
_graphql.visit.call(void 0, document, visitor);
|
20
|
-
return usedFieldsCache.set(
|
113
|
+
return usedFieldsCache.set(schema2, usedFields), usedFields;
|
21
114
|
}
|
22
115
|
const rule = {
|
23
116
|
meta: {
|
@@ -79,17 +172,34 @@ const rule = {
|
|
79
172
|
}
|
80
173
|
`
|
81
174
|
)
|
175
|
+
},
|
176
|
+
{
|
177
|
+
title: "Correct (ignoring fields)",
|
178
|
+
usage: [{ ignoredFieldSelectors: RELAY_DEFAULT_IGNORED_FIELD_SELECTORS }],
|
179
|
+
code: (
|
180
|
+
/* GraphQL */
|
181
|
+
`
|
182
|
+
### 1\uFE0F\u20E3 YOUR SCHEMA
|
183
|
+
${RELAY_SCHEMA}
|
184
|
+
|
185
|
+
### 2\uFE0F\u20E3 YOUR QUERY
|
186
|
+
${RELAY_QUERY}
|
187
|
+
`
|
188
|
+
)
|
82
189
|
}
|
83
190
|
]
|
84
191
|
},
|
85
192
|
type: "suggestion",
|
86
|
-
schema
|
193
|
+
schema,
|
87
194
|
hasSuggestions: !0
|
88
195
|
},
|
89
196
|
create(context) {
|
90
|
-
const
|
197
|
+
const schema2 = _utilsjs.requireGraphQLSchemaFromContext.call(void 0, RULE_ID, context), siblingsOperations = _utilsjs.requireSiblingsOperations.call(void 0, RULE_ID, context), usedFields = getUsedFields(schema2, siblingsOperations), { ignoredFieldSelectors } = context.options[0] || {};
|
91
198
|
return {
|
92
|
-
|
199
|
+
[(ignoredFieldSelectors || []).reduce(
|
200
|
+
(acc, selector2) => `${acc}:not(${selector2})`,
|
201
|
+
"FieldDefinition"
|
202
|
+
)](node) {
|
93
203
|
const fieldName = node.name.value, parentTypeName = node.parent.name.value;
|
94
204
|
_optionalChain([usedFields, 'access', _ => _[parentTypeName], 'optionalAccess', _2 => _2.has, 'call', _3 => _3(fieldName)]) || context.report({
|
95
205
|
node: node.name,
|
package/esm/index.d.ts
CHANGED
@@ -48,10 +48,10 @@ declare const _default: {
|
|
48
48
|
};
|
49
49
|
rules: {
|
50
50
|
alphabetize: GraphQLESLintRule<{
|
51
|
-
values?: boolean | undefined;
|
52
51
|
definitions?: boolean | undefined;
|
53
52
|
selections?: ("OperationDefinition" | "FragmentDefinition")[] | undefined;
|
54
53
|
arguments?: ("Field" | "Directive" | "FieldDefinition" | "DirectiveDefinition")[] | undefined;
|
54
|
+
values?: boolean | undefined;
|
55
55
|
fields?: ("ObjectTypeDefinition" | "InterfaceTypeDefinition" | "InputObjectTypeDefinition")[] | undefined;
|
56
56
|
variables?: boolean | undefined;
|
57
57
|
groups?: string[] | undefined;
|
@@ -117,7 +117,9 @@ declare const _default: {
|
|
117
117
|
'no-scalar-result-type-on-mutation': GraphQLESLintRule;
|
118
118
|
'no-typename-prefix': GraphQLESLintRule;
|
119
119
|
'no-unreachable-types': GraphQLESLintRule;
|
120
|
-
'no-unused-fields': GraphQLESLintRule
|
120
|
+
'no-unused-fields': GraphQLESLintRule<{
|
121
|
+
ignoredFieldSelectors?: string[] | undefined;
|
122
|
+
}[]>;
|
121
123
|
'relay-arguments': GraphQLESLintRule<{
|
122
124
|
includeBoth: boolean;
|
123
125
|
}[], true>;
|
package/esm/meta.js
CHANGED
package/esm/rules/index.d.ts
CHANGED
@@ -12,10 +12,10 @@ import 'json-schema-to-ts';
|
|
12
12
|
|
13
13
|
declare const rules: {
|
14
14
|
alphabetize: GraphQLESLintRule<{
|
15
|
-
values?: boolean | undefined;
|
16
15
|
definitions?: boolean | undefined;
|
17
16
|
selections?: ("OperationDefinition" | "FragmentDefinition")[] | undefined;
|
18
17
|
arguments?: ("Field" | "Directive" | "FieldDefinition" | "DirectiveDefinition")[] | undefined;
|
18
|
+
values?: boolean | undefined;
|
19
19
|
fields?: ("ObjectTypeDefinition" | "InterfaceTypeDefinition" | "InputObjectTypeDefinition")[] | undefined;
|
20
20
|
variables?: boolean | undefined;
|
21
21
|
groups?: string[] | undefined;
|
@@ -81,7 +81,9 @@ declare const rules: {
|
|
81
81
|
'no-scalar-result-type-on-mutation': GraphQLESLintRule;
|
82
82
|
'no-typename-prefix': GraphQLESLintRule;
|
83
83
|
'no-unreachable-types': GraphQLESLintRule;
|
84
|
-
'no-unused-fields': GraphQLESLintRule
|
84
|
+
'no-unused-fields': GraphQLESLintRule<{
|
85
|
+
ignoredFieldSelectors?: string[] | undefined;
|
86
|
+
}[]>;
|
85
87
|
'relay-arguments': GraphQLESLintRule<{
|
86
88
|
includeBoth: boolean;
|
87
89
|
}[], true>;
|
@@ -1,13 +1,34 @@
|
|
1
|
+
import { FromSchema } from 'json-schema-to-ts';
|
1
2
|
import { GraphQLESLintRule } from '../../types.js';
|
2
3
|
import 'eslint';
|
3
4
|
import 'estree';
|
4
5
|
import 'graphql';
|
5
6
|
import 'graphql-config';
|
6
|
-
import 'json-schema-to-ts';
|
7
7
|
import '../../estree-converter/types.js';
|
8
8
|
import '../../siblings.js';
|
9
9
|
import '@graphql-tools/utils';
|
10
10
|
|
11
|
-
declare const
|
11
|
+
declare const schema: {
|
12
|
+
readonly type: "array";
|
13
|
+
readonly maxItems: 1;
|
14
|
+
readonly items: {
|
15
|
+
readonly type: "object";
|
16
|
+
readonly additionalProperties: false;
|
17
|
+
readonly properties: {
|
18
|
+
readonly ignoredFieldSelectors: {
|
19
|
+
readonly type: "array";
|
20
|
+
readonly uniqueItems: true;
|
21
|
+
readonly minItems: 1;
|
22
|
+
readonly description: string;
|
23
|
+
readonly items: {
|
24
|
+
readonly type: "string";
|
25
|
+
readonly pattern: "^\\[(.+)]$";
|
26
|
+
};
|
27
|
+
};
|
28
|
+
};
|
29
|
+
};
|
30
|
+
};
|
31
|
+
type RuleOptions = FromSchema<typeof schema>;
|
32
|
+
declare const rule: GraphQLESLintRule<RuleOptions>;
|
12
33
|
|
13
|
-
export { rule };
|
34
|
+
export { type RuleOptions, rule };
|
@@ -2,12 +2,105 @@ import "../../chunk-UIAXBAMD.js";
|
|
2
2
|
import { TypeInfo, visit, visitWithTypeInfo } from "graphql";
|
3
3
|
import { ModuleCache } from "../../cache.js";
|
4
4
|
import { requireGraphQLSchemaFromContext, requireSiblingsOperations } from "../../utils.js";
|
5
|
-
const RULE_ID = "no-unused-fields",
|
6
|
-
|
7
|
-
|
5
|
+
const RULE_ID = "no-unused-fields", RELAY_SCHEMA = (
|
6
|
+
/* GraphQL */
|
7
|
+
`
|
8
|
+
# Root Query Type
|
9
|
+
type Query {
|
10
|
+
user: User
|
11
|
+
}
|
12
|
+
|
13
|
+
# User Type
|
14
|
+
type User {
|
15
|
+
id: ID!
|
16
|
+
name: String!
|
17
|
+
friends(first: Int, after: String): FriendConnection!
|
18
|
+
}
|
19
|
+
|
20
|
+
# FriendConnection Type (Relay Connection)
|
21
|
+
type FriendConnection {
|
22
|
+
edges: [FriendEdge]
|
23
|
+
pageInfo: PageInfo!
|
24
|
+
}
|
25
|
+
|
26
|
+
# FriendEdge Type
|
27
|
+
type FriendEdge {
|
28
|
+
cursor: String!
|
29
|
+
node: Friend!
|
30
|
+
}
|
31
|
+
|
32
|
+
# Friend Type
|
33
|
+
type Friend {
|
34
|
+
id: ID!
|
35
|
+
name: String!
|
36
|
+
}
|
37
|
+
|
38
|
+
# PageInfo Type (Relay Pagination)
|
39
|
+
type PageInfo {
|
40
|
+
hasPreviousPage: Boolean!
|
41
|
+
hasNextPage: Boolean!
|
42
|
+
startCursor: String
|
43
|
+
endCursor: String
|
44
|
+
}
|
45
|
+
`
|
46
|
+
), RELAY_QUERY = (
|
47
|
+
/* GraphQL */
|
48
|
+
`
|
49
|
+
query {
|
50
|
+
user {
|
51
|
+
id
|
52
|
+
name
|
53
|
+
friends(first: 10) {
|
54
|
+
edges {
|
55
|
+
node {
|
56
|
+
id
|
57
|
+
name
|
58
|
+
}
|
59
|
+
}
|
60
|
+
}
|
61
|
+
}
|
62
|
+
}
|
63
|
+
`
|
64
|
+
), RELAY_DEFAULT_IGNORED_FIELD_SELECTORS = [
|
65
|
+
"[parent.name.value=PageInfo][name.value=/(endCursor|startCursor|hasNextPage|hasPreviousPage)/]",
|
66
|
+
"[parent.name.value=/Edge$/][name.value=cursor]",
|
67
|
+
"[parent.name.value=/Connection$/][name.value=pageInfo]"
|
68
|
+
], schema = {
|
69
|
+
type: "array",
|
70
|
+
maxItems: 1,
|
71
|
+
items: {
|
72
|
+
type: "object",
|
73
|
+
additionalProperties: !1,
|
74
|
+
properties: {
|
75
|
+
ignoredFieldSelectors: {
|
76
|
+
type: "array",
|
77
|
+
uniqueItems: !0,
|
78
|
+
minItems: 1,
|
79
|
+
description: [
|
80
|
+
"Fields that will be ignored and are allowed to be unused.",
|
81
|
+
"",
|
82
|
+
"E.g. The following selector will ignore all the relay pagination fields for every connection exposed in the schema:",
|
83
|
+
"```json",
|
84
|
+
JSON.stringify(RELAY_DEFAULT_IGNORED_FIELD_SELECTORS, null, 2),
|
85
|
+
"```",
|
86
|
+
"",
|
87
|
+
"> These fields are defined by ESLint [`selectors`](https://eslint.org/docs/developer-guide/selectors).",
|
88
|
+
"> Paste or drop code into the editor in [ASTExplorer](https://astexplorer.net) and inspect the generated AST to compose your selector."
|
89
|
+
].join(`
|
90
|
+
`),
|
91
|
+
items: {
|
92
|
+
type: "string",
|
93
|
+
pattern: "^\\[(.+)]$"
|
94
|
+
}
|
95
|
+
}
|
96
|
+
}
|
97
|
+
}
|
98
|
+
}, usedFieldsCache = new ModuleCache();
|
99
|
+
function getUsedFields(schema2, operations) {
|
100
|
+
const cachedValue = usedFieldsCache.get(schema2);
|
8
101
|
if (process.env.NODE_ENV !== "test" && cachedValue)
|
9
102
|
return cachedValue;
|
10
|
-
const usedFields = /* @__PURE__ */ Object.create(null), typeInfo = new TypeInfo(
|
103
|
+
const usedFields = /* @__PURE__ */ Object.create(null), typeInfo = new TypeInfo(schema2), visitor = visitWithTypeInfo(typeInfo, {
|
11
104
|
Field(node) {
|
12
105
|
if (!typeInfo.getFieldDef())
|
13
106
|
return !1;
|
@@ -17,7 +110,7 @@ function getUsedFields(schema, operations) {
|
|
17
110
|
}), allDocuments = [...operations.getOperations(), ...operations.getFragments()];
|
18
111
|
for (const { document } of allDocuments)
|
19
112
|
visit(document, visitor);
|
20
|
-
return usedFieldsCache.set(
|
113
|
+
return usedFieldsCache.set(schema2, usedFields), usedFields;
|
21
114
|
}
|
22
115
|
const rule = {
|
23
116
|
meta: {
|
@@ -79,17 +172,34 @@ const rule = {
|
|
79
172
|
}
|
80
173
|
`
|
81
174
|
)
|
175
|
+
},
|
176
|
+
{
|
177
|
+
title: "Correct (ignoring fields)",
|
178
|
+
usage: [{ ignoredFieldSelectors: RELAY_DEFAULT_IGNORED_FIELD_SELECTORS }],
|
179
|
+
code: (
|
180
|
+
/* GraphQL */
|
181
|
+
`
|
182
|
+
### 1\uFE0F\u20E3 YOUR SCHEMA
|
183
|
+
${RELAY_SCHEMA}
|
184
|
+
|
185
|
+
### 2\uFE0F\u20E3 YOUR QUERY
|
186
|
+
${RELAY_QUERY}
|
187
|
+
`
|
188
|
+
)
|
82
189
|
}
|
83
190
|
]
|
84
191
|
},
|
85
192
|
type: "suggestion",
|
86
|
-
schema
|
193
|
+
schema,
|
87
194
|
hasSuggestions: !0
|
88
195
|
},
|
89
196
|
create(context) {
|
90
|
-
const
|
197
|
+
const schema2 = requireGraphQLSchemaFromContext(RULE_ID, context), siblingsOperations = requireSiblingsOperations(RULE_ID, context), usedFields = getUsedFields(schema2, siblingsOperations), { ignoredFieldSelectors } = context.options[0] || {};
|
91
198
|
return {
|
92
|
-
|
199
|
+
[(ignoredFieldSelectors || []).reduce(
|
200
|
+
(acc, selector2) => `${acc}:not(${selector2})`,
|
201
|
+
"FieldDefinition"
|
202
|
+
)](node) {
|
93
203
|
const fieldName = node.name.value, parentTypeName = node.parent.name.value;
|
94
204
|
usedFields[parentTypeName]?.has(fieldName) || context.report({
|
95
205
|
node: node.name,
|
package/index.browser.js
CHANGED
@@ -341,8 +341,8 @@ function convertLocation(location) {
|
|
341
341
|
}
|
342
342
|
|
343
343
|
// src/estree-converter/converter.ts
|
344
|
-
function convertToESTree(node,
|
345
|
-
let typeInfo =
|
344
|
+
function convertToESTree(node, schema16) {
|
345
|
+
let typeInfo = schema16 && new TypeInfo(schema16), visitor = {
|
346
346
|
leave(node2, key, parent) {
|
347
347
|
let leadingComments = "description" in node2 && node2.description ? [
|
348
348
|
{
|
@@ -408,12 +408,12 @@ function requireSiblingsOperations(ruleId, context) {
|
|
408
408
|
return siblingOperations;
|
409
409
|
}
|
410
410
|
function requireGraphQLSchemaFromContext(ruleId, context) {
|
411
|
-
let { schema:
|
412
|
-
if (!
|
411
|
+
let { schema: schema16 } = context.sourceCode.parserServices;
|
412
|
+
if (!schema16)
|
413
413
|
throw new Error(
|
414
414
|
`Rule \`${ruleId}\` requires graphql-config \`schema\` field to be set and loaded. See https://the-guild.dev/graphql/config/docs/user/schema for more info`
|
415
415
|
);
|
416
|
-
return
|
416
|
+
return schema16;
|
417
417
|
}
|
418
418
|
var chalk = {
|
419
419
|
red: (str) => `\x1B[31m${str}\x1B[39m`,
|
@@ -635,7 +635,7 @@ function parseForESLint(code, options) {
|
|
635
635
|
`\`parserOptions.${key}\` was removed in graphql-eslint@4. Use physical graphql-config for setting schema and documents or \`parserOptions.graphQLConfig\` for programmatic usage.`
|
636
636
|
);
|
637
637
|
try {
|
638
|
-
let { filePath } = options, { document } = parseGraphQLSDL(filePath, code, { noLocation: !1 }), project,
|
638
|
+
let { filePath } = options, { document } = parseGraphQLSDL(filePath, code, { noLocation: !1 }), project, schema16, documents;
|
639
639
|
documents = [
|
640
640
|
parseGraphQLSDL(
|
641
641
|
"operation.graphql",
|
@@ -644,14 +644,14 @@ function parseForESLint(code, options) {
|
|
644
644
|
)
|
645
645
|
];
|
646
646
|
try {
|
647
|
-
|
647
|
+
schema16 = buildSchema(options.graphQLConfig.schema);
|
648
648
|
} catch (error) {
|
649
649
|
throw error instanceof Error && (error.message = `Error while loading schema: ${error.message}`), error;
|
650
650
|
}
|
651
|
-
let rootTree = convertToESTree(document,
|
651
|
+
let rootTree = convertToESTree(document, schema16);
|
652
652
|
return {
|
653
653
|
services: {
|
654
|
-
schema:
|
654
|
+
schema: schema16,
|
655
655
|
siblingOperations: getSiblings(documents)
|
656
656
|
},
|
657
657
|
ast: {
|
@@ -1118,14 +1118,14 @@ import {
|
|
1118
1118
|
import { validateSDL } from "graphql/validation/validate.js";
|
1119
1119
|
function validateDocument({
|
1120
1120
|
context,
|
1121
|
-
schema:
|
1121
|
+
schema: schema16 = null,
|
1122
1122
|
documentNode,
|
1123
1123
|
rule: rule35,
|
1124
1124
|
hasDidYouMeanSuggestions
|
1125
1125
|
}) {
|
1126
1126
|
if (documentNode.definitions.length !== 0)
|
1127
1127
|
try {
|
1128
|
-
let validationErrors =
|
1128
|
+
let validationErrors = schema16 ? validate(schema16, documentNode, [rule35]) : validateSDL(documentNode, null, [rule35]);
|
1129
1129
|
for (let error of validationErrors) {
|
1130
1130
|
let { line, column } = error.locations[0], sourceCode = context.getSourceCode(), { tokens } = sourceCode.ast, token = tokens.find(
|
1131
1131
|
(token2) => token2.loc.start.line === line && token2.loc.start.column === column - 1
|
@@ -1191,7 +1191,7 @@ var getFragmentDefsAndFragmentSpreads = (node) => {
|
|
1191
1191
|
ruleId,
|
1192
1192
|
rule: rule35,
|
1193
1193
|
getDocumentNode,
|
1194
|
-
schema:
|
1194
|
+
schema: schema16 = [],
|
1195
1195
|
hasDidYouMeanSuggestions
|
1196
1196
|
}, docs) => ({
|
1197
1197
|
[ruleId]: {
|
@@ -1204,16 +1204,16 @@ var getFragmentDefsAndFragmentSpreads = (node) => {
|
|
1204
1204
|
description: `${docs.description}
|
1205
1205
|
> This rule is a wrapper around a \`graphql-js\` validation function.`
|
1206
1206
|
},
|
1207
|
-
schema:
|
1207
|
+
schema: schema16,
|
1208
1208
|
hasSuggestions: hasDidYouMeanSuggestions
|
1209
1209
|
},
|
1210
1210
|
create(context) {
|
1211
1211
|
return {
|
1212
1212
|
Document(node) {
|
1213
|
-
let
|
1213
|
+
let schema17 = docs.requiresSchema ? requireGraphQLSchemaFromContext(ruleId, context) : null, documentNode = getDocumentNode ? getDocumentNode({ ruleId, context, node: node.rawNode() }) : node.rawNode();
|
1214
1214
|
validateDocument({
|
1215
1215
|
context,
|
1216
|
-
schema:
|
1216
|
+
schema: schema17,
|
1217
1217
|
documentNode,
|
1218
1218
|
rule: rule35,
|
1219
1219
|
hasDidYouMeanSuggestions
|
@@ -3069,9 +3069,9 @@ var schema7 = {
|
|
3069
3069
|
schema: schema7
|
3070
3070
|
},
|
3071
3071
|
create(context) {
|
3072
|
-
let
|
3073
|
-
disallow.has("mutation") &&
|
3074
|
-
disallow.has("subscription") &&
|
3072
|
+
let schema16 = requireGraphQLSchemaFromContext("no-root-type", context), disallow = new Set(context.options[0].disallow), rootTypeNames = [
|
3073
|
+
disallow.has("mutation") && schema16.getMutationType(),
|
3074
|
+
disallow.has("subscription") && schema16.getSubscriptionType()
|
3075
3075
|
].filter(truthy).map((type) => type.name).join("|");
|
3076
3076
|
return rootTypeNames ? {
|
3077
3077
|
[`:matches(ObjectTypeDefinition, ObjectTypeExtension) > .name[value=/^(${rootTypeNames})$/]`](node) {
|
@@ -3130,13 +3130,13 @@ var RULE_ID8 = "no-scalar-result-type-on-mutation", rule13 = {
|
|
3130
3130
|
schema: []
|
3131
3131
|
},
|
3132
3132
|
create(context) {
|
3133
|
-
let
|
3133
|
+
let schema16 = requireGraphQLSchemaFromContext(RULE_ID8, context), mutationType = schema16.getMutationType();
|
3134
3134
|
return mutationType ? {
|
3135
3135
|
[[
|
3136
3136
|
`:matches(ObjectTypeDefinition, ObjectTypeExtension)[name.value=${mutationType.name}]`,
|
3137
3137
|
"> FieldDefinition > .gqlType Name"
|
3138
3138
|
].join(" ")](node) {
|
3139
|
-
let typeName = node.value, graphQLType =
|
3139
|
+
let typeName = node.value, graphQLType = schema16.getType(typeName);
|
3140
3140
|
if (isScalarType(graphQLType)) {
|
3141
3141
|
let fieldDef = node.parent;
|
3142
3142
|
for (; fieldDef.kind !== Kind12.FIELD_DEFINITION; )
|
@@ -3258,8 +3258,8 @@ var RULE_ID9 = "no-unreachable-types", KINDS = [
|
|
3258
3258
|
DirectiveLocation.INLINE_FRAGMENT,
|
3259
3259
|
DirectiveLocation.VARIABLE_DEFINITION
|
3260
3260
|
]);
|
3261
|
-
function getReachableTypes(
|
3262
|
-
let cachedValue = reachableTypesCache.get(
|
3261
|
+
function getReachableTypes(schema16) {
|
3262
|
+
let cachedValue = reachableTypesCache.get(schema16);
|
3263
3263
|
if (cachedValue)
|
3264
3264
|
return cachedValue;
|
3265
3265
|
let reachableTypes = /* @__PURE__ */ new Set(), collect = (node) => {
|
@@ -3267,9 +3267,9 @@ function getReachableTypes(schema15) {
|
|
3267
3267
|
if (reachableTypes.has(typeName))
|
3268
3268
|
return;
|
3269
3269
|
reachableTypes.add(typeName);
|
3270
|
-
let type =
|
3270
|
+
let type = schema16.getType(typeName) || schema16.getDirective(typeName);
|
3271
3271
|
if (isInterfaceType(type)) {
|
3272
|
-
let { objects, interfaces } =
|
3272
|
+
let { objects, interfaces } = schema16.getImplementations(type);
|
3273
3273
|
for (let { astNode } of [...objects, ...interfaces])
|
3274
3274
|
visit5(astNode, visitor);
|
3275
3275
|
} else type?.astNode && visit5(type.astNode, visitor);
|
@@ -3283,14 +3283,14 @@ function getReachableTypes(schema15) {
|
|
3283
3283
|
NamedType: collect
|
3284
3284
|
};
|
3285
3285
|
for (let type of [
|
3286
|
-
|
3286
|
+
schema16,
|
3287
3287
|
// visiting SchemaDefinition node
|
3288
|
-
|
3289
|
-
|
3290
|
-
|
3288
|
+
schema16.getQueryType(),
|
3289
|
+
schema16.getMutationType(),
|
3290
|
+
schema16.getSubscriptionType()
|
3291
3291
|
])
|
3292
3292
|
type?.astNode && visit5(type.astNode, visitor);
|
3293
|
-
for (let node of
|
3293
|
+
for (let node of schema16.getDirectives())
|
3294
3294
|
if (node.locations.some((location) => RequestDirectiveLocations.has(location))) {
|
3295
3295
|
reachableTypes.add(node.name);
|
3296
3296
|
for (let arg of node.args) {
|
@@ -3298,7 +3298,7 @@ function getReachableTypes(schema15) {
|
|
3298
3298
|
argTypeName && reachableTypes.add(argTypeName);
|
3299
3299
|
}
|
3300
3300
|
}
|
3301
|
-
return reachableTypesCache.set(
|
3301
|
+
return reachableTypesCache.set(schema16, reachableTypes), reachableTypes;
|
3302
3302
|
}
|
3303
3303
|
var rule15 = {
|
3304
3304
|
meta: {
|
@@ -3351,7 +3351,7 @@ var rule15 = {
|
|
3351
3351
|
hasSuggestions: !0
|
3352
3352
|
},
|
3353
3353
|
create(context) {
|
3354
|
-
let
|
3354
|
+
let schema16 = requireGraphQLSchemaFromContext(RULE_ID9, context), reachableTypes = getReachableTypes(schema16);
|
3355
3355
|
return {
|
3356
3356
|
[`:matches(${KINDS}) > .name`](node) {
|
3357
3357
|
let typeName = node.value;
|
@@ -3379,12 +3379,105 @@ var rule15 = {
|
|
3379
3379
|
|
3380
3380
|
// src/rules/no-unused-fields/index.ts
|
3381
3381
|
import { TypeInfo as TypeInfo2, visit as visit6, visitWithTypeInfo as visitWithTypeInfo2 } from "graphql";
|
3382
|
-
var RULE_ID10 = "no-unused-fields",
|
3383
|
-
|
3384
|
-
|
3382
|
+
var RULE_ID10 = "no-unused-fields", RELAY_SCHEMA = (
|
3383
|
+
/* GraphQL */
|
3384
|
+
`
|
3385
|
+
# Root Query Type
|
3386
|
+
type Query {
|
3387
|
+
user: User
|
3388
|
+
}
|
3389
|
+
|
3390
|
+
# User Type
|
3391
|
+
type User {
|
3392
|
+
id: ID!
|
3393
|
+
name: String!
|
3394
|
+
friends(first: Int, after: String): FriendConnection!
|
3395
|
+
}
|
3396
|
+
|
3397
|
+
# FriendConnection Type (Relay Connection)
|
3398
|
+
type FriendConnection {
|
3399
|
+
edges: [FriendEdge]
|
3400
|
+
pageInfo: PageInfo!
|
3401
|
+
}
|
3402
|
+
|
3403
|
+
# FriendEdge Type
|
3404
|
+
type FriendEdge {
|
3405
|
+
cursor: String!
|
3406
|
+
node: Friend!
|
3407
|
+
}
|
3408
|
+
|
3409
|
+
# Friend Type
|
3410
|
+
type Friend {
|
3411
|
+
id: ID!
|
3412
|
+
name: String!
|
3413
|
+
}
|
3414
|
+
|
3415
|
+
# PageInfo Type (Relay Pagination)
|
3416
|
+
type PageInfo {
|
3417
|
+
hasPreviousPage: Boolean!
|
3418
|
+
hasNextPage: Boolean!
|
3419
|
+
startCursor: String
|
3420
|
+
endCursor: String
|
3421
|
+
}
|
3422
|
+
`
|
3423
|
+
), RELAY_QUERY = (
|
3424
|
+
/* GraphQL */
|
3425
|
+
`
|
3426
|
+
query {
|
3427
|
+
user {
|
3428
|
+
id
|
3429
|
+
name
|
3430
|
+
friends(first: 10) {
|
3431
|
+
edges {
|
3432
|
+
node {
|
3433
|
+
id
|
3434
|
+
name
|
3435
|
+
}
|
3436
|
+
}
|
3437
|
+
}
|
3438
|
+
}
|
3439
|
+
}
|
3440
|
+
`
|
3441
|
+
), RELAY_DEFAULT_IGNORED_FIELD_SELECTORS = [
|
3442
|
+
"[parent.name.value=PageInfo][name.value=/(endCursor|startCursor|hasNextPage|hasPreviousPage)/]",
|
3443
|
+
"[parent.name.value=/Edge$/][name.value=cursor]",
|
3444
|
+
"[parent.name.value=/Connection$/][name.value=pageInfo]"
|
3445
|
+
], schema8 = {
|
3446
|
+
type: "array",
|
3447
|
+
maxItems: 1,
|
3448
|
+
items: {
|
3449
|
+
type: "object",
|
3450
|
+
additionalProperties: !1,
|
3451
|
+
properties: {
|
3452
|
+
ignoredFieldSelectors: {
|
3453
|
+
type: "array",
|
3454
|
+
uniqueItems: !0,
|
3455
|
+
minItems: 1,
|
3456
|
+
description: [
|
3457
|
+
"Fields that will be ignored and are allowed to be unused.",
|
3458
|
+
"",
|
3459
|
+
"E.g. The following selector will ignore all the relay pagination fields for every connection exposed in the schema:",
|
3460
|
+
"```json",
|
3461
|
+
JSON.stringify(RELAY_DEFAULT_IGNORED_FIELD_SELECTORS, null, 2),
|
3462
|
+
"```",
|
3463
|
+
"",
|
3464
|
+
"> These fields are defined by ESLint [`selectors`](https://eslint.org/docs/developer-guide/selectors).",
|
3465
|
+
"> Paste or drop code into the editor in [ASTExplorer](https://astexplorer.net) and inspect the generated AST to compose your selector."
|
3466
|
+
].join(`
|
3467
|
+
`),
|
3468
|
+
items: {
|
3469
|
+
type: "string",
|
3470
|
+
pattern: "^\\[(.+)]$"
|
3471
|
+
}
|
3472
|
+
}
|
3473
|
+
}
|
3474
|
+
}
|
3475
|
+
}, usedFieldsCache = new ModuleCache();
|
3476
|
+
function getUsedFields(schema16, operations) {
|
3477
|
+
let cachedValue = usedFieldsCache.get(schema16);
|
3385
3478
|
if (cachedValue)
|
3386
3479
|
return cachedValue;
|
3387
|
-
let usedFields = /* @__PURE__ */ Object.create(null), typeInfo = new TypeInfo2(
|
3480
|
+
let usedFields = /* @__PURE__ */ Object.create(null), typeInfo = new TypeInfo2(schema16), visitor = visitWithTypeInfo2(typeInfo, {
|
3388
3481
|
Field(node) {
|
3389
3482
|
if (!typeInfo.getFieldDef())
|
3390
3483
|
return !1;
|
@@ -3394,7 +3487,7 @@ function getUsedFields(schema15, operations) {
|
|
3394
3487
|
}), allDocuments = [...operations.getOperations(), ...operations.getFragments()];
|
3395
3488
|
for (let { document } of allDocuments)
|
3396
3489
|
visit6(document, visitor);
|
3397
|
-
return usedFieldsCache.set(
|
3490
|
+
return usedFieldsCache.set(schema16, usedFields), usedFields;
|
3398
3491
|
}
|
3399
3492
|
var rule16 = {
|
3400
3493
|
meta: {
|
@@ -3456,17 +3549,34 @@ var rule16 = {
|
|
3456
3549
|
}
|
3457
3550
|
`
|
3458
3551
|
)
|
3552
|
+
},
|
3553
|
+
{
|
3554
|
+
title: "Correct (ignoring fields)",
|
3555
|
+
usage: [{ ignoredFieldSelectors: RELAY_DEFAULT_IGNORED_FIELD_SELECTORS }],
|
3556
|
+
code: (
|
3557
|
+
/* GraphQL */
|
3558
|
+
`
|
3559
|
+
### 1\uFE0F\u20E3 YOUR SCHEMA
|
3560
|
+
${RELAY_SCHEMA}
|
3561
|
+
|
3562
|
+
### 2\uFE0F\u20E3 YOUR QUERY
|
3563
|
+
${RELAY_QUERY}
|
3564
|
+
`
|
3565
|
+
)
|
3459
3566
|
}
|
3460
3567
|
]
|
3461
3568
|
},
|
3462
3569
|
type: "suggestion",
|
3463
|
-
schema:
|
3570
|
+
schema: schema8,
|
3464
3571
|
hasSuggestions: !0
|
3465
3572
|
},
|
3466
3573
|
create(context) {
|
3467
|
-
let
|
3574
|
+
let schema16 = requireGraphQLSchemaFromContext(RULE_ID10, context), siblingsOperations = requireSiblingsOperations(RULE_ID10, context), usedFields = getUsedFields(schema16, siblingsOperations), { ignoredFieldSelectors } = context.options[0] || {};
|
3468
3575
|
return {
|
3469
|
-
|
3576
|
+
[(ignoredFieldSelectors || []).reduce(
|
3577
|
+
(acc, selector2) => `${acc}:not(${selector2})`,
|
3578
|
+
"FieldDefinition"
|
3579
|
+
)](node) {
|
3470
3580
|
let fieldName = node.name.value, parentTypeName = node.parent.name.value;
|
3471
3581
|
usedFields[parentTypeName]?.has(fieldName) || context.report({
|
3472
3582
|
node: node.name,
|
@@ -3489,7 +3599,7 @@ var rule16 = {
|
|
3489
3599
|
|
3490
3600
|
// src/rules/relay-arguments/index.ts
|
3491
3601
|
import { isScalarType as isScalarType2, Kind as Kind14 } from "graphql";
|
3492
|
-
var RULE_ID11 = "relay-arguments", MISSING_ARGUMENTS = "MISSING_ARGUMENTS",
|
3602
|
+
var RULE_ID11 = "relay-arguments", MISSING_ARGUMENTS = "MISSING_ARGUMENTS", schema9 = {
|
3493
3603
|
type: "array",
|
3494
3604
|
maxItems: 1,
|
3495
3605
|
items: {
|
@@ -3555,10 +3665,10 @@ var RULE_ID11 = "relay-arguments", MISSING_ARGUMENTS = "MISSING_ARGUMENTS", sche
|
|
3555
3665
|
messages: {
|
3556
3666
|
[MISSING_ARGUMENTS]: "A field that returns a Connection type must include forward pagination arguments (`first` and `after`), backward pagination arguments (`last` and `before`), or both."
|
3557
3667
|
},
|
3558
|
-
schema:
|
3668
|
+
schema: schema9
|
3559
3669
|
},
|
3560
3670
|
create(context) {
|
3561
|
-
let
|
3671
|
+
let schema16 = requireGraphQLSchemaFromContext(RULE_ID11, context), { includeBoth = !0 } = context.options[0] || {};
|
3562
3672
|
return {
|
3563
3673
|
"FieldDefinition > .gqlType Name[value=/Connection$/]"(node) {
|
3564
3674
|
let fieldNode = node.parent;
|
@@ -3576,7 +3686,7 @@ var RULE_ID11 = "relay-arguments", MISSING_ARGUMENTS = "MISSING_ARGUMENTS", sche
|
|
3576
3686
|
}
|
3577
3687
|
function checkField(typeName, argumentName) {
|
3578
3688
|
let argument = args[argumentName], hasArgument = !!argument, type = argument;
|
3579
|
-
if (hasArgument && type.gqlType.kind === Kind14.NON_NULL_TYPE && (type = type.gqlType), !(hasArgument && type.gqlType.kind === Kind14.NAMED_TYPE && (type.gqlType.name.value === typeName || typeName === "String" && isScalarType2(
|
3689
|
+
if (hasArgument && type.gqlType.kind === Kind14.NON_NULL_TYPE && (type = type.gqlType), !(hasArgument && type.gqlType.kind === Kind14.NAMED_TYPE && (type.gqlType.name.value === typeName || typeName === "String" && isScalarType2(schema16.getType(type.gqlType.name.value))))) {
|
3580
3690
|
let returnType = typeName === "String" ? "String or Scalar" : typeName;
|
3581
3691
|
context.report({
|
3582
3692
|
node: (argument || fieldNode).name,
|
@@ -3686,7 +3796,7 @@ import {
|
|
3686
3796
|
} from "graphql";
|
3687
3797
|
import { getDocumentNodeFromSchema } from "@graphql-tools/utils";
|
3688
3798
|
var RULE_ID12 = "relay-edge-types", MESSAGE_MUST_BE_OBJECT_TYPE = "MESSAGE_MUST_BE_OBJECT_TYPE", MESSAGE_MISSING_EDGE_SUFFIX = "MESSAGE_MISSING_EDGE_SUFFIX", MESSAGE_LIST_TYPE_ONLY_EDGE_TYPE = "MESSAGE_LIST_TYPE_ONLY_EDGE_TYPE", MESSAGE_SHOULD_IMPLEMENTS_NODE = "MESSAGE_SHOULD_IMPLEMENTS_NODE", edgeTypesCache;
|
3689
|
-
function getEdgeTypes(
|
3799
|
+
function getEdgeTypes(schema16) {
|
3690
3800
|
if (edgeTypesCache)
|
3691
3801
|
return edgeTypesCache;
|
3692
3802
|
let edgeTypes = /* @__PURE__ */ new Set(), visitor = {
|
@@ -3695,14 +3805,14 @@ function getEdgeTypes(schema15) {
|
|
3695
3805
|
return;
|
3696
3806
|
let edges = node.fields?.find((field) => field.name.value === "edges");
|
3697
3807
|
if (edges) {
|
3698
|
-
let edgesTypeName = getTypeName(edges), edgesType =
|
3808
|
+
let edgesTypeName = getTypeName(edges), edgesType = schema16.getType(edgesTypeName);
|
3699
3809
|
isObjectType2(edgesType) && edgeTypes.add(edgesTypeName);
|
3700
3810
|
}
|
3701
3811
|
}
|
3702
|
-
}, astNode = getDocumentNodeFromSchema(
|
3812
|
+
}, astNode = getDocumentNodeFromSchema(schema16);
|
3703
3813
|
return visit7(astNode, visitor), edgeTypesCache = edgeTypes, edgeTypesCache;
|
3704
3814
|
}
|
3705
|
-
var
|
3815
|
+
var schema10 = {
|
3706
3816
|
type: "array",
|
3707
3817
|
maxItems: 1,
|
3708
3818
|
items: {
|
@@ -3768,10 +3878,10 @@ var schema9 = {
|
|
3768
3878
|
[MESSAGE_LIST_TYPE_ONLY_EDGE_TYPE]: "A list type should only wrap an edge type.",
|
3769
3879
|
[MESSAGE_SHOULD_IMPLEMENTS_NODE]: "Edge type's field `node` must implement `Node` interface."
|
3770
3880
|
},
|
3771
|
-
schema:
|
3881
|
+
schema: schema10
|
3772
3882
|
},
|
3773
3883
|
create(context) {
|
3774
|
-
let
|
3884
|
+
let schema16 = requireGraphQLSchemaFromContext(RULE_ID12, context), edgeTypes = getEdgeTypes(schema16), options = {
|
3775
3885
|
withEdgeSuffix: !0,
|
3776
3886
|
shouldImplementNode: !0,
|
3777
3887
|
listTypeCanWrapOnlyEdgeType: !0,
|
@@ -3786,7 +3896,7 @@ var schema9 = {
|
|
3786
3896
|
else if (!isNamedOrNonNullNamed(nodeField.gqlType))
|
3787
3897
|
context.report({ node: nodeField.name, message: `Field \`node\` must ${message}` });
|
3788
3898
|
else if (options.shouldImplementNode) {
|
3789
|
-
let nodeReturnTypeName = getTypeName(nodeField.gqlType.rawNode()), type =
|
3899
|
+
let nodeReturnTypeName = getTypeName(nodeField.gqlType.rawNode()), type = schema16.getType(nodeReturnTypeName);
|
3790
3900
|
if (!isObjectType2(type))
|
3791
3901
|
return;
|
3792
3902
|
type.astNode.interfaces?.some((n) => n.name.value === "Node") || context.report({ node: node.name, messageId: MESSAGE_SHOULD_IMPLEMENTS_NODE });
|
@@ -3801,10 +3911,10 @@ var schema9 = {
|
|
3801
3911
|
return;
|
3802
3912
|
}
|
3803
3913
|
let typeName = getTypeName(cursorField.rawNode());
|
3804
|
-
(!isNamedOrNonNullNamed(cursorField.gqlType) || typeName !== "String" && !isScalarType3(
|
3914
|
+
(!isNamedOrNonNullNamed(cursorField.gqlType) || typeName !== "String" && !isScalarType3(schema16.getType(typeName))) && context.report({ node: cursorField.name, message: `Field \`cursor\` must ${message}` });
|
3805
3915
|
}, listeners = {
|
3806
3916
|
":matches(ObjectTypeDefinition, ObjectTypeExtension)[name.value=/Connection$/] > FieldDefinition[name.value=edges] > .gqlType Name"(node) {
|
3807
|
-
let type =
|
3917
|
+
let type = schema16.getType(node.value);
|
3808
3918
|
isObjectType2(type) || context.report({ node, messageId: MESSAGE_MUST_BE_OBJECT_TYPE });
|
3809
3919
|
},
|
3810
3920
|
":matches(ObjectTypeDefinition, ObjectTypeExtension)"(node) {
|
@@ -3863,8 +3973,8 @@ var RULE_ID13 = "relay-page-info", MESSAGE_MUST_EXIST = "MESSAGE_MUST_EXIST", ME
|
|
3863
3973
|
schema: []
|
3864
3974
|
},
|
3865
3975
|
create(context) {
|
3866
|
-
let
|
3867
|
-
return hasPageInfoChecked || (
|
3976
|
+
let schema16 = requireGraphQLSchemaFromContext(RULE_ID13, context);
|
3977
|
+
return hasPageInfoChecked || (schema16.getType("PageInfo") || context.report({
|
3868
3978
|
loc: REPORT_ON_FIRST_CHARACTER,
|
3869
3979
|
messageId: MESSAGE_MUST_EXIST
|
3870
3980
|
}), hasPageInfoChecked = !0), {
|
@@ -3878,7 +3988,7 @@ var RULE_ID13 = "relay-page-info", MESSAGE_MUST_EXIST = "MESSAGE_MUST_EXIST", ME
|
|
3878
3988
|
let field = fieldMap[fieldName], isAllowedType = !1;
|
3879
3989
|
if (field) {
|
3880
3990
|
let type = field.gqlType;
|
3881
|
-
typeName === "Boolean" ? isAllowedType = type.kind === Kind17.NON_NULL_TYPE && type.gqlType.kind === Kind17.NAMED_TYPE && type.gqlType.name.value === "Boolean" : type.kind === Kind17.NAMED_TYPE && (isAllowedType = type.name.value === "String" || isScalarType4(
|
3991
|
+
typeName === "Boolean" ? isAllowedType = type.kind === Kind17.NON_NULL_TYPE && type.gqlType.kind === Kind17.NAMED_TYPE && type.gqlType.name.value === "Boolean" : type.kind === Kind17.NAMED_TYPE && (isAllowedType = type.name.value === "String" || isScalarType4(schema16.getType(type.name.value)));
|
3882
3992
|
}
|
3883
3993
|
if (!isAllowedType) {
|
3884
3994
|
let returnType = typeName === "Boolean" ? "non-null Boolean" : "either String or Scalar, which can be null if there are no results";
|
@@ -3895,7 +4005,7 @@ var RULE_ID13 = "relay-page-info", MESSAGE_MUST_EXIST = "MESSAGE_MUST_EXIST", ME
|
|
3895
4005
|
};
|
3896
4006
|
|
3897
4007
|
// src/rules/require-deprecation-date/index.ts
|
3898
|
-
var DATE_REGEX = /^\d{2}\/\d{2}\/\d{4}$/, MESSAGE_REQUIRE_DATE = "MESSAGE_REQUIRE_DATE", MESSAGE_INVALID_FORMAT = "MESSAGE_INVALID_FORMAT", MESSAGE_INVALID_DATE = "MESSAGE_INVALID_DATE", MESSAGE_CAN_BE_REMOVED = "MESSAGE_CAN_BE_REMOVED",
|
4008
|
+
var DATE_REGEX = /^\d{2}\/\d{2}\/\d{4}$/, MESSAGE_REQUIRE_DATE = "MESSAGE_REQUIRE_DATE", MESSAGE_INVALID_FORMAT = "MESSAGE_INVALID_FORMAT", MESSAGE_INVALID_DATE = "MESSAGE_INVALID_DATE", MESSAGE_CAN_BE_REMOVED = "MESSAGE_CAN_BE_REMOVED", schema11 = {
|
3899
4009
|
type: "array",
|
3900
4010
|
maxItems: 1,
|
3901
4011
|
items: {
|
@@ -3961,7 +4071,7 @@ var DATE_REGEX = /^\d{2}\/\d{2}\/\d{4}$/, MESSAGE_REQUIRE_DATE = "MESSAGE_REQUIR
|
|
3961
4071
|
[MESSAGE_INVALID_DATE]: 'Invalid "{{ deletionDate }}" deletion date for {{ nodeName }}',
|
3962
4072
|
[MESSAGE_CAN_BE_REMOVED]: "{{ nodeName }} \u0441an be removed"
|
3963
4073
|
},
|
3964
|
-
schema:
|
4074
|
+
schema: schema11
|
3965
4075
|
},
|
3966
4076
|
create(context) {
|
3967
4077
|
return {
|
@@ -4091,7 +4201,7 @@ var RULE_ID14 = "require-description", ALLOWED_KINDS2 = [
|
|
4091
4201
|
Kind18.INPUT_VALUE_DEFINITION,
|
4092
4202
|
Kind18.ENUM_VALUE_DEFINITION,
|
4093
4203
|
Kind18.OPERATION_DEFINITION
|
4094
|
-
],
|
4204
|
+
], schema12 = {
|
4095
4205
|
type: "array",
|
4096
4206
|
minItems: 1,
|
4097
4207
|
maxItems: 1,
|
@@ -4199,14 +4309,14 @@ ${TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
|
|
4199
4309
|
messages: {
|
4200
4310
|
[RULE_ID14]: "Description is required for {{ nodeName }}"
|
4201
4311
|
},
|
4202
|
-
schema:
|
4312
|
+
schema: schema12
|
4203
4313
|
},
|
4204
4314
|
create(context) {
|
4205
4315
|
let { types, rootField, ...restOptions } = context.options[0] || {}, kinds = new Set(types ? TYPES_KINDS : []);
|
4206
4316
|
for (let [kind, isEnabled] of Object.entries(restOptions))
|
4207
4317
|
isEnabled ? kinds.add(kind) : kinds.delete(kind);
|
4208
4318
|
if (rootField) {
|
4209
|
-
let
|
4319
|
+
let schema16 = requireGraphQLSchemaFromContext(RULE_ID14, context), rootTypeNames = getRootTypeNames(schema16);
|
4210
4320
|
kinds.add(
|
4211
4321
|
`:matches(ObjectTypeDefinition, ObjectTypeExtension)[name.value=/^(${[
|
4212
4322
|
...rootTypeNames
|
@@ -4285,10 +4395,10 @@ var RULE_ID15 = "require-field-of-type-query-in-mutation-result", rule24 = {
|
|
4285
4395
|
schema: []
|
4286
4396
|
},
|
4287
4397
|
create(context) {
|
4288
|
-
let
|
4398
|
+
let schema16 = requireGraphQLSchemaFromContext(RULE_ID15, context), mutationType = schema16.getMutationType(), queryType = schema16.getQueryType();
|
4289
4399
|
return !mutationType || !queryType ? {} : {
|
4290
4400
|
[`:matches(ObjectTypeDefinition, ObjectTypeExtension)[name.value=${mutationType.name}] > FieldDefinition > .gqlType Name`](node) {
|
4291
|
-
let typeName = node.value, graphQLType =
|
4401
|
+
let typeName = node.value, graphQLType = schema16.getType(typeName);
|
4292
4402
|
if (isObjectType3(graphQLType)) {
|
4293
4403
|
let { fields } = graphQLType.astNode;
|
4294
4404
|
fields?.some((field) => getTypeName(field) === queryType.name) || context.report({
|
@@ -4523,8 +4633,8 @@ var RULE_ID18 = "require-nullable-result-in-root", rule27 = {
|
|
4523
4633
|
schema: []
|
4524
4634
|
},
|
4525
4635
|
create(context) {
|
4526
|
-
let
|
4527
|
-
[
|
4636
|
+
let schema16 = requireGraphQLSchemaFromContext(RULE_ID18, context), rootTypeNames = new Set(
|
4637
|
+
[schema16.getQueryType(), schema16.getMutationType()].filter(truthy).map((type) => type.name)
|
4528
4638
|
), sourceCode = context.getSourceCode();
|
4529
4639
|
return {
|
4530
4640
|
"ObjectTypeDefinition,ObjectTypeExtension"(node) {
|
@@ -4532,7 +4642,7 @@ var RULE_ID18 = "require-nullable-result-in-root", rule27 = {
|
|
4532
4642
|
for (let field of node.fields || []) {
|
4533
4643
|
if (field.gqlType.type !== Kind20.NON_NULL_TYPE || field.gqlType.gqlType.type !== Kind20.NAMED_TYPE)
|
4534
4644
|
continue;
|
4535
|
-
let name = field.gqlType.gqlType.name.value, type =
|
4645
|
+
let name = field.gqlType.gqlType.name.value, type = schema16.getType(name), resultType = type?.astNode ? getNodeName(type.astNode) : type?.name;
|
4536
4646
|
context.report({
|
4537
4647
|
node: field.gqlType,
|
4538
4648
|
messageId: RULE_ID18,
|
@@ -4567,7 +4677,7 @@ import {
|
|
4567
4677
|
visitWithTypeInfo as visitWithTypeInfo3
|
4568
4678
|
} from "graphql";
|
4569
4679
|
import { asArray } from "@graphql-tools/utils";
|
4570
|
-
var RULE_ID19 = "require-selections", DEFAULT_ID_FIELD_NAME = "id",
|
4680
|
+
var RULE_ID19 = "require-selections", DEFAULT_ID_FIELD_NAME = "id", schema13 = {
|
4571
4681
|
definitions: {
|
4572
4682
|
asString: {
|
4573
4683
|
type: "string"
|
@@ -4652,10 +4762,10 @@ var RULE_ID19 = "require-selections", DEFAULT_ID_FIELD_NAME = "id", schema12 = {
|
|
4652
4762
|
[RULE_ID19]: `Field{{ pluralSuffix }} {{ fieldName }} must be selected when it's available on a type.
|
4653
4763
|
Include it in your selection set{{ addition }}.`
|
4654
4764
|
},
|
4655
|
-
schema:
|
4765
|
+
schema: schema13
|
4656
4766
|
},
|
4657
4767
|
create(context) {
|
4658
|
-
let
|
4768
|
+
let schema16 = requireGraphQLSchemaFromContext(RULE_ID19, context), siblings = requireSiblingsOperations(RULE_ID19, context), { fieldName = DEFAULT_ID_FIELD_NAME } = context.options[0] || {}, idNames = asArray(fieldName), selector = "OperationDefinition SelectionSet[parent.kind!=/(^OperationDefinition|InlineFragment)$/]", typeInfo = new TypeInfo3(schema16);
|
4659
4769
|
function checkFragments(node) {
|
4660
4770
|
for (let selection of node.selections) {
|
4661
4771
|
if (selection.kind !== Kind21.FRAGMENT_SPREAD)
|
@@ -4810,7 +4920,7 @@ var RULE_ID20 = "require-type-pattern-with-oneof", rule29 = {
|
|
4810
4920
|
// src/rules/selection-set-depth/index.ts
|
4811
4921
|
import { Kind as Kind22 } from "graphql";
|
4812
4922
|
import depthLimit from "graphql-depth-limit";
|
4813
|
-
var RULE_ID21 = "selection-set-depth",
|
4923
|
+
var RULE_ID21 = "selection-set-depth", schema14 = {
|
4814
4924
|
type: "array",
|
4815
4925
|
minItems: 1,
|
4816
4926
|
maxItems: 1,
|
@@ -4878,7 +4988,7 @@ var RULE_ID21 = "selection-set-depth", schema13 = {
|
|
4878
4988
|
recommended: !0,
|
4879
4989
|
configOptions: [{ maxDepth: 7 }]
|
4880
4990
|
},
|
4881
|
-
schema:
|
4991
|
+
schema: schema14
|
4882
4992
|
},
|
4883
4993
|
create(context) {
|
4884
4994
|
let siblings = null;
|
@@ -4939,7 +5049,7 @@ var RULE_ID21 = "selection-set-depth", schema13 = {
|
|
4939
5049
|
|
4940
5050
|
// src/rules/strict-id-in-types/index.ts
|
4941
5051
|
import { Kind as Kind23 } from "graphql";
|
4942
|
-
var RULE_ID22 = "strict-id-in-types",
|
5052
|
+
var RULE_ID22 = "strict-id-in-types", schema15 = {
|
4943
5053
|
type: "array",
|
4944
5054
|
maxItems: 1,
|
4945
5055
|
items: {
|
@@ -5047,7 +5157,7 @@ var RULE_ID22 = "strict-id-in-types", schema14 = {
|
|
5047
5157
|
}
|
5048
5158
|
]
|
5049
5159
|
},
|
5050
|
-
schema:
|
5160
|
+
schema: schema15
|
5051
5161
|
},
|
5052
5162
|
create(context) {
|
5053
5163
|
let options = {
|
@@ -5055,12 +5165,12 @@ var RULE_ID22 = "strict-id-in-types", schema14 = {
|
|
5055
5165
|
acceptedIdTypes: ["ID"],
|
5056
5166
|
exceptions: {},
|
5057
5167
|
...context.options[0]
|
5058
|
-
},
|
5168
|
+
}, schema16 = requireGraphQLSchemaFromContext(RULE_ID22, context);
|
5059
5169
|
return {
|
5060
5170
|
[`ObjectTypeDefinition[name.value!=/^(${[
|
5061
|
-
|
5062
|
-
|
5063
|
-
|
5171
|
+
schema16.getQueryType(),
|
5172
|
+
schema16.getMutationType(),
|
5173
|
+
schema16.getSubscriptionType()
|
5064
5174
|
].filter(truthy).map((type) => type.name).join("|")})$/]`](node) {
|
5065
5175
|
let typeName = node.name.value;
|
5066
5176
|
if (options.exceptions.types?.includes(typeName) || options.exceptions.suffixes?.some((suffix) => typeName.endsWith(suffix)))
|