@graphql-eslint/eslint-plugin 4.3.0 → 4.3.1-alpha-20241207204625-6a4230707a78900a6339b03afe904b9dd6c31561

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 (110) hide show
  1. package/cjs/cache.js +6 -2
  2. package/cjs/configs/operations-all.js +2 -2
  3. package/cjs/configs/schema-all.js +2 -2
  4. package/cjs/configs/schema-recommended.js +1 -1
  5. package/cjs/documents.js +13 -7
  6. package/cjs/estree-converter/converter.js +17 -8
  7. package/cjs/estree-converter/utils.js +22 -9
  8. package/cjs/graphql-config.js +13 -6
  9. package/cjs/index.d.cts +18 -4
  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/index.d.cts +18 -4
  17. package/cjs/rules/input-name/index.js +51 -38
  18. package/cjs/rules/lone-executable-definition/index.js +15 -6
  19. package/cjs/rules/match-document-filename/index.d.cts +4 -3
  20. package/cjs/rules/match-document-filename/index.js +63 -37
  21. package/cjs/rules/naming-convention/index.d.cts +6 -10
  22. package/cjs/rules/naming-convention/index.js +146 -57
  23. package/cjs/rules/no-anonymous-operations/index.js +8 -5
  24. package/cjs/rules/no-deprecated/index.js +27 -13
  25. package/cjs/rules/no-duplicate-fields/index.js +15 -8
  26. package/cjs/rules/no-hashtag-description/index.js +18 -10
  27. package/cjs/rules/no-one-place-fragments/index.js +17 -10
  28. package/cjs/rules/no-root-type/index.js +15 -8
  29. package/cjs/rules/no-scalar-result-type-on-mutation/index.js +20 -12
  30. package/cjs/rules/no-typename-prefix/index.js +25 -21
  31. package/cjs/rules/no-unreachable-types/index.js +34 -17
  32. package/cjs/rules/no-unused-fields/index.js +56 -30
  33. package/cjs/rules/relay-arguments/index.js +31 -13
  34. package/cjs/rules/relay-connection-types/index.js +31 -9
  35. package/cjs/rules/relay-edge-types/index.js +84 -41
  36. package/cjs/rules/relay-page-info/index.js +31 -14
  37. package/cjs/rules/require-deprecation-date/index.js +20 -9
  38. package/cjs/rules/require-deprecation-reason/index.js +8 -5
  39. package/cjs/rules/require-description/index.d.cts +79 -13
  40. package/cjs/rules/require-description/index.js +67 -49
  41. package/cjs/rules/require-field-of-type-query-in-mutation-result/index.js +21 -10
  42. package/cjs/rules/require-import-fragment/index.js +20 -11
  43. package/cjs/rules/require-nullable-fields-with-oneof/index.js +12 -5
  44. package/cjs/rules/require-nullable-result-in-root/index.js +32 -27
  45. package/cjs/rules/require-selections/index.js +88 -46
  46. package/cjs/rules/require-type-pattern-with-oneof/index.js +14 -10
  47. package/cjs/rules/selection-set-depth/index.js +19 -10
  48. package/cjs/rules/strict-id-in-types/index.js +32 -19
  49. package/cjs/rules/unique-enum-value-names/index.js +4 -3
  50. package/cjs/rules/unique-fragment-name/index.js +25 -18
  51. package/cjs/rules/unique-operation-name/index.js +5 -5
  52. package/cjs/schema.js +14 -8
  53. package/cjs/siblings.js +60 -32
  54. package/cjs/utils.js +23 -9
  55. package/esm/cache.js +6 -2
  56. package/esm/configs/operations-all.js +2 -2
  57. package/esm/configs/schema-all.js +2 -2
  58. package/esm/configs/schema-recommended.js +1 -1
  59. package/esm/documents.js +13 -7
  60. package/esm/estree-converter/converter.js +17 -8
  61. package/esm/estree-converter/utils.js +22 -9
  62. package/esm/graphql-config.js +13 -6
  63. package/esm/index.d.ts +19 -5
  64. package/esm/meta.js +1 -1
  65. package/esm/parser.js +36 -9
  66. package/esm/processor.js +48 -20
  67. package/esm/rules/alphabetize/index.js +99 -47
  68. package/esm/rules/description-style/index.js +10 -6
  69. package/esm/rules/graphql-js-validation.js +142 -108
  70. package/esm/rules/index.d.ts +19 -5
  71. package/esm/rules/input-name/index.js +51 -38
  72. package/esm/rules/lone-executable-definition/index.js +15 -6
  73. package/esm/rules/match-document-filename/index.d.ts +4 -3
  74. package/esm/rules/match-document-filename/index.js +63 -37
  75. package/esm/rules/naming-convention/index.d.ts +6 -10
  76. package/esm/rules/naming-convention/index.js +146 -57
  77. package/esm/rules/no-anonymous-operations/index.js +8 -5
  78. package/esm/rules/no-deprecated/index.js +27 -13
  79. package/esm/rules/no-duplicate-fields/index.js +15 -8
  80. package/esm/rules/no-hashtag-description/index.js +18 -10
  81. package/esm/rules/no-one-place-fragments/index.js +17 -10
  82. package/esm/rules/no-root-type/index.js +15 -8
  83. package/esm/rules/no-scalar-result-type-on-mutation/index.js +20 -12
  84. package/esm/rules/no-typename-prefix/index.js +25 -21
  85. package/esm/rules/no-unreachable-types/index.js +34 -17
  86. package/esm/rules/no-unused-fields/index.js +56 -30
  87. package/esm/rules/relay-arguments/index.js +31 -13
  88. package/esm/rules/relay-connection-types/index.js +31 -9
  89. package/esm/rules/relay-edge-types/index.js +84 -41
  90. package/esm/rules/relay-page-info/index.js +31 -14
  91. package/esm/rules/require-deprecation-date/index.js +20 -9
  92. package/esm/rules/require-deprecation-reason/index.js +8 -5
  93. package/esm/rules/require-description/index.d.ts +79 -13
  94. package/esm/rules/require-description/index.js +67 -49
  95. package/esm/rules/require-field-of-type-query-in-mutation-result/index.js +21 -10
  96. package/esm/rules/require-import-fragment/index.js +20 -11
  97. package/esm/rules/require-nullable-fields-with-oneof/index.js +12 -5
  98. package/esm/rules/require-nullable-result-in-root/index.js +32 -27
  99. package/esm/rules/require-selections/index.js +88 -46
  100. package/esm/rules/require-type-pattern-with-oneof/index.js +14 -10
  101. package/esm/rules/selection-set-depth/index.js +19 -10
  102. package/esm/rules/strict-id-in-types/index.js +32 -19
  103. package/esm/rules/unique-enum-value-names/index.js +4 -3
  104. package/esm/rules/unique-fragment-name/index.js +25 -18
  105. package/esm/rules/unique-operation-name/index.js +5 -5
  106. package/esm/schema.js +15 -8
  107. package/esm/siblings.js +60 -32
  108. package/esm/utils.js +23 -9
  109. package/index.browser.js +1838 -1135
  110. package/package.json +1 -1
