@opengis/admin 0.1.64 → 0.1.66

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.
Files changed (112) hide show
  1. package/README.md +29 -29
  2. package/config.js +4 -4
  3. package/dist/{add-page-LONm322L.js → add-page-YonHQsF2.js} +1 -1
  4. package/dist/{admin-interface-eocB4uF3.js → admin-interface-DSR1im5I.js} +67 -65
  5. package/dist/{admin-view-CEePX3t5.js → admin-view-WZhYBXYw.js} +2 -2
  6. package/dist/admin.js +1 -1
  7. package/dist/admin.umd.cjs +46 -46
  8. package/dist/{card-page-CnQufGpK.js → card-page-BH8lGOKk.js} +2 -2
  9. package/dist/{card-view-MKU1ijjK.js → card-view-DYhMgpIH.js} +1 -1
  10. package/dist/{edit-page-C1wXXuPF.js → edit-page-D8fMSwEp.js} +1 -1
  11. package/dist/{import-file-BkyTVz51.js → import-file-Do-GQQHc.js} +3572 -3603
  12. package/dist/style.css +1 -1
  13. package/module/settings/card/admin.roles.table/access.hbs +27 -27
  14. package/module/settings/card/admin.roles.table/general_info.hbs +16 -16
  15. package/module/settings/card/admin.roles.table/index.yml +14 -14
  16. package/module/settings/card/admin.roles.table/users.hbs +27 -27
  17. package/module/settings/card/admin.routes.table/general_info.hbs +40 -40
  18. package/module/settings/card/admin.routes.table/index.yml +8 -8
  19. package/module/settings/card/admin.routes.table/users.hbs +33 -33
  20. package/module/settings/card/admin.users.table/general_info.hbs +25 -25
  21. package/module/settings/card/admin.users.table/index.yml +12 -12
  22. package/module/settings/card/admin.users.table/logs.hbs +30 -30
  23. package/module/settings/card/admin.users.table/user_roles.hbs +24 -24
  24. package/module/settings/cls/core.actions.json +13 -13
  25. package/module/settings/cls/core.scope.json +13 -13
  26. package/module/settings/cls/properties.site_status.json +13 -13
  27. package/module/settings/cls/properties.widget_status.json +13 -13
  28. package/module/settings/cls/users.user_type.json +13 -13
  29. package/module/settings/form/admin.access.form.json +36 -36
  30. package/module/settings/form/admin.custom_column.form.json +71 -71
  31. package/module/settings/form/admin.properties.form.json +15 -15
  32. package/module/settings/form/admin.roles.form.json +19 -19
  33. package/module/settings/form/admin.routes.form.json +25 -25
  34. package/module/settings/form/admin.user_properties.form.json +15 -15
  35. package/module/settings/form/admin.user_roles.form.json +21 -21
  36. package/module/settings/form/admin.users.form.json +150 -150
  37. package/module/settings/form/user.user_roles.form.json +13 -13
  38. package/module/settings/interface/admin.properties.json +4 -4
  39. package/module/settings/interface/admin.roles.json +4 -4
  40. package/module/settings/interface/admin.routes.json +4 -4
  41. package/module/settings/interface/admin.users.json +4 -4
  42. package/module/settings/menu.json +50 -50
  43. package/module/settings/select/core.routes.sql +1 -1
  44. package/module/settings/select/core.user_uid.sql +1 -1
  45. package/module/settings/table/admin.access.table.json +77 -77
  46. package/module/settings/table/admin.custom_column.table.json +94 -94
  47. package/module/settings/table/admin.properties.table.json +33 -33
  48. package/module/settings/table/admin.roles.table.json +58 -58
  49. package/module/settings/table/admin.routes.table.json +67 -67
  50. package/module/settings/table/admin.user_properties.table.json +28 -28
  51. package/module/settings/table/admin.user_roles.table.json +66 -66
  52. package/module/settings/table/admin.users.table.json +119 -119
  53. package/package.json +80 -80
  54. package/plugin.js +100 -100
  55. package/server/helpers/controllers/badge.js +11 -11
  56. package/server/helpers/controllers/hb.js +2 -2
  57. package/server/helpers/controllers/map.js +2 -2
  58. package/server/helpers/controllers/mls.js +2 -2
  59. package/server/helpers/controllers/vue.js +2 -2
  60. package/server/helpers/index.mjs +13 -13
  61. package/server/plugins/adminHook.js +165 -165
  62. package/server/plugins/cron.js +10 -10
  63. package/server/plugins/docs.js +28 -28
  64. package/server/plugins/hook.js +185 -194
  65. package/server/plugins/vite.js +69 -69
  66. package/server/routes/calendar/controllers/calendar.data.js +88 -88
  67. package/server/routes/calendar/index.mjs +17 -17
  68. package/server/routes/data/controllers/cardData.js +57 -57
  69. package/server/routes/data/controllers/cardTabData.js +49 -49
  70. package/server/routes/data/controllers/funcs/getFilterSQL/index.js +92 -92
  71. package/server/routes/data/controllers/funcs/getFilterSQL/util/formatValue.js +170 -170
  72. package/server/routes/data/controllers/funcs/getFilterSQL/util/getCustomQuery.js +13 -13
  73. package/server/routes/data/controllers/funcs/getFilterSQL/util/getFilterQuery.js +64 -64
  74. package/server/routes/data/controllers/funcs/getFilterSQL/util/getOptimizedQuery.js +12 -12
  75. package/server/routes/data/controllers/funcs/getFilterSQL/util/getTableSql.js +34 -34
  76. package/server/routes/data/controllers/tableData.js +112 -112
  77. package/server/routes/data/controllers/tableDataId.js +27 -27
  78. package/server/routes/data/controllers/tableFilter.js +63 -63
  79. package/server/routes/data/controllers/utils/assignTokens.js +30 -30
  80. package/server/routes/data/controllers/utils/getColumns.js +8 -8
  81. package/server/routes/data/index.mjs +15 -15
  82. package/server/routes/data/schema.js +7 -7
  83. package/server/routes/menu/controllers/getMenu.js +51 -34
  84. package/server/routes/menu/index.mjs +5 -5
  85. package/server/routes/notifications/controllers/readNotifications.js +30 -30
  86. package/server/routes/notifications/controllers/userNotifications.js +64 -64
  87. package/server/routes/notifications/hook/onWidgetSet.js +57 -63
  88. package/server/routes/notifications/index.mjs +40 -40
  89. package/server/routes/properties/controllers/admin.properties.get.js +29 -29
  90. package/server/routes/properties/controllers/user.properties.get.js +34 -34
  91. package/server/routes/properties/controllers/user.properties.post.js +30 -30
  92. package/server/routes/properties/funcs/getSettings.js +56 -56
  93. package/server/routes/properties/funcs/setSettings.js +44 -44
  94. package/server/routes/properties/funcs/utils/dataInsert.js +26 -26
  95. package/server/routes/properties/index.mjs +26 -26
  96. package/server/routes/root.mjs +3 -3
  97. package/server/routes/templates/controllers/getTemplate.js +22 -22
  98. package/server/routes/templates/index.mjs +14 -14
  99. package/server/templates/cls/itree.recrzone_category.json +73 -73
  100. package/server/templates/cls/test.json +9 -9
  101. package/server/templates/form/admin.user_cls.data.form.json +49 -49
  102. package/server/templates/form/admin.user_group_rel.form.json +21 -21
  103. package/server/templates/form/cp_building.form.json +32 -32
  104. package/server/templates/form/form-user-pass.json +10 -10
  105. package/server/templates/form/form-user_group.json +39 -39
  106. package/server/templates/form/form-users.json +156 -156
  107. package/server/templates/form/user_group_access.form.json +22 -22
  108. package/server/templates/select/account_id.json +2 -2
  109. package/server/templates/table/gis.dataset.table.json +43 -43
  110. package/server/templates/table/management.user_group.table.json +112 -112
  111. package/server/templates/table/management.users.table.json +126 -126
  112. package/utils.js +21 -21
