@shivaedev/quality 0.23.0 → 0.25.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 (411) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +6 -2
  3. package/dist/baseline/compare.d.ts +2 -2
  4. package/dist/baseline/compare.d.ts.map +1 -1
  5. package/dist/baseline/compare.js +6 -4
  6. package/dist/baseline/compare.js.map +1 -1
  7. package/dist/baseline/format.d.ts +5 -5
  8. package/dist/baseline/format.d.ts.map +1 -1
  9. package/dist/baseline/format.js +23 -13
  10. package/dist/baseline/format.js.map +1 -1
  11. package/dist/baseline/legacy.d.ts +2 -2
  12. package/dist/baseline/legacy.d.ts.map +1 -1
  13. package/dist/baseline/legacy.js +4 -4
  14. package/dist/baseline/legacy.js.map +1 -1
  15. package/dist/baseline/rewrite.d.ts +1 -1
  16. package/dist/baseline/rewrite.d.ts.map +1 -1
  17. package/dist/baseline/rewrite.js +2 -2
  18. package/dist/baseline/rewrite.js.map +1 -1
  19. package/dist/baseline/update.d.ts +2 -2
  20. package/dist/baseline/update.d.ts.map +1 -1
  21. package/dist/baseline/update.js +27 -21
  22. package/dist/baseline/update.js.map +1 -1
  23. package/dist/cli/args.d.ts +2 -4
  24. package/dist/cli/args.d.ts.map +1 -1
  25. package/dist/cli/args.js +19 -18
  26. package/dist/cli/args.js.map +1 -1
  27. package/dist/cli/baseline.d.ts +1 -1
  28. package/dist/cli/baseline.d.ts.map +1 -1
  29. package/dist/cli/baseline.js +10 -6
  30. package/dist/cli/baseline.js.map +1 -1
  31. package/dist/cli/fix.d.ts +2 -2
  32. package/dist/cli/fix.d.ts.map +1 -1
  33. package/dist/cli/fix.js +35 -41
  34. package/dist/cli/fix.js.map +1 -1
  35. package/dist/cli/lint.d.ts +1 -2
  36. package/dist/cli/lint.d.ts.map +1 -1
  37. package/dist/cli/lint.js +1 -2
  38. package/dist/cli/lint.js.map +1 -1
  39. package/dist/cli/messages.d.ts +1 -1
  40. package/dist/cli/messages.d.ts.map +1 -1
  41. package/dist/cli/messages.js +2 -2
  42. package/dist/cli/migrate.d.ts.map +1 -1
  43. package/dist/cli/migrate.js +2 -2
  44. package/dist/cli/migrate.js.map +1 -1
  45. package/dist/cli/migrateExceptions.js +1 -1
  46. package/dist/cli/migrateExceptions.js.map +1 -1
  47. package/dist/cli/program.js +1 -1
  48. package/dist/cli/program.js.map +1 -1
  49. package/dist/cli/{run-main.d.ts → runMain.d.ts} +1 -1
  50. package/dist/cli/runMain.d.ts.map +1 -0
  51. package/dist/cli/{run-main.js → runMain.js} +3 -3
  52. package/dist/cli/runMain.js.map +1 -0
  53. package/dist/cli/shrink.d.ts +2 -2
  54. package/dist/cli/shrink.d.ts.map +1 -1
  55. package/dist/cli/shrink.js +9 -3
  56. package/dist/cli/shrink.js.map +1 -1
  57. package/dist/cli.js +1 -1
  58. package/dist/cli.js.map +1 -1
  59. package/dist/config/decode.d.ts +1 -1
  60. package/dist/config/decode.d.ts.map +1 -1
  61. package/dist/config/decode.js +13 -9
  62. package/dist/config/decode.js.map +1 -1
  63. package/dist/config/load.d.ts.map +1 -1
  64. package/dist/config/load.js +26 -20
  65. package/dist/config/load.js.map +1 -1
  66. package/dist/config/resolve.d.ts +23 -3
  67. package/dist/config/resolve.d.ts.map +1 -1
  68. package/dist/config/resolve.js +19 -11
  69. package/dist/config/resolve.js.map +1 -1
  70. package/dist/config.d.ts +3 -3
  71. package/dist/config.d.ts.map +1 -1
  72. package/dist/config.js +3 -1
  73. package/dist/config.js.map +1 -1
  74. package/dist/decoded.d.ts +3 -3
  75. package/dist/decoded.d.ts.map +1 -1
  76. package/dist/decoded.js +8 -6
  77. package/dist/decoded.js.map +1 -1
  78. package/dist/engine/{baseline-file.d.ts → baselineFile.d.ts} +2 -2
  79. package/dist/engine/baselineFile.d.ts.map +1 -0
  80. package/dist/engine/{baseline-file.js → baselineFile.js} +5 -3
  81. package/dist/engine/baselineFile.js.map +1 -0
  82. package/dist/engine/evaluate.d.ts +2 -3
  83. package/dist/engine/evaluate.d.ts.map +1 -1
  84. package/dist/engine/evaluate.js +6 -5
  85. package/dist/engine/evaluate.js.map +1 -1
  86. package/dist/engine/{run-rules.d.ts → runRules.d.ts} +2 -2
  87. package/dist/engine/runRules.d.ts.map +1 -0
  88. package/dist/engine/runRules.js +44 -0
  89. package/dist/engine/runRules.js.map +1 -0
  90. package/dist/engine/session.d.ts +1 -1
  91. package/dist/engine/session.d.ts.map +1 -1
  92. package/dist/engine/session.js +10 -6
  93. package/dist/engine/session.js.map +1 -1
  94. package/dist/engine/violation.d.ts +8 -8
  95. package/dist/engine/violation.d.ts.map +1 -1
  96. package/dist/engine/violation.js +23 -11
  97. package/dist/engine/violation.js.map +1 -1
  98. package/dist/exceptions/registry.d.ts +2 -2
  99. package/dist/exceptions/registry.d.ts.map +1 -1
  100. package/dist/exceptions/registry.js +10 -6
  101. package/dist/exceptions/registry.js.map +1 -1
  102. package/dist/git/base.d.ts +1 -2
  103. package/dist/git/base.d.ts.map +1 -1
  104. package/dist/git/base.js +22 -10
  105. package/dist/git/base.js.map +1 -1
  106. package/dist/git/command.d.ts +2 -2
  107. package/dist/git/command.d.ts.map +1 -1
  108. package/dist/git/command.js +13 -9
  109. package/dist/git/command.js.map +1 -1
  110. package/dist/git/history.d.ts +1 -1
  111. package/dist/git/history.d.ts.map +1 -1
  112. package/dist/git/history.js +5 -3
  113. package/dist/git/history.js.map +1 -1
  114. package/dist/hooks/preCommit.js +1 -1
  115. package/dist/hooks/preCommit.js.map +1 -1
  116. package/dist/imports/generated.js +1 -1
  117. package/dist/imports/generated.js.map +1 -1
  118. package/dist/imports/{pnpm-workspace.d.ts → pnpmWorkspacePatterns.d.ts} +1 -1
  119. package/dist/imports/pnpmWorkspacePatterns.d.ts.map +1 -0
  120. package/dist/imports/{pnpm-workspace.js → pnpmWorkspacePatterns.js} +1 -1
  121. package/dist/imports/pnpmWorkspacePatterns.js.map +1 -0
  122. package/dist/imports/resolve.js +1 -1
  123. package/dist/imports/resolve.js.map +1 -1
  124. package/dist/imports/workspace.js +1 -1
  125. package/dist/imports/workspace.js.map +1 -1
  126. package/dist/inventory/collect.d.ts +1 -1
  127. package/dist/inventory/collect.d.ts.map +1 -1
  128. package/dist/inventory/collect.js +8 -6
  129. package/dist/inventory/collect.js.map +1 -1
  130. package/dist/inventory/filesystem.d.ts +1 -1
  131. package/dist/inventory/filesystem.d.ts.map +1 -1
  132. package/dist/inventory/filesystem.js +11 -7
  133. package/dist/inventory/filesystem.js.map +1 -1
  134. package/dist/inventory/ignoreScope.d.ts +17 -0
  135. package/dist/inventory/ignoreScope.d.ts.map +1 -0
  136. package/dist/inventory/{ignore-scope.js → ignoreScope.js} +19 -10
  137. package/dist/inventory/ignoreScope.js.map +1 -0
  138. package/dist/inventory/walk.d.ts +1 -1
  139. package/dist/inventory/walk.d.ts.map +1 -1
  140. package/dist/inventory/walk.js +1 -1
  141. package/dist/inventory/walk.js.map +1 -1
  142. package/dist/manifests/sorted.d.ts +1 -1
  143. package/dist/manifests/sorted.d.ts.map +1 -1
  144. package/dist/manifests/sorted.js +15 -17
  145. package/dist/manifests/sorted.js.map +1 -1
  146. package/dist/report/plural.d.ts +1 -1
  147. package/dist/report/plural.d.ts.map +1 -1
  148. package/dist/report/plural.js +3 -1
  149. package/dist/report/plural.js.map +1 -1
  150. package/dist/report/render.d.ts +1 -3
  151. package/dist/report/render.d.ts.map +1 -1
  152. package/dist/report/render.js +30 -32
  153. package/dist/report/render.js.map +1 -1
  154. package/dist/report/stale.d.ts +1 -1
  155. package/dist/report/stale.d.ts.map +1 -1
  156. package/dist/report/stale.js +18 -8
  157. package/dist/report/stale.js.map +1 -1
  158. package/dist/rule.d.ts +14 -14
  159. package/dist/rule.d.ts.map +1 -1
  160. package/dist/rule.js +11 -9
  161. package/dist/rule.js.map +1 -1
  162. package/dist/rules/{built-in.d.ts → builtIn.d.ts} +3 -3
  163. package/dist/rules/builtIn.d.ts.map +1 -0
  164. package/dist/rules/{built-in.js → builtIn.js} +17 -13
  165. package/dist/rules/builtIn.js.map +1 -0
  166. package/dist/rules/comments/{pattern-rule.d.ts → definePattern.d.ts} +2 -2
  167. package/dist/rules/comments/definePattern.d.ts.map +1 -0
  168. package/dist/rules/comments/definePattern.js +18 -0
  169. package/dist/rules/comments/definePattern.js.map +1 -0
  170. package/dist/rules/comments/kinds.d.ts +4 -4
  171. package/dist/rules/comments/kinds.d.ts.map +1 -1
  172. package/dist/rules/comments/kinds.js +16 -8
  173. package/dist/rules/comments/kinds.js.map +1 -1
  174. package/dist/rules/comments/{max-per-file.d.ts → maxPerFile.d.ts} +1 -1
  175. package/dist/rules/comments/maxPerFile.d.ts.map +1 -0
  176. package/dist/rules/comments/{max-per-file.js → maxPerFile.js} +14 -10
  177. package/dist/rules/comments/maxPerFile.js.map +1 -0
  178. package/dist/rules/comments/{no-banner.d.ts → noBanner.d.ts} +1 -1
  179. package/dist/rules/comments/noBanner.d.ts.map +1 -0
  180. package/dist/rules/comments/{no-banner.js → noBanner.js} +2 -2
  181. package/dist/rules/comments/noBanner.js.map +1 -0
  182. package/dist/rules/comments/{no-environment-pragma.d.ts → noEnvironmentPragma.d.ts} +1 -1
  183. package/dist/rules/comments/noEnvironmentPragma.d.ts.map +1 -0
  184. package/dist/rules/comments/{no-environment-pragma.js → noEnvironmentPragma.js} +2 -2
  185. package/dist/rules/comments/noEnvironmentPragma.js.map +1 -0
  186. package/dist/rules/comments/{no-jsdoc.d.ts → noJsdoc.d.ts} +1 -1
  187. package/dist/rules/comments/noJsdoc.d.ts.map +1 -0
  188. package/dist/rules/comments/{no-jsdoc.js → noJsdoc.js} +1 -1
  189. package/dist/rules/comments/noJsdoc.js.map +1 -0
  190. package/dist/rules/comments/{no-line-reference.d.ts → noLineReference.d.ts} +1 -1
  191. package/dist/rules/comments/noLineReference.d.ts.map +1 -0
  192. package/dist/rules/comments/{no-line-reference.js → noLineReference.js} +2 -2
  193. package/dist/rules/comments/noLineReference.js.map +1 -0
  194. package/dist/rules/comments/{no-pr-reference.d.ts → noPrReference.d.ts} +1 -1
  195. package/dist/rules/comments/noPrReference.d.ts.map +1 -0
  196. package/dist/rules/comments/{no-pr-reference.js → noPrReference.js} +2 -2
  197. package/dist/rules/comments/noPrReference.js.map +1 -0
  198. package/dist/rules/comments/{no-todo.d.ts → noTodo.d.ts} +1 -1
  199. package/dist/rules/comments/noTodo.d.ts.map +1 -0
  200. package/dist/rules/comments/{no-todo.js → noTodo.js} +2 -2
  201. package/dist/rules/comments/noTodo.js.map +1 -0
  202. package/dist/rules/comments/scan.d.ts +3 -3
  203. package/dist/rules/comments/scan.d.ts.map +1 -1
  204. package/dist/rules/comments/scan.js +23 -19
  205. package/dist/rules/comments/scan.js.map +1 -1
  206. package/dist/rules/{manifests-sorted.d.ts → manifestsSorted.d.ts} +1 -1
  207. package/dist/rules/manifestsSorted.d.ts.map +1 -0
  208. package/dist/rules/{manifests-sorted.js → manifestsSorted.js} +1 -1
  209. package/dist/rules/manifestsSorted.js.map +1 -0
  210. package/dist/rules/manifestsSourceFirst.d.ts +2 -0
  211. package/dist/rules/manifestsSourceFirst.d.ts.map +1 -0
  212. package/dist/rules/manifestsSourceFirst.js +43 -0
  213. package/dist/rules/manifestsSourceFirst.js.map +1 -0
  214. package/dist/rules/{max-lines.d.ts → maxLines.d.ts} +1 -1
  215. package/dist/rules/maxLines.d.ts.map +1 -0
  216. package/dist/rules/{max-lines.js → maxLines.js} +13 -11
  217. package/dist/rules/maxLines.js.map +1 -0
  218. package/dist/rules/stories/origins.d.ts +10 -0
  219. package/dist/rules/stories/origins.d.ts.map +1 -0
  220. package/dist/rules/stories/origins.js +129 -0
  221. package/dist/rules/stories/origins.js.map +1 -0
  222. package/dist/rules/stories/prerequisites.d.ts +4 -0
  223. package/dist/rules/stories/prerequisites.d.ts.map +1 -0
  224. package/dist/rules/stories/prerequisites.js +32 -0
  225. package/dist/rules/stories/prerequisites.js.map +1 -0
  226. package/dist/rules/stories/program.d.ts +5 -0
  227. package/dist/rules/stories/program.d.ts.map +1 -0
  228. package/dist/rules/stories/program.js +22 -0
  229. package/dist/rules/stories/program.js.map +1 -0
  230. package/dist/rules/stories/specs.d.ts +2 -0
  231. package/dist/rules/stories/specs.d.ts.map +1 -0
  232. package/dist/rules/stories/specs.js +80 -0
  233. package/dist/rules/stories/specs.js.map +1 -0
  234. package/dist/rules/suppressions/biome/configs.d.ts +1 -1
  235. package/dist/rules/suppressions/biome/configs.d.ts.map +1 -1
  236. package/dist/rules/suppressions/biome/configs.js +23 -17
  237. package/dist/rules/suppressions/biome/configs.js.map +1 -1
  238. package/dist/rules/suppressions/biome/declarations.d.ts +4 -4
  239. package/dist/rules/suppressions/biome/declarations.d.ts.map +1 -1
  240. package/dist/rules/suppressions/biome/declarations.js +15 -7
  241. package/dist/rules/suppressions/biome/declarations.js.map +1 -1
  242. package/dist/rules/suppressions/biome/json.d.ts +6 -6
  243. package/dist/rules/suppressions/biome/json.d.ts.map +1 -1
  244. package/dist/rules/suppressions/biome/json.js +27 -13
  245. package/dist/rules/suppressions/biome/json.js.map +1 -1
  246. package/dist/rules/suppressions/biome/resolve.d.ts +1 -1
  247. package/dist/rules/suppressions/biome/resolve.d.ts.map +1 -1
  248. package/dist/rules/suppressions/biome/resolve.js +23 -17
  249. package/dist/rules/suppressions/biome/resolve.js.map +1 -1
  250. package/dist/rules/suppressions/biome/weakenings.d.ts +1 -1
  251. package/dist/rules/suppressions/biome/weakenings.d.ts.map +1 -1
  252. package/dist/rules/suppressions/biome/weakenings.js +78 -52
  253. package/dist/rules/suppressions/biome/weakenings.js.map +1 -1
  254. package/dist/rules/suppressions/{biome-overrides.d.ts → biomeOverrides.d.ts} +1 -1
  255. package/dist/rules/suppressions/biomeOverrides.d.ts.map +1 -0
  256. package/dist/rules/suppressions/biomeOverrides.js +75 -0
  257. package/dist/rules/suppressions/biomeOverrides.js.map +1 -0
  258. package/dist/rules/suppressions/directives.d.ts +1 -1
  259. package/dist/rules/suppressions/directives.d.ts.map +1 -1
  260. package/dist/rules/suppressions/directives.js +5 -3
  261. package/dist/rules/suppressions/directives.js.map +1 -1
  262. package/dist/rules/suppressions/{no-double-cast.d.ts → noDoubleCast.d.ts} +1 -1
  263. package/dist/rules/suppressions/noDoubleCast.d.ts.map +1 -0
  264. package/dist/rules/suppressions/{no-double-cast.js → noDoubleCast.js} +15 -11
  265. package/dist/rules/suppressions/noDoubleCast.js.map +1 -0
  266. package/dist/rules/suppressions/noIgnoreDeprecations.js +1 -1
  267. package/dist/rules/suppressions/noIgnoreDeprecations.js.map +1 -1
  268. package/dist/rules/suppressions/{no-inline.d.ts → noInline.d.ts} +1 -1
  269. package/dist/rules/suppressions/noInline.d.ts.map +1 -0
  270. package/dist/rules/suppressions/{no-inline.js → noInline.js} +10 -8
  271. package/dist/rules/suppressions/noInline.js.map +1 -0
  272. package/dist/rules/suppressions/stylesheetComments.d.ts +4 -0
  273. package/dist/rules/suppressions/stylesheetComments.d.ts.map +1 -0
  274. package/dist/rules/suppressions/{stylesheet-comments.js → stylesheetComments.js} +12 -6
  275. package/dist/rules/suppressions/stylesheetComments.js.map +1 -0
  276. package/dist/rules/syntax.d.ts +1 -1
  277. package/dist/rules/syntax.d.ts.map +1 -1
  278. package/dist/rules/syntax.js +2 -2
  279. package/dist/rules/syntax.js.map +1 -1
  280. package/dist/{standard-schema.d.ts → standardSchema.d.ts} +7 -7
  281. package/dist/standardSchema.d.ts.map +1 -0
  282. package/dist/{standard-schema.js → standardSchema.js} +1 -1
  283. package/dist/standardSchema.js.map +1 -0
  284. package/docs/debt-and-hooks.md +2 -2
  285. package/docs/modules.md +27 -24
  286. package/docs/roadmap.md +1 -1
  287. package/docs/rules.md +2 -0
  288. package/package.json +2 -3
  289. package/src/baseline/compare.ts +6 -4
  290. package/src/baseline/format.ts +17 -10
  291. package/src/baseline/legacy.ts +4 -4
  292. package/src/baseline/rewrite.ts +2 -2
  293. package/src/baseline/update.ts +23 -19
  294. package/src/cli/args.ts +20 -21
  295. package/src/cli/baseline.ts +36 -35
  296. package/src/cli/fix.ts +40 -43
  297. package/src/cli/lint.ts +17 -21
  298. package/src/cli/messages.ts +2 -2
  299. package/src/cli/migrate.ts +21 -22
  300. package/src/cli/migrateExceptions.ts +1 -1
  301. package/src/cli/program.ts +1 -1
  302. package/src/cli/{run-main.ts → runMain.ts} +2 -2
  303. package/src/cli/shrink.ts +11 -8
  304. package/src/cli.ts +1 -1
  305. package/src/config/decode.ts +15 -10
  306. package/src/config/load.ts +44 -37
  307. package/src/config/resolve.ts +34 -29
  308. package/src/config.ts +5 -3
  309. package/src/decoded.ts +6 -5
  310. package/src/engine/baselineFile.ts +29 -0
  311. package/src/engine/evaluate.ts +7 -8
  312. package/src/engine/{run-rules.ts → runRules.ts} +22 -14
  313. package/src/engine/session.ts +34 -27
  314. package/src/engine/violation.ts +24 -13
  315. package/src/exceptions/registry.ts +10 -8
  316. package/src/git/base.ts +45 -37
  317. package/src/git/command.ts +6 -4
  318. package/src/git/history.ts +5 -4
  319. package/src/hooks/preCommit.ts +1 -1
  320. package/src/imports/generated.ts +1 -1
  321. package/src/imports/resolve.ts +1 -1
  322. package/src/imports/workspace.ts +1 -1
  323. package/src/inventory/collect.ts +40 -35
  324. package/src/inventory/filesystem.ts +38 -30
  325. package/src/inventory/{ignore-scope.ts → ignoreScope.ts} +20 -10
  326. package/src/inventory/walk.ts +1 -1
  327. package/src/manifests/sorted.ts +19 -19
  328. package/src/report/plural.ts +3 -1
  329. package/src/report/render.ts +24 -39
  330. package/src/report/stale.ts +33 -25
  331. package/src/rule.ts +26 -20
  332. package/src/rules/{built-in.ts → builtIn.ts} +16 -12
  333. package/src/rules/comments/{pattern-rule.ts → definePattern.ts} +5 -4
  334. package/src/rules/comments/kinds.ts +16 -9
  335. package/src/rules/comments/{max-per-file.ts → maxPerFile.ts} +15 -11
  336. package/src/rules/comments/{no-banner.ts → noBanner.ts} +1 -1
  337. package/src/rules/comments/{no-environment-pragma.ts → noEnvironmentPragma.ts} +1 -1
  338. package/src/rules/comments/{no-line-reference.ts → noLineReference.ts} +1 -1
  339. package/src/rules/comments/{no-pr-reference.ts → noPrReference.ts} +1 -1
  340. package/src/rules/comments/{no-todo.ts → noTodo.ts} +1 -1
  341. package/src/rules/comments/scan.ts +18 -15
  342. package/src/rules/manifestsSourceFirst.ts +48 -0
  343. package/src/rules/{max-lines.ts → maxLines.ts} +3 -2
  344. package/src/rules/stories/origins.ts +147 -0
  345. package/src/rules/stories/prerequisites.ts +37 -0
  346. package/src/rules/stories/program.ts +29 -0
  347. package/src/rules/stories/specs.ts +93 -0
  348. package/src/rules/suppressions/biome/configs.ts +23 -17
  349. package/src/rules/suppressions/biome/declarations.ts +15 -10
  350. package/src/rules/suppressions/biome/json.ts +25 -13
  351. package/src/rules/suppressions/biome/resolve.ts +23 -18
  352. package/src/rules/suppressions/biome/weakenings.ts +60 -41
  353. package/src/rules/suppressions/{biome-overrides.ts → biomeOverrides.ts} +32 -22
  354. package/src/rules/suppressions/directives.ts +5 -4
  355. package/src/rules/suppressions/{no-double-cast.ts → noDoubleCast.ts} +14 -10
  356. package/src/rules/suppressions/noIgnoreDeprecations.ts +1 -1
  357. package/src/rules/suppressions/{no-inline.ts → noInline.ts} +6 -5
  358. package/src/rules/suppressions/{stylesheet-comments.ts → stylesheetComments.ts} +11 -6
  359. package/src/rules/syntax.ts +2 -2
  360. package/src/{standard-schema.ts → standardSchema.ts} +4 -4
  361. package/dist/cli/run-main.d.ts.map +0 -1
  362. package/dist/cli/run-main.js.map +0 -1
  363. package/dist/engine/baseline-file.d.ts.map +0 -1
  364. package/dist/engine/baseline-file.js.map +0 -1
  365. package/dist/engine/run-rules.d.ts.map +0 -1
  366. package/dist/engine/run-rules.js +0 -34
  367. package/dist/engine/run-rules.js.map +0 -1
  368. package/dist/imports/pnpm-workspace.d.ts.map +0 -1
  369. package/dist/imports/pnpm-workspace.js.map +0 -1
  370. package/dist/inventory/ignore-scope.d.ts +0 -17
  371. package/dist/inventory/ignore-scope.d.ts.map +0 -1
  372. package/dist/inventory/ignore-scope.js.map +0 -1
  373. package/dist/rules/built-in.d.ts.map +0 -1
  374. package/dist/rules/built-in.js.map +0 -1
  375. package/dist/rules/comments/max-per-file.d.ts.map +0 -1
  376. package/dist/rules/comments/max-per-file.js.map +0 -1
  377. package/dist/rules/comments/no-banner.d.ts.map +0 -1
  378. package/dist/rules/comments/no-banner.js.map +0 -1
  379. package/dist/rules/comments/no-environment-pragma.d.ts.map +0 -1
  380. package/dist/rules/comments/no-environment-pragma.js.map +0 -1
  381. package/dist/rules/comments/no-jsdoc.d.ts.map +0 -1
  382. package/dist/rules/comments/no-jsdoc.js.map +0 -1
  383. package/dist/rules/comments/no-line-reference.d.ts.map +0 -1
  384. package/dist/rules/comments/no-line-reference.js.map +0 -1
  385. package/dist/rules/comments/no-pr-reference.d.ts.map +0 -1
  386. package/dist/rules/comments/no-pr-reference.js.map +0 -1
  387. package/dist/rules/comments/no-todo.d.ts.map +0 -1
  388. package/dist/rules/comments/no-todo.js.map +0 -1
  389. package/dist/rules/comments/pattern-rule.d.ts.map +0 -1
  390. package/dist/rules/comments/pattern-rule.js +0 -16
  391. package/dist/rules/comments/pattern-rule.js.map +0 -1
  392. package/dist/rules/manifests-sorted.d.ts.map +0 -1
  393. package/dist/rules/manifests-sorted.js.map +0 -1
  394. package/dist/rules/max-lines.d.ts.map +0 -1
  395. package/dist/rules/max-lines.js.map +0 -1
  396. package/dist/rules/suppressions/biome-overrides.d.ts.map +0 -1
  397. package/dist/rules/suppressions/biome-overrides.js +0 -63
  398. package/dist/rules/suppressions/biome-overrides.js.map +0 -1
  399. package/dist/rules/suppressions/no-double-cast.d.ts.map +0 -1
  400. package/dist/rules/suppressions/no-double-cast.js.map +0 -1
  401. package/dist/rules/suppressions/no-inline.d.ts.map +0 -1
  402. package/dist/rules/suppressions/no-inline.js.map +0 -1
  403. package/dist/rules/suppressions/stylesheet-comments.d.ts +0 -4
  404. package/dist/rules/suppressions/stylesheet-comments.d.ts.map +0 -1
  405. package/dist/rules/suppressions/stylesheet-comments.js.map +0 -1
  406. package/dist/standard-schema.d.ts.map +0 -1
  407. package/dist/standard-schema.js.map +0 -1
  408. package/src/engine/baseline-file.ts +0 -27
  409. /package/src/imports/{pnpm-workspace.ts → pnpmWorkspacePatterns.ts} +0 -0
  410. /package/src/rules/comments/{no-jsdoc.ts → noJsdoc.ts} +0 -0
  411. /package/src/rules/{manifests-sorted.ts → manifestsSorted.ts} +0 -0
