111 lines
3.1 KiB
JavaScript
111 lines
3.1 KiB
JavaScript
const fs = require('fs').promises;
|
|
const fsSync = require('fs');
|
|
const path = require('path');
|
|
|
|
function defaultLogger(level, message) {
|
|
const stamp = new Date().toISOString();
|
|
console.log(`${stamp} [PluginReset] [${level}] ${message}`);
|
|
}
|
|
|
|
async function pathExists(targetPath) {
|
|
try {
|
|
await fs.access(targetPath);
|
|
return true;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
async function removeIfExists(targetPath, logger) {
|
|
const exists = await pathExists(targetPath);
|
|
if (!exists) return false;
|
|
try {
|
|
await fs.rm(targetPath, { recursive: true, force: true });
|
|
logger('INFO', `Removed: ${targetPath}`);
|
|
return true;
|
|
} catch (err) {
|
|
if (err && (err.code === 'EACCES' || err.code === 'EPERM')) {
|
|
logger('WARN', `Permission denied removing ${targetPath} (${err.code})`);
|
|
return false;
|
|
}
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
function listPluginDirs(pluginSitesDir) {
|
|
if (!fsSync.existsSync(pluginSitesDir)) return [];
|
|
return fsSync
|
|
.readdirSync(pluginSitesDir, { withFileTypes: true })
|
|
.filter((entry) => entry.isDirectory())
|
|
.map((entry) => path.join(pluginSitesDir, entry.name));
|
|
}
|
|
|
|
function readPluginConfig(pluginDir) {
|
|
const configPath = path.join(pluginDir, 'config.json');
|
|
if (!fsSync.existsSync(configPath)) return null;
|
|
try {
|
|
return JSON.parse(fsSync.readFileSync(configPath, 'utf8'));
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
async function resetPluginStorage(options = {}) {
|
|
const projectRoot = options.projectRoot || path.resolve(__dirname, '..');
|
|
const pluginSitesDir = path.join(projectRoot, 'plugin-sites');
|
|
const cachePluginSpecDir = path.join(projectRoot, 'cache', 'plugin-spec');
|
|
const logger = options.logger || defaultLogger;
|
|
|
|
const pluginDirs = listPluginDirs(pluginSitesDir);
|
|
const touched = [];
|
|
const warnings = [];
|
|
|
|
for (const pluginDir of pluginDirs) {
|
|
const config = readPluginConfig(pluginDir);
|
|
if (!config || !config.hyperdb) continue;
|
|
|
|
const pluginName = config.domain || path.basename(pluginDir);
|
|
const removed = {
|
|
plugin: pluginName,
|
|
specRemoved: false,
|
|
dbRemoved: false,
|
|
cacheSpecRemoved: false
|
|
};
|
|
|
|
try {
|
|
removed.specRemoved = await removeIfExists(path.join(pluginDir, 'spec'), logger);
|
|
removed.dbRemoved = await removeIfExists(path.join(pluginDir, 'db'), logger);
|
|
removed.cacheSpecRemoved = await removeIfExists(path.join(cachePluginSpecDir, pluginName), logger);
|
|
} catch (err) {
|
|
warnings.push(`${pluginName}: ${err.message}`);
|
|
logger('WARN', `Failed to fully reset ${pluginName}: ${err.message}`);
|
|
}
|
|
|
|
touched.push(removed);
|
|
}
|
|
|
|
const summary = {
|
|
inspectedPlugins: pluginDirs.length,
|
|
resetCandidates: touched.length,
|
|
warnings,
|
|
touched
|
|
};
|
|
|
|
logger(
|
|
'INFO',
|
|
`Plugin storage reset complete (inspected=${summary.inspectedPlugins}, candidates=${summary.resetCandidates})`
|
|
);
|
|
|
|
return summary;
|
|
}
|
|
|
|
module.exports = {
|
|
resetPluginStorage
|
|
};
|
|
|
|
if (require.main === module) {
|
|
resetPluginStorage().catch((err) => {
|
|
console.error(`${new Date().toISOString()} [PluginReset] [ERROR] ${err.message}`);
|
|
process.exit(1);
|
|
});
|
|
} |