mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-20 22:42:53 -05:00
7326241718
closes #12263 - Express parses repeated query parameters as an array (req.query properties). Because there is no clear reason on why not to support this behavior extended order parameter parsing logic to handle arrays. This follows the rule of "liberal inputs, conservative outputs" - Example supported query string for ordering can now look like: `?order=featured&order=published_at asc`, the priority of the order stays the same with the most significant appearing first and least significant last
62 lines
2.1 KiB
JavaScript
62 lines
2.1 KiB
JavaScript
const _ = require('lodash');
|
|
|
|
const order = function order(Bookshelf) {
|
|
Bookshelf.Model = Bookshelf.Model.extend({
|
|
orderAttributes() {},
|
|
|
|
parseOrderOption: function (orderQueryString, withRelated) {
|
|
let orderAttributes;
|
|
let result;
|
|
let rules = [];
|
|
|
|
orderAttributes = this.orderAttributes();
|
|
if (withRelated && withRelated.indexOf('count.posts') > -1) {
|
|
orderAttributes.push('count.posts');
|
|
}
|
|
result = {};
|
|
|
|
// CASE: repeat order query parameter keys are present
|
|
if (_.isArray(orderQueryString)) {
|
|
orderQueryString.forEach((qs) => {
|
|
rules.push(...qs.split(','));
|
|
});
|
|
} else {
|
|
rules = orderQueryString.split(',');
|
|
}
|
|
|
|
_.each(rules, function (rule) {
|
|
let match;
|
|
let field;
|
|
let direction;
|
|
|
|
match = /^([a-z0-9_.]+)\s+(asc|desc)$/i.exec(rule.trim());
|
|
|
|
// invalid order syntax
|
|
if (!match) {
|
|
return;
|
|
}
|
|
|
|
field = match[1].toLowerCase();
|
|
direction = match[2].toUpperCase();
|
|
|
|
const matchingOrderAttribute = orderAttributes.find((orderAttribute) => {
|
|
// NOTE: this logic assumes we use different field names for "parent" and "child" relations.
|
|
// E.g.: ['parent.title', 'child.title'] and ['child.title', 'parent.title'] - would not
|
|
// distinguish on which relation to sort neither which order to pick the fields on.
|
|
// For more context see: https://github.com/TryGhost/Ghost/pull/12226#discussion_r493085098
|
|
return orderAttribute.endsWith(field);
|
|
});
|
|
|
|
if (!matchingOrderAttribute) {
|
|
return;
|
|
}
|
|
|
|
result[matchingOrderAttribute] = direction;
|
|
});
|
|
|
|
return result;
|
|
}
|
|
});
|
|
};
|
|
|
|
module.exports = order;
|