@@ -3,15 +3,18 @@ import { type Decoded, decodeWith } from "#decoded.ts";
3
3
  import { ExceptionDeclaration } from "#exceptions/declaration.ts";
4
4
  import type { Rule } from "#rule.ts";
5
5
 
6
- const isRule = (value: unknown): value is Rule =>
7
- typeof value === "object"
8
- && value !== null
9
- && "id" in value
10
- && typeof value.id === "string"
11
- && "description" in value
12
- && typeof value.description === "string"
13
- && "configure" in value
14
- && typeof value.configure === "function";
6
+ function isRule(value: unknown): value is Rule {
7
+ return (
8
+ typeof value === "object"
9
+ && value !== null
10
+ && "id" in value
11
+ && typeof value.id === "string"
12
+ && "description" in value
13
+ && typeof value.description === "string"
14
+ && "configure" in value
15
+ && typeof value.configure === "function"
16
+ );
17
+ }
15
18
 
16
19
  const Level = Schema.Literal("error");
17
20
 
@@ -44,4 +47,6 @@ export type ConfigInput = typeof ConfigInput.Type;
44
47
 
45
48
  const standard = Schema.toStandardSchemaV1(ConfigInput, { parseOptions: { errors: "all", onExcessProperty: "error" } });
46
49
 
