/* eslint-disable camelcase, node/handle-callback-err, max-len, no-unused-vars, */ // TODO: This file was created by bulk-decaffeinate. // Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ const request = require('request').defaults({ jar: false }) const OError = require('@overleaf/o-error') const logger = require('logger-sharelatex') const settings = require('settings-sharelatex') const Errors = require('../Errors/Errors') const { promisifyAll } = require('../../util/promises') const TIMEOUT = 30 * 1000 // request timeout const DocstoreManager = { deleteDoc(project_id, doc_id, name, deletedAt, callback) { if (callback == null) { callback = function (error) {} } const url = `${settings.apis.docstore.url}/project/${project_id}/doc/${doc_id}` const docMetaData = { deleted: true, deletedAt, name } const options = { url, json: docMetaData, timeout: TIMEOUT } request.patch(options, function (error, res) { if (error != null) { return callback(error) } if (res.statusCode >= 200 && res.statusCode < 300) { return callback(null) } else if (res.statusCode === 404) { error = new Errors.NotFoundError({ message: 'tried to delete doc not in docstore', info: { project_id, doc_id } }) return callback(error) // maybe suppress the error when delete doc which is not present? } else { error = new OError( `docstore api responded with non-success code: ${res.statusCode}`, { project_id, doc_id } ) return callback(error) } }) }, getAllDocs(project_id, callback) { if (callback == null) { callback = function (error) {} } const url = `${settings.apis.docstore.url}/project/${project_id}/doc` return request.get( { url, timeout: TIMEOUT, json: true }, function (error, res, docs) { if (error != null) { return callback(error) } if (res.statusCode >= 200 && res.statusCode < 300) { return callback(null, docs) } else { error = new OError( `docstore api responded with non-success code: ${res.statusCode}`, { project_id } ) return callback(error) } } ) }, getAllDeletedDocs(project_id, callback) { const url = `${settings.apis.docstore.url}/project/${project_id}/doc-deleted` request.get( { url, timeout: TIMEOUT, json: true }, function (error, res, docs) { if (error) { callback( OError.tag(error, 'could not get deleted docs from docstore') ) } else if (res.statusCode === 200) { callback(null, docs) } else { callback( new OError( `docstore api responded with non-success code: ${res.statusCode}`, { project_id } ) ) } } ) }, getAllRanges(project_id, callback) { if (callback == null) { callback = function (error) {} } const url = `${settings.apis.docstore.url}/project/${project_id}/ranges` return request.get( { url, timeout: TIMEOUT, json: true }, function (error, res, docs) { if (error != null) { return callback(error) } if (res.statusCode >= 200 && res.statusCode < 300) { return callback(null, docs) } else { error = new OError( `docstore api responded with non-success code: ${res.statusCode}`, { project_id } ) return callback(error) } } ) }, getDoc(project_id, doc_id, options, callback) { if (options == null) { options = {} } if (callback == null) { callback = function (error, lines, rev, version) {} } if (typeof options === 'function') { callback = options options = {} } let url = `${settings.apis.docstore.url}/project/${project_id}/doc/${doc_id}` if (options.include_deleted) { url += '?include_deleted=true' } return request.get( { url, timeout: TIMEOUT, json: true }, function (error, res, doc) { if (error != null) { return callback(error) } if (res.statusCode >= 200 && res.statusCode < 300) { logger.log( { doc_id, project_id, version: doc.version, rev: doc.rev }, 'got doc from docstore api' ) return callback(null, doc.lines, doc.rev, doc.version, doc.ranges) } else if (res.statusCode === 404) { error = new Errors.NotFoundError({ message: 'doc not found in docstore', info: { project_id, doc_id } }) return callback(error) } else { error = new OError( `docstore api responded with non-success code: ${res.statusCode}`, { project_id, doc_id } ) return callback(error) } } ) }, isDocDeleted(project_id, doc_id, callback) { const url = `${settings.apis.docstore.url}/project/${project_id}/doc/${doc_id}/deleted` request.get( { url, timeout: TIMEOUT, json: true }, function (err, res, body) { if (err) { callback(err) } else if (res.statusCode === 200) { callback(null, body.deleted) } else if (res.statusCode === 404) { callback( new Errors.NotFoundError({ message: 'doc does not exist in project', info: { project_id, doc_id } }) ) } else { callback( new OError( `docstore api responded with non-success code: ${res.statusCode}`, { project_id, doc_id } ) ) } } ) }, updateDoc(project_id, doc_id, lines, version, ranges, callback) { if (callback == null) { callback = function (error, modified, rev) {} } const url = `${settings.apis.docstore.url}/project/${project_id}/doc/${doc_id}` return request.post( { url, timeout: TIMEOUT, json: { lines, version, ranges } }, function (error, res, result) { if (error != null) { return callback(error) } if (res.statusCode >= 200 && res.statusCode < 300) { logger.log( { project_id, doc_id }, 'update doc in docstore url finished' ) return callback(null, result.modified, result.rev) } else { error = new OError( `docstore api responded with non-success code: ${res.statusCode}`, { project_id, doc_id } ) return callback(error) } } ) }, archiveProject(project_id, callback) { DocstoreManager._operateOnProject(project_id, 'archive', callback) }, unarchiveProject(project_id, callback) { DocstoreManager._operateOnProject(project_id, 'unarchive', callback) }, destroyProject(project_id, callback) { DocstoreManager._operateOnProject(project_id, 'destroy', callback) }, _operateOnProject(project_id, method, callback) { const url = `${settings.apis.docstore.url}/project/${project_id}/${method}` logger.log({ project_id }, `calling ${method} for project in docstore`) // use default timeout for archiving/unarchiving/destroying request.post(url, function (err, res, docs) { if (err != null) { OError.tag(err, `error calling ${method} project in docstore`, { project_id }) return callback(err) } if (res.statusCode >= 200 && res.statusCode < 300) { callback() } else { const error = new Error( `docstore api responded with non-success code: ${res.statusCode}` ) logger.warn( { err: error, project_id }, `error calling ${method} project in docstore` ) callback(error) } }) } } module.exports = DocstoreManager module.exports.promises = promisifyAll(DocstoreManager, { multiResult: { getDoc: ['lines', 'rev', 'version', 'ranges'], updateDoc: ['modified', 'rev'] } })