Ghost/core/server/apps/index.js

102 lines
3.8 KiB
JavaScript
Raw Normal View History

2014-01-21 12:45:27 +04:00
2014-02-05 12:40:30 +04:00
var _ = require('lodash'),
Promise = require('bluebird'),
🎨 configurable logging with bunyan (#7431) - 🛠 add bunyan and prettyjson, remove morgan - ✨ add logging module - GhostLogger class that handles setup of bunyan - PrettyStream for stdout - ✨ config for logging - @TODO: testing level fatal? - ✨ log each request via GhostLogger (express middleware) - @TODO: add errors to output - 🔥 remove errors.updateActiveTheme - we can read the value from config - 🔥 remove 15 helper functions in core/server/errors/index.js - all these functions get replaced by modules: 1. logging 2. error middleware handling for html/json 3. error creation (which will be part of PR #7477) - ✨ add express error handler for html/json - one true error handler for express responses - contains still some TODO's, but they are not high priority for first implementation/integration - this middleware only takes responsibility of either rendering html responses or return json error responses - 🎨 use new express error handler in middleware/index - 404 and 500 handling - 🎨 return error instead of error message in permissions/index.js - the rule for error handling should be: if you call a unit, this unit should return a custom Ghost error - 🎨 wrap serve static module - rule: if you call a module/unit, you should always wrap this error - it's always the same rule - so the caller never has to worry about what comes back - it's always a clear error instance - in this case: we return our notfounderror if serve static does not find the resource - this avoid having checks everywhere - 🎨 replace usages of errors/index.js functions and adapt tests - use logging.error, logging.warn - make tests green - remove some usages of logging and throwing api errors -> because when a request is involved, logging happens automatically - 🐛 return errorDetails to Ghost-Admin - errorDetails is used for Theme error handling - 🎨 use 500er error for theme is missing error in theme-handler - 🎨 extend file rotation to 1w
2016-10-04 18:33:43 +03:00
logging = require('../logging'),
errors = require('../errors'),
2014-01-21 12:45:27 +04:00
api = require('../api'),
loader = require('./loader'),
i18n = require('../i18n'),
config = require('../config'),
2014-01-21 12:45:27 +04:00
// Holds the available apps
availableApps = {};
function getInstalledApps() {
return api.settings.read({context: {internal: true}, key: 'installed_apps'}).then(function (response) {
var installed = response.settings[0];
2014-01-21 12:45:27 +04:00
installed.value = installed.value || '[]';
try {
installed = JSON.parse(installed.value);
} catch (e) {
return Promise.reject(e);
2014-01-21 12:45:27 +04:00
}
return installed.concat(config.get('internalApps'));
2014-01-21 12:45:27 +04:00
});
}
function saveInstalledApps(installedApps) {
return getInstalledApps().then(function (currentInstalledApps) {
var updatedAppsInstalled = _.difference(_.uniq(installedApps.concat(currentInstalledApps)), config.get('internalApps'));
2014-01-21 12:45:27 +04:00
return api.settings.edit({settings: [{key: 'installed_apps', value: updatedAppsInstalled}]}, {context: {internal: true}});
2014-01-21 12:45:27 +04:00
});
}
module.exports = {
init: function () {
var appsToLoad;
try {
// We have to parse the value because it's a string
api.settings.read({context: {internal: true}, key: 'active_apps'}).then(function (response) {
var aApps = response.settings[0];
2014-01-21 12:45:27 +04:00
appsToLoad = JSON.parse(aApps.value) || [];
appsToLoad = appsToLoad.concat(config.get('internalApps'));
2014-01-21 12:45:27 +04:00
});
🎨 configurable logging with bunyan (#7431) - 🛠 add bunyan and prettyjson, remove morgan - ✨ add logging module - GhostLogger class that handles setup of bunyan - PrettyStream for stdout - ✨ config for logging - @TODO: testing level fatal? - ✨ log each request via GhostLogger (express middleware) - @TODO: add errors to output - 🔥 remove errors.updateActiveTheme - we can read the value from config - 🔥 remove 15 helper functions in core/server/errors/index.js - all these functions get replaced by modules: 1. logging 2. error middleware handling for html/json 3. error creation (which will be part of PR #7477) - ✨ add express error handler for html/json - one true error handler for express responses - contains still some TODO's, but they are not high priority for first implementation/integration - this middleware only takes responsibility of either rendering html responses or return json error responses - 🎨 use new express error handler in middleware/index - 404 and 500 handling - 🎨 return error instead of error message in permissions/index.js - the rule for error handling should be: if you call a unit, this unit should return a custom Ghost error - 🎨 wrap serve static module - rule: if you call a module/unit, you should always wrap this error - it's always the same rule - so the caller never has to worry about what comes back - it's always a clear error instance - in this case: we return our notfounderror if serve static does not find the resource - this avoid having checks everywhere - 🎨 replace usages of errors/index.js functions and adapt tests - use logging.error, logging.warn - make tests green - remove some usages of logging and throwing api errors -> because when a request is involved, logging happens automatically - 🐛 return errorDetails to Ghost-Admin - errorDetails is used for Theme error handling - 🎨 use 500er error for theme is missing error in theme-handler - 🎨 extend file rotation to 1w
2016-10-04 18:33:43 +03:00
} catch (err) {
logging.error(new errors.GhostError({
err: err,
context: i18n.t('errors.apps.failedToParseActiveAppsSettings.context'),
help: i18n.t('errors.apps.failedToParseActiveAppsSettings.help')
}));
return Promise.resolve();
2014-01-21 12:45:27 +04:00
}
// Grab all installed apps, install any not already installed that are in appsToLoad.
return getInstalledApps().then(function (installedApps) {
var loadedApps = {},
recordLoadedApp = function (name, loadedApp) {
// After loading the app, add it to our hash of loaded apps
loadedApps[name] = loadedApp;
return Promise.resolve(loadedApp);
2014-01-21 12:45:27 +04:00
},
loadPromises = _.map(appsToLoad, function (app) {
// If already installed, just activate the app
if (_.includes(installedApps, app)) {
2014-01-21 12:45:27 +04:00
return loader.activateAppByName(app).then(function (loadedApp) {
return recordLoadedApp(app, loadedApp);
});
}
// Install, then activate the app
return loader.installAppByName(app).then(function () {
return loader.activateAppByName(app);
}).then(function (loadedApp) {
return recordLoadedApp(app, loadedApp);
});
});
return Promise.all(loadPromises).then(function () {
2014-01-21 12:45:27 +04:00
// Save our installed apps to settings
return saveInstalledApps(_.keys(loadedApps));
}).then(function () {
// Extend the loadedApps onto the available apps
_.extend(availableApps, loadedApps);
}).catch(function (err) {
logging.error(new errors.GhostError({
err: err,
context: i18n.t('errors.apps.appWillNotBeLoaded.error'),
help: i18n.t('errors.apps.appWillNotBeLoaded.help')
}));
2014-01-21 12:45:27 +04:00
});
});
},
availableApps: availableApps
};