@cplieger/deadset-ts 8.0.0-dev.1 → 8.0.0-dev.10

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 (276) hide show
  1. package/README.md +1 -1
  2. package/dist/bin/mapper-connection.js +2 -1
  3. package/dist/bin/node-host.js +24 -5
  4. package/dist/src/analysis.js +181 -341
  5. package/dist/src/augmentations.js +106 -13
  6. package/dist/src/automatic-types.js +10 -29
  7. package/dist/src/build-scripts.js +425 -0
  8. package/dist/src/component-layer.js +4 -2
  9. package/dist/src/components.js +2 -3
  10. package/dist/src/config.js +6 -82
  11. package/dist/src/configuration-files.js +28 -176
  12. package/dist/src/configured-declarations.js +15 -20
  13. package/dist/src/conformance-record.js +1 -1
  14. package/dist/src/consumers.js +3 -30
  15. package/dist/src/contextual-uses.js +56 -9
  16. package/dist/src/contract/config.generated.js +558 -0
  17. package/dist/src/contract/contract.generated.js +1244 -0
  18. package/dist/src/contract/report.generated.js +862 -0
  19. package/dist/src/convention-rows.js +73 -3
  20. package/dist/src/conventions.js +36 -66
  21. package/dist/src/dependencies.js +103 -40
  22. package/dist/src/edges.js +38 -122
  23. package/dist/src/element-access.js +4 -6
  24. package/dist/src/entry-point-gaps.js +2 -8
  25. package/dist/src/entry-points.js +11 -27
  26. package/dist/src/enum-group.js +3 -10
  27. package/dist/src/erased-stores.js +4 -6
  28. package/dist/src/exempt-classes.js +1 -63
  29. package/dist/src/exempt.js +21 -40
  30. package/dist/src/failure.js +36 -0
  31. package/dist/src/file-facts.js +2 -25
  32. package/dist/src/findings/completion.js +139 -72
  33. package/dist/src/findings/dependencies-and-module-machinery.js +4 -5
  34. package/dist/src/findings/emitters.js +5 -5
  35. package/dist/src/findings/interfaces.js +4 -5
  36. package/dist/src/findings/intra-function.js +13 -10
  37. package/dist/src/findings/non-code-artifacts.js +7 -8
  38. package/dist/src/findings/reads-and-writes.js +16 -13
  39. package/dist/src/findings/self-check.js +10 -12
  40. package/dist/src/findings/unused-declarations.js +41 -32
  41. package/dist/src/findings/visibility-narrowing.js +19 -16
  42. package/dist/src/findings-pass.js +8 -15
  43. package/dist/src/framework-lifecycle.js +7 -7
  44. package/dist/src/fs/document.js +52 -0
  45. package/dist/src/fs/manifest.js +72 -0
  46. package/dist/src/fs/tree.js +88 -0
  47. package/dist/src/generated-file.js +7 -4
  48. package/dist/src/git-ignore.js +39 -26
  49. package/dist/src/graph.js +5 -3
  50. package/dist/src/html-entries.js +6 -33
  51. package/dist/src/in-operands.js +2 -1
  52. package/dist/src/index.js +1 -1
  53. package/dist/src/injection-container.js +1 -1
  54. package/dist/src/intra-function-parts.js +63 -43
  55. package/dist/src/inventory.js +2 -21
  56. package/dist/src/javascript-file.js +33 -0
  57. package/dist/src/json-document.js +198 -67
  58. package/dist/src/keyof-comparisons.js +4 -6
  59. package/dist/src/kinds.js +3 -366
  60. package/dist/src/load/classify.js +270 -0
  61. package/dist/src/load/diagnostics.js +80 -0
  62. package/dist/src/load/discover.js +277 -0
  63. package/dist/src/{emit-map.js → load/emit-map.js} +1 -1
  64. package/dist/src/load/expected-module.js +136 -0
  65. package/dist/src/load/load.js +27 -0
  66. package/dist/src/load/module-lookup.js +37 -0
  67. package/dist/src/load/plan.js +313 -0
  68. package/dist/src/load/specifiers.js +115 -0
  69. package/dist/src/load/synthesize.js +140 -0
  70. package/dist/src/load/test-globals.js +207 -0
  71. package/dist/src/load/test-joins.js +82 -0
  72. package/dist/src/{workspace-manifests.js → load/workspace-manifests.js} +4 -4
  73. package/dist/src/{workspace-programs.js → load/workspace-programs.js} +89 -66
  74. package/dist/src/{workspace-resolution.js → load/workspace-resolution.js} +23 -65
  75. package/dist/src/{workspace-run.js → load/workspace-run.js} +7 -7
  76. package/dist/src/{workspace.js → load/workspace.js} +62 -124
  77. package/dist/src/manifest.js +49 -54
  78. package/dist/src/matrix.js +76 -4
  79. package/dist/src/mdx-entries.js +3 -26
  80. package/dist/src/outside-tests.js +1 -1
  81. package/dist/src/partial.js +2 -1
  82. package/dist/src/paths.js +26 -15
  83. package/dist/src/position.js +2 -1
  84. package/dist/src/print.js +11 -79
  85. package/dist/src/product.js +13 -0
  86. package/dist/src/query.js +1 -0
  87. package/dist/src/ref.js +1 -0
  88. package/dist/src/references.js +48 -30
  89. package/dist/src/report-schema.js +51 -0
  90. package/dist/src/report.js +57 -41
  91. package/dist/src/reporters/annotations.js +15 -8
  92. package/dist/src/reporters/sarif.js +16 -10
  93. package/dist/src/reporters/template.js +4 -19
  94. package/dist/src/resolve.js +245 -729
  95. package/dist/src/roots.js +273 -87
  96. package/dist/src/run.js +66 -77
  97. package/dist/src/schema.js +320 -343
  98. package/dist/src/scope.js +38 -115
  99. package/dist/src/serialization-contract.js +595 -21
  100. package/dist/src/session.js +34 -29
  101. package/dist/src/source-files.js +1 -1
  102. package/dist/src/suppress-file.js +25 -28
  103. package/dist/src/suppress-inline.js +3 -2
  104. package/dist/src/suppress.js +33 -51
  105. package/dist/src/sweep.js +7 -9
  106. package/dist/src/symbol-keys.js +3 -5
  107. package/dist/src/template-field.js +9 -19
  108. package/dist/src/test-support.js +8 -11
  109. package/dist/src/text/compare.js +26 -0
  110. package/dist/src/text/glob.js +194 -0
  111. package/dist/src/text/named-files.js +54 -0
  112. package/dist/src/text/shell.js +159 -0
  113. package/dist/src/text/yaml.js +393 -0
  114. package/dist/src/type-errors.js +11 -232
  115. package/dist/src/unseen-loads.js +100 -0
  116. package/dist/src/unwrap.js +23 -0
  117. package/dist/src/usage.js +10 -0
  118. package/dist/src/verbs/analyze.js +166 -126
  119. package/dist/src/verbs/describe.js +9 -16
  120. package/dist/src/verbs/explain.js +10 -7
  121. package/dist/src/verbs/print-config.js +2 -1
  122. package/dist/src/verbs/print-projects.js +6 -4
  123. package/dist/src/verbs/print-retained.js +4 -2
  124. package/dist/src/verbs/print-roots.js +4 -2
  125. package/dist/src/verbs/verb.js +1 -5
  126. package/dist/src/verbs/version.js +14 -3
  127. package/dist/src/workflow-steps.js +62 -64
  128. package/jsr.json +1 -1
  129. package/package.json +4 -3
  130. package/src/analysis.ts +245 -502
  131. package/src/augmentations.ts +135 -17
  132. package/src/automatic-types.ts +11 -29
  133. package/src/build-scripts.ts +543 -0
  134. package/src/component-layer.ts +4 -2
  135. package/src/components.ts +2 -4
  136. package/src/config.ts +31 -302
  137. package/src/configuration-files.ts +34 -179
  138. package/src/configured-declarations.ts +18 -23
  139. package/src/conformance-record.ts +1 -1
  140. package/src/consumers.ts +6 -57
  141. package/src/contextual-uses.ts +64 -12
  142. package/src/contract/config.generated.ts +818 -0
  143. package/src/contract/contract.generated.ts +1308 -0
  144. package/src/contract/report.generated.ts +1237 -0
  145. package/src/convention-rows.ts +85 -3
  146. package/src/conventions.ts +46 -84
  147. package/src/dependencies.ts +118 -46
  148. package/src/edges.ts +41 -140
  149. package/src/element-access.ts +4 -7
  150. package/src/entry-point-gaps.ts +3 -9
  151. package/src/entry-points.ts +12 -38
  152. package/src/enum-group.ts +2 -11
  153. package/src/erased-stores.ts +3 -7
  154. package/src/exempt-classes.ts +1 -75
  155. package/src/exempt.ts +36 -50
  156. package/src/failure.ts +63 -0
  157. package/src/file-facts.ts +9 -24
  158. package/src/finding.ts +14 -9
  159. package/src/findings/boundary.ts +2 -0
  160. package/src/findings/completion.ts +181 -84
  161. package/src/findings/dependencies-and-module-machinery.ts +4 -7
  162. package/src/findings/emitter.ts +8 -9
  163. package/src/findings/emitters.ts +7 -7
  164. package/src/findings/interfaces.ts +4 -6
  165. package/src/findings/intra-function.ts +13 -11
  166. package/src/findings/non-code-artifacts.ts +9 -11
  167. package/src/findings/reads-and-writes.ts +20 -16
  168. package/src/findings/self-check.ts +11 -17
  169. package/src/findings/unused-declarations.ts +45 -32
  170. package/src/findings/visibility-narrowing.ts +20 -17
  171. package/src/findings-pass.ts +10 -19
  172. package/src/framework-lifecycle.ts +7 -7
  173. package/src/fs/document.ts +70 -0
  174. package/src/fs/manifest.ts +92 -0
  175. package/src/fs/tree.ts +110 -0
  176. package/src/generated-file.ts +7 -4
  177. package/src/git-ignore.ts +50 -26
  178. package/src/graph.ts +5 -3
  179. package/src/host.ts +12 -5
  180. package/src/html-entries.ts +6 -33
  181. package/src/in-operands.ts +2 -1
  182. package/src/index.ts +1 -1
  183. package/src/injection-container.ts +1 -1
  184. package/src/intra-function-parts.ts +73 -44
  185. package/src/inventory.ts +2 -20
  186. package/src/javascript-file.ts +37 -0
  187. package/src/json-document.ts +241 -76
  188. package/src/keyof-comparisons.ts +3 -7
  189. package/src/kinds.ts +5 -413
  190. package/src/load/classify.ts +397 -0
  191. package/src/load/diagnostics.ts +144 -0
  192. package/src/load/discover.ts +455 -0
  193. package/src/{emit-map.ts → load/emit-map.ts} +1 -1
  194. package/src/load/expected-module.ts +188 -0
  195. package/src/load/load.ts +73 -0
  196. package/src/load/module-lookup.ts +50 -0
  197. package/src/load/plan.ts +504 -0
  198. package/src/load/specifiers.ts +168 -0
  199. package/src/load/synthesize.ts +211 -0
  200. package/src/load/test-globals.ts +251 -0
  201. package/src/load/test-joins.ts +98 -0
  202. package/src/{workspace-manifests.ts → load/workspace-manifests.ts} +5 -5
  203. package/src/{workspace-programs.ts → load/workspace-programs.ts} +128 -85
  204. package/src/{workspace-resolution.ts → load/workspace-resolution.ts} +33 -76
  205. package/src/{workspace-run.ts → load/workspace-run.ts} +18 -16
  206. package/src/{workspace.ts → load/workspace.ts} +90 -134
  207. package/src/manifest.ts +81 -75
  208. package/src/matrix.ts +122 -4
  209. package/src/mdx-entries.ts +3 -26
  210. package/src/outside-tests.ts +1 -1
  211. package/src/partial.ts +3 -2
  212. package/src/paths.ts +27 -15
  213. package/src/position.ts +2 -1
  214. package/src/print.ts +12 -92
  215. package/src/product.ts +18 -0
  216. package/src/query.ts +11 -0
  217. package/src/ref.ts +1 -0
  218. package/src/references.ts +52 -31
  219. package/src/report-schema.ts +68 -0
  220. package/src/report.ts +101 -224
  221. package/src/reporters/annotations.ts +22 -11
  222. package/src/reporters/json.ts +1 -1
  223. package/src/reporters/reporter.ts +2 -4
  224. package/src/reporters/reporters.ts +1 -1
  225. package/src/reporters/sarif.ts +29 -16
  226. package/src/reporters/template.ts +4 -20
  227. package/src/reporters/text.ts +3 -3
  228. package/src/resolve.ts +283 -1114
  229. package/src/roots.ts +339 -104
  230. package/src/run.ts +75 -91
  231. package/src/schema.ts +391 -388
  232. package/src/scope.ts +46 -138
  233. package/src/serialization-contract.ts +763 -22
  234. package/src/session.ts +70 -54
  235. package/src/source-files.ts +1 -1
  236. package/src/suppress-file.ts +24 -33
  237. package/src/suppress-inline.ts +2 -2
  238. package/src/suppress.ts +43 -58
  239. package/src/sweep.ts +23 -9
  240. package/src/symbol-keys.ts +2 -5
  241. package/src/template-field.ts +15 -25
  242. package/src/test-support.ts +17 -13
  243. package/src/text/compare.ts +27 -0
  244. package/src/text/glob.ts +210 -0
  245. package/src/text/named-files.inputs.json +1522 -0
  246. package/src/text/named-files.ts +68 -0
  247. package/src/text/shell.ts +161 -0
  248. package/src/text/yaml.ts +423 -0
  249. package/src/type-errors.ts +18 -288
  250. package/src/unseen-loads.ts +134 -0
  251. package/src/unwrap.ts +34 -0
  252. package/src/usage.ts +10 -0
  253. package/src/verbs/analyze.ts +224 -162
  254. package/src/verbs/describe.ts +14 -15
  255. package/src/verbs/explain.ts +10 -11
  256. package/src/verbs/print-config.ts +2 -1
  257. package/src/verbs/print-projects.ts +6 -4
  258. package/src/verbs/print-retained.ts +4 -2
  259. package/src/verbs/print-roots.ts +4 -2
  260. package/src/verbs/verb.ts +2 -8
  261. package/src/verbs/version.ts +15 -3
  262. package/src/workflow-steps.ts +74 -64
  263. package/dist/src/base-url.js +0 -18
  264. package/dist/src/discover.js +0 -468
  265. package/dist/src/glob.js +0 -65
  266. package/dist/src/pnpm-workspace.js +0 -120
  267. package/dist/src/setup-failure.js +0 -23
  268. package/dist/src/test-joins.js +0 -101
  269. package/dist/src/version.js +0 -7
  270. package/src/base-url.ts +0 -24
  271. package/src/discover.ts +0 -653
  272. package/src/glob.ts +0 -67
  273. package/src/pnpm-workspace.ts +0 -135
  274. package/src/setup-failure.ts +0 -39
  275. package/src/test-joins.ts +0 -120
  276. package/src/version.ts +0 -7
