0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-27 22:49:56 -05:00
ghost/core/server/services/apps/index.js
Hannah Wolfe 882a2361ee
Moved apps to /services/ & moved individual tests (#9187)
refs #9178

* Moved app handling code into services/apps
  - Apps is a service, that allows for the App lifecycle 
  - /server/apps = contains internal apps 
   - /server/services/apps = contains code for managing/handling app life cycle, providing the proxy, etc
* Split apps service tests into separate files
* Moved internal app tests into test folders
    - Problem: Not all the tests in apps were unit tests, yet they were treated like they were in Gruntfile.js
    - Unit tests now live in /test/unit/apps
    - Route tests now live in /test/functional/routes/apps
    - Gruntfile.js has been updated to match
* Switch api.read usage for settingsCache
* Add tests to cover the basic App lifecycle
* Simplify some of the init logic
2017-10-30 12:31:04 +00:00

76 lines
2.9 KiB
JavaScript

var debug = require('ghost-ignition').debug('services:apps'),
_ = require('lodash'),
Promise = require('bluebird'),
logging = require('../../logging'),
errors = require('../../errors'),
api = require('../../api'),
i18n = require('../../i18n'),
config = require('../../config'),
settingsCache = require('../../settings/cache'),
loader = require('./loader'),
// Internal APps are in config
internalApps = config.get('apps:internal'),
// Holds the available apps
availableApps = {};
function recordLoadedApp(name, loadedApp) {
// After loading the app, add it to our hash of loaded apps
availableApps[name] = loadedApp;
return loadedApp;
}
function saveInstalledApps(installedApps) {
debug('saving begin');
var currentInstalledApps = settingsCache.get('installed_apps'),
// Never save internal apps
updatedAppsInstalled = _.difference(_.uniq(installedApps.concat(currentInstalledApps)), internalApps);
if (_.difference(updatedAppsInstalled, currentInstalledApps).length === 0) {
debug('saving unneeded');
return new Promise.resolve();
}
debug('saving settings');
return api.settings.edit({settings: [{key: 'installed_apps', value: updatedAppsInstalled}]}, {context: {internal: true}});
}
module.exports = {
init: function () {
debug('init begin');
var activeApps = settingsCache.get('active_apps'),
installedApps = settingsCache.get('installed_apps'),
// Load means either activate, or install and activate
// We load all Active Apps, and all Internal Apps
appsToLoad = activeApps.concat(internalApps);
function loadApp(appName) {
// If internal or already installed, the app only needs activating
if (_.includes(internalApps, appName) || _.includes(installedApps, appName)) {
return loader.activateAppByName(appName).then(function (loadedApp) {
return recordLoadedApp(appName, loadedApp);
});
}
// Else first install, then activate the app
return loader.installAppByName(appName).then(function () {
return loader.activateAppByName(appName);
}).then(function (loadedApp) {
return recordLoadedApp(appName, loadedApp);
});
}
return Promise.map(appsToLoad, loadApp)
.then(function () {
// Save our installed apps to settings
return saveInstalledApps(_.keys(availableApps));
})
.catch(function (err) {
logging.error(new errors.GhostError({
err: err,
context: i18n.t('errors.apps.appWillNotBeLoaded.error'),
help: i18n.t('errors.apps.appWillNotBeLoaded.help')
}));
});
},
availableApps: availableApps
};