buncargo 1.0.26 → 3.0.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 (222) hide show
  1. package/dist/bin.d.ts +1 -12
  2. package/dist/bin.js +261 -252
  3. package/dist/cli/bin.d.ts +13 -0
  4. package/dist/cli/bin.js +315 -0
  5. package/dist/cli/commands/help.d.ts +1 -0
  6. package/dist/cli/commands/runtime.d.ts +5 -0
  7. package/dist/cli/commands/version.d.ts +1 -0
  8. package/dist/cli/index.d.ts +1 -0
  9. package/dist/cli/index.js +14 -0
  10. package/dist/cli/run-cli.d.ts +22 -0
  11. package/dist/cli.d.ts +1 -22
  12. package/dist/cli.js +5 -13
  13. package/dist/config/config.d.ts +1 -0
  14. package/dist/config/define-config.d.ts +13 -0
  15. package/dist/config/index.d.ts +3 -0
  16. package/dist/config/index.js +15 -0
  17. package/dist/config/merge-configs.d.ts +3 -0
  18. package/dist/config/validate-config.d.ts +3 -0
  19. package/dist/config.d.ts +1 -72
  20. package/dist/config.js +12 -12
  21. package/dist/core/docker.d.ts +1 -74
  22. package/dist/core/docker.js +35 -26
  23. package/dist/core/index.d.ts +1 -1
  24. package/dist/core/index.js +123 -108
  25. package/dist/core/network.js +2 -2
  26. package/dist/core/ports.d.ts +22 -0
  27. package/dist/core/ports.js +5 -1
  28. package/dist/core/process.js +1 -1
  29. package/dist/core/tunnel.d.ts +33 -0
  30. package/dist/core/utils.js +2 -2
  31. package/dist/core/watchdog-runner.js +45 -42
  32. package/dist/core/watchdog.d.ts +1 -0
  33. package/dist/core/watchdog.js +4 -2
  34. package/dist/docker/index.d.ts +1 -0
  35. package/dist/docker/index.js +38 -0
  36. package/dist/docker/runtime.d.ts +87 -0
  37. package/dist/docker/runtime.js +37 -0
  38. package/dist/docker-compose/compose.d.ts +1 -0
  39. package/dist/docker-compose/generated-file.d.ts +7 -0
  40. package/dist/docker-compose/index.d.ts +3 -0
  41. package/dist/docker-compose/index.js +15 -0
  42. package/dist/docker-compose/model.d.ts +6 -0
  43. package/dist/docker-compose/services/clickhouse.d.ts +16 -0
  44. package/dist/docker-compose/services/define-docker-service.d.ts +41 -0
  45. package/dist/docker-compose/services/index.d.ts +23 -0
  46. package/dist/docker-compose/services/index.js +17 -0
  47. package/dist/docker-compose/services/postgres.d.ts +12 -0
  48. package/dist/docker-compose/services/redis.d.ts +12 -0
  49. package/dist/docker-compose/services/shared.d.ts +7 -0
  50. package/dist/docker-compose/yaml.d.ts +2 -0
  51. package/dist/environment/create-dev-environment.d.ts +23 -0
  52. package/dist/environment/index.d.ts +1 -0
  53. package/dist/environment/index.js +15 -0
  54. package/dist/environment/logging.d.ts +17 -0
  55. package/dist/environment/seeding.d.ts +9 -0
  56. package/dist/environment.d.ts +1 -23
  57. package/dist/environment.js +12 -14
  58. package/dist/index-045jksh5.js +147 -0
  59. package/dist/index-08wa79cs.js +125 -117
  60. package/dist/index-0kxnae3z.js +335 -0
  61. package/dist/index-1mdrf7nz.js +66 -0
  62. package/dist/index-1yvbwj4k.js +262 -242
  63. package/dist/index-23ev345g.js +475 -0
  64. package/dist/index-2ckr49sf.js +228 -0
  65. package/dist/index-2f47khe5.js +376 -369
  66. package/dist/index-2fr3g85b.js +220 -183
  67. package/dist/index-38xnzpa6.js +450 -0
  68. package/dist/index-3h3dhtf2.js +51 -43
  69. package/dist/index-42x95209.js +51 -43
  70. package/dist/index-4gp0az1g.js +145 -0
  71. package/dist/index-4xrxh8yv.js +72 -0
  72. package/dist/index-5gmws6ah.js +181 -0
  73. package/dist/index-5hka0tff.js +78 -76
  74. package/dist/index-5rfqps4b.js +3 -0
  75. package/dist/index-5t9jxqm0.js +428 -0
  76. package/dist/index-6c1w1xk5.js +101 -0
  77. package/dist/index-6fm7mvwj.js +118 -97
  78. package/dist/index-6srpc523.js +127 -128
  79. package/dist/index-731rzzfp.js +187 -0
  80. package/dist/index-75y4cg2z.js +51 -43
  81. package/dist/index-7ja4ywyj.js +126 -127
  82. package/dist/index-8bw1cmz4.js +531 -0
  83. package/dist/index-8hbbj1mp.js +120 -121
  84. package/dist/index-8xj2p5n5.js +145 -0
  85. package/dist/index-bj79tw5w.js +0 -0
  86. package/dist/index-bnk6nr0g.js +73 -0
  87. package/dist/index-brbbzyks.js +72 -0
  88. package/dist/index-c0dr6mcv.js +123 -0
  89. package/dist/index-cty0bcry.js +235 -218
  90. package/dist/index-d8tyv5se.js +228 -0
  91. package/dist/index-d9efy0n4.js +176 -150
  92. package/dist/index-etfmqjjf.js +427 -0
  93. package/dist/index-fb29934k.js +172 -0
  94. package/dist/index-g50jw1yf.js +72 -0
  95. package/dist/index-g6eb5wdw.js +118 -117
  96. package/dist/index-ggq3yryx.js +99 -95
  97. package/dist/index-h70tce00.js +177 -0
  98. package/dist/index-hkxtfqtc.js +333 -0
  99. package/dist/index-kf3dhser.js +146 -143
  100. package/dist/index-ma6tgdb2.js +500 -0
  101. package/dist/index-mam0bcyz.js +123 -0
  102. package/dist/index-mm412dkp.js +274 -0
  103. package/dist/index-n8v18aeb.js +0 -0
  104. package/dist/index-ndnmnsej.js +378 -371
  105. package/dist/index-p8wty0e2.js +389 -379
  106. package/dist/index-qfphr2fd.js +100 -0
  107. package/dist/index-qqmms8rs.js +51 -43
  108. package/dist/index-qw4093g2.js +51 -43
  109. package/dist/index-qzwpzjbx.js +121 -122
  110. package/dist/index-segbnm0h.js +146 -143
  111. package/dist/index-t0fj6gg1.js +112 -0
  112. package/dist/index-thdkwnv7.js +122 -0
  113. package/dist/index-tjbx2r2t.js +270 -0
  114. package/dist/index-tjqw9vtj.js +62 -54
  115. package/dist/index-vbpb89jy.js +248 -0
  116. package/dist/index-vhs88xhe.js +99 -95
  117. package/dist/index-w8zxnjka.js +249 -0
  118. package/dist/index-wk2na3t9.js +404 -0
  119. package/dist/index-wz9x8g7z.js +383 -373
  120. package/dist/index-x249gyde.js +388 -378
  121. package/dist/index-xkvd0nsd.js +187 -0
  122. package/dist/index-yedqxm1z.js +80 -0
  123. package/dist/index-zfjzzjkf.js +266 -0
  124. package/dist/index.d.ts +12 -8
  125. package/dist/index.js +66 -35
  126. package/dist/lint.d.ts +1 -46
  127. package/dist/lint.js +3 -7
  128. package/dist/loader/cache.d.ts +4 -0
  129. package/dist/loader/find-config-file.d.ts +2 -0
  130. package/dist/loader/index.d.ts +5 -0
  131. package/dist/loader/index.js +24 -0
  132. package/dist/loader/load-dev-env.d.ts +5 -0
  133. package/dist/loader/loader.d.ts +1 -0
  134. package/dist/loader.d.ts +1 -45
  135. package/dist/loader.js +22 -20
  136. package/dist/prisma/index.d.ts +1 -0
  137. package/dist/prisma/prisma.d.ts +29 -0
  138. package/dist/prisma.d.ts +1 -29
  139. package/dist/prisma.js +6 -10
  140. package/dist/src/bin.js +309 -0
  141. package/dist/src/cli.js +5 -0
  142. package/dist/src/config.js +15 -0
  143. package/dist/src/core/docker.js +38 -0
  144. package/dist/src/core/index.js +130 -0
  145. package/dist/src/core/network.js +9 -0
  146. package/dist/src/core/ports.js +23 -0
  147. package/dist/src/core/process.js +31 -0
  148. package/dist/src/core/utils.js +11 -0
  149. package/dist/src/core/watchdog-runner.js +69 -0
  150. package/dist/src/core/watchdog.js +28 -0
  151. package/dist/src/docker/runtime.js +37 -0
  152. package/dist/src/docker-compose/index.js +16 -0
  153. package/dist/src/docker-compose/services/index.js +17 -0
  154. package/dist/src/environment.js +12 -0
  155. package/dist/src/index.js +122 -0
  156. package/dist/src/lint.js +3 -0
  157. package/dist/src/loader.js +25 -0
  158. package/dist/src/prisma.js +6 -0
  159. package/dist/src/types.js +0 -0
  160. package/dist/typecheck/index.d.ts +1 -0
  161. package/dist/typecheck/index.js +7 -0
  162. package/dist/typecheck/typecheck.d.ts +46 -0
  163. package/dist/types/all-types.d.ts +501 -0
  164. package/dist/types/cli.d.ts +1 -0
  165. package/dist/types/config.d.ts +6 -0
  166. package/dist/types/docker.d.ts +15 -0
  167. package/dist/types/environment.d.ts +8 -0
  168. package/dist/types/hooks.d.ts +9 -0
  169. package/dist/types/index.d.ts +1 -0
  170. package/dist/types/index.js +0 -0
  171. package/dist/types/prisma.d.ts +1 -0
  172. package/dist/types.d.ts +1 -393
  173. package/package.json +145 -140
  174. package/readme.md +358 -105
  175. package/src/cli/bin.ts +77 -0
  176. package/src/cli/commands/help.ts +39 -0
  177. package/src/cli/commands/runtime.ts +72 -0
  178. package/src/cli/commands/version.ts +4 -0
  179. package/src/cli/index.ts +1 -0
  180. package/{cli.ts → src/cli/run-cli.ts} +95 -6
  181. package/src/config/define-config.ts +30 -0
  182. package/src/config/index.ts +3 -0
  183. package/src/config/merge-configs.ts +33 -0
  184. package/src/config/validate-config.ts +136 -0
  185. package/{core → src/core}/index.ts +2 -2
  186. package/{core → src/core}/ports.ts +68 -1
  187. package/{core → src/core}/process.ts +6 -2
  188. package/src/core/tunnel.ts +151 -0
  189. package/{core → src/core}/utils.ts +1 -0
  190. package/{core → src/core}/watchdog.ts +5 -1
  191. package/src/docker/index.ts +1 -0
  192. package/{core/docker.ts → src/docker/runtime.ts} +40 -4
  193. package/src/docker-compose/generated-file.ts +45 -0
  194. package/src/docker-compose/index.ts +7 -0
  195. package/src/docker-compose/model.ts +197 -0
  196. package/src/docker-compose/services/clickhouse.ts +79 -0
  197. package/src/docker-compose/services/define-docker-service.ts +109 -0
  198. package/src/docker-compose/services/index.ts +67 -0
  199. package/src/docker-compose/services/postgres.ts +60 -0
  200. package/src/docker-compose/services/redis.ts +48 -0
  201. package/src/docker-compose/services/shared.ts +79 -0
  202. package/src/docker-compose/yaml.ts +88 -0
  203. package/{environment.ts → src/environment/create-dev-environment.ts} +101 -146
  204. package/src/environment/index.ts +1 -0
  205. package/src/environment/logging.ts +101 -0
  206. package/src/environment/seeding.ts +57 -0
  207. package/{index.ts → src/index.ts} +49 -15
  208. package/src/loader/cache.ts +23 -0
  209. package/src/loader/find-config-file.ts +29 -0
  210. package/src/loader/index.ts +17 -0
  211. package/src/loader/load-dev-env.ts +38 -0
  212. package/src/prisma/index.ts +1 -0
  213. package/{prisma.ts → src/prisma/prisma.ts} +4 -2
  214. package/src/typecheck/index.ts +1 -0
  215. package/{types.ts → src/types/all-types.ts} +137 -6
  216. package/src/types/index.ts +1 -0
  217. package/bin.ts +0 -191
  218. package/config.ts +0 -194
  219. package/loader.ts +0 -126
  220. /package/{core → src/core}/network.ts +0 -0
  221. /package/{core → src/core}/watchdog-runner.ts +0 -0
  222. /package/{lint.ts → src/typecheck/typecheck.ts} +0 -0
