mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-28 05:37:34 +03:00
Extracted frontend code from redirects API controllers (#10798)
refs #10790 - The code was moved out of controllers to reduce the number of coupling points between the API controllers and "frontend" services - A nice side effect of this move is a decreased amount of code that will need to be maintained and reusability between existing controllers - Calling just a few methods from frontend services on API level makes it easier to abstract fronted away from API
This commit is contained in:
parent
64735693be
commit
be27db46eb
5
core/frontend/services/redirects/index.js
Normal file
5
core/frontend/services/redirects/index.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module.exports = {
|
||||||
|
get settings() {
|
||||||
|
return require('./settings');
|
||||||
|
}
|
||||||
|
};
|
75
core/frontend/services/redirects/settings.js
Normal file
75
core/frontend/services/redirects/settings.js
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
const fs = require('fs-extra');
|
||||||
|
const path = require('path');
|
||||||
|
const Promise = require('bluebird');
|
||||||
|
const moment = require('moment-timezone');
|
||||||
|
|
||||||
|
const validation = require('./validation');
|
||||||
|
|
||||||
|
const config = require('../../../server/config');
|
||||||
|
const common = require('../../../server/lib/common');
|
||||||
|
|
||||||
|
const readRedirectsFile = (redirectsPath) => {
|
||||||
|
return fs.readFile(redirectsPath, 'utf-8')
|
||||||
|
.then((content) => {
|
||||||
|
try {
|
||||||
|
content = JSON.parse(content);
|
||||||
|
} catch (err) {
|
||||||
|
throw new common.errors.BadRequestError({
|
||||||
|
message: common.i18n.t('errors.general.jsonParse', {context: err.message})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return content;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
if (err.code === 'ENOENT') {
|
||||||
|
return Promise.resolve([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (common.errors.utils.isIgnitionError(err)) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new common.errors.NotFoundError({
|
||||||
|
err: err
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const setFromFilePath = (filePath) => {
|
||||||
|
const redirectsPath = path.join(config.getContentPath('data'), 'redirects.json');
|
||||||
|
const backupRedirectsPath = path.join(config.getContentPath('data'), `redirects-${moment().format('YYYY-MM-DD-HH-mm-ss')}.json`);
|
||||||
|
|
||||||
|
return fs.pathExists(redirectsPath)
|
||||||
|
.then((exists) => {
|
||||||
|
if (!exists) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fs.pathExists(backupRedirectsPath)
|
||||||
|
.then((exists) => {
|
||||||
|
if (!exists) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fs.unlink(backupRedirectsPath);
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
return fs.move(redirectsPath, backupRedirectsPath);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
return readRedirectsFile(filePath)
|
||||||
|
.then((content) => {
|
||||||
|
validation.validate(content);
|
||||||
|
return fs.writeFile(redirectsPath, JSON.stringify(content), 'utf-8');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const get = () => {
|
||||||
|
return readRedirectsFile(path.join(config.getContentPath('data'), 'redirects.json'));
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.get = get;
|
||||||
|
module.exports.setFromFilePath = setFromFilePath;
|
27
core/frontend/services/redirects/validation.js
Normal file
27
core/frontend/services/redirects/validation.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
const _ = require('lodash');
|
||||||
|
const common = require('../../../server/lib/common');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirects are file based at the moment, but they will live in the database in the future.
|
||||||
|
* See V2 of https://github.com/TryGhost/Ghost/issues/7707.
|
||||||
|
*/
|
||||||
|
const validate = (redirects) => {
|
||||||
|
if (!_.isArray(redirects)) {
|
||||||
|
throw new common.errors.ValidationError({
|
||||||
|
message: common.i18n.t('errors.utils.redirectsWrongFormat'),
|
||||||
|
help: 'https://docs.ghost.org/concepts/redirects/'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_.each(redirects, function (redirect) {
|
||||||
|
if (!redirect.from || !redirect.to) {
|
||||||
|
throw new common.errors.ValidationError({
|
||||||
|
message: common.i18n.t('errors.utils.redirectsWrongFormat'),
|
||||||
|
context: redirect,
|
||||||
|
help: 'https://docs.ghost.org/concepts/redirects/'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.validate = validate;
|
@ -1,88 +1,22 @@
|
|||||||
const fs = require('fs-extra'),
|
const localUtils = require('./utils'),
|
||||||
Promise = require('bluebird'),
|
web = require('../../web'),
|
||||||
moment = require('moment'),
|
redirects = require('../../../frontend/services/redirects');
|
||||||
path = require('path'),
|
|
||||||
config = require('../../config'),
|
|
||||||
common = require('../../lib/common'),
|
|
||||||
validation = require('../../data/validation'),
|
|
||||||
localUtils = require('./utils'),
|
|
||||||
web = require('../../web');
|
|
||||||
|
|
||||||
let redirectsAPI,
|
let redirectsAPI;
|
||||||
_private = {};
|
|
||||||
|
|
||||||
_private.readRedirectsFile = (customRedirectsPath) => {
|
|
||||||
const redirectsPath = customRedirectsPath || path.join(config.getContentPath('data'), 'redirects.json');
|
|
||||||
|
|
||||||
return fs.readFile(redirectsPath, 'utf-8')
|
|
||||||
.then((content) => {
|
|
||||||
try {
|
|
||||||
content = JSON.parse(content);
|
|
||||||
} catch (err) {
|
|
||||||
throw new common.errors.BadRequestError({
|
|
||||||
message: common.i18n.t('errors.general.jsonParse', {context: err.message})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return content;
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
if (err.code === 'ENOENT') {
|
|
||||||
return Promise.resolve([]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (common.errors.utils.isIgnitionError(err)) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new common.errors.NotFoundError({
|
|
||||||
err: err
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
redirectsAPI = {
|
redirectsAPI = {
|
||||||
download(options) {
|
download(options) {
|
||||||
return localUtils.handlePermissions('redirects', 'download')(options)
|
return localUtils.handlePermissions('redirects', 'download')(options)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return _private.readRedirectsFile();
|
return redirects.settings.get();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
upload(options) {
|
upload(options) {
|
||||||
const redirectsPath = path.join(config.getContentPath('data'), 'redirects.json'),
|
|
||||||
backupRedirectsPath = path.join(config.getContentPath('data'), `redirects-${moment().format('YYYY-MM-DD-HH-mm-ss')}.json`);
|
|
||||||
|
|
||||||
return localUtils.handlePermissions('redirects', 'upload')(options)
|
return localUtils.handlePermissions('redirects', 'upload')(options)
|
||||||
|
.then(() => redirects.settings.setFromFilePath(options.path))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return fs.pathExists(redirectsPath)
|
// CASE: trigger that redirects are getting re-registered
|
||||||
.then((exists) => {
|
web.shared.middlewares.customRedirects.reload();
|
||||||
if (!exists) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fs.pathExists(backupRedirectsPath)
|
|
||||||
.then((exists) => {
|
|
||||||
if (!exists) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fs.unlink(backupRedirectsPath);
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
return fs.move(redirectsPath, backupRedirectsPath);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
return _private.readRedirectsFile(options.path)
|
|
||||||
.then((content) => {
|
|
||||||
validation.validateRedirects(content);
|
|
||||||
return fs.writeFile(redirectsPath, JSON.stringify(content), 'utf-8');
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
// CASE: trigger that redirects are getting re-registered
|
|
||||||
web.shared.middlewares.customRedirects.reload();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,43 +1,5 @@
|
|||||||
const fs = require('fs-extra');
|
|
||||||
const path = require('path');
|
|
||||||
const Promise = require('bluebird');
|
|
||||||
const moment = require('moment-timezone');
|
|
||||||
const config = require('../../config');
|
|
||||||
const common = require('../../lib/common');
|
|
||||||
const validation = require('../../data/validation');
|
|
||||||
const web = require('../../web');
|
const web = require('../../web');
|
||||||
|
const redirects = require('../../../frontend/services/redirects');
|
||||||
const _private = {};
|
|
||||||
|
|
||||||
_private.readRedirectsFile = (customRedirectsPath) => {
|
|
||||||
const redirectsPath = customRedirectsPath || path.join(config.getContentPath('data'), 'redirects.json');
|
|
||||||
|
|
||||||
return fs.readFile(redirectsPath, 'utf-8')
|
|
||||||
.then((content) => {
|
|
||||||
try {
|
|
||||||
content = JSON.parse(content);
|
|
||||||
} catch (err) {
|
|
||||||
throw new common.errors.BadRequestError({
|
|
||||||
message: common.i18n.t('errors.general.jsonParse', {context: err.message})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return content;
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
if (err.code === 'ENOENT') {
|
|
||||||
return Promise.resolve([]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (common.errors.utils.isIgnitionError(err)) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new common.errors.NotFoundError({
|
|
||||||
err: err
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
docName: 'redirects',
|
docName: 'redirects',
|
||||||
@ -51,7 +13,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
permissions: true,
|
permissions: true,
|
||||||
query() {
|
query() {
|
||||||
return _private.readRedirectsFile();
|
return redirects.settings.get();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -61,37 +23,10 @@ module.exports = {
|
|||||||
cacheInvalidate: true
|
cacheInvalidate: true
|
||||||
},
|
},
|
||||||
query(frame) {
|
query(frame) {
|
||||||
const redirectsPath = path.join(config.getContentPath('data'), 'redirects.json');
|
return redirects.settings.setFromFilePath(frame.file.path)
|
||||||
const backupRedirectsPath = path.join(config.getContentPath('data'), `redirects-${moment().format('YYYY-MM-DD-HH-mm-ss')}.json`);
|
|
||||||
|
|
||||||
return fs.pathExists(redirectsPath)
|
|
||||||
.then((exists) => {
|
|
||||||
if (!exists) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fs.pathExists(backupRedirectsPath)
|
|
||||||
.then((exists) => {
|
|
||||||
if (!exists) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fs.unlink(backupRedirectsPath);
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
return fs.move(redirectsPath, backupRedirectsPath);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return _private.readRedirectsFile(frame.file.path)
|
// CASE: trigger that redirects are getting re-registered
|
||||||
.then((content) => {
|
web.shared.middlewares.customRedirects.reload();
|
||||||
validation.validateRedirects(content);
|
|
||||||
return fs.writeFile(redirectsPath, JSON.stringify(content), 'utf-8');
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
// CASE: trigger that redirects are getting re-registered
|
|
||||||
web.shared.middlewares.customRedirects.reload();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@ var schema = require('../schema').tables,
|
|||||||
validatePassword,
|
validatePassword,
|
||||||
validateSchema,
|
validateSchema,
|
||||||
validateSettings,
|
validateSettings,
|
||||||
validateRedirects,
|
|
||||||
validate;
|
validate;
|
||||||
|
|
||||||
function assertString(input) {
|
function assertString(input) {
|
||||||
@ -356,34 +355,10 @@ validate = function validate(value, key, validations, tableName) {
|
|||||||
return validationErrors;
|
return validationErrors;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Redirects are file based at the moment, but they will live in the database in the future.
|
|
||||||
* See V2 of https://github.com/TryGhost/Ghost/issues/7707.
|
|
||||||
*/
|
|
||||||
validateRedirects = function validateRedirects(redirects) {
|
|
||||||
if (!_.isArray(redirects)) {
|
|
||||||
throw new common.errors.ValidationError({
|
|
||||||
message: common.i18n.t('errors.utils.redirectsWrongFormat'),
|
|
||||||
help: 'https://docs.ghost.org/concepts/redirects/'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_.each(redirects, function (redirect) {
|
|
||||||
if (!redirect.from || !redirect.to) {
|
|
||||||
throw new common.errors.ValidationError({
|
|
||||||
message: common.i18n.t('errors.utils.redirectsWrongFormat'),
|
|
||||||
context: redirect,
|
|
||||||
help: 'https://docs.ghost.org/concepts/redirects/'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
validate: validate,
|
validate: validate,
|
||||||
validator: validator,
|
validator: validator,
|
||||||
validatePassword: validatePassword,
|
validatePassword: validatePassword,
|
||||||
validateSchema: validateSchema,
|
validateSchema: validateSchema,
|
||||||
validateSettings: validateSettings,
|
validateSettings: validateSettings
|
||||||
validateRedirects: validateRedirects
|
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user