Files
links/patches/puppeteer-api/lib/profile-dir.js
T

78 lines
2.1 KiB
JavaScript
Executable File

/**
* 按 sessionKey 解析持久 Chrome Profile 目录
*/
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const { RUNTIME_DIR, PERSIST_BROWSER_PROFILE, PROFILE_MAX_AGE_MS } = require('./constants');
const PROFILES_DIR = path.join(RUNTIME_DIR, 'profiles');
/**
* @param {string} sessionKey
* @param {'standard'|'real'} profile
* @returns {string|null}
*/
function resolveProfileDir(sessionKey, profile = 'standard') {
if (!sessionKey || !PERSIST_BROWSER_PROFILE) {
return null;
}
const hash = crypto.createHash('md5').update(String(sessionKey)).digest('hex');
const dir = path.join(PROFILES_DIR, `${hash}-${profile}`);
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
return dir;
}
function profileExists(sessionKey, profile = 'standard') {
const dir = resolveProfileDir(sessionKey, profile);
if (!dir) return false;
return fs.existsSync(dir);
}
function pruneStaleProfiles() {
if (!PERSIST_BROWSER_PROFILE || PROFILE_MAX_AGE_MS <= 0) {
return 0;
}
if (!fs.existsSync(PROFILES_DIR)) {
return 0;
}
const now = Date.now();
let removed = 0;
for (const name of fs.readdirSync(PROFILES_DIR)) {
const full = path.join(PROFILES_DIR, name);
try {
const stat = fs.statSync(full);
if (!stat.isDirectory()) continue;
if (now - stat.mtimeMs > PROFILE_MAX_AGE_MS) {
fs.rmSync(full, { recursive: true, force: true });
removed++;
}
} catch (_) {
/* ignore */
}
}
return removed;
}
function getProfileStats() {
if (!fs.existsSync(PROFILES_DIR)) {
return { profilesDir: PROFILES_DIR, count: 0 };
}
const count = fs.readdirSync(PROFILES_DIR).filter((name) => {
try {
return fs.statSync(path.join(PROFILES_DIR, name)).isDirectory();
} catch (_) {
return false;
}
}).length;
return { profilesDir: PROFILES_DIR, count };
}
module.exports = {
PROFILES_DIR,
resolveProfileDir,
profileExists,
pruneStaleProfiles,
getProfileStats,
};