mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-04-10 04:19:25 -07:00
106 lines
3.1 KiB
TypeScript
106 lines
3.1 KiB
TypeScript
import path from 'node:path';
|
|
|
|
type ExistsSync = (candidate: string) => boolean;
|
|
|
|
type ConfigPathOptions = {
|
|
platform?: NodeJS.Platform;
|
|
appDataDir?: string;
|
|
xdgConfigHome?: string;
|
|
homeDir: string;
|
|
existsSync: ExistsSync;
|
|
appNames?: readonly string[];
|
|
defaultAppName?: string;
|
|
};
|
|
|
|
const DEFAULT_APP_NAMES = ['SubMiner'] as const;
|
|
const DEFAULT_FILE_NAMES = ['config.jsonc', 'config.json'] as const;
|
|
|
|
function getPlatformPath(platform: NodeJS.Platform): typeof path.posix | typeof path.win32 {
|
|
return platform === 'win32' ? path.win32 : path.posix;
|
|
}
|
|
|
|
export function resolveConfigBaseDirs(
|
|
xdgConfigHome: string | undefined,
|
|
homeDir: string,
|
|
platform: NodeJS.Platform = process.platform,
|
|
appDataDir?: string,
|
|
): string[] {
|
|
const platformPath = getPlatformPath(platform);
|
|
if (platform === 'win32') {
|
|
const roamingBaseDir = platformPath.join(homeDir, 'AppData', 'Roaming');
|
|
const primaryBaseDir = appDataDir?.trim() || roamingBaseDir;
|
|
return Array.from(new Set([primaryBaseDir, roamingBaseDir]));
|
|
}
|
|
|
|
const fallbackBaseDir = platformPath.join(homeDir, '.config');
|
|
const primaryBaseDir = xdgConfigHome?.trim() || fallbackBaseDir;
|
|
return Array.from(new Set([primaryBaseDir, fallbackBaseDir]));
|
|
}
|
|
|
|
function getAppNames(options: ConfigPathOptions): readonly string[] {
|
|
return options.appNames ?? DEFAULT_APP_NAMES;
|
|
}
|
|
|
|
function getDefaultAppName(options: ConfigPathOptions): string {
|
|
return options.defaultAppName ?? DEFAULT_APP_NAMES[0];
|
|
}
|
|
|
|
export function resolveConfigDir(options: ConfigPathOptions): string {
|
|
const platform = options.platform ?? process.platform;
|
|
const platformPath = getPlatformPath(platform);
|
|
const baseDirs = resolveConfigBaseDirs(
|
|
options.xdgConfigHome,
|
|
options.homeDir,
|
|
platform,
|
|
options.appDataDir,
|
|
);
|
|
const appNames = getAppNames(options);
|
|
|
|
for (const baseDir of baseDirs) {
|
|
for (const appName of appNames) {
|
|
const dir = platformPath.join(baseDir, appName);
|
|
for (const fileName of DEFAULT_FILE_NAMES) {
|
|
if (options.existsSync(platformPath.join(dir, fileName))) {
|
|
return dir;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for (const baseDir of baseDirs) {
|
|
for (const appName of appNames) {
|
|
const dir = platformPath.join(baseDir, appName);
|
|
if (options.existsSync(dir)) {
|
|
return dir;
|
|
}
|
|
}
|
|
}
|
|
|
|
return platformPath.join(baseDirs[0]!, getDefaultAppName(options));
|
|
}
|
|
|
|
export function resolveConfigFilePath(options: ConfigPathOptions): string {
|
|
const platform = options.platform ?? process.platform;
|
|
const platformPath = getPlatformPath(platform);
|
|
const baseDirs = resolveConfigBaseDirs(
|
|
options.xdgConfigHome,
|
|
options.homeDir,
|
|
platform,
|
|
options.appDataDir,
|
|
);
|
|
const appNames = getAppNames(options);
|
|
|
|
for (const baseDir of baseDirs) {
|
|
for (const appName of appNames) {
|
|
for (const fileName of DEFAULT_FILE_NAMES) {
|
|
const candidate = platformPath.join(baseDir, appName, fileName);
|
|
if (options.existsSync(candidate)) {
|
|
return candidate;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return platformPath.join(baseDirs[0]!, getDefaultAppName(options), DEFAULT_FILE_NAMES[0]!);
|
|
}
|