@opengis/fastify-table 1.0.74 → 1.0.76

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 (64) hide show
  1. package/.eslintrc.cjs +42 -42
  2. package/Changelog.md +237 -229
  3. package/README.md +26 -26
  4. package/config.js +10 -10
  5. package/cron/controllers/cronApi.js +22 -22
  6. package/cron/controllers/utils/cronList.js +1 -1
  7. package/cron/funcs/addCron.js +131 -131
  8. package/cron/index.js +10 -10
  9. package/crud/controllers/deleteCrud.js +1 -1
  10. package/crud/controllers/utils/checkXSS.js +45 -45
  11. package/crud/controllers/utils/xssInjection.js +72 -72
  12. package/crud/funcs/dataDelete.js +15 -15
  13. package/crud/funcs/dataUpdate.js +24 -24
  14. package/crud/funcs/getAccess.js +2 -1
  15. package/crud/funcs/getToken.js +27 -27
  16. package/crud/funcs/isFileExists.js +13 -13
  17. package/crud/funcs/setToken.js +53 -53
  18. package/crud/index.js +36 -36
  19. package/index.js +97 -97
  20. package/migration/exec.migrations.js +75 -75
  21. package/notification/controllers/testEmail.js +49 -49
  22. package/notification/funcs/sendNotification.js +111 -111
  23. package/notification/funcs/utils/sendEmail.js +39 -39
  24. package/notification/index.js +38 -38
  25. package/package.json +26 -26
  26. package/pg/funcs/getPG.js +30 -30
  27. package/redis/funcs/getRedis.js +23 -23
  28. package/server/migrations/0.sql +64 -13
  29. package/server/migrations/crm.sql +150 -150
  30. package/server/migrations/log.sql +43 -43
  31. package/server.js +14 -14
  32. package/table/controllers/card.js +44 -44
  33. package/table/controllers/filter.js +37 -37
  34. package/table/controllers/form.js +28 -28
  35. package/table/controllers/search.js +72 -72
  36. package/table/controllers/suggest.js +62 -62
  37. package/table/controllers/table.js +44 -44
  38. package/table/controllers/utils/getSelectMeta.js +66 -66
  39. package/table/controllers/utils/getTemplate.js +28 -28
  40. package/table/controllers/utils/getTemplates.js +18 -18
  41. package/table/funcs/getFilterSQL/util/getTableSql.js +34 -34
  42. package/table/funcs/metaFormat/index.js +27 -27
  43. package/table/index.js +78 -78
  44. package/test/api/crud.test.js +18 -11
  45. package/test/api/crud.xss.test.js +72 -72
  46. package/test/api/notification.test.js +37 -37
  47. package/test/api/table.test.js +57 -57
  48. package/test/api/widget.test.js +114 -114
  49. package/test/config.example +18 -18
  50. package/test/funcs/crud.test.js +76 -76
  51. package/test/funcs/notification.test.js +31 -31
  52. package/test/funcs/pg.test.js +34 -34
  53. package/test/funcs/redis.test.js +19 -19
  54. package/test/templates/cls/test.json +9 -9
  55. package/test/templates/form/cp_building.form.json +32 -32
  56. package/test/templates/select/account_id.json +3 -3
  57. package/test/templates/select/storage.data.json +2 -2
  58. package/test/templates/table/gis.dataset.table.json +20 -20
  59. package/util/controllers/next.id.js +4 -4
  60. package/util/controllers/properties.add.js +50 -50
  61. package/util/controllers/properties.get.js +19 -19
  62. package/util/controllers/status.monitor.js +3 -0
  63. package/util/index.js +4 -3
  64. package/widget/index.js +40 -40
