@beechcms/cms 0.6.0-preview.3 → 0.6.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 (2) hide show
  1. package/bin/cli.mjs +159 -55
  2. package/package.json +20 -4
package/bin/cli.mjs CHANGED
@@ -5,77 +5,94 @@ import { spawnSync } from 'node:child_process'
5
5
  import { existsSync } from 'node:fs'
6
6
  import { resolve } from 'node:path'
7
7
  import { pathToFileURL } from 'node:url'
8
-
8
+ import pc from 'picocolors'
9
9
 
10
10
  const [,, command, ...args] = process.argv
11
11
 
12
12
  const COMMANDS = {
13
- build: cmdBuild,
14
- 'seed:load': cmdSeedLoad,
15
- 'seed:create': cmdSeedCreate,
16
- 'init': cmdInit,
17
- 'validate': cmdValidate,
18
- 'deploy': cmdDeploy,
19
- 'update': cmdUpdate,
20
- 'onboard': cmdOnboard,
21
- 'reset': cmdReset,
13
+ build: cmdBuild,
14
+ 'seed:load': cmdSeedLoad,
15
+ 'seed:create': cmdSeedCreate,
16
+ 'schema:diff': cmdSchemaDiff,
17
+ 'init': cmdInit,
18
+ 'validate': cmdValidate,
19
+ 'deploy': cmdDeploy,
20
+ 'update': cmdUpdate,
21
+ 'onboard': cmdOnboard,
22
+ 'reset': cmdReset,
23
+ 'generate:types': cmdGenerateTypes,
24
+ // New unified command mappings:
25
+ 'db:migrate': cmdDbMigrate,
26
+ 'db:reset': cmdDbReset,
27
+ 'dev': cmdDev,
28
+ 'start': cmdDev,
29
+ 'dev:stop': cmdDevStop,
30
+ 'dev:reset': cmdDevReset,
31
+ 'dev:tunnel': cmdDevTunnel,
32
+ 'mailpit:clear': cmdMailpitClear,
33
+ 'logs': cmdLogs,
34
+ 'test': cmdTest,
35
+ 'lint': cmdLint,
36
+ 'doctor': cmdDoctor,
22
37
  }
23
38
 
