UNPKG

@opengis/fastify-table

Version:

core-plugins

86 lines (85 loc) 3.55 kB
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, }); }