@nielspeter/eess-ts 0.2.1 → 0.5.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 (467) hide show
  1. package/README.md +61 -35
  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 +75 -32
  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 +141 -55
  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 +385 -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 +182 -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 +177 -39
  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 +16 -19
  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 +243 -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 +109 -42
  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 +8 -3
  55. package/dist/cli/commands/baseline.d.ts.map +1 -1
  56. package/dist/cli/commands/baseline.js +111 -7
  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 +385 -47
  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 +47 -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 +101 -43
  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 +25 -32
  85. package/dist/cli/load-rules.js.map +1 -1
  86. package/dist/cli/resolve-config.d.ts +0 -8
  87. package/dist/cli/resolve-config.d.ts.map +1 -1
  88. package/dist/cli/resolve-config.js +25 -55
  89. package/dist/cli/resolve-config.js.map +1 -1
  90. package/dist/cli/rule-file-findings.d.ts +178 -0
  91. package/dist/cli/rule-file-findings.d.ts.map +1 -0
  92. package/dist/cli/rule-file-findings.js +351 -0
  93. package/dist/cli/rule-file-findings.js.map +1 -0
  94. package/dist/cli/watch.d.ts +17 -34
  95. package/dist/cli/watch.d.ts.map +1 -1
  96. package/dist/cli/watch.js +14 -129
  97. package/dist/cli/watch.js.map +1 -1
  98. package/dist/conditions/body-analysis-function.d.ts.map +1 -1
  99. package/dist/conditions/body-analysis-function.js +16 -7
  100. package/dist/conditions/body-analysis-function.js.map +1 -1
  101. package/dist/conditions/body-analysis-module.d.ts.map +1 -1
  102. package/dist/conditions/body-analysis-module.js +14 -9
  103. package/dist/conditions/body-analysis-module.js.map +1 -1
  104. package/dist/conditions/body-analysis.d.ts.map +1 -1
  105. package/dist/conditions/body-analysis.js +16 -7
  106. package/dist/conditions/body-analysis.js.map +1 -1
  107. package/dist/conditions/call.d.ts.map +1 -1
  108. package/dist/conditions/call.js +41 -19
  109. package/dist/conditions/call.js.map +1 -1
  110. package/dist/conditions/catch-analysis.d.ts +2 -1
  111. package/dist/conditions/catch-analysis.d.ts.map +1 -1
  112. package/dist/conditions/catch-analysis.js.map +1 -1
  113. package/dist/conditions/cross-layer.d.ts +2 -10
  114. package/dist/conditions/cross-layer.d.ts.map +1 -1
  115. package/dist/conditions/cross-layer.js +227 -23
  116. package/dist/conditions/cross-layer.js.map +1 -1
  117. package/dist/conditions/dependency.d.ts +35 -6
  118. package/dist/conditions/dependency.d.ts.map +1 -1
  119. package/dist/conditions/dependency.js +299 -45
  120. package/dist/conditions/dependency.js.map +1 -1
  121. package/dist/conditions/exports.d.ts.map +1 -1
  122. package/dist/conditions/exports.js +41 -37
  123. package/dist/conditions/exports.js.map +1 -1
  124. package/dist/conditions/function.d.ts.map +1 -1
  125. package/dist/conditions/function.js +19 -5
  126. package/dist/conditions/function.js.map +1 -1
  127. package/dist/conditions/helpers.d.ts +2 -1
  128. package/dist/conditions/helpers.d.ts.map +1 -1
  129. package/dist/conditions/helpers.js +4 -1
  130. package/dist/conditions/helpers.js.map +1 -1
  131. package/dist/conditions/jsx.d.ts.map +1 -1
  132. package/dist/conditions/jsx.js +7 -2
  133. package/dist/conditions/jsx.js.map +1 -1
  134. package/dist/conditions/match-identity.d.ts +43 -0
  135. package/dist/conditions/match-identity.d.ts.map +1 -0
  136. package/dist/conditions/match-identity.js +43 -0
  137. package/dist/conditions/match-identity.js.map +1 -0
  138. package/dist/conditions/members.d.ts.map +1 -1
  139. package/dist/conditions/members.js +20 -6
  140. package/dist/conditions/members.js.map +1 -1
  141. package/dist/conditions/reverse-dependency.d.ts +18 -5
  142. package/dist/conditions/reverse-dependency.d.ts.map +1 -1
  143. package/dist/conditions/reverse-dependency.js +155 -93
  144. package/dist/conditions/reverse-dependency.js.map +1 -1
  145. package/dist/conditions/slice.d.ts +86 -2
  146. package/dist/conditions/slice.d.ts.map +1 -1
  147. package/dist/conditions/slice.js +234 -53
  148. package/dist/conditions/slice.js.map +1 -1
  149. package/dist/conditions/structural.d.ts.map +1 -1
  150. package/dist/conditions/structural.js +16 -4
  151. package/dist/conditions/structural.js.map +1 -1
  152. package/dist/core/check-all.d.ts +19 -0
  153. package/dist/core/check-all.d.ts.map +1 -0
  154. package/dist/core/check-all.js +150 -0
  155. package/dist/core/check-all.js.map +1 -0
  156. package/dist/core/combinators.d.ts +48 -0
  157. package/dist/core/combinators.d.ts.map +1 -0
  158. package/dist/core/combinators.js +49 -0
  159. package/dist/core/combinators.js.map +1 -0
  160. package/dist/core/descendant-cache.d.ts +36 -0
  161. package/dist/core/descendant-cache.d.ts.map +1 -0
  162. package/dist/core/descendant-cache.js +117 -0
  163. package/dist/core/descendant-cache.js.map +1 -0
  164. package/dist/core/diagnose.d.ts +234 -0
  165. package/dist/core/diagnose.d.ts.map +1 -0
  166. package/dist/core/diagnose.js +390 -0
  167. package/dist/core/diagnose.js.map +1 -0
  168. package/dist/core/disk-set.d.ts +48 -0
  169. package/dist/core/disk-set.d.ts.map +1 -0
  170. package/dist/core/disk-set.js +218 -0
  171. package/dist/core/disk-set.js.map +1 -0
  172. package/dist/core/element-cache.d.ts +75 -0
  173. package/dist/core/element-cache.d.ts.map +1 -0
  174. package/dist/core/element-cache.js +32 -0
  175. package/dist/core/element-cache.js.map +1 -0
  176. package/dist/core/empty-project-advice.d.ts +75 -0
  177. package/dist/core/empty-project-advice.d.ts.map +1 -0
  178. package/dist/core/empty-project-advice.js +61 -0
  179. package/dist/core/empty-project-advice.js.map +1 -0
  180. package/dist/core/exclusion-comments.d.ts +19 -0
  181. package/dist/core/exclusion-comments.d.ts.map +1 -0
  182. package/dist/core/exclusion-comments.js +7 -0
  183. package/dist/core/exclusion-comments.js.map +1 -0
  184. package/dist/core/execute-rule.d.ts +158 -0
  185. package/dist/core/execute-rule.d.ts.map +1 -0
  186. package/dist/core/execute-rule.js +666 -0
  187. package/dist/core/execute-rule.js.map +1 -0
  188. package/dist/core/glob-diagnosis.d.ts +78 -0
  189. package/dist/core/glob-diagnosis.d.ts.map +1 -0
  190. package/dist/core/glob-diagnosis.js +134 -0
  191. package/dist/core/glob-diagnosis.js.map +1 -0
  192. package/dist/core/glob-evaluator.d.ts +48 -0
  193. package/dist/core/glob-evaluator.d.ts.map +1 -0
  194. package/dist/core/glob-evaluator.js +89 -0
  195. package/dist/core/glob-evaluator.js.map +1 -0
  196. package/dist/core/import-candidates.d.ts +60 -0
  197. package/dist/core/import-candidates.d.ts.map +1 -0
  198. package/dist/core/import-candidates.js +93 -0
  199. package/dist/core/import-candidates.js.map +1 -0
  200. package/dist/core/import-options.d.ts +55 -2
  201. package/dist/core/import-options.d.ts.map +1 -1
  202. package/dist/core/import-options.js +64 -0
  203. package/dist/core/import-options.js.map +1 -1
  204. package/dist/core/invalidate-on-modify.d.ts +20 -0
  205. package/dist/core/invalidate-on-modify.d.ts.map +1 -0
  206. package/dist/core/invalidate-on-modify.js +26 -0
  207. package/dist/core/invalidate-on-modify.js.map +1 -0
  208. package/dist/core/line-index.d.ts +3 -0
  209. package/dist/core/line-index.d.ts.map +1 -0
  210. package/dist/core/line-index.js +227 -0
  211. package/dist/core/line-index.js.map +1 -0
  212. package/dist/core/metric-violation.d.ts +86 -0
  213. package/dist/core/metric-violation.d.ts.map +1 -0
  214. package/dist/core/metric-violation.js +132 -0
  215. package/dist/core/metric-violation.js.map +1 -0
  216. package/dist/core/module-edges.d.ts +361 -0
  217. package/dist/core/module-edges.d.ts.map +1 -0
  218. package/dist/core/module-edges.js +593 -0
  219. package/dist/core/module-edges.js.map +1 -0
  220. package/dist/core/object-literal-functions.d.ts +42 -0
  221. package/dist/core/object-literal-functions.d.ts.map +1 -0
  222. package/dist/core/object-literal-functions.js +75 -0
  223. package/dist/core/object-literal-functions.js.map +1 -0
  224. package/dist/core/orphan-exclusions.d.ts +44 -0
  225. package/dist/core/orphan-exclusions.d.ts.map +1 -0
  226. package/dist/core/orphan-exclusions.js +224 -0
  227. package/dist/core/orphan-exclusions.js.map +1 -0
  228. package/dist/core/pair-condition.d.ts +32 -3
  229. package/dist/core/pair-condition.d.ts.map +1 -1
  230. package/dist/core/path-universe.d.ts +22 -0
  231. package/dist/core/path-universe.d.ts.map +1 -0
  232. package/dist/core/path-universe.js +45 -0
  233. package/dist/core/path-universe.js.map +1 -0
  234. package/dist/core/per-root-compiler-options.d.ts +20 -0
  235. package/dist/core/per-root-compiler-options.d.ts.map +1 -0
  236. package/dist/core/per-root-compiler-options.js +57 -0
  237. package/dist/core/per-root-compiler-options.js.map +1 -0
  238. package/dist/core/project-relative.d.ts +98 -0
  239. package/dist/core/project-relative.d.ts.map +1 -0
  240. package/dist/core/project-relative.js +185 -0
  241. package/dist/core/project-relative.js.map +1 -0
  242. package/dist/core/project.d.ts +7 -1
  243. package/dist/core/project.d.ts.map +1 -1
  244. package/dist/core/project.js +29 -4
  245. package/dist/core/project.js.map +1 -1
  246. package/dist/core/rule-builder.d.ts +303 -0
  247. package/dist/core/rule-builder.d.ts.map +1 -0
  248. package/dist/core/rule-builder.js +463 -0
  249. package/dist/core/rule-builder.js.map +1 -0
  250. package/dist/core/rule-declaration.d.ts +32 -0
  251. package/dist/core/rule-declaration.d.ts.map +1 -0
  252. package/dist/core/rule-declaration.js +88 -0
  253. package/dist/core/rule-declaration.js.map +1 -0
  254. package/dist/core/terminal-builder.d.ts +629 -0
  255. package/dist/core/terminal-builder.d.ts.map +1 -0
  256. package/dist/core/terminal-builder.js +807 -0
  257. package/dist/core/terminal-builder.js.map +1 -0
  258. package/dist/core/terminal-execution.d.ts +39 -0
  259. package/dist/core/terminal-execution.d.ts.map +1 -0
  260. package/dist/core/terminal-execution.js +103 -0
  261. package/dist/core/terminal-execution.js.map +1 -0
  262. package/dist/core/ts-comment-mask.d.ts +2 -0
  263. package/dist/core/ts-comment-mask.d.ts.map +1 -0
  264. package/dist/core/ts-comment-mask.js +102 -0
  265. package/dist/core/ts-comment-mask.js.map +1 -0
  266. package/dist/core/vacuity-diagnosis.d.ts +103 -0
  267. package/dist/core/vacuity-diagnosis.d.ts.map +1 -0
  268. package/dist/core/vacuity-diagnosis.js +415 -0
  269. package/dist/core/vacuity-diagnosis.js.map +1 -0
  270. package/dist/core/violation.d.ts +16 -11
  271. package/dist/core/violation.d.ts.map +1 -1
  272. package/dist/core/violation.js +33 -13
  273. package/dist/core/violation.js.map +1 -1
  274. package/dist/graphql/graphql-rule-builder.d.ts +95 -0
  275. package/dist/graphql/graphql-rule-builder.d.ts.map +1 -0
  276. package/dist/graphql/graphql-rule-builder.js +127 -0
  277. package/dist/graphql/graphql-rule-builder.js.map +1 -0
  278. package/dist/graphql/index.d.ts +1 -0
  279. package/dist/graphql/index.d.ts.map +1 -1
  280. package/dist/graphql/index.js +2 -1
  281. package/dist/graphql/index.js.map +1 -1
  282. package/dist/graphql/resolver-rule-builder.d.ts +44 -23
  283. package/dist/graphql/resolver-rule-builder.d.ts.map +1 -1
  284. package/dist/graphql/resolver-rule-builder.js +80 -72
  285. package/dist/graphql/resolver-rule-builder.js.map +1 -1
  286. package/dist/graphql/schema-loader.d.ts +21 -0
  287. package/dist/graphql/schema-loader.d.ts.map +1 -1
  288. package/dist/graphql/schema-loader.js +82 -12
  289. package/dist/graphql/schema-loader.js.map +1 -1
  290. package/dist/graphql/schema-predicates.d.ts.map +1 -1
  291. package/dist/graphql/schema-predicates.js +17 -12
  292. package/dist/graphql/schema-predicates.js.map +1 -1
  293. package/dist/graphql/schema-rule-builder.d.ts +15 -24
  294. package/dist/graphql/schema-rule-builder.d.ts.map +1 -1
  295. package/dist/graphql/schema-rule-builder.js +39 -77
  296. package/dist/graphql/schema-rule-builder.js.map +1 -1
  297. package/dist/helpers/baseline-diagnostics.d.ts +45 -0
  298. package/dist/helpers/baseline-diagnostics.d.ts.map +1 -0
  299. package/dist/helpers/baseline-diagnostics.js +168 -0
  300. package/dist/helpers/baseline-diagnostics.js.map +1 -0
  301. package/dist/helpers/baseline-generator.d.ts +28 -0
  302. package/dist/helpers/baseline-generator.d.ts.map +1 -0
  303. package/dist/helpers/baseline-generator.js +27 -0
  304. package/dist/helpers/baseline-generator.js.map +1 -0
  305. package/dist/helpers/baseline.d.ts +336 -0
  306. package/dist/helpers/baseline.d.ts.map +1 -0
  307. package/dist/helpers/baseline.js +664 -0
  308. package/dist/helpers/baseline.js.map +1 -0
  309. package/dist/helpers/body-traversal.d.ts +27 -2
  310. package/dist/helpers/body-traversal.d.ts.map +1 -1
  311. package/dist/helpers/body-traversal.js +135 -16
  312. package/dist/helpers/body-traversal.js.map +1 -1
  313. package/dist/helpers/callback-extractor.d.ts.map +1 -1
  314. package/dist/helpers/callback-extractor.js +53 -84
  315. package/dist/helpers/callback-extractor.js.map +1 -1
  316. package/dist/helpers/complexity.d.ts +13 -5
  317. package/dist/helpers/complexity.d.ts.map +1 -1
  318. package/dist/helpers/complexity.js +15 -6
  319. package/dist/helpers/complexity.js.map +1 -1
  320. package/dist/helpers/diff-aware.d.ts +16 -0
  321. package/dist/helpers/diff-aware.d.ts.map +1 -0
  322. package/dist/helpers/diff-aware.js +16 -0
  323. package/dist/helpers/diff-aware.js.map +1 -0
  324. package/dist/helpers/matchers.d.ts +68 -7
  325. package/dist/helpers/matchers.d.ts.map +1 -1
  326. package/dist/helpers/matchers.js +164 -86
  327. package/dist/helpers/matchers.js.map +1 -1
  328. package/dist/helpers/slice-graph.d.ts +100 -8
  329. package/dist/helpers/slice-graph.d.ts.map +1 -1
  330. package/dist/helpers/slice-graph.js +126 -34
  331. package/dist/helpers/slice-graph.js.map +1 -1
  332. package/dist/helpers/tarjan.d.ts +0 -14
  333. package/dist/helpers/tarjan.d.ts.map +1 -1
  334. package/dist/helpers/tarjan.js +29 -16
  335. package/dist/helpers/tarjan.js.map +1 -1
  336. package/dist/index.d.ts +55 -19
  337. package/dist/index.d.ts.map +1 -1
  338. package/dist/index.js +67 -15
  339. package/dist/index.js.map +1 -1
  340. package/dist/models/arch-call.d.ts +3 -2
  341. package/dist/models/arch-call.d.ts.map +1 -1
  342. package/dist/models/arch-call.js.map +1 -1
  343. package/dist/models/arch-function.d.ts +54 -8
  344. package/dist/models/arch-function.d.ts.map +1 -1
  345. package/dist/models/arch-function.js +145 -8
  346. package/dist/models/arch-function.js.map +1 -1
  347. package/dist/models/arch-jsx-element.d.ts.map +1 -1
  348. package/dist/models/arch-jsx-element.js +18 -19
  349. package/dist/models/arch-jsx-element.js.map +1 -1
  350. package/dist/models/slice.d.ts +33 -9
  351. package/dist/models/slice.d.ts.map +1 -1
  352. package/dist/models/slice.js +129 -19
  353. package/dist/models/slice.js.map +1 -1
  354. package/dist/predicates/call.d.ts.map +1 -1
  355. package/dist/predicates/call.js +5 -0
  356. package/dist/predicates/call.js.map +1 -1
  357. package/dist/predicates/identity.d.ts +21 -0
  358. package/dist/predicates/identity.d.ts.map +1 -1
  359. package/dist/predicates/identity.js +75 -3
  360. package/dist/predicates/identity.js.map +1 -1
  361. package/dist/predicates/index.d.ts +1 -1
  362. package/dist/predicates/index.d.ts.map +1 -1
  363. package/dist/predicates/index.js +1 -1
  364. package/dist/predicates/index.js.map +1 -1
  365. package/dist/predicates/jsx.d.ts.map +1 -1
  366. package/dist/predicates/jsx.js +2 -1
  367. package/dist/predicates/jsx.js.map +1 -1
  368. package/dist/predicates/metrics.d.ts +4 -2
  369. package/dist/predicates/metrics.d.ts.map +1 -1
  370. package/dist/predicates/metrics.js +4 -2
  371. package/dist/predicates/metrics.js.map +1 -1
  372. package/dist/predicates/module.d.ts +4 -12
  373. package/dist/predicates/module.d.ts.map +1 -1
  374. package/dist/predicates/module.js +57 -37
  375. package/dist/predicates/module.js.map +1 -1
  376. package/dist/presets/agent-guardrails.d.ts +49 -16
  377. package/dist/presets/agent-guardrails.d.ts.map +1 -1
  378. package/dist/presets/agent-guardrails.js +308 -19
  379. package/dist/presets/agent-guardrails.js.map +1 -1
  380. package/dist/presets/boundaries.d.ts +46 -3
  381. package/dist/presets/boundaries.d.ts.map +1 -1
  382. package/dist/presets/boundaries.js +132 -23
  383. package/dist/presets/boundaries.js.map +1 -1
  384. package/dist/presets/data-layer.d.ts +23 -3
  385. package/dist/presets/data-layer.d.ts.map +1 -1
  386. package/dist/presets/data-layer.js +58 -16
  387. package/dist/presets/data-layer.js.map +1 -1
  388. package/dist/presets/index.d.ts +10 -5
  389. package/dist/presets/index.d.ts.map +1 -1
  390. package/dist/presets/index.js +19 -3
  391. package/dist/presets/index.js.map +1 -1
  392. package/dist/presets/layered.d.ts +47 -3
  393. package/dist/presets/layered.d.ts.map +1 -1
  394. package/dist/presets/layered.js +66 -29
  395. package/dist/presets/layered.js.map +1 -1
  396. package/dist/presets/recommended.d.ts +81 -10
  397. package/dist/presets/recommended.d.ts.map +1 -1
  398. package/dist/presets/recommended.js +25 -23
  399. package/dist/presets/recommended.js.map +1 -1
  400. package/dist/presets/shared.d.ts +267 -2
  401. package/dist/presets/shared.d.ts.map +1 -1
  402. package/dist/presets/shared.js +367 -4
  403. package/dist/presets/shared.js.map +1 -1
  404. package/dist/rules/code-quality.d.ts.map +1 -1
  405. package/dist/rules/code-quality.js +15 -6
  406. package/dist/rules/code-quality.js.map +1 -1
  407. package/dist/rules/hygiene.d.ts +1 -1
  408. package/dist/rules/hygiene.js +1 -1
  409. package/dist/rules/metrics-function.d.ts +2 -1
  410. package/dist/rules/metrics-function.d.ts.map +1 -1
  411. package/dist/rules/metrics-function.js +63 -39
  412. package/dist/rules/metrics-function.js.map +1 -1
  413. package/dist/rules/metrics.d.ts +2 -1
  414. package/dist/rules/metrics.d.ts.map +1 -1
  415. package/dist/rules/metrics.js +80 -47
  416. package/dist/rules/metrics.js.map +1 -1
  417. package/dist/smells/clusters.d.ts +78 -0
  418. package/dist/smells/clusters.d.ts.map +1 -0
  419. package/dist/smells/clusters.js +124 -0
  420. package/dist/smells/clusters.js.map +1 -0
  421. package/dist/smells/duplicate-bodies.d.ts +92 -5
  422. package/dist/smells/duplicate-bodies.d.ts.map +1 -1
  423. package/dist/smells/duplicate-bodies.js +203 -73
  424. package/dist/smells/duplicate-bodies.js.map +1 -1
  425. package/dist/smells/duplicate-report.d.ts +90 -0
  426. package/dist/smells/duplicate-report.d.ts.map +1 -0
  427. package/dist/smells/duplicate-report.js +344 -0
  428. package/dist/smells/duplicate-report.js.map +1 -0
  429. package/dist/smells/fingerprint.d.ts +20 -1
  430. package/dist/smells/fingerprint.d.ts.map +1 -1
  431. package/dist/smells/fingerprint.js +27 -3
  432. package/dist/smells/fingerprint.js.map +1 -1
  433. package/dist/smells/inconsistent-siblings.d.ts +128 -7
  434. package/dist/smells/inconsistent-siblings.d.ts.map +1 -1
  435. package/dist/smells/inconsistent-siblings.js +288 -86
  436. package/dist/smells/inconsistent-siblings.js.map +1 -1
  437. package/dist/smells/sibling-files.d.ts +47 -0
  438. package/dist/smells/sibling-files.d.ts.map +1 -0
  439. package/dist/smells/sibling-files.js +104 -0
  440. package/dist/smells/sibling-files.js.map +1 -0
  441. package/dist/smells/similar-pairs.d.ts +28 -0
  442. package/dist/smells/similar-pairs.d.ts.map +1 -0
  443. package/dist/smells/similar-pairs.js +134 -0
  444. package/dist/smells/similar-pairs.js.map +1 -0
  445. package/dist/smells/smell-builder.d.ts +57 -12
  446. package/dist/smells/smell-builder.d.ts.map +1 -1
  447. package/dist/smells/smell-builder.js +112 -14
  448. package/dist/smells/smell-builder.js.map +1 -1
  449. package/dist/smells/variation.d.ts +47 -0
  450. package/dist/smells/variation.d.ts.map +1 -0
  451. package/dist/smells/variation.js +90 -0
  452. package/dist/smells/variation.js.map +1 -0
  453. package/dist/tsconfig/index.d.ts +19 -0
  454. package/dist/tsconfig/index.d.ts.map +1 -0
  455. package/dist/tsconfig/index.js +20 -0
  456. package/dist/tsconfig/index.js.map +1 -0
  457. package/dist/tsconfig/tsconfig-builder.d.ts +42 -9
  458. package/dist/tsconfig/tsconfig-builder.d.ts.map +1 -1
  459. package/dist/tsconfig/tsconfig-builder.js +65 -16
  460. package/dist/tsconfig/tsconfig-builder.js.map +1 -1
  461. package/package.json +4 -2
  462. package/dist/core/module-dependencies.d.ts +0 -28
  463. package/dist/core/module-dependencies.d.ts.map +0 -1
  464. package/dist/core/module-dependencies.js +0 -35
  465. package/dist/core/module-dependencies.js.map +0 -1
  466. package/dist/helpers/within.d.ts.map +0 -1
  467. package/dist/helpers/within.js.map +0 -1
