From 680ebae30b881a3ae854208579aef652b01991bb Mon Sep 17 00:00:00 2001 From: Eric Mc Sween <5454374+emcsween@users.noreply.github.com> Date: Thu, 19 Oct 2023 07:38:17 -0400 Subject: [PATCH] Merge pull request #15172 from overleaf/em-promise-utils Move util/promises from web into a shared library GitOrigin-RevId: fe1980dc57b9dc8ce86fa1fad6a8a817e9505b3d --- package-lock.json | 148 ++++++++++-- .../Features/Analytics/AnalyticsManager.js | 2 +- .../src/Features/Analytics/AnalyticsRouter.js | 2 +- .../Authorization/AuthorizationMiddleware.js | 2 +- .../src/Features/Captcha/CaptchaMiddleware.js | 2 +- .../Collaborators/CollaboratorsController.js | 2 +- .../CollaboratorsInviteController.js | 2 +- .../src/Features/Compile/ClsiCookieManager.js | 2 +- .../src/Features/Compile/ClsiFormatChecker.js | 2 +- .../app/src/Features/Compile/ClsiManager.js | 2 +- .../src/Features/Compile/CompileController.js | 2 +- .../Features/Contacts/ContactController.js | 2 +- .../src/Features/Cooldown/CooldownManager.js | 2 +- .../src/Features/Docstore/DocstoreManager.js | 2 +- .../Features/Documents/DocumentController.js | 2 +- .../src/Features/Editor/EditorController.js | 2 +- .../Features/Editor/EditorHttpController.js | 2 +- .../Features/FileStore/FileStoreHandler.js | 2 +- .../Features/Institutions/InstitutionsAPI.js | 2 +- .../Institutions/InstitutionsFeatures.js | 2 +- .../LinkedFiles/LinkedFilesHandler.js | 2 +- .../app/src/Features/LinkedFiles/UrlAgent.js | 2 +- .../Notifications/NotificationsBuilder.js | 2 +- .../Notifications/NotificationsHandler.js | 2 +- .../PasswordReset/PasswordResetController.js | 2 +- .../Project/ProjectAuditLogHandler.js | 2 +- .../src/Features/Project/ProjectDeleter.js | 2 +- .../src/Features/Project/ProjectDuplicator.js | 2 +- .../Features/Project/ProjectEntityHandler.js | 2 +- .../ProjectEntityMongoUpdateHandler.js | 2 +- .../Project/ProjectEntityUpdateHandler.js | 2 +- .../app/src/Features/Project/ProjectGetter.js | 2 +- .../Features/Project/ProjectHistoryHandler.js | 2 +- .../Features/Project/ProjectListController.js | 2 +- .../src/Features/Project/ProjectLocator.js | 2 +- .../Features/Project/ProjectOptionsHandler.js | 2 +- .../Features/Project/ProjectRootDocManager.js | 2 +- .../Features/Project/ProjectUpdateHandler.js | 2 +- .../Features/Publishers/PublishersGetter.js | 2 +- .../src/Features/Referal/ReferalAllocator.js | 2 +- .../src/Features/Security/LoginRateLimiter.js | 2 +- .../Features/Security/OneTimeTokenHandler.js | 2 +- .../src/Features/Spelling/SpellingHandler.js | 2 +- .../Features/Subscription/FeaturesUpdater.js | 2 +- .../Subscription/LimitationsManager.js | 2 +- .../Subscription/SubscriptionController.js | 2 +- .../Subscription/SubscriptionHandler.js | 2 +- .../Subscription/SubscriptionUpdater.js | 2 +- .../SubscriptionViewModelBuilder.js | 2 +- .../Subscription/TeamInvitesController.js | 2 +- .../Subscription/TeamInvitesHandler.js | 5 +- .../Subscription/UserFeaturesUpdater.js | 2 +- .../Subscription/V1SubscriptionManager.js | 2 +- .../app/src/Features/Survey/SurveyHandler.js | 2 +- .../app/src/Features/Tags/TagsController.js | 2 +- .../web/app/src/Features/Tags/TagsHandler.js | 2 +- .../ThirdPartyDataStore/TpdsController.js | 2 +- .../TokenAccess/TokenAccessController.js | 2 +- .../TokenAccess/TokenAccessHandler.js | 2 +- .../Features/Tutorial/TutorialController.js | 2 +- .../src/Features/Uploads/ArchiveManager.js | 2 +- .../src/Features/Uploads/FileTypeManager.js | 2 +- .../src/Features/User/SAMLIdentityManager.js | 2 +- .../User/ThirdPartyIdentityManager.js | 2 +- .../app/src/Features/User/UserController.js | 2 +- .../src/Features/User/UserEmailsController.js | 2 +- .../web/app/src/Features/User/UserGetter.js | 2 +- .../app/src/Features/User/UserInfoManager.js | 2 +- .../src/Features/User/UserPagesController.js | 2 +- .../UserMembership/UserMembershipHandler.js | 2 +- .../UserMembershipMiddleware.js | 2 +- .../UserMembership/UserMembershipsHandler.js | 2 +- services/web/app/src/Features/V1/V1Api.js | 2 +- .../app/src/infrastructure/ExpressLocals.js | 2 +- .../web/app/src/infrastructure/FileWriter.js | 2 +- .../web/app/src/infrastructure/GeoIpLookup.js | 2 +- services/web/app/src/util/promises.js | 172 +------------- services/web/package.json | 1 + .../web/scripts/back_fill_deleted_files.js | 2 +- .../back_fill_doc_name_for_deleted_docs.js | 2 +- .../backfill_mixpanel_user_properties.js | 2 +- .../web/scripts/backfill_user_properties.js | 2 +- services/web/scripts/bench_bcrypt.js | 2 +- services/web/scripts/clear_sessions_2fa.js | 2 +- .../web/scripts/convert_archived_state.js | 2 +- .../scripts/delete_orphaned_chat_threads.js | 2 +- .../scripts/delete_orphaned_data_helper.js | 2 +- .../delete_orphaned_doc_comment_ranges.js | 2 +- .../delete_orphaned_docs_online_check.js | 2 +- .../delete_orphaned_project_archives.js | 2 +- services/web/scripts/migrate_audit_logs.js | 2 +- .../regenerate_duplicate_referral_ids.js | 2 +- .../src/helpers/RecurlySubscription.js | 2 +- services/web/test/unit/bootstrap.js | 1 - .../web/test/unit/src/util/promisesTests.js | 211 ------------------ 95 files changed, 229 insertions(+), 487 deletions(-) delete mode 100644 services/web/test/unit/src/util/promisesTests.js diff --git a/package-lock.json b/package-lock.json index 95f68c028d..022f8d0f2f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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" diff --git a/services/web/app/src/Features/Analytics/AnalyticsManager.js b/services/web/app/src/Features/Analytics/AnalyticsManager.js index d5c9cbfbc0..82b21de6f9 100644 --- a/services/web/app/src/Features/Analytics/AnalyticsManager.js +++ b/services/web/app/src/Features/Analytics/AnalyticsManager.js @@ -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') diff --git a/services/web/app/src/Features/Analytics/AnalyticsRouter.js b/services/web/app/src/Features/Analytics/AnalyticsRouter.js index 6f37839230..15b503dee2 100644 --- a/services/web/app/src/Features/Analytics/AnalyticsRouter.js +++ b/services/web/app/src/Features/Analytics/AnalyticsRouter.js @@ -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', { diff --git a/services/web/app/src/Features/Authorization/AuthorizationMiddleware.js b/services/web/app/src/Features/Authorization/AuthorizationMiddleware.js index d4f639224b..e45dc23556 100644 --- a/services/web/app/src/Features/Authorization/AuthorizationMiddleware.js +++ b/services/web/app/src/Features/Authorization/AuthorizationMiddleware.js @@ -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') diff --git a/services/web/app/src/Features/Captcha/CaptchaMiddleware.js b/services/web/app/src/Features/Captcha/CaptchaMiddleware.js index abbe6cabb9..39880d8dfd 100644 --- a/services/web/app/src/Features/Captcha/CaptchaMiddleware.js +++ b/services/web/app/src/Features/Captcha/CaptchaMiddleware.js @@ -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({ diff --git a/services/web/app/src/Features/Collaborators/CollaboratorsController.js b/services/web/app/src/Features/Collaborators/CollaboratorsController.js index 4707d4413a..c3af1ba18b 100644 --- a/services/web/app/src/Features/Collaborators/CollaboratorsController.js +++ b/services/web/app/src/Features/Collaborators/CollaboratorsController.js @@ -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') diff --git a/services/web/app/src/Features/Collaborators/CollaboratorsInviteController.js b/services/web/app/src/Features/Collaborators/CollaboratorsInviteController.js index 5fdfeaa9fe..f1387ff053 100644 --- a/services/web/app/src/Features/Collaborators/CollaboratorsInviteController.js +++ b/services/web/app/src/Features/Collaborators/CollaboratorsInviteController.js @@ -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') diff --git a/services/web/app/src/Features/Compile/ClsiCookieManager.js b/services/web/app/src/Features/Compile/ClsiCookieManager.js index 6f45a7fa5f..fc542fefaf 100644 --- a/services/web/app/src/Features/Compile/ClsiCookieManager.js +++ b/services/web/app/src/Features/Compile/ClsiCookieManager.js @@ -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 ?? '') !== '' diff --git a/services/web/app/src/Features/Compile/ClsiFormatChecker.js b/services/web/app/src/Features/Compile/ClsiFormatChecker.js index 235436e4f6..1828f2f417 100644 --- a/services/web/app/src/Features/Compile/ClsiFormatChecker.js +++ b/services/web/app/src/Features/Compile/ClsiFormatChecker.js @@ -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) { diff --git a/services/web/app/src/Features/Compile/ClsiManager.js b/services/web/app/src/Features/Compile/ClsiManager.js index 166daeba8b..92f05e9c53 100644 --- a/services/web/app/src/Features/Compile/ClsiManager.js +++ b/services/web/app/src/Features/Compile/ClsiManager.js @@ -1,5 +1,5 @@ const { callbackify } = require('util') -const { callbackifyMultiResult } = require('../../util/promises') +const { callbackifyMultiResult } = require('@overleaf/promise-utils') const { fetchString, fetchStringWithResponse, diff --git a/services/web/app/src/Features/Compile/CompileController.js b/services/web/app/src/Features/Compile/CompileController.js index 98333bfac9..4f1f59d163 100644 --- a/services/web/app/src/Features/Compile/CompileController.js +++ b/services/web/app/src/Features/Compile/CompileController.js @@ -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, diff --git a/services/web/app/src/Features/Contacts/ContactController.js b/services/web/app/src/Features/Contacts/ContactController.js index 9c600593ed..b7dbf58e25 100644 --- a/services/web/app/src/Features/Contacts/ContactController.js +++ b/services/web/app/src/Features/Contacts/ContactController.js @@ -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 { diff --git a/services/web/app/src/Features/Cooldown/CooldownManager.js b/services/web/app/src/Features/Cooldown/CooldownManager.js index 873e7723cb..67bdc98838 100644 --- a/services/web/app/src/Features/Cooldown/CooldownManager.js +++ b/services/web/app/src/Features/Cooldown/CooldownManager.js @@ -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 diff --git a/services/web/app/src/Features/Docstore/DocstoreManager.js b/services/web/app/src/Features/Docstore/DocstoreManager.js index 6490530971..6fb47d358c 100644 --- a/services/web/app/src/Features/Docstore/DocstoreManager.js +++ b/services/web/app/src/Features/Docstore/DocstoreManager.js @@ -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') diff --git a/services/web/app/src/Features/Documents/DocumentController.js b/services/web/app/src/Features/Documents/DocumentController.js index b2001135f4..a54475b1b3 100644 --- a/services/web/app/src/Features/Documents/DocumentController.js +++ b/services/web/app/src/Features/Documents/DocumentController.js @@ -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 diff --git a/services/web/app/src/Features/Editor/EditorController.js b/services/web/app/src/Features/Editor/EditorController.js index 4224bbed72..3196ddfc91 100644 --- a/services/web/app/src/Features/Editor/EditorController.js +++ b/services/web/app/src/Features/Editor/EditorController.js @@ -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) { diff --git a/services/web/app/src/Features/Editor/EditorHttpController.js b/services/web/app/src/Features/Editor/EditorHttpController.js index 1ac47d08fe..3958e86e21 100644 --- a/services/web/app/src/Features/Editor/EditorHttpController.js +++ b/services/web/app/src/Features/Editor/EditorHttpController.js @@ -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, diff --git a/services/web/app/src/Features/FileStore/FileStoreHandler.js b/services/web/app/src/Features/FileStore/FileStoreHandler.js index 4614aa93ca..0ea3aa1dc8 100644 --- a/services/web/app/src/Features/FileStore/FileStoreHandler.js +++ b/services/web/app/src/Features/FileStore/FileStoreHandler.js @@ -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 diff --git a/services/web/app/src/Features/Institutions/InstitutionsAPI.js b/services/web/app/src/Features/Institutions/InstitutionsAPI.js index ca8dd4450c..3e379ad410 100644 --- a/services/web/app/src/Features/Institutions/InstitutionsAPI.js +++ b/services/web/app/src/Features/Institutions/InstitutionsAPI.js @@ -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, diff --git a/services/web/app/src/Features/Institutions/InstitutionsFeatures.js b/services/web/app/src/Features/Institutions/InstitutionsFeatures.js index eaa48dcda9..ab5125114e 100644 --- a/services/web/app/src/Features/Institutions/InstitutionsFeatures.js +++ b/services/web/app/src/Features/Institutions/InstitutionsFeatures.js @@ -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) { diff --git a/services/web/app/src/Features/LinkedFiles/LinkedFilesHandler.js b/services/web/app/src/Features/LinkedFiles/LinkedFilesHandler.js index cd41de59af..430557b83e 100644 --- a/services/web/app/src/Features/LinkedFiles/LinkedFilesHandler.js +++ b/services/web/app/src/Features/LinkedFiles/LinkedFilesHandler.js @@ -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) { diff --git a/services/web/app/src/Features/LinkedFiles/UrlAgent.js b/services/web/app/src/Features/LinkedFiles/UrlAgent.js index 1ba52b40fd..3af360e2e7 100644 --- a/services/web/app/src/Features/LinkedFiles/UrlAgent.js +++ b/services/web/app/src/Features/LinkedFiles/UrlAgent.js @@ -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( diff --git a/services/web/app/src/Features/Notifications/NotificationsBuilder.js b/services/web/app/src/Features/Notifications/NotificationsBuilder.js index 3d636a8a65..4e77c0aa65 100644 --- a/services/web/app/src/Features/Notifications/NotificationsBuilder.js +++ b/services/web/app/src/Features/Notifications/NotificationsBuilder.js @@ -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') diff --git a/services/web/app/src/Features/Notifications/NotificationsHandler.js b/services/web/app/src/Features/Notifications/NotificationsHandler.js index b704652e6a..4958ad89c6 100644 --- a/services/web/app/src/Features/Notifications/NotificationsHandler.js +++ b/services/web/app/src/Features/Notifications/NotificationsHandler.js @@ -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 diff --git a/services/web/app/src/Features/PasswordReset/PasswordResetController.js b/services/web/app/src/Features/PasswordReset/PasswordResetController.js index 805fd3600a..5bdd23b94d 100644 --- a/services/web/app/src/Features/PasswordReset/PasswordResetController.js +++ b/services/web/app/src/Features/PasswordReset/PasswordResetController.js @@ -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 diff --git a/services/web/app/src/Features/Project/ProjectAuditLogHandler.js b/services/web/app/src/Features/Project/ProjectAuditLogHandler.js index 42eabfa7fe..1c31e1bb66 100644 --- a/services/web/app/src/Features/Project/ProjectAuditLogHandler.js +++ b/services/web/app/src/Features/Project/ProjectAuditLogHandler.js @@ -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: { diff --git a/services/web/app/src/Features/Project/ProjectDeleter.js b/services/web/app/src/Features/Project/ProjectDeleter.js index 9a01faf0d5..35fcf2e25a 100644 --- a/services/web/app/src/Features/Project/ProjectDeleter.js +++ b/services/web/app/src/Features/Project/ProjectDeleter.js @@ -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 diff --git a/services/web/app/src/Features/Project/ProjectDuplicator.js b/services/web/app/src/Features/Project/ProjectDuplicator.js index deefa7e380..cfbb856894 100644 --- a/services/web/app/src/Features/Project/ProjectDuplicator.js +++ b/services/web/app/src/Features/Project/ProjectDuplicator.js @@ -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') diff --git a/services/web/app/src/Features/Project/ProjectEntityHandler.js b/services/web/app/src/Features/Project/ProjectEntityHandler.js index 3c5940df10..bc87e8dc4c 100644 --- a/services/web/app/src/Features/Project/ProjectEntityHandler.js +++ b/services/web/app/src/Features/Project/ProjectEntityHandler.js @@ -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') diff --git a/services/web/app/src/Features/Project/ProjectEntityMongoUpdateHandler.js b/services/web/app/src/Features/Project/ProjectEntityMongoUpdateHandler.js index 249892841b..a33a125794 100644 --- a/services/web/app/src/Features/Project/ProjectEntityMongoUpdateHandler.js +++ b/services/web/app/src/Features/Project/ProjectEntityMongoUpdateHandler.js @@ -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') diff --git a/services/web/app/src/Features/Project/ProjectEntityUpdateHandler.js b/services/web/app/src/Features/Project/ProjectEntityUpdateHandler.js index 1e7f7fd437..ab63f6a0d6 100644 --- a/services/web/app/src/Features/Project/ProjectEntityUpdateHandler.js +++ b/services/web/app/src/Features/Project/ProjectEntityUpdateHandler.js @@ -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' diff --git a/services/web/app/src/Features/Project/ProjectGetter.js b/services/web/app/src/Features/Project/ProjectGetter.js index d4e667f56c..9693bc429d 100644 --- a/services/web/app/src/Features/Project/ProjectGetter.js +++ b/services/web/app/src/Features/Project/ProjectGetter.js @@ -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') diff --git a/services/web/app/src/Features/Project/ProjectHistoryHandler.js b/services/web/app/src/Features/Project/ProjectHistoryHandler.js index 572b06f378..2b5fd680cc 100644 --- a/services/web/app/src/Features/Project/ProjectHistoryHandler.js +++ b/services/web/app/src/Features/Project/ProjectHistoryHandler.js @@ -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) { diff --git a/services/web/app/src/Features/Project/ProjectListController.js b/services/web/app/src/Features/Project/ProjectListController.js index 89f334897c..fb8d7ef819 100644 --- a/services/web/app/src/Features/Project/ProjectListController.js +++ b/services/web/app/src/Features/Project/ProjectListController.js @@ -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') diff --git a/services/web/app/src/Features/Project/ProjectLocator.js b/services/web/app/src/Features/Project/ProjectLocator.js index aad676e15a..d25a4288ba 100644 --- a/services/web/app/src/Features/Project/ProjectLocator.js +++ b/services/web/app/src/Features/Project/ProjectLocator.js @@ -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) { diff --git a/services/web/app/src/Features/Project/ProjectOptionsHandler.js b/services/web/app/src/Features/Project/ProjectOptionsHandler.js index aac0dfa383..1ec1fa01b6 100644 --- a/services/web/app/src/Features/Project/ProjectOptionsHandler.js +++ b/services/web/app/src/Features/Project/ProjectOptionsHandler.js @@ -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'] diff --git a/services/web/app/src/Features/Project/ProjectRootDocManager.js b/services/web/app/src/Features/Project/ProjectRootDocManager.js index c1779fee58..2b2bb413d7 100644 --- a/services/web/app/src/Features/Project/ProjectRootDocManager.js +++ b/services/web/app/src/Features/Project/ProjectRootDocManager.js @@ -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) { diff --git a/services/web/app/src/Features/Project/ProjectUpdateHandler.js b/services/web/app/src/Features/Project/ProjectUpdateHandler.js index 98495a575f..6ada85c683 100644 --- a/services/web/app/src/Features/Project/ProjectUpdateHandler.js +++ b/services/web/app/src/Features/Project/ProjectUpdateHandler.js @@ -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) { diff --git a/services/web/app/src/Features/Publishers/PublishersGetter.js b/services/web/app/src/Features/Publishers/PublishersGetter.js index 769c8ed144..9167a70663 100644 --- a/services/web/app/src/Features/Publishers/PublishersGetter.js +++ b/services/web/app/src/Features/Publishers/PublishersGetter.js @@ -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') diff --git a/services/web/app/src/Features/Referal/ReferalAllocator.js b/services/web/app/src/Features/Referal/ReferalAllocator.js index 3fca5d2866..2346839b07 100644 --- a/services/web/app/src/Features/Referal/ReferalAllocator.js +++ b/services/web/app/src/Features/Referal/ReferalAllocator.js @@ -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, diff --git a/services/web/app/src/Features/Security/LoginRateLimiter.js b/services/web/app/src/Features/Security/LoginRateLimiter.js index c9bb30fba2..bdeba035af 100644 --- a/services/web/app/src/Features/Security/LoginRateLimiter.js +++ b/services/web/app/src/Features/Security/LoginRateLimiter.js @@ -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, diff --git a/services/web/app/src/Features/Security/OneTimeTokenHandler.js b/services/web/app/src/Features/Security/OneTimeTokenHandler.js index cf57eee0a5..69e5dd8861 100644 --- a/services/web/app/src/Features/Security/OneTimeTokenHandler.js +++ b/services/web/app/src/Features/Security/OneTimeTokenHandler.js @@ -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 diff --git a/services/web/app/src/Features/Spelling/SpellingHandler.js b/services/web/app/src/Features/Spelling/SpellingHandler.js index c913f970a0..8d6c42b540 100644 --- a/services/web/app/src/Features/Spelling/SpellingHandler.js +++ b/services/web/app/src/Features/Spelling/SpellingHandler.js @@ -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 = { diff --git a/services/web/app/src/Features/Subscription/FeaturesUpdater.js b/services/web/app/src/Features/Subscription/FeaturesUpdater.js index 160fdf38db..fd1fe6d1f3 100644 --- a/services/web/app/src/Features/Subscription/FeaturesUpdater.js +++ b/services/web/app/src/Features/Subscription/FeaturesUpdater.js @@ -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') diff --git a/services/web/app/src/Features/Subscription/LimitationsManager.js b/services/web/app/src/Features/Subscription/LimitationsManager.js index 91d4fa409d..97e47986c3 100644 --- a/services/web/app/src/Features/Subscription/LimitationsManager.js +++ b/services/web/app/src/Features/Subscription/LimitationsManager.js @@ -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) { diff --git a/services/web/app/src/Features/Subscription/SubscriptionController.js b/services/web/app/src/Features/Subscription/SubscriptionController.js index d23728b8df..6572964185 100644 --- a/services/web/app/src/Features/Subscription/SubscriptionController.js +++ b/services/web/app/src/Features/Subscription/SubscriptionController.js @@ -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') diff --git a/services/web/app/src/Features/Subscription/SubscriptionHandler.js b/services/web/app/src/Features/Subscription/SubscriptionHandler.js index 9c598accb1..674441f25b 100644 --- a/services/web/app/src/Features/Subscription/SubscriptionHandler.js +++ b/services/web/app/src/Features/Subscription/SubscriptionHandler.js @@ -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( diff --git a/services/web/app/src/Features/Subscription/SubscriptionUpdater.js b/services/web/app/src/Features/Subscription/SubscriptionUpdater.js index b6c76c9461..639f2bbd14 100644 --- a/services/web/app/src/Features/Subscription/SubscriptionUpdater.js +++ b/services/web/app/src/Features/Subscription/SubscriptionUpdater.js @@ -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') diff --git a/services/web/app/src/Features/Subscription/SubscriptionViewModelBuilder.js b/services/web/app/src/Features/Subscription/SubscriptionViewModelBuilder.js index d02e71cc49..f827b1a849 100644 --- a/services/web/app/src/Features/Subscription/SubscriptionViewModelBuilder.js +++ b/services/web/app/src/Features/Subscription/SubscriptionViewModelBuilder.js @@ -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, diff --git a/services/web/app/src/Features/Subscription/TeamInvitesController.js b/services/web/app/src/Features/Subscription/TeamInvitesController.js index 9de69042ac..bda8a8d1c9 100644 --- a/services/web/app/src/Features/Subscription/TeamInvitesController.js +++ b/services/web/app/src/Features/Subscription/TeamInvitesController.js @@ -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') diff --git a/services/web/app/src/Features/Subscription/TeamInvitesHandler.js b/services/web/app/src/Features/Subscription/TeamInvitesHandler.js index d5bb116bba..078919db5e 100644 --- a/services/web/app/src/Features/Subscription/TeamInvitesHandler.js +++ b/services/web/app/src/Features/Subscription/TeamInvitesHandler.js @@ -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) { diff --git a/services/web/app/src/Features/Subscription/UserFeaturesUpdater.js b/services/web/app/src/Features/Subscription/UserFeaturesUpdater.js index 6f1c594f8b..e3fb74970a 100644 --- a/services/web/app/src/Features/Subscription/UserFeaturesUpdater.js +++ b/services/web/app/src/Features/Subscription/UserFeaturesUpdater.js @@ -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) { diff --git a/services/web/app/src/Features/Subscription/V1SubscriptionManager.js b/services/web/app/src/Features/Subscription/V1SubscriptionManager.js index edaf2aa546..45731cce6c 100644 --- a/services/web/app/src/Features/Subscription/V1SubscriptionManager.js +++ b/services/web/app/src/Features/Subscription/V1SubscriptionManager.js @@ -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) { diff --git a/services/web/app/src/Features/Survey/SurveyHandler.js b/services/web/app/src/Features/Survey/SurveyHandler.js index 705f6efd4d..1e03e71e3b 100644 --- a/services/web/app/src/Features/Survey/SurveyHandler.js +++ b/services/web/app/src/Features/Survey/SurveyHandler.js @@ -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 diff --git a/services/web/app/src/Features/Tags/TagsController.js b/services/web/app/src/Features/Tags/TagsController.js index 6db9290a77..019cc74da9 100644 --- a/services/web/app/src/Features/Tags/TagsController.js +++ b/services/web/app/src/Features/Tags/TagsController.js @@ -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) { diff --git a/services/web/app/src/Features/Tags/TagsHandler.js b/services/web/app/src/Features/Tags/TagsHandler.js index aacdbe8995..fb9248e369 100644 --- a/services/web/app/src/Features/Tags/TagsHandler.js +++ b/services/web/app/src/Features/Tags/TagsHandler.js @@ -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 diff --git a/services/web/app/src/Features/ThirdPartyDataStore/TpdsController.js b/services/web/app/src/Features/ThirdPartyDataStore/TpdsController.js index 82342176f8..f386672521 100644 --- a/services/web/app/src/Features/ThirdPartyDataStore/TpdsController.js +++ b/services/web/app/src/Features/ThirdPartyDataStore/TpdsController.js @@ -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') diff --git a/services/web/app/src/Features/TokenAccess/TokenAccessController.js b/services/web/app/src/Features/TokenAccess/TokenAccessController.js index 8b8b6409c8..87a4723448 100644 --- a/services/web/app/src/Features/TokenAccess/TokenAccessController.js +++ b/services/web/app/src/Features/TokenAccess/TokenAccessController.js @@ -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 { diff --git a/services/web/app/src/Features/TokenAccess/TokenAccessHandler.js b/services/web/app/src/Features/TokenAccess/TokenAccessHandler.js index f51b5b46d8..6af5ca2045 100644 --- a/services/web/app/src/Features/TokenAccess/TokenAccessHandler.js +++ b/services/web/app/src/Features/TokenAccess/TokenAccessHandler.js @@ -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})' diff --git a/services/web/app/src/Features/Tutorial/TutorialController.js b/services/web/app/src/Features/Tutorial/TutorialController.js index e0eed5ce00..a550898aaf 100644 --- a/services/web/app/src/Features/Tutorial/TutorialController.js +++ b/services/web/app/src/Features/Tutorial/TutorialController.js @@ -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', diff --git a/services/web/app/src/Features/Uploads/ArchiveManager.js b/services/web/app/src/Features/Uploads/ArchiveManager.js index bc9cf0088e..672fdf85bb 100644 --- a/services/web/app/src/Features/Uploads/ArchiveManager.js +++ b/services/web/app/src/Features/Uploads/ArchiveManager.js @@ -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 diff --git a/services/web/app/src/Features/Uploads/FileTypeManager.js b/services/web/app/src/Features/Uploads/FileTypeManager.js index 0df4707281..76506690e1 100644 --- a/services/web/app/src/Features/Uploads/FileTypeManager.js +++ b/services/web/app/src/Features/Uploads/FileTypeManager.js @@ -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 diff --git a/services/web/app/src/Features/User/SAMLIdentityManager.js b/services/web/app/src/Features/User/SAMLIdentityManager.js index 9e89f132e4..94dea9aeb0 100644 --- a/services/web/app/src/Features/User/SAMLIdentityManager.js +++ b/services/web/app/src/Features/User/SAMLIdentityManager.js @@ -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( diff --git a/services/web/app/src/Features/User/ThirdPartyIdentityManager.js b/services/web/app/src/Features/User/ThirdPartyIdentityManager.js index 1a564db4c2..4994ac0d2d 100644 --- a/services/web/app/src/Features/User/ThirdPartyIdentityManager.js +++ b/services/web/app/src/Features/User/ThirdPartyIdentityManager.js @@ -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 || {} diff --git a/services/web/app/src/Features/User/UserController.js b/services/web/app/src/Features/User/UserController.js index bd93da530d..e086fdfbca 100644 --- a/services/web/app/src/Features/User/UserController.js +++ b/services/web/app/src/Features/User/UserController.js @@ -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') diff --git a/services/web/app/src/Features/User/UserEmailsController.js b/services/web/app/src/Features/User/UserEmailsController.js index 9b4d5454e1..64a4a4a869 100644 --- a/services/web/app/src/Features/User/UserEmailsController.js +++ b/services/web/app/src/Features/User/UserEmailsController.js @@ -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') diff --git a/services/web/app/src/Features/User/UserGetter.js b/services/web/app/src/Features/User/UserGetter.js index 805257720a..edade901a7 100644 --- a/services/web/app/src/Features/User/UserGetter.js +++ b/services/web/app/src/Features/User/UserGetter.js @@ -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') diff --git a/services/web/app/src/Features/User/UserInfoManager.js b/services/web/app/src/Features/User/UserInfoManager.js index f5d23d7cd8..7133cf0695 100644 --- a/services/web/app/src/Features/User/UserInfoManager.js +++ b/services/web/app/src/Features/User/UserInfoManager.js @@ -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, { diff --git a/services/web/app/src/Features/User/UserPagesController.js b/services/web/app/src/Features/User/UserPagesController.js index 8e96000d5e..a38c4061d2 100644 --- a/services/web/app/src/Features/User/UserPagesController.js +++ b/services/web/app/src/Features/User/UserPagesController.js @@ -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') diff --git a/services/web/app/src/Features/UserMembership/UserMembershipHandler.js b/services/web/app/src/Features/UserMembership/UserMembershipHandler.js index a9665632d0..1bcd497ba2 100644 --- a/services/web/app/src/Features/UserMembership/UserMembershipHandler.js +++ b/services/web/app/src/Features/UserMembership/UserMembershipHandler.js @@ -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, diff --git a/services/web/app/src/Features/UserMembership/UserMembershipMiddleware.js b/services/web/app/src/Features/UserMembership/UserMembershipMiddleware.js index 920bd9fbac..f2d062a721 100644 --- a/services/web/app/src/Features/UserMembership/UserMembershipMiddleware.js +++ b/services/web/app/src/Features/UserMembership/UserMembershipMiddleware.js @@ -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') diff --git a/services/web/app/src/Features/UserMembership/UserMembershipsHandler.js b/services/web/app/src/Features/UserMembership/UserMembershipsHandler.js index 3b93e694ae..6cd95614ab 100644 --- a/services/web/app/src/Features/UserMembership/UserMembershipsHandler.js +++ b/services/web/app/src/Features/UserMembership/UserMembershipsHandler.js @@ -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, diff --git a/services/web/app/src/Features/V1/V1Api.js b/services/web/app/src/Features/V1/V1Api.js index ff578273d9..ae8b9ec174 100644 --- a/services/web/app/src/Features/V1/V1Api.js +++ b/services/web/app/src/Features/V1/V1Api.js @@ -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 = { diff --git a/services/web/app/src/infrastructure/ExpressLocals.js b/services/web/app/src/infrastructure/ExpressLocals.js index 6f985355b5..ec8e0e4f07 100644 --- a/services/web/app/src/infrastructure/ExpressLocals.js +++ b/services/web/app/src/infrastructure/ExpressLocals.js @@ -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 diff --git a/services/web/app/src/infrastructure/FileWriter.js b/services/web/app/src/infrastructure/FileWriter.js index c560d5a833..5473a10114 100644 --- a/services/web/app/src/infrastructure/FileWriter.js +++ b/services/web/app/src/infrastructure/FileWriter.js @@ -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) { diff --git a/services/web/app/src/infrastructure/GeoIpLookup.js b/services/web/app/src/infrastructure/GeoIpLookup.js index f8471cc349..fb8a8e6b4a 100644 --- a/services/web/app/src/infrastructure/GeoIpLookup.js +++ b/services/web/app/src/infrastructure/GeoIpLookup.js @@ -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' diff --git a/services/web/app/src/util/promises.js b/services/web/app/src/util/promises.js index 7af3b03759..4b7860c3b5 100644 --- a/services/web/app/src/util/promises.js +++ b/services/web/app/src/util/promises.js @@ -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.' +) diff --git a/services/web/package.json b/services/web/package.json index 50dca841f9..1d0719c4a2 100644 --- a/services/web/package.json +++ b/services/web/package.json @@ -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", diff --git a/services/web/scripts/back_fill_deleted_files.js b/services/web/scripts/back_fill_deleted_files.js index 6619a89f0c..8aa5586005 100644 --- a/services/web/scripts/back_fill_deleted_files.js +++ b/services/web/scripts/back_fill_deleted_files.js @@ -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') diff --git a/services/web/scripts/back_fill_doc_name_for_deleted_docs.js b/services/web/scripts/back_fill_doc_name_for_deleted_docs.js index a756e7a339..4946ceb017 100644 --- a/services/web/scripts/back_fill_doc_name_for_deleted_docs.js +++ b/services/web/scripts/back_fill_doc_name_for_deleted_docs.js @@ -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') diff --git a/services/web/scripts/backfill_mixpanel_user_properties.js b/services/web/scripts/backfill_mixpanel_user_properties.js index 8ab9ca22e6..b780d63b56 100644 --- a/services/web/scripts/backfill_mixpanel_user_properties.js +++ b/services/web/scripts/backfill_mixpanel_user_properties.js @@ -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') diff --git a/services/web/scripts/backfill_user_properties.js b/services/web/scripts/backfill_user_properties.js index 887a0cff0f..1bbd85aab9 100644 --- a/services/web/scripts/backfill_user_properties.js +++ b/services/web/scripts/backfill_user_properties.js @@ -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') diff --git a/services/web/scripts/bench_bcrypt.js b/services/web/scripts/bench_bcrypt.js index 9f4b29618d..5b4fe9c802 100644 --- a/services/web/scripts/bench_bcrypt.js +++ b/services/web/scripts/bench_bcrypt.js @@ -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) diff --git a/services/web/scripts/clear_sessions_2fa.js b/services/web/scripts/clear_sessions_2fa.js index 73292eed7a..8b30a6751b 100644 --- a/services/web/scripts/clear_sessions_2fa.js +++ b/services/web/scripts/clear_sessions_2fa.js @@ -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)) diff --git a/services/web/scripts/convert_archived_state.js b/services/web/scripts/convert_archived_state.js index 40cc98b369..0069e7ff88 100644 --- a/services/web/scripts/convert_archived_state.js +++ b/services/web/scripts/convert_archived_state.js @@ -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 diff --git a/services/web/scripts/delete_orphaned_chat_threads.js b/services/web/scripts/delete_orphaned_chat_threads.js index cecfdc7c9b..7a2dce6ebc 100644 --- a/services/web/scripts/delete_orphaned_chat_threads.js +++ b/services/web/scripts/delete_orphaned_chat_threads.js @@ -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') diff --git a/services/web/scripts/delete_orphaned_data_helper.js b/services/web/scripts/delete_orphaned_data_helper.js index 24d9cffebf..7a8edc353e 100644 --- a/services/web/scripts/delete_orphaned_data_helper.js +++ b/services/web/scripts/delete_orphaned_data_helper.js @@ -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( diff --git a/services/web/scripts/delete_orphaned_doc_comment_ranges.js b/services/web/scripts/delete_orphaned_doc_comment_ranges.js index eec4ecc3a7..b53452cd36 100644 --- a/services/web/scripts/delete_orphaned_doc_comment_ranges.js +++ b/services/web/scripts/delete_orphaned_doc_comment_ranges.js @@ -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 diff --git a/services/web/scripts/delete_orphaned_docs_online_check.js b/services/web/scripts/delete_orphaned_docs_online_check.js index 06ebb5ca93..49dd750a89 100644 --- a/services/web/scripts/delete_orphaned_docs_online_check.js +++ b/services/web/scripts/delete_orphaned_docs_online_check.js @@ -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) diff --git a/services/web/scripts/delete_orphaned_project_archives.js b/services/web/scripts/delete_orphaned_project_archives.js index 67be55cf02..24edce4388 100644 --- a/services/web/scripts/delete_orphaned_project_archives.js +++ b/services/web/scripts/delete_orphaned_project_archives.js @@ -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') diff --git a/services/web/scripts/migrate_audit_logs.js b/services/web/scripts/migrate_audit_logs.js index a4b6495828..62ff8b9d3f 100644 --- a/services/web/scripts/migrate_audit_logs.js +++ b/services/web/scripts/migrate_audit_logs.js @@ -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') diff --git a/services/web/scripts/regenerate_duplicate_referral_ids.js b/services/web/scripts/regenerate_duplicate_referral_ids.js index 946ef8b08a..78014ff6ec 100644 --- a/services/web/scripts/regenerate_duplicate_referral_ids.js +++ b/services/web/scripts/regenerate_duplicate_referral_ids.js @@ -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') diff --git a/services/web/test/acceptance/src/helpers/RecurlySubscription.js b/services/web/test/acceptance/src/helpers/RecurlySubscription.js index 8ab1457f7c..346aa66156 100644 --- a/services/web/test/acceptance/src/helpers/RecurlySubscription.js +++ b/services/web/test/acceptance/src/helpers/RecurlySubscription.js @@ -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 diff --git a/services/web/test/unit/bootstrap.js b/services/web/test/unit/bootstrap.js index 5a9a5eabd0..1ca8a5a302 100644 --- a/services/web/test/unit/bootstrap.js +++ b/services/web/test/unit/bootstrap.js @@ -64,7 +64,6 @@ function getSandboxedModuleRequires() { } const internalModules = [ - '../../app/src/util/promises', '../../app/src/Features/Errors/Errors', '../../app/src/Features/Helpers/Mongo', ] diff --git a/services/web/test/unit/src/util/promisesTests.js b/services/web/test/unit/src/util/promisesTests.js deleted file mode 100644 index 64ffa4cbb1..0000000000 --- a/services/web/test/unit/src/util/promisesTests.js +++ /dev/null @@ -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() - }) - }) -})