@opengis/fastify-table 1.0.34 → 1.0.36

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 (77) hide show
  1. package/.eslintrc.cjs +42 -42
  2. package/Changelog.md +105 -101
  3. package/README.md +26 -26
  4. package/config.js +12 -12
  5. package/crud/controllers/deleteCrud.js +14 -14
  6. package/crud/controllers/insert.js +29 -29
  7. package/crud/controllers/update.js +31 -31
  8. package/crud/controllers/utils/checkXSS.js +45 -45
  9. package/crud/controllers/utils/xssInjection.js +72 -72
  10. package/crud/funcs/dataDelete.js +15 -15
  11. package/crud/funcs/dataInsert.js +24 -24
  12. package/crud/funcs/dataUpdate.js +24 -24
  13. package/crud/funcs/getOpt.js +10 -10
  14. package/crud/funcs/getToken.js +27 -27
  15. package/crud/funcs/isFileExists.js +13 -13
  16. package/crud/funcs/setOpt.js +16 -16
  17. package/crud/funcs/setToken.js +53 -53
  18. package/crud/index.js +29 -29
  19. package/helper.js +28 -28
  20. package/index.js +39 -39
  21. package/notification/controllers/userNotifications.js +19 -19
  22. package/notification/funcs/addNotification.js +8 -8
  23. package/notification/index.js +19 -19
  24. package/package.json +22 -22
  25. package/pg/funcs/getPG.js +29 -29
  26. package/pg/pgClients.js +20 -20
  27. package/policy/funcs/checkPolicy.js +74 -74
  28. package/policy/funcs/sqlInjection.js +33 -33
  29. package/policy/index.js +14 -14
  30. package/redis/client.js +8 -8
  31. package/redis/funcs/getRedis.js +23 -23
  32. package/redis/funcs/redisClients.js +2 -2
  33. package/redis/index.js +19 -19
  34. package/server/migrations/crm.sql +95 -95
  35. package/server/migrations/log.sql +41 -41
  36. package/server/templates/form/test.dataset.form.json +411 -411
  37. package/server/templates/select/test.storage.data.json +2 -2
  38. package/server/templates/table/test.dataset.table.json +24 -24
  39. package/server.js +14 -14
  40. package/table/controllers/data.js +57 -57
  41. package/table/controllers/filter.js +37 -32
  42. package/table/controllers/form.js +10 -10
  43. package/table/controllers/search.js +41 -41
  44. package/table/controllers/suggest.js +60 -60
  45. package/table/controllers/utils/getSelect.js +20 -20
  46. package/table/controllers/utils/getSelectMeta.js +66 -66
  47. package/table/controllers/utils/getTemplate.js +28 -28
  48. package/table/funcs/getFilterSQL/index.js +75 -75
  49. package/table/funcs/getFilterSQL/util/formatValue.js +142 -142
  50. package/table/funcs/getFilterSQL/util/getCustomQuery.js +13 -13
  51. package/table/funcs/getFilterSQL/util/getFilterQuery.js +73 -73
  52. package/table/funcs/getFilterSQL/util/getOptimizedQuery.js +12 -12
  53. package/table/funcs/getFilterSQL/util/getTableSql.js +34 -34
  54. package/table/funcs/metaFormat/getSelectVal.js +20 -20
  55. package/table/funcs/metaFormat/index.js +26 -26
  56. package/table/index.js +42 -42
  57. package/test/api/crud.test.js +56 -56
  58. package/test/api/crud.xss.test.js +71 -71
  59. package/test/api/notification.test.js +37 -37
  60. package/test/api/table.test.js +57 -57
  61. package/test/api/widget.test.js +114 -114
  62. package/test/config.example +18 -18
  63. package/test/funcs/crud.test.js +76 -76
  64. package/test/funcs/notification.test.js +31 -31
  65. package/test/funcs/pg.test.js +34 -34
  66. package/test/funcs/redis.test.js +19 -19
  67. package/test/templates/cls/test.json +9 -9
  68. package/test/templates/form/cp_building.form.json +32 -32
  69. package/test/templates/select/account_id.json +3 -3
  70. package/test/templates/select/storage.data.json +2 -2
  71. package/test/templates/table/gis.dataset.table.json +20 -20
  72. package/widget/controllers/utils/historyFormat.js +76 -76
  73. package/widget/controllers/utils/obj2db.js +13 -13
  74. package/widget/controllers/widget.del.js +41 -41
  75. package/widget/controllers/widget.get.js +77 -77
  76. package/widget/controllers/widget.set.js +64 -64
  77. package/widget/index.js +29 -29
