@ihelpee/crud-request
Version:
NestJs CRUD for RESTful APIs - request query builder
211 lines • 7.49 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RequestQueryBuilder = void 0;
const crud_util_1 = require("@ihelpee/crud-util");
const qs_1 = require("qs");
const request_query_validator_1 = require("./request-query.validator");
class RequestQueryBuilder {
constructor() {
this.setParamNames();
}
static _options = {
delim: '||',
delimStr: ',',
paramNamesMap: {
fields: ['fields', 'select'],
search: 's',
filter: 'filter',
or: 'or',
join: 'join',
sort: 'sort',
limit: ['limit', 'per_page'],
offset: 'offset',
page: 'page',
cache: 'cache',
includeDeleted: 'include_deleted',
extra: 'extra.',
},
};
paramNames = {};
joinConditionString = {
encode: false,
delimiter: this.options.delimStr,
arrayFormat: 'indices',
};
queryObject = {};
queryString;
static setOptions(options) {
RequestQueryBuilder._options = {
...RequestQueryBuilder._options,
...options,
paramNamesMap: {
...RequestQueryBuilder._options.paramNamesMap,
...(options.paramNamesMap ? options.paramNamesMap : {}),
},
};
}
static getOptions() {
return RequestQueryBuilder._options;
}
static create(params, customOperators) {
const qb = new RequestQueryBuilder();
return (0, crud_util_1.isObject)(params) ? qb.createFromParams(params, customOperators) : qb;
}
get options() {
return RequestQueryBuilder._options;
}
setParamNames() {
Object.keys(RequestQueryBuilder._options.paramNamesMap).forEach((key) => {
const name = RequestQueryBuilder._options.paramNamesMap[key];
this.paramNames[key] = (0, crud_util_1.isString)(name) ? name : name[0];
});
}
query(encode = true) {
if (this.queryObject[this.paramNames.search]) {
this.queryObject[this.paramNames.filter] = undefined;
this.queryObject[this.paramNames.or] = undefined;
}
this.queryString = (0, qs_1.stringify)(this.queryObject, { encode });
return this.queryString;
}
select(fields) {
if ((0, crud_util_1.isArrayFull)(fields)) {
(0, request_query_validator_1.validateFields)(fields);
this.queryObject[this.paramNames.fields] = fields.join(this.options.delimStr);
}
return this;
}
search(s) {
if (!(0, crud_util_1.isNil)(s) && (0, crud_util_1.isObject)(s)) {
this.queryObject[this.paramNames.search] = JSON.stringify(s);
}
return this;
}
setFilter(f, customOperators) {
this.setCondition(f, 'filter', customOperators);
return this;
}
setOr(f, customOperators) {
this.setCondition(f, 'or', customOperators);
return this;
}
setJoin(j) {
if (!(0, crud_util_1.isNil)(j)) {
const param = this.checkQueryObjectParam('join', []);
this.queryObject[param] = [
...this.queryObject[param],
...(Array.isArray(j) && !(0, crud_util_1.isString)(j[0])
? j.map((o) => this.addJoin(o))
: [this.addJoin(j)]),
];
}
return this;
}
sortBy(s) {
if (!(0, crud_util_1.isNil)(s)) {
const param = this.checkQueryObjectParam('sort', []);
this.queryObject[param] = [
...this.queryObject[param],
...(Array.isArray(s) && !(0, crud_util_1.isString)(s[0])
? s.map((o) => this.addSortBy(o))
: [this.addSortBy(s)]),
];
}
return this;
}
setLimit(n) {
this.setNumeric(n, 'limit');
return this;
}
setOffset(n) {
this.setNumeric(n, 'offset');
return this;
}
setPage(n) {
this.setNumeric(n, 'page');
return this;
}
resetCache() {
this.setNumeric(0, 'cache');
return this;
}
setIncludeDeleted(n) {
this.setNumeric(n, 'includeDeleted');
return this;
}
cond(f, cond = 'search', customOperators) {
const filter = Array.isArray(f) ? { field: f[0], operator: f[1], value: f[2] } : f;
(0, request_query_validator_1.validateCondition)(filter, cond, customOperators);
const d = this.options.delim;
return (filter.field +
d +
filter.operator +
((0, crud_util_1.hasValue)(filter.value) ? d + filter.value : ''));
}
addJoin(join) {
const { delim, delimStr } = this.options;
const normalizedJoin = Array.isArray(join)
? { field: join[0], select: join[1], on: join[2] }
: join;
(0, request_query_validator_1.validateJoin)(normalizedJoin);
const conditions = (0, crud_util_1.isArrayFull)(normalizedJoin.on)
? { on: normalizedJoin.on.map((condition) => this.cond(condition, 'filter')) }
: '';
const fieldPart = normalizedJoin.field;
const selectPart = (0, crud_util_1.isArrayFull)(normalizedJoin.select)
? delim + normalizedJoin.select.join(delimStr)
: '';
const conditionsPart = conditions
? delim + (0, qs_1.stringify)(conditions, this.joinConditionString)
: '';
return fieldPart + selectPart + conditionsPart;
}
addSortBy(s) {
const sort = Array.isArray(s) ? { field: s[0], order: s[1] } : s;
(0, request_query_validator_1.validateSort)(sort);
const ds = this.options.delimStr;
return sort.field + ds + sort.order;
}
createFromParams(params, customOperators) {
this.select(params.fields);
this.search(params.search);
this.setFilter(params.filter, customOperators);
this.setOr(params.or, customOperators);
this.setJoin(params.join);
this.setLimit(params.limit);
this.setOffset(params.offset);
this.setPage(params.page);
this.sortBy(params.sort);
if (params.resetCache) {
this.resetCache();
}
this.setIncludeDeleted(params.includeDeleted);
return this;
}
checkQueryObjectParam(cond, defaults) {
const param = this.paramNames[cond];
if ((0, crud_util_1.isNil)(this.queryObject[param]) && !(0, crud_util_1.isUndefined)(defaults)) {
this.queryObject[param] = defaults;
}
return param;
}
setCondition(f, cond, customOperators) {
if (!(0, crud_util_1.isNil)(f)) {
const param = this.checkQueryObjectParam(cond, []);
this.queryObject[param] = [
...this.queryObject[param],
...(Array.isArray(f) && !(0, crud_util_1.isString)(f[0])
? f.map((o) => this.cond(o, cond, customOperators))
: [this.cond(f, cond, customOperators)]),
];
}
}
setNumeric(n, cond) {
if (!(0, crud_util_1.isNil)(n)) {
(0, request_query_validator_1.validateNumeric)(n, cond);
this.queryObject[this.paramNames[cond]] = n;
}
}
}
exports.RequestQueryBuilder = RequestQueryBuilder;
//# sourceMappingURL=request-query.builder.js.map