@@ -1,31 +1,31 @@
1
- import { test } from 'node:test';
2
- import assert from 'node:assert';
3
-
4
- // import build from '../../helper.js';
5
- // import config from '../config.js';
6
-
7
- // import addNotification from '../../notification/funcs/addNotification.js';
8
-
9
- // import pgClients from '../../pg/pgClients.js';
10
-
11
- test('notification funcs', async (t) => {
12
- // await build(t);
13
- // const pg = pgClients.client;
14
- // let resp;
15
- /* await t.test('addNotification', async () => {
16
- resp = await addNotification({
17
- pg,
18
-
19
- title: 'test title',
20
- body: 'test body',
21
- link: 'http://link',
22
- notificationType: 'mention',
23
- uid: config.testUser?.uid || '1',
24
- });
25
- assert.ok(resp.id);
26
- });
27
- await t.test('clean up after test, before pool is closed', async () => {
28
- await pg.query('delete from crm.notification where notification_id=$1', [resp.id]);
29
- console.log(resp.id, 'deleted');
30
- }); */
31
- });
1
+ import { test } from 'node:test';
2
+ import assert from 'node:assert';
3
+
4
+ // import build from '../../helper.js';
5
+ // import config from '../config.js';
6
+
7
+ // import addNotification from '../../notification/funcs/addNotification.js';
8
+
9
+ // import pgClients from '../../pg/pgClients.js';
10
+
11
+ test('notification funcs', async (t) => {
12
+ // await build(t);
13
+ // const pg = pgClients.client;
14
+ // let resp;
15
+ /* await t.test('addNotification', async () => {
16
+ resp = await addNotification({
17
+ pg,
18
+
19
+ title: 'test title',
20
+ body: 'test body',
21
+ link: 'http://link',
22
+ notificationType: 'mention',
23
+ uid: config.testUser?.uid || '1',
24
+ });
25
+ assert.ok(resp.id);
26
+ });
27
+ await t.test('clean up after test, before pool is closed', async () => {
28
+ await pg.query('delete from crm.notification where notification_id=$1', [resp.id]);
29
+ console.log(resp.id, 'deleted');
30
+ }); */
31
+ });
@@ -1,34 +1,34 @@
1
- import { test } from 'node:test';
2
- import assert from 'node:assert';
3
-
4
- import '../config.js';
5
-
6
- import getMeta from '../../pg/funcs/getMeta.js';
7
- import autoIndex from '../../pg/funcs/autoIndex.js';
8
- import pgClients from '../../pg/pgClients.js';
9
- import rclient from '../../redis/client.js';
10
- // import pgClients from '../../pg/funcs/pgClients.js';
11
-
12
- test('funcs pg', async (t) => {
13
- await pgClients.client.init();
14
- await t.test('getMeta', async () => {
15
- const { columns } = await getMeta({ table: 'gis.dataset' });
16
- // console.log(columns)
17
- assert.ok(columns);
18
- });
19
-
20
- /* await t.test('getPG', async (t) => {
21
- const data = await getPG({});
22
- assert.ok(data);
23
- }); */
24
-
25
- await t.test('autoIndex', async () => {
26
- await autoIndex({ table: 'gis.dataset', columns: ['service_type'] });
27
- assert.ok(1);
28
- });
29
- t.after(() => {
30
- pgClients.client.end();
31
-
32
- rclient.quit();
33
- });
34
- });
1
+ import { test } from 'node:test';
2
+ import assert from 'node:assert';
3
+
4
+ import '../config.js';
5
+
6
+ import getMeta from '../../pg/funcs/getMeta.js';
7
+ import autoIndex from '../../pg/funcs/autoIndex.js';
8
+ import pgClients from '../../pg/pgClients.js';
9
+ import rclient from '../../redis/client.js';
10
+ // import pgClients from '../../pg/funcs/pgClients.js';
11
+
12
+ test('funcs pg', async (t) => {
13
+ await pgClients.client.init();
14
+ await t.test('getMeta', async () => {
15
+ const { columns } = await getMeta({ table: 'gis.dataset' });
16
+ // console.log(columns)
17
+ assert.ok(columns);
18
+ });
19
+
20
+ /* await t.test('getPG', async (t) => {
21
+ const data = await getPG({});
22
+ assert.ok(data);
23
+ }); */
24
+
25
+ await t.test('autoIndex', async () => {
26
+ await autoIndex({ table: 'gis.dataset', columns: ['service_type'] });
27
+ assert.ok(1);
28
+ });
29
+ t.after(() => {
30
+ pgClients.client.end();
31
+
32
+ rclient.quit();
33
+ });
34
+ });
@@ -1,19 +1,19 @@
1
- import { test } from 'node:test';
2
- import assert from 'node:assert';
3
-
4
- import '../config.js';
5
-
6
- import rclient from '../../redis/client.js';
7
-
8
- test('funcs redis', async (t) => {
9
- await t.test('get/set', async () => {
10
- await rclient.set('test', '1');
11
- const d = await rclient.get('test');
12
- // console.log(columns)
13
- assert.equal(d, '1');
14
- });
15
-
16
- t.after(() => {
17
- rclient.quit();
18
- });
19
- });
1
+ import { test } from 'node:test';
2
+ import assert from 'node:assert';
3
+
4
+ import '../config.js';
5
+
6
+ import rclient from '../../redis/client.js';
7
+
8
+ test('funcs redis', async (t) => {
9
+ await t.test('get/set', async () => {
10
+ await rclient.set('test', '1');
11
+ const d = await rclient.get('test');
12
+ // console.log(columns)
13
+ assert.equal(d, '1');
14
+ });
15
+
16
+ t.after(() => {
17
+ rclient.quit();
18
+ });
19
+ });
@@ -1,10 +1,10 @@
1
- [
2
- {
3
- "id": 1,
4
- "text": "test"
5
- },
6
- {
7
- "id": 2,
8
- "text": "test2"
9
- }
1
+ [
2
+ {
3
+ "id": 1,
4
+ "text": "test"
5
+ },
6
+ {
7
+ "id": 2,
8
+ "text": "test2"
9
+ }
10
10
  ]
@@ -1,33 +1,33 @@
1
- {
2
- "schema": {
3
-
4
- "cp_umuni_id": {
5
- "type": "Text",
6
- "ua": "ID UMUNI"
7
- },
8
- "cp_year": {
9
- "type": "Text",
10
- "ua": "Рік будівництва"
11
- },
12
- "cp_date_en_audit": {
13
- "type": "DatePicker",
14
- "ua": "Дата проведення останнього енергоаудиту"
15
- },
16
- "cp_certificate": {
17
- "type": "Text",
18
- "ua": "Сертифікат енергоефективності будівлі",
19
- "help": "Вкажіть посилання"
20
- },
21
- "cp_pkd": {
22
- "type": "Autocomplete",
23
- "data": "customer_name",
24
- "add": {
25
- "model": "crm_acc.crm_account",
26
- "ua": "Додати",
27
- "form": "account_light.form"
28
- },
29
- "ua": "Замовник ПКД"
30
- }
31
- },
32
- "label_style": "vertical"
1
+ {
2
+ "schema": {
3
+
4
+ "cp_umuni_id": {
5
+ "type": "Text",
6
+ "ua": "ID UMUNI"
7
+ },
8
+ "cp_year": {
9
+ "type": "Text",
10
+ "ua": "Рік будівництва"
11
+ },
12
+ "cp_date_en_audit": {
13
+ "type": "DatePicker",
14
+ "ua": "Дата проведення останнього енергоаудиту"
15
+ },
16
+ "cp_certificate": {
17
+ "type": "Text",
18
+ "ua": "Сертифікат енергоефективності будівлі",
19
+ "help": "Вкажіть посилання"
20
+ },
21
+ "cp_pkd": {
22
+ "type": "Autocomplete",
23
+ "data": "customer_name",
24
+ "add": {
25
+ "model": "crm_acc.crm_account",
26
+ "ua": "Додати",
27
+ "form": "account_light.form"
28
+ },
29
+ "ua": "Замовник ПКД"
30
+ }
31
+ },
32
+ "label_style": "vertical"
33
33
  }
@@ -1,4 +1,4 @@
1
- {
2
- "db": "mbk_lviv_dma",
3
- "searchColumn": "alternative_name"
1
+ {
2
+ "db": "mbk_lviv_dma",
3
+ "searchColumn": "alternative_name"
4
4
  }
@@ -1,3 +1,3 @@
1
- {
2
- "key": "dataset_id"
1
+ {
2
+ "key": "dataset_id"
3
3
  }
@@ -1,21 +1,21 @@
1
- {
2
- "columns": [
3
- {
4
- "name": "dataset_id",
5
- "title": "22"
6
- },
7
- {
8
- "name": "dataset_name",
9
- "title": "dataset_name"
10
- }
11
- ],
12
- "table": "gis.dataset",
13
- "order": "dataset_name",
14
- "filters": [
15
- {
16
- "ua": "Назва набору",
17
- "name": "dataset_name",
18
- "type": "text"
19
- }
20
- ]
1
+ {
2
+ "columns": [
3
+ {
4
+ "name": "dataset_id",
5
+ "title": "22"
6
+ },
7
+ {
8
+ "name": "dataset_name",
9
+ "title": "dataset_name"
10
+ }
11
+ ],
12
+ "table": "gis.dataset",
13
+ "order": "dataset_name",
14
+ "filters": [
15
+ {
16
+ "ua": "Назва набору",
17
+ "name": "dataset_name",
18
+ "type": "text"
19
+ }
20
+ ]
21
21
  }
@@ -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,51 +1,51 @@
1
- import dataInsert from "../../crud/funcs/dataInsert.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
- } else if (typeof body[key] === 'object') {
9
- return { [key]: 'json' };
10
- } else if (Date.parse(body[key], 'yyyy/MM/ddTHH:mm:ss.000Z')) {
11
- return { [key]: 'date' };
12
- }
13
- return { [key]: 'text' };
14
- }
15
-
16
- export default async function addExtraProperties({
17
- pg, params = {}, body = {},
18
- }) {
19
- const { id } = params;
20
- if (!id) {
21
- return { message: 'not enougn params: 1', status: 400 };
22
- }
23
- const extraProperties = Object.keys(body);
24
- if (!extraProperties.length) {
25
- return { message: 'not enougn params: 2', status: 400 };
26
- }
27
-
28
- if (!pg.pk?.[table]) {
29
- return { message: 'table not found: crm.properties', status: 400 };
30
- }
31
-
32
- try {
33
- await pg.query(`delete from crm.properties where object_id=$1`, [id]);
34
- const keyTypeMatch = extraProperties.filter((key) => body[key]).reduce((acc, curr) => Object.assign(acc, checkKeyType({ body, key: curr })), {});
35
- const res = await Promise.all(Object.keys(keyTypeMatch).map(async (key) => {
36
- const propertyType = keyTypeMatch[key];
37
- const { rows = [] } = await dataInsert({
38
- pg, table, data: {
39
- property_type: propertyType,
40
- property_key: key,
41
- object_id: id,
42
- [`property_${propertyType}`]: body[key],
43
- }
44
- });
45
- return { id: rows[0]?.property_id, type: propertyType, value: body[key] };
46
- }));
47
- return { message: { rows: res }, status: 200 };
48
- } catch (err) {
49
- return { error: err.toString(), status: 500 };
50
- }
1
+ import dataInsert from "../../crud/funcs/dataInsert.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
+ } else if (typeof body[key] === 'object') {
9
+ return { [key]: 'json' };
10
+ } else if (Date.parse(body[key], 'yyyy/MM/ddTHH:mm:ss.000Z')) {
11
+ return { [key]: 'date' };
12
+ }
13
+ return { [key]: 'text' };
14
+ }
15
+
16
+ export default async function addExtraProperties({
17
+ pg, params = {}, body = {},
18
+ }) {
19
+ const { id } = params;
20
+ if (!id) {
21
+ return { message: 'not enougn params: 1', status: 400 };
22
+ }
23
+ const extraProperties = Object.keys(body);
24
+ if (!extraProperties.length) {
25
+ return { message: 'not enougn params: 2', status: 400 };
26
+ }
27
+
28
+ if (!pg.pk?.[table]) {
29
+ return { message: 'table not found: crm.properties', status: 400 };
30
+ }
31
+
32
+ try {
33
+ await pg.query(`delete from crm.properties where object_id=$1`, [id]);
34
+ const keyTypeMatch = extraProperties.filter((key) => body[key]).reduce((acc, curr) => Object.assign(acc, checkKeyType({ body, key: curr })), {});
35
+ const res = await Promise.all(Object.keys(keyTypeMatch).map(async (key) => {
36
+ const propertyType = keyTypeMatch[key];
37
+ const { rows = [] } = await dataInsert({
38
+ pg, table, data: {
39
+ property_type: propertyType,
40
+ property_key: key,
41
+ object_id: id,
42
+ [`property_${propertyType}`]: body[key],
43
+ }
44
+ });
45
+ return { id: rows[0]?.property_id, type: propertyType, value: body[key] };
46
+ }));
47
+ return { message: { rows: res }, status: 200 };
48
+ } catch (err) {
49
+ return { error: err.toString(), status: 500 };
50
+ }
51
51
  }
@@ -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
  }
@@ -0,0 +1,3 @@
1
+ export default async function name() {
2
+ return { message: { memoryUsage: process.memoryUsage() }, status: 200 };
3
+ }
package/util/index.js CHANGED
@@ -1,18 +1,19 @@
1
1
  import getExtraProperties from './controllers/properties.get.js';
2
2
  import addExtraProperties from './controllers/properties.add.js';
3
3
  import nextId from './controllers/next.id.js';
4
-
4
+ import statusMonitor from './controllers/status.monitor.js';
5
5
 
6
6
  const propertiesSchema = {
7
7
  params: {
8
8
  id: { type: 'string', pattern: '^([\\d\\w]+)$' },
9
- }
10
- }
9
+ },
10
+ };
11
11
 
