@opengis/fastify-table 1.4.21 → 1.4.22

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/config.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import dotenv from 'dotenv';
2
+ import path from 'node:path';
2
3
 
3
4
  import { existsSync, readFileSync } from 'node:fs';
4
5
 
@@ -16,19 +17,39 @@ Object.assign(config, {
16
17
  env: process.env?.NODE_ENV || process.argv[2]?.split?.('=')?.pop?.(),
17
18
  });
18
19
 
19
- if (config.env && existsSync(`.env.${config.env}`)) {
20
- const { parsed } = dotenv.config({ path: `.env.${config.env}` });
21
- console.log('start with env:', config.env);
22
-
23
- const obj = unflattenObject(parsed);
24
-
25
- Object.keys(obj)
26
- .filter(key => typeof obj[key] === 'string'
27
- && (obj[key].startsWith('[') || ['true', 'false'].includes(obj[key]))) // json array / boolean
28
- .forEach(key => {
29
- obj[key] = JSON.parse(obj[key]);
30
- });
31
- Object.assign(config, { ...obj });
20
+ function loadEnvConfig() {
21
+ if (config.env && existsSync(`.env.${config.env}`)) {
22
+ const { parsed } = dotenv.config({ path: `.env.${config.env}` });
23
+ if (parsed) {
24
+ console.log('start with env:', config.env);
25
+
26
+ const obj = unflattenObject(parsed);
27
+
28
+ Object.keys(obj || {})
29
+ .filter(key => typeof obj[key] === 'string'
30
+ && (obj[key].startsWith('[') || ['true', 'false'].includes(obj[key]))) // json array / boolean
31
+ .forEach(key => {
32
+ try {
33
+ obj[key] = JSON.parse(obj[key]);
34
+ }
35
+ catch (err) {
36
+ console.warn(`Invalid JSON for key "${key}": ${obj[key]}`);
37
+ }
38
+ });
39
+ if (obj) {
40
+ Object.assign(config, obj);
41
+ console.log('env init success', config.env, config.pg?.database);
42
+ }
43
+ else {
44
+ console.log('env init error', config.env, config.pg?.database);
45
+ }
46
+ }
47
+ else {
48
+ console.error('env init error: malformed file', config.env);
49
+ }
50
+ }
32
51
  }
33
52
 
53
+ loadEnvConfig();
54
+
34
55
  export default config;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengis/fastify-table",
3
- "version": "1.4.21",
3
+ "version": "1.4.22",
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, tokenData, referer, id, pg: pg1, uid,
14
+ table: table1, tokenData, referer, id, pg: pg1, uid,
15
15
  }) {
16
16
  const pg = pg1 || getPG({ name: 'client' });
17
17
 
@@ -24,33 +24,67 @@ export default async function dataDelete({
24
24
  pg.pk = pgClients.client?.pk;
25
25
  }
26
26
 
27
- const { pk } = await getMeta({ pg, table })
28
- .catch(err => {
29
- logger.file('crud/delete', {
30
- error: err.toString(), stack: err.stack, table, id, referer, uid,
31
- });
32
- throw new Error(err);
33
- });
34
- const table1 = table.replace(/"/g, '');
27
+ const table = table1.replace(/"/g, '');
28
+
29
+ const { pk } = await getMeta({ pg, table });
30
+
35
31
  if (!pg.tlist?.includes(table1)) return 'table not exist';
32
+
36
33
  const delQuery = `delete from ${table} WHERE ${pk}::text = $1::text returning *`;
37
34
 
38
- const extraRes = await extraData({
39
- table, form: tokenData?.form, id, uid,
40
- }, pg);
35
+ // for transactions
36
+ const isClient = typeof pg.query === 'function' && typeof pg.release === 'function';
37
+ const client = isClient ? pg : await pg.connect();
38
+
39
+ if (!isClient) {
40
+ client.caller = 'dataDelete';
41
+ }
42
+
43
+ if (isClient || !client.pk) {
44
+ client.options = pg.options;
45
+ client.tlist = pg.tlist;
46
+ client.pgType = pg.pgType;
47
+ client.relkinds = pg.relkinds;
48
+ client.pk = pg.pk;
49
+ }
50
+
51
+ try {
52
+ if (client.caller === 'dataDelete') {
53
+ await client.query('begin;');
54
+ }
55
+
56
+ const row = {};
57
+ await extraData({
58
+ table, form: tokenData?.form, id, uid, row,
59
+ }, client);
60
+
61
+ const res = await client.query(delQuery, [id])
62
+ .then(el => (el.rows?.[0] ? { rowCount: 1, ...el.rows[0] } : {}));
63
+
64
+ await logChanges({
65
+ pg: client, table, tokenData, referer, id, uid, type: 'DELETE',
66
+ });
67
+
68
+ if (config.redis) { rclient.incr(`pg:${table}:crud`); }
69
+
70
+ if (client.caller === 'dataDelete') {
71
+ await client.query('commit;');
72
+ }
41
73
 
42
- const res = await pg.query(delQuery, [id])
43
- .catch(err => {
74
+ return { ...res, ...row };
75
+ }
76
+ catch (err) {
44
77
  logger.file('crud/delete', {
45
- error: err.toString(), stack: err.stack, table, id, referer, uid, q: delQuery,
78
+ error: err.toString(), stack: err.stack, table, id, referer, uid, form: tokenData?.form,
46
79
  });
80
+ if (client.caller === 'dataDelete') {
81
+ await client.query('rollback;');
82
+ }
47
83
  throw err;
48
- })
49
- .then(el => (el.rows?.[0] ? { rowCount: 1, ...el.rows[0] } : {}));
50
-
51
- await logChanges({
52
- pg, table, tokenData, referer, id, uid, type: 'DELETE',
53
- });
54
- if (config.redis) { rclient.incr(`pg:${table}:crud`); }
55
- return { ...res, ...extraRes || {} };
84
+ }
85
+ finally {
86
+ if (client.caller === 'dataDelete') {
87
+ await client.query('begin;');
88
+ }
89
+ }
56
90
  }
@@ -9,7 +9,7 @@ const defaultTable = 'crm.extra_data';
9
9
  function format(key, value, schema) {
10
10
  if (!key || !schema?.[key]) return value;
11
11
  if (schema?.[key]?.type && ['Number', 'Switcher'].includes(schema?.[key]?.type)) {
12
- return JSON.parse(value || null);
12
+ return typeof value === 'string' ? JSON.parse(value) : value;
13
13
  }
14
14
  return value;
15
15
  }
@@ -45,7 +45,9 @@ export default async function extraData({
45
45
  const deleteRes = await pg.query(`delete from ${extraTable} where object_id=$1 and property_key = any($2::text[]) returning *`, [id, Object.keys(loadTemplate?.schema || {})]);
46
46
 
47
47
  if (!data) {
48
- return deleteRes?.rows?.reduce?.((acc, curr) => Object.assign(acc, { [curr.property_key]: format(curr.property_key, curr.value_text, curr.value_array, loadTemplate?.schema) }), {});
48
+ const result = deleteRes?.rows?.reduce?.((acc, curr) => Object.assign(acc, { [curr.property_key]: format(curr.property_key, curr.value_text || curr.value_array, loadTemplate?.schema) }), {}) || {};
49
+ Object.assign(row, result);
50
+ return result;
49
51
  }
50
52
 
51
53
  const rows = Object.keys(data || {})
@@ -70,7 +72,7 @@ export default async function extraData({
70
72
  }));
71
73
 
72
74
  Object.assign(row, {
73
- ...res.reduce((acc, curr) => Object.assign(acc, { [curr.property_key]: format(curr.property_key, curr.value_text, curr.value_array, loadTemplate?.schema) }), {}),
75
+ ...res.reduce((acc, curr) => Object.assign(acc, { [curr.property_key]: format(curr.property_key, curr.value_text || curr.value_array, loadTemplate?.schema) }), {}),
74
76
  id: res?.[0]?.object_id,
75
77
  });
76
78
  return row;
@@ -44,21 +44,9 @@ export default async function extraDataGet({
44
44
  rows.forEach(row => {
45
45
  Object.assign(row, {
46
46
  ...extraRows
47
- .filter(el => el.object_id === row.id)
47
+ .filter(el => el.object_id === row.id && (el.value_text || el.value_array))
48
48
  .reduce((acc, curr) => {
49
- let value = null;
50
-
51
- if (curr.value_text !== null) {
52
- value = curr.value_text;
53
- }
54
- else if (curr.value_array !== null) {
55
- value = curr.value_array;
56
- }
57
-
58
- if (value !== null) {
59
- acc[curr.property_key] = format(curr.property_key, value, loadTemplate?.schema);
60
- }
61
-
49
+ acc[curr.property_key] = format(curr.property_key, curr.value_text || curr.value_array, loadTemplate?.schema);
62
50
  return acc;
63
51
  }, {}),
64
52
  });
@@ -32,7 +32,7 @@ export default async function insert(req, reply) {
32
32
  return reply.status(400).send('invalid token');
33
33
  }
34
34
 
35
- if (!actions.includes('add') && !config.local) {
35
+ if (!actions.includes('add') && !config.local && !tokenData) {
36
36
  return reply.status(403).send('access restricted: actions');
37
37
  }
38
38
 
@@ -36,7 +36,7 @@ export default async function update(req, reply) {
36
36
  return reply.status(400).send('invalid token');
37
37
  }
38
38
 
39
- if (!actions.includes('edit') && !config.local) {
39
+ if (!actions.includes('edit') && !config.local && !tokenData) {
40
40
  return reply.status(403).send('access restricted: actions');
41
41
  }
42
42
 
@@ -13,7 +13,7 @@ export default function checkUserAccess({ user = {}, token }) {
13
13
  return { message: 'access granted', status: 200 };
14
14
  }
15
15
  // console.log(user);
16
- if (user.user_type !== 'admin' && !config?.local && !config.auth?.disable) {
16
+ if (!user.user_type?.includes?.('admin') && !config?.local && !config.auth?.disable) {
17
17
  return { message: 'access restricted', status: 403 };
18
18
  }
19
19