LinkedFilesHandler.mjs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import fs from 'node:fs'
  2. import FileWriter from '../../infrastructure/FileWriter.mjs'
  3. import EditorController from '../Editor/EditorController.mjs'
  4. import ProjectLocator from '../Project/ProjectLocator.mjs'
  5. import { Project } from '../../models/Project.mjs'
  6. import ProjectGetter from '../Project/ProjectGetter.mjs'
  7. import LinkedFilesErrors from './LinkedFilesErrors.mjs'
  8. import { callbackifyAll } from '@overleaf/promise-utils'
  9. const { ProjectNotFoundError, V1ProjectNotFoundError, BadDataError } =
  10. LinkedFilesErrors
  11. const LinkedFilesHandler = {
  12. async getFileById(projectId, fileId) {
  13. const { element, path, folder } = await ProjectLocator.promises.findElement(
  14. {
  15. project_id: projectId,
  16. element_id: fileId,
  17. type: 'file',
  18. }
  19. )
  20. return { file: element, path, parentFolder: folder }
  21. },
  22. async getSourceProject(data) {
  23. const projection = { _id: 1, name: 1, overleaf: 1 } // include the historyId for future use
  24. if (data.v1_source_doc_id != null) {
  25. const project = await Project.findOne(
  26. { 'overleaf.id': data.v1_source_doc_id },
  27. projection
  28. ).exec()
  29. if (project == null) {
  30. throw new V1ProjectNotFoundError()
  31. }
  32. return project
  33. } else if (data.source_project_id != null) {
  34. const project = await ProjectGetter.promises.getProject(
  35. data.source_project_id,
  36. projection
  37. )
  38. if (project == null) {
  39. throw new ProjectNotFoundError()
  40. }
  41. return project
  42. } else {
  43. throw new BadDataError('neither v1 nor v2 id present')
  44. }
  45. },
  46. async importFromStream(
  47. projectId,
  48. readStream,
  49. linkedFileData,
  50. name,
  51. parentFolderId,
  52. userId
  53. ) {
  54. const fsPath = await FileWriter.promises.writeStreamToDisk(
  55. projectId,
  56. readStream
  57. )
  58. try {
  59. return await EditorController.promises.upsertFile(
  60. projectId,
  61. parentFolderId,
  62. name,
  63. fsPath,
  64. linkedFileData,
  65. 'upload',
  66. userId
  67. )
  68. } finally {
  69. await fs.promises.unlink(fsPath).catch(() => {})
  70. }
  71. },
  72. async importContent(
  73. projectId,
  74. content,
  75. linkedFileData,
  76. name,
  77. parentFolderId,
  78. userId
  79. ) {
  80. const fsPath = await FileWriter.promises.writeContentToDisk(
  81. projectId,
  82. content
  83. )
  84. try {
  85. return await EditorController.promises.upsertFile(
  86. projectId,
  87. parentFolderId,
  88. name,
  89. fsPath,
  90. linkedFileData,
  91. 'upload',
  92. userId
  93. )
  94. } finally {
  95. await fs.promises.unlink(fsPath).catch(() => {})
  96. }
  97. },
  98. }
  99. export default {
  100. promises: LinkedFilesHandler,
  101. ...callbackifyAll(LinkedFilesHandler, {
  102. multiResult: { getFileById: ['file', 'path', 'parentFolder'] },
  103. }),
  104. }