binary-collections 2.0.11 → 2.0.13

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 (330) hide show
  1. package/binaries/binary-executor.cjs +89 -13
  2. package/binaries/clean-nodemodule.cjs +89 -13
  3. package/binaries/clean-nodemodules.cjs +89 -13
  4. package/binaries/dev.cjs +89 -13
  5. package/binaries/empty.cjs +89 -13
  6. package/binaries/git-reduce-size.cjs +89 -13
  7. package/binaries/javakill.cjs +89 -13
  8. package/binaries/kill-process.cjs +89 -13
  9. package/binaries/nodekill.cjs +89 -13
  10. package/binaries/prod.cjs +89 -13
  11. package/binaries/py.cjs +89 -13
  12. package/binaries/rmfind.cjs +89 -13
  13. package/binaries/rmx +15 -1
  14. package/binaries/rmx.cjs +89 -13
  15. package/binaries/rmx.cmd +12 -0
  16. package/binaries/submodule-token.cjs +89 -13
  17. package/binaries/test-cjs +9 -1
  18. package/binaries/test-cjs.cjs +89 -13
  19. package/binaries/test-cjs.cmd +16 -1
  20. package/binaries/test-esm +16 -0
  21. package/binaries/test-esm.cjs +254 -0
  22. package/binaries/test-esm.cmd +23 -0
  23. package/binaries/yarn-clean +1 -1
  24. package/binaries/yarn-clean.cjs +89 -13
  25. package/binaries/yarn-clean.cmd +1 -1
  26. package/binaries/yarn-clean.py +33 -15
  27. package/binaries/yc +131 -0
  28. package/binaries/yc.cjs +254 -0
  29. package/binaries/ycw +256 -0
  30. package/binaries/ycw.cjs +254 -0
  31. package/docs-src/binary-collections.md +34 -0
  32. package/docs-src/changelog.md +26 -0
  33. package/docs-src/clean-github-actions-caches.md +91 -2
  34. package/docs-src/copy-move-file.md +59 -0
  35. package/docs-src/del-gradle.md +17 -0
  36. package/docs-src/del-ps.md +28 -0
  37. package/docs-src/downloader.md +62 -0
  38. package/docs-src/env-helpers.md +29 -0
  39. package/docs-src/find-node-modules.md +17 -0
  40. package/docs-src/git-diff.md +33 -0
  41. package/docs-src/git-fix.md +34 -0
  42. package/docs-src/git-purge.md +17 -0
  43. package/docs-src/git-reduce-size.md +17 -0
  44. package/docs-src/git-undo.md +21 -0
  45. package/docs-src/kill-night-crows.md +26 -0
  46. package/docs-src/node-cache-cleaner.md +182 -0
  47. package/docs-src/node-executor.md +50 -0
  48. package/docs-src/node-package-packer.md +48 -0
  49. package/docs-src/npm-run-series.md +43 -0
  50. package/docs-src/package-resolutions-updater.md +22 -0
  51. package/docs-src/php-cs-fixer-staged.md +19 -0
  52. package/docs-src/print-directory-tree.md +35 -0
  53. package/docs-src/print-tarball-tree.md +55 -0
  54. package/docs-src/py.md +19 -0
  55. package/docs-src/remove-module.md +32 -0
  56. package/docs-src/rmfind-rmx.md +21 -0
  57. package/docs-src/rmpath.md +38 -0
  58. package/docs-src/run-by-checksum.md +87 -0
  59. package/docs-src/submodule-install.md +31 -0
  60. package/docs-src/submodule-remove.md +22 -0
  61. package/docs-src/submodule-token.md +17 -0
  62. package/docs-src/test-runners.md +21 -0
  63. package/docs-src/yarn-install.md +31 -0
  64. package/docs-src/yarn-reinstall.md +27 -0
  65. package/lib/binary-collections/config.cjs +126 -0
  66. package/lib/binary-collections/config.mjs +7 -0
  67. package/lib/binary-collections/executeScript.cjs +19 -0
  68. package/lib/binary-collections/executeScript.d.cts +12 -0
  69. package/lib/binary-collections/executeScript.mjs +6 -0
  70. package/lib/binary-collections/findScript.cjs +309 -0
  71. package/lib/binary-collections/findScript.d.cts +12 -0
  72. package/lib/binary-collections/findScript.mjs +7 -0
  73. package/lib/binary-collections/listScript.cjs +291 -0
  74. package/lib/binary-collections/listScript.d.cts +19 -0
  75. package/lib/binary-collections/listScript.mjs +7 -0
  76. package/lib/binary-collections.cjs +264 -157
  77. package/lib/binary-collections.mjs +26 -286
  78. package/lib/changelog.cjs +9 -14
  79. package/lib/changelog.mjs +2 -2
  80. package/lib/chunk-2MN4VPV2.mjs +246 -0
  81. package/lib/chunk-6C7KTYGZ.mjs +41 -0
  82. package/lib/{chunk-Z6JLYU2J.mjs → chunk-6RK5UCTP.mjs} +7 -12
  83. package/lib/chunk-CD3HF3LK.mjs +190 -0
  84. package/lib/chunk-FLYSZFLW.mjs +61 -0
  85. package/lib/{chunk-N436BNBK.mjs → chunk-GAGABICI.mjs} +19 -13
  86. package/lib/chunk-H44UWUFY.mjs +105 -0
  87. package/lib/chunk-KLKAIFKI.mjs +40 -0
  88. package/lib/chunk-LVSPEFU2.mjs +86 -0
  89. package/lib/{chunk-RWLXRTYP.mjs → chunk-MGPYPKIE.mjs} +2 -2
  90. package/lib/chunk-NGFK3EYW.mjs +28 -0
  91. package/lib/chunk-NQXUYO67.mjs +253 -0
  92. package/lib/chunk-NVEG3LEZ.mjs +143 -0
  93. package/lib/chunk-OBXLTXFJ.mjs +34 -0
  94. package/lib/chunk-OGXVGBRI.mjs +29 -0
  95. package/lib/chunk-OXV52GD5.mjs +62 -0
  96. package/lib/chunk-PXBMHE7O.mjs +35 -0
  97. package/lib/chunk-QD4T255Z.mjs +40 -0
  98. package/lib/chunk-QII2EKCS.mjs +26 -0
  99. package/lib/chunk-R5FJOR63.mjs +47 -0
  100. package/lib/chunk-RDGDLSPD.mjs +76 -0
  101. package/lib/chunk-RDN6HF5Z.mjs +79 -0
  102. package/lib/chunk-RJKTSUAX.mjs +123 -0
  103. package/lib/{chunk-XA3SNBPA.mjs → chunk-TBWXE7ST.mjs} +97 -38
  104. package/lib/chunk-UXCFNAR6.mjs +55 -0
  105. package/lib/{chunk-M3YIYRHT.mjs → chunk-UY5VUEA3.mjs} +1 -1
  106. package/lib/chunk-WSHVPGNM.mjs +44 -0
  107. package/lib/{chunk-66PAU5PS.mjs → chunk-X2B3X7D4.mjs} +10 -6
  108. package/lib/clean-github-actions-caches-cli.cjs +507 -0
  109. package/lib/clean-github-actions-caches-cli.mjs +74 -0
  110. package/lib/clean-github-actions-caches.cjs +246 -106
  111. package/lib/clean-github-actions-caches.d.cts +53 -1
  112. package/lib/clean-github-actions-caches.mjs +5 -130
  113. package/lib/cross-env/command.cjs +63 -0
  114. package/lib/cross-env/command.d.ts +8 -0
  115. package/lib/cross-env/command.js +45 -0
  116. package/lib/{ps/isWin.mjs → cross-env/command.mjs} +4 -5
  117. package/lib/cross-env/index.cjs +178 -0
  118. package/lib/cross-env/index.d.ts +8 -0
  119. package/lib/cross-env/index.js +102 -0
  120. package/lib/cross-env/index.mjs +101 -0
  121. package/lib/cross-env/variable.cjs +60 -0
  122. package/lib/cross-env/variable.d.ts +7 -0
  123. package/lib/cross-env/variable.js +59 -0
  124. package/lib/cross-env/variable.mjs +9 -0
  125. package/lib/del-gradle.cjs +8 -13
  126. package/lib/del-gradle.js +8 -8
  127. package/lib/del-gradle.mjs +1 -1
  128. package/lib/del-node-modules.cjs +185 -3
  129. package/lib/del-node-modules.js +25 -25
  130. package/lib/del-node-modules.mjs +6 -3
  131. package/lib/{del-ps.cjs → del-ps-cli.cjs} +38 -43
  132. package/lib/del-ps-cli.d.mts +1 -0
  133. package/lib/del-ps-cli.mjs +44 -0
  134. package/lib/del-yarn-caches.cjs +8 -13
  135. package/lib/del-yarn-caches.js +2 -2
  136. package/lib/del-yarn-caches.mjs +1 -1
  137. package/lib/downloader-cli.cjs +256 -0
  138. package/lib/downloader-cli.d.cts +2 -0
  139. package/lib/downloader-cli.mjs +90 -0
  140. package/lib/file/copy-cli.cjs +273 -0
  141. package/lib/file/copy-cli.d.mts +1 -0
  142. package/lib/file/copy-cli.mjs +59 -0
  143. package/lib/file/copy.cjs +56 -0
  144. package/lib/file/copy.d.mts +1 -0
  145. package/lib/file/copy.mjs +8 -0
  146. package/lib/file/move-cli.cjs +272 -0
  147. package/lib/file/move-cli.d.mts +1 -0
  148. package/lib/file/move-cli.mjs +59 -0
  149. package/lib/file/move.cjs +55 -0
  150. package/lib/file/move.d.mts +1 -0
  151. package/lib/file/move.mjs +8 -0
  152. package/lib/find-node-modules-cli.cjs +1 -1
  153. package/lib/find-node-modules-cli.js +1 -1
  154. package/lib/find-node-modules-cli.mjs +1 -1
  155. package/lib/find-node-modules.cjs +1 -1
  156. package/lib/find-node-modules.mjs +1 -1
  157. package/lib/free-chatgpt.cjs +27 -26
  158. package/lib/free-chatgpt.js +10 -10
  159. package/lib/free-chatgpt.mjs +2 -2
  160. package/lib/git/user-config.cjs +9 -14
  161. package/lib/git/user-config.mjs +2 -2
  162. package/lib/git-diff-cli.cjs +273 -66
  163. package/lib/git-diff-cli.mjs +5 -4
  164. package/lib/git-diff.cjs +273 -66
  165. package/lib/git-diff.d.ts +2 -1
  166. package/lib/git-diff.js +153 -39
  167. package/lib/git-diff.mjs +5 -4
  168. package/lib/git-fix.cjs +9 -14
  169. package/lib/git-fix.mjs +2 -2
  170. package/lib/git-purge.cjs +9 -14
  171. package/lib/git-purge.mjs +2 -2
  172. package/lib/index.cjs +1 -1
  173. package/lib/index.d.ts +1 -1
  174. package/lib/index.mjs +1 -1
  175. package/lib/kill-night-crows.cjs +7 -7
  176. package/lib/kill-night-crows.mjs +7 -7
  177. package/lib/node-cache-cleaner/npm.cjs +65 -0
  178. package/lib/node-cache-cleaner/npm.d.ts +2 -0
  179. package/lib/node-cache-cleaner/npm.js +41 -0
  180. package/lib/node-cache-cleaner/npm.mjs +10 -0
  181. package/lib/node-cache-cleaner/npx.cjs +89 -0
  182. package/lib/node-cache-cleaner/npx.d.ts +4 -0
  183. package/lib/node-cache-cleaner/npx.js +82 -0
  184. package/lib/{ps/index.d.mjs → node-cache-cleaner/npx.mjs} +6 -5
  185. package/lib/node-cache-cleaner/yarn.cjs +73 -0
  186. package/lib/node-cache-cleaner/yarn.d.ts +2 -0
  187. package/lib/node-cache-cleaner/yarn.js +62 -0
  188. package/lib/node-cache-cleaner/yarn.mjs +10 -0
  189. package/lib/node-cache-cleaner-cli.cjs +365 -0
  190. package/lib/node-cache-cleaner-cli.d.ts +2 -0
  191. package/lib/node-cache-cleaner-cli.js +57 -0
  192. package/lib/node-cache-cleaner-cli.mjs +60 -0
  193. package/lib/node-executor.cjs +272 -0
  194. package/lib/node-executor.d.cts +2 -0
  195. package/lib/node-executor.mjs +106 -0
  196. package/lib/node-package-packer/build-readme.cjs +150 -0
  197. package/lib/node-package-packer/build-readme.d.mts +10 -0
  198. package/lib/node-package-packer/build-readme.mjs +10 -0
  199. package/lib/node-package-packer/build-tarball.cjs +495 -0
  200. package/lib/node-package-packer/build-tarball.d.mts +33 -0
  201. package/lib/node-package-packer/build-tarball.mjs +175 -0
  202. package/lib/node-package-packer-cli.cjs +525 -0
  203. package/lib/node-package-packer-cli.d.mts +1 -0
  204. package/lib/node-package-packer-cli.mjs +34 -0
  205. package/lib/npm-run-series.cjs +28 -40
  206. package/lib/npm-run-series.mjs +21 -7
  207. package/lib/package-resolutions-updater-cli.cjs +255 -173
  208. package/lib/package-resolutions-updater-cli.mjs +19 -40
  209. package/lib/package-resolutions-updater.cjs +244 -141
  210. package/lib/package-resolutions-updater.d.mts +54 -1
  211. package/lib/package-resolutions-updater.mjs +8 -5
  212. package/lib/php-cs-fixer-staged.cjs +1 -1
  213. package/lib/php-cs-fixer-staged.mjs +1 -1
  214. package/lib/print-directory-tree.cjs +18 -20
  215. package/lib/print-directory-tree.mjs +11 -8
  216. package/lib/print-tarball-tree.cjs +262 -0
  217. package/lib/print-tarball-tree.d.mts +1 -0
  218. package/lib/print-tarball-tree.mjs +68 -0
  219. package/lib/ps/connected-domain.js +10 -10
  220. package/lib/ps/index.cjs +11 -11
  221. package/lib/ps/index.mjs +180 -174
  222. package/lib/ps/table-parser.d.ts +3 -4
  223. package/lib/ps/table-parser.js +15 -22
  224. package/lib/remove-module.cjs +19 -24
  225. package/lib/remove-module.mjs +2 -2
  226. package/lib/rm-node-module-cli.cjs +389 -0
  227. package/lib/rm-node-module-cli.d.cts +1 -0
  228. package/lib/rm-node-module-cli.mjs +92 -0
  229. package/lib/rm-node-modules.cjs +127 -0
  230. package/lib/rm-node-modules.d.cts +35 -0
  231. package/lib/{binary-collections-config.mjs → rm-node-modules.mjs} +3 -3
  232. package/lib/rmpath-cli.cjs +285 -0
  233. package/lib/rmpath-cli.d.mts +1 -0
  234. package/lib/rmpath-cli.mjs +23 -0
  235. package/lib/rmpath.cjs +6 -217
  236. package/lib/rmpath.mjs +5 -101
  237. package/lib/run-by-checksum/cache.cjs +69 -0
  238. package/lib/run-by-checksum/cache.d.ts +19 -0
  239. package/lib/run-by-checksum/cache.js +50 -0
  240. package/lib/run-by-checksum/cache.mjs +12 -0
  241. package/lib/run-by-checksum/hash.cjs +72 -0
  242. package/lib/run-by-checksum/hash.d.ts +14 -0
  243. package/lib/run-by-checksum/hash.js +85 -0
  244. package/lib/run-by-checksum/hash.mjs +10 -0
  245. package/lib/run-by-checksum/run.cjs +169 -0
  246. package/lib/run-by-checksum/run.d.ts +22 -0
  247. package/lib/run-by-checksum/run.js +93 -0
  248. package/lib/run-by-checksum/run.mjs +10 -0
  249. package/lib/run-by-checksum-cli.cjs +382 -0
  250. package/lib/run-by-checksum-cli.d.ts +2 -0
  251. package/lib/run-by-checksum-cli.js +43 -0
  252. package/lib/run-by-checksum-cli.mjs +56 -0
  253. package/lib/submodule-install.cjs +55 -47
  254. package/lib/submodule-install.mjs +48 -35
  255. package/lib/submodule-remove-cli.cjs +170 -4
  256. package/lib/submodule-remove-cli.js +5 -5
  257. package/lib/submodule-remove-cli.mjs +6 -4
  258. package/lib/utils/chatgpt.cjs +19 -13
  259. package/lib/utils/chatgpt.js +94 -94
  260. package/lib/utils/chatgpt.mjs +1 -1
  261. package/lib/utils/fetchResponse.cjs +24 -0
  262. package/lib/utils/fetchResponse.d.cts +25 -0
  263. package/lib/utils/fetchResponse.mjs +6 -0
  264. package/lib/utils/findEnvFiles.cjs +28 -46
  265. package/lib/utils/findEnvFiles.d.cts +19 -0
  266. package/lib/utils/findEnvFiles.mjs +3 -5
  267. package/lib/utils/findWorkspaceRoot.js +4 -4
  268. package/lib/utils/index.cjs +7 -12
  269. package/lib/utils/index.d.cts +2 -9
  270. package/lib/utils/index.mjs +1 -1
  271. package/lib/utils/isGithubTokenValid.js +7 -7
  272. package/lib/{ps/isWin.cjs → utils/isWindows.cjs} +12 -7
  273. package/lib/utils/isWindows.d.ts +5 -0
  274. package/lib/utils/isWindows.js +10 -0
  275. package/lib/utils/isWindows.mjs +10 -0
  276. package/lib/utils/runBash.cjs +53 -0
  277. package/lib/utils/runBash.d.cts +12 -0
  278. package/lib/utils/runBash.mjs +66 -0
  279. package/lib/yarn-per-branch-lock-installer.cjs +288 -0
  280. package/lib/yarn-per-branch-lock-installer.d.cts +2 -0
  281. package/lib/yarn-per-branch-lock-installer.mjs +122 -0
  282. package/lib/yarn-reinstall.cjs +8 -13
  283. package/lib/yarn-reinstall.mjs +1 -1
  284. package/package.json +91 -57
  285. package/readme.html +784 -0
  286. package/readme.md +107 -219
  287. package/releases/readme.md +6 -3
  288. package/test/README.md +2 -2
  289. package/test-project/workspaces/workspace-a/readme.md +20 -0
  290. package/test-project/workspaces/workspace-a/release/readme.md +42 -0
  291. package/test-project/workspaces/workspace-a/test/readme.md +12 -0
  292. package/test-project/workspaces/workspace-b/readme.md +94 -0
  293. package/test-project/workspaces/workspace-b/requirements.txt +1 -0
  294. package/test-project/workspaces/workspace-b/themes/hexo-theme-flowbite/readme.md +156 -0
  295. package/tmp/test-repo/README.md +2 -35
  296. package/tmp/test-repo-runChecksum/test-complex-glob/README.md +1 -0
  297. package/tmp/test-repo-runChecksum/test-mixed-args/README.md +1 -0
  298. package/lib/binary-collections-config.cjs +0 -15
  299. package/lib/chunk-2CBJCW7E.mjs +0 -81
  300. package/lib/chunk-4UHL4WVN.mjs +0 -136
  301. package/lib/chunk-6HHJRKFB.mjs +0 -59
  302. package/lib/chunk-6S4NXESK.mjs +0 -26
  303. package/lib/chunk-7XTEJHOE.mjs +0 -193
  304. package/lib/chunk-AJDD5DZM.mjs +0 -109
  305. package/lib/chunk-FCDQGYBF.mjs +0 -136
  306. package/lib/chunk-GEYA2USY.mjs +0 -207
  307. package/lib/chunk-GJTGHXRA.mjs +0 -356
  308. package/lib/chunk-ID2WBTE2.mjs +0 -80
  309. package/lib/chunk-JXFOHKDM.mjs +0 -239
  310. package/lib/chunk-NCXAP7AA.mjs +0 -31
  311. package/lib/chunk-PDSXF5HY.mjs +0 -187
  312. package/lib/chunk-TOIVAQF7.mjs +0 -136
  313. package/lib/chunk-V5SKYJUB.mjs +0 -136
  314. package/lib/chunk-WSRETQCA.mjs +0 -59
  315. package/lib/chunk-YYLIQQKF.mjs +0 -31
  316. package/lib/del-ps.js +0 -32
  317. package/lib/del-ps.mjs +0 -43
  318. package/lib/ps/index.d.cjs +0 -17
  319. package/lib/ps/index.d.ts +0 -2
  320. package/lib/ps/index.js +0 -254
  321. package/lib/ps/isWin.d.ts +0 -2
  322. package/lib/ps/isWin.js +0 -4
  323. package/lib/utils/findEnvFiles.d.ts +0 -8
  324. package/lib/utils/findEnvFiles.js +0 -121
  325. package/test/package.json +0 -20
  326. package/test-project/package.json +0 -16
  327. package/tmp/test-repo/package.json +0 -7
  328. package/tmp/typedoc/readme.md +0 -320
  329. /package/lib/{binary-collections-config.d.cts → binary-collections/config.d.cts} +0 -0
  330. /package/lib/{del-ps.d.ts → clean-github-actions-caches-cli.d.cts} +0 -0
