@nielspeter/eess-ts 0.2.0 → 0.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 (433) hide show
  1. package/README.md +87 -34
  2. package/dist/builders/call-rule-builder.d.ts +66 -26
  3. package/dist/builders/call-rule-builder.d.ts.map +1 -1
  4. package/dist/builders/call-rule-builder.js +73 -31
  5. package/dist/builders/call-rule-builder.js.map +1 -1
  6. package/dist/builders/class-rule-builder.d.ts +125 -26
  7. package/dist/builders/class-rule-builder.d.ts.map +1 -1
  8. package/dist/builders/class-rule-builder.js +134 -30
  9. package/dist/builders/class-rule-builder.js.map +1 -1
  10. package/dist/builders/correspondence-builder.d.ts +287 -0
  11. package/dist/builders/correspondence-builder.d.ts.map +1 -0
  12. package/dist/builders/correspondence-builder.js +393 -0
  13. package/dist/builders/correspondence-builder.js.map +1 -0
  14. package/dist/builders/correspondence-findings.d.ts +104 -0
  15. package/dist/builders/correspondence-findings.d.ts.map +1 -0
  16. package/dist/builders/correspondence-findings.js +301 -0
  17. package/dist/builders/correspondence-findings.js.map +1 -0
  18. package/dist/builders/cross-layer-builder.d.ts +99 -16
  19. package/dist/builders/cross-layer-builder.d.ts.map +1 -1
  20. package/dist/builders/cross-layer-builder.js +181 -35
  21. package/dist/builders/cross-layer-builder.js.map +1 -1
  22. package/dist/builders/function-rule-builder.d.ts +144 -25
  23. package/dist/builders/function-rule-builder.d.ts.map +1 -1
  24. package/dist/builders/function-rule-builder.js +173 -26
  25. package/dist/builders/function-rule-builder.js.map +1 -1
  26. package/dist/builders/jsx-rule-builder.d.ts +70 -14
  27. package/dist/builders/jsx-rule-builder.d.ts.map +1 -1
  28. package/dist/builders/jsx-rule-builder.js +73 -14
  29. package/dist/builders/jsx-rule-builder.js.map +1 -1
  30. package/dist/builders/module-rule-builder.d.ts +2 -2
  31. package/dist/builders/module-rule-builder.d.ts.map +1 -1
  32. package/dist/builders/module-rule-builder.js +12 -3
  33. package/dist/builders/module-rule-builder.js.map +1 -1
  34. package/dist/builders/scoped-function-rule-builder.d.ts +11 -0
  35. package/dist/builders/scoped-function-rule-builder.d.ts.map +1 -1
  36. package/dist/builders/scoped-function-rule-builder.js +12 -0
  37. package/dist/builders/scoped-function-rule-builder.js.map +1 -1
  38. package/dist/builders/slice-discovery-message.d.ts +36 -0
  39. package/dist/builders/slice-discovery-message.d.ts.map +1 -0
  40. package/dist/builders/slice-discovery-message.js +181 -0
  41. package/dist/builders/slice-discovery-message.js.map +1 -0
  42. package/dist/builders/slice-rule-builder.d.ts +151 -12
  43. package/dist/builders/slice-rule-builder.d.ts.map +1 -1
  44. package/dist/builders/slice-rule-builder.js +242 -35
  45. package/dist/builders/slice-rule-builder.js.map +1 -1
  46. package/dist/builders/type-rule-builder.d.ts +95 -24
  47. package/dist/builders/type-rule-builder.d.ts.map +1 -1
  48. package/dist/builders/type-rule-builder.js +105 -29
  49. package/dist/builders/type-rule-builder.js.map +1 -1
  50. package/dist/{helpers → builders}/within.d.ts +2 -2
  51. package/dist/builders/within.d.ts.map +1 -0
  52. package/dist/{helpers → builders}/within.js +1 -1
  53. package/dist/builders/within.js.map +1 -0
  54. package/dist/cli/commands/baseline.d.ts +3 -2
  55. package/dist/cli/commands/baseline.d.ts.map +1 -1
  56. package/dist/cli/commands/baseline.js +68 -6
  57. package/dist/cli/commands/baseline.js.map +1 -1
  58. package/dist/cli/commands/check.d.ts +7 -2
  59. package/dist/cli/commands/check.d.ts.map +1 -1
  60. package/dist/cli/commands/check.js +241 -45
  61. package/dist/cli/commands/check.js.map +1 -1
  62. package/dist/cli/commands/doctor.d.ts +29 -0
  63. package/dist/cli/commands/doctor.d.ts.map +1 -0
  64. package/dist/cli/commands/doctor.js +224 -0
  65. package/dist/cli/commands/doctor.js.map +1 -0
  66. package/dist/cli/commands/explain.d.ts +2 -1
  67. package/dist/cli/commands/explain.d.ts.map +1 -1
  68. package/dist/cli/commands/explain.js +19 -10
  69. package/dist/cli/commands/explain.js.map +1 -1
  70. package/dist/cli/commands/init.d.ts +9 -3
  71. package/dist/cli/commands/init.d.ts.map +1 -1
  72. package/dist/cli/commands/init.js +162 -137
  73. package/dist/cli/commands/init.js.map +1 -1
  74. package/dist/cli/import-rule-module.d.ts +29 -0
  75. package/dist/cli/import-rule-module.d.ts.map +1 -0
  76. package/dist/cli/import-rule-module.js +60 -0
  77. package/dist/cli/import-rule-module.js.map +1 -0
  78. package/dist/cli/index.d.ts +2 -2
  79. package/dist/cli/index.d.ts.map +1 -1
  80. package/dist/cli/index.js +98 -33
  81. package/dist/cli/index.js.map +1 -1
  82. package/dist/cli/load-rules.d.ts +6 -11
  83. package/dist/cli/load-rules.d.ts.map +1 -1
  84. package/dist/cli/load-rules.js +21 -29
  85. package/dist/cli/load-rules.js.map +1 -1
  86. package/dist/cli/resolve-config.d.ts.map +1 -1
  87. package/dist/cli/resolve-config.js +24 -14
  88. package/dist/cli/resolve-config.js.map +1 -1
  89. package/dist/cli/rule-file-findings.d.ts +178 -0
  90. package/dist/cli/rule-file-findings.d.ts.map +1 -0
  91. package/dist/cli/rule-file-findings.js +293 -0
  92. package/dist/cli/rule-file-findings.js.map +1 -0
  93. package/dist/cli/watch.d.ts +20 -7
  94. package/dist/cli/watch.d.ts.map +1 -1
  95. package/dist/cli/watch.js +39 -14
  96. package/dist/cli/watch.js.map +1 -1
  97. package/dist/conditions/body-analysis-function.d.ts.map +1 -1
  98. package/dist/conditions/body-analysis-function.js +16 -7
  99. package/dist/conditions/body-analysis-function.js.map +1 -1
  100. package/dist/conditions/body-analysis-module.d.ts.map +1 -1
  101. package/dist/conditions/body-analysis-module.js +14 -9
  102. package/dist/conditions/body-analysis-module.js.map +1 -1
  103. package/dist/conditions/body-analysis.d.ts.map +1 -1
  104. package/dist/conditions/body-analysis.js +16 -7
  105. package/dist/conditions/body-analysis.js.map +1 -1
  106. package/dist/conditions/call.d.ts.map +1 -1
  107. package/dist/conditions/call.js +38 -17
  108. package/dist/conditions/call.js.map +1 -1
  109. package/dist/conditions/catch-analysis.d.ts +2 -1
  110. package/dist/conditions/catch-analysis.d.ts.map +1 -1
  111. package/dist/conditions/catch-analysis.js.map +1 -1
  112. package/dist/conditions/cross-layer.d.ts +2 -10
  113. package/dist/conditions/cross-layer.d.ts.map +1 -1
  114. package/dist/conditions/cross-layer.js +227 -23
  115. package/dist/conditions/cross-layer.js.map +1 -1
  116. package/dist/conditions/dependency.d.ts +35 -6
  117. package/dist/conditions/dependency.d.ts.map +1 -1
  118. package/dist/conditions/dependency.js +299 -45
  119. package/dist/conditions/dependency.js.map +1 -1
  120. package/dist/conditions/exports.d.ts.map +1 -1
  121. package/dist/conditions/exports.js +10 -0
  122. package/dist/conditions/exports.js.map +1 -1
  123. package/dist/conditions/function.d.ts.map +1 -1
  124. package/dist/conditions/function.js +19 -5
  125. package/dist/conditions/function.js.map +1 -1
  126. package/dist/conditions/helpers.d.ts +2 -1
  127. package/dist/conditions/helpers.d.ts.map +1 -1
  128. package/dist/conditions/helpers.js +4 -1
  129. package/dist/conditions/helpers.js.map +1 -1
  130. package/dist/conditions/jsx.d.ts.map +1 -1
  131. package/dist/conditions/jsx.js +7 -2
  132. package/dist/conditions/jsx.js.map +1 -1
  133. package/dist/conditions/match-identity.d.ts +43 -0
  134. package/dist/conditions/match-identity.d.ts.map +1 -0
  135. package/dist/conditions/match-identity.js +43 -0
  136. package/dist/conditions/match-identity.js.map +1 -0
  137. package/dist/conditions/members.d.ts.map +1 -1
  138. package/dist/conditions/members.js +17 -4
  139. package/dist/conditions/members.js.map +1 -1
  140. package/dist/conditions/reverse-dependency.d.ts +18 -5
  141. package/dist/conditions/reverse-dependency.d.ts.map +1 -1
  142. package/dist/conditions/reverse-dependency.js +109 -92
  143. package/dist/conditions/reverse-dependency.js.map +1 -1
  144. package/dist/conditions/slice.d.ts +86 -2
  145. package/dist/conditions/slice.d.ts.map +1 -1
  146. package/dist/conditions/slice.js +234 -53
  147. package/dist/conditions/slice.js.map +1 -1
  148. package/dist/conditions/structural.d.ts.map +1 -1
  149. package/dist/conditions/structural.js +16 -4
  150. package/dist/conditions/structural.js.map +1 -1
  151. package/dist/core/check-all.d.ts +19 -0
  152. package/dist/core/check-all.d.ts.map +1 -0
  153. package/dist/core/check-all.js +96 -0
  154. package/dist/core/check-all.js.map +1 -0
  155. package/dist/core/combinators.d.ts +48 -0
  156. package/dist/core/combinators.d.ts.map +1 -0
  157. package/dist/core/combinators.js +56 -0
  158. package/dist/core/combinators.js.map +1 -0
  159. package/dist/core/descendant-cache.d.ts +36 -0
  160. package/dist/core/descendant-cache.d.ts.map +1 -0
  161. package/dist/core/descendant-cache.js +119 -0
  162. package/dist/core/descendant-cache.js.map +1 -0
  163. package/dist/core/diagnose.d.ts +234 -0
  164. package/dist/core/diagnose.d.ts.map +1 -0
  165. package/dist/core/diagnose.js +382 -0
  166. package/dist/core/diagnose.js.map +1 -0
  167. package/dist/core/disk-set.d.ts +48 -0
  168. package/dist/core/disk-set.d.ts.map +1 -0
  169. package/dist/core/disk-set.js +218 -0
  170. package/dist/core/disk-set.js.map +1 -0
  171. package/dist/core/element-cache.d.ts +75 -0
  172. package/dist/core/element-cache.d.ts.map +1 -0
  173. package/dist/core/element-cache.js +32 -0
  174. package/dist/core/element-cache.js.map +1 -0
  175. package/dist/core/empty-project-advice.d.ts +75 -0
  176. package/dist/core/empty-project-advice.d.ts.map +1 -0
  177. package/dist/core/empty-project-advice.js +61 -0
  178. package/dist/core/empty-project-advice.js.map +1 -0
  179. package/dist/core/exclusion-comments.d.ts +54 -0
  180. package/dist/core/exclusion-comments.d.ts.map +1 -0
  181. package/dist/core/exclusion-comments.js +310 -0
  182. package/dist/core/exclusion-comments.js.map +1 -0
  183. package/dist/core/execute-rule.d.ts +150 -0
  184. package/dist/core/execute-rule.d.ts.map +1 -0
  185. package/dist/core/execute-rule.js +580 -0
  186. package/dist/core/execute-rule.js.map +1 -0
  187. package/dist/core/glob-diagnosis.d.ts +78 -0
  188. package/dist/core/glob-diagnosis.d.ts.map +1 -0
  189. package/dist/core/glob-diagnosis.js +134 -0
  190. package/dist/core/glob-diagnosis.js.map +1 -0
  191. package/dist/core/glob-evaluator.d.ts +48 -0
  192. package/dist/core/glob-evaluator.d.ts.map +1 -0
  193. package/dist/core/glob-evaluator.js +89 -0
  194. package/dist/core/glob-evaluator.js.map +1 -0
  195. package/dist/core/import-candidates.d.ts +60 -0
  196. package/dist/core/import-candidates.d.ts.map +1 -0
  197. package/dist/core/import-candidates.js +93 -0
  198. package/dist/core/import-candidates.js.map +1 -0
  199. package/dist/core/import-options.d.ts +55 -2
  200. package/dist/core/import-options.d.ts.map +1 -1
  201. package/dist/core/import-options.js +64 -0
  202. package/dist/core/import-options.js.map +1 -1
  203. package/dist/core/line-index.d.ts +3 -0
  204. package/dist/core/line-index.d.ts.map +1 -0
  205. package/dist/core/line-index.js +229 -0
  206. package/dist/core/line-index.js.map +1 -0
  207. package/dist/core/metric-violation.d.ts +86 -0
  208. package/dist/core/metric-violation.d.ts.map +1 -0
  209. package/dist/core/metric-violation.js +132 -0
  210. package/dist/core/metric-violation.js.map +1 -0
  211. package/dist/core/module-edges.d.ts +361 -0
  212. package/dist/core/module-edges.d.ts.map +1 -0
  213. package/dist/core/module-edges.js +592 -0
  214. package/dist/core/module-edges.js.map +1 -0
  215. package/dist/core/object-literal-functions.d.ts +42 -0
  216. package/dist/core/object-literal-functions.d.ts.map +1 -0
  217. package/dist/core/object-literal-functions.js +75 -0
  218. package/dist/core/object-literal-functions.js.map +1 -0
  219. package/dist/core/orphan-exclusions.d.ts +44 -0
  220. package/dist/core/orphan-exclusions.d.ts.map +1 -0
  221. package/dist/core/orphan-exclusions.js +214 -0
  222. package/dist/core/orphan-exclusions.js.map +1 -0
  223. package/dist/core/pair-condition.d.ts +32 -3
  224. package/dist/core/pair-condition.d.ts.map +1 -1
  225. package/dist/core/path-universe.d.ts +54 -0
  226. package/dist/core/path-universe.d.ts.map +1 -0
  227. package/dist/core/path-universe.js +65 -0
  228. package/dist/core/path-universe.js.map +1 -0
  229. package/dist/core/per-root-compiler-options.d.ts +20 -0
  230. package/dist/core/per-root-compiler-options.d.ts.map +1 -0
  231. package/dist/core/per-root-compiler-options.js +57 -0
  232. package/dist/core/per-root-compiler-options.js.map +1 -0
  233. package/dist/core/project-relative.d.ts +98 -0
  234. package/dist/core/project-relative.d.ts.map +1 -0
  235. package/dist/core/project-relative.js +185 -0
  236. package/dist/core/project-relative.js.map +1 -0
  237. package/dist/core/project.d.ts +7 -1
  238. package/dist/core/project.d.ts.map +1 -1
  239. package/dist/core/project.js +24 -0
  240. package/dist/core/project.js.map +1 -1
  241. package/dist/core/rule-builder.d.ts +282 -0
  242. package/dist/core/rule-builder.d.ts.map +1 -0
  243. package/dist/core/rule-builder.js +445 -0
  244. package/dist/core/rule-builder.js.map +1 -0
  245. package/dist/core/rule-declaration.d.ts +32 -0
  246. package/dist/core/rule-declaration.d.ts.map +1 -0
  247. package/dist/core/rule-declaration.js +126 -0
  248. package/dist/core/rule-declaration.js.map +1 -0
  249. package/dist/core/terminal-builder.d.ts +625 -0
  250. package/dist/core/terminal-builder.d.ts.map +1 -0
  251. package/dist/core/terminal-builder.js +787 -0
  252. package/dist/core/terminal-builder.js.map +1 -0
  253. package/dist/core/terminal-execution.d.ts +23 -0
  254. package/dist/core/terminal-execution.d.ts.map +1 -0
  255. package/dist/core/terminal-execution.js +71 -0
  256. package/dist/core/terminal-execution.js.map +1 -0
  257. package/dist/core/vacuity-diagnosis.d.ts +103 -0
  258. package/dist/core/vacuity-diagnosis.d.ts.map +1 -0
  259. package/dist/core/vacuity-diagnosis.js +415 -0
  260. package/dist/core/vacuity-diagnosis.js.map +1 -0
  261. package/dist/core/violation.d.ts +16 -11
  262. package/dist/core/violation.d.ts.map +1 -1
  263. package/dist/core/violation.js +33 -13
  264. package/dist/core/violation.js.map +1 -1
  265. package/dist/graphql/index.js +1 -1
  266. package/dist/graphql/index.js.map +1 -1
  267. package/dist/graphql/resolver-rule-builder.d.ts +98 -23
  268. package/dist/graphql/resolver-rule-builder.d.ts.map +1 -1
  269. package/dist/graphql/resolver-rule-builder.js +151 -21
  270. package/dist/graphql/resolver-rule-builder.js.map +1 -1
  271. package/dist/graphql/schema-loader.d.ts +21 -0
  272. package/dist/graphql/schema-loader.d.ts.map +1 -1
  273. package/dist/graphql/schema-loader.js +81 -12
  274. package/dist/graphql/schema-loader.js.map +1 -1
  275. package/dist/graphql/schema-rule-builder.d.ts +57 -20
  276. package/dist/graphql/schema-rule-builder.d.ts.map +1 -1
  277. package/dist/graphql/schema-rule-builder.js +101 -25
  278. package/dist/graphql/schema-rule-builder.js.map +1 -1
  279. package/dist/helpers/baseline-diagnostics.d.ts +45 -0
  280. package/dist/helpers/baseline-diagnostics.d.ts.map +1 -0
  281. package/dist/helpers/baseline-diagnostics.js +168 -0
  282. package/dist/helpers/baseline-diagnostics.js.map +1 -0
  283. package/dist/helpers/baseline-generator.d.ts +19 -0
  284. package/dist/helpers/baseline-generator.d.ts.map +1 -0
  285. package/dist/helpers/baseline-generator.js +18 -0
  286. package/dist/helpers/baseline-generator.js.map +1 -0
  287. package/dist/helpers/baseline.d.ts +336 -0
  288. package/dist/helpers/baseline.d.ts.map +1 -0
  289. package/dist/helpers/baseline.js +664 -0
  290. package/dist/helpers/baseline.js.map +1 -0
  291. package/dist/helpers/body-traversal.d.ts +27 -2
  292. package/dist/helpers/body-traversal.d.ts.map +1 -1
  293. package/dist/helpers/body-traversal.js +122 -16
  294. package/dist/helpers/body-traversal.js.map +1 -1
  295. package/dist/helpers/callback-extractor.d.ts.map +1 -1
  296. package/dist/helpers/callback-extractor.js +48 -47
  297. package/dist/helpers/callback-extractor.js.map +1 -1
  298. package/dist/helpers/complexity.d.ts +13 -5
  299. package/dist/helpers/complexity.d.ts.map +1 -1
  300. package/dist/helpers/complexity.js +15 -6
  301. package/dist/helpers/complexity.js.map +1 -1
  302. package/dist/helpers/diff-aware.d.ts +44 -0
  303. package/dist/helpers/diff-aware.d.ts.map +1 -0
  304. package/dist/helpers/diff-aware.js +84 -0
  305. package/dist/helpers/diff-aware.js.map +1 -0
  306. package/dist/helpers/matchers.d.ts +68 -7
  307. package/dist/helpers/matchers.d.ts.map +1 -1
  308. package/dist/helpers/matchers.js +114 -20
  309. package/dist/helpers/matchers.js.map +1 -1
  310. package/dist/helpers/slice-graph.d.ts +100 -8
  311. package/dist/helpers/slice-graph.d.ts.map +1 -1
  312. package/dist/helpers/slice-graph.js +126 -34
  313. package/dist/helpers/slice-graph.js.map +1 -1
  314. package/dist/helpers/tarjan.d.ts +0 -14
  315. package/dist/helpers/tarjan.d.ts.map +1 -1
  316. package/dist/helpers/tarjan.js +29 -16
  317. package/dist/helpers/tarjan.js.map +1 -1
  318. package/dist/index.d.ts +56 -17
  319. package/dist/index.d.ts.map +1 -1
  320. package/dist/index.js +57 -13
  321. package/dist/index.js.map +1 -1
  322. package/dist/models/arch-call.d.ts +3 -2
  323. package/dist/models/arch-call.d.ts.map +1 -1
  324. package/dist/models/arch-call.js.map +1 -1
  325. package/dist/models/arch-function.d.ts +28 -6
  326. package/dist/models/arch-function.d.ts.map +1 -1
  327. package/dist/models/arch-function.js +106 -3
  328. package/dist/models/arch-function.js.map +1 -1
  329. package/dist/models/arch-jsx-element.js +2 -2
  330. package/dist/models/arch-jsx-element.js.map +1 -1
  331. package/dist/models/slice.d.ts +33 -9
  332. package/dist/models/slice.d.ts.map +1 -1
  333. package/dist/models/slice.js +129 -19
  334. package/dist/models/slice.js.map +1 -1
  335. package/dist/predicates/call.d.ts.map +1 -1
  336. package/dist/predicates/call.js +5 -0
  337. package/dist/predicates/call.js.map +1 -1
  338. package/dist/predicates/identity.d.ts +21 -0
  339. package/dist/predicates/identity.d.ts.map +1 -1
  340. package/dist/predicates/identity.js +75 -3
  341. package/dist/predicates/identity.js.map +1 -1
  342. package/dist/predicates/index.d.ts +1 -1
  343. package/dist/predicates/index.d.ts.map +1 -1
  344. package/dist/predicates/index.js +1 -1
  345. package/dist/predicates/index.js.map +1 -1
  346. package/dist/predicates/metrics.d.ts +4 -2
  347. package/dist/predicates/metrics.d.ts.map +1 -1
  348. package/dist/predicates/metrics.js +4 -2
  349. package/dist/predicates/metrics.js.map +1 -1
  350. package/dist/predicates/module.d.ts +4 -12
  351. package/dist/predicates/module.d.ts.map +1 -1
  352. package/dist/predicates/module.js +57 -37
  353. package/dist/predicates/module.js.map +1 -1
  354. package/dist/presets/agent-guardrails.d.ts +22 -15
  355. package/dist/presets/agent-guardrails.d.ts.map +1 -1
  356. package/dist/presets/agent-guardrails.js +124 -19
  357. package/dist/presets/agent-guardrails.js.map +1 -1
  358. package/dist/presets/boundaries.d.ts +45 -2
  359. package/dist/presets/boundaries.d.ts.map +1 -1
  360. package/dist/presets/boundaries.js +132 -23
  361. package/dist/presets/boundaries.js.map +1 -1
  362. package/dist/presets/data-layer.d.ts +22 -2
  363. package/dist/presets/data-layer.d.ts.map +1 -1
  364. package/dist/presets/data-layer.js +58 -16
  365. package/dist/presets/data-layer.js.map +1 -1
  366. package/dist/presets/index.d.ts +7 -5
  367. package/dist/presets/index.d.ts.map +1 -1
  368. package/dist/presets/index.js +9 -3
  369. package/dist/presets/index.js.map +1 -1
  370. package/dist/presets/layered.d.ts +46 -2
  371. package/dist/presets/layered.d.ts.map +1 -1
  372. package/dist/presets/layered.js +66 -29
  373. package/dist/presets/layered.js.map +1 -1
  374. package/dist/presets/recommended.d.ts +80 -9
  375. package/dist/presets/recommended.d.ts.map +1 -1
  376. package/dist/presets/recommended.js +25 -23
  377. package/dist/presets/recommended.js.map +1 -1
  378. package/dist/presets/shared.d.ts +270 -2
  379. package/dist/presets/shared.d.ts.map +1 -1
  380. package/dist/presets/shared.js +338 -4
  381. package/dist/presets/shared.js.map +1 -1
  382. package/dist/rules/code-quality.d.ts.map +1 -1
  383. package/dist/rules/code-quality.js +15 -6
  384. package/dist/rules/code-quality.js.map +1 -1
  385. package/dist/rules/hygiene.d.ts +1 -1
  386. package/dist/rules/hygiene.js +1 -1
  387. package/dist/rules/metrics-function.d.ts +2 -1
  388. package/dist/rules/metrics-function.d.ts.map +1 -1
  389. package/dist/rules/metrics-function.js +33 -6
  390. package/dist/rules/metrics-function.js.map +1 -1
  391. package/dist/rules/metrics.d.ts +2 -1
  392. package/dist/rules/metrics.d.ts.map +1 -1
  393. package/dist/rules/metrics.js +39 -9
  394. package/dist/rules/metrics.js.map +1 -1
  395. package/dist/smells/duplicate-bodies.d.ts +58 -5
  396. package/dist/smells/duplicate-bodies.d.ts.map +1 -1
  397. package/dist/smells/duplicate-bodies.js +137 -56
  398. package/dist/smells/duplicate-bodies.js.map +1 -1
  399. package/dist/smells/fingerprint.d.ts +8 -1
  400. package/dist/smells/fingerprint.d.ts.map +1 -1
  401. package/dist/smells/fingerprint.js +21 -3
  402. package/dist/smells/fingerprint.js.map +1 -1
  403. package/dist/smells/inconsistent-siblings.d.ts +128 -7
  404. package/dist/smells/inconsistent-siblings.d.ts.map +1 -1
  405. package/dist/smells/inconsistent-siblings.js +288 -86
  406. package/dist/smells/inconsistent-siblings.js.map +1 -1
  407. package/dist/smells/sibling-files.d.ts +47 -0
  408. package/dist/smells/sibling-files.d.ts.map +1 -0
  409. package/dist/smells/sibling-files.js +104 -0
  410. package/dist/smells/sibling-files.js.map +1 -0
  411. package/dist/smells/similar-pairs.d.ts +27 -0
  412. package/dist/smells/similar-pairs.d.ts.map +1 -0
  413. package/dist/smells/similar-pairs.js +52 -0
  414. package/dist/smells/similar-pairs.js.map +1 -0
  415. package/dist/smells/smell-builder.d.ts +57 -12
  416. package/dist/smells/smell-builder.d.ts.map +1 -1
  417. package/dist/smells/smell-builder.js +111 -14
  418. package/dist/smells/smell-builder.js.map +1 -1
  419. package/dist/tsconfig/index.d.ts +19 -0
  420. package/dist/tsconfig/index.d.ts.map +1 -0
  421. package/dist/tsconfig/index.js +20 -0
  422. package/dist/tsconfig/index.js.map +1 -0
  423. package/dist/tsconfig/tsconfig-builder.d.ts +42 -9
  424. package/dist/tsconfig/tsconfig-builder.d.ts.map +1 -1
  425. package/dist/tsconfig/tsconfig-builder.js +64 -16
  426. package/dist/tsconfig/tsconfig-builder.js.map +1 -1
  427. package/package.json +3 -2
  428. package/dist/core/module-dependencies.d.ts +0 -28
  429. package/dist/core/module-dependencies.d.ts.map +0 -1
  430. package/dist/core/module-dependencies.js +0 -35
  431. package/dist/core/module-dependencies.js.map +0 -1
  432. package/dist/helpers/within.d.ts.map +0 -1
  433. package/dist/helpers/within.js.map +0 -1
