UNPKG

@opengis/fastify-table

Version:

core-plugins

116 lines (91 loc) 5.16 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) { 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 { message: hookData?.message, status: hookData?.status }; } const templateName = hookData?.table || tokenData.table || params.table; const loadTable = await getTemplate('table', templateName); if (!loadTable && !pg.pk?.[tokenData.table]) { return { message: 'not found', status: 404 }; } const { table = params.table, /* columns, */ form } = hookData || loadTable || tokenData; const id = hookData?.id || tokenData.id || params.id; if (tokenData && !id) return { message: {} }; if (!table && !id) { return reply.status(400).send('not enough params'); } const { actions = [], query: accessQuery } = await getAccess({ table, form, id, user, }, pg) || {}; if (!tokenData && !config?.local && !config.security?.disableToken) { return reply.status(400).send('invalid token'); } if (!actions.includes('edit') && !config?.local && !tokenData) { return reply.status(403).send('access restricted: actions'); } const { pk, columns: dbColumns = [] } = await getMeta({ pg, table }); if (!pk) { return reply.status(404).send(`table not found: ${table}`); } // 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(`object not found: ${id}`); } 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')) { data.token = tokenData?.table ? params.table : setToken({ ids: [JSON.stringify({ id, table, form })], 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 || {}; }