@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,105 @@
1
+ /**
2
+ * Every element in the left layer must have at least one match in the right layer.
3
+ *
4
+ * Produces a violation for each left-layer file that has no matching pair.
5
+ * "Match" is determined by the mapping function provided via `.mapping()`.
6
+ *
7
+ * @param layers - The resolved layers, needed to identify unmatched left files
8
+ */
9
+ export function haveMatchingCounterpart(layers) {
10
+ return {
11
+ description: 'have a matching counterpart in the paired layer',
12
+ evaluate(pairs, context) {
13
+ if (layers.length < 2)
14
+ return [];
15
+ const violations = [];
16
+ // Check consecutive layer pairs
17
+ for (let i = 0; i < layers.length - 1; i++) {
18
+ const leftLayer = layers[i];
19
+ const rightLayer = layers[i + 1];
20
+ if (!leftLayer || !rightLayer)
21
+ continue;
22
+ // Collect all left files that appear in at least one pair
23
+ const matchedLeftFiles = new Set();
24
+ for (const pair of pairs) {
25
+ if (pair.leftLayer === leftLayer.name && pair.rightLayer === rightLayer.name) {
26
+ matchedLeftFiles.add(pair.left.getFilePath());
27
+ }
28
+ }
29
+ // Find unmatched left files
30
+ for (const file of leftLayer.files) {
31
+ if (!matchedLeftFiles.has(file.getFilePath())) {
32
+ violations.push({
33
+ rule: context.rule,
34
+ element: file.getBaseName(),
35
+ file: file.getFilePath(),
36
+ line: 1,
37
+ message: `File "${file.getBaseName()}" in layer "${leftLayer.name}" has no matching counterpart in layer "${rightLayer.name}"`,
38
+ because: context.because,
39
+ ruleId: context.ruleId,
40
+ suggestion: context.suggestion,
41
+ docs: context.docs,
42
+ });
43
+ }
44
+ }
45
+ }
46
+ return violations;
47
+ },
48
+ };
49
+ }
50
+ /**
51
+ * The matched pair must have consistent exported symbol names.
52
+ *
53
+ * Takes two extractor functions that pull symbol names from each side.
54
+ * Every symbol extracted from the left file must appear in the right file.
55
+ */
56
+ export function haveConsistentExports(extractLeft, extractRight) {
57
+ return {
58
+ description: 'have consistent exports between paired layers',
59
+ evaluate(pairs, context) {
60
+ const violations = [];
61
+ for (const pair of pairs) {
62
+ const leftSymbols = extractLeft(pair.left);
63
+ const rightSymbols = new Set(extractRight(pair.right));
64
+ for (const symbol of leftSymbols) {
65
+ if (!rightSymbols.has(symbol)) {
66
+ violations.push({
67
+ rule: context.rule,
68
+ element: pair.left.getBaseName(),
69
+ file: pair.left.getFilePath(),
70
+ line: 1,
71
+ message: `Symbol "${symbol}" in "${pair.left.getBaseName()}" (${pair.leftLayer}) has no counterpart in "${pair.right.getBaseName()}" (${pair.rightLayer})`,
72
+ because: context.because,
73
+ ruleId: context.ruleId,
74
+ suggestion: context.suggestion,
75
+ docs: context.docs,
76
+ });
77
+ }
78
+ }
79
+ }
80
+ return violations;
81
+ },
82
+ };
83
+ }
84
+ /**
85
+ * Custom pair assertion — shorthand for inline PairCondition.
86
+ *
87
+ * The provided function is called for each pair. Return an `ArchViolation`
88
+ * to signal failure, or `null` if the pair is consistent.
89
+ */
90
+ export function satisfyPairCondition(description, fn) {
91
+ return {
92
+ description,
93
+ evaluate(pairs, _context) {
94
+ const violations = [];
95
+ for (const pair of pairs) {
96
+ const result = fn(pair);
97
+ if (result !== null) {
98
+ violations.push(result);
99
+ }
100
+ }
101
+ return violations;
102
+ },
103
+ };
104
+ }
105
+ //# sourceMappingURL=cross-layer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cross-layer.js","sourceRoot":"","sources":["../../src/conditions/cross-layer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import type { SourceFile } from 'ts-morph';
2
+ import type { Condition } from '@nielspeter/eess';
3
+ export type { ImportOptions } from '../core/import-options.js';
4
+ import type { ImportOptions } from '../core/import-options.js';
5
+ /**
6
+ * Every import in the module must resolve to a path matching at least one of the globs.
7
+ * Imports that don't match any glob produce violations.
8
+ *
9
+ * @example
10
+ * modules(p)
11
+ * .that().resideInFolder('** /domain/** ')
12
+ * .should().onlyImportFrom('** /domain/** ', '** /shared/** ')
13
+ * .check()
14
+ */
15
+ export declare function onlyImportFrom(globs: string[], options: ImportOptions): Condition<SourceFile>;
16
+ export declare function onlyImportFrom(...globs: string[]): Condition<SourceFile>;
17
+ /**
18
+ * No import in the module may resolve to a path matching any of the globs.
19
+ * Imports that match a glob produce violations.
20
+ *
21
+ * @example
22
+ * modules(p)
23
+ * .that().resideInFolder('** /features/** ')
24
+ * .should().notImportFrom('** /legacy/** ')
25
+ * .check()
26
+ */
27
+ export declare function notImportFrom(globs: string[], options: ImportOptions): Condition<SourceFile>;
28
+ export declare function notImportFrom(...globs: string[]): Condition<SourceFile>;
29
+ /**
30
+ * Module must import from at least one path matching a glob.
31
+ * Completes the import-condition family: onlyImportFrom (all),
32
+ * notImportFrom (none), dependOn (at least one).
33
+ *
34
+ * Only considers static `import` declarations. Dynamic `import()`
35
+ * expressions are not checked — use `beImported()` for import-graph
36
+ * analysis that includes dynamic imports.
37
+ *
38
+ * @example
39
+ * modules(p)
40
+ * .that().resideInFolder('** /services/** ')
41
+ * .should().satisfy(dependOn('** /logging/** '))
42
+ * .check()
43
+ */
44
+ export declare function dependOn(globs: string[], options: ImportOptions): Condition<SourceFile>;
45
+ export declare function dependOn(...globs: string[]): Condition<SourceFile>;
46
+ /**
47
+ * No import in the module may use an aliased named specifier (`import { x as y }`).
48
+ * Each aliased specifier produces a violation.
49
+ * Does not flag namespace imports (`import * as Foo`) — only named specifier aliases.
50
+ *
51
+ * To scope the check to specific import sources, filter with
52
+ * `.that().importFrom(...)` predicates.
53
+ *
54
+ * @example
55
+ * modules(p)
56
+ * .that().resideInFolder('** /src/** ')
57
+ * .should().notHaveAliasedImports()
58
+ * .because('aliases hide API design problems')
59
+ * .check()
60
+ */
61
+ export declare function notHaveAliasedImports(): Condition<SourceFile>;
62
+ /**
63
+ * Imports from paths matching the given globs must use `import type`, not `import`.
64
+ * Non-matching imports are ignored. Matching imports that are not type-only produce violations.
65
+ *
66
+ * @example
67
+ * modules(p)
68
+ * .that().resideInFolder('** /api/** ')
69
+ * .should().onlyHaveTypeImportsFrom('** /domain/entities/** ')
70
+ * .check()
71
+ */
72
+ export declare function onlyHaveTypeImportsFrom(...globs: string[]): Condition<SourceFile>;
73
+ //# sourceMappingURL=dependency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency.d.ts","sourceRoot":"","sources":["../../src/conditions/dependency.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAqB,MAAM,UAAU,CAAA;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAoB,MAAM,kBAAkB,CAAA;AAUnE,YAAY,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AA8B9D;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,aAAa,GAAG,SAAS,CAAC,UAAU,CAAC,CAAA;AAC9F,wBAAgB,cAAc,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC,UAAU,CAAC,CAAA;AAqCzE;;;;;;;;;GASG;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;AAqCxE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,aAAa,GAAG,SAAS,CAAC,UAAU,CAAC,CAAA;AACxF,wBAAgB,QAAQ,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC,UAAU,CAAC,CAAA;AAqCnE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,IAAI,SAAS,CAAC,UAAU,CAAC,CAyB7D;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC,UAAU,CAAC,CAyBjF"}
@@ -0,0 +1,177 @@
1
+ import picomatch from 'picomatch';
2
+ import { isTypeOnlyImport } from '../core/import-options.js';
3
+ import { getDependencyDecls, resolveDependencyPath, isTypeOnlyDependency, } from '../core/module-dependencies.js';
4
+ /**
5
+ * Resolve an import declaration to an absolute path or raw specifier.
6
+ */
7
+ function resolveImportPath(decl) {
8
+ const resolved = decl.getModuleSpecifierSourceFile();
9
+ return resolved ? resolved.getFilePath() : decl.getModuleSpecifierValue();
10
+ }
11
+ /**
12
+ * Create a violation for a source file with a specific offending dependency edge
13
+ * (an `import … from` or an `export … from` re-export).
14
+ */
15
+ function importViolation(sourceFile, importDecl, message, context) {
16
+ return {
17
+ rule: context.rule,
18
+ element: sourceFile.getBaseName(),
19
+ file: sourceFile.getFilePath(),
20
+ line: importDecl.getStartLineNumber(),
21
+ message,
22
+ because: context.because,
23
+ };
24
+ }
25
+ export function onlyImportFrom(...args) {
26
+ // ADR-005: as casts required — TS cannot narrow tuple union rest params after Array.isArray
27
+ // eess-exclude eess/adr005-no-type-assertions: tuple-union rest param — TS cannot narrow [string[], ImportOptions] | string[] to string[] from Array.isArray(args[0])
28
+ const globs = Array.isArray(args[0]) ? args[0] : args;
29
+ // eess-exclude eess/adr005-no-type-assertions: tuple-union rest param — args[1] is ImportOptions only in the [globs, options] overload
30
+ const options = Array.isArray(args[0]) && args.length > 1 ? args[1] : undefined;
31
+ const ignoreType = options?.ignoreTypeImports === true;
32
+ const matchers = globs.map((g) => picomatch(g));
33
+ const quotedGlobs = globs.map((g) => `"${g}"`).join(', ');
34
+ return {
35
+ description: `only import from ${quotedGlobs}`,
36
+ evaluate(sourceFiles, context) {
37
+ const violations = [];
38
+ for (const sf of sourceFiles) {
39
+ for (const decl of getDependencyDecls(sf)) {
40
+ if (ignoreType && isTypeOnlyDependency(decl))
41
+ continue;
42
+ const importPath = resolveDependencyPath(decl);
43
+ if (!matchers.some((m) => m(importPath))) {
44
+ violations.push(importViolation(sf, decl, `${sf.getBaseName()} imports "${importPath}" which does not match any of [${globs.join(', ')}]`, context));
45
+ }
46
+ }
47
+ }
48
+ return violations;
49
+ },
50
+ };
51
+ }
52
+ export function notImportFrom(...args) {
53
+ // ADR-005: as casts required — TS cannot narrow tuple union rest params after Array.isArray
54
+ // eess-exclude eess/adr005-no-type-assertions: tuple-union rest param — TS cannot narrow [string[], ImportOptions] | string[] to string[] from Array.isArray(args[0])
55
+ const globs = Array.isArray(args[0]) ? args[0] : args;
56
+ // eess-exclude eess/adr005-no-type-assertions: tuple-union rest param — args[1] is ImportOptions only in the [globs, options] overload
57
+ const options = Array.isArray(args[0]) && args.length > 1 ? args[1] : undefined;
58
+ const ignoreType = options?.ignoreTypeImports === true;
59
+ const matchers = globs.map((g) => picomatch(g));
60
+ const quotedGlobs = globs.map((g) => `"${g}"`).join(', ');
61
+ return {
62
+ description: `not import from ${quotedGlobs}`,
63
+ evaluate(sourceFiles, context) {
64
+ const violations = [];
65
+ for (const sf of sourceFiles) {
66
+ for (const decl of getDependencyDecls(sf)) {
67
+ if (ignoreType && isTypeOnlyDependency(decl))
68
+ continue;
69
+ const importPath = resolveDependencyPath(decl);
70
+ if (matchers.some((m) => m(importPath))) {
71
+ violations.push(importViolation(sf, decl, `${sf.getBaseName()} imports "${importPath}" which matches forbidden [${globs.join(', ')}]`, context));
72
+ }
73
+ }
74
+ }
75
+ return violations;
76
+ },
77
+ };
78
+ }
79
+ export function dependOn(...args) {
80
+ // ADR-005: as casts required — TS cannot narrow tuple union rest params after Array.isArray
81
+ // eess-exclude eess/adr005-no-type-assertions: tuple-union rest param — TS cannot narrow [string[], ImportOptions] | string[] to string[] from Array.isArray(args[0])
82
+ const globs = Array.isArray(args[0]) ? args[0] : args;
83
+ // eess-exclude eess/adr005-no-type-assertions: tuple-union rest param — args[1] is ImportOptions only in the [globs, options] overload
84
+ const options = Array.isArray(args[0]) && args.length > 1 ? args[1] : undefined;
85
+ const ignoreType = options?.ignoreTypeImports === true;
86
+ const matchers = globs.map((g) => picomatch(g));
87
+ const quotedGlobs = globs.map((g) => `"${g}"`).join(', ');
88
+ return {
89
+ description: globs.length === 1 ? `depend on ${quotedGlobs}` : `depend on at least one of ${quotedGlobs}`,
90
+ evaluate(sourceFiles, context) {
91
+ const violations = [];
92
+ for (const sf of sourceFiles) {
93
+ const hasMatch = getDependencyDecls(sf).some((decl) => {
94
+ if (ignoreType && isTypeOnlyDependency(decl))
95
+ return false;
96
+ const importPath = resolveDependencyPath(decl);
97
+ return matchers.some((m) => m(importPath));
98
+ });
99
+ if (!hasMatch) {
100
+ violations.push({
101
+ rule: context.rule,
102
+ element: sf.getBaseName(),
103
+ file: sf.getFilePath(),
104
+ line: 1,
105
+ message: `${sf.getBaseName()} does not import from any path matching [${globs.join(', ')}]`,
106
+ because: context.because,
107
+ });
108
+ }
109
+ }
110
+ return violations;
111
+ },
112
+ };
113
+ }
114
+ /**
115
+ * No import in the module may use an aliased named specifier (`import { x as y }`).
116
+ * Each aliased specifier produces a violation.
117
+ * Does not flag namespace imports (`import * as Foo`) — only named specifier aliases.
118
+ *
119
+ * To scope the check to specific import sources, filter with
120
+ * `.that().importFrom(...)` predicates.
121
+ *
122
+ * @example
123
+ * modules(p)
124
+ * .that().resideInFolder('** /src/** ')
125
+ * .should().notHaveAliasedImports()
126
+ * .because('aliases hide API design problems')
127
+ * .check()
128
+ */
129
+ export function notHaveAliasedImports() {
130
+ return {
131
+ description: 'not have aliased imports',
132
+ evaluate(sourceFiles, context) {
133
+ const violations = [];
134
+ for (const sf of sourceFiles) {
135
+ for (const decl of sf.getImportDeclarations()) {
136
+ for (const specifier of decl.getNamedImports()) {
137
+ const alias = specifier.getAliasNode();
138
+ if (alias) {
139
+ violations.push(importViolation(sf, decl, `${sf.getBaseName()} aliases "${specifier.getName()}" as "${alias.getText()}"`, context));
140
+ }
141
+ }
142
+ }
143
+ }
144
+ return violations;
145
+ },
146
+ };
147
+ }
148
+ /**
149
+ * Imports from paths matching the given globs must use `import type`, not `import`.
150
+ * Non-matching imports are ignored. Matching imports that are not type-only produce violations.
151
+ *
152
+ * @example
153
+ * modules(p)
154
+ * .that().resideInFolder('** /api/** ')
155
+ * .should().onlyHaveTypeImportsFrom('** /domain/entities/** ')
156
+ * .check()
157
+ */
158
+ export function onlyHaveTypeImportsFrom(...globs) {
159
+ const matchers = globs.map((g) => picomatch(g));
160
+ const quotedGlobs = globs.map((g) => `"${g}"`).join(', ');
161
+ return {
162
+ description: `only have type imports from ${quotedGlobs}`,
163
+ evaluate(sourceFiles, context) {
164
+ const violations = [];
165
+ for (const sf of sourceFiles) {
166
+ for (const decl of sf.getImportDeclarations()) {
167
+ const importPath = resolveImportPath(decl);
168
+ if (matchers.some((m) => m(importPath)) && !isTypeOnlyImport(decl)) {
169
+ violations.push(importViolation(sf, decl, `${sf.getBaseName()} has a value import from "${importPath}" which should be a type-only import`, context));
170
+ }
171
+ }
172
+ }
173
+ return violations;
174
+ },
175
+ };
176
+ }
177
+ //# sourceMappingURL=dependency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency.js","sourceRoot":"","sources":["../../src/conditions/dependency.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import type { SourceFile } from 'ts-morph';
2
+ import type { Condition } from '@nielspeter/eess';
3
+ /**
4
+ * Module must NOT have a default export.
5
+ *
6
+ * @example
7
+ * modules(p).that().resideInFolder('** /src/** ')
8
+ * .should().notHaveDefaultExport()
9
+ * .check()
10
+ */
11
+ export declare function notHaveDefaultExport(): Condition<SourceFile>;
12
+ /**
13
+ * Module must have a default export.
14
+ *
15
+ * @example
16
+ * modules(p).that().resideInFolder('** /pages/** ')
17
+ * .should().haveDefaultExport()
18
+ * .check()
19
+ */
20
+ export declare function haveDefaultExport(): Condition<SourceFile>;
21
+ /**
22
+ * Module must have at most `max` named exports.
23
+ *
24
+ * Counts distinct export names (not declarations — a re-export counts as one).
25
+ * Default exports are not counted.
26
+ *
27
+ * @example
28
+ * modules(p).that().resideInFolder('** /domain/** ')
29
+ * .should().haveMaxExports(1)
30
+ * .check()
31
+ */
32
+ export declare function haveMaxExports(max: number): Condition<SourceFile>;
33
+ //# sourceMappingURL=exports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exports.d.ts","sourceRoot":"","sources":["../../src/conditions/exports.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAC1C,OAAO,KAAK,EAAE,SAAS,EAAoB,MAAM,kBAAkB,CAAA;AAGnE;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,IAAI,SAAS,CAAC,UAAU,CAAC,CAoB5D;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,IAAI,SAAS,CAAC,UAAU,CAAC,CAoBzD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC,UAAU,CAAC,CA6BjE"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Module must NOT have a default export.
3
+ *
4
+ * @example
5
+ * modules(p).that().resideInFolder('** /src/** ')
6
+ * .should().notHaveDefaultExport()
7
+ * .check()
8
+ */
9
+ export function notHaveDefaultExport() {
10
+ return {
11
+ description: 'not have a default export',
12
+ evaluate(elements, context) {
13
+ const violations = [];
14
+ for (const sf of elements) {
15
+ if (sf.getDefaultExportSymbol()) {
16
+ violations.push({
17
+ rule: context.rule,
18
+ element: sf.getBaseName(),
19
+ file: sf.getFilePath(),
20
+ line: 1,
21
+ message: `${sf.getBaseName()} has a default export`,
22
+ because: context.because,
23
+ });
24
+ }
25
+ }
26
+ return violations;
27
+ },
28
+ };
29
+ }
30
+ /**
31
+ * Module must have a default export.
32
+ *
33
+ * @example
34
+ * modules(p).that().resideInFolder('** /pages/** ')
35
+ * .should().haveDefaultExport()
36
+ * .check()
37
+ */
38
+ export function haveDefaultExport() {
39
+ return {
40
+ description: 'have a default export',
41
+ evaluate(elements, context) {
42
+ const violations = [];
43
+ for (const sf of elements) {
44
+ if (!sf.getDefaultExportSymbol()) {
45
+ violations.push({
46
+ rule: context.rule,
47
+ element: sf.getBaseName(),
48
+ file: sf.getFilePath(),
49
+ line: 1,
50
+ message: `${sf.getBaseName()} does not have a default export`,
51
+ because: context.because,
52
+ });
53
+ }
54
+ }
55
+ return violations;
56
+ },
57
+ };
58
+ }
59
+ /**
60
+ * Module must have at most `max` named exports.
61
+ *
62
+ * Counts distinct export names (not declarations — a re-export counts as one).
63
+ * Default exports are not counted.
64
+ *
65
+ * @example
66
+ * modules(p).that().resideInFolder('** /domain/** ')
67
+ * .should().haveMaxExports(1)
68
+ * .check()
69
+ */
70
+ export function haveMaxExports(max) {
71
+ if (!Number.isInteger(max) || max < 0) {
72
+ throw new Error(`haveMaxExports: max must be a non-negative integer, got ${String(max)}`);
73
+ }
74
+ return {
75
+ description: `have at most ${String(max)} export(s)`,
76
+ evaluate(elements, context) {
77
+ const violations = [];
78
+ for (const sf of elements) {
79
+ const exportMap = sf.getExportedDeclarations();
80
+ // Count named exports — exclude 'default' key
81
+ let count = 0;
82
+ for (const key of exportMap.keys()) {
83
+ if (key !== 'default')
84
+ count++;
85
+ }
86
+ if (count > max) {
87
+ violations.push({
88
+ rule: context.rule,
89
+ element: sf.getBaseName(),
90
+ file: sf.getFilePath(),
91
+ line: 1,
92
+ message: `${sf.getBaseName()} has ${String(count)} named export(s), exceeding the limit of ${String(max)}`,
93
+ because: context.because,
94
+ });
95
+ }
96
+ }
97
+ return violations;
98
+ },
99
+ };
100
+ }
101
+ //# sourceMappingURL=exports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exports.js","sourceRoot":"","sources":["../../src/conditions/exports.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ import type { Condition } from '@nielspeter/eess';
2
+ import type { ArchFunction } from '../models/arch-function.js';
3
+ import type { TypeMatcher } from '../helpers/type-matchers.js';
4
+ /**
5
+ * The predicate set must be empty — no functions should match.
6
+ *
7
+ * If ANY functions exist after predicate filtering, each one
8
+ * becomes a violation.
9
+ *
10
+ * @example
11
+ * functions(project)
12
+ * .that().haveNameMatching(/^parse\w+Order$/)
13
+ * .should(notExist())
14
+ * .because('use shared parseOrder() utility instead')
15
+ */
16
+ export declare function notExist(): Condition<ArchFunction>;
17
+ /**
18
+ * Functions must be exported from their module.
19
+ */
20
+ export declare function beExported(): Condition<ArchFunction>;
21
+ /**
22
+ * Functions must be async.
23
+ */
24
+ export declare function beAsync(): Condition<ArchFunction>;
25
+ /**
26
+ * Functions must have a name matching the given pattern.
27
+ */
28
+ export declare function haveNameMatching(pattern: RegExp): Condition<ArchFunction>;
29
+ /**
30
+ * Assert that at least one parameter of the function has a type matching
31
+ * the given matcher.
32
+ *
33
+ * Passes when at least one parameter satisfies `matcher`.
34
+ * Reports one violation per function that has no matching parameter.
35
+ *
36
+ * **Scope note:** This operates on the function's own parameter list only.
37
+ * Unlike the class-level counterpart, it does NOT scan set accessors
38
+ * because `collectFunctions()` excludes them.
39
+ */
40
+ export declare function acceptParameterOfType(matcher: TypeMatcher): Condition<ArchFunction>;
41
+ /**
42
+ * Assert that NO parameter of the function has a type matching the given
43
+ * matcher.
44
+ *
45
+ * Reports one violation **per parameter** whose type satisfies `matcher`,
46
+ * with actionable messages including the parameter name and type.
47
+ *
48
+ * **Scope note:** This operates on the function's own parameter list only.
49
+ * Unlike the class-level counterpart, it does NOT scan set accessors
50
+ * because `collectFunctions()` excludes them.
51
+ */
52
+ export declare function notAcceptParameterOfType(matcher: TypeMatcher): Condition<ArchFunction>;
53
+ /**
54
+ * Functions must have a return type that satisfies the given TypeMatcher.
55
+ *
56
+ * Unlike the `haveReturnType` predicate (which filters with RegExp),
57
+ * this is a condition (assertion in `.should()`) that uses TypeMatcher
58
+ * for composability with `isString()`, `matching()`, `not()`, `exactly()`, etc.
59
+ *
60
+ * @example
61
+ * functions(project)
62
+ * .that().haveNameMatching(/^list/)
63
+ * .should().haveReturnTypeMatching(matching(/Collection/))
64
+ * .check()
65
+ */
66
+ export declare function haveReturnTypeMatching(matcher: TypeMatcher): Condition<ArchFunction>;
67
+ /**
68
+ * Functions must reside in a file matching the glob.
69
+ * ArchFunction is not a ts-morph Node, so the generic structural condition
70
+ * cannot be used — this is the ArchFunction-specific equivalent.
71
+ */
72
+ export declare function resideInFile(glob: string): Condition<ArchFunction>;
73
+ /**
74
+ * Functions must reside in a folder matching the glob.
75
+ * ArchFunction is not a ts-morph Node, so the generic structural condition
76
+ * cannot be used — this is the ArchFunction-specific equivalent.
77
+ */
78
+ export declare function resideInFolder(glob: string): Condition<ArchFunction>;
79
+ //# sourceMappingURL=function.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"function.d.ts","sourceRoot":"","sources":["../../src/conditions/function.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAoB,MAAM,kBAAkB,CAAA;AAEnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAA;AA+B9D;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,IAAI,SAAS,CAAC,YAAY,CAAC,CAclD;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,SAAS,CAAC,YAAY,CAAC,CAMpD;AAED;;GAEG;AACH,wBAAgB,OAAO,IAAI,SAAS,CAAC,YAAY,CAAC,CAMjD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC,YAAY,CAAC,CASzE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,GAAG,SAAS,CAAC,YAAY,CAAC,CAMnF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,WAAW,GAAG,SAAS,CAAC,YAAY,CAAC,CAyBtF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,WAAW,GAAG,SAAS,CAAC,YAAY,CAAC,CAOpF;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC,YAAY,CAAC,CAQlE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC,YAAY,CAAC,CAepE"}