buncargo 1.0.29 → 3.2.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 (246) hide show
  1. package/dist/bin.d.ts +1 -12
  2. package/dist/bin.js +261 -253
  3. package/dist/cli/bin.d.ts +13 -0
  4. package/dist/cli/bin.js +317 -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 +30 -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 -83
  22. package/dist/core/docker.js +35 -32
  23. package/dist/core/index.d.ts +1 -1
  24. package/dist/core/index.js +123 -118
  25. package/dist/core/network.js +2 -2
  26. package/dist/core/ports.js +1 -1
  27. package/dist/core/process.js +1 -1
  28. package/dist/core/quick-tunnel/cloudflared-process.d.ts +10 -0
  29. package/dist/core/quick-tunnel/constants.d.ts +9 -0
  30. package/dist/core/quick-tunnel/index.d.ts +17 -0
  31. package/dist/core/quick-tunnel/install.d.ts +1 -0
  32. package/dist/core/tunnel.d.ts +34 -0
  33. package/dist/core/utils.js +2 -2
  34. package/dist/core/watchdog-runner.js +45 -42
  35. package/dist/core/watchdog.d.ts +1 -0
  36. package/dist/core/watchdog.js +4 -2
  37. package/dist/docker/index.d.ts +1 -0
  38. package/dist/docker/index.js +38 -0
  39. package/dist/docker/runtime.d.ts +87 -0
  40. package/dist/docker/runtime.js +37 -0
  41. package/dist/docker-compose/compose.d.ts +1 -0
  42. package/dist/docker-compose/generated-file.d.ts +7 -0
  43. package/dist/docker-compose/index.d.ts +3 -0
  44. package/dist/docker-compose/index.js +15 -0
  45. package/dist/docker-compose/model.d.ts +6 -0
  46. package/dist/docker-compose/services/clickhouse.d.ts +16 -0
  47. package/dist/docker-compose/services/define-docker-service.d.ts +41 -0
  48. package/dist/docker-compose/services/index.d.ts +23 -0
  49. package/dist/docker-compose/services/index.js +17 -0
  50. package/dist/docker-compose/services/postgres.d.ts +12 -0
  51. package/dist/docker-compose/services/redis.d.ts +12 -0
  52. package/dist/docker-compose/services/shared.d.ts +7 -0
  53. package/dist/docker-compose/yaml.d.ts +2 -0
  54. package/dist/environment/create-dev-environment.d.ts +23 -0
  55. package/dist/environment/index.d.ts +1 -0
  56. package/dist/environment/index.js +15 -0
  57. package/dist/environment/logging.d.ts +17 -0
  58. package/dist/environment/only-apps.d.ts +10 -0
  59. package/dist/environment/seeding.d.ts +9 -0
  60. package/dist/environment.d.ts +1 -23
  61. package/dist/environment.js +12 -14
  62. package/dist/index-045jksh5.js +147 -0
  63. package/dist/index-08wa79cs.js +125 -117
  64. package/dist/index-0kxnae3z.js +335 -0
  65. package/dist/index-1mdrf7nz.js +51 -43
  66. package/dist/index-1yvbwj4k.js +262 -242
  67. package/dist/index-23ev345g.js +475 -0
  68. package/dist/index-2ckr49sf.js +228 -0
  69. package/dist/index-2f47khe5.js +376 -369
  70. package/dist/index-2fr3g85b.js +220 -183
  71. package/dist/index-38xnzpa6.js +450 -0
  72. package/dist/index-3eyrdxw9.js +577 -0
  73. package/dist/index-3h3dhtf2.js +51 -43
  74. package/dist/index-42x95209.js +51 -43
  75. package/dist/index-4gp0az1g.js +145 -0
  76. package/dist/index-4xrxh8yv.js +72 -0
  77. package/dist/index-5aq985p4.js +250 -0
  78. package/dist/index-5gmws6ah.js +181 -0
  79. package/dist/index-5hka0tff.js +78 -76
  80. package/dist/index-5rfqps4b.js +3 -0
  81. package/dist/index-5t9jxqm0.js +428 -0
  82. package/dist/index-6c1w1xk5.js +101 -0
  83. package/dist/index-6cmex7m5.js +72 -0
  84. package/dist/index-6d6x175r.js +572 -0
  85. package/dist/index-6fm7mvwj.js +118 -97
  86. package/dist/index-6srpc523.js +127 -128
  87. package/dist/index-731rzzfp.js +157 -142
  88. package/dist/index-75y4cg2z.js +51 -43
  89. package/dist/index-7ja4ywyj.js +126 -127
  90. package/dist/index-7v19es2e.js +666 -0
  91. package/dist/index-8bw1cmz4.js +531 -0
  92. package/dist/index-8hbbj1mp.js +120 -121
  93. package/dist/index-8xj2p5n5.js +118 -97
  94. package/dist/index-9wyhzw0h.js +574 -0
  95. package/dist/index-ag90ry8t.js +576 -0
  96. package/dist/index-bj79tw5w.js +0 -0
  97. package/dist/index-bnk6nr0g.js +73 -0
  98. package/dist/index-brbbzyks.js +72 -0
  99. package/dist/index-byeqyjrz.js +72 -0
  100. package/dist/index-c0dr6mcv.js +123 -0
  101. package/dist/index-cty0bcry.js +235 -218
  102. package/dist/index-d8tyv5se.js +228 -0
  103. package/dist/index-d9efy0n4.js +176 -150
  104. package/dist/index-enj4zdma.js +574 -0
  105. package/dist/index-etfmqjjf.js +427 -0
  106. package/dist/index-fb29934k.js +172 -0
  107. package/dist/index-g50jw1yf.js +72 -0
  108. package/dist/index-g6eb5wdw.js +118 -117
  109. package/dist/index-ggq3yryx.js +99 -95
  110. package/dist/index-h70tce00.js +177 -0
  111. package/dist/index-hkxtfqtc.js +333 -0
  112. package/dist/index-k370bech.js +72 -0
  113. package/dist/index-kf3dhser.js +146 -143
  114. package/dist/index-ma6tgdb2.js +500 -0
  115. package/dist/index-mam0bcyz.js +123 -0
  116. package/dist/index-mm412dkp.js +274 -0
  117. package/dist/index-n8v18aeb.js +0 -0
  118. package/dist/index-ndnmnsej.js +378 -371
  119. package/dist/index-p8wty0e2.js +389 -379
  120. package/dist/index-qa8akv6y.js +666 -0
  121. package/dist/index-qfphr2fd.js +78 -76
  122. package/dist/index-qqmms8rs.js +51 -43
  123. package/dist/index-qw4093g2.js +51 -43
  124. package/dist/index-qzwpzjbx.js +121 -122
  125. package/dist/index-segbnm0h.js +146 -143
  126. package/dist/index-t0fj6gg1.js +112 -0
  127. package/dist/index-thdkwnv7.js +122 -0
  128. package/dist/index-tjbx2r2t.js +270 -0
  129. package/dist/index-tjqw9vtj.js +62 -54
  130. package/dist/index-vbpb89jy.js +248 -0
  131. package/dist/index-vg55rq0y.js +250 -0
  132. package/dist/index-vhs88xhe.js +99 -95
  133. package/dist/index-vs81yaks.js +244 -0
  134. package/dist/index-w8zxnjka.js +249 -0
  135. package/dist/index-wk2na3t9.js +385 -375
  136. package/dist/index-wz9x8g7z.js +383 -373
  137. package/dist/index-x249gyde.js +388 -378
  138. package/dist/index-x54nbgs7.js +355 -0
  139. package/dist/index-xkvd0nsd.js +187 -0
  140. package/dist/index-yedqxm1z.js +80 -0
  141. package/dist/index-yz4jfz7z.js +338 -0
  142. package/dist/index-zfjzzjkf.js +240 -199
  143. package/dist/index.d.ts +12 -8
  144. package/dist/index.js +56 -34
  145. package/dist/lint.d.ts +1 -46
  146. package/dist/lint.js +3 -7
  147. package/dist/loader/cache.d.ts +4 -0
  148. package/dist/loader/find-config-file.d.ts +2 -0
  149. package/dist/loader/index.d.ts +5 -0
  150. package/dist/loader/index.js +24 -0
  151. package/dist/loader/load-dev-env.d.ts +5 -0
  152. package/dist/loader/loader.d.ts +1 -0
  153. package/dist/loader.d.ts +1 -45
  154. package/dist/loader.js +22 -20
  155. package/dist/prisma/index.d.ts +1 -0
  156. package/dist/prisma/prisma.d.ts +29 -0
  157. package/dist/prisma.d.ts +1 -29
  158. package/dist/prisma.js +6 -10
  159. package/dist/src/bin.js +309 -0
  160. package/dist/src/cli.js +5 -0
  161. package/dist/src/config.js +15 -0
  162. package/dist/src/core/docker.js +38 -0
  163. package/dist/src/core/index.js +130 -0
  164. package/dist/src/core/network.js +9 -0
  165. package/dist/src/core/ports.js +23 -0
  166. package/dist/src/core/process.js +31 -0
  167. package/dist/src/core/utils.js +11 -0
  168. package/dist/src/core/watchdog-runner.js +69 -0
  169. package/dist/src/core/watchdog.js +28 -0
  170. package/dist/src/docker/runtime.js +37 -0
  171. package/dist/src/docker-compose/index.js +16 -0
  172. package/dist/src/docker-compose/services/index.js +17 -0
  173. package/dist/src/environment.js +12 -0
  174. package/dist/src/index.js +122 -0
  175. package/dist/src/lint.js +3 -0
  176. package/dist/src/loader.js +25 -0
  177. package/dist/src/prisma.js +6 -0
  178. package/dist/src/types.js +0 -0
  179. package/dist/typecheck/index.d.ts +1 -0
  180. package/dist/typecheck/index.js +7 -0
  181. package/dist/typecheck/typecheck.d.ts +46 -0
  182. package/dist/types/all-types.d.ts +544 -0
  183. package/dist/types/cli.d.ts +1 -0
  184. package/dist/types/config.d.ts +6 -0
  185. package/dist/types/docker.d.ts +15 -0
  186. package/dist/types/environment.d.ts +8 -0
  187. package/dist/types/hooks.d.ts +9 -0
  188. package/dist/types/index.d.ts +1 -0
  189. package/dist/types/index.js +0 -0
  190. package/dist/types/prisma.d.ts +1 -0
  191. package/dist/types.d.ts +1 -399
  192. package/package.json +55 -48
  193. package/readme.md +365 -109
  194. package/src/cli/bin.ts +77 -0
  195. package/src/cli/commands/help.ts +39 -0
  196. package/src/cli/commands/runtime.ts +72 -0
  197. package/src/cli/commands/version.ts +4 -0
  198. package/src/cli/index.ts +1 -0
  199. package/{cli.ts → src/cli/run-cli.ts} +114 -10
  200. package/src/config/define-config.ts +30 -0
  201. package/src/config/index.ts +3 -0
  202. package/src/config/merge-configs.ts +33 -0
  203. package/src/config/validate-config.ts +136 -0
  204. package/{core → src/core}/index.ts +2 -2
  205. package/{core → src/core}/ports.ts +5 -2
  206. package/{core → src/core}/process.ts +6 -2
  207. package/src/core/quick-tunnel/cloudflared-process.ts +83 -0
  208. package/src/core/quick-tunnel/constants.ts +31 -0
  209. package/src/core/quick-tunnel/index.ts +96 -0
  210. package/src/core/quick-tunnel/install.ts +160 -0
  211. package/src/core/tunnel.ts +165 -0
  212. package/{core → src/core}/utils.ts +1 -0
  213. package/{core → src/core}/watchdog.ts +5 -1
  214. package/src/docker/index.ts +1 -0
  215. package/{core/docker.ts → src/docker/runtime.ts} +11 -4
  216. package/src/docker-compose/generated-file.ts +45 -0
  217. package/src/docker-compose/index.ts +7 -0
  218. package/src/docker-compose/model.ts +197 -0
  219. package/src/docker-compose/services/clickhouse.ts +79 -0
  220. package/src/docker-compose/services/define-docker-service.ts +109 -0
  221. package/src/docker-compose/services/index.ts +67 -0
  222. package/src/docker-compose/services/postgres.ts +60 -0
  223. package/src/docker-compose/services/redis.ts +48 -0
  224. package/src/docker-compose/services/shared.ts +79 -0
  225. package/src/docker-compose/yaml.ts +88 -0
  226. package/{environment.ts → src/environment/create-dev-environment.ts} +214 -141
  227. package/src/environment/index.ts +1 -0
  228. package/src/environment/logging.ts +115 -0
  229. package/src/environment/only-apps.ts +34 -0
  230. package/src/environment/seeding.ts +57 -0
  231. package/{index.ts → src/index.ts} +52 -20
  232. package/src/loader/cache.ts +23 -0
  233. package/src/loader/find-config-file.ts +29 -0
  234. package/src/loader/index.ts +17 -0
  235. package/src/loader/load-dev-env.ts +38 -0
  236. package/src/prisma/index.ts +1 -0
  237. package/{prisma.ts → src/prisma/prisma.ts} +4 -2
  238. package/src/typecheck/index.ts +1 -0
  239. package/{types.ts → src/types/all-types.ts} +186 -8
  240. package/src/types/index.ts +1 -0
  241. package/bin.ts +0 -192
  242. package/config.ts +0 -194
  243. package/loader.ts +0 -126
  244. /package/{core → src/core}/network.ts +0 -0
  245. /package/{core → src/core}/watchdog-runner.ts +0 -0
  246. /package/{lint.ts → src/typecheck/typecheck.ts} +0 -0
