@opengis/fastify-table
Version:
core-plugins
113 lines (112 loc) • 4.52 kB
JavaScript
import { getTemplate, getMeta, metaFormat, applyHook, handlebars, pgClients, } from "../../../../utils.js";
export default async function tableInfo({ pg = pgClients.client, params, query = {}, user = {}, }, reply) {
const time = Date.now();
const { uid } = user;
if (!uid) {
return reply.status(403).send("access restricted: uid");
}
if (!params?.id || !params?.table) {
return reply.status(400).send("not enougn params");
}
const loadTable = await getTemplate("table", params.table);
if (!loadTable) {
return reply.status(404).send("template not found");
}
const { table, columns = [], sql, cardSql, filters, form, meta, public: ispublic, } = loadTable;
if (!meta?.info) {
return reply.status(400).send("empty meta info");
}
const tableMeta = await getMeta({ pg, table });
if (tableMeta?.view) {
if (!loadTable?.key) {
return reply.status(404).send(`key not found: ${table}`);
}
Object.assign(tableMeta, { pk: loadTable?.key });
}
const { pk } = tableMeta || {};
if (!pk) {
return reply.status(404).send(`table not found: ${table}`);
}
const sqlTable = sql
?.filter?.((el) => !el?.disabled && el?.sql?.replace)
?.map((el, i) => ` left join lateral (${el.sql.replace("{{uid}}", uid)}) ${el.name || `t${i}`} on 1=1 `)
?.join("") || "";
const cardSqlFiltered = params.id
? cardSql?.filter?.((el) => !el?.disabled && el?.name && el?.sql?.replace) || []
: [];
const cardSqlTable = cardSqlFiltered.length
? cardSqlFiltered
.map((el, i) => ` left join lateral (${el.sql.replace("{{uid}}", uid)}) ct${i} on 1=1 `)
.join("\n") || ""
: "";
const interfaceQuery = params?.query
? await handlebars.compile(params?.query)({ user, uid })
: undefined;
const where = [
params.id ? `"${pk}" = $1` : null,
loadTable.query,
interfaceQuery,
]
.filter((el) => el)
.filter((el) => user?.user_type === "superadmin" ? !el.includes("{{uid}}") : true);
const { fields = [] } = await pg.query(`select * from ${table} where ${sqlTable ? "true" : where.join(" and ") || "true"} limit 0`, [sqlTable ? null : params.id].filter((el) => el));
const columnList = fields.map((el) => el.name);
const metaInfoCols = meta.info
.split(",")
.filter((el) => columnList.includes(el))
.map((el) => `"${el}"`);
if (!metaInfoCols.length) {
return reply.status(400).send("invalid meta info: columns not found");
}
const q = `select ${pk ? `"${pk}" as id,` : ""}
${metaInfoCols.join(",")}
from (select * from ${table} where ${sqlTable ? "true" : where.join(" and ") || "true"}) t
${sqlTable}
${cardSqlTable}
where ${where.join(" and ") || "true"}
limit 1`.replace(/{{uid}}/g, uid);
if (query.sql === "1") {
return q;
}
const { rows } = await pg.query(q, [params.id]);
const qCount = `select
count(*)::int as total,
count(*) FILTER(WHERE ${[interfaceQuery].filter((el) => el).join(" and ") || "true"})::int as filtered
from ${table} t ${sqlTable}
where ${[loadTable.query].filter((el) => el).join(" and ") || "true"} `.replace(/{{uid}}/g, uid);
const { total, filtered } = params.id
? rows.length
: await pg
.queryCache?.(qCount, { table: loadTable.table, time: 5 })
.then((el) => el?.rows?.[0] || {});
const cls = meta.info
.split(",")
.filter((el) => columnList.includes(el))
.map((el) => ({
name: el,
data: columns.find((col) => col.name === el)?.data,
}))
.filter((el) => el.data)
.reduce((acc, curr) => Object.assign(acc, { [curr.name]: curr.data }), {});
await metaFormat({ rows, cls /* , sufix: false */ }, pg);
const res = {
time: Date.now() - time,
public: ispublic,
card: loadTable.card,
total,
filtered,
count: rows.length,
pk,
form,
rows,
meta,
columns,
filters,
};
const result = await applyHook("afterData", {
table: loadTable.table,
payload: res,
user,
});
return result || res;
}