@@ -6,50 +6,66 @@
6
6
  var _graphql = require('graphql');
7
7
  var _utils = require('@graphql-tools/utils');
8
8
  var _utilsjs = require('../../utils.js');
9
- const RULE_ID = "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";
9
+ const RULE_ID = "relay-edge-types";
10
+ const MESSAGE_MUST_BE_OBJECT_TYPE = "MESSAGE_MUST_BE_OBJECT_TYPE";
11
+ const MESSAGE_MISSING_EDGE_SUFFIX = "MESSAGE_MISSING_EDGE_SUFFIX";
12
+ const MESSAGE_LIST_TYPE_ONLY_EDGE_TYPE = "MESSAGE_LIST_TYPE_ONLY_EDGE_TYPE";
13
+ const MESSAGE_SHOULD_IMPLEMENTS_NODE = "MESSAGE_SHOULD_IMPLEMENTS_NODE";
10
14
  let edgeTypesCache;
11
15
  function getEdgeTypes(schema2) {
12
- if (process.env.NODE_ENV !== "test" && edgeTypesCache)
16
+ if (process.env.NODE_ENV !== "test" && edgeTypesCache) {
13
17
  return edgeTypesCache;
14
- const edgeTypes = /* @__PURE__ */ new Set(), visitor = {
18
+ }
19
+ const edgeTypes = /* @__PURE__ */ new Set();
20
+ const visitor = {
15
21
  ObjectTypeDefinition(node) {
16
- if (!node.name.value.endsWith("Connection"))
22
+ const typeName = node.name.value;
23
+ const hasConnectionSuffix = typeName.endsWith("Connection");
24
+ if (!hasConnectionSuffix) {
17
25
  return;
26
+ }
18
27
  const edges = _optionalChain([node, 'access', _ => _.fields, 'optionalAccess', _2 => _2.find, 'call', _3 => _3((field) => field.name.value === "edges")]);
19
28
  if (edges) {
20
- const edgesTypeName = _utilsjs.getTypeName.call(void 0, edges), edgesType = schema2.getType(edgesTypeName);
21
- _graphql.isObjectType.call(void 0, edgesType) && edgeTypes.add(edgesTypeName);
29
+ const edgesTypeName = _utilsjs.getTypeName.call(void 0, edges);
30
+ const edgesType = schema2.getType(edgesTypeName);
31
+ if (_graphql.isObjectType.call(void 0, edgesType)) {
32
+ edgeTypes.add(edgesTypeName);
33
+ }
22
34
  }
23
35
  }
24
- }, astNode = _utils.getDocumentNodeFromSchema.call(void 0, schema2);
25
- return _graphql.visit.call(void 0, astNode, visitor), edgeTypesCache = edgeTypes, edgeTypesCache;
36
+ };
37
+ const astNode = _utils.getDocumentNodeFromSchema.call(void 0, schema2);
38
+ _graphql.visit.call(void 0, astNode, visitor);
39
+ edgeTypesCache = edgeTypes;
40
+ return edgeTypesCache;
26
41
  }