@@ -1,58 +1,66 @@
1
- import {
2
- createDevEnvironment
3
- } from "./index-wk2na3t9.js";
4
-
5
1
  // loader.ts
6
2
  import { existsSync } from "node:fs";
7
3
  import { dirname, join } from "node:path";
4
+ import { createDevEnvironment } from "./index-wk2na3t9.js";
5
+
8
6
  var CONFIG_FILES = [
9
- "dev.config.ts",
10
- "dev.config.js",
11
- "dev-tools.config.ts",
12
- "dev-tools.config.js"
7
+ "dev.config.ts",
8
+ "dev.config.js",
9
+ "dev-tools.config.ts",
10
+ "dev-tools.config.js",
13
11
  ];
14
12
  function findConfigFile(startDir) {
15
- let currentDir = startDir;
16
- while (true) {
17
- for (const file of CONFIG_FILES) {
18
- const configPath = join(currentDir, file);
19
- if (existsSync(configPath)) {
20
- return configPath;
21
- }
22
- }
23
- const parentDir = dirname(currentDir);
24
- if (parentDir === currentDir) {
25
- return null;
26
- }
27
- currentDir = parentDir;
28
- }
13
+ let currentDir = startDir;
14
+ while (true) {
15
+ for (const file of CONFIG_FILES) {
16
+ const configPath = join(currentDir, file);
17
+ if (existsSync(configPath)) {
18
+ return configPath;
19
+ }
20
+ }
21
+ const parentDir = dirname(currentDir);
22
+ if (parentDir === currentDir) {
23
+ return null;
24
+ }
25
+ currentDir = parentDir;
26
+ }
29
27
  }
