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
@@ -0,0 +1,115 @@
1
+ import pc from "picocolors";
2
+
3
+ function formatUrl(url: string): string {
4
+ return pc.cyan(
5
+ url.replace(/:(\d+)(\/?)/, (_, port, slash) => `:${pc.bold(port)}${slash}`),
6
+ );
7
+ }
8
+
9
+ function formatLabel(label: string, value: string, arrow = "➜"): string {
10
+ return ` ${pc.green(arrow)} ${pc.bold(label.padEnd(10))} ${value}`;
11
+ }
12
+
13
+ function formatDimLabel(label: string, value: string): string {
14
+ return ` ${pc.dim("•")} ${pc.dim(label.padEnd(10))} ${pc.dim(value)}`;
15
+ }
16
+
17
+ function tunnelFor(
18
+ tunnels:
19
+ | Array<{
20
+ kind: "service" | "app";
21
+ name: string;
22
+ publicUrl: string;
23
+ localUrl: string;
24
+ }>
25
+ | undefined,
26
+ name: string,
27
+ kind: "service" | "app",
28
+ ) {
29
+ return tunnels?.find((t) => t.name === name && t.kind === kind);
30
+ }
31
+
32
+ export function logEnvironmentInfo(input: {
33
+ label: string;
34
+ projectName: string;
35
+ services: Record<string, unknown>;
36
+ apps: Record<string, unknown>;
37
+ ports: Record<string, number>;
38
+ localIp: string;
39
+ worktree: boolean;
40
+ portOffset: number;
41
+ projectSuffix?: string;
42
+ tunnels?: Array<{
43
+ kind: "service" | "app";
44
+ name: string;
45
+ publicUrl: string;
46
+ localUrl: string;
47
+ }>;
48
+ }): void {
49
+ const {
50
+ label,
51
+ projectName,
52
+ services,
53
+ apps,
54
+ ports,
55
+ localIp,
56
+ worktree,
57
+ portOffset,
58
+ projectSuffix,
59
+ tunnels,
60
+ } = input;
61
+ const serviceNames = Object.keys(services);
62
+ const appNames = Object.keys(apps);
63
+
64
+ console.log("");
65
+ console.log(` ${pc.cyan(pc.bold(`🐳 ${label}`))}`);
66
+ console.log(formatLabel("Project:", pc.white(projectName)));
67
+
68
+ if (serviceNames.length > 0) {
69
+ console.log("");
70
+ console.log(` ${pc.dim("─── Services ───")}`);
71
+ for (const name of serviceNames) {
72
+ const port = ports[name];
73
+ const url = `localhost:${port}`;
74
+ console.log(formatLabel(`${name}:`, formatUrl(`http://${url}`)));
75
+ const t = tunnelFor(tunnels, name, "service");
76
+ if (t) {
77
+ console.log(
78
+ ` ${pc.dim("Public:")} ${formatUrl(t.publicUrl)} ${pc.dim("(tunnel)")}`,
79
+ );
80
+ }
81
+ }
82
+ }
83
+
84
+ if (appNames.length > 0) {
85
+ console.log("");
86
+ console.log(` ${pc.dim("─── Applications ───")}`);
87
+ for (const name of appNames) {
88
+ const port = ports[name];
89
+ const localUrl = `http://localhost:${port}`;
90
+ const networkUrl = `http://${localIp}:${port}`;
91
+
92
+ console.log(` ${pc.green("➜")} ${pc.bold(pc.cyan(name))}`);
93
+ console.log(` ${pc.dim("Local:")} ${formatUrl(localUrl)}`);
94
+ console.log(` ${pc.dim("Network:")} ${formatUrl(networkUrl)}`);
95
+ const t = tunnelFor(tunnels, name, "app");
96
+ if (t) {
97
+ console.log(
98
+ ` ${pc.dim("Public:")} ${formatUrl(t.publicUrl)} ${pc.dim("(tunnel)")}`,
99
+ );
100
+ }
101
+ }
102
+ }
103
+
104
+ console.log("");
105
+ console.log(` ${pc.dim("─── Environment ───")}`);
106
+ console.log(formatDimLabel("Worktree:", worktree ? "yes" : "no"));
107
+ console.log(
108
+ formatDimLabel("Port offset:", portOffset > 0 ? `+${portOffset}` : "none"),
109
+ );
110
+ if (projectSuffix) {
111
+ console.log(formatDimLabel("Suffix:", projectSuffix));
112
+ }
113
+ console.log(formatDimLabel("Local IP:", localIp));
114
+ console.log("");
115
+ }
@@ -0,0 +1,34 @@
1
+ import type { AppConfig } from "../types";
2
+
3
+ /**
4
+ * Ensures every name in `onlyApps` exists as a key in `apps`.
5
+ */
6
+ export function assertOnlyAppNames(
7
+ appKeys: string[],
8
+ onlyApps: string[] | undefined,
9
+ ): void {
10
+ if (onlyApps === undefined) return;
11
+ const unknown = onlyApps.filter((n) => !appKeys.includes(n));
12
+ if (unknown.length > 0) {
13
+ throw new Error(`Unknown app name(s) in onlyApps: ${unknown.join(", ")}`);
14
+ }
15
+ }
16
+
17
+ /**
18
+ * Returns a subset of `apps` when `onlyApps` is set; otherwise the full map.
19
+ * When `onlyApps` is `[]`, returns `{}`.
20
+ */
21
+ export function pickApps<TApps extends Record<string, AppConfig>>(
22
+ apps: TApps,
23
+ onlyApps: string[] | undefined,
24
+ ): Record<string, AppConfig> {
25
+ if (onlyApps === undefined) return apps;
26
+ const out: Record<string, AppConfig> = {};
27
+ for (const name of onlyApps) {
28
+ const config = apps[name];
29
+ if (config !== undefined) {
30
+ out[name] = config;
31
+ }
32
+ }
33
+ return out;
34
+ }
@@ -0,0 +1,57 @@
1
+ import type {
2
+ AppConfig,
3
+ HookContext,
4
+ SeedCheckContext,
5
+ ServiceConfig,
6
+ } from "../types";
7
+
8
+ export function createCheckTableHelper<
9
+ TServices extends Record<string, ServiceConfig>,
10
+ TApps extends Record<string, AppConfig>,
11
+ >(
12
+ urls: Record<string, string>,
13
+ exec: (
14
+ cmd: string,
15
+ options?: { throwOnError?: boolean },
16
+ ) => Promise<{
17
+ exitCode: number;
18
+ stdout: string;
19
+ stderr: string;
20
+ }>,
21
+ ): SeedCheckContext<TServices, TApps>["checkTable"] {
22
+ return async (
23
+ tableName: string,
24
+ service?: keyof TServices,
25
+ ): Promise<boolean> => {
26
+ const serviceName = (service ?? "postgres") as string;
27
+ const serviceUrl = urls[serviceName];
28
+ if (!serviceUrl) {
29
+ console.warn(`⚠️ Service "${serviceName}" not found for checkTable`);
30
+ return true;
31
+ }
32
+ const checkResult = await exec(
33
+ `psql "${serviceUrl}" -tAc 'SELECT COUNT(*) FROM "${tableName}" LIMIT 1'`,
34
+ { throwOnError: false },
35
+ );
36
+ const count = checkResult.stdout.trim();
37
+ const shouldSeed =
38
+ checkResult.exitCode !== 0 || count === "0" || count === "";
39
+ if (!shouldSeed) {
40
+ console.log(` 📊 Table "${tableName}" has ${count} rows`);
41
+ }
42
+ return shouldSeed;
43
+ };
44
+ }
45
+
46
+ export function createSeedCheckContext<
47
+ TServices extends Record<string, ServiceConfig>,
48
+ TApps extends Record<string, AppConfig>,
49
+ >(
50
+ baseContext: HookContext<TServices, TApps>,
51
+ checkTable: SeedCheckContext<TServices, TApps>["checkTable"],
52
+ ): SeedCheckContext<TServices, TApps> {
53
+ return {
54
+ ...baseContext,
55
+ checkTable,
56
+ };
57
+ }
@@ -3,25 +3,33 @@
3
3
  // ═══════════════════════════════════════════════════════════════════════════
