@opengis/fastify-table 1.1.50 → 1.1.51

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 (211) hide show
  1. package/.eslintrc.cjs +42 -42
  2. package/.gitlab-ci.yml +18 -18
  3. package/Changelog.md +352 -351
  4. package/README.md +26 -26
  5. package/config.js +10 -10
  6. package/cron/controllers/cronApi.js +22 -22
  7. package/cron/controllers/utils/cronList.js +1 -1
  8. package/cron/funcs/addCron.js +132 -132
  9. package/cron/index.js +10 -10
  10. package/crud/controllers/deleteCrud.js +36 -36
  11. package/crud/controllers/insert.js +71 -71
  12. package/crud/controllers/update.js +76 -76
  13. package/crud/controllers/utils/xssInjection.js +72 -72
  14. package/crud/funcs/dataDelete.js +19 -19
  15. package/crud/funcs/dataInsert.js +30 -30
  16. package/crud/funcs/dataUpdate.js +48 -48
  17. package/crud/funcs/getAccess.js +46 -44
  18. package/crud/funcs/getOpt.js +10 -10
  19. package/crud/funcs/getToken.js +27 -27
  20. package/crud/funcs/isFileExists.js +13 -13
  21. package/crud/funcs/setOpt.js +16 -16
  22. package/crud/funcs/setToken.js +53 -53
  23. package/crud/funcs/utils/getFolder.js +9 -9
  24. package/crud/funcs/utils/logChanges.js +62 -62
  25. package/crud/index.js +36 -36
  26. package/docs/.vitepress/abbr.mjs +26 -26
  27. package/docs/.vitepress/config.mjs +127 -127
  28. package/docs/.vitepress/navigation.mjs +82 -82
  29. package/docs/.vitepress/theme/Layout.vue +17 -17
  30. package/docs/.vitepress/theme/components/NavigationLinks.vue +102 -102
  31. package/docs/.vitepress/theme/components/Panzoom.vue +169 -169
  32. package/docs/.vitepress/theme/index.mjs +15 -15
  33. package/docs/.vitepress/theme/style.scss +163 -163
  34. package/docs/abbr.json +4 -4
  35. package/docs/api/cron/cronApi.md +56 -56
  36. package/docs/api/crud/deleteCrud.md +58 -58
  37. package/docs/api/crud/insert.md +82 -82
  38. package/docs/api/crud/update.md +85 -85
  39. package/docs/api/index.md +47 -47
  40. package/docs/api/notification/testEmail.md +91 -91
  41. package/docs/api/table/card.md +73 -73
  42. package/docs/api/table/data.md +134 -134
  43. package/docs/api/table/export.md +60 -60
  44. package/docs/api/table/filter.md +104 -104
  45. package/docs/api/table/form.md +126 -126
  46. package/docs/api/table/search.md +123 -123
  47. package/docs/api/table/suggest.md +156 -156
  48. package/docs/api/table/table.md +107 -107
  49. package/docs/api/user/user.cls.id.md +77 -77
  50. package/docs/api/user/user.cls.md +49 -49
  51. package/docs/api/user/user.cls.post.md +62 -62
  52. package/docs/api/user/user.info.md +37 -37
  53. package/docs/api/utils/logger.file.md +60 -60
  54. package/docs/api/utils/next.id.md +34 -34
  55. package/docs/api/utils/properties.add.md +127 -127
  56. package/docs/api/utils/properties.get.md +73 -73
  57. package/docs/api/utils/status.monitor.md +36 -36
  58. package/docs/api/widget/widget.del.md +76 -76
  59. package/docs/api/widget/widget.get.md +233 -233
  60. package/docs/api/widget/widget.set.md +88 -88
  61. package/docs/db/admin.md +947 -947
  62. package/docs/db/crm.md +564 -564
  63. package/docs/db/index.md +9 -9
  64. package/docs/db/log.md +204 -204
  65. package/docs/hook/card/afterCard.md +20 -20
  66. package/docs/hook/card/preCard.md +25 -25
  67. package/docs/hook/data/afterData.md +26 -26
  68. package/docs/hook/data/preData.md +26 -26
  69. package/docs/hook/deleteCrud/afterDelete.md +21 -21
  70. package/docs/hook/deleteCrud/preDelete.md +26 -26
  71. package/docs/hook/form/afterForm.md +19 -19
  72. package/docs/hook/form/preForm.md +26 -26
  73. package/docs/hook/getTemplate/afterTemplate.md +24 -24
  74. package/docs/hook/getTemplate/preTemplate.md +29 -29
  75. package/docs/hook/index.md +45 -45
  76. package/docs/hook/insert/afterInsert.md +41 -41
  77. package/docs/hook/insert/preInsert.md +25 -25
  78. package/docs/hook/table/afterTable.md +20 -20
  79. package/docs/hook/table/preTable.md +25 -25
  80. package/docs/hook/update/afterUpdate.md +41 -41
  81. package/docs/hook/update/preUpdate.md +25 -25
  82. package/docs/index.md +42 -42
  83. package/docs/public/fastify-dark.svg +3 -3
  84. package/docs/public/logo-short-dark.svg +11 -11
  85. package/docs/public/logo-short.svg +10 -10
  86. package/docs/public/logo.svg +19 -19
  87. package/docs/readme/index.md +121 -121
  88. package/docs/templates/card.md +83 -83
  89. package/docs/templates/cls.md +29 -29
  90. package/docs/templates/filters.md +91 -91
  91. package/docs/templates/forms.md +139 -139
  92. package/docs/templates/index.md +28 -28
  93. package/docs/templates/select.md +90 -90
  94. package/docs/templates/table.md +162 -162
  95. package/docs/utils/cron/addCron.md +29 -29
  96. package/docs/utils/crud/dataInsert.md +51 -51
  97. package/docs/utils/crud/dataUpdate.md +52 -52
  98. package/docs/utils/crud/getOpt.md +33 -33
  99. package/docs/utils/crud/isFileExists.md +37 -37
  100. package/docs/utils/crud/setOpt.md +37 -37
  101. package/docs/utils/hook/addHook.md +74 -74
  102. package/docs/utils/hook/applyHook.md +64 -64
  103. package/docs/utils/index.md +47 -47
  104. package/docs/utils/notification/addNotification.md +28 -28
  105. package/docs/utils/notification/notification.md +41 -41
  106. package/docs/utils/pg/autoIndex.md +22 -22
  107. package/docs/utils/pg/getMeta.md +58 -58
  108. package/docs/utils/pg/getPG.md +34 -34
  109. package/docs/utils/pg/init.md +29 -29
  110. package/docs/utils/pg/pg.md +70 -70
  111. package/docs/utils/redis/getRedis.md +36 -36
  112. package/docs/utils/redis/rclient.md +74 -74
  113. package/docs/utils/table/getForm.md +68 -68
  114. package/docs/utils/table/getMeta.md +55 -55
  115. package/docs/utils/table/getSelect.md +38 -38
  116. package/docs/utils/table/getSelectMeta.md +46 -46
  117. package/docs/utils/table/getTable.md +77 -77
  118. package/helper.js +30 -30
  119. package/index.js +105 -105
  120. package/migration/exec.migrations.js +79 -79
  121. package/module/core/select/core.user_mentioned.sql +1 -1
  122. package/module/test/cls/itree.composition.json +25 -25
  123. package/module/test/table/test.rest_zone.table.json +265 -265
  124. package/notification/controllers/readNotifications.js +30 -30
  125. package/notification/controllers/testEmail.js +50 -50
  126. package/notification/controllers/userNotifications.js +64 -64
  127. package/notification/funcs/addNotification.js +21 -21
  128. package/notification/funcs/sendNotification.js +112 -112
  129. package/package.json +41 -41
  130. package/pg/funcs/getMeta.js +29 -29
  131. package/pg/funcs/getPG.js +30 -30
  132. package/pg/pgClients.js +20 -20
  133. package/policy/funcs/checkPolicy.js +92 -92
  134. package/policy/funcs/sqlInjection.js +33 -33
  135. package/policy/index.js +14 -14
  136. package/redis/client.js +8 -8
  137. package/redis/funcs/getRedis.js +23 -23
  138. package/redis/funcs/redisClients.js +2 -2
  139. package/redis/index.js +19 -19
  140. package/server/migrations/0.sql +78 -78
  141. package/server/migrations/cls.sql +39 -39
  142. package/server/migrations/log.sql +80 -80
  143. package/server/migrations/properties.sql +144 -144
  144. package/server/migrations/roles.sql +172 -166
  145. package/server/migrations/users.sql +168 -168
  146. package/server.js +26 -26
  147. package/table/controllers/data.js +150 -150
  148. package/table/controllers/filter.js +50 -50
  149. package/table/controllers/form.js +42 -42
  150. package/table/controllers/search.js +80 -80
  151. package/table/controllers/suggest.js +79 -79
  152. package/table/controllers/table.js +83 -83
  153. package/table/controllers/utils/addTemplateDir.js +8 -8
  154. package/table/controllers/utils/getSelect.js +19 -19
  155. package/table/controllers/utils/getSelectMeta.js +66 -66
  156. package/table/controllers/utils/getTemplate_old.js +28 -28
  157. package/table/controllers/utils/getTemplates.js +18 -18
  158. package/table/controllers/utils/gisIRColumn.js +67 -67
  159. package/table/controllers/utils/loadTemplate.js +1 -1
  160. package/table/controllers/utils/loadTemplatePath.js +1 -1
  161. package/table/controllers/utils/userTemplateDir.js +1 -1
  162. package/table/funcs/getFilterSQL/index.js +94 -94
  163. package/table/funcs/getFilterSQL/util/formatValue.js +170 -170
  164. package/table/funcs/getFilterSQL/util/getCustomQuery.js +13 -13
  165. package/table/funcs/getFilterSQL/util/getFilterQuery.js +66 -66
  166. package/table/funcs/getFilterSQL/util/getOptimizedQuery.js +12 -12
  167. package/table/funcs/getFilterSQL/util/getTableSql.js +34 -34
  168. package/table/funcs/metaFormat/getSelectVal.js +21 -21
  169. package/table/funcs/metaFormat/index.js +28 -28
  170. package/table/index.js +37 -37
  171. package/table/schema.js +54 -54
  172. package/test/api/applyHook.test.js +95 -95
  173. package/test/api/crud.test.js +89 -89
  174. package/test/api/crud.xss.test.js +80 -80
  175. package/test/api/suggest.test.js +66 -66
  176. package/test/api/table.test.js +134 -134
  177. package/test/api/user.test.js +85 -85
  178. package/test/api/widget.test.js +117 -117
  179. package/test/config.example +18 -18
  180. package/test/funcs/pg.test.js +34 -34
  181. package/test/funcs/redis.test.js +19 -19
  182. package/test/helper/formatDate.test.js +62 -62
  183. package/test/templates/cls/test.json +9 -9
  184. package/test/templates/form/cp_building.form.json +32 -32
  185. package/test/templates/select/account_id.json +3 -3
  186. package/test/templates/select/storage.data.json +2 -2
  187. package/test/templates/select/test.storage.data.json +3 -3
  188. package/test/templates/select/test.suggest.ato_new.json +3 -3
  189. package/test/templates/select/test.suggest.ato_new.sql +25 -25
  190. package/test/templates/select/test.suggest.data.json +4 -4
  191. package/test/templates/select/test.suggest.parent.sql +1 -1
  192. package/test/templates/table/gis.dataset.table.json +20 -20
  193. package/user/controllers/user.cls.id.js +14 -14
  194. package/user/controllers/user.cls.js +75 -75
  195. package/user/controllers/user.cls.post.js +55 -55
  196. package/user/controllers/user.info.js +21 -21
  197. package/util/controllers/logger.file.js +91 -91
  198. package/util/controllers/next.id.js +4 -4
  199. package/util/controllers/properties.add.js +60 -60
  200. package/util/controllers/properties.get.js +19 -19
  201. package/util/controllers/status.monitor.js +8 -8
  202. package/util/controllers/utils/checkUserAccess.js +17 -17
  203. package/util/controllers/utils/getRootDir.js +25 -25
  204. package/util/index.js +23 -23
  205. package/utils.js +104 -104
  206. package/widget/controllers/utils/historyFormat.js +76 -76
  207. package/widget/controllers/utils/obj2db.js +13 -13
  208. package/widget/controllers/widget.del.js +44 -44
  209. package/widget/controllers/widget.get.js +102 -102
  210. package/widget/controllers/widget.set.js +79 -79
  211. package/widget/index.js +40 -40