12
12
  async function plugin(fastify, config = {}) {
13
13
  const prefix = config.prefix || '/api';
14
14
 
15
15
  fastify.get(`${prefix}/next-id`, {}, nextId);
16
+ fastify.get(`${prefix}/status-monitor`, {}, statusMonitor);
16
17
  fastify.get(`${prefix}/properties/:id`, { schema: propertiesSchema }, getExtraProperties);
17
18
  fastify.post(`${prefix}/properties/:id`, { schema: propertiesSchema }, addExtraProperties);
18
19
  }
package/widget/index.js CHANGED
@@ -1,40 +1,40 @@
1
- import widgetDel from './controllers/widget.del.js';
2
- import widgetSet from './controllers/widget.set.js';
3
- import widgetGet from './controllers/widget.get.js';
4
-
5
- const tableSchema = {
6
- params: {
7
- // type: { type: 'string', pattern: '^([\\d\\w]+)$' },
8
- objectid: { type: 'string', pattern: '^([\\d\\w]+)$' },
9
- id: { type: 'string', pattern: '^([\\d\\w]+)$' },
10
- },
11
- querystring: {
12
- debug: { type: 'string', pattern: '^(\\d+)$' },
13
- }
14
- };
15
-
16
- async function route(fastify, opt) {
17
- const prefix = opt.prefix || '/api';
18
- fastify.route({
19
- method: 'DELETE',
20
- url: `${prefix}/widget/:type/:objectid/:id`,
21
- schema: tableSchema,
22
- handler: widgetDel,
23
- });
24
- fastify.route({
25
- method: 'POST',
26
- path: `${prefix}/widget/:type/:objectid/:id?`,
27
- schema: tableSchema,
28
- handler: widgetSet,
29
- });
30
- fastify.route({
31
- method: 'GET',
32
- path: `${prefix}/widget/:type/:objectid`,
33
- config: {
34
- policy: ['public'],
35
- },
36
- schema: tableSchema,
37
- handler: widgetGet,
38
- });
39
- }
40
- export default route;
1
+ import widgetDel from './controllers/widget.del.js';
2
+ import widgetSet from './controllers/widget.set.js';
3
+ import widgetGet from './controllers/widget.get.js';
4
+
5
+ const tableSchema = {
6
+ params: {
7
+ // type: { type: 'string', pattern: '^([\\d\\w]+)$' },
8
+ objectid: { type: 'string', pattern: '^([\\d\\w]+)$' },
9
+ id: { type: 'string', pattern: '^([\\d\\w]+)$' },
10
+ },
11
+ querystring: {
12
+ debug: { type: 'string', pattern: '^(\\d+)$' },
13
+ }
14
+ };
15
+
16
+ async function route(fastify, opt) {
17
+ const prefix = opt.prefix || '/api';
18
+ fastify.route({
19
+ method: 'DELETE',
20
+ url: `${prefix}/widget/:type/:objectid/:id`,
21
+ schema: tableSchema,
22
+ handler: widgetDel,
23
+ });
24
+ fastify.route({
25
+ method: 'POST',
26
+ path: `${prefix}/widget/:type/:objectid/:id?`,
27
+ schema: tableSchema,
28
+ handler: widgetSet,
29
+ });
30
+ fastify.route({
31
+ method: 'GET',
32
+ path: `${prefix}/widget/:type/:objectid`,
33
+ config: {
34
+ policy: ['public'],
35
+ },
36
+ schema: tableSchema,
37
+ handler: widgetGet,
38
+ });
39
+ }
40
+ export default route;