@graphql-eslint/eslint-plugin 4.3.0 → 4.3.1-alpha-20241209185034-de2d7397da8c26620a8930dd12b6dff42e43f537

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.
Files changed (100) hide show
  1. package/{index.browser.js → browser.js} +1756 -1104
  2. package/cjs/cache.js +6 -2
  3. package/cjs/configs/operations-all.js +2 -2
  4. package/cjs/configs/schema-all.js +2 -2
  5. package/cjs/configs/schema-recommended.js +1 -1
  6. package/cjs/documents.js +13 -7
  7. package/cjs/estree-converter/converter.js +17 -8
  8. package/cjs/estree-converter/utils.js +22 -9
  9. package/cjs/graphql-config.js +13 -6
  10. package/cjs/meta.js +1 -1
  11. package/cjs/parser.js +36 -9
  12. package/cjs/processor.js +48 -20
  13. package/cjs/rules/alphabetize/index.js +99 -47
  14. package/cjs/rules/description-style/index.js +10 -6
  15. package/cjs/rules/graphql-js-validation.js +142 -108
  16. package/cjs/rules/input-name/index.js +51 -38
  17. package/cjs/rules/lone-executable-definition/index.js +15 -6
  18. package/cjs/rules/match-document-filename/index.js +57 -32
  19. package/cjs/rules/naming-convention/index.js +76 -37
  20. package/cjs/rules/no-anonymous-operations/index.js +8 -5
  21. package/cjs/rules/no-deprecated/index.js +27 -13
  22. package/cjs/rules/no-duplicate-fields/index.js +15 -8
  23. package/cjs/rules/no-hashtag-description/index.js +18 -10
  24. package/cjs/rules/no-one-place-fragments/index.js +17 -10
  25. package/cjs/rules/no-root-type/index.js +15 -8
  26. package/cjs/rules/no-scalar-result-type-on-mutation/index.js +20 -12
  27. package/cjs/rules/no-typename-prefix/index.js +25 -21
  28. package/cjs/rules/no-unreachable-types/index.js +34 -17
  29. package/cjs/rules/no-unused-fields/index.js +56 -30
  30. package/cjs/rules/relay-arguments/index.js +31 -13
  31. package/cjs/rules/relay-connection-types/index.js +31 -9
  32. package/cjs/rules/relay-edge-types/index.js +84 -41
  33. package/cjs/rules/relay-page-info/index.js +31 -14
  34. package/cjs/rules/require-deprecation-date/index.js +20 -9
  35. package/cjs/rules/require-deprecation-reason/index.js +8 -5
  36. package/cjs/rules/require-description/index.js +60 -42
  37. package/cjs/rules/require-field-of-type-query-in-mutation-result/index.js +21 -10
  38. package/cjs/rules/require-import-fragment/index.js +20 -11
  39. package/cjs/rules/require-nullable-fields-with-oneof/index.js +12 -5
  40. package/cjs/rules/require-nullable-result-in-root/index.js +32 -27
  41. package/cjs/rules/require-selections/index.js +88 -46
  42. package/cjs/rules/require-type-pattern-with-oneof/index.js +14 -10
  43. package/cjs/rules/selection-set-depth/index.js +19 -10
  44. package/cjs/rules/strict-id-in-types/index.js +32 -19
  45. package/cjs/rules/unique-enum-value-names/index.js +4 -3
  46. package/cjs/rules/unique-fragment-name/index.js +25 -18
  47. package/cjs/rules/unique-operation-name/index.js +5 -5
  48. package/cjs/schema.js +14 -8
  49. package/cjs/siblings.js +60 -32
  50. package/cjs/utils.js +23 -9
  51. package/esm/cache.js +6 -2
  52. package/esm/configs/operations-all.js +2 -2
  53. package/esm/configs/schema-all.js +2 -2
  54. package/esm/configs/schema-recommended.js +1 -1
  55. package/esm/documents.js +13 -7
  56. package/esm/estree-converter/converter.js +17 -8
  57. package/esm/estree-converter/utils.js +22 -9
  58. package/esm/graphql-config.js +13 -6
  59. package/esm/meta.js +1 -1
  60. package/esm/parser.js +36 -9
  61. package/esm/processor.js +48 -20
  62. package/esm/rules/alphabetize/index.js +99 -47
  63. package/esm/rules/description-style/index.js +10 -6
  64. package/esm/rules/graphql-js-validation.js +142 -108
  65. package/esm/rules/input-name/index.js +51 -38
  66. package/esm/rules/lone-executable-definition/index.js +15 -6
  67. package/esm/rules/match-document-filename/index.js +57 -32
  68. package/esm/rules/naming-convention/index.js +76 -37
  69. package/esm/rules/no-anonymous-operations/index.js +8 -5
  70. package/esm/rules/no-deprecated/index.js +27 -13
  71. package/esm/rules/no-duplicate-fields/index.js +15 -8
  72. package/esm/rules/no-hashtag-description/index.js +18 -10
  73. package/esm/rules/no-one-place-fragments/index.js +17 -10
  74. package/esm/rules/no-root-type/index.js +15 -8
  75. package/esm/rules/no-scalar-result-type-on-mutation/index.js +20 -12
  76. package/esm/rules/no-typename-prefix/index.js +25 -21
  77. package/esm/rules/no-unreachable-types/index.js +34 -17
  78. package/esm/rules/no-unused-fields/index.js +56 -30
  79. package/esm/rules/relay-arguments/index.js +31 -13
  80. package/esm/rules/relay-connection-types/index.js +31 -9
  81. package/esm/rules/relay-edge-types/index.js +84 -41
  82. package/esm/rules/relay-page-info/index.js +31 -14
  83. package/esm/rules/require-deprecation-date/index.js +20 -9
  84. package/esm/rules/require-deprecation-reason/index.js +8 -5
  85. package/esm/rules/require-description/index.js +60 -42
  86. package/esm/rules/require-field-of-type-query-in-mutation-result/index.js +21 -10
  87. package/esm/rules/require-import-fragment/index.js +20 -11
  88. package/esm/rules/require-nullable-fields-with-oneof/index.js +12 -5
  89. package/esm/rules/require-nullable-result-in-root/index.js +32 -27
  90. package/esm/rules/require-selections/index.js +88 -46
  91. package/esm/rules/require-type-pattern-with-oneof/index.js +14 -10
  92. package/esm/rules/selection-set-depth/index.js +19 -10
  93. package/esm/rules/strict-id-in-types/index.js +32 -19
  94. package/esm/rules/unique-enum-value-names/index.js +4 -3
  95. package/esm/rules/unique-fragment-name/index.js +25 -18
  96. package/esm/rules/unique-operation-name/index.js +5 -5
  97. package/esm/schema.js +15 -8
  98. package/esm/siblings.js +60 -32
  99. package/esm/utils.js +23 -9
  100. package/package.json +11 -1
