UNPKG

@opengis/fastify-table

Version:

core-plugins

161 lines (160 loc) 6.37 kB
import { config, getAccess, getTemplate, getMeta, setToken, applyHook, getToken, pgClients, } from "../../../../utils.js"; import extraDataGet from "../../../plugins/extra/extraDataGet.js"; export default async function tableAPI(req, reply, called) { const { pg = pgClients.client, params, user = {}, query = {} } = req; const tokenData = await getToken({ token: params?.table, uid: user.uid, json: 1, }); const hookData = (await applyHook("preTable", { pg, table: params?.table, id: params?.id, ...(tokenData || {}), user, })); if (hookData?.message && hookData?.status) { return reply.status(hookData?.status).send(hookData?.message); } const templateName = hookData?.table || tokenData?.table || params.table; const loadTable = await getTemplate("table", templateName); if (!loadTable && !pg.pk?.[tokenData?.table] && !(pg.pk?.[templateName] && called)) { return reply.status(404).send({ error: "not found", code: 404 }); } const { table: table1 = params.table, form: form1, obj, } = hookData || loadTable || tokenData || {}; const table = loadTable?.table || table1; const form = loadTable?.form || form1; const id = hookData?.id || tokenData?.id || params.id; if (tokenData && !id) { return reply.status(403).send({ error: "invalid token", code: 403 }); } if (!table && !id) { return reply.status(400).send("not enough params"); } const { actions = [], query: accessQuery } = (await getAccess({ table: templateName, form, id, user, }, pg)) || {}; if (!tokenData && !config?.local && !config.security?.disableToken && !called) { return reply.status(400).send("invalid token"); } if (!actions.includes("edit") && !config?.local && !tokenData && !called) { return reply .status(403) .send({ error: "access restricted: actions", code: 403 }); } const { pk, columns: dbColumns = [] } = await getMeta({ pg, table, }); if (!pk) { return reply .status(404) .send({ error: `table not found: ${table}`, code: 404 }); } // const cols = columns.map((el) => el.name || el).join(','); const formData = (await getTemplate("form", form)) || {}; const schema = formData?.schema || formData || {}; // skip DataTable from another table const extraKeys = Object.keys(schema).filter((key) => schema[key]?.table && schema[key]?.parent_id && Object.hasOwn(schema[key], "colModel")); // skip non-existing columns const columnList = dbColumns.map((el) => el.name || el).join(","); const { fields = [] } = !loadTable?.table ? await pg.query(`select * from ${table} limit 0`) : {}; const cols = loadTable?.table ? Object.keys(schema || {}) .filter((col) => columnList.includes(col) && !extraKeys.includes(col)) ?.map((col) => col?.includes("geom") && schema?.[col]?.type === "Geom" ? `st_asgeojson(${col})::json as "${col}"` : `"${col}"`) ?.join(",") : fields .map((el) => el?.name?.includes("geom") && pg.pgType[el?.dataTypeID] === "geometry" ? `st_asgeojson(${el.name})::json as "${el.name}"` : `"${el?.name}"`) .join(","); const where = [`"${pk}" = $1`, loadTable?.query, accessQuery] .filter(Boolean) .filter((el) => user?.user_type === "superadmin" ? !el.includes("{{uid}}") : true); const geom = dbColumns.find((el) => el.name === "geom" && pg.pgType[el.dataTypeID] === "geometry") ? ",st_asgeojson(geom)::json as geom" : ""; const q = `select "${pk}" as id, ${cols || "*"} ${geom} from ${table} t where ${where.join(" and ") || "true"} limit 1`; if (query?.sql === "1") { const extraQ = extraKeys ?.map((key) => { const { colModel, table: extraTable, parent_id: parentId, } = schema[key]; const colModel1 = Array.isArray(colModel) ? colModel : Object.values(colModel || {}); return colModel1.length ? `/*${key}*/ select ${parentId} as parent, ${colModel1 .map((col) => col.name || col.key) .join(",")} from ${extraTable} a where ${parentId}::text=$1` : null; }) .filter((el) => el) .join(";"); return `${q};${extraQ || ""}`.replace(/\$1/g, `'${id}'`); } const data = await pg .query(q.replace(/{{uid}}/, user?.uid), [id]) .then((el) => el.rows[0]); if (!data) { return reply .status(404) .send({ error: `object not found: ${id}`, code: 404 }); } Object.keys(schema) .filter((key) => schema[key]?.type === "DataTable") .forEach((key) => { if (data[key] && !Array.isArray(data[key])) { data[key] = null; } }); if (extraKeys?.length) { await Promise.all(extraKeys?.map(async (key) => { const { colModel, table: extraTable, parent_id: parentId, } = schema[key]; const colModel1 = Array.isArray(colModel) ? colModel : Object.values(colModel || {}); const q1 = `select ${parentId} as parent, ${colModel1 .map((col) => col.name || col.key) .join(",")} from ${extraTable} a where ${parentId}=$1`; // console.log(table, formName, q1); const { rows: extraRows } = await pg.query(q1, [id]); Object.assign(data, { [key]: extraRows }); })); } if (user?.uid && !config.security?.disableToken && actions.includes("edit") && !called) { data.token = tokenData?.table ? params.table : setToken({ ids: [JSON.stringify({ id, table, form, obj })], uid: user.uid, array: 1, })?.[0]; } await extraDataGet({ rows: [data], table, form }, pg); const res = await applyHook("afterTable", { pg, table, payload: [data], user, }); return res || data || {}; }