@@ -140,14 +140,16 @@ export interface ConventionRow {
140
140
  readonly manifestEntries?: readonly ManifestEntryKey[];
141
141
  /** The settings that make the tool's output import a runtime helper package. */
142
142
  readonly helpers?: readonly HelperReading[];
143
+ /** Whether the tool bundles the package's modules, so it resolves them as a bundler does. */
144
+ readonly bundles?: true;
143
145
  }
144
146
 
145
147
  const SCRIPT = "{js,jsx,ts,tsx}";
146
148
  const MODULE = "{js,mjs,ts,mts}";
147
149
  const ANY_MODULE = "{js,mjs,cjs,ts,mts,cts}";
148
150
  const VITE_CONFIG = `vite.config.${ANY_MODULE}`;
149
- /** The legacy configuration files of ESLint that hold JSON or a CommonJS module. */
150
- const ESLINTRC = [".eslintrc", ".eslintrc.json", ".eslintrc.{js,cjs}"];
151
+ /** The legacy configuration files of ESLint: JSON, YAML or a CommonJS module. */
152
+ const ESLINTRC = [".eslintrc", ".eslintrc.json", ".eslintrc.{yml,yaml}", ".eslintrc.{js,cjs}"];
151
153
 
152
154
  const SVELTEKIT_ROUTE_FILES = "+{page,layout,server,page.server,layout.server,error}";
