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
7 changes: 6 additions & 1 deletion .oxlintrc.effect.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,23 @@
"!apps/cli/src/command-internal/branch-target.*",
"!apps/cli/src/command-internal/connect-errors.*",
"!apps/cli/src/command-internal/db-*.ts",
"!apps/cli/src/command-internal/dotenv.*",
"!apps/cli/src/command-internal/experimental-feature.ts",
"!apps/cli/src/command-internal/local-project-context.*",
"!apps/cli/src/command-internal/pgpass.*",
"!apps/cli/src/command-internal/pgservicefile.*",
"!apps/cli/src/command-internal/pooler-fallback.*",
"!apps/cli/src/command-internal/postgres-client.run.ts",
"!apps/cli/src/command-internal/project-environment.*",
"!apps/cli/src/command-internal/schema-flags.*",
"!apps/cli/src/command-internal/stack-api.ts",
"!apps/cli/src/command-internal/stack-backend.ts",
"!apps/cli/src/command-internal/stack-catalog-setup.ts",
"!apps/cli/src/command-internal/stack-config.ts",
"!apps/cli/src/command-internal/stack-local-database.ts",
"!apps/cli/src/command-internal/stack-shadow.ts",
"!apps/cli/src/command-internal/stack-storage.ts"
"!apps/cli/src/command-internal/stack-storage.ts",
"!apps/cli/src/command-internal/vault-decrypt.*",
"!apps/cli/src/command-internal/vault.*"
]
}
34 changes: 27 additions & 7 deletions apps/cli/src/command-internal/local-project-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
type CliConfig,
} from "@supabase/config/effect";
import { loadCliConfig } from "@supabase/config/internal";
import { Crypto, Effect, FileSystem, Path, Schema } from "effect";
import { Config, Crypto, Effect, FileSystem, Option, Path, Schema } from "effect";

import { recordOrioleDbTelemetry } from "./db-image.ts";
import { resolveLocalProjectId, sanitizeProjectId } from "./docker-ids.ts";
Expand Down Expand Up @@ -38,6 +38,14 @@ export const loadLocalProjectContext = <E>(
FileSystem.FileSystem | Path.Path | RuntimeInfo | Crypto.Crypto
> =>
Effect.gen(function* () {
const supabaseEnv =
Option.getOrUndefined(
yield* Config.option(Config.String("SUPABASE_ENV")).pipe(
Effect.mapError(() =>
mapConfigLoadError("failed to resolve environment variable: SUPABASE_ENV"),
),
),
) || "development";
// `workdir` is already the fully-resolved chdir target, so `search: false` stops
// `@supabase/config` from climbing ancestors and picking up an unrelated project's
// config.toml when `workdir` has none of its own.
Expand All @@ -47,18 +55,21 @@ export const loadLocalProjectContext = <E>(
search: false,
// Omits `.env.local` when `SUPABASE_ENV=test`, matching
// `resolveProjectEnvironmentValues`'s gating for the project-root pass.
skipEnvLocal: (process.env["SUPABASE_ENV"] || "development") === "test",
skipEnvLocal: supabaseEnv === "test",
}).pipe(
Effect.mapError((cause) => mapConfigLoadError(`failed to read config: ${String(cause)}`)),
);

// Must resolve before `loadCliConfig` decodes config.toml: an `env(...)`-valued `project_id`
// needs these values available to the decoder already. `workdir` is passed through so dotenv
// files under `<workdir>/supabase` are still discovered even when `projectEnv` is `null`.
const projectEnvValues = yield* Effect.try({
try: () => resolveProjectEnvironmentValues(projectEnv, workdir),
catch: (cause) => mapConfigLoadError(`failed to read config: ${String(cause)}`),
});
const projectEnvValues = yield* resolveProjectEnvironmentValues(
projectEnv,
workdir,
supabaseEnv,
).pipe(
Effect.mapError((cause) => mapConfigLoadError(`failed to read config: ${String(cause)}`)),
);

// An absent config.toml is not a failure — a project id still resolves from the workdir
// basename default. Only a malformed file is a hard error.
Expand Down Expand Up @@ -90,7 +101,16 @@ export const loadLocalProjectContext = <E>(
resolveLocalProjectId(
loaded?.appliedRemote !== undefined
? undefined
: (projectEnvValues["SUPABASE_PROJECT_ID"] ?? process.env["SUPABASE_PROJECT_ID"]),
: (projectEnvValues["SUPABASE_PROJECT_ID"] ??
Option.getOrUndefined(
yield* Config.option(Config.String("SUPABASE_PROJECT_ID")).pipe(
Effect.mapError(() =>
mapConfigLoadError(
"failed to resolve environment variable: SUPABASE_PROJECT_ID",
),
),
),
)),
config.project_id,
workdir,
projectRef,
Expand Down
Loading
Loading