Files
dify/cli/src/sys/index.ts

123 lines
3.1 KiB
TypeScript

import fs from 'node:fs'
import { homedir } from 'node:os'
import { join } from 'node:path'
export function getEnv(name: string): string | undefined {
return process.env[name]
}
export function env(): NodeJS.ProcessEnv {
return process.env
}
export function processExit(code: number): never {
return process.exit(code) as never
}
export function io() {
return {
out: process.stdout,
err: process.stderr,
in: process.stdin,
isOutTTY: Boolean(process.stdout.isTTY),
isErrTTY: Boolean(process.stderr.isTTY),
}
}
export function handle(sig: string, handler: () => void) {
process.once(sig, handler)
}
export function unhandle(sig: string, handler: () => void) {
process.off(sig, handler)
}
export function platform(): NodeJS.Platform {
return process.platform
}
export function arch(): string {
return process.arch
}
export function pid(): number {
return Number(process.pid)
}
export type Platform = {
id: () => NodeJS.Platform
configDir: () => string
cacheDir: () => string
atomicReplace: (src: string, dst: string) => void
}
export const SUBDIR = 'difyctl'
export const ENV_XDG_CONFIG_HOME = 'XDG_CONFIG_HOME'
export const ENV_XDG_CACHE_HOME = 'XDG_CACHE_HOME'
function appDataDir(): string | undefined {
return getEnv('APPDATA') ?? getEnv('LOCALAPPDATA')
}
type PlatformFactory = () => Platform
function posixAtomicReplace(src: string, dst: string): void {
fs.renameSync(src, dst)
}
function win32AtomicReplace(src: string, dst: string): void {
try {
fs.unlinkSync(dst)
}
catch { }
fs.renameSync(src, dst)
}
const platformImpls: Partial<Record<NodeJS.Platform, PlatformFactory>> = {
linux: () => ({
id: () => 'linux',
configDir: () => {
const xdg = getEnv(ENV_XDG_CONFIG_HOME)
return (xdg !== undefined && xdg !== '') ? join(xdg, SUBDIR) : join(homedir(), '.config', SUBDIR)
},
cacheDir: () => {
const xdg = getEnv(ENV_XDG_CACHE_HOME)
return (xdg !== undefined && xdg !== '') ? join(xdg, SUBDIR) : join(homedir(), '.cache', SUBDIR)
},
atomicReplace: posixAtomicReplace,
}),
darwin: () => ({
id: () => 'darwin',
configDir: () => join(homedir(), '.config', SUBDIR),
cacheDir: () => join(homedir(), 'Library', 'Caches', SUBDIR),
atomicReplace: posixAtomicReplace,
}),
win32: () => ({
id: () => 'win32',
configDir: () => {
const appData = appDataDir()
if (appData === undefined || appData === '')
throw new Error('cannot resolve %APPDATA% on Windows')
return join(appData, SUBDIR)
},
cacheDir: () => {
const appData = appDataDir()
if (appData === undefined || appData === '')
throw new Error('cannot resolve %LOCALAPPDATA% on Windows')
return join(appData, SUBDIR)
},
atomicReplace: win32AtomicReplace,
}),
}
const defaultPlatformFactory: PlatformFactory = () => ({
id: () => platform(),
configDir: () => join(homedir(), '.config', SUBDIR),
cacheDir: () => join(homedir(), '.cache', SUBDIR),
atomicReplace: posixAtomicReplace,
})
export function resolvePlatform(): Platform {
return (platformImpls[platform()] ?? defaultPlatformFactory)()
}