UNPKG

stackpress

Version:

Incept is a content management framework.

171 lines (170 loc) 9.25 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = search; const Nest_1 = __importDefault(require("@stackpress/lib/Nest")); const helpers_js_1 = require("../helpers.js"); function search(model_1, engine_1) { return __awaiter(this, arguments, void 0, function* (model, engine, query = {}, seed) { let { q, columns = ['*'], filter = {}, span = {}, sort = {}, skip = 0, take = 50, total: useTotal = true } = query; columns = columns.map(column => (0, helpers_js_1.getColumns)(column, model)).flat(); const info = columns .map(column => (0, helpers_js_1.getColumnInfo)(column, model)) .filter(column => column.path.length > 0); const selectors = info.map(selector => { const q = engine.dialect.q; const column = selector.table.length > 0 ? `${q}${selector.table}${q}.${q}${selector.column}${q}` : `${q}${model.snake}${q}.${q}${selector.column}${q}`; return `${column} AS ${q}${selector.alias}${q}`; }); const select = engine.select(selectors).from(model.snake); const count = engine .select('COUNT(*) as total') .from(model.snake); const joins = {}; info.forEach(selector => Object.assign(joins, selector.joins)); Object.values(joins).forEach(({ table, from, to, alias }) => { const q = engine.dialect.q; select.join('inner', table, from.replaceAll('.', `${q}.${q}`), to.replaceAll('.', `${q}.${q}`), alias); count.join('inner', table, from.replaceAll('.', `${q}.${q}`), to.replaceAll('.', `${q}.${q}`), alias); }); if (skip) { select.offset(skip); } if (take) { select.limit(take); } if (q && model.searchables.length > 0) { select.where(model.searchables.map(column => `${column.snake} ILIKE ?`).join(' OR '), model.searchables.map(_ => `%${q}%`)); count.where(model.searchables.map(column => `${column.snake} ILIKE ?`).join(' OR '), model.searchables.map(_ => `%${q}%`)); } if (model.active) { if (typeof filter[model.active.name] === 'undefined') { filter[model.active.name] = true; } else if (filter[model.active.name] == -1) { delete filter[model.active.name]; } } Object.entries(filter).forEach(([key, value]) => { var _a; const info = (0, helpers_js_1.getColumnInfo)(key, model).last; if (!info) return; const q = engine.dialect.q; const selector = `${q}${info.model.snake}${q}.${q}${info.column.snake}${q}`; value = info.column.serialize(value, undefined, seed); const serialized = helpers_js_1.stringable.includes(info.column.type) ? (0, helpers_js_1.toSqlString)(value) : helpers_js_1.floatable.includes(info.column.type) ? (0, helpers_js_1.toSqlFloat)(value) : helpers_js_1.intable.includes(info.column.type) ? (0, helpers_js_1.toSqlInteger)(value) : helpers_js_1.boolable.includes(info.column.type) ? (0, helpers_js_1.toSqlBoolean)(value) : helpers_js_1.dateable.includes(info.column.type) ? (_a = (0, helpers_js_1.toSqlDate)(value)) === null || _a === void 0 ? void 0 : _a.toISOString() : String(value); if (typeof serialized !== 'undefined' && serialized !== '') { select.where(`${selector} = ?`, [serialized]); count.where(`${selector} = ?`, [serialized]); } }); Object.entries(span).forEach(([key, values]) => { var _a, _b; const info = (0, helpers_js_1.getColumnInfo)(key, model).last; if (!info) return; const q = engine.dialect.q; const selector = `${q}${info.model.snake}${q}.${q}${info.column.snake}${q}`; if (typeof values[0] !== 'undefined' && values[0] !== null && values[0] !== '') { const value = info.column.unserialize(values[0], undefined, seed); const serialized = helpers_js_1.stringable.includes(info.column.type) ? (0, helpers_js_1.toSqlString)(value) : helpers_js_1.floatable.includes(info.column.type) ? (0, helpers_js_1.toSqlFloat)(value) : helpers_js_1.intable.includes(info.column.type) ? (0, helpers_js_1.toSqlInteger)(value) : helpers_js_1.boolable.includes(info.column.type) ? (0, helpers_js_1.toSqlBoolean)(value) : helpers_js_1.dateable.includes(info.column.type) ? (_a = (0, helpers_js_1.toSqlDate)(value)) === null || _a === void 0 ? void 0 : _a.toISOString() : String(value); if (typeof serialized !== 'undefined' && serialized !== '') { select.where(`${selector} >= ?`, [serialized]); count.where(`${selector} >= ?`, [serialized]); } } if (typeof values[1] !== 'undefined' && values[1] !== null && values[1] !== '') { const value = info.column.unserialize(values[1], undefined, seed); const serialized = helpers_js_1.stringable.includes(info.column.type) ? (0, helpers_js_1.toSqlString)(value) : helpers_js_1.floatable.includes(info.column.type) ? (0, helpers_js_1.toSqlFloat)(value) : helpers_js_1.intable.includes(info.column.type) ? (0, helpers_js_1.toSqlInteger)(value) : helpers_js_1.boolable.includes(info.column.type) ? (0, helpers_js_1.toSqlBoolean)(value) : helpers_js_1.dateable.includes(info.column.type) ? (_b = (0, helpers_js_1.toSqlDate)(value)) === null || _b === void 0 ? void 0 : _b.toISOString() : String(value); if (typeof serialized !== 'undefined') { select.where(`${selector} <= ?`, [serialized]); count.where(`${selector} <= ?`, [serialized]); } } }); Object.entries(sort).forEach(([key, value]) => { const direction = typeof value === 'string' ? value : ''; if (direction.toLowerCase() !== 'asc' && direction.toLowerCase() !== 'desc') { return; } const info = (0, helpers_js_1.getColumnInfo)(key, model).last; if (!info) return; const q = engine.dialect.q; const selector = `${info.model.snake}${q}.${q}${info.column.snake}`; select.order(selector, direction.toUpperCase()); }); try { const results = yield select; const total = useTotal ? yield count : [{ total: 0 }]; const rows = []; results.forEach(row => { const nest = new Nest_1.default(); Object.entries(row).forEach(([alias, value]) => { const selector = info.find(selector => selector.alias === alias); if (!selector) { return nest.withPath.set(alias.trim() .replaceAll('__', '.') .replace(/([a-z])_([a-z0-9])/ig, (_, a, b) => a + b.toUpperCase()), value); } nest.withPath.set(selector.name, selector.last.column.unserialize(value, undefined, seed)); }); rows.push(nest.get()); }); return (0, helpers_js_1.toResponse)(rows, Number(total[0].total) || undefined); } catch (e) { return (0, helpers_js_1.toErrorResponse)(e); } }); } ;