You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

83 lines
2.4 KiB

11 months ago
  1. const fs = require("fs");
  2. const path = require("path");
  3. const {
  4. purgeVectorCache,
  5. purgeSourceDocument,
  6. normalizePath,
  7. isWithin,
  8. documentsPath,
  9. } = require(".");
  10. const { Document } = require("../../models/documents");
  11. const { Workspace } = require("../../models/workspace");
  12. async function purgeDocument(filename = null) {
  13. if (!filename || !normalizePath(filename)) return;
  14. await purgeVectorCache(filename);
  15. await purgeSourceDocument(filename);
  16. const workspaces = await Workspace.where();
  17. for (const workspace of workspaces) {
  18. await Document.removeDocuments(workspace, [filename]);
  19. }
  20. return;
  21. }
  22. async function purgeFolder(folderName = null) {
  23. if (!folderName) return;
  24. const subFolder = normalizePath(folderName);
  25. const subFolderPath = path.resolve(documentsPath, subFolder);
  26. const validRemovableSubFolders = fs
  27. .readdirSync(documentsPath)
  28. .map((folder) => {
  29. // Filter out any results which are not folders or
  30. // are the protected custom-documents folder.
  31. if (folder === "custom-documents") return null;
  32. const subfolderPath = path.resolve(documentsPath, folder);
  33. if (!fs.lstatSync(subfolderPath).isDirectory()) return null;
  34. return folder;
  35. })
  36. .filter((subFolder) => !!subFolder);
  37. if (
  38. !validRemovableSubFolders.includes(subFolder) ||
  39. !fs.existsSync(subFolderPath) ||
  40. !isWithin(documentsPath, subFolderPath)
  41. )
  42. return;
  43. const filenames = fs
  44. .readdirSync(subFolderPath)
  45. .map((file) =>
  46. path.join(subFolderPath, file).replace(documentsPath + "/", "")
  47. );
  48. const workspaces = await Workspace.where();
  49. const purgePromises = [];
  50. // Remove associated Vector-cache files
  51. for (const filename of filenames) {
  52. const rmVectorCache = () =>
  53. new Promise((resolve) =>
  54. purgeVectorCache(filename).then(() => resolve(true))
  55. );
  56. purgePromises.push(rmVectorCache);
  57. }
  58. // Remove workspace document associations
  59. for (const workspace of workspaces) {
  60. const rmWorkspaceDoc = () =>
  61. new Promise((resolve) =>
  62. Document.removeDocuments(workspace, filenames).then(() => resolve(true))
  63. );
  64. purgePromises.push(rmWorkspaceDoc);
  65. }
  66. await Promise.all(purgePromises.flat().map((f) => f()));
  67. fs.rmSync(subFolderPath, { recursive: true }); // Delete target document-folder and source files.
  68. return;
  69. }
  70. module.exports = {
  71. purgeDocument,
  72. purgeFolder,
  73. };