@opengis/fastify-table 1.4.9 → 1.4.11

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengis/fastify-table",
3
- "version": "1.4.9",
3
+ "version": "1.4.11",
4
4
  "type": "module",
5
5
  "description": "core-plugins",
6
6
  "keywords": [
@@ -26,14 +26,20 @@
26
26
  "test:routes": "node --test .\\test\\routes",
27
27
  "test:functions": "node --test .\\test\\functions",
28
28
  "compress": "node compress.js",
29
- "dev": "cross-env NODE_ENV=development node server.js"
29
+ "dev": "set NODE_ENV=development&& node server.js"
30
30
  },
31
31
  "dependencies": {
32
+ "@aws-sdk/client-s3": "3.554.0",
32
33
  "@fastify/http-proxy": "11.1.2",
34
+ "@fastify/multipart": "9.0.3",
35
+ "@grpc/grpc-js": "1.10.6",
36
+ "@grpc/proto-loader": "0.7.12",
33
37
  "dotenv": "16.5.0",
34
38
  "fastify": "5.3.3",
35
39
  "fastify-plugin": "5.0.1",
40
+ "formidable": "3.5.1",
36
41
  "handlebars": "4.7.8",
42
+ "image-size": "1.2.0",
37
43
  "ioredis": "5.3.2",
38
44
  "js-yaml": "4.1.0",
39
45
  "markdown-it": "14.1.0",
@@ -42,16 +48,9 @@
42
48
  "pino-abstract-transport": "2.0.0",
43
49
  "promised-handlebars": "2.0.1",
44
50
  "qrcode": "1.5.4",
45
- "uglify-js": "3.19.3",
46
- "@aws-sdk/client-s3": "3.554.0",
47
- "@fastify/multipart": "9.0.3",
48
- "@grpc/grpc-js": "1.10.6",
49
- "@grpc/proto-loader": "0.7.12",
50
- "formidable": "3.5.1",
51
- "image-size": "1.2.0"
51
+ "uglify-js": "3.19.3"
52
52
  },
53
53
  "devDependencies": {
54
- "cross-env": "7.0.3",
55
54
  "eslint": "8.49.0",
56
55
  "eslint-config-airbnb": "19.0.4"
57
56
  },
@@ -2,16 +2,7 @@ import pgClients from '../../pg/pgClients.js';
2
2
  import getTemplate from '../../table/funcs/getTemplate.js';
3
3
  import applyHook from '../../hook/funcs/applyHook.js';
4
4
 
5
- /**
6
- * @param {Array} user_roles.actions Actions - user actions <> group actions
7
- * @param {Array} role_access.actions Actions - user actions = group actions
8
- * @param {String} body.actions Actions from table template
9
- * @param {String} table Table name / Interface alias
10
- * @param {Object} user User object
11
- * @param {String} user.uid User ID
12
- * @param {String} user.user_type User type
13
- * @returns { scope: String, actions: String[], query: String }
14
- */
5
+ const allActions = ['view', 'edit', 'add', 'del'];
15
6
 
16
7
  const q = `select a.route_id as id, d.actions as user_roles, d.actions as role_actions, coalesce(b.actions, array['view']) as interface_actions, b.scope, c.role_id
17
8
  from admin.routes a
@@ -29,7 +20,18 @@ left join admin.user_roles d on
29
20
  end )
30
21
  where $1 in (a.route_id, a.alias, a.table_name) and $2 in (b.user_uid, d.user_uid)`;
31
22
 