@@ -1,5 +1,6 @@
1
1
  import { displayNodeName } from "../../utils.js";
2
- const RULE_ID = "require-type-pattern-with-oneof", rule = {
2
+ const RULE_ID = "require-type-pattern-with-oneof";
3
+ const rule = {
3
4
  meta: {
4
5
  type: "suggestion",
5
6
  docs: {
@@ -44,15 +45,18 @@ const RULE_ID = "require-type-pattern-with-oneof", rule = {
44
45
  parent
45
46
  }) {
46
47
  const requiredFields = ["error", "ok"];
47
- for (const fieldName of requiredFields)
48
- parent.fields?.some((field) => field.name.value === fieldName) || context.report({
49
- node: parent.name,
50
- messageId: RULE_ID,
51
- data: {
52
- nodeName: displayNodeName(parent),
53
- fieldName
54
- }
55
- });
48
+ for (const fieldName of requiredFields) {
49
+ if (!parent.fields?.some((field) => field.name.value === fieldName)) {
50
+ context.report({
51
+ node: parent.name,
52
+ messageId: RULE_ID,
53
+ data: {
54
+ nodeName: displayNodeName(parent),
55
+ fieldName
56
+ }
57
+ });
58
+ }
59
+ }
56
60
  }
57
61
  };
58
62
  }
@@ -1,13 +1,14 @@
1
1
  import { Kind } from "graphql";
2
2
  import depthLimit from "graphql-depth-limit";
3
3
  import { ARRAY_DEFAULT_OPTIONS, logger, requireGraphQLOperations } from "../../utils.js";
4
- const RULE_ID = "selection-set-depth", schema = {
4
+ const RULE_ID = "selection-set-depth";
5
+ const schema = {
5
6
  type: "array",
6
7
  minItems: 1,
7
8
  maxItems: 1,
8
9
  items: {
9
10
  type: "object",
10
- additionalProperties: !1,
11
+ additionalProperties: false,
11
12
  required: ["maxDepth"],
12
13
  properties: {
13
14
  maxDepth: {
@@ -16,15 +17,16 @@ const RULE_ID = "selection-set-depth", schema = {
16
17
  ignore: ARRAY_DEFAULT_OPTIONS
17
18
  }
18
19
  }
19
- }, rule = {
20
+ };
21
+ const rule = {
20
22
  meta: {
21
23
  type: "suggestion",
22
- hasSuggestions: !0,
24
+ hasSuggestions: true,
23
25
  docs: {
24
26
  category: "Operations",
25
27
  description: "Limit the complexity of the GraphQL operations solely by their depth. Based on [graphql-depth-limit](https://npmjs.com/package/graphql-depth-limit).",
26
28
  url: `https://the-guild.dev/graphql/eslint/rules/${RULE_ID}`,
27
- requiresSiblings: !0,
29
+ requiresSiblings: true,
28
30
  examples: [
29
31
  {
30
32
  title: "Incorrect",
@@ -66,7 +68,7 @@ const RULE_ID = "selection-set-depth", schema = {
66
68
  `
67
69
  }
68
70
  ],
69
- recommended: !0,
71
+ recommended: true,
70
72
  configOptions: [{ maxDepth: 7 }]
71
73
  },
72
74
  schema
@@ -80,18 +82,23 @@ const RULE_ID = "selection-set-depth", schema = {
80
82
  `Rule "${RULE_ID}" works best with siblings operations loaded. See https://the-guild.dev/graphql/eslint/docs/usage#providing-operations for more info`
81
83
  );
82
84
  }
83
- const { maxDepth, ignore = [] } = context.options[0], checkFn = depthLimit(maxDepth, { ignore });
85
+ const { maxDepth, ignore = [] } = context.options[0];
86
+ const checkFn = depthLimit(maxDepth, { ignore });
84
87
  return {
85
88
  "OperationDefinition, FragmentDefinition"(node) {
86
89
  try {
87
- const rawNode = node.rawNode(), fragmentsInUse = siblings ? siblings.getFragmentsInUse(rawNode) : [], document = {
90
+ const rawNode = node.rawNode();
91
+ const fragmentsInUse = siblings ? siblings.getFragmentsInUse(rawNode) : [];
92
+ const document = {
88
93
  kind: Kind.DOCUMENT,
89
94
  definitions: [rawNode, ...fragmentsInUse]
90
95
  };
91
96
  checkFn({
92
97
  getDocument: () => document,
93
98
  reportError(error) {
94
- const { line, column } = error.locations[0], token = context.sourceCode.getAncestors(node)[0].tokens.find(
99
+ const { line, column } = error.locations[0];
100
+ const ancestors = context.sourceCode.getAncestors(node);
101
+ const token = ancestors[0].tokens.find(
95
102
  (token2) => token2.loc.start.line === line && token2.loc.start.column === column - 1
96
103
  );
97
104
  context.report({
@@ -106,7 +113,9 @@ const RULE_ID = "selection-set-depth", schema = {
106
113
  {
107
114
  desc: "Remove selections",
108
115
  fix(fixer) {
109
- const foundNode = context.getSourceCode().getNodeByRangeIndex(token.range[0]), parentNode = foundNode.parent.parent;
116
+ const sourceCode = context.getSourceCode();
117
+ const foundNode = sourceCode.getNodeByRangeIndex(token.range[0]);
118
+ const parentNode = foundNode.parent.parent;
110
119
  return fixer.remove(
111
120
  foundNode.kind === "Name" ? parentNode.parent : parentNode
112
121
  );
@@ -5,12 +5,13 @@ import {
5
5
  englishJoinWords,
6
6
  requireGraphQLSchema
7
7
  } from "../../utils.js";
8
- const RULE_ID = "strict-id-in-types", schema = {
8
+ const RULE_ID = "strict-id-in-types";
9
+ const schema = {
9
10
  type: "array",
10
11
  maxItems: 1,
11
12
  items: {
12
13
  type: "object",
13
- additionalProperties: !1,
14
+ additionalProperties: false,
14
15
  properties: {
15
16
  acceptedIdNames: {
16
17
  ...ARRAY_DEFAULT_OPTIONS,
@@ -22,7 +23,7 @@ const RULE_ID = "strict-id-in-types", schema = {
22
23
  },
23
24
  exceptions: {
24
25
  type: "object",
25
- additionalProperties: !1,
26
+ additionalProperties: false,
26
27
  properties: {
27
28
  types: {
28
29
  ...ARRAY_DEFAULT_OPTIONS,
@@ -36,15 +37,16 @@ const RULE_ID = "strict-id-in-types", schema = {
36
37
  }
37
38
  }
38
39
  }
39
- }, rule = {
40
+ };
41
+ const rule = {
40
42
  meta: {
41
43
  type: "suggestion",
42
44
  docs: {
43
45
  description: "Requires output types to have one unique identifier unless they do not have a logical one. Exceptions can be used to ignore output types that do not have unique identifiers.",
44
46
  category: "Schema",
45
- recommended: !0,
47
+ recommended: true,
46
48
  url: `https://the-guild.dev/graphql/eslint/rules/${RULE_ID}`,
47
- requiresSchema: !0,
49
+ requiresSchema: true,
48
50
  examples: [
49
51
  {
50
52
  title: "Incorrect",
@@ -121,22 +123,33 @@ const RULE_ID = "strict-id-in-types", schema = {
121
123
  acceptedIdTypes: ["ID"],
122
124
  exceptions: {},
123
125
  ...context.options[0]
124
- }, schema2 = requireGraphQLSchema(RULE_ID, context);
126
+ };
127
+ const schema2 = requireGraphQLSchema(RULE_ID, context);
128
+ const rootTypeNames = [
129
+ schema2.getQueryType(),
130
+ schema2.getMutationType(),
131
+ schema2.getSubscriptionType()
132
+ ].filter((v) => !!v).map((type) => type.name);
133
+ const selector = `ObjectTypeDefinition[name.value!=/^(${rootTypeNames.join("|")})$/]`;
125
134
  return {
126
- [`ObjectTypeDefinition[name.value!=/^(${[
127
- schema2.getQueryType(),
128
- schema2.getMutationType(),
129
- schema2.getSubscriptionType()
130
- ].filter((v) => !!v).map((type) => type.name).join("|")})$/]`](node) {
135
+ [selector](node) {
131
136
  const typeName = node.name.value;
132
- if (options.exceptions.types?.includes(typeName) || options.exceptions.suffixes?.some((suffix) => typeName.endsWith(suffix)))
137
+ const shouldIgnoreNode = options.exceptions.types?.includes(typeName) || options.exceptions.suffixes?.some((suffix) => typeName.endsWith(suffix));
138
+ if (shouldIgnoreNode) {
133
139
  return;
134
- if (node.fields?.filter((field) => {
135
- const fieldNode = field.rawNode(), isValidIdName = options.acceptedIdNames.includes(fieldNode.name.value);
136
- let isValidIdType = !1;
137
- return fieldNode.type.kind === Kind.NON_NULL_TYPE && fieldNode.type.type.kind === Kind.NAMED_TYPE && (isValidIdType = options.acceptedIdTypes.includes(fieldNode.type.type.name.value)), isValidIdName && isValidIdType;
138
- })?.length !== 1) {
139
- const pluralNamesSuffix = options.acceptedIdNames.length > 1 ? "s" : "", pluralTypesSuffix = options.acceptedIdTypes.length > 1 ? "s" : "";
140
+ }
141
+ const validIds = node.fields?.filter((field) => {
142
+ const fieldNode = field.rawNode();
143
+ const isValidIdName = options.acceptedIdNames.includes(fieldNode.name.value);
144
+ let isValidIdType = false;
145
+ if (fieldNode.type.kind === Kind.NON_NULL_TYPE && fieldNode.type.type.kind === Kind.NAMED_TYPE) {
146
+ isValidIdType = options.acceptedIdTypes.includes(fieldNode.type.type.name.value);
147
+ }
148
+ return isValidIdName && isValidIdType;
149
+ });
150
+ if (validIds?.length !== 1) {
151
+ const pluralNamesSuffix = options.acceptedIdNames.length > 1 ? "s" : "";
152
+ const pluralTypesSuffix = options.acceptedIdTypes.length > 1 ? "s" : "";
140
153
  context.report({
141
154
  node: node.name,
142
155
  message: `${displayNodeName(node)} must have exactly one non-nullable unique identifier.
@@ -3,11 +3,11 @@ import { getNodeName } from "../../utils.js";
3
3
  const rule = {
4
4
  meta: {
5
5
  type: "suggestion",
6
- hasSuggestions: !0,
6
+ hasSuggestions: true,
7
7
  docs: {
8
8
  url: "https://the-guild.dev/graphql/eslint/rules/unique-enum-value-names",
9
9
  category: "Schema",
10
- recommended: !0,
10
+ recommended: true,
11
11
  description: `A GraphQL enum type is only valid if all its values are uniquely named.
12
12
  > This rule disallows case-insensitive enum values duplicates too.`,
13
13
  examples: [
@@ -42,8 +42,9 @@ const rule = {
42
42
  schema: []
43
43
  },
44
44
  create(context) {
45
+ const selector = [Kind.ENUM_TYPE_DEFINITION, Kind.ENUM_TYPE_EXTENSION].join(",");
45
46
  return {
46
- [[Kind.ENUM_TYPE_DEFINITION, Kind.ENUM_TYPE_EXTENSION].join(",")](node) {
47
+ [selector](node) {
47
48
  const duplicates = node.values?.filter(
48
49
  (item, index, array) => array.findIndex((v) => v.name.value.toLowerCase() === item.name.value.toLowerCase()) !== index
49
50
  );
@@ -1,30 +1,38 @@
1
1
  import { relative } from "node:path";
2
2
  import { Kind } from "graphql";
3
3
  import { CWD, requireGraphQLOperations, slash, VIRTUAL_DOCUMENT_REGEX } from "../../utils.js";
4
- const RULE_ID = "unique-fragment-name", checkNode = (context, node, ruleId) => {
5
- const documentName = node.name.value, siblings = requireGraphQLOperations(ruleId, context), siblingDocuments = node.kind === Kind.FRAGMENT_DEFINITION ? siblings.getFragment(documentName) : siblings.getOperation(documentName), filepath = context.filename, conflictingDocuments = siblingDocuments.filter((f) => {
6
- const isSameName = f.document.name?.value === documentName, isSamePath = slash(f.filePath) === slash(filepath);
4
+ const RULE_ID = "unique-fragment-name";
5
+ const checkNode = (context, node, ruleId) => {
6
+ const documentName = node.name.value;
7
+ const siblings = requireGraphQLOperations(ruleId, context);
8
+ const siblingDocuments = node.kind === Kind.FRAGMENT_DEFINITION ? siblings.getFragment(documentName) : siblings.getOperation(documentName);
9
+ const filepath = context.filename;
10
+ const conflictingDocuments = siblingDocuments.filter((f) => {
11
+ const isSameName = f.document.name?.value === documentName;
12
+ const isSamePath = slash(f.filePath) === slash(filepath);
7
13
  return isSameName && !isSamePath;
8
14
  });
9
- conflictingDocuments.length > 0 && context.report({
10
- messageId: ruleId,
11
- data: {
12
- documentName,
13
- summary: conflictingDocuments.map((f) => ` ${relative(CWD, f.filePath.replace(VIRTUAL_DOCUMENT_REGEX, ""))}`).join(`
14
- `)
15
- },
16
- // @ts-expect-error name will exist
17
- node: node.name
18
- });
19
- }, rule = {
15
+ if (conflictingDocuments.length > 0) {
16
+ context.report({
17
+ messageId: ruleId,
18
+ data: {
19
+ documentName,
20
+ summary: conflictingDocuments.map((f) => ` ${relative(CWD, f.filePath.replace(VIRTUAL_DOCUMENT_REGEX, ""))}`).join("\n")
21
+ },
22
+ // @ts-expect-error name will exist
23
+ node: node.name
24
+ });
25
+ }
26
+ };
27
+ const rule = {
20
28
  meta: {
21
29
  type: "suggestion",
22
30
  docs: {
23
31
  category: "Operations",
24
32
  description: "Enforce unique fragment names across your project.",
25
33
  url: `https://the-guild.dev/graphql/eslint/rules/${RULE_ID}`,
26
- requiresSiblings: !0,
27
- recommended: !0,
34
+ requiresSiblings: true,
35
+ recommended: true,
28
36
  examples: [
29
37
  {
30
38
  title: "Incorrect",
@@ -67,8 +75,7 @@ const RULE_ID = "unique-fragment-name", checkNode = (context, node, ruleId) => {
67
75
  ]
68
76
  },
69
77
  messages: {
70
- [RULE_ID]: `Fragment named "{{ documentName }}" already defined in:
71
- {{ summary }}`
78
+ [RULE_ID]: 'Fragment named "{{ documentName }}" already defined in:\n{{ summary }}'
72
79
  },
73
80
  schema: []
74
81
  },
@@ -1,13 +1,14 @@
1
1
  import { checkNode } from "../unique-fragment-name/index.js";
2
- const RULE_ID = "unique-operation-name", rule = {
2
+ const RULE_ID = "unique-operation-name";
3
+ const rule = {
3
4
  meta: {
4
5
  type: "suggestion",
5
6
  docs: {
6
7
  category: "Operations",
7
8
  description: "Enforce unique operation names across your project.",
8
9
  url: `https://the-guild.dev/graphql/eslint/rules/${RULE_ID}`,
9
- requiresSiblings: !0,
10
- recommended: !0,
10
+ requiresSiblings: true,
11
+ recommended: true,
11
12
  examples: [
12
13
  {
13
14
  title: "Incorrect",
@@ -54,8 +55,7 @@ const RULE_ID = "unique-operation-name", rule = {
54
55
  ]
55
56
  },
56
57
  messages: {
57
- [RULE_ID]: `Operation named "{{ documentName }}" already defined in:
58
- {{ summary }}`
58
+ [RULE_ID]: 'Operation named "{{ documentName }}" already defined in:\n{{ summary }}'
59
59
  },
60
60
  schema: []
61
61
  },
package/esm/schema.js CHANGED
@@ -3,19 +3,24 @@ import debugFactory from "debug";
3
3
  import fg from "fast-glob";
4
4
  import { BREAK, GraphQLSchema, visit } from "graphql";
5
5
  import { ModuleCache } from "./cache.js";
6
- const schemaCache = new ModuleCache(), debug = debugFactory("graphql-eslint:schema"), require2 = createRequire(import.meta.url);
6
+ const schemaCache = new ModuleCache();
7
+ const debug = debugFactory("graphql-eslint:schema");
8
+ const require2 = createRequire(import.meta.url);
7
9
  function getSchema(project) {
8
10
  const schemaKey = project.schema;
9
- if (!schemaKey)
11
+ if (!schemaKey) {
10
12
  return null;
13
+ }
11
14
  const cache = schemaCache.get(schemaKey);
12
- if (cache)
15
+ if (cache) {
13
16
  return cache;
17
+ }
14
18
  debug("Loading schema from %o", project.schema);
15
19
  const opts = {
16
20
  pluckConfig: project.extensions.pluckConfig
17
- }, typeDefs = project.loadSchemaSync(project.schema, "DocumentNode", opts);
18
- let isFederation = !1;
21
+ };
22
+ const typeDefs = project.loadSchemaSync(project.schema, "DocumentNode", opts);
23
+ let isFederation = false;
19
24
  visit(typeDefs, {
20
25
  SchemaExtension(node) {
21
26
  const linkDirective = node.directives?.find((d) => d.name.value === "link");
@@ -30,14 +35,16 @@ function getSchema(project) {
30
35
  if (isFederation) {
31
36
  const { buildSubgraphSchema } = require2("@apollo/subgraph");
32
37
  schema = buildSubgraphSchema({ typeDefs });
33
- } else
38
+ } else {
34
39
  schema = project.loadSchemaSync(project.schema, "GraphQLSchema", opts);
40
+ }
35
41
  if (debug.enabled) {
36
42
  debug("Schema loaded: %o", schema instanceof GraphQLSchema);
37
- const schemaPaths = fg.sync(project.schema, { absolute: !0 });
43
+ const schemaPaths = fg.sync(project.schema, { absolute: true });
38
44
  debug("Schema pointers %O", schemaPaths);
39
45
  }
40
- return schemaCache.set(schemaKey, schema), schema;
46
+ schemaCache.set(schemaKey, schema);
47
+ return schema;
41
48
  }
42
49
  export {
43
50
  getSchema
package/esm/siblings.js CHANGED
@@ -6,12 +6,18 @@ import { logger } from "./utils.js";
6
6
  const siblingOperationsCache = /* @__PURE__ */ new Map();
7
7
  function getSiblings(documents) {
8
8
  if (documents.length === 0) {
9
- let printed = !1;
10
- const noopWarn = () => (printed || (logger.warn(
11
- "getSiblingOperations was called without any operations. Make sure to set graphql-config `documents` field to make this feature available! See https://the-guild.dev/graphql/config/docs/user/documents for more info"
12
- ), printed = !0), []);
9
+ let printed = false;
10
+ const noopWarn = () => {
11
+ if (!printed) {
12
+ logger.warn(
13
+ "getSiblingOperations was called without any operations. Make sure to set graphql-config `documents` field to make this feature available! See https://the-guild.dev/graphql/config/docs/user/documents for more info"
14
+ );
15
+ printed = true;
16
+ }
17
+ return [];
18
+ };
13
19
  return {
14
- available: !1,
20
+ available: false,
15
21
  getFragment: noopWarn,
16
22
  getFragments: noopWarn,
17
23
  getFragmentByType: noopWarn,
@@ -22,18 +28,23 @@ function getSiblings(documents) {
22
28
  };
23
29
  }
24
30
  const value = siblingOperationsCache.get(documents);
25
- if (value)
31
+ if (value) {
26
32
  return value;
33
+ }
27
34
  let fragmentsCache = null;
28
35
  const getFragments = () => {
29
36
  if (fragmentsCache === null) {
30
37
  const result = [];
31
- for (const source of documents)
32
- for (const definition of source.document?.definitions || [])
33
- definition.kind === Kind.FRAGMENT_DEFINITION && result.push({
34
- filePath: source.location,
35
- document: definition
36
- });
38
+ for (const source of documents) {
39
+ for (const definition of source.document?.definitions || []) {
40
+ if (definition.kind === Kind.FRAGMENT_DEFINITION) {
41
+ result.push({
42
+ filePath: source.location,
43
+ document: definition
44
+ });
45
+ }
46
+ }
47
+ }
37
48
  fragmentsCache = result;
38
49
  }
39
50
  return fragmentsCache;
@@ -42,37 +53,54 @@ function getSiblings(documents) {
42
53
  const getOperations = () => {
43
54
  if (cachedOperations === null) {
44
55
  const result = [];
45
- for (const source of documents)
46
- for (const definition of source.document?.definitions || [])
47
- definition.kind === Kind.OPERATION_DEFINITION && result.push({
48
- filePath: source.location,
49
- document: definition
50
- });
56
+ for (const source of documents) {
57
+ for (const definition of source.document?.definitions || []) {
58
+ if (definition.kind === Kind.OPERATION_DEFINITION) {
59
+ result.push({
60
+ filePath: source.location,
61
+ document: definition
62
+ });
63
+ }
64
+ }
65
+ }
51
66
  cachedOperations = result;
52
67
  }
53
68
  return cachedOperations;
54
- }, getFragment = (name) => getFragments().filter((f) => f.document.name.value === name), collectFragments = (selectable, recursive, collected = /* @__PURE__ */ new Map()) => (visit(selectable, {
55
- FragmentSpread(spread) {
56
- const fragmentName = spread.name.value, [fragment] = getFragment(fragmentName);
57
- if (!fragment) {
58
- logger.warn(
59
- `Unable to locate fragment named "${fragmentName}", please make sure it's loaded using "parserOptions.operations"`
60
- );
61
- return;
69
+ };
70
+ const getFragment = (name) => getFragments().filter((f) => f.document.name.value === name);
71
+ const collectFragments = (selectable, recursive, collected = /* @__PURE__ */ new Map()) => {
72
+ visit(selectable, {
73
+ FragmentSpread(spread) {
74
+ const fragmentName = spread.name.value;
75
+ const [fragment] = getFragment(fragmentName);
76
+ if (!fragment) {
77
+ logger.warn(
78
+ `Unable to locate fragment named "${fragmentName}", please make sure it's loaded using "parserOptions.operations"`
79
+ );
80
+ return;
81
+ }
82
+ if (!collected.has(fragmentName)) {
83
+ collected.set(fragmentName, fragment.document);
84
+ if (recursive) {
85
+ collectFragments(fragment.document, recursive, collected);
86
+ }
87
+ }
62
88
  }
63
- collected.has(fragmentName) || (collected.set(fragmentName, fragment.document), recursive && collectFragments(fragment.document, recursive, collected));
64
- }
65
- }), collected), siblingOperations = {
66
- available: !0,
89
+ });
90
+ return collected;
91
+ };
92
+ const siblingOperations = {
93
+ available: true,
67
94
  getFragment,
68
95
  getFragments,
69
96
  getFragmentByType: (typeName) => getFragments().filter((f) => f.document.typeCondition.name.value === typeName),
70
- getFragmentsInUse: (selectable, recursive = !0) => Array.from(collectFragments(selectable, recursive).values()),
97
+ getFragmentsInUse: (selectable, recursive = true) => Array.from(collectFragments(selectable, recursive).values()),
71
98
  getOperation: (name) => getOperations().filter((o) => o.document.name?.value === name),
72
99
  getOperations,
73
100
  getOperationByType: (type) => getOperations().filter((o) => o.document.operation === type)
74
101
  };
75
- return siblingOperationsCache.set(documents, siblingOperations), siblingOperations;
102
+ siblingOperationsCache.set(documents, siblingOperations);
103
+ return siblingOperations;
76
104
  }
77
105
  export {
78
106
  getSiblings
package/esm/utils.js CHANGED
@@ -2,24 +2,27 @@ import { Kind } from "graphql";
2
2
  import lowerCase from "lodash.lowercase";
3
3
  function requireGraphQLOperations(ruleId, context) {
4
4
  const { siblingOperations } = context.sourceCode.parserServices;
5
- if (!siblingOperations.available)
5
+ if (!siblingOperations.available) {
6
6
  throw new Error(
7
7
  `Rule \`${ruleId}\` requires graphql-config \`documents\` field to be set and loaded. See https://the-guild.dev/graphql/eslint/docs/usage#providing-operations for more info`
8
8
  );
9
+ }
9
10
  return siblingOperations;
10
11
  }
11
12
  function requireGraphQLSchema(ruleId, context) {
12
13
  const { schema } = context.sourceCode.parserServices;
13
- if (!schema)
14
+ if (!schema) {
14
15
  throw new Error(
15
16
  `Rule \`${ruleId}\` requires graphql-config \`schema\` field to be set and loaded. See https://the-guild.dev/graphql/eslint/docs/usage#providing-schema for more info`
16
17
  );
18
+ }
17
19
  return schema;
18
20
  }
19
21
  const chalk = {
20
22
  red: (str) => `\x1B[31m${str}\x1B[39m`,
21
23
  yellow: (str) => `\x1B[33m${str}\x1B[39m`
22
- }, logger = {
24
+ };
25
+ const logger = {
23
26
  error: (...args) => (
24
27
  // eslint-disable-next-line no-console
25
28
  console.error(chalk.red("error"), "[graphql-eslint]", ...args)
@@ -28,17 +31,25 @@ const chalk = {
28
31
  // eslint-disable-next-line no-console
29
32
  console.warn(chalk.yellow("warning"), "[graphql-eslint]", ...args)
30
33
  )
31
- }, slash = (path) => path.replaceAll("\\", "/"), VIRTUAL_DOCUMENT_REGEX = /[/\\]\d+_document.graphql$/, CWD = process.cwd(), getTypeName = (node) => "type" in node ? getTypeName(node.type) : "name" in node && node.name ? node.name.value : "", TYPES_KINDS = [
34
+ };
35
+ const slash = (path) => path.replaceAll("\\", "/");
36
+ const VIRTUAL_DOCUMENT_REGEX = /[/\\]\d+_document.graphql$/;
37
+ const CWD = process.cwd();
38
+ const getTypeName = (node) => "type" in node ? getTypeName(node.type) : "name" in node && node.name ? node.name.value : "";
39
+ const TYPES_KINDS = [
32
40
  Kind.OBJECT_TYPE_DEFINITION,
33
41
  Kind.INTERFACE_TYPE_DEFINITION,
34
42
  Kind.ENUM_TYPE_DEFINITION,
35
43
  Kind.SCALAR_TYPE_DEFINITION,
36
44
  Kind.INPUT_OBJECT_TYPE_DEFINITION,
37
45
  Kind.UNION_TYPE_DEFINITION
38
- ], pascalCase = (str) => lowerCase(str).split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(""), camelCase = (str) => {
46
+ ];
47
+ const pascalCase = (str) => lowerCase(str).split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
48
+ const camelCase = (str) => {
39
49
  const result = pascalCase(str);
40
50
  return result.charAt(0).toLowerCase() + result.slice(1);
41
- }, convertCase = (style, str) => {
51
+ };
52
+ const convertCase = (style, str) => {
42
53
  switch (style) {
43
54
  case "camelCase":
44
55
  return camelCase(str);
@@ -65,14 +76,17 @@ function getLocation(start, fieldName = "") {
65
76
  }
66
77
  };
67
78
  }
68
- const REPORT_ON_FIRST_CHARACTER = { column: 0, line: 1 }, ARRAY_DEFAULT_OPTIONS = {
79
+ const REPORT_ON_FIRST_CHARACTER = { column: 0, line: 1 };
80
+ const ARRAY_DEFAULT_OPTIONS = {
69
81
  type: "array",
70
- uniqueItems: !0,
82
+ uniqueItems: true,
71
83
  minItems: 1,
72
84
  items: {
73
85
  type: "string"
74
86
  }
75
- }, englishJoinWords = (words) => new Intl.ListFormat("en-US", { type: "disjunction" }).format(words), DisplayNodeNameMap = {
87
+ };
88
+ const englishJoinWords = (words) => new Intl.ListFormat("en-US", { type: "disjunction" }).format(words);
89
+ const DisplayNodeNameMap = {
76
90
  [Kind.ARGUMENT]: "argument",
77
91
  [Kind.BOOLEAN]: "boolean",
78
92
  [Kind.DIRECTIVE_DEFINITION]: "directive",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphql-eslint/eslint-plugin",
3
- "version": "4.3.0",
3
+ "version": "4.3.1-alpha-20241209185034-de2d7397da8c26620a8930dd12b6dff42e43f537",
4
4
  "type": "module",
5
5
  "description": "GraphQL plugin for ESLint",
6
6
  "repository": "https://github.com/dimaMachina/graphql-eslint",
@@ -20,6 +20,16 @@
20
20
  "types": "./esm/index.d.ts",
21
21
  "default": "./esm/index.js"
22
22
  }
23
+ },
24
+ "./*": {
25
+ "require": {
26
+ "types": "./cjs/*.d.cts",
27
+ "default": "./cjs/*.js"
28
+ },
29
+ "import": {
30
+ "types": "./esm/*.d.ts",
31
+ "default": "./esm/*.js"
32
+ }
23
33
  }
24
34
  },
25
35
  "types": "esm/index.d.ts",