mirror of
https://github.com/cline/cline.git
synced 2026-10-31 02:42:02 +08:00
Allow overriding the API base url (#11440)
* Allow overriding the base url * Override the mcpbaseurl * update the api base url * Fix tests
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
CLINE_ENVIRONMENT_ENV,
|
||||
CLINE_ENVIRONMENT_OVERRIDE_ENV,
|
||||
@@ -8,58 +8,75 @@ import {
|
||||
resolveClineEnvironment,
|
||||
} from "./cline-environment";
|
||||
|
||||
const ENV_KEYS = [
|
||||
CLINE_ENVIRONMENT_ENV,
|
||||
CLINE_ENVIRONMENT_OVERRIDE_ENV,
|
||||
"CLINE_API_BASE_URL",
|
||||
] as const;
|
||||
|
||||
const originalEnvValues = Object.fromEntries(
|
||||
ENV_KEYS.map((key) => [key, process.env[key]]),
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
vi.unstubAllGlobals();
|
||||
for (const key of ENV_KEYS) {
|
||||
delete process.env[key];
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.unstubAllGlobals();
|
||||
for (const key of ENV_KEYS) {
|
||||
const value = originalEnvValues[key];
|
||||
if (typeof value === "string") {
|
||||
process.env[key] = value;
|
||||
} else {
|
||||
delete process.env[key];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
describe("resolveClineEnvironment", () => {
|
||||
it("defaults to production when no env var is set", () => {
|
||||
expect(resolveClineEnvironment({ env: {} })).toBe("production");
|
||||
expect(resolveClineEnvironment()).toBe(DEFAULT_CLINE_ENVIRONMENT);
|
||||
});
|
||||
|
||||
it("reads CLINE_ENVIRONMENT", () => {
|
||||
expect(
|
||||
resolveClineEnvironment({
|
||||
env: { [CLINE_ENVIRONMENT_ENV]: "staging" },
|
||||
}),
|
||||
).toBe("staging");
|
||||
expect(
|
||||
resolveClineEnvironment({
|
||||
env: { [CLINE_ENVIRONMENT_ENV]: "local" },
|
||||
}),
|
||||
).toBe("local");
|
||||
it("reads CLINE_ENVIRONMENT from process.env", () => {
|
||||
process.env[CLINE_ENVIRONMENT_ENV] = "staging";
|
||||
expect(resolveClineEnvironment()).toBe("staging");
|
||||
|
||||
process.env[CLINE_ENVIRONMENT_ENV] = "local";
|
||||
expect(resolveClineEnvironment()).toBe("local");
|
||||
});
|
||||
|
||||
it("prefers CLINE_ENVIRONMENT_OVERRIDE over CLINE_ENVIRONMENT", () => {
|
||||
expect(
|
||||
resolveClineEnvironment({
|
||||
env: {
|
||||
[CLINE_ENVIRONMENT_OVERRIDE_ENV]: "local",
|
||||
[CLINE_ENVIRONMENT_ENV]: "staging",
|
||||
},
|
||||
}),
|
||||
).toBe("local");
|
||||
process.env[CLINE_ENVIRONMENT_OVERRIDE_ENV] = "local";
|
||||
process.env[CLINE_ENVIRONMENT_ENV] = "staging";
|
||||
|
||||
expect(resolveClineEnvironment()).toBe("local");
|
||||
});
|
||||
|
||||
it("normalizes case and surrounding whitespace", () => {
|
||||
expect(
|
||||
resolveClineEnvironment({
|
||||
env: { [CLINE_ENVIRONMENT_ENV]: " STAGING " },
|
||||
}),
|
||||
).toBe("staging");
|
||||
process.env[CLINE_ENVIRONMENT_ENV] = " STAGING ";
|
||||
|
||||
expect(resolveClineEnvironment()).toBe("staging");
|
||||
});
|
||||
|
||||
it("ignores unknown values and falls through to the next source", () => {
|
||||
expect(
|
||||
resolveClineEnvironment({
|
||||
env: {
|
||||
[CLINE_ENVIRONMENT_OVERRIDE_ENV]: "qa",
|
||||
[CLINE_ENVIRONMENT_ENV]: "staging",
|
||||
},
|
||||
}),
|
||||
).toBe("staging");
|
||||
process.env[CLINE_ENVIRONMENT_OVERRIDE_ENV] = "qa";
|
||||
process.env[CLINE_ENVIRONMENT_ENV] = "staging";
|
||||
expect(resolveClineEnvironment()).toBe("staging");
|
||||
|
||||
expect(
|
||||
resolveClineEnvironment({
|
||||
env: { [CLINE_ENVIRONMENT_ENV]: "qa" },
|
||||
}),
|
||||
).toBe(DEFAULT_CLINE_ENVIRONMENT);
|
||||
delete process.env[CLINE_ENVIRONMENT_OVERRIDE_ENV];
|
||||
process.env[CLINE_ENVIRONMENT_ENV] = "qa";
|
||||
expect(resolveClineEnvironment()).toBe(DEFAULT_CLINE_ENVIRONMENT);
|
||||
});
|
||||
|
||||
it("defaults to production when process is unavailable", () => {
|
||||
vi.stubGlobal("process", undefined);
|
||||
|
||||
expect(resolveClineEnvironment()).toBe(DEFAULT_CLINE_ENVIRONMENT);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -74,18 +91,31 @@ describe("getClineEnvironmentConfig", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("resolves from env when no explicit environment is passed", () => {
|
||||
expect(
|
||||
getClineEnvironmentConfig({
|
||||
env: { [CLINE_ENVIRONMENT_ENV]: "staging" },
|
||||
}),
|
||||
).toBe(CLINE_ENVIRONMENTS.staging);
|
||||
it("falls back to production by default", () => {
|
||||
expect(getClineEnvironmentConfig()).toBe(CLINE_ENVIRONMENTS.production);
|
||||
});
|
||||
|
||||
it("falls back to production by default", () => {
|
||||
expect(getClineEnvironmentConfig({ env: {} })).toBe(
|
||||
CLINE_ENVIRONMENTS.production,
|
||||
);
|
||||
it("uses the resolved process.env environment when no explicit environment is provided", () => {
|
||||
process.env[CLINE_ENVIRONMENT_ENV] = "staging";
|
||||
|
||||
expect(getClineEnvironmentConfig()).toBe(CLINE_ENVIRONMENTS.staging);
|
||||
});
|
||||
|
||||
it("applies CLINE_API_BASE_URL without mutating the catalog config", () => {
|
||||
process.env.CLINE_API_BASE_URL = "http://127.0.0.1:3000";
|
||||
|
||||
expect(getClineEnvironmentConfig("local")).toEqual({
|
||||
...CLINE_ENVIRONMENTS.local,
|
||||
apiBaseUrl: "http://127.0.0.1:3000",
|
||||
mcpBaseUrl: "http://127.0.0.1:3000/v1/mcp",
|
||||
});
|
||||
expect(CLINE_ENVIRONMENTS.local.apiBaseUrl).toBe("http://localhost:7777");
|
||||
});
|
||||
|
||||
it("defaults to production when process is unavailable", () => {
|
||||
vi.stubGlobal("process", undefined);
|
||||
|
||||
expect(getClineEnvironmentConfig()).toBe(CLINE_ENVIRONMENTS.production);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -67,10 +67,8 @@ function readProcessEnv(): NodeJS.ProcessEnv {
|
||||
return process.env;
|
||||
}
|
||||
|
||||
export function resolveClineEnvironment(
|
||||
options: ResolveClineEnvironmentOptions = {},
|
||||
): ClineEnvironment {
|
||||
const env = options.env ?? readProcessEnv();
|
||||
export function resolveClineEnvironment(): ClineEnvironment {
|
||||
const env = readProcessEnv();
|
||||
return (
|
||||
normalizeClineEnvironment(env[CLINE_ENVIRONMENT_OVERRIDE_ENV]) ??
|
||||
normalizeClineEnvironment(env[CLINE_ENVIRONMENT_ENV]) ??
|
||||
@@ -78,11 +76,32 @@ export function resolveClineEnvironment(
|
||||
);
|
||||
}
|
||||
|
||||
export function getClineEnvironmentConfig(
|
||||
environmentOrOptions?: ClineEnvironment | ResolveClineEnvironmentOptions,
|
||||
): ClineEnvironmentConfig {
|
||||
if (typeof environmentOrOptions === "string") {
|
||||
return CLINE_ENVIRONMENTS[environmentOrOptions];
|
||||
function getEnvConfig(env?: ClineEnvironment) {
|
||||
if (typeof env === "string") {
|
||||
return CLINE_ENVIRONMENTS[env];
|
||||
}
|
||||
return CLINE_ENVIRONMENTS[resolveClineEnvironment(environmentOrOptions)];
|
||||
return CLINE_ENVIRONMENTS[resolveClineEnvironment()];
|
||||
}
|
||||
|
||||
function applyConfigOverrides(
|
||||
config: ClineEnvironmentConfig,
|
||||
env: NodeJS.ProcessEnv,
|
||||
): ClineEnvironmentConfig {
|
||||
if (env.CLINE_API_BASE_URL) {
|
||||
config = {
|
||||
...config,
|
||||
apiBaseUrl: env.CLINE_API_BASE_URL,
|
||||
mcpBaseUrl: `${env.CLINE_API_BASE_URL}/v1/mcp`,
|
||||
};
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
export function getClineEnvironmentConfig(
|
||||
env?: ClineEnvironment,
|
||||
): ClineEnvironmentConfig {
|
||||
const config = getEnvConfig(env);
|
||||
|
||||
return applyConfigOverrides(config, readProcessEnv());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user