ProjectEntityHandler.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. const path = require('path')
  2. const DocstoreManager = require('../Docstore/DocstoreManager')
  3. const Errors = require('../Errors/Errors')
  4. const ProjectGetter = require('./ProjectGetter')
  5. const { promisifyAll } = require('../../util/promises')
  6. const ProjectEntityHandler = {
  7. getAllDocs(projectId, callback) {
  8. // We get the path and name info from the project, and the lines and
  9. // version info from the doc store.
  10. DocstoreManager.getAllDocs(projectId, (error, docContentsArray) => {
  11. if (error != null) {
  12. return callback(error)
  13. }
  14. // Turn array from docstore into a dictionary based on doc id
  15. const docContents = {}
  16. for (const docContent of docContentsArray) {
  17. docContents[docContent._id] = docContent
  18. }
  19. ProjectEntityHandler._getAllFolders(projectId, (error, folders) => {
  20. if (error != null) {
  21. return callback(error)
  22. }
  23. const docs = {}
  24. for (const { path: folderPath, folder } of folders) {
  25. for (const doc of folder.docs || []) {
  26. const content = docContents[doc._id.toString()]
  27. if (content != null) {
  28. docs[path.join(folderPath, doc.name)] = {
  29. _id: doc._id,
  30. name: doc.name,
  31. lines: content.lines,
  32. rev: content.rev,
  33. }
  34. }
  35. }
  36. }
  37. callback(null, docs)
  38. })
  39. })
  40. },
  41. getAllFiles(projectId, callback) {
  42. ProjectEntityHandler._getAllFolders(projectId, (err, folders) => {
  43. if (err != null) {
  44. return callback(err)
  45. }
  46. const files = {}
  47. for (const { path: folderPath, folder } of folders) {
  48. for (const file of folder.fileRefs || []) {
  49. if (file != null) {
  50. files[path.join(folderPath, file.name)] = file
  51. }
  52. }
  53. }
  54. callback(null, files)
  55. })
  56. },
  57. getAllEntities(projectId, callback) {
  58. ProjectGetter.getProject(projectId, (err, project) => {
  59. if (err != null) {
  60. return callback(err)
  61. }
  62. if (project == null) {
  63. return callback(new Errors.NotFoundError('project not found'))
  64. }
  65. const entities = ProjectEntityHandler.getAllEntitiesFromProject(project)
  66. callback(null, entities)
  67. })
  68. },
  69. getAllEntitiesFromProject(project) {
  70. const folders = ProjectEntityHandler._getAllFoldersFromProject(project)
  71. const docs = []
  72. const files = []
  73. for (const { path: folderPath, folder } of folders) {
  74. for (const doc of folder.docs || []) {
  75. if (doc != null) {
  76. docs.push({ path: path.join(folderPath, doc.name), doc })
  77. }
  78. }
  79. for (const file of folder.fileRefs || []) {
  80. if (file != null) {
  81. files.push({ path: path.join(folderPath, file.name), file })
  82. }
  83. }
  84. }
  85. return { docs, files, folders }
  86. },
  87. getAllDocPathsFromProjectById(projectId, callback) {
  88. ProjectGetter.getProjectWithoutDocLines(projectId, (err, project) => {
  89. if (err != null) {
  90. return callback(err)
  91. }
  92. if (project == null) {
  93. return callback(Errors.NotFoundError('no project'))
  94. }
  95. const docPaths = ProjectEntityHandler.getAllDocPathsFromProject(project)
  96. callback(null, docPaths)
  97. })
  98. },
  99. getAllDocPathsFromProject(project) {
  100. const folders = ProjectEntityHandler._getAllFoldersFromProject(project)
  101. const docPath = {}
  102. for (const { path: folderPath, folder } of folders) {
  103. for (const doc of folder.docs || []) {
  104. docPath[doc._id] = path.join(folderPath, doc.name)
  105. }
  106. }
  107. return docPath
  108. },
  109. getDoc(projectId, docId, options, callback) {
  110. if (options == null) {
  111. options = {}
  112. }
  113. if (typeof options === 'function') {
  114. callback = options
  115. options = {}
  116. }
  117. DocstoreManager.getDoc(projectId, docId, options, callback)
  118. },
  119. /**
  120. * @param {ObjectID | string} projectId
  121. * @param {ObjectID | string} docId
  122. * @param {Function} callback
  123. */
  124. getDocPathByProjectIdAndDocId(projectId, docId, callback) {
  125. ProjectGetter.getProjectWithoutDocLines(projectId, (err, project) => {
  126. if (err != null) {
  127. return callback(err)
  128. }
  129. if (project == null) {
  130. return callback(new Errors.NotFoundError('no project'))
  131. }
  132. ProjectEntityHandler.getDocPathFromProjectByDocId(
  133. project,
  134. docId,
  135. (err, docPath) => {
  136. if (err) return callback(Errors.OError.tag(err))
  137. if (docPath == null) {
  138. return callback(new Errors.NotFoundError('no doc'))
  139. }
  140. callback(null, docPath)
  141. }
  142. )
  143. })
  144. },
  145. /**
  146. * @param {Project} project
  147. * @param {ObjectID | string} docId
  148. * @param {Function} callback
  149. */
  150. getDocPathFromProjectByDocId(project, docId, callback) {
  151. function recursivelyFindDocInFolder(basePath, docId, folder) {
  152. const docInCurrentFolder = (folder.docs || []).find(
  153. currentDoc => currentDoc._id.toString() === docId.toString()
  154. )
  155. if (docInCurrentFolder != null) {
  156. return path.join(basePath, docInCurrentFolder.name)
  157. } else {
  158. let docPath, childFolder
  159. for (childFolder of folder.folders || []) {
  160. docPath = recursivelyFindDocInFolder(
  161. path.join(basePath, childFolder.name),
  162. docId,
  163. childFolder
  164. )
  165. if (docPath != null) {
  166. return docPath
  167. }
  168. }
  169. return null
  170. }
  171. }
  172. const docPath = recursivelyFindDocInFolder(
  173. '/',
  174. docId,
  175. project.rootFolder[0]
  176. )
  177. callback(null, docPath)
  178. },
  179. _getAllFolders(projectId, callback) {
  180. ProjectGetter.getProjectWithoutDocLines(projectId, (err, project) => {
  181. if (err != null) {
  182. return callback(err)
  183. }
  184. if (project == null) {
  185. return callback(new Errors.NotFoundError('no project'))
  186. }
  187. const folders = ProjectEntityHandler._getAllFoldersFromProject(project)
  188. callback(null, folders)
  189. })
  190. },
  191. _getAllFoldersFromProject(project) {
  192. const folders = []
  193. function processFolder(basePath, folder) {
  194. folders.push({ path: basePath, folder })
  195. for (const childFolder of folder.folders || []) {
  196. if (childFolder.name != null) {
  197. processFolder(path.join(basePath, childFolder.name), childFolder)
  198. }
  199. }
  200. }
  201. processFolder('/', project.rootFolder[0])
  202. return folders
  203. },
  204. }
  205. module.exports = ProjectEntityHandler
  206. module.exports.promises = promisifyAll(ProjectEntityHandler, {
  207. without: ['getAllEntitiesFromProject'],
  208. multiResult: {
  209. getAllEntities: ['docs', 'files'],
  210. getDoc: ['lines', 'rev', 'version', 'ranges'],
  211. },
  212. })