Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions apps/cli/docs/go-cli-porting-status.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,12 @@ The old Go `storage` family could target either the linked project or the local

Current TS only exposes low-level Management API routes under [`api`](../src/next/commands/platform/api.command.ts). This tracker does not count those routes as parity for the old `storage` object-management CLI surface, especially because there is no TS equivalent for the old local Storage API workflow.

| Old command | TS status | New TS counterpart(s) | Notes |
| ------------ | --------- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `storage cp` | `missing` | `missing` | No TS object copy command in `next/`. Legacy shell proxy exposes `--recursive`, `--local`, `--linked`, `--cache-control`, `--content-type`, `--copy-metadata` matching the Go CLI flag surface. |
| `storage ls` | `missing` | `missing` | No TS object listing command in `next/`. Legacy shell proxy exposes `--recursive`, `--local`, `--linked` matching the Go CLI flag surface. |
| `storage mv` | `missing` | `missing` | No TS object move command in `next/`. Legacy shell proxy exposes `--recursive`, `--local`, `--linked` matching the Go CLI flag surface. |
| `storage rm` | `missing` | `missing` | No TS object remove command in `next/`. Legacy shell proxy exposes `--recursive`, `--local`, `--linked` matching the Go CLI flag surface. Pass global `--yes` to skip the interactive confirmation prompt. |
| Old command | TS status | New TS counterpart(s) | Notes |
| ------------ | --------- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `storage cp` | `missing` | `missing` | No TS object copy command in `next/`. Natively ported in the legacy shell ([`legacy/commands/storage/cp/`](../src/legacy/commands/storage/cp/cp.command.ts)) — `--recursive`, `--local`, `--linked`, `--cache-control`, `--content-type`, `--jobs` (Go has no `--copy-metadata`). Adds TS-only `--output-format json\|stream-json`. |
| `storage ls` | `missing` | `missing` | No TS object listing command in `next/`. Natively ported in the legacy shell ([`legacy/commands/storage/ls/`](../src/legacy/commands/storage/ls/ls.command.ts)) — `--recursive`, `--local`, `--linked`. Adds TS-only `--output-format json\|stream-json`. |
| `storage mv` | `missing` | `missing` | No TS object move command in `next/`. Natively ported in the legacy shell ([`legacy/commands/storage/mv/`](../src/legacy/commands/storage/mv/mv.command.ts)) — `--recursive`, `--local`, `--linked`. Adds TS-only `--output-format json\|stream-json`. |
| `storage rm` | `missing` | `missing` | No TS object remove command in `next/`. Natively ported in the legacy shell ([`legacy/commands/storage/rm/`](../src/legacy/commands/storage/rm/rm.command.ts)) — `--recursive`, `--local`, `--linked`; global `--yes`/`SUPABASE_YES` skips the confirmation. Adds TS-only `--output-format json\|stream-json`. |

## Management APIs

Expand Down Expand Up @@ -291,10 +291,10 @@ Legend:
| `functions deploy` | `ported` | [`../src/legacy/commands/functions/deploy/deploy.command.ts`](../src/legacy/commands/functions/deploy/deploy.command.ts) |
| `functions new` | `wrapped` | [`../src/legacy/commands/functions/new/new.command.ts`](../src/legacy/commands/functions/new/new.command.ts) |
| `functions serve` | `ported` | [`../src/legacy/commands/functions/serve/serve.command.ts`](../src/legacy/commands/functions/serve/serve.command.ts) |
| `storage ls` | `wrapped` | [`../src/legacy/commands/storage/ls/ls.command.ts`](../src/legacy/commands/storage/ls/ls.command.ts) |
| `storage cp` | `wrapped` | [`../src/legacy/commands/storage/cp/cp.command.ts`](../src/legacy/commands/storage/cp/cp.command.ts) |
| `storage mv` | `wrapped` | [`../src/legacy/commands/storage/mv/mv.command.ts`](../src/legacy/commands/storage/mv/mv.command.ts) |
| `storage rm` | `wrapped` | [`../src/legacy/commands/storage/rm/rm.command.ts`](../src/legacy/commands/storage/rm/rm.command.ts) |
| `storage ls` | `ported` | [`../src/legacy/commands/storage/ls/ls.command.ts`](../src/legacy/commands/storage/ls/ls.command.ts) |
| `storage cp` | `ported` | [`../src/legacy/commands/storage/cp/cp.command.ts`](../src/legacy/commands/storage/cp/cp.command.ts) |
| `storage mv` | `ported` | [`../src/legacy/commands/storage/mv/mv.command.ts`](../src/legacy/commands/storage/mv/mv.command.ts) |
| `storage rm` | `ported` | [`../src/legacy/commands/storage/rm/rm.command.ts`](../src/legacy/commands/storage/rm/rm.command.ts) |
| `test db` | `ported` | [`../src/legacy/commands/test/db/db.command.ts`](../src/legacy/commands/test/db/db.command.ts) |
| `test new` | `ported` | [`../src/legacy/commands/test/new/new.command.ts`](../src/legacy/commands/test/new/new.command.ts) |
| `seed buckets` | `ported` | [`../src/legacy/commands/seed/buckets/buckets.command.ts`](../src/legacy/commands/seed/buckets/buckets.command.ts) |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { withJsonErrorHandling } from "../../../../shared/output/json-error-hand
import { withLegacyCommandInstrumentation } from "../../../telemetry/legacy-command-instrumentation.ts";
import { LegacySeedLinkedFlag, LegacySeedLocalFlag } from "../seed.flags.ts";
import { legacyAssertSeedTargetsExclusive } from "./buckets.flags.ts";
import { legacySeedRuntimeLayer } from "../seed.layers.ts";
import { legacyStorageGatewayRuntimeLayer } from "../../../shared/legacy-storage-runtime.layer.ts";
import { legacySeedBuckets } from "./buckets.handler.ts";

