LocalFileWriter.js 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. const fs = require('fs')
  2. const uuid = require('node-uuid')
  3. const path = require('path')
  4. const Stream = require('stream')
  5. const { callbackify, promisify } = require('util')
  6. const metrics = require('@overleaf/metrics')
  7. const Settings = require('@overleaf/settings')
  8. const { WriteError } = require('./Errors')
  9. module.exports = {
  10. promises: {
  11. writeStream,
  12. deleteFile,
  13. },
  14. writeStream: callbackify(writeStream),
  15. deleteFile: callbackify(deleteFile),
  16. }
  17. const pipeline = promisify(Stream.pipeline)
  18. async function writeStream(stream, key) {
  19. const timer = new metrics.Timer('writingFile')
  20. const fsPath = _getPath(key)
  21. const writeStream = fs.createWriteStream(fsPath)
  22. try {
  23. await pipeline(stream, writeStream)
  24. timer.done()
  25. return fsPath
  26. } catch (err) {
  27. await deleteFile(fsPath)
  28. throw new WriteError('problem writing file locally', { fsPath }, err)
  29. }
  30. }
  31. async function deleteFile(fsPath) {
  32. if (!fsPath) {
  33. return
  34. }
  35. try {
  36. await promisify(fs.unlink)(fsPath)
  37. } catch (err) {
  38. if (err.code !== 'ENOENT') {
  39. throw new WriteError('failed to delete file', { fsPath }, err)
  40. }
  41. }
  42. }
  43. function _getPath(key) {
  44. if (key == null) {
  45. key = uuid.v1()
  46. }
  47. key = key.replace(/\//g, '-')
  48. return path.join(Settings.path.uploadFolder, key)
  49. }