103 lines
2.9 KiB
JavaScript
Executable File
103 lines
2.9 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const fsp = fs.promises;
|
|
|
|
async function pathExists(location) {
|
|
try {
|
|
await fsp.access(location);
|
|
return true;
|
|
} catch (error) {
|
|
if (error && error.code === 'ENOENT') {
|
|
return false;
|
|
}
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async function moveFile(source, destination) {
|
|
await fsp.mkdir(path.dirname(destination), { recursive: true });
|
|
try {
|
|
await fsp.rename(source, destination);
|
|
} catch (error) {
|
|
if (error.code === 'EXDEV') {
|
|
await fsp.copyFile(source, destination);
|
|
await fsp.unlink(source);
|
|
} else if (error.code === 'EEXIST') {
|
|
console.warn(`Destination already exists, leaving original in place: ${destination}`);
|
|
return;
|
|
} else {
|
|
throw error;
|
|
}
|
|
}
|
|
}
|
|
|
|
async function migrate() {
|
|
const backendRoot = path.resolve(__dirname, '..');
|
|
const defaultStorage = path.resolve(backendRoot, '../storage');
|
|
const targetStorage = path.resolve(process.env.STORAGE_PATH || defaultStorage);
|
|
const legacyUploadsRoot = path.resolve(backendRoot, 'storage/uploads');
|
|
const targetUploadsRoot = path.join(targetStorage, 'uploads');
|
|
|
|
if (legacyUploadsRoot === targetUploadsRoot) {
|
|
console.log('Legacy uploads directory already matches target STORAGE_PATH. Nothing to migrate.');
|
|
return;
|
|
}
|
|
|
|
if (!fs.existsSync(legacyUploadsRoot)) {
|
|
console.log(`Legacy uploads directory not found at ${legacyUploadsRoot}. Nothing to migrate.`);
|
|
return;
|
|
}
|
|
|
|
const categories = ['logos', 'favicons'];
|
|
let migratedCounter = 0;
|
|
|
|
for (const category of categories) {
|
|
const legacyDir = path.join(legacyUploadsRoot, category);
|
|
if (!fs.existsSync(legacyDir)) {
|
|
continue;
|
|
}
|
|
|
|
const targetDir = path.join(targetUploadsRoot, category);
|
|
await fsp.mkdir(targetDir, { recursive: true });
|
|
|
|
const entries = await fsp.readdir(legacyDir, { withFileTypes: true });
|
|
for (const entry of entries) {
|
|
if (!entry.isFile()) {
|
|
continue;
|
|
}
|
|
|
|
const sourcePath = path.join(legacyDir, entry.name);
|
|
const destinationPath = path.join(targetDir, entry.name);
|
|
|
|
if (await pathExists(destinationPath)) {
|
|
console.warn(`Skipping ${sourcePath} because ${destinationPath} already exists.`);
|
|
continue;
|
|
}
|
|
|
|
await moveFile(sourcePath, destinationPath);
|
|
migratedCounter += 1;
|
|
}
|
|
|
|
const remaining = await fsp.readdir(legacyDir);
|
|
if (remaining.length === 0) {
|
|
await fsp.rm(legacyDir, { recursive: true, force: true });
|
|
}
|
|
}
|
|
|
|
if (migratedCounter === 0) {
|
|
console.log('No legacy logo or favicon files needed migration.');
|
|
return;
|
|
}
|
|
|
|
console.log(`Migrated ${migratedCounter} files into ${targetUploadsRoot}.`);
|
|
console.log('If the database still references legacy absolute paths, they will be cleaned up automatically on the next upload.');
|
|
}
|
|
|
|
migrate().catch((error) => {
|
|
console.error('Migration failed:', error);
|
|
process.exitCode = 1;
|
|
});
|