mirror of
https://github.com/Mintplex-Labs/anything-llm
synced 2026-04-25 17:15:37 +02:00
* add eslint config to server * add break statements to switch case * add support for browser globals and turn off empty catch blocks * disable lines with useless try/catch wrappers * format * fix no-undef errors * disbale lines violating no-unsafe-finally * ignore syncStaticLists.mjs * use proper null check for creatorId instead of unreachable nullish coalescing * remove unneeded typescript eslint comment * make no-unused-private-class-members a warning * disable line for no-empty-objects * add new lint script * fix no-unused-vars violations * make no-unsued-vars an error --------- Co-authored-by: shatfield4 <seanhatfield5@gmail.com> Co-authored-by: Timothy Carambat <rambat1010@gmail.com>
80 lines
2.7 KiB
JavaScript
80 lines
2.7 KiB
JavaScript
const fs = require("fs");
|
|
const path = require("path");
|
|
const { default: slugify } = require("slugify");
|
|
const { log, conclude } = require("./helpers/index.js");
|
|
const { WorkspaceParsedFiles } = require("../models/workspaceParsedFiles.js");
|
|
const { directUploadsPath } = require("../utils/files");
|
|
|
|
async function batchDeleteFiles(filesToDelete, batchSize = 500) {
|
|
let deletedCount = 0;
|
|
let failedCount = 0;
|
|
|
|
for (let i = 0; i < filesToDelete.length; i += batchSize) {
|
|
const batch = filesToDelete.slice(i, i + batchSize);
|
|
|
|
try {
|
|
await Promise.all(
|
|
batch.map((filePath) => {
|
|
if (!fs.existsSync(filePath)) return;
|
|
if (fs.lstatSync(filePath).isDirectory())
|
|
fs.rmSync(filePath, { recursive: true });
|
|
else fs.unlinkSync(filePath);
|
|
})
|
|
);
|
|
deletedCount += batch.length;
|
|
|
|
log(
|
|
`Deleted batch ${Math.floor(i / batchSize) + 1}: ${batch.length} files`
|
|
);
|
|
} catch {
|
|
// If batch fails, try individual files sync
|
|
for (const filePath of batch) {
|
|
try {
|
|
fs.unlinkSync(filePath);
|
|
deletedCount++;
|
|
} catch (fileErr) {
|
|
failedCount++;
|
|
log(`Failed to delete ${filePath}: ${fileErr.message}`);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return { deletedCount, failedCount };
|
|
}
|
|
|
|
(async () => {
|
|
try {
|
|
const filesToDelete = [];
|
|
const knownFiles = await WorkspaceParsedFiles.where({}, null, null, {
|
|
filename: true,
|
|
})
|
|
// Slugify the filename to match the direct uploads naming convention otherwise
|
|
// files with spaces will not result in a match and will be pruned when attached to a thread.
|
|
// This could then result in files showing "Attached" but the model not seeing them during chat.
|
|
.then((files) => new Set(files.map((f) => slugify(f.filename))));
|
|
|
|
if (!fs.existsSync(directUploadsPath))
|
|
return log("No direct uploads path found - exiting.");
|
|
const filesInDirectUploadsPath = fs.readdirSync(directUploadsPath);
|
|
if (filesInDirectUploadsPath.length === 0) return;
|
|
|
|
for (let i = 0; i < filesInDirectUploadsPath.length; i++) {
|
|
const file = filesInDirectUploadsPath[i];
|
|
if (knownFiles.has(file)) continue;
|
|
filesToDelete.push(path.resolve(directUploadsPath, file));
|
|
}
|
|
|
|
if (filesToDelete.length === 0) return; // No orphaned files to delete
|
|
log(`Found ${filesToDelete.length} orphaned files to delete`);
|
|
const { deletedCount, failedCount } = await batchDeleteFiles(filesToDelete);
|
|
log(`Deleted ${deletedCount} orphaned files`);
|
|
if (failedCount > 0) log(`Failed to delete ${failedCount} files`);
|
|
} catch (e) {
|
|
console.error(e);
|
|
log(`errored with ${e.message}`);
|
|
} finally {
|
|
conclude();
|
|
}
|
|
})();
|