@@ -1,3 +1,3 @@
1
- {
2
- "key": "dataset_id"
1
+ {
2
+ "key": "dataset_id"
3
3
  }
@@ -1,25 +1,25 @@
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
- "meta": {
15
- "title": "dataset_name",
16
- "search": "dataset_name,dataset_id"
17
- },
18
- "filters": [
19
- {
20
- "ua": "Назва набору",
21
- "name": "dataset_name",
22
- "type": "text"
23
- }
24
- ]
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
+ "meta": {
15
+ "title": "dataset_name",
16
+ "search": "dataset_name,dataset_id"
17
+ },
18
+ "filters": [
19
+ {
20
+ "ua": "Назва набору",
21
+ "name": "dataset_name",
22
+ "type": "text"
23
+ }
24
+ ]
25
25
  }
package/server.js CHANGED
@@ -1,14 +1,14 @@
1
- // This file contains code that we reuse
2
- // between our tests.
3
- import Fastify from 'fastify';
4
- import config from './test/config.js';
5
- import appService from './index.js';
6
-
7
- const app = Fastify({ logger: false });
8
- app.register(appService, config);
9
- app.listen({ host: '0.0.0.0', port: process.env.PORT || 3000 }, (err) => {
10
- if (err) {
11
- app.log.error(err);
12
- process.exit(1);
13
- }
14
- });
1
+ // This file contains code that we reuse
2
+ // between our tests.
3
+ import Fastify from 'fastify';
4
+ import config from './test/config.js';
5
+ import appService from './index.js';
6
+
7
+ const app = Fastify({ logger: false });
8
+ app.register(appService, config);
9
+ app.listen({ host: '0.0.0.0', port: process.env.PORT || 3000 }, (err) => {
10
+ if (err) {
11
+ app.log.error(err);
12
+ process.exit(1);
13
+ }
14
+ });
@@ -1,57 +1,57 @@
1
- import getTemplate from './utils/getTemplate.js';
2
- import getFilterSQL from '../funcs/getFilterSQL/index.js';
3
- import getMeta from '../../pg/funcs/getMeta.js';
4
- import metaFormat from '../funcs/metaFormat/index.js';
5
-
6
- const maxLimit = 100;
7
- export default async function data(req) {
8
- const time = Date.now();
9
- const {
10
- pg, params, query = {},
11
- } = req;
12
-
13
- const loadTable = await getTemplate('table', params.table);
14
-
15
- if (!loadTable) { return { status: 404, message: 'not found' }; }
16
-
17
- const {
18
- table, columns, sql, filters, form, meta,
19
- } = loadTable;
20
- const { pk } = await getMeta(table);
21
-
22
- const cols = columns.map((el) => el.name || el).join(',');
23
- const sqlTable = sql?.filter?.((el) => !el?.disabled && el?.sql?.replace).map((el, i) => ` left join lateral (${el.sql}) ${el.name || `t${i}`} on 1=1 `)?.join('') || '';
24
-
25
- const fData = query.filter ? await getFilterSQL({
26
- filter: query.filter,
27
- table: params.table,
28
- json: 1,
29
- }) : {};
30
-
31
- const keyQuery = query.key && loadTable.key && !params.id ? `${loadTable.key}=$1` : null;
32
-
33
- const limit = Math.min(maxLimit, +(query.limit || 10));
34
-
35
- const offset = query.page && query.page > 0 ? ` offset ${(query.page - 1) * limit}` : '';
36
- // id, query, filter
37
- const [orderColumn, orderDir] = (query.order || loadTable.order || '').split('-');
38
-
39
- const order = cols.includes(orderColumn) && orderColumn?.length ? `order by ${orderColumn} ${query.desc || orderDir === 'desc' ? 'desc' : ''}` : '';
40
- const state = loadTable.filterState && query.state ? loadTable.filterState[query.state]?.sql : null;
41
- const custom = loadTable.filterCustom && query.custom ? loadTable.filterCustom[query.custom]?.sql : null;
42
- const search = loadTable.meta?.search && query.search ? `(${loadTable.meta?.search.split(',').map(el => `${el} ilike '%${query.search}%'`).join(' or ')})` : null;
43
-
44
- const where = [(params.id ? ` "${pk}" = $1` : null), keyQuery, loadTable.query, fData.q, state, custom, search].filter((el) => el);
45
- const q = `select ${pk ? `"${pk}" as id,` : ''} ${query.id || query.key ? '*' : cols || '*'} from ${table} t ${sqlTable} where ${where.join(' and ') || 'true'} ${order} ${offset} limit ${limit}`;
46
-
47
- if (query.sql === '1') { return q; }
48
-
49
- const { rows } = await pg.query(q, (params.id ? [params.id] : null) || (query.key && loadTable.key ? [query.key] : []));
50
-
51
- const total = keyQuery || params.id ? rows.length : await pg.queryCache(`select count(*) from ${table} t where ${where.join(' and ') || 'true'}`).then((el) => el?.rows[0]?.count);
52
-
53
- await metaFormat({ rows, table: params.table });
54
- return {
55
- time: Date.now() - time, total, count: rows.length, pk, form, rows, meta, columns, filters,
56
- };
57
- }
1
+ import getTemplate from './utils/getTemplate.js';
2
+ import getFilterSQL from '../funcs/getFilterSQL/index.js';
3
+ import getMeta from '../../pg/funcs/getMeta.js';
4
+ import metaFormat from '../funcs/metaFormat/index.js';
5
+
6
+ const maxLimit = 100;
7
+ export default async function data(req) {
8
+ const time = Date.now();
9
+ const {
10
+ pg, params, query = {},
11
+ } = req;
12
+
13
+ const loadTable = await getTemplate('table', params.table);
14
+
15
+ if (!loadTable) { return { status: 404, message: 'not found' }; }
16
+
17
+ const {
18
+ table, columns, sql, filters, form, meta,
19
+ } = loadTable;
20
+ const { pk } = await getMeta(table);
21
+
22
+ const cols = columns.map((el) => el.name || el).join(',');
23
+ const sqlTable = sql?.filter?.((el) => !el?.disabled && el?.sql?.replace).map((el, i) => ` left join lateral (${el.sql}) ${el.name || `t${i}`} on 1=1 `)?.join('') || '';
24
+
25
+ const fData = query.filter ? await getFilterSQL({
26
+ filter: query.filter,
27
+ table: params.table,
28
+ json: 1,
29
+ }) : {};
30
+
31
+ const keyQuery = query.key && loadTable.key && !params.id ? `${loadTable.key}=$1` : null;
32
+
33
+ const limit = Math.min(maxLimit, +(query.limit || 10));
34
+
35
+ const offset = query.page && query.page > 0 ? ` offset ${(query.page - 1) * limit}` : '';
36
+ // id, query, filter
37
+ const [orderColumn, orderDir] = (query.order || loadTable.order || '').split('-');
38
+
39
+ const order = cols.includes(orderColumn) && orderColumn?.length ? `order by ${orderColumn} ${query.desc || orderDir === 'desc' ? 'desc' : ''}` : '';
40
+ const state = loadTable.filterState && query.state ? loadTable.filterState[query.state]?.sql : null;
41
+ const custom = loadTable.filterCustom && query.custom ? loadTable.filterCustom[query.custom]?.sql : null;
42
+ const search = loadTable.meta?.search && query.search ? `(${loadTable.meta?.search.split(',').map(el => `${el} ilike '%${query.search}%'`).join(' or ')})` : null;
43
+
44
+ const where = [(params.id ? ` "${pk}" = $1` : null), keyQuery, loadTable.query, fData.q, state, custom, search].filter((el) => el);
45
+ const q = `select ${pk ? `"${pk}" as id,` : ''} ${query.id || query.key ? '*' : cols || '*'} from ${table} t ${sqlTable} where ${where.join(' and ') || 'true'} ${order} ${offset} limit ${limit}`;
46
+
47
+ if (query.sql === '1') { return q; }
48
+
49
+ const { rows } = await pg.query(q, (params.id ? [params.id] : null) || (query.key && loadTable.key ? [query.key] : []));
50
+
51
+ const total = keyQuery || params.id ? rows.length : await pg.queryCache(`select count(*) from ${table} t where ${where.join(' and ') || 'true'}`).then((el) => el?.rows[0]?.count);
52
+
53
+ await metaFormat({ rows, table: params.table });
54
+ return {
55
+ time: Date.now() - time, total, count: rows.length, pk, form, rows, meta, columns, filters,
56
+ };
57
+ }
@@ -1,32 +1,37 @@
1
- import getTemplate from './utils/getTemplate.js';
2
- import getSelect from './utils/getSelect.js';
3
-
4
- export default async function filter(req) {
5
- const time = Date.now();
6
-
7
- const {
8
- params,
9
- } = req;
10
- const loadTable = await getTemplate('table', params.table);
11
- if (!loadTable) { return { status: 404, message: 'not found' }; }
12
-
13
- const filters = loadTable?.filters || loadTable?.filterList || [];
14
- await Promise.all(filters.filter((el) => el.data).map(async (el) => {
15
- const cls = await getSelect(el.data);
16
- if (!cls?.arr || !loadTable.table) return;
17
- const countArr = await req.pg.queryCache(`select ${el.id}::text as id,count(*) from ${loadTable.table} group by ${el.id}`);
18
-
19
- const options = countArr.rows.map(cel => {
20
- const data = cls?.arr.find(c => c.id === cel.id);
21
- return { ...cel, ...data };
22
- });
23
- Object.assign(el, { options });
24
- }));
25
- return {
26
- time: Date.now() - time,
27
- list: filters,
28
- custom: loadTable?.filterCustom?.map(el => ({ label: el.label })),
29
- inline: loadTable?.filterInline,
30
- state: loadTable?.filterState?.map(el => ({ label: el.label })),
31
- };
32
- }
1
+ import getTemplate from './utils/getTemplate.js';
2
+ import getSelect from './utils/getSelect.js';
3
+ import getMeta from '../../pg/funcs/getMeta.js';
4
+
5
+ export default async function filter(req) {
6
+ const time = Date.now();
7
+
8
+ const {
9
+ params,
10
+ } = req;
11
+ const loadTable = await getTemplate('table', params.table);
12
+ if (!loadTable) { return { status: 404, message: 'not found' }; }
13
+ const { columns } = await getMeta({ table: loadTable.table });
14
+
15
+ const filters = loadTable?.filters || loadTable?.filterList || [];
16
+ await Promise.all(filters.filter((el) => el.data).map(async (el) => {
17
+ const cls = await getSelect(el.data);
18
+ if (!cls?.arr || !loadTable.table) return;
19
+ const { dataTypeID } = columns.find((item) => item.name === el.id) || {};
20
+ const countArr = req.pg.pgType[dataTypeID]?.includes('[]')
21
+ ? await req.pg.queryCache(`select unnest(${el.id})::text as id,count(*) from ${loadTable.table} group by unnest(${el.id})`)
22
+ : await req.pg.queryCache(`select ${el.id}::text as id,count(*) from ${loadTable.table} group by ${el.id}`);
23
+
24
+ const options = countArr.rows.map(cel => {
25
+ const data = cls?.arr.find(c => c.id === cel.id);
26
+ return { ...cel, ...data };
27
+ });
28
+ Object.assign(el, { options });
29
+ }));
30
+ return {
31
+ time: Date.now() - time,
32
+ list: filters,
33
+ custom: loadTable?.filterCustom?.map(el => ({ label: el.label })),
34
+ inline: loadTable?.filterInline,
35
+ state: loadTable?.filterState?.map(el => ({ label: el.label })),
36
+ };
37
+ }
@@ -1,10 +1,10 @@
1
- import getTemplate from './utils/getTemplate.js';
2
-
3
- export default async function formFunction(req) {
4
- const time = Date.now();
5
- const { params } = req;
6
- const form = await getTemplate('form', params.form);
7
- if (!form) { return { status: 404, message: 'not found' }; }
8
-
9
- return { time: Date.now() - time, form };
10
- }
1
+ import getTemplate from './utils/getTemplate.js';
2
+
3
+ export default async function formFunction(req) {
4
+ const time = Date.now();
5
+ const { params } = req;
6
+ const form = await getTemplate('form', params.form);
7
+ if (!form) { return { status: 404, message: 'not found' }; }
8
+
9
+ return { time: Date.now() - time, form };
10
+ }
@@ -1,41 +1,41 @@
1
- import getTemplate from './utils/getTemplate.js';
2
- import getMeta from '../../pg/funcs/getMeta.js';
3
- import metaFormat from '../funcs/metaFormat/index.js';
4
-
5
- const maxLimit = 100;
6
-
7
- export default async function data({
8
- pg, query = {},
9
- }) {
10
- const time = Date.now();
11
-
12
- const loadTable = await getTemplate('table', query.table);
13
-
14
- if (!loadTable) { return { message: 'not found', status: 404 }; }
15
-
16
- const { table, columns, meta } = loadTable;
17
- const { pk } = await getMeta(table);
18
-
19
- const cols = columns.map((el) => el.name || el).join(',');
20
- const [orderColumn, orderDir] = (query.order || loadTable.order || '').split('-');
21
- const order = cols.includes(orderColumn) && orderColumn?.length ? `order by ${orderColumn} ${query.desc || orderDir === 'desc' ? 'desc' : ''}` : '';
22
-
23
- const limit = Math.min(maxLimit, +(query.limit || 10));
24
- const offset = query.page && query.page > 0 ? ` offset ${(query.page - 1) * limit}` : '';
25
-
26
- const search = meta?.search && query.key ? `(${meta?.search.concat(meta?.title ? `,${meta?.title}` : '').split(',').map(el => `${el} ilike '%${query.key}%'`).join(' or ')})` : null;
27
-
28
- const where = [loadTable.query, search].filter((el) => el);
29
- const q = `select ${pk ? `"${pk}" as id,` : ''} * from ${table} t where ${where.join(' and ') || 'true'} ${order} ${offset} limit ${limit}`;
30
-
31
- if (query.sql === '1') return q;
32
-
33
- const { rows } = await pg.query(q);
34
-
35
- const total = await pg.queryCache(`select count(*) from ${table} t where ${where.join(' and ') || 'true'}`).then((el) => el?.rows[0]?.count);
36
-
37
- await metaFormat({ rows, table: query.table });
38
- return {
39
- time: Date.now() - time, total, count: rows.length, rows,
40
- };
41
- }
1
+ import getTemplate from './utils/getTemplate.js';
2
+ import getMeta from '../../pg/funcs/getMeta.js';
3
+ import metaFormat from '../funcs/metaFormat/index.js';
4
+
5
+ const maxLimit = 100;
6
+
7
+ export default async function data({
8
+ pg, query = {},
9
+ }) {
10
+ const time = Date.now();
11
+
12
+ const loadTable = await getTemplate('table', query.table);
13
+
14
+ if (!loadTable) { return { message: 'not found', status: 404 }; }
15
+
16
+ const { table, columns, meta } = loadTable;
17
+ const { pk } = await getMeta(table);
18
+
19
+ const cols = columns.map((el) => el.name || el).join(',');
20
+ const [orderColumn, orderDir] = (query.order || loadTable.order || '').split('-');
21
+ const order = cols.includes(orderColumn) && orderColumn?.length ? `order by ${orderColumn} ${query.desc || orderDir === 'desc' ? 'desc' : ''}` : '';
22
+
23
+ const limit = Math.min(maxLimit, +(query.limit || 10));
24
+ const offset = query.page && query.page > 0 ? ` offset ${(query.page - 1) * limit}` : '';
25
+
26
+ const search = meta?.search && query.key ? `(${meta?.search.concat(meta?.title ? `,${meta?.title}` : '').split(',').map(el => `${el} ilike '%${query.key}%'`).join(' or ')})` : null;
27
+
28
+ const where = [loadTable.query, search].filter((el) => el);
29
+ const q = `select ${pk ? `"${pk}" as id,` : ''} * from ${table} t where ${where.join(' and ') || 'true'} ${order} ${offset} limit ${limit}`;
30
+
31
+ if (query.sql === '1') return q;
32
+
33
+ const { rows } = await pg.query(q);
34
+
35
+ const total = await pg.queryCache(`select count(*) from ${table} t where ${where.join(' and ') || 'true'}`).then((el) => el?.rows[0]?.count);
36
+
37
+ await metaFormat({ rows, table: query.table });
38
+ return {
39
+ time: Date.now() - time, total, count: rows.length, rows,
40
+ };
41
+ }
@@ -1,60 +1,60 @@
1
- import getSelectMeta from './utils/getSelectMeta.js';
2
- import getPG from '../../pg/funcs/getPG.js';
3
-
4
- const limit = 50;
5
- const headers = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET', 'Cache-Control': 'no-cache' };
6
-
7
- export default async function suggest(req) {
8
- const { params, query, pg: pg1 } = req;
9
-
10
- const lang = query.lang || 'ua';
11
- const time = Date.now();
12
- const parent = query.parent || '';
13
-
14
- const selectName = query.sel || query.name || params.data;
15
- if (!selectName) return { headers, status: 400, message: 'name is required' };
16
-
17
- const meta = await getSelectMeta({ name: selectName });
18
- const pg = meta.db ? getPG({ db: meta.db }) : pg1;
19
- if (!meta) return { headers, status: 404, message: 'Not found query select ' };
20
-
21
- const { arr, searchQuery } = meta;
22
-
23
- if (arr) {
24
- const lower = query.key?.toLowerCase();
25
- const data = query.key || query.val
26
- ? arr?.filter((el) => !lower || (el[lang] || el.text)?.toLowerCase()?.indexOf(lower) !== -1)?.filter((el) => !query.val || el.id === query.val)
27
- : arr;
28
- return {
29
- limit, count: data.length, mode: 'array', time: Date.now() - time, data,
30
- };
31
- }
32
-
33
- // search
34
- const search = query.key ? searchQuery : null;
35
-
36
- // val
37
- const pk = meta.originalCols.split(',')[0];
38
- const val = query.val ? ` ${pk}=any('{${query.val.replace(/'/g, "''")}}')` : '';
39
-
40
- const sqlSuggest = `with rows(id,text) as (${meta.original.replace(/{{parent}}/gi, parent)} where ${[search, val].filter((el) => el).join(' and ') || 'true'}) select * from rows limit ${limit}`;
41
- if (query.sql) return sqlSuggest;
42
-
43
- // query
44
- const { rows: dataNew } = meta.searchColumn ? { rows: [] } : await pg.query(sqlSuggest, query.key ? [`${query.key}%`] : []);
45
- const { rows: dataNew1 } = dataNew.length < limit ? await pg.query(sqlSuggest, query.key ? [`%${query.key}%`] : []) : {};
46
- const ids = dataNew.map((el) => el.id);
47
- const data = dataNew.concat((dataNew1 || []).filter((el) => !ids?.includes(el.id)));
48
-
49
- const message = {
50
- time: Date.now() - time,
51
- count: data.length,
52
- total: meta.count - 0,
53
- mode: 'sql',
54
- db: meta.db,
55
- sql: sqlSuggest,
56
- data,
57
- };
58
-
59
- return message;
60
- }
1
+ import getSelectMeta from './utils/getSelectMeta.js';
2
+ import getPG from '../../pg/funcs/getPG.js';
3
+
4
+ const limit = 50;
5
+ const headers = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET', 'Cache-Control': 'no-cache' };
6
+
7
+ export default async function suggest(req) {
8
+ const { params, query, pg: pg1 } = req;
9
+
10
+ const lang = query.lang || 'ua';
11
+ const time = Date.now();
12
+ const parent = query.parent || '';
13
+
14
+ const selectName = query.sel || query.name || params.data;
15
+ if (!selectName) return { headers, status: 400, message: 'name is required' };
16
+
17
+ const meta = await getSelectMeta({ name: selectName });
18
+ const pg = meta.db ? getPG({ db: meta.db }) : pg1;
19
+ if (!meta) return { headers, status: 404, message: 'Not found query select ' };
20
+
21
+ const { arr, searchQuery } = meta;
22
+
23
+ if (arr) {
24
+ const lower = query.key?.toLowerCase();
25
+ const data = query.key || query.val
26
+ ? arr?.filter((el) => !lower || (el[lang] || el.text)?.toLowerCase()?.indexOf(lower) !== -1)?.filter((el) => !query.val || el.id === query.val)
27
+ : arr;
28
+ return {
29
+ limit, count: data.length, mode: 'array', time: Date.now() - time, data,
30
+ };
31
+ }
32
+
33
+ // search
34
+ const search = query.key ? searchQuery : null;
35
+
36
+ // val
37
+ const pk = meta.originalCols.split(',')[0];
38
+ const val = query.val ? ` ${pk}=any('{${query.val.replace(/'/g, "''")}}')` : '';
39
+
40
+ const sqlSuggest = `with rows(id,text) as (${meta.original.replace(/{{parent}}/gi, parent)} where ${[search, val].filter((el) => el).join(' and ') || 'true'}) select * from rows limit ${limit}`;
41
+ if (query.sql) return sqlSuggest;
42
+
43
+ // query
44
+ const { rows: dataNew } = meta.searchColumn ? { rows: [] } : await pg.query(sqlSuggest, query.key ? [`${query.key}%`] : []);
45
+ const { rows: dataNew1 } = dataNew.length < limit ? await pg.query(sqlSuggest, query.key ? [`%${query.key}%`] : []) : {};
46
+ const ids = dataNew.map((el) => el.id);
47
+ const data = dataNew.concat((dataNew1 || []).filter((el) => !ids?.includes(el.id)));
48
+
49
+ const message = {
50
+ time: Date.now() - time,
51
+ count: data.length,
52
+ total: meta.count - 0,
53
+ mode: 'sql',
54
+ db: meta.db,
55
+ sql: sqlSuggest,
56
+ data,
57
+ };
58
+
59
+ return message;
60
+ }
@@ -1,20 +1,20 @@
1
- import getTemplate from './getTemplate.js';
2
-
3
- const loadCls = {};
4
-
5
- export default async function getTable(name) {
6
- if (loadCls[name]) return loadCls[name];
7
-
8
- const clsData = await getTemplate('cls', name);
9
-
10
- if (clsData) {
11
- loadCls[name] = { arr: clsData };
12
- return loadCls[name];
13
- }
14
-
15
- const selectData = await getTemplate('select', name);
16
- if (!selectData) { return null; }
17
-
18
- loadCls[name] = selectData;
19
- return loadCls[name];
20
- }
1
+ import getTemplate from './getTemplate.js';
2
+
3
+ const loadCls = {};
4
+
5
+ export default async function getTable(name) {
6
+ if (loadCls[name]) return loadCls[name];
7
+
8
+ const clsData = await getTemplate('cls', name);
9
+
10
+ if (clsData) {
11
+ loadCls[name] = { arr: clsData };
12
+ return loadCls[name];
13
+ }
14
+
15
+ const selectData = await getTemplate('select', name);
16
+ if (!selectData) { return null; }
17
+
18
+ loadCls[name] = selectData;
19
+ return loadCls[name];
20
+ }