@graphql-eslint/eslint-plugin 3.14.0-alpha-20221221142641-4e1a924 → 3.14.0-alpha-20221222012949-5caade4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (231) hide show
  1. package/README.md +309 -0
  2. package/cjs/cache.js +30 -0
  3. package/cjs/configs/base.js +7 -0
  4. package/cjs/configs/index.js +16 -0
  5. package/cjs/configs/operations-all.js +31 -0
  6. package/cjs/configs/operations-recommended.js +56 -0
  7. package/cjs/configs/relay.js +12 -0
  8. package/cjs/configs/schema-all.js +23 -0
  9. package/cjs/configs/schema-recommended.js +52 -0
  10. package/cjs/documents.js +149 -0
  11. package/cjs/estree-converter/converter.js +62 -0
  12. package/cjs/estree-converter/index.js +6 -0
  13. package/cjs/estree-converter/types.js +2 -0
  14. package/cjs/estree-converter/utils.js +109 -0
  15. package/cjs/graphql-config.js +55 -0
  16. package/cjs/index.js +17 -0
  17. package/cjs/parser.js +61 -0
  18. package/cjs/processor.js +78 -0
  19. package/cjs/rules/alphabetize.js +348 -0
  20. package/cjs/rules/description-style.js +78 -0
  21. package/cjs/rules/graphql-js-validation.js +499 -0
  22. package/cjs/rules/index.js +68 -0
  23. package/cjs/rules/input-name.js +136 -0
  24. package/cjs/rules/lone-executable-definition.js +88 -0
  25. package/cjs/rules/match-document-filename.js +235 -0
  26. package/cjs/rules/naming-convention.js +310 -0
  27. package/cjs/rules/no-anonymous-operations.js +67 -0
  28. package/cjs/rules/no-case-insensitive-enum-values-duplicates.js +61 -0
  29. package/cjs/rules/no-deprecated.js +124 -0
  30. package/cjs/rules/no-duplicate-fields.js +112 -0
  31. package/cjs/rules/no-hashtag-description.js +89 -0
  32. package/cjs/rules/no-root-type.js +86 -0
  33. package/cjs/rules/no-scalar-result-type-on-mutation.js +66 -0
  34. package/cjs/rules/no-typename-prefix.js +65 -0
  35. package/cjs/rules/no-unreachable-types.js +158 -0
  36. package/cjs/rules/no-unused-fields.js +130 -0
  37. package/cjs/rules/relay-arguments.js +121 -0
  38. package/cjs/rules/relay-connection-types.js +107 -0
  39. package/cjs/rules/relay-edge-types.js +189 -0
  40. package/cjs/rules/relay-page-info.js +100 -0
  41. package/cjs/rules/require-deprecation-date.js +123 -0
  42. package/cjs/rules/require-deprecation-reason.js +56 -0
  43. package/cjs/rules/require-description.js +193 -0
  44. package/cjs/rules/require-field-of-type-query-in-mutation-result.js +72 -0
  45. package/cjs/rules/require-id-when-available.js +199 -0
  46. package/cjs/rules/selection-set-depth.js +135 -0
  47. package/cjs/rules/strict-id-in-types.js +162 -0
  48. package/cjs/rules/unique-fragment-name.js +90 -0
  49. package/cjs/rules/unique-operation-name.js +65 -0
  50. package/cjs/schema.js +42 -0
  51. package/cjs/testkit.js +183 -0
  52. package/cjs/types.js +2 -0
  53. package/cjs/utils.js +96 -0
  54. package/docs/README.md +82 -0
  55. package/docs/custom-rules.md +184 -0
  56. package/docs/deprecated-rules.md +24 -0
  57. package/docs/parser-options.md +95 -0
  58. package/docs/parser.md +67 -0
  59. package/docs/rules/alphabetize.md +194 -0
  60. package/docs/rules/description-style.md +57 -0
  61. package/docs/rules/executable-definitions.md +20 -0
  62. package/docs/rules/fields-on-correct-type.md +23 -0
  63. package/docs/rules/fragments-on-composite-type.md +20 -0
  64. package/docs/rules/input-name.md +80 -0
  65. package/docs/rules/known-argument-names.md +23 -0
  66. package/docs/rules/known-directives.md +48 -0
  67. package/docs/rules/known-fragment-names.md +72 -0
  68. package/docs/rules/known-type-names.md +24 -0
  69. package/docs/rules/lone-anonymous-operation.md +20 -0
  70. package/docs/rules/lone-executable-definition.md +59 -0
  71. package/docs/rules/lone-schema-definition.md +19 -0
  72. package/docs/rules/match-document-filename.md +181 -0
  73. package/docs/rules/naming-convention.md +320 -0
  74. package/docs/rules/no-anonymous-operations.md +43 -0
  75. package/docs/rules/no-case-insensitive-enum-values-duplicates.md +46 -0
  76. package/docs/rules/no-deprecated.md +88 -0
  77. package/docs/rules/no-duplicate-fields.md +69 -0
  78. package/docs/rules/no-fragment-cycles.md +19 -0
  79. package/docs/rules/no-hashtag-description.md +62 -0
  80. package/docs/rules/no-root-type.md +55 -0
  81. package/docs/rules/no-scalar-result-type-on-mutation.md +39 -0
  82. package/docs/rules/no-typename-prefix.md +42 -0
  83. package/docs/rules/no-undefined-variables.md +20 -0
  84. package/docs/rules/no-unreachable-types.md +52 -0
  85. package/docs/rules/no-unused-fields.md +64 -0
  86. package/docs/rules/no-unused-fragments.md +20 -0
  87. package/docs/rules/no-unused-variables.md +20 -0
  88. package/docs/rules/one-field-subscriptions.md +19 -0
  89. package/docs/rules/overlapping-fields-can-be-merged.md +20 -0
  90. package/docs/rules/possible-fragment-spread.md +21 -0
  91. package/docs/rules/possible-type-extension.md +19 -0
  92. package/docs/rules/provided-required-arguments.md +21 -0
  93. package/docs/rules/relay-arguments.md +59 -0
  94. package/docs/rules/relay-connection-types.md +43 -0
  95. package/docs/rules/relay-edge-types.md +60 -0
  96. package/docs/rules/relay-page-info.md +34 -0
  97. package/docs/rules/require-deprecation-date.md +59 -0
  98. package/docs/rules/require-deprecation-reason.md +49 -0
  99. package/docs/rules/require-description.md +147 -0
  100. package/docs/rules/require-field-of-type-query-in-mutation-result.md +50 -0
  101. package/docs/rules/require-id-when-available.md +91 -0
  102. package/docs/rules/scalar-leafs.md +23 -0
  103. package/docs/rules/selection-set-depth.md +86 -0
  104. package/docs/rules/strict-id-in-types.md +129 -0
  105. package/docs/rules/unique-argument-names.md +19 -0
  106. package/docs/rules/unique-directive-names-per-location.md +21 -0
  107. package/docs/rules/unique-directive-names.md +19 -0
  108. package/docs/rules/unique-enum-value-names.md +16 -0
  109. package/docs/rules/unique-field-definition-names.md +19 -0
  110. package/docs/rules/unique-fragment-name.md +52 -0
  111. package/docs/rules/unique-input-field-names.md +19 -0
  112. package/docs/rules/unique-operation-name.md +56 -0
  113. package/docs/rules/unique-operation-types.md +19 -0
  114. package/docs/rules/unique-type-names.md +19 -0
  115. package/docs/rules/unique-variable-names.md +19 -0
  116. package/docs/rules/value-literals-of-correct-type.md +22 -0
  117. package/docs/rules/variables-are-input-types.md +20 -0
  118. package/docs/rules/variables-in-allowed-position.md +19 -0
  119. package/package.json +8 -11
  120. package/{cache.d.ts → typings/cache.d.cts} +0 -0
  121. package/typings/cache.d.ts +10 -0
  122. package/typings/configs/base.d.cts +5 -0
  123. package/typings/configs/base.d.ts +5 -0
  124. package/typings/configs/index.d.cts +139 -0
  125. package/typings/configs/index.d.ts +139 -0
  126. package/typings/configs/operations-all.d.cts +20 -0
  127. package/typings/configs/operations-all.d.ts +20 -0
  128. package/typings/configs/operations-recommended.d.cts +50 -0
  129. package/typings/configs/operations-recommended.d.ts +50 -0
  130. package/typings/configs/relay.d.cts +10 -0
  131. package/typings/configs/relay.d.ts +10 -0
  132. package/typings/configs/schema-all.d.cts +15 -0
  133. package/typings/configs/schema-all.d.ts +15 -0
  134. package/typings/configs/schema-recommended.d.cts +47 -0
  135. package/typings/configs/schema-recommended.d.ts +47 -0
  136. package/{documents.d.ts → typings/documents.d.cts} +0 -0
  137. package/typings/documents.d.ts +21 -0
  138. package/{estree-converter/converter.d.ts → typings/estree-converter/converter.d.cts} +0 -0
  139. package/typings/estree-converter/converter.d.ts +3 -0
  140. package/{estree-converter/index.d.ts → typings/estree-converter/index.d.cts} +0 -0
  141. package/typings/estree-converter/index.d.ts +3 -0
  142. package/{estree-converter/types.d.ts → typings/estree-converter/types.d.cts} +0 -0
  143. package/typings/estree-converter/types.d.ts +40 -0
  144. package/{estree-converter/utils.d.ts → typings/estree-converter/utils.d.cts} +0 -0
  145. package/typings/estree-converter/utils.d.ts +13 -0
  146. package/{graphql-config.d.ts → typings/graphql-config.d.cts} +0 -0
  147. package/typings/graphql-config.d.ts +4 -0
  148. package/typings/index.d.cts +9 -0
  149. package/{index.d.ts → typings/index.d.ts} +1 -5
  150. package/{parser.d.ts → typings/parser.d.cts} +0 -0
  151. package/typings/parser.d.ts +2 -0
  152. package/{processor.d.ts → typings/processor.d.cts} +0 -0
  153. package/typings/processor.d.ts +6 -0
  154. package/{rules/alphabetize.d.ts → typings/rules/alphabetize.d.cts} +0 -0
  155. package/typings/rules/alphabetize.d.ts +76 -0
  156. package/{rules/description-style.d.ts → typings/rules/description-style.d.cts} +0 -0
  157. package/typings/rules/description-style.d.ts +20 -0
  158. package/{rules/graphql-js-validation.d.ts → typings/rules/graphql-js-validation.d.cts} +0 -0
  159. package/typings/rules/graphql-js-validation.d.ts +2 -0
  160. package/{rules/index.d.ts → typings/rules/index.d.cts} +0 -0
  161. package/typings/rules/index.d.ts +104 -0
  162. package/{rules/input-name.d.ts → typings/rules/input-name.d.cts} +0 -0
  163. package/typings/rules/input-name.d.ts +35 -0
  164. package/{rules/lone-executable-definition.d.ts → typings/rules/lone-executable-definition.d.cts} +0 -0
  165. package/typings/rules/lone-executable-definition.d.ts +26 -0
  166. package/{rules/match-document-filename.d.ts → typings/rules/match-document-filename.d.cts} +0 -0
  167. package/typings/rules/match-document-filename.d.ts +72 -0
  168. package/{rules/naming-convention.d.ts → typings/rules/naming-convention.d.cts} +0 -0
  169. package/typings/rules/naming-convention.d.ts +83 -0
  170. package/{rules/no-anonymous-operations.d.ts → typings/rules/no-anonymous-operations.d.cts} +0 -0
  171. package/{rules/no-case-insensitive-enum-values-duplicates.d.ts → typings/rules/no-anonymous-operations.d.ts} +0 -0
  172. package/{rules/no-hashtag-description.d.ts → typings/rules/no-case-insensitive-enum-values-duplicates.d.cts} +0 -0
  173. package/{rules/no-scalar-result-type-on-mutation.d.ts → typings/rules/no-case-insensitive-enum-values-duplicates.d.ts} +0 -0
  174. package/{rules/no-deprecated.d.ts → typings/rules/no-deprecated.d.cts} +0 -0
  175. package/typings/rules/no-deprecated.d.ts +2 -0
  176. package/{rules/no-duplicate-fields.d.ts → typings/rules/no-duplicate-fields.d.cts} +0 -0
  177. package/{rules/relay-page-info.d.ts → typings/rules/no-duplicate-fields.d.ts} +0 -0
  178. package/{rules/no-typename-prefix.d.ts → typings/rules/no-hashtag-description.d.cts} +0 -0
  179. package/{rules/no-unreachable-types.d.ts → typings/rules/no-hashtag-description.d.ts} +0 -0
  180. package/{rules/no-root-type.d.ts → typings/rules/no-root-type.d.cts} +0 -0
  181. package/typings/rules/no-root-type.d.ts +25 -0
  182. package/{rules/no-unused-fields.d.ts → typings/rules/no-scalar-result-type-on-mutation.d.cts} +0 -0
  183. package/{rules/unique-operation-name.d.ts → typings/rules/no-scalar-result-type-on-mutation.d.ts} +0 -0
  184. package/typings/rules/no-typename-prefix.d.cts +2 -0
  185. package/typings/rules/no-typename-prefix.d.ts +2 -0
  186. package/typings/rules/no-unreachable-types.d.cts +2 -0
  187. package/typings/rules/no-unreachable-types.d.ts +2 -0
  188. package/typings/rules/no-unused-fields.d.cts +2 -0
  189. package/typings/rules/no-unused-fields.d.ts +2 -0
  190. package/{rules/relay-arguments.d.ts → typings/rules/relay-arguments.d.cts} +0 -0
  191. package/typings/rules/relay-arguments.d.ts +21 -0
  192. package/{rules/relay-connection-types.d.ts → typings/rules/relay-connection-types.d.cts} +0 -0
  193. package/typings/rules/relay-connection-types.d.ts +4 -0
  194. package/{rules/relay-edge-types.d.ts → typings/rules/relay-edge-types.d.cts} +0 -0
  195. package/typings/rules/relay-edge-types.d.ts +31 -0
  196. package/{rules/require-deprecation-reason.d.ts → typings/rules/relay-page-info.d.cts} +0 -0
  197. package/{rules/require-field-of-type-query-in-mutation-result.d.ts → typings/rules/relay-page-info.d.ts} +0 -0
  198. package/{rules/require-deprecation-date.d.ts → typings/rules/require-deprecation-date.d.cts} +0 -0
  199. package/typings/rules/require-deprecation-date.d.ts +18 -0
  200. package/typings/rules/require-deprecation-reason.d.cts +2 -0
  201. package/typings/rules/require-deprecation-reason.d.ts +2 -0
  202. package/{rules/require-description.d.ts → typings/rules/require-description.d.cts} +0 -0
  203. package/typings/rules/require-description.d.ts +14 -0
  204. package/typings/rules/require-field-of-type-query-in-mutation-result.d.cts +2 -0
  205. package/typings/rules/require-field-of-type-query-in-mutation-result.d.ts +2 -0
  206. package/{rules/require-id-when-available.d.ts → typings/rules/require-id-when-available.d.cts} +0 -0
  207. package/typings/rules/require-id-when-available.d.ts +36 -0
  208. package/{rules/selection-set-depth.d.ts → typings/rules/selection-set-depth.d.cts} +0 -0
  209. package/typings/rules/selection-set-depth.d.ts +28 -0
  210. package/{rules/strict-id-in-types.d.ts → typings/rules/strict-id-in-types.d.cts} +0 -0
  211. package/typings/rules/strict-id-in-types.d.ts +57 -0
  212. package/{rules/unique-fragment-name.d.ts → typings/rules/unique-fragment-name.d.cts} +0 -0
  213. package/typings/rules/unique-fragment-name.d.ts +5 -0
  214. package/typings/rules/unique-operation-name.d.cts +2 -0
  215. package/typings/rules/unique-operation-name.d.ts +2 -0
  216. package/{schema.d.ts → typings/schema.d.cts} +0 -0
  217. package/typings/schema.d.ts +3 -0
  218. package/{testkit.d.ts → typings/testkit.d.cts} +0 -0
  219. package/typings/testkit.d.ts +27 -0
  220. package/{types.d.ts → typings/types.d.cts} +0 -0
  221. package/typings/types.d.ts +81 -0
  222. package/{utils.d.ts → typings/utils.d.cts} +0 -0
  223. package/typings/utils.d.ts +34 -0
  224. package/configs/base.json +0 -4
  225. package/configs/operations-all.json +0 -25
  226. package/configs/operations-recommended.json +0 -50
  227. package/configs/relay.json +0 -9
  228. package/configs/schema-all.json +0 -17
  229. package/configs/schema-recommended.json +0 -49
  230. package/index.js +0 -4995
  231. package/index.mjs +0 -4983
