refactor: share platform secret source helpers
This commit is contained in:
+39
-2
@@ -98,6 +98,14 @@ interface DesiredSecret {
|
||||
fingerprint: string | null;
|
||||
}
|
||||
|
||||
export interface EnvSourceFileMaterial {
|
||||
sourceRef: string;
|
||||
sourcePath: string;
|
||||
sourcePathRedacted: string;
|
||||
values: Record<string, string>;
|
||||
valuesPrinted: false;
|
||||
}
|
||||
|
||||
export function secretsHelp(): Record<string, unknown> {
|
||||
return {
|
||||
command: "secrets plan|sync|status",
|
||||
@@ -673,7 +681,26 @@ function secretRoot(config: SecretDistributionConfig): string {
|
||||
return isAbsolute(root) ? root : rootPath(root);
|
||||
}
|
||||
|
||||
function parseEnvFile(text: string): Record<string, string> {
|
||||
export function readTextFile(path: string): string {
|
||||
if (!existsSync(path)) throw new Error(`required secret source ${redactRepoPath(path)} is missing`);
|
||||
return readFileSync(path, "utf8");
|
||||
}
|
||||
|
||||
export function readEnvSourceFile(params: { root: string; sourceRef: string; missingMessage?: (sourcePath: string) => string }): EnvSourceFileMaterial {
|
||||
const sourcePath = join(params.root, params.sourceRef);
|
||||
if (!existsSync(sourcePath)) {
|
||||
throw new Error(params.missingMessage?.(sourcePath) ?? `required secret source ${redactRepoPath(sourcePath)} is missing`);
|
||||
}
|
||||
return {
|
||||
sourceRef: params.sourceRef,
|
||||
sourcePath,
|
||||
sourcePathRedacted: redactRepoPath(sourcePath),
|
||||
values: parseEnvFile(readFileSync(sourcePath, "utf8")),
|
||||
valuesPrinted: false,
|
||||
};
|
||||
}
|
||||
|
||||
export function parseEnvFile(text: string): Record<string, string> {
|
||||
const result: Record<string, string> = {};
|
||||
for (const rawLine of text.split(/\r?\n/u)) {
|
||||
const line = rawLine.trim();
|
||||
@@ -692,6 +719,16 @@ function unquoteEnvValue(value: string): string {
|
||||
return value;
|
||||
}
|
||||
|
||||
export function requiredEnvValue(values: Record<string, string>, key: string, sourceRef: string): string {
|
||||
const value = values[key];
|
||||
if (value === undefined || value.length === 0) throw new Error(`${sourceRef} is missing required key ${key}`);
|
||||
return value;
|
||||
}
|
||||
|
||||
export function fingerprintSecretValues(values: Record<string, string>, keys: string[]): string {
|
||||
return fingerprintValues(values, keys);
|
||||
}
|
||||
|
||||
function writeEnvFile(path: string, values: Record<string, string>): void {
|
||||
mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
|
||||
const lines = Object.keys(values).sort().map((key) => `${key}=${quoteEnv(values[key])}`);
|
||||
@@ -704,7 +741,7 @@ function quoteEnv(value: string): string {
|
||||
return `'${value.replaceAll("'", "'\"'\"'")}'`;
|
||||
}
|
||||
|
||||
function redactRepoPath(path: string): string {
|
||||
export function redactRepoPath(path: string): string {
|
||||
const root = rootPath();
|
||||
return path.startsWith(`${root}/`) ? path.slice(root.length + 1) : path;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user