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,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";
@@ -27,12 +27,106 @@ export interface UrlBuilderContext {
27
27
  */
28
28
  export type UrlBuilderFn = (ctx: UrlBuilderContext) => string;
29
29
 
30
+ // ═══════════════════════════════════════════════════════════════════════════
31
+ // Docker Compose Configuration
32
+ // ═══════════════════════════════════════════════════════════════════════════
33
+
34
+ /**
35
+ * Recursive YAML-safe value used for Docker Compose objects.
36
+ */
37
+ export type DockerComposeNode =
38
+ | string
39
+ | number
40
+ | boolean
41
+ | null
42
+ | DockerComposeNode[]
43
+ | { [key: string]: DockerComposeNode | undefined };
44
+
45
+ /**
46
+ * Built-in Docker service presets.
47
+ */
48
+ export type DockerPresetName = "postgres" | "redis" | "clickhouse";
49
+
50
+ /**
51
+ * Docker Compose healthcheck object.
52
+ */
53
+ export interface DockerComposeHealthcheckRaw {
54
+ test?: string[] | string;
55
+ interval?: string;
56
+ timeout?: string;
57
+ retries?: number;
58
+ start_period?: string;
59
+ disable?: boolean;
60
+ [composeKey: string]: DockerComposeNode | undefined;
61
+ }
62
+
63
+ /**
64
+ * Docker Compose service (raw escape hatch).
65
+ * Includes common fields plus index signature for advanced keys.
66
+ */
67
+ export interface DockerComposeServiceRaw {
68
+ image?: string;
69
+ container_name?: string;
70
+ ports?: string[];
71
+ volumes?: string[];
72
+ environment?: Record<string, string | number | boolean>;
73
+ command?: string | string[];
74
+ entrypoint?: string | string[];
75
+ depends_on?: string[] | Record<string, DockerComposeNode>;
76
+ healthcheck?: DockerComposeHealthcheckRaw;
77
+ ulimits?: Record<string, number | { soft: number; hard: number }>;
78
+ restart?: string;
79
+ working_dir?: string;
80
+ [composeKey: string]: DockerComposeNode | undefined;
81
+ }
82
+
83
+ /**
84
+ * Docker Compose volume object.
85
+ */
86
+ export interface DockerComposeVolumeRaw {
87
+ driver?: string;
88
+ driver_opts?: Record<string, string | number | boolean>;
89
+ [composeKey: string]: DockerComposeNode | undefined;
90
+ }
91
+
92
+ /**
93
+ * Helper-friendly preset service definition.
94
+ */
95
+ export interface DockerPresetServiceDefinition {
96
+ kind: "preset";
97
+ preset: DockerPresetName;
98
+ service?: DockerComposeServiceRaw;
99
+ }
100
+
101
+ /**
102
+ * Docker service definition accepted by service config.
103
+ * - raw object is the manual escape hatch
104
+ * - helper mode returns `kind`-based definitions
105
+ */
106
+ export type DockerServiceDefinition =
107
+ | DockerComposeServiceRaw
108
+ | DockerPresetServiceDefinition;
109
+
110
+ /**
111
+ * Docker Compose generation configuration.
112
+ */
113
+ export interface DockerComposeGenerationOptions {
114
+ /** Path to generated compose file relative to root. Default: '.buncargo/docker-compose.generated.yml' */
115
+ generatedFile?: string;
116
+ /** Write strategy for generated compose file. Default: 'always' */
117
+ writeStrategy?: "always" | "if-missing";
118
+ /** Extra top-level named volumes */
119
+ volumes?: Record<string, DockerComposeVolumeRaw>;
120
+ }
121
+
30
122
  /**
31
123
  * Configuration for a Docker Compose service (e.g., postgres, redis).
32
124
  */
33
125
  export interface ServiceConfig {
34
126
  /** Base port for the service (before offset is applied) */
35
127
  port: number;
128
+ /** Whether this service can be exposed publicly via tunnel */
129
+ expose?: boolean;
36
130
  /** Optional secondary port (e.g., ClickHouse native protocol) */
37
131
  secondaryPort?: number;
38
132
  /** Health check: built-in name, custom function, or disabled (false) */
@@ -53,6 +147,8 @@ export interface ServiceConfig {
53
147
  user?: string;
54
148
  /** Password (default: 'postgres' for postgres, 'root' for mysql, 'clickhouse' for clickhouse) */
55
149
  password?: string;
150
+ /** Docker Compose service definition (preset helper or raw escape hatch) */
151
+ docker?: DockerServiceDefinition;
56
152
  }
57
153
 
58
154
  // ═══════════════════════════════════════════════════════════════════════════
@@ -65,6 +161,8 @@ export interface ServiceConfig {
65
161
  export interface AppConfig {
66
162
  /** Base port for the app (before offset is applied) */
67
163
  port: number;
164
+ /** Whether this app can be exposed publicly via tunnel */
165
+ expose?: boolean;
68
166
  /** Command to start the dev server */
69
167
  devCommand: string;
70
168
  /** Command to start production server (optional) */
@@ -110,6 +208,8 @@ export interface HookContext<
110
208
  ports: ComputedPorts<TServices, TApps>;
111
209
  /** Computed URLs for all services and apps */
112
210
  urls: ComputedUrls<TServices, TApps>;
211
+ /** Public tunnel URLs for exposed services/apps (when active) */
212
+ publicUrls: ComputedPublicUrls<TServices, TApps>;
113
213
  /** Execute a shell command with environment variables set */
114
214
  exec: (
115
215
  cmd: string,
@@ -259,12 +359,16 @@ export interface SeedConfig<
259
359
  * Options for the dev environment.
260
360
  */
261
361
  export interface DevOptions {
262
- /** Enable worktree isolation (unique ports per worktree). Default: true */
362
+ /**
363
+ * Enable worktree isolation. When true (default), each worktree gets:
364
+ * - unique ports (offset)
365
+ * - unique Docker Compose project name (separate containers/networks/volumes)
366
+ *
367
+ * Set to false to intentionally share Docker state across worktrees.
368
+ */
263
369
  worktreeIsolation?: boolean;
264
370
  /** Auto-shutdown after idle time in ms. Set to false to disable. Default: false */
265
371
  autoShutdown?: number | false;
266
- /** Path to docker-compose.yml relative to root. Default: 'docker-compose.yml' */
267
- composeFile?: string;
268
372
  /** Default verbose setting for all operations. Default: true */
269
373
  verbose?: boolean;
270
374
  }
@@ -278,7 +382,12 @@ export type EnvVarsBuilder<
278
382
  > = (
279
383
  ports: ComputedPorts<TServices, TApps>,
280
384
  urls: ComputedUrls<TServices, TApps>,
281
- ctx: { projectName: string; localIp: string; portOffset: number },
385
+ ctx: {
386
+ projectName: string;
387
+ localIp: string;
388
+ portOffset: number;
389
+ publicUrls: ComputedPublicUrls<TServices, TApps>;
390
+ },
282
391
  ) => Record<string, string | number>;
283
392
 
284
393
  /**
@@ -302,11 +411,12 @@ export interface DevConfig<
302
411
  *
303
412
  * @example
304
413
  * ```typescript
305
- * envVars: (ports, urls, { localIp }) => ({
414
+ * envVars: (ports, urls, { localIp, publicUrls }) => ({
306
415
  * DATABASE_URL: urls.postgres,
307
416
  * BASE_URL: urls.api,
308
417
  * VITE_PORT: ports.platform,
309
- * EXPO_API_URL: `http://${localIp}:${ports.api}`
418
+ * EXPO_API_URL: `http://${localIp}:${ports.api}`,
419
+ * WEBHOOK_URL: publicUrls.api
310
420
  * })
311
421
  * ```
312
422
  */
@@ -321,6 +431,8 @@ export interface DevConfig<
321
431
  prisma?: PrismaConfig;
322
432
  /** Additional options (optional) */
323
433
  options?: DevOptions;
434
+ /** Docker Compose generation options (optional) */
435
+ docker?: DockerComposeGenerationOptions;
324
436
  }
325
437
 
326
438
  // ═══════════════════════════════════════════════════════════════════════════
@@ -360,6 +472,13 @@ export type ComputedUrls<
360
472
  [K in keyof TApps]: string;
361
473
  };
362
474
 
475
+ export type ComputedPublicUrls<
476
+ TServices extends Record<string, ServiceConfig>,
477
+ TApps extends Record<string, AppConfig>,
478
+ > = Partial<{
479
+ [K in keyof TServices | keyof TApps]: string;
480
+ }>;
481
+
363
482
  // ═══════════════════════════════════════════════════════════════════════════
364
483
  // Start/Stop Options
365
484
  // ═══════════════════════════════════════════════════════════════════════════
@@ -420,6 +539,10 @@ export interface DevEnvironment<
420
539
  readonly ports: ComputedPorts<TServices, TApps>;
421
540
  /** Computed URLs for all services and apps */
422
541
  readonly urls: ComputedUrls<TServices, TApps>;
542
+ /** Public tunnel URLs for exposed services/apps (when active) */
543
+ readonly publicUrls: ComputedPublicUrls<TServices, TApps>;
544
+ /** Services configuration */
545
+ readonly services: TServices;
423
546
  /** Apps configuration (for CLI to build commands) */
424
547
  readonly apps: TApps;
425
548
  /** Port offset applied (0 for main, > 0 for worktrees) */
@@ -430,6 +553,8 @@ export interface DevEnvironment<
430
553
  readonly localIp: string;
431
554
  /** Path to monorepo root */
432
555
  readonly root: string;
556
+ /** Path passed to docker compose -f */
557
+ readonly composeFile: string;
433
558
 
434
559
  // ─────────────────────────────────────────────────────────────────────────
435
560
  // Container Management
@@ -467,6 +592,12 @@ export interface DevEnvironment<
467
592
 
468
593
  /** Build environment variables for shell commands */
469
594
  buildEnvVars(production?: boolean): Record<string, string>;
595
+ /** Set public tunnel URLs used by envVars and *_PUBLIC_URL injection */
596
+ setPublicUrls(urls: ComputedPublicUrls<TServices, TApps>): void;
597
+ /** Clear all public tunnel URLs */
598
+ clearPublicUrls(): void;
599
+ /** Ensure generated docker compose file exists and return path used with -f */
600
+ ensureComposeFile(): string;
470
601
  /** Execute a command with environment variables set */
471
602
  exec(
472
603
  cmd: string,
@@ -0,0 +1 @@
1
+ export * from "./all-types";
package/bin.ts DELETED
@@ -1,191 +0,0 @@
1
- #!/usr/bin/env bun
2
-
3
- /**
4
- * CLI Entry Point for buncargo
5
- *
6
- * Usage:
7
- * bunx buncargo dev # Start containers + dev servers
8
- * bunx buncargo dev --down # Stop containers
9
- * bunx buncargo dev --reset # Stop + remove volumes
10
- * bunx buncargo typecheck # Run TypeScript typecheck
11
- * bunx buncargo prisma ... # Run prisma commands
12
- * bunx buncargo help # Show help
13
- */
14
-
15
- import { runCli } from "./cli";
16
- import { loadDevEnv } from "./loader";
17
-
18
- /**
19
- * Load the dev environment with CLI-friendly error output.
20
- */
21
- async function loadEnv() {
22
- try {
23
- return await loadDevEnv();
24
- } catch (error) {
25
- console.error(`❌ ${error instanceof Error ? error.message : error}`);
26
- process.exit(1);
27
- }
28
- }
29
-
30
- // ═══════════════════════════════════════════════════════════════════════════
31
- // Command Handlers
32
- // ═══════════════════════════════════════════════════════════════════════════
33
-
34
- async function handleDev(args: string[]): Promise<void> {
35
- const env = await loadEnv();
36
- await runCli(env, { args });
37
- }
38
-
39
- async function handlePrisma(args: string[]): Promise<void> {
40
- const env = await loadEnv();
41
-
42
- if (!env.prisma) {
43
- console.error("❌ Prisma is not configured in your dev config.");
44
- console.error("");
45
- console.error(" Add prisma to your config:");
46
- console.error("");
47
- console.error(" export default defineDevConfig({");
48
- console.error(" ...");
49
- console.error(" prisma: {");
50
- console.error(" cwd: 'packages/prisma'");
51
- console.error(" }");
52
- console.error(" })");
53
- process.exit(1);
54
- }
55
-
56
- // Ensure database is running
57
- const running = await env.isRunning();
58
- if (!running) {
59
- console.log("🐳 Starting database container...");
60
- await env.start({ startServers: false, wait: true });
61
- }
62
-
63
- const exitCode = await env.prisma.run(args);
64
- process.exit(exitCode);
65
- }
66
-
67
- async function handleEnv(): Promise<void> {
68
- const env = await loadEnv();
69
- console.log(
70
- JSON.stringify(
71
- {
72
- projectName: env.projectName,
73
- ports: env.ports,
74
- urls: env.urls,
75
- portOffset: env.portOffset,
76
- isWorktree: env.isWorktree,
77
- localIp: env.localIp,
78
- root: env.root,
79
- },
80
- null,
81
- 2,
82
- ),
83
- );
84
- }
85
-
86
- async function handleTypecheck(): Promise<void> {
87
- const env = await loadEnv();
88
- const { runWorkspaceTypecheck } = await import("./lint");
89
- const result = await runWorkspaceTypecheck({
90
- root: env.root,
91
- verbose: true,
92
- });
93
- process.exit(result.success ? 0 : 1);
94
- }
95
-
96
- function showHelp(): void {
97
- console.log(`
98
- buncargo - Development environment CLI
99
-
100
- USAGE:
101
- bunx buncargo <command> [options]
102
-
103
- COMMANDS:
104
- dev Start the development environment
105
- typecheck Run TypeScript typecheck across workspaces
106
- prisma <args> Run Prisma CLI with correct DATABASE_URL
107
- env Print environment info as JSON
108
- help Show this help message
109
- version Show version
110
-
111
- EXAMPLES:
112
- bunx buncargo dev # Start everything
113
- bunx buncargo dev --help # Show dev command options
114
- bunx buncargo dev --down # Stop containers
115
- bunx buncargo typecheck # Run typecheck
116
- bunx buncargo prisma studio # Open Prisma Studio
117
- bunx buncargo env # Get ports/urls as JSON
118
-
119
- CONFIG:
120
- Create a dev.config.ts with a default export:
121
-
122
- import { defineDevConfig } from 'buncargo'
123
-
124
- export default defineDevConfig({
125
- projectPrefix: 'myapp',
126
- services: { ... },
127
- apps: { ... }
128
- })
129
-
130
- Run "bunx buncargo dev --help" for dev command options.
131
- `);
132
- }
133
-
134
- function showVersion(): void {
135
- const pkg = require("./package.json");
136
- console.log(`buncargo v${pkg.version}`);
137
- }
138
-
139
- // ═══════════════════════════════════════════════════════════════════════════
140
- // Main
141
- // ═══════════════════════════════════════════════════════════════════════════
142
-
143
- async function main(): Promise<void> {
144
- const args = process.argv.slice(2);
145
- const command = args[0];
146
- const commandArgs = args.slice(1);
147
-
148
- if (
149
- !command ||
150
- command === "help" ||
151
- command === "--help" ||
152
- command === "-h"
153
- ) {
154
- showHelp();
155
- process.exit(0);
156
- }
157
-
158
- if (command === "version" || command === "--version" || command === "-v") {
159
- showVersion();
160
- process.exit(0);
161
- }
162
-
163
- switch (command) {
164
- case "dev":
165
- await handleDev(commandArgs);
166
- break;
167
-
168
- case "typecheck":
169
- await handleTypecheck();
170
- break;
171
-
172
- case "prisma":
173
- await handlePrisma(commandArgs);
174
- break;
175
-
176
- case "env":
177
- await handleEnv();
178
- break;
179
-
180
- default:
181
- console.error(`❌ Unknown command: ${command}`);
182
- console.error("");
183
- console.error(' Run "bunx buncargo help" for available commands.');
184
- process.exit(1);
185
- }
186
- }
187
-
188
- main().catch((error) => {
189
- console.error("❌ Fatal error:", error);
190
- process.exit(1);
191
- });