@@ -0,0 +1,310 @@
1
+ import path from 'node:path';
2
+ import { Project, SyntaxKind } from 'ts-morph';
3
+ // A directive must BEGIN its comment. The regexes are anchored at `^` and the
4
+ // caller slices each line from its first `//`, so they see the comment and
5
+ // nothing before it — which keeps the documented TRAILING form working
6
+ // (`const a = 1 // <directive>`), where the comment starts mid-line. Anchoring
7
+ // to the start of the LINE instead was the first attempt and broke exactly
8
+ // that; the guard's trailing rows caught it.
9
+ //
10
+ // It used to match anywhere in the line, which made any comment *mentioning*
11
+ // the syntax a live directive. This file's own grammar documentation was one:
12
+ // a line reading "Single-line without reason: <the directive>" declared a
13
+ // real, reason-less exclusion against whatever rule was being evaluated, and
14
+ // this repo's preset fan-out test caught it the moment comments started being
15
+ // read correctly. Every user documenting the feature in a code comment would
16
+ // have hit the same thing.
17
+ //
18
+ // A trailing directive still works — `const a = 1 // <directive>` — because
19
+ // there the comment itself begins with it.
20
+ const SINGLE_LINE_RE = /^\/\/\s*eess-exclude\s+(.+)/;
21
+ // Block start: // eess-exclude-start <rule-id>[, <rule-id>]: <reason>
22
+ const BLOCK_START_RE = /^\/\/\s*eess-exclude-start\s+(.+)/;
23
+ // Block end: // eess-exclude-end
24
+ const BLOCK_END_RE = /^\/\/\s*eess-exclude-end\b/;
25
+ /**
26
+ * Parse rule IDs and reason from the content after the directive keyword.
27
+ *
28
+ * Format: `rule-a, rule-b: reason text`
29
+ * If no colon is present, all content is treated as rule IDs and reason is empty.
30
+ */
31
+ function parseRuleIdsAndReason(content) {
32
+ const colonIndex = content.indexOf(':');
33
+ if (colonIndex < 0) {
34
+ // No colon — all content is rule IDs, no reason
35
+ const ruleIds = content
36
+ .split(',')
37
+ .map((s) => s.trim())
38
+ .filter((s) => s.length > 0);
39
+ return { ruleIds, reason: '' };
40
+ }
41
+ const idsPart = content.slice(0, colonIndex);
42
+ const reason = content.slice(colonIndex + 1).trim();
43
+ const ruleIds = idsPart
44
+ .split(',')
45
+ .map((s) => s.trim())
46
+ .filter((s) => s.length > 0);
47
+ return { ruleIds, reason };
48
+ }
49
+ /** Handle a block-end directive line. */
50
+ function handleBlockEnd(frames, exclusions, warnings, filePath, lineNum) {
51
+ const innermost = frames.pop();
52
+ if (innermost === undefined) {
53
+ warnings.push({
54
+ message: `eess-exclude-end without matching start`,
55
+ file: filePath,
56
+ line: lineNum,
57
+ kind: 'malformed',
58
+ });
59
+ return;
60
+ }
61
+ // Close the innermost frame only. This used to close **every** open block,
62
+ // which is how a nested region silently ended its parent early (bug 0039):
63
+ // the inner `-end` closed the outer, and everything after it was unexcluded
64
+ // while looking excluded in the source.
65
+ for (const comment of innermost) {
66
+ comment.endLine = lineNum;
67
+ exclusions.push(comment);
68
+ }
69
+ }
70
+ /** Emit undocumented-exclusion warnings for each rule ID when no reason is given. */
71
+ function warnUndocumented(warnings, ruleIds, directive, filePath, lineNum) {
72
+ for (const ruleId of ruleIds) {
73
+ warnings.push({
74
+ message: `Undocumented exclusion at ${filePath}:${String(lineNum)} — ` +
75
+ `// ${directive} ${ruleId}\n` +
76
+ ` Fix: Add a reason — // ${directive} ${ruleId}: <why>`,
77
+ file: filePath,
78
+ line: lineNum,
79
+ kind: 'undocumented',
80
+ });
81
+ }
82
+ }
83
+ /** Handle a block-start directive line. */
84
+ function handleBlockStart(content, frames, warnings, filePath, lineNum) {
85
+ const { ruleIds, reason } = parseRuleIdsAndReason(content);
86
+ if (reason === '') {
87
+ warnUndocumented(warnings, ruleIds, 'eess-exclude-start', filePath, lineNum);
88
+ }
89
+ // Nesting a DIFFERENT rule is legitimate and used to be refused outright —
90
+ // exempting `arch/no-cycles` across a module and `arch/no-any` across one
91
+ // function inside it is an ordinary thing to want. The old code warned and
92
+ // dropped the inner directive, then let the inner `-end` close the outer
93
+ // block, so both exemptions were wrong: the inner never applied and the outer
94
+ // stopped early. Frames make both work.
95
+ //
96
+ // Re-opening a rule that is ALREADY open is different — it is redundant, and
97
+ // the likeliest cause is a missing `-end`. Warned, but still pushed: refusing
98
+ // it is what produced the early-close bug.
99
+ const alreadyOpen = new Set(frames.flat().map((c) => c.ruleId));
100
+ for (const ruleId of ruleIds) {
101
+ if (alreadyOpen.has(ruleId)) {
102
+ warnings.push({
103
+ message: `eess-exclude-start for '${ruleId}' is already open — ` +
104
+ `the enclosing block covers this region. Fix: remove this directive, ` +
105
+ `or close the enclosing block first if the nesting was unintended.`,
106
+ file: filePath,
107
+ line: lineNum,
108
+ kind: 'malformed',
109
+ });
110
+ }
111
+ }
112
+ frames.push(ruleIds.map((ruleId) => ({
113
+ ruleId,
114
+ reason,
115
+ file: filePath,
116
+ line: lineNum,
117
+ isBlock: true,
118
+ })));
119
+ }
120
+ /** Handle a single-line exclude directive. */
121
+ function handleSingleLine(content, exclusions, warnings, filePath, lineNum) {
122
+ // Skip if this was a block start or end (already handled above, but guard)
123
+ if (content.startsWith('-start') || content.startsWith('-end'))
124
+ return;
125
+ const { ruleIds, reason } = parseRuleIdsAndReason(content);
126
+ if (reason === '') {
127
+ warnUndocumented(warnings, ruleIds, 'eess-exclude', filePath, lineNum);
128
+ }
129
+ for (const ruleId of ruleIds) {
130
+ exclusions.push({
131
+ ruleId,
132
+ reason,
133
+ file: filePath,
134
+ line: lineNum,
135
+ isBlock: false,
136
+ });
137
+ }
138
+ }
139
+ /**
140
+ * Scan a source file for eess-ts exclusion comments.
141
+ *
142
+ * Supported formats:
143
+ * // eess-exclude <rule-id>: <reason>
144
+ * // eess-exclude-start <rule-id>: <reason>
145
+ * // eess-exclude-end
146
+ * // eess-exclude <rule-a>, <rule-b>: <reason>
147
+ */
148
+ /**
149
+ * Every string-like literal, blanked — [ts-archunit bug 0043](https://github.com/nielspeter/ts-archunit/blob/main/bugs/fixed/0043-an-exclusion-directive-inside-a-string-literal-suppresses.md).
150
+ *
151
+ * The scan below is line-based, and a line-based scan cannot tell a directive
152
+ * from the same characters inside a string. Measured before this existed: all
153
+ * three of `"…"`, `'…'` and `` `…` `` containing the directive text produced a
154
+ * **live exclusion** that silenced a real finding — silently, because a
155
+ * directive carrying a reason never triggers the undocumented-exclusion warning.
156
+ *
157
+ * **Newlines are preserved**, and that is the load-bearing part: the scan below
158
+ * is line-based and reports `line` on every exclusion, so a mask that dropped a
159
+ * newline would misreport every directive after it.
160
+ *
161
+ * Characters are replaced with spaces rather than removed, which keeps
162
+ * intra-line offsets stable too — but nothing downstream consumes a column, so
163
+ * that half is defence in depth rather than a guarded property. Measured:
164
+ * collapsing the blanks to `''`, and masking one character short, both leave the
165
+ * suite green. Recorded rather than dressed up — a sabotage row that survives
166
+ * for a real reason is a different thing from a missing guard.
167
+ *
168
+ * ## Why a parse, and not a scan
169
+ *
170
+ * The first attempt used `ts.createScanner`, which is the real lexer and fixed
171
+ * the three plain cases. It left two: `` `${x} // …` `` and JSX text. A bare
172
+ * scanner has no parser context, so it cannot know when to re-scan a template
173
+ * middle or JSX children, and both were classified as code — meaning the `//`
174
+ * inside them became a comment. Measured, not predicted.
175
+ *
176
+ * So: parse, and blank the literals. Everything remaining is code, where `//`
177
+ * genuinely does start a comment.
178
+ *
179
+ * A **ts-morph** project rather than the raw compiler API, per
180
+ * [ADR-002](../../../../adr/002-ts-morph-ast-engine.md), reusing one in-memory project
181
+ * across calls so the cost is a parse rather than a project construction. The
182
+ * whole scan is gated on a rule having already produced a violation in the file,
183
+ * so nothing is parsed for a clean run.
184
+ *
185
+ * A `TemplateExpression` is blanked **whole**, including its `${…}`
186
+ * substitutions. A comment is legal inside a substitution, so this can miss a
187
+ * real directive there — it errs toward *not* suppressing, which is the safe
188
+ * direction for a mechanism whose failure mode is a silent green.
189
+ */
190
+ const LITERAL_KINDS = [
191
+ SyntaxKind.StringLiteral,
192
+ SyntaxKind.NoSubstitutionTemplateLiteral,
193
+ SyntaxKind.TemplateExpression,
194
+ SyntaxKind.RegularExpressionLiteral,
195
+ SyntaxKind.JsxText,
196
+ ];
197
+ let scratch;
198
+ function withoutLiterals(sourceText, filePath) {
199
+ scratch ??= new Project({ useInMemoryFileSystem: true });
200
+ // `.tsx` so JSX parses; a `.ts` parse reads `<div>` as a type assertion and
201
+ // the JsxText case silently stops being covered.
202
+ const sourceFile = scratch.createSourceFile(`/scan/${path.basename(filePath)}.tsx`, sourceText, {
203
+ overwrite: true,
204
+ });
205
+ const out = sourceText.split('');
206
+ for (const kind of LITERAL_KINDS) {
207
+ for (const node of sourceFile.getDescendantsOfKind(kind)) {
208
+ for (let i = node.getStart(); i < node.getEnd(); i++) {
209
+ if (out[i] !== undefined && out[i] !== '\n')
210
+ out[i] = ' ';
211
+ }
212
+ }
213
+ }
214
+ const withoutLiteralText = out.join('');
215
+ // Block comments too, and this is not tidying — it is the difference between
216
+ // documenting the feature and invoking it.
217
+ //
218
+ // The grammar is `//`-only and always has been (a `/* … */` directive produced
219
+ // no exclusion before this fix and still produces none). But a JSDoc block
220
+ // that *mentions* the directive in prose puts the characters on a line, and
221
+ // the line scan below cannot tell prose from a directive.
222
+ //
223
+ // Found the hard way: this very file's docstring explains the bug, contains
224
+ // the directive text, and the moment comments started being read correctly it
225
+ // declared a live exclusion against `preset/boundaries/no-cross-boundary` —
226
+ // caught by this repo's own preset fan-out test. Any user writing a code
227
+ // comment about the feature would hit the same thing.
228
+ //
229
+ // Safe to do with a regex here, and only here: every string, template and
230
+ // regex literal has already been blanked, so a surviving `/*` is a real
231
+ // block-comment start.
232
+ return withoutLiteralText.replace(/\/\*[\s\S]*?\*\//g, (m) => m.replace(/[^\n]/g, ' '));
233
+ }
234
+ export function parseExclusionComments(sourceText, filePath) {
235
+ // A directive inside a string is not a directive (bug 0043).
236
+ const lines = withoutLiterals(sourceText, filePath).split('\n');
237
+ const exclusions = [];
238
+ const warnings = [];
239
+ // A STACK of frames, one per `-start` line, each holding that line's rule ids.
240
+ // One `-end` closes one frame. A single-level block behaves exactly as before;
241
+ // nesting now works instead of silently mangling both regions.
242
+ const frames = [];
243
+ for (let i = 0; i < lines.length; i++) {
244
+ const line = lines[i];
245
+ if (line === undefined)
246
+ continue;
247
+ const lineNum = i + 1;
248
+ // Slice from the comment start. Literals are already blanked, so the first
249
+ // `//` on the line is a real comment opener — and anything before it is
250
+ // code, which cannot contain a directive.
251
+ const commentStart = line.indexOf('//');
252
+ if (commentStart === -1)
253
+ continue;
254
+ const comment = line.slice(commentStart);
255
+ // Check block end first (before start/single so we don't match -start as single)
256
+ if (BLOCK_END_RE.test(comment)) {
257
+ handleBlockEnd(frames, exclusions, warnings, filePath, lineNum);
258
+ continue;
259
+ }
260
+ // Check block start
261
+ const startMatch = BLOCK_START_RE.exec(comment);
262
+ if (startMatch?.[1]) {
263
+ handleBlockStart(startMatch[1], frames, warnings, filePath, lineNum);
264
+ continue;
265
+ }
266
+ // Check single-line exclude (must not match block directives)
267
+ const singleMatch = SINGLE_LINE_RE.exec(comment);
268
+ if (singleMatch?.[1]) {
269
+ handleSingleLine(singleMatch[1], exclusions, warnings, filePath, lineNum);
270
+ }
271
+ }
272
+ // Any unclosed frame is an error, and pushes no exclusion — so an unterminated
273
+ // block fails closed: the violation it meant to cover still fires.
274
+ for (const comment of frames.flat()) {
275
+ warnings.push({
276
+ message: `eess-exclude-start without matching end for rule '${comment.ruleId}'`,
277
+ file: filePath,
278
+ line: comment.line,
279
+ kind: 'malformed',
280
+ });
281
+ }
282
+ return { exclusions, warnings };
283
+ }
284
+ /**
285
+ * Check if a violation is covered by an exclusion comment.
286
+ *
287
+ * For single-line comments: the violation must be in the same file and
288
+ * on the line immediately after the comment.
289
+ *
290
+ * For block comments: the violation must be in the same file and
291
+ * within the line range (start line, end line) inclusive.
292
+ */
293
+ /** Check if a single comment covers the given violation. */
294
+ function commentCoversViolation(comment, violationLine) {
295
+ if (comment.isBlock) {
296
+ return (comment.endLine !== undefined &&
297
+ violationLine >= comment.line &&
298
+ violationLine <= comment.endLine);
299
+ }
300
+ return violationLine === comment.line + 1;
301
+ }
302
+ export function isExcludedByComment(violation, comments) {
303
+ const ruleId = violation.ruleId;
304
+ if (!ruleId)
305
+ return false;
306
+ return comments.some((comment) => comment.ruleId === ruleId &&
307
+ comment.file === violation.file &&
308
+ commentCoversViolation(comment, violation.line));
309
+ }
310
+ //# sourceMappingURL=exclusion-comments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exclusion-comments.js","sourceRoot":"","sources":["../../src/core/exclusion-comments.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,150 @@
1
+ import type { ArchViolation } from '@nielspeter/eess';
2
+ import type { CheckOptions, OutputFormat } from '@nielspeter/eess';
3
+ import type { RuleMetadata } from '@nielspeter/eess';
4
+ import type { EdgeCoverage } from '@nielspeter/eess';
5
+ /**
6
+ * Context for executing a rule's terminal methods.
7
+ * Shared across all builder types (RuleBuilder, SliceRuleBuilder,
8
+ * SchemaRuleBuilder, ResolverRuleBuilder, PairFinalBuilder, SmellBuilder).
9
+ */
10
+ interface ExecuteRuleContext {
11
+ reason?: string;
12
+ metadata?: RuleMetadata;
13
+ exclusions?: (string | RegExp)[];
14
+ silentIndices?: Set<number>;
15
+ }
16
+ /**
17
+ * Complete each violation's identity, then apply `.excluding()` patterns and
18
+ * inline exclusion comments.
19
+ *
20
+ * Extracted to eliminate terminal-method duplication across builders.
21
+ *
22
+ * **Not** baseline or diff filtering, despite what this said for several
23
+ * releases — those run in `executeCheck` / `executeWarn`, after this returns.
24
+ *
25
+ * ## The invariant, for whoever adds the next filter
26
+ *
27
+ * **Enrichment runs first, so every filter sees a complete violation.** That is
28
+ * the whole reason for the ordering, and it is easy to undo by accident because
29
+ * enrichment looks like output formatting rather than identity. It is not: the
30
+ * comment filter matches on `ruleId`, and when enrichment ran last that filter
31
+ * saw `undefined` for every condition that did not stamp the field itself
32
+ * (bug 0041) — a documented feature that silently did nothing.
33
+ *
34
+ * Enrichment is pure, idempotent, and writes a **disjoint field set** from
35
+ * everything the filters read: it touches `ruleId`, `because`, `suggestion` and
36
+ * `docs`; `.excluding()` matches on `element`/`file`/`message`, and the
37
+ * `bypassFilters` refusal path reads a flag enrichment never writes. So
38
+ * "identity is complete before anything reads it" is a simpler invariant to hold
39
+ * than "each filter must know which fields exist yet". Add a filter that reads
40
+ * one of those four fields and it will work; add a mutation of them below a
41
+ * filter and you have reintroduced 0041.
42
+ */
43
+ export declare function applyFilters(violations: ArchViolation[], ctx: ExecuteRuleContext): ArchViolation[];
44
+ /**
45
+ * Write a severity-aware, single-document report for the given format.
46
+ *
47
+ * Shared by the CLI runner and the throwing `check` terminal so the three
48
+ * format branches live in one place:
49
+ * - `json` ALWAYS emits one valid document (even with zero violations) so
50
+ * consumers/agents can parse a clean run.
51
+ * - `github` partitions by severity so warnings render as `::warning`, not
52
+ * `::error`.
53
+ * - terminal (default) writes the rich format to stderr.
54
+ *
55
+ * Terminal/github emit nothing when there are no violations.
56
+ */
57
+ export declare function writeReport(violations: ArchViolation[], format?: OutputFormat, reason?: string,
58
+ /** Allowlist rules that tested no edges, for the JSON document (bug 0015). */
59
+ untested?: readonly EdgeCoverage[]): void;
60
+ /**
61
+ * Run `fn` with report aggregation on, restoring the previous value afterwards.
62
+ *
63
+ * **A dynamic extent, not a latch.** This replaced an exported
64
+ * `setCallerAggregatesReports(on)` that the CLI called once and nothing ever set
65
+ * back. Aggregation is a property of a RUN, and while `executeCheck` was the only
66
+ * reader the difference was invisible — the CLI wanted suppression for its whole
67
+ * life. It stopped being invisible the moment `deliver()` and `checkAll()` read it
68
+ * too (bug 0203): measured, a preset called directly in a process that had already
69
+ * run `runCheck` once emitted **6 violation blocks before and 0 after**. It still
70
+ * threw, so nothing went falsely green — but the report, the `Why:` and the `Fix:`
71
+ * were gone, with no signal that anything had been swallowed.
72
+ *
73
+ * Not an option on `CheckOptions`: a self-executing rule file writes `.check()`
74
+ * with no arguments and a preset is called by the RULE FILE, not by the CLI, so
75
+ * there is no per-call site the CLI could set. This is a property of who is
76
+ * driving the run.
77
+ *
78
+ * Restores rather than clears, so nesting cannot switch a still-running outer
79
+ * aggregation off.
80
+ */
81
+ export declare function withCallerAggregating<T>(fn: () => Promise<T>): Promise<T>;
82
+ /**
83
+ * How many violations have actually been WRITTEN by either emitter, ever.
84
+ *
85
+ * Read as a delta across one rule file's evaluation, this answers the only
86
+ * question the CLI's "your output was not filtered" notice may assert: *did
87
+ * anything emit while that module was loading?*
88
+ *
89
+ * **This replaced an inverted signal, and the inversion was a measured defect.**
90
+ * The first version counted the writes `executeCheck` SUPPRESSED and concluded
91
+ * "then nothing leaked" from the absence of a suppression. That is a double
92
+ * negative, and a rule file that suppresses one terminal while leaking through
93
+ * another satisfies it while leaking — measured: a `report: 'warn'` preset plus a
94
+ * silenced `.check()` in one file leaked 7 violation blocks and the notice stayed
95
+ * silent. A silence built from a stale signal is worse than the false claim it was
96
+ * introduced to fix, because the run says nothing at all.
97
+ *
98
+ * **Three emitters are counted, not two, and an earlier version of this docblock
99
+ * got the list wrong.** It said `writeReport` was "used by `executeCheck`,
100
+ * `executeWarn` and `check-all.ts`" — `executeWarn` does not call it. It writes
101
+ * through `writeStderr` / `process.stdout.write` directly, with its own
102
+ * json/github/terminal branching, so it moved neither counter and the leak
103
+ * detector could not see it. Measured: a live `.warn()` beside a throwing
104
+ * `.check()` under `--baseline` leaked its advisory findings in silence.
105
+ *
106
+ * The three: this module's `writeReport` (`executeCheck`, `check-all.ts`), this
107
+ * module's `executeWarn` advisory write, and the kernel's `reportViolations`
108
+ * (`finishPreset`). Missing any one reproduces the blind spot on that path — which
109
+ * is exactly what happened, twice.
110
+ *
111
+ * That every emitter must be counted, and that nothing enforces it, is
112
+ * [bug 0205](../../../../work/bugs/0205-four-emitters-restate-the-suppression-rule-and-disagree.md).
113
+ */
114
+ /**
115
+ * Is a caller aggregating reports for this run?
116
+ *
117
+ * Exposed so the two OTHER ts-side emitters can honour the same contract
118
+ * `executeCheck` does: `presets/shared.ts`'s `deliver()` and `core/check-all.ts`.
119
+ * Both used to emit unconditionally, so a preset or a `checkAll()` at module scope
120
+ * printed its findings before the aggregating caller saw them — and the caller then
121
+ * reported the same violations again off the throw. Bug 0203.
122
+ */
123
+ export declare function callerAggregates(): boolean;
124
+ export declare function violationsWritten(): number;
125
+ /**
126
+ * Execute the terminal "check" action: apply options, format, throw on violations.
127
+ */
128
+ export declare function executeCheck(violations: ArchViolation[], ctx: ExecuteRuleContext, options?: CheckOptions): void;
129
+ /**
130
+ * Execute the terminal "warn" action: apply options, format, log to stderr.
131
+ *
132
+ * Advisory for ordinary violations, which are logged exactly as before and
133
+ * never throw. **A `bypassFilters` configuration finding throws**, carrying
134
+ * only those findings.
135
+ *
136
+ * `.warn()` says "this rule's violations are advisory". A finding that the
137
+ * rule enforces nothing is not a violation of the rule — it reports that the
138
+ * rule cannot fire — and there is nothing advisory about that. Leaving the
139
+ * hole open would make `.warn()` the documented escape hatch for exactly the
140
+ * class of finding this release exists to surface, on exactly the
141
+ * gradual-adoption audience the docs point at it.
142
+ *
143
+ * The payload matters as much as the throw: an error carrying 200 warn-level
144
+ * violations plus one meta-finding would make "these findings are true" false
145
+ * for 200 of 201 entries. `.violations()` remains the non-throwing
146
+ * programmatic surface.
147
+ */
148
+ export declare function executeWarn(violations: ArchViolation[], ctx: ExecuteRuleContext, options?: CheckOptions): void;
149
+ export {};
150
+ //# sourceMappingURL=execute-rule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute-rule.d.ts","sourceRoot":"","sources":["../../src/core/execute-rule.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAOrD,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAWpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEpD;;;;GAIG;AACH,UAAU,kBAAkB;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,YAAY,CAAA;IACvB,UAAU,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAA;IAChC,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,aAAa,EAAE,EAC3B,GAAG,EAAE,kBAAkB,GACtB,aAAa,EAAE,CAgSjB;AAeD;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,aAAa,EAAE,EAC3B,MAAM,CAAC,EAAE,YAAY,EACrB,MAAM,CAAC,EAAE,MAAM;AACf,8EAA8E;AAC9E,QAAQ,GAAE,SAAS,YAAY,EAAO,GACrC,IAAI,CAoBN;AAwBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAQ/E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,aAAa,EAAE,EAC3B,GAAG,EAAE,kBAAkB,EACvB,OAAO,CAAC,EAAE,YAAY,GACrB,IAAI,CAqCN;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,aAAa,EAAE,EAC3B,GAAG,EAAE,kBAAkB,EACvB,OAAO,CAAC,EAAE,YAAY,GACrB,IAAI,CA+DN"}