153
155
 
@@ -209,6 +211,60 @@ const ANGULAR_PACKAGE_KEYS: readonly PackageKey[] = [
209
211
  "scripts",
210
212
  ].map((key) => ({ key, files: ["angular.json"] }));
211
213
 
214
+ /**
215
+ * The row of a code generator that writes its output below one directory its
216
+ * configuration's `property` sets, `fallback` where no configuration file sets it, so
217
+ * every file there is a generated file.
218
+ */
219
+ function outputDirectoryRow(row: {
220
+ readonly name: string;
221
+ readonly package: string;
222
+ readonly range: string;
223
+ readonly files: readonly string[];
224
+ readonly property: string;
225
+ readonly fallback: string;
226
+ }): ConventionRow {
227
+ return {
228
+ name: row.name,
229
+ package: row.package,
230
+ range: row.range,
231
+ entries: [],
232
+ generated: ["<output>"],
233
+ moves: [
234
+ {
235
+ id: "output",
236
+ defaults: [row.fallback],
237
+ readings: [{ property: row.property, files: row.files }],
238
+ },
239
+ ],
240
+ };
241
+ }
242
+
243
+ /**
244
+ * The test runners and the assertion, mock and runner libraries whose import is test
245
+ * evidence beside each runner a row reads test files for. Each applies whether or not a
246
+ * manifest declares it, so none is a row.
247
+ */
248
+ export const TEST_LIBRARIES: readonly string[] = [
249
+ "@jest/globals",
250
+ "@playwright/test",
251
+ "ava",
252
+ "chai",
253
+ "expect",
254
+ "jasmine",
255
+ "jest",
256
+ "mocha",
257
+ "msw",
258
+ "nock",
259
+ "node:test",
260
+ "sinon",
261
+ "tap",
262
+ "uvu",
263
+ ];
264
+
265
+ /** The scopes every package of which is a test library. */
266
+ export const TEST_LIBRARY_SCOPES: readonly string[] = ["@testing-library/"];
267
+
212
268
  /** Every row, ordered by name and then by range. */
