@opengis/fastify-table
Version:
core-plugins
86 lines (85 loc) • 3.55 kB
JavaScript
import { getTemplate, getMeta, metaFormat, getAccess, applyHook, pgClients, } from "../../../../utils.js";
export default async function card(req, reply) {
const time = Date.now();
const { pg = pgClients.client, user, params = {}, query = {} } = req;
const hookData = (await applyHook("preCard", {
table: params?.table,
id: params?.id,
user,
}));
if (hookData?.message && hookData?.status) {
const response = hookData.status >= 400
? { error: hookData.message, code: hookData.status }
: hookData.message;
return reply.status(hookData.status).send(response);
}
const { actions = [], scope, my, } = (await getAccess({
table: hookData?.table || params.table,
id: hookData?.id || params?.id,
user,
})) || {};
if (!actions.includes("view") || (scope === "my" && !my)) {
return reply.status(403).send({ error: "access restricted", code: 403 });
}
const loadTable = await getTemplate("table", hookData?.table || params.table);
if (!loadTable) {
return reply.status(404).send({ error: "table not found", code: 404 });
}
const { table, columns, meta, sql, cardSql } = loadTable;
const { pk, columns: dbColumns = [] } = await getMeta(table);
if (!pk) {
return reply.status(404).send({ error: "table pk not found", code: 404 });
}
const cols = columns.map((el) => el.name || el).join(",");
const sqlTable = sql
?.filter?.((el) => !el?.disabled && el?.sql?.replace)
.map((el, i) => ` left join lateral (${el.sql}) ${el.name || `t${i}`} on 1=1 `)
?.join("") || "";
const cardSqlFiltered = hookData?.id || params.id
? cardSql?.filter?.((el) => !el?.disabled && el?.name && el?.sql?.replace)
: [];
const cardSqlTable = cardSqlFiltered?.length
? cardSqlFiltered
.map((el, i) => ` left join lateral (select json_agg(row_to_json(q)) as ${el.name} from (${el.sql})q) ct${i} on 1=1 `)
.join("") || ""
: "";
const where = [`"${pk}" = $1`, loadTable.query].filter((el) => el);
const cardColumns = cardSqlFiltered?.length
? `,${cardSqlFiltered.map((el) => el.name)}`
: "";
const q = `select ${pk ? `"${pk}" as id,` : ""} ${dbColumns.find((el) => el.name === "geom" && pg.pgType[el.dataTypeID] === "geometry")
? "st_asgeojson(geom)::json as geom,"
: ""} ${cols || "*"} ${cardColumns} from ${table} t ${sqlTable} ${cardSqlTable}
where ${where.join(" and ") || "true"} limit 1`;
if (query.sql === "1") {
return q;
}
const rows = await pg
.query(q, [hookData?.id || params.id])
.then((el) => el.rows || []);
await metaFormat({ rows, table: hookData?.table || params.table });
const data = meta?.card?.length
? meta.card
.filter((el) => columns.find((col) => col.name === el))
.reduce((acc, curr) => {
const colData = columns.find((col) => col.name === curr);
Object.assign(acc, {
[colData.ua || colData.name]: rows?.[0]?.[curr],
});
return acc;
}, {})
: {};
const afterHookData = await applyHook("afterCard", {
table: hookData?.table || params.table,
id: hookData?.id || params?.id,
user,
payload: {
time: Date.now() - time,
data,
},
});
return (afterHookData || {
time: Date.now() - time,
data,
});
}