@graphql-eslint/eslint-plugin 3.19.3-alpha-20230702093957-98f7783 → 3.20.0-alpha-20230703154330-0d51273

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 (302) hide show
  1. package/{typings → cjs}/cache.d.ts +3 -1
  2. package/cjs/cache.js +57 -26
  3. package/{typings → cjs}/configs/index.d.ts +3 -1
  4. package/cjs/configs/index.js +47 -14
  5. package/{typings → cjs}/configs/operations-all.d.ts +2 -1
  6. package/cjs/configs/operations-all.js +47 -30
  7. package/{typings → cjs}/configs/operations-recommended.d.ts +2 -1
  8. package/cjs/configs/operations-recommended.js +72 -55
  9. package/{typings → cjs}/configs/relay.d.ts +2 -1
  10. package/cjs/configs/relay.js +31 -11
  11. package/{typings → cjs}/configs/schema-all.d.ts +2 -1
  12. package/cjs/configs/schema-all.js +41 -24
  13. package/{typings → cjs}/configs/schema-recommended.d.ts +2 -1
  14. package/cjs/configs/schema-recommended.js +68 -51
  15. package/{typings → cjs}/documents.d.ts +4 -1
  16. package/cjs/documents.js +74 -43
  17. package/cjs/estree-converter/converter.d.ts +8 -0
  18. package/cjs/estree-converter/converter.js +80 -59
  19. package/cjs/estree-converter/index.d.ts +8 -0
  20. package/cjs/estree-converter/index.js +25 -5
  21. package/{typings → cjs}/estree-converter/types.d.ts +7 -5
  22. package/cjs/estree-converter/types.js +16 -0
  23. package/cjs/estree-converter/utils.d.ts +18 -0
  24. package/cjs/estree-converter/utils.js +119 -95
  25. package/{typings → cjs}/flat-configs.d.ts +12 -1
  26. package/cjs/flat-configs.js +56 -32
  27. package/cjs/graphql-config.d.ts +13 -0
  28. package/cjs/graphql-config.js +78 -47
  29. package/cjs/index.d.ts +22 -0
  30. package/cjs/index.js +50 -18
  31. package/cjs/parser.d.ts +12 -0
  32. package/cjs/parser.js +96 -76
  33. package/cjs/processor.d.ts +9 -0
  34. package/cjs/processor.js +119 -88
  35. package/{typings → cjs}/rules/alphabetize.d.ts +12 -4
  36. package/cjs/rules/alphabetize.js +337 -295
  37. package/{typings → cjs}/rules/description-style.d.ts +12 -4
  38. package/cjs/rules/description-style.js +96 -66
  39. package/cjs/rules/graphql-js-validation.d.ts +12 -0
  40. package/cjs/rules/graphql-js-validation.js +595 -433
  41. package/cjs/rules/index.d.ts +125 -0
  42. package/cjs/rules/index.js +97 -76
  43. package/{typings → cjs}/rules/input-name.d.ts +12 -4
  44. package/cjs/rules/input-name.js +153 -123
  45. package/{typings → cjs}/rules/lone-executable-definition.d.ts +12 -4
  46. package/cjs/rules/lone-executable-definition.js +101 -72
  47. package/{typings → cjs}/rules/match-document-filename.d.ts +14 -6
  48. package/cjs/rules/match-document-filename.js +229 -182
  49. package/{typings → cjs}/rules/naming-convention.d.ts +12 -4
  50. package/cjs/rules/naming-convention.js +380 -316
  51. package/cjs/rules/no-anonymous-operations.d.ts +12 -0
  52. package/cjs/rules/no-anonymous-operations.js +88 -57
  53. package/cjs/rules/no-case-insensitive-enum-values-duplicates.d.ts +12 -0
  54. package/cjs/rules/no-case-insensitive-enum-values-duplicates.js +82 -50
  55. package/cjs/rules/no-deprecated.d.ts +12 -0
  56. package/cjs/rules/no-deprecated.js +106 -75
  57. package/cjs/rules/no-duplicate-fields.d.ts +12 -0
  58. package/cjs/rules/no-duplicate-fields.js +116 -82
  59. package/cjs/rules/no-hashtag-description.d.ts +13 -0
  60. package/cjs/rules/no-hashtag-description.js +119 -82
  61. package/cjs/rules/no-one-place-fragments.d.ts +12 -0
  62. package/cjs/rules/no-one-place-fragments.js +88 -58
  63. package/{typings → cjs}/rules/no-root-type.d.ts +12 -4
  64. package/cjs/rules/no-root-type.js +101 -74
  65. package/cjs/rules/no-scalar-result-type-on-mutation.d.ts +12 -0
  66. package/cjs/rules/no-scalar-result-type-on-mutation.js +90 -60
  67. package/cjs/rules/no-typename-prefix.d.ts +12 -0
  68. package/cjs/rules/no-typename-prefix.js +88 -55
  69. package/cjs/rules/no-unreachable-types.d.ts +12 -0
  70. package/cjs/rules/no-unreachable-types.js +169 -134
  71. package/cjs/rules/no-unused-fields.d.ts +12 -0
  72. package/cjs/rules/no-unused-fields.js +117 -92
  73. package/{typings → cjs}/rules/relay-arguments.d.ts +12 -4
  74. package/cjs/rules/relay-arguments.js +136 -110
  75. package/cjs/rules/relay-connection-types.d.ts +13 -0
  76. package/cjs/rules/relay-connection-types.js +123 -94
  77. package/{typings → cjs}/rules/relay-edge-types.d.ts +12 -4
  78. package/cjs/rules/relay-edge-types.js +196 -179
  79. package/cjs/rules/relay-page-info.d.ts +12 -0
  80. package/cjs/rules/relay-page-info.js +108 -89
  81. package/{typings → cjs}/rules/require-deprecation-date.d.ts +12 -4
  82. package/cjs/rules/require-deprecation-date.js +143 -112
  83. package/cjs/rules/require-deprecation-reason.d.ts +12 -0
  84. package/cjs/rules/require-deprecation-reason.js +80 -46
  85. package/{typings → cjs}/rules/require-description.d.ts +13 -5
  86. package/cjs/rules/require-description.js +170 -132
  87. package/cjs/rules/require-field-of-type-query-in-mutation-result.d.ts +12 -0
  88. package/cjs/rules/require-field-of-type-query-in-mutation-result.js +81 -51
  89. package/{typings → cjs}/rules/require-id-when-available.d.ts +12 -4
  90. package/cjs/rules/require-id-when-available.js +196 -173
  91. package/cjs/rules/require-import-fragment.d.ts +12 -0
  92. package/cjs/rules/require-import-fragment.js +138 -88
  93. package/cjs/rules/require-nullable-fields-with-oneof.d.ts +12 -0
  94. package/cjs/rules/require-nullable-fields-with-oneof.js +80 -50
  95. package/cjs/rules/require-nullable-result-in-root.d.ts +12 -0
  96. package/cjs/rules/require-nullable-result-in-root.js +97 -68
  97. package/cjs/rules/require-type-pattern-with-oneof.d.ts +12 -0
  98. package/cjs/rules/require-type-pattern-with-oneof.js +70 -42
  99. package/{typings → cjs}/rules/selection-set-depth.d.ts +12 -4
  100. package/cjs/rules/selection-set-depth.js +147 -107
  101. package/{typings → cjs}/rules/strict-id-in-types.d.ts +12 -4
  102. package/cjs/rules/strict-id-in-types.js +143 -122
  103. package/cjs/rules/unique-fragment-name.d.ts +13 -0
  104. package/cjs/rules/unique-fragment-name.js +88 -62
  105. package/cjs/rules/unique-operation-name.d.ts +12 -0
  106. package/cjs/rules/unique-operation-name.js +65 -35
  107. package/cjs/schema.d.ts +12 -0
  108. package/cjs/schema.js +62 -30
  109. package/cjs/siblings.d.ts +8 -0
  110. package/cjs/siblings.js +124 -106
  111. package/cjs/testkit.d.ts +8 -0
  112. package/cjs/testkit.js +165 -144
  113. package/cjs/types-e3367e3c.d.ts +129 -0
  114. package/cjs/types.d.ts +8 -0
  115. package/cjs/types.js +16 -0
  116. package/cjs/utils.d.ts +44 -0
  117. package/cjs/utils.js +181 -124
  118. package/{typings/cache.d.cts → esm/cache.d.mts} +3 -1
  119. package/esm/cache.js +25 -23
  120. package/{typings/configs/index.d.cts → esm/configs/index.d.mts} +3 -1
  121. package/esm/configs/index.js +14 -11
  122. package/{typings/configs/operations-all.d.cts → esm/configs/operations-all.d.mts} +2 -1
  123. package/esm/configs/operations-all.js +28 -28
  124. package/{typings/configs/operations-recommended.d.cts → esm/configs/operations-recommended.d.mts} +2 -1
  125. package/esm/configs/operations-recommended.js +53 -53
  126. package/{typings/configs/relay.d.cts → esm/configs/relay.d.mts} +2 -1
  127. package/esm/configs/relay.js +12 -9
  128. package/{typings/configs/schema-all.d.cts → esm/configs/schema-all.d.mts} +2 -1
  129. package/esm/configs/schema-all.js +22 -22
  130. package/{typings/configs/schema-recommended.d.cts → esm/configs/schema-recommended.d.mts} +2 -1
  131. package/esm/configs/schema-recommended.js +49 -49
  132. package/{typings/documents.d.cts → esm/documents.d.mts} +4 -1
  133. package/esm/documents.js +41 -39
  134. package/esm/estree-converter/converter.d.mts +8 -0
  135. package/esm/estree-converter/converter.js +63 -57
  136. package/esm/estree-converter/index.d.mts +8 -0
  137. package/esm/estree-converter/index.js +3 -3
  138. package/{typings/estree-converter/types.d.cts → esm/estree-converter/types.d.mts} +7 -5
  139. package/esm/estree-converter/utils.d.mts +18 -0
  140. package/esm/estree-converter/utils.js +102 -93
  141. package/{typings/flat-configs.d.cts → esm/flat-configs.d.mts} +13 -2
  142. package/esm/flat-configs.js +33 -30
  143. package/esm/graphql-config.d.mts +13 -0
  144. package/esm/graphql-config.js +49 -44
  145. package/esm/index.d.mts +22 -0
  146. package/esm/index.js +18 -9
  147. package/esm/package.json +1 -1
  148. package/esm/parser.d.mts +12 -0
  149. package/esm/parser.js +64 -73
  150. package/esm/processor.d.mts +9 -0
  151. package/esm/processor.js +98 -86
  152. package/{typings/rules/alphabetize.d.cts → esm/rules/alphabetize.d.mts} +12 -4
  153. package/esm/rules/alphabetize.js +304 -290
  154. package/{typings/rules/description-style.d.cts → esm/rules/description-style.d.mts} +12 -4
  155. package/esm/rules/description-style.js +73 -64
  156. package/esm/rules/graphql-js-validation.d.mts +12 -0
  157. package/esm/rules/graphql-js-validation.js +580 -429
  158. package/esm/rules/index.d.mts +125 -0
  159. package/esm/rules/index.js +74 -74
  160. package/{typings/rules/input-name.d.cts → esm/rules/input-name.d.mts} +12 -4
  161. package/esm/rules/input-name.js +132 -121
  162. package/{typings/rules/lone-executable-definition.d.cts → esm/rules/lone-executable-definition.d.mts} +12 -4
  163. package/esm/rules/lone-executable-definition.js +78 -70
  164. package/{typings/rules/match-document-filename.d.cts → esm/rules/match-document-filename.d.mts} +14 -6
  165. package/esm/rules/match-document-filename.js +210 -180
  166. package/{typings/rules/naming-convention.d.cts → esm/rules/naming-convention.d.mts} +12 -4
  167. package/esm/rules/naming-convention.js +363 -314
  168. package/esm/rules/no-anonymous-operations.d.mts +12 -0
  169. package/esm/rules/no-anonymous-operations.js +65 -55
  170. package/esm/rules/no-case-insensitive-enum-values-duplicates.d.mts +12 -0
  171. package/esm/rules/no-case-insensitive-enum-values-duplicates.js +59 -48
  172. package/esm/rules/no-deprecated.d.mts +12 -0
  173. package/esm/rules/no-deprecated.js +83 -73
  174. package/esm/rules/no-duplicate-fields.d.mts +12 -0
  175. package/esm/rules/no-duplicate-fields.js +93 -80
  176. package/esm/rules/no-hashtag-description.d.mts +13 -0
  177. package/esm/rules/no-hashtag-description.js +95 -80
  178. package/esm/rules/no-one-place-fragments.d.mts +12 -0
  179. package/esm/rules/no-one-place-fragments.js +65 -56
  180. package/{typings/rules/no-root-type.d.cts → esm/rules/no-root-type.d.mts} +12 -4
  181. package/esm/rules/no-root-type.js +78 -72
  182. package/esm/rules/no-scalar-result-type-on-mutation.d.mts +12 -0
  183. package/esm/rules/no-scalar-result-type-on-mutation.js +67 -58
  184. package/esm/rules/no-typename-prefix.d.mts +12 -0
  185. package/esm/rules/no-typename-prefix.js +65 -53
  186. package/esm/rules/no-unreachable-types.d.mts +12 -0
  187. package/esm/rules/no-unreachable-types.js +141 -131
  188. package/esm/rules/no-unused-fields.d.mts +12 -0
  189. package/esm/rules/no-unused-fields.js +94 -90
  190. package/{typings/rules/relay-arguments.d.cts → esm/rules/relay-arguments.d.mts} +12 -4
  191. package/esm/rules/relay-arguments.js +113 -108
  192. package/esm/rules/relay-connection-types.d.mts +13 -0
  193. package/esm/rules/relay-connection-types.js +98 -91
  194. package/{typings/rules/relay-edge-types.d.cts → esm/rules/relay-edge-types.d.mts} +12 -4
  195. package/esm/rules/relay-edge-types.js +178 -177
  196. package/esm/rules/relay-page-info.d.mts +12 -0
  197. package/esm/rules/relay-page-info.js +84 -86
  198. package/{typings/rules/require-deprecation-date.d.cts → esm/rules/require-deprecation-date.d.mts} +12 -4
  199. package/esm/rules/require-deprecation-date.js +120 -110
  200. package/esm/rules/require-deprecation-reason.d.mts +12 -0
  201. package/esm/rules/require-deprecation-reason.js +57 -44
  202. package/{typings/rules/require-description.d.cts → esm/rules/require-description.d.mts} +13 -5
  203. package/esm/rules/require-description.js +151 -130
  204. package/esm/rules/require-field-of-type-query-in-mutation-result.d.mts +12 -0
  205. package/esm/rules/require-field-of-type-query-in-mutation-result.js +58 -49
  206. package/{typings/rules/require-id-when-available.d.cts → esm/rules/require-id-when-available.d.mts} +12 -4
  207. package/esm/rules/require-id-when-available.js +186 -171
  208. package/esm/rules/require-import-fragment.d.mts +12 -0
  209. package/esm/rules/require-import-fragment.js +105 -85
  210. package/esm/rules/require-nullable-fields-with-oneof.d.mts +12 -0
  211. package/esm/rules/require-nullable-fields-with-oneof.js +57 -48
  212. package/esm/rules/require-nullable-result-in-root.d.mts +12 -0
  213. package/esm/rules/require-nullable-result-in-root.js +74 -66
  214. package/esm/rules/require-type-pattern-with-oneof.d.mts +12 -0
  215. package/esm/rules/require-type-pattern-with-oneof.js +47 -40
  216. package/{typings/rules/selection-set-depth.d.cts → esm/rules/selection-set-depth.d.mts} +12 -4
  217. package/esm/rules/selection-set-depth.js +114 -104
  218. package/{typings/rules/strict-id-in-types.d.cts → esm/rules/strict-id-in-types.d.mts} +12 -4
  219. package/esm/rules/strict-id-in-types.js +125 -119
  220. package/esm/rules/unique-fragment-name.d.mts +13 -0
  221. package/esm/rules/unique-fragment-name.js +65 -60
  222. package/esm/rules/unique-operation-name.d.mts +12 -0
  223. package/esm/rules/unique-operation-name.js +42 -33
  224. package/esm/schema.d.mts +12 -0
  225. package/esm/schema.js +29 -26
  226. package/esm/siblings.d.mts +8 -0
  227. package/esm/siblings.js +105 -104
  228. package/esm/testkit.d.mts +8 -0
  229. package/esm/testkit.js +132 -141
  230. package/esm/types-2e1afd7c.d.ts +129 -0
  231. package/esm/types.d.mts +8 -0
  232. package/esm/utils.d.mts +44 -0
  233. package/esm/utils.js +138 -116
  234. package/package.json +40 -30
  235. package/typings/estree-converter/converter.d.cts +0 -3
  236. package/typings/estree-converter/converter.d.ts +0 -3
  237. package/typings/estree-converter/index.d.cts +0 -3
  238. package/typings/estree-converter/index.d.ts +0 -3
  239. package/typings/estree-converter/utils.d.cts +0 -13
  240. package/typings/estree-converter/utils.d.ts +0 -13
  241. package/typings/graphql-config.d.cts +0 -4
  242. package/typings/graphql-config.d.ts +0 -4
  243. package/typings/index.d.cts +0 -10
  244. package/typings/index.d.ts +0 -10
  245. package/typings/parser.d.cts +0 -2
  246. package/typings/parser.d.ts +0 -2
  247. package/typings/processor.d.cts +0 -6
  248. package/typings/processor.d.ts +0 -6
  249. package/typings/rules/graphql-js-validation.d.cts +0 -2
  250. package/typings/rules/graphql-js-validation.d.ts +0 -2
  251. package/typings/rules/index.d.cts +0 -111
  252. package/typings/rules/index.d.ts +0 -111
  253. package/typings/rules/no-anonymous-operations.d.cts +0 -2
  254. package/typings/rules/no-anonymous-operations.d.ts +0 -2
  255. package/typings/rules/no-case-insensitive-enum-values-duplicates.d.cts +0 -2
  256. package/typings/rules/no-case-insensitive-enum-values-duplicates.d.ts +0 -2
  257. package/typings/rules/no-deprecated.d.cts +0 -2
  258. package/typings/rules/no-deprecated.d.ts +0 -2
  259. package/typings/rules/no-duplicate-fields.d.cts +0 -2
  260. package/typings/rules/no-duplicate-fields.d.ts +0 -2
  261. package/typings/rules/no-hashtag-description.d.cts +0 -3
  262. package/typings/rules/no-hashtag-description.d.ts +0 -3
  263. package/typings/rules/no-one-place-fragments.d.cts +0 -2
  264. package/typings/rules/no-one-place-fragments.d.ts +0 -2
  265. package/typings/rules/no-scalar-result-type-on-mutation.d.cts +0 -2
  266. package/typings/rules/no-scalar-result-type-on-mutation.d.ts +0 -2
  267. package/typings/rules/no-typename-prefix.d.cts +0 -2
  268. package/typings/rules/no-typename-prefix.d.ts +0 -2
  269. package/typings/rules/no-unreachable-types.d.cts +0 -2
  270. package/typings/rules/no-unreachable-types.d.ts +0 -2
  271. package/typings/rules/no-unused-fields.d.cts +0 -2
  272. package/typings/rules/no-unused-fields.d.ts +0 -2
  273. package/typings/rules/relay-connection-types.d.cts +0 -4
  274. package/typings/rules/relay-connection-types.d.ts +0 -4
  275. package/typings/rules/relay-page-info.d.cts +0 -2
  276. package/typings/rules/relay-page-info.d.ts +0 -2
  277. package/typings/rules/require-deprecation-reason.d.cts +0 -2
  278. package/typings/rules/require-deprecation-reason.d.ts +0 -2
  279. package/typings/rules/require-field-of-type-query-in-mutation-result.d.cts +0 -2
  280. package/typings/rules/require-field-of-type-query-in-mutation-result.d.ts +0 -2
  281. package/typings/rules/require-import-fragment.d.cts +0 -2
  282. package/typings/rules/require-import-fragment.d.ts +0 -2
  283. package/typings/rules/require-nullable-fields-with-oneof.d.cts +0 -2
  284. package/typings/rules/require-nullable-fields-with-oneof.d.ts +0 -2
  285. package/typings/rules/require-nullable-result-in-root.d.cts +0 -2
  286. package/typings/rules/require-nullable-result-in-root.d.ts +0 -2
  287. package/typings/rules/require-type-pattern-with-oneof.d.cts +0 -2
  288. package/typings/rules/require-type-pattern-with-oneof.d.ts +0 -2
  289. package/typings/rules/unique-fragment-name.d.cts +0 -5
  290. package/typings/rules/unique-fragment-name.d.ts +0 -5
  291. package/typings/rules/unique-operation-name.d.cts +0 -2
  292. package/typings/rules/unique-operation-name.d.ts +0 -2
  293. package/typings/schema.d.cts +0 -3
  294. package/typings/schema.d.ts +0 -3
  295. package/typings/siblings.d.cts +0 -22
  296. package/typings/siblings.d.ts +0 -22
  297. package/typings/testkit.d.cts +0 -29
  298. package/typings/testkit.d.ts +0 -29
  299. package/typings/types.d.cts +0 -83
  300. package/typings/types.d.ts +0 -83
  301. package/typings/utils.d.cts +0 -40
  302. package/typings/utils.d.ts +0 -40