32
- export default async function getAccess({ table, user = {} }, pg = pgClients.client) {
23
+ /**
24
+ * @param {Array} user_roles.actions Actions - user actions <> group actions
25
+ * @param {Array} role_access.actions Actions - user actions = group actions
26
+ * @param {String} body.actions Actions from table template
27
+ * @param {String} table Table name / Interface alias
28
+ * @param {Object} user User object
29
+ * @param {String} user.uid User ID
30
+ * @param {String} user.user_type User type
31
+ * @returns { scope: String, roles: String[], actions: String[], query: String }
32
+ */
33
+
34
+ export default async function getAccess({ table, form, user = {} }, pg = pgClients.client) {
33
35
  if (!table) return null;
34
36
 
35
37
  const hookData = await applyHook('getAccess', { table, user, pg });
@@ -38,15 +40,19 @@ export default async function getAccess({ table, user = {} }, pg = pgClients.cli
38
40
  const { uid, user_type: userType = 'regular' } = user;
39
41
 
40
42
  if (userType === 'superadmin') {
41
- return { actions: ['view', 'edit', 'add', 'del'], query: '1=1' };
43
+ return { actions: allActions, query: '1=1' };
42
44
  }
43
45
 
44
46
  const body = await getTemplate('table', table);
45
- const tableActions = ['view'].concat(body?.actions || body?.action_default || []);
47
+ const tableActions = !body && form
48
+ ? allActions // if db table and form => full access (token)
49
+ : ['view'].concat(body?.actions || body?.action_default || []);
46
50
 
47
51
  if (userType === 'admin') {
48
- const adminActions = body?.form ? ['view', 'del', 'edit', 'add'] : ['view', 'del'];
49
- return { actions: body?.actions || body?.action_default ? tableActions : adminActions, query: '1=1' };
52
+ if (!(body?.actions || body?.action_default) && (body?.form || form)) {
53
+ return { actions: allActions, query: '1=1' };
54
+ }
55
+ return { actions: tableActions, query: '1=1' };
50
56
  }
51
57
 
52
58
  if (body?.public || body?.access === 'public') {
@@ -76,7 +82,7 @@ export default async function getAccess({ table, user = {} }, pg = pgClients.cli
76
82
  const query = userAccess?.scope === 'my' ? `uid='${uid}'` : '1=1';
77
83
  const actions = userAccess?.interface_actions
78
84
  ?.filter?.((el, idx, arr) => arr.indexOf(el) === idx)
79
- ?.filter(el => userAccess?.role_actions?.length ? userAccess?.role_actions.includes(el) : true)
85
+ ?.filter(el => (userAccess?.role_actions?.length ? userAccess?.role_actions.includes(el) : true))
80
86
  ?.filter(el => tableActions.includes(el));
81
87
  return {
82
88
  scope: userAccess?.scope,
@@ -6,7 +6,6 @@ const providers = (opt) => ({
6
6
  s3: s3(opt),
7
7
  });
8
8
 
9
- // import config from '@opengis/fastify-file/config.js';
10
9
  import config from '../../../../config.js';
11
10
 
12
11
  // storage s3 or file
@@ -28,7 +28,7 @@ export default async function deleteCrud(req, reply) {
28
28
  }
29
29
 
30
30
  if (!actions.includes('del') && !config?.local) {
31
- return reply.status(403).send('access restricted');
31
+ return reply.status(403).send('access restricted: actions');
32
32
  }
33
33
 
34
34
  const loadTemplate = await getTemplate('table', del);
@@ -26,14 +26,14 @@ export default async function insert(req, reply) {
26
26
 
27
27
  const { form, table: add } = hookData || tokenData || (config.security?.disableToken || config.local || config.auth?.disable ? req.params : {});
28
28
 
29
- const { actions = [] } = await getAccess({ table: add, user }, pg) || {};
29
+ const { actions = [] } = await getAccess({ table: add, form, user }, pg) || {};
30
30
 
31
31
  if (!tokenData && !config.local && !config.security?.disableToken && !config.auth?.disable) {
32
32
  return reply.status(400).send('invalid token');
33
33
  }
34
34
 
35
35
  if (!actions.includes('add') && !config.local) {
36
- return reply.status(403).send('access restricted');
36
+ return reply.status(403).send('access restricted: actions');
37
37
  }
38
38
 
39
39
  if (!add) {
@@ -17,57 +17,56 @@ export default async function tableAPI(req, reply) {
17
17
  if (hookData?.message && hookData?.status) {
18
18
  return { message: hookData?.message, status: hookData?.status };
19
19
  }
20
- const tableName1 = hookData?.table || tokenData.table || params.table;
20
+ const templateName = hookData?.table || tokenData.table || params.table;
21
+
22
+ const loadTable = await getTemplate('table', templateName);
21
23
 
22
- const loadTable = await getTemplate('table', tableName1) || {};
23
24
  if (!loadTable && !pg.pk?.[tokenData.table]) {
24
25
  return { message: 'not found', status: 404 };
25
26
  }
26
27
 
27
- const { table, /* columns, */ form } = loadTable;
28
-
29
- const templateName = hookData?.table || tokenData.table || params.table;
30
- const tableName = table || templateName;
28
+ const { table = params.table, /* columns, */ form } = hookData || loadTable || tokenData;
31
29
 
32
30
  const id = hookData?.id || tokenData.id || params.id;
33
31
 
34
32
  if (tokenData && !id) return { message: {} };
35
- if (!tableName && !id) {
33
+ if (!table && !id) {
36
34
  return reply.status(400).send('not enough params');
37
35
  }
38
36
 
39
- const { actions = [], query: accessQuery } = await getAccess({ table: templateName, id, user }, pg) || {};
37
+ const { actions = [], query: accessQuery } = await getAccess({
38
+ table, form, id, user,
39
+ }, pg) || {};
40
40
 
41
41
  if (!tokenData && !config?.local && !config.security?.disableToken) {
42
42
  return reply.status(400).send('invalid token');
43
43
  }
44
44
 
45
45
  if (!actions.includes('edit') && !config?.local) {
46
- return reply.status(403).send('access restricted');
46
+ return reply.status(403).send('access restricted: actions');
47
47
  }
48
48
 
49
- const { pk, columns: dbColumns = [] } = await getMeta({ pg, table: tableName });
49
+ const { pk, columns: dbColumns = [] } = await getMeta({ pg, table });
50
50
 
51
51
  if (!pk) {
52
52
  return reply.status(404).send(`table not found: ${table}`);
53
53
  }
54
54
 
55
55
  // const cols = columns.map((el) => el.name || el).join(',');
56
- const formName = hookData?.form || tokenData?.form || form;
57
- const formData = await getTemplate('form', formName) || {};
56
+ const formData = await getTemplate('form', form) || {};
58
57
  const schema = formData?.schema || formData || {};
59
58
  // skip DataTable from another table
60
59
  const extraKeys = Object.keys(schema).filter((key) => schema[key]?.table && schema[key]?.parent_id && Object.hasOwn(schema[key], 'colModel'));
61
60
  // skip non-existing columns
62
61
  const columnList = dbColumns.map((el) => el.name || el).join(',');
63
62
 
64
- const { fields = [] } = !loadTable?.table ? await pg.query(`select * from ${tableName} limit 0`) : {};
63
+ const { fields = [] } = !loadTable?.table ? await pg.query(`select * from ${table} limit 0`) : {};
65
64
  const cols = loadTable?.table
66
65
  ? Object.keys(schema || {}).filter((col) => columnList.includes(col) && !extraKeys.includes(col))?.map((col) => (col?.includes('geom') && schema?.[col]?.type === 'Geom' ? `st_asgeojson(${col})::json as "${col}"` : `"${col}"`))?.join(',')
67
66
  : fields.map((el) => (el?.name?.includes('geom') && pg.pgType[el?.dataTypeID] === 'geometry' ? `st_asgeojson(${el.name})::json as "${el.name}"` : `"${el?.name}"`)).join(',');
68
- const where = [`"${pk}" = $1`, loadTable.query, accessQuery].filter((el) => el).filter((el) => (user?.user_type === 'superadmin' ? !el.includes('{{uid}}') : true));
67
+ const where = [`"${pk}" = $1`, loadTable?.query, accessQuery].filter(Boolean).filter((el) => (user?.user_type === 'superadmin' ? !el.includes('{{uid}}') : true));
69
68
  const geom = dbColumns.find((el) => el.name === 'geom' && pg.pgType[el.dataTypeID] === 'geometry') ? ',st_asgeojson(geom)::json as geom' : '';
70
- const q = `select "${pk}" as id, ${cols || '*'} ${geom} from ${tableName} t where ${where.join(' and ') || 'true'} limit 1`;
69
+ const q = `select "${pk}" as id, ${cols || '*'} ${geom} from ${table} t where ${where.join(' and ') || 'true'} limit 1`;
71
70
 
72
71
  if (query?.sql === '1') {
73
72
  const extraQ = extraKeys?.map((key) => {
@@ -93,23 +92,23 @@ export default async function tableAPI(req, reply) {
93
92
  const { colModel, table: extraTable, parent_id: parentId } = schema[key];
94
93
  const colModel1 = Array.isArray(colModel) ? colModel : Object.values(colModel || {});
95
94
  const q1 = `select ${parentId} as parent, ${colModel1.map((col) => col.name || col.key).join(',')} from ${extraTable} a where ${parentId}=$1`;
96
- // console.log(tableName, formName, q1);
95
+ // console.log(table, formName, q1);
97
96
  const { rows: extraRows } = await pg.query(q1, [id]);
98
97
  Object.assign(data, { [key]: extraRows });
99
98
  }));
100
99
  }
101
100
  if (user?.uid && !config.security?.disableToken && actions.includes('edit')) {
102
101
  data.token = tokenData?.table ? params.table : setToken({
103
- ids: [JSON.stringify({ id, table: tableName, form: loadTable.form })],
102
+ ids: [JSON.stringify({ id, table, form })],
104
103
  uid: user.uid,
105
104
  array: 1,
106
105
  })?.[0];
107
106
  }
108
107
 
109
- await extraDataGet({ rows: [data], table: tableName, form: hookData?.form || tokenData?.form || loadTable.form }, pg);
108
+ await extraDataGet({ rows: [data], table, form }, pg);
110
109
 
111
110
  const res = await applyHook('afterTable', {
112
- pg, table: tableName, payload: [data], user,
111
+ pg, table, payload: [data], user,
113
112
  });
114
113
 
115
114
  return res || data || {};
@@ -28,14 +28,16 @@ export default async function update(req, reply) {
28
28
 
29
29
  const { form, table: edit, id } = hookData || tokenData || (config.security?.disableToken || config.local || config.auth?.disable ? params : {});
30
30
 
31
- const { actions = [] } = await getAccess({ table: edit, id, user }, pg) || {};
31
+ const { actions = [] } = await getAccess({
32
+ table: edit, form, id, user,
33
+ }, pg) || {};
32
34
 
33
35
  if (!tokenData && !config.local && !config.security?.disableToken && !config.auth?.disable) {
34
36
  return reply.status(400).send('invalid token');
35
37
  }
36
38
 
37
39
  if (!actions.includes('edit') && !config.local) {
38
- return reply.status(403).send('access restricted');
40
+ return reply.status(403).send('access restricted: actions');
39
41
  }
40
42
 
41
43
  if (!edit) {
@@ -1,4 +1,6 @@
1
- import { logger, autoIndex, getSelect, getTemplate, getSelectVal, pgClients } from '../../../../utils.js';
1
+ import {
2
+ logger, autoIndex, getSelect, getTemplate, getSelectVal, pgClients,
3
+ } from '../../../../utils.js';
2
4
 
3
5
  export default async function filterAPI(req) {
4
6
  const time = Date.now();
@@ -21,8 +23,10 @@ export default async function filterAPI(req) {
21
23
  const filters = (loadTable?.filter_list || loadTable?.filters || loadTable?.filterList || []).concat(loadTable?.filterSql || []);
22
24
 
23
25
  // admin.custom_column - user filter NA-165
24
- const { rows: properties = [] } = await pg.query(`select column_id, name, title, format, data from admin.custom_column where entity=$1 and uid=$2 and filter`, [params.table, user?.uid]);
25
- properties.forEach((row) => filters.push({ id: row.name, name: row.name, ua: row.title, type: row.format, data: row.data }));
26
+ const { rows: properties = [] } = await pg.query('select column_id, name, title, format, data from admin.custom_column where entity=$1 and uid=$2 and filter', [params.table, user?.uid]);
27
+ properties.forEach((row) => filters.push({
28
+ id: row.name, name: row.name, ua: row.title, type: row.format, data: row.data,
29
+ }));
26
30
 
27
31
  // KRYVYIRIH-231
28
32
  autoIndex({ table: loadTable.table, columns: filters.filter((el) => columns?.find?.((item) => item?.name === el.name)) })
@@ -43,7 +47,7 @@ export default async function filterAPI(req) {
43
47
  const { dataTypeID } = columns.find((item) => item.name === el.id) || {};
44
48
 
45
49
  if (el.extra && Array.isArray(cls?.arr || cls)) {
46
- const countArr = await pg.query(`select value_text as id, count(*) from crm.extra_data where property_key=$1 and property_entity=$2 group by value_text`, [el.id, loadTable.table]);
50
+ const countArr = await pg.query('select value_text as id, count(*) from crm.extra_data where property_key=$1 and property_entity=$2 group by value_text', [el.id, loadTable.table]);
47
51
  const options = countArr.rows.map(cel => {
48
52
  const data = (cls?.arr || cls).find(c => c.id === cel.id);
49
53
  return { ...cel, ...data };
@@ -73,12 +77,10 @@ export default async function filterAPI(req) {
73
77
  return { ...cel, ...data };
74
78
  });
75
79
  Object.assign(el, { options });
76
-
77
80
  }));
78
81
 
79
82
  const q = ((loadTable?.filterState || []).concat(loadTable?.filterCustom || [])).filter((el) => el.name && el.sql).map((el) => `select count(*), '${el.name}' as name from (${optimizedSQL})q where ${el.sql}`).join(' union all ');
80
83
 
81
-
82
84
  const { rows = [], timeout: timeout1 } = q ? await pg.queryCache(q) : {};
83
85
  if (timeout1) logger.file('timeout/filter', { table: params.table, type: 'state/custom' });
84
86
 
@@ -89,7 +91,6 @@ export default async function filterAPI(req) {
89
91
  });
90
92
  }
91
93
 
92
-
93
94
  const sqlList = loadTable?.sql
94
95
  ?.filter((el) => !el.disabled && el?.sql?.replace)
95
96
  ?.map((el, i) => ` left join lateral (${el.filter ? el.sql.replace(/limit 1/ig, '') : el.sql}) as ${el.name || `t${i + 1}`} on 1=1 `)
@@ -97,23 +98,23 @@ export default async function filterAPI(req) {
97
98
 
98
99
  // percentile_cont - alternative
99
100
  await Promise.all(filters.filter((el) => el.name && el.type === 'Range' && fields?.find?.((item) => item?.name === el.name)).map(async (el) => {
100
-
101
- const data = await pg.queryCache(`select array[
101
+ const data = await pg.queryCache(
102
+ `select array[
102
103
  min(${el.name}),
103
104
  percentile_disc(0.25) within group (order by ${el.name}),
104
105
  percentile_disc(0.5) within group (order by ${el.name}),
105
106
  percentile_disc(0.75) within group (order by ${el.name}),
106
107
  max(${el.name})
107
108
  ] as range from ${loadTable.table} ${sqlList && false ? ` t ${sqlList}` : ''} where ${loadTable.query || '1=1'}`,
108
- { table: loadTable.table }).then(el => {
109
- if (el.timeout) {
110
- logger.file('timeout/filter', { table: params.table, type: 'Range', filter: el.name });
111
- return el;
112
- }
113
- return el.rows?.[0]?.range;
114
- });
109
+ { table: loadTable.table },
110
+ ).then(el => {
111
+ if (el.timeout) {
112
+ logger.file('timeout/filter', { table: params.table, type: 'Range', filter: el.name });
113
+ return el;
114
+ }
115
+ return el.rows?.[0]?.range;
116
+ });
115
117
  Object.assign(el, { data });
116
-
117
118
  }));
118
119
 
119
120
  const sqlFilters = (loadTable?.filterCustom || []).filter((el) => el.name && el.sql);
@@ -136,4 +137,4 @@ export default async function filterAPI(req) {
136
137
  inline: loadTable?.filterInline,
137
138
  state: loadTable?.filterState,
138
139
  };
139
- }
140
+ }
@@ -1,5 +1,5 @@
1
1
  import {
2
- config, getTemplate, getFilterSQL, getMeta, metaFormat, getAccess, setToken, gisIRColumn, applyHook, handlebars, handlebarsSync, getSelect, setOpt, getOpt, pgClients,
2
+ config, getTemplate, getFilterSQL, getMeta, metaFormat, getAccess, setToken, gisIRColumn, applyHook, handlebars, handlebarsSync, getSelect, setOpt, getOpt, pgClients, logger, getFilter,
3
3
  } from '../../../../utils.js';
4
4
 
5
5
  import extraDataGet from '../../../plugins/extra/extraDataGet.js';
@@ -78,13 +78,22 @@ export default async function dataAPI(req, reply, called) {
78
78
  table, columns = [], sql, cardSql, form, meta, sqlColumns, public: ispublic, editable = false,
79
79
  } = loadTable || hookData || tokenData || params;
80
80
 
81
- const filters = ((body?.filter_list || [])
81
+ /* const filters = ((body?.filter_list || [])
82
82
  .concat(body?.filterInline || [])
83
83
  .concat(body?.filterCustom || [])
84
84
  .concat(body?.filterState || [])
85
85
  .concat(body?.filterList || [])
86
86
  .concat(body?.filters || [])
87
- ).filter(el => el.id || el.name);
87
+ ).filter(el => el.id || el.name); */
88
+
89
+ if (body?.filter_list || body?.filterList) {
90
+ console.warn('invalid filters in template: filter_list / filterList');
91
+ logger.file('crud/warning', { msg: 'invalid filters', template: tokenData?.table || hookData?.table || params.table });
92
+ }
93
+
94
+ const { list: filters = [] } = await getFilter({
95
+ pg, table: tokenData?.table || hookData?.table || params.table, user,
96
+ }) || {};
88
97
 
89
98
  const tableMeta = await getMeta({ pg, table });
90
99
  timeArr.push(Date.now());
@@ -5,7 +5,6 @@ import cardData from './controllers/cardData.js';
5
5
  import dataInfo from './controllers/dataInfo.js';
6
6
  import tableInfo from './controllers/tableInfo.js';
7
7
  import tokenInfo from './controllers/tokenInfo.js';
8
- import tableFilter from './controllers/tableFilter.js';
9
8
 
10
9
  import card from './controllers/card.js';
11
10
  import search from './controllers/search.js';
@@ -15,7 +14,7 @@ import form from './controllers/form.js';
15
14
  import loadTemplatePath from '../../plugins/table/funcs/loadTemplatePath.js';
16
15
 
17
16
  import {
18
- tableDataSchema, tableSchema, searchSchema, suggestSchema, formSchema, filterSchema, cardTabDataSchema, tableDataIdSchema, tableFilterSchema,
17
+ tableDataSchema, tableSchema, searchSchema, suggestSchema, formSchema, filterSchema, cardTabDataSchema, tableDataIdSchema,
19
18
  } from './schema.js';
20
19
 
21
20
  const policy = ['public'];
@@ -25,7 +24,7 @@ async function plugin(app, config = {}) {
25
24
 
26
25
  app.get(`${prefix}/token-info/:token`, { config: { policy: ['admin'] } }, tokenInfo);
27
26
 
28
- app.get(`${prefix}/table-filter/:table`, { config: { policy }, schema: tableFilterSchema }, tableFilter);
27
+ app.get(`${prefix}/table-filter/:table`, { config: { policy }, schema: filterSchema }, filter);
29
28
 
30
29
  app.get(`${prefix}/table-info/:table/:id?`, { config: { policy }, schema: tableDataSchema }, tableInfo);
31
30
  app.get(`${prefix}/suggest/:data`, { config: { policy }, schema: suggestSchema }, suggest);
@@ -1,33 +1,24 @@
1
1
  const tableDataSchema = {
2
2
  type: 'object',
3
3
  properties: {
4
- querystring: {
5
- limit: { type: 'string', pattern: '^(\\d+)$' },
6
- page: { type: 'string', pattern: '^(\\d+)$' },
7
- // filter: { type: 'string', pattern: '^([\\w\\d_-]+)=([А-Яа-яҐґЄєІіЇї\\d\\w\\s\\/\\[\\]\\(\\)\\{\\}\\|,.!?;:—_=-@%#$&^*+=`~]+)$' },
8
- // search: { type: 'string', pattern: '^([А-Яа-яҐґЄєІіЇї\\d\\w\\s\\/\\[\\]\\(\\)\\{\\}\\|,.!?;:—_=-@%#$&^*+=`~]+)$' },
9
- order: { type: 'string', pattern: '^([\\d\\w_.-]+)$' },
10
- desc: { type: 'string', pattern: '^(\\d+)$' },
11
- state: { type: 'string', pattern: '^([\\d\\w._-]+)$' },
12
- custom: { type: 'string', pattern: '^([\\d\\w._-]+)$' },
13
- bbox: { type: 'string', pattern: '^([\\d\\s,.-]+)$' },
14
- polyline: { type: 'string', pattern: '^([\\d\\w|@{}~_`]+)$' },
15
- // key: { type: 'string', pattern: '^([\\d\\w_]+)$' },
16
- sql: { type: 'string', pattern: '^(\\d)$' },
17
- },
18
- params: {
19
- id: { type: 'string', pattern: '^([\\d\\w_.-]+)$' },
20
- table: { type: 'string', pattern: '^([\\d\\w_.-]+)$' },
21
- },
22
- },
23
- };
24
-
25
- const tableFilterSchema = {
26
- type: 'object',
27
- properties: {
28
- params: {
29
- name: { type: 'string', pattern: '^([\\d\\w._-]+)$' },
30
- },
4
+ querystring: {
5
+ limit: { type: 'string', pattern: '^(\\d+)$' },
6
+ page: { type: 'string', pattern: '^(\\d+)$' },
7
+ // filter: { type: 'string', pattern: '^([\\w\\d_-]+)=([А-Яа-яҐґЄєІіЇї\\d\\w\\s\\/\\[\\]\\(\\)\\{\\}\\|,.!?;:—_=-@%#$&^*+=`~]+)$' },
8
+ // search: { type: 'string', pattern: '^([А-Яа-яҐґЄєІіЇї\\d\\w\\s\\/\\[\\]\\(\\)\\{\\}\\|,.!?;:—_=-@%#$&^*+=`~]+)$' },
9
+ order: { type: 'string', pattern: '^([\\d\\w_.-]+)$' },
10
+ desc: { type: 'string', pattern: '^(\\d+)$' },
11
+ state: { type: 'string', pattern: '^([\\d\\w._-]+)$' },
12
+ custom: { type: 'string', pattern: '^([\\d\\w._-]+)$' },
13
+ bbox: { type: 'string', pattern: '^([\\d\\s,.-]+)$' },
14
+ polyline: { type: 'string', pattern: '^([\\d\\w|@{}~_`]+)$' },
15
+ // key: { type: 'string', pattern: '^([\\d\\w_]+)$' },
16
+ sql: { type: 'string', pattern: '^(\\d)$' },
17
+ },
18
+ params: {
19
+ id: { type: 'string', pattern: '^([\\d\\w_.-]+)$' },
20
+ table: { type: 'string', pattern: '^([\\d\\w_.-]+)$' },
21
+ },
31
22
  },
32
23
  };
33
24
 
@@ -85,7 +76,7 @@ const suggestSchema = {
85
76
  count: { type: 'string', pattern: '^(\\d)$' },
86
77
  },
87
78
  params: {
88
- // data: { type: 'string', pattern: '^([\\d\\w]+)$' },
79
+ // data: { type: 'string', pattern: '^([\\d\\w]+)$' },
89
80
  },
90
81
  },
91
82
  };
@@ -111,25 +102,25 @@ const filterSchema = {
111
102
  const cardTabDataSchema = {
112
103
  type: 'object',
113
104
  properties: {
114
- querystring: {
115
- sql: { type: 'string', pattern: '^(\\d)$' }
116
- },
117
- params: {
118
- token: { type: 'string', pattern: '^([\\d\\w]+)$' },
119
- },
105
+ querystring: {
106
+ sql: { type: 'string', pattern: '^(\\d)$' },
107
+ },
108
+ params: {
109
+ token: { type: 'string', pattern: '^([\\d\\w]+)$' },
110
+ },
120
111
  },
121
112
  };
122
113
 
123
114
  const tableDataIdSchema = {
124
115
  type: 'object',
125
116
  properties: {
126
- params: {
127
- id: { type: 'string', pattern: '^([\\d\\w_.-]+)$' },
128
- name: { type: 'string', pattern: '^([\\d\\w._-]+)$' },
129
- },
117
+ params: {
118
+ id: { type: 'string', pattern: '^([\\d\\w_.-]+)$' },
119
+ name: { type: 'string', pattern: '^([\\d\\w._-]+)$' },
120
+ },
130
121
  },
131
122
  };
132
123
 
133
124
  export {
134
- tableDataSchema, tableDataIdSchema, tableSchema, searchSchema, suggestSchema, formSchema, filterSchema, cardTabDataSchema, tableFilterSchema,
125
+ tableDataSchema, tableDataIdSchema, tableSchema, searchSchema, suggestSchema, formSchema, filterSchema, cardTabDataSchema,
135
126
  };
@@ -1,16 +0,0 @@
1
- import { getFilter, pgClients } from '../../../../utils.js';
2
-
3
- export default async function tableFilter(req) {
4
- const {
5
- pg = pgClients.client, params = {}, query = {}, user = {},
6
- } = req;
7
-
8
- const {
9
- filter, custom, state, search,
10
- } = query;
11
-
12
- const result = await getFilter({
13
- table: params.table, pg, filter, custom, state, search, user,
14
- });
15
- return result;
16
- }