lendb-server
Version:
`LenDB Server` is a wrapper around another database called Acebase that acts like a client. Think of it as parse-server and firebase had baby then voilah!!! `Hello World!!` LenDB is born.
892 lines (891 loc) • 40.3 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const cuid_1 = __importDefault(require("cuid"));
const lodash_1 = require("lodash");
class Serializer {
// protected Queue: { [ref: string]: Queue };
constructor(acebaseInstance, emitteryInstance, refHook, authHook, auth, link, publisher) {
this.acebase = acebaseInstance;
this.emitter = emitteryInstance;
this.refHooks = refHook;
this.authHook = authHook;
this.links = link;
this.auth = auth;
this.publisher = publisher;
// this.searchables = searchables;
}
async Execute(payload, server) {
try {
let result = {};
let resultArray = [];
if (Array.isArray(payload)) {
//run acl and schema validation here
//cache the old value and rollback when error occurs
for (const transaction of payload) {
if (!["save", "destroy"].includes(transaction?.operation)) {
throw new Error("Error: Invalid operation");
}
if (transaction?.operation == "save") {
resultArray.push(await this.Save(transaction, server));
}
else if (transaction?.operation == "destroy") {
resultArray.push(await this.Destroy(transaction, server));
}
}
return resultArray;
}
else {
const operations = ["save", "load", "query", "destroy", "exists"];
if (!payload?.operation || !operations.includes(payload?.operation)) {
return Promise.reject("Error: Invalid operation.");
}
let transaction = payload;
switch (transaction?.operation) {
case "save": {
result = await this.Save(transaction, server);
break;
}
case "query": {
result = await this.Query(transaction, server);
break;
}
case "load": {
result = await this.Load(transaction, server);
break;
}
case "exists": {
result = await this.Exists(transaction);
break;
}
case "destroy": {
result = await this.Destroy(transaction, server);
break;
}
case "aggregate": {
break;
}
default:
break;
}
}
return Promise.resolve(result);
}
catch (error) {
return Promise.reject(error);
}
}
ExecuteHook(event, ref, data, req, res, user) {
if (ref && typeof ref == "string" && event) {
return this.refHooks.find((h) => h.ref == ref && h.event == event)?.callback(data, req, res, user);
}
else if (event && !ref) {
this.authHook.find((a) => a.event == event)?.callback(data);
}
}
getData(transaction) {
let temp = transaction;
delete temp.operation;
delete temp._page;
delete temp.created_at;
delete temp.updated_at;
delete temp.created_by;
delete temp.updated_by;
delete temp.ref;
delete temp.singular;
delete temp.hook;
delete temp.rawData;
delete temp.emit;
delete temp.eventHandles;
delete temp.childPropsNames;
const entries = Object.entries(transaction);
for (const entry of entries) {
const key = entry[0];
const value = entry[0];
if (Array.isArray(value) && !value.length) {
delete transaction[key];
}
}
return temp;
}
async Destroy(transaction, server) {
try {
//! Must intercept the ref when they query keys that dont belong to them
//! when ACL implemented
let user = null;
if (this.auth?.enabled) {
let sentToken = server?.req.header("token");
if (sentToken) {
try {
user = await this.auth.GetUser(sentToken);
}
catch (error) {
return Promise.reject("Error: Access Denied");
}
}
else {
return Promise.reject("Error: Access Denied");
}
}
const { key, singular, eventHandles } = transaction;
let ref = this.sanitizeRefference(transaction?.ref);
//secure refs
if (ref.includes("__users__") || ref.includes("__tokens__")) {
return Promise.reject("Error: Cannot access secured refferences use instance.User() instead.");
}
//wilcard path
if (ref.includes("*")) {
return Promise.reject("Error: Commiting or deleting must not use wildcard within LenObject instance not allowed.");
}
//check if path have cuid
// if (singular) {
// const splitted = ref.split("/");
// if (splitted.some((r) => cuid.isCuid(r))) {
// return Promise.reject(
// "Error: Cannot save singular object reffered from a collection with cuid."
// );
// }
// }
// if(!singular){
// const splitted = ref.split("/")
// if(splitted.length > 1){
// if(cuid.isCuid(splitted[splitted.length - 1])){
// splitted.pop()
// ref = splitted.join("/")
// }
// }
// }
if (!singular) {
const splitted = ref.split("/");
if (splitted.length > 1) {
if (cuid_1.default.isCuid(splitted[splitted.length - 1])) {
splitted.pop();
ref = splitted.join("/");
}
}
}
// check cuid key
if (!cuid_1.default.isCuid(key) && !singular) {
return Promise.reject("Error: Invalid key for the collection. Key: " + key);
}
const hook = eventHandles?.hook;
const emit = eventHandles?.emit;
const executeHook = hook == undefined || (hook && typeof hook == "boolean");
const executeEmit = emit == undefined || (typeof emit == "boolean" && emit);
const hookRef = singular ? ref : this.toWildCardPath(ref);
const refference = singular ? ref : ref + "/" + key;
let instance = this.acebase.ref(refference);
let oldData = (await instance.get()).val();
if (singular) {
oldData = (await this.acebase.ref(ref).get()).val();
}
else {
if (key && cuid_1.default.isCuid(key) && ref && typeof ref == "string") {
let splitted = ref.split("/");
const last = splitted[splitted.length - 1];
if (cuid_1.default.isCuid(last)) {
splitted[splitted.length - 1] = key;
}
else {
splitted.push(key);
}
const joined = splitted.join("/");
oldData = (await this.acebase.ref(joined).get()).val();
}
}
if (executeHook)
this.ExecuteHook("beforeDestroy", hookRef, oldData, server?.req, server?.res, user);
await this.acebase.ref(refference).remove();
if (executeHook)
this.ExecuteHook("afterDestroy", hookRef, oldData, server?.req, server?.res, user);
//! access level permission when emitting for client side
if (executeEmit) {
this.emitter.emit("destroy:" + hookRef, oldData);
}
return Promise.resolve(oldData);
}
catch (error) {
return Promise.reject(error);
}
}
async Exists(transaction) {
try {
const { key, ref, singular } = transaction;
let result = false;
if (singular) {
result = await this.acebase.ref(ref).exists();
}
else {
let splitted = ref.split("/");
if (splitted.some((s) => s.includes("*"))) {
return Promise.reject("Wildcards not supported on checking if refference exists");
}
// if(cuid.isCuid(splitted[splitted.length - 1])) return Promise.reject("")
splitted.push(key);
const joined = splitted.join("/");
result = await this.acebase.ref(joined).exists();
}
return Promise.resolve(result);
}
catch (error) {
return Promise.reject(error);
}
}
async Load(transaction, server) {
try {
//! Must intercept the ref when the keys that dont belong to them
//! when ACL implemented
let user = null;
if (this.auth?.enabled) {
let sentToken = server?.req.header("token");
if (sentToken) {
try {
user = await this.auth.GetUser(sentToken);
}
catch (error) {
return Promise.reject("Error: Access Denied");
}
}
else {
return Promise.reject("Error: Access Denied");
}
}
const { key, singular, eventHandles } = transaction;
let ref = this.sanitizeRefference(transaction?.ref);
let result = {};
const hook = eventHandles?.hook;
const executeHook = hook == undefined || (hook && typeof hook == "boolean");
if (executeHook)
this.ExecuteHook("beforeLoad", this.toWildCardPath(ref), {}, server?.req, server?.res, user);
if (singular) {
result = (await this.acebase.ref(ref).get()).val();
}
else {
if (key && cuid_1.default.isCuid(key) && ref && typeof ref == "string") {
let splitted = ref.split("/");
const last = splitted[splitted.length - 1];
if (cuid_1.default.isCuid(last)) {
splitted[splitted.length - 1] = key;
}
else {
splitted.push(key);
}
const joined = splitted.join("/");
console.log(joined);
result = (await this.acebase.ref(joined).get()).val();
}
}
if (executeHook)
this.ExecuteHook("afterLoad", this.toWildCardPath(ref), {}, server?.req, server?.res, user);
return Promise.resolve(result);
}
catch (error) {
return Promise.reject(error);
}
}
async Save(transaction, server) {
try {
//! Must intercept the ref when they query keys that dont belong to them
//! when ACL implemented
let user = null;
if (this.auth?.enabled) {
let sentToken = server?.req.header("token");
if (sentToken) {
try {
user = await this.auth.GetUser(sentToken);
}
catch (error) {
return Promise.reject("Error: Access Denied");
}
}
else {
return Promise.reject("Error: Access Denied");
}
}
const { eventHandles, key, singular } = transaction;
let ref = this.sanitizeRefference(transaction.ref);
//wilcard path
if (ref.includes("*")) {
return Promise.reject("Error: Adding or Updating must not contain wildcard path");
}
//check if path have cuid
// if (singular) {
// const splitted = ref.split("/");
// if (splitted.some((r) => cuid.isCuid(r))) {
// return Promise.reject(
// "Error: Cannot save singular object reffered from a collection with cuid."
// );
// }
// }
//cuid key check
if (!cuid_1.default.isCuid(key) && !singular) {
return Promise.reject("Error: Invalid key for the collection.");
}
const hook = eventHandles?.hook;
const emit = eventHandles?.emit;
const queue = eventHandles?.queue;
const executeHook = hook == undefined || (typeof hook == "boolean" && hook);
const executeEmit = emit == undefined || (typeof emit == "boolean" && emit);
let data = this.getData(Object.assign({}, transaction));
const hookRef = singular ? ref : this.toWildCardPath(ref);
const refference = singular ? ref : ref + "/" + key;
!singular || delete data.key;
let instance = this.acebase.ref(refference);
const exists = await instance.exists();
const event = {
before: exists ? "beforeUpdate" : "beforeAdd",
after: exists ? "afterUpdate" : "afterAdd",
};
if (executeHook) {
const hookData = await this.ExecuteHook(event.before, hookRef, data, server?.req, server?.res, user);
if (hookData && (0, lodash_1.isObject)(hookData) && !(0, lodash_1.isDate)(hookData)) {
console.log(hookData);
Object.assign(data, hookData);
}
}
if (exists)
data.updated_at = new Date(Date.now());
else
data.created_at = new Date(Date.now());
for (const entry of Object.entries(data)) {
//@ts-ignore
if ((0, lodash_1.isDate)(entry[0])) {
//@ts-ignore
data[entry[0]] = new Date(entry[1]);
}
}
this.ProcessLink(refference, key, data);
await this.ProcessLink(ref, key, data);
if (exists)
instance.update(data);
else
instance.set(data);
if (!singular) {
let indexes = await this.acebase.indexes.get();
if (!indexes.find((i) => {
return i.path == ref && key == "key";
})) {
this.acebase.indexes.create(ref, "key");
}
}
let returnData = (await instance.get()).val();
if (executeHook) {
await this.ExecuteHook(event.after, hookRef, returnData, server?.req, server?.res, user);
}
//! access level permission when emitting for client side
if (executeEmit) {
if (exists) {
this.emitter.emit("update:" + hookRef, returnData);
}
else {
this.emitter.emit("add:" + hookRef, returnData);
}
}
return Promise.resolve(returnData);
}
catch (error) {
return Promise.reject(error);
}
}
async Upload(req, res, uploadPath) {
try {
//@ts-ignore
// await req.session.start();
await req.multipart(async (arrbuff) => {
try {
let file = arrbuff.file;
if (file) {
let tempFilename = file?.name;
if (typeof tempFilename == "string" && tempFilename.split("-$-").length == 2) {
let splitted = tempFilename.split("-$-");
let key = splitted[0];
let filename = splitted[1];
let ext = filename.substring(filename.lastIndexOf("."));
let savename = (0, cuid_1.default)();
ext = ext.split(" ").join("");
if (ext != filename)
savename = savename + ext;
savename = savename.split(" ").join("");
let props = {
key,
filename,
savename,
};
if (await this.acebase.ref("__uploads__/" + key).exists()) {
res.json({ key, filename, url: savename });
}
await arrbuff.write(uploadPath + savename);
await this.acebase.ref("__uploads__/" + key).set(props);
res.end(JSON.stringify({
key,
filename,
url: savename,
}));
}
else {
throw new Error("Error: Invalid File");
}
}
else {
res.sendStatus(500);
res.send("Error: file required");
}
}
catch (error) {
throw Error(error);
}
});
}
catch (error) {
res.end(error);
throw error;
}
}
// protected aggregatedQuery() {}
generateSearchString(data) {
if ((0, lodash_1.isObject)(data) && !(0, lodash_1.isDate)(data)) {
let word = "";
let values = Object.values(data);
for (const value of values) {
if (typeof value == "string" || typeof value == "number") {
word = word + value;
}
}
return word;
}
else {
return null;
}
}
//implement last and first query
//delete where
async ProcessLink(ref, key, data) {
try {
if (!(0, lodash_1.isObject)(data) || (0, lodash_1.isDate)(data)) {
return Promise.resolve(null);
}
let wildcardRef = this.toWildCardPath(ref);
let fromSource = this.links.filter((link) => link.source == wildcardRef);
let fromTarget = this.links.find((link) => link.target == wildcardRef);
if (fromSource.length) {
//get the targets and set the update
for (const source of fromSource) {
let updates = {};
for (const field of source.fields) {
const { sourceField, targetField } = field;
if (sourceField in data) {
updates[targetField] = data[sourceField];
}
}
const targets = await this.acebase.query(source.target).filter(source.identity, "==", key).find();
for (const snap of targets) {
await snap.update(updates);
}
}
}
if (fromTarget) {
//get the value from source then set to target
let target = fromTarget;
const sourceKey = data[target.identity];
if (!sourceKey) {
return Promise.reject(null);
}
let source = (await this.acebase.query(target.source).filter("key", "==", sourceKey).get())[0].val();
for (const field of target.fields) {
const { sourceField, targetField } = field;
if (sourceField in source) {
data[targetField] = source[sourceField];
}
}
return Promise.resolve(data);
}
}
catch (error) {
return Promise.reject(error);
}
}
async autoIndex(path, data) {
try {
if ((0, lodash_1.isObject)(data)) {
const dataArr = Object.entries(data);
for (const arr of dataArr) {
const field = arr[0];
const value = arr[1];
path = this.toWildCardPath(path);
if ((0, lodash_1.isObject)(value)) {
await this.autoIndex(path + "/" + field, value);
}
else if (Array.isArray(value)) {
this.acebase.indexes.create(path, field, {
type: "array",
});
}
else {
this.acebase.indexes.create(path, field);
}
}
}
return Promise.resolve(true);
}
catch (error) {
return Promise.reject(error);
}
}
toWildCardPath(ref) {
return ref
.split("/")
.map((r) => {
return cuid_1.default.isCuid(r) ? "*" : r;
})
.join("/");
}
sanitizeRefference(ref) {
if (ref.startsWith("/")) {
ref = ref.substring(1);
}
if (ref.endsWith("/"))
ref = ref.substring(0, ref.length - 1);
return ref;
}
async Query(transaction, server) {
try {
const { ref, hook } = transaction;
if (ref.includes("__users__") || ref.includes("__tokens__")) {
return Promise.reject("Error: cannot access secured refferences use instance.User() instead.");
}
let clone = (0, lodash_1.cloneDeep)(transaction);
let queryRef = this.acebase.query(ref);
const executeHook = hook == undefined || (typeof hook == "boolean" && hook);
if (executeHook) {
const hookedQuery = this.ExecuteHook("beforeFind", ref, clone, server?.req, server?.res);
if (hookedQuery) {
clone = hookedQuery;
}
}
queryRef = this.applyFilters(clone, queryRef);
const { aggregates, limit, exclusion, inclusion } = clone;
let count = 0;
let data = [];
if ((0, lodash_1.isObject)(aggregates) && !(0, lodash_1.isDate)(aggregates)) {
queryRef.take(Infinity);
let groups = {};
let countRefs = {};
let sumRefs = {};
let undefinedRefs = {};
//@ts-ignore
let inclusions = [aggregates.groupBy];
//@ts-ignore
for (const aggregation of aggregates.list) {
if (!inclusions.includes(aggregation.field) && aggregation.type != "COUNT") {
inclusions.push(aggregation.field);
}
}
//@ts-ignore
const groupKey = aggregates.groupBy;
let searchedGroup = [];
//unwind group keys
const searchAndGroup = async (groupRes) => {
try {
let tempGroups = groupRes;
let groupQuery = this.applyFilters(clone, this.acebase.query(ref));
if (tempGroups.length) {
groupQuery.filter(groupKey, "!in", tempGroups);
}
groupQuery.take(Infinity);
await groupQuery.forEach({ include: inclusions }, async (snap) => {
if (Object.keys(tempGroups).length == limit) {
return false;
}
let value = snap.val();
let group = value != undefined ? value[groupKey] : null;
if (group != undefined && !tempGroups.includes(group)) {
tempGroups.push(group);
await searchAndGroup(tempGroups);
return false;
}
});
searchedGroup = [...tempGroups];
return Promise.resolve(false);
}
catch (error) {
throw error;
}
};
await searchAndGroup(searchedGroup);
for (const sg of searchedGroup) {
groups[sg] = {};
}
if (!searchedGroup.length) {
data = [];
count = 0;
}
else {
await queryRef.filter("type", "in", searchedGroup).forEach({ include: inclusions }, (snap) => {
if (Object.keys(groups).length == limit) {
return false;
}
let value = snap.val();
let group = value[groupKey];
//@ts-ignore
for (const aggregation of aggregates.list) {
if (!(aggregation.alias in groups[group])) {
if (aggregation.operation == "MIN") {
groups[group][aggregation.alias] = value[aggregation.field];
}
else if (aggregation.operation == "MAX") {
groups[group][aggregation.alias] = value[aggregation.field];
}
else if (aggregation.operation == "SUM") {
groups[group][aggregation.alias] = value[aggregation.field];
}
else if (aggregation.operation == "AVG") {
if (!(`${group}.${aggregation.alias}` in undefinedRefs))
undefinedRefs[`${group}.${aggregation.alias}`] = aggregation.operation;
if (!(`${group}.${aggregation.alias}` in sumRefs)) {
sumRefs[`${group}.${aggregation.alias}`] = value[aggregation.field];
}
else {
sumRefs[`${group}.${aggregation.alias}`] += value[aggregation.field];
}
}
else if (aggregation.operation == "COUNT" || aggregation.operation == "AVG") {
if (!(`${group}.${aggregation.alias}` in undefinedRefs))
undefinedRefs[`${group}.${aggregation.alias}`] = aggregation.operation;
if (!(group in countRefs)) {
countRefs[group] = 1;
}
else {
countRefs[group] += 1;
}
}
}
else {
if (aggregation.operation == "MIN") {
groups[group][aggregation.alias] =
groups[group][aggregation.alias] < value[aggregation.field]
? groups[group][aggregation.alias]
: value[aggregation.field];
}
else if (aggregation.operation == "MAX") {
groups[group][aggregation.alias] =
groups[group][aggregation.alias] > value[aggregation.field]
? groups[group][aggregation.alias]
: value[aggregation.field];
}
else if (aggregation.operation == "SUM") {
groups[group][aggregation.alias] =
groups[group][aggregation.alias] + value[aggregation.field];
}
else if (aggregation.operation == "AVG") {
if (!(`${group}.${aggregation.alias}` in undefinedRefs))
undefinedRefs[`${group}.${aggregation.alias}`] = aggregation.operation;
if (!(`${group}.${aggregation.alias}` in sumRefs)) {
sumRefs[`${group}.${aggregation.alias}`] = value[aggregation.field];
}
else {
sumRefs[`${group}.${aggregation.alias}`] += value[aggregation.field];
}
}
else if (aggregation.operation == "COUNT") {
if (!(`${group}.${aggregation.alias}` in undefinedRefs))
undefinedRefs[`${group}.${aggregation.alias}`] = aggregation.operation;
if (!(group in countRefs)) {
countRefs[group] = 1;
}
else {
countRefs[group] += 1;
}
}
}
}
});
for (const undefinedRef of Object.entries(undefinedRefs)) {
let keySplit = undefinedRef[0].split(".");
const group = keySplit[0];
const alias = keySplit[1];
const op = undefinedRef[1];
let count = countRefs[group];
let avg = sumRefs[undefinedRef[0]] / count;
if (count == undefined) {
//throw error
}
if (typeof avg != "number" || avg == NaN) {
//throw error
}
if (!groups[group])
groups[group] = {};
if (op == "AVG")
groups[group][alias] = avg;
if (op == "COUNT")
groups[group][alias] = count;
}
count = Object.entries(groups).length;
data = Object.entries(groups).map((g) => {
//@ts-ignore
return { [groupKey]: g[0], ...g[1] };
});
}
}
else {
if (transaction?.compoundFilter?.length) {
let compoundResult = await this.compound(transaction);
data = compoundResult.data;
count = compoundResult.count;
}
else {
if ((Array.isArray(exclusion) && exclusion.length) || (Array.isArray(inclusion) && inclusion.length)) {
if (exclusion?.length && inclusion?.length) {
data = (await queryRef.get({
exclude: exclusion,
include: inclusion,
})).map((snap) => snap.val());
}
else if (exclusion?.length) {
data = (await queryRef.get({ exclude: exclusion })).map((snap) => snap.val());
}
else if (inclusion?.length) {
data = (await queryRef.get({ include: inclusion })).map((snap) => snap.val());
}
}
else {
data = (await queryRef.get()).map((snap) => snap.val());
}
queryRef.take(Infinity);
count = await queryRef.count();
}
}
//! todo return decorated data
if (executeHook) {
const afterHookData = this.ExecuteHook("afterFind", ref, { data, count }, server?.req, server?.res);
if (Array.isArray(afterHookData?.data) && (0, lodash_1.isNumber)(afterHookData?.count)) {
return {
data: afterHookData.data,
count: afterHookData.count,
};
}
}
return { data, count };
}
catch (error) {
if (error?.message.startsWith("Error: This wildcard path query on"))
return Promise.resolve({ data: [], count: 0 });
throw new Error(error);
}
}
async compound(transaction) {
try {
let queryResults = [];
let keys = [];
let count = 0;
for (const filter of transaction.compoundFilter) {
let tempQuery = this.acebase.query(transaction.ref);
tempQuery = this.applyFilters(transaction, tempQuery);
let resultkeys = queryResults.map(qr => qr.key);
if (queryResults.length && resultkeys.length) {
tempQuery.filter("key", "!in", resultkeys);
}
tempQuery.filter(filter[0], filter[1], filter[2]);
keys = (0, lodash_1.uniq)([...keys, ...(await tempQuery.find()).map(dr => dr.key)]);
count += await tempQuery.take(Infinity).count();
}
const { exclusion, inclusion } = transaction;
if ((Array.isArray(exclusion) && exclusion.length) || (Array.isArray(inclusion) && inclusion.length)) {
if (exclusion?.length && inclusion?.length) {
queryResults = (await Promise.all(keys.map(key => {
return this.acebase.ref(transaction.ref + "/" + key).get({ include: inclusion, exclude: exclusion });
}))).map(ds => ds.val());
}
else if (exclusion?.length) {
queryResults = (await Promise.all(keys.map(key => {
return this.acebase.ref(transaction.ref + "/" + key).get({ exclude: exclusion });
}))).map(ds => ds.val());
}
else if (inclusion?.length) {
queryResults = (await Promise.all(keys.map(key => {
return this.acebase.ref(transaction.ref + "/" + key).get({ include: inclusion });
}))).map(ds => ds.val());
}
}
else {
queryResults = (await Promise.all(keys.map(key => {
return this.acebase.ref(transaction.ref + "/" + key).get();
}))).map(ds => ds.val());
}
if (transaction?.sorts?.length) {
const sortingKeys = transaction.sorts.map((t) => t[0]);
const sortingValues = transaction.sorts.map((t) => (t[1] ? "asc" : "desc"));
queryResults = (0, lodash_1.orderBy)(queryResults, sortingKeys, sortingValues);
}
else {
queryResults = (0, lodash_1.orderBy)(queryResults, ["rev_ticks", "asc"]);
}
queryResults = queryResults.slice(0, transaction?.limit);
return Promise.resolve({ data: queryResults, count });
}
catch (error) {
return Promise.reject(error);
}
}
async LivePayload(transaction, eventEmitted) {
try {
let index = -1;
let count = 0;
let data = [];
let newData = {};
//@ts-ignore
delete transaction.subscriptionKey;
//@ts-ignore
transaction.live = false;
let res = await this.Query(transaction, null);
if (eventEmitted?.snapshot) {
if (Object.keys(eventEmitted.snapshot.val()).length == 1) {
newData = (await eventEmitted.snapshot.ref.get()).val();
}
else
newData = eventEmitted.snapshot.val();
}
else {
newData = (await eventEmitted.ref.get()).val();
}
index = res.data.findIndex((v) => v == newData.key);
data = res.data;
count = res.count;
return { newData, count, index, data };
}
catch (error) {
return Promise.reject(error);
}
}
applyFilters(payload, queryRef) {
//! Must intercept the filters when they query keys that dont belong to them
//! when ACL implemented
if (Array.isArray(payload?.filters) && payload?.filters.length) {
payload.filters.forEach((f) => {
queryRef.filter(f[0], f[1], f[2]);
});
}
if (Array.isArray(payload?.sorts)) {
payload.sorts.forEach((s) => {
if (s.length > 1)
queryRef.sort(s[0], s[1]);
else
queryRef.sort(s[0]);
});
}
queryRef.take(payload?.limit || 100);
queryRef.skip(payload?.skip || 0);
if (payload?.page && payload?.page > 1) {
if (payload?.take)
queryRef.skip((payload?.page - 1) * payload?.limit);
else
queryRef.skip((payload?.page - 1) * 100);
}
else {
queryRef.skip(0);
}
return queryRef;
}
}
exports.default = Serializer;