@@ -1,43 +1,58 @@
1
- import { asArray } from '@graphql-tools/utils';
2
- import { GraphQLInterfaceType, GraphQLObjectType, GraphQLUnionType, Kind, TypeInfo, visit, visitWithTypeInfo, } from 'graphql';
3
- import { getBaseType } from '../estree-converter/index.js';
4
- import { ARRAY_DEFAULT_OPTIONS, englishJoinWords, requireGraphQLSchemaFromContext, requireSiblingsOperations, } from '../utils.js';
5
- const RULE_ID = 'require-id-when-available';
6
- const DEFAULT_ID_FIELD_NAME = 'id';
1
+ import { asArray } from "@graphql-tools/utils";
2
+ import {
3
+ GraphQLInterfaceType,
4
+ GraphQLObjectType,
5
+ GraphQLUnionType,
6
+ Kind,
7
+ TypeInfo,
8
+ visit,
9
+ visitWithTypeInfo
10
+ } from "graphql";
11
+ import { getBaseType } from "../estree-converter/index.js";
12
+ import {
13
+ ARRAY_DEFAULT_OPTIONS,
14
+ englishJoinWords,
15
+ requireGraphQLSchemaFromContext,
16
+ requireSiblingsOperations
17
+ } from "../utils.js";
18
+ const RULE_ID = "require-id-when-available";
19
+ const DEFAULT_ID_FIELD_NAME = "id";
7
20
  const schema = {
8
- definitions: {
9
- asString: {
10
- type: 'string',
11
- },
12
- asArray: ARRAY_DEFAULT_OPTIONS,
13
- },
14
- type: 'array',
15
- maxItems: 1,
16
- items: {
17
- type: 'object',
18
- additionalProperties: false,
19
- properties: {
20
- fieldName: {
21
- oneOf: [{ $ref: '#/definitions/asString' }, { $ref: '#/definitions/asArray' }],
22
- default: DEFAULT_ID_FIELD_NAME,
23
- },
24
- },
21
+ definitions: {
22
+ asString: {
23
+ type: "string"
25
24
  },
25
+ asArray: ARRAY_DEFAULT_OPTIONS
26
+ },
27
+ type: "array",
28
+ maxItems: 1,
29
+ items: {
30
+ type: "object",
31
+ additionalProperties: false,
32
+ properties: {
33
+ fieldName: {
34
+ oneOf: [{ $ref: "#/definitions/asString" }, { $ref: "#/definitions/asArray" }],
35
+ default: DEFAULT_ID_FIELD_NAME
36
+ }
37
+ }
38
+ }
26
39
  };
27
- export const rule = {
28
- meta: {
29
- type: 'suggestion',
30
- hasSuggestions: true,
31
- docs: {
32
- category: 'Operations',
33
- description: 'Enforce selecting specific fields when they are available on the GraphQL type.',
34
- url: `https://the-guild.dev/graphql/eslint/rules/${RULE_ID}`,
35
- requiresSchema: true,
36
- requiresSiblings: true,
37
- examples: [
38
- {
39
- title: 'Incorrect',
40
- code: /* GraphQL */ `
40
+ const rule = {
41
+ meta: {
42
+ type: "suggestion",
43
+ hasSuggestions: true,
44
+ docs: {
45
+ category: "Operations",
46
+ description: "Enforce selecting specific fields when they are available on the GraphQL type.",
47
+ url: `https://the-guild.dev/graphql/eslint/rules/${RULE_ID}`,
48
+ requiresSchema: true,
49
+ requiresSiblings: true,
50
+ examples: [
51
+ {
52
+ title: "Incorrect",
53
+ code: (
54
+ /* GraphQL */
55
+ `
41
56
  # In your schema
42
57
  type User {
43
58
  id: ID!
@@ -50,11 +65,14 @@ export const rule = {
50
65
  name
51
66
  }
52
67
  }
53
- `,
54
- },
55
- {
56
- title: 'Correct',
57
- code: /* GraphQL */ `
68
+ `
69
+ )
70
+ },
71
+ {
72
+ title: "Correct",
73
+ code: (
74
+ /* GraphQL */
75
+ `
58
76
  # In your schema
59
77
  type User {
60
78
  id: ID!
@@ -75,141 +93,138 @@ export const rule = {
75
93
  id: name
76
94
  }
77
95
  }
78
- `,
79
- },
80
- ],
81
- recommended: true,
82
- },
83
- messages: {
84
- [RULE_ID]: "Field{{ pluralSuffix }} {{ fieldName }} must be selected when it's available on a type.\nInclude it in your selection set{{ addition }}.",
85
- },
86
- schema,
96
+ `
97
+ )
98
+ }
99
+ ],
100
+ recommended: true
101
+ },
102
+ messages: {
103
+ [RULE_ID]: "Field{{ pluralSuffix }} {{ fieldName }} must be selected when it's available on a type.\nInclude it in your selection set{{ addition }}."
87
104
  },
88
- create(context) {
89
- const schema = requireGraphQLSchemaFromContext(RULE_ID, context);
90
- const siblings = requireSiblingsOperations(RULE_ID, context);
91
- const { fieldName = DEFAULT_ID_FIELD_NAME } = context.options[0] || {};
92
- const idNames = asArray(fieldName);
93
- // Check selections only in OperationDefinition,
94
- // skip selections of OperationDefinition and InlineFragment
95
- const selector = 'OperationDefinition SelectionSet[parent.kind!=/(^OperationDefinition|InlineFragment)$/]';
96
- const typeInfo = new TypeInfo(schema);
97
- function checkFragments(node) {
98
- for (const selection of node.selections) {
99
- if (selection.kind !== Kind.FRAGMENT_SPREAD) {
100
- continue;
101
- }
102
- const [foundSpread] = siblings.getFragment(selection.name.value);
103
- if (!foundSpread) {
104
- continue;
105
- }
106
- const checkedFragmentSpreads = new Set();
107
- const visitor = visitWithTypeInfo(typeInfo, {
108
- SelectionSet(node, key, _parent) {
109
- const parent = _parent;
110
- if (parent.kind === Kind.FRAGMENT_DEFINITION) {
111
- checkedFragmentSpreads.add(parent.name.value);
112
- }
113
- else if (parent.kind !== Kind.INLINE_FRAGMENT) {
114
- checkSelections(node, typeInfo.getType(), selection.loc.start, parent, checkedFragmentSpreads);
115
- }
116
- },
117
- });
118
- visit(foundSpread.document, visitor);
105
+ schema
106
+ },
107
+ create(context) {
108
+ const schema2 = requireGraphQLSchemaFromContext(RULE_ID, context);
109
+ const siblings = requireSiblingsOperations(RULE_ID, context);
110
+ const { fieldName = DEFAULT_ID_FIELD_NAME } = context.options[0] || {};
111
+ const idNames = asArray(fieldName);
112
+ const selector = "OperationDefinition SelectionSet[parent.kind!=/(^OperationDefinition|InlineFragment)$/]";
113
+ const typeInfo = new TypeInfo(schema2);
114
+ function checkFragments(node) {
115
+ for (const selection of node.selections) {
116
+ if (selection.kind !== Kind.FRAGMENT_SPREAD) {
117
+ continue;
118
+ }
119
+ const [foundSpread] = siblings.getFragment(selection.name.value);
120
+ if (!foundSpread) {
121
+ continue;
122
+ }
123
+ const checkedFragmentSpreads = /* @__PURE__ */ new Set();
124
+ const visitor = visitWithTypeInfo(typeInfo, {
125
+ SelectionSet(node2, key, _parent) {
126
+ const parent = _parent;
127
+ if (parent.kind === Kind.FRAGMENT_DEFINITION) {
128
+ checkedFragmentSpreads.add(parent.name.value);
129
+ } else if (parent.kind !== Kind.INLINE_FRAGMENT) {
130
+ checkSelections(
131
+ node2,
132
+ typeInfo.getType(),
133
+ selection.loc.start,
134
+ parent,
135
+ checkedFragmentSpreads
136
+ );
119
137
  }
138
+ }
139
+ });
140
+ visit(foundSpread.document, visitor);
141
+ }
142
+ }
143
+ function checkSelections(node, type, loc, parent, checkedFragmentSpreads = /* @__PURE__ */ new Set()) {
144
+ const rawType = getBaseType(type);
145
+ if (rawType instanceof GraphQLObjectType || rawType instanceof GraphQLInterfaceType) {
146
+ checkFields(rawType);
147
+ } else if (rawType instanceof GraphQLUnionType) {
148
+ for (const selection of node.selections) {
149
+ if (selection.kind === Kind.INLINE_FRAGMENT) {
150
+ const types = rawType.getTypes();
151
+ const t = types.find((t2) => t2.name === selection.typeCondition.name.value);
152
+ if (t) {
153
+ checkFields(t);
154
+ }
155
+ }
156
+ }
157
+ }
158
+ function checkFields(rawType2) {
159
+ const fields = rawType2.getFields();
160
+ const hasIdFieldInType = idNames.some((name) => fields[name]);
161
+ if (!hasIdFieldInType) {
162
+ return;
120
163
  }
121
- function checkSelections(node, type,
122
- // Fragment can be placed in separate file
123
- // Provide actual fragment spread location instead of location in fragment
124
- loc,
125
- // Can't access to node.parent in GraphQL AST.Node, so pass as argument
126
- parent, checkedFragmentSpreads = new Set()) {
127
- const rawType = getBaseType(type);
128
- if (rawType instanceof GraphQLObjectType || rawType instanceof GraphQLInterfaceType) {
129
- checkFields(rawType);
164
+ function hasIdField({ selections }) {
165
+ return selections.some((selection) => {
166
+ if (selection.kind === Kind.FIELD) {
167
+ if (selection.alias && idNames.includes(selection.alias.value)) {
168
+ return true;
169
+ }
170
+ return idNames.includes(selection.name.value);
130
171
  }
131
- else if (rawType instanceof GraphQLUnionType) {
132
- for (const selection of node.selections) {
133
- if (selection.kind === Kind.INLINE_FRAGMENT) {
134
- const types = rawType.getTypes();
135
- const t = types.find(t => t.name === selection.typeCondition.name.value);
136
- if (t) {
137
- checkFields(t);
138
- }
139
- }
140
- }
172
+ if (selection.kind === Kind.INLINE_FRAGMENT) {
173
+ return hasIdField(selection.selectionSet);
141
174
  }
142
- function checkFields(rawType) {
143
- const fields = rawType.getFields();
144
- const hasIdFieldInType = idNames.some(name => fields[name]);
145
- if (!hasIdFieldInType) {
146
- return;
147
- }
148
- function hasIdField({ selections }) {
149
- return selections.some(selection => {
150
- if (selection.kind === Kind.FIELD) {
151
- if (selection.alias && idNames.includes(selection.alias.value)) {
152
- return true;
153
- }
154
- return idNames.includes(selection.name.value);
155
- }
156
- if (selection.kind === Kind.INLINE_FRAGMENT) {
157
- return hasIdField(selection.selectionSet);
158
- }
159
- if (selection.kind === Kind.FRAGMENT_SPREAD) {
160
- const [foundSpread] = siblings.getFragment(selection.name.value);
161
- if (foundSpread) {
162
- const fragmentSpread = foundSpread.document;
163
- checkedFragmentSpreads.add(fragmentSpread.name.value);
164
- return hasIdField(fragmentSpread.selectionSet);
165
- }
166
- }
167
- return false;
168
- });
169
- }
170
- const hasId = hasIdField(node);
171
- checkFragments(node);
172
- if (hasId) {
173
- return;
174
- }
175
- const pluralSuffix = idNames.length > 1 ? 's' : '';
176
- const fieldName = englishJoinWords(idNames.map(name => `\`${(parent.alias || parent.name).value}.${name}\``));
177
- const addition = checkedFragmentSpreads.size === 0
178
- ? ''
179
- : ` or add to used fragment${checkedFragmentSpreads.size > 1 ? 's' : ''} ${englishJoinWords([...checkedFragmentSpreads].map(name => `\`${name}\``))}`;
180
- const problem = {
181
- loc,
182
- messageId: RULE_ID,
183
- data: {
184
- pluralSuffix,
185
- fieldName,
186
- addition,
187
- },
188
- };
189
- // Don't provide suggestions for selections in fragments as fragment can be in a separate file
190
- if ('type' in node) {
191
- problem.suggest = idNames.map(idName => ({
192
- desc: `Add \`${idName}\` selection`,
193
- fix: fixer => {
194
- let insertNode = node.selections[0];
195
- insertNode =
196
- insertNode.kind === Kind.INLINE_FRAGMENT
197
- ? insertNode.selectionSet.selections[0]
198
- : insertNode;
199
- return fixer.insertTextBefore(insertNode, `${idName} `);
200
- },
201
- }));
202
- }
203
- context.report(problem);
175
+ if (selection.kind === Kind.FRAGMENT_SPREAD) {
176
+ const [foundSpread] = siblings.getFragment(selection.name.value);
177
+ if (foundSpread) {
178
+ const fragmentSpread = foundSpread.document;
179
+ checkedFragmentSpreads.add(fragmentSpread.name.value);
180
+ return hasIdField(fragmentSpread.selectionSet);
181
+ }
204
182
  }
