@opengis/fastify-table 1.4.82 → 1.4.83

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengis/fastify-table",
3
- "version": "1.4.82",
3
+ "version": "1.4.83",
4
4
  "type": "module",
5
5
  "description": "core-plugins",
6
6
  "keywords": [
@@ -11,7 +11,7 @@ import logger from '../../logger/getLogger.js';
11
11
  const rclient = getRedis();
12
12
 
13
13
  export default async function dataDelete({
14
- table: table1, tokenData, referer, id, pg: pg1, uid,
14
+ table: table1, tokenData, referer, id, pg: pg1, uid, query = 'true',
15
15
  }) {
16
16
  const pg = pg1 || getPG({ name: 'client' });
17
17
 
@@ -30,7 +30,7 @@ export default async function dataDelete({
30
30
 
31
31
  const { pk } = await getMeta({ pg, table });
32
32
 
33
- const delQuery = `delete from ${table} WHERE ${pk}::text = $1::text returning *`;
33
+ const delQuery = `delete from ${table} WHERE ${pk}::text = $1::text and ${query} returning *`;
34
34
 
35
35
  // for transactions
36
36
  const isClient = typeof pg.query === 'function' && typeof pg.release === 'function';
@@ -44,8 +44,8 @@ async function init(client) {
44
44
  }
45
45
 
46
46
  async function querySafe(q, param = {}) {
47
- const { args, isstream } = param;
48
- const data = await query(q, args, isstream);
47
+ const args = Array.isArray(param) ? param : (param.args || []);
48
+ const data = await query(q, args, true);
49
49
  return data;
50
50
  }
51
51
 
@@ -10,6 +10,7 @@ export default function unflattenObject(flatObj) {
10
10
  if (index === keys.length - 1) {
11
11
  // json array
12
12
  if (typeof flatObj[key] === 'string' && flatObj[key].startsWith('[') && flatObj[key] !== ('[object Object]')) {
13
+ // console.log('unflatten aray', key);
13
14
  try {
14
15
  nestedObj[part] = JSON.parse(flatObj[key] || '{}');
15
16
  }
@@ -18,7 +19,8 @@ export default function unflattenObject(flatObj) {
18
19
  nestedObj[part] = flatObj[key]; // fallback to original value if parsing fails
19
20
  }
20
21
  }
21
- else if (['true', 'false'].includes(flatObj[key]) || (!isNaN(flatObj[key]) && key !== 'auth.uid')) {
22
+ else if (['true', 'false'].includes(flatObj[key]) || (!isNaN(flatObj[key])) && false) {
23
+ // console.log('unflatten number', key);
22
24
  try {
23
25
  nestedObj[part] = JSON.parse(flatObj[key] || '{}');
24
26
  }
@@ -28,6 +30,7 @@ export default function unflattenObject(flatObj) {
28
30
  }
29
31
  }
30
32
  else {
33
+ // console.log('unflatten else', key);
31
34
  nestedObj[part] = flatObj[key];
32
35
  }
33
36
  }
@@ -18,17 +18,31 @@ export default async function deleteCrud(req, reply) {
18
18
  const { referer } = headers;
19
19
  const tokenData = await getToken({
20
20
  uid: user.uid, token: params.id || params.table, json: 1,
21
- }) || await getOpt(params.id || params.table, user.uid);
21
+ }) || await getOpt(params.id || params.table, user.uid) || await getOpt(params.table, user.uid);
22
22
 
23
- const { table: del, id } = hookData || tokenData || (config.security?.disableToken || config.local || config.auth?.disable ? req.params : {});
23
+ const {
24
+ table: del, id = params.id, query, actions: actionsToken,
25
+ } = hookData || tokenData || (config.security?.disableToken || config.local || config.auth?.disable ? req.params : {});
26
+ if (actionsToken && !actionsToken?.include('del')) {
27
+ return reply.status(403).send({
28
+ error: 'del is not allowed ',
29
+ code: 403,
30
+ });
31
+ }
24
32
  const { actions = [] } = await getAccess({ table: del, id, user }, pg) || {};
25
33
 
26
34
  if (!tokenData && !config?.local && !config.security?.disableToken && !config.auth?.disable) {
27
- return reply.status(400).send('invalid token');
35
+ return reply.status(403).send({
36
+ error: 'invalid token',
37
+ code: 403,
38
+ });
28
39
  }
29
40
 
30
41
  if (!actions.includes('del') && !config?.local && !tokenData) {
31
- return reply.status(403).send('access restricted: actions');
42
+ return reply.status(403).send({
43
+ error: 'access restricted: actions',
44
+ code: 403,
45
+ });
32
46
  }
33
47
 
34
48
  const loadTemplate = await getTemplate('table', del);
@@ -36,22 +50,34 @@ export default async function deleteCrud(req, reply) {
36
50
  const { table } = loadTemplate || hookData || tokenData || req.params || {};
37
51
 
38
52
  if (!table) {
39
- return reply.status(404).send('table is required');
53
+ return reply.status(404).send({
54
+ error: 'table is required',
55
+ code: 404,
56
+ });
40
57
  }
41
58
 
42
59
  if (!id) {
43
- return reply.status(404).send('id is required');
60
+ return reply.status(404).send({
61
+ error: 'id is required',
62
+ code: 404,
63
+ });
44
64
  }
45
65
 
46
66
  const data = await dataDelete({
47
- pg, table, id, uid: user?.uid, tokenData, referer,
67
+ pg, table, id, uid: user?.uid, tokenData, referer, query,
48
68
  }).catch(err => {
49
69
  if (err.message?.includes?.('foreign key' || 'unique')) {
50
70
  const constraint = err.message.match(/constraint "([^"]+)"/g);
51
- return reply.status(400).send(`Видалення заборонено для збереження цілісності БД: ${constraint}`);
71
+ return reply.status(400).send({
72
+ error: `Видалення заборонено для збереження цілісності БД: ${constraint}`,
73
+ code: 400,
74
+ });
52
75
  }
53
76
  if (config.trace) console.error(err.toString());
54
- return err.toString();
77
+ return {
78
+ error: err.toString(),
79
+ code: 400,
80
+ };
55
81
  });
56
82
 
57
83
  return reply.status(200).send({ rowCount: data?.rowCount || 0, msg: !data?.rowCount ? data : null });
@@ -30,7 +30,7 @@ export default async function getTableData(req, reply, called) {
30
30
  }
31
31
 
32
32
  const resp = await getData({
33
- pg, params: { id, table: tokenData.table }, headers, query, user, contextQuery: [contextQuery1, tokenData.query].filter(Boolean).join(' and '), sufix, filterList,
33
+ pg, params: { id, table: tokenData.table }, headers, query, user, contextQuery: [contextQuery1, tokenData.query].filter(Boolean).join(' and '), sufix, filterList, actions: tokenData1?.actions,
34
34
  }, reply, called);
35
35
  if (resp?.addToken && tokenData.obj) { Object.assign(resp, { addToken: params.table }); }
36
36
  return resp;
@@ -52,7 +52,7 @@ export default async function getTableData(req, reply, called) {
52
52
  const contextQuery = [contextQuery1, interfaceQuery, context].filter(Boolean).join(' and ') || ' 2=2 ';
53
53
 
54
54
  const res = await getData({
55
- pg, params, query, headers, user, contextQuery, sufix, filterList,
55
+ pg, params, query, headers, user, contextQuery, sufix, filterList, actions: tokenData1?.actions,
56
56
  }, reply, called);
57
57
  const route = pg.tlist?.includes('admin.routes') ? await pg.query('select route_id as path, title from admin.routes where enabled and alias=$1 limit 1', [params.table])
58
58
  .then(el => el.rows?.[0] || {}) : {};
@@ -34,7 +34,7 @@ const defaultLimit = 20;
34
34
 
35
35
  export default async function dataAPI(req, reply, called) {
36
36
  const {
37
- pg = pgClients.client, params, headers = {}, query = {}, user = {}, contextQuery, sufix = true, filterList,
37
+ pg = pgClients.client, params, headers = {}, query = {}, user = {}, contextQuery, sufix = true, filterList, actions: actionsParam,
38
38
  } = req;
39
39
 
40
40
  const time = Date.now();
@@ -52,8 +52,8 @@ export default async function dataAPI(req, reply, called) {
52
52
  }
53
53
 
54
54
  const tokenData = await getOpt(params.table, user?.uid);
55
-
56
- const loadTable = await getTemplate('table', tokenData?.table || hookData?.table || params.table);
55
+ const templateName = tokenData?.table || hookData?.table || params.table;
56
+ const loadTable = await getTemplate('table', templateName);
57
57
 
58
58
  // check sql inline fields count
59
59
  if (!checkInline[params?.table] && loadTable?.sql?.length && loadTable.table) {
@@ -227,7 +227,7 @@ export default async function dataAPI(req, reply, called) {
227
227
 
228
228
  timeArr.push(Date.now());
229
229
 
230
- if (uid && rows.length && !config.security?.disableToken && (editable || actions.includes('edit') || actions.includes('del'))) {
230
+ if (uid && rows.length && !config.security?.disableToken && (editable || actionsParam?.includes('edit') || actions.includes('edit') || actions.includes('del'))) {
231
231
  rows.forEach(row => {
232
232
  Object.assign(row, {
233
233
  token: setToken({
@@ -381,8 +381,8 @@ export default async function dataAPI(req, reply, called) {
381
381
 
382
382
  public: ispublic,
383
383
  tokens,
384
- card: loadTable?.card,
385
- actions,
384
+ card: !!(loadTable?.card ?? await getTemplate('card', templateName)),
385
+ actions: actionsParam || actions || ['view'],
386
386
  total,
387
387
  filtered,
388
388
  count: rows.length,