213
269
  export const CONVENTION_ROWS: readonly ConventionRow[] = [
214
270
  {
@@ -229,6 +285,7 @@ export const CONVENTION_ROWS: readonly ConventionRow[] = [
229
285
  },
230
286
  {
231
287
  name: "astro",
288
+ bundles: true,
232
289
  package: "astro",
233
290
  range: ">=5.0.0 <8.0.0",
234
291
  entries: [
@@ -274,6 +331,7 @@ export const CONVENTION_ROWS: readonly ConventionRow[] = [
274
331
  range: ">=4.0.0 <10.0.0",
275
332
  entries: [],
276
333
  moves: [],
334
+ packageKeys: [{ key: "parser", files: ESLINTRC }],
277
335
  prefixedNames: [
278
336
  { property: "plugins", files: ESLINTRC, prefix: "eslint-plugin" },
279
337
  { property: "extends", files: ESLINTRC, prefix: "eslint-plugin", marker: "plugin:" },
@@ -297,12 +355,13 @@ export const CONVENTION_ROWS: readonly ConventionRow[] = [
297
355
  {
298
356
  name: "expo-router",
299
357
  package: "expo-router",
300
- range: ">=3.0.0 <58.0.0",
358
+ range: ">=3.0.0 <59.0.0",
301
359
  entries: [`{,src/}app/**/*.${SCRIPT}`],
302
360
  moves: [],
303
361
  },
304
362
  {
305
363
  name: "next",
364
+ bundles: true,
306
365
  package: "next",
307
366
  range: ">=13.4.0 <17.0.0",
308
367
  generated: [".next"],
@@ -320,6 +379,7 @@ export const CONVENTION_ROWS: readonly ConventionRow[] = [
320
379
  },
321
380
  {
322
381
  name: "nuxt",
382
+ bundles: true,
323
383
  package: "nuxt",
324
384
  range: ">=3.0.0 <5.0.0",
325
385
  generated: [".nuxt"],
@@ -389,8 +449,17 @@ export const CONVENTION_ROWS: readonly ConventionRow[] = [
389
449
  { key: "oclif.hooks", directory: false },
390
450
  ],
391
451
  },
452
+ outputDirectoryRow({
453
+ name: "panda",
454
+ package: "@pandacss/dev",
455
+ range: ">=0.1.0 <2.0.0",
456
+ files: [`panda.config.${ANY_MODULE}`],
457
+ property: "outdir",
458
+ fallback: "styled-system",
459
+ }),
392
460
  {
393
461
  name: "parcel",
462
+ bundles: true,
394
463
  package: "parcel",
395
464
  range: ">=2.0.0 <3.0.0",
396
465
  entries: [],
@@ -456,6 +525,13 @@ export const CONVENTION_ROWS: readonly ConventionRow[] = [
456
525
  },
457
526
  ],
458
527
  },
528
+ {
529
+ name: "react-scripts",
530
+ package: "react-scripts",
531
+ range: ">=1.0.0 <6.0.0",
532
+ entries: [`src/index.${SCRIPT}`, "src/setupProxy.js", `src/setupTests.${SCRIPT}`],
533
+ moves: [],
534
+ },
459
535
  {
460
536
  name: "remix",
461
537
  package: "@remix-run/dev",
@@ -483,6 +559,7 @@ export const CONVENTION_ROWS: readonly ConventionRow[] = [
483
559
  },
484
560
  {
485
561
  name: "rolldown",
562
+ bundles: true,
486
563
  package: "rolldown",
487
564
  range: ">=1.0.0 <2.0.0",
488
565
  entries: [],
@@ -528,6 +605,7 @@ export const CONVENTION_ROWS: readonly ConventionRow[] = [
528
605
  },
529
606
  {
530
607
  name: "storybook",
608
+ bundles: true,
531
609
  package: "storybook",
532
610
  range: ">=7.0.0 <11.0.0",
533
611
  entries: [
@@ -561,6 +639,7 @@ export const CONVENTION_ROWS: readonly ConventionRow[] = [
561
639
  },
562
640
  {
563
641
  name: "sveltekit",
642
+ bundles: true,
564
643
  package: "@sveltejs/kit",
565
644
  range: ">=2.0.0 <3.0.0",
566
645
  entries: [...SVELTEKIT_ENTRIES, "<params>/*.{js,ts}"],
@@ -626,6 +705,7 @@ export const CONVENTION_ROWS: readonly ConventionRow[] = [
626
705
  },
627
706
  {
628
707
  name: "sveltekit",
708
+ bundles: true,
629
709
  package: "@sveltejs/kit",
630
710
  range: ">=3.0.0 <4.0.0",
631
711
  entries: [...SVELTEKIT_ENTRIES, "<params>.{js,ts}"],
@@ -718,6 +798,7 @@ export const CONVENTION_ROWS: readonly ConventionRow[] = [
718
798
  },
719
799
  {
720
800
  name: "vite",
801
+ bundles: true,
721
802
  package: "vite",
722
803
  range: ">=8.0.0 <9.0.0",
723
804
  entries: [],
@@ -733,6 +814,7 @@ export const CONVENTION_ROWS: readonly ConventionRow[] = [
733
814
  },
734
815
  {
735
816
  name: "vitepress",
817
+ bundles: true,
736
818
  package: "vitepress",
737
819
  range: ">=1.0.0 <2.0.0-0 || >=2.0.0-alpha.0 <3.0.0",
738
820
  entries: [
@@ -8,7 +8,6 @@
8
8
 
9
9
  import {
10
10
  isArrayLiteralExpression,
11
- isAsExpression,
12
11
  isBinaryExpression,
13
12
  isCallExpression,
14
13
  isClassDeclaration,
@@ -22,27 +21,20 @@ import {
22
21
  isNamedExports,
23
22
  isNamespaceImport,
24
23
  isNoSubstitutionTemplateLiteral,
25
- isNonNullExpression,
26
24
  isNumericLiteral,
27
25
  isObjectBindingPattern,
28
26
  isObjectLiteralExpression,
29
- isParenthesizedExpression,
30
27
  isPropertyAccessExpression,
31
28
  isPropertyAssignment,
32
- isSatisfiesExpression,
33
29
  isShorthandPropertyAssignment,
34
30
  isSpreadAssignment,
35
31
  isStringLiteral,
36
32
  isVariableStatement,
37
33
  SyntaxKind,
38
- type AsExpression,
39
34
  type Identifier,
40
35
  type Node,
41
36
  type ObjectBindingPattern,
42
- type NonNullExpression,
43
37
  type ObjectLiteralExpression,
44
- type ParenthesizedExpression,
45
- type SatisfiesExpression,
46
38
  type SourceFile,
47
39
  } from "@typescript/native/ast";
48
40
  import { lineOf } from "./component-files.ts";
@@ -60,12 +52,25 @@ import {
60
52
  type TestFileReading,
61
53
  } from "./convention-rows.ts";
62
54
  import { documentStrings } from "./configuration-files.ts";
63
- import { globExpression } from "./glob.ts";
64
55
  import type { Host } from "./host.ts";
65
- import { dirnamePath, joinPath, normalizePath, relativePath, resolvePath } from "./paths.ts";
66
- import type { SetupFailure } from "./setup-failure.ts";
56
+ import {
57
+ ancestors,
58
+ dirnamePath,
59
+ joinPath,
60
+ normalizePath,
61
+ relativePath,
62
+ resolvePath,
63
+ } from "./paths.ts";
64
+ import type { Failure } from "./failure.ts";
67
65
  import type { SourceFiles } from "./source-files.ts";
68
66
  import { satisfies } from "./version-range.ts";
67
+ import { bytewise } from "./text/compare.ts";
68
+ import { isRecord } from "./json-document.ts";
69
+ import { unwrapped } from "./unwrap.ts";
70
+ import { filesIn } from "./fs/tree.ts";
71
+ import { DEPENDENCY_SECTIONS, INSTALLED_PACKAGES, MANIFEST, readJSON } from "./fs/manifest.ts";
72
+ import { globExpression } from "./text/glob.ts";
73
+ import { yamlDocument } from "./text/yaml.ts";
69
74
 
70
75
  /** One manifest the analysis reads. */
71
76
  export interface ConventionManifest {
@@ -110,7 +115,7 @@ interface GeneratedDirectory {
110
115
  /** A setup failure a row met, at the directory of the manifest that declared it. */
111
116
  interface ConventionFailure {
112
117
  readonly dir: string;
113
- readonly failure: SetupFailure;
118
+ readonly failure: Failure;
114
119
  }
115
120
 
116
121
  /** What the rows decided for one run. */
@@ -151,30 +156,19 @@ type ParseSource = (fileName: string, text: string) => SourceFile;
151
156
 
152
157
  const JSON_EXTENSION = ".json";
153
158
 
159
+ /**
160
+ * A configuration file its tool reads as a YAML document, read as the JSON document it
161
+ * denotes. Its nodes' offsets are that JSON text's, so no move may read one: a failure's
162
+ * line would name the wrong line.
163
+ */
164
+ const YAML_NAME = /\.ya?ml$/u;
165
+
154
166
  /** A configuration file with no extension that its tool reads as a JSON document. */
155
167
  const JSON_RC = /^\.[\w-]+rc$/u;
156
168
 
157
169
  /** The sections an installed package is required by, so its absence fails the run. */
158
170
  const REQUIRED_SECTIONS = ["dependencies", "devDependencies"] as const;
159
171
 
160
- const DEPENDENCY_SECTIONS = [
161
- ...REQUIRED_SECTIONS,
162
- "peerDependencies",
163
- "optionalDependencies",
164
- ] as const;
165
-
166
- function isRecord(value: unknown): value is Record<string, unknown> {
167
- return typeof value === "object" && value !== null && !Array.isArray(value);
168
- }
169
-
170
- function readJSON(host: Host, path: string): unknown {
171
- try {
172
- return JSON.parse(host.readFile(path));
173
- } catch {
174
- return undefined;
175
- }
176
- }
177
-
178
172
  function declares(
179
173
  manifest: unknown,
180
174
  name: string,
@@ -195,38 +189,15 @@ function declares(
195
189
  * none, or `undefined` where no `node_modules` holds it.
196
190
  */
197
191
  function installedVersion(host: Host, dir: string, name: string): string | undefined {
198
- for (let at = normalizePath(dir); ; at = dirnamePath(at)) {
199
- const path = joinPath(at, "node_modules", name, "package.json");
192
+ for (const at of ancestors(dir)) {
193
+ const path = joinPath(at, INSTALLED_PACKAGES, name, MANIFEST);
200
194
  if (host.kindOf(path) === "file") {
201
195
  const manifest = readJSON(host, path);
202
196
  const version = isRecord(manifest) ? manifest["version"] : undefined;
203
197
  return typeof version === "string" ? version : "";
204
198
  }
205
- if (dirnamePath(at) === at) {
206
- return undefined;
207
- }
208
199
  }
209
- }
210
-
211
- /** Whether one node wraps an expression without changing its value. */
212
- function isWrapper(
213
- node: Node,
214
- ): node is ParenthesizedExpression | AsExpression | SatisfiesExpression | NonNullExpression {
215
- return (
216
- isParenthesizedExpression(node) ||
217
- isAsExpression(node) ||
218
- isSatisfiesExpression(node) ||
219
- isNonNullExpression(node)
220
- );
221
- }
222
-
223
- /** The expression a wrapper that changes no value holds. */
224
- function unwrapped(node: Node): Node {
225
- let at = node;
226
- while (isWrapper(at)) {
227
- at = at.expression;
228
- }
229
- return at;
200
+ return undefined;
230
201
  }
231
202
 
232
203
  /** The key one property is written with, where it is written as a name or as literal text. */
@@ -815,16 +786,7 @@ function expand(
815
786
  /** The configuration files in one directory that one glob names, by name. */
816
787
  function configurationFiles(host: Host, dir: string, glob: string): readonly string[] {
817
788
  const expression = globExpression(glob);
818
- let entries;
819
- try {
820
- entries = host.readDirectory(dir);
821
- } catch {
822
- return [];
823
- }
824
- return entries
825
- .filter((entry) => !entry.directory && expression.test(entry.name))
826
- .map((entry) => entry.name)
827
- .sort();
789
+ return filesIn(host, dir, (name) => expression.test(name));
828
790
  }
829
791
 
830
792
  /** What one move resolved to: its directories, or the failure its property met. */
@@ -883,6 +845,14 @@ function readingFiles(
883
845
  } catch {
884
846
  continue;
885
847
  }
848
+ if (YAML_NAME.test(name)) {
849
+ const value = yamlDocument(text);
850
+ if (value !== undefined) {
851
+ const json = JSON.stringify(value);
852
+ found.push({ name, text: json, file: parse(`${path}${JSON_EXTENSION}`, json) });
853
+ }
854
+ continue;
855
+ }
886
856
  found.push({
887
857
  name,
888
858
  text,
@@ -932,7 +902,7 @@ function shortNameUses(
932
902
  }
933
903
  }
934
904
  }
935
- return [...used].filter((name) => declared.has(name)).sort(compare);
905
+ return [...used].filter((name) => declared.has(name)).sort(bytewise);
936
906
  }
937
907
 
938
908
  /**
@@ -992,7 +962,7 @@ function prefixedNameUses(
992
962
  }
993
963
  }
994
964
  }
995
- return [...used].sort(compare);
965
+ return [...used].sort(bytewise);
996
966
  }
997
967
 
998
968
  /** The declared dependencies an applied row's helper settings use. */
@@ -1076,14 +1046,6 @@ function packageKeyUses(
1076
1046
  );
1077
1047
  }
1078
1048
 
1079
- /** Two strings ordered bytewise. */
1080
- function compare(a: string, b: string): number {
1081
- if (a === b) {
1082
- return 0;
1083
- }
1084
- return a < b ? -1 : 1;
1085
- }
1086
-
1087
1049
  /**
1088
1050
  * What the rows decide over the manifests the analysis reads. A row `disabled` names
1089
1051
  * is skipped before anything is read for it.
@@ -1103,7 +1065,7 @@ export function readConventions(
1103
1065
  const selected = new Map<string, { starts: Set<number>; texts: string[] }>();
1104
1066
  const testFiles = new Set<string>();
1105
1067
  for (const manifest of manifests) {
1106
- const declared = readJSON(host, joinPath(manifest.dir, "package.json"));
1068
+ const declared = readJSON(host, joinPath(manifest.dir, MANIFEST));
1107
1069
  const versions = new Map<string, string | undefined>();
1108
1070
  const missing = new Set<string>();
1109
1071
  for (const row of rows) {
@@ -1126,7 +1088,7 @@ export function readConventions(
1126
1088
  failures.push({
1127
1089
  dir: manifest.dir,
1128
1090
  failure: {
1129
- setupClass: "missing-module",
1091
+ failureClass: "missing-module",
1130
1092
  detail:
1131
1093
  `${manifest.path} declares ${row.package}, which no node_modules at or ` +
1132
1094
  `above its directory holds: run the package manager's install`,
@@ -1152,7 +1114,7 @@ export function readConventions(
1152
1114
  failures.push({
1153
1115
  dir: manifest.dir,
1154
1116
  failure: {
1155
- setupClass: "convention-not-literal",
1117
+ failureClass: "convention-not-literal",
1156
1118
  detail: where === "." ? failed : `${where}/${failed}`,
1157
1119
  },
1158
1120
  });
@@ -1206,16 +1168,16 @@ export function readConventions(
1206
1168
  const unique = [...new Map(applied.map((one) => [JSON.stringify(one), one])).values()];
1207
1169
  unique.sort(
1208
1170
  (a, b) =>
1209
- compare(a.name, b.name) ||
1210
- compare(a.manifest, b.manifest) ||
1211
- compare(JSON.stringify(a), JSON.stringify(b)),
1171
+ bytewise(a.name, b.name) ||
1172
+ bytewise(a.manifest, b.manifest) ||
1173
+ bytewise(JSON.stringify(a), JSON.stringify(b)),
1212
1174
  );
1213
1175
  return {
1214
1176
  applied: unique,
1215
1177
  globs,
1216
1178
  generated,
1217
1179
  failures,
1218
- uses: [...uses].sort(compare),
1180
+ uses: [...uses].sort(bytewise),
1219
1181
  selected,
1220
1182
  testFiles,
1221
1183
  };
@@ -1273,7 +1235,7 @@ export function conventionFailuresFor(
1273
1235
  conventions: Conventions,
1274
1236
  configFile: string,
1275
1237
  ownFiles: readonly string[],
1276
- ): readonly SetupFailure[] {
1238
+ ): readonly Failure[] {
1277
1239
  return conventions.failures
1278
1240
  .filter(
1279
1241
  ({ dir }) =>