stackpress
Version:
Incept is a content management framework.
171 lines (170 loc) • 9.25 kB
JavaScript
;
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);
}
});
}
;