@@ -0,0 +1,228 @@
1
+ import {
2
+ sleep
3
+ } from "./index-c0dr6mcv.js";
4
+
5
+ // src/docker/runtime.ts
6
+ import { execSync } from "node:child_process";
7
+ var POLL_INTERVAL = 250;
8
+ var MAX_ATTEMPTS = 120;
9
+ var DOCKER_NOT_RUNNING_MESSAGE = "Docker is not running. Please start Docker and try again.";
10
+ async function isContainerRunning(project, service) {
11
+ try {
12
+ const result = execSync(`docker ps --filter "label=com.docker.compose.project=${project}" --filter "label=com.docker.compose.service=${service}" --format "{{.State}}"`, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
13
+ return result.trim() === "running";
14
+ } catch {
15
+ return false;
16
+ }
17
+ }
18
+ function isDockerRunning() {
19
+ try {
20
+ execSync('docker info --format "{{.ServerVersion}}"', {
21
+ encoding: "utf-8",
22
+ stdio: ["pipe", "pipe", "pipe"]
23
+ });
24
+ return true;
25
+ } catch {
26
+ return false;
27
+ }
28
+ }
29
+ function assertDockerRunning() {
30
+ if (!isDockerRunning()) {
31
+ throw new Error(DOCKER_NOT_RUNNING_MESSAGE);
32
+ }
33
+ }
34
+ async function areContainersRunning(project, minCount = 1) {
35
+ try {
36
+ const result = execSync(`docker ps --filter "label=com.docker.compose.project=${project}" --format "{{.State}}"`, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
37
+ const states = result.trim().split(`
38
+ `).filter(Boolean);
39
+ if (states.length < minCount)
40
+ return false;
41
+ return states.every((state) => state === "running");
42
+ } catch {
43
+ return false;
44
+ }
45
+ }
46
+ function getComposeArg(composeFile) {
47
+ return composeFile ? `-f "${composeFile}"` : "";
48
+ }
49
+ function startContainers(root, projectName, envVars, options = {}) {
50
+ const { verbose = true, wait = true, composeFile } = options;
51
+ assertDockerRunning();
52
+ if (verbose)
53
+ console.log("\uD83D\uDC33 Starting Docker containers...");
54
+ const composeArg = getComposeArg(composeFile);
55
+ const waitFlag = wait ? "--wait" : "";
56
+ const cmd = `docker compose ${composeArg} up -d ${waitFlag}`.trim();
57
+ execSync(cmd, {
58
+ cwd: root,
59
+ env: { ...process.env, ...envVars, COMPOSE_PROJECT_NAME: projectName },
60
+ stdio: verbose ? "inherit" : "ignore"
61
+ });
62
+ if (verbose)
63
+ console.log("✓ Containers started");
64
+ }
65
+ function stopContainers(root, projectName, options = {}) {
66
+ const { verbose = true, removeVolumes = false, composeFile } = options;
67
+ assertDockerRunning();
68
+ if (verbose) {
69
+ console.log(removeVolumes ? "\uD83D\uDDD1️ Stopping containers and removing volumes..." : "\uD83D\uDED1 Stopping containers...");
70
+ }
71
+ const composeArg = getComposeArg(composeFile);
72
+ const volumeFlag = removeVolumes ? "-v" : "";
73
+ const cmd = `docker compose ${composeArg} down ${volumeFlag}`.trim();
74
+ execSync(cmd, {
75
+ cwd: root,
76
+ env: { ...process.env, COMPOSE_PROJECT_NAME: projectName },
77
+ stdio: verbose ? "inherit" : "ignore"
78
+ });
79
+ if (verbose)
80
+ console.log("✓ Containers stopped");
81
+ }
82
+ function startService(root, projectName, serviceName, envVars, options = {}) {
83
+ const { verbose = true, composeFile } = options;
84
+ assertDockerRunning();
85
+ if (verbose)
86
+ console.log(`\uD83D\uDC33 Starting ${serviceName}...`);
87
+ const composeArg = getComposeArg(composeFile);
88
+ const cmd = `docker compose ${composeArg} up -d ${serviceName}`.trim();
89
+ execSync(cmd, {
90
+ cwd: root,
91
+ env: { ...process.env, ...envVars, COMPOSE_PROJECT_NAME: projectName },
92
+ stdio: verbose ? "inherit" : "ignore"
93
+ });
94
+ }
95
+ function createBuiltInHealthCheck(type, serviceName, context = {}) {
96
+ const { projectName, root } = context;
97
+ switch (type) {
98
+ case "pg_isready":
99
+ return async () => {
100
+ try {
101
+ const projectArg = projectName ? `-p ${projectName}` : "";
102
+ execSync(`docker compose ${projectArg} exec -T ${serviceName} pg_isready -U postgres`, {
103
+ cwd: root,
104
+ stdio: ["pipe", "pipe", "pipe"]
105
+ });
106
+ return true;
107
+ } catch {
108
+ return false;
109
+ }
110
+ };
111
+ case "redis-cli":
112
+ return async () => {
113
+ try {
114
+ const projectArg = projectName ? `-p ${projectName}` : "";
115
+ execSync(`docker compose ${projectArg} exec -T ${serviceName} redis-cli ping`, {
116
+ cwd: root,
117
+ stdio: ["pipe", "pipe", "pipe"]
118
+ });
119
+ return true;
120
+ } catch {
121
+ return false;
122
+ }
123
+ };
124
+ case "http":
125
+ return async (port) => {
126
+ try {
127
+ const controller = new AbortController;
128
+ const timeoutId = setTimeout(() => controller.abort(), 2000);
129
+ try {
130
+ const response = await fetch(`http://localhost:${port}/`, {
131
+ signal: controller.signal
132
+ });
133
+ clearTimeout(timeoutId);
134
+ return response.ok || response.status === 404;
135
+ } catch {
136
+ clearTimeout(timeoutId);
137
+ return false;
138
+ }
139
+ } catch {
140
+ return false;
141
+ }
142
+ };
143
+ case "tcp":
144
+ return async (port) => {
145
+ try {
146
+ const controller = new AbortController;
147
+ const timeoutId = setTimeout(() => controller.abort(), 1000);
148
+ try {
149
+ await fetch(`http://localhost:${port}/`, {
150
+ signal: controller.signal
151
+ });
152
+ clearTimeout(timeoutId);
153
+ return true;
154
+ } catch (error) {
155
+ clearTimeout(timeoutId);
156
+ if (error instanceof Error && error.message.includes("ECONNREFUSED")) {
157
+ return false;
158
+ }
159
+ return true;
160
+ }
161
+ } catch {
162
+ return false;
163
+ }
164
+ };
165
+ default:
166
+ return async () => true;
167
+ }
168
+ }
169
+ async function waitForService(serviceName, config, port, options = {}) {
170
+ const {
171
+ maxAttempts = MAX_ATTEMPTS,
172
+ pollInterval = POLL_INTERVAL,
173
+ projectName,
174
+ root
175
+ } = options;
176
+ if (config.healthCheck === false || config.healthCheck === undefined) {
177
+ return;
178
+ }
179
+ const healthCheckFn = typeof config.healthCheck === "function" ? config.healthCheck : createBuiltInHealthCheck(config.healthCheck, config.serviceName ?? serviceName, { projectName, root });
180
+ for (let i = 0;i < maxAttempts; i++) {
181
+ const isHealthy = await healthCheckFn(port);
182
+ if (isHealthy)
183
+ return;
184
+ await sleep(pollInterval);
185
+ }
186
+ throw new Error(`Service ${serviceName} did not become ready in time`);
187
+ }
188
+ async function waitForAllServices(services, ports, options = {}) {
189
+ const { verbose = true, ...waitOptions } = options;
190
+ if (verbose)
191
+ console.log("⏳ Waiting for services to be healthy...");
192
+ const promises = Object.entries(services).map(([name, config]) => {
193
+ const port = ports[name];
194
+ if (port === undefined) {
195
+ console.warn(`⚠️ No port found for service ${name}, skipping health check`);
196
+ return Promise.resolve();
197
+ }
198
+ return waitForService(name, config, port, waitOptions);
199
+ });
200
+ await Promise.all(promises);
201
+ if (verbose)
202
+ console.log("✓ All services healthy");
203
+ }
204
+ async function waitForServiceByType(serviceName, healthCheckType, port, options = {}) {
205
+ const {
206
+ maxAttempts = MAX_ATTEMPTS,
207
+ pollInterval = POLL_INTERVAL,
208
+ verbose = false,
209
+ projectName,
210
+ root
211
+ } = options;
212
+ const healthCheckFn = createBuiltInHealthCheck(healthCheckType, serviceName, {
213
+ projectName,
214
+ root
215
+ });
216
+ for (let i = 0;i < maxAttempts; i++) {
217
+ const isHealthy = await healthCheckFn(port);
218
+ if (isHealthy) {
219
+ if (verbose)
220
+ console.log(`✓ ${serviceName} is ready`);
221
+ return;
222
+ }
223
+ await sleep(pollInterval);
224
+ }
225
+ throw new Error(`Service ${serviceName} did not become ready in time`);
226
+ }
227
+
228
+ export { POLL_INTERVAL, MAX_ATTEMPTS, DOCKER_NOT_RUNNING_MESSAGE, isContainerRunning, isDockerRunning, assertDockerRunning, areContainersRunning, getComposeArg, startContainers, stopContainers, startService, createBuiltInHealthCheck, waitForService, waitForAllServices, waitForServiceByType };
@@ -3,176 +3,202 @@ import { execSync } from "node:child_process";
3
3
  import { readFileSync, unlinkSync } from "node:fs";
4
4
  import { join } from "node:path";
5
5
  import fg from "fast-glob";
6
+
6
7
  var DEFAULT_PATTERNS = ["apps/*", "packages/*", "modules"];
7
8
  var DEFAULT_CONCURRENCY = 1;
8
9
  var CORRUPTED_CACHE_PATTERNS = [
9
- "all goroutines are asleep - deadlock",
10
- "fatal error:",
11
- "panic:",
12
- "github.com/microsoft/typescript-go"
10
+ "all goroutines are asleep - deadlock",
11
+ "fatal error:",
12
+ "panic:",
13
+ "github.com/microsoft/typescript-go",
13
14
  ];
14
15
  function isCorruptedCacheError(output) {
15
- return CORRUPTED_CACHE_PATTERNS.some((pattern) => output.includes(pattern));
16
+ return CORRUPTED_CACHE_PATTERNS.some((pattern) => output.includes(pattern));
16
17
  }
17
18
  async function clearTsBuildInfo(workspace, verbose) {
18
- if (verbose) {
19
- console.log(`\uD83E\uDDF9 Clearing corrupted tsbuildinfo cache for ${workspace}...`);
20
- }
21
- try {
22
- const tsbuildInfoFiles = await fg(`${workspace}/**/*.tsbuildinfo`, {
23
- absolute: true
24
- });
25
- for (const file of tsbuildInfoFiles) {
26
- try {
27
- unlinkSync(file);
28
- } catch {}
29
- }
30
- const cacheFiles = await fg(`${workspace}/**/.cache/tsbuildinfo.json`, {
31
- absolute: true
32
- });
33
- for (const file of cacheFiles) {
34
- try {
35
- unlinkSync(file);
36
- } catch {}
37
- }
38
- } catch {}
19
+ if (verbose) {
20
+ console.log(
21
+ `\uD83E\uDDF9 Clearing corrupted tsbuildinfo cache for ${workspace}...`,
22
+ );
23
+ }
24
+ try {
25
+ const tsbuildInfoFiles = await fg(`${workspace}/**/*.tsbuildinfo`, {
26
+ absolute: true,
27
+ });
28
+ for (const file of tsbuildInfoFiles) {
29
+ try {
30
+ unlinkSync(file);
31
+ } catch {}
32
+ }
33
+ const cacheFiles = await fg(`${workspace}/**/.cache/tsbuildinfo.json`, {
34
+ absolute: true,
35
+ });
36
+ for (const file of cacheFiles) {
37
+ try {
38
+ unlinkSync(file);
39
+ } catch {}
40
+ }
41
+ } catch {}
39
42
  }
40
43
  async function countTypeScriptFiles(pkgPath, root) {
41
- const files = await fg(`${pkgPath}/**/*.{ts,tsx}`, {
42
- cwd: root,
43
- ignore: ["**/node_modules/**"]
44
- });
45
- return files.length;
44
+ const files = await fg(`${pkgPath}/**/*.{ts,tsx}`, {
45
+ cwd: root,
46
+ ignore: ["**/node_modules/**"],
47
+ });
48
+ return files.length;
46
49
  }
47
50
  function formatErrorOutput(output) {
48
- return output.split(`
49
- `).map((line) => {
50
- return line.replace(/\.\.\/\.\.\/packages\/modules\//g, "").replace(/\((\d+),(\d+)\):?/g, ":$1:$2 -");
51
- }).join(`
52
- `).trim();
51
+ return output
52
+ .split(`
53
+ `)
54
+ .map((line) => {
55
+ return line
56
+ .replace(/\.\.\/\.\.\/packages\/modules\//g, "")
57
+ .replace(/\((\d+),(\d+)\):?/g, ":$1:$2 -");
58
+ })
59
+ .join(`
60
+ `)
61
+ .trim();
53
62
  }
54
- async function runSingleTypecheck(workspace, fileCount, root, verbose, isRetry = false) {
55
- const startTime = performance.now();
56
- if (verbose) {
57
- console.log(`Running typecheck in ${workspace} (${fileCount} files)${isRetry ? " (retry)" : ""}...`);
58
- }
59
- const workspacePath = join(root, workspace);
60
- let success = false;
61
- let stdout = "";
62
- let stderr = "";
63
- try {
64
- const output = execSync("bun run typecheck", {
65
- cwd: workspacePath,
66
- encoding: "utf-8",
67
- stdio: ["pipe", "pipe", "pipe"]
68
- });
69
- stdout = output ?? "";
70
- success = true;
71
- } catch (error) {
72
- const execError = error;
73
- stdout = execError.stdout ?? "";
74
- stderr = execError.stderr ?? "";
75
- success = false;
76
- }
77
- const duration = Number(((performance.now() - startTime) / 1000).toFixed(2));
78
- let errorOutput;
79
- if (!success) {
80
- const parts = [stdout.trim(), stderr.trim()].filter(Boolean);
81
- errorOutput = parts.length > 0 ? parts.join(`
82
- `) : undefined;
83
- if (!isRetry && errorOutput && isCorruptedCacheError(errorOutput)) {
84
- await clearTsBuildInfo(workspacePath, verbose);
85
- return runSingleTypecheck(workspace, fileCount, root, verbose, true);
86
- }
87
- }
88
- return { workspace, duration, success, fileCount, errorOutput };
63
+ async function runSingleTypecheck(
64
+ workspace,
65
+ fileCount,
66
+ root,
67
+ verbose,
68
+ isRetry = false,
69
+ ) {
70
+ const startTime = performance.now();
71
+ if (verbose) {
72
+ console.log(
73
+ `Running typecheck in ${workspace} (${fileCount} files)${isRetry ? " (retry)" : ""}...`,
74
+ );
75
+ }
76
+ const workspacePath = join(root, workspace);
77
+ let success = false;
78
+ let stdout = "";
79
+ let stderr = "";
80
+ try {
81
+ const output = execSync("bun run typecheck", {
82
+ cwd: workspacePath,
83
+ encoding: "utf-8",
84
+ stdio: ["pipe", "pipe", "pipe"],
85
+ });
86
+ stdout = output ?? "";
87
+ success = true;
88
+ } catch (error) {
89
+ const execError = error;
90
+ stdout = execError.stdout ?? "";
91
+ stderr = execError.stderr ?? "";
92
+ success = false;
93
+ }
94
+ const duration = Number(((performance.now() - startTime) / 1000).toFixed(2));
95
+ let errorOutput;
96
+ if (!success) {
97
+ const parts = [stdout.trim(), stderr.trim()].filter(Boolean);
98
+ errorOutput =
99
+ parts.length > 0
100
+ ? parts.join(`
101
+ `)
102
+ : undefined;
103
+ if (!isRetry && errorOutput && isCorruptedCacheError(errorOutput)) {
104
+ await clearTsBuildInfo(workspacePath, verbose);
105
+ return runSingleTypecheck(workspace, fileCount, root, verbose, true);
106
+ }
107
+ }
108
+ return { workspace, duration, success, fileCount, errorOutput };
89
109
  }
90
110
  async function discoverWorkspaces(patterns, root) {
91
- const workspaces = [];
92
- for (const pattern of patterns) {
93
- const matches = await fg(`${pattern}/package.json`, { cwd: root });
94
- for (const match of matches) {
95
- const pkgPath = match.replace("/package.json", "");
96
- try {
97
- const pkgJsonContent = readFileSync(join(root, match), "utf-8");
98
- const pkgJson = JSON.parse(pkgJsonContent);
99
- if (pkgJson.scripts?.typecheck) {
100
- const fileCount = await countTypeScriptFiles(pkgPath, root);
101
- workspaces.push({ path: pkgPath, fileCount });
102
- }
103
- } catch {}
104
- }
105
- }
106
- workspaces.sort((a, b) => a.fileCount - b.fileCount);
107
- return workspaces;
111
+ const workspaces = [];
112
+ for (const pattern of patterns) {
113
+ const matches = await fg(`${pattern}/package.json`, { cwd: root });
114
+ for (const match of matches) {
115
+ const pkgPath = match.replace("/package.json", "");
116
+ try {
117
+ const pkgJsonContent = readFileSync(join(root, match), "utf-8");
118
+ const pkgJson = JSON.parse(pkgJsonContent);
119
+ if (pkgJson.scripts?.typecheck) {
120
+ const fileCount = await countTypeScriptFiles(pkgPath, root);
121
+ workspaces.push({ path: pkgPath, fileCount });
122
+ }
123
+ } catch {}
124
+ }
125
+ }
126
+ workspaces.sort((a, b) => a.fileCount - b.fileCount);
127
+ return workspaces;
108
128
  }
109
129
  async function runWorkspaceTypecheck(options = {}) {
110
- const {
111
- root = process.cwd(),
112
- patterns = DEFAULT_PATTERNS,
113
- concurrency = DEFAULT_CONCURRENCY,
114
- verbose = true
115
- } = options;
116
- const workspaces = await discoverWorkspaces(patterns, root);
117
- if (workspaces.length === 0) {
118
- if (verbose) {
119
- console.log("No workspaces with typecheck script found.");
120
- }
121
- return {
122
- success: true,
123
- totalDuration: 0,
124
- totalFiles: 0,
125
- workspaceCount: 0,
126
- results: []
127
- };
128
- }
129
- const totalStartTime = performance.now();
130
- if (verbose) {
131
- console.log(`Running typecheck across ${workspaces.length} workspaces with concurrency limit of ${concurrency}...
130
+ const {
131
+ root = process.cwd(),
132
+ patterns = DEFAULT_PATTERNS,
133
+ concurrency = DEFAULT_CONCURRENCY,
134
+ verbose = true,
135
+ } = options;
136
+ const workspaces = await discoverWorkspaces(patterns, root);
137
+ if (workspaces.length === 0) {
138
+ if (verbose) {
139
+ console.log("No workspaces with typecheck script found.");
140
+ }
141
+ return {
142
+ success: true,
143
+ totalDuration: 0,
144
+ totalFiles: 0,
145
+ workspaceCount: 0,
146
+ results: [],
147
+ };
148
+ }
149
+ const totalStartTime = performance.now();
150
+ if (verbose) {
151
+ console.log(`Running typecheck across ${workspaces.length} workspaces with concurrency limit of ${concurrency}...
132
152
  `);
133
- }
134
- const results = [];
135
- const running = new Set;
136
- for (let i = 0;i < workspaces.length; i++) {
137
- const { path, fileCount } = workspaces[i];
138
- const promise = runSingleTypecheck(path, fileCount, root, verbose).then((result) => {
139
- results[i] = result;
140
- running.delete(promise);
141
- if (verbose) {
142
- const icon = result.success ? "✅" : "❌";
143
- const log = result.success ? console.log : console.error;
144
- log(`${icon} ${result.workspace} (${result.fileCount} files) ${result.success ? "completed" : "failed"} in ${result.duration.toFixed(2)}s`);
145
- if (!result.success && result.errorOutput) {
146
- console.error(`
153
+ }
154
+ const results = [];
155
+ const running = new Set();
156
+ for (let i = 0; i < workspaces.length; i++) {
157
+ const { path, fileCount } = workspaces[i];
158
+ const promise = runSingleTypecheck(path, fileCount, root, verbose).then(
159
+ (result) => {
160
+ results[i] = result;
161
+ running.delete(promise);
162
+ if (verbose) {
163
+ const icon = result.success ? "✅" : "❌";
164
+ const log = result.success ? console.log : console.error;
165
+ log(
166
+ `${icon} ${result.workspace} (${result.fileCount} files) ${result.success ? "completed" : "failed"} in ${result.duration.toFixed(2)}s`,
167
+ );
168
+ if (!result.success && result.errorOutput) {
169
+ console.error(`
147
170
  ${formatErrorOutput(result.errorOutput)}`);
148
- }
149
- }
150
- });
151
- running.add(promise);
152
- if (running.size >= concurrency) {
153
- await Promise.race(running);
154
- }
155
- }
156
- await Promise.all(running);
157
- const totalDuration = Number(((performance.now() - totalStartTime) / 1000).toFixed(2));
158
- const totalFiles = workspaces.reduce((sum, w) => sum + w.fileCount, 0);
159
- const success = results.every((r) => r.success);
160
- if (verbose) {
161
- if (success) {
162
- console.log(`
171
+ }
172
+ }
173
+ },
174
+ );
175
+ running.add(promise);
176
+ if (running.size >= concurrency) {
177
+ await Promise.race(running);
178
+ }
179
+ }
180
+ await Promise.all(running);
181
+ const totalDuration = Number(
182
+ ((performance.now() - totalStartTime) / 1000).toFixed(2),
183
+ );
184
+ const totalFiles = workspaces.reduce((sum, w) => sum + w.fileCount, 0);
185
+ const success = results.every((r) => r.success);
186
+ if (verbose) {
187
+ if (success) {
188
+ console.log(`
163
189
  All typecheck checks passed! Total time: ${totalDuration}s (${totalFiles} files)`);
164
- } else {
165
- console.error(`
190
+ } else {
191
+ console.error(`
166
192
  Typecheck failed. Total time: ${totalDuration}s`);
167
- }
168
- }
169
- return {
170
- success,
171
- totalDuration,
172
- totalFiles,
173
- workspaceCount: workspaces.length,
174
- results
175
- };
193
+ }
194
+ }
195
+ return {
196
+ success,
197
+ totalDuration,
198
+ totalFiles,
199
+ workspaceCount: workspaces.length,
200
+ results,
201
+ };
176
202
  }
177
203
 
178
204
  export { runWorkspaceTypecheck };