package/plugin.js CHANGED
@@ -1,101 +1,101 @@
1
- import fp from 'fastify-plugin';
2
- import path from 'node:path';
3
-
4
- import { getTemplatePath, getTemplate, pgClients } from '@opengis/fastify-table/utils.js';
5
-
6
- import config from './config.js';
7
- import getMenu from './server/routes/menu/controllers/getMenu.js';
8
-
9
- config.prefix = config.prefix || '/api';
10
-
11
- async function plugin(fastify, opts = config) {
12
- // const prefix = config.prefix || '/api';
13
-
14
- fastify.register(import('./server/helpers/index.mjs'), opts);
15
- // fastify.register(import('@opengis/fastify-auth'), config);
16
-
17
- fastify.addHook('onListen', async () => {
18
- const { client } = pgClients;
19
- const json = await getMenu();
20
- // insert interface list to db (user access management)
21
- if (client?.pk?.['admin.routes'] && json?.length) {
22
- const menuList = json.filter((el) => el?.menu?.length && el?.ua || el?.en || el?.name);
23
- const interfaces = menuList.reduce((acc, curr) => { curr.menu.forEach((el) => acc.push(el.path)); return acc; }, []);
24
- await client.query('update admin.routes set enabled=false where not array[route_id] <@ $1::text[]', [interfaces]);
25
-
26
- const q = `insert into admin.menu(name, ord) values${menuList.map((el, i) => `('${(el?.ua || el?.en || el?.name).replace(/'/g, '’')}', ${i}) `).join(',')
27
- } on conflict (name) do update set ord=excluded.ord, enabled=true returning name, menu_id`;
28
- const { rows = [] } = menuList?.length ? await client.query(q) : {};
29
- await client.query('update admin.menu set enabled=false where not array[menu_id] <@ $1::text[]', [rows.map((el) => el.menu_id)]);
30
-
31
- const menus = rows.reduce((acc, curr) => Object.assign(acc, { [curr.menu_id]: menuList.find((item) => (item?.ua || item?.en || item?.name) === curr.name) }), {});
32
- const values = Object.entries(menus).reduce((acc, curr) => { curr[1]?.menu?.forEach((el) => acc.push({ ...el, menuId: curr[0] })); return acc; }, []);
33
-
34
- await Promise.all(values.filter((el) => el?.table).map(async (el) => Object.assign(el, { table1: (await getTemplate('table', el.table))?.table || el.table })));
35
-
36
- const q1 = `insert into admin.routes(route_id, alias, title, menu_id, table_name) values ${values.map((el) => `('${el.path}', '${el.table}', ${(el.title || el.ua) ? `'${el.title || el.ua}'` : ''}, '${el.menuId}', '${el.table1}')`).join(',')}
37
- on conflict (route_id) do update set menu_id=excluded.menu_id, alias=excluded.alias, title=excluded.title, enabled=true,
38
- table_name=excluded.table_name returning route_id, table_name`;
39
- try {
40
- const { rowCount } = values?.length ? await client.query(q1) : {};
41
- //console.log('interface insert ok', values, rowCount);
42
- } catch (err) {
43
- console.log('interface insert error', values, q1, err);
44
- }
45
- }
46
- });
47
-
48
- fastify.addHook('onListen', async () => {
49
- const { client: pg } = pgClients;
50
- const clsQuery = [];
51
- if (!pg.pk?.['admin.cls']) return;
52
-
53
- const selectList = await getTemplatePath('select');
54
- const clsList = (await getTemplatePath('cls'))?.filter((el) => !(selectList?.map((el) => el?.[0]) || []).includes(el[0]));
55
- const cls = (selectList || []).concat(clsList || [])
56
- ?.map((el) => ({ name: el[0], module: path.basename(path.dirname(path.dirname(el[1]))), type: { 'json': 'cls', 'sql': 'select' }[el[2]] }))
57
- if (!cls?.length) return;
58
-
59
- const dupes = cls.filter((el, idx, arr) => arr.map((item) => item.name).indexOf(el.name) !== idx);
60
- //console.log('cls insert skip dupes', dupes.map((el) => el.name));
61
-
62
- try {
63
- await Promise.all(cls.filter((el, idx, arr) => arr.map((item) => item.name).indexOf(el.name) === idx).map(async (el) => {
64
- const { name, module, type } = el;
65
- const loadTemplate = await getTemplate(type, name);
66
- // console.log(name, type);
67
- if (type === 'select') {
68
- clsQuery.push(`insert into admin.cls(name,type,data,module) values('${name}','sql','${(loadTemplate?.sql || loadTemplate)?.replace(/'/g, "''")}', '${module?.replace(/'/g, "''")}')`);
69
- } else if (type === 'cls' && loadTemplate?.length) {
70
- clsQuery.push(`insert into admin.cls(name,type, module) values('${name}','json', '${module?.replace(/'/g, "''")}');
71
- insert into admin.cls(code,name,parent,icon)
72
- select value->>'id',value->>'text','${name}',value->>'icon'
73
- from json_array_elements('${JSON.stringify(loadTemplate).replace(/'/g, "''")}'::json)`);
74
- } else {
75
- console.log(name, type, 'empty');
76
- }
77
- }));
78
-
79
- await pg.query('truncate admin.cls');
80
- if (clsQuery.filter((el) => el).length) {
81
- await pg.query(clsQuery.filter((el) => el).join(';'));
82
- console.log('cls insert ok', clsQuery?.length);
83
- }
84
- } catch (err) {
85
- console.error('cls insert error', err.toString());
86
- }
87
- });
88
-
89
-
90
- // API
91
- fastify.register(import('./server/plugins/cron.js'), opts); // cron / scheduler
92
- fastify.register(import('./server/plugins/hook.js'), opts); // data / template hooks
93
- fastify.register(import('./server/routes/properties/index.mjs'), opts);
94
- fastify.register(import('./server/routes/calendar/index.mjs'), opts);
95
- fastify.register(import('./server/routes/notifications/index.mjs'), opts);
96
- fastify.register(import('./server/routes/templates/index.mjs'), opts);
97
- fastify.register(import('./server/routes/menu/index.mjs'), opts);
98
- fastify.register(import('./server/routes/data/index.mjs'), opts);
99
-
100
- }
1
+ import fp from 'fastify-plugin';
2
+ import path from 'node:path';
3
+
4
+ import { getTemplatePath, getTemplate, pgClients } from '@opengis/fastify-table/utils.js';
5
+
6
+ import config from './config.js';
7
+ import getMenu from './server/routes/menu/controllers/getMenu.js';
8
+
9
+ config.prefix = config.prefix || '/api';
10
+
11
+ async function plugin(fastify, opts = config) {
12
+ // const prefix = config.prefix || '/api';
13
+
14
+ fastify.register(import('./server/helpers/index.mjs'), opts);
15
+ // fastify.register(import('@opengis/fastify-auth'), config);
16
+
17
+ fastify.addHook('onListen', async () => {
18
+ const { client } = pgClients;
19
+ const json = await getMenu();
20
+ // insert interface list to db (user access management)
21
+ if (client?.pk?.['admin.routes'] && json?.length) {
22
+ const menuList = json.filter((el) => el?.menu?.length && el?.ua || el?.en || el?.name);
23
+ const interfaces = menuList.reduce((acc, curr) => { curr.menu.forEach((el) => acc.push(el.path)); return acc; }, []);
24
+ await client.query('update admin.routes set enabled=false where not array[route_id] <@ $1::text[]', [interfaces]);
25
+
26
+ const q = `insert into admin.menu(name, ord) values${menuList.map((el, i) => `('${(el?.ua || el?.en || el?.name).replace(/'/g, '’')}', ${i}) `).join(',')
27
+ } on conflict (name) do update set ord=excluded.ord, enabled=true returning name, menu_id`;
28
+ const { rows = [] } = menuList?.length ? await client.query(q) : {};
29
+ await client.query('update admin.menu set enabled=false where not array[menu_id] <@ $1::text[]', [rows.map((el) => el.menu_id)]);
30
+
31
+ const menus = rows.reduce((acc, curr) => Object.assign(acc, { [curr.menu_id]: menuList.find((item) => (item?.ua || item?.en || item?.name) === curr.name) }), {});
32
+ const values = Object.entries(menus).reduce((acc, curr) => { curr[1]?.menu?.forEach((el) => acc.push({ ...el, menuId: curr[0] })); return acc; }, []);
33
+
34
+ await Promise.all(values.filter((el) => el?.table).map(async (el) => Object.assign(el, { table1: (await getTemplate('table', el.table))?.table || el.table })));
35
+
36
+ const q1 = `insert into admin.routes(route_id, alias, title, menu_id, table_name) values ${values.map((el) => `('${el.path}', '${el.table}', ${(el.title || el.ua) ? `'${el.title || el.ua}'` : ''}, '${el.menuId}', '${el.table1}')`).join(',')}
37
+ on conflict (route_id) do update set menu_id=excluded.menu_id, alias=excluded.alias, title=excluded.title, enabled=true,
38
+ table_name=excluded.table_name returning route_id, table_name`;
39
+ try {
40
+ const { rowCount } = values?.length ? await client.query(q1) : {};
41
+ //console.log('interface insert ok', values, rowCount);
42
+ } catch (err) {
43
+ console.log('interface insert error', values, q1, err);
44
+ }
45
+ }
46
+ });
47
+
48
+ fastify.addHook('onListen', async () => {
49
+ const { client: pg } = pgClients;
50
+ const clsQuery = [];
51
+ if (!pg.pk?.['admin.cls']) return;
52
+
53
+ const selectList = await getTemplatePath('select');
54
+ const clsList = (await getTemplatePath('cls'))?.filter((el) => !(selectList?.map((el) => el?.[0]) || []).includes(el[0]));
55
+ const cls = (selectList || []).concat(clsList || [])
56
+ ?.map((el) => ({ name: el[0], module: path.basename(path.dirname(path.dirname(el[1]))), type: { 'json': 'cls', 'sql': 'select' }[el[2]] }))
57
+ if (!cls?.length) return;
58
+
59
+ const dupes = cls.filter((el, idx, arr) => arr.map((item) => item.name).indexOf(el.name) !== idx);
60
+ //console.log('cls insert skip dupes', dupes.map((el) => el.name));
61
+
62
+ try {
63
+ await Promise.all(cls.filter((el, idx, arr) => arr.map((item) => item.name).indexOf(el.name) === idx).map(async (el) => {
64
+ const { name, module, type } = el;
65
+ const loadTemplate = await getTemplate(type, name);
66
+ // console.log(name, type);
67
+ if (type === 'select') {
68
+ clsQuery.push(`insert into admin.cls(name,type,data,module) values('${name}','sql','${(loadTemplate?.sql || loadTemplate)?.replace(/'/g, "''")}', '${module?.replace(/'/g, "''")}')`);
69
+ } else if (type === 'cls' && loadTemplate?.length) {
70
+ clsQuery.push(`insert into admin.cls(name,type, module) values('${name}','json', '${module?.replace(/'/g, "''")}');
71
+ insert into admin.cls(code,name,parent,icon)
72
+ select value->>'id',value->>'text','${name}',value->>'icon'
73
+ from json_array_elements('${JSON.stringify(loadTemplate).replace(/'/g, "''")}'::json)`);
74
+ } else {
75
+ console.log(name, type, 'empty');
76
+ }
77
+ }));
78
+
79
+ await pg.query('truncate admin.cls');
80
+ if (clsQuery.filter((el) => el).length) {
81
+ await pg.query(clsQuery.filter((el) => el).join(';'));
82
+ console.log('cls insert ok', clsQuery?.length);
83
+ }
84
+ } catch (err) {
85
+ console.error('cls insert error', err.toString());
86
+ }
87
+ });
88
+
89
+
90
+ // API
91
+ fastify.register(import('./server/plugins/cron.js'), opts); // cron / scheduler
92
+ fastify.register(import('./server/plugins/hook.js'), opts); // data / template hooks
93
+ fastify.register(import('./server/routes/properties/index.mjs'), opts);
94
+ fastify.register(import('./server/routes/calendar/index.mjs'), opts);
95
+ fastify.register(import('./server/routes/notifications/index.mjs'), opts);
96
+ fastify.register(import('./server/routes/templates/index.mjs'), opts);
97
+ fastify.register(import('./server/routes/menu/index.mjs'), opts);
98
+ fastify.register(import('./server/routes/data/index.mjs'), opts);
99
+
100
+ }
101
101
  export default fp(plugin)
