@opengis/fastify-table
Version:
core-plugins
78 lines (59 loc) • 2.99 kB
JavaScript
import {
getTemplate, getMeta, metaFormat, getAccess, applyHook,
} from '../../../../utils.js';
export default async function card(req) {
const time = Date.now();
const {
pg, user, params = {}, query = {},
} = req;
const hookData = await applyHook('preCard', {
table: params?.table, id: params?.id, user,
});
if (hookData?.message && hookData?.status) {
return { message: hookData?.message, status: hookData?.status };
}
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 { message: 'access restricted', status: 403 };
}
const loadTable = await getTemplate('table', hookData?.table || params.table);
if (!loadTable) { return { message: 'template not found', status: 404 }; }
const {
table, columns, meta, sql, cardSql,
} = loadTable;
const { pk, columns: dbColumns = [] } = await getMeta(table);
if (!pk) return { message: `table not found: ${table}`, status: 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]);
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,
};
}