4
4
 
5
5
  // CLI runner
6
- export { getFlagValue, hasFlag, runCli } from "./cli";
6
+ export { getFlagValue, hasFlag, runCli } from "./cli/run-cli";
7
7
  // Config factory
8
8
  export {
9
9
  assertValidConfig,
10
10
  defineDevConfig,
11
11
  mergeConfigs,
12
12
  validateConfig,
13
- } from "./config";
13
+ } from "./config/index";
14
+ export type {
15
+ ClickhouseServiceOptions,
16
+ CustomServiceOptions,
17
+ PostgresServiceOptions,
18
+ RedisServiceOptions,
19
+ } from "./docker-compose/services";
20
+ // Service helpers
21
+ export { service } from "./docker-compose/services";
14
22
  // Environment factory
15
- export { createDevEnvironment } from "./environment";
23
+ export { createDevEnvironment } from "./environment/index";
24
+ // Config loader (for programmatic access)
25
+ export { clearDevEnvCache, getDevEnv, loadDevEnv } from "./loader/index";
16
26
  // Lint / Typecheck
17
27
  export {
18
28
  runWorkspaceTypecheck,
19
29
  type TypecheckResult,
20
30
  type WorkspaceTypecheckOptions,
21
31
  type WorkspaceTypecheckResult,
22
- } from "./lint";
23
- // Config loader (for programmatic access)
24
- export { clearDevEnvCache, getDevEnv, loadDevEnv } from "./loader";
32
+ } from "./typecheck/index";
25
33
 
