@nielspeter/eess-ts 0.1.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 (371) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +364 -0
  3. package/dist/builders/call-rule-builder.d.ts +199 -0
  4. package/dist/builders/call-rule-builder.d.ts.map +1 -0
  5. package/dist/builders/call-rule-builder.js +254 -0
  6. package/dist/builders/call-rule-builder.js.map +1 -0
  7. package/dist/builders/class-rule-builder.d.ts +136 -0
  8. package/dist/builders/class-rule-builder.d.ts.map +1 -0
  9. package/dist/builders/class-rule-builder.js +253 -0
  10. package/dist/builders/class-rule-builder.js.map +1 -0
  11. package/dist/builders/cross-layer-builder.d.ts +96 -0
  12. package/dist/builders/cross-layer-builder.d.ts.map +1 -0
  13. package/dist/builders/cross-layer-builder.js +172 -0
  14. package/dist/builders/cross-layer-builder.js.map +1 -0
  15. package/dist/builders/function-rule-builder.d.ts +198 -0
  16. package/dist/builders/function-rule-builder.d.ts.map +1 -0
  17. package/dist/builders/function-rule-builder.js +287 -0
  18. package/dist/builders/function-rule-builder.js.map +1 -0
  19. package/dist/builders/jsx-rule-builder.d.ts +113 -0
  20. package/dist/builders/jsx-rule-builder.d.ts.map +1 -0
  21. package/dist/builders/jsx-rule-builder.js +150 -0
  22. package/dist/builders/jsx-rule-builder.js.map +1 -0
  23. package/dist/builders/module-rule-builder.d.ts +159 -0
  24. package/dist/builders/module-rule-builder.d.ts.map +1 -0
  25. package/dist/builders/module-rule-builder.js +237 -0
  26. package/dist/builders/module-rule-builder.js.map +1 -0
  27. package/dist/builders/scoped-function-rule-builder.d.ts +21 -0
  28. package/dist/builders/scoped-function-rule-builder.d.ts.map +1 -0
  29. package/dist/builders/scoped-function-rule-builder.js +26 -0
  30. package/dist/builders/scoped-function-rule-builder.js.map +1 -0
  31. package/dist/builders/slice-rule-builder.d.ts +85 -0
  32. package/dist/builders/slice-rule-builder.d.ts.map +1 -0
  33. package/dist/builders/slice-rule-builder.js +134 -0
  34. package/dist/builders/slice-rule-builder.js.map +1 -0
  35. package/dist/builders/type-rule-builder.d.ts +103 -0
  36. package/dist/builders/type-rule-builder.d.ts.map +1 -0
  37. package/dist/builders/type-rule-builder.js +170 -0
  38. package/dist/builders/type-rule-builder.js.map +1 -0
  39. package/dist/cli/bin.d.ts +3 -0
  40. package/dist/cli/bin.d.ts.map +1 -0
  41. package/dist/cli/bin.js +4 -0
  42. package/dist/cli/bin.js.map +1 -0
  43. package/dist/cli/commands/baseline.d.ts +11 -0
  44. package/dist/cli/commands/baseline.d.ts.map +1 -0
  45. package/dist/cli/commands/baseline.js +16 -0
  46. package/dist/cli/commands/baseline.js.map +1 -0
  47. package/dist/cli/commands/check.d.ts +21 -0
  48. package/dist/cli/commands/check.d.ts.map +1 -0
  49. package/dist/cli/commands/check.js +94 -0
  50. package/dist/cli/commands/check.js.map +1 -0
  51. package/dist/cli/commands/explain.d.ts +9 -0
  52. package/dist/cli/commands/explain.d.ts.map +1 -0
  53. package/dist/cli/commands/explain.js +49 -0
  54. package/dist/cli/commands/explain.js.map +1 -0
  55. package/dist/cli/config.d.ts +31 -0
  56. package/dist/cli/config.d.ts.map +1 -0
  57. package/dist/cli/config.js +20 -0
  58. package/dist/cli/config.js.map +1 -0
  59. package/dist/cli/index.d.ts +21 -0
  60. package/dist/cli/index.d.ts.map +1 -0
  61. package/dist/cli/index.js +168 -0
  62. package/dist/cli/index.js.map +1 -0
  63. package/dist/cli/load-rules.d.ts +20 -0
  64. package/dist/cli/load-rules.d.ts.map +1 -0
  65. package/dist/cli/load-rules.js +97 -0
  66. package/dist/cli/load-rules.js.map +1 -0
  67. package/dist/cli/resolve-config.d.ts +11 -0
  68. package/dist/cli/resolve-config.d.ts.map +1 -0
  69. package/dist/cli/resolve-config.js +61 -0
  70. package/dist/cli/resolve-config.js.map +1 -0
  71. package/dist/cli/watch.d.ts +49 -0
  72. package/dist/cli/watch.d.ts.map +1 -0
  73. package/dist/cli/watch.js +138 -0
  74. package/dist/cli/watch.js.map +1 -0
  75. package/dist/conditions/body-analysis-function.d.ts +23 -0
  76. package/dist/conditions/body-analysis-function.d.ts.map +1 -0
  77. package/dist/conditions/body-analysis-function.js +103 -0
  78. package/dist/conditions/body-analysis-function.js.map +1 -0
  79. package/dist/conditions/body-analysis-module.d.ts +27 -0
  80. package/dist/conditions/body-analysis-module.d.ts.map +1 -0
  81. package/dist/conditions/body-analysis-module.js +99 -0
  82. package/dist/conditions/body-analysis-module.js.map +1 -0
  83. package/dist/conditions/body-analysis.d.ts +34 -0
  84. package/dist/conditions/body-analysis.d.ts.map +1 -0
  85. package/dist/conditions/body-analysis.js +95 -0
  86. package/dist/conditions/body-analysis.js.map +1 -0
  87. package/dist/conditions/call.d.ts +62 -0
  88. package/dist/conditions/call.d.ts.map +1 -0
  89. package/dist/conditions/call.js +267 -0
  90. package/dist/conditions/call.js.map +1 -0
  91. package/dist/conditions/catch-analysis.d.ts +31 -0
  92. package/dist/conditions/catch-analysis.d.ts.map +1 -0
  93. package/dist/conditions/catch-analysis.js +78 -0
  94. package/dist/conditions/catch-analysis.js.map +1 -0
  95. package/dist/conditions/class.d.ts +33 -0
  96. package/dist/conditions/class.d.ts.map +1 -0
  97. package/dist/conditions/class.js +110 -0
  98. package/dist/conditions/class.js.map +1 -0
  99. package/dist/conditions/cross-layer.d.ts +28 -0
  100. package/dist/conditions/cross-layer.d.ts.map +1 -0
  101. package/dist/conditions/cross-layer.js +105 -0
  102. package/dist/conditions/cross-layer.js.map +1 -0
  103. package/dist/conditions/dependency.d.ts +73 -0
  104. package/dist/conditions/dependency.d.ts.map +1 -0
  105. package/dist/conditions/dependency.js +177 -0
  106. package/dist/conditions/dependency.js.map +1 -0
  107. package/dist/conditions/exports.d.ts +33 -0
  108. package/dist/conditions/exports.d.ts.map +1 -0
  109. package/dist/conditions/exports.js +101 -0
  110. package/dist/conditions/exports.js.map +1 -0
  111. package/dist/conditions/function.d.ts +79 -0
  112. package/dist/conditions/function.d.ts.map +1 -0
  113. package/dist/conditions/function.js +167 -0
  114. package/dist/conditions/function.js.map +1 -0
  115. package/dist/conditions/helpers.d.ts +14 -0
  116. package/dist/conditions/helpers.d.ts.map +1 -0
  117. package/dist/conditions/helpers.js +26 -0
  118. package/dist/conditions/helpers.js.map +1 -0
  119. package/dist/conditions/jsx.d.ts +40 -0
  120. package/dist/conditions/jsx.d.ts.map +1 -0
  121. package/dist/conditions/jsx.js +133 -0
  122. package/dist/conditions/jsx.js.map +1 -0
  123. package/dist/conditions/members.d.ts +74 -0
  124. package/dist/conditions/members.d.ts.map +1 -0
  125. package/dist/conditions/members.js +224 -0
  126. package/dist/conditions/members.js.map +1 -0
  127. package/dist/conditions/pattern.d.ts +20 -0
  128. package/dist/conditions/pattern.d.ts.map +1 -0
  129. package/dist/conditions/pattern.js +108 -0
  130. package/dist/conditions/pattern.js.map +1 -0
  131. package/dist/conditions/reverse-dependency.d.ts +28 -0
  132. package/dist/conditions/reverse-dependency.d.ts.map +1 -0
  133. package/dist/conditions/reverse-dependency.js +275 -0
  134. package/dist/conditions/reverse-dependency.js.map +1 -0
  135. package/dist/conditions/slice.d.ts +49 -0
  136. package/dist/conditions/slice.d.ts.map +1 -0
  137. package/dist/conditions/slice.js +153 -0
  138. package/dist/conditions/slice.js.map +1 -0
  139. package/dist/conditions/structural.d.ts +58 -0
  140. package/dist/conditions/structural.d.ts.map +1 -0
  141. package/dist/conditions/structural.js +102 -0
  142. package/dist/conditions/structural.js.map +1 -0
  143. package/dist/conditions/type-level.d.ts +29 -0
  144. package/dist/conditions/type-level.d.ts.map +1 -0
  145. package/dist/conditions/type-level.js +48 -0
  146. package/dist/conditions/type-level.js.map +1 -0
  147. package/dist/core/import-options.d.ts +32 -0
  148. package/dist/core/import-options.d.ts.map +1 -0
  149. package/dist/core/import-options.js +29 -0
  150. package/dist/core/import-options.js.map +1 -0
  151. package/dist/core/module-dependencies.d.ts +28 -0
  152. package/dist/core/module-dependencies.d.ts.map +1 -0
  153. package/dist/core/module-dependencies.js +35 -0
  154. package/dist/core/module-dependencies.js.map +1 -0
  155. package/dist/core/pair-condition.d.ts +10 -0
  156. package/dist/core/pair-condition.d.ts.map +1 -0
  157. package/dist/core/pair-condition.js +2 -0
  158. package/dist/core/pair-condition.js.map +1 -0
  159. package/dist/core/project.d.ts +68 -0
  160. package/dist/core/project.d.ts.map +1 -0
  161. package/dist/core/project.js +127 -0
  162. package/dist/core/project.js.map +1 -0
  163. package/dist/core/type-matcher.d.ts +10 -0
  164. package/dist/core/type-matcher.d.ts.map +1 -0
  165. package/dist/core/type-matcher.js +2 -0
  166. package/dist/core/type-matcher.js.map +1 -0
  167. package/dist/core/violation.d.ts +38 -0
  168. package/dist/core/violation.d.ts.map +1 -0
  169. package/dist/core/violation.js +130 -0
  170. package/dist/core/violation.js.map +1 -0
  171. package/dist/graphql/index.d.ts +76 -0
  172. package/dist/graphql/index.d.ts.map +1 -0
  173. package/dist/graphql/index.js +108 -0
  174. package/dist/graphql/index.js.map +1 -0
  175. package/dist/graphql/resolver-rule-builder.d.ts +75 -0
  176. package/dist/graphql/resolver-rule-builder.d.ts.map +1 -0
  177. package/dist/graphql/resolver-rule-builder.js +146 -0
  178. package/dist/graphql/resolver-rule-builder.js.map +1 -0
  179. package/dist/graphql/schema-conditions.d.ts +31 -0
  180. package/dist/graphql/schema-conditions.d.ts.map +1 -0
  181. package/dist/graphql/schema-conditions.js +119 -0
  182. package/dist/graphql/schema-conditions.js.map +1 -0
  183. package/dist/graphql/schema-loader.d.ts +75 -0
  184. package/dist/graphql/schema-loader.d.ts.map +1 -0
  185. package/dist/graphql/schema-loader.js +113 -0
  186. package/dist/graphql/schema-loader.js.map +1 -0
  187. package/dist/graphql/schema-predicates.d.ts +42 -0
  188. package/dist/graphql/schema-predicates.d.ts.map +1 -0
  189. package/dist/graphql/schema-predicates.js +74 -0
  190. package/dist/graphql/schema-predicates.js.map +1 -0
  191. package/dist/graphql/schema-rule-builder.d.ts +74 -0
  192. package/dist/graphql/schema-rule-builder.d.ts.map +1 -0
  193. package/dist/graphql/schema-rule-builder.js +188 -0
  194. package/dist/graphql/schema-rule-builder.js.map +1 -0
  195. package/dist/helpers/body-traversal.d.ts +58 -0
  196. package/dist/helpers/body-traversal.d.ts.map +1 -0
  197. package/dist/helpers/body-traversal.js +180 -0
  198. package/dist/helpers/body-traversal.js.map +1 -0
  199. package/dist/helpers/callback-extractor.d.ts +28 -0
  200. package/dist/helpers/callback-extractor.d.ts.map +1 -0
  201. package/dist/helpers/callback-extractor.js +159 -0
  202. package/dist/helpers/callback-extractor.js.map +1 -0
  203. package/dist/helpers/complexity.d.ts +26 -0
  204. package/dist/helpers/complexity.d.ts.map +1 -0
  205. package/dist/helpers/complexity.js +64 -0
  206. package/dist/helpers/complexity.js.map +1 -0
  207. package/dist/helpers/matchers.d.ts +206 -0
  208. package/dist/helpers/matchers.d.ts.map +1 -0
  209. package/dist/helpers/matchers.js +470 -0
  210. package/dist/helpers/matchers.js.map +1 -0
  211. package/dist/helpers/pattern.d.ts +37 -0
  212. package/dist/helpers/pattern.d.ts.map +1 -0
  213. package/dist/helpers/pattern.js +22 -0
  214. package/dist/helpers/pattern.js.map +1 -0
  215. package/dist/helpers/slice-graph.d.ts +32 -0
  216. package/dist/helpers/slice-graph.d.ts.map +1 -0
  217. package/dist/helpers/slice-graph.js +89 -0
  218. package/dist/helpers/slice-graph.js.map +1 -0
  219. package/dist/helpers/tarjan.d.ts +21 -0
  220. package/dist/helpers/tarjan.d.ts.map +1 -0
  221. package/dist/helpers/tarjan.js +71 -0
  222. package/dist/helpers/tarjan.js.map +1 -0
  223. package/dist/helpers/type-matchers.d.ts +67 -0
  224. package/dist/helpers/type-matchers.d.ts.map +1 -0
  225. package/dist/helpers/type-matchers.js +108 -0
  226. package/dist/helpers/type-matchers.js.map +1 -0
  227. package/dist/helpers/within.d.ts +41 -0
  228. package/dist/helpers/within.d.ts.map +1 -0
  229. package/dist/helpers/within.js +32 -0
  230. package/dist/helpers/within.js.map +1 -0
  231. package/dist/index.d.ts +101 -0
  232. package/dist/index.d.ts.map +1 -0
  233. package/dist/index.js +116 -0
  234. package/dist/index.js.map +1 -0
  235. package/dist/models/arch-call.d.ts +83 -0
  236. package/dist/models/arch-call.d.ts.map +1 -0
  237. package/dist/models/arch-call.js +90 -0
  238. package/dist/models/arch-call.js.map +1 -0
  239. package/dist/models/arch-function.d.ts +76 -0
  240. package/dist/models/arch-function.d.ts.map +1 -0
  241. package/dist/models/arch-function.js +122 -0
  242. package/dist/models/arch-function.js.map +1 -0
  243. package/dist/models/arch-jsx-element.d.ts +75 -0
  244. package/dist/models/arch-jsx-element.d.ts.map +1 -0
  245. package/dist/models/arch-jsx-element.js +231 -0
  246. package/dist/models/arch-jsx-element.js.map +1 -0
  247. package/dist/models/cross-layer.d.ts +15 -0
  248. package/dist/models/cross-layer.d.ts.map +1 -0
  249. package/dist/models/cross-layer.js +2 -0
  250. package/dist/models/cross-layer.js.map +1 -0
  251. package/dist/models/slice.d.ts +60 -0
  252. package/dist/models/slice.d.ts.map +1 -0
  253. package/dist/models/slice.js +89 -0
  254. package/dist/models/slice.js.map +1 -0
  255. package/dist/predicates/call.d.ts +49 -0
  256. package/dist/predicates/call.d.ts.map +1 -0
  257. package/dist/predicates/call.js +115 -0
  258. package/dist/predicates/call.js.map +1 -0
  259. package/dist/predicates/class.d.ts +42 -0
  260. package/dist/predicates/class.d.ts.map +1 -0
  261. package/dist/predicates/class.js +83 -0
  262. package/dist/predicates/class.js.map +1 -0
  263. package/dist/predicates/function.d.ts +81 -0
  264. package/dist/predicates/function.d.ts.map +1 -0
  265. package/dist/predicates/function.js +157 -0
  266. package/dist/predicates/function.js.map +1 -0
  267. package/dist/predicates/identity.d.ts +55 -0
  268. package/dist/predicates/identity.d.ts.map +1 -0
  269. package/dist/predicates/identity.js +96 -0
  270. package/dist/predicates/identity.js.map +1 -0
  271. package/dist/predicates/index.d.ts +4 -0
  272. package/dist/predicates/index.d.ts.map +1 -0
  273. package/dist/predicates/index.js +3 -0
  274. package/dist/predicates/index.js.map +1 -0
  275. package/dist/predicates/jsx.d.ts +41 -0
  276. package/dist/predicates/jsx.d.ts.map +1 -0
  277. package/dist/predicates/jsx.js +84 -0
  278. package/dist/predicates/jsx.js.map +1 -0
  279. package/dist/predicates/metrics.d.ts +30 -0
  280. package/dist/predicates/metrics.d.ts.map +1 -0
  281. package/dist/predicates/metrics.js +65 -0
  282. package/dist/predicates/metrics.js.map +1 -0
  283. package/dist/predicates/module.d.ts +44 -0
  284. package/dist/predicates/module.d.ts.map +1 -0
  285. package/dist/predicates/module.js +70 -0
  286. package/dist/predicates/module.js.map +1 -0
  287. package/dist/predicates/type.d.ts +48 -0
  288. package/dist/predicates/type.d.ts.map +1 -0
  289. package/dist/predicates/type.js +107 -0
  290. package/dist/predicates/type.js.map +1 -0
  291. package/dist/presets/boundaries.d.ts +19 -0
  292. package/dist/presets/boundaries.d.ts.map +1 -0
  293. package/dist/presets/boundaries.js +93 -0
  294. package/dist/presets/boundaries.js.map +1 -0
  295. package/dist/presets/data-layer.d.ts +20 -0
  296. package/dist/presets/data-layer.d.ts.map +1 -0
  297. package/dist/presets/data-layer.js +30 -0
  298. package/dist/presets/data-layer.js.map +1 -0
  299. package/dist/presets/index.d.ts +9 -0
  300. package/dist/presets/index.d.ts.map +1 -0
  301. package/dist/presets/index.js +5 -0
  302. package/dist/presets/index.js.map +1 -0
  303. package/dist/presets/layered.d.ts +21 -0
  304. package/dist/presets/layered.d.ts.map +1 -0
  305. package/dist/presets/layered.js +103 -0
  306. package/dist/presets/layered.js.map +1 -0
  307. package/dist/presets/shared.d.ts +3 -0
  308. package/dist/presets/shared.d.ts.map +1 -0
  309. package/dist/presets/shared.js +5 -0
  310. package/dist/presets/shared.js.map +1 -0
  311. package/dist/rules/architecture.d.ts +10 -0
  312. package/dist/rules/architecture.d.ts.map +1 -0
  313. package/dist/rules/architecture.js +14 -0
  314. package/dist/rules/architecture.js.map +1 -0
  315. package/dist/rules/code-quality.d.ts +55 -0
  316. package/dist/rules/code-quality.d.ts.map +1 -0
  317. package/dist/rules/code-quality.js +116 -0
  318. package/dist/rules/code-quality.js.map +1 -0
  319. package/dist/rules/dependencies.d.ts +32 -0
  320. package/dist/rules/dependencies.d.ts.map +1 -0
  321. package/dist/rules/dependencies.js +37 -0
  322. package/dist/rules/dependencies.js.map +1 -0
  323. package/dist/rules/errors.d.ts +31 -0
  324. package/dist/rules/errors.d.ts.map +1 -0
  325. package/dist/rules/errors.js +97 -0
  326. package/dist/rules/errors.js.map +1 -0
  327. package/dist/rules/hygiene.d.ts +54 -0
  328. package/dist/rules/hygiene.d.ts.map +1 -0
  329. package/dist/rules/hygiene.js +62 -0
  330. package/dist/rules/hygiene.js.map +1 -0
  331. package/dist/rules/metrics-function.d.ts +45 -0
  332. package/dist/rules/metrics-function.d.ts.map +1 -0
  333. package/dist/rules/metrics-function.js +87 -0
  334. package/dist/rules/metrics-function.js.map +1 -0
  335. package/dist/rules/metrics.d.ts +64 -0
  336. package/dist/rules/metrics.d.ts.map +1 -0
  337. package/dist/rules/metrics.js +157 -0
  338. package/dist/rules/metrics.js.map +1 -0
  339. package/dist/rules/naming.d.ts +24 -0
  340. package/dist/rules/naming.d.ts.map +1 -0
  341. package/dist/rules/naming.js +51 -0
  342. package/dist/rules/naming.js.map +1 -0
  343. package/dist/rules/security.d.ts +59 -0
  344. package/dist/rules/security.d.ts.map +1 -0
  345. package/dist/rules/security.js +92 -0
  346. package/dist/rules/security.js.map +1 -0
  347. package/dist/rules/typescript.d.ts +73 -0
  348. package/dist/rules/typescript.d.ts.map +1 -0
  349. package/dist/rules/typescript.js +105 -0
  350. package/dist/rules/typescript.js.map +1 -0
  351. package/dist/smells/duplicate-bodies.d.ts +24 -0
  352. package/dist/smells/duplicate-bodies.d.ts.map +1 -0
  353. package/dist/smells/duplicate-bodies.js +131 -0
  354. package/dist/smells/duplicate-bodies.js.map +1 -0
  355. package/dist/smells/fingerprint.d.ts +27 -0
  356. package/dist/smells/fingerprint.d.ts.map +1 -0
  357. package/dist/smells/fingerprint.js +50 -0
  358. package/dist/smells/fingerprint.js.map +1 -0
  359. package/dist/smells/inconsistent-siblings.d.ts +21 -0
  360. package/dist/smells/inconsistent-siblings.d.ts.map +1 -0
  361. package/dist/smells/inconsistent-siblings.js +135 -0
  362. package/dist/smells/inconsistent-siblings.js.map +1 -0
  363. package/dist/smells/index.d.ts +12 -0
  364. package/dist/smells/index.d.ts.map +1 -0
  365. package/dist/smells/index.js +15 -0
  366. package/dist/smells/index.js.map +1 -0
  367. package/dist/smells/smell-builder.d.ts +37 -0
  368. package/dist/smells/smell-builder.d.ts.map +1 -0
  369. package/dist/smells/smell-builder.js +51 -0
  370. package/dist/smells/smell-builder.js.map +1 -0
  371. package/package.json +121 -0