24
39
  function help() {
25
40
  console.log(`
26
- beech <command> [options]
41
+ ${pc.cyan('beech')} <command> [options]
27
42
 
28
- Commands:
29
- init Check project files and optionally initialise the database
43
+ ${pc.bold('1. Local Management & Onboarding')}
44
+ ${pc.cyan('init')} Check project files and optionally initialise the database
30
45
  --db Also initialise the D1 database (system tables)
31
46
  --remote Target remote D1 instead of local (default: local)
32
47
  --db-name <n> Override D1 database name
48
+ --yes, -y Run in non-interactive mode
49
+ ${pc.cyan('onboard')} One-command local provisioning (init --db + seed:load)
50
+ --remote Target remote D1 instead of local (default: local)
51
+ --yes, -y Skip all interactive prompts (non-interactive mode)
52
+ --db <name> Override D1 database name
53
+ ${pc.cyan('update')} Update internals to latest, then apply system D1 migrations
33
54
 
34
- build Rebuild @beechcms/core after editing seeds.ts
35
-
36
- validate Validate SEED_REGISTRY for common errors (duplicate aliases,
37
- missing displayNameAlias, duplicate slugs). Exit code 1 on errors.
55
+ ${pc.bold('2. Database & Migrations')}
56
+ ${pc.cyan('db:migrate')} Apply all pending local migrations
57
+ ${pc.cyan('db:reset')} Remove local Wrangler state and re-bootstrap database
38
58
 
39
- seed:load Create/update content tables from SEED_REGISTRY
59
+ ${pc.bold('3. Seed & Schema Management')}
60
+ ${pc.cyan('seed:create')} Interactive wizard — generate a new Seed schema in seeds.ts
61
+ ${pc.cyan('seed:load')} Create/update content tables from SEED_REGISTRY
40
62
  --dry-run Print SQL without executing
41
63
  --diff Show schema differences vs current DB
42
64
  --remote Execute against remote D1 (default: local)
43
65
  --db <name> Override D1 database name
44
-
45
- seed:create Interactive wizard generate a new Seed definition and append
46
- it to seeds.ts, including SEED_REGISTRY entry
47
-
48
- deploy Deploy Worker, sync remote schema, and verify /admin
66
+ ${pc.cyan('schema:diff')} Diff SEED_REGISTRY vs D1 and generate additive SQL migration
67
+ --write Write the migration file (default: preview only)
68
+ --name <name> Migration name used in the filename
69
+ --remote Diff against remote D1 (default: local)
70
+ --db <name> Override D1 database name
71
+ ${pc.cyan('validate')} Validate seeds registry for errors
72
+ ${pc.cyan('generate:types')} Generate TypeScript interfaces from seed definitions
73
+ --out <path> Output file (default: src/types/beech.ts)
74
+ --local Read from seeds.ts instead of querying live D1
75
+
76
+ ${pc.bold('4. Local Stack & Docker')}
77
+ ${pc.cyan('dev / start')} Start the local dev environment (Docker + API + Dashboard)
78
+ --plain Avoid Ink visual TUI and run clean log streaming
79
+ ${pc.cyan('dev:stop')} Stop Docker containers without wiping data
80
+ ${pc.cyan('dev:reset')} Stop Docker containers and remove all persistent volumes
81
+ ${pc.cyan('dev:tunnel')} Display Cloudflare tunnel public testing URL
82
+ ${pc.cyan('mailpit:clear')} Clear local test inbox in Mailpit
83
+
84
+ ${pc.bold('5. Logs Streaming')}
85
+ ${pc.cyan('logs <service>')} Show streaming logs for docker service: mailpit, db, tunnel, storage
86
+
87
+ ${pc.bold('6. Quality & Deployment')}
88
+ ${pc.cyan('test')} Run the test suite via Turborepo / Vitest
89
+ --coverage Generate coverage reports
90
+ --diff Run test coverage only for files modified on the branch
91
+ ${pc.cyan('lint')} Run ESLint quality checks
92
+ ${pc.cyan('deploy')} Compile, test, deploy to Cloudflare environment
49
93
  --skip-seed Skip remote seed:load step
50
94
  --skip-check Skip /admin reachability check
51
-
52
- update Update @beechcms/api and @beechcms/core to latest, then
53
- apply any new system migrations to the local database
54
-
55
- onboard One-command local provisioning (init + seed:load). Designed
56
- for non-interactive use by agents and CI.
57
- --remote Target remote D1 instead of local (default: local)
58
- --yes Skip all interactive prompts (non-interactive mode)
59
- --db <name> Override D1 database name
60
-
61
- reset Reset database and/or Docker containers/volumes
62
- --db Wipe local Wrangler state & bootstrap D1 DB
63
- --docker Down Docker containers and wipe volumes
64
- --all Reset both (database & docker)
65
-
66
- Scaffold a new project (interactive, or pass --yes for non-interactive defaults):
67
- npm create @beechcms/cms [project-name] [--yes] [--with-examples]
68
-
69
- Golden path (local):
70
- npx beech onboard --local --yes # fully automated
71
- # or step by step:
72
- npx beech init --db --local
73
- npx beech seed:load --local
74
- npx wrangler dev
75
-
76
- Golden path (deploy):
77
- npx beech deploy
78
- npx beech init --db --remote # verify remote DB post-deploy
95
+ ${pc.cyan('doctor')} Execute React diagnostics check on Dashboard
79
96
  `)
80
97
  }
81
98
 
@@ -159,9 +176,10 @@ async function cmdInit(args) {
159
176
  const remote = args.includes('--remote')
160
177
  const dbIdx = args.indexOf('--db-name')
161
178
  const db = dbIdx !== -1 ? args[dbIdx + 1] : undefined
179
+ const yes = args.includes('--yes') || args.includes('-y')
162
180
 
163
181
  const { init } = await import('@beechcms/cli')
164
- await init({ initDb, local: !remote, db })
182
+ await init({ initDb, local: !remote, db, yes })
165
183
  }
