FolderStructureBuilder.js 1.9 KB

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