@graphql-eslint/eslint-plugin 3.14.0-alpha-20221222204442-94bf749 → 3.14.0-alpha-20221222211346-788e7eb

Sign up to get free protection for your applications and to get access to all the features.
@@ -24,6 +24,7 @@ exports.default = {
24
24
  fragment: 'kebab-case',
25
25
  },
26
26
  ],
27
+ '@graphql-eslint/no-one-place-fragments': 'error',
27
28
  '@graphql-eslint/unique-fragment-name': 'error',
28
29
  '@graphql-eslint/unique-operation-name': 'error',
29
30
  },
@@ -16,6 +16,7 @@ const no_case_insensitive_enum_values_duplicates_1 = require("./no-case-insensit
16
16
  const no_deprecated_1 = require("./no-deprecated");
17
17
  const no_duplicate_fields_1 = require("./no-duplicate-fields");
18
18
  const no_hashtag_description_1 = require("./no-hashtag-description");
19
+ const no_one_place_fragments_1 = require("./no-one-place-fragments");
19
20
  const no_root_type_1 = require("./no-root-type");
20
21
  const no_scalar_result_type_on_mutation_1 = require("./no-scalar-result-type-on-mutation");
21
22
  const no_typename_prefix_1 = require("./no-typename-prefix");
@@ -49,6 +50,7 @@ exports.rules = {
49
50
  'no-deprecated': no_deprecated_1.rule,
50
51
  'no-duplicate-fields': no_duplicate_fields_1.rule,
51
52
  'no-hashtag-description': no_hashtag_description_1.rule,
53
+ 'no-one-place-fragments': no_one_place_fragments_1.rule,
52
54
  'no-root-type': no_root_type_1.rule,
53
55
  'no-scalar-result-type-on-mutation': no_scalar_result_type_on_mutation_1.rule,
54
56
  'no-typename-prefix': no_typename_prefix_1.rule,
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rule = void 0;
4
+ const eslint_plugin_1 = require("@graphql-eslint/eslint-plugin");
5
+ const utils_1 = require("../utils");
6
+ const path_1 = require("path");
7
+ const graphql_1 = require("graphql");
8
+ const RULE_ID = 'no-one-place-fragments';
9
+ exports.rule = {
10
+ meta: {
11
+ type: 'suggestion',
12
+ docs: {
13
+ category: 'Operations',
14
+ description: 'Disallow fragments that are used only in one place.',
15
+ url: `https://github.com/B2o5T/graphql-eslint/blob/master/docs/rules/${RULE_ID}.md`,
16
+ examples: [
17
+ {
18
+ title: 'Incorrect',
19
+ code: /* GraphQL */ `
20
+ fragment UserFields on User {
21
+ id
22
+ }
23
+
24
+ {
25
+ user {
26
+ ...UserFields
27
+ friends {
28
+ ...UserFields
29
+ }
30
+ }
31
+ }
32
+ `,
33
+ },
34
+ {
35
+ title: 'Correct',
36
+ code: /* GraphQL */ `
37
+ fragment UserFields on User {
38
+ id
39
+ }
40
+
41
+ {
42
+ user {
43
+ ...UserFields
44
+ }
45
+ }
46
+ `,
47
+ },
48
+ ],
49
+ requiresSiblings: true,
50
+ },
51
+ messages: {
52
+ [RULE_ID]: 'Fragment `{{fragmentName}}` used only once. Inline him in "{{filePath}}".',
53
+ },
54
+ schema: [],
55
+ },
56
+ create(context) {
57
+ const operations = (0, eslint_plugin_1.requireSiblingsOperations)(RULE_ID, context);
58
+ const allDocuments = [...operations.getOperations(), ...operations.getFragments()];
59
+ const usedFragmentsMap = Object.create(null);
60
+ for (const { document, filePath } of allDocuments) {
61
+ const relativeFilePath = (0, path_1.relative)(utils_1.CWD, filePath);
62
+ (0, graphql_1.visit)(document, {
63
+ FragmentSpread({ name }) {
64
+ const spreadName = name.value;
65
+ usedFragmentsMap[spreadName] || (usedFragmentsMap[spreadName] = []);
66
+ usedFragmentsMap[spreadName].push(relativeFilePath);
67
+ },
68
+ });
69
+ }
70
+ return {
71
+ 'FragmentDefinition > Name'(node) {
72
+ const fragmentName = node.value;
73
+ const fragmentUsage = usedFragmentsMap[fragmentName];
74
+ if (fragmentUsage.length === 1) {
75
+ context.report({
76
+ node,
77
+ messageId: RULE_ID,
78
+ data: { fragmentName, filePath: fragmentUsage[0] },
79
+ });
80
+ }
81
+ },
82
+ };
83
+ },
84
+ };
package/docs/README.md CHANGED
@@ -36,6 +36,7 @@ Name            &nbs
36
36
  [no-duplicate-fields](rules/no-duplicate-fields.md)|Checks for duplicate fields in selection set, variables in operation definition, or in arguments set of a field.|![recommended][]|đŸ“Ļ|🚀|💡
37
37
  [no-fragment-cycles](rules/no-fragment-cycles.md)|A GraphQL fragment is only valid when it does not have cycles in fragments usage.|![recommended][]|đŸ“Ļ|🔮|
38
38
  [no-hashtag-description](rules/no-hashtag-description.md)|Requires to use `"""` or `"` for adding a GraphQL description instead of `#`.|![recommended][]|📄|🚀|💡
39
+ [no-one-place-fragments](rules/no-one-place-fragments.md)|Disallow fragments that are used only in one place.|![all][]|đŸ“Ļ|🚀|
39
40
  [no-root-type](rules/no-root-type.md)|Disallow using root types `mutation` and/or `subscription`.||📄|🚀|💡
40
41
  [no-scalar-result-type-on-mutation](rules/no-scalar-result-type-on-mutation.md)|Avoid scalar result type on mutation type to make sure to return a valid state.|![all][]|📄|🚀|💡
41
42
  [no-typename-prefix](rules/no-typename-prefix.md)|Enforces users to avoid using the type name in a field name while defining your schema.|![recommended][]|📄|🚀|💡
@@ -0,0 +1,51 @@
1
+ # `no-one-place-fragments`
2
+
3
+ - Category: `Operations`
4
+ - Rule name: `@graphql-eslint/no-one-place-fragments`
5
+ - Requires GraphQL Schema: `false` [ℹī¸](../../README.md#extended-linting-rules-with-graphql-schema)
6
+ - Requires GraphQL Operations: `true`
7
+ [ℹī¸](../../README.md#extended-linting-rules-with-siblings-operations)
8
+
9
+ Disallow fragments that are used only in one place.
10
+
11
+ ## Usage Examples
12
+
13
+ ### Incorrect
14
+
15
+ ```graphql
16
+ # eslint @graphql-eslint/no-one-place-fragments: 'error'
17
+
18
+ fragment UserFields on User {
19
+ id
20
+ }
21
+
22
+ {
23
+ user {
24
+ ...UserFields
25
+ friends {
26
+ ...UserFields
27
+ }
28
+ }
29
+ }
30
+ ```
31
+
32
+ ### Correct
33
+
34
+ ```graphql
35
+ # eslint @graphql-eslint/no-one-place-fragments: 'error'
36
+
37
+ fragment UserFields on User {
38
+ id
39
+ }
40
+
41
+ {
42
+ user {
43
+ ...UserFields
44
+ }
45
+ }
46
+ ```
47
+
48
+ ## Resources
49
+
50
+ - [Rule source](../../packages/plugin/src/rules/no-one-place-fragments.ts)
51
+ - [Test source](../../packages/plugin/tests/no-one-place-fragments.spec.ts)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphql-eslint/eslint-plugin",
3
- "version": "3.14.0-alpha-20221222204442-94bf749",
3
+ "version": "3.14.0-alpha-20221222211346-788e7eb",
4
4
  "description": "GraphQL plugin for ESLint",
5
5
  "sideEffects": false,
6
6
  "peerDependencies": {
@@ -125,6 +125,7 @@ export declare const configs: {
125
125
  subscription: string;
126
126
  fragment: string;
127
127
  })[];
128
+ '@graphql-eslint/no-one-place-fragments': string;
128
129
  '@graphql-eslint/unique-fragment-name': string;
129
130
  '@graphql-eslint/unique-operation-name': string;
130
131
  };
@@ -125,6 +125,7 @@ export declare const configs: {
125
125
  subscription: string;
126
126
  fragment: string;
127
127
  })[];
128
+ '@graphql-eslint/no-one-place-fragments': string;
128
129
  '@graphql-eslint/unique-fragment-name': string;
129
130
  '@graphql-eslint/unique-operation-name': string;
130
131
  };
@@ -13,6 +13,7 @@ declare const _default: {
13
13
  subscription: string;
14
14
  fragment: string;
15
15
  })[];