// `--linked`/`--local` are scoped globals on the `seed` group (`seed.flags.ts`),
Expand Down Expand Up @@ -36,5 +36,5 @@ export const legacyBucketsCommand = Command.make("buckets").pipe(
return yield* legacySeedBuckets(flags).pipe(withLegacyCommandInstrumentation({ flags }));
}).pipe(withJsonErrorHandling),
),
Command.provide(legacySeedRuntimeLayer(["seed", "buckets"])),
Command.provide(legacyStorageGatewayRuntimeLayer(["seed", "buckets"])),
);
69 changes: 10 additions & 59 deletions apps/cli/src/legacy/commands/seed/buckets/buckets.errors.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,20 @@
import { Data } from "effect";

/**
* Domain errors for `supabase seed buckets`.
* Domain errors specific to `supabase seed buckets`.
*
* The Storage service-gateway calls fail with one of two shapes, mirroring Go's
* `pkg/fetcher`:
* - transport failure (`failed to execute http request`) →
* `LegacySeedStorageNetworkError`
* - non-2xx response (`Error status <d>: <body>`, `pkg/fetcher/http.go:112`) →
* `LegacySeedStorageStatusError`
*
* `message` reproduces Go's verbatim error text so the vector graceful-skip
* classifiers in `buckets.classify.ts` match on the same substrings Go inspects.
* The Storage gateway and credential-derivation errors are shared with
* `storage ls/cp/mv/rm` and live in `legacy/shared/legacy-storage-gateway.errors.ts`
* and `legacy/shared/legacy-storage-credentials.errors.ts`. This file keeps only
* the seed-specific errors.
*/
export class LegacySeedStorageNetworkError extends Data.TaggedError(
"LegacySeedStorageNetworkError",
)<{
readonly message: string;
}> {}

export class LegacySeedStorageStatusError extends Data.TaggedError("LegacySeedStorageStatusError")<{
readonly status: number;
readonly body: string;
readonly message: string;
}> {}

