FolderStructureBuilder.mjs 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import Path from 'node:path'
  2. import OError from '@overleaf/o-error'
  3. import mongodb from 'mongodb-legacy'
  4. const { ObjectId } = mongodb
  5. export default { buildFolderStructure }
  6. function buildFolderStructure(docEntries, fileEntries) {
  7. const builder = new FolderStructureBuilder()
  8. for (const docEntry of docEntries) {
  9. builder.addDocEntry(docEntry)
  10. }
  11. for (const fileEntry of fileEntries) {
  12. builder.addFileEntry(fileEntry)
  13. }
  14. return builder.rootFolder
  15. }
  16. class FolderStructureBuilder {
  17. constructor() {
  18. this.foldersByPath = new Map()
  19. this.entityPaths = new Set()
  20. this.rootFolder = this.createFolder('rootFolder')
  21. this.foldersByPath.set('/', this.rootFolder)
  22. this.entityPaths.add('/')
  23. }
  24. addDocEntry(docEntry) {
  25. this.recordEntityPath(docEntry.path)
  26. const folderPath = Path.dirname(docEntry.path)
  27. const folder = this.mkdirp(folderPath)
  28. folder.docs.push(docEntry.doc)
  29. }
  30. addFileEntry(fileEntry) {
  31. this.recordEntityPath(fileEntry.path)
  32. const folderPath = Path.dirname(fileEntry.path)
  33. const folder = this.mkdirp(folderPath)
  34. folder.fileRefs.push(fileEntry.file)
  35. }
  36. mkdirp(path) {
  37. const existingFolder = this.foldersByPath.get(path)
  38. if (existingFolder != null) {
  39. return existingFolder
  40. }
  41. // Folder not found, create it.
  42. this.recordEntityPath(path)
  43. const dirname = Path.dirname(path)
  44. const basename = Path.basename(path)
  45. const parentFolder = this.mkdirp(dirname)
  46. const newFolder = this.createFolder(basename)
  47. parentFolder.folders.push(newFolder)
  48. this.foldersByPath.set(path, newFolder)
  49. return newFolder
  50. }
  51. recordEntityPath(path) {
  52. if (this.entityPaths.has(path)) {
  53. throw new OError('entity already exists', { path })
  54. }
  55. this.entityPaths.add(path)
  56. }
  57. createFolder(name) {
  58. return {
  59. _id: new ObjectId(),
  60. name,
  61. folders: [],
  62. docs: [],
  63. fileRefs: [],
  64. }
  65. }
  66. }