refactor(core): dedupe shared config and runtime helpers

This commit is contained in:
Peter Steinberger
2026-02-16 14:52:03 +00:00
parent 544ffbcf7b
commit 04892ee230
68 changed files with 1966 additions and 2018 deletions

View File

@@ -36,6 +36,45 @@ export class MissingEnvVarError extends Error {
}
}
type EnvToken =
| { kind: "escaped"; name: string; end: number }
| { kind: "substitution"; name: string; end: number };
function parseEnvTokenAt(value: string, index: number): EnvToken | null {
if (value[index] !== "$") {
return null;
}
const next = value[index + 1];
const afterNext = value[index + 2];
// Escaped: $${VAR} -> ${VAR}
if (next === "$" && afterNext === "{") {
const start = index + 3;
const end = value.indexOf("}", start);
if (end !== -1) {
const name = value.slice(start, end);
if (ENV_VAR_NAME_PATTERN.test(name)) {
return { kind: "escaped", name, end };
}
}
}
// Substitution: ${VAR} -> value
if (next === "{") {
const start = index + 2;
const end = value.indexOf("}", start);
if (end !== -1) {
const name = value.slice(start, end);
if (ENV_VAR_NAME_PATTERN.test(name)) {
return { kind: "substitution", name, end };
}
}
}
return null;
}
function substituteString(value: string, env: NodeJS.ProcessEnv, configPath: string): string {
if (!value.includes("$")) {
return value;
@@ -50,39 +89,20 @@ function substituteString(value: string, env: NodeJS.ProcessEnv, configPath: str
continue;
}
const next = value[i + 1];
const afterNext = value[i + 2];
// Escaped: $${VAR} -> ${VAR}
if (next === "$" && afterNext === "{") {
const start = i + 3;
const end = value.indexOf("}", start);
if (end !== -1) {
const name = value.slice(start, end);
if (ENV_VAR_NAME_PATTERN.test(name)) {
chunks.push(`\${${name}}`);
i = end;
continue;
}
}
const token = parseEnvTokenAt(value, i);
if (token?.kind === "escaped") {
chunks.push(`\${${token.name}}`);
i = token.end;
continue;
}
// Substitution: ${VAR} -> value
if (next === "{") {
const start = i + 2;
const end = value.indexOf("}", start);
if (end !== -1) {
const name = value.slice(start, end);
if (ENV_VAR_NAME_PATTERN.test(name)) {
const envValue = env[name];
if (envValue === undefined || envValue === "") {
throw new MissingEnvVarError(name, configPath);
}
chunks.push(envValue);
i = end;
continue;
}
if (token?.kind === "substitution") {
const envValue = env[token.name];
if (envValue === undefined || envValue === "") {
throw new MissingEnvVarError(token.name, configPath);
}
chunks.push(envValue);
i = token.end;
continue;
}
// Leave untouched if not a recognized pattern
@@ -103,32 +123,13 @@ export function containsEnvVarReference(value: string): boolean {
continue;
}
const next = value[i + 1];
const afterNext = value[i + 2];
// Escaped: $${VAR} -> ${VAR}
if (next === "$" && afterNext === "{") {
const start = i + 3;
const end = value.indexOf("}", start);
if (end !== -1) {
const name = value.slice(start, end);
if (ENV_VAR_NAME_PATTERN.test(name)) {
i = end;
continue;
}
}
const token = parseEnvTokenAt(value, i);
if (token?.kind === "escaped") {
i = token.end;
continue;
}
// Substitution: ${VAR} -> value
if (next === "{") {
const start = i + 2;
const end = value.indexOf("}", start);
if (end !== -1) {
const name = value.slice(start, end);
if (ENV_VAR_NAME_PATTERN.test(name)) {
return true;
}
}
if (token?.kind === "substitution") {
return true;
}
}