27
42
  const schema = {
28
43
  type: "array",
29
44
  maxItems: 1,
30
45
  items: {
31
46
  type: "object",
32
- additionalProperties: !1,
47
+ additionalProperties: false,
33
48
  minProperties: 1,
34
49
  properties: {
35
50
  withEdgeSuffix: {
36
51
  type: "boolean",
37
- default: !0,
52
+ default: true,
38
53
  description: 'Edge type name must end in "Edge".'
39
54
  },
40
55
  shouldImplementNode: {
41
56
  type: "boolean",
42
- default: !0,
57
+ default: true,
43
58
  description: "Edge type's field `node` must implement `Node` interface."
44
59
  },
45
60
  listTypeCanWrapOnlyEdgeType: {
46
61
  type: "boolean",
47
- default: !0,
62
+ default: true,
48
63
  description: "A list type should only wrap an edge type."
49
64
  }
50
65
  }
51
66
  }
52
- }, rule = exports.rule = {
67
+ };
68
+ const rule = {
53
69
  meta: {
54
70
  type: "problem",
55
71
  docs: {
@@ -64,11 +80,10 @@ const schema = {
64
80
  '- Edge type name must end in "Edge" _(optional)_',
65
81
  "- Edge type's field `node` must implement `Node` interface _(optional)_",
66
82
  "- A list type should only wrap an edge type _(optional)_"
67
- ].join(`
68
- `),
83
+ ].join("\n"),
69
84
  url: `https://the-guild.dev/graphql/eslint/rules/${RULE_ID}`,
70
- isDisabledForAllConfig: !0,
71
- requiresSchema: !0,
85
+ isDisabledForAllConfig: true,
86
+ requiresSchema: true,
72
87
  examples: [
73
88
  {
74
89
  title: "Correct",
@@ -93,28 +108,40 @@ const schema = {
93
108
  schema
94
109
  },
95
110
  create(context) {
96
- const schema2 = _utilsjs.requireGraphQLSchema.call(void 0, RULE_ID, context), edgeTypes = getEdgeTypes(schema2), options = {
97
- withEdgeSuffix: !0,
98
- shouldImplementNode: !0,
99
- listTypeCanWrapOnlyEdgeType: !0,
111
+ const schema2 = _utilsjs.requireGraphQLSchema.call(void 0, RULE_ID, context);
112
+ const edgeTypes = getEdgeTypes(schema2);
113
+ const options = {
114
+ withEdgeSuffix: true,
115
+ shouldImplementNode: true,
116
+ listTypeCanWrapOnlyEdgeType: true,
100
117
  ...context.options[0]
101
- }, isNamedOrNonNullNamed = (node) => node.kind === _graphql.Kind.NAMED_TYPE || node.kind === _graphql.Kind.NON_NULL_TYPE && node.gqlType.kind === _graphql.Kind.NAMED_TYPE, checkNodeField = (node) => {
102
- const nodeField = _optionalChain([node, 'access', _4 => _4.fields, 'optionalAccess', _5 => _5.find, 'call', _6 => _6((field) => field.name.value === "node")]), message = "return either a Scalar, Enum, Object, Interface, Union, or a non-null wrapper around one of those types.";
103
- if (!nodeField)
118
+ };
119
+ const isNamedOrNonNullNamed = (node) => node.kind === _graphql.Kind.NAMED_TYPE || node.kind === _graphql.Kind.NON_NULL_TYPE && node.gqlType.kind === _graphql.Kind.NAMED_TYPE;
120
+ const checkNodeField = (node) => {
121
+ const nodeField = _optionalChain([node, 'access', _4 => _4.fields, 'optionalAccess', _5 => _5.find, 'call', _6 => _6((field) => field.name.value === "node")]);
122
+ const message = "return either a Scalar, Enum, Object, Interface, Union, or a non-null wrapper around one of those types.";
123
+ if (!nodeField) {
104
124
  context.report({
105
125
  node: node.name,
106
126
  message: `Edge type must contain a field \`node\` that ${message}`
107
127
  });
108
- else if (!isNamedOrNonNullNamed(nodeField.gqlType))
128
+ } else if (!isNamedOrNonNullNamed(nodeField.gqlType)) {
109
129
  context.report({ node: nodeField.name, message: `Field \`node\` must ${message}` });
110
- else if (options.shouldImplementNode) {
111
- const nodeReturnTypeName = _utilsjs.getTypeName.call(void 0, nodeField.gqlType.rawNode()), type = schema2.getType(nodeReturnTypeName);
112
- if (!_graphql.isObjectType.call(void 0, type))
130
+ } else if (options.shouldImplementNode) {
131
+ const nodeReturnTypeName = _utilsjs.getTypeName.call(void 0, nodeField.gqlType.rawNode());
132
+ const type = schema2.getType(nodeReturnTypeName);
133
+ if (!_graphql.isObjectType.call(void 0, type)) {
113
134
  return;
114
- _optionalChain([type, 'access', _7 => _7.astNode, 'access', _8 => _8.interfaces, 'optionalAccess', _9 => _9.some, 'call', _10 => _10((n) => n.name.value === "Node")]) || context.report({ node: node.name, messageId: MESSAGE_SHOULD_IMPLEMENTS_NODE });
135
+ }
136
+ const implementsNode = _optionalChain([type, 'access', _7 => _7.astNode, 'access', _8 => _8.interfaces, 'optionalAccess', _9 => _9.some, 'call', _10 => _10((n) => n.name.value === "Node")]);
137
+ if (!implementsNode) {
138
+ context.report({ node: node.name, messageId: MESSAGE_SHOULD_IMPLEMENTS_NODE });
139
+ }
115
140
  }
116
- }, checkCursorField = (node) => {
117
- const cursorField = _optionalChain([node, 'access', _11 => _11.fields, 'optionalAccess', _12 => _12.find, 'call', _13 => _13((field) => field.name.value === "cursor")]), message = "return either a String, Scalar, or a non-null wrapper wrapper around one of those types.";
141
+ };
142
+ const checkCursorField = (node) => {
143
+ const cursorField = _optionalChain([node, 'access', _11 => _11.fields, 'optionalAccess', _12 => _12.find, 'call', _13 => _13((field) => field.name.value === "cursor")]);
144
+ const message = "return either a String, Scalar, or a non-null wrapper wrapper around one of those types.";
118
145
  if (!cursorField) {
119
146
  context.report({
120
147
  node: node.name,
@@ -123,23 +150,39 @@ const schema = {
123
150
  return;
124
151
  }
125
152
  const typeName = _utilsjs.getTypeName.call(void 0, cursorField.rawNode());
126
- (!isNamedOrNonNullNamed(cursorField.gqlType) || typeName !== "String" && !_graphql.isScalarType.call(void 0, schema2.getType(typeName))) && context.report({ node: cursorField.name, message: `Field \`cursor\` must ${message}` });
127
- }, listeners = {
153
+ if (!isNamedOrNonNullNamed(cursorField.gqlType) || typeName !== "String" && !_graphql.isScalarType.call(void 0, schema2.getType(typeName))) {
154
+ context.report({ node: cursorField.name, message: `Field \`cursor\` must ${message}` });
155
+ }
156
+ };
157
+ const listeners = {
128
158
  ":matches(ObjectTypeDefinition, ObjectTypeExtension)[name.value=/Connection$/] > FieldDefinition[name.value=edges] > .gqlType Name"(node) {
129
159
  const type = schema2.getType(node.value);
130
- _graphql.isObjectType.call(void 0, type) || context.report({ node, messageId: MESSAGE_MUST_BE_OBJECT_TYPE });
160
+ if (!_graphql.isObjectType.call(void 0, type)) {
161
+ context.report({ node, messageId: MESSAGE_MUST_BE_OBJECT_TYPE });
162
+ }
131
163
  },
132
164
  ":matches(ObjectTypeDefinition, ObjectTypeExtension)"(node) {
133
165
  const typeName = node.name.value;
134
- edgeTypes.has(typeName) && (checkNodeField(node), checkCursorField(node), options.withEdgeSuffix && !typeName.endsWith("Edge") && context.report({ node: node.name, messageId: MESSAGE_MISSING_EDGE_SUFFIX }));
166
+ if (edgeTypes.has(typeName)) {
167
+ checkNodeField(node);
168
+ checkCursorField(node);
169
+ if (options.withEdgeSuffix && !typeName.endsWith("Edge")) {
170
+ context.report({ node: node.name, messageId: MESSAGE_MISSING_EDGE_SUFFIX });
171
+ }
172
+ }
135
173
  }
136
174
  };
137
- return options.listTypeCanWrapOnlyEdgeType && (listeners["FieldDefinition > .gqlType"] = (node) => {
138
- if (node.kind === _graphql.Kind.LIST_TYPE || node.kind === _graphql.Kind.NON_NULL_TYPE && node.gqlType.kind === _graphql.Kind.LIST_TYPE) {
139
- const typeName = _utilsjs.getTypeName.call(void 0, node.rawNode());
140
- edgeTypes.has(typeName) || context.report({ node, messageId: MESSAGE_LIST_TYPE_ONLY_EDGE_TYPE });
141
- }
142
- }), listeners;
175
+ if (options.listTypeCanWrapOnlyEdgeType) {
176
+ listeners["FieldDefinition > .gqlType"] = (node) => {
177
+ if (node.kind === _graphql.Kind.LIST_TYPE || node.kind === _graphql.Kind.NON_NULL_TYPE && node.gqlType.kind === _graphql.Kind.LIST_TYPE) {
178
+ const typeName = _utilsjs.getTypeName.call(void 0, node.rawNode());
179
+ if (!edgeTypes.has(typeName)) {
180
+ context.report({ node, messageId: MESSAGE_LIST_TYPE_ONLY_EDGE_TYPE });
181
+ }
182
+ }
183
+ };
184
+ }
185
+ return listeners;
143
186
  }
144
187
  };
145
188
 
@@ -1,8 +1,11 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _graphql = require('graphql');
2
2
  var _utilsjs = require('../../utils.js');
3
3
  var _indexjs = require('../relay-connection-types/index.js');
4
- const RULE_ID = "relay-page-info", MESSAGE_MUST_EXIST = "MESSAGE_MUST_EXIST", MESSAGE_MUST_BE_OBJECT_TYPE = "MESSAGE_MUST_BE_OBJECT_TYPE", notPageInfoTypesSelector = `:matches(${_indexjs.NON_OBJECT_TYPES})[name.value=PageInfo] > .name`;
5
- let hasPageInfoChecked = !1;
4
+ const RULE_ID = "relay-page-info";
5
+ const MESSAGE_MUST_EXIST = "MESSAGE_MUST_EXIST";
6
+ const MESSAGE_MUST_BE_OBJECT_TYPE = "MESSAGE_MUST_BE_OBJECT_TYPE";
7
+ const notPageInfoTypesSelector = `:matches(${_indexjs.NON_OBJECT_TYPES})[name.value=PageInfo] > .name`;
8
+ let hasPageInfoChecked = false;
6
9
  const rule = {
7
10
  meta: {
8
11
  type: "problem",
@@ -14,8 +17,7 @@ const rule = {
14
17
  "- `PageInfo` must be an Object type",
15
18
  "- `PageInfo` must contain fields `hasPreviousPage` and `hasNextPage`, that return non-null Boolean",
16
19
  "- `PageInfo` must contain fields `startCursor` and `endCursor`, that return either String or Scalar, which can be null if there are no results"
17
- ].join(`
18
- `),
20
+ ].join("\n"),
19
21
  url: `https://the-guild.dev/graphql/eslint/rules/${RULE_ID}`,
20
22
  examples: [
21
23
  {
@@ -33,8 +35,8 @@ const rule = {
33
35
  )
34
36
  }
35
37
  ],
36
- isDisabledForAllConfig: !0,
37
- requiresSchema: !0
38
+ isDisabledForAllConfig: true,
39
+ requiresSchema: true
38
40
  },
39
41
  messages: {
40
42
  [MESSAGE_MUST_EXIST]: "The server must provide a `PageInfo` object.",
@@ -44,22 +46,34 @@ const rule = {
44
46
  },
45
47
  create(context) {
46
48
  const schema = _utilsjs.requireGraphQLSchema.call(void 0, RULE_ID, context);
47
- return (process.env.NODE_ENV === "test" || !hasPageInfoChecked) && (schema.getType("PageInfo") || context.report({
48
- loc: _utilsjs.REPORT_ON_FIRST_CHARACTER,
49
- messageId: MESSAGE_MUST_EXIST
50
- }), hasPageInfoChecked = !0), {
49
+ if (process.env.NODE_ENV === "test" || !hasPageInfoChecked) {
50
+ const pageInfoType = schema.getType("PageInfo");
51
+ if (!pageInfoType) {
52
+ context.report({
53
+ loc: _utilsjs.REPORT_ON_FIRST_CHARACTER,
54
+ messageId: MESSAGE_MUST_EXIST
55
+ });
56
+ }
57
+ hasPageInfoChecked = true;
58
+ }
59
+ return {
51
60
  [notPageInfoTypesSelector](node) {
52
61
  context.report({ node, messageId: MESSAGE_MUST_BE_OBJECT_TYPE });
53
62
  },
54
63
  "ObjectTypeDefinition[name.value=PageInfo]"(node) {
55
64
  const fieldMap = Object.fromEntries(
56
65
  _optionalChain([node, 'access', _ => _.fields, 'optionalAccess', _2 => _2.map, 'call', _3 => _3((field) => [field.name.value, field])]) || []
57
- ), checkField = (fieldName, typeName) => {
66
+ );
67
+ const checkField = (fieldName, typeName) => {
58
68
  const field = fieldMap[fieldName];
59
- let isAllowedType = !1;
69
+ let isAllowedType = false;
60
70
  if (field) {
61
71
  const type = field.gqlType;
62
- typeName === "Boolean" ? isAllowedType = type.kind === _graphql.Kind.NON_NULL_TYPE && type.gqlType.kind === _graphql.Kind.NAMED_TYPE && type.gqlType.name.value === "Boolean" : type.kind === _graphql.Kind.NAMED_TYPE && (isAllowedType = type.name.value === "String" || _graphql.isScalarType.call(void 0, schema.getType(type.name.value)));
72
+ if (typeName === "Boolean") {
73
+ isAllowedType = type.kind === _graphql.Kind.NON_NULL_TYPE && type.gqlType.kind === _graphql.Kind.NAMED_TYPE && type.gqlType.name.value === "Boolean";
74
+ } else if (type.kind === _graphql.Kind.NAMED_TYPE) {
75
+ isAllowedType = type.name.value === "String" || _graphql.isScalarType.call(void 0, schema.getType(type.name.value));
76
+ }
63
77
  }
64
78
  if (!isAllowedType) {
65
79
  const returnType = typeName === "Boolean" ? "non-null Boolean" : "either String or Scalar, which can be null if there are no results";
@@ -69,7 +83,10 @@ const rule = {
69
83
  });
70
84
  }
71
85
  };
72
- checkField("hasPreviousPage", "Boolean"), checkField("hasNextPage", "Boolean"), checkField("startCursor", "String"), checkField("endCursor", "String");
86
+ checkField("hasPreviousPage", "Boolean");
87
+ checkField("hasNextPage", "Boolean");
88
+ checkField("startCursor", "String");
89
+ checkField("endCursor", "String");
73
90
  }
74
91
  };
75
92
  }
@@ -1,21 +1,27 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _indexjs = require('../../estree-converter/index.js');
2
2
  var _utilsjs = require('../../utils.js');
3
- const 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", schema = {
3
+ const DATE_REGEX = /^\d{2}\/\d{2}\/\d{4}$/;
4
+ const MESSAGE_REQUIRE_DATE = "MESSAGE_REQUIRE_DATE";
5
+ const MESSAGE_INVALID_FORMAT = "MESSAGE_INVALID_FORMAT";
6
+ const MESSAGE_INVALID_DATE = "MESSAGE_INVALID_DATE";
7
+ const MESSAGE_CAN_BE_REMOVED = "MESSAGE_CAN_BE_REMOVED";
8
+ const schema = {
4
9
  type: "array",
5
10
  maxItems: 1,
6
11
  items: {
7
12
  type: "object",
8
- additionalProperties: !1,
13
+ additionalProperties: false,
9
14
  properties: {
10
15
  argumentName: {
11
16
  type: "string"
12
17
  }
13
18
  }
14
19
  }
15
- }, rule = exports.rule = {
20
+ };
21
+ const rule = {
16
22
  meta: {
17
23
  type: "suggestion",
18
- hasSuggestions: !0,
24
+ hasSuggestions: true,
19
25
  docs: {
20
26
  category: "Schema",
21
27
  description: "Require deletion date on `@deprecated` directive. Suggest removing deprecated things after deprecated date.",
@@ -71,7 +77,8 @@ const DATE_REGEX = /^\d{2}\/\d{2}\/\d{4}$/, MESSAGE_REQUIRE_DATE = "MESSAGE_REQU
71
77
  create(context) {
72
78
  return {
73
79
  "Directive[name.value=deprecated]"(node) {
74
- const argName = _optionalChain([context, 'access', _ => _.options, 'access', _2 => _2[0], 'optionalAccess', _3 => _3.argumentName]) || "deletionDate", deletionDateNode = _optionalChain([node, 'access', _4 => _4.arguments, 'optionalAccess', _5 => _5.find, 'call', _6 => _6((arg) => arg.name.value === argName)]);
80
+ const argName = _optionalChain([context, 'access', _ => _.options, 'access', _2 => _2[0], 'optionalAccess', _3 => _3.argumentName]) || "deletionDate";
81
+ const deletionDateNode = _optionalChain([node, 'access', _4 => _4.arguments, 'optionalAccess', _5 => _5.find, 'call', _6 => _6((arg) => arg.name.value === argName)]);
75
82
  if (!deletionDateNode) {
76
83
  context.report({
77
84
  node: node.name,
@@ -83,7 +90,8 @@ const DATE_REGEX = /^\d{2}\/\d{2}\/\d{4}$/, MESSAGE_REQUIRE_DATE = "MESSAGE_REQU
83
90
  return;
84
91
  }
85
92
  const deletionDate = _indexjs.valueFromNode.call(void 0, deletionDateNode.value);
86
- if (!DATE_REGEX.test(deletionDate)) {
93
+ const isValidDate = DATE_REGEX.test(deletionDate);
94
+ if (!isValidDate) {
87
95
  context.report({
88
96
  node: deletionDateNode.value,
89
97
  messageId: MESSAGE_INVALID_FORMAT,
@@ -92,7 +100,8 @@ const DATE_REGEX = /^\d{2}\/\d{2}\/\d{4}$/, MESSAGE_REQUIRE_DATE = "MESSAGE_REQU
92
100
  return;
93
101
  }
94
102
  let [day, month, year] = deletionDate.split("/");
95
- day = day.padStart(2, "0"), month = month.padStart(2, "0");
103
+ day = day.padStart(2, "0");
104
+ month = month.padStart(2, "0");
96
105
  const deletionDateInMS = Date.parse(`${year}-${month}-${day}`);
97
106
  if (Number.isNaN(deletionDateInMS)) {
98
107
  context.report({
@@ -105,8 +114,10 @@ const DATE_REGEX = /^\d{2}\/\d{2}\/\d{4}$/, MESSAGE_REQUIRE_DATE = "MESSAGE_REQU
105
114
  });
106
115
  return;
107
116
  }
108
- if (Date.now() > deletionDateInMS) {
109
- const { parent } = node, nodeName = parent.name.value;
117
+ const canRemove = Date.now() > deletionDateInMS;
118
+ if (canRemove) {
119
+ const { parent } = node;
120
+ const nodeName = parent.name.value;
110
121
  context.report({
111
122
  node: parent.name,
112
123
  messageId: MESSAGE_CAN_BE_REMOVED,
@@ -6,7 +6,7 @@ const rule = {
6
6
  description: "Require all deprecation directives to specify a reason.",
7
7
  category: "Schema",
8
8
  url: "https://the-guild.dev/graphql/eslint/rules/require-deprecation-reason",
9
- recommended: !0,
9
+ recommended: true,
10
10
  examples: [
11
11
  {
12
12
  title: "Incorrect",
@@ -52,10 +52,13 @@ const rule = {
52
52
  const reasonArgument = _optionalChain([node, 'access', _ => _.arguments, 'optionalAccess', _2 => _2.find, 'call', _3 => _3(
53
53
  (arg) => arg.name.value === "reason"
54
54
  )]);
55
- reasonArgument && String(_indexjs.valueFromNode.call(void 0, reasonArgument.value)).trim() || context.report({
56
- node: node.name,
57
- message: `Deprecation reason is required for ${_utilsjs.getNodeName.call(void 0, node.parent)}.`
58
- });
55
+ const value = reasonArgument && String(_indexjs.valueFromNode.call(void 0, reasonArgument.value)).trim();
56
+ if (!value) {
57
+ context.report({
58
+ node: node.name,
59
+ message: `Deprecation reason is required for ${_utilsjs.getNodeName.call(void 0, node.parent)}.`
60
+ });
61
+ }
59
62
  }
60
63
  };
61
64
  }
@@ -1,25 +1,91 @@
1
- import { Kind } from 'graphql';
1
+ import { FromSchema } from 'json-schema-to-ts';
2
2
  import { GraphQLESLintRule } from '../../types.cjs';
3
3
  import 'eslint';
4
4
  import 'estree';
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
11
  declare const RULE_ID = "require-description";
12
- declare const ALLOWED_KINDS: readonly [Kind.OBJECT_TYPE_DEFINITION, Kind.INTERFACE_TYPE_DEFINITION, Kind.ENUM_TYPE_DEFINITION, Kind.SCALAR_TYPE_DEFINITION, Kind.INPUT_OBJECT_TYPE_DEFINITION, Kind.UNION_TYPE_DEFINITION, Kind.DIRECTIVE_DEFINITION, Kind.FIELD_DEFINITION, Kind.INPUT_VALUE_DEFINITION, Kind.ENUM_VALUE_DEFINITION, Kind.OPERATION_DEFINITION];
13
- type AllowedKind = (typeof ALLOWED_KINDS)[number];
14
- type RuleOptions = [
15
- {
16
- [key in AllowedKind]?: boolean;
17
- } & {
18
- types?: true;
19
- rootField?: true;
20
- ignoredSelectors?: string[];
21
- }
22
- ];
12
+ declare const schema: {
13
+ readonly type: "array";
14
+ readonly minItems: 1;
15
+ readonly maxItems: 1;
16
+ readonly items: {
17
+ readonly type: "object";
18
+ readonly additionalProperties: false;
19
+ readonly minProperties: 1;
20
+ readonly properties: {
21
+ readonly OperationDefinition: {
22
+ type: "boolean";
23
+ description: string;
24
+ };
25
+ readonly ScalarTypeDefinition: {
26
+ type: "boolean";
27
+ description: string;
28
+ };
29
+ readonly ObjectTypeDefinition: {
30
+ type: "boolean";
31
+ description: string;
32
+ };
33
+ readonly FieldDefinition: {
34
+ type: "boolean";
35
+ description: string;
36
+ };
37
+ readonly InputValueDefinition: {
38
+ type: "boolean";
39
+ description: string;
40
+ };
41
+ readonly InterfaceTypeDefinition: {
42
+ type: "boolean";
43
+ description: string;
44
+ };
45
+ readonly UnionTypeDefinition: {
46
+ type: "boolean";
47
+ description: string;
48
+ };
49
+ readonly EnumTypeDefinition: {
50
+ type: "boolean";
51
+ description: string;
52
+ };
53
+ readonly EnumValueDefinition: {
54
+ type: "boolean";
55
+ description: string;
56
+ };
57
+ readonly InputObjectTypeDefinition: {
58
+ type: "boolean";
59
+ description: string;
60
+ };
61
+ readonly DirectiveDefinition: {
62
+ type: "boolean";
63
+ description: string;
64
+ };
65
+ readonly types: {
66
+ readonly type: "boolean";
67
+ readonly enum: readonly [true];
68
+ readonly description: `Includes:
69
+ ${string}`;
70
+ };
71
+ readonly rootField: {
72
+ readonly type: "boolean";
73
+ readonly enum: readonly [true];
74
+ readonly description: "Definitions within `Query`, `Mutation`, and `Subscription` root types.";
75
+ };
76
+ readonly ignoredSelectors: {
77
+ readonly description: string;
78
+ readonly type: "array";
79
+ readonly uniqueItems: true;
80
+ readonly minItems: 1;
81
+ readonly items: {
82
+ readonly type: "string";
83
+ };
84
+ };
85
+ };
86
+ };
87
+ };
88
+ type RuleOptions = FromSchema<typeof schema>;
23
89
  declare const rule: GraphQLESLintRule<RuleOptions>;
24
90
 
25
91
  export { RULE_ID, type RuleOptions, rule };