@@ -0,0 +1,49 @@
1
+ import { loadRuleFiles } from '../load-rules.js';
2
+ function isDescribable(value) {
3
+ return (value !== null &&
4
+ value !== undefined &&
5
+ typeof value === 'object' &&
6
+ 'describeRule' in value &&
7
+ typeof value['describeRule'] === 'function');
8
+ }
9
+ /**
10
+ * Dump all active rules as structured JSON or markdown.
11
+ */
12
+ export async function runExplain(args) {
13
+ const builders = await loadRuleFiles(args.ruleFiles);
14
+ const descriptions = [];
15
+ for (const builder of builders) {
16
+ if (isDescribable(builder)) {
17
+ descriptions.push(builder.describeRule());
18
+ }
19
+ }
20
+ if (args.markdown) {
21
+ outputMarkdown(descriptions);
22
+ }
23
+ else {
24
+ outputJson(descriptions);
25
+ }
26
+ }
27
+ function outputJson(descriptions) {
28
+ const output = {
29
+ rules: descriptions,
30
+ generatedAt: new Date().toISOString(),
31
+ };
32
+ process.stdout.write(JSON.stringify(output, null, 2) + '\n');
33
+ }
34
+ function outputMarkdown(descriptions) {
35
+ if (descriptions.length === 0) {
36
+ process.stdout.write('No rules found.\n');
37
+ return;
38
+ }
39
+ process.stdout.write('| ID | Rule | Because | Suggestion |\n');
40
+ process.stdout.write('|----|------|---------|------------|\n');
41
+ for (const d of descriptions) {
42
+ const id = d.id ?? '-';
43
+ const rule = d.rule || '-';
44
+ const because = d.because ?? '-';
45
+ const suggestion = d.suggestion ?? '-';
46
+ process.stdout.write(`| ${id} | ${rule} | ${because} | ${suggestion} |\n`);
47
+ }
48
+ }
49
+ //# sourceMappingURL=explain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explain.js","sourceRoot":"","sources":["../../../src/cli/commands/explain.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAYhD,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,CACL,KAAK,KAAK,IAAI;QACd,KAAK,KAAK,SAAS;QACnB,OAAO,KAAK,KAAK,QAAQ;QACzB,cAAc,IAAI,KAAK;QACvB,OAAO,KAAK,CAAC,cAAc,CAAC,KAAK,UAAU,CAC5C,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAiB;IAChD,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IAEpD,MAAM,YAAY,GAAsB,EAAE,CAAA;IAC1C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,CAAA;QAC3C,CAAC;IACH,CAAC;IAED,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,cAAc,CAAC,YAAY,CAAC,CAAA;IAC9B,CAAC;SAAM,CAAC;QACN,UAAU,CAAC,YAAY,CAAC,CAAA;IAC1B,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,YAA+B;IACjD,MAAM,MAAM,GAAG;QACb,KAAK,EAAE,YAAY;QACnB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACtC,CAAA;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;AAC9D,CAAC;AAED,SAAS,cAAc,CAAC,YAA+B;IACrD,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAA;QACzC,OAAM;IACR,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAA;IAC9D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAA;IAC9D,KAAK,MAAM,CAAC,IAAI,YAAY,EAAE,CAAC;QAC7B,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,CAAA;QACtB,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,GAAG,CAAA;QAC1B,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,IAAI,GAAG,CAAA;QAChC,MAAM,UAAU,GAAG,CAAC,CAAC,UAAU,IAAI,GAAG,CAAA;QACtC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,IAAI,MAAM,OAAO,MAAM,UAAU,MAAM,CAAC,CAAA;IAC5E,CAAC;AACH,CAAC"}
@@ -0,0 +1,31 @@
1
+ import type { OutputFormat } from '@nielspeter/eess';
2
+ export interface CliConfig {
3
+ /** Path to tsconfig.json. Default: 'tsconfig.json' */
4
+ project?: string;
5
+ /** Rule files to load. Default: discovered via glob */
6
+ rules?: string[];
7
+ /** Baseline file path */
8
+ baseline?: string;
9
+ /** Output format. 'auto' uses detectFormat() */
10
+ format?: OutputFormat | 'auto';
11
+ /** Directories to watch in --watch mode. Default: ['src'] */
12
+ watchDirs?: string[];
13
+ }
14
+ /**
15
+ * Define a CLI configuration with type safety.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * // eess-ts.config.ts
20
+ * import { defineConfig } from '@nielspeter/eess-ts'
21
+ *
22
+ * export default defineConfig({
23
+ * project: 'tsconfig.json',
24
+ * rules: ['arch.rules.ts'],
25
+ * baseline: 'arch-baseline.json',
26
+ * format: 'auto',
27
+ * })
28
+ * ```
29
+ */
30
+ export declare function defineConfig(config: CliConfig): CliConfig;
31
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEpD,MAAM,WAAW,SAAS;IACxB,sDAAsD;IACtD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,yBAAyB;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,gDAAgD;IAChD,MAAM,CAAC,EAAE,YAAY,GAAG,MAAM,CAAA;IAC9B,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;CACrB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,CAEzD"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Define a CLI configuration with type safety.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * // eess-ts.config.ts
7
+ * import { defineConfig } from '@nielspeter/eess-ts'
8
+ *
9
+ * export default defineConfig({
10
+ * project: 'tsconfig.json',
11
+ * rules: ['arch.rules.ts'],
12
+ * baseline: 'arch-baseline.json',
13
+ * format: 'auto',
14
+ * })
15
+ * ```
16
+ */
17
+ export function defineConfig(config) {
18
+ return config;
19
+ }
20
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"AAeA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,YAAY,CAAC,MAAiB;IAC5C,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -0,0 +1,21 @@
1
+ interface ParsedArgs {
2
+ values: {
3
+ baseline?: string;
4
+ output?: string;
5
+ changed?: boolean;
6
+ base?: string;
7
+ format?: string;
8
+ config?: string;
9
+ help?: boolean;
10
+ version?: boolean;
11
+ watch?: boolean;
12
+ markdown?: boolean;
13
+ fix?: boolean;
14
+ apply?: boolean;
15
+ };
16
+ positionals: string[];
17
+ }
18
+ export declare function parseCliArgs(args: string[]): ParsedArgs;
19
+ export declare function run(args: string[]): Promise<void>;
20
+ export {};
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AA4CA,UAAU,UAAU;IAClB,MAAM,EAAE;QACN,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,OAAO,CAAC,EAAE,OAAO,CAAA;QACjB,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,IAAI,CAAC,EAAE,OAAO,CAAA;QACd,OAAO,CAAC,EAAE,OAAO,CAAA;QACjB,KAAK,CAAC,EAAE,OAAO,CAAA;QACf,QAAQ,CAAC,EAAE,OAAO,CAAA;QAClB,GAAG,CAAC,EAAE,OAAO,CAAA;QACb,KAAK,CAAC,EAAE,OAAO,CAAA;KAChB,CAAA;IACD,WAAW,EAAE,MAAM,EAAE,CAAA;CACtB;AAGD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAoBvD;AAuED,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAoDvD"}
@@ -0,0 +1,168 @@
1
+ import { parseArgs } from 'node:util';
2
+ import { readFileSync } from 'node:fs';
3
+ import { fileURLToPath } from 'node:url';
4
+ import path from 'node:path';
5
+ import { resetProjectCache } from '../core/project.js';
6
+ import { resolveConfig } from './resolve-config.js';
7
+ import { runCheck } from './commands/check.js';
8
+ import { runBaseline } from './commands/baseline.js';
9
+ import { runExplain } from './commands/explain.js';
10
+ import { watchAndRerun } from './watch.js';
11
+ function getVersion() {
12
+ const pkgPath = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../package.json');
13
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
14
+ if (pkg && typeof pkg === 'object' && 'version' in pkg && typeof pkg.version === 'string') {
15
+ return pkg.version;
16
+ }
17
+ return '0.0.0';
18
+ }
19
+ const HELP_TEXT = `
20
+ eess-ts — Architecture testing for TypeScript
21
+
22
+ Usage:
23
+ eess-ts check [files...] Run architecture rules
24
+ eess-ts baseline [files...] Generate baseline file
25
+ eess-ts explain [files...] Dump all active rules as JSON
26
+
27
+ Options:
28
+ --baseline <path> Baseline file for filtering known violations
29
+ --output <path> Output path for baseline file (default: arch-baseline.json)
30
+ --changed Only report violations in changed files (git diff)
31
+ --base <branch> Base branch for diff (default: main)
32
+ --format <format> Output format: terminal, json, github, auto (default: auto)
33
+ --markdown Output explain results as markdown table
34
+ --fix Apply deterministic fixes; dry-run (preview) unless --apply
35
+ --apply With --fix, write the fixes to disk
36
+ -w, --watch Watch for changes and re-run (check command only)
37
+ --config <path> Path to config file
38
+ -v, --version Show version number
39
+ -h, --help Show this help message
40
+ `;
41
+ // eess-exclude eess/no-unused-exports: consumed by the test suite (tests are outside the build project)
42
+ export function parseCliArgs(args) {
43
+ return parseArgs({
44
+ args,
45
+ options: {
46
+ baseline: { type: 'string' },
47
+ output: { type: 'string' },
48
+ changed: { type: 'boolean', default: false },
49
+ markdown: { type: 'boolean', default: false },
50
+ base: { type: 'string', default: 'main' },
51
+ format: { type: 'string' },
52
+ config: { type: 'string' },
53
+ help: { type: 'boolean', short: 'h', default: false },
54
+ version: { type: 'boolean', short: 'v', default: false },
55
+ watch: { type: 'boolean', short: 'w', default: false },
56
+ fix: { type: 'boolean', default: false },
57
+ apply: { type: 'boolean', default: false },
58
+ },
59
+ allowPositionals: true,
60
+ strict: true,
61
+ });
62
+ }
63
+ /** Require rule files to be specified, printing an error and setting exit code if missing. */
64
+ function requireRuleFiles(ruleFiles) {
65
+ if (ruleFiles.length > 0)
66
+ return true;
67
+ console.error('Error: No rule files specified. Pass rule files as arguments or set them in config.');
68
+ process.exitCode = 1;
69
+ return false;
70
+ }
71
+ /** Handle the `check` subcommand. */
72
+ async function handleCheck(ruleFiles, values, config, format, baseline, changed, base) {
73
+ if (!requireRuleFiles(ruleFiles))
74
+ return;
75
+ if (values.watch === true) {
76
+ const watchDirs = config.watchDirs ?? ['src'];
77
+ const checkArgs = { ruleFiles, baseline, changed, base, format, fresh: true };
78
+ process.stdout.write('eess-ts — watching for changes\n\n');
79
+ resetProjectCache();
80
+ await runCheck(checkArgs).catch(() => {
81
+ // Initial violations are printed by runCheck — don't exit
82
+ });
83
+ process.stdout.write('\nWatching for changes...\n');
84
+ watchAndRerun({
85
+ watchDirs,
86
+ watchFiles: ruleFiles,
87
+ onChangeDetected: async () => {
88
+ resetProjectCache();
89
+ await runCheck(checkArgs);
90
+ },
91
+ });
92
+ }
93
+ else {
94
+ const failures = await runCheck({
95
+ ruleFiles,
96
+ baseline,
97
+ changed,
98
+ base,
99
+ format,
100
+ fix: values.fix === true,
101
+ apply: values.apply === true,
102
+ });
103
+ if (failures > 0) {
104
+ process.exitCode = 1;
105
+ }
106
+ }
107
+ }
108
+ /** Handle the `baseline` subcommand. */
109
+ async function handleBaseline(ruleFiles, output) {
110
+ if (!requireRuleFiles(ruleFiles))
111
+ return;
112
+ await runBaseline({ ruleFiles, output });
113
+ }
114
+ /** Handle the `explain` subcommand. */
115
+ async function handleExplain(ruleFiles, markdown) {
116
+ if (!requireRuleFiles(ruleFiles))
117
+ return;
118
+ await runExplain({ ruleFiles, markdown });
119
+ }
120
+ export async function run(args) {
121
+ const parsed = parseCliArgs(args);
122
+ const { values, positionals } = parsed;
123
+ if (values.version === true) {
124
+ process.stdout.write(getVersion() + '\n');
125
+ return;
126
+ }
127
+ if (values.help === true) {
128
+ process.stdout.write(HELP_TEXT + '\n');
129
+ return;
130
+ }
131
+ const command = positionals[0];
132
+ if (command === undefined) {
133
+ console.error('Error: No command specified. Use --help for usage.');
134
+ process.exitCode = 1;
135
+ return;
136
+ }
137
+ if (values.watch === true && command !== 'check') {
138
+ console.error('Error: --watch is only supported with the check command.');
139
+ process.exitCode = 1;
140
+ return;
141
+ }
142
+ const config = await resolveConfig(values.config);
143
+ const ruleFiles = positionals.slice(1).length > 0 ? positionals.slice(1) : (config.rules ?? []);
144
+ const formatCandidate = values.format ?? config.format ?? 'auto';
145
+ const format = formatCandidate === 'json' ||
146
+ formatCandidate === 'github' ||
147
+ formatCandidate === 'terminal' ||
148
+ formatCandidate === 'auto'
149
+ ? formatCandidate
150
+ : 'auto';
151
+ const baseline = values.baseline ?? config.baseline;
152
+ const base = values.base ?? 'main';
153
+ const changed = values.changed ?? false;
154
+ if (command === 'check') {
155
+ await handleCheck(ruleFiles, values, config, format, baseline, changed, base);
156
+ }
157
+ else if (command === 'baseline') {
158
+ await handleBaseline(ruleFiles, values.output ?? 'arch-baseline.json');
159
+ }
160
+ else if (command === 'explain') {
161
+ await handleExplain(ruleFiles, values.markdown);
162
+ }
163
+ else {
164
+ console.error(`Error: Unknown command "${command}". Use --help for usage.`);
165
+ process.exitCode = 1;
166
+ }
167
+ }
168
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { CheckOptions, ArchViolation } from '@nielspeter/eess';
2
+ /** Minimal interface for rule builders — needs .check(); .violations() enables --fix. */
3
+ export interface RuleBuilderLike {
4
+ check: (opts?: CheckOptions) => void;
5
+ /** Collect violations without printing/throwing — used by --fix. */
6
+ violations?: () => ArchViolation[];
7
+ }
8
+ export interface LoadOptions {
9
+ /** Use cache-busting imports for watch mode. Default: false */
10
+ fresh?: boolean;
11
+ }
12
+ /**
13
+ * Load rule files via jiti (supports `.ts` and `.js`/`.mjs`).
14
+ *
15
+ * Rule files must export a default array of rule builders or a function
16
+ * returning one. When `fresh` is true, a cache-busting jiti instance is used so
17
+ * watch-mode re-runs pick up file changes.
18
+ */
19
+ export declare function loadRuleFiles(files: string[], options?: LoadOptions): Promise<RuleBuilderLike[]>;
20
+ //# sourceMappingURL=load-rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-rules.d.ts","sourceRoot":"","sources":["../../src/cli/load-rules.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAEnE,yFAAyF;AAEzF,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,YAAY,KAAK,IAAI,CAAA;IACpC,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,aAAa,EAAE,CAAA;CACnC;AAGD,MAAM,WAAW,WAAW;IAC1B,+DAA+D;IAC/D,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAYD;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,eAAe,EAAE,CAAC,CA8B5B"}
@@ -0,0 +1,97 @@
1
+ import path from 'node:path';
2
+ import { createJiti } from 'jiti';
3
+ // jiti so rule files can be authored in TypeScript (`arch.rules.ts`) — native
4
+ // `import()` cannot load `.ts`. Cached, except in watch mode where a fresh
5
+ // instance busts the module cache to pick up edits.
6
+ let cachedJiti;
7
+ function getJiti(fresh) {
8
+ if (fresh)
9
+ return createJiti(import.meta.url, { fsCache: false, moduleCache: false });
10
+ if (!cachedJiti)
11
+ cachedJiti = createJiti(import.meta.url);
12
+ return cachedJiti;
13
+ }
14
+ /**
15
+ * Load rule files via jiti (supports `.ts` and `.js`/`.mjs`).
16
+ *
17
+ * Rule files must export a default array of rule builders or a function
18
+ * returning one. When `fresh` is true, a cache-busting jiti instance is used so
19
+ * watch-mode re-runs pick up file changes.
20
+ */
21
+ export async function loadRuleFiles(files, options) {
22
+ const builders = [];
23
+ const jiti = getJiti(options?.fresh === true);
24
+ for (const file of files) {
25
+ const resolved = path.resolve(file);
26
+ const mod = await jiti.import(resolved);
27
+ const exported = extractDefault(mod);
28
+ const items = resolveExported(exported, file);
29
+ // A non-builder value in the default-export array is a loud error, never a
30
+ // silent skip: a silently-dropped rule is a green-but-empty gate, which the
31
+ // whole point of this tool is to forbid (plan 0061, Phase 0). Every entry
32
+ // must be a `.check()`-able builder — a void preset call (`preset(...)`
33
+ // returning `undefined`) is the classic offender and must fail here, not
34
+ // vanish.
35
+ items.forEach((item, index) => {
36
+ if (!isRuleBuilderLike(item)) {
37
+ throw new Error(`Rule file "${file}": default export entry [${index}] is not a rule builder ` +
38
+ `(got ${describeValue(item)}). Every entry must be a builder with a .check() ` +
39
+ `method — e.g. \`modules(p).that()…\`. A preset that returns void cannot be placed ` +
40
+ `directly in the array; call it in its own statement, or export a builder.`);
41
+ }
42
+ builders.push(item);
43
+ });
44
+ }
45
+ return builders;
46
+ }
47
+ /**
48
+ * Resolve the exported value to an array of unknowns.
49
+ * Supports: direct arrays, or factory functions returning arrays.
50
+ *
51
+ * A default export of the wrong shape (not an array, or a function that does
52
+ * not return an array) is a loud error — otherwise the rule file contributes
53
+ * zero gates silently.
54
+ */
55
+ function resolveExported(exported, file) {
56
+ if (Array.isArray(exported)) {
57
+ return exported;
58
+ }
59
+ if (typeof exported === 'function') {
60
+ // Runtime validated: exported is a function, call it and check result
61
+ // eess-exclude eess/adr005-no-type-assertions: exported is runtime-verified as callable (typeof check); the static `Function` type is not callable with a typed signature
62
+ const result = exported();
63
+ if (Array.isArray(result)) {
64
+ return result;
65
+ }
66
+ throw new Error(`Rule file "${file}": default-exported function must return an array of rule builders ` +
67
+ `(got ${describeValue(result)}).`);
68
+ }
69
+ throw new Error(`Rule file "${file}": default export must be an array of rule builders, or a function ` +
70
+ `returning one (got ${describeValue(exported)}). Add \`export default [ …builders ]\`.`);
71
+ }
72
+ /** Short human-readable description of an unexpected value, for error messages. */
73
+ function describeValue(value) {
74
+ if (value === null)
75
+ return 'null';
76
+ if (Array.isArray(value))
77
+ return 'an array';
78
+ return typeof value;
79
+ }
80
+ function extractDefault(mod) {
81
+ if (mod === null || mod === undefined || typeof mod !== 'object') {
82
+ return undefined;
83
+ }
84
+ // Dynamic import returns a module namespace object — 'in' narrows safely
85
+ if ('default' in mod) {
86
+ return mod['default'];
87
+ }
88
+ return undefined;
89
+ }
90
+ function isRuleBuilderLike(value) {
91
+ if (value === null || value === undefined || typeof value !== 'object') {
92
+ return false;
93
+ }
94
+ // Structural type check: must have a 'check' method ('in' narrows the read)
95
+ return 'check' in value && typeof value['check'] === 'function';
96
+ }
97
+ //# sourceMappingURL=load-rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-rules.js","sourceRoot":"","sources":["../../src/cli/load-rules.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { CliConfig } from './config.js';
2
+ /**
3
+ * Resolve CLI configuration from an explicit path or by searching for a config file.
4
+ *
5
+ * Config resolution order:
6
+ * 1. CLI flags (highest priority) — handled by caller
7
+ * 2. eess-ts.config.ts in project root
8
+ * 3. Defaults (project: 'tsconfig.json', format: 'auto')
9
+ */
10
+ export declare function resolveConfig(explicitPath?: string): Promise<CliConfig>;
11
+ //# sourceMappingURL=resolve-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-config.d.ts","sourceRoot":"","sources":["../../src/cli/resolve-config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAK5C;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAO7E"}
@@ -0,0 +1,61 @@
1
+ import path from 'node:path';
2
+ import fs from 'node:fs';
3
+ // Config file names, in resolution order. First match wins.
4
+ const CONFIG_FILENAMES = ['eess-ts.config.ts', 'eess-ts.config.js'];
5
+ /**
6
+ * Resolve CLI configuration from an explicit path or by searching for a config file.
7
+ *
8
+ * Config resolution order:
9
+ * 1. CLI flags (highest priority) — handled by caller
10
+ * 2. eess-ts.config.ts in project root
11
+ * 3. Defaults (project: 'tsconfig.json', format: 'auto')
12
+ */
13
+ export async function resolveConfig(explicitPath) {
14
+ const configPath = explicitPath ?? findConfigFile();
15
+ if (configPath === undefined)
16
+ return {};
17
+ const mod = await import(path.resolve(configPath));
18
+ return extractDefault(mod);
19
+ }
20
+ function findConfigFile() {
21
+ const cwd = process.cwd();
22
+ for (const name of CONFIG_FILENAMES) {
23
+ const candidate = path.join(cwd, name);
24
+ if (fs.existsSync(candidate))
25
+ return candidate;
26
+ }
27
+ return undefined;
28
+ }
29
+ /**
30
+ * Extract the default export from an ESM module.
31
+ * Supports both `export default config` and `module.exports = config`.
32
+ */
33
+ function extractDefault(mod) {
34
+ if (mod === null || mod === undefined || typeof mod !== 'object') {
35
+ return {};
36
+ }
37
+ // Dynamic import returns a module namespace — 'in' narrows safely
38
+ if (!('default' in mod)) {
39
+ return {};
40
+ }
41
+ const defaultExport = mod['default'];
42
+ if (defaultExport === null || defaultExport === undefined || typeof defaultExport !== 'object') {
43
+ return {};
44
+ }
45
+ // Runtime validate: only pick known CliConfig fields ('in' narrows each read)
46
+ const config = {};
47
+ if ('project' in defaultExport && typeof defaultExport.project === 'string')
48
+ config.project = defaultExport.project;
49
+ if ('baseline' in defaultExport && typeof defaultExport.baseline === 'string')
50
+ config.baseline = defaultExport.baseline;
51
+ if ('format' in defaultExport) {
52
+ const format = defaultExport.format;
53
+ if (format === 'terminal' || format === 'json' || format === 'github' || format === 'auto') {
54
+ config.format = format;
55
+ }
56
+ }
57
+ if ('rules' in defaultExport && Array.isArray(defaultExport.rules))
58
+ config.rules = defaultExport.rules.filter((r) => typeof r === 'string');
59
+ return config;
60
+ }
61
+ //# sourceMappingURL=resolve-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-config.js","sourceRoot":"","sources":["../../src/cli/resolve-config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,MAAM,SAAS,CAAA;AAGxB,4DAA4D;AAC5D,MAAM,gBAAgB,GAAG,CAAC,mBAAmB,EAAE,mBAAmB,CAAC,CAAA;AAEnE;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,YAAqB;IACvD,MAAM,UAAU,GAAG,YAAY,IAAI,cAAc,EAAE,CAAA;IAEnD,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO,EAAE,CAAA;IAEvC,MAAM,GAAG,GAAY,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAA;IAC3D,OAAO,cAAc,CAAC,GAAG,CAAC,CAAA;AAC5B,CAAC;AAED,SAAS,cAAc;IACrB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;IACzB,KAAK,MAAM,IAAI,IAAI,gBAAgB,EAAE,CAAC;QACpC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;QACtC,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAA;IAChD,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;GAGG;AACH,SAAS,cAAc,CAAC,GAAY;IAClC,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACjE,OAAO,EAAE,CAAA;IACX,CAAC;IACD,kEAAkE;IAClE,IAAI,CAAC,CAAC,SAAS,IAAI,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,CAAA;IACX,CAAC;IACD,MAAM,aAAa,GAAY,GAAG,CAAC,SAAS,CAAC,CAAA;IAC7C,IAAI,aAAa,KAAK,IAAI,IAAI,aAAa,KAAK,SAAS,IAAI,OAAO,aAAa,KAAK,QAAQ,EAAE,CAAC;QAC/F,OAAO,EAAE,CAAA;IACX,CAAC;IACD,8EAA8E;IAC9E,MAAM,MAAM,GAAc,EAAE,CAAA;IAC5B,IAAI,SAAS,IAAI,aAAa,IAAI,OAAO,aAAa,CAAC,OAAO,KAAK,QAAQ;QACzE,MAAM,CAAC,OAAO,GAAG,aAAa,CAAC,OAAO,CAAA;IACxC,IAAI,UAAU,IAAI,aAAa,IAAI,OAAO,aAAa,CAAC,QAAQ,KAAK,QAAQ;QAC3E,MAAM,CAAC,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAA;IAC1C,IAAI,QAAQ,IAAI,aAAa,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,CAAA;QACnC,IAAI,MAAM,KAAK,UAAU,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YAC3F,MAAM,CAAC,MAAM,GAAG,MAAM,CAAA;QACxB,CAAC;IACH,CAAC;IACD,IAAI,OAAO,IAAI,aAAa,IAAI,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC;QAChE,MAAM,CAAC,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAA;IACtF,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -0,0 +1,49 @@
1
+ export interface WatchOptions {
2
+ /** Directories to watch for changes */
3
+ watchDirs: string[];
4
+ /** Additional files to watch (e.g., rule files) */
5
+ watchFiles: string[];
6
+ /** Callback to run on detected changes */
7
+ onChangeDetected: () => Promise<void>;
8
+ /** Debounce window in ms. Default: 250 */
9
+ debounceMs?: number;
10
+ }
11
+ export declare const TS_FILE_RE: RegExp;
12
+ /**
13
+ * Scheduling logic for watch mode — extracted for testability.
14
+ *
15
+ * Debounces rapid triggers. If a trigger arrives while the callback
16
+ * is running, it queues a re-run after the current run completes.
17
+ */
18
+ export declare class RunScheduler {
19
+ #private;
20
+ private debounceTimer;
21
+ private running;
22
+ private _pendingRerun;
23
+ private readonly debounceMs;
24
+ private readonly onRun;
25
+ constructor(onRun: (trigger: string) => Promise<void>, debounceMs?: number);
26
+ get runCount(): number;
27
+ get pendingRerun(): boolean;
28
+ get isRunning(): boolean;
29
+ /**
30
+ * Queue a run for the given trigger, resetting the debounce window.
31
+ * If a run is already in progress, marks a pending re-run instead.
32
+ */
33
+ schedule(trigger: string): void;
34
+ private executeRun;
35
+ }
36
+ /**
37
+ * Watch for file changes and re-run the callback.
38
+ *
39
+ * Uses Node.js `fs.watch` with `recursive: true` (Node 24+).
40
+ * Debounces rapid filesystem events. If a change arrives while
41
+ * a run is in progress, it is queued and executed after the
42
+ * current run completes.
43
+ *
44
+ * Known limitation: each re-run loads rule files with a fresh (cache-busting)
45
+ * jiti instance. Over long sessions, memory grows — restart the watcher
46
+ * periodically for long sessions.
47
+ */
48
+ export declare function watchAndRerun(options: WatchOptions): void;
49
+ //# sourceMappingURL=watch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/cli/watch.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,uCAAuC;IACvC,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,mDAAmD;IACnD,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,0CAA0C;IAC1C,gBAAgB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAGD,eAAO,MAAM,UAAU,QAAiB,CAAA;AAExC;;;;;GAKG;AAEH,qBAAa,YAAY;;IACvB,OAAO,CAAC,aAAa,CAA2C;IAChE,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoC;gBAG9C,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE,UAAU,SAAM;IAKvE,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,YAAY,IAAI,OAAO,CAE1B;IAED,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAW/B,OAAO,CAAC,UAAU;CAwBnB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAqDzD"}