Skip to content
Merged
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
50 changes: 48 additions & 2 deletions packages/shared/src/cli/commands/doctor/resolve-targets.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@ describe("targetsFromManifestFile", () => {
expect(targets).toEqual([]);
});

it("excludes value-default and platform-injected fields from envVars", () => {
it("keeps only user-supplied fields, excluding cli/platform/static ones", () => {
// A synced manifest stamps `origin`. Only the user-supplied field should
// reach envVars; the cli-, platform-, and static-origin fields are excluded.
const targets = targetsFromManifestFile(
writeManifest({
version: "2.0",
Expand All @@ -175,6 +177,10 @@ describe("targetsFromManifestFile", () => {
alias: "Postgres",
permission: "CAN_CONNECT_AND_CREATE",
fields: {
instanceName: {
env: "LAKEBASE_INSTANCE_NAME",
origin: "user",
},
endpointPath: { env: "LAKEBASE_ENDPOINT", origin: "cli" },
host: {
env: "PGHOST",
Expand Down Expand Up @@ -203,7 +209,47 @@ describe("targetsFromManifestFile", () => {
}),
);
const pg = targets.find((t) => t.type === "postgres");
expect(pg?.envVars).toEqual(["LAKEBASE_ENDPOINT"]);
expect(pg?.envVars).toEqual(["LAKEBASE_INSTANCE_NAME"]);
});

it("excludes cli-origin fields, whether stamped or derived from `resolve`", () => {
// A stamped `origin: "cli"` (synced manifest) and an unstamped field with
// `resolve` (authored manifest) must both be treated as non-user, so
// doctor never reports them as MISSING user env vars.
const targets = targetsFromManifestFile(
writeManifest({
version: "2.0",
plugins: {
lakebase: {
requiredByTemplate: true,
resources: {
required: [
{
type: "postgres",
resourceKey: "pg",
alias: "Postgres",
permission: "CAN_CONNECT_AND_CREATE",
fields: {
// synced manifest: origin stamped by `plugin sync`
stampedCli: { env: "LAKEBASE_ENDPOINT", origin: "cli" },
// authored manifest: no stamped origin, resolve → cli
derivedCli: {
env: "LAKEBASE_HOST",
resolve: "postgres:host",
},
// genuine user-supplied field survives
user: { env: "LAKEBASE_INSTANCE_NAME" },
},
},
],
optional: [],
},
},
},
}),
);
const pg = targets.find((t) => t.type === "postgres");
expect(pg?.envVars).toEqual(["LAKEBASE_INSTANCE_NAME"]);
});

it("resolves fieldValues from a static `value` when the env var is unset", () => {
Expand Down
13 changes: 7 additions & 6 deletions packages/shared/src/cli/commands/doctor/resolve-targets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import fs from "node:fs";
import path from "node:path";
import { computeOriginFromField } from "../../../schemas/manifest";
import type { ResourceTarget } from "./types";
import { errorMessage } from "./utils";

Expand All @@ -17,6 +18,8 @@ interface ManifestField {
/** Static default value baked into the manifest. */
value?: string;
origin?: "user" | "platform" | "static" | "cli";
/** Resolver key (cli origin), e.g. "postgres:host". */
resolve?: string;
/** Only generated into the local .env; the platform injects it at deploy. */
localOnly?: boolean;
}
Expand Down Expand Up @@ -47,13 +50,11 @@ interface TemplateManifest {
plugins?: Record<string, ManifestPlugin>;
}

/** A field's env var is the developer's to supply only when it has no static
* default and isn't platform-injected at deploy time. */
/** A field's env var is the developer's to supply only when its effective
* origin is `"user"` — a stamped `origin`, else derived from the field shape. */
function isUserSuppliedEnv(field: ManifestField): boolean {
if (field.value !== undefined) return false;
if (field.origin === "platform" || field.origin === "static") return false;
if (field.localOnly) return false;
return true;
const origin = field.origin ?? computeOriginFromField(field);
return origin === "user";
}

/** Env vars the config layer should presence-check (i.e. user-supplied ones). */
Expand Down
Loading