47
- export const decodeConfig = (value: unknown): Promise<Decoded<ConfigInput>> => decodeWith(standard, value);
50
+ export function decodeConfig(value: unknown): Promise<Decoded<ConfigInput>> {
51
+ return decodeWith(standard, value);
52
+ }
@@ -22,10 +22,12 @@ export interface ResolvedConfig extends ResolvedRules, InventoryScope {
22
22
  readonly root: string;
23
23
  }
24
24
 
25
- const messageOf = (cause: unknown): string => (cause instanceof Error ? cause.message : String(cause));
25
+ function messageOf(cause: unknown): string {
26
+ return cause instanceof Error ? cause.message : String(cause);
27
+ }
26
28
 
27
- const importDefault = (file: string): Effect.Effect<unknown, SetupFailure> =>
28
- Effect.flatMap(
29
+ function importDefault(file: string): Effect.Effect<unknown, SetupFailure> {
30
+ return Effect.flatMap(
29
31
  Effect.tryPromise({
30
32
  catch: (cause) => new SetupFailure({ message: `cannot load ${file}: ${messageOf(cause)}` }),
31
33
  try: async (): Promise<unknown> => import(pathToFileURL(file).href),
@@ -35,6 +37,7 @@ const importDefault = (file: string): Effect.Effect<unknown, SetupFailure> =>
35
37
  ? Effect.succeed(loaded.default)
36
38
  : Effect.fail(new SetupFailure({ message: `${file} has no default export. Export defineConfig({ ... }) as the default.` })),
37
39
  );
40
+ }
38
41
 
39
42
  const LegacyOptions = Schema.Struct({ declared: Schema.Array(ConsumerDeclaration) });
40
43
  function biomeDeclarations(config: ConfigInput): readonly Declaration[] {
@@ -43,38 +46,42 @@ function biomeDeclarations(config: ConfigInput): readonly Declaration[] {
43
46
  return Schema.is(LegacyOptions)(options) ? options.declared : [];
44
47
  }
45
48
 
46
- const resolved = (root: string, file: string, config: ConfigInput, rules: ResolvedRules): ResolvedConfig => ({
47
- ...rules,
48
- baseline: config.baseline ?? "quality/baseline.jsonl",
49
- biomeDeclarations: biomeDeclarations(config),
50
- exceptions: config.exceptions ?? [],
51
- exclude: [],
52
- extensions: config.extensions ?? DEFAULT_EXTENSIONS,
53
- file,
54
- registry: config.registry ?? "quality/registry.json",
55
- root,
56
- sources: config.sources ?? ["."],
57
- });
49
+ function resolved(root: string, file: string, config: ConfigInput, rules: ResolvedRules): ResolvedConfig {
50
+ return {
51
+ ...rules,
52
+ baseline: config.baseline ?? "quality/baseline.jsonl",
53
+ biomeDeclarations: biomeDeclarations(config),
54
+ exceptions: config.exceptions ?? [],
55
+ exclude: [],
56
+ extensions: config.extensions ?? DEFAULT_EXTENSIONS,
57
+ file,
58
+ registry: config.registry ?? "quality/registry.json",
59
+ root,
60
+ sources: config.sources ?? ["."],
61
+ };
62
+ }
58
63
 
59
- export const loadConfig = (cwd: string, path: string | undefined): Effect.Effect<ResolvedConfig, SetupFailure, FileSystem.FileSystem> =>
60
- Effect.gen(function* () {
61
- const fs = yield* FileSystem.FileSystem;
62
- const file = resolve(cwd, path ?? CONFIG_FILE);
63
- const entries = yield* fs
64
- .readDirectory(dirname(file))
65
- .pipe(
66
- Effect.catchTag("PlatformError", (error) =>
67
- error.reason._tag === "NotFound"
68
- ? Effect.succeed<string[]>([])
69
- : Effect.fail(new SetupFailure({ message: `cannot inspect ${file}: ${error.message}` })),
70
- ),
71
- );
72
- const present = entries.includes(basename(file));
73
- if (!present && path !== undefined) {
74
- return yield* new SetupFailure({ message: `no config at ${file}. Check the --config path.` });
75
- }
76
- const loaded = present ? yield* importDefault(file) : {};
77
- const config = yield* validOrFail(file, yield* Effect.promise(() => decodeConfig(loaded)));
78
- const rules = yield* validOrFail(file, yield* resolveRules(config));
79
- return resolved(dirname(file), file, config, rules);
80
- });
64
+ export const loadConfig = Effect.fn("Config.loadConfig")(function* (
65
+ cwd: string,
66
+ path: string | undefined,
67
+ ): Effect.fn.Return<ResolvedConfig, SetupFailure, FileSystem.FileSystem> {
68
+ const fs = yield* FileSystem.FileSystem;
69
+ const file = resolve(cwd, path ?? CONFIG_FILE);
70
+ const entries = yield* fs
71
+ .readDirectory(dirname(file))
72
+ .pipe(
73
+ Effect.catchTag("PlatformError", (error) =>
74
+ error.reason._tag === "NotFound"
75
+ ? Effect.succeed<string[]>([])
76
+ : Effect.fail(new SetupFailure({ message: `cannot inspect ${file}: ${error.message}` })),
77
+ ),
78
+ );
79
+ const present = entries.includes(basename(file));
80
+ if (!present && path !== undefined) {
81
+ return yield* new SetupFailure({ message: `no config at ${file}. Check the --config path.` });
82
+ }
83
+ const loaded = present ? yield* importDefault(file) : {};
84
+ const config = yield* validOrFail(file, yield* Effect.promise(() => decodeConfig(loaded)));
85
+ const rules = yield* validOrFail(file, yield* resolveRules(config));
86
+ return resolved(dirname(file), file, config, rules);
87
+ });
@@ -1,9 +1,9 @@
1
1
  import { Effect } from "effect";
2
2
  import type { Decoded } from "#decoded.ts";
3
- import type { ActiveRule } from "#engine/run-rules.ts";
3
+ import type { ActiveRule } from "#engine/runRules.ts";
4
4
  import type { RuleIndex } from "#engine/violation.ts";
5
5
  import type { Rule } from "#rule.ts";
6
- import { builtInRules } from "#rules/built-in.ts";
6
+ import { builtInRules } from "#rules/builtIn.ts";
7
7
  import type { ConfigInput } from "./decode.ts";
8
8
 
9
9
  export interface ResolvedRules extends RuleIndex {
@@ -12,14 +12,19 @@ export interface ResolvedRules extends RuleIndex {
12
12
 
13
13
  type Setting = NonNullable<ConfigInput["rules"]>[string];
14
14
 
15
- const messageOf = (cause: unknown): string => (cause instanceof Error ? cause.message : String(cause));
15
+ function messageOf(cause: unknown): string {
16
+ return cause instanceof Error ? cause.message : String(cause);
17
+ }
16
18
 
17
- const optionsOf = (setting: Setting | undefined): unknown => (typeof setting === "object" ? setting.options : undefined);
19
+ function optionsOf(setting: Setting | undefined): unknown {
20
+ return typeof setting === "object" ? setting.options : undefined;
21
+ }
18
22
 
19
- const duplicateIssues = (rules: readonly Rule[]): readonly string[] =>
20
- rules.flatMap((rule, index) =>
23
+ function duplicateIssues(rules: readonly Rule[]): readonly string[] {
24
+ return rules.flatMap((rule, index) =>
21
25
  rules.findIndex((other) => other.id === rule.id) === index ? [] : [`local: rule id "${rule.id}" is already defined`],
22
26
  );
27
+ }
23
28
 
24
29
  function activeRule(rule: Rule, check: ActiveRule["check"]): ActiveRule {
25
30
  return {
@@ -32,8 +37,8 @@ function activeRule(rule: Rule, check: ActiveRule["check"]): ActiveRule {
32
37
  };
33
38
  }
34
39
 
35
- const activate = (rule: Rule, setting: Setting | undefined): Effect.Effect<Decoded<ActiveRule>> =>
36
- Effect.tryPromise({ catch: messageOf, try: () => rule.configure(optionsOf(setting)) }).pipe(
40
+ function activate(rule: Rule, setting: Setting | undefined): Effect.Effect<Decoded<ActiveRule>> {
41
+ return Effect.tryPromise({ catch: messageOf, try: () => rule.configure(optionsOf(setting)) }).pipe(
37
42
  Effect.map(
38
43
  (configured): Decoded<ActiveRule> =>
39
44
  configured._tag === "Invalid"
@@ -47,25 +52,25 @@ const activate = (rule: Rule, setting: Setting | undefined): Effect.Effect<Decod
47
52
  Effect.succeed<Decoded<ActiveRule>>({ _tag: "Invalid", issues: [`rules.${rule.id}.options: validation threw: ${failure}`] }),
48
53
  ),
49
54
  );
55
+ }
50
56
 
51
- export const resolveRules = (config: ConfigInput): Effect.Effect<Decoded<ResolvedRules>> =>
52
- Effect.gen(function* () {
53
- const rules: readonly Rule[] = [...builtInRules, ...(config.local ?? [])];
54
- const settings = config.rules ?? {};
55
- const known = new Set(rules.map((rule) => rule.id));
56
- const families = new Set(rules.filter((rule) => rule.family === true).map((rule) => rule.id));
57
- const unknown = [
58
- ...Object.keys(settings)
59
- .filter((id) => !known.has(id))
60
- .map((id) => `rules.${id}`),
61
- ].map((path) => `${path}: no built-in or local rule has this id`);
62
- const activated = yield* Effect.forEach(rules, (rule) => activate(rule, settings[rule.id]));
63
- const issues = [...duplicateIssues(rules), ...unknown, ...activated.flatMap((result) => (result._tag === "Invalid" ? result.issues : []))];
64
- if (issues.length > 0) {
65
- return { _tag: "Invalid", issues };
66
- }
67
- const active = activated.flatMap((result) => (result._tag === "Valid" ? [result.value] : []));
68
- const levels = new Map(rules.map((rule) => [rule.id, "error" as const]));
69
- const unregistrable = new Set(rules.filter((rule) => rule.registrable === false).map((rule) => rule.id));
70
- return { _tag: "Valid", value: { active, families, levels, unregistrable } };
71
- });
57
+ export const resolveRules = Effect.fn("Config.resolveRules")(function* (config: ConfigInput): Effect.fn.Return<Decoded<ResolvedRules>> {
58
+ const rules: readonly Rule[] = [...builtInRules, ...(config.local ?? [])];
59
+ const settings = config.rules ?? {};
60
+ const known = new Set(rules.map((rule) => rule.id));
61
+ const families = new Set(rules.filter((rule) => rule.family === true).map((rule) => rule.id));
62
+ const unknown = [
63
+ ...Object.keys(settings)
64
+ .filter((id) => !known.has(id))
65
+ .map((id) => `rules.${id}`),
66
+ ].map((path) => `${path}: no built-in or local rule has this id`);
67
+ const activated = yield* Effect.forEach(rules, (rule) => activate(rule, settings[rule.id]));
68
+ const issues = [...duplicateIssues(rules), ...unknown, ...activated.flatMap((result) => (result._tag === "Invalid" ? result.issues : []))];
69
+ if (issues.length > 0) {
70
+ return { _tag: "Invalid", issues };
71
+ }
72
+ const active = activated.flatMap((result) => (result._tag === "Valid" ? [result.value] : []));
73
+ const levels = new Map(rules.map((rule) => [rule.id, "error" as const]));
74
+ const unregistrable = new Set(rules.filter((rule) => rule.registrable === false).map((rule) => rule.id));
75
+ return { _tag: "Valid", value: { active, families, levels, unregistrable } };
76
+ });
package/src/config.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import type { ExceptionDeclaration } from "#exceptions/declaration.ts";
2
- import type { builtInRules } from "#rules/built-in.ts";
2
+ import type { builtInRules } from "#rules/builtIn.ts";
3
3
  import type { Rule } from "./rule.ts";
4
4
 
5
- export type Level = "error" | "warn" | "off";
5
+ export type Level = "error";
6
6
 
7
7
  export type RuleSetting<TInput> = "error" | { readonly level?: "error"; readonly options?: TInput };
8
8
 
@@ -24,4 +24,6 @@ export interface QualityConfig<TLocal extends readonly Rule[] = readonly Rule[]>
24
24
  readonly sources?: readonly string[];
25
25
  }
26
26
 
27
- export const defineConfig = <const TLocal extends readonly Rule[] = readonly []>(config: QualityConfig<TLocal>): QualityConfig<TLocal> => config;
27
+ export function defineConfig<const TLocal extends readonly Rule[] = readonly []>(config: QualityConfig<TLocal>): QualityConfig<TLocal> {
28
+ return config;
29
+ }
package/src/decoded.ts CHANGED
@@ -1,15 +1,16 @@
1
1
  import { Effect } from "effect";
2
2
  import { SetupFailure } from "./failure.ts";
3
- import { describeIssue, type StandardSchemaV1 } from "./standard-schema.ts";
3
+ import { describeIssue, type StandardSchemaV1 } from "./standardSchema.ts";
4
4
 
5
5
  export type Decoded<TValue> = { readonly _tag: "Valid"; readonly value: TValue } | { readonly _tag: "Invalid"; readonly issues: readonly string[] };
6
6
 
7
- export const decodeWith = async <TOutput>(schema: StandardSchemaV1<unknown, TOutput>, value: unknown): Promise<Decoded<TOutput>> => {
7
+ export async function decodeWith<TOutput>(schema: StandardSchemaV1<unknown, TOutput>, value: unknown): Promise<Decoded<TOutput>> {
8
8
  const result = await schema["~standard"].validate(value);
9
9
  return result.issues === undefined ? { _tag: "Valid", value: result.value } : { _tag: "Invalid", issues: result.issues.map(describeIssue) };
10
- };
10
+ }
11
11
 
12
- export const validOrFail = <TValue>(file: string, decoded: Decoded<TValue>): Effect.Effect<TValue, SetupFailure> =>
13
- decoded._tag === "Valid"
12
+ export function validOrFail<TValue>(file: string, decoded: Decoded<TValue>): Effect.Effect<TValue, SetupFailure> {
13
+ return decoded._tag === "Valid"
14
14
  ? Effect.succeed(decoded.value)
15
15
  : Effect.fail(new SetupFailure({ message: `${file} is invalid:\n${decoded.issues.map((issue) => ` - ${issue}`).join("\n")}` }));
16
+ }
@@ -0,0 +1,29 @@
1
+ import { join } from "node:path";
2
+ import { Effect, type FileSystem } from "effect";
3
+ import { type BaselineEntry, decodeBaseline } from "#baseline/format.ts";
4
+ import { LEGACY_BASELINE } from "#baseline/legacy.ts";
5
+ import type { ResolvedConfig } from "#config/load.ts";
6
+ import { validOrFail } from "#decoded.ts";
7
+ import { SetupFailure } from "#failure.ts";
8
+ import { readOptionalText } from "#inventory/filesystem.ts";
9
+
10
+ export interface BaselineFile {
11
+ readonly entries: readonly BaselineEntry[];
12
+ readonly raw: string | undefined;
13
+ }
14
+
15
+ export function readInput(root: string, path: string): Effect.Effect<string | undefined, SetupFailure, FileSystem.FileSystem> {
16
+ return Effect.mapError(readOptionalText(join(root, path)), (failure) => new SetupFailure({ message: failure.message }));
17
+ }
18
+
19
+ export const readBaseline = Effect.fn("Engine.readBaseline")(function* (
20
+ config: ResolvedConfig,
21
+ ): Effect.fn.Return<BaselineFile, SetupFailure, FileSystem.FileSystem> {
22
+ const raw = yield* readInput(config.root, config.baseline);
23
+ if (raw === undefined && config.baseline !== LEGACY_BASELINE && (yield* readInput(config.root, LEGACY_BASELINE)) !== undefined) {
24
+ return yield* new SetupFailure({
25
+ message: `${LEGACY_BASELINE} holds a baseline in the earlier JSON format. Run \`quality baseline migrate\` to move it to ${config.baseline}.`,
26
+ });
27
+ }
28
+ return { entries: yield* validOrFail(config.baseline, yield* Effect.promise(() => decodeBaseline(raw))), raw };
29
+ });
@@ -11,29 +11,28 @@ export interface Outcome {
11
11
  readonly regressions: readonly Regression[];
12
12
  readonly staleBaseline: readonly StaleBaselineEntry[];
13
13
  readonly staleRegistry: readonly StaleRegistryEntry[];
14
- readonly warnings: readonly Violation[];
15
14
  }
16
15
 
17
- export const evaluate = (
16
+ export function evaluate(
18
17
  violations: readonly Violation[],
19
18
  registry: readonly RegistryEntry[],
20
19
  baseline: readonly BaselineEntry[],
21
20
  rules: RuleIndex,
22
- ): Outcome => {
21
+ ): Outcome {
23
22
  const registered = applyRegistry(violations, registry, rules);
24
23
  const baselined = applyBaseline(registered.kept, baseline, rules);
25
24
  const kept = [...baselined.kept].sort(byLocation);
26
25
  return {
27
26
  baselined: baselined.baselined,
28
- errors: kept.filter((violation) => violation.level === "error"),
27
+ errors: kept,
29
28
  looseBaseline: baselined.loose,
30
29
  registered: registered.registered,
31
30
  regressions: baselined.regressions,
32
31
  staleBaseline: baselined.stale,
33
32
  staleRegistry: registered.stale,
34
- warnings: kept.filter((violation) => violation.level === "warn"),
35
33
  };
36
- };
34
+ }
37
35
 
38
- export const passes = (outcome: Outcome): boolean =>
39
- outcome.errors.length === 0 && outcome.staleBaseline.length === 0 && outcome.staleRegistry.length === 0;
36
+ export function passes(outcome: Outcome): boolean {
37
+ return outcome.errors.length === 0 && outcome.staleBaseline.length === 0 && outcome.staleRegistry.length === 0;
38
+ }
@@ -1,7 +1,7 @@
1
1
  import { isAbsolute, relative } from "node:path";
2
2
  import { Effect } from "effect";
3
3
  import { SetupFailure } from "#failure.ts";
4
- import { posix } from "#inventory/ignore-scope.ts";
4
+ import { posix } from "#inventory/ignoreScope.ts";
5
5
  import type { Finding, Findings, RuleInputs } from "#rule.ts";
6
6
  import type { ActiveLevel, Violation } from "./violation.ts";
7
7
 
@@ -14,10 +14,14 @@ export interface ActiveRule {
14
14
  readonly registrable?: boolean;
15
15
  }
16
16
 
17
- const messageOf = (cause: unknown): string => (cause instanceof Error ? cause.message : String(cause));
17
+ function messageOf(cause: unknown): string {
18
+ return cause instanceof Error ? cause.message : String(cause);
19
+ }
18
20
 
19
21
  // Registry and baseline entries match on the path, so every finding names its file the same way.
20
- const repositoryPath = (root: string, file: string): string => posix(isAbsolute(file) ? relative(root, file) : file).replace(/^(\.\/)+/u, "");
22
+ function repositoryPath(root: string, file: string): string {
23
+ return posix(isAbsolute(file) ? relative(root, file) : file).replace(/^(?:\.\/)+/u, "");
24
+ }
21
25
 
22
26
  function exceptionHint(rule: ActiveRule, finding: Finding, file: string, config: string): string {
23
27
  const id = rule.family && finding.subject !== undefined ? `${rule.id}/${finding.subject}` : rule.id;
@@ -34,25 +38,29 @@ function exceptionHint(rule: ActiveRule, finding: Finding, file: string, config:
34
38
  return ` For a permanent exception, add to exceptions in ${config}: ${shape}.`;
35
39
  }
36
40
 
37
- const violationOf = (rule: ActiveRule, root: string, finding: Finding, exceptionFile: string): Violation => ({
38
- ...finding,
39
- file: repositoryPath(root, finding.file),
40
- level: rule.level,
41
- message: finding.message + exceptionHint(rule, finding, repositoryPath(root, finding.file), exceptionFile),
42
- rule: rule.family && finding.subject !== undefined ? `${rule.id}/${finding.subject}` : rule.id,
43
- });
41
+ function violationOf(rule: ActiveRule, root: string, finding: Finding, exceptionFile: string): Violation {
42
+ return {
43
+ ...finding,
44
+ file: repositoryPath(root, finding.file),
45
+ level: rule.level,
46
+ message: finding.message + exceptionHint(rule, finding, repositoryPath(root, finding.file), exceptionFile),
47
+ rule: rule.family && finding.subject !== undefined ? `${rule.id}/${finding.subject}` : rule.id,
48
+ };
49
+ }
44
50
 
45
- const runRule = (rule: ActiveRule, inputs: RuleInputs, exceptionFile: string): Effect.Effect<readonly Violation[], SetupFailure> =>
46
- Effect.map(
51
+ function runRule(rule: ActiveRule, inputs: RuleInputs, exceptionFile: string): Effect.Effect<readonly Violation[], SetupFailure> {
52
+ return Effect.map(
47
53
  Effect.tryPromise({
48
54
  catch: (cause) => new SetupFailure({ message: `rule ${rule.id} failed: ${messageOf(cause)}` }),
49
55
  try: () => rule.check(inputs),
50
56
  }),
51
57
  (findings) => findings.map((finding) => violationOf(rule, inputs.root, finding, exceptionFile)),
52
58
  );
59
+ }
53
60
 
54
- export const runRules = (rules: readonly ActiveRule[], inputs: RuleInputs): Effect.Effect<readonly Violation[], SetupFailure> =>
55
- Effect.map(
61
+ export function runRules(rules: readonly ActiveRule[], inputs: RuleInputs): Effect.Effect<readonly Violation[], SetupFailure> {
62
+ return Effect.map(
56
63
  Effect.forEach(rules, (rule) => runRule(rule, inputs, inputs.configFile ?? "quality.config.ts"), { concurrency: "unbounded" }),
57
64
  (results) => results.flat(),
58
65
  );
66
+ }
@@ -7,8 +7,8 @@ import { registryEntries } from "#exceptions/registryEntries.ts";
7
7
  import { SetupFailure } from "#failure.ts";
8
8
  import { collectInventory, type Inventory } from "#inventory/collect.ts";
9
9
  import { type FilesystemFailure, readOptionalText } from "#inventory/filesystem.ts";
10
- import { type BaselineFile, readBaseline, readInput } from "./baseline-file.ts";
11
- import { runRules } from "./run-rules.ts";
10
+ import { type BaselineFile, readBaseline, readInput } from "./baselineFile.ts";
11
+ import { runRules } from "./runRules.ts";
12
12
  import type { Violation } from "./violation.ts";
13
13
 
14
14
  export interface Session {
@@ -19,32 +19,39 @@ export interface Session {
19
19
  readonly violations: readonly Violation[];
20
20
  }
21
21
 
22
- const setup = <TValue, TRequirements>(
22
+ function setup<TValue, TRequirements>(
23
23
  effect: Effect.Effect<TValue, FilesystemFailure, TRequirements>,
24
- ): Effect.Effect<TValue, SetupFailure, TRequirements> => Effect.mapError(effect, (failure) => new SetupFailure({ message: failure.message }));
24
+ ): Effect.Effect<TValue, SetupFailure, TRequirements> {
25
+ return Effect.mapError(effect, (failure) => new SetupFailure({ message: failure.message }));
26
+ }
25
27
 
26
- export const scan = (config: ResolvedConfig): Effect.Effect<Pick<Session, "inventory" | "violations">, SetupFailure, FileSystem.FileSystem> =>
27
- Effect.gen(function* () {
28
- const inventory = yield* setup(collectInventory(config.root, config));
29
- const services = yield* Effect.context<FileSystem.FileSystem>();
30
- const readText = (path: string): Promise<string | undefined> => Effect.runPromiseWith(services)(readOptionalText(resolve(config.root, path)));
31
- const violations = yield* runRules(config.active, {
32
- configFile: relative(config.root, config.file),
33
- exceptions: config.exceptions,
34
- files: inventory.files,
35
- readText,
36
- root: config.root,
37
- sources: inventory.sources,
38
- });
39
- return { inventory, violations };
28
+ export const scan = Effect.fn("Engine.scan")(function* (
29
+ config: ResolvedConfig,
30
+ ): Effect.fn.Return<Pick<Session, "inventory" | "violations">, SetupFailure, FileSystem.FileSystem> {
31
+ const inventory = yield* setup(collectInventory(config.root, config));
32
+ const services = yield* Effect.context<FileSystem.FileSystem>();
33
+ function readText(path: string): Promise<string | undefined> {
34
+ return Effect.runPromiseWith(services)(readOptionalText(resolve(config.root, path)));
35
+ }
36
+ const violations = yield* runRules(config.active, {
37
+ configFile: relative(config.root, config.file),
38
+ exceptions: config.exceptions,
39
+ files: inventory.files,
40
+ readText,
41
+ root: config.root,
42
+ sources: inventory.sources,
40
43
  });
44
+ return { inventory, violations };
45
+ });
41
46
 
42
- export const openSession = (cwd: string, configPath: string | undefined): Effect.Effect<Session, SetupFailure, FileSystem.FileSystem> =>
43
- Effect.gen(function* () {
44
- const config = yield* loadConfig(cwd, configPath);
45
- const registryRaw = yield* readInput(config.root, config.registry);
46
- const registry = yield* validOrFail(config.registry, yield* Effect.promise(() => decodeRegistry(registryRaw)));
47
- const baseline = yield* readBaseline(config);
48
- const { inventory, violations } = yield* scan(config);
49
- return { baseline, config, inventory, registry: [...registry, ...registryEntries(config.exceptions)], violations };
50
- });
47
+ export const openSession = Effect.fn("Engine.openSession")(function* (
48
+ cwd: string,
49
+ configPath: string | undefined,
50
+ ): Effect.fn.Return<Session, SetupFailure, FileSystem.FileSystem> {
51
+ const config = yield* loadConfig(cwd, configPath);
52
+ const registryRaw = yield* readInput(config.root, config.registry);
53
+ const registry = yield* validOrFail(config.registry, yield* Effect.promise(() => decodeRegistry(registryRaw)));
54
+ const baseline = yield* readBaseline(config);
55
+ const { inventory, violations } = yield* scan(config);
56
+ return { baseline, config, inventory, registry: [...registry, ...registryEntries(config.exceptions)], violations };
57
+ });
@@ -1,19 +1,22 @@
1
1
  import type { Level } from "#config.ts";
2
2
  import type { Finding } from "#rule.ts";
3
3
 
4
- export type ActiveLevel = "error" | "warn";
4
+ export type ActiveLevel = "error";
5
5
 
6
6
  export interface Violation extends Finding {
7
7
  readonly level: ActiveLevel;
8
8
  readonly rule: string;
9
9
  }
10
10
 
11
- export const keyOf = (rule: string, file: string): string => `${rule}\u0000${file}`;
11
+ export function keyOf(rule: string, file: string): string {
12
+ return `${rule}\u0000${file}`;
13
+ }
12
14
 
13
- export const byLocation = (left: Violation, right: Violation): number =>
14
- left.rule.localeCompare(right.rule) || left.file.localeCompare(right.file) || (left.line ?? 0) - (right.line ?? 0);
15
+ export function byLocation(left: Violation, right: Violation): number {
16
+ return left.rule.localeCompare(right.rule) || left.file.localeCompare(right.file) || (left.line ?? 0) - (right.line ?? 0);
17
+ }
15
18
 
16
- export const groupBy = <TItem>(items: readonly TItem[], key: (item: TItem) => string): ReadonlyMap<string, readonly TItem[]> => {
19
+ export function groupBy<TItem>(items: readonly TItem[], key: (item: TItem) => string): ReadonlyMap<string, readonly TItem[]> {
17
20
  const groups = new Map<string, TItem[]>();
18
21
  for (const item of items) {
19
22
  const group = groups.get(key(item));
@@ -24,7 +27,7 @@ export const groupBy = <TItem>(items: readonly TItem[], key: (item: TItem) => st
24
27
  }
25
28
  }
26
29
  return groups;
27
- };
30
+ }
28
31
 
29
32
  export interface RuleIndex {
30
33
  readonly families: ReadonlySet<string>;
@@ -32,18 +35,26 @@ export interface RuleIndex {
32
35
  readonly unregistrable: ReadonlySet<string>;
33
36
  }
34
37
 
35
- export const covers = (name: string, rule: string): boolean => rule === name || rule.startsWith(`${name}/`);
38
+ export function covers(name: string, rule: string): boolean {
39
+ return rule === name || rule.startsWith(`${name}/`);
40
+ }
36
41
 
37
- const ownerOf = (index: RuleIndex, rule: string): string => [...index.families].find((family) => covers(family, rule)) ?? rule;
42
+ function ownerOf(index: RuleIndex, rule: string): string {
43
+ return [...index.families].find((family) => covers(family, rule)) ?? rule;
44
+ }
38
45
 
39
- export const levelOf = (index: RuleIndex, rule: string): Level | undefined => index.levels.get(ownerOf(index, rule));
46
+ export function levelOf(index: RuleIndex, rule: string): Level | undefined {
47
+ return index.levels.get(ownerOf(index, rule));
48
+ }
40
49
 
41
- export const registrable = (index: RuleIndex, rule: string): boolean => !index.unregistrable.has(ownerOf(index, rule));
50
+ export function registrable(index: RuleIndex, rule: string): boolean {
51
+ return !index.unregistrable.has(ownerOf(index, rule));
52
+ }
42
53
 
43
- export const unusedEntryProblem = (index: RuleIndex, rule: string, unused: string): string => {
54
+ export function unusedEntryProblem(index: RuleIndex, rule: string, unused: string): string {
44
55
  const level = levelOf(index, rule);
45
56
  if (level === undefined) {
46
57
  return "names no known rule";
47
58
  }
48
- return level === "off" ? "names a rule that is off" : unused;
49
- };
59
+ return unused;
60
+ }
@@ -15,8 +15,9 @@ const standard = Schema.toStandardSchemaV1(Schema.fromJsonString(Schema.Array(Re
15
15
  parseOptions: { errors: "all", onExcessProperty: "error" },
16
16
  });
17
17
 
18
- export const decodeRegistry = (raw: string | undefined): Promise<Decoded<readonly RegistryEntry[]>> =>
19
- raw === undefined ? Promise.resolve({ _tag: "Valid", value: [] }) : decodeWith(standard, raw);
18
+ export function decodeRegistry(raw: string | undefined): Promise<Decoded<readonly RegistryEntry[]>> {
19
+ return raw === undefined ? Promise.resolve({ _tag: "Valid", value: [] }) : decodeWith(standard, raw);
20
+ }
20
21
 
21
22
  export interface StaleRegistryEntry {
22
23
  readonly entry: RegistryEntry;
@@ -29,17 +30,18 @@ export interface RegistryCheck {
29
30
  readonly stale: readonly StaleRegistryEntry[];
30
31
  }
31
32
 
32
- const covers = (entry: RegistryEntry, violation: Violation): boolean =>
33
- entry.rule === violation.rule && entry.file === violation.file && (entry.subject === undefined || entry.subject === violation.subject);
33
+ function covers(entry: RegistryEntry, violation: Violation): boolean {
34
+ return entry.rule === violation.rule && entry.file === violation.file && (entry.subject === undefined || entry.subject === violation.subject);
35
+ }
34
36
 
35
37
  const UNREGISTRABLE = "names a rule that takes no exceptions. Fix the code, or baseline the violations while the repository adopts the rule";
36
38
 
37
- const coveringEntry = (entries: readonly RegistryEntry[], violation: Violation): RegistryEntry | undefined => {
39
+ function coveringEntry(entries: readonly RegistryEntry[], violation: Violation): RegistryEntry | undefined {
38
40
  const matching = entries.filter((entry) => covers(entry, violation));
39
41
  return matching.find((entry) => entry.subject !== undefined) ?? matching[0];
40
- };
42
+ }
41
43
 
42
- export const applyRegistry = (violations: readonly Violation[], entries: readonly RegistryEntry[], rules: RuleIndex): RegistryCheck => {
44
+ export function applyRegistry(violations: readonly Violation[], entries: readonly RegistryEntry[], rules: RuleIndex): RegistryCheck {
43
45
  const usable = entries.filter((entry) => registrable(rules, entry.rule));
44
46
  const used = new Set<RegistryEntry>();
45
47
  const kept = violations.filter((violation) => {
@@ -56,4 +58,4 @@ export const applyRegistry = (violations: readonly Violation[], entries: readonl
56
58
  problem: registrable(rules, entry.rule) ? unusedEntryProblem(rules, entry.rule, "matches no violation") : UNREGISTRABLE,
57
59
  }));
58
60
  return { kept, registered: violations.length - kept.length, stale };
59
- };
61
+ }