/**
* Raised when `supabase/config.toml` cannot be parsed. Mirrors the `config push`
* CLI-1489 tradeoff (`config/push/push.handler.ts:96-114`): `loadProjectConfig`
* raises `ProjectConfigParseError` on `env(...)` refs over numeric/bool fields,
* which Go resolves transparently.
* Raised when `supabase/config.toml` cannot be parsed, or a config-load-time
* validation Go runs before any Storage call fails (bucket name regex,
* `file_size_limit` numeral). Mirrors the `config push` CLI-1489 tradeoff:
* `loadProjectConfig` raises `ProjectConfigParseError` on `env(...)` refs over
* numeric/bool fields, which Go resolves transparently.
*/
export class LegacySeedConfigLoadError extends Data.TaggedError("LegacySeedConfigLoadError")<{
readonly message: string;
Expand All @@ -44,37 +29,3 @@ export class LegacySeedMutuallyExclusiveFlagsError extends Data.TaggedError(
)<{
readonly message: string;
}> {}

/**
* Raised on `--linked` when the project's api-keys response yields no keys,
* mirroring Go's `tenant.GetApiKeys` → `errMissingKey` ("Anon key not found.",
* `apps/cli-go/internal/utils/tenant/client.go:16,80-82`), which aborts before
* the remote Storage client is built. Message matches Go verbatim.
*/
export class LegacySeedMissingApiKeyError extends Data.TaggedError("LegacySeedMissingApiKeyError")<{
readonly message: string;
}> {}

/**
* Transport failure fetching the project's api-keys on `--linked`, mirroring Go's
* `tenant.GetApiKeys` network path (`failed to get api keys: <cause>`).
*/
export class LegacySeedApiKeysNetworkError extends Data.TaggedError(
"LegacySeedApiKeysNetworkError",
)<{
readonly message: string;
}> {}

/**
* `GET /v1/projects/{ref}/api-keys?reveal=true` returned a non-200 status on a
* `--linked` run. Byte-matches Go's `tenant.GetApiKeys` → `ErrAuthToken`,
* `"Authorization failed for the access token and project ref pair: " + body`
* (`apps/cli-go/internal/utils/tenant/client.go:15,77-78`). This is the user-facing
* error for an invalid access token / project-ref pair — distinct from the
* `projects api-keys` helper's `unexpected get api keys status ...`.
*/
export class LegacySeedAuthTokenError extends Data.TaggedError("LegacySeedAuthTokenError")<{
readonly status: number;
readonly body: string;
readonly message: string;
}> {}
65 changes: 8 additions & 57 deletions apps/cli/src/legacy/commands/seed/buckets/buckets.flags.ts
Original file line number Diff line number Diff line change
@@ -1,67 +1,18 @@
import { Effect } from "effect";

import {
VALUE_CONSUMING_LONG_FLAGS,
VALUE_CONSUMING_SHORT_FLAGS,
} from "../../../shared/legacy-db-target-flags.ts";
import { legacyChangedLinkedLocalFlags } from "../../../shared/legacy-db-target-flags.ts";
import { LegacySeedMutuallyExclusiveFlagsError } from "./buckets.errors.ts";

/**
* Detects which of `--local` / `--linked` were explicitly set on the command
* line, reproducing cobra's `pflag.Changed` for `seed`'s
* `MarkFlagsMutuallyExclusive("local", "linked")` (`apps/cli-go/cmd/seed.go:32`).
*
* Effect CLI's parsed flags carry no `Changed` bit, so we re-derive it from raw
* argv. Value-consuming flags (`--workdir <path>`, `-o <fmt>`, …) skip their
* value token to avoid false positives like `--workdir --linked`.
*
* Returned in cobra's alphabetically-sorted order `["linked", "local"]` so the
* rendered conflict string matches Go exactly.
* Detects which of `--local` / `--linked` were explicitly set, reproducing
* cobra's `pflag.Changed` for `seed`'s `MarkFlagsMutuallyExclusive`
* (`apps/cli-go/cmd/seed.go:32`). Delegates to the shared linked/local scanner
* (also used by `storage`). The seed target is selected from this changed set
* (Go's `flag.Changed`, via `internal/utils/flags/db_url.go:46-63`), not the
* parsed flag value.
*/
export function legacySeedChangedTargetFlags(args: ReadonlyArray<string>): ReadonlyArray<string> {
let linked = false;
let local = false;
let skipNext = false;

for (const token of args) {
if (skipNext) {
skipNext = false;
continue;
}
if (token === "--") break;

if (token.startsWith("--")) {
const eqIdx = token.indexOf("=");
const name = eqIdx === -1 ? token.slice(2) : token.slice(2, eqIdx);
const isBare = eqIdx === -1;
// Treat Effect CLI's boolean negation form (`--no-linked`/`--no-local`) as
// "changed" too — it sets the flag false but is unambiguously present on
// argv, the TS equivalent of cobra's `pflag.Changed` (and the seed target
// is selected from Changed, not the value, so `--no-linked` is still the
// linked path). Mirrors the sibling DB scanner (legacy-db-target-flags.ts).
if (name === "linked" || name === "no-linked") {
linked = true;
continue;
}
if (name === "local" || name === "no-local") {
local = true;
continue;
}
if (isBare && VALUE_CONSUMING_LONG_FLAGS.has(name)) skipNext = true;
continue;
}

if (token.startsWith("-") && token.length >= 2 && token.charAt(1) !== "-") {
if (token.length === 2 && VALUE_CONSUMING_SHORT_FLAGS.has(token.charAt(1))) {
skipNext = true;
}
}
}

const setFlags: Array<string> = [];
if (linked) setFlags.push("linked");
if (local) setFlags.push("local");
return setFlags;
return legacyChangedLinkedLocalFlags(args);
}

/**
Expand Down

This file was deleted.

Loading
Loading