From e9dd0160798da0bf43f819de266139f81dff9d72 Mon Sep 17 00:00:00 2001 From: Princi Vershwal Date: Tue, 11 Jul 2023 21:06:03 +0530 Subject: [PATCH] Refactored to use native Promise.all in place of Bluebird (#17026) refs https://github.com/TryGhost/Ghost/issues/14882 - removed Bluebird Promise.props from files in favor of native Promise.all --- .../core/frontend/services/data/fetch-data.js | 27 +++++++++++-------- .../services/routing/controllers/static.js | 18 +++++++------ ghost/core/core/server/models/user.js | 14 +++++----- 3 files changed, 33 insertions(+), 26 deletions(-) diff --git a/ghost/core/core/frontend/services/data/fetch-data.js b/ghost/core/core/frontend/services/data/fetch-data.js index 124c1c3134..7f7369fec5 100644 --- a/ghost/core/core/frontend/services/data/fetch-data.js +++ b/ghost/core/core/frontend/services/data/fetch-data.js @@ -3,7 +3,6 @@ * Dynamically build and execute queries on the API */ const _ = require('lodash'); -const Promise = require('bluebird'); // The default settings for a default post query const queryDefaults = { @@ -64,7 +63,7 @@ function processQuery(query, slugParam, locals) { * Fetch data from API helper for controllers. * * Calls out to get posts per page, builds the final posts query & builds any additional queries - * Wraps the queries using Promise.props to ensure it gets named responses + * Uses Promise.all to handle the queries and ensure concurrent execution. * Does a first round of formatting on the response, and returns */ function fetchData(pathOptions, routerOptions, locals) { @@ -72,7 +71,7 @@ function fetchData(pathOptions, routerOptions, locals) { routerOptions = routerOptions || {}; let postQuery = _.cloneDeep(defaultPostQuery); - let props = {}; + let promises = []; if (routerOptions.filter) { postQuery.options.filter = routerOptions.filter; @@ -92,26 +91,32 @@ function fetchData(pathOptions, routerOptions, locals) { // CASE: always fetch post entries // The filter can in theory contain a "%s" e.g. filter="primary_tag:%s" - props.posts = processQuery(postQuery, pathOptions.slug, locals); + promises.push(processQuery(postQuery, pathOptions.slug, locals)); // CASE: fetch more data defined by the router e.g. tags, authors - see TaxonomyRouter _.each(routerOptions.data, function (query, name) { const dataQueryOptions = _.merge(query, defaultDataQueryOptions[name]); - props[name] = processQuery(dataQueryOptions, pathOptions.slug, locals); + promises.push(processQuery(dataQueryOptions, pathOptions.slug, locals)); }); - return Promise.props(props) + return Promise.all(promises) .then(function formatResponse(results) { - const response = _.cloneDeep(results.posts); + const response = _.cloneDeep(results[0]); if (routerOptions.data) { response.data = {}; - _.each(routerOptions.data, function (config, name) { - response.data[name] = results[name][config.resource]; + let resultIndex = 1; - if (config.type === 'browse') { - response.data[name].meta = results[name].meta; + _.each(routerOptions.data, function (config, name) { + if (results[resultIndex]) { + response.data[name] = results[resultIndex][config.resource]; + + if (config.type === 'browse') { + response.data[name].meta = results[resultIndex].meta; + } + + resultIndex = resultIndex + 1; } }); } diff --git a/ghost/core/core/frontend/services/routing/controllers/static.js b/ghost/core/core/frontend/services/routing/controllers/static.js index 9df5a62010..64fbed9816 100644 --- a/ghost/core/core/frontend/services/routing/controllers/static.js +++ b/ghost/core/core/frontend/services/routing/controllers/static.js @@ -1,5 +1,4 @@ const _ = require('lodash'); -const Promise = require('bluebird'); const debug = require('@tryghost/debug')('services:routing:controllers:static'); const renderer = require('../../rendering'); @@ -36,27 +35,30 @@ function processQuery(query, locals) { module.exports = function staticController(req, res, next) { debug('staticController', res.routerOptions); - let props = {}; + let promises = []; - _.each(res.routerOptions.data, function (query, name) { - props[name] = processQuery(query, res.locals); + _.each(res.routerOptions.data, function (query) { + promises.push(processQuery(query, res.locals)); }); - return Promise.props(props) + return Promise.all(promises) .then(function handleResult(result) { let response = {}; if (res.routerOptions.data) { response.data = {}; + let resultIndex = 0; _.each(res.routerOptions.data, function (config, name) { - response.data[name] = result[name][config.resource]; + response.data[name] = result[resultIndex][config.resource]; if (config.type === 'browse') { - response.data[name].meta = result[name].meta; + response.data[name].meta = result[resultIndex].meta; // @TODO: remove in Ghost 3.0 (see https://github.com/TryGhost/Ghost/issues/10434) - response.data[name][config.resource] = result[name][config.resource]; + response.data[name][config.resource] = result[resultIndex][config.resource]; } + + resultIndex = resultIndex + 1; }); } diff --git a/ghost/core/core/server/models/user.js b/ghost/core/core/server/models/user.js index 870752b011..296a3be794 100644 --- a/ghost/core/core/server/models/user.js +++ b/ghost/core/core/server/models/user.js @@ -204,7 +204,7 @@ User = ghostBookshelf.Model.extend({ // If the user's email is set & has changed & we are not importing if (self.hasChanged('email') && self.get('email') && !options.importing) { - tasks.gravatar = (function lookUpGravatar() { + tasks.push((function lookUpGravatar() { const {gravatar} = require('../lib/image'); return gravatar.lookup({ @@ -214,11 +214,11 @@ User = ghostBookshelf.Model.extend({ self.set('profile_image', response.image); } }); - })(); + })()); } if (this.hasChanged('slug') || !this.get('slug')) { - tasks.slug = (function generateSlug() { + tasks.push((function generateSlug() { return ghostBookshelf.Model.generateSlug( User, self.get('slug') || self.get('name'), @@ -230,7 +230,7 @@ User = ghostBookshelf.Model.extend({ .then(function then(slug) { self.set({slug: slug}); }); - })(); + })()); } /** @@ -274,15 +274,15 @@ User = ghostBookshelf.Model.extend({ } } - tasks.hashPassword = (function hashPassword() { + tasks.push((function hashPassword() { return security.password.hash(self.get('password')) .then(function (hash) { self.set('password', hash); }); - })(); + })()); } - return Promise.props(tasks); + return Promise.all(tasks); }, toJSON: function toJSON(unfilteredOptions) {