183
+ return false;
184
+ });
185
+ }
186
+ const hasId = hasIdField(node);
187
+ checkFragments(node);
188
+ if (hasId) {
189
+ return;
205
190
  }
206
- return {
207
- [selector](node) {
208
- const typeInfo = node.typeInfo();
209
- if (typeInfo.gqlType) {
210
- checkSelections(node, typeInfo.gqlType, node.loc.start, node.parent);
211
- }
212
- },
191
+ const pluralSuffix = idNames.length > 1 ? "s" : "";
192
+ const fieldName2 = englishJoinWords(
193
+ idNames.map((name) => `\`${(parent.alias || parent.name).value}.${name}\``)
194
+ );
195
+ const addition = checkedFragmentSpreads.size === 0 ? "" : ` or add to used fragment${checkedFragmentSpreads.size > 1 ? "s" : ""} ${englishJoinWords([...checkedFragmentSpreads].map((name) => `\`${name}\``))}`;
196
+ const problem = {
197
+ loc,
198
+ messageId: RULE_ID,
199
+ data: {
200
+ pluralSuffix,
201
+ fieldName: fieldName2,
202
+ addition
203
+ }
213
204
  };
214
- },
205
+ if ("type" in node) {
206
+ problem.suggest = idNames.map((idName) => ({
207
+ desc: `Add \`${idName}\` selection`,
208
+ fix: (fixer) => {
209
+ let insertNode = node.selections[0];
210
+ insertNode = insertNode.kind === Kind.INLINE_FRAGMENT ? insertNode.selectionSet.selections[0] : insertNode;
211
+ return fixer.insertTextBefore(insertNode, `${idName} `);
212
+ }
213
+ }));
214
+ }
215
+ context.report(problem);
216
+ }
217
+ }
218
+ return {
219
+ [selector](node) {
220
+ const typeInfo2 = node.typeInfo();
221
+ if (typeInfo2.gqlType) {
222
+ checkSelections(node, typeInfo2.gqlType, node.loc.start, node.parent);
223
+ }
224
+ }
225
+ };
226
+ }
227
+ };
228
+ export {
229
+ rule
215
230
  };
