@opengis/fastify-table 1.1.51 → 1.1.53

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 (218) hide show
  1. package/.eslintrc.cjs +42 -42
  2. package/.gitlab-ci.yml +18 -18
  3. package/Changelog.md +352 -352
  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 +12 -10
  10. package/cron/schema.js +8 -0
  11. package/crud/controllers/deleteCrud.js +36 -36
  12. package/crud/controllers/insert.js +71 -71
  13. package/crud/controllers/update.js +76 -76
  14. package/crud/controllers/utils/xssInjection.js +72 -72
  15. package/crud/funcs/dataDelete.js +19 -19
  16. package/crud/funcs/dataInsert.js +30 -30
  17. package/crud/funcs/dataUpdate.js +48 -48
  18. package/crud/funcs/getAccess.js +46 -46
  19. package/crud/funcs/getOpt.js +10 -10
  20. package/crud/funcs/getToken.js +27 -27
  21. package/crud/funcs/isFileExists.js +13 -13
  22. package/crud/funcs/setOpt.js +16 -16
  23. package/crud/funcs/setToken.js +53 -53
  24. package/crud/funcs/utils/getFolder.js +9 -9
  25. package/crud/funcs/utils/logChanges.js +62 -62
  26. package/crud/index.js +31 -36
  27. package/crud/schema.js +11 -0
  28. package/docs/.vitepress/abbr.mjs +26 -26
  29. package/docs/.vitepress/config.mjs +127 -127
  30. package/docs/.vitepress/navigation.mjs +82 -82
  31. package/docs/.vitepress/theme/Layout.vue +17 -17
  32. package/docs/.vitepress/theme/components/NavigationLinks.vue +102 -102
  33. package/docs/.vitepress/theme/components/Panzoom.vue +169 -169
  34. package/docs/.vitepress/theme/index.mjs +15 -15
  35. package/docs/.vitepress/theme/style.scss +163 -163
  36. package/docs/abbr.json +4 -4
  37. package/docs/api/cron/cronApi.md +56 -56
  38. package/docs/api/crud/deleteCrud.md +58 -58
  39. package/docs/api/crud/insert.md +82 -82
  40. package/docs/api/crud/update.md +85 -85
  41. package/docs/api/index.md +47 -47
  42. package/docs/api/notification/testEmail.md +91 -91
  43. package/docs/api/table/card.md +73 -73
  44. package/docs/api/table/data.md +134 -134
  45. package/docs/api/table/export.md +60 -60
  46. package/docs/api/table/filter.md +104 -104
  47. package/docs/api/table/form.md +126 -126
  48. package/docs/api/table/search.md +123 -123
  49. package/docs/api/table/suggest.md +156 -156
  50. package/docs/api/table/table.md +107 -107
  51. package/docs/api/user/user.cls.id.md +77 -77
  52. package/docs/api/user/user.cls.md +49 -49
  53. package/docs/api/user/user.cls.post.md +62 -62
  54. package/docs/api/user/user.info.md +37 -37
  55. package/docs/api/utils/logger.file.md +60 -60
  56. package/docs/api/utils/next.id.md +34 -34
  57. package/docs/api/utils/properties.add.md +127 -127
  58. package/docs/api/utils/properties.get.md +73 -73
  59. package/docs/api/utils/status.monitor.md +36 -36
  60. package/docs/api/widget/widget.del.md +76 -76
  61. package/docs/api/widget/widget.get.md +233 -233
  62. package/docs/api/widget/widget.set.md +88 -88
  63. package/docs/db/admin.md +947 -947
  64. package/docs/db/crm.md +564 -564
  65. package/docs/db/index.md +9 -9
  66. package/docs/db/log.md +204 -204
  67. package/docs/hook/card/afterCard.md +20 -20
  68. package/docs/hook/card/preCard.md +25 -25
  69. package/docs/hook/data/afterData.md +26 -26
  70. package/docs/hook/data/preData.md +26 -26
  71. package/docs/hook/deleteCrud/afterDelete.md +21 -21
  72. package/docs/hook/deleteCrud/preDelete.md +26 -26
  73. package/docs/hook/form/afterForm.md +19 -19
  74. package/docs/hook/form/preForm.md +26 -26
  75. package/docs/hook/getTemplate/afterTemplate.md +24 -24
  76. package/docs/hook/getTemplate/preTemplate.md +29 -29
  77. package/docs/hook/index.md +45 -45
  78. package/docs/hook/insert/afterInsert.md +41 -41
  79. package/docs/hook/insert/preInsert.md +25 -25
  80. package/docs/hook/table/afterTable.md +20 -20
  81. package/docs/hook/table/preTable.md +25 -25
  82. package/docs/hook/update/afterUpdate.md +41 -41
  83. package/docs/hook/update/preUpdate.md +25 -25
  84. package/docs/index.md +42 -42
  85. package/docs/public/fastify-dark.svg +3 -3
  86. package/docs/public/logo-short-dark.svg +11 -11
  87. package/docs/public/logo-short.svg +10 -10
  88. package/docs/public/logo.svg +19 -19
  89. package/docs/readme/index.md +121 -121
  90. package/docs/templates/card.md +83 -83
  91. package/docs/templates/cls.md +29 -29
  92. package/docs/templates/filters.md +91 -91
  93. package/docs/templates/forms.md +139 -139
  94. package/docs/templates/index.md +28 -28
  95. package/docs/templates/select.md +90 -90
  96. package/docs/templates/table.md +162 -162
  97. package/docs/utils/cron/addCron.md +29 -29
  98. package/docs/utils/crud/dataInsert.md +51 -51
  99. package/docs/utils/crud/dataUpdate.md +52 -52
  100. package/docs/utils/crud/getOpt.md +33 -33
  101. package/docs/utils/crud/isFileExists.md +37 -37
  102. package/docs/utils/crud/setOpt.md +37 -37
  103. package/docs/utils/hook/addHook.md +74 -74
  104. package/docs/utils/hook/applyHook.md +64 -64
  105. package/docs/utils/index.md +47 -47
  106. package/docs/utils/notification/addNotification.md +28 -28
  107. package/docs/utils/notification/notification.md +41 -41
  108. package/docs/utils/pg/autoIndex.md +22 -22
  109. package/docs/utils/pg/getMeta.md +58 -58
  110. package/docs/utils/pg/getPG.md +34 -34
  111. package/docs/utils/pg/init.md +29 -29
  112. package/docs/utils/pg/pg.md +70 -70
  113. package/docs/utils/redis/getRedis.md +36 -36
  114. package/docs/utils/redis/rclient.md +74 -74
  115. package/docs/utils/table/getForm.md +68 -68
  116. package/docs/utils/table/getMeta.md +55 -55
  117. package/docs/utils/table/getSelect.md +38 -38
  118. package/docs/utils/table/getSelectMeta.md +46 -46
  119. package/docs/utils/table/getTable.md +77 -77
  120. package/helper.js +30 -30
  121. package/index.js +105 -105
  122. package/migration/exec.migrations.js +79 -79
  123. package/module/core/select/core.user_mentioned.sql +1 -1
  124. package/module/test/cls/itree.composition.json +25 -25
  125. package/module/test/table/test.rest_zone.table.json +265 -265
  126. package/notification/controllers/readNotifications.js +27 -30
  127. package/notification/controllers/testEmail.js +46 -50
  128. package/notification/controllers/userNotifications.js +61 -64
  129. package/notification/funcs/addNotification.js +21 -21
  130. package/notification/funcs/sendNotification.js +112 -112
  131. package/notification/index.js +3 -8
  132. package/notification/schema.js +10 -0
  133. package/package.json +41 -41
  134. package/pg/funcs/getMeta.js +29 -29
  135. package/pg/funcs/getPG.js +30 -30
  136. package/pg/pgClients.js +20 -20
  137. package/policy/funcs/checkPolicy.js +92 -92
  138. package/policy/funcs/sqlInjection.js +33 -33
  139. package/policy/index.js +14 -14
  140. package/redis/client.js +8 -8
  141. package/redis/funcs/getRedis.js +23 -23
  142. package/redis/funcs/redisClients.js +2 -2
  143. package/redis/index.js +19 -19
  144. package/server/migrations/0.sql +78 -78
  145. package/server/migrations/cls.sql +39 -39
  146. package/server/migrations/log.sql +80 -80
  147. package/server/migrations/properties.sql +144 -144
  148. package/server/migrations/roles.sql +172 -172
  149. package/server/migrations/users.sql +168 -168
  150. package/server.js +26 -26
  151. package/table/controllers/data.js +157 -150
  152. package/table/controllers/filter.js +61 -50
  153. package/table/controllers/form.js +42 -42
  154. package/table/controllers/search.js +76 -80
  155. package/table/controllers/suggest.js +79 -79
  156. package/table/controllers/table.js +83 -83
  157. package/table/controllers/utils/addTemplateDir.js +8 -8
  158. package/table/controllers/utils/getSelect.js +19 -19
  159. package/table/controllers/utils/getSelectMeta.js +66 -66
  160. package/table/controllers/utils/getTemplate_old.js +28 -28
  161. package/table/controllers/utils/getTemplates.js +18 -18
  162. package/table/controllers/utils/gisIRColumn.js +72 -67
  163. package/table/controllers/utils/loadTemplate.js +1 -1
  164. package/table/controllers/utils/loadTemplatePath.js +1 -1
  165. package/table/controllers/utils/userTemplateDir.js +1 -1
  166. package/table/funcs/getFilterSQL/index.js +94 -94
  167. package/table/funcs/getFilterSQL/util/formatValue.js +170 -170
  168. package/table/funcs/getFilterSQL/util/getCustomQuery.js +13 -13
  169. package/table/funcs/getFilterSQL/util/getFilterQuery.js +66 -66
  170. package/table/funcs/getFilterSQL/util/getOptimizedQuery.js +12 -12
  171. package/table/funcs/getFilterSQL/util/getTableSql.js +34 -34
  172. package/table/funcs/metaFormat/getSelectVal.js +21 -21
  173. package/table/funcs/metaFormat/index.js +28 -28
  174. package/table/index.js +37 -37
  175. package/table/schema.js +64 -54
  176. package/test/api/applyHook.test.js +95 -95
  177. package/test/api/crud.test.js +89 -89
  178. package/test/api/crud.xss.test.js +80 -80
  179. package/test/api/suggest.test.js +66 -66
  180. package/test/api/table.test.js +134 -134
  181. package/test/api/user.test.js +85 -85
  182. package/test/api/widget.test.js +117 -117
  183. package/test/config.example +18 -18
  184. package/test/funcs/pg.test.js +34 -34
  185. package/test/funcs/redis.test.js +19 -19
  186. package/test/helper/formatDate.test.js +62 -62
  187. package/test/templates/cls/test.json +9 -9
  188. package/test/templates/form/cp_building.form.json +32 -32
  189. package/test/templates/select/account_id.json +3 -3
  190. package/test/templates/select/storage.data.json +2 -2
  191. package/test/templates/select/test.storage.data.json +3 -3
  192. package/test/templates/select/test.suggest.ato_new.json +3 -3
  193. package/test/templates/select/test.suggest.ato_new.sql +25 -25
  194. package/test/templates/select/test.suggest.data.json +4 -4
  195. package/test/templates/select/test.suggest.parent.sql +1 -1
  196. package/test/templates/table/gis.dataset.table.json +20 -20
  197. package/user/controllers/user.cls.id.js +14 -14
  198. package/user/controllers/user.cls.js +71 -75
  199. package/user/controllers/user.cls.post.js +52 -55
  200. package/user/controllers/user.info.js +17 -21
  201. package/user/index.js +7 -36
  202. package/user/schema.js +17 -0
  203. package/util/controllers/logger.file.js +91 -91
  204. package/util/controllers/next.id.js +4 -4
  205. package/util/controllers/properties.add.js +56 -60
  206. package/util/controllers/properties.get.js +16 -19
  207. package/util/controllers/status.monitor.js +8 -8
  208. package/util/controllers/utils/checkUserAccess.js +20 -17
  209. package/util/controllers/utils/getRootDir.js +25 -25
  210. package/util/index.js +19 -23
  211. package/util/schema.js +19 -0
  212. package/utils.js +106 -104
  213. package/widget/controllers/utils/historyFormat.js +76 -76
  214. package/widget/controllers/utils/obj2db.js +13 -13
  215. package/widget/controllers/widget.del.js +41 -44
  216. package/widget/controllers/widget.get.js +96 -102
  217. package/widget/controllers/widget.set.js +74 -79
  218. package/widget/index.js +40 -40
