Skip to content

feat(cli): port orgs commands to native TypeScript#5379

Merged
jgoux merged 3 commits into
developfrom
cli/port-orgs-command
May 28, 2026
Merged

feat(cli): port orgs commands to native TypeScript#5379
jgoux merged 3 commits into
developfrom
cli/port-orgs-command

Conversation

@Coly010
Copy link
Copy Markdown
Contributor

@Coly010 Coly010 commented May 28, 2026

Summary

Promotes supabase orgs list and supabase orgs create from Phase 0 Go-binary proxies to native TypeScript implementations in the legacy shell. The handlers reuse the shared infrastructure introduced by the branches port — HTTP error mapper, Go-compatible JSON/YAML/TOML/env encoders, and Glamour-rendered pretty tables — so no new shared helpers were needed.

Go source mirrored 1:1: apps/cli-go/internal/orgs/list/list.go and apps/cli-go/internal/orgs/create/create.go. Error templates, output mode behaviour, and the Created organization: <id> preamble byte-match the Go CLI.

Notable parity rules

  • orgs list --output env is rejected with the byte-exact Go message --output env flag is not supported.
  • orgs list --output toml wraps the array as [[organizations]] (Go uses a TOML envelope for arrays).
  • orgs create --output env is supported here, unlike on list — matches Go's EncodeOutput flattening of a single object into ID=… NAME=… SLUG=….
  • Created organization: <id> preamble fires before every Go-output mode (json / yaml / toml / env / pretty) but is omitted from --output-format json / stream-json, where the message is delivered as a structured event field instead.
  • Telemetry flushes in Effect.ensuring on success and failure (CLAUDE.md PersistentPostRun parity rule). No linked-project cache write — these are user-level commands without a --project-ref.
  • Parent description matches Go exactly: Manage Supabase organizations (no trailing period).

Tests

  • 3 unit tests for renderOrgsListTable (header-only, multi-row, literal | passthrough).
  • 32 integration tests covering every output mode for both subcommands, the env-not-supported rejection, --output-over---output-format precedence, network and HTTP-503 error paths (including the format !== "text" spinner-undefined branch), and telemetry flush on both success and failure.

E2E coverage deliberately omitted — these are pure Management-API CRUD commands with no subprocess-specific behaviour to validate (per CLAUDE.md testing policy).

Reviewer-relevant context

  • The orgs handlers never resolve a project ref but still use legacyManagementApiRuntimeLayer, which constructs the project-ref resolver lazily. The orgs handlers simply don't yield those services. This is intentional: keeping a single shared runtime layer is cheaper than maintaining a user-vs-project layer split.
  • orgs.errors.ts and orgs.format.ts are colocated at the family root, not hoisted to legacy/shared/. Per CLAUDE.md hoist-before-duplicate, the threshold is "used across ≥2 families" — branches has its own branches.format.ts/branches.errors.ts, and these are the second instance of the pattern, not yet a third.
  • The Glamour table renders API-supplied strings (id, name) without ANSI/control-character stripping. This is strict Go parity — both SIDE_EFFECTS.md files document the deliberate pass-through under "Security Notes" so a future renderer-level sanitization fix has a clear pointer.

Refs CLI-1290.

Promote `orgs list` and `orgs create` from Phase 0 Go-binary proxies to
native TypeScript implementations in the legacy shell. Mirrors the just-
landed branches port: shared HTTP error mapper, Go-compatible
JSON/YAML/TOML/env encoders, Glamour-rendered pretty table, and the full
five-mode `--output` flag with TS `--output-format` deferral.

- `orgs list` rejects `--output env` with the byte-exact Go message and
  wraps TOML output as `[[organizations]]` per Go parity.
- `orgs create` emits the `Created organization: <id>` preamble before
  every Go-output mode (json/yaml/toml/env supported; the env branch
  works here unlike on list, matching Go's encoder behaviour).
- Telemetry flushes in `Effect.ensuring` on success and failure; no
  linked-project cache write because no `--project-ref` is resolved.

Tests: 3 unit + 32 integration covering every output branch, the
non-text-format + API-failure spinner-undefined path, and the
`cli_command_executed` telemetry parity rules.

Refs CLI-1290.
@Coly010 Coly010 requested a review from a team as a code owner May 28, 2026 13:01
@Coly010 Coly010 self-assigned this May 28, 2026
@jgoux jgoux enabled auto-merge (squash) May 28, 2026 15:06
@jgoux jgoux merged commit f03d18e into develop May 28, 2026
8 checks passed
@jgoux jgoux deleted the cli/port-orgs-command branch May 28, 2026 15:10
Coly010 added a commit that referenced this pull request May 29, 2026
…und-trip)

The orgs port (#5379) documented an important parity rule: Go's
`strings.ReplaceAll(value, "|", "\\|")` is a markdown-intermediate escape
that Glamour decodes back to literal `|` in the rendered ASCII bytes.
`renderGlamourTable` bypasses the markdown round-trip, so passing
pre-escaped values produces `\|` in stdout where Go produces `|` — a
byte-level parity divergence for any snippet name, visibility, or owner
username containing a pipe.

Fix: drop the `escapePipe` helper, pass raw values to renderGlamourTable.
Updated unit + integration tests to assert literal `|` preservation
(matching the pattern orgs.format.unit.test.ts uses).

Also adopts the `yield* new ErrorClass(...)` shorthand from orgs handlers
for tagged-error short-circuits.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants