Files

40 lines
1.7 KiB
JavaScript

import { chmodSync, lstatSync, mkdirSync, mkdtempSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join, resolve } from 'node:path'
export const CHATLAB_TEMP_ROOT_ENV = 'CHATLAB_TEMP_ROOT'
const CHATLAB_TEMP_SCOPES = new Set(['tests', 'runtime', 'imports', 'merge', 'sync', 'parser', 'build', 'bench'])
export function resolveChatLabTempRoot(env = process.env) {
const configured = env[CHATLAB_TEMP_ROOT_ENV]?.trim()
if (configured) return resolve(configured)
return resolve(process.platform === 'darwin' ? '/private/tmp/chatlab' : join(tmpdir(), 'chatlab'))
}
function ensurePrivateDirectory(dirPath) {
mkdirSync(dirPath, { recursive: true, mode: 0o700 })
const stats = lstatSync(dirPath)
if (stats.isSymbolicLink()) throw new Error(`ChatLab temp directory must not be a symbolic link: ${dirPath}`)
if (!stats.isDirectory()) throw new Error(`ChatLab temp path must be a directory: ${dirPath}`)
if (typeof process.getuid === 'function' && stats.uid !== process.getuid()) {
throw new Error(`ChatLab temp directory is owned by another user: ${dirPath}`)
}
if (process.platform !== 'win32') chmodSync(dirPath, 0o700)
}
export function getChatLabTempScopeDir(scope, env = process.env) {
if (!CHATLAB_TEMP_SCOPES.has(scope)) throw new Error(`Invalid ChatLab temp scope: ${scope}`)
const root = resolveChatLabTempRoot(env)
ensurePrivateDirectory(root)
env[CHATLAB_TEMP_ROOT_ENV] = root
const scopeDir = join(root, scope)
ensurePrivateDirectory(scopeDir)
return scopeDir
}
export function createChatLabTempDir(scope, prefix, env = process.env) {
if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(prefix)) throw new Error(`Invalid ChatLab temp prefix: ${prefix}`)
return mkdtempSync(join(getChatLabTempScopeDir(scope, env), prefix))
}