intershell 0.3.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 (357) hide show
  1. package/README.md +301 -0
  2. package/dist/commands/ci/act.d.ts +13 -0
  3. package/dist/commands/ci/act.d.ts.map +1 -0
  4. package/dist/commands/ci/act.js +89 -0
  5. package/dist/commands/ci/act.js.map +1 -0
  6. package/dist/commands/ci/attach-affected.d.ts +12 -0
  7. package/dist/commands/ci/attach-affected.d.ts.map +1 -0
  8. package/dist/commands/ci/attach-affected.js +83 -0
  9. package/dist/commands/ci/attach-affected.js.map +1 -0
  10. package/dist/commands/ci/attach-service-ports.d.ts +10 -0
  11. package/dist/commands/ci/attach-service-ports.d.ts.map +1 -0
  12. package/dist/commands/ci/attach-service-ports.js +25 -0
  13. package/dist/commands/ci/attach-service-ports.js.map +1 -0
  14. package/dist/commands/commit-check.d.ts +13 -0
  15. package/dist/commands/commit-check.d.ts.map +1 -0
  16. package/dist/commands/commit-check.js +110 -0
  17. package/dist/commands/commit-check.js.map +1 -0
  18. package/dist/commands/commit.d.ts +16 -0
  19. package/dist/commands/commit.d.ts.map +1 -0
  20. package/dist/commands/commit.js +91 -0
  21. package/dist/commands/commit.js.map +1 -0
  22. package/dist/commands/dev/check.d.ts +13 -0
  23. package/dist/commands/dev/check.d.ts.map +1 -0
  24. package/dist/commands/dev/check.js +91 -0
  25. package/dist/commands/dev/check.js.map +1 -0
  26. package/dist/commands/dev/cleanup.d.ts +10 -0
  27. package/dist/commands/dev/cleanup.d.ts.map +1 -0
  28. package/dist/commands/dev/cleanup.js +28 -0
  29. package/dist/commands/dev/cleanup.js.map +1 -0
  30. package/dist/commands/dev/rm.d.ts +12 -0
  31. package/dist/commands/dev/rm.d.ts.map +1 -0
  32. package/dist/commands/dev/rm.js +49 -0
  33. package/dist/commands/dev/rm.js.map +1 -0
  34. package/dist/commands/dev/setup.d.ts +10 -0
  35. package/dist/commands/dev/setup.d.ts.map +1 -0
  36. package/dist/commands/dev/setup.js +40 -0
  37. package/dist/commands/dev/setup.js.map +1 -0
  38. package/dist/commands/local/cleanup.d.ts +12 -0
  39. package/dist/commands/local/cleanup.d.ts.map +1 -0
  40. package/dist/commands/local/cleanup.js +62 -0
  41. package/dist/commands/local/cleanup.js.map +1 -0
  42. package/dist/commands/local/setup.d.ts +11 -0
  43. package/dist/commands/local/setup.d.ts.map +1 -0
  44. package/dist/commands/local/setup.js +55 -0
  45. package/dist/commands/local/setup.js.map +1 -0
  46. package/dist/commands/local/vscode.d.ts +17 -0
  47. package/dist/commands/local/vscode.d.ts.map +1 -0
  48. package/dist/commands/local/vscode.js +94 -0
  49. package/dist/commands/local/vscode.js.map +1 -0
  50. package/dist/commands/update-package-json.d.ts +12 -0
  51. package/dist/commands/update-package-json.d.ts.map +1 -0
  52. package/dist/commands/update-package-json.js +82 -0
  53. package/dist/commands/update-package-json.js.map +1 -0
  54. package/dist/commands/version/apply.d.ts +16 -0
  55. package/dist/commands/version/apply.d.ts.map +1 -0
  56. package/dist/commands/version/apply.js +120 -0
  57. package/dist/commands/version/apply.js.map +1 -0
  58. package/dist/commands/version/ci.d.ts +12 -0
  59. package/dist/commands/version/ci.d.ts.map +1 -0
  60. package/dist/commands/version/ci.js +67 -0
  61. package/dist/commands/version/ci.js.map +1 -0
  62. package/dist/commands/version/prepare.d.ts +19 -0
  63. package/dist/commands/version/prepare.d.ts.map +1 -0
  64. package/dist/commands/version/prepare.js +153 -0
  65. package/dist/commands/version/prepare.js.map +1 -0
  66. package/dist/core/colorify.d.ts +21 -0
  67. package/dist/core/colorify.d.ts.map +1 -0
  68. package/dist/core/colorify.js +56 -0
  69. package/dist/core/colorify.js.map +1 -0
  70. package/dist/core/index.d.ts +4 -0
  71. package/dist/core/index.d.ts.map +1 -0
  72. package/dist/core/index.js +3 -0
  73. package/dist/core/index.js.map +1 -0
  74. package/dist/core/types.d.ts +181 -0
  75. package/dist/core/types.d.ts.map +1 -0
  76. package/dist/core/types.js +5 -0
  77. package/dist/core/types.js.map +1 -0
  78. package/dist/core/wrapshell.d.ts +19 -0
  79. package/dist/core/wrapshell.d.ts.map +1 -0
  80. package/dist/core/wrapshell.js +323 -0
  81. package/dist/core/wrapshell.js.map +1 -0
  82. package/dist/entities/affected/affected.d.ts +4 -0
  83. package/dist/entities/affected/affected.d.ts.map +1 -0
  84. package/dist/entities/affected/affected.js +20 -0
  85. package/dist/entities/affected/affected.js.map +1 -0
  86. package/dist/entities/affected/affected.test.d.ts +2 -0
  87. package/dist/entities/affected/affected.test.d.ts.map +1 -0
  88. package/dist/entities/affected/affected.test.js +305 -0
  89. package/dist/entities/affected/affected.test.js.map +1 -0
  90. package/dist/entities/affected/index.d.ts +2 -0
  91. package/dist/entities/affected/index.d.ts.map +1 -0
  92. package/dist/entities/affected/index.js +2 -0
  93. package/dist/entities/affected/index.js.map +1 -0
  94. package/dist/entities/branch/branch.d.ts +8 -0
  95. package/dist/entities/branch/branch.d.ts.map +1 -0
  96. package/dist/entities/branch/branch.js +74 -0
  97. package/dist/entities/branch/branch.js.map +1 -0
  98. package/dist/entities/branch/branch.test.d.ts +2 -0
  99. package/dist/entities/branch/branch.test.d.ts.map +1 -0
  100. package/dist/entities/branch/branch.test.js +316 -0
  101. package/dist/entities/branch/branch.test.js.map +1 -0
  102. package/dist/entities/branch/branch.types.d.ts +6 -0
  103. package/dist/entities/branch/branch.types.d.ts.map +1 -0
  104. package/dist/entities/branch/branch.types.js +2 -0
  105. package/dist/entities/branch/branch.types.js.map +1 -0
  106. package/dist/entities/branch/index.d.ts +3 -0
  107. package/dist/entities/branch/index.d.ts.map +1 -0
  108. package/dist/entities/branch/index.js +3 -0
  109. package/dist/entities/branch/index.js.map +1 -0
  110. package/dist/entities/commit/commit.d.ts +15 -0
  111. package/dist/entities/commit/commit.d.ts.map +1 -0
  112. package/dist/entities/commit/commit.js +196 -0
  113. package/dist/entities/commit/commit.js.map +1 -0
  114. package/dist/entities/commit/commit.test.d.ts +26 -0
  115. package/dist/entities/commit/commit.test.d.ts.map +1 -0
  116. package/dist/entities/commit/commit.test.js +550 -0
  117. package/dist/entities/commit/commit.test.js.map +1 -0
  118. package/dist/entities/commit/commit.types.d.ts +49 -0
  119. package/dist/entities/commit/commit.types.d.ts.map +1 -0
  120. package/dist/entities/commit/commit.types.js +31 -0
  121. package/dist/entities/commit/commit.types.js.map +1 -0
  122. package/dist/entities/commit/index.d.ts +3 -0
  123. package/dist/entities/commit/index.d.ts.map +1 -0
  124. package/dist/entities/commit/index.js +3 -0
  125. package/dist/entities/commit/index.js.map +1 -0
  126. package/dist/entities/commit/pr.d.ts +11 -0
  127. package/dist/entities/commit/pr.d.ts.map +1 -0
  128. package/dist/entities/commit/pr.js +201 -0
  129. package/dist/entities/commit/pr.js.map +1 -0
  130. package/dist/entities/commit/pr.test.d.ts +2 -0
  131. package/dist/entities/commit/pr.test.d.ts.map +1 -0
  132. package/dist/entities/commit/pr.test.js +782 -0
  133. package/dist/entities/commit/pr.test.js.map +1 -0
  134. package/dist/entities/compose/compose.d.ts +18 -0
  135. package/dist/entities/compose/compose.d.ts.map +1 -0
  136. package/dist/entities/compose/compose.js +197 -0
  137. package/dist/entities/compose/compose.js.map +1 -0
  138. package/dist/entities/compose/compose.test.d.ts +2 -0
  139. package/dist/entities/compose/compose.test.d.ts.map +1 -0
  140. package/dist/entities/compose/compose.test.js +406 -0
  141. package/dist/entities/compose/compose.test.js.map +1 -0
  142. package/dist/entities/compose/compose.types.d.ts +77 -0
  143. package/dist/entities/compose/compose.types.d.ts.map +1 -0
  144. package/dist/entities/compose/compose.types.js +2 -0
  145. package/dist/entities/compose/compose.types.js.map +1 -0
  146. package/dist/entities/compose/index.d.ts +3 -0
  147. package/dist/entities/compose/index.d.ts.map +1 -0
  148. package/dist/entities/compose/index.js +3 -0
  149. package/dist/entities/compose/index.js.map +1 -0
  150. package/dist/entities/entities.shell.d.ts +29 -0
  151. package/dist/entities/entities.shell.d.ts.map +1 -0
  152. package/dist/entities/entities.shell.js +27 -0
  153. package/dist/entities/entities.shell.js.map +1 -0
  154. package/dist/entities/entities.shell.test.d.ts +2 -0
  155. package/dist/entities/entities.shell.test.d.ts.map +1 -0
  156. package/dist/entities/entities.shell.test.js +23 -0
  157. package/dist/entities/entities.shell.test.js.map +1 -0
  158. package/dist/entities/index.d.ts +12 -0
  159. package/dist/entities/index.d.ts.map +1 -0
  160. package/dist/entities/index.js +12 -0
  161. package/dist/entities/index.js.map +1 -0
  162. package/dist/entities/intershell-config/intershell-config.d.ts +11 -0
  163. package/dist/entities/intershell-config/intershell-config.d.ts.map +1 -0
  164. package/dist/entities/intershell-config/intershell-config.default.d.ts +188 -0
  165. package/dist/entities/intershell-config/intershell-config.default.d.ts.map +1 -0
  166. package/dist/entities/intershell-config/intershell-config.default.js +225 -0
  167. package/dist/entities/intershell-config/intershell-config.default.js.map +1 -0
  168. package/dist/entities/intershell-config/intershell-config.js +132 -0
  169. package/dist/entities/intershell-config/intershell-config.js.map +1 -0
  170. package/dist/entities/intershell-config/intershell-config.test.d.ts +2 -0
  171. package/dist/entities/intershell-config/intershell-config.test.d.ts.map +1 -0
  172. package/dist/entities/intershell-config/intershell-config.test.js +102 -0
  173. package/dist/entities/intershell-config/intershell-config.test.js.map +1 -0
  174. package/dist/entities/intershell-config/intershell-config.types.d.ts +103 -0
  175. package/dist/entities/intershell-config/intershell-config.types.d.ts.map +1 -0
  176. package/dist/entities/intershell-config/intershell-config.types.js +2 -0
  177. package/dist/entities/intershell-config/intershell-config.types.js.map +1 -0
  178. package/dist/entities/package/index.d.ts +4 -0
  179. package/dist/entities/package/index.d.ts.map +1 -0
  180. package/dist/entities/package/index.js +4 -0
  181. package/dist/entities/package/index.js.map +1 -0
  182. package/dist/entities/package/package.d.ts +49 -0
  183. package/dist/entities/package/package.d.ts.map +1 -0
  184. package/dist/entities/package/package.js +234 -0
  185. package/dist/entities/package/package.js.map +1 -0
  186. package/dist/entities/package/package.shell.d.ts +48 -0
  187. package/dist/entities/package/package.shell.d.ts.map +1 -0
  188. package/dist/entities/package/package.shell.js +118 -0
  189. package/dist/entities/package/package.shell.js.map +1 -0
  190. package/dist/entities/package/package.test.d.ts +23 -0
  191. package/dist/entities/package/package.test.d.ts.map +1 -0
  192. package/dist/entities/package/package.test.js +637 -0
  193. package/dist/entities/package/package.test.js.map +1 -0
  194. package/dist/entities/package/package.types.d.ts +48 -0
  195. package/dist/entities/package/package.types.d.ts.map +1 -0
  196. package/dist/entities/package/package.types.js +2 -0
  197. package/dist/entities/package/package.types.js.map +1 -0
  198. package/dist/entities/package-changelog/index.d.ts +4 -0
  199. package/dist/entities/package-changelog/index.d.ts.map +1 -0
  200. package/dist/entities/package-changelog/index.js +4 -0
  201. package/dist/entities/package-changelog/index.js.map +1 -0
  202. package/dist/entities/package-changelog/package-changelog.d.ts +20 -0
  203. package/dist/entities/package-changelog/package-changelog.d.ts.map +1 -0
  204. package/dist/entities/package-changelog/package-changelog.js +59 -0
  205. package/dist/entities/package-changelog/package-changelog.js.map +1 -0
  206. package/dist/entities/package-changelog/package-changelog.types.d.ts +25 -0
  207. package/dist/entities/package-changelog/package-changelog.types.d.ts.map +1 -0
  208. package/dist/entities/package-changelog/package-changelog.types.js +2 -0
  209. package/dist/entities/package-changelog/package-changelog.types.js.map +1 -0
  210. package/dist/entities/package-changelog/template.d.ts +20 -0
  211. package/dist/entities/package-changelog/template.d.ts.map +1 -0
  212. package/dist/entities/package-changelog/template.default.d.ts +10 -0
  213. package/dist/entities/package-changelog/template.default.d.ts.map +1 -0
  214. package/dist/entities/package-changelog/template.default.js +85 -0
  215. package/dist/entities/package-changelog/template.default.js.map +1 -0
  216. package/dist/entities/package-changelog/template.js +90 -0
  217. package/dist/entities/package-changelog/template.js.map +1 -0
  218. package/dist/entities/package-commits/dependency-analyzer.d.ts +35 -0
  219. package/dist/entities/package-commits/dependency-analyzer.d.ts.map +1 -0
  220. package/dist/entities/package-commits/dependency-analyzer.js +169 -0
  221. package/dist/entities/package-commits/dependency-analyzer.js.map +1 -0
  222. package/dist/entities/package-commits/dependency-analyzer.test.d.ts +2 -0
  223. package/dist/entities/package-commits/dependency-analyzer.test.d.ts.map +1 -0
  224. package/dist/entities/package-commits/dependency-analyzer.test.js +25 -0
  225. package/dist/entities/package-commits/dependency-analyzer.test.js.map +1 -0
  226. package/dist/entities/package-commits/index.d.ts +3 -0
  227. package/dist/entities/package-commits/index.d.ts.map +1 -0
  228. package/dist/entities/package-commits/index.js +3 -0
  229. package/dist/entities/package-commits/index.js.map +1 -0
  230. package/dist/entities/package-commits/package-commits.d.ts +33 -0
  231. package/dist/entities/package-commits/package-commits.d.ts.map +1 -0
  232. package/dist/entities/package-commits/package-commits.js +149 -0
  233. package/dist/entities/package-commits/package-commits.js.map +1 -0
  234. package/dist/entities/package-commits/package-commits.test.d.ts +2 -0
  235. package/dist/entities/package-commits/package-commits.test.d.ts.map +1 -0
  236. package/dist/entities/package-commits/package-commits.test.js +40 -0
  237. package/dist/entities/package-commits/package-commits.test.js.map +1 -0
  238. package/dist/entities/package-tags/index.d.ts +2 -0
  239. package/dist/entities/package-tags/index.d.ts.map +1 -0
  240. package/dist/entities/package-tags/index.js +2 -0
  241. package/dist/entities/package-tags/index.js.map +1 -0
  242. package/dist/entities/package-tags/package-tags.d.ts +24 -0
  243. package/dist/entities/package-tags/package-tags.d.ts.map +1 -0
  244. package/dist/entities/package-tags/package-tags.js +197 -0
  245. package/dist/entities/package-tags/package-tags.js.map +1 -0
  246. package/dist/entities/package-tags/package-tags.test.d.ts +2 -0
  247. package/dist/entities/package-tags/package-tags.test.d.ts.map +1 -0
  248. package/dist/entities/package-tags/package-tags.test.js +60 -0
  249. package/dist/entities/package-tags/package-tags.test.js.map +1 -0
  250. package/dist/entities/package-version/index.d.ts +3 -0
  251. package/dist/entities/package-version/index.d.ts.map +1 -0
  252. package/dist/entities/package-version/index.js +3 -0
  253. package/dist/entities/package-version/index.js.map +1 -0
  254. package/dist/entities/package-version/package-version.d.ts +16 -0
  255. package/dist/entities/package-version/package-version.d.ts.map +1 -0
  256. package/dist/entities/package-version/package-version.js +166 -0
  257. package/dist/entities/package-version/package-version.js.map +1 -0
  258. package/dist/entities/package-version/package-version.test.d.ts +2 -0
  259. package/dist/entities/package-version/package-version.test.d.ts.map +1 -0
  260. package/dist/entities/package-version/package-version.test.js +113 -0
  261. package/dist/entities/package-version/package-version.test.js.map +1 -0
  262. package/dist/entities/package-version/package-version.types.d.ts +31 -0
  263. package/dist/entities/package-version/package-version.types.d.ts.map +1 -0
  264. package/dist/entities/package-version/package-version.types.js +2 -0
  265. package/dist/entities/package-version/package-version.types.js.map +1 -0
  266. package/dist/entities/tag/index.d.ts +3 -0
  267. package/dist/entities/tag/index.d.ts.map +1 -0
  268. package/dist/entities/tag/index.js +3 -0
  269. package/dist/entities/tag/index.js.map +1 -0
  270. package/dist/entities/tag/tag.d.ts +24 -0
  271. package/dist/entities/tag/tag.d.ts.map +1 -0
  272. package/dist/entities/tag/tag.js +168 -0
  273. package/dist/entities/tag/tag.js.map +1 -0
  274. package/dist/entities/tag/tag.test.d.ts +2 -0
  275. package/dist/entities/tag/tag.test.d.ts.map +1 -0
  276. package/dist/entities/tag/tag.test.js +638 -0
  277. package/dist/entities/tag/tag.test.js.map +1 -0
  278. package/dist/entities/tag/tag.types.d.ts +35 -0
  279. package/dist/entities/tag/tag.types.d.ts.map +1 -0
  280. package/dist/entities/tag/tag.types.js +2 -0
  281. package/dist/entities/tag/tag.types.js.map +1 -0
  282. package/dist/index.d.ts +3 -0
  283. package/dist/index.d.ts.map +1 -0
  284. package/dist/index.js +6 -0
  285. package/dist/index.js.map +1 -0
  286. package/package.json +73 -0
  287. package/src/commands/ci/act.ts +95 -0
  288. package/src/commands/ci/attach-affected.ts +93 -0
  289. package/src/commands/ci/attach-service-ports.ts +31 -0
  290. package/src/commands/commit-check.ts +124 -0
  291. package/src/commands/commit.ts +103 -0
  292. package/src/commands/dev/check.ts +117 -0
  293. package/src/commands/dev/cleanup.ts +34 -0
  294. package/src/commands/dev/rm.ts +66 -0
  295. package/src/commands/dev/setup.ts +48 -0
  296. package/src/commands/local/cleanup.ts +74 -0
  297. package/src/commands/local/setup.ts +68 -0
  298. package/src/commands/local/vscode.ts +118 -0
  299. package/src/commands/update-package-json.ts +104 -0
  300. package/src/commands/version/apply.ts +156 -0
  301. package/src/commands/version/ci.ts +85 -0
  302. package/src/commands/version/prepare.ts +217 -0
  303. package/src/core/colorify.ts +61 -0
  304. package/src/core/index.ts +3 -0
  305. package/src/core/types.ts +262 -0
  306. package/src/core/wrapshell.ts +388 -0
  307. package/src/entities/affected/affected.test.ts +427 -0
  308. package/src/entities/affected/affected.ts +22 -0
  309. package/src/entities/affected/index.ts +1 -0
  310. package/src/entities/branch/branch.test.ts +348 -0
  311. package/src/entities/branch/branch.ts +89 -0
  312. package/src/entities/branch/branch.types.ts +5 -0
  313. package/src/entities/branch/index.ts +2 -0
  314. package/src/entities/commit/commit.test.ts +769 -0
  315. package/src/entities/commit/commit.ts +245 -0
  316. package/src/entities/commit/commit.types.ts +81 -0
  317. package/src/entities/commit/index.ts +2 -0
  318. package/src/entities/commit/pr.test.ts +860 -0
  319. package/src/entities/commit/pr.ts +241 -0
  320. package/src/entities/compose/compose.test.ts +496 -0
  321. package/src/entities/compose/compose.ts +251 -0
  322. package/src/entities/compose/compose.types.ts +88 -0
  323. package/src/entities/compose/index.ts +2 -0
  324. package/src/entities/entities.shell.test.ts +35 -0
  325. package/src/entities/entities.shell.ts +81 -0
  326. package/src/entities/index.ts +11 -0
  327. package/src/entities/intershell-config/intershell-config.default.ts +229 -0
  328. package/src/entities/intershell-config/intershell-config.test.ts +117 -0
  329. package/src/entities/intershell-config/intershell-config.ts +143 -0
  330. package/src/entities/intershell-config/intershell-config.types.ts +118 -0
  331. package/src/entities/package/index.ts +3 -0
  332. package/src/entities/package/package.shell.ts +124 -0
  333. package/src/entities/package/package.test.ts +830 -0
  334. package/src/entities/package/package.ts +267 -0
  335. package/src/entities/package/package.types.ts +49 -0
  336. package/src/entities/package-changelog/index.ts +3 -0
  337. package/src/entities/package-changelog/package-changelog.ts +81 -0
  338. package/src/entities/package-changelog/package-changelog.types.ts +30 -0
  339. package/src/entities/package-changelog/template.default.ts +109 -0
  340. package/src/entities/package-changelog/template.ts +118 -0
  341. package/src/entities/package-commits/dependency-analyzer.test.ts +29 -0
  342. package/src/entities/package-commits/dependency-analyzer.ts +194 -0
  343. package/src/entities/package-commits/index.ts +2 -0
  344. package/src/entities/package-commits/package-commits.test.ts +44 -0
  345. package/src/entities/package-commits/package-commits.ts +191 -0
  346. package/src/entities/package-tags/index.ts +1 -0
  347. package/src/entities/package-tags/package-tags.test.ts +73 -0
  348. package/src/entities/package-tags/package-tags.ts +234 -0
  349. package/src/entities/package-version/index.ts +2 -0
  350. package/src/entities/package-version/package-version.test.ts +141 -0
  351. package/src/entities/package-version/package-version.ts +234 -0
  352. package/src/entities/package-version/package-version.types.ts +35 -0
  353. package/src/entities/tag/index.ts +2 -0
  354. package/src/entities/tag/tag.test.ts +844 -0
  355. package/src/entities/tag/tag.ts +208 -0
  356. package/src/entities/tag/tag.types.ts +37 -0
  357. package/src/index.ts +7 -0
