typeorm-paginator
Version:
TypeORM query builder pagination library.
542 lines (541 loc) • 26.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.CursorPaginator = void 0;
var _regeneratorRuntime = _interopRequireDefault(require("regenerator-runtime"));
var _base64Transformer = require("./transformers/base64-transformer");
var _normalizeOrderBy = require("./utils/normalizeOrderBy");
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
}
if (info.done) {
resolve(value);
} else {
Promise.resolve(value).then(_next, _throw);
}
}
function _asyncToGenerator(fn) {
return function() {
var self = this, args = arguments;
return new Promise(function(resolve, reject) {
var gen = fn.apply(self, args);
function _next(value) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
}
function _throw(err) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
}
_next(undefined);
});
};
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for(var i = 0; i < props.length; i++){
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function _iterableToArrayLimit(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for(var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true){
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally{
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally{
if (_d) throw _e;
}
}
return _arr;
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
function _slicedToArray(arr, i) {
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
}
var CursorPaginator = /*#__PURE__*/ function() {
"use strict";
function CursorPaginator(entity, param) {
var orderBy = param.orderBy, columnNames = param.columnNames, take = param.take, transformer = param.transformer;
_classCallCheck(this, CursorPaginator);
this.entity = entity;
this.orders = [];
this.orders = (0, _normalizeOrderBy).normalizeOrderBy(orderBy);
this.columnNames = columnNames !== null && columnNames !== void 0 ? columnNames : {
};
var ref, ref1, ref2;
this.takeOptions = typeof take === 'number' ? {
default: take,
min: 0,
max: Infinity
} : {
default: (ref = take === null || take === void 0 ? void 0 : take.default) !== null && ref !== void 0 ? ref : 20,
min: Math.max(0, (ref1 = take === null || take === void 0 ? void 0 : take.min) !== null && ref1 !== void 0 ? ref1 : 0),
max: (ref2 = take === null || take === void 0 ? void 0 : take.max) !== null && ref2 !== void 0 ? ref2 : Infinity
};
this.transformer = transformer !== null && transformer !== void 0 ? transformer : new _base64Transformer.Base64Transformer();
}
_createClass(CursorPaginator, [
{
key: "paginate",
value: function paginate(qb) {
var params = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {
};
return _asyncToGenerator(_regeneratorRuntime.default.mark(function _callee() {
var take, qbForCount, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, _value, key, value, _key, hasPrev, nodes2, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, _value1, key1, value1, _key1, hasNext, nodes1;
return _regeneratorRuntime.default.wrap(function _callee$(_ctx) {
while(1)switch(_ctx.prev = _ctx.next){
case 0:
take = Math.max(this.takeOptions.min, Math.min(params.take || this.takeOptions.default, this.takeOptions.max));
qbForCount = qb.clone();
if (!params.prevCursor) {
_ctx.next = 33;
break;
}
try {
this._applyWhereQuery(qb, this.transformer.parse(params.prevCursor), false);
} catch (e) {
qb.andWhere('1 = 0');
}
_iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
_ctx.prev = 5;
for(_iterator = this.orders[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
_value = _slicedToArray(_step.value, 2), key = _value[0], value = _value[1];
;
qb.addOrderBy((_key = this.columnNames[key]) !== null && _key !== void 0 ? _key : "".concat(qb.alias, ".").concat(key), value ? 'DESC' : 'ASC');
}
_ctx.next = 13;
break;
case 9:
_ctx.prev = 9;
_ctx.t0 = _ctx["catch"](5);
_didIteratorError = true;
_iteratorError = _ctx.t0;
case 13:
_ctx.prev = 13;
_ctx.prev = 14;
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
case 16:
_ctx.prev = 16;
if (!_didIteratorError) {
_ctx.next = 19;
break;
}
throw _iteratorError;
case 19:
return _ctx.finish(16);
case 20:
return _ctx.finish(13);
case 21:
hasPrev = false;
_ctx.next = 24;
return qb.clone().take(take + 1).getMany().then(function(nodes) {
if (nodes.length > take) {
hasPrev = true;
}
return nodes.slice(0, take).reverse();
});
case 24:
nodes2 = _ctx.sent;
_ctx.next = 27;
return qbForCount.getCount();
case 27:
_ctx.t1 = _ctx.sent;
_ctx.t2 = nodes2;
_ctx.t3 = hasPrev;
_ctx.t4 = nodes2.length > 0 ? this.transformer.stringify(this._createCursor(nodes2[0])) : null;
_ctx.t5 = nodes2.length > 0 ? this.transformer.stringify(this._createCursor(nodes2[nodes2.length - 1])) : null;
return _ctx.abrupt("return", {
count: _ctx.t1,
nodes: _ctx.t2,
hasPrev: _ctx.t3,
hasNext: true,
prevCursor: _ctx.t4,
nextCursor: _ctx.t5
});
case 33:
if (params.nextCursor) {
try {
this._applyWhereQuery(qb, this.transformer.parse(params.nextCursor), true);
} catch (e) {
qb.andWhere('1 = 0');
}
}
_iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
_ctx.prev = 35;
for(_iterator1 = this.orders[Symbol.iterator](); !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
_value1 = _slicedToArray(_step1.value, 2), key1 = _value1[0], value1 = _value1[1];
;
qb.addOrderBy((_key1 = this.columnNames[key1]) !== null && _key1 !== void 0 ? _key1 : "".concat(qb.alias, ".").concat(key1), value1 ? 'ASC' : 'DESC');
}
_ctx.next = 43;
break;
case 39:
_ctx.prev = 39;
_ctx.t6 = _ctx["catch"](35);
_didIteratorError1 = true;
_iteratorError1 = _ctx.t6;
case 43:
_ctx.prev = 43;
_ctx.prev = 44;
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
_iterator1.return();
}
case 46:
_ctx.prev = 46;
if (!_didIteratorError1) {
_ctx.next = 49;
break;
}
throw _iteratorError1;
case 49:
return _ctx.finish(46);
case 50:
return _ctx.finish(43);
case 51:
hasNext = false;
_ctx.next = 54;
return qb.clone().take(take + 1).getMany().then(function(nodes) {
if (nodes.length > take) {
hasNext = true;
}
return nodes.slice(0, take);
});
case 54:
nodes1 = _ctx.sent;
_ctx.next = 57;
return qbForCount.getCount();
case 57:
_ctx.t7 = _ctx.sent;
_ctx.t8 = nodes1.slice(0, take);
_ctx.t9 = !!params.nextCursor;
_ctx.t10 = hasNext;
_ctx.t11 = nodes1.length > 0 ? this.transformer.stringify(this._createCursor(nodes1[0])) : null;
_ctx.t12 = nodes1.length > 0 ? this.transformer.stringify(this._createCursor(nodes1[nodes1.length - 1])) : null;
return _ctx.abrupt("return", {
count: _ctx.t7,
nodes: _ctx.t8,
hasPrev: _ctx.t9,
hasNext: _ctx.t10,
prevCursor: _ctx.t11,
nextCursor: _ctx.t12
});
case 64:
case "end":
return _ctx.stop();
}
}, _callee, this, [
[
5,
9,
13,
21
],
[
14,
,
16,
20
],
[
35,
39,
43,
51
],
[
44,
,
46,
50
]
]);
}).bind(this))();
}
},
{
key: "promisePaginate",
value: function promisePaginate(qb) {
var params = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {
};
var _this2 = this;
var take = Math.max(this.takeOptions.min, Math.min(params.take || this.takeOptions.default, this.takeOptions.max));
var qbForCount = qb.clone();
if (params.prevCursor) {
var _this1 = this;
try {
this._applyWhereQuery(qb, this.transformer.parse(params.prevCursor), false);
} catch (e) {
qb.andWhere('1 = 0');
}
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
try {
for(var _iterator = this.orders[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
var _value = _slicedToArray(_step.value, 2), key = _value[0], value = _value[1];
var _key;
qb.addOrderBy((_key = this.columnNames[key]) !== null && _key !== void 0 ? _key : "".concat(qb.alias, ".").concat(key), value ? 'DESC' : 'ASC');
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally{
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally{
if (_didIteratorError) {
throw _iteratorError;
}
}
}
var cachePromiseNodes = null;
var promiseNodes = function() {
if (!cachePromiseNodes) {
var _this = _this1;
cachePromiseNodes = qb.clone().take(take + 1).getMany().then(function(nodes) {
var hasPrev = false;
if (nodes.length > take) {
hasPrev = true;
}
nodes = nodes.slice(0, take).reverse();
return {
nodes: nodes,
hasPrev: hasPrev,
hasNext: true,
prevCursor: nodes.length > 0 ? _this.transformer.stringify(_this._createCursor(nodes[0])) : null,
nextCursor: nodes.length > 0 ? _this.transformer.stringify(_this._createCursor(nodes[nodes.length - 1])) : null
};
});
}
return cachePromiseNodes;
};
return {
get count () {
return qbForCount.getCount();
},
get nodes () {
return promiseNodes().then(function(param) {
var nodes = param.nodes;
return nodes;
});
},
get hasPrev () {
return promiseNodes().then(function(param) {
var hasPrev = param.hasPrev;
return hasPrev;
});
},
get hasNext () {
return promiseNodes().then(function(param) {
var hasNext = param.hasNext;
return hasNext;
});
},
get prevCursor () {
return promiseNodes().then(function(param) {
var prevCursor = param.prevCursor;
return prevCursor;
});
},
get nextCursor () {
return promiseNodes().then(function(param) {
var nextCursor = param.nextCursor;
return nextCursor;
});
}
};
}
if (params.nextCursor) {
try {
this._applyWhereQuery(qb, this.transformer.parse(params.nextCursor), true);
} catch (e) {
qb.andWhere('1 = 0');
}
}
var _iteratorNormalCompletion2 = true, _didIteratorError2 = false, _iteratorError2 = undefined;
try {
for(var _iterator2 = this.orders[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true){
var _value2 = _slicedToArray(_step2.value, 2), key2 = _value2[0], value2 = _value2[1];
var _key2;
qb.addOrderBy((_key2 = this.columnNames[key2]) !== null && _key2 !== void 0 ? _key2 : "".concat(qb.alias, ".").concat(key2), value2 ? 'ASC' : 'DESC');
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally{
try {
if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
_iterator2.return();
}
} finally{
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
var cachePromiseNodes1 = null;
var promiseNodes1 = function() {
if (!cachePromiseNodes1) {
var _this = _this2;
cachePromiseNodes1 = qb.clone().take(take + 1).getMany().then(function(nodes) {
var hasNext = false;
if (nodes.length > take) {
hasNext = true;
}
nodes = nodes.slice(0, take);
return {
nodes: nodes.slice(0, take),
hasPrev: !!params.nextCursor,
hasNext: hasNext,
prevCursor: nodes.length > 0 ? _this.transformer.stringify(_this._createCursor(nodes[0])) : null,
nextCursor: nodes.length > 0 ? _this.transformer.stringify(_this._createCursor(nodes[nodes.length - 1])) : null
};
});
}
return cachePromiseNodes1;
};
return {
get count () {
return qbForCount.getCount();
},
get nodes () {
return promiseNodes1().then(function(param) {
var nodes = param.nodes;
return nodes;
});
},
get hasPrev () {
return promiseNodes1().then(function(param) {
var hasPrev = param.hasPrev;
return hasPrev;
});
},
get hasNext () {
return promiseNodes1().then(function(param) {
var hasNext = param.hasNext;
return hasNext;
});
},
get prevCursor () {
return promiseNodes1().then(function(param) {
var prevCursor = param.prevCursor;
return prevCursor;
});
},
get nextCursor () {
return promiseNodes1().then(function(param) {
var nextCursor = param.nextCursor;
return nextCursor;
});
}
};
}
},
{
key: "_applyWhereQuery",
value: function _applyWhereQuery(qb, cursor, isNext) {
var metadata = qb.expressionMap.mainAlias.metadata;
var queryPrefix = '';
var queryParts = [];
var queryParams = {
};
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
try {
for(var _iterator = this.orders[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
var _value = _slicedToArray(_step.value, 2), key = _value[0], asc = _value[1];
var _key;
var columnName = (_key = this.columnNames[key]) !== null && _key !== void 0 ? _key : "".concat(qb.alias, ".").concat(key);
queryParts.push("(".concat(queryPrefix).concat(columnName, " ").concat(!asc !== isNext ? '>' : '<', " :cursor__").concat(key, ")"));
queryPrefix = "".concat(queryPrefix).concat(columnName, " = :cursor__").concat(key, " AND ");
var column = metadata.findColumnWithPropertyPath(key);
queryParams["cursor__".concat(key)] = column ? qb.connection.driver.preparePersistentValue(cursor[key], column) : cursor[key];
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally{
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally{
if (_didIteratorError) {
throw _iteratorError;
}
}
}
qb.andWhere("(".concat(queryParts.join(' OR '), ")"), queryParams);
}
},
{
key: "_createCursor",
value: function _createCursor(node) {
var cursor = {
};
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
try {
for(var _iterator = this.orders[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
var _value = _slicedToArray(_step.value, 2), key = _value[0], _ = _value[1];
cursor[key] = node[key];
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally{
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally{
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return cursor;
}
}
]);
return CursorPaginator;
}();
exports.CursorPaginator = CursorPaginator;