166
184
 
167
185
  async function cmdSeedLoad(args) {
@@ -203,7 +221,7 @@ async function cmdUpdate(_args) {
203
221
 
204
222
  async function cmdOnboard(args) {
205
223
  const local = !args.includes('--remote')
206
- const yes = args.includes('--yes')
224
+ const yes = args.includes('--yes') || args.includes('-y')
207
225
  const dbIdx = args.indexOf('--db')
208
226
  const db = dbIdx !== -1 ? args[dbIdx + 1] : undefined
209
227
  const registry = await tryLoadLocalRegistry()
@@ -215,9 +233,95 @@ async function cmdReset(args) {
215
233
  const db = args.includes('--db')
216
234
  const docker = args.includes('--docker')
217
235
  const all = args.includes('--all')
218
-
236
+ const yes = args.includes('--yes') || args.includes('-y')
237
+
219
238
  const { reset } = await import('@beechcms/cli')
220
- await reset({ db, docker, all })
239
+ await reset({ db, docker, all, yes })
240
+ }
241
+
242
+ async function cmdSchemaDiff(args) {
243
+ const remote = args.includes('--remote')
244
+ const write = args.includes('--write')
245
+ const nameIdx = args.indexOf('--name')
246
+ const name = nameIdx !== -1 ? args[nameIdx + 1] : undefined
247
+ const dbIdx = args.indexOf('--db')
248
+ const db = dbIdx !== -1 ? args[dbIdx + 1] : undefined
249
+ const registry = await tryLoadLocalRegistry()
250
+ const { schemaDiff } = await import('@beechcms/cli')
251
+ await schemaDiff({ local: !remote, write, name, db, registry })
252
+ }
253
+
254
+ async function cmdGenerateTypes(args) {
255
+ const outIdx = args.indexOf('--out')
256
+ const out = outIdx !== -1 ? args[outIdx + 1] : 'src/types/beech.ts'
257
+ const local = args.includes('--local')
258
+ const dbIdx = args.indexOf('--db')
259
+ const db = dbIdx !== -1 ? args[dbIdx + 1] : undefined
260
+
261
+ const registry = local ? await tryLoadLocalRegistry() : null
262
+
263
+ const { generateTypes } = await import('@beechcms/cli')
264
+ await generateTypes({ out, local, db, registry })
265
+ }
266
+
267
+ // New unified command wrappers:
268
+ async function cmdDbMigrate(args) {
269
+ const { dbMigrate } = await import('@beechcms/cli')
270
+ await dbMigrate({})
271
+ }
272
+
273
+ async function cmdDbReset(args) {
274
+ const { dbReset } = await import('@beechcms/cli')
275
+ await dbReset({})
276
+ }
277
+
278
+ async function cmdDev(args) {
279
+ const plain = args.includes('--plain')
280
+ const { dev } = await import('@beechcms/cli')
281
+ await dev({ plain })
282
+ }
283
+
284
+ async function cmdDevStop(args) {
285
+ const { devStop } = await import('@beechcms/cli')
286
+ await devStop()
287
+ }
288
+
289
+ async function cmdDevReset(args) {
290
+ const { devReset } = await import('@beechcms/cli')
291
+ await devReset()
292
+ }
293
+
294
+ async function cmdDevTunnel(args) {
295
+ const { devTunnel } = await import('@beechcms/cli')
296
+ await devTunnel()
297
+ }
298
+
299
+ async function cmdMailpitClear(args) {
300
+ const { mailpitClear } = await import('@beechcms/cli')
301
+ await mailpitClear()
302
+ }
303
+
304
+ async function cmdLogs(args) {
305
+ const service = args[0]
306
+ const { logs } = await import('@beechcms/cli')
307
+ await logs({ service })
308
+ }
309
+
310
+ async function cmdTest(args) {
311
+ const coverage = args.includes('--coverage')
312
+ const diff = args.includes('--diff')
313
+ const { test } = await import('@beechcms/cli')
314
+ await test({ coverage, diff })
315
+ }
316
+
317
+ async function cmdLint(args) {
318
+ const { lint } = await import('@beechcms/cli')
319
+ await lint()
320
+ }
321
+
322
+ async function cmdDoctor(args) {
323
+ const { doctor } = await import('@beechcms/cli')
324
+ await doctor()
221
325
  }
222
326
 
223
327
  const handler = COMMANDS[command]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beechcms/cms",
3
- "version": "0.6.0-preview.3",
3
+ "version": "0.6.0",
4
4
  "description": "Edge-Native, Schema-Driven Headless CMS built on Cloudflare Workers, D1, and R2. Features the Botanical Engine for alias-stable field management, a modular widget layer, and a React + Vite admin dashboard.",
5
5
  "keywords": [
6
6
  "cms",
@@ -38,9 +38,13 @@
38
38
  },
39
39
  "type": "module",
40
40
  "devDependencies": {
41
+ "@eslint/js": "^9.39.1",
42
+ "@types/node": "^24.10.1",
41
43
  "@vitest/coverage-v8": "^4.1.0",
42
44
  "cross-env": "^10.1.0",
45
+ "eslint": "^9.39.1",
43
46
  "execa": "^9.6.1",
47
+ "globals": "^16.5.0",
44
48
  "husky": "^9.1.7",
45
49
  "ink": "^6.8.0",
46
50
  "ink-spinner": "^5.0.0",
@@ -52,11 +56,16 @@
52
56
  "strip-ansi": "^7.2.0",
53
57
  "tsx": "^4.22.4",
54
58
  "turbo": "^2.9.18",
55
- "typescript": "^5.9.3",
56
- "vitest": "^4.1.0"
59
+ "typedoc": "^0.28.20",
60
+ "typedoc-plugin-markdown": "^4.12.0",
61
+ "typescript": "^7.0.2",
62
+ "typescript-eslint": "^8.63.0",
63
+ "vitepress": "^1.6.4",
64
+ "vitest": "^4.1.0",
65
+ "vue": "^3.5.39"
57
66
  },
58
67
  "dependencies": {
59
- "@beechcms/cli": "^0.6.0-preview.3",
68
+ "@beechcms/cli": "^0.6.0",
60
69
  "@clack/prompts": "^0.9.1",
61
70
  "picocolors": "^1.1.1"
62
71
  },
@@ -73,6 +82,11 @@
73
82
  }
74
83
  },
75
84
  "scripts": {
85
+ "docs:generate": "typedoc",
86
+ "docs:dev": "vitepress dev docs",
87
+ "docs:build": "typedoc && vitepress build docs",
88
+ "docs:preview": "vitepress preview docs",
89
+ "beech": "node bin/cli.mjs",
76
90
  "dev": "node scripts/dev.mjs",
77
91
  "dev:full": "node scripts/dev.mjs",
78
92
  "dev:plain": "cross-env BEECH_DEV_PLAIN=1 node scripts/dev.mjs",
@@ -85,11 +99,13 @@
85
99
  "dev:stop": "docker compose -f docker/docker-compose.yml stop",
86
100
  "dev:reset": "docker compose -f docker/docker-compose.yml down -v",
87
101
  "build": "turbo run build",
102
+ "lint": "turbo run lint",
88
103
  "type-check": "turbo run type-check",
89
104
  "test": "turbo run test",
90
105
  "test:coverage": "turbo run test:coverage",
91
106
  "test:diff": "node scripts/test-coverage-diff.mjs",
92
107
  "test:dev-cli": "vitest run --config scripts/dev-cli/vitest.config.ts",
108
+ "pipeline": "node scripts/pipeline.mjs",
93
109
  "setup:graph": "node scripts/setup-graph.mjs",
94
110
  "release": "node scripts/release.mjs",
95
111
  "release:preview": "node scripts/release.mjs --preview",