@@ -1,12 +1,12 @@
1
- export default async function badge(data, options = {}) {
2
- if (!data) return '-';
3
- //const cls = await getSelect(options.data, { val: data, full: 1 });
4
-
5
- return data;
6
- /*const html = cls?.map((el) => {
7
- const color = bscolor[el.color] || el.color || '#aaa';
8
- return `<span class="el-tag el-tag--mini" style="color:${color || '#aaa'};border-color:${color || '#aaa'};background:unset;">
9
- ${funcs.locale(el.id, { lang: root.lang, prefix: opt.data, type: 'cls' }) || el.text}</span>`;
10
- }).join(', ');
11
- return html;*/
1
+ export default async function badge(data, options = {}) {
2
+ if (!data) return '-';
3
+ //const cls = await getSelect(options.data, { val: data, full: 1 });
4
+
5
+ return data;
6
+ /*const html = cls?.map((el) => {
7
+ const color = bscolor[el.color] || el.color || '#aaa';
8
+ return `<span class="el-tag el-tag--mini" style="color:${color || '#aaa'};border-color:${color || '#aaa'};background:unset;">
9
+ ${funcs.locale(el.id, { lang: root.lang, prefix: opt.data, type: 'cls' }) || el.text}</span>`;
10
+ }).join(', ');
11
+ return html;*/
12
12
  }
@@ -1,3 +1,3 @@
1
- export default async function _hb() {
2
- return '';
1
+ export default async function _hb() {
2
+ return '';
3
3
  }
@@ -1,3 +1,3 @@
1
- export default async function map() {
2
- return '';
1
+ export default async function map() {
2
+ return '';
3
3
  }
@@ -1,3 +1,3 @@
1
- export default async function _mls(data, options={}) {
2
- return data.hash?.ua || options?.hash?.ua || '';
1
+ export default async function _mls(data, options={}) {
2
+ return data.hash?.ua || options?.hash?.ua || '';
3
3
  }
@@ -1,3 +1,3 @@
1
- export default async function _vue() {
2
- return '';
1
+ export default async function _vue() {
2
+ return '';
3
3
  }
@@ -1,13 +1,13 @@
1
- import _hb from "./controllers/hb.js";
2
- import _vue from "./controllers/vue.js";
3
- import map from "./controllers/map.js";
4
- import _mls from "./controllers/mls.js";
5
- import badge from "./controllers/badge.js";
6
-
7
- export default async function route(fastify) {
8
- fastify.handlebars.registerHelper('_hb', _hb);
9
- fastify.handlebars.registerHelper('_vue', _vue);
10
- fastify.handlebars.registerHelper('map', map);
11
- fastify.handlebars.registerHelper('mls', _mls);
12
- fastify.handlebars.registerHelper('badge', badge);
13
- }
1
+ import _hb from "./controllers/hb.js";
2
+ import _vue from "./controllers/vue.js";
3
+ import map from "./controllers/map.js";
4
+ import _mls from "./controllers/mls.js";
5
+ import badge from "./controllers/badge.js";
6
+
7
+ export default async function route(fastify) {
8
+ fastify.handlebars.registerHelper('_hb', _hb);
9
+ fastify.handlebars.registerHelper('_vue', _vue);
10
+ fastify.handlebars.registerHelper('map', map);
11
+ fastify.handlebars.registerHelper('mls', _mls);
12
+ fastify.handlebars.registerHelper('badge', badge);
13
+ }
@@ -1,165 +1,165 @@
1
- import fp from 'fastify-plugin';
2
- import fs from 'node:fs';
3
- import path from 'node:path';
4
-
5
- import { getTemplatePath, getTemplate, pgClients } from '@opengis/fastify-table/utils.js';
6
-
7
- import getMenu from '../routes/menu/controllers/getMenu.js';
8
-
9
- import config from '../../config.js';
10
-
11
- // to export the decorators to the outer scope
12
-
13
- async function plugin(fastify) {
14
- fastify.decorate('config', config);
15
-
16
- fastify.addHook('onListen', async () => {
17
- const { client } = pgClients;
18
- const json = await getMenu();
19
- // insert interface list to db (user access management)
20
- if (client?.pk?.['admin.routes'] && json?.length) {
21
- const menuList = json.filter((el) => el?.menu?.length && el?.ua || el?.en || el?.name);
22
- const interfaces = menuList.reduce((acc, curr) => { curr.menu.forEach((el) => acc.push(el.path)); return acc; }, []);
23
- await client.query('update admin.routes set enabled=false where not array[route_id] <@ $1::text[]', [interfaces]);
24
-
25
- const q = `insert into admin.menu(name, ord) values${menuList.map((el, i) => `('${(el?.ua || el?.en || el?.name).replace(/'/g, '’')}', ${i}) `).join(',')
26
- } on conflict (name) do update set ord=excluded.ord, enabled=true returning name, menu_id`;
27
- const { rows = [] } = await client.query(q);
28
- await client.query('update admin.menu set enabled=false where not array[menu_id] <@ $1::text[]', [rows.map((el) => el.menu_id)]);
29
-
30
- const menus = rows.reduce((acc, curr) => Object.assign(acc, { [curr.menu_id]: menuList.find((item) => (item?.ua || item?.en || item?.name) === curr.name) }), {});
31
- const values = Object.entries(menus).reduce((acc, curr) => { curr[1]?.menu?.forEach((el) => acc.push({ ...el, menuId: curr[0] })); return acc; }, []);
32
-
33
- await Promise.all(values.filter((el) => el?.table).map(async (el) => Object.assign(el, { table: (await getTemplate('table', el.table))?.table || el.table })));
34
-
35
- const q1 = `insert into admin.routes(route_id, alias, title, menu_id, table_name) values ${values.map((el) => `('${el.path}', '${el.path}', '${el.title}', '${el.menuId}', '${el.table}')`).join(',')}
36
- on conflict (route_id) do update set menu_id=excluded.menu_id, title=excluded.title, enabled=true,
37
- table_name=excluded.table_name returning route_id, table_name`;
38
- try {
39
- const { rowCount } = await client.query(q1);
40
- // console.log('interface insert ok', values, rowCount);
41
- } catch (err) {
42
- console.log('interface insert error', values, q1, err);
43
- }
44
- }
45
- });
46
-
47
- fastify.addHook('onListen', async () => {
48
- const { client: pg } = pgClients;
49
- const clsQuery = [];
50
- if (!pg.pk?.['admin.cls']) return;
51
-
52
- const selectList = await getTemplatePath('select');
53
- const clsList = (await getTemplatePath('cls'))?.filter((el) => !(selectList?.map((el) => el?.[0]) || []).includes(el[0]));
54
- const cls = (selectList || []).concat(clsList || [])
55
- ?.map((el) => ({ name: el[0], module: path.basename(path.dirname(path.dirname(el[1]))), type: { 'json': 'cls', 'sql': 'select' }[el[2]] }))
56
- if (!cls?.length) return;
57
-
58
- const dupes = cls.filter((el, idx, arr) => arr.map((item) => item.name).indexOf(el.name) !== idx);
59
- // console.log('cls insert skip dupes', dupes.map((el) => el.name));
60
-
61
- try {
62
- await Promise.all(cls.filter((el, idx, arr) => arr.map((item) => item.name).indexOf(el.name) === idx).map(async (el) => {
63
- const { name, module, type } = el;
64
- const loadTemplate = await getTemplate(type, name);
65
- //console.log(name, type);
66
- if (type === 'select') {
67
- clsQuery.push(`insert into admin.cls(name,type,data,module) values('${name}','sql','${(loadTemplate?.sql || loadTemplate)?.replace(/'/g, "''")}', '${module?.replace(/'/g, "''")}')`);
68
- } else if (type === 'cls' && loadTemplate?.length) {
69
- clsQuery.push(`insert into admin.cls(name,type, module) values('${name}','json', '${module?.replace(/'/g, "''")}');
70
- insert into admin.cls(code,name,parent,icon)
71
- select value->>'id',value->>'text','${name}',value->>'icon'
72
- from json_array_elements('${JSON.stringify(loadTemplate).replace(/'/g, "''")}'::json)`);
73
- } else {
74
- console.log(name, type, 'empty');
75
- }
76
- }));
77
-
78
- await pg.query('truncate admin.cls');
79
- if (clsQuery.filter((el) => el).length) {
80
- await pg.query(clsQuery.filter((el) => el).join(';'));
81
- console.log('cls insert ok', clsQuery?.length);
82
- }
83
- } catch (err) {
84
- console.error('cls insert error', err.toString());
85
- }
86
- });
87
-
88
- // pre Request
89
- fastify.addHook('onRequest', async (req) => {
90
- req.funcs = fastify;
91
- const { user } = req.session?.passport || {};
92
- req.user = user;
93
- });
94
-
95
- // preSerialization
96
- fastify.addHook('preSerialization', async (req, reply, payload) => {
97
- if (req.url.includes('/suggest/') && !req.query.json) {
98
- return payload?.data;
99
- }
100
- if (payload?.redirect) {
101
- return reply.redirect(payload.redirect);
102
- }
103
- if (reply.sent) {
104
- return null;
105
- }
106
-
107
- if (['200', '400', '500', '403', '404'].includes(payload?.status)) {
108
- reply.status(payload.status);
109
- }
110
- /* if (payload.headers) {
111
- reply.headers(payload.headers);
112
- } */
113
- if (payload?.buffer) {
114
- return payload.buffer;
115
- }
116
- if (payload?.file) {
117
- // const buffer = await readFile(payload.file);
118
- // return reply.send(buffer);
119
- const stream = fs.createReadStream(payload.file);
120
- return stream;
121
- // return reply.send(stream);
122
- }
123
-
124
- if (payload?.message) {
125
- return payload.message;
126
- }
127
- return payload;
128
- });
129
-
130
- // preValidation
131
- fastify.addHook('preValidation', async (req) => {
132
- const parseRawBody = ['POST', 'PUT'].includes(req.method) && req.body && typeof req.body === 'string'
133
- && req.body.trim(/\r\n/g).startsWith('{')
134
- && req.body.trim(/\r\n/g).endsWith('}');
135
- if (parseRawBody) {
136
- try {
137
- req.body = JSON.parse(req.body || '{}');
138
- }
139
- catch (err) {
140
- // throw new Error('invalid body');
141
- // return { error: 'invalid body', status: 400 };
142
- }
143
- }
144
- });
145
-
146
- // allow upload file
147
- const kIsMultipart = Symbol.for('[FastifyMultipart.isMultipart]');
148
- fastify.addContentTypeParser('multipart', (request, _, done) => {
149
- request[kIsMultipart] = true;
150
- done(null);
151
- });
152
-
153
- // parse Body
154
- function contentParser(req, body, done) {
155
- const parseBody = decodeURIComponent(body.toString()).split('&').reduce((acc, el) => {
156
- const [key, val] = el.split('=');
157
- return { ...acc, [key]: val };
158
- }, {});
159
- done(null, parseBody);
160
- }
161
-
162
- fastify.addContentTypeParser('application/x-www-form-urlencoded', { parseAs: 'buffer' }, contentParser);
163
- }
164
-
165
- export default fp(plugin);
1
+ import fp from 'fastify-plugin';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+
5
+ import { getTemplatePath, getTemplate, pgClients } from '@opengis/fastify-table/utils.js';
6
+
7
+ import getMenu from '../routes/menu/controllers/getMenu.js';
8
+
9
+ import config from '../../config.js';
10
+
11
+ // to export the decorators to the outer scope
12
+
13
+ async function plugin(fastify) {
14
+ fastify.decorate('config', config);
15
+
16
+ fastify.addHook('onListen', async () => {
17
+ const { client } = pgClients;
18
+ const json = await getMenu();
19
+ // insert interface list to db (user access management)
20
+ if (client?.pk?.['admin.routes'] && json?.length) {
21
+ const menuList = json.filter((el) => el?.menu?.length && el?.ua || el?.en || el?.name);
22
+ const interfaces = menuList.reduce((acc, curr) => { curr.menu.forEach((el) => acc.push(el.path)); return acc; }, []);
23
+ await client.query('update admin.routes set enabled=false where not array[route_id] <@ $1::text[]', [interfaces]);
24
+
25
+ const q = `insert into admin.menu(name, ord) values${menuList.map((el, i) => `('${(el?.ua || el?.en || el?.name).replace(/'/g, '’')}', ${i}) `).join(',')
26
+ } on conflict (name) do update set ord=excluded.ord, enabled=true returning name, menu_id`;
27
+ const { rows = [] } = await client.query(q);
28
+ await client.query('update admin.menu set enabled=false where not array[menu_id] <@ $1::text[]', [rows.map((el) => el.menu_id)]);
29
+
30
+ const menus = rows.reduce((acc, curr) => Object.assign(acc, { [curr.menu_id]: menuList.find((item) => (item?.ua || item?.en || item?.name) === curr.name) }), {});
31
+ const values = Object.entries(menus).reduce((acc, curr) => { curr[1]?.menu?.forEach((el) => acc.push({ ...el, menuId: curr[0] })); return acc; }, []);
32
+
33
+ await Promise.all(values.filter((el) => el?.table).map(async (el) => Object.assign(el, { table: (await getTemplate('table', el.table))?.table || el.table })));
34
+
35
+ const q1 = `insert into admin.routes(route_id, alias, title, menu_id, table_name) values ${values.map((el) => `('${el.path}', '${el.path}', '${el.title}', '${el.menuId}', '${el.table}')`).join(',')}
36
+ on conflict (route_id) do update set menu_id=excluded.menu_id, title=excluded.title, enabled=true,
37
+ table_name=excluded.table_name returning route_id, table_name`;
38
+ try {
39
+ const { rowCount } = await client.query(q1);
40
+ // console.log('interface insert ok', values, rowCount);
41
+ } catch (err) {
42
+ console.log('interface insert error', values, q1, err);
43
+ }
44
+ }
45
+ });
46
+
47
+ fastify.addHook('onListen', async () => {
48
+ const { client: pg } = pgClients;
49
+ const clsQuery = [];
50
+ if (!pg.pk?.['admin.cls']) return;
51
+
52
+ const selectList = await getTemplatePath('select');
53
+ const clsList = (await getTemplatePath('cls'))?.filter((el) => !(selectList?.map((el) => el?.[0]) || []).includes(el[0]));
54
+ const cls = (selectList || []).concat(clsList || [])
55
+ ?.map((el) => ({ name: el[0], module: path.basename(path.dirname(path.dirname(el[1]))), type: { 'json': 'cls', 'sql': 'select' }[el[2]] }))
56
+ if (!cls?.length) return;
57
+
58
+ const dupes = cls.filter((el, idx, arr) => arr.map((item) => item.name).indexOf(el.name) !== idx);
59
+ // console.log('cls insert skip dupes', dupes.map((el) => el.name));
60
+
61
+ try {
62
+ await Promise.all(cls.filter((el, idx, arr) => arr.map((item) => item.name).indexOf(el.name) === idx).map(async (el) => {
63
+ const { name, module, type } = el;
64
+ const loadTemplate = await getTemplate(type, name);
65
+ //console.log(name, type);
66
+ if (type === 'select') {
67
+ clsQuery.push(`insert into admin.cls(name,type,data,module) values('${name}','sql','${(loadTemplate?.sql || loadTemplate)?.replace(/'/g, "''")}', '${module?.replace(/'/g, "''")}')`);
68
+ } else if (type === 'cls' && loadTemplate?.length) {
69
+ clsQuery.push(`insert into admin.cls(name,type, module) values('${name}','json', '${module?.replace(/'/g, "''")}');
70
+ insert into admin.cls(code,name,parent,icon)
71
+ select value->>'id',value->>'text','${name}',value->>'icon'
72
+ from json_array_elements('${JSON.stringify(loadTemplate).replace(/'/g, "''")}'::json)`);
73
+ } else {
74
+ console.log(name, type, 'empty');
75
+ }
76
+ }));
77
+
78
+ await pg.query('truncate admin.cls');
79
+ if (clsQuery.filter((el) => el).length) {
80
+ await pg.query(clsQuery.filter((el) => el).join(';'));
81
+ console.log('cls insert ok', clsQuery?.length);
82
+ }
83
+ } catch (err) {
84
+ console.error('cls insert error', err.toString());
85
+ }
86
+ });
87
+
88
+ // pre Request
89
+ fastify.addHook('onRequest', async (req) => {
90
+ req.funcs = fastify;
91
+ const { user } = req.session?.passport || {};
92
+ req.user = user;
93
+ });
94
+
95
+ // preSerialization
96
+ fastify.addHook('preSerialization', async (req, reply, payload) => {
97
+ if (req.url.includes('/suggest/') && !req.query.json) {
98
+ return payload?.data;
99
+ }
100
+ if (payload?.redirect) {
101
+ return reply.redirect(payload.redirect);
102
+ }
103
+ if (reply.sent) {
104
+ return null;
105
+ }
106
+
107
+ if (['200', '400', '500', '403', '404'].includes(payload?.status)) {
108
+ reply.status(payload.status);
109
+ }
110
+ /* if (payload.headers) {
111
+ reply.headers(payload.headers);
112
+ } */
113
+ if (payload?.buffer) {
114
+ return payload.buffer;
115
+ }
116
+ if (payload?.file) {
117
+ // const buffer = await readFile(payload.file);
118
+ // return reply.send(buffer);
119
+ const stream = fs.createReadStream(payload.file);
120
+ return stream;
121
+ // return reply.send(stream);
122
+ }
123
+
124
+ if (payload?.message) {
125
+ return payload.message;
126
+ }
127
+ return payload;
128
+ });
129
+
130
+ // preValidation
131
+ fastify.addHook('preValidation', async (req) => {
132
+ const parseRawBody = ['POST', 'PUT'].includes(req.method) && req.body && typeof req.body === 'string'
133
+ && req.body.trim(/\r\n/g).startsWith('{')
134
+ && req.body.trim(/\r\n/g).endsWith('}');
135
+ if (parseRawBody) {
136
+ try {
137
+ req.body = JSON.parse(req.body || '{}');
138
+ }
139
+ catch (err) {
140
+ // throw new Error('invalid body');
141
+ // return { error: 'invalid body', status: 400 };
142
+ }
143
+ }
144
+ });
145
+
146
+ // allow upload file
147
+ const kIsMultipart = Symbol.for('[FastifyMultipart.isMultipart]');
148
+ fastify.addContentTypeParser('multipart', (request, _, done) => {
149
+ request[kIsMultipart] = true;
150
+ done(null);
151
+ });
152
+
153
+ // parse Body
154
+ function contentParser(req, body, done) {
155
+ const parseBody = decodeURIComponent(body.toString()).split('&').reduce((acc, el) => {
156
+ const [key, val] = el.split('=');
157
+ return { ...acc, [key]: val };
158
+ }, {});
159
+ done(null, parseBody);
160
+ }
161
+
162
+ fastify.addContentTypeParser('application/x-www-form-urlencoded', { parseAs: 'buffer' }, contentParser);
163
+ }
164
+
165
+ export default fp(plugin);
@@ -1,11 +1,11 @@
1
- //import { addCron } from '@opengis/fastify-table/utils.js';
2
-
3
- async function deleteOldNotifications({ pg }) {
4
- const { rowCount } = pg?.pk?.['crm.notifications'] ? await pg.query('delete from crm.notifications where CURRENT_DATE - \'14 days\'::interval > cdate') : {};
5
- return { rowCount };
6
- }
7
-
8
- export default async function cron(fastify) {
9
- // addCron(deleteOldNotifications, 60 * 60 * 24, fastify);
10
- // addCron(deleteOldNotifications, 60 * 1, fastify); // debug
1
+ //import { addCron } from '@opengis/fastify-table/utils.js';
2
+
3
+ async function deleteOldNotifications({ pg }) {
4
+ const { rowCount } = pg?.pk?.['crm.notifications'] ? await pg.query('delete from crm.notifications where CURRENT_DATE - \'14 days\'::interval > cdate') : {};
5
+ return { rowCount };
6
+ }
7
+
8
+ export default async function cron(fastify) {
9
+ // addCron(deleteOldNotifications, 60 * 60 * 24, fastify);
10
+ // addCron(deleteOldNotifications, 60 * 1, fastify); // debug
11
11
  }