@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,30 @@
1
+ import type { ClassDeclaration } from 'ts-morph';
2
+ import type { Predicate } from '@nielspeter/eess';
3
+ import type { ArchFunction } from '../models/arch-function.js';
4
+ /**
5
+ * Predicate: class has a method (or constructor/getter/setter) with
6
+ * cyclomatic complexity above threshold.
7
+ */
8
+ export declare function haveCyclomaticComplexity(opts: {
9
+ greaterThan: number;
10
+ }): Predicate<ClassDeclaration>;
11
+ /**
12
+ * Predicate: function has cyclomatic complexity above threshold.
13
+ * Uses ArchFunction.getBody() — works for all function kinds.
14
+ */
15
+ export declare function haveComplexity(opts: {
16
+ greaterThan: number;
17
+ }): Predicate<ArchFunction>;
18
+ /**
19
+ * Predicate: class has more than N lines of code (span lines).
20
+ */
21
+ export declare function haveMoreLinesThan(threshold: number): Predicate<ClassDeclaration>;
22
+ /**
23
+ * Predicate: function has more than N lines of code (span lines).
24
+ */
25
+ export declare function haveMoreFunctionLinesThan(threshold: number): Predicate<ArchFunction>;
26
+ /**
27
+ * Predicate: class has more than N methods.
28
+ */
29
+ export declare function haveMoreMethodsThan(threshold: number): Predicate<ClassDeclaration>;
30
+ //# sourceMappingURL=metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/predicates/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAG9D;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,WAAW,EAAE,MAAM,CAAA;CACpB,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAa9B;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAAC,YAAY,CAAC,CAOrF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAOhF;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC,YAAY,CAAC,CAOpF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAOlF"}
@@ -0,0 +1,65 @@
1
+ import { cyclomaticComplexity, linesOfCode, methodCount } from '../helpers/complexity.js';
2
+ /**
3
+ * Predicate: class has a method (or constructor/getter/setter) with
4
+ * cyclomatic complexity above threshold.
5
+ */
6
+ export function haveCyclomaticComplexity(opts) {
7
+ return {
8
+ description: `have a method with cyclomatic complexity > ${String(opts.greaterThan)}`,
9
+ test(cls) {
10
+ const bodies = [
11
+ ...cls.getMethods().map((m) => m.getBody()),
12
+ ...cls.getConstructors().map((c) => c.getBody()),
13
+ ...cls.getGetAccessors().map((g) => g.getBody()),
14
+ ...cls.getSetAccessors().map((s) => s.getBody()),
15
+ ];
16
+ return bodies.some((body) => cyclomaticComplexity(body) > opts.greaterThan);
17
+ },
18
+ };
19
+ }
20
+ /**
21
+ * Predicate: function has cyclomatic complexity above threshold.
22
+ * Uses ArchFunction.getBody() — works for all function kinds.
23
+ */
24
+ export function haveComplexity(opts) {
25
+ return {
26
+ description: `have cyclomatic complexity > ${String(opts.greaterThan)}`,
27
+ test(fn) {
28
+ return cyclomaticComplexity(fn.getBody()) > opts.greaterThan;
29
+ },
30
+ };
31
+ }
32
+ /**
33
+ * Predicate: class has more than N lines of code (span lines).
34
+ */
35
+ export function haveMoreLinesThan(threshold) {
36
+ return {
37
+ description: `have more than ${String(threshold)} lines`,
38
+ test(cls) {
39
+ return linesOfCode(cls) > threshold;
40
+ },
41
+ };
42
+ }
43
+ /**
44
+ * Predicate: function has more than N lines of code (span lines).
45
+ */
46
+ export function haveMoreFunctionLinesThan(threshold) {
47
+ return {
48
+ description: `have more than ${String(threshold)} lines`,
49
+ test(fn) {
50
+ return linesOfCode(fn.getNode()) > threshold;
51
+ },
52
+ };
53
+ }
54
+ /**
55
+ * Predicate: class has more than N methods.
56
+ */
57
+ export function haveMoreMethodsThan(threshold) {
58
+ return {
59
+ description: `have more than ${String(threshold)} methods`,
60
+ test(cls) {
61
+ return methodCount(cls) > threshold;
62
+ },
63
+ };
64
+ }
65
+ //# sourceMappingURL=metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/predicates/metrics.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAEzF;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAExC;IACC,OAAO;QACL,WAAW,EAAE,8CAA8C,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE;QACrF,IAAI,CAAC,GAAqB;YACxB,MAAM,MAAM,GAAG;gBACb,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC3C,GAAG,GAAG,CAAC,eAAe,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;gBAChD,GAAG,GAAG,CAAC,eAAe,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;gBAChD,GAAG,GAAG,CAAC,eAAe,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;aACjD,CAAA;YACD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAA;QAC7E,CAAC;KACF,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,IAA6B;IAC1D,OAAO;QACL,WAAW,EAAE,gCAAgC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE;QACvE,IAAI,CAAC,EAAgB;YACnB,OAAO,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,WAAW,CAAA;QAC9D,CAAC;KACF,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,SAAiB;IACjD,OAAO;QACL,WAAW,EAAE,kBAAkB,MAAM,CAAC,SAAS,CAAC,QAAQ;QACxD,IAAI,CAAC,GAAqB;YACxB,OAAO,WAAW,CAAC,GAAG,CAAC,GAAG,SAAS,CAAA;QACrC,CAAC;KACF,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,yBAAyB,CAAC,SAAiB;IACzD,OAAO;QACL,WAAW,EAAE,kBAAkB,MAAM,CAAC,SAAS,CAAC,QAAQ;QACxD,IAAI,CAAC,EAAgB;YACnB,OAAO,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,SAAS,CAAA;QAC9C,CAAC;KACF,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,SAAiB;IACnD,OAAO;QACL,WAAW,EAAE,kBAAkB,MAAM,CAAC,SAAS,CAAC,UAAU;QAC1D,IAAI,CAAC,GAAqB;YACxB,OAAO,WAAW,CAAC,GAAG,CAAC,GAAG,SAAS,CAAA;QACrC,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,44 @@
1
+ import type { SourceFile } from 'ts-morph';
2
+ import type { Predicate } from '@nielspeter/eess';
3
+ import type { ImportOptions } from '../core/import-options.js';
4
+ /**
5
+ * Matches modules that import from a path matching any of the given globs.
6
+ *
7
+ * The globs are matched against resolved absolute import paths.
8
+ * For external (non-resolvable) imports, they match against the raw specifier.
9
+ *
10
+ * @example
11
+ * modules(p).that().importFrom('** /infrastructure/**')
12
+ * modules(p).that().importFrom('fastify', 'knex', 'bullmq')
13
+ */
14
+ export declare function importFrom(globs: string[], options: ImportOptions): Predicate<SourceFile>;
15
+ export declare function importFrom(...globs: string[]): Predicate<SourceFile>;
16
+ /**
17
+ * Matches modules that do NOT import from any path matching the given globs.
18
+ *
19
+ * @example
20
+ * modules(p).that().notImportFrom('** /legacy/**')
21
+ * modules(p).that().notImportFrom('fastify', 'knex', 'bullmq')
22
+ */
23
+ export declare function notImportFrom(globs: string[], options: ImportOptions): Predicate<SourceFile>;
24
+ export declare function notImportFrom(...globs: string[]): Predicate<SourceFile>;
25
+ /**
26
+ * Matches modules that export a symbol with the given name.
27
+ *
28
+ * Checks the module's exported declarations for a matching name.
29
+ *
30
+ * @example
31
+ * modules(p).that().exportSymbolNamed('default')
32
+ */
33
+ export declare function exportSymbolNamed(name: string): Predicate<SourceFile>;
34
+ /**
35
+ * Matches modules whose file path matches the given glob.
36
+ *
37
+ * Similar to resideInFile but semantically clearer for modules —
38
+ * "modules that have path matching" vs "elements that reside in file".
39
+ *
40
+ * @example
41
+ * modules(p).that().havePathMatching('** /services/*.ts')
42
+ */
43
+ export declare function havePathMatching(glob: string): Predicate<SourceFile>;
44
+ //# sourceMappingURL=module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../src/predicates/module.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAC1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAmB9D;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,aAAa,GAAG,SAAS,CAAC,UAAU,CAAC,CAAA;AAC1F,wBAAgB,UAAU,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC,UAAU,CAAC,CAAA;AAgBrE;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,aAAa,GAAG,SAAS,CAAC,UAAU,CAAC,CAAA;AAC7F,wBAAgB,aAAa,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC,UAAU,CAAC,CAAA;AAkBxE;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC,UAAU,CAAC,CAKrE;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC,UAAU,CAAC,CAMpE"}
@@ -0,0 +1,70 @@
1
+ import picomatch from 'picomatch';
2
+ import { getDependencyDecls, resolveDependencyPath, isTypeOnlyDependency, } from '../core/module-dependencies.js';
3
+ /**
4
+ * Resolve the dependency paths for a source file — `import … from` plus
5
+ * `export … from` re-exports (both are dependency edges) — optionally filtering
6
+ * out type-only edges. Returns absolute paths for resolvable targets, raw
7
+ * specifiers for external packages.
8
+ */
9
+ function getImportPaths(sourceFile, ignoreTypeImports = false) {
10
+ return getDependencyDecls(sourceFile)
11
+ .filter((decl) => (ignoreTypeImports ? !isTypeOnlyDependency(decl) : true))
12
+ .map(resolveDependencyPath);
13
+ }
14
+ export function importFrom(...args) {
15
+ // ADR-005: as casts required — TS cannot narrow tuple union rest params after Array.isArray
16
+ // eess-exclude eess/adr005-no-type-assertions: tuple-union rest param — TS cannot narrow [string[], ImportOptions] | string[] to string[] from Array.isArray(args[0])
17
+ const globs = Array.isArray(args[0]) ? args[0] : args;
18
+ // eess-exclude eess/adr005-no-type-assertions: tuple-union rest param — args[1] is ImportOptions only in the [globs, options] overload
19
+ const options = Array.isArray(args[0]) && args.length > 1 ? args[1] : undefined;
20
+ const ignoreType = options?.ignoreTypeImports === true;
21
+ const matchers = globs.map((g) => picomatch(g));
22
+ return {
23
+ description: 'import from ' + globs.map((g) => `"${g}"`).join(', '),
24
+ test: (sourceFile) => getImportPaths(sourceFile, ignoreType).some((p) => matchers.some((m) => m(p))),
25
+ };
26
+ }
27
+ export function notImportFrom(...args) {
28
+ // ADR-005: as casts required — TS cannot narrow tuple union rest params after Array.isArray
29
+ // eess-exclude eess/adr005-no-type-assertions: tuple-union rest param — TS cannot narrow [string[], ImportOptions] | string[] to string[] from Array.isArray(args[0])
30
+ const globs = Array.isArray(args[0]) ? args[0] : args;
31
+ // eess-exclude eess/adr005-no-type-assertions: tuple-union rest param — args[1] is ImportOptions only in the [globs, options] overload
32
+ const options = Array.isArray(args[0]) && args.length > 1 ? args[1] : undefined;
33
+ const ignoreType = options?.ignoreTypeImports === true;
34
+ const matchers = globs.map((g) => picomatch(g));
35
+ return {
36
+ description: 'not import from ' + globs.map((g) => `"${g}"`).join(', '),
37
+ test: (sourceFile) => !getImportPaths(sourceFile, ignoreType).some((p) => matchers.some((m) => m(p))),
38
+ };
39
+ }
40
+ /**
41
+ * Matches modules that export a symbol with the given name.
42
+ *
43
+ * Checks the module's exported declarations for a matching name.
44
+ *
45
+ * @example
46
+ * modules(p).that().exportSymbolNamed('default')
47
+ */
48
+ export function exportSymbolNamed(name) {
49
+ return {
50
+ description: `export symbol named "${name}"`,
51
+ test: (sourceFile) => sourceFile.getExportedDeclarations().has(name),
52
+ };
53
+ }
54
+ /**
55
+ * Matches modules whose file path matches the given glob.
56
+ *
57
+ * Similar to resideInFile but semantically clearer for modules —
58
+ * "modules that have path matching" vs "elements that reside in file".
59
+ *
60
+ * @example
61
+ * modules(p).that().havePathMatching('** /services/*.ts')
62
+ */
63
+ export function havePathMatching(glob) {
64
+ const isMatch = picomatch(glob);
65
+ return {
66
+ description: `have path matching "${glob}"`,
67
+ test: (sourceFile) => isMatch(sourceFile.getFilePath()),
68
+ };
69
+ }
70
+ //# sourceMappingURL=module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module.js","sourceRoot":"","sources":["../../src/predicates/module.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { type InterfaceDeclaration, type TypeAliasDeclaration } from 'ts-morph';
2
+ import type { Predicate } from '@nielspeter/eess';
3
+ import type { TypeMatcher } from '../helpers/type-matchers.js';
4
+ /**
5
+ * Union type representing both interface and type alias declarations.
6
+ * Used as the element type for TypeRuleBuilder.
7
+ */
8
+ export type TypeDeclaration = InterfaceDeclaration | TypeAliasDeclaration;
9
+ /**
10
+ * Matches only InterfaceDeclaration elements.
11
+ *
12
+ * @example
13
+ * types(project).that().areInterfaces() // only interfaces, not type aliases
14
+ */
15
+ export declare function areInterfaces(): Predicate<TypeDeclaration>;
16
+ /**
17
+ * Matches only TypeAliasDeclaration elements.
18
+ *
19
+ * @example
20
+ * types(project).that().areTypeAliases() // only type aliases, not interfaces
21
+ */
22
+ export declare function areTypeAliases(): Predicate<TypeDeclaration>;
23
+ /**
24
+ * Matches types that have a property with the given name.
25
+ * Works for both interfaces (direct properties) and type aliases
26
+ * (resolved type properties).
27
+ *
28
+ * @example
29
+ * types(project).that().haveProperty('sortBy')
30
+ */
31
+ export declare function haveProperty(name: string): Predicate<TypeDeclaration>;
32
+ /**
33
+ * Matches types that have a property whose type satisfies the given matcher.
34
+ * Resolves through type aliases, Partial<>, Pick<>, etc.
35
+ *
36
+ * @example
37
+ * types(project).that().havePropertyOfType('sortBy', isString())
38
+ */
39
+ export declare function havePropertyOfType(name: string, matcher: TypeMatcher): Predicate<TypeDeclaration>;
40
+ /**
41
+ * Matches interfaces that extend the given type name.
42
+ * For type aliases, checks if the type text references the name.
43
+ *
44
+ * @example
45
+ * types(project).that().extendType('BaseConfig')
46
+ */
47
+ export declare function extendType(name: string): Predicate<TypeDeclaration>;
48
+ //# sourceMappingURL=type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../src/predicates/type.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,oBAAoB,EAAE,KAAK,oBAAoB,EAAE,MAAM,UAAU,CAAA;AACrF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAA;AAE9D;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,oBAAoB,GAAG,oBAAoB,CAAA;AAEzE;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI,SAAS,CAAC,eAAe,CAAC,CAK1D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,IAAI,SAAS,CAAC,eAAe,CAAC,CAK3D;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC,eAAe,CAAC,CAQrE;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,SAAS,CAAC,eAAe,CAAC,CASjG;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC,eAAe,CAAC,CAgBnE"}
@@ -0,0 +1,107 @@
1
+ import { Node } from 'ts-morph';
2
+ /**
3
+ * Matches only InterfaceDeclaration elements.
4
+ *
5
+ * @example
6
+ * types(project).that().areInterfaces() // only interfaces, not type aliases
7
+ */
8
+ export function areInterfaces() {
9
+ return {
10
+ description: 'are interfaces',
11
+ test: (element) => Node.isInterfaceDeclaration(element),
12
+ };
13
+ }
14
+ /**
15
+ * Matches only TypeAliasDeclaration elements.
16
+ *
17
+ * @example
18
+ * types(project).that().areTypeAliases() // only type aliases, not interfaces
19
+ */
20
+ export function areTypeAliases() {
21
+ return {
22
+ description: 'are type aliases',
23
+ test: (element) => Node.isTypeAliasDeclaration(element),
24
+ };
25
+ }
26
+ /**
27
+ * Matches types that have a property with the given name.
28
+ * Works for both interfaces (direct properties) and type aliases
29
+ * (resolved type properties).
30
+ *
31
+ * @example
32
+ * types(project).that().haveProperty('sortBy')
33
+ */
34
+ export function haveProperty(name) {
35
+ return {
36
+ description: `have property "${name}"`,
37
+ test: (element) => {
38
+ const type = getResolvedType(element);
39
+ return type.getProperty(name) !== undefined;
40
+ },
41
+ };
42
+ }
43
+ /**
44
+ * Matches types that have a property whose type satisfies the given matcher.
45
+ * Resolves through type aliases, Partial<>, Pick<>, etc.
46
+ *
47
+ * @example
48
+ * types(project).that().havePropertyOfType('sortBy', isString())
49
+ */
50
+ export function havePropertyOfType(name, matcher) {
51
+ return {
52
+ description: `have property "${name}" of matching type`,
53
+ test: (element) => {
54
+ const propType = getPropertyType(element, name);
55
+ if (propType === undefined)
56
+ return false;
57
+ return matcher(propType);
58
+ },
59
+ };
60
+ }
61
+ /**
62
+ * Matches interfaces that extend the given type name.
63
+ * For type aliases, checks if the type text references the name.
64
+ *
65
+ * @example
66
+ * types(project).that().extendType('BaseConfig')
67
+ */
68
+ export function extendType(name) {
69
+ return {
70
+ description: `extend type "${name}"`,
71
+ test: (element) => {
72
+ if (Node.isInterfaceDeclaration(element)) {
73
+ const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
74
+ const nameRegex = new RegExp(`^${escaped}(\\b|$|<)`);
75
+ return element.getExtends().some((ext) => nameRegex.test(ext.getText()));
76
+ }
77
+ // For type aliases, check if the type directly references the named type
78
+ // Use word boundary matching to avoid false positives (e.g., "BaseConfig" inside "{ bar: BaseConfig }")
79
+ const typeText = element.getType().getText();
80
+ const nameRegex = new RegExp(`\\b${name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`);
81
+ return nameRegex.test(typeText);
82
+ },
83
+ };
84
+ }
85
+ // --- Internal helpers ---
86
+ /**
87
+ * Resolve a TypeDeclaration to its ts-morph Type.
88
+ */
89
+ function getResolvedType(element) {
90
+ return element.getType();
91
+ }
92
+ /**
93
+ * Get the Type of a named property on a TypeDeclaration.
94
+ *
95
+ * Uses getTypeAtLocation() to resolve in context, which is critical
96
+ * for Partial<T>, Pick<T, K>, and other mapped types.
97
+ */
98
+ function getPropertyType(element, name) {
99
+ const type = getResolvedType(element);
100
+ const prop = type.getProperty(name);
101
+ if (prop === undefined)
102
+ return undefined;
103
+ // getTypeAtLocation resolves the property type in the context of the declaration.
104
+ // Without this, Partial<StrictOptions>['sortBy'] would not resolve correctly.
105
+ return prop.getTypeAtLocation(element);
106
+ }
107
+ //# sourceMappingURL=type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type.js","sourceRoot":"","sources":["../../src/predicates/type.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { ArchProject } from '../core/project.js';
2
+ import type { ArchViolation } from '../core/violation.js';
3
+ import type { PresetBaseOptions } from './shared.js';
4
+ export interface StrictBoundariesOptions extends PresetBaseOptions {
5
+ /** Glob pattern for boundary folders (e.g., 'src/features/*') */
6
+ folders: string;
7
+ /** Glob patterns for shared folders accessible by all boundaries */
8
+ shared?: string[];
9
+ /** If true, test files cannot import from other boundaries' tests */
10
+ isolateTests?: boolean;
11
+ /** If true, warn on copy-pasted function bodies across boundaries */
12
+ noCopyPaste?: boolean;
13
+ }
14
+ /**
15
+ * Enforce strict module boundaries: no cycles, no cross-boundary imports,
16
+ * shared isolation, and optional copy-paste detection.
17
+ */
18
+ export declare function strictBoundaries(p: ArchProject, options: StrictBoundariesOptions): ArchViolation[];
19
+ //# sourceMappingURL=boundaries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boundaries.d.ts","sourceRoot":"","sources":["../../src/presets/boundaries.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAIzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAGpD,MAAM,WAAW,uBAAwB,SAAQ,iBAAiB;IAChE,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAA;IACf,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,qEAAqE;IACrE,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,qEAAqE;IACrE,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAgED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,CAAC,EAAE,WAAW,EACd,OAAO,EAAE,uBAAuB,GAC/B,aAAa,EAAE,CA8EjB"}
@@ -0,0 +1,93 @@
1
+ import picomatch from 'picomatch';
2
+ import { slices } from '../builders/slice-rule-builder.js';
3
+ import { modules } from '../builders/module-rule-builder.js';
4
+ import { smells } from '../smells/index.js';
5
+ import { dispatchRule, validateOverrides, finishPreset } from './shared.js';
6
+ const RULE_IDS = [
7
+ 'preset/boundaries/no-cycles',
8
+ 'preset/boundaries/no-cross-boundary',
9
+ 'preset/boundaries/shared-isolation',
10
+ 'preset/boundaries/test-isolation',
11
+ 'preset/boundaries/no-duplicate-bodies',
12
+ ];
13
+ /**
14
+ * Collect violations for shared-folder isolation rules.
15
+ */
16
+ function applySharedIsolation(p, sharedGlobs, boundaryFolders, overrides) {
17
+ const violations = [];
18
+ for (const sharedGlob of sharedGlobs) {
19
+ for (const dir of boundaryFolders) {
20
+ violations.push(...dispatchRule(modules(p).that().resideInFolder(sharedGlob).should().notImportFrom(`${dir}/**`), 'preset/boundaries/shared-isolation', 'error', overrides));
21
+ }
22
+ }
23
+ return violations;
24
+ }
25
+ /**
26
+ * Collect violations for test-isolation rules across boundaries.
27
+ */
28
+ function applyTestIsolation(p, boundaryFolders, overrides) {
29
+ const violations = [];
30
+ for (const dir of boundaryFolders) {
31
+ const testPattern = `${dir}/**/*.test.*`;
32
+ const otherBoundaryTests = boundaryFolders
33
+ .filter((d) => d !== dir)
34
+ .map((d) => `${d}/**/*.test.*`);
35
+ for (const otherTestGlob of otherBoundaryTests) {
36
+ violations.push(...dispatchRule(modules(p).that().resideInFile(testPattern).should().notImportFrom(otherTestGlob), 'preset/boundaries/test-isolation', 'error', overrides));
37
+ }
38
+ }
39
+ return violations;
40
+ }
41
+ /**
42
+ * Enforce strict module boundaries: no cycles, no cross-boundary imports,
43
+ * shared isolation, and optional copy-paste detection.
44
+ */
45
+ export function strictBoundaries(p, options) {
46
+ const overrides = options.overrides;
47
+ validateOverrides(overrides, [...RULE_IDS]);
48
+ const sharedGlobs = options.shared ?? [];
49
+ const violations = [];
50
+ // Discover boundary folders from the glob pattern
51
+ const boundaryGlob = options.folders;
52
+ const matcher = picomatch(boundaryGlob);
53
+ const boundaryFolders = [];
54
+ for (const sf of p.getSourceFiles()) {
55
+ const dir = sf.getFilePath().replace(/\/[^/]+$/, '');
56
+ if (matcher(dir) && !boundaryFolders.includes(dir)) {
57
+ boundaryFolders.push(dir);
58
+ }
59
+ }
60
+ // Build a slice definition from discovered boundaries
61
+ const sliceDef = {};
62
+ for (const dir of boundaryFolders) {
63
+ const name = dir.split('/').pop() ?? dir;
64
+ sliceDef[name] = `${dir}/**`;
65
+ }
66
+ // --- No cycles between boundaries ---
67
+ if (Object.keys(sliceDef).length > 0) {
68
+ violations.push(...dispatchRule(slices(p).assignedFrom(sliceDef).should().beFreeOfCycles(), 'preset/boundaries/no-cycles', 'error', overrides));
69
+ }
70
+ // --- No cross-boundary imports ---
71
+ // Each boundary folder: modules in it can only import from itself + shared
72
+ for (const dir of boundaryFolders) {
73
+ const boundaryPattern = `${dir}/**`;
74
+ const allowedGlobs = [boundaryPattern, ...sharedGlobs];
75
+ violations.push(...dispatchRule(modules(p)
76
+ .that()
77
+ .resideInFolder(boundaryPattern)
78
+ .should()
79
+ .onlyImportFrom(...allowedGlobs), 'preset/boundaries/no-cross-boundary', 'error', overrides));
80
+ }
81
+ // --- Shared isolation: shared folders don't import from boundaries ---
82
+ violations.push(...applySharedIsolation(p, sharedGlobs, boundaryFolders, overrides));
83
+ // --- Test isolation ---
84
+ if (options.isolateTests) {
85
+ violations.push(...applyTestIsolation(p, boundaryFolders, overrides));
86
+ }
87
+ // --- No copy-paste across boundaries ---
88
+ if (options.noCopyPaste) {
89
+ violations.push(...dispatchRule(smells.duplicateBodies(p), 'preset/boundaries/no-duplicate-bodies', 'warn', overrides));
90
+ }
91
+ return finishPreset(violations, options);
92
+ }
93
+ //# sourceMappingURL=boundaries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boundaries.js","sourceRoot":"","sources":["../../src/presets/boundaries.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { ArchProject } from '../core/project.js';
2
+ import type { ArchViolation } from '../core/violation.js';
3
+ import type { PresetBaseOptions } from './shared.js';
4
+ export interface DataLayerIsolationOptions extends PresetBaseOptions {
5
+ /** Glob pattern for repository files */
6
+ repositories: string;
7
+ /** Base class that all repositories must extend */
8
+ baseClass?: string;
9
+ /** If true, repositories must throw typed errors, not generic Error */
10
+ requireTypedErrors?: boolean;
11
+ }
12
+ /**
13
+ * Companion to `layeredArchitecture`. Enforces repository pattern:
14
+ * base class extension and typed error throwing.
15
+ *
16
+ * Does NOT duplicate layer ordering or import direction — those
17
+ * are `layeredArchitecture`'s job.
18
+ */
19
+ export declare function dataLayerIsolation(p: ArchProject, options: DataLayerIsolationOptions): ArchViolation[];
20
+ //# sourceMappingURL=data-layer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-layer.d.ts","sourceRoot":"","sources":["../../src/presets/data-layer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAGzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAGpD,MAAM,WAAW,yBAA0B,SAAQ,iBAAiB;IAClE,wCAAwC;IACxC,YAAY,EAAE,MAAM,CAAA;IACpB,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,uEAAuE;IACvE,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B;AAID;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,CAAC,EAAE,WAAW,EACd,OAAO,EAAE,yBAAyB,GACjC,aAAa,EAAE,CAmCjB"}
@@ -0,0 +1,30 @@
1
+ import { classes } from '../builders/class-rule-builder.js';
2
+ import { newExpr } from '../helpers/matchers.js';
3
+ import { dispatchRule, validateOverrides, finishPreset } from './shared.js';
4
+ const RULE_IDS = ['preset/data/extend-base', 'preset/data/typed-errors'];
5
+ /**
6
+ * Companion to `layeredArchitecture`. Enforces repository pattern:
7
+ * base class extension and typed error throwing.
8
+ *
9
+ * Does NOT duplicate layer ordering or import direction — those
10
+ * are `layeredArchitecture`'s job.
11
+ */
12
+ export function dataLayerIsolation(p, options) {
13
+ const overrides = options.overrides;
14
+ validateOverrides(overrides, [...RULE_IDS]);
15
+ const violations = [];
16
+ // --- Base class enforcement ---
17
+ if (options.baseClass) {
18
+ violations.push(...dispatchRule(classes(p).that().resideInFolder(options.repositories).should().extend(options.baseClass), 'preset/data/extend-base', 'error', overrides));
19
+ }
20
+ // --- Typed errors ---
21
+ if (options.requireTypedErrors) {
22
+ violations.push(...dispatchRule(classes(p)
23
+ .that()
24
+ .resideInFolder(options.repositories)
25
+ .should()
26
+ .notContain(newExpr('Error')), 'preset/data/typed-errors', 'error', overrides));
27
+ }
28
+ return finishPreset(violations, options);
29
+ }
30
+ //# sourceMappingURL=data-layer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-layer.js","sourceRoot":"","sources":["../../src/presets/data-layer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,mCAAmC,CAAA;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AAEhD,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAW3E,MAAM,QAAQ,GAAG,CAAC,yBAAyB,EAAE,0BAA0B,CAAU,CAAA;AAEjF;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAChC,CAAc,EACd,OAAkC;IAElC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAA;IACnC,iBAAiB,CAAC,SAAS,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAA;IAE3C,MAAM,UAAU,GAAoB,EAAE,CAAA;IAEtC,iCAAiC;IACjC,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACtB,UAAU,CAAC,IAAI,CACb,GAAG,YAAY,CACb,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EACzF,yBAAyB,EACzB,OAAO,EACP,SAAS,CACV,CACF,CAAA;IACH,CAAC;IAED,uBAAuB;IACvB,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;QAC/B,UAAU,CAAC,IAAI,CACb,GAAG,YAAY,CACb,OAAO,CAAC,CAAC,CAAC;aACP,IAAI,EAAE;aACN,cAAc,CAAC,OAAO,CAAC,YAAY,CAAC;aACpC,MAAM,EAAE;aACR,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,EAC/B,0BAA0B,EAC1B,OAAO,EACP,SAAS,CACV,CACF,CAAA;IACH,CAAC;IAED,OAAO,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;AAC1C,CAAC"}
@@ -0,0 +1,9 @@
1
+ export type { RuleSeverity, PresetBaseOptions } from './shared.js';
2
+ export { dispatchRule, validateOverrides, throwIfViolations } from './shared.js';
3
+ export type { LayeredArchitectureOptions } from './layered.js';
4
+ export { layeredArchitecture } from './layered.js';
5
+ export type { DataLayerIsolationOptions } from './data-layer.js';
6
+ export { dataLayerIsolation } from './data-layer.js';
7
+ export type { StrictBoundariesOptions } from './boundaries.js';
8
+ export { strictBoundaries } from './boundaries.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/presets/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAClE,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEhF,YAAY,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAA;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAElD,YAAY,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAA;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAEpD,YAAY,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA"}
@@ -0,0 +1,5 @@
1
+ export { dispatchRule, validateOverrides, throwIfViolations } from './shared.js';
2
+ export { layeredArchitecture } from './layered.js';
3
+ export { dataLayerIsolation } from './data-layer.js';
4
+ export { strictBoundaries } from './boundaries.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/presets/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAGhF,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAGlD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAGpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA"}
@@ -0,0 +1,21 @@
1
+ import type { ArchProject } from '../core/project.js';
2
+ import type { ArchViolation } from '../core/violation.js';
3
+ import type { PresetBaseOptions } from './shared.js';
4
+ export interface LayeredArchitectureOptions extends PresetBaseOptions {
5
+ /** Layer name → glob pattern mapping. Order = dependency direction (first depends on second, etc.) */
6
+ layers: Record<string, string>;
7
+ /** Glob patterns for shared/utility folders accessible by all layers */
8
+ shared?: string[];
9
+ /** If true, innermost layer only imports from itself + shared */
10
+ strict?: boolean;
11
+ /** Layers where cross-layer type imports are allowed (value imports still forbidden) */
12
+ typeImportsAllowed?: string[];
13
+ /** Package restriction: glob → list of npm package name patterns. Only those layers may import those packages. */
14
+ restrictedPackages?: Record<string, string[]>;
15
+ }
16
+ /**
17
+ * Enforce a layered architecture: dependency direction, cycle freedom,
18
+ * and optional package restrictions.
19
+ */
20
+ export declare function layeredArchitecture(p: ArchProject, options: LayeredArchitectureOptions): ArchViolation[];
21
+ //# sourceMappingURL=layered.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layered.d.ts","sourceRoot":"","sources":["../../src/presets/layered.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAKzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAGpD,MAAM,WAAW,0BAA2B,SAAQ,iBAAiB;IACnE,sGAAsG;IACtG,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,iEAAiE;IACjE,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,wFAAwF;IACxF,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC7B,kHAAkH;IAClH,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;CAC9C;AAiFD;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,CAAC,EAAE,WAAW,EACd,OAAO,EAAE,0BAA0B,GAClC,aAAa,EAAE,CAsEjB"}