repositories / pi-ext
pi-ext
bugabingas pi extensions
owned by admin
extensions/web/store.ts
Rawimport { createHash, randomUUID } from "node:crypto";
import { mkdir, writeFile } from "node:fs/promises";
import { homedir } from "node:os";
import path from "node:path";
export interface StateDirOptions {
platform?: NodeJS.Platform;
env?: NodeJS.ProcessEnv;
home?: string;
}
export interface SavedJsonResult {
namespace: string;
responseId: string;
fullOutputPath: string;
byteLength: number;
}
export function platformStateDir(
platform: NodeJS.Platform = process.platform,
env: NodeJS.ProcessEnv = process.env,
home = homedir(),
): string {
const paths = platform === "win32" ? path.win32 : path.posix;
// Treat XDG_STATE_HOME as an explicit override for hermetic tests/CI,
// even on platforms where it is not the native convention.
if (env.XDG_STATE_HOME) return paths.join(env.XDG_STATE_HOME, "pi");
if (platform === "win32")
return paths.join(
env.LOCALAPPDATA ?? paths.join(home, "AppData", "Local"),
"pi",
);
if (platform === "darwin")
return paths.join(home, "Library", "Application Support", "pi");
return paths.join(home, ".local", "state", "pi");
}
export function projectStoreDir(
namespace: string,
cwd: string,
options: StateDirOptions = {},
): string {
const paths = pathModule(options.platform);
return paths.join(
platformStateDir(options.platform, options.env, options.home),
namespace,
hash(cwd),
);
}
export async function saveJsonResult(
namespace: string,
cwd: string,
value: unknown,
options: StateDirOptions = {},
): Promise<SavedJsonResult> {
const responseId = randomUUID();
const paths = pathModule(options.platform);
const dir = paths.join(projectStoreDir(namespace, cwd, options), "results");
await mkdir(dir, { recursive: true, mode: 0o700 });
const fullOutputPath = paths.join(dir, `${responseId}.json`);
const body = `${JSON.stringify(value, null, 2)}\n`;
await writeFile(fullOutputPath, body, { mode: 0o600 });
return {
namespace,
responseId,
fullOutputPath,
byteLength: Buffer.byteLength(body),
};
}
function pathModule(platform: NodeJS.Platform = process.platform) {
return platform === "win32" ? path.win32 : path.posix;
}
function hash(input: string): string {
return createHash("sha256").update(input).digest("hex");
}