Merge pull request #15172 from overleaf/em-promise-utils

Move util/promises from web into a shared library

GitOrigin-RevId: fe1980dc57b9dc8ce86fa1fad6a8a817e9505b3d
This commit is contained in:
Eric Mc Sween 2023-10-19 07:38:17 -04:00 committed by Copybot
parent 6f2b24706a
commit 680ebae30b
95 changed files with 229 additions and 487 deletions

148
package-lock.json generated
View file

@ -502,6 +502,62 @@
"mocha": "^5.2.0"
}
},
"libraries/promise-utils": {
"name": "@overleaf/promise-utils",
"version": "0.1.0",
"license": "AGPL-3.0-only",
"dependencies": {
"p-limit": "^2.3.0"
},
"devDependencies": {
"chai": "^4.3.10",
"mocha": "^10.2.0"
}
},
"libraries/promise-utils/node_modules/chai": {
"version": "4.3.10",
"resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz",
"integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==",
"dev": true,
"dependencies": {
"assertion-error": "^1.1.0",
"check-error": "^1.0.3",
"deep-eql": "^4.1.3",
"get-func-name": "^2.0.2",
"loupe": "^2.3.6",
"pathval": "^1.1.1",
"type-detect": "^4.0.8"
},
"engines": {
"node": ">=4"
}
},
"libraries/promise-utils/node_modules/deep-eql": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz",
"integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==",
"dev": true,
"dependencies": {
"type-detect": "^4.0.0"
},
"engines": {
"node": ">=6"
}
},
"libraries/promise-utils/node_modules/p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dependencies": {
"p-try": "^2.0.0"
},
"engines": {
"node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"libraries/ranges-tracker": {
"name": "@overleaf/ranges-tracker",
"devDependencies": {
@ -7636,6 +7692,10 @@
"resolved": "services/project-history",
"link": true
},
"node_modules/@overleaf/promise-utils": {
"resolved": "libraries/promise-utils",
"link": true
},
"node_modules/@overleaf/ranges-tracker": {
"resolved": "libraries/ranges-tracker",
"link": true
@ -16134,10 +16194,13 @@
}
},
"node_modules/check-error": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
"integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz",
"integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==",
"dev": true,
"dependencies": {
"get-func-name": "^2.0.2"
},
"engines": {
"node": "*"
}
@ -22348,9 +22411,9 @@
}
},
"node_modules/get-func-name": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
"integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz",
"integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==",
"dev": true,
"engines": {
"node": "*"
@ -27039,9 +27102,9 @@
}
},
"node_modules/loupe": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.1.tgz",
"integrity": "sha512-EN1D3jyVmaX4tnajVlfbREU4axL647hLec1h/PXAb8CPDMJiYitcWF2UeLVNttRqaIqQs4x+mRvXf+d+TlDrCA==",
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz",
"integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==",
"dev": true,
"dependencies": {
"get-func-name": "^2.0.0"
@ -39214,6 +39277,7 @@
"@overleaf/metrics": "*",
"@overleaf/o-error": "*",
"@overleaf/object-persistor": "*",
"@overleaf/promise-utils": "*",
"@overleaf/redis-wrapper": "*",
"@overleaf/settings": "*",
"@slack/webhook": "^6.1.0",
@ -46968,6 +47032,48 @@
}
}
},
"@overleaf/promise-utils": {
"version": "file:libraries/promise-utils",
"requires": {
"chai": "^4.3.10",
"mocha": "^10.2.0",
"p-limit": "^2.3.0"
},
"dependencies": {
"chai": {
"version": "4.3.10",
"resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz",
"integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==",
"dev": true,
"requires": {
"assertion-error": "^1.1.0",
"check-error": "^1.0.3",
"deep-eql": "^4.1.3",
"get-func-name": "^2.0.2",
"loupe": "^2.3.6",
"pathval": "^1.1.1",
"type-detect": "^4.0.8"
}
},
"deep-eql": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz",
"integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==",
"dev": true,
"requires": {
"type-detect": "^4.0.0"
}
},
"p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"requires": {
"p-try": "^2.0.0"
}
}
}
},
"@overleaf/ranges-tracker": {
"version": "file:libraries/ranges-tracker",
"requires": {
@ -47452,6 +47558,7 @@
"@overleaf/metrics": "*",
"@overleaf/o-error": "*",
"@overleaf/object-persistor": "*",
"@overleaf/promise-utils": "*",
"@overleaf/ranges-tracker": "*",
"@overleaf/redis-wrapper": "*",
"@overleaf/settings": "*",
@ -54897,10 +55004,13 @@
"requires": {}
},
"check-error": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
"integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
"dev": true
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz",
"integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==",
"dev": true,
"requires": {
"get-func-name": "^2.0.2"
}
},
"check-more-types": {
"version": "2.24.0",
@ -59536,9 +59646,9 @@
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
},
"get-func-name": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
"integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz",
"integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==",
"dev": true
},
"get-intrinsic": {
@ -63152,9 +63262,9 @@
}
},
"loupe": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.1.tgz",
"integrity": "sha512-EN1D3jyVmaX4tnajVlfbREU4axL647hLec1h/PXAb8CPDMJiYitcWF2UeLVNttRqaIqQs4x+mRvXf+d+TlDrCA==",
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz",
"integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==",
"dev": true,
"requires": {
"get-func-name": "^2.0.0"

View file

@ -5,7 +5,7 @@ const Metrics = require('../../infrastructure/Metrics')
const Queues = require('../../infrastructure/Queues')
const crypto = require('crypto')
const _ = require('lodash')
const { expressify } = require('../../util/promises')
const { expressify } = require('@overleaf/promise-utils')
const logger = require('@overleaf/logger')
const { getAnalyticsIdFromMongoUser } = require('./AnalyticsHelper')

View file

@ -3,7 +3,7 @@ const AnalyticsController = require('./AnalyticsController')
const AnalyticsProxy = require('./AnalyticsProxy')
const { RateLimiter } = require('../../infrastructure/RateLimiter')
const RateLimiterMiddleware = require('../Security/RateLimiterMiddleware')
const { expressify } = require('../../util/promises')
const { expressify } = require('@overleaf/promise-utils')
const rateLimiters = {
recordEvent: new RateLimiter('analytics-record-event', {

View file

@ -6,7 +6,7 @@ const HttpErrorHandler = require('../Errors/HttpErrorHandler')
const AuthenticationController = require('../Authentication/AuthenticationController')
const SessionManager = require('../Authentication/SessionManager')
const TokenAccessHandler = require('../TokenAccess/TokenAccessHandler')
const { expressify } = require('../../util/promises')
const { expressify } = require('@overleaf/promise-utils')
const {
canRedirectToAdminDomain,
} = require('../Helpers/AdminAuthorizationHelper')

View file

@ -5,7 +5,7 @@ const Metrics = require('@overleaf/metrics')
const OError = require('@overleaf/o-error')
const DeviceHistory = require('./DeviceHistory')
const AuthenticationController = require('../Authentication/AuthenticationController')
const { expressify } = require('../../util/promises')
const { expressify } = require('@overleaf/promise-utils')
function respondInvalidCaptcha(req, res) {
res.status(400).json({

View file

@ -9,7 +9,7 @@ const EditorRealTimeController = require('../Editor/EditorRealTimeController')
const TagsHandler = require('../Tags/TagsHandler')
const Errors = require('../Errors/Errors')
const logger = require('@overleaf/logger')
const { expressify } = require('../../util/promises')
const { expressify } = require('@overleaf/promise-utils')
const { hasAdminAccess } = require('../Helpers/AdminAuthorizationHelper')
const TokenAccessHandler = require('../TokenAccess/TokenAccessHandler')
const ProjectAuditLogHandler = require('../Project/ProjectAuditLogHandler')

View file

@ -11,7 +11,7 @@ const EditorRealTimeController = require('../Editor/EditorRealTimeController')
const AnalyticsManager = require('../Analytics/AnalyticsManager')
const SessionManager = require('../Authentication/SessionManager')
const { RateLimiter } = require('../../infrastructure/RateLimiter')
const { expressify } = require('../../util/promises')
const { expressify } = require('@overleaf/promise-utils')
const ProjectAuditLogHandler = require('../Project/ProjectAuditLogHandler')
const Errors = require('../Errors/Errors')

View file

@ -6,7 +6,7 @@ const RedisWrapper = require('../../infrastructure/RedisWrapper')
const Cookie = require('cookie')
const logger = require('@overleaf/logger')
const Metrics = require('@overleaf/metrics')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const clsiCookiesEnabled = (Settings.clsiCookie?.key ?? '') !== ''

View file

@ -13,7 +13,7 @@ let ClsiFormatChecker
const _ = require('lodash')
const async = require('async')
const settings = require('@overleaf/settings')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
module.exports = ClsiFormatChecker = {
checkRecoursesForProblems(resources, callback) {

View file

@ -1,5 +1,5 @@
const { callbackify } = require('util')
const { callbackifyMultiResult } = require('../../util/promises')
const { callbackifyMultiResult } = require('@overleaf/promise-utils')
const {
fetchString,
fetchStringWithResponse,

View file

@ -17,7 +17,7 @@ const ClsiCookieManager = require('./ClsiCookieManager')(
const Path = require('path')
const AnalyticsManager = require('../Analytics/AnalyticsManager')
const SplitTestHandler = require('../SplitTests/SplitTestHandler')
const { callbackify } = require('../../util/promises')
const { callbackify } = require('@overleaf/promise-utils')
const {
fetchStreamWithResponse,
RequestFailedError,

View file

@ -2,7 +2,7 @@ const SessionManager = require('../Authentication/SessionManager')
const ContactManager = require('./ContactManager')
const UserGetter = require('../User/UserGetter')
const Modules = require('../../infrastructure/Modules')
const { expressify } = require('../../util/promises')
const { expressify } = require('@overleaf/promise-utils')
function _formatContact(contact) {
return {

View file

@ -14,7 +14,7 @@ let CooldownManager
const RedisWrapper = require('../../infrastructure/RedisWrapper')
const rclient = RedisWrapper.client('cooldown')
const logger = require('@overleaf/logger')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const COOLDOWN_IN_SECONDS = 60 * 10

View file

@ -1,5 +1,5 @@
const { promisify } = require('util')
const { promisifyMultiResult } = require('../../util/promises')
const { promisifyMultiResult } = require('@overleaf/promise-utils')
const request = require('request').defaults({ jar: false })
const OError = require('@overleaf/o-error')
const logger = require('@overleaf/logger')

View file

@ -5,7 +5,7 @@ const ProjectEntityUpdateHandler = require('../Project/ProjectEntityUpdateHandle
const logger = require('@overleaf/logger')
const _ = require('lodash')
const { plainTextResponse } = require('../../infrastructure/Response')
const { expressify } = require('../../util/promises')
const { expressify } = require('@overleaf/promise-utils')
async function getDocument(req, res) {
const { Project_id: projectId, doc_id: docId } = req.params

View file

@ -8,7 +8,7 @@ const ProjectDeleter = require('../Project/ProjectDeleter')
const EditorRealTimeController = require('./EditorRealTimeController')
const async = require('async')
const PublicAccessLevels = require('../Authorization/PublicAccessLevels')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const EditorController = {
addDoc(projectId, folderId, docName, docLines, source, userId, callback) {

View file

@ -13,7 +13,7 @@ const SessionManager = require('../Authentication/SessionManager')
const Errors = require('../Errors/Errors')
const DocstoreManager = require('../Docstore/DocstoreManager')
const logger = require('@overleaf/logger')
const { expressify } = require('../../util/promises')
const { expressify } = require('@overleaf/promise-utils')
const SplitTestHandler = require('../SplitTests/SplitTestHandler')
const {
NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF,

View file

@ -8,7 +8,7 @@ const FileHashManager = require('./FileHashManager')
const { File } = require('../../models/File')
const Errors = require('../Errors/Errors')
const OError = require('@overleaf/o-error')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const ONE_MIN_IN_MS = 60 * 1000
const FIVE_MINS_IN_MS = ONE_MIN_IN_MS * 5

View file

@ -3,7 +3,7 @@ const logger = require('@overleaf/logger')
const metrics = require('@overleaf/metrics')
const settings = require('@overleaf/settings')
const request = require('requestretry')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const NotificationsBuilder = require('../Notifications/NotificationsBuilder')
const {
V1ConnectionError,

View file

@ -2,7 +2,7 @@ let InstitutionsFeatures
const UserGetter = require('../User/UserGetter')
const PlansLocator = require('../Subscription/PlansLocator')
const Settings = require('@overleaf/settings')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
module.exports = InstitutionsFeatures = {
getInstitutionsFeatures(userId, callback) {

View file

@ -21,7 +21,7 @@ const {
V1ProjectNotFoundError,
BadDataError,
} = require('./LinkedFilesErrors')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const LinkedFilesHandler = {
getFileById(projectId, fileId, callback) {

View file

@ -4,7 +4,7 @@ const { InvalidUrlError, UrlFetchFailedError } = require('./LinkedFilesErrors')
const LinkedFilesHandler = require('./LinkedFilesHandler')
const UrlHelper = require('../Helpers/UrlHelper')
const { fetchStream, RequestFailedError } = require('@overleaf/fetch-utils')
const { callbackify } = require('../../util/promises')
const { callbackify } = require('@overleaf/promise-utils')
const { FileTooLargeError } = require('../Errors/Errors')
async function createLinkedFile(

View file

@ -1,5 +1,5 @@
const NotificationsHandler = require('./NotificationsHandler')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const request = require('request')
const settings = require('@overleaf/settings')

View file

@ -2,7 +2,7 @@ const settings = require('@overleaf/settings')
const request = require('request')
const logger = require('@overleaf/logger')
const _ = require('lodash')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const notificationsApi = _.get(settings, ['apis', 'notifications', 'url'])
const oneSecond = 1000

View file

@ -7,7 +7,7 @@ const UserUpdater = require('../User/UserUpdater')
const UserSessionsManager = require('../User/UserSessionsManager')
const OError = require('@overleaf/o-error')
const EmailsHelper = require('../Helpers/EmailHelper')
const { expressify } = require('../../util/promises')
const { expressify } = require('@overleaf/promise-utils')
async function setNewUserPassword(req, res, next) {
let user

View file

@ -1,6 +1,6 @@
const logger = require('@overleaf/logger')
const { ProjectAuditLogEntry } = require('../../models/ProjectAuditLogEntry')
const { callbackify } = require('../../util/promises')
const { callbackify } = require('@overleaf/promise-utils')
module.exports = {
promises: {

View file

@ -20,7 +20,7 @@ const FilestoreHandler = require('../FileStore/FileStoreHandler')
const TpdsUpdateSender = require('../ThirdPartyDataStore/TpdsUpdateSender')
const ChatApiHandler = require('../Chat/ChatApiHandler')
const moment = require('moment')
const { promiseMapWithLimit } = require('../../util/promises')
const { promiseMapWithLimit } = require('@overleaf/promise-utils')
const { READ_PREFERENCE_SECONDARY } = require('../../infrastructure/mongodb')
const EXPIRE_PROJECTS_AFTER_DAYS = 90

View file

@ -1,7 +1,7 @@
const { callbackify } = require('util')
const Path = require('path')
const OError = require('@overleaf/o-error')
const { promiseMapWithLimit } = require('../../util/promises')
const { promiseMapWithLimit } = require('@overleaf/promise-utils')
const { Doc } = require('../../models/Doc')
const { File } = require('../../models/File')
const DocstoreManager = require('../Docstore/DocstoreManager')

View file

@ -2,7 +2,7 @@ const path = require('path')
const DocstoreManager = require('../Docstore/DocstoreManager')
const Errors = require('../Errors/Errors')
const ProjectGetter = require('./ProjectGetter')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const OError = require('@overleaf/o-error')
const { iterablePaths } = require('./IterablePath')

View file

@ -1,5 +1,5 @@
const { callbackify } = require('util')
const { callbackifyMultiResult } = require('../../util/promises')
const { callbackifyMultiResult } = require('@overleaf/promise-utils')
const _ = require('underscore')
const logger = require('@overleaf/logger')
const path = require('path')

View file

@ -21,7 +21,7 @@ const SafePath = require('./SafePath')
const TpdsUpdateSender = require('../ThirdPartyDataStore/TpdsUpdateSender')
const FileWriter = require('../../infrastructure/FileWriter')
const EditorRealTimeController = require('../Editor/EditorRealTimeController')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const { iterablePaths } = require('./IterablePath')
const LOCK_NAMESPACE = 'sequentialProjectStructureUpdateLock'

View file

@ -2,7 +2,7 @@ const { db } = require('../../infrastructure/mongodb')
const { normalizeQuery } = require('../Helpers/Mongo')
const OError = require('@overleaf/o-error')
const metrics = require('@overleaf/metrics')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const { Project } = require('../../models/Project')
const logger = require('@overleaf/logger')
const LockManager = require('../../infrastructure/LockManager')

View file

@ -2,7 +2,7 @@ const { Project } = require('../../models/Project')
const ProjectDetailsHandler = require('./ProjectDetailsHandler')
const HistoryManager = require('../History/HistoryManager')
const ProjectEntityUpdateHandler = require('./ProjectEntityUpdateHandler')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const ProjectHistoryHandler = {
setHistoryId(projectId, historyId, callback) {

View file

@ -9,7 +9,7 @@ const Sources = require('../Authorization/Sources')
const UserGetter = require('../User/UserGetter')
const SurveyHandler = require('../Survey/SurveyHandler')
const TagsHandler = require('../Tags/TagsHandler')
const { expressify } = require('../../util/promises')
const { expressify } = require('@overleaf/promise-utils')
const logger = require('@overleaf/logger')
const Features = require('../../infrastructure/Features')
const SubscriptionViewModelBuilder = require('../Subscription/SubscriptionViewModelBuilder')

View file

@ -4,7 +4,7 @@ const OError = require('@overleaf/o-error')
const async = require('async')
const ProjectGetter = require('./ProjectGetter')
const Errors = require('../Errors/Errors')
const { promisifyMultiResult } = require('../../util/promises')
const { promisifyMultiResult } = require('@overleaf/promise-utils')
const { iterablePaths } = require('./IterablePath')
function findElement(options, _callback) {

View file

@ -1,6 +1,6 @@
const { Project } = require('../../models/Project')
const settings = require('@overleaf/settings')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const safeCompilers = ['xelatex', 'pdflatex', 'latex', 'lualatex']

View file

@ -23,7 +23,7 @@ const { promisify } = require('util')
const async = require('async')
const globby = require('globby')
const _ = require('underscore')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
module.exports = ProjectRootDocManager = {
setRootDocAutomatically(projectId, callback) {

View file

@ -11,7 +11,7 @@
*/
const { Project } = require('../../models/Project')
const logger = require('@overleaf/logger')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const ProjectUpdateHandler = {
markAsUpdated(projectId, lastUpdatedAt, lastUpdatedBy, callback) {

View file

@ -1,7 +1,7 @@
const Settings = require('@overleaf/settings')
const logger = require('@overleaf/logger')
const { fetchJson } = require('@overleaf/fetch-utils')
const { callbackify } = require('../../util/promises')
const { callbackify } = require('@overleaf/promise-utils')
const UserMembershipsHandler = require('../UserMembership/UserMembershipsHandler')
const UserMembershipEntityConfigs = require('../UserMembership/UserMembershipEntityConfigs')

View file

@ -1,7 +1,7 @@
const OError = require('@overleaf/o-error')
const { User } = require('../../models/User')
const FeaturesUpdater = require('../Subscription/FeaturesUpdater')
const { promisify } = require('../../util/promises')
const { promisify } = require('@overleaf/promise-utils')
function allocate(
referalId,

View file

@ -1,5 +1,5 @@
const { RateLimiter } = require('../../infrastructure/RateLimiter')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const rateLimiter = new RateLimiter('login', {
points: 10,

View file

@ -1,7 +1,7 @@
const crypto = require('crypto')
const { db } = require('../../infrastructure/mongodb')
const Errors = require('../Errors/Errors')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const ONE_HOUR_IN_S = 60 * 60

View file

@ -1,6 +1,6 @@
const OError = require('@overleaf/o-error')
const Metrics = require('@overleaf/metrics')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const LearnedWordsManager = require('./LearnedWordsManager')
module.exports = {

View file

@ -1,6 +1,6 @@
const _ = require('lodash')
const { callbackify } = require('util')
const { callbackifyMultiResult } = require('../../util/promises')
const { callbackifyMultiResult } = require('@overleaf/promise-utils')
const PlansLocator = require('./PlansLocator')
const SubscriptionLocator = require('./SubscriptionLocator')
const UserFeaturesUpdater = require('./UserFeaturesUpdater')

View file

@ -8,7 +8,7 @@ const CollaboratorsGetter = require('../Collaborators/CollaboratorsGetter')
const CollaboratorsInvitesHandler = require('../Collaborators/CollaboratorsInviteHandler')
const V1SubscriptionManager = require('./V1SubscriptionManager')
const { V1ConnectionError } = require('../Errors/Errors')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const LimitationsManager = {
allowedNumberOfCollaboratorsInProject(projectId, callback) {

View file

@ -14,7 +14,7 @@ const GroupPlansData = require('./GroupPlansData')
const V1SubscriptionManager = require('./V1SubscriptionManager')
const AnalyticsManager = require('../Analytics/AnalyticsManager')
const RecurlyEventHandler = require('./RecurlyEventHandler')
const { expressify } = require('../../util/promises')
const { expressify } = require('@overleaf/promise-utils')
const OError = require('@overleaf/o-error')
const SplitTestHandler = require('../SplitTests/SplitTestHandler')
const SubscriptionHelper = require('./SubscriptionHelper')

View file

@ -9,7 +9,7 @@ const LimitationsManager = require('./LimitationsManager')
const EmailHandler = require('../Email/EmailHandler')
const PlansLocator = require('./PlansLocator')
const SubscriptionHelper = require('./SubscriptionHelper')
const { callbackify } = require('../../util/promises')
const { callbackify } = require('@overleaf/promise-utils')
function validateNoSubscriptionInRecurly(userId, callback) {
RecurlyWrapper.listAccountActiveSubscriptions(

View file

@ -1,5 +1,5 @@
const { db, ObjectId } = require('../../infrastructure/mongodb')
const { callbackify } = require('../../util/promises')
const { callbackify } = require('@overleaf/promise-utils')
const { Subscription } = require('../../models/Subscription')
const SubscriptionLocator = require('./SubscriptionLocator')
const PlansLocator = require('./PlansLocator')

View file

@ -11,7 +11,7 @@ const sanitizeHtml = require('sanitize-html')
const _ = require('underscore')
const async = require('async')
const SubscriptionHelper = require('./SubscriptionHelper')
const { callbackify } = require('../../util/promises')
const { callbackify } = require('@overleaf/promise-utils')
const {
InvalidError,
NotFoundError,

View file

@ -7,7 +7,7 @@ const SubscriptionLocator = require('./SubscriptionLocator')
const ErrorController = require('../Errors/ErrorController')
const EmailHelper = require('../Helpers/EmailHelper')
const UserGetter = require('../User/UserGetter')
const { expressify } = require('../../util/promises')
const { expressify } = require('@overleaf/promise-utils')
const HttpErrorHandler = require('../Errors/HttpErrorHandler')
const PermissionsManager = require('../Authorization/PermissionsManager')
const EmailHandler = require('../Email/EmailHandler')

View file

@ -16,7 +16,10 @@ const EmailHandler = require('../Email/EmailHandler')
const EmailHelper = require('../Helpers/EmailHelper')
const Errors = require('../Errors/Errors')
const { callbackify, callbackifyMultiResult } = require('../../util/promises')
const {
callbackify,
callbackifyMultiResult,
} = require('@overleaf/promise-utils')
const NotificationsBuilder = require('../Notifications/NotificationsBuilder')
async function getInvite(token) {

View file

@ -1,5 +1,5 @@
const { User } = require('../../models/User')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const Settings = require('@overleaf/settings')
function _featuresChanged(newFeatures, featuresBefore) {

View file

@ -3,7 +3,7 @@ const UserGetter = require('../User/UserGetter')
const request = require('requestretry')
const settings = require('@overleaf/settings')
const { V1ConnectionError, NotFoundError } = require('../Errors/Errors')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
module.exports = V1SubscriptionManager = {
getSubscriptionsFromV1(userId, callback) {

View file

@ -1,7 +1,7 @@
const crypto = require('crypto')
const SurveyCache = require('./SurveyCache')
const SubscriptionLocator = require('../Subscription/SubscriptionLocator')
const { callbackify } = require('../../util/promises')
const { callbackify } = require('@overleaf/promise-utils')
/**
* @typedef {import('../../../../types/project/dashboard/survey').Survey} Survey

View file

@ -1,7 +1,7 @@
const TagsHandler = require('./TagsHandler')
const SessionManager = require('../Authentication/SessionManager')
const Errors = require('../Errors/Errors')
const { expressify } = require('../../util/promises')
const { expressify } = require('@overleaf/promise-utils')
async function _getTags(userId, _req, res) {
if (!userId) {

View file

@ -1,5 +1,5 @@
const { Tag } = require('../../models/Tag')
const { callbackify } = require('../../util/promises')
const { callbackify } = require('@overleaf/promise-utils')
const MAX_TAG_LENGTH = 50

View file

@ -1,4 +1,4 @@
const { expressify } = require('../../util/promises')
const { expressify } = require('@overleaf/promise-utils')
const TpdsUpdateHandler = require('./TpdsUpdateHandler')
const UpdateMerger = require('./UpdateMerger')
const Errors = require('../Errors/Errors')

View file

@ -5,7 +5,7 @@ const Errors = require('../Errors/Errors')
const logger = require('@overleaf/logger')
const settings = require('@overleaf/settings')
const OError = require('@overleaf/o-error')
const { expressify } = require('../../util/promises')
const { expressify } = require('@overleaf/promise-utils')
const AuthorizationManager = require('../Authorization/AuthorizationManager')
const PrivilegeLevels = require('../Authorization/PrivilegeLevels')
const {

View file

@ -6,7 +6,7 @@ const Settings = require('@overleaf/settings')
const logger = require('@overleaf/logger')
const V1Api = require('../V1/V1Api')
const crypto = require('crypto')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const Analytics = require('../Analytics/AnalyticsManager')
const READ_AND_WRITE_TOKEN_PATTERN = '([0-9]+[a-z]{6,12})'

View file

@ -1,6 +1,6 @@
const SessionManager = require('../Authentication/SessionManager')
const TutorialHandler = require('./TutorialHandler')
const { expressify } = require('../../util/promises')
const { expressify } = require('@overleaf/promise-utils')
const VALID_KEYS = [
'react-history-buttons-tutorial',

View file

@ -26,7 +26,7 @@ const {
ZipContentsTooLargeError,
} = require('./ArchiveErrors')
const _ = require('underscore')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const ONE_MEG = 1024 * 1024

View file

@ -1,7 +1,7 @@
const fs = require('fs')
const Path = require('path')
const isUtf8 = require('utf-8-validate')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const Settings = require('@overleaf/settings')
const Minimatch = require('minimatch').Minimatch

View file

@ -10,7 +10,7 @@ const UserGetter = require('../User/UserGetter')
const UserUpdater = require('../User/UserUpdater')
const logger = require('@overleaf/logger')
const { User } = require('../../models/User')
const { promiseMapWithLimit } = require('../../util/promises')
const { promiseMapWithLimit } = require('@overleaf/promise-utils')
async function _addAuditLogEntry(operation, userId, auditLog, extraInfo) {
await UserAuditLogHandler.promises.addEntry(

View file

@ -8,7 +8,7 @@ const logger = require('@overleaf/logger')
const OError = require('@overleaf/o-error')
const settings = require('@overleaf/settings')
const { User } = require(`${APP_ROOT}/models/User`)
const { promisifyAll } = require(`${APP_ROOT}/util/promises`)
const { promisifyAll } = require('@overleaf/promise-utils')
const oauthProviders = settings.oauthProviders || {}

View file

@ -17,7 +17,7 @@ const OError = require('@overleaf/o-error')
const EmailHandler = require('../Email/EmailHandler')
const UrlHelper = require('../Helpers/UrlHelper')
const { promisify } = require('util')
const { expressify } = require('../../util/promises')
const { expressify } = require('@overleaf/promise-utils')
const {
acceptsJson,
} = require('../../infrastructure/RequestContentTypeDetection')

View file

@ -10,7 +10,7 @@ const UserEmailsConfirmationHandler = require('./UserEmailsConfirmationHandler')
const { endorseAffiliation } = require('../Institutions/InstitutionsAPI')
const Errors = require('../Errors/Errors')
const HttpErrorHandler = require('../Errors/HttpErrorHandler')
const { expressify } = require('../../util/promises')
const { expressify } = require('@overleaf/promise-utils')
const AsyncFormHelper = require('../Helpers/AsyncFormHelper')
const AnalyticsManager = require('../Analytics/AnalyticsManager')
const UserPrimaryEmailCheckHandler = require('../User/UserPrimaryEmailCheckHandler')

View file

@ -4,7 +4,7 @@ const metrics = require('@overleaf/metrics')
const logger = require('@overleaf/logger')
const moment = require('moment')
const settings = require('@overleaf/settings')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const {
promises: InstitutionsAPIPromises,
} = require('../Institutions/InstitutionsAPI')

View file

@ -1,5 +1,5 @@
const UserGetter = require('./UserGetter')
const { callbackify } = require('../../util/promises')
const { callbackify } = require('@overleaf/promise-utils')
async function getPersonalInfo(userId) {
return UserGetter.promises.getUser(userId, {

View file

@ -8,7 +8,7 @@ const SessionManager = require('../Authentication/SessionManager')
const NewsletterManager = require('../Newsletter/NewsletterManager')
const SubscriptionLocator = require('../Subscription/SubscriptionLocator')
const _ = require('lodash')
const { expressify } = require('../../util/promises')
const { expressify } = require('@overleaf/promise-utils')
const Features = require('../../infrastructure/Features')
const SplitTestHandler = require('../SplitTests/SplitTestHandler')

View file

@ -13,7 +13,7 @@
*/
const { ObjectId } = require('mongodb')
const async = require('async')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const Errors = require('../Errors/Errors')
const EntityModels = {
Institution: require('../../models/Institution').Institution,

View file

@ -1,4 +1,4 @@
const { expressify } = require('../../util/promises')
const { expressify } = require('@overleaf/promise-utils')
const async = require('async')
const UserMembershipAuthorization = require('./UserMembershipAuthorization')
const AuthenticationController = require('../Authentication/AuthenticationController')

View file

@ -10,7 +10,7 @@
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
const async = require('async')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
const EntityModels = {
Institution: require('../../models/Institution').Institution,
Subscription: require('../../models/Subscription').Subscription,

View file

@ -10,7 +10,7 @@
const request = require('request')
const settings = require('@overleaf/settings')
const Errors = require('../Errors/Errors')
const { promisifyAll } = require('../../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
// TODO: check what happens when these settings aren't defined
const DEFAULT_V1_PARAMS = {

View file

@ -20,7 +20,7 @@ const {
const {
addOptionalCleanupHandlerAfterDrainingConnections,
} = require('./GracefulShutdown')
const { expressify } = require('../util/promises')
const { expressify } = require('@overleaf/promise-utils')
const IEEE_BRAND_ID = Settings.ieeeBrandId

View file

@ -19,7 +19,7 @@ const Settings = require('@overleaf/settings')
const request = require('request')
const { Transform, pipeline } = require('stream')
const { FileTooLargeError } = require('../Features/Errors/Errors')
const { promisifyAll } = require('../util/promises')
const { promisifyAll } = require('@overleaf/promise-utils')
class SizeLimitedStream extends Transform {
constructor(options) {

View file

@ -3,7 +3,7 @@ const settings = require('@overleaf/settings')
const _ = require('underscore')
const logger = require('@overleaf/logger')
const { URL } = require('url')
const { promisify, promisifyMultiResult } = require('../util/promises')
const { promisify, promisifyMultiResult } = require('@overleaf/promise-utils')
const DEFAULT_CURRENCY_CODE = 'USD'

View file

@ -1,168 +1,8 @@
const { promisify, callbackify } = require('util')
const pLimit = require('p-limit')
// This stub module is temporary. Keep it around for a while to allow old
// branches to be merged.
module.exports = {
promisify,
promisifyAll,
promisifyClass,
promisifyMultiResult,
callbackify,
callbackifyMultiResult,
expressify,
promiseMapWithLimit,
}
module.exports = require('@overleaf/promise-utils')
/**
* Promisify all functions in a module.
*
* This is meant to be used only when all functions in the module are async
* callback-style functions.
*
* It's very much tailored to our current module structure. In particular, it
* binds `this` to the module when calling the function in order not to break
* modules that call sibling functions using `this`.
*
* This will not magically fix all modules. Special cases should be promisified
* manually.
*
* The second argument is a bag of options:
*
* - without: an array of function names that shouldn't be promisified
*
* - multiResult: an object whose keys are function names and values are lists
* of parameter names. This is meant for functions that invoke their callbacks
* with more than one result in separate parameters. The promisifed function
* will return these results as a single object, with each result keyed under
* the corresponding parameter name.
*/
function promisifyAll(module, opts = {}) {
const { without = [], multiResult = {} } = opts
const promises = {}
for (const propName of Object.getOwnPropertyNames(module)) {
if (without.includes(propName)) {
continue
}
const propValue = module[propName]
if (typeof propValue !== 'function') {
continue
}
if (multiResult[propName] != null) {
promises[propName] = promisifyMultiResult(
propValue,
multiResult[propName]
).bind(module)
} else {
promises[propName] = promisify(propValue).bind(module)
}
}
return promises
}
/**
* Promisify all methods in a class.
*
* Options are the same as for promisifyAll
*/
function promisifyClass(cls, opts = {}) {
const promisified = class extends cls {}
const { without = [], multiResult = {} } = opts
for (const propName of Object.getOwnPropertyNames(cls.prototype)) {
if (propName === 'constructor' || without.includes(propName)) {
continue
}
const propValue = cls.prototype[propName]
if (typeof propValue !== 'function') {
continue
}
if (multiResult[propName] != null) {
promisified.prototype[propName] = promisifyMultiResult(
propValue,
multiResult[propName]
)
} else {
promisified.prototype[propName] = promisify(propValue)
}
}
return promisified
}
/**
* Promisify a function that returns multiple results via additional callback
* parameters.
*
* The promisified function returns the results in a single object whose keys
* are the names given in the array `resultNames`.
*
* Example:
*
* function f(callback) {
* return callback(null, 1, 2, 3)
* }
*
* const g = promisifyMultiResult(f, ['a', 'b', 'c'])
*
* const result = await g() // returns {a: 1, b: 2, c: 3}
*/
function promisifyMultiResult(fn, resultNames) {
function promisified(...args) {
return new Promise((resolve, reject) => {
try {
fn.bind(this)(...args, (err, ...results) => {
if (err != null) {
return reject(err)
}
const promiseResult = {}
for (let i = 0; i < resultNames.length; i++) {
promiseResult[resultNames[i]] = results[i]
}
resolve(promiseResult)
})
} catch (err) {
reject(err)
}
})
}
return promisified
}
/**
* Reverse the effect of `promisifyMultiResult`.
*
* This is meant for providing a temporary backward compatible callback
* interface while we migrate to promises.
*/
function callbackifyMultiResult(fn, resultNames) {
function callbackified(...args) {
const [callback] = args.splice(-1)
fn(...args)
.then(result => {
const cbResults = resultNames.map(resultName => result[resultName])
callback(null, ...cbResults)
})
.catch(err => {
callback(err)
})
}
return callbackified
}
/**
* Transform an async function into an Express middleware
*
* Any error will be passed to the error middlewares via `next()`
*/
function expressify(fn) {
return (req, res, next) => {
fn(req, res, next).catch(next)
}
}
/**
* Map values in `array` with the async function `fn`
*
* Limit the number of unresolved promises to `concurrency`.
*/
function promiseMapWithLimit(concurrency, array, fn) {
const limit = pLimit(concurrency)
return Promise.all(array.map(x => limit(() => fn(x))))
}
process.emitWarning(
'The util/promises module is deprecated. Use @overleaf/promise-utils instead.'
)

View file

@ -74,6 +74,7 @@
"@overleaf/metrics": "*",
"@overleaf/o-error": "*",
"@overleaf/object-persistor": "*",
"@overleaf/promise-utils": "*",
"@overleaf/redis-wrapper": "*",
"@overleaf/settings": "*",
"@slack/webhook": "^6.1.0",

View file

@ -1,5 +1,5 @@
const { batchedUpdate } = require('./helpers/batchedUpdate')
const { promiseMapWithLimit, promisify } = require('../app/src/util/promises')
const { promiseMapWithLimit, promisify } = require('@overleaf/promise-utils')
const { db } = require('../app/src/infrastructure/mongodb')
const sleep = promisify(setTimeout)
const _ = require('lodash')

View file

@ -1,5 +1,5 @@
const { batchedUpdate } = require('./helpers/batchedUpdate')
const { promiseMapWithLimit, promisify } = require('../app/src/util/promises')
const { promiseMapWithLimit, promisify } = require('@overleaf/promise-utils')
const { db } = require('../app/src/infrastructure/mongodb')
const sleep = promisify(setTimeout)
const _ = require('lodash')

View file

@ -3,7 +3,7 @@ const WRITE_CONCURRENCY = parseInt(process.env.WRITE_CONCURRENCY, 10) || 10
require('../app/src/models/User')
const { batchedUpdateWithResultHandling } = require('./helpers/batchedUpdate')
const { promiseMapWithLimit } = require('../app/src/util/promises')
const { promiseMapWithLimit } = require('@overleaf/promise-utils')
const { getQueue } = require('../app/src/infrastructure/Queues')
const SubscriptionLocator = require('../app/src/Features/Subscription/SubscriptionLocator')

View file

@ -1,7 +1,7 @@
const WRITE_CONCURRENCY = parseInt(process.env.WRITE_CONCURRENCY, 10) || 10
const { batchedUpdateWithResultHandling } = require('./helpers/batchedUpdate')
const { promiseMapWithLimit } = require('../app/src/util/promises')
const { promiseMapWithLimit } = require('@overleaf/promise-utils')
const SubscriptionLocator = require('../app/src/Features/Subscription/SubscriptionLocator')
const PlansLocator = require('../app/src/Features/Subscription/PlansLocator')
const FeaturesHelper = require('../app/src/Features/Subscription/FeaturesHelper')

View file

@ -1,7 +1,7 @@
const minimist = require('minimist')
const { promisify } = require('util')
const bcrypt = require('bcrypt')
const { promiseMapWithLimit } = require('../app/src/util/promises')
const { promiseMapWithLimit } = require('@overleaf/promise-utils')
const csv = require('csv/sync')
const bcryptCompare = promisify(bcrypt.compare)

View file

@ -1,4 +1,4 @@
const { promisify, promiseMapWithLimit } = require('../app/src/util/promises')
const { promisify, promiseMapWithLimit } = require('@overleaf/promise-utils')
const rClient = require('../app/src/Features/User/UserSessionsRedis').client()
const args = require('minimist')(process.argv.slice(2))

View file

@ -4,7 +4,7 @@ const WRITE_CONCURRENCY = parseInt(process.env.WRITE_CONCURRENCY, 10) || 10
const { db } = require('../app/src/infrastructure/mongodb')
const { batchedUpdate } = require('./helpers/batchedUpdate')
const { promiseMapWithLimit } = require('../app/src/util/promises')
const { promiseMapWithLimit } = require('@overleaf/promise-utils')
// $ node scripts/convert_archived_state.js FIRST,SECOND

View file

@ -14,7 +14,7 @@ process.env.MONGO_SOCKET_TIMEOUT =
parseInt(process.env.MONGO_SOCKET_TIMEOUT, 10) || 600000
const { ObjectId } = require('mongodb')
const { promiseMapWithLimit } = require('../app/src/util/promises')
const { promiseMapWithLimit } = require('@overleaf/promise-utils')
const { batchedUpdate } = require('./helpers/batchedUpdate')
const ChatApiHandler = require('../app/src/Features/Chat/ChatApiHandler')
const { getHardDeletedProjectIds } = require('./delete_orphaned_data_helper')

View file

@ -3,7 +3,7 @@ const {
READ_PREFERENCE_PRIMARY,
READ_PREFERENCE_SECONDARY,
} = require('../app/src/infrastructure/mongodb')
const { promiseMapWithLimit } = require('../app/src/util/promises')
const { promiseMapWithLimit } = require('@overleaf/promise-utils')
async function getDeletedProject(projectId, readPreference) {
return await db.deletedProjects.findOne(

View file

@ -6,7 +6,7 @@ const { waitForDb } = require('../app/src/infrastructure/mongodb')
const ChatApiHandler = require('../app/src/Features/Chat/ChatApiHandler')
const DocstoreManager = require('../app/src/Features/Docstore/DocstoreManager')
const DocumentUpdaterHandler = require('../app/src/Features/DocumentUpdater/DocumentUpdaterHandler')
const { promiseMapWithLimit } = require('../app/src/util/promises')
const { promiseMapWithLimit } = require('@overleaf/promise-utils')
/**
* Remove doc comment ranges that are "orphaned" as they do have matching chat

View file

@ -7,7 +7,7 @@ const {
READ_PREFERENCE_PRIMARY,
READ_PREFERENCE_SECONDARY,
} = require('../app/src/infrastructure/mongodb')
const { promiseMapWithLimit } = require('../app/src/util/promises')
const { promiseMapWithLimit } = require('@overleaf/promise-utils')
const { getHardDeletedProjectIds } = require('./delete_orphaned_data_helper')
const sleep = promisify(setTimeout)

View file

@ -1,7 +1,7 @@
const Settings = require('@overleaf/settings')
const { fetchJson } = require('@overleaf/fetch-utils')
const { waitForDb } = require('../app/src/infrastructure/mongodb')
const { promiseMapWithLimit } = require('../app/src/util/promises')
const { promiseMapWithLimit } = require('@overleaf/promise-utils')
const { getHardDeletedProjectIds } = require('./delete_orphaned_data_helper')
const TpdsUpdateSender = require('../app/src/Features/ThirdPartyDataStore/TpdsUpdateSender')
const { promisify } = require('util')

View file

@ -1,5 +1,5 @@
const { batchedUpdate } = require('./helpers/batchedUpdate')
const { promiseMapWithLimit, promisify } = require('../app/src/util/promises')
const { promiseMapWithLimit, promisify } = require('@overleaf/promise-utils')
const { db, ObjectId, waitForDb } = require('../app/src/infrastructure/mongodb')
const sleep = promisify(setTimeout)
const _ = require('lodash')

View file

@ -8,7 +8,7 @@ const {
db,
READ_PREFERENCE_SECONDARY,
} = require('../app/src/infrastructure/mongodb')
const { promiseMapWithLimit } = require('../app/src/util/promises')
const { promiseMapWithLimit } = require('@overleaf/promise-utils')
const TokenGenerator = require('../app/src/Features/TokenGenerator/TokenGenerator')
const { batchedUpdate } = require('./helpers/batchedUpdate')

View file

@ -2,7 +2,7 @@ const { ObjectId } = require('mongodb')
const Subscription = require('./Subscription')
const MockRecurlyApiClass = require('../mocks/MockRecurlyApi')
const RecurlyWrapper = require('../../../../app/src/Features/Subscription/RecurlyWrapper')
const { promisifyClass } = require('../../../../app/src/util/promises')
const { promisifyClass } = require('@overleaf/promise-utils')
let MockRecurlyApi

View file

@ -64,7 +64,6 @@ function getSandboxedModuleRequires() {
}
const internalModules = [
'../../app/src/util/promises',
'../../app/src/Features/Errors/Errors',
'../../app/src/Features/Helpers/Mongo',
]

View file

@ -1,211 +0,0 @@
const { expect } = require('chai')
const {
promisifyAll,
promisifyClass,
callbackifyMultiResult,
} = require('../../../../app/src/util/promises')
describe('promisifyAll', function () {
describe('basic functionality', function () {
before(function () {
this.module = {
SOME_CONSTANT: 1,
asyncAdd(a, b, callback) {
callback(null, a + b)
},
asyncDouble(x, callback) {
this.asyncAdd(x, x, callback)
},
}
this.promisified = promisifyAll(this.module)
})
it('promisifies functions in the module', async function () {
const sum = await this.promisified.asyncAdd(29, 33)
expect(sum).to.equal(62)
})
it('binds this to the original module', async function () {
const sum = await this.promisified.asyncDouble(38)
expect(sum).to.equal(76)
})
it('does not copy over non-functions', async function () {
expect(this.promisified).not.to.have.property('SOME_CONSTANT')
})
it('does not modify the prototype of the module', async function () {
expect(this.promisified.toString()).to.equal('[object Object]')
})
})
describe('without option', function () {
before(function () {
this.module = {
asyncAdd(a, b, callback) {
callback(null, a + b)
},
syncAdd(a, b) {
return a + b
},
}
this.promisified = promisifyAll(this.module, { without: ['syncAdd'] })
})
it('does not promisify excluded functions', function () {
expect(this.promisified.syncAdd).not.to.exist
})
it('promisifies other functions', async function () {
const sum = await this.promisified.asyncAdd(12, 89)
expect(sum).to.equal(101)
})
})
describe('multiResult option', function () {
before(function () {
this.module = {
asyncAdd(a, b, callback) {
callback(null, a + b)
},
asyncArithmetic(a, b, callback) {
callback(null, a + b, a * b)
},
}
this.promisified = promisifyAll(this.module, {
multiResult: { asyncArithmetic: ['sum', 'product'] },
})
})
it('promisifies multi-result functions', async function () {
const result = await this.promisified.asyncArithmetic(3, 6)
expect(result).to.deep.equal({ sum: 9, product: 18 })
})
it('promisifies other functions normally', async function () {
const sum = await this.promisified.asyncAdd(6, 1)
expect(sum).to.equal(7)
})
})
})
describe('promisifyClass', function () {
describe('basic functionality', function () {
before(function () {
this.Class = class {
constructor(a) {
this.a = a
}
asyncAdd(b, callback) {
callback(null, this.a + b)
}
}
this.Promisified = promisifyClass(this.Class)
})
it('promisifies the class methods', async function () {
const adder = new this.Promisified(1)
const sum = await adder.asyncAdd(2)
expect(sum).to.equal(3)
})
})
describe('without option', function () {
before(function () {
this.Class = class {
constructor(a) {
this.a = a
}
asyncAdd(b, callback) {
callback(null, this.a + b)
}
syncAdd(b) {
return this.a + b
}
}
this.Promisified = promisifyClass(this.Class, { without: ['syncAdd'] })
})
it('does not promisify excluded functions', function () {
const adder = new this.Promisified(10)
const sum = adder.syncAdd(12)
expect(sum).to.equal(22)
})
it('promisifies other functions', async function () {
const adder = new this.Promisified(23)
const sum = await adder.asyncAdd(3)
expect(sum).to.equal(26)
})
})
describe('multiResult option', function () {
before(function () {
this.Class = class {
constructor(a) {
this.a = a
}
asyncAdd(b, callback) {
callback(null, this.a + b)
}
asyncArithmetic(b, callback) {
callback(null, this.a + b, this.a * b)
}
}
this.Promisified = promisifyClass(this.Class, {
multiResult: { asyncArithmetic: ['sum', 'product'] },
})
})
it('promisifies multi-result functions', async function () {
const adder = new this.Promisified(3)
const result = await adder.asyncArithmetic(6)
expect(result).to.deep.equal({ sum: 9, product: 18 })
})
it('promisifies other functions normally', async function () {
const adder = new this.Promisified(6)
const sum = await adder.asyncAdd(1)
expect(sum).to.equal(7)
})
})
})
describe('callbackifyMultiResult', function () {
it('callbackifies a multi-result function', function (done) {
async function asyncArithmetic(a, b) {
return { sum: a + b, product: a * b }
}
const callbackified = callbackifyMultiResult(asyncArithmetic, [
'sum',
'product',
])
callbackified(3, 11, (err, sum, product) => {
if (err != null) {
return done(err)
}
expect(sum).to.equal(14)
expect(product).to.equal(33)
done()
})
})
it('propagates errors', function (done) {
async function asyncBomb() {
throw new Error('BOOM!')
}
const callbackified = callbackifyMultiResult(asyncBomb, [
'explosives',
'dynamite',
])
callbackified(err => {
expect(err).to.exist
done()
})
})
})