objection-paginator
Version:
Paginated queries for Objection.js
113 lines • 4.03 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Paginator = void 0;
const lodash_1 = __importDefault(require("lodash"));
const cursor_js_1 = require("./cursor.js");
const invalid_cursor_error_js_1 = require("./invalid-cursor-error.js");
const unknown_sort_error_js_1 = require("./unknown-sort-error.js");
const create_sort_node_js_1 = require("./create-sort-node.js");
class Paginator {
constructor(options = {}, ...rest) {
const { limit, sort } = options;
Object.defineProperties(this, {
limit: { value: limit || 1000, enumerable: true },
sort: { value: sort || "default", enumerable: true },
args: { value: rest[0], enumerable: true, writable: true },
});
}
static async getPage(options, ...rest) {
return new this(options, ...rest).execute(options && options.cursor);
}
static _getQueryName() {
return this.queryName || this.name;
}
static _createSortNodes() {
return this.sorts ? lodash_1.default.mapValues(this.sorts, create_sort_node_js_1.createSortNode) : {};
}
static _getSortNodes() {
let nodes = this._sortNodes;
if (!nodes)
nodes = this._sortNodes = this._createSortNodes();
return nodes;
}
get _cls() {
return this.constructor;
}
async execute(cursor) {
const qry = this._getQuery(cursor);
const items = await qry;
const lastItem = lodash_1.default.last(items);
let remaining = 0;
if (lastItem) {
remaining = await this._getRemainingCount(qry, items.length);
cursor = this._createCursorString(lastItem);
}
else if (!cursor) {
cursor = this._createCursorString();
}
return { items, remaining, cursor };
}
_getSortNode() {
const node = this._cls._getSortNodes()[this.sort];
if (node)
return node;
throw new unknown_sort_error_js_1.UnknownSortError({ info: { sort: this.sort } });
}
_createCursor(item) {
return new cursor_js_1.Cursor(this._cls._getQueryName(), this.sort, item && this._getSortNode().getCursorValues(item));
}
_createCursorString(item) {
return this._createCursor(item).serialize();
}
_validateCursor(cursor) {
const queryName = this._cls._getQueryName();
if (cursor.query !== queryName) {
throw new invalid_cursor_error_js_1.InvalidCursorError({
shortMessage: "Cursor is for a different query",
info: {
cursorQuery: cursor.query,
expectedQuery: queryName,
},
});
}
if (cursor.sort !== this.sort) {
throw new invalid_cursor_error_js_1.InvalidCursorError({
shortMessage: "Cursor is for a different sort",
info: {
cursorSort: cursor.sort,
expectedSort: this.sort,
},
});
}
return cursor;
}
_parseCursor(str) {
return this._validateCursor(cursor_js_1.Cursor.parse(str));
}
_getCursorValues(str) {
if (!lodash_1.default.isNil(str))
return this._parseCursor(str).values;
}
_applySortNode(qry, cursor) {
this._getSortNode().apply(qry, this._getCursorValues(cursor));
}
_applyLimit(qry) {
qry.limit(this.limit);
}
_getQuery(cursor) {
const qry = this.getBaseQuery();
this._applySortNode(qry, cursor);
this._applyLimit(qry);
return qry;
}
async _getRemainingCount(qry, itemCount) {
if (itemCount < this.limit)
return 0;
return await qry.resultSize() - itemCount;
}
}
exports.Paginator = Paginator;
//# sourceMappingURL=paginator.js.map