@@ -1,21 +1,21 @@
1
- export default async function userInfo({
2
- pg, session = {},
3
- }) {
4
- const { uid } = session.passport?.user || {};
5
-
6
- if (!uid) {
7
- return { message: 'access restricted', status: 403 };
8
- }
9
-
10
- const data = await pg.query(`select user_name, sur_name, father_name, user_rnokpp, user_type, email, login from admin.users
11
- where uid=$1`, [uid]).then((res) => res.rows?.[0] || {});
12
-
13
- try {
14
- const { notifications = 0 } = await pg.query(`select count(*)::int as notifications from crm.notifications
15
- where addressee_id=$1 and read is not true`, [uid]).then((res) => res.rows?.[0] || {});
16
- return { uid, ...data, notifications };
17
- }
18
- catch (err) {
19
- return { error: err.toString(), status: 500 };
20
- }
21
- }
1
+ export default async function userInfo({
2
+ pg, session = {},
3
+ }) {
4
+ const { uid } = session.passport?.user || {};
5
+
6
+ if (!uid) {
7
+ return { message: 'access restricted', status: 403 };
8
+ }
9
+
10
+ const data = await pg.query(`select user_name, sur_name, father_name, user_rnokpp, user_type, email, login from admin.users
11
+ where uid=$1`, [uid]).then((res) => res.rows?.[0] || {});
12
+
13
+ try {
14
+ const { notifications = 0 } = await pg.query(`select count(*)::int as notifications from crm.notifications
15
+ where addressee_id=$1 and read is not true`, [uid]).then((res) => res.rows?.[0] || {});
16
+ return { uid, ...data, notifications };
17
+ }
18
+ catch (err) {
19
+ return { error: err.toString(), status: 500 };
20
+ }
21
+ }
@@ -1,91 +1,91 @@
1
- import path from 'path';
2
- import { lstat, readdir, readFile } from 'fs/promises';
3
- import { createReadStream, existsSync } from 'fs';
4
- import readline from 'readline';
5
-
6
- import checkUserAccess from './utils/checkUserAccess.js';
7
- import getRootDir from './utils/getRootDir.js';
8
-
9
- /**
10
- *
11
- * @method GET
12
- * @summary API для перегляду логів
13
- *
14
- */
15
-
16
- export default async function loggerFile({
17
- params = {}, user = {}, query = {}, originalUrl, funcs = {},
18
- }, reply) {
19
- const limit = 200000;
20
- const access = await checkUserAccess({ user });
21
-
22
- const { config = {} } = funcs;
23
- if (access?.status === 403 && !config?.local) return access;
24
-
25
- // absolute / relative path
26
- const rootDir = getRootDir();
27
-
28
- const filepath = path.join(rootDir, params['*'] || '');
29
-
30
- if (!existsSync(filepath)) {
31
- return { error: 'file not exists', status: 404 };
32
- }
33
- const stat = await lstat(filepath);
34
- const isFile = stat.isFile();
35
-
36
- if (query.download && isFile) {
37
- return reply.download(filepath);
38
- }
39
-
40
- if (query.full && isFile) {
41
- if (stat.size > 20 * 1000 * 1000) {
42
- return { message: 'file size > 20MB' };
43
- }
44
- const buffer = await readFile(filepath, { buffer: true });
45
- return buffer;
46
- }
47
-
48
- if (isFile) {
49
- const ext = path.extname(filepath);
50
-
51
- const lines = await new Promise((resolve) => {
52
- const rl = readline.createInterface({
53
- input: createReadStream(filepath, { start: stat.size > limit ? stat.size - limit : 0 }),
54
- });
55
- const lines1 = [];
56
- rl.on('close', () => resolve(lines1));
57
- rl.on('line', (line) => lines1.push(line));
58
- });
59
-
60
- if (ext === '.html') {
61
- const buffer = await readFile(filepath, { buffer: true });
62
- reply.headers({ 'Content-type': 'text/html; charset=UTF-8' });
63
- return buffer;
64
- }
65
-
66
- reply.headers({ 'Content-type': 'text/plain' });
67
- return stat.size > limit && lines.length > 1
68
- ? lines.reverse().slice(0, -1).join('\n')
69
- : lines.reverse().join('\n');
70
- }
71
-
72
- // dir
73
- const files = await readdir(filepath);
74
-
75
- if (query.dir) {
76
- return files.filter((el) => !['backup', 'marker_icon', 'error', 'migration'].includes(el));
77
- }
78
-
79
- const lstatsArr = await Promise.all(files.map(async (file) => [file, await lstat(path.join(filepath, file))]));
80
- const lstats = Object.fromEntries(lstatsArr);
81
-
82
- const message = (params['*'] ? '<a href="/logger-file/">...</a><br>' : '')
83
- + files.map((file) => `<a href="${originalUrl}/${file}">${file}</a> (${lstats[file].size} bytes)`).join('</br>');
84
-
85
- reply.headers({
86
- 'Content-Type': 'text/html; charset=UTF-8',
87
- 'Content-Security-Policy': "default-src 'none'",
88
- 'X-Content-Type-Options': 'nosniff',
89
- });
90
- return message;
91
- }
1
+ import path from 'path';
2
+ import { lstat, readdir, readFile } from 'fs/promises';
3
+ import { createReadStream, existsSync } from 'fs';
4
+ import readline from 'readline';
5
+
6
+ import checkUserAccess from './utils/checkUserAccess.js';
7
+ import getRootDir from './utils/getRootDir.js';
8
+
9
+ /**
10
+ *
11
+ * @method GET
12
+ * @summary API для перегляду логів
13
+ *
14
+ */
15
+
16
+ export default async function loggerFile({
17
+ params = {}, user = {}, query = {}, originalUrl, funcs = {},
18
+ }, reply) {
19
+ const limit = 200000;
20
+ const access = await checkUserAccess({ user });
21
+
22
+ const { config = {} } = funcs;
23
+ if (access?.status === 403 && !config?.local) return access;
24
+
25
+ // absolute / relative path
26
+ const rootDir = getRootDir();
27
+
28
+ const filepath = path.join(rootDir, params['*'] || '');
29
+
30
+ if (!existsSync(filepath)) {
31
+ return { error: 'file not exists', status: 404 };
32
+ }
33
+ const stat = await lstat(filepath);
34
+ const isFile = stat.isFile();
35
+
36
+ if (query.download && isFile) {
37
+ return reply.download(filepath);
38
+ }
39
+
40
+ if (query.full && isFile) {
41
+ if (stat.size > 20 * 1000 * 1000) {
42
+ return { message: 'file size > 20MB' };
43
+ }
44
+ const buffer = await readFile(filepath, { buffer: true });
45
+ return buffer;
46
+ }
47
+
48
+ if (isFile) {
49
+ const ext = path.extname(filepath);
50
+
51
+ const lines = await new Promise((resolve) => {
52
+ const rl = readline.createInterface({
53
+ input: createReadStream(filepath, { start: stat.size > limit ? stat.size - limit : 0 }),
54
+ });
55
+ const lines1 = [];
56
+ rl.on('close', () => resolve(lines1));
57
+ rl.on('line', (line) => lines1.push(line));
58
+ });
59
+
60
+ if (ext === '.html') {
61
+ const buffer = await readFile(filepath, { buffer: true });
62
+ reply.headers({ 'Content-type': 'text/html; charset=UTF-8' });
63
+ return buffer;
64
+ }
65
+
66
+ reply.headers({ 'Content-type': 'text/plain' });
67
+ return stat.size > limit && lines.length > 1
68
+ ? lines.reverse().slice(0, -1).join('\n')
69
+ : lines.reverse().join('\n');
70
+ }
71
+
72
+ // dir
73
+ const files = await readdir(filepath);
74
+
75
+ if (query.dir) {
76
+ return files.filter((el) => !['backup', 'marker_icon', 'error', 'migration'].includes(el));
77
+ }
78
+
79
+ const lstatsArr = await Promise.all(files.map(async (file) => [file, await lstat(path.join(filepath, file))]));
80
+ const lstats = Object.fromEntries(lstatsArr);
81
+
82
+ const message = (params['*'] ? '<a href="/logger-file/">...</a><br>' : '')
83
+ + files.map((file) => `<a href="${originalUrl}/${file}">${file}</a> (${lstats[file].size} bytes)`).join('</br>');
84
+
85
+ reply.headers({
86
+ 'Content-Type': 'text/html; charset=UTF-8',
87
+ 'Content-Security-Policy': "default-src 'none'",
88
+ 'X-Content-Type-Options': 'nosniff',
89
+ });
90
+ return message;
91
+ }
@@ -1,4 +1,4 @@
1
- export default async function nextId({ pg }) {
2
- const { id } = await pg.one('select next_id() as id');
3
- return { id: id.toString() };
4
- };
1
+ export default async function nextId({ pg }) {
2
+ const { id } = await pg.one('select next_id() as id');
3
+ return { id: id.toString() };
4
+ };
@@ -1,60 +1,60 @@
1
- import { dataInsert, config } from '../../utils.js';
2
-
3
- const table = 'crm.properties';
4
-
5
- function checkKeyType({ body, key }) {
6
- if (typeof body[key] === 'number' && (!/\D/.test(body[key].toString()) && body[key].toString().length < 10)) {
7
- return { [key]: 'int' };
8
- } if (typeof body[key] === 'object') {
9
- return { [key]: 'json' };
10
- }
11
- if (Date.parse(body[key], 'yyyy/MM/ddTHH:mm:ss.000Z')) {
12
- return { [key]: 'date' };
13
- }
14
- return { [key]: 'text' };
15
- }
16
-
17
- export default async function addExtraProperties({
18
- pg, params = {}, body = {}, user = {},
19
- }) {
20
- const { id } = params;
21
- const { uid } = user;
22
- if (!uid) {
23
- return { message: 'access restricted: uid', status: 403 };
24
- }
25
- if (!id) {
26
- return { message: 'not enougn params: 1', status: 400 };
27
- }
28
- const extraProperties = Object.keys(body);
29
- if (!extraProperties.length) {
30
- return { message: 'not enougn params: 2', status: 400 };
31
- }
32
-
33
- if (!pg.pk?.[table]) {
34
- return { message: 'table not found: crm.properties', status: 400 };
35
- }
36
-
37
- try {
38
- await pg.query('delete from crm.properties where object_id=$1', [id]); // rewrite?
39
- const keyTypeMatch = extraProperties.filter((key) => body[key]).reduce((acc, curr) => Object.assign(acc, checkKeyType({ body, key: curr })), {});
40
- const res = await Promise.all(Object.keys(keyTypeMatch).map(async (key) => {
41
- const propertyType = keyTypeMatch[key];
42
- const { rows = [] } = await dataInsert({
43
- pg,
44
- table,
45
- data: {
46
- property_type: propertyType,
47
- property_key: key,
48
- object_id: id,
49
- [`property_${propertyType}`]: body[key],
50
- },
51
- uid,
52
- });
53
- return { id: rows[0]?.property_id, type: propertyType, value: body[key] };
54
- }));
55
- return { message: { rows: res }, status: 200 };
56
- }
57
- catch (err) {
58
- return { error: err.toString(), status: 500 };
59
- }
60
- }
1
+ import { dataInsert, config } from '../../utils.js';
2
+
3
+ const table = 'crm.properties';
4
+
5
+ function checkKeyType({ body, key }) {
6
+ if (typeof body[key] === 'number' && (!/\D/.test(body[key].toString()) && body[key].toString().length < 10)) {
7
+ return { [key]: 'int' };
8
+ } if (typeof body[key] === 'object') {
9
+ return { [key]: 'json' };
10
+ }
11
+ if (Date.parse(body[key], 'yyyy/MM/ddTHH:mm:ss.000Z')) {
12
+ return { [key]: 'date' };
13
+ }
14
+ return { [key]: 'text' };
15
+ }
16
+
17
+ export default async function addExtraProperties({
18
+ pg, params = {}, body = {}, user = {},
19
+ }) {
20
+ const { id } = params;
21
+ const { uid } = user;
22
+ if (!uid) {
23
+ return { message: 'access restricted: uid', status: 403 };
24
+ }
25
+ if (!id) {
26
+ return { message: 'not enougn params: 1', status: 400 };
27
+ }
28
+ const extraProperties = Object.keys(body);
29
+ if (!extraProperties.length) {
30
+ return { message: 'not enougn params: 2', status: 400 };
31
+ }
32
+
33
+ if (!pg.pk?.[table]) {
34
+ return { message: 'table not found: crm.properties', status: 400 };
35
+ }
36
+
37
+ try {
38
+ await pg.query('delete from crm.properties where object_id=$1', [id]); // rewrite?
39
+ const keyTypeMatch = extraProperties.filter((key) => body[key]).reduce((acc, curr) => Object.assign(acc, checkKeyType({ body, key: curr })), {});
40
+ const res = await Promise.all(Object.keys(keyTypeMatch).map(async (key) => {
41
+ const propertyType = keyTypeMatch[key];
42
+ const { rows = [] } = await dataInsert({
43
+ pg,
44
+ table,
45
+ data: {
46
+ property_type: propertyType,
47
+ property_key: key,
48
+ object_id: id,
49
+ [`property_${propertyType}`]: body[key],
50
+ },
51
+ uid,
52
+ });
53
+ return { id: rows[0]?.property_id, type: propertyType, value: body[key] };
54
+ }));
55
+ return { message: { rows: res }, status: 200 };
56
+ }
57
+ catch (err) {
58
+ return { error: err.toString(), status: 500 };
59
+ }
60
+ }
@@ -1,20 +1,20 @@
1
- export default async function getExtraProperties({
2
- pg, params = {},
3
- }) {
4
- const { id } = params;
5
- if (!id) {
6
- return { message: 'not enougn params', status: 400 };
7
- }
8
- try {
9
- const { rows = [] } = pg.pk?.['crm.properties']
10
- ? await pg.query(`select property_key, property_type, property_text, property_int,
11
- property_json, property_date from crm.properties where property_key is not null and object_id=$1`, [id])
12
- : {};
13
- if (!rows.length) return {};
14
-
15
- const data = rows.reduce((acc, curr) => Object.assign(acc, { [curr.property_key]: curr[`property_${curr.property_type}`] }), {});
16
- return { message: data, status: 200 };
17
- } catch (err) {
18
- return { error: err.toString(), status: 500 };
19
- }
1
+ export default async function getExtraProperties({
2
+ pg, params = {},
3
+ }) {
4
+ const { id } = params;
5
+ if (!id) {
6
+ return { message: 'not enougn params', status: 400 };
7
+ }
8
+ try {
9
+ const { rows = [] } = pg.pk?.['crm.properties']
10
+ ? await pg.query(`select property_key, property_type, property_text, property_int,
11
+ property_json, property_date from crm.properties where property_key is not null and object_id=$1`, [id])
12
+ : {};
13
+ if (!rows.length) return {};
14
+
15
+ const data = rows.reduce((acc, curr) => Object.assign(acc, { [curr.property_key]: curr[`property_${curr.property_type}`] }), {});
16
+ return { message: data, status: 200 };
17
+ } catch (err) {
18
+ return { error: err.toString(), status: 500 };
19
+ }
20
20
  }
@@ -1,8 +1,8 @@
1
- const formatMemoryUsage = (data) => `${Math.round(data / 1024 / 1024 * 100) / 100} MB`;
2
-
3
- export default async function statusMonitor() {
4
- const memoryUsage = process.memoryUsage();
5
- const message = Object.keys(memoryUsage)
6
- .reduce((acc, curr) => Object.assign(acc, { [curr]: formatMemoryUsage(memoryUsage[curr]) }), {});
7
- return { message, status: 200 };
8
- }
1
+ const formatMemoryUsage = (data) => `${Math.round(data / 1024 / 1024 * 100) / 100} MB`;
2
+
3
+ export default async function statusMonitor() {
4
+ const memoryUsage = process.memoryUsage();
5
+ const message = Object.keys(memoryUsage)
6
+ .reduce((acc, curr) => Object.assign(acc, { [curr]: formatMemoryUsage(memoryUsage[curr]) }), {});
7
+ return { message, status: 200 };
8
+ }
@@ -1,17 +1,17 @@
1
- /**
2
- *
3
- * @summary check user access to logger interface - per admin user type or user group
4
- * @returns {Object} message, status
5
- */
6
-
7
- export default async function checkUserAccess({
8
- user,
9
- }) {
10
- // console.log(user);
11
- if (!user?.uid) return { message: 'access restricted', status: 403 };
12
-
13
- /* if (!['admin', 'superadmin']?.includes(user.user_type) && count === '0') {
14
- return { message: 'access restricted', status: 403 };
15
- } */
16
- return { message: 'access granted', status: 200 };
17
- }
1
+ /**
2
+ *
3
+ * @summary check user access to logger interface - per admin user type or user group
4
+ * @returns {Object} message, status
5
+ */
6
+
7
+ export default async function checkUserAccess({
8
+ user,
9
+ }) {
10
+ // console.log(user);
11
+ if (!user?.uid) return { message: 'access restricted', status: 403 };
12
+
13
+ /* if (!['admin', 'superadmin']?.includes(user.user_type) && count === '0') {
14
+ return { message: 'access restricted', status: 403 };
15
+ } */
16
+ return { message: 'access granted', status: 200 };
17
+ }
@@ -1,25 +1,25 @@
1
- import path from 'path';
2
- import fs from 'fs';
3
- import config from '../../../config.js';
4
-
5
- // import { existsSync } from 'fs';
6
- let logDir = null;
7
- export default function getRootDir() {
8
- // absolute / relative path
9
- if (logDir) return logDir;
10
- const file = ['config.json', '/data/local/config.json'].find(el => (fs.existsSync(el) ? el : null));
11
- const root = file === 'config.json' ? process.cwd() : '/data/local';
12
- logDir = config.logDir || path.join(root, config.log?.dir || 'log');
13
- console.log({ logDir });
14
- return logDir;
15
-
16
- // windows debug support
17
- /* const customLogDir = process.cwd().includes(':') ? 'c:/data/local' : '/data/local';
18
- // docker default path
19
- if (existsSync(customLogDir)) {
20
- return path.join(customLogDir, config.folder || '', 'log');
21
- }
22
-
23
- // non-docker default path
24
- return path.join(config.root || '/data/local', config.folder || '', 'log'); */
25
- }
1
+ import path from 'path';
2
+ import fs from 'fs';
3
+ import config from '../../../config.js';
4
+
5
+ // import { existsSync } from 'fs';
6
+ let logDir = null;
7
+ export default function getRootDir() {
8
+ // absolute / relative path
9
+ if (logDir) return logDir;
10
+ const file = ['config.json', '/data/local/config.json'].find(el => (fs.existsSync(el) ? el : null));
11
+ const root = file === 'config.json' ? process.cwd() : '/data/local';
12
+ logDir = config.logDir || path.join(root, config.log?.dir || 'log');
13
+ console.log({ logDir });
14
+ return logDir;
15
+
16
+ // windows debug support
17
+ /* const customLogDir = process.cwd().includes(':') ? 'c:/data/local' : '/data/local';
18
+ // docker default path
19
+ if (existsSync(customLogDir)) {
20
+ return path.join(customLogDir, config.folder || '', 'log');
21
+ }
22
+
23
+ // non-docker default path
24
+ return path.join(config.root || '/data/local', config.folder || '', 'log'); */
25
+ }
package/util/index.js CHANGED
@@ -1,23 +1,23 @@
1
- import getExtraProperties from './controllers/properties.get.js';
2
- import addExtraProperties from './controllers/properties.add.js';
3
- import nextId from './controllers/next.id.js';
4
- import statusMonitor from './controllers/status.monitor.js';
5
- import loggerFile from './controllers/logger.file.js';
6
-
7
- const propertiesSchema = {
8
- params: {
9
- id: { type: 'string', pattern: '^([\\d\\w]+)$' },
10
- },
11
- };
12
-
13
- async function plugin(fastify, config = {}) {
14
- const prefix = config.prefix || '/api';
15
-
16
- fastify.get(`${prefix}/next-id`, {}, nextId);
17
- fastify.get(`${prefix}/status-monitor`, {}, statusMonitor);
18
- fastify.get(`${prefix}/properties/:id`, { schema: propertiesSchema }, getExtraProperties);
19
- fastify.post(`${prefix}/properties/:id`, { schema: propertiesSchema }, addExtraProperties);
20
- fastify.get('/logger-file/*', { config: { policy: ['log'] } }, loggerFile);
21
- }
22
-
23
- export default plugin;
1
+ import getExtraProperties from './controllers/properties.get.js';
2
+ import addExtraProperties from './controllers/properties.add.js';
3
+ import nextId from './controllers/next.id.js';
4
+ import statusMonitor from './controllers/status.monitor.js';
5
+ import loggerFile from './controllers/logger.file.js';
6
+
7
+ const propertiesSchema = {
8
+ params: {
9
+ id: { type: 'string', pattern: '^([\\d\\w]+)$' },
10
+ },
11
+ };
12
+
13
+ async function plugin(fastify, config = {}) {
14
+ const prefix = config.prefix || '/api';
15
+
16
+ fastify.get(`${prefix}/next-id`, {}, nextId);
17
+ fastify.get(`${prefix}/status-monitor`, {}, statusMonitor);
18
+ fastify.get(`${prefix}/properties/:id`, { schema: propertiesSchema }, getExtraProperties);
19
+ fastify.post(`${prefix}/properties/:id`, { schema: propertiesSchema }, addExtraProperties);
20
+ fastify.get('/logger-file/*', { config: { policy: ['log'] } }, loggerFile);
21
+ }
22
+
23
+ export default plugin;