26
34
  // ═══════════════════════════════════════════════════════════════════════════
27
35
  // Types
@@ -34,6 +42,7 @@ export type {
34
42
  CliOptions,
35
43
  // Computed types
36
44
  ComputedPorts,
45
+ ComputedPublicUrls,
37
46
  ComputedUrls,
38
47
  // Main config
39
48
  DevConfig,
@@ -42,15 +51,26 @@ export type {
42
51
  DevHooks,
43
52
  DevOptions,
44
53
  DevServerPids,
54
+ DockerComposeGenerationOptions,
55
+ DockerComposeHealthcheckRaw,
56
+ DockerComposeNode,
57
+ DockerComposeServiceRaw,
58
+ DockerComposeVolumeRaw,
59
+ DockerPresetName,
60
+ DockerPresetServiceDefinition,
61
+ DockerServiceDefinition,
45
62
  EnvVarsBuilder,
46
63
  ExecOptions,
47
64
  HealthCheckFn,
48
65
  HookContext,
49
66
  // Migrations & Seed
50
67
  MigrationConfig,
68
+ OpenPublicTunnelsOptions,
69
+ OpenPublicTunnelsResult,
51
70
  // Prisma
52
71
  PrismaConfig,
53
72
  PrismaRunner,
73
+ PublicTunnelHandle,
54
74
  SeedCheckContext,
55
75
  SeedCheckHelpers,
56
76
  SeedConfig,
@@ -61,33 +81,22 @@ export type {
61
81
  StopOptions,
62
82
  UrlBuilderContext,
63
83
  UrlBuilderFn,
64
- } from "./types";
84
+ } from "./types/index";
65
85
 
66
86
  // ═══════════════════════════════════════════════════════════════════════════
67
87
  // Core Utilities (for advanced use cases)
68
88
  // ═══════════════════════════════════════════════════════════════════════════
69
89
 
70
- export {
71
- areContainersRunning,
72
- assertDockerRunning,
73
- DOCKER_NOT_RUNNING_MESSAGE,
74
- isContainerRunning,
75
- isDockerRunning,
76
- MAX_ATTEMPTS,
77
- POLL_INTERVAL,
78
- } from "./core/docker";
79
-
80
90
  export { getLocalIp, isPortAvailable, waitForServer } from "./core/network";
81
91
  export {
82
- computeDevIdentity,
83
92
  calculatePortOffset,
93
+ computeDevIdentity,
84
94
  findMonorepoRoot,
85
95
  getProjectName,
86
- getWorktreeProjectSuffix,
87
96
  getWorktreeName,
97
+ getWorktreeProjectSuffix,
88
98
  isWorktree,
89
99
  } from "./core/ports";
90
-
91
100
  export {
92
101
  getProcessOnPort,
93
102
  isPortInUse,
@@ -96,6 +105,13 @@ export {
96
105
  killProcessOnPort,
97
106
  killProcessOnPortAndWait,
98
107
  } from "./core/process";
108
+ export {
109
+ type PublicExposeTarget,
110
+ type PublicTunnel,
111
+ resolveExposeTargets,
112
+ startPublicTunnels,
113
+ stopPublicTunnels,
114
+ } from "./core/tunnel";
99
115
  export {
100
116
  getEnvVar,
101
117
  isCI,
@@ -113,3 +129,19 @@ export {
113
129
  stopHeartbeat,
114
130
  stopWatchdog,
115
131
  } from "./core/watchdog";
132
+ export {
133
+ areContainersRunning,
134
+ assertDockerRunning,
135
+ DOCKER_NOT_RUNNING_MESSAGE,
136
+ isContainerRunning,
137
+ isDockerRunning,
138
+ MAX_ATTEMPTS,
139
+ POLL_INTERVAL,
140
+ } from "./docker/index";
141
+ export {
142
+ buildComposeModel,
143
+ composeToYaml,
144
+ DEFAULT_GENERATED_COMPOSE_FILE,
145
+ getGeneratedComposePath,
146
+ writeGeneratedComposeFile,
147
+ } from "./docker-compose/index";
@@ -0,0 +1,23 @@
1
+ import type { AppConfig, DevEnvironment, ServiceConfig } from "../types";
2
+
3
+ let cachedEnv: DevEnvironment<
4
+ Record<string, ServiceConfig>,
5
+ Record<string, AppConfig>
6
+ > | null = null;
7
+
8
+ export function setCachedDevEnv(
9
+ env: DevEnvironment<Record<string, ServiceConfig>, Record<string, AppConfig>>,
10
+ ): void {
11
+ cachedEnv = env;
12
+ }
13
+
14
+ export function getCachedDevEnv(): DevEnvironment<
15
+ Record<string, ServiceConfig>,
16
+ Record<string, AppConfig>
17
+ > | null {
18
+ return cachedEnv;
19
+ }
20
+
21
+ export function clearDevEnvCache(): void {
22
+ cachedEnv = null;
23
+ }
@@ -0,0 +1,29 @@
1
+ import { existsSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+
4
+ export const CONFIG_FILES = [
5
+ "dev.config.ts",
6
+ "dev.config.js",
7
+ "dev-tools.config.ts",
8
+ "dev-tools.config.js",
9
+ ];
10
+
11
+ export function findConfigFile(startDir: string): string | null {
12
+ let currentDir = startDir;
13
+
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
+
22
+ const parentDir = dirname(currentDir);
23
+ if (parentDir === currentDir) {
24
+ return null;
25
+ }
26
+
27
+ currentDir = parentDir;
28
+ }
29
+ }
@@ -0,0 +1,17 @@
1
+ import type { AppConfig, DevEnvironment, ServiceConfig } from "../types";
2
+ import { getCachedDevEnv } from "./cache";
3
+
4
+ export { clearDevEnvCache } from "./cache";
5
+ export { CONFIG_FILES, findConfigFile } from "./find-config-file";
6
+ export { loadDevEnv } from "./load-dev-env";
7
+
8
+ export function getDevEnv(): DevEnvironment<
9
+ Record<string, ServiceConfig>,
10
+ Record<string, AppConfig>
11
+ > {
12
+ const env = getCachedDevEnv();
13
+ if (!env) {
14
+ throw new Error("Dev environment not loaded. Call loadDevEnv() first.");
15
+ }
16
+ return env;
17
+ }
@@ -0,0 +1,38 @@
1
+ import { createDevEnvironment } from "../environment";
2
+ import type { AppConfig, DevEnvironment, ServiceConfig } from "../types";
3
+ import { getCachedDevEnv, setCachedDevEnv } from "./cache";
4
+ import { findConfigFile } from "./find-config-file";
5
+
6
+ export async function loadDevEnv(options?: {
7
+ cwd?: string;
8
+ reload?: boolean;
9
+ }): Promise<
10
+ DevEnvironment<Record<string, ServiceConfig>, Record<string, AppConfig>>
11
+ > {
12
+ if (!options?.reload) {
13
+ const cached = getCachedDevEnv();
14
+ if (cached) return cached;
15
+ }
16
+
17
+ const cwd = options?.cwd ?? process.cwd();
18
+ const configPath = findConfigFile(cwd);
19
+
20
+ if (configPath) {
21
+ const mod = await import(configPath);
22
+ const config = mod.default;
23
+
24
+ if (!config?.projectPrefix || !config?.services) {
25
+ throw new Error(
26
+ `Invalid config in "${configPath}". Use defineDevConfig() and export as default.`,
27
+ );
28
+ }
29
+
30
+ const env = createDevEnvironment(config);
31
+ setCachedDevEnv(env);
32
+ return env;
33
+ }
34
+
35
+ throw new Error(
36
+ "No config file found. Create dev.config.ts with: export default defineDevConfig({ ... })",
37
+ );
38
+ }
@@ -0,0 +1 @@
1
+ export * from "./prisma";
@@ -28,7 +28,7 @@ import {
28
28
  isContainerRunning,
29
29
  startService,
30
30
  waitForServiceByType,
31
- } from "./core/docker";
31
+ } from "../docker/runtime";
32
32
  import type {
33
33
  AppConfig,
34
34
  BuiltInHealthCheck,
@@ -36,7 +36,7 @@ import type {
36
36
  PrismaConfig,
37
37
  PrismaRunner,
38
38
  ServiceConfig,
39
- } from "./types";
39
+ } from "../types";
40
40
 
41
41
  /**
42
42
  * Create a Prisma runner from config (used internally by createDevEnvironment).
@@ -80,9 +80,11 @@ export function createPrismaRunner<
80
80
 
81
81
  console.log(`🐳 Starting ${service}...`);
82
82
 
83
+ const composeFile = env.ensureComposeFile();
83
84
  const envVars = env.buildEnvVars();
84
85
  startService(env.root, env.projectName, service, envVars, {
85
86
  verbose: false,
87
+ composeFile,
86
88
  });
87
89
 
88
90
  const port = (env.ports as Record<string, number>)[service];
@@ -0,0 +1 @@
1
+ export * from "./typecheck";