@@ -1,80 +1,80 @@
1
- import { test } from 'node:test';
2
- import assert from 'node:assert';
3
-
4
- import build from '../../helper.js';
5
-
6
- import setToken from '../../crud/funcs/setToken.js';
7
- import getToken from '../../crud/funcs/getToken.js';
8
- import addHook from '../../hook/funcs/addHook.js';
9
- import config from '../config.js';
10
- import pgClients from '../../pg/pgClients.js';
11
-
12
- addHook('preInsert', async ({ table }) => getToken({
13
- mode: 'a', token: table, uid: '1', json: 1,
14
- }));
15
-
16
- addHook('preUpdate', async ({ table }) => getToken({
17
- mode: 'w', token: table, uid: '1', json: 1,
18
- }));
19
-
20
- addHook('preDelete', async ({ table }) => getToken({
21
- mode: 'w', token: table, uid: '1', json: 1,
22
- }));
23
-
24
- test('api crud xss', async (t) => {
25
- const app = await build(t);
26
- const session = { passport: { user: { uid: '1', user_type: 'admin' } } };
27
- app.addHook('onRequest', async (req) => {
28
- req.session = session;
29
- req.user = session.passport.user;
30
- });
31
-
32
- const id = 'test';
33
- const prefix = config.prefix || '/api';
34
-
35
- await t.test('POST /insert', async () => {
36
- const addTokens = setToken({
37
- ids: [JSON.stringify({ table: 'test.rest_zone.table', form: 'rest_zone.form' })],
38
- mode: 'a',
39
- uid: 1,
40
- array: 1,
41
- });
42
- assert.ok(addTokens.length, 'invalid token');
43
- const res = await app.inject({
44
- method: 'POST',
45
- url: `${prefix}/table/${addTokens[0]}`,
46
- body: { rz_id: 'test', composition: '<a onClick="alert("XSS Injection")">xss injection</a>' },
47
- });
48
- assert.equal(res?.json()?.status || res?.statusCode, 409);
49
- });
50
-
51
- const editTokens = setToken({
52
- ids: [JSON.stringify({ id, table: 'test.rest_zone.table', form: 'rest_zone.form' })],
53
- mode: 'w',
54
- uid: 1,
55
- array: 1,
56
- });
57
-
58
- await t.test('PUT /update', async () => {
59
- const res = await app.inject({
60
- method: 'PUT',
61
- url: `${prefix}/table/${editTokens[0]}`,
62
- body: { editor_id: '11', composition: '<a onClick="alert("XSS Injection")">xss injection</a>' },
63
- });
64
- assert.equal(res.json()?.status || res?.statusCode, 409);
65
- });
66
- await t.test('DELETE /delete', async () => {
67
- const res = await app.inject({
68
- method: 'DELETE',
69
- url: `${prefix}/table/${editTokens[0]}`,
70
- });
71
- assert.equal(res?.json()?.status || res?.statusCode, 200);
72
- });
73
-
74
- // after
75
- await t.test('clean up', async () => {
76
- const { rowCount } = await pgClients.client.query('delete from itree.rest_zones where composition::text ilike \'%xss injection%\'');
77
- const { rowCount: testRows } = await pgClients.client.query('delete from itree.rest_zones where rz_id=\'test\'');
78
- console.log('clean up', rowCount, testRows);
79
- });
80
- });
1
+ import { test } from 'node:test';
2
+ import assert from 'node:assert';
3
+
4
+ import build from '../../helper.js';
5
+
6
+ import setToken from '../../crud/funcs/setToken.js';
7
+ import getToken from '../../crud/funcs/getToken.js';
8
+ import addHook from '../../hook/funcs/addHook.js';
9
+ import config from '../config.js';
10
+ import pgClients from '../../pg/pgClients.js';
11
+
12
+ addHook('preInsert', async ({ table }) => getToken({
13
+ mode: 'a', token: table, uid: '1', json: 1,
14
+ }));
15
+
16
+ addHook('preUpdate', async ({ table }) => getToken({
17
+ mode: 'w', token: table, uid: '1', json: 1,
18
+ }));
19
+
20
+ addHook('preDelete', async ({ table }) => getToken({
21
+ mode: 'w', token: table, uid: '1', json: 1,
22
+ }));
23
+
24
+ test('api crud xss', async (t) => {
25
+ const app = await build(t);
26
+ const session = { passport: { user: { uid: '1', user_type: 'admin' } } };
27
+ app.addHook('onRequest', async (req) => {
28
+ req.session = session;
29
+ req.user = session.passport.user;
30
+ });
31
+
32
+ const id = 'test';
33
+ const prefix = config.prefix || '/api';
34
+
35
+ await t.test('POST /insert', async () => {
36
+ const addTokens = setToken({
37
+ ids: [JSON.stringify({ table: 'test.rest_zone.table', form: 'rest_zone.form' })],
38
+ mode: 'a',
39
+ uid: 1,
40
+ array: 1,
41
+ });
42
+ assert.ok(addTokens.length, 'invalid token');
43
+ const res = await app.inject({
44
+ method: 'POST',
45
+ url: `${prefix}/table/${addTokens[0]}`,
46
+ body: { rz_id: 'test', composition: '<a onClick="alert("XSS Injection")">xss injection</a>' },
47
+ });
48
+ assert.equal(res?.json()?.status || res?.statusCode, 409);
49
+ });
50
+
51
+ const editTokens = setToken({
52
+ ids: [JSON.stringify({ id, table: 'test.rest_zone.table', form: 'rest_zone.form' })],
53
+ mode: 'w',
54
+ uid: 1,
55
+ array: 1,
56
+ });
57
+
58
+ await t.test('PUT /update', async () => {
59
+ const res = await app.inject({
60
+ method: 'PUT',
61
+ url: `${prefix}/table/${editTokens[0]}`,
62
+ body: { editor_id: '11', composition: '<a onClick="alert("XSS Injection")">xss injection</a>' },
63
+ });
64
+ assert.equal(res.json()?.status || res?.statusCode, 409);
65
+ });
66
+ await t.test('DELETE /delete', async () => {
67
+ const res = await app.inject({
68
+ method: 'DELETE',
69
+ url: `${prefix}/table/${editTokens[0]}`,
70
+ });
71
+ assert.equal(res?.json()?.status || res?.statusCode, 200);
72
+ });
73
+
74
+ // after
75
+ await t.test('clean up', async () => {
76
+ const { rowCount } = await pgClients.client.query('delete from itree.rest_zones where composition::text ilike \'%xss injection%\'');
77
+ const { rowCount: testRows } = await pgClients.client.query('delete from itree.rest_zones where rz_id=\'test\'');
78
+ console.log('clean up', rowCount, testRows);
79
+ });
80
+ });
@@ -1,66 +1,66 @@
1
- import { test } from 'node:test';
2
- import assert from 'node:assert';
3
-
4
- import build from '../../helper.js';
5
-
6
- test('api suggest', async (t) => {
7
- const app = await build(t);
8
-
9
- await t.test('GET /suggest', async () => {
10
- const res = await app.inject({
11
- method: 'GET',
12
- url: '/api/suggest/test.storage.data',
13
- });
14
- const rep = JSON.parse(res?.body);
15
- // console.log(rep);
16
- assert.equal(res?.statusCode, 200);
17
- assert.ok(rep?.count);
18
- });
19
-
20
- await t.test('GET /suggest key query', async () => {
21
- const key = 'rest_zone';
22
- const res = await app.inject({
23
- method: 'GET',
24
- url: `/api/suggest/test.storage.data?key=${key}`,
25
- });
26
- const rep = JSON.parse(res?.body);
27
- // console.log(rep);
28
- assert.equal(res?.statusCode, 200);
29
- assert.ok(rep?.count);
30
- });
31
-
32
- await t.test('GET /suggest key searchColumn', async () => {
33
- const key = 'site.rest_zone.table';
34
- const res = await app.inject({
35
- method: 'GET',
36
- url: `/api/suggest/test.storage.data?key=${key}`,
37
- });
38
- const rep = JSON.parse(res?.body);
39
- // console.log(rep);
40
- assert.equal(res?.statusCode, 200);
41
- assert.ok(rep?.count);
42
- });
43
- /*
44
- await t.test('GET /suggest інша db', async () => {
45
- const res = await app.inject({
46
- method: 'GET',
47
- url: '/api/suggest/test.suggest.data',
48
- });
49
- const rep = JSON.parse(res?.body);
50
- // console.log(rep);
51
- assert.equal(res?.statusCode, 200);
52
- assert.ok(rep?.count);
53
- }); */
54
-
55
- await t.test('GET /suggest parent', async () => {
56
- const parent = '1';
57
- const res = await app.inject({
58
- method: 'GET',
59
- url: `/api/suggest/test.suggest.parent?parent=${parent}`,
60
- });
61
- const rep = JSON.parse(res?.body);
62
- // console.log(rep);
63
- assert.equal(res?.statusCode, 200);
64
- assert.ok(rep?.count);
65
- });
66
- });
1
+ import { test } from 'node:test';
2
+ import assert from 'node:assert';
3
+
4
+ import build from '../../helper.js';
5
+
6
+ test('api suggest', async (t) => {
7
+ const app = await build(t);
8
+
9
+ await t.test('GET /suggest', async () => {
10
+ const res = await app.inject({
11
+ method: 'GET',
12
+ url: '/api/suggest/test.storage.data',
13
+ });
14
+ const rep = JSON.parse(res?.body);
15
+ // console.log(rep);
16
+ assert.equal(res?.statusCode, 200);
17
+ assert.ok(rep?.count);
18
+ });
19
+
20
+ await t.test('GET /suggest key query', async () => {
21
+ const key = 'rest_zone';
22
+ const res = await app.inject({
23
+ method: 'GET',
24
+ url: `/api/suggest/test.storage.data?key=${key}`,
25
+ });
26
+ const rep = JSON.parse(res?.body);
27
+ // console.log(rep);
28
+ assert.equal(res?.statusCode, 200);
29
+ assert.ok(rep?.count);
30
+ });
31
+
32
+ await t.test('GET /suggest key searchColumn', async () => {
33
+ const key = 'site.rest_zone.table';
34
+ const res = await app.inject({
35
+ method: 'GET',
36
+ url: `/api/suggest/test.storage.data?key=${key}`,
37
+ });
38
+ const rep = JSON.parse(res?.body);
39
+ // console.log(rep);
40
+ assert.equal(res?.statusCode, 200);
41
+ assert.ok(rep?.count);
42
+ });
43
+ /*
44
+ await t.test('GET /suggest інша db', async () => {
45
+ const res = await app.inject({
46
+ method: 'GET',
47
+ url: '/api/suggest/test.suggest.data',
48
+ });
49
+ const rep = JSON.parse(res?.body);
50
+ // console.log(rep);
51
+ assert.equal(res?.statusCode, 200);
52
+ assert.ok(rep?.count);
53
+ }); */
54
+
55
+ await t.test('GET /suggest parent', async () => {
56
+ const parent = '1';
57
+ const res = await app.inject({
58
+ method: 'GET',
59
+ url: `/api/suggest/test.suggest.parent?parent=${parent}`,
60
+ });
61
+ const rep = JSON.parse(res?.body);
62
+ // console.log(rep);
63
+ assert.equal(res?.statusCode, 200);
64
+ assert.ok(rep?.count);
65
+ });
66
+ });
@@ -1,134 +1,134 @@
1
- import { test } from 'node:test';
2
- import assert from 'node:assert';
3
- import pgClients from '../../pg/pgClients.js';
4
- import init from '../../pg/funcs/init.js';
5
-
6
- import build from '../../helper.js';
7
- import config from '../config.js';
8
- import { getTemplate } from '../../utils.js';
9
-
10
- const table = 'test.rest_zone.table';
11
-
12
- test('api table', async (t) => {
13
- const app = await build(t);
14
-
15
- const session = { passport: { user: { uid: '1', user_type: 'admin' } } };
16
- app.addHook('onRequest', async (req) => {
17
- req.session = session;
18
- req.user = session.passport.user;
19
- });
20
-
21
- await init(pgClients.client);
22
-
23
- const body = await getTemplate('table', table);
24
- assert.equal(body?.table, 'itree.rest_zones');
25
- assert.ok(pgClients.client?.pk?.[body?.table], 'invalid db - skip filter unit test');
26
-
27
- if (pgClients.client?.pk?.[body?.table]) {
28
- const custom = body?.filterCustom?.[0] || {};
29
- assert.ok(custom.name && custom.sql, 'invalid test template - empty filterCustom');
30
- const state = body?.filterState?.[0] || {};
31
- assert.ok(state.name && state.sql, 'invalid test template - empty filterState');
32
-
33
- await t.test('GET /data (filter + custom + state + sql)', async () => {
34
- const res = await app.inject({
35
- method: 'GET',
36
- url: `${config.prefix || '/api'}/data/${table}`,
37
- query: {
38
- custom: custom.name,
39
- state: state.name,
40
- filter: 'balancer~1;composition=1',
41
- sql: 1,
42
- },
43
- });
44
- assert.ok(res.body?.includes(custom.sql), 'filterCustom not ok');
45
- assert.ok(res.body?.includes(state.sql), 'filterState not ok');
46
- assert.ok(res.body?.includes('balancer::text ilike \'%1%\' and \'{1}\'::text[] && composition::text[]'), 'filter not ok');
47
- });
48
- }
49
-
50
- const bbox = '20.276526313524393 40.6651677831094,35.27752631352439 50.66616778310941';
51
- const { count = 0 } = pgClients.client?.pk[body?.table] ? await pgClients.client.query(`select count(*) from itree.rest_zones
52
- where verif and '{1}'::text[] && composition::text[] and geom && 'box(${bbox})'::box2d`).then((res) => res.rows[0] || {}) : {};
53
-
54
- await t.test('GET /data (meta bbox / cls)', async () => {
55
- const res = await app.inject({
56
- method: 'GET',
57
- url: `${config.prefix || '/api'}/data/${table}`,
58
- query: { bbox, filter: 'composition=1' },
59
- });
60
- const json = res.json();
61
- const res1 = await app.inject({
62
- method: 'GET',
63
- url: `${config.prefix || '/api'}/data/${table}`,
64
- query: { bbox, sql: 1 },
65
- });
66
- const { body: sql } = res1;
67
- assert.ok(sql?.includes(bbox), 'meta bbox sql - not ok');
68
- assert.ok(json?.rows?.length && +count >= json?.rows?.length, 'meta bbox - not ok');
69
- assert.ok(json?.rows?.length ? json?.rows?.[0]?.composition_text : true, 'meta cls - not ok');
70
- });
71
-
72
- const polyline = 'wfvkH_jsvCoKvj@oKfiB?fw@?nd@?nK?nK~WgEfE?wQfw@gEfE?vQwQvj@wQvcAoKvQoKnKgEnd@_cBgw@wj@fEwj@nKg^vQg^oK?vQgEnKgpAvj@?vcAfEf^fEf^?vj@vQvj@vQgE~Wvj@?~p@gE~iAfEnK?~iA_XnvA?nd@fEf^~p@~bBvQ?nd@wQ?vQfEf^fEnK?vQ?vj@oKfEoKfEvQnd@nKvj@?vQfEvQgEf^gEf^?vQfEvQfEvQfE~W?fE?fE?~W?f^?nd@?nK?nKfEfEg^oKwj@nK_X~W~p@~WvQnKoKn}@wQvj@oK~Wg^vcAgEnK?~Wfw@vgD~p@oKfpAvQnd@nKoKvQoKvQ?fE?fEnKvj@wQvQ?fEod@fw@~Wn}@fEn}@_Xv|A_jA~fEwQwQ_XoKwQoKoKoKoKoKg^gE_XgEoKg^gEgEgE?gEfEgEfEgEf^_XoKwQ?gEgEoK?wQ?gE~WoKoKoKwQfEgEnK_X?gEgE?oKfEoKoKgE_XgEgEwQfEoKod@_Xgw@gEoKgE_Xg^wQoKg^_XnvAgE?gEvQgE?od@fpA?vQ?f^oKvcAwj@oKg^?wQn}@gEf^oK?w|AnKgE??nKwj@gEgEg^oKwQoKoK?gEwQoaD?oKod@oKod@gEod@wQo}@oKfEf^gEfEgpAnd@_XfEgE?wQnKo}@_q@?gEgEwj@?oK?oK?_X?oKfEoK?oKfEoK?oK?oK?gEfEoKwQfEoK?gEwQwj@nKo}@nKwQ~Wod@nKoKfEgw@ovAgEwQgE??oKoKgEoKgEgEwQ?oKfEoKnKwQfEwQoK?g^fE?wQfEg^fEod@gE??fEoKvQ?nKoKnKgEfEgEgE?g^nK_q@nKod@?oKoKoK~Wgw@fEoKnd@fE?_XfEoKfEwQfEoKfEwQfEoKvQ?fEfE?vj@gE~W~WvQvQwj@vQvQf^o}@nKvQ?_XgEg^gEg^nKod@?wQgEgEgE?oK_XgEoK?oKgEoKgE_XoKg^oKg^oKod@?gEfEoKvQgEnK?nKfE?_Xnd@gw@fEwQf^wj@fEwQnd@w|A?gEgEgEgEwQfEoKfEgEnKoKnKwQfEgE?oKfEoKnKgEnKwQ_XwQnKwcAod@wQvQod@~Wgw@nKgw@oKg^f^ovAgEwQ?_X?od@gEwj@gEwQvQg^fEoKnKoKvQnK~WfEnKvQ~Wod@f^wj@~WoKnKg^~W?vQgE~WoKnKoK~WoKfEwQvQwQfEgEnKwQnKwQvQwQnKoKnKgEnKgEnKgEvQnKnK?fE?fE?~WwQnKgEnKgEfE?fE?nK?fE?fE?vQgEfE?nKfEfE?fE?vQ?~W?~WgEfEgEnKgEnKwQfEnKnKfE?wj@?o}@g^o}@_Xod@?gEf^_X?o}@?wQ~W?~WgE~WgEfE?f^gEf^oK~Wg^nKgE?oK~WwQ?od@nK_XfEwQnKoKfEgEfE~W?f^f^fEfEfEnKfEnK?gEf^vQfEnK?~WnKvQnK?vQf^nKfEfEgE~WnKfEnK?fEgEfE?nK?fEfEfEgEnK?nKgEnK?nKfEf^?vQgEvQ?nd@gEnKo}@vQgE~WgEf^gE'; // UA26040270000047749
73
-
74
- const { count1 } = await pgClients.client.query('select count(*) as count1 from itree.rest_zones where verif and ST_Contains(ST_MakePolygon(ST_LineFromEncodedPolyline($1)),geom)', [polyline])
75
- .then((res) => res.rows[0] || {});
76
- await t.test('GET /data (meta polyline)', async () => {
77
- const res = await app.inject({
78
- method: 'GET',
79
- url: `${config.prefix || '/api'}/data/${table}`,
80
- query: { polyline },
81
- });
82
- const json = res.json();
83
- assert.ok(json?.rows?.length === +count1, 'meta bbox (polyline) - not ok');
84
- });
85
-
86
- /* await t.test('GET /suggest', async () => {
87
- const res = await app.inject({
88
- method: 'GET',
89
- url: '/api/suggest/test.storage.data',
90
- });
91
- // console.log(res?.body);
92
- const rep = JSON.parse(res?.body);
93
- // console.log(rep.total);
94
- assert.ok(rep.total);
95
- }); */
96
- /* await t.test('GET /data', async () => {
97
- const res = await app.inject({
98
- method: 'GET',
99
- url: '/api/data/test.dataset.table',
100
- });
101
- // console.log(res);
102
- const rep = JSON.parse(res?.body);
103
- // console.log(rep.total);
104
- assert.ok(rep.total);
105
- }); */
106
- /* await t.test('GET /search', async () => {
107
- const res = await app.inject({
108
- method: 'GET',
109
- url: '/api/search?table=test.dataset.table&key=0',
110
- });
111
- const rep = JSON.parse(res?.body);
112
- assert.ok(rep.total);
113
- }); */
114
- await t.test('GET /form', async () => {
115
- const res = await app.inject({
116
- method: 'GET',
117
- url: '/api/form/test.dataset.form',
118
- });
119
- // console.log(res);
120
- const rep = JSON.parse(res?.body);
121
- // console.log(rep.total);
122
- assert.ok(rep);
123
- });
124
- await t.test('GET /filter', async () => {
125
- const res = await app.inject({
126
- method: 'GET',
127
- url: '/api/filter/test.dataset.table',
128
- });
129
- // console.log(res);
130
- const rep = JSON.parse(res?.body);
131
- // console.log(rep.total);
132
- assert.ok(rep);
133
- });
134
- });
1
+ import { test } from 'node:test';
2
+ import assert from 'node:assert';
3
+ import pgClients from '../../pg/pgClients.js';
4
+ import init from '../../pg/funcs/init.js';
5
+
6
+ import build from '../../helper.js';
7
+ import config from '../config.js';
8
+ import { getTemplate } from '../../utils.js';
9
+
10
+ const table = 'test.rest_zone.table';
11
+
12
+ test('api table', async (t) => {
13
+ const app = await build(t);
14
+
15
+ const session = { passport: { user: { uid: '1', user_type: 'admin' } } };
16
+ app.addHook('onRequest', async (req) => {
17
+ req.session = session;
18
+ req.user = session.passport.user;
19
+ });
20
+
21
+ await init(pgClients.client);
22
+
23
+ const body = await getTemplate('table', table);
24
+ assert.equal(body?.table, 'itree.rest_zones');
25
+ assert.ok(pgClients.client?.pk?.[body?.table], 'invalid db - skip filter unit test');
26
+
27
+ if (pgClients.client?.pk?.[body?.table]) {
28
+ const custom = body?.filterCustom?.[0] || {};
29
+ assert.ok(custom.name && custom.sql, 'invalid test template - empty filterCustom');
30
+ const state = body?.filterState?.[0] || {};
31
+ assert.ok(state.name && state.sql, 'invalid test template - empty filterState');
32
+
33
+ await t.test('GET /data (filter + custom + state + sql)', async () => {
34
+ const res = await app.inject({
35
+ method: 'GET',
36
+ url: `${config.prefix || '/api'}/data/${table}`,
37
+ query: {
38
+ custom: custom.name,
39
+ state: state.name,
40
+ filter: 'balancer~1;composition=1',
41
+ sql: 1,
42
+ },
43
+ });
44
+ assert.ok(res.body?.includes(custom.sql), 'filterCustom not ok');
45
+ assert.ok(res.body?.includes(state.sql), 'filterState not ok');
46
+ assert.ok(res.body?.includes('balancer::text ilike \'%1%\' and \'{1}\'::text[] && composition::text[]'), 'filter not ok');
47
+ });
48
+ }
49
+
50
+ const bbox = '20.276526313524393 40.6651677831094,35.27752631352439 50.66616778310941';
51
+ const { count = 0 } = pgClients.client?.pk[body?.table] ? await pgClients.client.query(`select count(*) from itree.rest_zones
52
+ where verif and '{1}'::text[] && composition::text[] and geom && 'box(${bbox})'::box2d`).then((res) => res.rows[0] || {}) : {};
53
+
54
+ await t.test('GET /data (meta bbox / cls)', async () => {
55
+ const res = await app.inject({
56
+ method: 'GET',
57
+ url: `${config.prefix || '/api'}/data/${table}`,
58
+ query: { bbox, filter: 'composition=1' },
59
+ });
60
+ const json = res.json();
61
+ const res1 = await app.inject({
62
+ method: 'GET',
63
+ url: `${config.prefix || '/api'}/data/${table}`,
64
+ query: { bbox, sql: 1 },
65
+ });
66
+ const { body: sql } = res1;
67
+ assert.ok(sql?.includes(bbox), 'meta bbox sql - not ok');
68
+ assert.ok(json?.rows?.length && +count >= json?.rows?.length, 'meta bbox - not ok');
69
+ assert.ok(json?.rows?.length ? json?.rows?.[0]?.composition_text : true, 'meta cls - not ok');
70
+ });
71
+
72
+ const polyline = 'wfvkH_jsvCoKvj@oKfiB?fw@?nd@?nK?nK~WgEfE?wQfw@gEfE?vQwQvj@wQvcAoKvQoKnKgEnd@_cBgw@wj@fEwj@nKg^vQg^oK?vQgEnKgpAvj@?vcAfEf^fEf^?vj@vQvj@vQgE~Wvj@?~p@gE~iAfEnK?~iA_XnvA?nd@fEf^~p@~bBvQ?nd@wQ?vQfEf^fEnK?vQ?vj@oKfEoKfEvQnd@nKvj@?vQfEvQgEf^gEf^?vQfEvQfEvQfE~W?fE?fE?~W?f^?nd@?nK?nKfEfEg^oKwj@nK_X~W~p@~WvQnKoKn}@wQvj@oK~Wg^vcAgEnK?~Wfw@vgD~p@oKfpAvQnd@nKoKvQoKvQ?fE?fEnKvj@wQvQ?fEod@fw@~Wn}@fEn}@_Xv|A_jA~fEwQwQ_XoKwQoKoKoKoKoKg^gE_XgEoKg^gEgEgE?gEfEgEfEgEf^_XoKwQ?gEgEoK?wQ?gE~WoKoKoKwQfEgEnK_X?gEgE?oKfEoKoKgE_XgEgEwQfEoKod@_Xgw@gEoKgE_Xg^wQoKg^_XnvAgE?gEvQgE?od@fpA?vQ?f^oKvcAwj@oKg^?wQn}@gEf^oK?w|AnKgE??nKwj@gEgEg^oKwQoKoK?gEwQoaD?oKod@oKod@gEod@wQo}@oKfEf^gEfEgpAnd@_XfEgE?wQnKo}@_q@?gEgEwj@?oK?oK?_X?oKfEoK?oKfEoK?oK?oK?gEfEoKwQfEoK?gEwQwj@nKo}@nKwQ~Wod@nKoKfEgw@ovAgEwQgE??oKoKgEoKgEgEwQ?oKfEoKnKwQfEwQoK?g^fE?wQfEg^fEod@gE??fEoKvQ?nKoKnKgEfEgEgE?g^nK_q@nKod@?oKoKoK~Wgw@fEoKnd@fE?_XfEoKfEwQfEoKfEwQfEoKvQ?fEfE?vj@gE~W~WvQvQwj@vQvQf^o}@nKvQ?_XgEg^gEg^nKod@?wQgEgEgE?oK_XgEoK?oKgEoKgE_XoKg^oKg^oKod@?gEfEoKvQgEnK?nKfE?_Xnd@gw@fEwQf^wj@fEwQnd@w|A?gEgEgEgEwQfEoKfEgEnKoKnKwQfEgE?oKfEoKnKgEnKwQ_XwQnKwcAod@wQvQod@~Wgw@nKgw@oKg^f^ovAgEwQ?_X?od@gEwj@gEwQvQg^fEoKnKoKvQnK~WfEnKvQ~Wod@f^wj@~WoKnKg^~W?vQgE~WoKnKoK~WoKfEwQvQwQfEgEnKwQnKwQvQwQnKoKnKgEnKgEnKgEvQnKnK?fE?fE?~WwQnKgEnKgEfE?fE?nK?fE?fE?vQgEfE?nKfEfE?fE?vQ?~W?~WgEfEgEnKgEnKwQfEnKnKfE?wj@?o}@g^o}@_Xod@?gEf^_X?o}@?wQ~W?~WgE~WgEfE?f^gEf^oK~Wg^nKgE?oK~WwQ?od@nK_XfEwQnKoKfEgEfE~W?f^f^fEfEfEnKfEnK?gEf^vQfEnK?~WnKvQnK?vQf^nKfEfEgE~WnKfEnK?fEgEfE?nK?fEfEfEgEnK?nKgEnK?nKfEf^?vQgEvQ?nd@gEnKo}@vQgE~WgEf^gE'; // UA26040270000047749
73
+
74
+ const { count1 } = await pgClients.client.query('select count(*) as count1 from itree.rest_zones where verif and ST_Contains(ST_MakePolygon(ST_LineFromEncodedPolyline($1)),geom)', [polyline])
75
+ .then((res) => res.rows[0] || {});
76
+ await t.test('GET /data (meta polyline)', async () => {
77
+ const res = await app.inject({
78
+ method: 'GET',
79
+ url: `${config.prefix || '/api'}/data/${table}`,
80
+ query: { polyline },
81
+ });
82
+ const json = res.json();
83
+ assert.ok(json?.rows?.length === +count1, 'meta bbox (polyline) - not ok');
84
+ });
85
+
86
+ /* await t.test('GET /suggest', async () => {
87
+ const res = await app.inject({
88
+ method: 'GET',
89
+ url: '/api/suggest/test.storage.data',
90
+ });
91
+ // console.log(res?.body);
92
+ const rep = JSON.parse(res?.body);
93
+ // console.log(rep.total);
94
+ assert.ok(rep.total);
95
+ }); */
96
+ /* await t.test('GET /data', async () => {
97
+ const res = await app.inject({
98
+ method: 'GET',
99
+ url: '/api/data/test.dataset.table',
100
+ });
101
+ // console.log(res);
102
+ const rep = JSON.parse(res?.body);
103
+ // console.log(rep.total);
104
+ assert.ok(rep.total);
105
+ }); */
106
+ /* await t.test('GET /search', async () => {
107
+ const res = await app.inject({
108
+ method: 'GET',
109
+ url: '/api/search?table=test.dataset.table&key=0',
110
+ });
111
+ const rep = JSON.parse(res?.body);
112
+ assert.ok(rep.total);
113
+ }); */
114
+ await t.test('GET /form', async () => {
115
+ const res = await app.inject({
116
+ method: 'GET',
117
+ url: '/api/form/test.dataset.form',
118
+ });
119
+ // console.log(res);
120
+ const rep = JSON.parse(res?.body);
121
+ // console.log(rep.total);
122
+ assert.ok(rep);
123
+ });
124
+ await t.test('GET /filter', async () => {
125
+ const res = await app.inject({
126
+ method: 'GET',
127
+ url: '/api/filter/test.dataset.table',
128
+ });
129
+ // console.log(res);
130
+ const rep = JSON.parse(res?.body);
131
+ // console.log(rep.total);
132
+ assert.ok(rep);
133
+ });
134
+ });