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

Sign up to get free protection for your applications and to get access to all the features.
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
package/esm/siblings.js CHANGED
@@ -1,109 +1,110 @@
1
- import { parseGraphQLSDL } from '@graphql-tools/utils';
2
- import { Kind, visit, } from 'graphql';
3
- import { getDocuments } from './documents.js';
4
- import { logger } from './utils.js';
5
- const siblingOperationsCache = new Map();
6
- export function getSiblings(project, documents) {
7
- const siblings = project
8
- ? getDocuments(project)
9
- : typeof documents === 'string'
10
- ? [parseGraphQLSDL('operation.graphql', documents, { noLocation: true })]
11
- : [];
12
- if (siblings.length === 0) {
13
- let printed = false;
14
- const noopWarn = () => {
15
- if (!printed) {
16
- logger.warn('getSiblingOperations was called without any operations. Make sure to set "parserOptions.operations" to make this feature available!');
17
- printed = true;
18
- }
19
- return [];
20
- };
21
- return {
22
- available: false,
23
- getFragment: noopWarn,
24
- getFragments: noopWarn,
25
- getFragmentByType: noopWarn,
26
- getFragmentsInUse: noopWarn,
27
- getOperation: noopWarn,
28
- getOperations: noopWarn,
29
- getOperationByType: noopWarn,
30
- };
1
+ import { parseGraphQLSDL } from "@graphql-tools/utils";
2
+ import {
3
+ Kind,
4
+ visit
5
+ } from "graphql";
6
+ import { getDocuments } from "./documents.js";
7
+ import { logger } from "./utils.js";
8
+ const siblingOperationsCache = /* @__PURE__ */ new Map();
9
+ function getSiblings(project, documents) {
10
+ const siblings = project ? getDocuments(project) : typeof documents === "string" ? [parseGraphQLSDL("operation.graphql", documents, { noLocation: true })] : [];
11
+ if (siblings.length === 0) {
12
+ let printed = false;
13
+ const noopWarn = () => {
14
+ if (!printed) {
15
+ logger.warn(
16
+ 'getSiblingOperations was called without any operations. Make sure to set "parserOptions.operations" to make this feature available!'
17
+ );
18
+ printed = true;
19
+ }
20
+ return [];
21
+ };
22
+ return {
23
+ available: false,
24
+ getFragment: noopWarn,
25
+ getFragments: noopWarn,
26
+ getFragmentByType: noopWarn,
27
+ getFragmentsInUse: noopWarn,
28
+ getOperation: noopWarn,
29
+ getOperations: noopWarn,
30
+ getOperationByType: noopWarn
31
+ };
32
+ }
33
+ const value = siblingOperationsCache.get(siblings);
34
+ if (value) {
35
+ return value;
36
+ }
37
+ let fragmentsCache = null;
38
+ const getFragments = () => {
39
+ if (fragmentsCache === null) {
40
+ const result = [];
41
+ for (const source of siblings) {
42
+ for (const definition of source.document?.definitions || []) {
43
+ if (definition.kind === Kind.FRAGMENT_DEFINITION) {
44
+ result.push({
45
+ filePath: source.location,
46
+ document: definition
47
+ });
48
+ }
49
+ }
50
+ }
51
+ fragmentsCache = result;
31
52
  }
32
- // Since the siblings array is cached, we can use it as cache key.
33
- // We should get the same array reference each time we get
34
- // to this point for the same graphql project
35
- const value = siblingOperationsCache.get(siblings);
36
- if (value) {
37
- return value;
53
+ return fragmentsCache;
54
+ };
55
+ let cachedOperations = null;
56
+ const getOperations = () => {
57
+ if (cachedOperations === null) {
58
+ const result = [];
59
+ for (const source of siblings) {
60
+ for (const definition of source.document?.definitions || []) {
61
+ if (definition.kind === Kind.OPERATION_DEFINITION) {
62
+ result.push({
63
+ filePath: source.location,
64
+ document: definition
65
+ });
66
+ }
67
+ }
68
+ }
69
+ cachedOperations = result;
38
70
  }
39
- let fragmentsCache = null;
40
- const getFragments = () => {
41
- var _a;
42
- if (fragmentsCache === null) {
43
- const result = [];
44
- for (const source of siblings) {
45
- for (const definition of ((_a = source.document) === null || _a === void 0 ? void 0 : _a.definitions) || []) {
46
- if (definition.kind === Kind.FRAGMENT_DEFINITION) {
47
- result.push({
48
- filePath: source.location,
49
- document: definition,
50
- });
51
- }
52
- }
53
- }
54
- fragmentsCache = result;
71
+ return cachedOperations;
72
+ };
73
+ const getFragment = (name) => getFragments().filter((f) => f.document.name.value === name);
74
+ const collectFragments = (selectable, recursive, collected = /* @__PURE__ */ new Map()) => {
75
+ visit(selectable, {
76
+ FragmentSpread(spread) {
77
+ const fragmentName = spread.name.value;
78
+ const [fragment] = getFragment(fragmentName);
79
+ if (!fragment) {
80
+ logger.warn(
81
+ `Unable to locate fragment named "${fragmentName}", please make sure it's loaded using "parserOptions.operations"`
82
+ );
83
+ return;
55
84
  }
56
- return fragmentsCache;
57
- };
58
- let cachedOperations = null;
59
- const getOperations = () => {
60
- var _a;
61
- if (cachedOperations === null) {
62
- const result = [];
63
- for (const source of siblings) {
64
- for (const definition of ((_a = source.document) === null || _a === void 0 ? void 0 : _a.definitions) || []) {
65
- if (definition.kind === Kind.OPERATION_DEFINITION) {
66
- result.push({
67
- filePath: source.location,
68
- document: definition,
69
- });
70
- }
71
- }
72
- }
73
- cachedOperations = result;
85
+ if (!collected.has(fragmentName)) {
86
+ collected.set(fragmentName, fragment.document);
87
+ if (recursive) {
88
+ collectFragments(fragment.document, recursive, collected);
89
+ }
74
90
  }
75
- return cachedOperations;
76
- };
77
- const getFragment = (name) => getFragments().filter(f => f.document.name.value === name);
78
- const collectFragments = (selectable, recursive, collected = new Map()) => {
79
- visit(selectable, {
80
- FragmentSpread(spread) {
81
- const fragmentName = spread.name.value;
82
- const [fragment] = getFragment(fragmentName);
83
- if (!fragment) {
84
- logger.warn(`Unable to locate fragment named "${fragmentName}", please make sure it's loaded using "parserOptions.operations"`);
85
- return;
86
- }
87
- if (!collected.has(fragmentName)) {
88
- collected.set(fragmentName, fragment.document);
89
- if (recursive) {
90
- collectFragments(fragment.document, recursive, collected);
91
- }
92
- }
93
- },
94
- });
95
- return collected;
96
- };
97
- const siblingOperations = {
98
- available: true,
99
- getFragment,
100
- getFragments,
101
- getFragmentByType: typeName => getFragments().filter(f => f.document.typeCondition.name.value === typeName),
102
- getFragmentsInUse: (selectable, recursive = true) => Array.from(collectFragments(selectable, recursive).values()),
103
- getOperation: name => getOperations().filter(o => { var _a; return ((_a = o.document.name) === null || _a === void 0 ? void 0 : _a.value) === name; }),
104
- getOperations,
105
- getOperationByType: type => getOperations().filter(o => o.document.operation === type),
106
- };
107
- siblingOperationsCache.set(siblings, siblingOperations);
108
- return siblingOperations;
91
+ }
92
+ });
93
+ return collected;
94
+ };
95
+ const siblingOperations = {
96
+ available: true,
97
+ getFragment,
98
+ getFragments,
99
+ getFragmentByType: (typeName) => getFragments().filter((f) => f.document.typeCondition.name.value === typeName),
100
+ getFragmentsInUse: (selectable, recursive = true) => Array.from(collectFragments(selectable, recursive).values()),
101
+ getOperation: (name) => getOperations().filter((o) => o.document.name?.value === name),
102
+ getOperations,
103
+ getOperationByType: (type) => getOperations().filter((o) => o.document.operation === type)
104
+ };
105
+ siblingOperationsCache.set(siblings, siblingOperations);
106
+ return siblingOperations;
109
107
  }
108
+ export {
109
+ getSiblings
110
+ };
@@ -0,0 +1,8 @@
1
+ import 'eslint';
2
+ import 'graphql';
3
+ import './estree-converter/types.mjs';
4
+ export { G as GraphQLESLintRuleListener, b as GraphQLInvalidTestCase, c as GraphQLRuleTester, a as GraphQLValidTestCase } from './types-2e1afd7c.js';
5
+ import 'estree';
6
+ import '@graphql-tools/utils';
7
+ import 'graphql-config';
8
+ import 'json-schema-to-ts';
package/esm/testkit.js CHANGED
@@ -1,160 +1,151 @@
1
1
  import { createRequire } from 'module';
2
2
  const require = createRequire(import.meta.url);
3
- import { readFileSync } from 'fs';
4
- import { resolve } from 'path';
5
- import { codeFrameColumns } from '@babel/code-frame';
6
- import { Linter, RuleTester } from 'eslint';
3
+ import { readFileSync } from "fs";
4
+ import { resolve } from "path";
5
+ import { codeFrameColumns } from "@babel/code-frame";
6
+ import { Linter, RuleTester } from "eslint";
7
7
  function indentCode(code, indent = 4) {
8
- return code.replace(/^/gm, ' '.repeat(indent));
8
+ return code.replace(/^/gm, " ".repeat(indent));
9
9
  }
10
- // A simple version of `SourceCodeFixer.applyFixes`
11
- // https://github.com/eslint/eslint/issues/14936#issuecomment-906746754
12
10
  function applyFix(code, { range, text }) {
13
- return [code.slice(0, range[0]), text, code.slice(range[1])].join('');
11
+ return [code.slice(0, range[0]), text, code.slice(range[1])].join("");
14
12
  }
15
- export class GraphQLRuleTester extends RuleTester {
16
- constructor(parserOptions = {}) {
17
- const config = {
18
- parser: require.resolve('@graphql-eslint/eslint-plugin'),
19
- parserOptions: {
20
- ...parserOptions,
21
- skipGraphQLConfig: true,
22
- },
23
- };
24
- super(config);
25
- this.config = config;
26
- }
27
- fromMockFile(path) {
28
- return readFileSync(resolve(__dirname, `../tests/mocks/${path}`), 'utf-8');
29
- }
30
- runGraphQLTests(ruleId, rule, tests) {
31
- super.run(ruleId, rule, tests);
32
- const linter = new Linter();
33
- linter.defineRule(ruleId, rule);
34
- const hasOnlyTest = [...tests.valid, ...tests.invalid].some(t => typeof t !== 'string' && t.only);
35
- // for (const [index, testCase] of tests.valid.entries()) {
36
- // const { name, code, filename, only }: RuleTester.ValidTestCase =
37
- // typeof testCase === 'string' ? { code: testCase } : testCase;
38
- //
39
- // if (hasOnlyTest && !only) {
40
- // continue;
41
- // }
42
- //
43
- // const verifyConfig = getVerifyConfig<Options>(ruleId, this.config, testCase);
44
- // defineParser(linter, verifyConfig.parser);
45
- //
46
- // const messages = linter.verify(code, verifyConfig, { filename });
47
- // const codeFrame = printCode(code, { line: 0, column: 0 });
48
- //
49
- // it(name || `Valid #${index + 1}\n${codeFrame}`, () => {
50
- // expect(messages).toEqual([]);
51
- // });
52
- // }
53
- for (const [idx, testCase] of tests.invalid.entries()) {
54
- const { only, filename, options, name } = testCase;
55
- if (hasOnlyTest && !only) {
56
- continue;
57
- }
58
- const code = removeTrailingBlankLines(testCase.code);
59
- const verifyConfig = getVerifyConfig(ruleId, this.config, testCase);
60
- defineParser(linter, verifyConfig.parser);
61
- const messages = linter.verify(code, verifyConfig, filename);
62
- if (messages.length === 0) {
63
- throw new Error('Invalid case should have at least one error.');
64
- }
65
- const codeFrame = indentCode(printCode(code, { line: 0, column: 0 }));
66
- const messageForSnapshot = ['#### ⌨️ Code', codeFrame];
67
- if (options) {
68
- const opts = JSON.stringify(options, null, 2).slice(1, -1);
69
- messageForSnapshot.push('#### ⚙️ Options', indentCode(removeTrailingBlankLines(opts), 2));
70
- }
71
- for (const [index, message] of messages.entries()) {
72
- if (message.fatal) {
73
- throw new Error(message.message);
74
- }
75
- const codeWithMessage = printCode(code, message, 1);
76
- messageForSnapshot.push(printWithIndex('#### ❌ Error', index, messages.length), indentCode(codeWithMessage));
77
- // Don't print suggestions in snapshots for too big codes
78
- if (message.suggestions && (code.match(/\n/g) || '').length < 1000) {
79
- for (const [i, suggestion] of message.suggestions.entries()) {
80
- const title = printWithIndex('#### 💡 Suggestion', i, message.suggestions.length, suggestion.desc);
81
- const output = applyFix(code, suggestion.fix);
82
- const codeFrame = printCode(output, { line: 0, column: 0 });
83
- messageForSnapshot.push(title, indentCode(codeFrame, 2));
84
- }
85
- }
86
- }
87
- if (rule.meta.fixable) {
88
- const { fixed, output } = linter.verifyAndFix(code, verifyConfig, filename);
89
- if (fixed) {
90
- messageForSnapshot.push('#### 🔧 Autofix output', indentCode(printCode(output)));
91
- }
92
- }
93
- it(name || `Invalid #${idx + 1}`, () => {
94
- expect(messageForSnapshot.join('\n\n')).toMatchSnapshot();
95
- });
13
+ class GraphQLRuleTester extends RuleTester {
14
+ constructor(parserOptions = {}) {
15
+ const config = {
16
+ parser: require.resolve("@graphql-eslint/eslint-plugin"),
17
+ parserOptions: {
18
+ ...parserOptions,
19
+ skipGraphQLConfig: true
20
+ }
21
+ };
22
+ super(config);
23
+ this.config = config;
24
+ }
25
+ fromMockFile(path) {
26
+ return readFileSync(resolve(__dirname, `../tests/mocks/${path}`), "utf-8");
27
+ }
28
+ runGraphQLTests(ruleId, rule, tests) {
29
+ super.run(ruleId, rule, tests);
30
+ const linter = new Linter();
31
+ linter.defineRule(ruleId, rule);
32
+ const hasOnlyTest = [...tests.valid, ...tests.invalid].some(
33
+ (t) => typeof t !== "string" && t.only
34
+ );
35
+ for (const [idx, testCase] of tests.invalid.entries()) {
36
+ const { only, filename, options, name } = testCase;
37
+ if (hasOnlyTest && !only) {
38
+ continue;
39
+ }
40
+ const code = removeTrailingBlankLines(testCase.code);
41
+ const verifyConfig = getVerifyConfig(ruleId, this.config, testCase);
42
+ defineParser(linter, verifyConfig.parser);
43
+ const messages = linter.verify(code, verifyConfig, filename);
44
+ if (messages.length === 0) {
45
+ throw new Error("Invalid case should have at least one error.");
46
+ }
47
+ const codeFrame = indentCode(printCode(code, { line: 0, column: 0 }));
48
+ const messageForSnapshot = ["#### \u2328\uFE0F Code", codeFrame];
49
+ if (options) {
50
+ const opts = JSON.stringify(options, null, 2).slice(1, -1);
51
+ messageForSnapshot.push("#### \u2699\uFE0F Options", indentCode(removeTrailingBlankLines(opts), 2));
52
+ }
53
+ for (const [index, message] of messages.entries()) {
54
+ if (message.fatal) {
55
+ throw new Error(message.message);
56
+ }
57
+ const codeWithMessage = printCode(code, message, 1);
58
+ messageForSnapshot.push(
59
+ printWithIndex("#### \u274C Error", index, messages.length),
60
+ indentCode(codeWithMessage)
61
+ );
62
+ if (message.suggestions && (code.match(/\n/g) || "").length < 1e3) {
63
+ for (const [i, suggestion] of message.suggestions.entries()) {
64
+ const title = printWithIndex(
65
+ "#### \u{1F4A1} Suggestion",
66
+ i,
67
+ message.suggestions.length,
68
+ suggestion.desc
69
+ );
70
+ const output = applyFix(code, suggestion.fix);
71
+ const codeFrame2 = printCode(output, { line: 0, column: 0 });
72
+ messageForSnapshot.push(title, indentCode(codeFrame2, 2));
73
+ }
96
74
  }
75
+ }
76
+ if (rule.meta.fixable) {
77
+ const { fixed, output } = linter.verifyAndFix(code, verifyConfig, filename);
78
+ if (fixed) {
79
+ messageForSnapshot.push("#### \u{1F527} Autofix output", indentCode(printCode(output)));
80
+ }
81
+ }
82
+ it(name || `Invalid #${idx + 1}`, () => {
83
+ expect(messageForSnapshot.join("\n\n")).toMatchSnapshot();
84
+ });
97
85
  }
86
+ }
98
87
  }
99
88
  function removeTrailingBlankLines(text) {
100
- return text.replace(/^\s*\n/, '').trimEnd();
89
+ return text.replace(/^\s*\n/, "").trimEnd();
101
90
  }
102
91
  function printWithIndex(title, index, total, description) {
103
- if (total > 1) {
104
- title += ` ${index + 1}/${total}`;
105
- }
106
- if (description) {
107
- title += `: ${description}`;
108
- }
109
- return title;
92
+ if (total > 1) {
93
+ title += ` ${index + 1}/${total}`;
94
+ }
95
+ if (description) {
96
+ title += `: ${description}`;
97
+ }
98
+ return title;
110
99
  }
111
100
  function getVerifyConfig(ruleId, testerConfig, testCase) {
112
- const { parser = testerConfig.parser, parserOptions, options } = testCase;
113
- return {
114
- ...testerConfig,
115
- parser,
116
- parserOptions: {
117
- ...testerConfig.parserOptions,
118
- ...parserOptions,
119
- },
120
- rules: {
121
- [ruleId]: Array.isArray(options) ? ['error', ...options] : 'error',
122
- },
123
- };
101
+ const { parser = testerConfig.parser, parserOptions, options } = testCase;
102
+ return {
103
+ ...testerConfig,
104
+ parser,
105
+ parserOptions: {
106
+ ...testerConfig.parserOptions,
107
+ ...parserOptions
108
+ },
109
+ rules: {
110
+ [ruleId]: Array.isArray(options) ? ["error", ...options] : "error"
111
+ }
112
+ };
124
113
  }
125
- const parsers = new WeakMap();
114
+ const parsers = /* @__PURE__ */ new WeakMap();
126
115
  function defineParser(linter, parser) {
127
- if (!parser) {
128
- return;
129
- }
130
- if (!parsers.has(linter)) {
131
- parsers.set(linter, new Set());
132
- }
133
- const defined = parsers.get(linter);
134
- if (!defined.has(parser)) {
135
- defined.add(parser);
136
- // eslint-disable-next-line @typescript-eslint/no-var-requires
137
- linter.defineParser(parser, require(parser));
138
- }
116
+ if (!parser) {
117
+ return;
118
+ }
119
+ if (!parsers.has(linter)) {
120
+ parsers.set(linter, /* @__PURE__ */ new Set());
121
+ }
122
+ const defined = parsers.get(linter);
123
+ if (!defined.has(parser)) {
124
+ defined.add(parser);
125
+ linter.defineParser(parser, require(parser));
126
+ }
139
127
  }
140
128
  function printCode(code, result = {}, linesOffset = Number.POSITIVE_INFINITY) {
141
- const { line, column, endLine, endColumn, message } = result;
142
- const location = {};
143
- if (typeof line === 'number' && typeof column === 'number') {
144
- location.start = {
145
- line,
146
- column,
147
- };
148
- }
149
- if (typeof endLine === 'number' && typeof endColumn === 'number') {
150
- location.end = {
151
- line: endLine,
152
- column: endColumn,
153
- };
154
- }
155
- return codeFrameColumns(code, location, {
156
- linesAbove: linesOffset,
157
- linesBelow: linesOffset,
158
- message,
159
- });
129
+ const { line, column, endLine, endColumn, message } = result;
130
+ const location = {};
131
+ if (typeof line === "number" && typeof column === "number") {
132
+ location.start = {
133
+ line,
134
+ column
135
+ };
136
+ }
137
+ if (typeof endLine === "number" && typeof endColumn === "number") {
138
+ location.end = {
139
+ line: endLine,
140
+ column: endColumn
141
+ };
142
+ }
143
+ return codeFrameColumns(code, location, {
144
+ linesAbove: linesOffset,
145
+ linesBelow: linesOffset,
146
+ message
147
+ });
160
148
  }
149
+ export {
150
+ GraphQLRuleTester
151
+ };
@@ -0,0 +1,129 @@
1
+ import { GraphQLParseOptions } from '@graphql-tools/utils';
2
+ import { RuleTester, Linter, Rule, AST } from 'eslint';
3
+ import * as ESTree from 'estree';
4
+ import { FragmentDefinitionNode, OperationDefinitionNode, SelectionSetNode, OperationTypeNode, ASTKindToNode, GraphQLSchema } from 'graphql';
5
+ import { GraphQLProjectConfig, IExtensions, IGraphQLProject } from 'graphql-config';
6
+ import { JSONSchema } from 'json-schema-to-ts';
7
+ import { GraphQLESTreeNode } from './estree-converter/types.mjs';
8
+
9
+ type FragmentSource = {
10
+ filePath: string;
11
+ document: FragmentDefinitionNode;
12
+ };
13
+ type OperationSource = {
14
+ filePath: string;
15
+ document: OperationDefinitionNode;
16
+ };
17
+ type SiblingOperations = {
18
+ available: boolean;
19
+ getFragment(fragmentName: string): FragmentSource[];
20
+ getFragments(): FragmentSource[];
21
+ getFragmentByType(typeName: string): FragmentSource[];
22
+ getFragmentsInUse(baseOperation: FragmentDefinitionNode | OperationDefinitionNode | SelectionSetNode, recursive?: boolean): FragmentDefinitionNode[];
23
+ getOperation(operationName: string): OperationSource[];
24
+ getOperations(): OperationSource[];
25
+ getOperationByType(operationType: OperationTypeNode): OperationSource[];
26
+ };
27
+ declare function getSiblings(project?: GraphQLProjectConfig, documents?: ParserOptions['documents']): SiblingOperations;
28
+
29
+ type GraphQLESLintRuleListener<WithTypeInfo extends boolean = false> = Record<string, any> & {
30
+ [K in keyof ASTKindToNode]?: (node: GraphQLESTreeNode<ASTKindToNode[K], WithTypeInfo>) => void;
31
+ };
32
+ type GraphQLValidTestCase<Options = []> = Omit<RuleTester.ValidTestCase, 'options' | 'parserOptions'> & {
33
+ options?: Options;
34
+ parserOptions?: Omit<ParserOptions, 'filePath'>;
35
+ };
36
+ type GraphQLInvalidTestCase<T = []> = GraphQLValidTestCase<T> & {
37
+ errors: (RuleTester.TestCaseError | string)[] | number;
38
+ output?: string | null;
39
+ };
40
+ type RuleTesterConfig = {
41
+ parser: string;
42
+ parserOptions: Omit<ParserOptions, 'filePath'>;
43
+ };
44
+ declare class GraphQLRuleTester extends RuleTester {
45
+ config: RuleTesterConfig;
46
+ constructor(parserOptions?: Omit<ParserOptions, 'filePath'>);
47
+ fromMockFile(path: string): string;
48
+ runGraphQLTests<Options, WithTypeInfo extends boolean = false>(ruleId: string, rule: GraphQLESLintRule<Options, WithTypeInfo>, tests: {
49
+ valid: (GraphQLValidTestCase<Options> | string)[];
50
+ invalid: GraphQLInvalidTestCase<Options>[];
51
+ }): void;
52
+ }
53
+
54
+ type Schema = GraphQLSchema | null;
55
+ type Pointer = string | string[];
56
+ interface ParserOptions {
57
+ schema?: Pointer | Record<string, {
58
+ headers: Record<string, string>;
59
+ }>;
60
+ documents?: Pointer;
61
+ extensions?: IExtensions;
62
+ include?: Pointer;
63
+ exclude?: Pointer;
64
+ projects?: Record<string, IGraphQLProject>;
65
+ schemaOptions?: Omit<GraphQLParseOptions, 'assumeValidSDL'> & {
66
+ headers: Record<string, string>;
67
+ };
68
+ graphQLParserOptions?: Omit<GraphQLParseOptions, 'noLocation'>;
69
+ skipGraphQLConfig?: boolean;
70
+ filePath: string;
71
+ /** @deprecated Use `documents` instead */
72
+ operations?: Pointer;
73
+ }
74
+ type ParserServices = {
75
+ schema: Schema;
76
+ siblingOperations: SiblingOperations;
77
+ };
78
+ type GraphQLESLintParseResult = Linter.ESLintParseResult & {
79
+ services: ParserServices;
80
+ };
81
+ type Location = AST.SourceLocation | ESTree.Position;
82
+ type ReportDescriptorLocation = {
83
+ loc: Location;
84
+ } | {
85
+ node: {
86
+ loc: Location;
87
+ };
88
+ };
89
+ type ReportDescriptor = ReportDescriptorLocation & Rule.ReportDescriptorMessage & Rule.ReportDescriptorOptions;
90
+ type GraphQLESLintRuleContext<Options = any[]> = Omit<Rule.RuleContext, 'options' | 'parserServices' | 'report'> & {
91
+ options: Options;
92
+ parserServices: ParserServices;
93
+ report(descriptor: ReportDescriptor): void;
94
+ };
95
+ type CategoryType = 'Operations' | 'Schema';
96
+ type RuleMetaDataDocs = Required<Rule.RuleMetaData>['docs'];
97
+ type RuleDocsInfo<T> = Omit<RuleMetaDataDocs, 'category' | 'suggestion'> & {
98
+ category: CategoryType | CategoryType[];
99
+ requiresSchema?: true;
100
+ requiresSiblings?: true;
101
+ examples?: {
102
+ title: string;
103
+ code: string;
104
+ usage?: T;
105
+ }[];
106
+ configOptions?: T | {
107
+ schema?: T;
108
+ operations?: T;
109
+ };
110
+ graphQLJSRuleName?: string;
111
+ isDisabledForAllConfig?: true;
112
+ };
113
+ type GraphQLESLintRule<Options = [], WithTypeInfo extends boolean = false> = {
114
+ meta: Omit<Rule.RuleMetaData, 'docs' | 'schema'> & {
115
+ docs?: RuleDocsInfo<Options>;
116
+ schema: Readonly<JSONSchema> | [];
117
+ };
118
+ create(context: GraphQLESLintRuleContext<Options>): GraphQLESLintRuleListener<WithTypeInfo>;
119
+ };
120
+ type ValueOf<T> = T[keyof T];
121
+ type Id<T> = {
122
+ [P in keyof T]: T[P];
123
+ } & {};
124
+ type OmitDistributive<T, K extends PropertyKey> = T extends object ? Id<OmitRecursively<T, K>> : T;
125
+ type OmitRecursively<T extends object, K extends PropertyKey> = Omit<{
126
+ [P in keyof T]: OmitDistributive<T[P], K>;
127
+ }, K>;
128
+
129
+ export { CategoryType as C, FragmentSource as F, GraphQLESLintRuleListener as G, OmitRecursively as O, ParserOptions as P, ReportDescriptor as R, Schema as S, ValueOf as V, GraphQLValidTestCase as a, GraphQLInvalidTestCase as b, GraphQLRuleTester as c, Pointer as d, ParserServices as e, GraphQLESLintParseResult as f, GraphQLESLintRuleContext as g, RuleDocsInfo as h, GraphQLESLintRule as i, SiblingOperations as j, OperationSource as k, getSiblings as l };