@@ -0,0 +1,254 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Built-in Node.js modules:
5
+ *
6
+ * - child_process:
7
+ * Used to launch external scripts/programs.
8
+ *
9
+ * - path:
10
+ * Safely handles file paths across operating systems.
11
+ *
12
+ * - fs:
13
+ * Used to check whether files exist.
14
+ */
15
+ const { spawnSync } = require('child_process');
16
+ const path = require('path');
17
+ const fs = require('fs');
18
+ const which = require('which');
19
+ const { isWindows } = require('../src/utils/isWindows.js');
20
+
21
+ /**
22
+ * __dirname
23
+ * Absolute directory path of this launcher script.
24
+ *
25
+ * __filename
26
+ * Absolute path of this launcher file itself.
27
+ *
28
+ * base
29
+ * Filename without extension.
30
+ *
31
+ * Example:
32
+ * File = "/tools/mytool.js"
33
+ *
34
+ * binDir = "/tools"
35
+ * base = "mytool"
36
+ */
37
+ const binDir = __dirname;
38
+ const base = path.basename(__filename, path.extname(__filename));
39
+
40
+ /**
41
+ * Determine which script extensions to search for
42
+ * based on the current operating system.
43
+ *
44
+ * Windows:
45
+ * .cmd
46
+ * .bat
47
+ * .ps1
48
+ * .vbs
49
+ *
50
+ * Linux/macOS:
51
+ * .sh
52
+ * executable file without extension
53
+ */
54
+ const candidates = process.platform === 'win32' ? ['.cmd', '.bat', '.ps1', '.vbs'] : ['.sh', ''];
55
+
56
+ /**
57
+ * Search for the first matching script
58
+ * in the same directory as this launcher.
59
+ *
60
+ * Example:
61
+ * If base = "mytool"
62
+ *
63
+ * Windows checks:
64
+ * mytool.cmd
65
+ * mytool.bat
66
+ * mytool.ps1
67
+ * mytool.vbs
68
+ *
69
+ * Linux/macOS checks:
70
+ * mytool.sh
71
+ * mytool
72
+ */
73
+ let found = null;
74
+
75
+ for (const ext of candidates) {
76
+ const script = path.join(binDir, base + ext);
77
+ const exists = fs.existsSync(script);
78
+ // console.log(`Checking for ${script}: ${exists ? 'found' : 'not found'}`);
79
+ if (exists) {
80
+ found = script;
81
+ break;
82
+ }
83
+ }
84
+
85
+ /**
86
+ * If no matching script was found,
87
+ * try check if `bash` is available and if so, check for a .sh script.
88
+ */
89
+ if (!found) {
90
+ try {
91
+ spawnSync('bash', ['--version'], { stdio: 'ignore' });
92
+ const bashScript = [path.join(binDir, base), path.join(binDir, base + '.sh')].find((script) =>
93
+ fs.existsSync(script)
94
+ );
95
+ if (bashScript) {
96
+ found = bashScript;
97
+ }
98
+ } catch {
99
+ // bash is not available, do nothing
100
+ }
101
+ }
102
+
103
+ /**
104
+ * If no matching script was found,
105
+ * print an error and exit with failure code 1.
106
+ */
107
+ if (!found) {
108
+ console.error(`No script found for ${base} in ${binDir}`);
109
+ process.exit(1);
110
+ }
111
+
112
+ /**
113
+ * Detect special script types
114
+ * that require a shell/interpreter.
115
+ */
116
+ const isPs1 = found.endsWith('.ps1');
117
+ const isCmd = found.endsWith('.cmd');
118
+ const isUnixShell = found.endsWith('.sh') || path.extname(found) === '';
119
+
120
+ /**
121
+ * cmd
122
+ * The executable program to launch.
123
+ *
124
+ * args
125
+ * Arguments passed to the executable.
126
+ */
127
+ let cmd, args;
128
+
129
+ /**
130
+ * PowerShell scripts:
131
+ *
132
+ * Run through powershell.exe because .ps1 files
133
+ * are not directly executable like binaries.
134
+ *
135
+ * Flags:
136
+ * -NoProfile
137
+ * Prevent loading user profile scripts.
138
+ *
139
+ * -ExecutionPolicy Bypass
140
+ * Allow script execution even if policy blocks it.
141
+ *
142
+ * -File
143
+ * Specifies the script to execute.
144
+ *
145
+ * process.argv.slice(2)
146
+ * Forward all user-provided command-line arguments.
147
+ */
148
+ if (isPs1) {
149
+ cmd = 'powershell.exe';
150
+
151
+ args = ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', found, ...process.argv.slice(2)];
152
+
153
+ /**
154
+ * CMD batch files:
155
+ *
156
+ * Run through cmd.exe using:
157
+ * /c
158
+ * which means:
159
+ * "execute command and terminate"
160
+ */
161
+ } else if (isCmd) {
162
+ cmd = 'cmd.exe';
163
+
164
+ args = ['/c', found, ...process.argv.slice(2)];
165
+
166
+ /**
167
+ * Other scripts:
168
+ *
169
+ * Usually:
170
+ * - shell scripts (.sh)
171
+ * - executable binaries
172
+ *
173
+ * These can be executed directly.
174
+ */
175
+ } else if (isUnixShell) {
176
+ // Capture shebang scripts (no extension) and .sh scripts
177
+ const shebang = fs.readFileSync(found, 'utf8').split('\n')[0].trim();
178
+ const interpreter = shebang.startsWith('#!')
179
+ ? shebang
180
+ .slice(2)
181
+ .trim()
182
+ .replace(/^\/usr\/bin\/env\s+/, '')
183
+ .replace(/^\/bin\/env\s+/, '')
184
+ .replace(/^\/usr\/bin\//, '')
185
+ .replace(/^\/bin\//, '')
186
+ : null;
187
+
188
+ if (interpreter) {
189
+ const resolvedOrNull = which.sync(interpreter, { nothrow: true });
190
+ if (!resolvedOrNull) {
191
+ if (['bash', 'sh'].includes(interpreter) && isWindows()) {
192
+ const locationsToCheck = [
193
+ 'C:\\Program Files\\Git\\usr\\bin',
194
+ 'C:\\Program Files\\Git\\bin',
195
+ 'C:\\Program Files (x86)\\Git\\usr\\bin',
196
+ 'C:\\msys64\\usr\\bin',
197
+ 'C:\\msys64\\bin',
198
+ 'C:\\cygwin64\\bin',
199
+ 'C:\\cygwin\\bin',
200
+ 'C:\\MinGW\\bin',
201
+ 'C:\\MinGW\\msys\\1.0\\bin'
202
+ ];
203
+ for (const location of locationsToCheck) {
204
+ const potentialPath = path.join(location, 'bash.exe');
205
+ if (fs.existsSync(potentialPath)) {
206
+ cmd = potentialPath;
207
+ args = [found, ...process.argv.slice(2)];
208
+ break;
209
+ }
210
+ }
211
+ }
212
+ } else {
213
+ cmd = resolvedOrNull || interpreter;
214
+ args = [found, ...process.argv.slice(2)];
215
+ }
216
+ } else {
217
+ cmd = found;
218
+ args = process.argv.slice(2);
219
+ }
220
+ } else {
221
+ cmd = found;
222
+ args = process.argv.slice(2);
223
+ }
224
+
225
+ console.log(
226
+ `Executing: ${path.isAbsolute(cmd) ? path.relative(process.cwd(), cmd) : cmd} ${args
227
+ .map((f) => {
228
+ if (path.isAbsolute(f)) return path.relative(process.cwd(), f);
229
+ return f;
230
+ })
231
+ .join(' ')}`
232
+ );
233
+
234
+ /**
235
+ * Execute the selected script synchronously.
236
+ *
237
+ * stdio: "inherit"
238
+ * Shares the current terminal with the child process,
239
+ * so stdout/stderr/input behave normally.
240
+ *
241
+ * spawnSync waits until the child process exits.
242
+ */
243
+ const result = spawnSync(cmd, args, {
244
+ stdio: 'inherit'
245
+ });
246
+
247
+ /**
248
+ * Exit using the same exit code
249
+ * returned by the child process.
250
+ *
251
+ * If result.status is null/undefined,
252
+ * default to exit code 1.
253
+ */
254
+ process.exit(result.status ?? 1);
package/binaries/ycw ADDED
@@ -0,0 +1,256 @@
1
+ #!/bin/bash
2
+ set -u
3
+
4
+ cwd="$(pwd)"
5
+ max_jobs=4
6
+
7
+ usage() {
8
+ cat <<'EOF'
9
+ Usage: ycw [options]
10
+
11
+ Clean node_modules directories across a Yarn monorepo (workspaces-aware).
12
+
13
+ This tool:
14
+ - Automatically detects monorepo root via package.json "workspaces"
15
+ - Expands workspace globs (e.g. packages/*)
16
+ - Removes node_modules in root + all workspace packages
17
+ - Runs partial cleanup in parallel for speed
18
+
19
+ Options:
20
+ -h, --help Show this help message and exit
21
+ -c, --concurrent <num> Maximum parallel jobs (default: 4)
22
+
23
+ Behavior:
24
+ • Root is detected by scanning upward for package.json with "workspaces"
25
+ • Workspace patterns are read from package.json (no jq required)
26
+ • node_modules folders are removed in two phases:
27
+ 1. Partial cleanup (letter-based parallel deletion)
28
+ 2. Final full removal of remaining node_modules directories
29
+
30
+ Notes:
31
+ - Designed for Yarn workspaces monorepos
32
+ - Safe fallback: if no root is detected, current directory is used
33
+ - Uses rm -rf (destructive operation)
34
+
35
+ Example:
36
+ ycw
37
+ ycw --help
38
+ ycw -c 8
39
+
40
+ EOF
41
+ }
42
+
43
+ while [[ $# -gt 0 ]]; do
44
+ case "$1" in
45
+ -h|--help) usage; exit 0 ;;
46
+ -c|--concurrent) max_jobs="$2"; shift 2 ;;
47
+ *) shift ;;
48
+ esac
49
+ done
50
+
51
+ # colors
52
+ GREEN='\033[0;32m'
53
+ RED='\033[0;31m'
54
+ GRAY='\033[0;90m'
55
+ BLUE='\033[0;34m'
56
+ NC='\033[0m'
57
+
58
+ timestamp() {
59
+ date "+%Y-%m-%d %H:%M:%S"
60
+ }
61
+
62
+ relative_path() {
63
+ local path="$1"
64
+ path="${path#"$cwd"/}"
65
+ [[ "$path" == "$cwd" ]] && path="."
66
+ echo "$path"
67
+ }
68
+
69
+ log() {
70
+ local level="$1"
71
+ shift
72
+
73
+ local color="$NC"
74
+ case "$level" in
75
+ OK) color="$GREEN" ;;
76
+ FAIL) color="$RED" ;;
77
+ SKIP) color="$GRAY" ;;
78
+ INFO) color="$BLUE" ;;
79
+ esac
80
+
81
+ echo -e "[${GRAY}$(timestamp)${NC}] [${color}${level}${NC}] $*"
82
+ }
83
+
84
+ # -----------------------------------
85
+ # find project root (NO GIT)
86
+ # -----------------------------------
87
+ find_root() {
88
+ local dir="$cwd"
89
+
90
+ while [[ "$dir" != "/" ]]; do
91
+ if [[ -f "$dir/package.json" ]] && grep -q '"workspaces"' "$dir/package.json" 2>/dev/null; then
92
+ echo "$dir"
93
+ return 0
94
+ fi
95
+ dir="$(dirname "$dir")"
96
+ done
97
+
98
+ echo "$cwd"
99
+ }
100
+
101
+ ROOT="$(find_root)"
102
+ cwd="$ROOT"
103
+
104
+ log INFO "Using root: $(relative_path "$ROOT")"
105
+
106
+ # -----------------------------------
107
+ # parse workspaces from package.json
108
+ # -----------------------------------
109
+ get_workspaces() {
110
+ local pkg="$ROOT/package.json"
111
+
112
+ # naive JSON parsing (no jq required)
113
+ # supports:
114
+ # "workspaces": ["packages/*"] OR { "packages": [] }
115
+
116
+ grep -oP '"workspaces"\s*:\s*\K\[[^\]]+\]' "$pkg" 2>/dev/null |
117
+ tr -d '[]"' |
118
+ tr ',' '\n' |
119
+ sed 's/^[[:space:]]*//;s/[[:space:]]*$//'
120
+ }
121
+
122
+ # -----------------------------------
123
+ # expand glob patterns safely
124
+ # -----------------------------------
125
+ expand_glob() {
126
+ local pattern="$1"
127
+
128
+ for dir in $pattern; do
129
+ [[ -d "$dir" ]] && echo "$ROOT/$dir"
130
+ done
131
+ }
132
+
133
+ # -----------------------------------
134
+ # collect node_modules targets
135
+ # -----------------------------------
136
+ declare -a NODE_MODULES_TARGETS
137
+
138
+ # root
139
+ NODE_MODULES_TARGETS+=("$ROOT/node_modules")
140
+
141
+ # workspaces
142
+ while IFS= read -r pattern; do
143
+ [[ -z "$pattern" ]] && continue
144
+
145
+ while IFS= read -r ws; do
146
+ NODE_MODULES_TARGETS+=("$ws/node_modules")
147
+ done < <(expand_glob "$pattern")
148
+
149
+ done < <(get_workspaces)
150
+
151
+ # -----------------------------------
152
+ # deduplicate
153
+ # -----------------------------------
154
+ declare -A seen
155
+ declare -a unique
156
+
157
+ for t in "${NODE_MODULES_TARGETS[@]}"; do
158
+ [[ -z "$t" ]] && continue
159
+ [[ -n "${seen[$t]:-}" ]] && continue
160
+ seen["$t"]=1
161
+ unique+=("$t")
162
+ done
163
+
164
+ NODE_MODULES_TARGETS=("${unique[@]}")
165
+
166
+ # -----------------------------------
167
+ # cleanup function
168
+ # -----------------------------------
169
+ cleanup_letter() {
170
+ local base="$1"
171
+ local letter="$2"
172
+
173
+ [[ -d "$base" ]] || return 0
174
+
175
+ shopt -s nullglob
176
+
177
+ local targets=(
178
+ "${base}/${letter}"*
179
+ "${base}/@types/${letter}"*
180
+ "${base}/@${letter}"*
181
+ )
182
+
183
+ local removed_any=0
184
+
185
+ for path in "${targets[@]}"; do
186
+ [[ -e "$path" ]] || continue
187
+
188
+ local rel
189
+ rel="$(relative_path "$path")"
190
+
191
+ if rm -rf "$path"; then
192
+ log OK "$rel"
193
+ removed_any=1
194
+ else
195
+ log FAIL "$rel"
196
+ fi
197
+ done
198
+
199
+ if (( removed_any == 0 )); then
200
+ log SKIP "$(relative_path "$base") '${letter}'"
201
+ fi
202
+ }
203
+
204
+ # export for parallel
205
+ export -f cleanup_letter
206
+ export -f log
207
+ export -f timestamp
208
+ export -f relative_path
209
+ export cwd GREEN RED GRAY BLUE NC ROOT
210
+
211
+ log INFO "Detected ${#NODE_MODULES_TARGETS[@]} node_modules directories"
212
+
213
+ for t in "${NODE_MODULES_TARGETS[@]}"; do
214
+ log INFO "$(relative_path "$t")"
215
+ done
216
+
217
+ # -----------------------------------
218
+ # parallel deletion
219
+ # -----------------------------------
220
+ running=0
221
+
222
+ for base in "${NODE_MODULES_TARGETS[@]}"; do
223
+ for letter in $(printf "%s\n" {a..z} | shuf); do
224
+
225
+ cleanup_letter "$base" "$letter" &
226
+
227
+ ((running++))
228
+
229
+ if (( running >= max_jobs )); then
230
+ wait -n
231
+ ((running--))
232
+ fi
233
+
234
+ done
235
+ done
236
+
237
+ wait
238
+
239
+ # -----------------------------------
240
+ # final cleanup
241
+ # -----------------------------------
242
+ log INFO "Removing remaining node_modules directories"
243
+
244
+ for target in "${NODE_MODULES_TARGETS[@]}"; do
245
+ [[ -e "$target" ]] || continue
246
+
247
+ rel="$(relative_path "$target")"
248
+
249
+ if rm -rf "$target"; then
250
+ log OK "$rel"
251
+ else
252
+ log FAIL "$rel"
253
+ fi
254
+ done
255
+
256
+ log INFO "Done"