16
+ '@graphql-eslint/no-one-place-fragments': string;
16
17
  '@graphql-eslint/unique-fragment-name': string;
17
18
  '@graphql-eslint/unique-operation-name': string;
18
19
  };
@@ -13,6 +13,7 @@ declare const _default: {
13
13
  subscription: string;
14
14
  fragment: string;
15
15
  })[];
16
+ '@graphql-eslint/no-one-place-fragments': string;
16
17
  '@graphql-eslint/unique-fragment-name': string;
17
18
  '@graphql-eslint/unique-operation-name': string;
18
19
  };
@@ -61,6 +61,7 @@ export declare const rules: {
61
61
  'no-deprecated': import("..").GraphQLESLintRule<[], true>;
62
62
  'no-duplicate-fields': import("..").GraphQLESLintRule<any[], false>;
63
63
  'no-hashtag-description': import("..").GraphQLESLintRule<any[], false>;
64
+ 'no-one-place-fragments': import("..").GraphQLESLintRule<any[], false>;
64
65
  'no-root-type': import("..").GraphQLESLintRule<{
65
66
  disallow: ("mutation" | "subscription")[];
66
67
  }[], false>;
@@ -61,6 +61,7 @@ export declare const rules: {
61
61
  'no-deprecated': import("..").GraphQLESLintRule<[], true>;
62
62
  'no-duplicate-fields': import("..").GraphQLESLintRule<any[], false>;
63
63
  'no-hashtag-description': import("..").GraphQLESLintRule<any[], false>;
64
+ 'no-one-place-fragments': import("..").GraphQLESLintRule<any[], false>;
64
65
  'no-root-type': import("..").GraphQLESLintRule<{
65
66
  disallow: ("mutation" | "subscription")[];
66
67
  }[], false>;
@@ -0,0 +1,2 @@
1
+ import { GraphQLESLintRule } from '../types';
2
+ export declare const rule: GraphQLESLintRule;
@@ -0,0 +1,2 @@
1
+ import { GraphQLESLintRule } from '../types';
2
+ export declare const rule: GraphQLESLintRule;