package/docs/README.md ADDED
@@ -0,0 +1,82 @@
1
+ # Available Rules
2
+
3
+ Each rule has emojis denoting:
4
+
5
+ - 📄 if the rule applies to schema documents
6
+ - 📦 if the rule applies to operations
7
+ - 🚀 `graphql-eslint` rule
8
+ - 🔮 `graphql-js` rule
9
+ - 🔧 if some problems reported by the rule are automatically fixable by the `--fix`
10
+ [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) option
11
+ - 💡 if some problems reported by the rule are manually fixable by editor
12
+ [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions)
13
+
14
+ <!-- 🚨 IMPORTANT! Do not manually modify this table. Run: `yarn generate:docs` -->
15
+ <!-- prettier-ignore-start -->
16
+ Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|Description|&nbsp;&nbsp;&nbsp;&nbsp;Config&nbsp;&nbsp;&nbsp;&nbsp;|📄&nbsp;/&nbsp;📦|🚀&nbsp;/&nbsp;🔮|🔧&nbsp;/&nbsp;💡
17
+ -|-|:-:|:-:|:-:|:-:
18
+ [alphabetize](rules/alphabetize.md)|Enforce arrange in alphabetical order for type fields, enum values, input object fields, operation selections and more.|![all][]|📄 📦|🚀|🔧
19
+ [description-style](rules/description-style.md)|Require all comments to follow the same style (either block or inline).|![recommended][]|📄|🚀|💡
20
+ [executable-definitions](rules/executable-definitions.md)|A GraphQL document is only valid for execution if all definitions are either operation or fragment definitions.|![recommended][]|📦|🔮|
21
+ [fields-on-correct-type](rules/fields-on-correct-type.md)|A GraphQL document is only valid if all fields selected are defined by the parent type, or are an allowed meta field such as `__typename`.|![recommended][]|📦|🔮|💡
22
+ [fragments-on-composite-type](rules/fragments-on-composite-type.md)|Fragments use a type condition to determine if they apply, since fragments can only be spread into a composite type (object, interface, or union), the type condition must also be a composite type.|![recommended][]|📦|🔮|
23
+ [input-name](rules/input-name.md)|Require mutation argument to be always called "input" and input type to be called Mutation name + "Input".|![all][]|📄|🚀|💡
24
+ [known-argument-names](rules/known-argument-names.md)|A GraphQL field is only valid if all supplied arguments are defined by that field.|![recommended][]|📄 📦|🔮|💡
25
+ [known-directives](rules/known-directives.md)|A GraphQL document is only valid if all `@directive`s are known by the schema and legally positioned.|![recommended][]|📄 📦|🔮|
26
+ [known-fragment-names](rules/known-fragment-names.md)|A GraphQL document is only valid if all `...Fragment` fragment spreads refer to fragments defined in the same document.|![recommended][]|📦|🔮|
27
+ [known-type-names](rules/known-type-names.md)|A GraphQL document is only valid if referenced types (specifically variable definitions and fragment conditions) are defined by the type schema.|![recommended][]|📄 📦|🔮|💡
28
+ [lone-anonymous-operation](rules/lone-anonymous-operation.md)|A GraphQL document that contains an anonymous operation (the `query` short-hand) is only valid if it contains only that one operation definition.|![recommended][]|📦|🔮|
29
+ [lone-executable-definition](rules/lone-executable-definition.md)|Require all queries, mutations, subscriptions and fragments to be located in separate files.|![all][]|📦|🚀|
30
+ [lone-schema-definition](rules/lone-schema-definition.md)|A GraphQL document is only valid if it contains only one schema definition.|![recommended][]|📄|🔮|
31
+ [match-document-filename](rules/match-document-filename.md)|This rule allows you to enforce that the file name should match the operation name.|![all][]|📦|🚀|
32
+ [naming-convention](rules/naming-convention.md)|Require names to follow specified conventions.|![recommended][]|📄 📦|🚀|💡
33
+ [no-anonymous-operations](rules/no-anonymous-operations.md)|Require name for your GraphQL operations. This is useful since most GraphQL client libraries are using the operation name for caching purposes.|![recommended][]|📦|🚀|💡
34
+ [no-case-insensitive-enum-values-duplicates](rules/no-case-insensitive-enum-values-duplicates.md)|Disallow case-insensitive enum values duplicates.|![recommended][]|📄|🚀|💡
35
+ [no-deprecated](rules/no-deprecated.md)|Enforce that deprecated fields or enum values are not in use by operations.|![recommended][]|📦|🚀|💡
36
+ [no-duplicate-fields](rules/no-duplicate-fields.md)|Checks for duplicate fields in selection set, variables in operation definition, or in arguments set of a field.|![recommended][]|📦|🚀|💡
37
+ [no-fragment-cycles](rules/no-fragment-cycles.md)|A GraphQL fragment is only valid when it does not have cycles in fragments usage.|![recommended][]|📦|🔮|
38
+ [no-hashtag-description](rules/no-hashtag-description.md)|Requires to use `"""` or `"` for adding a GraphQL description instead of `#`.|![recommended][]|📄|🚀|💡
39
+ [no-root-type](rules/no-root-type.md)|Disallow using root types `mutation` and/or `subscription`.||📄|🚀|💡
40
+ [no-scalar-result-type-on-mutation](rules/no-scalar-result-type-on-mutation.md)|Avoid scalar result type on mutation type to make sure to return a valid state.|![all][]|📄|🚀|💡
41
+ [no-typename-prefix](rules/no-typename-prefix.md)|Enforces users to avoid using the type name in a field name while defining your schema.|![recommended][]|📄|🚀|💡
42
+ [no-undefined-variables](rules/no-undefined-variables.md)|A GraphQL operation is only valid if all variables encountered, both directly and via fragment spreads, are defined by that operation.|![recommended][]|📦|🔮|
43
+ [no-unreachable-types](rules/no-unreachable-types.md)|Requires all types to be reachable at some level by root level fields.|![recommended][]|📄|🚀|💡
44
+ [no-unused-fields](rules/no-unused-fields.md)|Requires all fields to be used at some level by siblings operations.||📄|🚀|💡
45
+ [no-unused-fragments](rules/no-unused-fragments.md)|A GraphQL document is only valid if all fragment definitions are spread within operations, or spread within other fragments spread within operations.|![recommended][]|📦|🔮|
46
+ [no-unused-variables](rules/no-unused-variables.md)|A GraphQL operation is only valid if all variables defined by an operation are used, either directly or within a spread fragment.|![recommended][]|📦|🔮|
47
+ [one-field-subscriptions](rules/one-field-subscriptions.md)|A GraphQL subscription is valid only if it contains a single root field.|![recommended][]|📦|🔮|
48
+ [overlapping-fields-can-be-merged](rules/overlapping-fields-can-be-merged.md)|A selection set is only valid if all fields (including spreading any fragments) either correspond to distinct response names or can be merged without ambiguity.|![recommended][]|📦|🔮|
49
+ [possible-fragment-spread](rules/possible-fragment-spread.md)|A fragment spread is only valid if the type condition could ever possibly be true: if there is a non-empty intersection of the possible parent types, and possible types which pass the type condition.|![recommended][]|📦|🔮|
50
+ [possible-type-extension](rules/possible-type-extension.md)|A type extension is only valid if the type is defined and has the same kind.||📄|🔮|💡
51
+ [provided-required-arguments](rules/provided-required-arguments.md)|A field or directive is only valid if all required (non-null without a default value) field arguments have been provided.|![recommended][]|📄 📦|🔮|
52
+ [relay-arguments](rules/relay-arguments.md)|Set of rules to follow Relay specification for Arguments.|![relay][]|📄|🚀|
53
+ [relay-connection-types](rules/relay-connection-types.md)|Set of rules to follow Relay specification for Connection types.|![relay][]|📄|🚀|
54
+ [relay-edge-types](rules/relay-edge-types.md)|Set of rules to follow Relay specification for Edge types.|![relay][]|📄|🚀|
55
+ [relay-page-info](rules/relay-page-info.md)|Set of rules to follow Relay specification for `PageInfo` object.|![relay][]|📄|🚀|
56
+ [require-deprecation-date](rules/require-deprecation-date.md)|Require deletion date on `@deprecated` directive. Suggest removing deprecated things after deprecated date.|![all][]|📄|🚀|💡
57
+ [require-deprecation-reason](rules/require-deprecation-reason.md)|Require all deprecation directives to specify a reason.|![recommended][]|📄|🚀|
58
+ [require-description](rules/require-description.md)|Enforce descriptions in type definitions and operations.|![recommended][]|📄|🚀|
59
+ [require-field-of-type-query-in-mutation-result](rules/require-field-of-type-query-in-mutation-result.md)|Allow the client in one round-trip not only to call mutation but also to get a wagon of data to update their application.|![all][]|📄|🚀|
60
+ [require-id-when-available](rules/require-id-when-available.md)|Enforce selecting specific fields when they are available on the GraphQL type.|![recommended][]|📦|🚀|💡
61
+ [scalar-leafs](rules/scalar-leafs.md)|A GraphQL document is valid only if all leaf fields (fields without sub selections) are of scalar or enum types.|![recommended][]|📦|🔮|💡
62
+ [selection-set-depth](rules/selection-set-depth.md)|Limit the complexity of the GraphQL operations solely by their depth. Based on [graphql-depth-limit](https://npmjs.com/package/graphql-depth-limit).|![recommended][]|📦|🚀|💡
63
+ [strict-id-in-types](rules/strict-id-in-types.md)|Requires output types to have one unique identifier unless they do not have a logical one. Exceptions can be used to ignore output types that do not have unique identifiers.|![recommended][]|📄|🚀|
64
+ [unique-argument-names](rules/unique-argument-names.md)|A GraphQL field or directive is only valid if all supplied arguments are uniquely named.|![recommended][]|📦|🔮|
65
+ [unique-directive-names](rules/unique-directive-names.md)|A GraphQL document is only valid if all defined directives have unique names.|![recommended][]|📄|🔮|
66
+ [unique-directive-names-per-location](rules/unique-directive-names-per-location.md)|A GraphQL document is only valid if all non-repeatable directives at a given location are uniquely named.|![recommended][]|📄 📦|🔮|
67
+ [unique-enum-value-names](rules/unique-enum-value-names.md)|A GraphQL enum type is only valid if all its values are uniquely named.||📄|🔮|
68
+ [unique-field-definition-names](rules/unique-field-definition-names.md)|A GraphQL complex type is only valid if all its fields are uniquely named.|![recommended][]|📄|🔮|
69
+ [unique-fragment-name](rules/unique-fragment-name.md)|Enforce unique fragment names across your project.|![all][]|📦|🚀|
70
+ [unique-input-field-names](rules/unique-input-field-names.md)|A GraphQL input object value is only valid if all supplied fields are uniquely named.|![recommended][]|📦|🔮|
71
+ [unique-operation-name](rules/unique-operation-name.md)|Enforce unique operation names across your project.|![all][]|📦|🚀|
72
+ [unique-operation-types](rules/unique-operation-types.md)|A GraphQL document is only valid if it has only one type per operation.|![recommended][]|📄|🔮|
73
+ [unique-type-names](rules/unique-type-names.md)|A GraphQL document is only valid if all defined types have unique names.|![recommended][]|📄|🔮|
74
+ [unique-variable-names](rules/unique-variable-names.md)|A GraphQL operation is only valid if all its variables are uniquely named.|![recommended][]|📦|🔮|
75
+ [value-literals-of-correct-type](rules/value-literals-of-correct-type.md)|A GraphQL document is only valid if all value literals are of the type expected at their position.|![recommended][]|📦|🔮|💡
76
+ [variables-are-input-types](rules/variables-are-input-types.md)|A GraphQL operation is only valid if all the variables it defines are of input types (scalar, enum, or input object).|![recommended][]|📦|🔮|
77
+ [variables-in-allowed-position](rules/variables-in-allowed-position.md)|Variables passed to field arguments conform to type.|![recommended][]|📦|🔮|
78
+ <!-- prettier-ignore-end -->
79
+
80
+ [recommended]: https://img.shields.io/badge/-recommended-green.svg
81
+ [all]: https://img.shields.io/badge/-all-blue.svg
82
+ [relay]: https://img.shields.io/badge/-relay-orange.svg
@@ -0,0 +1,184 @@
1
+ # Writing Custom Rules
2
+
3
+ To get started with your own rules, start by understanding how
4
+ [ESLint custom rules works](https://eslint.org/docs/developer-guide/working-with-rules).
5
+
6
+ `graphql-eslint` converts the [GraphQL AST](https://graphql.org/graphql-js/language) into
7
+ [ESTree structure](https://github.com/estree/estree), so it allows you to easily travel the GraphQL
8
+ AST tree easily.
9
+
10
+ You can visit any GraphQL AST node in your custom rules, and report this as error. You don't need to
11
+ have special handlers for code-files, since `graphql-eslint` extracts usages of `gql` and magic
12
+ `/* GraphQL */` comments automatically, and runs it through the parser, and eventually it knows to
13
+ adjust errors location to fit in your code files original location.
14
+
15
+ You can explore the GraphQL AST for a given input on
16
+ [astexplorer.net](https://astexplorer.net/#/gist/e72aaccc1e57cbba41659d73cabbf75c/f10ee29317a31ff8012a21762a382c4a03c34d40).
17
+
18
+ ## Getting Started
19
+
20
+ Start by creating a
21
+ [simple ESLint rule file](https://eslint.org/docs/developer-guide/working-with-rules), and choose
22
+ the AST nodes you wish to visit. It can either be a
23
+ [simple AST node `Kind`](https://github.com/graphql/graphql-js/blob/master/src/language/kinds.d.ts)
24
+ or a complex [ESLint selector](https://eslint.org/docs/developer-guide/selectors) that allows you to
25
+ travel and filter AST nodes.
26
+
27
+ We recommend you to read the [graphql-eslint parser documentation](parser.md) before getting
28
+ started, to understand the differences between the AST structures.
29
+
30
+ The `graphql-eslint` comes with a TypeScript wrapper for ESLint rules, and provides a testkit to
31
+ simplify testing process with GraphQL schemas, so you can use that by importing `GraphQLESLintRule`
32
+ type. But if you wish to use JavaScript - that's fine :)
33
+
34
+ Here's an example for a simple rule that reports on anonymous GraphQL operations:
35
+
36
+ ```ts
37
+ import { GraphQLESLintRule } from '@graphql-eslint/eslint-plugin'
38
+
39
+ const rule: GraphQLESLintRule = {
40
+ create(context) {
41
+ return {
42
+ OperationDefinition(node) {
43
+ if (!node.name || !node.name.value) {
44
+ context.report({
45
+ node,
46
+ message: 'Oops, name is required!'
47
+ })
48
+ }
49
+ }
50
+ }
51
+ }
52
+ }
53
+ ```
54
+
55
+ So what happens here?
56
+
57
+ 1. `@graphql-eslint/eslint-plugin` handles the parsing process for your GraphQL content. It will
58
+ load the GraphQL files (either from code files or from `.graphql` files with SDL), parse it using
59
+ GraphQL parser, converts it to ESTree structure and let ESLint do the rest.
60
+ 1. Your rule is being loaded by ESLint, and executes just like any other ESLint rule.
61
+ 1. Our custom rule asks ESLint to run our function for every `OperationDefinition` found.
62
+ 1. If the `OperationDefinition` node doesn't have a valid `name` - we report an error to ESLint.
63
+
64
+ #### More Examples
65
+
66
+ You can scan the `packages/plugin/src/rules` directory in this repo for references for implementing
67
+ rules. It coverts most of the use-cases and concepts of rules.
68
+
69
+ ## Accessing original GraphQL AST nodes
70
+
71
+ Since our parser converts GraphQL AST to ESTree structure, there are some minor differences in the
72
+ structure of the objects. If you are using TypeScript, and you typed your rule with
73
+ `GraphQLESLintRule` - you'll see that each `node` is a bit different from the AST nodes of GraphQL
74
+ (you can read more about that in [graphql-eslint parser documentation](parser.md)).
75
+
76
+ If you need access to the original GraphQL AST `node`, you can use `.rawNode()` method on each node
77
+ you get from the AST structure of ESLint.
78
+
79
+ This is useful if you wish to use other GraphQL tools that works with the original GraphQL AST
80
+ objects.
81
+
82
+ Here's an example for using original `graphql-js` validate method to validate `OperationDefinition`:
83
+
84
+ ```ts
85
+ import { validate } from 'graphql'
86
+ import { requireGraphQLSchemaFromContext } from '@graphql-eslint/eslint-plugin'
87
+
88
+ export const rule = {
89
+ create(context) {
90
+ return {
91
+ OperationDefinition(node) {
92
+ const schema = requireGraphQLSchemaFromContext(context)
93
+
94
+ validate(context, schema, {
95
+ kind: Kind.DOCUMENT,
96
+ definitions: [node.rawNode()]
97
+ })
98
+ }
99
+ }
100
+ }
101
+ }
102
+ ```
103
+
104
+ ## `TypeInfo` / `GraphQLSchema`
105
+
106
+ If you provide GraphQL schema in your ESLint configuration, it will get loaded automatically, and
107
+ become available in your rules in two ways:
108
+
109
+ 1. You'll be able to access the loaded `GraphQLSchema` object.
110
+ 2. In every visited node, you'll be able to use `.typeInfo()` method to get an object with complete
111
+ type information on your visited node (see
112
+ [TypeInfo documentation](https://graphql.org/graphql-js/utilities/#typeinfo)).
113
+
114
+ #### Getting `GraphQLSchema`
115
+
116
+ To mark your ESLint rules as a rule that needs access to GraphQL schema, start by running
117
+ `requireGraphQLSchemaFromContext` from the plugin package, it will make sure to return a schema, or
118
+ throw an error for the user about the missing schema.
119
+
120
+ ```ts
121
+ const schema = requireGraphQLSchemaFromContext(context)
122
+ ```
123
+
124
+ #### Accessing TypeInfo
125
+
126
+ If schema is provided and loaded successfully, the `typeInfo` will be available to use. Otherwise -
127
+ it will be `undefined`. If your plugin requires `typeInfo` in order to operate and run, make sure to
128
+ call `requireGraphQLSchemaFromContext` - it will validate that the schema is loaded.
129
+
130
+ `typeInfo` is provided on every node, based on the type of that node, for example, to access the
131
+ `GraphQLOutputType` while you are visiting a `SelectionSet` node, you can do:
132
+
133
+ ```ts
134
+ import { requireGraphQLSchemaFromContext } from '@graphql-eslint/eslint-plugin'
135
+
136
+ export const rule = {
137
+ create(context) {
138
+ requireGraphQLSchemaFromContext('your-rule-name', context)
139
+
140
+ return {
141
+ SelectionSet(node) {
142
+ const typeInfo = node.typeInfo()
143
+ if (typeInfo.gqlType) {
144
+ console.log(`The GraphQLOutputType is: ${typeInfo.gqlType}`)
145
+ }
146
+ }
147
+ }
148
+ }
149
+ }
150
+ ```
151
+
152
+ The structure of the return value of `.typeInfo()` is
153
+ [defined here](https://github.com/B2o5T/graphql-eslint/blob/master/packages/plugin/src/estree-converter/converter.ts#L32-L40).
154
+ So based on the `node` you are using, you'll get a different values on `.typeInfo()` result.
155
+
156
+ ## Testing your rules
157
+
158
+ To test your rules, you can either use the wrapped `GraphQLRuleTester` from this library, or use the
159
+ built-it [`RuleTester`](https://eslint.org/docs/developer-guide/working-with-rules#rule-unit-tests)
160
+ of ESLint.
161
+
162
+ The wrapped `GraphQLRuleTester` provides built-in configured parser, and a schema loader, if you
163
+ need to test your rule with a loaded schema.
164
+
165
+ ```ts
166
+ import { GraphQLRuleTester } from '@graphql-eslint/eslint-plugin'
167
+ import { rule } from './my-rule'
168
+
169
+ const ruleTester = new GraphQLRuleTester()
170
+
171
+ ruleTester.runGraphQLTests('my-rule', rule, {
172
+ valid: [
173
+ {
174
+ code: 'query something { foo }'
175
+ }
176
+ ],
177
+ invalid: [
178
+ {
179
+ code: 'query invalid { foo }',
180
+ errors: [{ message: 'Your error message.' }]
181
+ }
182
+ ]
183
+ })
184
+ ```
@@ -0,0 +1,24 @@
1
+ # Deprecated Rules
2
+
3
+ ## avoid-duplicate-fields
4
+
5
+ This rule was renamed to [`no-duplicate-fields`](rules/no-duplicate-fields.md).
6
+
7
+ ## avoid-scalar-result-type-on-mutation
8
+
9
+ This rule was renamed to
10
+ [`no-scalar-result-type-on-mutation`](rules/no-scalar-result-type-on-mutation.md).
11
+
12
+ ## avoid-typename-prefix
13
+
14
+ This rule was renamed to [`no-typename-prefix`](rules/no-typename-prefix.md).
15
+
16
+ ## avoid-operation-name-prefix
17
+
18
+ This rule was removed because the same things can be validated using
19
+ [`naming-convention`](rules/naming-convention.md).
20
+
21
+ ## no-operation-name-suffix
22
+
23
+ This rule was removed because the same things can be validated using
24
+ [`naming-convention`](rules/naming-convention.md).
@@ -0,0 +1,95 @@
1
+ # Parser Options
2
+
3
+ ## `graphQLParserOptions`
4
+
5
+ With this configuration, you can specify custom configurations for GraphQL's `parse` method. By
6
+ default, `graphql-eslint` parser just adds `noLocation: false` to make sure all parsed AST has
7
+ `location` set, since we need this for tokenizing and for converting the GraphQL AST into ESTree.
8
+
9
+ You can find the
10
+ [complete set of options for this object here](https://github.com/graphql/graphql-js/blob/6e48d16f92b9a6df8638b1486354c6be2537033b/src/language/parser.ts#L73)
11
+
12
+ ## `skipGraphQLConfig`
13
+
14
+ If you are using [`graphql-config`](https://graphql-config.com) in your project, the parser will
15
+ automatically use that to load your default GraphQL schema.
16
+
17
+ You can disable this behaviour using `skipGraphQLConfig: true` in the `parserOptions`:
18
+
19
+ ```json
20
+ "parserOptions": {
21
+ "skipGraphQLConfig": true
22
+ }
23
+ ```
24
+
25
+ ## `schema`
26
+
27
+ You can specify `parserOptions.schema` to load your GraphQL schema. The parser uses `graphql-tools`
28
+ and it's loaders, that means you can either specify a URL, a path to a local `.json` (introspection)
29
+ file, or a path to a local `.graphql` file(s). You can also use Glob expressions to load multiple
30
+ files.
31
+
32
+ Here are a few examples for a valid setup:
33
+
34
+ ```json
35
+ "parserOptions": {
36
+ "schema": "./schema.graphql"
37
+ }
38
+ ```
39
+
40
+ ```json
41
+ "parserOptions": {
42
+ "schema": "./schema.json"
43
+ }
44
+ ```
45
+
46
+ ```json
47
+ "parserOptions": {
48
+ "schema": "http://my-server/graphql"
49
+ }
50
+ ```
51
+
52
+ ```json
53
+ "parserOptions": {
54
+ "schema": "./src/**/*.graphql"
55
+ }
56
+ ```
57
+
58
+ ```json
59
+ "parserOptions": {
60
+ "schema": [
61
+ "src/schema-a.graphql",
62
+ "src/schema-b.graphql",
63
+ "src/schema-c.graphql"
64
+ ]
65
+ }
66
+ ```
67
+
68
+ ## `schemaOptions`
69
+
70
+ If you wish to send additional configuration for the `graphql-tools` loaders that loads your schema,
71
+ you can specify `schemaOptions` object:
72
+
73
+ ```json
74
+ "parserOptions": {
75
+ "schema": "http://my-server/graphql",
76
+ "schemaOptions": {
77
+ "headers": {
78
+ "Authorization": "Bearer MY_TOKEN"
79
+ }
80
+ }
81
+ }
82
+ ```
83
+
84
+ ```json
85
+ "parserOptions": {
86
+ "schema": "./src/**/*.graphql",
87
+ "schemaOptions": {
88
+ "assumeValid": true
89
+ }
90
+ }
91
+ ```
92
+
93
+ > The configuration here is flexible, and will be sent to `graphql-tools` and it's loaders. So
94
+ > depends on the schema source, the options may vary.
95
+ > [You can read more about these loaders and their configuration here](https://graphql-tools.com/docs/api/interfaces/loaders_graphql_file_src.GraphQLFileLoaderOptions#properties).
package/docs/parser.md ADDED
@@ -0,0 +1,67 @@
1
+ # GraphQL-ESLint Parser
2
+
3
+ The `graphql-eslint` parser is works in the following way:
4
+
5
+ 1. Loads all relevant GraphQL code using ESLint core (either from `.graphql` files, or using
6
+ [ESLint `processor`](https://eslint.org/docs/developer-guide/working-with-plugins#processors-in-plugins)
7
+ to find in code-files).
8
+ 1. Is uses `graphql-js` (and `graphql-tools`) to parse the found string into a `DocumentNode`.
9
+ 1. Extracts all comments (marked as `# ...`) from the parsed AST, and provides to ESLint as
10
+ directives hints.
11
+ 1. If `graphql-config` is used, or `schema` field is provided, the schema is being loaded and
12
+ provided to the rules using `parserServices`.
13
+ 1. Converts the `DocumentNode` to ESTree structure (and enrich the nodes with `typeInfo`, if schema
14
+ is loaded).
15
+
16
+ ## ESTree Conversion
17
+
18
+ The GraphQL AST structure is very similar to ESTree structure, but there are a few differences that
19
+ the `parser` does.
20
+
21
+ Here's a list of changes that the parser performs, in order to make the GraphQL AST compatible with
22
+ ESTree:
23
+
24
+ ---
25
+
26
+ **Problem**: GraphQL uses `kind` field to define the kind of the AST node, while ESTree uses `type`.
27
+
28
+ **Solution**: The parser adds `type` field on each node, and just copies the value from `kind`
29
+ field.
30
+
31
+ ---
32
+
33
+ **Problem**: Some GraphQL AST nodes are using `type` field (which conflicts with the ESTree kind).
34
+
35
+ **Solution**: AST nodes that has `type` field are being transformed, and the `type` field changes to
36
+ `gqlType`.
37
+
38
+ ---
39
+
40
+ **Problem**: GraphQL AST structure allows circular JSON links (while ESTree might fail on
41
+ `Maximum call stack exceeded`).
42
+
43
+ **Solution**: The parser removes circular JSONs (specifically around GraphQL `Location` and the
44
+ `Lexer`)
45
+
46
+ ---
47
+
48
+ **Problem**: GraphQL uses `location` field to store the AST locations, while ESTree also uses it in
49
+ a different structure.
50
+
51
+ **Solution**: The parser creates a new `location` field that is compatible with ESTree.
52
+
53
+ ### Loading GraphQL Schema
54
+
55
+ If you are using [`graphql-config`](https://graphql-config.com) in your project, the parser will
56
+ automatically use that to load your default GraphQL schema (you can disable this behaviour using
57
+ `skipGraphQLConfig: true` in the `parserOptions`).
58
+
59
+ If you are not using `graphql-config`, you can specify `parserOptions.schema` to load your GraphQL
60
+ schema. The parser uses `graphql-tools` and it's loaders, that means you can either specify a URL, a
61
+ path to a local `.json` (introspection) file, or a path to a local `.graphql` file(s). You can also
62
+ use Glob expressions to load multiple files.
63
+
64
+ [You can find more detail on the `parserOptions` config here](parser-options.md)
65
+
66
+ Providing the schema will make sure that rules that needs it will be able to access it, and it
67
+ enriches every converted AST node with `typeInfo`.
@@ -0,0 +1,194 @@
1
+ # `alphabetize`
2
+
3
+ 🔧 The `--fix` option on the
4
+ [command line](https://eslint.org/docs/user-guide/command-line-interface#--fix) can automatically
5
+ fix some of the problems reported by this rule.
6
+
7
+ - Category: `Schema & Operations`
8
+ - Rule name: `@graphql-eslint/alphabetize`
9
+ - Requires GraphQL Schema: `false` [ℹ️](../../README.md#extended-linting-rules-with-graphql-schema)
10
+ - Requires GraphQL Operations: `false`
11
+ [ℹ️](../../README.md#extended-linting-rules-with-siblings-operations)
12
+
13
+ Enforce arrange in alphabetical order for type fields, enum values, input object fields, operation
14
+ selections and more.
15
+
16
+ ## Usage Examples
17
+
18
+ ### Incorrect
19
+
20
+ ```graphql
21
+ # eslint @graphql-eslint/alphabetize: ['error', { fields: ['ObjectTypeDefinition'] }]
22
+
23
+ type User {
24
+ password: String
25
+ firstName: String! # should be before "password"
26
+ age: Int # should be before "firstName"
27
+ lastName: String!
28
+ }
29
+ ```
30
+
31
+ ### Correct
32
+
33
+ ```graphql
34
+ # eslint @graphql-eslint/alphabetize: ['error', { fields: ['ObjectTypeDefinition'] }]
35
+
36
+ type User {
37
+ age: Int
38
+ firstName: String!
39
+ lastName: String!
40
+ password: String
41
+ }
42
+ ```
43
+
44
+ ### Incorrect
45
+
46
+ ```graphql
47
+ # eslint @graphql-eslint/alphabetize: ['error', { values: ['EnumTypeDefinition'] }]
48
+
49
+ enum Role {
50
+ SUPER_ADMIN
51
+ ADMIN # should be before "SUPER_ADMIN"
52
+ USER
53
+ GOD # should be before "USER"
54
+ }
55
+ ```
56
+
57
+ ### Correct
58
+
59
+ ```graphql
60
+ # eslint @graphql-eslint/alphabetize: ['error', { values: ['EnumTypeDefinition'] }]
61
+
62
+ enum Role {
63
+ ADMIN
64
+ GOD
65
+ SUPER_ADMIN
66
+ USER
67
+ }
68
+ ```
69
+
70
+ ### Incorrect
71
+
72
+ ```graphql
73
+ # eslint @graphql-eslint/alphabetize: ['error', { selections: ['OperationDefinition'] }]
74
+
75
+ query {
76
+ me {
77
+ firstName
78
+ lastName
79
+ email # should be before "lastName"
80
+ }
81
+ }
82
+ ```
83
+
84
+ ### Correct
85
+
86
+ ```graphql
87
+ # eslint @graphql-eslint/alphabetize: ['error', { selections: ['OperationDefinition'] }]
88
+
89
+ query {
90
+ me {
91
+ email
92
+ firstName
93
+ lastName
94
+ }
95
+ }
96
+ ```
97
+
98
+ ## Config Schema
99
+
100
+ The schema defines the following properties:
101
+
102
+ ### `fields` (array)
103
+
104
+ Fields of `type`, `interface`, and `input`.
105
+
106
+ The elements of the array can contain the following enum values:
107
+
108
+ - `ObjectTypeDefinition`
109
+ - `InterfaceTypeDefinition`
110
+ - `InputObjectTypeDefinition`
111
+
112
+ Additional restrictions:
113
+
114
+ - Minimum items: `1`
115
+ - Unique items: `true`
116
+
117
+ ### `values` (array)
118
+
119
+ Values of `enum`.
120
+
121
+ The elements of the array can contain the following enum values:
122
+
123
+ - `EnumTypeDefinition`
124
+
125
+ Additional restrictions:
126
+
127
+ - Minimum items: `1`
128
+ - Unique items: `true`
129
+
130
+ ### `selections` (array)
131
+
132
+ Selections of `fragment` and operations `query`, `mutation` and `subscription`.
133
+
134
+ The elements of the array can contain the following enum values:
135
+
136
+ - `OperationDefinition`
137
+ - `FragmentDefinition`
138
+
139
+ Additional restrictions:
140
+
141
+ - Minimum items: `1`
142
+ - Unique items: `true`
143
+
144
+ ### `variables` (array)
145
+
146
+ Variables of operations `query`, `mutation` and `subscription`.
147
+
148
+ The elements of the array can contain the following enum values:
149
+
150
+ - `OperationDefinition`
151
+
152
+ Additional restrictions:
153
+
154
+ - Minimum items: `1`
155
+ - Unique items: `true`
156
+
157
+ ### `arguments` (array)
158
+
159
+ Arguments of fields and directives.
160
+
161
+ The elements of the array can contain the following enum values:
162
+
163
+ - `FieldDefinition`
164
+ - `Field`
165
+ - `DirectiveDefinition`
166
+ - `Directive`
167
+
168
+ Additional restrictions:
169
+
170
+ - Minimum items: `1`
171
+ - Unique items: `true`
172
+
173
+ ### `definitions` (boolean)
174
+
175
+ Definitions – `type`, `interface`, `enum`, `scalar`, `input`, `union` and `directive`.
176
+
177
+ Default: `false`
178
+
179
+ ### `groups` (array)
180
+
181
+ Custom order group. Example: `['id', '*', 'createdAt', 'updatedAt']` where `*` says for everything
182
+ else.
183
+
184
+ The object is an array with all elements of the type `string`.
185
+
186
+ Additional restrictions:
187
+
188
+ - Minimum items: `2`
189
+ - Unique items: `true`
190
+
191
+ ## Resources
192
+
193
+ - [Rule source](../../packages/plugin/src/rules/alphabetize.ts)
194
+ - [Test source](../../packages/plugin/tests/alphabetize.spec.ts)