@@ -0,0 +1,12 @@
1
+ import { i as GraphQLESLintRule } from '../types-2e1afd7c.js';
2
+ import '@graphql-tools/utils';
3
+ import 'eslint';
4
+ import 'estree';
5
+ import 'graphql';
6
+ import 'graphql-config';
7
+ import 'json-schema-to-ts';
8
+ import '../estree-converter/types.mjs';
9
+
10
+ declare const rule: GraphQLESLintRule;
11
+
12
+ export { rule };
@@ -1,111 +1,131 @@
1
- import path from 'path';
2
- import { requireSiblingsOperations } from '../utils.js';
3
- const RULE_ID = 'require-import-fragment';
4
- const SUGGESTION_ID = 'add-import-expression';
5
- export const rule = {
6
- meta: {
7
- type: 'suggestion',
8
- docs: {
9
- category: 'Operations',
10
- description: 'Require fragments to be imported via an import expression.',
11
- url: `https://the-guild.dev/graphql/eslint/rules/${RULE_ID}`,
12
- examples: [
13
- {
14
- title: 'Incorrect',
15
- code: /* GraphQL */ `
1
+ import path from "path";
2
+ import { requireSiblingsOperations } from "../utils.js";
3
+ const RULE_ID = "require-import-fragment";
4
+ const SUGGESTION_ID = "add-import-expression";
5
+ const rule = {
6
+ meta: {
7
+ type: "suggestion",
8
+ docs: {
9
+ category: "Operations",
10
+ description: "Require fragments to be imported via an import expression.",
11
+ url: `https://the-guild.dev/graphql/eslint/rules/${RULE_ID}`,
12
+ examples: [
13
+ {
14
+ title: "Incorrect",
15
+ code: (
16
+ /* GraphQL */
17
+ `
16
18
  query {
17
19
  user {
18
20
  ...UserFields
19
21
  }
20
22
  }
21
- `,
22
- },
23
- {
24
- title: 'Incorrect',
25
- code: /* GraphQL */ `
23
+ `
24
+ )
25
+ },
26
+ {
27
+ title: "Incorrect",
28
+ code: (
29
+ /* GraphQL */
30
+ `
26
31
  # import 'post-fields.fragment.graphql'
27
32
  query {
28
33
  user {
29
34
  ...UserFields
30
35
  }
31
36
  }
32
- `,
33
- },
34
- {
35
- title: 'Incorrect',
36
- code: /* GraphQL */ `
37
+ `
38
+ )
39
+ },
40
+ {
41
+ title: "Incorrect",
42
+ code: (
43
+ /* GraphQL */
44
+ `
37
45
  # import UserFields from 'post-fields.fragment.graphql'
38
46
  query {
39
47
  user {
40
48
  ...UserFields
41
49
  }
42
50
  }
43
- `,
44
- },
45
- {
46
- title: 'Correct',
47
- code: /* GraphQL */ `
51
+ `
52
+ )
53
+ },
54
+ {
55
+ title: "Correct",
56
+ code: (
57
+ /* GraphQL */
58
+ `
48
59
  # import UserFields from 'user-fields.fragment.graphql'
49
60
  query {
50
61
  user {
51
62
  ...UserFields
52
63
  }
53
64
  }
54
- `,
55
- },
56
- ],
57
- requiresSiblings: true,
58
- isDisabledForAllConfig: true,
59
- },
60
- hasSuggestions: true,
61
- messages: {
62
- [RULE_ID]: 'Expected "{{fragmentName}}" fragment to be imported.',
63
- [SUGGESTION_ID]: 'Add import expression for "{{fragmentName}}".',
64
- },
65
- schema: [],
65
+ `
66
+ )
67
+ }
68
+ ],
69
+ requiresSiblings: true,
70
+ isDisabledForAllConfig: true
66
71
  },
67
- create(context) {
68
- const comments = context.getSourceCode().getAllComments();
69
- const siblings = requireSiblingsOperations(RULE_ID, context);
70
- const filePath = context.getFilename();
71
- return {
72
- 'FragmentSpread > .name'(node) {
73
- var _a;
74
- const fragmentName = node.value;
75
- const fragmentsFromSiblings = siblings.getFragment(fragmentName);
76
- for (const comment of comments) {
77
- if (comment.type !== 'Line')
78
- continue;
79
- // 1. could start with extra whitespace
80
- // 2. match both named/default import
81
- const isPossibleImported = new RegExp(`^\\s*import\\s+(${fragmentName}\\s+from\\s+)?['"]`).test(comment.value);
82
- if (!isPossibleImported)
83
- continue;
84
- const extractedImportPath = (_a = comment.value.match(/(["'])((?:\1|.)*?)\1/)) === null || _a === void 0 ? void 0 : _a[2];
85
- if (!extractedImportPath)
86
- continue;
87
- const importPath = path.join(path.dirname(filePath), extractedImportPath);
88
- const hasInSiblings = fragmentsFromSiblings.some(source => source.filePath === importPath);
89
- if (hasInSiblings)
90
- return;
91
- }
92
- const fragmentInSameFile = fragmentsFromSiblings.some(source => source.filePath === filePath);
93
- if (fragmentInSameFile)
94
- return;
95
- const suggestedFilePaths = fragmentsFromSiblings.length
96
- ? fragmentsFromSiblings.map(o => path.relative(path.dirname(filePath), o.filePath))
97
- : ['CHANGE_ME.graphql'];
98
- context.report({
99
- node,
100
- messageId: RULE_ID,
101
- data: { fragmentName },
102
- suggest: suggestedFilePaths.map(suggestedPath => ({
103
- messageId: SUGGESTION_ID,
104
- data: { fragmentName },
105
- fix: fixer => fixer.insertTextBeforeRange([0, 0], `# import ${fragmentName} from '${suggestedPath}'\n`),
106
- })),
107
- });
108
- },
109
- };
72
+ hasSuggestions: true,
73
+ messages: {
74
+ [RULE_ID]: 'Expected "{{fragmentName}}" fragment to be imported.',
75
+ [SUGGESTION_ID]: 'Add import expression for "{{fragmentName}}".'
110
76
  },
77
+ schema: []
78
+ },
79
+ create(context) {
80
+ const comments = context.getSourceCode().getAllComments();
81
+ const siblings = requireSiblingsOperations(RULE_ID, context);
82
+ const filePath = context.getFilename();
83
+ return {
84
+ "FragmentSpread > .name"(node) {
85
+ const fragmentName = node.value;
86
+ const fragmentsFromSiblings = siblings.getFragment(fragmentName);
87
+ for (const comment of comments) {
88
+ if (comment.type !== "Line")
89
+ continue;
90
+ const isPossibleImported = new RegExp(
91
+ `^\\s*import\\s+(${fragmentName}\\s+from\\s+)?['"]`
92
+ ).test(comment.value);
93
+ if (!isPossibleImported)
94
+ continue;
95
+ const extractedImportPath = comment.value.match(/(["'])((?:\1|.)*?)\1/)?.[2];
96
+ if (!extractedImportPath)
97
+ continue;
98
+ const importPath = path.join(path.dirname(filePath), extractedImportPath);
99
+ const hasInSiblings = fragmentsFromSiblings.some(
100
+ (source) => source.filePath === importPath
101
+ );
102
+ if (hasInSiblings)
103
+ return;
104
+ }
105
+ const fragmentInSameFile = fragmentsFromSiblings.some(
106
+ (source) => source.filePath === filePath
107
+ );
108
+ if (fragmentInSameFile)
109
+ return;
110
+ const suggestedFilePaths = fragmentsFromSiblings.length ? fragmentsFromSiblings.map((o) => path.relative(path.dirname(filePath), o.filePath)) : ["CHANGE_ME.graphql"];
111
+ context.report({
112
+ node,
113
+ messageId: RULE_ID,
114
+ data: { fragmentName },
115
+ suggest: suggestedFilePaths.map((suggestedPath) => ({
116
+ messageId: SUGGESTION_ID,
117
+ data: { fragmentName },
118
+ fix: (fixer) => fixer.insertTextBeforeRange(
119
+ [0, 0],
120
+ `# import ${fragmentName} from '${suggestedPath}'
121
+ `
122
+ )
123
+ }))
124
+ });
125
+ }
126
+ };
127
+ }
128
+ };
129
+ export {
130
+ rule
111
131
  };
@@ -0,0 +1,12 @@
1
+ import { i as GraphQLESLintRule } from '../types-2e1afd7c.js';
2
+ import '@graphql-tools/utils';
3
+ import 'eslint';
4
+ import 'estree';
5
+ import 'graphql';
6
+ import 'graphql-config';
7
+ import 'json-schema-to-ts';
8
+ import '../estree-converter/types.mjs';
9
+
10
+ declare const rule: GraphQLESLintRule;
11
+
12
+ export { rule };