@nodeswork/sbase
Version:
Basic REST api foundation from Nodeswork.
134 lines (132 loc) • 4.29 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
require("../mongoose/model-config");
const _ = require("underscore");
const debug_1 = require("debug");
const object_path_1 = require("object-path");
const d = debug_1.default('sbase:overrides');
/**
* Generate an overrides middleware to help build mongoose queries.
*
* 1. Fetch query params to override query:
* overrides('request.query.status->query.status')
* overrides('request.body.status->query.status')
*
* 2. Set object to override query:
* overrides(['constValue', 'query.status'])
*
* 3. Extract object from ctx:
* overrides([(ctx) =>
* moment(ctx.request.query.date).startOf('month').toDate(),
* 'query.date',
* ])
*
* 4. Append to array target:
* overrides(['constValue', 'query.$or.[].status'])
*/
function overrides(...rules) {
const rs = [];
for (const rule of rules) {
if (_.isString(rule)) {
const [os, odWithFormat] = rule.split('->');
const [od, format, ...args] = odWithFormat.split(':');
if (!od) {
throw new Error(`Rule ${rule} is not correct`);
}
if (format != null &&
format !== 'regex' &&
format !== 'date' &&
format !== 'string' &&
format !== 'seconds') {
throw new Error(`Unknown format ${format}`);
}
rs.push({
src: split(os),
dst: split(od),
format: format,
args,
});
}
else {
const [os, odWithFormat, format1, ...args1] = rule;
const [od, format, ...args] = odWithFormat.split(':');
rs.push({
src: _.isFunction(os) ? os : () => os,
dst: split(od),
format: (format || format1),
args: args.concat(args1),
});
}
}
d('Prepared overrides: %O', rs);
return async (ctx, next) => {
for (const { src, dst, format, args } of rs) {
let value;
if (_.isArray(src)) {
value = object_path_1.withInheritedProps.get(ctx, src);
}
else if (_.isFunction(src)) {
value = src(ctx);
if (value && value.then) {
value = await value;
}
}
switch (format) {
case 'regex':
value = new RegExp(value, ...args);
break;
case 'date':
value = new Date(value);
break;
case 'string':
value = value.toString();
break;
case 'seconds':
value = new Date(value).getTime() / 1000;
break;
}
if (value !== undefined) {
setValue(ctx, ['overrides'].concat(dst), value);
d('Set overrides %O with value %O, result: %O', dst, value, ctx.overrides);
}
}
await next();
};
}
exports.overrides = overrides;
function clearOverrides() {
return async (ctx, next) => {
ctx.overrides = {
query: {},
doc: {},
};
await next();
};
}
exports.clearOverrides = clearOverrides;
function setValue(target, keys, value) {
const parts = [];
keys = _.map(keys, (key) => {
if (key === '[]') {
if (!object_path_1.withInheritedProps.has(target, parts)) {
object_path_1.withInheritedProps.set(target, parts, []);
}
key = object_path_1.withInheritedProps.get(target, parts).length.toString();
}
parts.push(key);
return key;
});
object_path_1.withInheritedProps.set(target, keys, value);
}
function split(str) {
const strs = str.split('.');
for (let i = strs.length - 1; i >= 1; i--) {
if (strs[i - 1].endsWith('\\')) {
strs[i - 1] =
strs[i - 1].substring(0, strs[i - 1].length - 1) + '.' + strs[i];
strs[i] = '';
}
}
return _.filter(strs, (x) => !!x);
}
//# sourceMappingURL=overrides.js.map