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.
- package/dist/bin.d.ts +1 -12
- package/dist/bin.js +261 -253
- package/dist/cli/bin.d.ts +13 -0
- package/dist/cli/bin.js +317 -0
- package/dist/cli/commands/help.d.ts +1 -0
- package/dist/cli/commands/runtime.d.ts +5 -0
- package/dist/cli/commands/version.d.ts +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +14 -0
- package/dist/cli/run-cli.d.ts +30 -0
- package/dist/cli.d.ts +1 -22
- package/dist/cli.js +5 -13
- package/dist/config/config.d.ts +1 -0
- package/dist/config/define-config.d.ts +13 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.js +15 -0
- package/dist/config/merge-configs.d.ts +3 -0
- package/dist/config/validate-config.d.ts +3 -0
- package/dist/config.d.ts +1 -72
- package/dist/config.js +12 -12
- package/dist/core/docker.d.ts +1 -83
- package/dist/core/docker.js +35 -32
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +123 -118
- package/dist/core/network.js +2 -2
- package/dist/core/ports.js +1 -1
- package/dist/core/process.js +1 -1
- package/dist/core/quick-tunnel/cloudflared-process.d.ts +10 -0
- package/dist/core/quick-tunnel/constants.d.ts +9 -0
- package/dist/core/quick-tunnel/index.d.ts +17 -0
- package/dist/core/quick-tunnel/install.d.ts +1 -0
- package/dist/core/tunnel.d.ts +34 -0
- package/dist/core/utils.js +2 -2
- package/dist/core/watchdog-runner.js +45 -42
- package/dist/core/watchdog.d.ts +1 -0
- package/dist/core/watchdog.js +4 -2
- package/dist/docker/index.d.ts +1 -0
- package/dist/docker/index.js +38 -0
- package/dist/docker/runtime.d.ts +87 -0
- package/dist/docker/runtime.js +37 -0
- package/dist/docker-compose/compose.d.ts +1 -0
- package/dist/docker-compose/generated-file.d.ts +7 -0
- package/dist/docker-compose/index.d.ts +3 -0
- package/dist/docker-compose/index.js +15 -0
- package/dist/docker-compose/model.d.ts +6 -0
- package/dist/docker-compose/services/clickhouse.d.ts +16 -0
- package/dist/docker-compose/services/define-docker-service.d.ts +41 -0
- package/dist/docker-compose/services/index.d.ts +23 -0
- package/dist/docker-compose/services/index.js +17 -0
- package/dist/docker-compose/services/postgres.d.ts +12 -0
- package/dist/docker-compose/services/redis.d.ts +12 -0
- package/dist/docker-compose/services/shared.d.ts +7 -0
- package/dist/docker-compose/yaml.d.ts +2 -0
- package/dist/environment/create-dev-environment.d.ts +23 -0
- package/dist/environment/index.d.ts +1 -0
- package/dist/environment/index.js +15 -0
- package/dist/environment/logging.d.ts +17 -0
- package/dist/environment/only-apps.d.ts +10 -0
- package/dist/environment/seeding.d.ts +9 -0
- package/dist/environment.d.ts +1 -23
- package/dist/environment.js +12 -14
- package/dist/index-045jksh5.js +147 -0
- package/dist/index-08wa79cs.js +125 -117
- package/dist/index-0kxnae3z.js +335 -0
- package/dist/index-1mdrf7nz.js +51 -43
- package/dist/index-1yvbwj4k.js +262 -242
- package/dist/index-23ev345g.js +475 -0
- package/dist/index-2ckr49sf.js +228 -0
- package/dist/index-2f47khe5.js +376 -369
- package/dist/index-2fr3g85b.js +220 -183
- package/dist/index-38xnzpa6.js +450 -0
- package/dist/index-3eyrdxw9.js +577 -0
- package/dist/index-3h3dhtf2.js +51 -43
- package/dist/index-42x95209.js +51 -43
- package/dist/index-4gp0az1g.js +145 -0
- package/dist/index-4xrxh8yv.js +72 -0
- package/dist/index-5aq985p4.js +250 -0
- package/dist/index-5gmws6ah.js +181 -0
- package/dist/index-5hka0tff.js +78 -76
- package/dist/index-5rfqps4b.js +3 -0
- package/dist/index-5t9jxqm0.js +428 -0
- package/dist/index-6c1w1xk5.js +101 -0
- package/dist/index-6cmex7m5.js +72 -0
- package/dist/index-6d6x175r.js +572 -0
- package/dist/index-6fm7mvwj.js +118 -97
- package/dist/index-6srpc523.js +127 -128
- package/dist/index-731rzzfp.js +157 -142
- package/dist/index-75y4cg2z.js +51 -43
- package/dist/index-7ja4ywyj.js +126 -127
- package/dist/index-7v19es2e.js +666 -0
- package/dist/index-8bw1cmz4.js +531 -0
- package/dist/index-8hbbj1mp.js +120 -121
- package/dist/index-8xj2p5n5.js +118 -97
- package/dist/index-9wyhzw0h.js +574 -0
- package/dist/index-ag90ry8t.js +576 -0
- package/dist/index-bj79tw5w.js +0 -0
- package/dist/index-bnk6nr0g.js +73 -0
- package/dist/index-brbbzyks.js +72 -0
- package/dist/index-byeqyjrz.js +72 -0
- package/dist/index-c0dr6mcv.js +123 -0
- package/dist/index-cty0bcry.js +235 -218
- package/dist/index-d8tyv5se.js +228 -0
- package/dist/index-d9efy0n4.js +176 -150
- package/dist/index-enj4zdma.js +574 -0
- package/dist/index-etfmqjjf.js +427 -0
- package/dist/index-fb29934k.js +172 -0
- package/dist/index-g50jw1yf.js +72 -0
- package/dist/index-g6eb5wdw.js +118 -117
- package/dist/index-ggq3yryx.js +99 -95
- package/dist/index-h70tce00.js +177 -0
- package/dist/index-hkxtfqtc.js +333 -0
- package/dist/index-k370bech.js +72 -0
- package/dist/index-kf3dhser.js +146 -143
- package/dist/index-ma6tgdb2.js +500 -0
- package/dist/index-mam0bcyz.js +123 -0
- package/dist/index-mm412dkp.js +274 -0
- package/dist/index-n8v18aeb.js +0 -0
- package/dist/index-ndnmnsej.js +378 -371
- package/dist/index-p8wty0e2.js +389 -379
- package/dist/index-qa8akv6y.js +666 -0
- package/dist/index-qfphr2fd.js +78 -76
- package/dist/index-qqmms8rs.js +51 -43
- package/dist/index-qw4093g2.js +51 -43
- package/dist/index-qzwpzjbx.js +121 -122
- package/dist/index-segbnm0h.js +146 -143
- package/dist/index-t0fj6gg1.js +112 -0
- package/dist/index-thdkwnv7.js +122 -0
- package/dist/index-tjbx2r2t.js +270 -0
- package/dist/index-tjqw9vtj.js +62 -54
- package/dist/index-vbpb89jy.js +248 -0
- package/dist/index-vg55rq0y.js +250 -0
- package/dist/index-vhs88xhe.js +99 -95
- package/dist/index-vs81yaks.js +244 -0
- package/dist/index-w8zxnjka.js +249 -0
- package/dist/index-wk2na3t9.js +385 -375
- package/dist/index-wz9x8g7z.js +383 -373
- package/dist/index-x249gyde.js +388 -378
- package/dist/index-x54nbgs7.js +355 -0
- package/dist/index-xkvd0nsd.js +187 -0
- package/dist/index-yedqxm1z.js +80 -0
- package/dist/index-yz4jfz7z.js +338 -0
- package/dist/index-zfjzzjkf.js +240 -199
- package/dist/index.d.ts +12 -8
- package/dist/index.js +56 -34
- package/dist/lint.d.ts +1 -46
- package/dist/lint.js +3 -7
- package/dist/loader/cache.d.ts +4 -0
- package/dist/loader/find-config-file.d.ts +2 -0
- package/dist/loader/index.d.ts +5 -0
- package/dist/loader/index.js +24 -0
- package/dist/loader/load-dev-env.d.ts +5 -0
- package/dist/loader/loader.d.ts +1 -0
- package/dist/loader.d.ts +1 -45
- package/dist/loader.js +22 -20
- package/dist/prisma/index.d.ts +1 -0
- package/dist/prisma/prisma.d.ts +29 -0
- package/dist/prisma.d.ts +1 -29
- package/dist/prisma.js +6 -10
- package/dist/src/bin.js +309 -0
- package/dist/src/cli.js +5 -0
- package/dist/src/config.js +15 -0
- package/dist/src/core/docker.js +38 -0
- package/dist/src/core/index.js +130 -0
- package/dist/src/core/network.js +9 -0
- package/dist/src/core/ports.js +23 -0
- package/dist/src/core/process.js +31 -0
- package/dist/src/core/utils.js +11 -0
- package/dist/src/core/watchdog-runner.js +69 -0
- package/dist/src/core/watchdog.js +28 -0
- package/dist/src/docker/runtime.js +37 -0
- package/dist/src/docker-compose/index.js +16 -0
- package/dist/src/docker-compose/services/index.js +17 -0
- package/dist/src/environment.js +12 -0
- package/dist/src/index.js +122 -0
- package/dist/src/lint.js +3 -0
- package/dist/src/loader.js +25 -0
- package/dist/src/prisma.js +6 -0
- package/dist/src/types.js +0 -0
- package/dist/typecheck/index.d.ts +1 -0
- package/dist/typecheck/index.js +7 -0
- package/dist/typecheck/typecheck.d.ts +46 -0
- package/dist/types/all-types.d.ts +544 -0
- package/dist/types/cli.d.ts +1 -0
- package/dist/types/config.d.ts +6 -0
- package/dist/types/docker.d.ts +15 -0
- package/dist/types/environment.d.ts +8 -0
- package/dist/types/hooks.d.ts +9 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +0 -0
- package/dist/types/prisma.d.ts +1 -0
- package/dist/types.d.ts +1 -399
- package/package.json +55 -48
- package/readme.md +365 -109
- package/src/cli/bin.ts +77 -0
- package/src/cli/commands/help.ts +39 -0
- package/src/cli/commands/runtime.ts +72 -0
- package/src/cli/commands/version.ts +4 -0
- package/src/cli/index.ts +1 -0
- package/{cli.ts → src/cli/run-cli.ts} +114 -10
- package/src/config/define-config.ts +30 -0
- package/src/config/index.ts +3 -0
- package/src/config/merge-configs.ts +33 -0
- package/src/config/validate-config.ts +136 -0
- package/{core → src/core}/index.ts +2 -2
- package/{core → src/core}/ports.ts +5 -2
- package/{core → src/core}/process.ts +6 -2
- package/src/core/quick-tunnel/cloudflared-process.ts +83 -0
- package/src/core/quick-tunnel/constants.ts +31 -0
- package/src/core/quick-tunnel/index.ts +96 -0
- package/src/core/quick-tunnel/install.ts +160 -0
- package/src/core/tunnel.ts +165 -0
- package/{core → src/core}/utils.ts +1 -0
- package/{core → src/core}/watchdog.ts +5 -1
- package/src/docker/index.ts +1 -0
- package/{core/docker.ts → src/docker/runtime.ts} +11 -4
- package/src/docker-compose/generated-file.ts +45 -0
- package/src/docker-compose/index.ts +7 -0
- package/src/docker-compose/model.ts +197 -0
- package/src/docker-compose/services/clickhouse.ts +79 -0
- package/src/docker-compose/services/define-docker-service.ts +109 -0
- package/src/docker-compose/services/index.ts +67 -0
- package/src/docker-compose/services/postgres.ts +60 -0
- package/src/docker-compose/services/redis.ts +48 -0
- package/src/docker-compose/services/shared.ts +79 -0
- package/src/docker-compose/yaml.ts +88 -0
- package/{environment.ts → src/environment/create-dev-environment.ts} +214 -141
- package/src/environment/index.ts +1 -0
- package/src/environment/logging.ts +115 -0
- package/src/environment/only-apps.ts +34 -0
- package/src/environment/seeding.ts +57 -0
- package/{index.ts → src/index.ts} +52 -20
- package/src/loader/cache.ts +23 -0
- package/src/loader/find-config-file.ts +29 -0
- package/src/loader/index.ts +17 -0
- package/src/loader/load-dev-env.ts +38 -0
- package/src/prisma/index.ts +1 -0
- package/{prisma.ts → src/prisma/prisma.ts} +4 -2
- package/src/typecheck/index.ts +1 -0
- package/{types.ts → src/types/all-types.ts} +186 -8
- package/src/types/index.ts +1 -0
- package/bin.ts +0 -192
- package/config.ts +0 -194
- package/loader.ts +0 -126
- /package/{core → src/core}/network.ts +0 -0
- /package/{core → src/core}/watchdog-runner.ts +0 -0
- /package/{lint.ts → src/typecheck/typecheck.ts} +0 -0
package/readme.md
CHANGED
|
@@ -1,110 +1,224 @@
|
|
|
1
1
|
# Buncargo
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A Bun-first development environment toolkit that eliminates the friction of local dev setup. Define your entire dev stack in a single typed config file—Docker services, app servers, environment variables, migrations, and more.
|
|
4
|
+
|
|
5
|
+
## Why Buncargo?
|
|
6
|
+
|
|
7
|
+
**The problem**: Local development environments are fragile. Teams maintain separate `docker-compose.yml` files, scatter port assignments across `.env` files, manually manage container lifecycles, and struggle with port conflicts when working on multiple branches.
|
|
8
|
+
|
|
9
|
+
**The solution**: Buncargo provides a single source of truth for your dev environment. One `dev.config.ts` file defines everything. Type-safe. Auto-generated Docker Compose. Worktree-aware port isolation. Zero configuration drift.
|
|
10
|
+
|
|
11
|
+
## Key Features
|
|
12
|
+
|
|
13
|
+
- **Single config file** — Define services, apps, ports, URLs, migrations, and hooks in one typed `dev.config.ts`
|
|
14
|
+
- **Auto-generated Docker Compose** — No manual compose files; buncargo generates them from your config
|
|
15
|
+
- **Worktree isolation** — Each git worktree gets unique ports and isolated containers automatically
|
|
16
|
+
- **Built-in service presets** — One-liner setup for Postgres, Redis, ClickHouse with health checks and URL templates
|
|
17
|
+
- **Custom service support** — Full Docker Compose escape hatch for any service
|
|
18
|
+
- **Dev server orchestration** — Start and monitor multiple app servers with health checks
|
|
19
|
+
- **Public tunnels** — Expose services via Cloudflare Quick Tunnels for webhook testing and mobile dev
|
|
20
|
+
- **Prisma integration** — Run Prisma commands with auto-injected `DATABASE_URL`
|
|
21
|
+
- **Lifecycle hooks** — Run migrations, seeders, or custom scripts at the right time
|
|
22
|
+
- **Programmatic API** — Access ports/URLs in tests or scripts
|
|
23
|
+
- **Watchdog auto-shutdown** — Containers stop automatically after inactivity
|
|
4
24
|
|
|
5
25
|
## Quick Start
|
|
6
26
|
|
|
7
|
-
### 1.
|
|
27
|
+
### 1. Install
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
bun add -d buncargo
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 2. Create `dev.config.ts`
|
|
8
34
|
|
|
9
35
|
```typescript
|
|
10
|
-
import { defineDevConfig } from 'buncargo'
|
|
36
|
+
import { defineDevConfig, service } from 'buncargo'
|
|
11
37
|
|
|
12
38
|
export default defineDevConfig({
|
|
13
39
|
projectPrefix: 'myapp',
|
|
14
40
|
|
|
15
41
|
services: {
|
|
16
|
-
postgres: {
|
|
17
|
-
|
|
18
|
-
healthCheck: 'pg_isready',
|
|
19
|
-
urlTemplate: ({ port }) => `postgresql://postgres:postgres@localhost:${port}/mydb`
|
|
20
|
-
},
|
|
21
|
-
redis: {
|
|
22
|
-
port: 6379,
|
|
23
|
-
healthCheck: 'redis-cli'
|
|
24
|
-
}
|
|
42
|
+
postgres: service.postgres({ database: 'mydb' }),
|
|
43
|
+
redis: service.redis(),
|
|
25
44
|
},
|
|
26
45
|
|
|
27
46
|
apps: {
|
|
28
47
|
api: {
|
|
29
48
|
port: 3000,
|
|
30
49
|
devCommand: 'bun run dev',
|
|
31
|
-
cwd: 'apps/backend'
|
|
50
|
+
cwd: 'apps/backend',
|
|
32
51
|
},
|
|
33
52
|
web: {
|
|
34
53
|
port: 5173,
|
|
35
54
|
devCommand: 'bun run dev',
|
|
36
|
-
cwd: 'apps/frontend'
|
|
37
|
-
}
|
|
55
|
+
cwd: 'apps/frontend',
|
|
56
|
+
},
|
|
38
57
|
},
|
|
39
58
|
|
|
40
59
|
envVars: (ports, urls) => ({
|
|
41
60
|
DATABASE_URL: urls.postgres,
|
|
42
61
|
REDIS_URL: urls.redis,
|
|
43
|
-
API_PORT: ports.api
|
|
62
|
+
API_PORT: ports.api,
|
|
44
63
|
}),
|
|
45
|
-
|
|
46
|
-
hooks: {
|
|
47
|
-
afterContainersReady: async (ctx) => {
|
|
48
|
-
await ctx.exec('bunx prisma migrate deploy', { cwd: 'packages/prisma' })
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
|
|
52
|
-
prisma: {
|
|
53
|
-
cwd: 'packages/prisma'
|
|
54
|
-
}
|
|
55
64
|
})
|
|
56
65
|
```
|
|
57
66
|
|
|
58
|
-
###
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
bunx buncargo dev # Start containers + dev servers
|
|
62
|
-
bunx buncargo dev --up-only # Start containers only
|
|
63
|
-
bunx buncargo dev --down # Stop containers
|
|
64
|
-
bunx buncargo dev --reset # Stop and remove volumes
|
|
65
|
-
bunx buncargo typecheck # Run TypeScript typecheck across workspaces
|
|
66
|
-
bunx buncargo prisma studio # Run prisma with correct DATABASE_URL
|
|
67
|
-
bunx buncargo env # Print ports/urls as JSON
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
Or add scripts to `package.json`:
|
|
67
|
+
### 3. Add scripts to `package.json`
|
|
71
68
|
|
|
72
69
|
```json
|
|
73
70
|
{
|
|
74
71
|
"scripts": {
|
|
75
72
|
"dev": "bunx buncargo dev",
|
|
76
|
-
"dev:
|
|
77
|
-
"
|
|
73
|
+
"dev:up": "bunx buncargo dev --up-only",
|
|
74
|
+
"dev:down": "bunx buncargo dev --down",
|
|
75
|
+
"dev:reset": "bunx buncargo dev --reset",
|
|
76
|
+
"dev:expose": "bunx buncargo dev --expose",
|
|
78
77
|
"prisma": "bunx buncargo prisma"
|
|
79
78
|
}
|
|
80
79
|
}
|
|
81
80
|
```
|
|
82
81
|
|
|
83
|
-
|
|
82
|
+
### 4. Run
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
bun run dev
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Buncargo will:
|
|
89
|
+
1. Generate a Docker Compose file from your config
|
|
90
|
+
2. Start all containers and wait for health checks
|
|
91
|
+
3. Run any configured migrations
|
|
92
|
+
4. Start your dev servers
|
|
93
|
+
5. Print all ports and URLs
|
|
94
|
+
|
|
95
|
+
## CLI Commands
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
bunx buncargo dev # Start containers + dev servers
|
|
99
|
+
bunx buncargo dev --up-only # Start containers only (no dev servers)
|
|
100
|
+
bunx buncargo dev --down # Stop containers
|
|
101
|
+
bunx buncargo dev --reset # Stop containers and remove volumes
|
|
102
|
+
bunx buncargo dev --expose # Start with public tunnels for expose:true targets
|
|
103
|
+
bunx buncargo dev --expose=api # Expose specific targets
|
|
104
|
+
bunx buncargo dev --migrate # Run migrations only
|
|
105
|
+
bunx buncargo dev --seed # Run migrations and seeders
|
|
106
|
+
bunx buncargo prisma <args> # Run Prisma CLI with correct DATABASE_URL
|
|
107
|
+
bunx buncargo typecheck # Run TypeScript typecheck across workspaces
|
|
108
|
+
bunx buncargo env # Print ports/URLs as JSON
|
|
109
|
+
bunx buncargo help # Show help
|
|
110
|
+
bunx buncargo version # Show version
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Services
|
|
84
114
|
|
|
85
|
-
|
|
115
|
+
### Built-in Presets
|
|
116
|
+
|
|
117
|
+
Use `service.*` helpers for common databases with sensible defaults:
|
|
86
118
|
|
|
87
119
|
```typescript
|
|
88
|
-
|
|
120
|
+
services: {
|
|
121
|
+
postgres: service.postgres({ database: 'mydb' }),
|
|
122
|
+
redis: service.redis(),
|
|
123
|
+
clickhouse: service.clickhouse({ database: 'analytics' }),
|
|
124
|
+
}
|
|
125
|
+
```
|
|
89
126
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
127
|
+
Each preset includes:
|
|
128
|
+
- Default Docker image
|
|
129
|
+
- Health check configuration
|
|
130
|
+
- URL template (e.g., `postgresql://postgres:postgres@localhost:5432/mydb`)
|
|
131
|
+
- Volume for data persistence
|
|
132
|
+
|
|
133
|
+
### Custom Services
|
|
134
|
+
|
|
135
|
+
Use `service.custom()` for any Docker service:
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
services: {
|
|
139
|
+
rabbitmq: service.custom({
|
|
140
|
+
port: 5672,
|
|
141
|
+
healthCheck: false,
|
|
142
|
+
docker: {
|
|
143
|
+
image: 'rabbitmq:3-management-alpine',
|
|
144
|
+
ports: ['${RABBITMQ_PORT:-5672}:5672', '15672:15672'],
|
|
145
|
+
environment: {
|
|
146
|
+
RABBITMQ_DEFAULT_USER: 'guest',
|
|
147
|
+
RABBITMQ_DEFAULT_PASS: 'guest',
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
}),
|
|
151
|
+
nats: service.custom({
|
|
152
|
+
port: 4222,
|
|
153
|
+
docker: {
|
|
154
|
+
image: 'nats:2-alpine',
|
|
155
|
+
ports: ['${NATS_PORT:-4222}:4222'],
|
|
156
|
+
},
|
|
157
|
+
}),
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Apps
|
|
162
|
+
|
|
163
|
+
Define dev servers to run alongside containers:
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
apps: {
|
|
167
|
+
api: {
|
|
168
|
+
port: 3000,
|
|
169
|
+
devCommand: 'bun run dev',
|
|
170
|
+
cwd: 'apps/backend',
|
|
171
|
+
healthEndpoint: '/health',
|
|
172
|
+
},
|
|
173
|
+
web: {
|
|
174
|
+
port: 5173,
|
|
175
|
+
devCommand: 'bun run dev',
|
|
176
|
+
cwd: 'apps/frontend',
|
|
177
|
+
healthEndpoint: '/',
|
|
178
|
+
},
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Use `onlyApps` on `start()` or `startServers()` to launch and wait for only those named apps (same env injection and health checks as when all apps run).
|
|
183
|
+
|
|
184
|
+
## Environment Variables
|
|
185
|
+
|
|
186
|
+
The `envVars` function builds all env vars from computed ports and URLs:
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
envVars: (ports, urls, { localIp, publicUrls }) => ({
|
|
190
|
+
DATABASE_URL: urls.postgres,
|
|
191
|
+
REDIS_URL: urls.redis,
|
|
192
|
+
API_PORT: ports.api,
|
|
193
|
+
EXPO_API_URL: `http://${localIp}:${ports.api}`,
|
|
194
|
+
WEBHOOK_URL: publicUrls.api ?? urls.api,
|
|
195
|
+
})
|
|
94
196
|
```
|
|
95
197
|
|
|
96
|
-
|
|
198
|
+
`buildEnvVars()` always includes, for each service/app name `foo`:
|
|
199
|
+
|
|
200
|
+
- `FOO_PORT` — assigned port
|
|
201
|
+
- `FOO_URL` — local URL (LAN)
|
|
202
|
+
- `FOO_PUBLIC_URL` — only while a public tunnel is active for that name
|
|
97
203
|
|
|
98
|
-
|
|
204
|
+
Your `envVars` callback receives `publicUrls` and typically maps client bundles, e.g. `EXPO_PUBLIC_API_URL: publicUrls.api ?? urls.api`.
|
|
205
|
+
|
|
206
|
+
These are injected into:
|
|
207
|
+
- Docker Compose services
|
|
208
|
+
- Dev server processes
|
|
209
|
+
- Hook `exec()` calls
|
|
210
|
+
- Prisma commands
|
|
99
211
|
|
|
100
|
-
|
|
212
|
+
## Worktree Isolation
|
|
101
213
|
|
|
102
|
-
|
|
103
|
-
-
|
|
214
|
+
When working in git worktrees, buncargo automatically assigns unique port offsets (10-99) so each worktree has isolated:
|
|
215
|
+
- Ports (e.g., postgres on 5442 instead of 5432)
|
|
216
|
+
- Docker Compose project names
|
|
217
|
+
- Containers, networks, and volumes
|
|
104
218
|
|
|
105
|
-
This means
|
|
219
|
+
This means you can run multiple branches simultaneously without conflicts.
|
|
106
220
|
|
|
107
|
-
|
|
221
|
+
To disable isolation and share state across worktrees:
|
|
108
222
|
|
|
109
223
|
```typescript
|
|
110
224
|
options: {
|
|
@@ -112,46 +226,71 @@ options: {
|
|
|
112
226
|
}
|
|
113
227
|
```
|
|
114
228
|
|
|
115
|
-
|
|
229
|
+
## Public Tunnels
|
|
116
230
|
|
|
117
|
-
|
|
231
|
+
Expose local services to the internet using Cloudflare Quick Tunnels:
|
|
118
232
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
233
|
+
```typescript
|
|
234
|
+
services: {
|
|
235
|
+
postgres: service.postgres({ database: 'mydb' }),
|
|
236
|
+
},
|
|
237
|
+
apps: {
|
|
238
|
+
api: {
|
|
239
|
+
port: 3000,
|
|
240
|
+
devCommand: 'bun run dev',
|
|
241
|
+
expose: true, // Mark as exposable
|
|
242
|
+
},
|
|
243
|
+
}
|
|
244
|
+
```
|
|
123
245
|
|
|
124
|
-
|
|
246
|
+
```bash
|
|
247
|
+
bun run dev --expose # Expose all targets with expose: true
|
|
248
|
+
bun run dev --expose=api # Expose specific targets
|
|
249
|
+
```
|
|
125
250
|
|
|
126
|
-
|
|
251
|
+
Public URLs are printed in the console and available via `publicUrls` in `envVars`:
|
|
127
252
|
|
|
128
253
|
```typescript
|
|
129
|
-
|
|
130
|
-
|
|
254
|
+
envVars: (_ports, urls, { publicUrls }) => ({
|
|
255
|
+
WEBHOOK_URL: publicUrls.api ?? urls.api,
|
|
256
|
+
})
|
|
131
257
|
```
|
|
132
258
|
|
|
133
|
-
|
|
259
|
+
**CLI vs programmatic ordering:** `bunx buncargo dev --expose` starts Cloudflare quick tunnels after containers and migrations but **before** the interactive dev-server command (e.g. `concurrently`) runs. Until those servers are listening on their ports, tunnel traffic can briefly error. For “servers first, then public URLs,” use the API: e.g. `await dev.startServers({ onlyApps: ['api', 'platform'] })`, then `await dev.openPublicTunnels({ waitForHealthy: ['api', 'platform'] })` (optional; waits HTTP health first), then read `dev.buildEnvVars()` for spawned children.
|
|
260
|
+
|
|
261
|
+
**Expo hybrid:** buncargo is suited to exposing **API** and **platform** (Vite, etc.) for devices on cellular. **Metro** often uses Expo’s own tunnel (`expo start --tunnel`); you usually do **not** add Metro as a buncargo `app` unless you want buncargo to start it. Wire `EXPO_PUBLIC_*` from `publicUrls.* ?? urls.*` in `envVars`.
|
|
134
262
|
|
|
135
|
-
|
|
263
|
+
**Programmatic helper:** `openPublicTunnels({ names?, waitForHealthy? })` applies tunnel URLs via `setPublicUrls` and returns `close()` to stop tunnels and clear public URLs. Call `buildEnvVars()` after `openPublicTunnels` resolves so `envVars` and `*_PUBLIC_URL` see the tunnel origins.
|
|
264
|
+
|
|
265
|
+
## Lifecycle Hooks
|
|
266
|
+
|
|
267
|
+
Run code at specific points in the startup/shutdown cycle:
|
|
136
268
|
|
|
137
269
|
```typescript
|
|
138
270
|
hooks: {
|
|
139
|
-
afterContainersReady: async (ctx) => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
271
|
+
afterContainersReady: async (ctx) => {
|
|
272
|
+
await ctx.exec('bunx prisma migrate deploy', { cwd: 'packages/prisma' })
|
|
273
|
+
},
|
|
274
|
+
beforeServers: async (ctx) => {
|
|
275
|
+
await ctx.exec('bun run seed')
|
|
276
|
+
},
|
|
277
|
+
afterServers: async (ctx) => {
|
|
278
|
+
console.log(`API running at ${ctx.urls.api}`)
|
|
279
|
+
},
|
|
280
|
+
beforeStop: async (ctx) => {
|
|
281
|
+
await ctx.exec('bun run cleanup', { throwOnError: false })
|
|
282
|
+
},
|
|
143
283
|
}
|
|
144
284
|
```
|
|
145
285
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
Hooks receive a context object with:
|
|
286
|
+
Hook context provides:
|
|
149
287
|
|
|
150
288
|
```typescript
|
|
151
289
|
interface HookContext {
|
|
152
290
|
projectName: string
|
|
153
291
|
ports: { postgres: number, api: number, ... }
|
|
154
292
|
urls: { postgres: string, api: string, ... }
|
|
293
|
+
publicUrls: { api?: string, ... }
|
|
155
294
|
root: string
|
|
156
295
|
isCI: boolean
|
|
157
296
|
portOffset: number
|
|
@@ -160,54 +299,171 @@ interface HookContext {
|
|
|
160
299
|
}
|
|
161
300
|
```
|
|
162
301
|
|
|
163
|
-
|
|
302
|
+
## Migrations and Seeding
|
|
164
303
|
|
|
165
|
-
|
|
304
|
+
### Migrations
|
|
166
305
|
|
|
167
|
-
|
|
306
|
+
Run migration commands after containers are healthy:
|
|
168
307
|
|
|
308
|
+
```typescript
|
|
309
|
+
migrations: [
|
|
310
|
+
{ name: 'prisma', command: 'bunx prisma migrate deploy', cwd: 'packages/prisma' },
|
|
311
|
+
{ name: 'clickhouse', command: 'bun run migrate:clickhouse' },
|
|
312
|
+
]
|
|
169
313
|
```
|
|
170
|
-
COMMANDS:
|
|
171
|
-
dev Start the development environment
|
|
172
|
-
typecheck Run TypeScript typecheck across workspaces
|
|
173
|
-
prisma <args> Run Prisma CLI with correct DATABASE_URL
|
|
174
|
-
env Print environment info as JSON
|
|
175
|
-
help Show help
|
|
176
|
-
version Show version
|
|
177
314
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
315
|
+
### Seeding
|
|
316
|
+
|
|
317
|
+
Seed the database with a check to avoid re-seeding:
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
seed: {
|
|
321
|
+
command: 'bun run seed',
|
|
322
|
+
check: ({ checkTable }) => checkTable('User', 'postgres'),
|
|
323
|
+
}
|
|
184
324
|
```
|
|
185
325
|
|
|
186
|
-
##
|
|
326
|
+
## Prisma Integration
|
|
187
327
|
|
|
188
|
-
|
|
328
|
+
Configure Prisma to use the correct database URL:
|
|
189
329
|
|
|
190
330
|
```typescript
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
}
|
|
331
|
+
prisma: {
|
|
332
|
+
cwd: 'packages/prisma',
|
|
333
|
+
service: 'postgres', // Default: 'postgres'
|
|
334
|
+
urlEnvVar: 'DATABASE_URL', // Default: 'DATABASE_URL'
|
|
335
|
+
}
|
|
196
336
|
```
|
|
197
337
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
338
|
+
Then run Prisma commands through buncargo:
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
bun run prisma migrate dev
|
|
342
|
+
bun run prisma studio
|
|
343
|
+
bun run prisma db push
|
|
344
|
+
```
|
|
202
345
|
|
|
203
|
-
|
|
346
|
+
Buncargo ensures the database container is running and injects the correct `DATABASE_URL` with worktree-aware ports.
|
|
204
347
|
|
|
205
|
-
|
|
348
|
+
## Programmatic API
|
|
206
349
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
350
|
+
Access the dev environment from code (useful for tests):
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
import { loadDevEnv } from 'buncargo'
|
|
354
|
+
|
|
355
|
+
const env = await loadDevEnv()
|
|
356
|
+
|
|
357
|
+
console.log(env.ports.postgres) // 5432 (or offset port)
|
|
358
|
+
console.log(env.urls.api) // http://localhost:3000
|
|
359
|
+
console.log(env.urls.postgres) // postgresql://postgres:postgres@localhost:5432/mydb
|
|
360
|
+
|
|
361
|
+
// Start/stop programmatically
|
|
362
|
+
await env.start()
|
|
363
|
+
await env.stop({ removeVolumes: true })
|
|
364
|
+
|
|
365
|
+
// Build env vars for subprocess
|
|
366
|
+
const envVars = env.buildEnvVars()
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
## Docker Compose Generation
|
|
370
|
+
|
|
371
|
+
Buncargo generates Docker Compose from your config. No external `docker-compose.yml` is read.
|
|
372
|
+
|
|
373
|
+
```typescript
|
|
374
|
+
docker: {
|
|
375
|
+
generatedFile: '.buncargo/docker-compose.generated.yml',
|
|
376
|
+
writeStrategy: 'always', // or 'if-missing'
|
|
377
|
+
volumes: {
|
|
378
|
+
shared_cache: {},
|
|
379
|
+
},
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
## Health Checks
|
|
384
|
+
|
|
385
|
+
Built-in health check types:
|
|
386
|
+
|
|
387
|
+
| Type | Description |
|
|
388
|
+
|------|-------------|
|
|
389
|
+
| `pg_isready` | PostgreSQL readiness check |
|
|
390
|
+
| `redis-cli` | Redis PING check |
|
|
391
|
+
| `http` | HTTP endpoint check |
|
|
392
|
+
| `tcp` | TCP port check |
|
|
393
|
+
|
|
394
|
+
Or provide a custom health check function:
|
|
395
|
+
|
|
396
|
+
```typescript
|
|
397
|
+
healthCheck: async (port) => {
|
|
398
|
+
const res = await fetch(`http://localhost:${port}/health`)
|
|
399
|
+
return res.ok
|
|
400
|
+
}
|
|
213
401
|
```
|
|
402
|
+
|
|
403
|
+
## Watchdog Auto-Shutdown
|
|
404
|
+
|
|
405
|
+
When running via CLI, containers automatically stop after 10 minutes of inactivity. The watchdog monitors heartbeats and shuts down orphaned environments.
|
|
406
|
+
|
|
407
|
+
## Full Example
|
|
408
|
+
|
|
409
|
+
```typescript
|
|
410
|
+
import { defineDevConfig, service } from 'buncargo'
|
|
411
|
+
|
|
412
|
+
export default defineDevConfig({
|
|
413
|
+
projectPrefix: 'platform',
|
|
414
|
+
|
|
415
|
+
services: {
|
|
416
|
+
postgres: service.postgres({ database: 'platform' }),
|
|
417
|
+
redis: service.redis(),
|
|
418
|
+
clickhouse: service.clickhouse({ database: 'platform' }),
|
|
419
|
+
},
|
|
420
|
+
|
|
421
|
+
apps: {
|
|
422
|
+
api: {
|
|
423
|
+
port: 3000,
|
|
424
|
+
expose: true,
|
|
425
|
+
devCommand: 'bun run dev',
|
|
426
|
+
cwd: 'apps/backend',
|
|
427
|
+
healthEndpoint: '/health',
|
|
428
|
+
},
|
|
429
|
+
web: {
|
|
430
|
+
port: 5173,
|
|
431
|
+
devCommand: 'bun run dev',
|
|
432
|
+
cwd: 'apps/frontend',
|
|
433
|
+
},
|
|
434
|
+
},
|
|
435
|
+
|
|
436
|
+
envVars: (ports, urls, { localIp, publicUrls }) => ({
|
|
437
|
+
DATABASE_URL: urls.postgres,
|
|
438
|
+
REDIS_URL: urls.redis,
|
|
439
|
+
CLICKHOUSE_URL: urls.clickhouse,
|
|
440
|
+
API_URL: urls.api,
|
|
441
|
+
VITE_API_URL: urls.api,
|
|
442
|
+
EXPO_API_URL: `http://${localIp}:${ports.api}`,
|
|
443
|
+
WEBHOOK_URL: publicUrls.api ?? urls.api,
|
|
444
|
+
}),
|
|
445
|
+
|
|
446
|
+
migrations: [
|
|
447
|
+
{ name: 'prisma', command: 'bunx prisma migrate deploy', cwd: 'packages/prisma' },
|
|
448
|
+
],
|
|
449
|
+
|
|
450
|
+
seed: {
|
|
451
|
+
command: 'bun run seed',
|
|
452
|
+
check: ({ checkTable }) => checkTable('User', 'postgres'),
|
|
453
|
+
},
|
|
454
|
+
|
|
455
|
+
prisma: {
|
|
456
|
+
cwd: 'packages/prisma',
|
|
457
|
+
},
|
|
458
|
+
|
|
459
|
+
hooks: {
|
|
460
|
+
afterContainersReady: async (ctx) => {
|
|
461
|
+
console.log(`Containers ready on port offset ${ctx.portOffset}`)
|
|
462
|
+
},
|
|
463
|
+
},
|
|
464
|
+
})
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
## License
|
|
468
|
+
|
|
469
|
+
MIT
|
package/src/cli/bin.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
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 { showHelp } from "./commands/help";
|
|
16
|
+
import {
|
|
17
|
+
handleDev,
|
|
18
|
+
handleEnv,
|
|
19
|
+
handlePrisma,
|
|
20
|
+
handleTypecheck,
|
|
21
|
+
} from "./commands/runtime";
|
|
22
|
+
import { showVersion } from "./commands/version";
|
|
23
|
+
|
|
24
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
25
|
+
// Main
|
|
26
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
27
|
+
|
|
28
|
+
async function main(): Promise<void> {
|
|
29
|
+
const args = process.argv.slice(2);
|
|
30
|
+
const command = args[0];
|
|
31
|
+
const commandArgs = args.slice(1);
|
|
32
|
+
|
|
33
|
+
if (
|
|
34
|
+
!command ||
|
|
35
|
+
command === "help" ||
|
|
36
|
+
command === "--help" ||
|
|
37
|
+
command === "-h"
|
|
38
|
+
) {
|
|
39
|
+
showHelp();
|
|
40
|
+
process.exit(0);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (command === "version" || command === "--version" || command === "-v") {
|
|
44
|
+
showVersion();
|
|
45
|
+
process.exit(0);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
switch (command) {
|
|
49
|
+
case "dev":
|
|
50
|
+
await handleDev(commandArgs);
|
|
51
|
+
break;
|
|
52
|
+
|
|
53
|
+
case "typecheck":
|
|
54
|
+
await handleTypecheck();
|
|
55
|
+
break;
|
|
56
|
+
|
|
57
|
+
case "prisma":
|
|
58
|
+
await handlePrisma(commandArgs);
|
|
59
|
+
break;
|
|
60
|
+
|
|
61
|
+
case "env":
|
|
62
|
+
await handleEnv();
|
|
63
|
+
break;
|
|
64
|
+
|
|
65
|
+
default:
|
|
66
|
+
console.error(`❌ Unknown command: ${command}`);
|
|
67
|
+
console.error("");
|
|
68
|
+
console.error(' Run "bunx buncargo help" for available commands.');
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
main().catch((error) => {
|
|
74
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
75
|
+
console.error(`❌ ${message}`);
|
|
76
|
+
process.exit(1);
|
|
77
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export function showHelp(): void {
|
|
2
|
+
console.log(`
|
|
3
|
+
buncargo - Development environment CLI
|
|
4
|
+
|
|
5
|
+
USAGE:
|
|
6
|
+
bunx buncargo <command> [options]
|
|
7
|
+
|
|
8
|
+
COMMANDS:
|
|
9
|
+
dev Start the development environment
|
|
10
|
+
typecheck Run TypeScript typecheck across workspaces
|
|
11
|
+
prisma <args> Run Prisma CLI with correct DATABASE_URL
|
|
12
|
+
env Print environment info as JSON
|
|
13
|
+
help Show this help message
|
|
14
|
+
version Show version
|
|
15
|
+
|
|
16
|
+
EXAMPLES:
|
|
17
|
+
bunx buncargo dev # Start everything
|
|
18
|
+
bunx buncargo dev --expose # Public quick tunnel for expose:true targets
|
|
19
|
+
bunx buncargo dev --expose=api # Public quick tunnel for selected target
|
|
20
|
+
bunx buncargo dev --help # Show dev command options
|
|
21
|
+
bunx buncargo dev --down # Stop containers
|
|
22
|
+
bunx buncargo typecheck # Run typecheck
|
|
23
|
+
bunx buncargo prisma studio # Open Prisma Studio
|
|
24
|
+
bunx buncargo env # Get ports/urls as JSON
|
|
25
|
+
|
|
26
|
+
CONFIG:
|
|
27
|
+
Create a dev.config.ts with a default export:
|
|
28
|
+
|
|
29
|
+
import { defineDevConfig } from 'buncargo'
|
|
30
|
+
|
|
31
|
+
export default defineDevConfig({
|
|
32
|
+
projectPrefix: 'myapp',
|
|
33
|
+
services: { ... },
|
|
34
|
+
apps: { ... }
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
Run "bunx buncargo dev --help" for dev command options.
|
|
38
|
+
`);
|
|
39
|
+
}
|