@starci/eslint-canon-fe 9.3.0 → 9.4.0

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 (177) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +5 -1
  3. package/dist/brand-values.d.ts +28 -0
  4. package/dist/brand-values.js +172 -0
  5. package/dist/button-intent.d.ts +11 -0
  6. package/dist/button-intent.js +361 -0
  7. package/dist/callback-shape.d.ts +7 -0
  8. package/dist/callback-shape.js +396 -0
  9. package/dist/class-names.d.ts +19 -0
  10. package/dist/class-names.js +170 -0
  11. package/dist/client-boundary.d.ts +42 -0
  12. package/dist/client-boundary.js +404 -0
  13. package/dist/comments.d.ts +47 -0
  14. package/dist/comments.js +156 -0
  15. package/dist/control-height.d.ts +7 -0
  16. package/dist/control-height.js +83 -0
  17. package/dist/drawing.d.ts +31 -0
  18. package/dist/drawing.js +376 -0
  19. package/dist/env-owner.d.ts +22 -0
  20. package/dist/env-owner.js +291 -0
  21. package/dist/fe-stack.d.ts +10 -0
  22. package/dist/fe-stack.js +73 -0
  23. package/dist/file-layout.d.ts +71 -0
  24. package/dist/file-layout.js +465 -0
  25. package/dist/formatting.d.ts +25 -0
  26. package/dist/formatting.js +104 -0
  27. package/dist/function-budget.d.ts +9 -0
  28. package/dist/function-budget.js +48 -0
  29. package/dist/grammar-shim.d.ts +5 -0
  30. package/dist/grammar-shim.js +126 -0
  31. package/dist/hooks-folder.d.ts +34 -0
  32. package/dist/hooks-folder.js +320 -0
  33. package/dist/hygiene.d.ts +39 -0
  34. package/dist/hygiene.js +540 -0
  35. package/dist/index.d.ts +105 -0
  36. package/dist/index.js +310 -0
  37. package/{landmark.mjs → dist/landmark.d.ts} +4 -6
  38. package/dist/landmark.js +6 -0
  39. package/dist/lib/ast.d.ts +36 -0
  40. package/dist/lib/ast.js +94 -0
  41. package/dist/lib/bindings.d.ts +84 -0
  42. package/dist/lib/bindings.js +168 -0
  43. package/dist/lib/class-text.d.ts +3 -0
  44. package/dist/lib/class-text.js +30 -0
  45. package/dist/lib/config.d.ts +81 -0
  46. package/dist/lib/config.js +141 -0
  47. package/dist/lib/drawing-scope.d.ts +5 -0
  48. package/{lib/drawing-scope.mjs → dist/lib/drawing-scope.js} +6 -11
  49. package/dist/lib/eslint-boundary.d.ts +23 -0
  50. package/dist/lib/eslint-boundary.js +6 -0
  51. package/dist/lib/fe-stack.d.ts +49 -0
  52. package/dist/lib/fe-stack.js +98 -0
  53. package/dist/lib/hfs-view.d.ts +74 -0
  54. package/dist/lib/hfs-view.js +6 -0
  55. package/dist/lib/hfs.d.ts +34 -0
  56. package/dist/lib/hfs.js +72 -0
  57. package/dist/lib/next.d.ts +4 -0
  58. package/dist/lib/next.js +10 -0
  59. package/dist/lib/own-hook-origin.d.ts +17 -0
  60. package/dist/lib/own-hook-origin.js +52 -0
  61. package/dist/lib/package-root.d.ts +4 -0
  62. package/dist/lib/package-root.js +10 -0
  63. package/dist/lib/path.d.ts +2 -0
  64. package/{lib/path.mjs → dist/lib/path.js} +1 -1
  65. package/dist/lib/platform.d.ts +26 -0
  66. package/{lib/platform.mjs → dist/lib/platform.js} +38 -35
  67. package/dist/lib/program-for.d.ts +5 -0
  68. package/dist/lib/program-for.js +23 -0
  69. package/dist/lib/pure-owner-helper.d.ts +10 -0
  70. package/dist/lib/pure-owner-helper.js +156 -0
  71. package/dist/lib/react.d.ts +16 -0
  72. package/dist/lib/react.js +22 -0
  73. package/dist/lib/redux-hook-origin.d.ts +4 -0
  74. package/dist/lib/redux-hook-origin.js +50 -0
  75. package/dist/lib/rule.d.ts +28 -0
  76. package/dist/lib/rule.js +5 -0
  77. package/dist/lib/scope.d.ts +88 -0
  78. package/{lib/scope.mjs → dist/lib/scope.js} +83 -93
  79. package/dist/lib/typed-class-values.d.ts +13 -0
  80. package/dist/lib/typed-class-values.js +92 -0
  81. package/dist/lib/types.d.ts +44 -0
  82. package/dist/lib/types.js +64 -0
  83. package/dist/lib/why.d.ts +350 -0
  84. package/dist/lib/why.js +350 -0
  85. package/dist/lint-escape-hatch.d.ts +24 -0
  86. package/{lint-escape-hatch.mjs → dist/lint-escape-hatch.js} +38 -45
  87. package/dist/lists.d.ts +31 -0
  88. package/dist/lists.js +202 -0
  89. package/dist/loading.d.ts +34 -0
  90. package/dist/loading.js +157 -0
  91. package/dist/naming.d.ts +33 -0
  92. package/dist/naming.js +176 -0
  93. package/dist/native-controls.d.ts +24 -0
  94. package/dist/native-controls.js +105 -0
  95. package/dist/next-conventions.d.ts +48 -0
  96. package/dist/next-conventions.js +452 -0
  97. package/dist/project-graph.d.ts +5 -0
  98. package/{project-graph.mjs → dist/project-graph.js} +8 -12
  99. package/dist/props-and-slots.d.ts +19 -0
  100. package/dist/props-and-slots.js +320 -0
  101. package/dist/served-locale.d.ts +38 -0
  102. package/dist/served-locale.js +263 -0
  103. package/dist/shape-slot.d.ts +18 -0
  104. package/dist/shape-slot.js +324 -0
  105. package/dist/size-and-state-budget.d.ts +46 -0
  106. package/dist/size-and-state-budget.js +424 -0
  107. package/dist/size-growth.d.ts +24 -0
  108. package/dist/size-growth.js +64 -0
  109. package/dist/sonar-parity.d.ts +5 -0
  110. package/{sonar-parity.mjs → dist/sonar-parity.js} +11 -7
  111. package/dist/surface-rules.d.ts +18 -0
  112. package/dist/surface-rules.js +491 -0
  113. package/dist/swr-family.d.ts +15 -0
  114. package/dist/swr-family.js +419 -0
  115. package/dist/the-split.d.ts +27 -0
  116. package/dist/the-split.js +157 -0
  117. package/dist/tokens.d.ts +9 -0
  118. package/dist/tokens.js +35 -0
  119. package/dist/translation.d.ts +51 -0
  120. package/dist/translation.js +403 -0
  121. package/dist/transport.d.ts +73 -0
  122. package/dist/transport.js +885 -0
  123. package/dist/type-safety.d.ts +43 -0
  124. package/dist/type-safety.js +139 -0
  125. package/dist/ui-rulings.d.ts +11 -0
  126. package/dist/ui-rulings.js +121 -0
  127. package/package.json +31 -9
  128. package/runtime/knowledge/hfs/canon-pins.yaml +17 -10
  129. package/brand-values.mjs +0 -172
  130. package/button-intent.mjs +0 -320
  131. package/callback-shape.mjs +0 -332
  132. package/class-names.mjs +0 -149
  133. package/client-boundary.mjs +0 -400
  134. package/comments.mjs +0 -159
  135. package/control-height.mjs +0 -77
  136. package/drawing.mjs +0 -321
  137. package/env-owner.mjs +0 -244
  138. package/fe-stack.mjs +0 -86
  139. package/file-layout.mjs +0 -472
  140. package/formatting.mjs +0 -110
  141. package/function-budget.mjs +0 -49
  142. package/grammar-shim.mjs +0 -123
  143. package/hooks-folder.mjs +0 -300
  144. package/hygiene.mjs +0 -513
  145. package/index.mjs +0 -317
  146. package/lib/ast.mjs +0 -97
  147. package/lib/bindings.mjs +0 -159
  148. package/lib/class-text.mjs +0 -29
  149. package/lib/config.mjs +0 -142
  150. package/lib/fe-stack.mjs +0 -77
  151. package/lib/hfs.mjs +0 -49
  152. package/lib/next.mjs +0 -6
  153. package/lib/own-hook-origin.mjs +0 -53
  154. package/lib/program-for.mjs +0 -22
  155. package/lib/pure-owner-helper.mjs +0 -148
  156. package/lib/react.mjs +0 -28
  157. package/lib/redux-hook-origin.mjs +0 -44
  158. package/lib/typed-class-values.mjs +0 -81
  159. package/lib/types.mjs +0 -63
  160. package/lib/why.mjs +0 -352
  161. package/lists.mjs +0 -193
  162. package/loading.mjs +0 -156
  163. package/naming.mjs +0 -185
  164. package/native-controls.mjs +0 -108
  165. package/next-conventions.mjs +0 -447
  166. package/props-and-slots.mjs +0 -276
  167. package/served-locale.mjs +0 -243
  168. package/size-and-state-budget.mjs +0 -376
  169. package/size-growth.mjs +0 -62
  170. package/surface-rules.mjs +0 -443
  171. package/swr-family.mjs +0 -326
  172. package/the-split.mjs +0 -155
  173. package/tokens.mjs +0 -39
  174. package/translation.mjs +0 -392
  175. package/transport.mjs +0 -830
  176. package/type-safety.mjs +0 -147
  177. package/ui-rulings.mjs +0 -134
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Type-aware helpers of the front-end canon: a rule asks what a node IS (its TypeScript type, the symbol an identifier
3
+ * resolves to, the module a declaration comes from), never what it is called. `starciFeConfig` turns typed linting on for
4
+ * the source tree (`parserOptions.projectService`), so these helpers refuse to run without the program instead of falling
5
+ * back to a name match.
6
+ */
7
+ import ts from "typescript";
8
+ /**
9
+ * The TypeScript services of the file being linted.
10
+ *
11
+ * @param context - The ESLint rule context.
12
+ * @returns The program, its checker and the ESTree to TS node map.
13
+ */
14
+ export const typed = (context) => {
15
+ const services = context.sourceCode?.parserServices ?? context.parserServices;
16
+ if (!services?.program || !services.esTreeNodeToTSNodeMap) {
17
+ throw new Error(`${context.id ?? "a starci-fe rule"} needs typed linting (parserOptions.projectService); lint through starciFeConfig, which turns it on`);
18
+ }
19
+ const program = services.program;
20
+ const map = services.esTreeNodeToTSNodeMap;
21
+ return { program, checker: program.getTypeChecker(), toTs: (node) => map.get(node) };
22
+ };
23
+ /**
24
+ * True when the type of an expression is a promise (a thenable carrying a `then` method), after union members are read.
25
+ *
26
+ * @param context - The ESLint rule context.
27
+ * @param node - An ESTree expression.
28
+ * @returns Whether evaluating the node yields a promise.
29
+ */
30
+ export const isPromiseValued = (context, node) => {
31
+ const { checker, toTs } = typed(context);
32
+ const tsNode = toTs(node);
33
+ if (!tsNode)
34
+ return false;
35
+ const type = checker.getTypeAtLocation(tsNode);
36
+ const parts = type.isUnion() ? type.types : [type];
37
+ return parts.some((part) => Boolean(part.getProperty("then")));
38
+ };
39
+ /**
40
+ * The declarations the symbol of an identifier resolves to, after import aliases are followed.
41
+ *
42
+ * @param context - The ESLint rule context.
43
+ * @param identifier - An ESTree identifier (or any node with a symbol).
44
+ * @returns The TypeScript declarations (empty when the checker has no symbol).
45
+ */
46
+ export const declarationsOf = (context, identifier) => {
47
+ const { checker, toTs } = typed(context);
48
+ const tsNode = toTs(identifier);
49
+ if (!tsNode)
50
+ return [];
51
+ let symbol = checker.getSymbolAtLocation(tsNode);
52
+ if (!symbol)
53
+ return [];
54
+ if ((symbol.flags & ts.SymbolFlags.Alias) !== 0)
55
+ symbol = checker.getAliasedSymbol(symbol);
56
+ return symbol.getDeclarations() ?? [];
57
+ };
58
+ /**
59
+ * The forward-slash file name a declaration lives in.
60
+ *
61
+ * @param declaration - A TypeScript declaration.
62
+ * @returns Its source file name.
63
+ */
64
+ export const fileOf = (declaration) => String(declaration.getSourceFile().fileName).split("\\").join("/");
@@ -0,0 +1,350 @@
1
+ /**
2
+ * The "why" of each rule the HFS catalogue assigns to this canon.
3
+ *
4
+ * WHERE IT IS SURFACED. An ESLint message is written for the developer at the terminal, in English,
5
+ * and says what is wrong in the vocabulary of the rule. The agent that reads a failed land gate needs
6
+ * the catalogue's sentence instead: the finding code (the key in `modules/kernel/failure-codes.yaml`)
7
+ * and a headline and next step it can quote to the owner. This map is the canon's half of that
8
+ * contract: `code` is the finding code, `en` the English source of the headline with `<file>` /
9
+ * `<what>` placeholders the reader fills from the ESLint location, `fix` the one sentence "what do I
10
+ * do now". The owner reads both in Vietnamese through the declared message catalog: the `en` and
11
+ * `fix` strings are the keys of `modules/i18n/messages/canon.yaml`, so `translator('vi')(entry.en)` and
12
+ * `translator('vi')(entry.fix)` hand back the Vietnamese of the same sentence.
13
+ *
14
+ * Every rule that carries a catalogue id (R18, R22, R49-R59, R60-R62, R65, the fe-stack catalog) has an entry;
15
+ * the twin test refuses a rule of those laws with no entry and an entry for a rule that does not exist.
16
+ */
17
+ /** @typedef {{ code: string, en: string, fix: string }} Why */
18
+ /** @type {Record<string, Why>} */
19
+ export declare const why: {
20
+ "selection-fill-no-check": {
21
+ code: string;
22
+ en: string;
23
+ fix: string;
24
+ };
25
+ "no-grammar-internal-selector": {
26
+ code: string;
27
+ en: string;
28
+ fix: string;
29
+ };
30
+ "divider-full-bleed": {
31
+ code: string;
32
+ en: string;
33
+ fix: string;
34
+ };
35
+ "button-intent-required": {
36
+ code: string;
37
+ en: string;
38
+ fix: string;
39
+ };
40
+ "control-height": {
41
+ code: string;
42
+ en: string;
43
+ fix: string;
44
+ };
45
+ "no-grammar-shim": {
46
+ code: string;
47
+ en: string;
48
+ fix: string;
49
+ };
50
+ "button-no-variant": {
51
+ code: string;
52
+ en: string;
53
+ fix: string;
54
+ };
55
+ "destructive-confirm-in-dialog": {
56
+ code: string;
57
+ en: string;
58
+ fix: string;
59
+ };
60
+ "single-commit-per-render": {
61
+ code: string;
62
+ en: string;
63
+ fix: string;
64
+ };
65
+ "no-commit-in-collection-item": {
66
+ code: string;
67
+ en: string;
68
+ fix: string;
69
+ };
70
+ "nested-control-variant": {
71
+ code: string;
72
+ en: string;
73
+ fix: string;
74
+ };
75
+ "no-app-surface-paint": {
76
+ code: string;
77
+ en: string;
78
+ fix: string;
79
+ };
80
+ "no-list-panel-padding": {
81
+ code: string;
82
+ en: string;
83
+ fix: string;
84
+ };
85
+ "no-env-outside-config": {
86
+ code: string;
87
+ en: string;
88
+ fix: string;
89
+ };
90
+ "no-hardcoded-endpoint-fallback": {
91
+ code: string;
92
+ en: string;
93
+ fix: string;
94
+ };
95
+ "fetch-only-in-api-client": {
96
+ code: string;
97
+ en: string;
98
+ fix: string;
99
+ };
100
+ "client-fetch-has-signal": {
101
+ code: string;
102
+ en: string;
103
+ fix: string;
104
+ };
105
+ "no-shared-transport-state": {
106
+ code: string;
107
+ en: string;
108
+ fix: string;
109
+ };
110
+ "client-maps-auth-to-refused": {
111
+ code: string;
112
+ en: string;
113
+ fix: string;
114
+ };
115
+ "no-failure-collapse": {
116
+ code: string;
117
+ en: string;
118
+ fix: string;
119
+ };
120
+ "no-hand-typed-wire": {
121
+ code: string;
122
+ en: string;
123
+ fix: string;
124
+ };
125
+ "use-client-only-at-boundary": {
126
+ code: string;
127
+ en: string;
128
+ fix: string;
129
+ };
130
+ "hooks-folder-holds-hooks-only": {
131
+ code: string;
132
+ en: string;
133
+ fix: string;
134
+ };
135
+ "no-middleware-file": {
136
+ code: string;
137
+ en: string;
138
+ fix: string;
139
+ };
140
+ "locale-segment-is-locale": {
141
+ code: string;
142
+ en: string;
143
+ fix: string;
144
+ };
145
+ "no-second-i18n-stack": {
146
+ code: string;
147
+ en: string;
148
+ fix: string;
149
+ };
150
+ "html-lang-from-locale": {
151
+ code: string;
152
+ en: string;
153
+ fix: string;
154
+ };
155
+ "no-hardcoded-copy": {
156
+ code: string;
157
+ en: string;
158
+ fix: string;
159
+ };
160
+ "no-raw-brand-value": {
161
+ code: string;
162
+ en: string;
163
+ fix: string;
164
+ };
165
+ "no-native-form-control": {
166
+ code: string;
167
+ en: string;
168
+ fix: string;
169
+ };
170
+ "component-line-budget": {
171
+ code: string;
172
+ en: string;
173
+ fix: string;
174
+ };
175
+ "unit-hook-budget": {
176
+ code: string;
177
+ en: string;
178
+ fix: string;
179
+ };
180
+ "no-hand-rolled-polling": {
181
+ code: string;
182
+ en: string;
183
+ fix: string;
184
+ };
185
+ "no-inline-lint-config": {
186
+ code: string;
187
+ en: string;
188
+ fix: string;
189
+ };
190
+ "no-double-cast": {
191
+ code: string;
192
+ en: string;
193
+ fix: string;
194
+ };
195
+ "no-type-assertion": {
196
+ code: string;
197
+ en: string;
198
+ fix: string;
199
+ };
200
+ "no-non-null-assertion": {
201
+ code: string;
202
+ en: string;
203
+ fix: string;
204
+ };
205
+ "no-explicit-any": {
206
+ code: string;
207
+ en: string;
208
+ fix: string;
209
+ };
210
+ "list-item-has-key": {
211
+ code: string;
212
+ en: string;
213
+ fix: string;
214
+ };
215
+ "no-index-key": {
216
+ code: string;
217
+ en: string;
218
+ fix: string;
219
+ };
220
+ "no-inline-literal-prop-in-list": {
221
+ code: string;
222
+ en: string;
223
+ fix: string;
224
+ };
225
+ "effect-subscription-needs-cleanup": {
226
+ code: string;
227
+ en: string;
228
+ fix: string;
229
+ };
230
+ "no-data-fetch-in-effect": {
231
+ code: string;
232
+ en: string;
233
+ fix: string;
234
+ };
235
+ "no-empty-catch": {
236
+ code: string;
237
+ en: string;
238
+ fix: string;
239
+ };
240
+ "no-console": {
241
+ code: string;
242
+ en: string;
243
+ fix: string;
244
+ };
245
+ "page-exports-metadata": {
246
+ code: string;
247
+ en: string;
248
+ fix: string;
249
+ };
250
+ "no-null-suspense-fallback": {
251
+ code: string;
252
+ en: string;
253
+ fix: string;
254
+ };
255
+ "navigation-from-intl": {
256
+ code: string;
257
+ en: string;
258
+ fix: string;
259
+ };
260
+ "no-native-anchor": {
261
+ code: string;
262
+ en: string;
263
+ fix: string;
264
+ };
265
+ "use-intl-formatter": {
266
+ code: string;
267
+ en: string;
268
+ fix: string;
269
+ };
270
+ "no-hardcoded-route": {
271
+ code: string;
272
+ en: string;
273
+ fix: string;
274
+ };
275
+ "client-no-server-import": {
276
+ code: string;
277
+ en: string;
278
+ fix: string;
279
+ };
280
+ "server-module-marks-server-only": {
281
+ code: string;
282
+ en: string;
283
+ fix: string;
284
+ };
285
+ "no-server-action": {
286
+ code: string;
287
+ en: string;
288
+ fix: string;
289
+ };
290
+ "web-storage-only-in-modules": {
291
+ code: string;
292
+ en: string;
293
+ fix: string;
294
+ };
295
+ "no-dangerous-html": {
296
+ code: string;
297
+ en: string;
298
+ fix: string;
299
+ };
300
+ "response-cookie-attributes": {
301
+ code: string;
302
+ en: string;
303
+ fix: string;
304
+ };
305
+ "props-fields-readonly": {
306
+ code: string;
307
+ en: string;
308
+ fix: string;
309
+ };
310
+ "no-native-img": {
311
+ code: string;
312
+ en: string;
313
+ fix: string;
314
+ };
315
+ "image-has-size": {
316
+ code: string;
317
+ en: string;
318
+ fix: string;
319
+ };
320
+ "outcome-kinds-exhaustive": {
321
+ code: string;
322
+ en: string;
323
+ fix: string;
324
+ };
325
+ "one-outcome-union": {
326
+ code: string;
327
+ en: string;
328
+ fix: string;
329
+ };
330
+ "i18n-stack-in-one-module": {
331
+ code: string;
332
+ en: string;
333
+ fix: string;
334
+ };
335
+ "no-app-relative-clock": {
336
+ code: string;
337
+ en: string;
338
+ fix: string;
339
+ };
340
+ "fe-stack-import": {
341
+ code: string;
342
+ en: string;
343
+ fix: string;
344
+ };
345
+ "file-size-growth": {
346
+ code: string;
347
+ en: string;
348
+ fix: string;
349
+ };
350
+ };