@@ -0,0 +1,132 @@
1
+ import { createViolation, enclosingScopeName, getElementName } from './violation.js';
2
+ /**
3
+ * A finding whose message states a **measurement** — bug 0012.
4
+ *
5
+ * Metric conditions write the measured value into the message:
6
+ *
7
+ * Big has 10 methods (max: 5) — consider splitting into focused classes
8
+ *
9
+ * `hashViolation` identifies a violation by its message, so the identity moved
10
+ * whenever the measurement moved — **in either direction**. Baseline a class at
11
+ * 10 methods, delete two, and the finding was reported as new:
12
+ *
13
+ * 10 → 10 green ✓
14
+ * 10 → 12 red ✓ (worse)
15
+ * 10 → 8 RED ✗ (better — the defect)
16
+ * 10 → 5 green ✓ (under the threshold)
17
+ *
18
+ * Paying down the debt failed CI, and kept failing on every incremental step
19
+ * until the class dropped under the threshold entirely. A team that split four
20
+ * methods out of an 87-method service got a red build for its trouble. The
21
+ * external audit that motivated this recommends adopting these rules "behind a
22
+ * ratchet (accept today's god objects, block new regressions)" and records them
23
+ * at **zero uses** — the ratchet they were told to use did not work.
24
+ *
25
+ * ## Why identity alone cannot fix it
26
+ *
27
+ * Bug 0010 added `identity` for messages that state a derived population, and
28
+ * applying it naively here trades one failure for a worse one:
29
+ *
30
+ * | identity contains | improving to 8 | regressing to 12 |
31
+ * | ----------------- | -------------- | ---------------- |
32
+ * | the count | **red** ✗ | red ✓ |
33
+ * | no count | green ✓ | **green** ✗ |
34
+ *
35
+ * Dropping the count turns the baseline into a mute button. Identity answers
36
+ * "is this the same finding?", and a metric needs "is it **worse** than what we
37
+ * accepted?" — a comparison, not an equality. So this carries both: a stable
38
+ * identity that finds the entry, and `measured`, which the baseline stores and
39
+ * compares. See `Baseline.isKnown`.
40
+ *
41
+ * **Ten sites produce these, not the eight the bug enumerated.** That table was
42
+ * built by grepping the `has N <noun>` message shape, which misses the two
43
+ * complexity conditions — `has cyclomatic complexity N` puts the number last.
44
+ * Both were left on `createViolation` in the first cut of this fix while the
45
+ * docs already claimed complexity was ratcheted, so a reader would have removed
46
+ * their CI escape hatch for a gate that still fired on every improvement. Found
47
+ * by review; a mechanical enumeration by *shape* is not one by *behaviour*.
48
+ */
49
+ export function metricViolation(node, options, context) {
50
+ const base = createViolation(node, options.message, context);
51
+ return {
52
+ ...base,
53
+ // The qualified name reaches `element` too, not only `identity` — bug 0068's
54
+ // first consequence. `createViolation` derives it with `getElementName`,
55
+ // which resolves an unnamed node up to its nearest named ancestor, so a
56
+ // finding ABOUT an object-literal function was labelled with the ENCLOSING
57
+ // function's name while its own message named it correctly. `element` is
58
+ // what the terminal prints, what the JSON reports, and one of the three
59
+ // fields string-form `.excluding()` matches by exact membership
60
+ // (`execute-rule.ts`), so the disagreement also made an exclusion written
61
+ // against the printed name silently miss.
62
+ element: options.qualifiedName ?? base.element,
63
+ // File, element and metric — never the value. The value is the thing being
64
+ // ratcheted, so putting it here makes every change a new finding, which is
65
+ // the bug. Leaving the FILE out is the other half, and it was shipped once:
66
+ // two classes named `Big` in different files produced one identity, one
67
+ // hash, and `withBaseline`'s last-write-wins picked whichever ceiling came
68
+ // last — measured, a real 10 → 15 regression was silently accepted while
69
+ // the sibling sat at 20. That is bug 0028's shape recreated inside bug
70
+ // 0012's fix, and `ArchViolation.identity`'s own contract forbids it: "two
71
+ // distinct violations sharing one identity are one violation to the
72
+ // baseline, and accepting either accepts both."
73
+ //
74
+ // A path here is portable: `hashViolation` scrubs identity through
75
+ // `normalizeIdentityText(text, root)`, which is what that scrub is for.
76
+ identity: `${node.getSourceFile().getFilePath()}::${identityName(node, options.qualifiedName)}::${options.metric}`,
77
+ measured: options.measured,
78
+ // Defaults to the metric's own name: for `methods` or `parameters` the name
79
+ // IS the unit, and only a metric that can change what it counts under a
80
+ // stable name needs to say so explicitly.
81
+ measuredUnit: options.unit ?? options.metric,
82
+ };
83
+ }
84
+ /**
85
+ * The name segment of a metric identity: the subject's own name, **prefixed by the
86
+ * name of whatever encloses it**, so that two subjects sharing a name in one file
87
+ * are still two identities.
88
+ *
89
+ * Measured, across every function shape — neither name alone is sufficient:
90
+ *
91
+ * | shape | own name | enclosing scope | identity segment |
92
+ * | ------------------------------------ | ------------------- | --------------- | ------------------------- |
93
+ * | two factories returning `{build}` | `build`, `build` | `makeBeta`, `makeGamma` | `makeBeta.build`, … |
94
+ * | an arrow inside a named function | `errorResponseBuilder` | `makeAlpha` | `makeAlpha.errorResponseBuilder` |
95
+ * | a top-level `function takesFive` | `takesFive` | none | `takesFive` — unchanged |
96
+ * | a class method via `functions()` | `Repo.save` | `Repo` | `Repo.save` — already carries it |
97
+ *
98
+ * Two mistakes are recorded here because both shipped and both were found by
99
+ * review rather than by reasoning:
100
+ *
101
+ * 1. **The own name alone** (bug 0068's first fix) moved the collision instead of
102
+ * closing it: `owningBindingName` deliberately declines to prefix a literal
103
+ * returned from a factory, so both `build`s are just `build`.
104
+ * 2. **`getElementName` is not a scope.** It returns the node's OWN name when the
105
+ * node has one and only walks ancestors otherwise — so for method shorthand
106
+ * (`{ build() {} }`, a `MethodDeclaration`) it returned `build`, the prefix was
107
+ * skipped, and the fix worked for the arrow spelling of the same code and not
108
+ * for this one. The scope now comes from `enclosingScopeName`, which always
109
+ * walks from the parent.
110
+ *
111
+ * There is deliberately **no `own === scope` short-circuit**: a nested function
112
+ * whose name equals its enclosing function's (`function save() { return { save:
113
+ * … } }`) is exactly the case that needs the prefix, and equality of strings
114
+ * cannot tell "the scope is me" from "the scope happens to share my name".
115
+ *
116
+ * Known limit, stated rather than papered over: a literal in a **call argument**
117
+ * at module level (`register({ handler: … })`) has no enclosing named
118
+ * declaration, so two of them in one file still share an identity. Nothing stable
119
+ * distinguishes them — that is bug 0067's territory ("there is no right name
120
+ * yet"), not this one's.
121
+ */
122
+ function identityName(node, qualifiedName) {
123
+ const own = qualifiedName ?? getElementName(node);
124
+ const scope = enclosingScopeName(node);
125
+ if (scope === undefined)
126
+ return own;
127
+ // Already carries it — a class method's `Repo.save` under scope `Repo`.
128
+ if (own.startsWith(`${scope}.`) || own.endsWith(`.${scope}`))
129
+ return own;
130
+ return `${scope}.${own}`;
131
+ }
132
+ //# sourceMappingURL=metric-violation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metric-violation.js","sourceRoot":"","sources":["../../src/core/metric-violation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAU,EACV,OA6BC,EACD,OAMC;IAED,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IAC5D,OAAO;QACL,GAAG,IAAI;QACP,6EAA6E;QAC7E,yEAAyE;QACzE,wEAAwE;QACxE,2EAA2E;QAC3E,yEAAyE;QACzE,wEAAwE;QACxE,gEAAgE;QAChE,0EAA0E;QAC1E,0CAA0C;QAC1C,OAAO,EAAE,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,OAAO;QAC9C,2EAA2E;QAC3E,2EAA2E;QAC3E,4EAA4E;QAC5E,wEAAwE;QACxE,2EAA2E;QAC3E,yEAAyE;QACzE,uEAAuE;QACvE,2EAA2E;QAC3E,oEAAoE;QACpE,gDAAgD;QAChD,EAAE;QACF,mEAAmE;QACnE,wEAAwE;QACxE,QAAQ,EAAE,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,WAAW,EAAE,KAAK,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,aAAa,CAAC,KAAK,OAAO,CAAC,MAAM,EAAE;QAClH,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,4EAA4E;QAC5E,wEAAwE;QACxE,0CAA0C;QAC1C,YAAY,EAAE,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,MAAM;KAC7C,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,SAAS,YAAY,CAAC,IAAU,EAAE,aAAiC;IACjE,MAAM,GAAG,GAAG,aAAa,IAAI,cAAc,CAAC,IAAI,CAAC,CAAA;IACjD,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAA;IACtC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,GAAG,CAAA;IACnC,wEAAwE;IACxE,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,EAAE,CAAC;QAAE,OAAO,GAAG,CAAA;IACxE,OAAO,GAAG,KAAK,IAAI,GAAG,EAAE,CAAA;AAC1B,CAAC"}
@@ -0,0 +1,361 @@
1
+ import type { SourceFile } from 'ts-morph';
2
+ /**
3
+ * One definition of "a module edge", for every condition that needs one.
4
+ *
5
+ * [ts-archunit Bug 0022](https://github.com/nielspeter/ts-archunit/blob/main/bugs/fixed/0022-forward-import-conditions-are-blind-to-reexports-and-dynamic-imports.md):
6
+ * `src/conditions/dependency.ts` collected edges from `sf.getImportDeclarations()`
7
+ * at five sites — static `import` statements and nothing else — while the reverse
8
+ * graph indexed static imports, re-exports **and** dynamic imports. So
9
+ * `onlyBeImportedVia('…')` saw a re-export as an import and `notImportFrom('…')`
10
+ * did not, and `export { x } from './banned.js'` crossed every banned edge
11
+ * unflagged.
12
+ *
13
+ * `SourceFile.getImportStringLiterals()` returns one literal per module
14
+ * specifier across every edge-carrying form, from the binder's cached
15
+ * `compilerNode.imports` rather than a descendant walk. Measured over 20 forms;
16
+ * the table lives in plan 0071 §1 and the fixture that pins it is
17
+ * `tests/fixtures/module-edge-forms/`.
18
+ *
19
+ * **Two classification traps**, both of which would mark a *runtime* dependency
20
+ * as erased — and both are why `kind` is a five-member union rather than four:
21
+ *
22
+ * - `import x = require('s')` has parent `ExternalModuleReference`. A 4-way
23
+ * branch ending in `else → 'type-expression'` gives it `typeOnly: true`,
24
+ * exempt under `ignoreTypeImports`. Common in hand-written `.d.ts`.
25
+ * - `require('s')` in `.js` under `allowJs` has parent `CallExpression`, the same
26
+ * as `import('s')`. `getExpression().getKind() === ImportKeyword` is the only
27
+ * discriminator, as `reverse-dependency.ts` already knew.
28
+ *
29
+ * **Nothing here narrows the literal.** `getImportStringLiterals()` is declared
30
+ * `StringLiteral[]` and ``import(`./x.js`)`` yields a
31
+ * `NoSubstitutionTemplateLiteral`, for which `Node.isStringLiteral()` is
32
+ * **false**. ADR-005 bars the `as` that would re-narrow it, so an implementer
33
+ * narrowing defensively silently drops the edge and `tsc` says nothing.
34
+ * `getLiteralText()` typechecks and is correct for both.
35
+ */
36
+ export type ModuleEdgeKind = 'import' | 'reexport' | 'dynamic' | 'type-expression' | 'require';
37
+ /** One module specifier leaving one file. */
38
+ export interface ModuleEdge {
39
+ readonly kind: ModuleEdgeKind;
40
+ /** The specifier as written. */
41
+ readonly specifier: string;
42
+ /** Resolved absolute path, when the compiler resolved it. */
43
+ readonly resolvedPath: string | undefined;
44
+ /**
45
+ * 1-based line of the **statement** carrying the edge.
46
+ *
47
+ * Equals `decl.getStartLineNumber()` for `kind === 'import'`, which
48
+ * `tests/core/module-edges-corpus.test.ts` asserts across the whole repo: 88
49
+ * of this repo's 1751 import declarations (5.0%) put the specifier on a
50
+ * different line from the keyword, so keying off the literal would move 5% of
51
+ * reported lines. Not a baseline concern — `hashViolation` never sees the line
52
+ * — but it drives the code frame and the GitHub annotation position.
53
+ *
54
+ * The same gap exists for every other kind, which is why the fixture carries a
55
+ * multi-line form of each: a multi-line `export { … } from` and a multi-line
56
+ * `import(…)` both move too, and a line taken from the literal passes every
57
+ * single-line test.
58
+ */
59
+ readonly line: number;
60
+ /**
61
+ * The **bindings** crossing this edge are type-level. Per-kind; see below.
62
+ *
63
+ * This is the *coupling* question — "does this file reference that file's types" —
64
+ * and it is what `dependOn`, `notImportFrom`, `onlyImportFrom` and the module
65
+ * predicates ask. It is deliberately NOT the same question as
66
+ * {@link erasesModuleRequest}, and conflating them was
67
+ * [ts-archunit plan 0087](https://github.com/nielspeter/ts-archunit/blob/main/plans/completed/0087-an-inline-type-import-still-requests-the-module.md).
68
+ */
69
+ readonly typeOnly: boolean;
70
+ /**
71
+ * The whole statement disappears, so **no module request is emitted** and the
72
+ * target module is never evaluated.
73
+ *
74
+ * This is the *module-initialization* question — "will importing this file cause
75
+ * that file to run" — and it is what cycle detection must ask. A cycle is a
76
+ * deadlock in initialization order; a coupling is not.
77
+ *
78
+ * The two differ for exactly two spellings, and only under
79
+ * `verbatimModuleSyntax: true`. Measured through ts-morph's own emit, same source,
80
+ * both settings:
81
+ *
82
+ * | form | `vms: false` | `vms: true` |
83
+ * | ----------------------------- | ------------ | --------------------------- |
84
+ * | `import type { X } from 's'` | erased | erased |
85
+ * | `import { type X } from 's'` | erased | **`import {} from 's'`** |
86
+ * | `import { type X, y } from` | requests | requests |
87
+ * | `export type { X } from 's'` | erased | erased |
88
+ * | `export { type X } from 's'` | erased | **`export {} from 's'`** |
89
+ * | `export { type X, y } from` | requests | requests |
90
+ * | `export * from 's'` | requests | requests |
91
+ * | `export type * as N from 's'` | erased | erased |
92
+ *
93
+ * The specifiers vanish; the module request does not. So under that flag those two
94
+ * forms are eager edges that can close a cycle, and treating them as erased is a
95
+ * false negative — which is what `beFreeOfCycles` did until v0.49.0.
96
+ *
97
+ * `erasesModuleRequest` implies `typeOnly`: a statement cannot vanish while still
98
+ * binding a runtime value. `tests/conditions/verbatim-module-syntax.test.ts` asserts that
99
+ * invariant over every form rather than leaving it as a claim.
100
+ */
101
+ readonly erasesModuleRequest: boolean;
102
+ /**
103
+ * Named bindings crossing the edge.
104
+ *
105
+ * **The name, not the local binding** — and which one differs per kind:
106
+ *
107
+ * - `reexport`: the **outward** name, `getAliasNode() ?? getName()`. For
108
+ * `export { INNER as OUTER } from 's'` this is `OUTER`, because that is the
109
+ * key the re-exporting module's runtime namespace carries, and the runtime
110
+ * independence guard compares against a runtime namespace. Under the
111
+ * local-name reading that guard fails on a *correct* implementation.
112
+ * - `import`: the **inward** name, `getName()`. For `import { c as d }` this is
113
+ * `c` — the name crossing the edge, not the local binding `d`.
114
+ *
115
+ * **Empty for `export *`**, and not because the names are unknowable:
116
+ * `sf.getExportSymbols()` flattens `export *` in a single call, and on a
117
+ * circular pair the compiler and the Node runtime independently agree.
118
+ * Nothing is recursive. It is empty for two other reasons:
119
+ *
120
+ * 1. it cannot separate an erased re-export from a runtime one — `export type
121
+ * { X } from` and `export { X } from` both come back with
122
+ * `SymbolFlags.Alias` and a single `ExportSpecifier`, indistinguishable
123
+ * without `getAliasedSymbol()` per name; and
124
+ * 2. it includes names with no runtime existence — a `declare module
125
+ * './star-src.js' { export const INJECTED: number }` augmentation anywhere
126
+ * in the project injects `INJECTED` into the star target's exports.
127
+ *
128
+ * (`symbol.getExports()` does **not** flatten; it hands back a synthetic
129
+ * `__export` member. The obvious call gives the unflattened view.)
130
+ *
131
+ * **`export * as NS from 's'` is not a star for this purpose**: it contributes
132
+ * exactly one name, `NS`, statically, with no recursion. `isNamespaceExport()`
133
+ * returns **true for both** star forms — measured — so `getNamespaceExport()`
134
+ * is the only discriminator.
135
+ *
136
+ * Also empty for `dynamic`, `require`, `type-expression`, and for a default or
137
+ * namespace `import` binding (`import D from 's'`, `import * as NS from 's'`),
138
+ * which cross an edge under a name the specifier list does not carry.
139
+ */
140
+ readonly names: readonly string[];
141
+ /**
142
+ * How many edges of the same `kind` and `specifier` precede this one in the file,
143
+ * in source order. `0` for the first.
144
+ *
145
+ * It exists because {@link names} is **empty** wherever no name crosses the edge,
146
+ * and a finding's identity is built from `kind::specifier::names`. That is `dynamic`,
147
+ * `require` and `type-expression` — and also four ordinary `import`/`reexport`
148
+ * spellings: `import D from`, `import * as NS from`, a bare `import './x.js'`, and
149
+ * `export * from`. So two lazy imports of the same module from one file produced two
150
+ * findings and **one** baseline hash — measured 2/1, against a control of 2/2 for two
151
+ * named imports — which means one accepted entry silently pre-accepts the next one
152
+ * someone adds. Measured on `main`, the same 2/1 held for two default imports and for
153
+ * two bare side-effect imports, in **both** families. Bug 0028's shape, wherever a
154
+ * kind or a spelling had no discriminator
155
+ * ([ts-archunit bug 0059](https://github.com/nielspeter/ts-archunit/blob/main/bugs/fixed/0059-slice-conditions-and-module-conditions-disagree-about-a-dependency.md)).
156
+ *
157
+ * **Source-order ordinal rather than the line**, deliberately: a line moves when
158
+ * anything above it is edited, and `identity` exists precisely to survive that.
159
+ * The ordinal only moves when an edge of the same kind to the same module is
160
+ * added or removed before it — which is a real change to what the file does.
161
+ *
162
+ * The residual caveat, and it is inherent to any positional tiebreaker. **A baseline entry
163
+ * accepts "an edge of this kind to this module at position n", not _this_ edge.** Measured
164
+ * end-to-end, v0.55.3 baselines replayed through this version:
165
+ *
166
+ * | edit to an accepted colliding pair | new reds reported |
167
+ * | --------------------------------------- | ----------------- |
168
+ * | add a third sibling | 1 — correct |
169
+ * | insert a sibling **above** the first | 1 — correct |
170
+ * | **delete the first, add a different one**| **0 — silent** |
171
+ *
172
+ * So the insertion case is safe and the equal-count swap is a fail-open: a dependency edge
173
+ * that did not exist when the baseline was written arrives accepted. This is strictly better
174
+ * than the pre-ordinal behaviour, where *any* number of added siblings was pre-accepted
175
+ * rather than only an equal-count swap — but it is a limitation, not a guarantee, and it is
176
+ * why {@link edgeDiscriminator} is a tiebreaker of last resort rather than an identity
177
+ * component. The durable fix is a `binding` field consulted before the ordinal, which would
178
+ * separate `import A` from `import C` outright; recorded as out-of-scope in
179
+ * [ts-archunit plan 0094](https://github.com/nielspeter/ts-archunit/blob/main/plans/0094-the-residual-findings-from-the-v0-56-0-review.md).
180
+ *
181
+ * Both collectors must agree on it, so both walk the literals in source order;
182
+ * `edgeStream` sorts for that reason and not for output tidiness.
183
+ */
184
+ readonly ordinal: number;
185
+ }
186
+ /**
187
+ * Every module edge leaving each file, in one call (ADR-007 rule 2).
188
+ *
189
+ * **Cached since plan 0076**, per file, invalidated by `onModified`. The
190
+ * sentence this paragraph used to carry — *"No cache … if a consumer reports a
191
+ * multiple-slowdown, the fix is a cache of resolution, not of the walk"* — was
192
+ * half right: a consumer did report one, and the walk is indeed not the cost
193
+ * (1ms across five passes over 520 files). But resolution is not the cost
194
+ * either. Building the `ModuleEdge` is: 15ms resolution against ~32ms
195
+ * construction, of 48ms total. So the cache is of the built edges, and the
196
+ * forward commitment this docstring made — *"what it forecloses is batching a
197
+ * resolution cache later"* — is discharged rather than left standing.
198
+ *
199
+ */
200
+ export declare function moduleEdges(files: readonly SourceFile[]): ReadonlyMap<string, readonly ModuleEdge[]>;
201
+ /**
202
+ * Every module edge leaving one file, in source order.
203
+ *
204
+ * Exported for the predicate sites, which are per-element by construction and
205
+ * would otherwise build a one-entry `Map` per file just to read it back out.
206
+ */
207
+ export declare function edgesOf(sourceFile: SourceFile): readonly ModuleEdge[];
208
+ /**
209
+ * What tells two edges of the same kind, from the same file, to the same module apart.
210
+ *
211
+ * `names` when there are any; the source-order ordinal when there are not — and **`names` is
212
+ * empty for a SPELLING, not for a kind**, which is the distinction the whole of this comment
213
+ * turns on. `dynamic`, `require` and `type-expression` never carry names, and neither do four
214
+ * ordinary `import`/`reexport` spellings (`import D from`, `import * as NS from`, a bare
215
+ * `import './x.js'`, `export * from`). Any of them, twice to one module from one file,
216
+ * measured **2 findings, 1 hash** against a control of 2/2 for two named imports — so one
217
+ * accepted baseline entry silently pre-accepts the next one someone adds. Bug 0028's shape,
218
+ * in every spelling that reached this function without a discriminator; the lazy kinds are
219
+ * merely the ones
220
+ * [ts-archunit bug 0059](https://github.com/nielspeter/ts-archunit/blob/main/bugs/fixed/0059-slice-conditions-and-module-conditions-disagree-about-a-dependency.md)
221
+ * made reportable, which is how the narrower reading got written here in the first place.
222
+ *
223
+ * The sort and the `,` are load-bearing and cheap to lose: `getNamedImports()` returns source
224
+ * order, so without the sort a cosmetic reorder of a named import list moves every multi-name
225
+ * entry in an adopter's baseline — an import-sorting lint autofix would do it. Without the
226
+ * separator, `['a','b']` and `['ab']` collide. Both are pinned by the multi-name row in
227
+ * `tests/conditions/identity-does-not-move.test.ts`, and by nothing else in the suite.
228
+ *
229
+ * **No existing baseline entry moves**, and that is what the `ordinal === 0` branch buys.
230
+ * The naive form — `#${ordinal}` whenever `names` is empty — moves far more than the three
231
+ * kinds it was written for, because `names` is empty for four ordinary `import`/`reexport`
232
+ * spellings too: `import D from`, `import * as NS from`, a bare `import './x.js'`, and
233
+ * `export * from` (the barrel). `export * as NS from` is **not** among them — it carries one
234
+ * statically-known name. That form shipped briefly in v0.56.0's development and was caught by
235
+ * review, measured against `main` through the public conditions: 4 of 7 spellings moved, in
236
+ * both families, while the CHANGELOG and ts-archunit's `docs/upgrading.md` promised none did.
237
+ *
238
+ * Emitting `''` for the first edge of each group reproduces exactly what the pre-ordinal
239
+ * formula produced (`[...names].sort().join(',')` over an empty list), so every
240
+ * single-occurrence finding keeps a byte-identical identity — measured across all seven
241
+ * spellings plus `dynamic` and `type-expression`, zero diff. The `#n` suffix appears only on
242
+ * the **second and later** edge of one kind to one module from one file, which is precisely
243
+ * the group that had two findings and one hash before, i.e. a baseline entry that was already
244
+ * wrong. So the fail-open closes and the migration is empty — the surviving entry still
245
+ * matches, and only the genuinely-new sibling is reported.
246
+ *
247
+ * Uniqueness still holds: within a group the sequence `''`, `#1`, `#2`, … is injective, and
248
+ * `''` is unreachable from the named branch because no import specifier is an empty
249
+ * identifier.
250
+ *
251
+ * The cost, stated so it is a decision rather than a discovery: the discriminator is no longer
252
+ * uniform, so `…::` no longer distinguishes "names-less, first" from "not computed". That is
253
+ * a readability loss traded for a migration nobody has to perform.
254
+ */
255
+ export declare function edgeDiscriminator(edge: ModuleEdge): string;
256
+ /**
257
+ * How a finding refers to this kind of edge.
258
+ *
259
+ * **An exhaustive `switch`, not a `Record` lookup or a 4-way branch** (plan 0071
260
+ * §4). Measured on a build with `require` unfiltered and no `require` verb: a
261
+ * `Record` lookup emitted the literal string `undefined` into a message —
262
+ * `cjs-consumer.js undefined "…/target.ts" which matches forbidden […]` — and
263
+ * that text is hashed into a baseline. A missing verb must be a compile error;
264
+ * with an explicit `string` return and no fallthrough, adding a sixth
265
+ * `ModuleEdgeKind` breaks the build here.
266
+ *
267
+ * `require` gets a real verb even though no condition reports it (§3). The
268
+ * alternative — throwing, or returning a placeholder — makes a forgotten kind
269
+ * filter produce nonsense instead of a correct sentence, and a correct sentence
270
+ * costs one line.
271
+ *
272
+ * **`import` must stay byte-identical.** Every existing baselined dependency
273
+ * finding hashes its message, so changing this string for `import` silently
274
+ * invalidates them all; the new kinds get distinct verbs precisely so their
275
+ * findings are NOT absorbed by an existing `import` entry for the same module.
276
+ */
277
+ export declare function edgeVerb(kind: ModuleEdgeKind): string;
278
+ /**
279
+ * How a finding describes a **runtime** edge of this kind, for
280
+ * `onlyHaveTypeImportsFrom`.
281
+ *
282
+ * Separate from {@link edgeVerb} because that condition's sentence needs a noun
283
+ * phrase ("has a value import from") rather than a verb, and because its remedy
284
+ * differs per kind in a way the verb does not capture — see
285
+ * {@link edgeTypeOnlyRemedy}.
286
+ */
287
+ export declare function edgeValuePhrase(kind: ModuleEdgeKind): string;
288
+ /**
289
+ * The remedy for a runtime edge that should be type-only — **per kind, because
290
+ * the remedy differs and one of them has a consequence** (ADR-009 rule 2).
291
+ *
292
+ * `onlyHaveTypeImportsFrom`'s shipped preset says *"Use `import type { X }` so
293
+ * the dependency is erased"*. For an `import` that is complete and local. For a
294
+ * re-export it is not: `export type { X } from` erases the edge **and removes a
295
+ * runtime export consumers may be importing as a value**. The finding still
296
+ * stands — the runtime dependency is real — but a remedy that silently changes
297
+ * what the module publishes is a remedy the reader must be told about.
298
+ *
299
+ * `dynamic` is excluded from that condition entirely for the stronger version of
300
+ * the same reason: there is no remedy at all. You cannot erase an
301
+ * `await import(…)`.
302
+ */
303
+ export declare function edgeTypeOnlyRemedy(edge: Pick<ModuleEdge, 'kind' | 'names'>): string;
304
+ /**
305
+ * The noun for this kind of edge, for `onlyHaveTypeImportsFrom`'s sentence tail.
306
+ *
307
+ * `edgeValuePhrase` was made per-kind and the tail was not, so a re-export read
308
+ * "has a runtime re-export of … which should be a type-only **import**". The two
309
+ * halves have to agree or the sentence contradicts itself.
310
+ */
311
+ /**
312
+ * The kinds a **forward** dependency site reports on.
313
+ *
314
+ * One constant, because there were two: `DEPENDENCY_KINDS` in
315
+ * `conditions/dependency.ts` and `PREDICATE_KINDS` in `predicates/module.ts`, whose
316
+ * docstring said "the same set as the conditions … and it has to be" with prose as
317
+ * the only enforcement. `notImportFrom` is one identifier with two definitions
318
+ * chosen by chain position, so a predicate that disagreed with its own condition
319
+ * about what an import is would be this release's Problem statement in miniature.
320
+ *
321
+ * **Exhaustive, not an allowlist filter.** A sixth `ModuleEdgeKind` is a compile
322
+ * error here rather than a kind silently excluded everywhere — that fail-open is the
323
+ * same false green this release closes.
324
+ *
325
+ * `require` is `false`: the kind exists so a 4-way branch cannot mark a CJS runtime
326
+ * dependency as erased, not to enforce CJS. The **reverse** graph counts it, which
327
+ * is the opposite disposition and deliberately so — see `indexEdges`'s reasoning.
328
+ * `onlyHaveTypeImportsFrom` diverges further still (`TYPE_IMPORT_KINDS`), and that
329
+ * one divergence is intentional and documented at its own site.
330
+ */
331
+ export declare const FORWARD_EDGE_KINDS: Record<ModuleEdgeKind, boolean>;
332
+ /**
333
+ * Every module edge leaving one file, **lazily and unsorted**.
334
+ *
335
+ * For a caller that only asks "is there any edge matching X". `edgesOf` builds and
336
+ * resolves the whole array before returning, so `edgesOf(sf).some(...)` pays a
337
+ * `getSymbol()` for every literal in the file even when the first one answers the
338
+ * question — on a 100-import file whose first import matches, 100 checker calls
339
+ * where the pre-0.28.0 code made 1.
340
+ *
341
+ * **Order is unspecified, and since plan 0076 it differs between a cold and a
342
+ * warm call.** Cold, edges arrive in walk order — the declaration forms first,
343
+ * because that is how ts-morph enumerates them. Warm, they arrive in the source
344
+ * order {@link edgesOf} sorted them into. Measured, on a file whose dynamic
345
+ * import precedes its declaration import:
346
+ *
347
+ * cold ./a.js, ./b.js
348
+ * warm ./b.js, ./a.js
349
+ *
350
+ * No verdict depends on it today: the only consumer is `dependOn`
351
+ * (`conditions/dependency.ts`), which is a `.some()` and stops at the first
352
+ * match. But "sometimes sorted" is a worse contract than "never sorted", so it
353
+ * is stated rather than left to be discovered. **Anything that reports a
354
+ * finding must use {@link edgesOf}**, whose source ordering is part of its
355
+ * contract — a reporting site fed from here would name a different edge
356
+ * depending on whether an unrelated rule warmed the file first, which is one
357
+ * finding with two identities.
358
+ */
359
+ export declare function edgeStream(sourceFile: SourceFile): Generator<ModuleEdge>;
360
+ export declare function edgeTypeOnlyNoun(kind: ModuleEdgeKind): string;
361
+ //# sourceMappingURL=module-edges.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-edges.d.ts","sourceRoot":"","sources":["../../src/core/module-edges.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAiB,MAAM,UAAU,CAAA;AAKzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,iBAAiB,GAAG,SAAS,CAAA;AAE9F,6CAA6C;AAC7C,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;IAC7B,gCAAgC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,6DAA6D;IAC7D,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAA;IACzC;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB;;;;;;;;OAQG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAA;IACrC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAqCG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA0CG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,SAAS,UAAU,EAAE,GAC3B,WAAW,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC,CAM5C;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,UAAU,EAAE,CAYrE;AAqFD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAY1D;AA0ND;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAErD;AA0BD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAE5D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,MAAM,CA4BnF;AAED;;;;;;GAMG;AACH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,cAAc,EAAE,OAAO,CAM9D,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAiB,UAAU,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,CAAC,UAAU,CAAC,CA8BzE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAW7D"}