Ghost/core/frontend/services/settings/ensure-settings.js
Nazar Gargol 5582d030e3 Added routes.yaml content checksum storage to the db
closes #11999

- When the routes.yaml file changes (manually or through API) we need
to store a checksum to be able to optimize routes reloads in the future
- Added mechanism to detect differences between stored and current routes.yaml hash value
- Added routes.yaml sync on server boot
- Added routes.yaml handling in controllers
- Added routes hash synchronization method in core settings. It lives in core settings
as it needs access to model layer. To avoid coupling with the frontend settings it accepts
a function which has to resolve to a routes hash
- Added note about settings validation side-effect. It mutates input!
- Added async check for currently loaded routes hash
- Extended frontend settings loader with async loader. The default behavior of the loader is
to load settings syncronously for reasons spelled in 0ac19dcf84
To avoid blocking the eventloop added async loading method
- Refactored frontend setting loader for reusability of  settings file path
- Added integrity check test for routes.yaml file
2020-09-10 10:54:57 +12:00

48 lines
2.0 KiB
JavaScript

const fs = require('fs-extra');
const Promise = require('bluebird');
const path = require('path');
const debug = require('ghost-ignition').debug('frontend:services:settings:ensure-settings');
const {i18n} = require('../../../server/lib/common');
const errors = require('@tryghost/errors');
const config = require('../../../shared/config');
/**
* Makes sure that all supported settings files are in the
* `/content/settings` directory. If not, copy the default files
* over.
* @param {Array} knownSettings
* @returns {Promise}
* @description Reads the `/settings` folder of the content path and makes
* sure that the associated yaml file for each setting exists. If it doesn't
* copy the default yaml file over.
*/
module.exports = function ensureSettingsFiles(knownSettings) {
const contentPath = config.getContentPath('settings');
const defaultSettingsPath = config.get('paths').defaultSettings;
return Promise.each(knownSettings, function (setting) {
const fileName = `${setting}.yaml`;
const defaultFileName = `default-${fileName}`;
const filePath = path.join(contentPath, fileName);
return fs.readFile(filePath, 'utf8')
.catch({code: 'ENOENT'}, () => {
const defaultFilePath = path.join(defaultSettingsPath, defaultFileName);
// CASE: file doesn't exist, copy it from our defaults
return fs.copy(
defaultFilePath,
filePath
).then(() => {
debug(`'${defaultFileName}' copied to ${contentPath}.`);
});
}).catch((error) => {
// CASE: we might have a permission error, as we can't access the directory
throw new errors.GhostError({
message: i18n.t('errors.services.settings.ensureSettings', {path: contentPath}),
err: error,
context: error.path
});
});
});
};