Files
sk-az-tools/src/index.ts

59 lines
1.7 KiB
TypeScript

// SPDX-License-Identifier: MIT
import { readFile } from "node:fs/promises";
import os from "node:os";
import path from "node:path";
type Config = {
tenantId?: string;
clientId?: string;
};
type ConfigCandidate = {
tenantId?: unknown;
clientId?: unknown;
};
export function getUserConfigDir(): string {
if (process.platform === "win32") {
return process.env.LOCALAPPDATA ?? path.join(os.homedir(), "AppData", "Local");
}
return process.env.XDG_CONFIG_HOME ?? path.join(os.homedir(), ".config");
}
async function loadConfig(configFileName: string): Promise<Config> {
if (typeof configFileName !== "string" || configFileName.trim() === "") {
throw new Error(
'Invalid config file name. Expected a non-empty string like "public-config.json" or "confidential-config.json".',
);
}
const envConfig: Config = {
tenantId: process.env.AZURE_TENANT_ID,
clientId: process.env.AZURE_CLIENT_ID,
};
const configPath = path.join(getUserConfigDir(), "sk-az-tools", configFileName);
return readFile(configPath, "utf8")
.then((configJson) => JSON.parse(configJson) as ConfigCandidate)
.catch((err: unknown) => {
if ((err as { code?: string } | null)?.code === "ENOENT") {
return {} as ConfigCandidate;
}
throw err;
})
.then((json) => ({
tenantId: typeof json.tenantId === "string" && json.tenantId ? json.tenantId : envConfig.tenantId,
clientId: typeof json.clientId === "string" && json.clientId ? json.clientId : envConfig.clientId,
}));
}
export function loadPublicConfig(): Promise<Config> {
return loadConfig("public-config.json");
}
export function loadConfidentialConfig(): Promise<Config> {
return loadConfig("confidential-config.json");
}