30
28
  var cachedEnv = null;
31
29
  async function loadDevEnv(options) {
32
- if (cachedEnv && !options?.reload) {
33
- return cachedEnv;
34
- }
35
- const cwd = options?.cwd ?? process.cwd();
36
- const configPath = findConfigFile(cwd);
37
- if (configPath) {
38
- const mod = await import(configPath);
39
- const config = mod.default;
40
- if (!config?.projectPrefix || !config?.services) {
41
- throw new Error(`Invalid config in "${configPath}". Use defineDevConfig() and export as default.`);
42
- }
43
- cachedEnv = createDevEnvironment(config);
44
- return cachedEnv;
45
- }
46
- throw new Error(`No config file found. Create dev.config.ts with: export default defineDevConfig({ ... })`);
30
+ if (cachedEnv && !options?.reload) {
31
+ return cachedEnv;
32
+ }
33
+ const cwd = options?.cwd ?? process.cwd();
34
+ const configPath = findConfigFile(cwd);
35
+ if (configPath) {
36
+ const mod = await import(configPath);
37
+ const config = mod.default;
38
+ if (!config?.projectPrefix || !config?.services) {
39
+ throw new Error(
40
+ `Invalid config in "${configPath}". Use defineDevConfig() and export as default.`,
41
+ );
42
+ }
43
+ cachedEnv = createDevEnvironment(config);
44
+ return cachedEnv;
45
+ }
46
+ throw new Error(
47
+ `No config file found. Create dev.config.ts with: export default defineDevConfig({ ... })`,
48
+ );
47
49
  }
