@graphql-eslint/eslint-plugin 3.3.0-alpha-db2c2cb.0 → 3.3.0-alpha-0df1b98.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/require-id-when-available.md +2 -2
- package/index.js +33 -33
- package/index.mjs +33 -33
- package/package.json +3 -2
- package/rules/index.d.ts +1 -3
- package/rules/require-id-when-available.d.ts +2 -2
package/index.js
CHANGED
@@ -2866,7 +2866,8 @@ const convertNode = (typeInfo) => (node, key, parent) => {
|
|
2866
2866
|
}
|
2867
2867
|
};
|
2868
2868
|
|
2869
|
-
const
|
2869
|
+
const RULE_ID$2 = 'require-id-when-available';
|
2870
|
+
const MESSAGE_ID = 'REQUIRE_ID_WHEN_AVAILABLE';
|
2870
2871
|
const DEFAULT_ID_FIELD_NAME = 'id';
|
2871
2872
|
const rule$j = {
|
2872
2873
|
meta: {
|
@@ -2874,7 +2875,7 @@ const rule$j = {
|
|
2874
2875
|
docs: {
|
2875
2876
|
category: 'Operations',
|
2876
2877
|
description: 'Enforce selecting specific fields when they are available on the GraphQL type.',
|
2877
|
-
url:
|
2878
|
+
url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_ID$2}.md`,
|
2878
2879
|
requiresSchema: true,
|
2879
2880
|
requiresSiblings: true,
|
2880
2881
|
examples: [
|
@@ -2888,7 +2889,7 @@ const rule$j = {
|
|
2888
2889
|
}
|
2889
2890
|
|
2890
2891
|
# Query
|
2891
|
-
query
|
2892
|
+
query {
|
2892
2893
|
user {
|
2893
2894
|
name
|
2894
2895
|
}
|
@@ -2905,7 +2906,7 @@ const rule$j = {
|
|
2905
2906
|
}
|
2906
2907
|
|
2907
2908
|
# Query
|
2908
|
-
query
|
2909
|
+
query {
|
2909
2910
|
user {
|
2910
2911
|
id
|
2911
2912
|
name
|
@@ -2917,7 +2918,7 @@ const rule$j = {
|
|
2917
2918
|
recommended: true,
|
2918
2919
|
},
|
2919
2920
|
messages: {
|
2920
|
-
[
|
2921
|
+
[MESSAGE_ID]: [
|
2921
2922
|
`Field {{ fieldName }} must be selected when it's available on a type. Please make sure to include it in your selection set!`,
|
2922
2923
|
`If you are using fragments, make sure that all used fragments {{ checkedFragments }}specifies the field {{ fieldName }}.`,
|
2923
2924
|
].join('\n'),
|
@@ -2948,14 +2949,16 @@ const rule$j = {
|
|
2948
2949
|
},
|
2949
2950
|
},
|
2950
2951
|
create(context) {
|
2951
|
-
requireGraphQLSchemaFromContext(
|
2952
|
-
const siblings = requireSiblingsOperations(
|
2952
|
+
requireGraphQLSchemaFromContext(RULE_ID$2, context);
|
2953
|
+
const siblings = requireSiblingsOperations(RULE_ID$2, context);
|
2953
2954
|
const { fieldName = DEFAULT_ID_FIELD_NAME } = context.options[0] || {};
|
2954
|
-
const idNames =
|
2955
|
+
const idNames = utils.asArray(fieldName);
|
2955
2956
|
const isFound = (s) => s.kind === graphql.Kind.FIELD && idNames.includes(s.name.value);
|
2957
|
+
// Skip check selections in FragmentDefinition
|
2958
|
+
const selector = 'OperationDefinition SelectionSet[parent.kind!=OperationDefinition]';
|
2956
2959
|
return {
|
2957
|
-
|
2958
|
-
var _a
|
2960
|
+
[selector](node) {
|
2961
|
+
var _a;
|
2959
2962
|
const typeInfo = node.typeInfo();
|
2960
2963
|
if (!typeInfo.gqlType) {
|
2961
2964
|
return;
|
@@ -2972,41 +2975,38 @@ const rule$j = {
|
|
2972
2975
|
return;
|
2973
2976
|
}
|
2974
2977
|
const checkedFragmentSpreads = new Set();
|
2975
|
-
let found = false;
|
2976
2978
|
for (const selection of node.selections) {
|
2977
2979
|
if (isFound(selection)) {
|
2978
|
-
|
2980
|
+
return;
|
2979
2981
|
}
|
2980
|
-
|
2981
|
-
|
2982
|
+
if (selection.kind === graphql.Kind.INLINE_FRAGMENT && selection.selectionSet.selections.some(isFound)) {
|
2983
|
+
return;
|
2982
2984
|
}
|
2983
|
-
|
2985
|
+
if (selection.kind === graphql.Kind.FRAGMENT_SPREAD) {
|
2984
2986
|
const [foundSpread] = siblings.getFragment(selection.name.value);
|
2985
2987
|
if (foundSpread) {
|
2986
2988
|
checkedFragmentSpreads.add(foundSpread.document.name.value);
|
2987
|
-
|
2989
|
+
if (foundSpread.document.selectionSet.selections.some(isFound)) {
|
2990
|
+
return;
|
2991
|
+
}
|
2988
2992
|
}
|
2989
2993
|
}
|
2990
|
-
if (found) {
|
2991
|
-
break;
|
2992
|
-
}
|
2993
2994
|
}
|
2994
2995
|
const { parent } = node;
|
2995
|
-
const hasIdFieldInInterfaceSelectionSet = parent &&
|
2996
|
-
parent.kind === graphql.Kind.
|
2997
|
-
parent.parent
|
2998
|
-
|
2999
|
-
|
3000
|
-
if (!found && !hasIdFieldInInterfaceSelectionSet) {
|
3001
|
-
context.report({
|
3002
|
-
loc: getLocation(node.loc),
|
3003
|
-
messageId: REQUIRE_ID_WHEN_AVAILABLE,
|
3004
|
-
data: {
|
3005
|
-
checkedFragments: checkedFragmentSpreads.size === 0 ? '' : `(${[...checkedFragmentSpreads].join(', ')}) `,
|
3006
|
-
fieldName: idNames.map(name => `"${name}"`).join(' or '),
|
3007
|
-
},
|
3008
|
-
});
|
2996
|
+
const hasIdFieldInInterfaceSelectionSet = (parent === null || parent === void 0 ? void 0 : parent.kind) === graphql.Kind.INLINE_FRAGMENT &&
|
2997
|
+
((_a = parent.parent) === null || _a === void 0 ? void 0 : _a.kind) === graphql.Kind.SELECTION_SET &&
|
2998
|
+
parent.parent.selections.some(isFound);
|
2999
|
+
if (hasIdFieldInInterfaceSelectionSet) {
|
3000
|
+
return;
|
3009
3001
|
}
|
3002
|
+
context.report({
|
3003
|
+
loc: getLocation(node.loc),
|
3004
|
+
messageId: MESSAGE_ID,
|
3005
|
+
data: {
|
3006
|
+
checkedFragments: checkedFragmentSpreads.size === 0 ? '' : `(${[...checkedFragmentSpreads].join(', ')}) `,
|
3007
|
+
fieldName: idNames.map(name => `"${name}"`).join(' or '),
|
3008
|
+
},
|
3009
|
+
});
|
3010
3010
|
},
|
3011
3011
|
};
|
3012
3012
|
},
|
package/index.mjs
CHANGED
@@ -2860,7 +2860,8 @@ const convertNode = (typeInfo) => (node, key, parent) => {
|
|
2860
2860
|
}
|
2861
2861
|
};
|
2862
2862
|
|
2863
|
-
const
|
2863
|
+
const RULE_ID$2 = 'require-id-when-available';
|
2864
|
+
const MESSAGE_ID = 'REQUIRE_ID_WHEN_AVAILABLE';
|
2864
2865
|
const DEFAULT_ID_FIELD_NAME = 'id';
|
2865
2866
|
const rule$j = {
|
2866
2867
|
meta: {
|
@@ -2868,7 +2869,7 @@ const rule$j = {
|
|
2868
2869
|
docs: {
|
2869
2870
|
category: 'Operations',
|
2870
2871
|
description: 'Enforce selecting specific fields when they are available on the GraphQL type.',
|
2871
|
-
url:
|
2872
|
+
url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_ID$2}.md`,
|
2872
2873
|
requiresSchema: true,
|
2873
2874
|
requiresSiblings: true,
|
2874
2875
|
examples: [
|
@@ -2882,7 +2883,7 @@ const rule$j = {
|
|
2882
2883
|
}
|
2883
2884
|
|
2884
2885
|
# Query
|
2885
|
-
query
|
2886
|
+
query {
|
2886
2887
|
user {
|
2887
2888
|
name
|
2888
2889
|
}
|
@@ -2899,7 +2900,7 @@ const rule$j = {
|
|
2899
2900
|
}
|
2900
2901
|
|
2901
2902
|
# Query
|
2902
|
-
query
|
2903
|
+
query {
|
2903
2904
|
user {
|
2904
2905
|
id
|
2905
2906
|
name
|
@@ -2911,7 +2912,7 @@ const rule$j = {
|
|
2911
2912
|
recommended: true,
|
2912
2913
|
},
|
2913
2914
|
messages: {
|
2914
|
-
[
|
2915
|
+
[MESSAGE_ID]: [
|
2915
2916
|
`Field {{ fieldName }} must be selected when it's available on a type. Please make sure to include it in your selection set!`,
|
2916
2917
|
`If you are using fragments, make sure that all used fragments {{ checkedFragments }}specifies the field {{ fieldName }}.`,
|
2917
2918
|
].join('\n'),
|
@@ -2942,14 +2943,16 @@ const rule$j = {
|
|
2942
2943
|
},
|
2943
2944
|
},
|
2944
2945
|
create(context) {
|
2945
|
-
requireGraphQLSchemaFromContext(
|
2946
|
-
const siblings = requireSiblingsOperations(
|
2946
|
+
requireGraphQLSchemaFromContext(RULE_ID$2, context);
|
2947
|
+
const siblings = requireSiblingsOperations(RULE_ID$2, context);
|
2947
2948
|
const { fieldName = DEFAULT_ID_FIELD_NAME } = context.options[0] || {};
|
2948
|
-
const idNames =
|
2949
|
+
const idNames = asArray(fieldName);
|
2949
2950
|
const isFound = (s) => s.kind === Kind.FIELD && idNames.includes(s.name.value);
|
2951
|
+
// Skip check selections in FragmentDefinition
|
2952
|
+
const selector = 'OperationDefinition SelectionSet[parent.kind!=OperationDefinition]';
|
2950
2953
|
return {
|
2951
|
-
|
2952
|
-
var _a
|
2954
|
+
[selector](node) {
|
2955
|
+
var _a;
|
2953
2956
|
const typeInfo = node.typeInfo();
|
2954
2957
|
if (!typeInfo.gqlType) {
|
2955
2958
|
return;
|
@@ -2966,41 +2969,38 @@ const rule$j = {
|
|
2966
2969
|
return;
|
2967
2970
|
}
|
2968
2971
|
const checkedFragmentSpreads = new Set();
|
2969
|
-
let found = false;
|
2970
2972
|
for (const selection of node.selections) {
|
2971
2973
|
if (isFound(selection)) {
|
2972
|
-
|
2974
|
+
return;
|
2973
2975
|
}
|
2974
|
-
|
2975
|
-
|
2976
|
+
if (selection.kind === Kind.INLINE_FRAGMENT && selection.selectionSet.selections.some(isFound)) {
|
2977
|
+
return;
|
2976
2978
|
}
|
2977
|
-
|
2979
|
+
if (selection.kind === Kind.FRAGMENT_SPREAD) {
|
2978
2980
|
const [foundSpread] = siblings.getFragment(selection.name.value);
|
2979
2981
|
if (foundSpread) {
|
2980
2982
|
checkedFragmentSpreads.add(foundSpread.document.name.value);
|
2981
|
-
|
2983
|
+
if (foundSpread.document.selectionSet.selections.some(isFound)) {
|
2984
|
+
return;
|
2985
|
+
}
|
2982
2986
|
}
|
2983
2987
|
}
|
2984
|
-
if (found) {
|
2985
|
-
break;
|
2986
|
-
}
|
2987
2988
|
}
|
2988
2989
|
const { parent } = node;
|
2989
|
-
const hasIdFieldInInterfaceSelectionSet = parent &&
|
2990
|
-
parent.kind === Kind.
|
2991
|
-
parent.parent
|
2992
|
-
|
2993
|
-
|
2994
|
-
if (!found && !hasIdFieldInInterfaceSelectionSet) {
|
2995
|
-
context.report({
|
2996
|
-
loc: getLocation(node.loc),
|
2997
|
-
messageId: REQUIRE_ID_WHEN_AVAILABLE,
|
2998
|
-
data: {
|
2999
|
-
checkedFragments: checkedFragmentSpreads.size === 0 ? '' : `(${[...checkedFragmentSpreads].join(', ')}) `,
|
3000
|
-
fieldName: idNames.map(name => `"${name}"`).join(' or '),
|
3001
|
-
},
|
3002
|
-
});
|
2990
|
+
const hasIdFieldInInterfaceSelectionSet = (parent === null || parent === void 0 ? void 0 : parent.kind) === Kind.INLINE_FRAGMENT &&
|
2991
|
+
((_a = parent.parent) === null || _a === void 0 ? void 0 : _a.kind) === Kind.SELECTION_SET &&
|
2992
|
+
parent.parent.selections.some(isFound);
|
2993
|
+
if (hasIdFieldInInterfaceSelectionSet) {
|
2994
|
+
return;
|
3003
2995
|
}
|
2996
|
+
context.report({
|
2997
|
+
loc: getLocation(node.loc),
|
2998
|
+
messageId: MESSAGE_ID,
|
2999
|
+
data: {
|
3000
|
+
checkedFragments: checkedFragmentSpreads.size === 0 ? '' : `(${[...checkedFragmentSpreads].join(', ')}) `,
|
3001
|
+
fieldName: idNames.map(name => `"${name}"`).join(' or '),
|
3002
|
+
},
|
3003
|
+
});
|
3004
3004
|
},
|
3005
3005
|
};
|
3006
3006
|
},
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@graphql-eslint/eslint-plugin",
|
3
|
-
"version": "3.3.0-alpha-
|
3
|
+
"version": "3.3.0-alpha-0df1b98.0",
|
4
4
|
"description": "GraphQL plugin for ESLint",
|
5
5
|
"sideEffects": false,
|
6
6
|
"peerDependencies": {
|
@@ -10,7 +10,7 @@
|
|
10
10
|
"@babel/code-frame": "7.16.0",
|
11
11
|
"@graphql-tools/code-file-loader": "7.2.3",
|
12
12
|
"@graphql-tools/graphql-tag-pluck": "7.1.4",
|
13
|
-
"@graphql-tools/utils": "8.5.
|
13
|
+
"@graphql-tools/utils": "8.5.5",
|
14
14
|
"graphql-config": "4.1.0",
|
15
15
|
"graphql-depth-limit": "1.1.0",
|
16
16
|
"lodash.lowercase": "4.3.0"
|
@@ -31,6 +31,7 @@
|
|
31
31
|
"definition": "index.d.ts"
|
32
32
|
},
|
33
33
|
"exports": {
|
34
|
+
"./package.json": "./package.json",
|
34
35
|
".": {
|
35
36
|
"require": "./index.js",
|
36
37
|
"import": "./index.mjs"
|
package/rules/index.d.ts
CHANGED
@@ -48,9 +48,7 @@ export declare const rules: {
|
|
48
48
|
DirectiveDefinition?: boolean;
|
49
49
|
}], false>;
|
50
50
|
'require-field-of-type-query-in-mutation-result': import("..").GraphQLESLintRule<any[], false>;
|
51
|
-
'require-id-when-available': import("..").GraphQLESLintRule<[
|
52
|
-
fieldName: string;
|
53
|
-
}], true>;
|
51
|
+
'require-id-when-available': import("..").GraphQLESLintRule<[import("./require-id-when-available").RequireIdWhenAvailableRuleConfig], true>;
|
54
52
|
'selection-set-depth': import("..").GraphQLESLintRule<[{
|
55
53
|
maxDepth: number;
|
56
54
|
ignore?: string[];
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { GraphQLESLintRule } from '../types';
|
2
|
-
declare type RequireIdWhenAvailableRuleConfig = {
|
3
|
-
fieldName: string;
|
2
|
+
export declare type RequireIdWhenAvailableRuleConfig = {
|
3
|
+
fieldName: string | string[];
|
4
4
|
};
|
5
5
|
declare const rule: GraphQLESLintRule<[RequireIdWhenAvailableRuleConfig], true>;
|
6
6
|
export default rule;
|