@@ -0,0 +1,830 @@
1
+ /** biome-ignore-all lint/suspicious/noExplicitAny: Mock types require any for flexibility */
2
+ import { afterEach, beforeEach, describe, expect, it, type Mock, mock } from "bun:test";
3
+ import type { $ } from "bun";
4
+ import { EntityPackage } from "./package";
5
+ import type { PackageJson } from "./package.types";
6
+
7
+ export type EntityPackageMock = Mock<
8
+ () => Partial<{
9
+ getPath: ReturnType<typeof mock>;
10
+ getJsonPath: ReturnType<typeof mock>;
11
+ readJson: ReturnType<typeof mock>;
12
+ writeJson: ReturnType<typeof mock>;
13
+ readVersion: ReturnType<typeof mock>;
14
+ writeVersion: ReturnType<typeof mock>;
15
+ getChangelogPath: ReturnType<typeof mock>;
16
+ readChangelog: ReturnType<typeof mock>;
17
+ writeChangelog: ReturnType<typeof mock>;
18
+ validatePackage: ReturnType<typeof mock>;
19
+ shouldVersion: ReturnType<typeof mock>;
20
+ getTagSeriesName: ReturnType<typeof mock>;
21
+ getRepoUrl: ReturnType<typeof mock>;
22
+ getAllPackages: ReturnType<typeof mock>;
23
+ getVersionedPackages: ReturnType<typeof mock>;
24
+ getUnversionedPackages: ReturnType<typeof mock>;
25
+ validateAllPackages: ReturnType<typeof mock>;
26
+ }>
27
+ >;
28
+
29
+ export function mockEntityPackage(EntityPackage: EntityPackageMock) {
30
+ // Return the mock object directly instead of using mock.module
31
+ return EntityPackage;
32
+ }
33
+
34
+ describe("EntityPackage", () => {
35
+ let packages: InstanceType<typeof EntityPackage>;
36
+ const mockPackageName = "test-package";
37
+
38
+ const mockPackageJson = (overrides: Partial<PackageJson> = {}): PackageJson => ({
39
+ name: "test-package",
40
+ version: "1.0.0",
41
+ description: "Test package",
42
+ ...overrides,
43
+ });
44
+
45
+ let mockPackagesShell: {
46
+ readJsonFile: ReturnType<typeof mock>;
47
+ writeJsonFile: ReturnType<typeof mock>;
48
+ readChangelogFile: ReturnType<typeof mock>;
49
+ writeChangelogFile: ReturnType<typeof mock>;
50
+ runBiomeCheck: ReturnType<typeof mock>;
51
+ fileExists: ReturnType<typeof mock>;
52
+ readDirectory: ReturnType<typeof mock>;
53
+ canAccessFile: ReturnType<typeof mock>;
54
+ readFileAsText: ReturnType<typeof mock>;
55
+ getWorkspaceRoot: ReturnType<typeof mock>;
56
+ };
57
+
58
+ let mockEntitiesShell: {
59
+ runBiomeCheck: ReturnType<typeof mock>;
60
+ };
61
+
62
+ // Store original methods to restore after tests
63
+ let originalPackagesShellReadJsonFile: (filePath: string) => PackageJson;
64
+ let originalPackagesShellWriteJsonFile: (filePath: string, data: PackageJson) => Promise<void>;
65
+ let originalPackagesShellReadChangelogFile: (filePath: string) => string;
66
+ let originalPackagesShellWriteChangelogFile: (filePath: string, content: string) => Promise<void>;
67
+ let originalPackagesShellFileExists: (filePath: string) => Promise<boolean>;
68
+ let originalPackagesShellReadDirectory: (dirPath: string) => Promise<string[]>;
69
+ let originalPackagesShellCanAccessFile: (filePath: string) => Promise<boolean>;
70
+ let originalPackagesShellReadFileAsText: (filePath: string) => Promise<string>;
71
+ let originalPackagesShellGetWorkspaceRoot: () => Promise<string>;
72
+ let originalEntitiesShellRunBiomeCheck: (filePath: string) => $.ShellPromise;
73
+
74
+ beforeEach(async () => {
75
+ // Import fresh modules to avoid interference
76
+ const { packagesShell } = await import("./package.shell");
77
+ const { entitiesShell } = await import("../entities.shell");
78
+
79
+ // Store original methods if not already stored
80
+ if (!originalPackagesShellReadJsonFile) {
81
+ originalPackagesShellReadJsonFile = packagesShell.readJsonFile;
82
+ }
83
+ if (!originalPackagesShellWriteJsonFile) {
84
+ originalPackagesShellWriteJsonFile = packagesShell.writeJsonFile;
85
+ }
86
+ if (!originalPackagesShellReadChangelogFile) {
87
+ originalPackagesShellReadChangelogFile = packagesShell.readChangelogFile;
88
+ }
89
+ if (!originalPackagesShellWriteChangelogFile) {
90
+ originalPackagesShellWriteChangelogFile = packagesShell.writeChangelogFile;
91
+ }
92
+ if (!originalPackagesShellFileExists) {
93
+ originalPackagesShellFileExists = packagesShell.fileExists;
94
+ }
95
+ if (!originalPackagesShellReadDirectory) {
96
+ originalPackagesShellReadDirectory = packagesShell.readDirectory;
97
+ }
98
+ if (!originalPackagesShellCanAccessFile) {
99
+ originalPackagesShellCanAccessFile = packagesShell.canAccessFile;
100
+ }
101
+ if (!originalPackagesShellReadFileAsText) {
102
+ originalPackagesShellReadFileAsText = packagesShell.readFileAsText;
103
+ }
104
+ if (!originalPackagesShellGetWorkspaceRoot) {
105
+ originalPackagesShellGetWorkspaceRoot = packagesShell.getWorkspaceRoot;
106
+ }
107
+ if (!originalEntitiesShellRunBiomeCheck) {
108
+ originalEntitiesShellRunBiomeCheck = entitiesShell.runBiomeCheck;
109
+ }
110
+
111
+ // Clear any existing mock state
112
+ mock.clearAllMocks();
113
+
114
+ // Mock packagesShell
115
+ mockPackagesShell = {
116
+ readJsonFile: mock((path: string) => {
117
+ if (path.includes("package.json")) {
118
+ return mockPackageJson();
119
+ }
120
+ throw new Error(`File not found: ${path}`);
121
+ }),
122
+ writeJsonFile: mock(() => Promise.resolve()),
123
+ readChangelogFile: mock((path: string) => {
124
+ if (path.includes("CHANGELOG.md")) {
125
+ return "# Test Changelog\n\n## 1.0.0\n- Initial release";
126
+ }
127
+ return "";
128
+ }),
129
+ writeChangelogFile: mock(() => Promise.resolve()),
130
+ runBiomeCheck: mock(() => Promise.resolve()),
131
+ fileExists: mock(() => Promise.resolve(true)),
132
+ readDirectory: mock(() => Promise.resolve([])),
133
+ canAccessFile: mock(() => Promise.resolve(true)),
134
+ readFileAsText: mock((path: string) => {
135
+ if (path.includes("package.json")) {
136
+ return Promise.resolve(JSON.stringify(mockPackageJson()));
137
+ }
138
+ return Promise.resolve("");
139
+ }),
140
+ getWorkspaceRoot: mock(() => Promise.resolve("/workspace")),
141
+ };
142
+
143
+ // Mock the packagesShell methods directly
144
+ packagesShell.readJsonFile = mockPackagesShell.readJsonFile;
145
+ packagesShell.writeJsonFile = mockPackagesShell.writeJsonFile;
146
+ packagesShell.readChangelogFile = mockPackagesShell.readChangelogFile;
147
+ packagesShell.writeChangelogFile = mockPackagesShell.writeChangelogFile;
148
+ packagesShell.fileExists = mockPackagesShell.fileExists;
149
+ packagesShell.readDirectory = mockPackagesShell.readDirectory;
150
+ packagesShell.canAccessFile = mockPackagesShell.canAccessFile;
151
+ packagesShell.readFileAsText = mockPackagesShell.readFileAsText;
152
+ packagesShell.getWorkspaceRoot = mockPackagesShell.getWorkspaceRoot;
153
+
154
+ // Mock the entitiesShell methods directly
155
+ mockEntitiesShell = {
156
+ runBiomeCheck: mock(() => Promise.resolve()),
157
+ };
158
+
159
+ entitiesShell.runBiomeCheck = mockEntitiesShell.runBiomeCheck;
160
+
161
+ // Store for cleanup
162
+ // Original methods are now stored globally above
163
+
164
+ // Original methods are now stored globally above
165
+
166
+ // Create instance after mocking
167
+ packages = new EntityPackage(mockPackageName);
168
+ });
169
+
170
+ afterEach(async () => {
171
+ // Restore original methods
172
+ const { packagesShell } = await import("./package.shell");
173
+ const { entitiesShell } = await import("../entities.shell");
174
+
175
+ if (originalPackagesShellReadJsonFile) {
176
+ packagesShell.readJsonFile = originalPackagesShellReadJsonFile;
177
+ }
178
+ if (originalPackagesShellWriteJsonFile) {
179
+ packagesShell.writeJsonFile = originalPackagesShellWriteJsonFile;
180
+ }
181
+ if (originalPackagesShellReadChangelogFile) {
182
+ packagesShell.readChangelogFile = originalPackagesShellReadChangelogFile;
183
+ }
184
+ if (originalPackagesShellWriteChangelogFile) {
185
+ packagesShell.writeChangelogFile = originalPackagesShellWriteChangelogFile;
186
+ }
187
+ if (originalPackagesShellFileExists) {
188
+ packagesShell.fileExists = originalPackagesShellFileExists;
189
+ }
190
+ if (originalPackagesShellReadDirectory) {
191
+ packagesShell.readDirectory = originalPackagesShellReadDirectory;
192
+ }
193
+ if (originalPackagesShellCanAccessFile) {
194
+ packagesShell.canAccessFile = originalPackagesShellCanAccessFile;
195
+ }
196
+ if (originalPackagesShellReadFileAsText) {
197
+ packagesShell.readFileAsText = originalPackagesShellReadFileAsText;
198
+ }
199
+ if (originalPackagesShellGetWorkspaceRoot) {
200
+ packagesShell.getWorkspaceRoot = originalPackagesShellGetWorkspaceRoot;
201
+ }
202
+ if (originalEntitiesShellRunBiomeCheck) {
203
+ entitiesShell.runBiomeCheck = originalEntitiesShellRunBiomeCheck;
204
+ }
205
+ });
206
+
207
+ describe("constructor", () => {
208
+ it("should create instance with package name", () => {
209
+ packages = new EntityPackage(mockPackageName);
210
+ expect(packages).toBeInstanceOf(EntityPackage);
211
+ });
212
+
213
+ it("should read package.json on construction", () => {
214
+ packages = new EntityPackage(mockPackageName);
215
+ expect(packages).toBeInstanceOf(EntityPackage);
216
+ });
217
+ });
218
+
219
+ describe("getPath", () => {
220
+ beforeEach(() => {
221
+ packages = new EntityPackage(mockPackageName);
222
+ });
223
+
224
+ it("should return root path for root package", () => {
225
+ const rootPackages = new EntityPackage("root");
226
+ expect(rootPackages.getPath()).toBe(".");
227
+ });
228
+
229
+ it("should return packages path for @repo packages", () => {
230
+ const repoPackages = new EntityPackage("@repo/test-package");
231
+ expect(repoPackages.getPath()).toBe("packages/test-package");
232
+ });
233
+
234
+ it("should return apps path for regular packages", () => {
235
+ expect(packages.getPath()).toBe("apps/test-package");
236
+ });
237
+ });
238
+
239
+ describe("getJsonPath", () => {
240
+ beforeEach(() => {
241
+ packages = new EntityPackage(mockPackageName);
242
+ });
243
+
244
+ it("should return correct package.json path", () => {
245
+ expect(packages.getJsonPath()).toBe("apps/test-package/package.json");
246
+ });
247
+
248
+ it("should return correct path for root package", () => {
249
+ const rootPackages = new EntityPackage("root");
250
+ expect(rootPackages.getJsonPath()).toBe("./package.json");
251
+ });
252
+
253
+ it("should return correct path for @repo package", () => {
254
+ const repoPackages = new EntityPackage("@repo/test-package");
255
+ expect(repoPackages.getJsonPath()).toBe("packages/test-package/package.json");
256
+ });
257
+ });
258
+
259
+ describe.skip("readJson", () => {
260
+ beforeEach(() => {
261
+ packages = new EntityPackage(mockPackageName);
262
+ });
263
+
264
+ it("should return cached package.json if available", () => {
265
+ const result1 = packages.readJson();
266
+ expect(result1).toEqual(mockPackageJson());
267
+
268
+ const result2 = packages.readJson();
269
+ expect(result2).toEqual(mockPackageJson());
270
+ });
271
+
272
+ it("should read and parse package.json from file", () => {
273
+ const result = packages.readJson();
274
+ expect(result).toEqual(mockPackageJson());
275
+ });
276
+
277
+ it("should throw error when file read fails", async () => {
278
+ // Create a fresh mock for this test
279
+ const { packagesShell } = await import("./package.shell");
280
+ packagesShell.readJsonFile = mock(() => {
281
+ throw new Error("File read failed");
282
+ });
283
+
284
+ expect(() => {
285
+ new EntityPackage("error-package");
286
+ }).toThrow(
287
+ "Package not found error-package at apps/error-package/package.json: Error: File read failed",
288
+ );
289
+ });
290
+
291
+ it("should throw error when JSON parsing fails", () => {
292
+ // Mock packagesShell to return invalid JSON for this test
293
+ mockPackagesShell.readJsonFile.mockImplementationOnce(() => {
294
+ throw new Error("Invalid JSON");
295
+ });
296
+
297
+ expect(() => {
298
+ new EntityPackage("invalid-json-package");
299
+ }).toThrow(
300
+ "Package not found invalid-json-package at apps/invalid-json-package/package.json: Error: Invalid JSON",
301
+ );
302
+ });
303
+ });
304
+
305
+ describe.skip("writeJson", () => {
306
+ beforeEach(() => {
307
+ packages = new EntityPackage(mockPackageName);
308
+ });
309
+
310
+ it("should write package.json and run biome check", async () => {
311
+ // Use the already mocked packagesShell methods from beforeEach
312
+ // No need for additional mock.module since we're already mocking at the method level
313
+
314
+ const newData = { ...mockPackageJson(), version: "2.0.0" };
315
+ await packages.writeJson(newData);
316
+
317
+ expect(packages.readJson().version).toBe("2.0.0");
318
+ });
319
+
320
+ it("should update cached package.json", async () => {
321
+ const newData = { ...mockPackageJson(), version: "3.0.0" };
322
+ await packages.writeJson(newData);
323
+
324
+ expect(packages.readJson().version).toBe("3.0.0");
325
+ });
326
+ });
327
+
328
+ describe("readVersion", () => {
329
+ beforeEach(() => {
330
+ packages = new EntityPackage(mockPackageName);
331
+ });
332
+
333
+ it("should return version from package.json", () => {
334
+ const version = packages.readVersion();
335
+ expect(version).toBe("1.0.0");
336
+ });
337
+ });
338
+
339
+ describe.skip("writeVersion", () => {
340
+ beforeEach(() => {
341
+ packages = new EntityPackage(mockPackageName);
342
+ });
343
+
344
+ it("should update version and write package.json", async () => {
345
+ await packages.writeVersion("2.0.0");
346
+ expect(packages.readVersion()).toBe("2.0.0");
347
+ });
348
+
349
+ it("should update cached package.json version", async () => {
350
+ await packages.writeVersion("3.0.0");
351
+ expect(packages.readVersion()).toBe("3.0.0");
352
+ });
353
+ });
354
+
355
+ describe("getChangelogPath", () => {
356
+ beforeEach(() => {
357
+ packages = new EntityPackage(mockPackageName);
358
+ });
359
+
360
+ it("should return correct changelog path", () => {
361
+ expect(packages.getChangelogPath()).toBe("apps/test-package/CHANGELOG.md");
362
+ });
363
+ });
364
+
365
+ describe("readChangelog", () => {
366
+ beforeEach(() => {
367
+ packages = new EntityPackage(mockPackageName);
368
+ });
369
+
370
+ it("should read changelog content", () => {
371
+ // Update the mock for this specific test
372
+ mockPackagesShell.readChangelogFile.mockImplementationOnce((path: string) => {
373
+ if (path.includes("CHANGELOG.md")) {
374
+ return "# Test Changelog\n\n## 1.0.0\n- Initial release";
375
+ }
376
+ return "";
377
+ });
378
+
379
+ const changelogPackages = new EntityPackage("test-package");
380
+ const result = changelogPackages.readChangelog();
381
+ expect(result).toBe("# Test Changelog\n\n## 1.0.0\n- Initial release");
382
+ });
383
+
384
+ it("should return empty string when changelog is empty", () => {
385
+ // Update the mock for this specific test
386
+ mockPackagesShell.readChangelogFile.mockImplementationOnce(() => "");
387
+
388
+ const emptyChangelogPackages = new EntityPackage("test-package");
389
+ const result = emptyChangelogPackages.readChangelog();
390
+ expect(result).toBe("");
391
+ });
392
+
393
+ it("should not throw error when changelog read fails", () => {
394
+ // The readChangelog method should handle errors gracefully
395
+ expect(() => packages.readChangelog()).not.toThrow();
396
+ });
397
+ });
398
+
399
+ describe("writeChangelog", () => {
400
+ beforeEach(() => {
401
+ packages = new EntityPackage(mockPackageName);
402
+ });
403
+
404
+ it("should write changelog when file exists", async () => {
405
+ const content = "# New Changelog\n\n## 2.0.0\n- New features";
406
+ await packages.writeChangelog(content);
407
+ expect(packages).toBeDefined();
408
+ });
409
+
410
+ it("should create changelog with createPath when file doesn't exist", async () => {
411
+ const content = "# New Changelog\n\n## 2.0.0\n- New features";
412
+ await packages.writeChangelog(content);
413
+ expect(packages).toBeDefined();
414
+ });
415
+ });
416
+
417
+ describe("validatePackage", () => {
418
+ beforeEach(() => {
419
+ packages = new EntityPackage(mockPackageName);
420
+ });
421
+
422
+ it.skip("should return valid result for valid package", () => {
423
+ const result = packages.validatePackage();
424
+ expect(result).toHaveLength(0);
425
+ });
426
+
427
+ it.skip("should return error for invalid version format", () => {
428
+ // Mock packagesShell to return invalid version for this test
429
+ mockPackagesShell.readJsonFile.mockImplementationOnce(() =>
430
+ mockPackageJson({ version: "invalid-version" }),
431
+ );
432
+
433
+ const invalidPackages = new EntityPackage("invalid-version-package");
434
+ const result = invalidPackages.validatePackage();
435
+ expect(result).toHaveLength(1);
436
+ expect(result[0]).toContain(
437
+ "invalid-version-package: Version should follow semantic versioning",
438
+ );
439
+ });
440
+
441
+ it.skip("should return error for missing description", () => {
442
+ const packageJson = mockPackageJson();
443
+ delete packageJson.description;
444
+
445
+ // Mock packagesShell to return package without description for this test
446
+ mockPackagesShell.readJsonFile.mockImplementationOnce(() => packageJson);
447
+
448
+ const noDescPackages = new EntityPackage("no-description-package");
449
+ const result = noDescPackages.validatePackage();
450
+ expect(result).toHaveLength(1);
451
+ expect(result[0]).toContain(
452
+ "no-description-package: Consider adding a description to package.json",
453
+ );
454
+ });
455
+
456
+ it.skip("should return multiple errors for multiple issues", () => {
457
+ const packageJson = mockPackageJson({ version: "invalid" });
458
+ delete packageJson.description;
459
+
460
+ // Mock packagesShell to return package with multiple issues for this test
461
+ mockPackagesShell.readJsonFile.mockImplementationOnce(() => packageJson);
462
+
463
+ const multiIssuePackages = new EntityPackage("multi-issue-package");
464
+ const result = multiIssuePackages.validatePackage();
465
+ expect(result).toHaveLength(2);
466
+ expect(result).toEqual(
467
+ expect.arrayContaining([
468
+ expect.stringContaining("Version should follow semantic versioning"),
469
+ expect.stringContaining("Consider adding a description to package.json"),
470
+ ]),
471
+ );
472
+ });
473
+
474
+ it.skip("should validate semantic versioning correctly", () => {
475
+ const validVersions = ["1.0.0", "2.1.3", "10.20.30"];
476
+ const invalidVersions = ["1.0", "1.0.0.0", "1.0.0-beta", "v1.0.0"];
477
+
478
+ validVersions.forEach((version) => {
479
+ // Mock packagesShell to return valid version for this test
480
+ mockPackagesShell.readJsonFile.mockImplementationOnce(() => mockPackageJson({ version }));
481
+
482
+ const validPackages = new EntityPackage(`valid-${version}-package`);
483
+ const result = validPackages.validatePackage();
484
+ expect(result).toHaveLength(0);
485
+ });
486
+
487
+ invalidVersions.forEach((version) => {
488
+ // Mock packagesShell to return invalid version for this test
489
+ mockPackagesShell.readJsonFile.mockImplementationOnce(() => mockPackageJson({ version }));
490
+
491
+ const invalidPackages = new EntityPackage(`invalid-${version}-package`);
492
+ const result = invalidPackages.validatePackage();
493
+ expect(result.length).toBeGreaterThan(0);
494
+ });
495
+ });
496
+ });
497
+
498
+ describe("selective versioning", () => {
499
+ describe("shouldVersion", () => {
500
+ it.skip("should return true for packages with private: false", () => {
501
+ // Mock packagesShell to return package with private: false for this test
502
+ mockPackagesShell.readJsonFile.mockImplementationOnce(() =>
503
+ mockPackageJson({ private: false }),
504
+ );
505
+
506
+ const publicPackages = new EntityPackage("public-package");
507
+ expect(publicPackages.shouldVersion()).toBe(true);
508
+ });
509
+
510
+ it.skip("should return true for packages with no private field", () => {
511
+ const packageJson = mockPackageJson();
512
+ delete packageJson.private;
513
+
514
+ // Mock packagesShell to return package without private field for this test
515
+ mockPackagesShell.readJsonFile.mockImplementationOnce(() => packageJson);
516
+
517
+ const defaultPackages = new EntityPackage("default-package");
518
+ expect(defaultPackages.shouldVersion()).toBe(true);
519
+ });
520
+
521
+ it.skip("should return false for packages with private: true", () => {
522
+ // Mock packagesShell to return package with private: true for this test
523
+ mockPackagesShell.readJsonFile.mockImplementationOnce(() =>
524
+ mockPackageJson({ private: true }),
525
+ );
526
+
527
+ const privatePackages = new EntityPackage("private-package");
528
+ expect(privatePackages.shouldVersion()).toBe(false);
529
+ });
530
+ });
531
+
532
+ describe("getTagSeriesName", () => {
533
+ it.skip("should return 'v' for root package", () => {
534
+ // Mock packagesShell to return root package for this test
535
+ mockPackagesShell.readJsonFile.mockImplementationOnce(() =>
536
+ mockPackageJson({ name: "root", private: false }),
537
+ );
538
+
539
+ const rootPackages = new EntityPackage("root");
540
+ expect(rootPackages.getTagSeriesName()).toBe("v");
541
+ });
542
+
543
+ it.skip("should return 'package-name-v' for @repo packages", () => {
544
+ // Mock packagesShell to return @repo package for this test
545
+ mockPackagesShell.readJsonFile.mockImplementationOnce(() =>
546
+ mockPackageJson({ name: "@repo/package-name", private: false }),
547
+ );
548
+
549
+ const intershellPackages = new EntityPackage("@repo/package-name");
550
+ expect(intershellPackages.getTagSeriesName()).toBe("package-name-v");
551
+ });
552
+
553
+ it.skip("should return 'package-name-v' for regular packages", () => {
554
+ // Mock packagesShell to return regular package for this test
555
+ mockPackagesShell.readJsonFile.mockImplementationOnce(() =>
556
+ mockPackageJson({ name: "my-app", private: false }),
557
+ );
558
+
559
+ const appPackages = new EntityPackage("my-app");
560
+ expect(appPackages.getTagSeriesName()).toBe("my-app-v");
561
+ });
562
+
563
+ it.skip("should return null for private packages", () => {
564
+ // Mock packagesShell to return private package for this test
565
+ mockPackagesShell.readJsonFile.mockImplementationOnce(() =>
566
+ mockPackageJson({ private: true }),
567
+ );
568
+
569
+ const privatePackages = new EntityPackage("private-package");
570
+ expect(privatePackages.getTagSeriesName()).toBe(null);
571
+ });
572
+ });
573
+ });
574
+
575
+ describe("static methods", () => {
576
+ describe("getRepoUrl", () => {
577
+ it.skip("should return repository URL when repository is a string", () => {
578
+ // Mock packagesShell to return root package with string repository for this test
579
+ mockPackagesShell.readJsonFile.mockImplementationOnce(() =>
580
+ mockPackageJson({
581
+ name: "root",
582
+ repository: "https://github.com/user/repo.git",
583
+ }),
584
+ );
585
+
586
+ const result = EntityPackage.getRepoUrl();
587
+ expect(result).toBe("https://github.com/user/repo.git");
588
+ });
589
+
590
+ it.skip("should return repository URL when repository is an object", () => {
591
+ // Mock packagesShell to return root package with object repository for this test
592
+ mockPackagesShell.readJsonFile.mockImplementationOnce(() =>
593
+ mockPackageJson({
594
+ name: "root",
595
+ repository: {
596
+ type: "git",
597
+ url: "https://github.com/user/repo.git",
598
+ },
599
+ }),
600
+ );
601
+
602
+ const result = EntityPackage.getRepoUrl();
603
+ expect(result).toBe("https://github.com/user/repo.git");
604
+ });
605
+
606
+ it("should return empty string when repository is missing", () => {
607
+ const packageJson = mockPackageJson({ name: "root" });
608
+ delete packageJson.repository;
609
+
610
+ // Mock packagesShell to return root package without repository for this test
611
+ mockPackagesShell.readJsonFile.mockImplementationOnce(() => packageJson);
612
+
613
+ const result = EntityPackage.getRepoUrl();
614
+ expect(result).toBe("");
615
+ });
616
+
617
+ it("should return empty string when repository object has no url", () => {
618
+ // Mock packagesShell to return root package with repository object without url for this test
619
+ mockPackagesShell.readJsonFile.mockImplementationOnce(() =>
620
+ mockPackageJson({
621
+ name: "root",
622
+ repository: {
623
+ type: "git",
624
+ url: "",
625
+ },
626
+ }),
627
+ );
628
+
629
+ const result = EntityPackage.getRepoUrl();
630
+ expect(result).toBe("");
631
+ });
632
+
633
+ it("should return empty string when repository object has no url property", () => {
634
+ // Mock packagesShell to return root package with repository object without url property for this test
635
+ mockPackagesShell.readJsonFile.mockImplementationOnce(() =>
636
+ mockPackageJson({
637
+ name: "root",
638
+ repository: {
639
+ type: "git",
640
+ url: "", // Provide empty url to satisfy type requirements
641
+ },
642
+ }),
643
+ );
644
+
645
+ const result = EntityPackage.getRepoUrl();
646
+ expect(result).toBe("");
647
+ });
648
+
649
+ it("should return empty string when repository is undefined", () => {
650
+ // Mock packagesShell to return root package with undefined repository for this test
651
+ mockPackagesShell.readJsonFile.mockImplementationOnce(() =>
652
+ mockPackageJson({
653
+ name: "root",
654
+ repository: undefined,
655
+ }),
656
+ );
657
+
658
+ const result = EntityPackage.getRepoUrl();
659
+ expect(result).toBe("");
660
+ });
661
+
662
+ it.skip("should return repository URL when repository is a string", () => {
663
+ // Mock packagesShell to return root package with string repository for this test
664
+ mockPackagesShell.readJsonFile.mockImplementationOnce(() =>
665
+ mockPackageJson({
666
+ name: "root",
667
+ repository: "https://github.com/example/repo",
668
+ }),
669
+ );
670
+
671
+ const result = EntityPackage.getRepoUrl();
672
+ expect(result).toBe("https://github.com/example/repo");
673
+ });
674
+ });
675
+
676
+ describe("getAllPackages", () => {
677
+ it("should return list of packages including root", async () => {
678
+ // Mock packagesShell methods for this test
679
+ mockPackagesShell.getWorkspaceRoot.mockResolvedValueOnce("/workspace");
680
+ mockPackagesShell.readDirectory
681
+ .mockResolvedValueOnce(["test-app", "another-app"]) // apps
682
+ .mockResolvedValueOnce(["ui", "utils"]); // packages
683
+ mockPackagesShell.canAccessFile
684
+ .mockResolvedValueOnce(true) // apps/test-app/package.json
685
+ .mockResolvedValueOnce(true) // apps/another-app/package.json
686
+ .mockResolvedValueOnce(true) // packages/ui/package.json
687
+ .mockResolvedValueOnce(true); // packages/utils/package.json
688
+ mockPackagesShell.readFileAsText
689
+ .mockResolvedValueOnce('{"name": "test-app", "version": "1.0.0"}')
690
+ .mockResolvedValueOnce('{"name": "another-app", "version": "1.0.0"}')
691
+ .mockResolvedValueOnce('{"name": "@repo/ui", "version": "1.0.0"}')
692
+ .mockResolvedValueOnce('{"name": "@repo/utils", "version": "1.0.0"}');
693
+
694
+ const result = await EntityPackage.getAllPackages();
695
+
696
+ expect(result).toContain("root");
697
+ expect(result).toContain("test-app");
698
+ expect(result).toContain("another-app");
699
+ expect(result).toContain("@repo/ui");
700
+ expect(result).toContain("@repo/utils");
701
+ });
702
+
703
+ it("should handle empty directories gracefully", async () => {
704
+ // Mock packagesShell methods for this test
705
+ mockPackagesShell.getWorkspaceRoot.mockResolvedValueOnce("/workspace");
706
+ mockPackagesShell.readDirectory
707
+ .mockResolvedValueOnce([]) // apps
708
+ .mockResolvedValueOnce([]); // packages
709
+
710
+ const result = await EntityPackage.getAllPackages();
711
+ expect(result).toEqual(["root"]);
712
+ });
713
+
714
+ it("should filter out packages without valid package.json", async () => {
715
+ // Mock packagesShell methods for this test
716
+ mockPackagesShell.getWorkspaceRoot.mockResolvedValueOnce("/workspace");
717
+ mockPackagesShell.readDirectory
718
+ .mockResolvedValueOnce(["invalid-app"]) // apps
719
+ .mockResolvedValueOnce(["invalid-pkg"]); // packages
720
+ mockPackagesShell.canAccessFile
721
+ .mockResolvedValueOnce(false) // apps/invalid-app/package.json
722
+ .mockResolvedValueOnce(false); // packages/invalid-pkg/package.json
723
+
724
+ const result = await EntityPackage.getAllPackages();
725
+ expect(result).toEqual(["root"]);
726
+ });
727
+ });
728
+ });
729
+
730
+ describe("edge cases and error handling", () => {
731
+ it("should handle package names with special characters", () => {
732
+ const specialPackages = new EntityPackage("test-package@1.0.0");
733
+ expect(specialPackages.getPath()).toBe("apps/test-package@1.0.0");
734
+ });
735
+
736
+ it("should handle empty package name", () => {
737
+ const emptyPackages = new EntityPackage("");
738
+ expect(emptyPackages.getPath()).toBe("apps/");
739
+ });
740
+
741
+ it("should handle very long package names", () => {
742
+ const longName = "a".repeat(1000);
743
+ const longPackages = new EntityPackage(longName);
744
+ expect(longPackages.getPath()).toBe(`apps/${longName}`);
745
+ });
746
+
747
+ it("should handle package names with spaces", () => {
748
+ const spacedPackages = new EntityPackage("test package");
749
+ expect(spacedPackages.getPath()).toBe("apps/test package");
750
+ });
751
+ });
752
+
753
+ describe("getVersionedPackages", () => {
754
+ it.skip("should return packages that should be versioned", async () => {
755
+ // Mock packagesShell methods for this test
756
+ mockPackagesShell.getWorkspaceRoot.mockResolvedValueOnce("/workspace");
757
+ mockPackagesShell.readDirectory
758
+ .mockResolvedValueOnce(["test-app"]) // apps
759
+ .mockResolvedValueOnce(["ui"]); // packages
760
+ mockPackagesShell.canAccessFile
761
+ .mockResolvedValueOnce(true) // apps/test-app/package.json
762
+ .mockResolvedValueOnce(true); // packages/ui/package.json
763
+ mockPackagesShell.readFileAsText
764
+ .mockResolvedValueOnce('{"name": "test-app", "version": "1.0.0", "private": false}')
765
+ .mockResolvedValueOnce('{"name": "@repo/ui", "version": "1.0.0", "private": false}');
766
+
767
+ const result = await EntityPackage.getVersionedPackages();
768
+ expect(Array.isArray(result)).toBe(true);
769
+ expect(result).toContain("test-app");
770
+ expect(result).toContain("@repo/ui");
771
+ });
772
+ });
773
+
774
+ describe("getUnversionedPackages", () => {
775
+ it.skip("should return packages that should not be versioned", async () => {
776
+ // Override the readJsonFile mock for this specific test to return private packages
777
+ mockPackagesShell.readJsonFile.mockImplementation((path: string) => {
778
+ if (path.includes("test-app")) {
779
+ return { name: "test-app", version: "1.0.0", private: true };
780
+ }
781
+ if (path.includes("ui")) {
782
+ return { name: "@repo/ui", version: "1.0.0", private: true };
783
+ }
784
+ // Default fallback
785
+ return mockPackageJson();
786
+ });
787
+
788
+ // Mock packagesShell methods for this test
789
+ mockPackagesShell.getWorkspaceRoot.mockResolvedValueOnce("/workspace");
790
+ mockPackagesShell.readDirectory
791
+ .mockResolvedValueOnce(["test-app"]) // apps
792
+ .mockResolvedValueOnce(["ui"]); // packages
793
+ mockPackagesShell.canAccessFile
794
+ .mockResolvedValueOnce(true) // apps/test-app/package.json
795
+ .mockResolvedValueOnce(true); // packages/ui/package.json
796
+ mockPackagesShell.readFileAsText
797
+ .mockResolvedValueOnce('{"name": "test-app", "version": "1.0.0", "private": true}')
798
+ .mockResolvedValueOnce('{"name": "@repo/ui", "version": "1.0.0", "private": true}');
799
+
800
+ const result = await EntityPackage.getUnversionedPackages();
801
+ expect(Array.isArray(result)).toBe(true);
802
+ expect(result).toContain("test-app");
803
+ expect(result).toContain("@repo/ui");
804
+ });
805
+ });
806
+
807
+ describe.skip("validateAllPackages", () => {
808
+ it("should validate all packages and return results", async () => {
809
+ // Mock packagesShell methods for this test
810
+ mockPackagesShell.getWorkspaceRoot.mockResolvedValueOnce("/workspace");
811
+ mockPackagesShell.readDirectory
812
+ .mockResolvedValueOnce(["test-app"]) // apps
813
+ .mockResolvedValueOnce(["ui"]); // packages
814
+ mockPackagesShell.canAccessFile
815
+ .mockResolvedValueOnce(true) // apps/test-app/package.json
816
+ .mockResolvedValueOnce(true); // packages/ui/package.json
817
+ mockPackagesShell.readFileAsText
818
+ .mockResolvedValueOnce('{"name": "test-app", "version": "1.0.0", "private": false}')
819
+ .mockResolvedValueOnce('{"name": "@repo/ui", "version": "1.0.0", "private": false}');
820
+
821
+ const result = await EntityPackage.validateAllPackages();
822
+ expect(Array.isArray(result)).toBe(true);
823
+ console.log(result);
824
+ expect(result).toHaveLength(3);
825
+ expect(result).toContain("root: Consider adding a description to package.json");
826
+ expect(result).toContain("test-app: Consider adding a description to package.json");
827
+ expect(result).toContain("@repo/ui: Consider adding a description to package.json");
828
+ });
829
+ });
830
+ });