|
| 1 | +# Catalyst CLI (`@bigcommerce/catalyst`) |
| 2 | + |
| 3 | +CLI tool for Catalyst development and deployment — handles build, dev server, and deployment to Cloudflare Workers. |
| 4 | + |
| 5 | +## Directory Structure |
| 6 | + |
| 7 | +``` |
| 8 | +src/cli/ |
| 9 | +├── index.ts # Entry point (#!/usr/bin/env node) |
| 10 | +├── program.ts # Commander program setup, registers all commands |
| 11 | +├── commands/ # CLI command implementations (auth, build, deploy, logs, project, start, telemetry, version) |
| 12 | +├── hooks/ # Pre/post action hooks (telemetry) |
| 13 | +└── lib/ # Utilities (auth, logger, project config, credentials, wrangler config, telemetry, deployment errors) |
| 14 | +templates/ # OpenNext config and public_headers template |
| 15 | +tests/mocks/ # MSW handlers and test mocks |
| 16 | +dist/cli.js # Bundled output (single ESM file) |
| 17 | +``` |
| 18 | + |
| 19 | +## CLI Commands |
| 20 | + |
| 21 | +| Command | Description | |
| 22 | +|---------|-------------| |
| 23 | +| `auth whoami/login/logout` | Manage authentication (device code OAuth flow, credential storage) | |
| 24 | +| `build` | Build Catalyst project using OpenNext/Cloudflare adapter | |
| 25 | +| `deploy` | Deploy to Cloudflare with bundle upload | |
| 26 | +| `logs` | View logs (`tail` default, `query` planned). Supports `--format` (default/json/pretty/short/request) | |
| 27 | +| `project create/list/link` | Manage BigCommerce infrastructure projects | |
| 28 | +| `start` | Start local preview using OpenNext Cloudflare adapter | |
| 29 | +| `telemetry` | Enable/disable/check telemetry | |
| 30 | +| `version` | Display version and platform info | |
| 31 | + |
| 32 | +## Development |
| 33 | + |
| 34 | +```bash |
| 35 | +pnpm dev # Watch mode (rebuilds dist/cli.js on changes) |
| 36 | +pnpm build # Production build via tsup |
| 37 | +pnpm test # Run tests (vitest) |
| 38 | +pnpm test:watch # Watch mode tests |
| 39 | +pnpm typecheck # tsc --noEmit |
| 40 | +pnpm lint # eslint with 0 warnings threshold |
| 41 | +``` |
| 42 | + |
| 43 | +## Testing Changes |
| 44 | + |
| 45 | +To test CLI changes directly without a full publish cycle, build the CLI package first, then run the compiled output from inside the `core/` directory using its absolute path: |
| 46 | + |
| 47 | +```bash |
| 48 | +# From packages/catalyst — rebuild the CLI |
| 49 | +pnpm build |
| 50 | + |
| 51 | +# From core/ — run the CLI using the absolute path to the built output |
| 52 | +pnpm exec <repo-root>/packages/catalyst/dist/cli.js <command> |
| 53 | +``` |
| 54 | + |
| 55 | +For example: `pnpm exec <repo-root>/packages/catalyst/dist/cli.js project list`. |
| 56 | + |
| 57 | +## Build |
| 58 | + |
| 59 | +- **Bundler**: tsup (`tsup.config.ts`) |
| 60 | +- **Entry**: `src/cli/index.ts` → `dist/cli.js` (single ESM bundle with source maps) |
| 61 | +- **Environment variables** injected at build time: `CLI_SEGMENT_WRITE_KEY`, `CONSOLA_LEVEL` |
| 62 | + |
| 63 | +## Testing |
| 64 | + |
| 65 | +- **Framework**: Vitest (`vitest.config.ts`) |
| 66 | +- **Coverage threshold**: 100% (strict) |
| 67 | +- **Mocking**: MSW for BigCommerce API calls; telemetry always disabled in tests (`vitest.setup.ts`) |
| 68 | +- **Test files**: co-located as `*.spec.ts` next to source files |
| 69 | + |
| 70 | +## Key Dependencies |
| 71 | + |
| 72 | +- `commander` — CLI framework |
| 73 | +- `execa` — process execution (next, pnpm, wrangler) |
| 74 | +- `consola` — logging |
| 75 | +- `zod` — API response validation |
| 76 | +- `conf` — persistent config (`.bigcommerce/project.json`) |
| 77 | +- `@segment/analytics-node` — telemetry |
| 78 | +- `adm-zip` — bundle zipping for deploy |
| 79 | + |
| 80 | +## After Making Changes |
| 81 | + |
| 82 | +Always run `pnpm typecheck` and `pnpm lint` after making code changes, and fix any errors or warnings before considering the work done. The lint config enforces zero warnings (`--max-warnings 0`). Use `pnpm lint --fix` to auto-fix formatting and fixable lint issues before manually editing. |
| 83 | + |
| 84 | +## Code Style Notes |
| 85 | + |
| 86 | +- **No `let` when avoidable** — prefer `const` with `while (true)` + `break` over mutable flags. |
| 87 | +- **No iterators/generators** — eslint `no-restricted-syntax` disallows `for...of` and generator functions. Use `.forEach()`, `.map()`, etc. |
| 88 | +- **Consola for logging** — use `consola` (from `../lib/logger`) instead of `console`. Use `colorize` from `consola/utils` for colored output. |
| 89 | +- **Shared CLI options** — commands that need `--store-hash`, `--access-token`, `--api-host`, and `--project-uuid` should use the shared option factories from `lib/shared-options.ts`. Chain `.makeOptionMandatory()` inline where needed to preserve commander's extra-typings inference. |
| 90 | +- **SSE stream pattern** — the fetch API's `ReadableStreamDefaultReader` doesn't support async iteration, so `while (true)` + `reader.read()` + `break` is the standard pattern. For long-lived streams, implement a TTL-based reconnect to free connection pool resources, and distinguish server-side disconnects (`TypeError: terminated`) from actual failures for retry logic. |
| 91 | + |
| 92 | +## Integration Points |
| 93 | + |
| 94 | +- **BigCommerce Infrastructure API**: `https://api.bigcommerce.com/stores/{storeHash}/v3/infrastructure/` |
| 95 | +- **Next.js**: dev/build/start |
| 96 | +- **OpenNext + Cloudflare**: serverless build and deploy via Wrangler |
0 commit comments