48
50
  function getDevEnv() {
49
- if (!cachedEnv) {
50
- throw new Error("Dev environment not loaded. Call loadDevEnv() first.");
51
- }
52
- return cachedEnv;
51
+ if (!cachedEnv) {
52
+ throw new Error("Dev environment not loaded. Call loadDevEnv() first.");
53
+ }
54
+ return cachedEnv;
53
55
  }
54
56
  function clearDevEnvCache() {
55
- cachedEnv = null;
57
+ cachedEnv = null;
56
58
  }
57
59
 
58
- export { CONFIG_FILES, findConfigFile, loadDevEnv, getDevEnv, clearDevEnvCache };
60
+ export {
61
+ CONFIG_FILES,
62
+ findConfigFile,
63
+ loadDevEnv,
64
+ getDevEnv,
65
+ clearDevEnvCache,
66
+ };
@@ -1,274 +1,294 @@
1
1
  // core/process.ts
2
- import {
3
- execSync,
4
- spawn
5
- } from "node:child_process";
2
+ import { execSync, spawn } from "node:child_process";
6
3
  import { platform } from "node:os";
7
4
  import { resolve } from "node:path";
5
+
8
6
  function exec(cmd, root, envVars, options = {}) {
9
- const { cwd, verbose = false, env = {}, throwOnError = true } = options;
10
- const workingDir = cwd ? resolve(root, cwd) : root;
11
- const fullEnv = { ...process.env, ...envVars, ...env };
12
- try {
13
- const stdout = execSync(cmd, {
14
- cwd: workingDir,
15
- env: fullEnv,
16
- encoding: "utf-8",
17
- stdio: verbose ? "inherit" : ["pipe", "pipe", "pipe"]
18
- });
19
- return {
20
- exitCode: 0,
21
- stdout: typeof stdout === "string" ? stdout : "",
22
- stderr: ""
23
- };
24
- } catch (error) {
25
- const execError = error;
26
- const result = {
27
- exitCode: execError.status ?? 1,
28
- stdout: execError.stdout ?? "",
29
- stderr: execError.stderr ?? ""
30
- };
31
- if (throwOnError) {
32
- throw new Error(`Command failed with exit code ${result.exitCode}: ${cmd}
7
+ const { cwd, verbose = false, env = {}, throwOnError = true } = options;
8
+ const workingDir = cwd ? resolve(root, cwd) : root;
9
+ const fullEnv = { ...process.env, ...envVars, ...env };
10
+ try {
11
+ const stdout = execSync(cmd, {
12
+ cwd: workingDir,
13
+ env: fullEnv,
14
+ encoding: "utf-8",
15
+ stdio: verbose ? "inherit" : ["pipe", "pipe", "pipe"],
16
+ });
17
+ return {
18
+ exitCode: 0,
19
+ stdout: typeof stdout === "string" ? stdout : "",
20
+ stderr: "",
21
+ };
22
+ } catch (error) {
23
+ const execError = error;
24
+ const result = {
25
+ exitCode: execError.status ?? 1,
26
+ stdout: execError.stdout ?? "",
27
+ stderr: execError.stderr ?? "",
28
+ };
29
+ if (throwOnError) {
30
+ throw new Error(`Command failed with exit code ${result.exitCode}: ${cmd}
33
31
  ${result.stderr}`);
34
- }
35
- return result;
36
- }
32
+ }
33
+ return result;
34
+ }
37
35
  }
38
36
  async function execAsync(cmd, root, envVars, options = {}) {
39
- return new Promise((resolve2) => {
40
- const result = exec(cmd, root, envVars, {
41
- ...options,
42
- throwOnError: false
43
- });
44
- resolve2(result);
45
- });
37
+ return new Promise((resolve2) => {
38
+ const result = exec(cmd, root, envVars, {
39
+ ...options,
40
+ throwOnError: false,
41
+ });
42
+ resolve2(result);
43
+ });
46
44
  }
47
45
  async function spawnDevServer(command, root, appCwd, envVars, options = {}) {
48
- const {
49
- verbose = false,
50
- detached = true,
51
- isCI = false,
52
- killExisting = true,
53
- port
54
- } = options;
55
- if (killExisting && port !== undefined) {
56
- const existingPid = getProcessOnPort(port);
57
- if (existingPid !== null) {
58
- if (verbose) {
59
- console.log(` ⚠️ Port ${port} is in use by process ${existingPid}`);
60
- }
61
- await killProcessOnPortAndWait(port, { verbose });
62
- }
63
- }
64
- const parts = command.split(" ");
65
- const cmd = parts[0];
66
- const args = parts.slice(1);
67
- if (!cmd) {
68
- throw new Error("Command cannot be empty");
69
- }
70
- const workingDir = appCwd ? resolve(root, appCwd) : root;
71
- const spawnOptions = {
72
- cwd: workingDir,
73
- env: { ...process.env, ...envVars },
74
- detached,
75
- stdio: isCI || verbose ? "inherit" : "ignore"
76
- };
77
- const proc = spawn(cmd, args, spawnOptions);
78
- if (detached && proc.unref) {
79
- proc.unref();
80
- }
81
- return proc;
46
+ const {
47
+ verbose = false,
48
+ detached = true,
49
+ isCI = false,
50
+ killExisting = true,
51
+ port,
52
+ } = options;
53
+ if (killExisting && port !== undefined) {
54
+ const existingPid = getProcessOnPort(port);
55
+ if (existingPid !== null) {
56
+ if (verbose) {
57
+ console.log(` ⚠️ Port ${port} is in use by process ${existingPid}`);
58
+ }
59
+ await killProcessOnPortAndWait(port, { verbose });
60
+ }
61
+ }
62
+ const parts = command.split(" ");
63
+ const cmd = parts[0];
64
+ const args = parts.slice(1);
65
+ if (!cmd) {
66
+ throw new Error("Command cannot be empty");
67
+ }
68
+ const workingDir = appCwd ? resolve(root, appCwd) : root;
69
+ const spawnOptions = {
70
+ cwd: workingDir,
71
+ env: { ...process.env, ...envVars },
72
+ detached,
73
+ stdio: isCI || verbose ? "inherit" : "ignore",
74
+ };
75
+ const proc = spawn(cmd, args, spawnOptions);
76
+ if (detached && proc.unref) {
77
+ proc.unref();
78
+ }
79
+ return proc;
82
80
  }
83
81
  async function startDevServers(apps, root, envVars, ports, options = {}) {
84
- const {
85
- verbose = true,
86
- productionBuild = false,
87
- isCI = false,
88
- killExisting = true
89
- } = options;
90
- const pids = {};
91
- if (verbose) {
92
- console.log(productionBuild ? "\uD83D\uDE80 Starting production servers..." : "\uD83D\uDD27 Starting dev servers...");
93
- }
94
- for (const [name, config] of Object.entries(apps)) {
95
- const command = productionBuild ? config.prodCommand ?? config.devCommand : config.devCommand;
96
- const port = ports[name];
97
- const proc = await spawnDevServer(command, root, config.cwd, envVars, {
98
- verbose,
99
- isCI,
100
- killExisting,
101
- port
102
- });
103
- if (proc.pid) {
104
- pids[name] = proc.pid;
105
- if (verbose) {
106
- console.log(` ${name} PID: ${proc.pid}`);
107
- }
108
- }
109
- }
110
- return pids;
82
+ const {
83
+ verbose = true,
84
+ productionBuild = false,
85
+ isCI = false,
86
+ killExisting = true,
87
+ } = options;
88
+ const pids = {};
89
+ if (verbose) {
90
+ console.log(
91
+ productionBuild
92
+ ? "\uD83D\uDE80 Starting production servers..."
93
+ : "\uD83D\uDD27 Starting dev servers...",
94
+ );
95
+ }
96
+ for (const [name, config] of Object.entries(apps)) {
97
+ const command = productionBuild
98
+ ? (config.prodCommand ?? config.devCommand)
99
+ : config.devCommand;
100
+ const port = ports[name];
101
+ const proc = await spawnDevServer(command, root, config.cwd, envVars, {
102
+ verbose,
103
+ isCI,
104
+ killExisting,
105
+ port,
106
+ });
107
+ if (proc.pid) {
108
+ pids[name] = proc.pid;
109
+ if (verbose) {
110
+ console.log(` ${name} PID: ${proc.pid}`);
111
+ }
112
+ }
113
+ }
114
+ return pids;
111
115
  }
112
116
  function getProcessOnPort(port) {
113
- try {
114
- const os = platform();
115
- let output;
116
- if (os === "win32") {
117
- output = execSync(`netstat -ano | findstr :${port}`, {
118
- encoding: "utf-8",
119
- stdio: ["pipe", "pipe", "pipe"]
120
- });
121
- const lines = output.trim().split(`
117
+ try {
118
+ const os = platform();
119
+ let output;
120
+ if (os === "win32") {
121
+ output = execSync(`netstat -ano | findstr :${port}`, {
122
+ encoding: "utf-8",
123
+ stdio: ["pipe", "pipe", "pipe"],
124
+ });
125
+ const lines = output.trim().split(`
122
126
  `);
123
- for (const line of lines) {
124
- if (line.includes("LISTENING")) {
125
- const parts = line.trim().split(/\s+/);
126
- const pid = Number.parseInt(parts[parts.length - 1], 10);
127
- if (!Number.isNaN(pid) && pid > 0) {
128
- return pid;
129
- }
130
- }
131
- }
132
- } else {
133
- output = execSync(`lsof -ti :${port}`, {
134
- encoding: "utf-8",
135
- stdio: ["pipe", "pipe", "pipe"]
136
- });
137
- const pid = Number.parseInt(output.trim().split(`
138
- `)[0], 10);
139
- if (!Number.isNaN(pid) && pid > 0) {
140
- return pid;
141
- }
142
- }
143
- return null;
144
- } catch {
145
- return null;
146
- }
127
+ for (const line of lines) {
128
+ if (line.includes("LISTENING")) {
129
+ const parts = line.trim().split(/\s+/);
130
+ const pid = Number.parseInt(parts[parts.length - 1], 10);
131
+ if (!Number.isNaN(pid) && pid > 0) {
132
+ return pid;
133
+ }
134
+ }
135
+ }
136
+ } else {
137
+ output = execSync(`lsof -ti :${port}`, {
138
+ encoding: "utf-8",
139
+ stdio: ["pipe", "pipe", "pipe"],
140
+ });
141
+ const pid = Number.parseInt(
142
+ output.trim().split(`
143
+ `)[0],
144
+ 10,
145
+ );
146
+ if (!Number.isNaN(pid) && pid > 0) {
147
+ return pid;
148
+ }
149
+ }
150
+ return null;
151
+ } catch {
152
+ return null;
153
+ }
147
154
  }
148
155
  function isPortInUse(port) {
149
- return getProcessOnPort(port) !== null;
156
+ return getProcessOnPort(port) !== null;
150
157
  }
151
158
  function killProcessOnPort(port, options = {}) {
152
- const { verbose = false, signal = "SIGTERM" } = options;
153
- const pid = getProcessOnPort(port);
154
- if (pid === null) {
155
- return false;
156
- }
157
- try {
158
- if (verbose) {
159
- console.log(` Killing process ${pid} on port ${port}`);
160
- }
161
- process.kill(pid, signal);
162
- return true;
163
- } catch {
164
- return false;
165
- }
159
+ const { verbose = false, signal = "SIGTERM" } = options;
160
+ const pid = getProcessOnPort(port);
161
+ if (pid === null) {
162
+ return false;
163
+ }
164
+ try {
165
+ if (verbose) {
166
+ console.log(` Killing process ${pid} on port ${port}`);
167
+ }
168
+ process.kill(pid, signal);
169
+ return true;
170
+ } catch {
171
+ return false;
172
+ }
166
173
  }
167
174
  async function killProcessOnPortAndWait(port, options = {}) {
168
- const { verbose = false, timeout = 5000 } = options;
169
- const pid = getProcessOnPort(port);
170
- if (pid === null) {
171
- return false;
172
- }
173
- if (verbose) {
174
- console.log(` Killing process ${pid} on port ${port}...`);
175
- }
176
- try {
177
- process.kill(pid, "SIGTERM");
178
- } catch {
179
- return false;
180
- }
181
- const startTime = Date.now();
182
- const checkInterval = 100;
183
- while (Date.now() - startTime < timeout) {
184
- await new Promise((resolve2) => setTimeout(resolve2, checkInterval));
185
- if (!isPortInUse(port)) {
186
- if (verbose) {
187
- console.log(` ✓ Port ${port} released`);
188
- }
189
- return true;
190
- }
191
- }
192
- if (verbose) {
193
- console.log(` Process ${pid} didn't exit, sending SIGKILL...`);
194
- }
195
- try {
196
- process.kill(pid, "SIGKILL");
197
- } catch {}
198
- await new Promise((resolve2) => setTimeout(resolve2, 500));
199
- const released = !isPortInUse(port);
200
- if (verbose) {
201
- if (released) {
202
- console.log(` ✓ Port ${port} released after SIGKILL`);
203
- } else {
204
- console.log(` ⚠ Port ${port} still in use`);
205
- }
206
- }
207
- return released;
175
+ const { verbose = false, timeout = 5000 } = options;
176
+ const pid = getProcessOnPort(port);
177
+ if (pid === null) {
178
+ return false;
179
+ }
180
+ if (verbose) {
181
+ console.log(` Killing process ${pid} on port ${port}...`);
182
+ }
183
+ try {
184
+ process.kill(pid, "SIGTERM");
185
+ } catch {
186
+ return false;
187
+ }
188
+ const startTime = Date.now();
189
+ const checkInterval = 100;
190
+ while (Date.now() - startTime < timeout) {
191
+ await new Promise((resolve2) => setTimeout(resolve2, checkInterval));
192
+ if (!isPortInUse(port)) {
193
+ if (verbose) {
194
+ console.log(` ✓ Port ${port} released`);
195
+ }
196
+ return true;
197
+ }
198
+ }
199
+ if (verbose) {
200
+ console.log(` Process ${pid} didn't exit, sending SIGKILL...`);
201
+ }
202
+ try {
203
+ process.kill(pid, "SIGKILL");
204
+ } catch {}
205
+ await new Promise((resolve2) => setTimeout(resolve2, 500));
206
+ const released = !isPortInUse(port);
207
+ if (verbose) {
208
+ if (released) {
209
+ console.log(` ✓ Port ${port} released after SIGKILL`);
210
+ } else {
211
+ console.log(` ⚠ Port ${port} still in use`);
212
+ }
213
+ }
214
+ return released;
208
215
  }
209
216
  async function killProcessesOnAppPorts(apps, ports, options = {}) {
210
- const { verbose = true } = options;
211
- const appNames = Object.keys(apps);
212
- if (appNames.length === 0)
213
- return;
214
- let killedAny = false;
215
- for (const name of appNames) {
216
- const port = ports[name];
217
- if (port === undefined)
218
- continue;
219
- const existingPid = getProcessOnPort(port);
220
- if (existingPid !== null) {
221
- if (!killedAny && verbose) {
222
- console.log("");
223
- killedAny = true;
224
- }
225
- if (verbose) {
226
- console.log(`⚠️ Port ${port} (${name}) is in use by process ${existingPid}`);
227
- }
228
- const killed = await killProcessOnPortAndWait(port, { verbose });
229
- if (!killed && verbose) {
230
- console.log(` ⚠️ Could not kill process on port ${port}, server may fail to start`);
231
- }
232
- }
233
- }
217
+ const { verbose = true } = options;
218
+ const appNames = Object.keys(apps);
219
+ if (appNames.length === 0) return;
220
+ let killedAny = false;
221
+ for (const name of appNames) {
222
+ const port = ports[name];
223
+ if (port === undefined) continue;
224
+ const existingPid = getProcessOnPort(port);
225
+ if (existingPid !== null) {
226
+ if (!killedAny && verbose) {
227
+ console.log("");
228
+ killedAny = true;
229
+ }
230
+ if (verbose) {
231
+ console.log(
232
+ `⚠️ Port ${port} (${name}) is in use by process ${existingPid}`,
233
+ );
234
+ }
235
+ const killed = await killProcessOnPortAndWait(port, { verbose });
236
+ if (!killed && verbose) {
237
+ console.log(
238
+ ` ⚠️ Could not kill process on port ${port}, server may fail to start`,
239
+ );
240
+ }
241
+ }
242
+ }
234
243
  }
235
244
  function stopProcess(pid) {
236
- try {
237
- process.kill(pid, "SIGTERM");
238
- } catch {}
245
+ try {
246
+ process.kill(pid, "SIGTERM");
247
+ } catch {}
239
248
  }
240
249
  function stopAllProcesses(pids, options = {}) {
241
- const { verbose = true } = options;
242
- for (const [name, pid] of Object.entries(pids)) {
243
- if (pid) {
244
- if (verbose)
245
- console.log(` Stopping ${name} (PID: ${pid})`);
246
- stopProcess(pid);
247
- }
248
- }
250
+ const { verbose = true } = options;
251
+ for (const [name, pid] of Object.entries(pids)) {
252
+ if (pid) {
253
+ if (verbose) console.log(` Stopping ${name} (PID: ${pid})`);
254
+ stopProcess(pid);
255
+ }
256
+ }
249
257
  }
250
258
  function isProcessAlive(pid) {
251
- try {
252
- process.kill(pid, 0);
253
- return true;
254
- } catch {
255
- return false;
256
- }
259
+ try {
260
+ process.kill(pid, 0);
261
+ return true;
262
+ } catch {
263
+ return false;
264
+ }
257
265
  }
258
266
  function buildApps(apps, root, envVars, options = {}) {
259
- const { verbose = true } = options;
260
- for (const [name, config] of Object.entries(apps)) {
261
- if (config.buildCommand) {
262
- if (verbose)
263
- console.log(`\uD83D\uDD28 Building ${name}...`);
264
- exec(config.buildCommand, root, envVars, {
265
- cwd: config.cwd,
266
- verbose
267
- });
268
- }
269
- }
270
- if (verbose)
271
- console.log("✓ Build complete");
267
+ const { verbose = true } = options;
268
+ for (const [name, config] of Object.entries(apps)) {
269
+ if (config.buildCommand) {
270
+ if (verbose) console.log(`\uD83D\uDD28 Building ${name}...`);
271
+ exec(config.buildCommand, root, envVars, {
272
+ cwd: config.cwd,
273
+ verbose,
274
+ });
275
+ }
276
+ }
277
+ if (verbose) console.log("✓ Build complete");
272
278
  }
273
279
 
274
- export { exec, execAsync, spawnDevServer, startDevServers, getProcessOnPort, isPortInUse, killProcessOnPort, killProcessOnPortAndWait, killProcessesOnAppPorts, stopProcess, stopAllProcesses, isProcessAlive, buildApps };
280
+ export {
281
+ exec,
282
+ execAsync,
283
+ spawnDevServer,
284
+ startDevServers,
285
+ getProcessOnPort,
286
+ isPortInUse,
287
+ killProcessOnPort,
288
+ killProcessOnPortAndWait,
289
+ killProcessesOnAppPorts,
290
+ stopProcess,
291
+ stopAllProcesses,
292
+ isProcessAlive,
293
+ buildApps,
294
+ };