@opengis/fastify-table 1.4.50 → 1.4.52
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/config.js +1 -0
- package/index.js +1 -0
- package/package.json +1 -1
- package/server/helpers/format/formatNum.js +59 -59
- package/server/helpers/format/formatNumber.js +1 -0
- package/server/helpers/format/formatUnit.js +4 -2
- package/server/helpers/format/num_format.js +2 -0
- package/server/helpers/funcs/_math.js +4 -4
- package/server/helpers/funcs/contentList.js +6 -10
- package/server/helpers/funcs/ifCond.js +34 -31
- package/server/helpers/funcs/ifCondAnd.js +21 -4
- package/server/helpers/funcs/ifCondOr.js +21 -4
- package/server/helpers/funcs/json.js +1 -1
- package/server/helpers/funcs/round.js +5 -4
- package/server/helpers/funcs/select.js +6 -6
- package/server/helpers/index.js +3 -2
- package/server/helpers/list/tableList.js +2 -0
- package/server/helpers/list/utils/buttonDel.js +2 -2
- package/server/helpers/list/utils/buttonEdit.js +2 -2
- package/server/helpers/string/coalesce.js +13 -5
- package/server/helpers/utils/paddingNumber.js +3 -2
- package/server/plugins/crud/funcs/validateData.js +4 -2
- package/server/plugins/grpc/grpc.js +2 -0
- package/server/plugins/grpc/office2pdf.js +3 -1
- package/server/plugins/md/funcs/formatMdoc.js +4 -3
- package/server/plugins/migration/exec.migrations.js +0 -1
- package/server/plugins/migration/exec.sql.js +1 -0
- package/server/plugins/policy/index.js +2 -3
- package/server/plugins/policy/sqlInjection.js +1 -0
- package/server/plugins/policy/xssInjection.js +1 -0
- package/server/plugins/table/funcs/getFilterSQL/index.js +2 -2
- package/server/plugins/table/funcs/getFilterSQL/util/getRangeQuery.js +5 -4
- package/server/plugins/table/funcs/getSelect.js +1 -1
- package/server/plugins/util/funcs/flattenObject.js +2 -2
- package/server/plugins/util/funcs/unflattenObject.js +4 -2
- package/server/routes/crud/controllers/update.js +5 -5
- package/server/routes/file/controllers/resize.js +1 -0
- package/server/routes/logger/controllers/logger.test.api.js +1 -0
- package/server/routes/table/controllers/filter.js +3 -3
- package/server/routes/table/functions/getData.js +8 -6
- package/server/plugins/migration/get.caller.dir.js +0 -26
package/config.js
CHANGED
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -89,67 +89,67 @@ const mapNumbers = {
|
|
|
89
89
|
};
|
|
90
90
|
const mapOrders = {
|
|
91
91
|
ua: [
|
|
92
|
-
{
|
|
93
|
-
{
|
|
94
|
-
{
|
|
95
|
-
{
|
|
96
|
-
{
|
|
92
|
+
{ Gender: true, arrStates: ['', '', ''] },
|
|
93
|
+
{ Gender: true, arrStates: ['тисяча', 'тисячі', 'тисяч'] },
|
|
94
|
+
{ Gender: false, arrStates: ['мільйон', 'мільйона', 'мільйонів'] },
|
|
95
|
+
{ Gender: false, arrStates: ['мільярд', 'мільярда', 'мільярдів'] },
|
|
96
|
+
{ Gender: false, arrStates: ['триліон', 'триліона', 'триліонів'] },
|
|
97
97
|
{
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
Gender: true,
|
|
99
|
+
arrStates: {
|
|
100
100
|
uah: ['грн.', 'грн.', 'грн.'],
|
|
101
101
|
rur: ['руб.', 'руб.', 'руб.'],
|
|
102
102
|
},
|
|
103
|
-
|
|
103
|
+
bAddZeroWord: true,
|
|
104
104
|
},
|
|
105
105
|
{
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
106
|
+
Gender: true,
|
|
107
|
+
arrStates: ['ціла', 'цілих', 'цілих'],
|
|
108
|
+
bAddZeroWord: true,
|
|
109
109
|
},
|
|
110
|
-
{
|
|
110
|
+
{ Gender: true, arrStates: ['', '', ''], bAddZeroWord: true },
|
|
111
111
|
{
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
112
|
+
Gender: true,
|
|
113
|
+
arrStates: ['дол.', 'дол.', 'дол.'],
|
|
114
|
+
bAddZeroWord: true,
|
|
115
115
|
},
|
|
116
116
|
{
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
117
|
+
Gender: true,
|
|
118
|
+
arrStates: ['грн.', 'грн.', 'грн.'],
|
|
119
|
+
bAddZeroWord: true,
|
|
120
120
|
},
|
|
121
121
|
],
|
|
122
122
|
ru: [
|
|
123
|
-
{
|
|
124
|
-
{
|
|
125
|
-
{
|
|
126
|
-
{
|
|
127
|
-
{
|
|
123
|
+
{ Gender: true, arrStates: ['', '', ''] },
|
|
124
|
+
{ Gender: true, arrStates: ['тысяча', 'тысячи', 'тысяч'] },
|
|
125
|
+
{ Gender: false, arrStates: ['миллион', 'миллиона', 'миллионов'] },
|
|
126
|
+
{ Gender: false, arrStates: ['миллиард', 'миллиарда', 'миллиардов'] },
|
|
127
|
+
{ Gender: false, arrStates: ['триллион', 'триллиона', 'триллионов'] },
|
|
128
128
|
{
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
Gender: true,
|
|
130
|
+
arrStates: {
|
|
131
131
|
uah: ['грн.', 'грн.', 'грн.'],
|
|
132
132
|
rur: ['руб.', 'руб.', 'руб.'],
|
|
133
133
|
usd: ['дол.', 'дол.', 'дол.'],
|
|
134
134
|
},
|
|
135
|
-
|
|
135
|
+
bAddZeroWord: true,
|
|
136
136
|
},
|
|
137
137
|
{
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
138
|
+
Gender: true,
|
|
139
|
+
arrStates: ['целых', 'целых', 'целых'],
|
|
140
|
+
bAddZeroWord: true,
|
|
141
141
|
},
|
|
142
|
-
{
|
|
142
|
+
{ Gender: true, arrStates: ['', '', ''], bAddZeroWord: true },
|
|
143
143
|
{
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
144
|
+
Gender: true,
|
|
145
|
+
arrStates: ['дол.', 'дол.', 'дол.'],
|
|
146
|
+
bAddZeroWord: true,
|
|
147
147
|
},
|
|
148
148
|
],
|
|
149
149
|
};
|
|
150
150
|
const objCur = {
|
|
151
|
-
|
|
152
|
-
|
|
151
|
+
Gender: false,
|
|
152
|
+
arrStates: {
|
|
153
153
|
uah: ['грн.', 'грн.', 'грн.'],
|
|
154
154
|
rur: ['руб.', 'руб.', 'руб.'],
|
|
155
155
|
usd: ['дол.', 'дол.', 'дол.'],
|
|
@@ -157,15 +157,15 @@ const objCur = {
|
|
|
157
157
|
},
|
|
158
158
|
};
|
|
159
159
|
const objCoin = {
|
|
160
|
-
|
|
161
|
-
|
|
160
|
+
Gender: false,
|
|
161
|
+
arrStates: {
|
|
162
162
|
uah: 'коп.',
|
|
163
163
|
rur: 'коп.',
|
|
164
164
|
usd: 'цен.',
|
|
165
165
|
num: { ru: 'сот.', ua: 'сот.', en: 'hund.' },
|
|
166
166
|
},
|
|
167
167
|
};
|
|
168
|
-
|
|
168
|
+
// функции которые отвечают за форматирование
|
|
169
169
|
/**
|
|
170
170
|
* Formatting from number to string
|
|
171
171
|
*
|
|
@@ -197,17 +197,17 @@ function value(dVal, bGender, lang) {
|
|
|
197
197
|
* from0To999(arrRet, 404,
|
|
198
198
|
* oObjDesc:
|
|
199
199
|
* {
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
200
|
+
* Gender: true,
|
|
201
|
+
* bAddZeroWord: undefined,
|
|
202
|
+
* arrStates: ['','',''],
|
|
203
203
|
* },
|
|
204
204
|
* lang: 'ru'
|
|
205
205
|
* })
|
|
206
206
|
* @param {Array} arrRet
|
|
207
207
|
* @param {Number} fValue
|
|
208
|
-
* @param {Object} [oObjDesc.
|
|
209
|
-
* @param {Object} [oObjDesc.
|
|
210
|
-
* @param {Object} [oObjDesc.
|
|
208
|
+
* @param {Object} [oObjDesc.Gender]
|
|
209
|
+
* @param {Object} [oObjDesc.bAddZeroWord]
|
|
210
|
+
* @param {Object} [oObjDesc.arrStates]
|
|
211
211
|
* @param oObjDesc
|
|
212
212
|
* @param {String} lang
|
|
213
213
|
*/
|
|
@@ -216,32 +216,32 @@ function from0To999(arrRet, fValue, oObjDesc, lang) {
|
|
|
216
216
|
let nCurrState = 2;
|
|
217
217
|
if (Math.floor(fValueNew / 100) > 0) {
|
|
218
218
|
const fCurr = Math.floor(fValueNew / 100) * 100;
|
|
219
|
-
arrRet.push(value(fCurr, oObjDesc.
|
|
219
|
+
arrRet.push(value(fCurr, oObjDesc.Gender, lang));
|
|
220
220
|
nCurrState = mapNumbers[lang][fCurr][0];
|
|
221
221
|
fValueNew -= fCurr;
|
|
222
222
|
}
|
|
223
223
|
if (fValueNew === 0) {
|
|
224
|
-
arrRet.push(value(fValueNew, oObjDesc.
|
|
224
|
+
arrRet.push(value(fValueNew, oObjDesc.Gender, lang));
|
|
225
225
|
nCurrState = mapNumbers[lang][fValueNew][0];
|
|
226
226
|
}
|
|
227
|
-
|
|
228
|
-
if (Math.floor(fValueNew) > 0 || oObjDesc.
|
|
229
|
-
arrRet.push(value(fValueNew, oObjDesc.
|
|
227
|
+
else if (fValueNew < 20) {
|
|
228
|
+
if (Math.floor(fValueNew) > 0 || oObjDesc.bAddZeroWord) {
|
|
229
|
+
arrRet.push(value(fValueNew, oObjDesc.Gender, lang));
|
|
230
230
|
nCurrState = mapNumbers[lang][fValueNew][0];
|
|
231
231
|
}
|
|
232
232
|
}
|
|
233
|
-
|
|
233
|
+
else {
|
|
234
234
|
const fCurr = Math.floor(fValueNew / 10) * 10;
|
|
235
|
-
arrRet.push(value(fCurr, oObjDesc.
|
|
235
|
+
arrRet.push(value(fCurr, oObjDesc.Gender, lang));
|
|
236
236
|
nCurrState = mapNumbers[lang][fCurr][0];
|
|
237
237
|
fValueNew -= fCurr;
|
|
238
238
|
|
|
239
239
|
if (Math.floor(fValueNew) > 0) {
|
|
240
|
-
arrRet.push(value(fValueNew, oObjDesc.
|
|
240
|
+
arrRet.push(value(fValueNew, oObjDesc.Gender, lang));
|
|
241
241
|
nCurrState = mapNumbers[lang][fValueNew][0];
|
|
242
242
|
}
|
|
243
243
|
}
|
|
244
|
-
arrRet.push(oObjDesc.
|
|
244
|
+
arrRet.push(oObjDesc.arrStates[nCurrState]);
|
|
245
245
|
}
|
|
246
246
|
|
|
247
247
|
/**
|
|
@@ -289,11 +289,11 @@ function floatToSamplesInWordsUkr(fAmount, resultStr, exp, lang, currency) {
|
|
|
289
289
|
/%d/,
|
|
290
290
|
Math.floor(parseInt(fAmount, 10) + 0.005),
|
|
291
291
|
);
|
|
292
|
-
if (currency !== 'num' && objCur.
|
|
293
|
-
|
|
292
|
+
if (currency !== 'num' && objCur.arrStates[currency]) { resultStrNew = resultStrNew.replace(/%curr/, objCur.arrStates[currency][0]); }
|
|
293
|
+
else {
|
|
294
294
|
resultStrNew = resultStrNew.replace(
|
|
295
295
|
/%curr/,
|
|
296
|
-
objCur.
|
|
296
|
+
objCur.arrStates[lang === 'ru' ? 'rur' : lang][0],
|
|
297
297
|
);
|
|
298
298
|
}
|
|
299
299
|
|
|
@@ -309,11 +309,11 @@ function floatToSamplesInWordsUkr(fAmount, resultStr, exp, lang, currency) {
|
|
|
309
309
|
|
|
310
310
|
resultStrNew = resultStrNew.replace(/%f/, fDec);
|
|
311
311
|
|
|
312
|
-
if (currency !== 'num' && objCur.
|
|
313
|
-
|
|
312
|
+
if (currency !== 'num' && objCur.arrStates[currency]) { resultStrNew = resultStrNew.replace(/%coin/, objCoin.arrStates[currency]); }
|
|
313
|
+
else {
|
|
314
314
|
resultStrNew = resultStrNew.replace(
|
|
315
315
|
/%coin/,
|
|
316
|
-
objCoin.
|
|
316
|
+
objCoin.arrStates[lang === 'ru' ? 'rur' : lang],
|
|
317
317
|
);
|
|
318
318
|
}
|
|
319
319
|
return resultStrNew;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/* eslint-disable no-restricted-globals */
|
|
2
|
+
/* eslint-disable no-param-reassign */
|
|
1
3
|
/**
|
|
2
4
|
* Повертає розмір файлу на диску у встановлених одиницях вимірювання об'єму файлу.
|
|
3
5
|
*
|
|
@@ -17,13 +19,13 @@ export default function formatUnit(data, options) {
|
|
|
17
19
|
data = parseFloat(data);
|
|
18
20
|
if (isNaN(data)) return data;
|
|
19
21
|
|
|
20
|
-
const
|
|
22
|
+
const UNIT = {
|
|
21
23
|
B: {
|
|
22
24
|
4: 'TB', 3: 'GB', 2: 'MB', 1: 'KB', 0: 'B',
|
|
23
25
|
},
|
|
24
26
|
};
|
|
25
27
|
|
|
26
|
-
const unit =
|
|
28
|
+
const unit = UNIT[options.hash.unit] || UNIT.B;
|
|
27
29
|
const number = options.hash.number || 0;
|
|
28
30
|
|
|
29
31
|
for (let i = 4; i >= 0; i -= 1) {
|
|
@@ -15,12 +15,12 @@
|
|
|
15
15
|
* @param {Object} operator Оператор для дії з числами
|
|
16
16
|
* @param {Object} arg1 Перше число для дії
|
|
17
17
|
* @param {Object} arg2 Друге число для дії
|
|
18
|
-
* @param {Array} args[0]
|
|
19
|
-
* @param {Array} args[1]
|
|
20
|
-
* @param {Array} args[2]
|
|
18
|
+
* @param {Array} args[0] Перше число для дії
|
|
19
|
+
* @param {Array} args[1] Оператор для дії з числами
|
|
20
|
+
* @param {Array} args[2] Друге число для дії
|
|
21
21
|
* @returns {String} Returns HTML
|
|
22
22
|
*/
|
|
23
|
-
export default function
|
|
23
|
+
export default function math(...args) {
|
|
24
24
|
const options = args.pop();
|
|
25
25
|
const opt = options.hash;
|
|
26
26
|
|
|
@@ -25,9 +25,9 @@ const maxLimit = 100;
|
|
|
25
25
|
* @returns {String} Returns HTML
|
|
26
26
|
*/
|
|
27
27
|
export default async function contentList(options) {
|
|
28
|
-
const {
|
|
29
|
-
|
|
30
|
-
} = options.hash;
|
|
28
|
+
const {
|
|
29
|
+
table, limit, query, order, sql, debug,
|
|
30
|
+
} = options.hash;
|
|
31
31
|
if (!table) { return 'Table undefined'; }
|
|
32
32
|
|
|
33
33
|
try {
|
|
@@ -35,11 +35,7 @@ export default async function contentList(options) {
|
|
|
35
35
|
|
|
36
36
|
const hasBrackets = table.trim().startsWith('(') && table.trim().endsWith(')');
|
|
37
37
|
|
|
38
|
-
const
|
|
39
|
-
const _limit = limit !== undefined && limit !== null ? Math.min(maxLimit, +limit) : 15;
|
|
40
|
-
const _order = order ? `order by ${order}` : '';
|
|
41
|
-
|
|
42
|
-
const SQL = `select *,${pg.pk[table] || '1'}::text from ${hasBrackets ? `${table} t` : table} ${where} ${_order} limit ${_limit}`;
|
|
38
|
+
const SQL = `select *,${pg.pk[table] || '1'}::text from ${hasBrackets ? `${table} t` : table} where ${query || '1=1'} ${order ? `order by ${order}` : ''} limit ${limit !== undefined && limit !== null ? Math.min(maxLimit, +limit) : 15}`;
|
|
43
39
|
const compiledSQL = Handlebars.compile(SQL)(options.data.root);
|
|
44
40
|
|
|
45
41
|
if (sql) {
|
|
@@ -54,8 +50,8 @@ export default async function contentList(options) {
|
|
|
54
50
|
}
|
|
55
51
|
|
|
56
52
|
return options.fn(data);
|
|
57
|
-
}
|
|
58
|
-
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
59
55
|
return `Сталася помилка, зверніться до відділу підтримки.<!-- err: ${err.toString()} -->`;
|
|
60
56
|
}
|
|
61
57
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable no-param-reassign */
|
|
1
2
|
/**
|
|
2
3
|
* Перетинає два масиви
|
|
3
4
|
*
|
|
@@ -32,75 +33,77 @@ function intersect(a, b) {
|
|
|
32
33
|
* @example
|
|
33
34
|
* {{#ifCond 'debug' 'in' @root.setting.core.setting}}Умова виконана{{^}}Не виконана умова{{/ifCond}}
|
|
34
35
|
* @param {Array} args Параметри для значень і умов
|
|
35
|
-
* @param {Array} args[0]
|
|
36
|
-
* @param {Array} args[1]
|
|
37
|
-
* @param {Array} args[2]
|
|
36
|
+
* @param {Array} args[0] Перше значення
|
|
37
|
+
* @param {Array} args[1] Оператор
|
|
38
|
+
* @param {Array} args[2] Друге значення
|
|
38
39
|
* @returns {String} Returns HTML
|
|
39
40
|
*/
|
|
40
41
|
export default function ifCond(v1, operator, v2, options) {
|
|
41
|
-
const
|
|
42
|
+
const obj = this;
|
|
42
43
|
|
|
43
44
|
const isEmpty = (val) => val === null || val === undefined || (Array.isArray(val) && val.length === 0) || val === '';
|
|
44
45
|
|
|
45
46
|
switch (operator) {
|
|
46
47
|
case '==':
|
|
47
|
-
|
|
48
|
+
// eslint-disable-next-line eqeqeq
|
|
49
|
+
return (v1 == v2) ? options.fn(obj) : options.inverse(obj);
|
|
48
50
|
case '!=':
|
|
49
|
-
|
|
51
|
+
// eslint-disable-next-line eqeqeq
|
|
52
|
+
return (v1 != v2) ? options.fn(obj) : options.inverse(obj);
|
|
50
53
|
case '===':
|
|
51
|
-
return (v1 === v2) ? options.fn(
|
|
54
|
+
return (v1 === v2) ? options.fn(obj) : options.inverse(obj);
|
|
52
55
|
case '!==':
|
|
53
|
-
return (v1 !== v2) ? options.fn(
|
|
56
|
+
return (v1 !== v2) ? options.fn(obj) : options.inverse(obj);
|
|
54
57
|
case '&&':
|
|
55
|
-
return (v1 && v2) ? options.fn(
|
|
58
|
+
return (v1 && v2) ? options.fn(obj) : options.inverse(obj);
|
|
56
59
|
case '||':
|
|
57
|
-
return (v1 || v2) ? options.fn(
|
|
60
|
+
return (v1 || v2) ? options.fn(obj) : options.inverse(obj);
|
|
58
61
|
case '<':
|
|
59
|
-
return (v1 < v2) ? options.fn(
|
|
62
|
+
return (v1 < v2) ? options.fn(obj) : options.inverse(obj);
|
|
60
63
|
case '<=':
|
|
61
|
-
return (v1 <= v2) ? options.fn(
|
|
64
|
+
return (v1 <= v2) ? options.fn(obj) : options.inverse(obj);
|
|
62
65
|
case '>':
|
|
63
|
-
return (v1 > v2) ? options.fn(
|
|
66
|
+
return (v1 > v2) ? options.fn(obj) : options.inverse(obj);
|
|
64
67
|
case '>=':
|
|
65
|
-
return (v1 >= v2) ? options.fn(
|
|
68
|
+
return (v1 >= v2) ? options.fn(obj) : options.inverse(obj);
|
|
66
69
|
case '&':
|
|
67
70
|
return (!isEmpty(v1) && !isEmpty(v2) && intersect(v1, v2).length !== 0)
|
|
68
|
-
? options.fn(
|
|
69
|
-
: options.inverse(
|
|
71
|
+
? options.fn(obj)
|
|
72
|
+
: options.inverse(obj);
|
|
70
73
|
case '!~':
|
|
71
74
|
return (v1 || '').indexOf(v2) === -1
|
|
72
|
-
? options.fn(
|
|
73
|
-
: options.inverse(
|
|
75
|
+
? options.fn(obj)
|
|
76
|
+
: options.inverse(obj);
|
|
74
77
|
case '~':
|
|
75
78
|
return (v1 || '').indexOf(v2) !== -1
|
|
76
|
-
? options.fn(
|
|
77
|
-
: options.inverse(
|
|
79
|
+
? options.fn(obj)
|
|
80
|
+
: options.inverse(obj);
|
|
78
81
|
case 'period':
|
|
79
82
|
return (!isEmpty(v1) && !isEmpty(v2) && new Date(v1) < new Date() && new Date(v2) > new Date())
|
|
80
|
-
? options.fn(
|
|
81
|
-
: options.inverse(
|
|
83
|
+
? options.fn(obj)
|
|
84
|
+
: options.inverse(obj);
|
|
82
85
|
case 'in': {
|
|
83
86
|
if (typeof v2 === 'string') v2 = v2.split(',').map(item => item.trim());
|
|
84
|
-
if (isEmpty(v1) || isEmpty(v2)) return options.inverse(
|
|
87
|
+
if (isEmpty(v1) || isEmpty(v2)) return options.inverse(obj);
|
|
85
88
|
|
|
86
89
|
if (Array.isArray(v1)) {
|
|
87
90
|
return v1.some((value) => v2.includes(value.toString()))
|
|
88
|
-
? options.fn(
|
|
89
|
-
: options.inverse(
|
|
91
|
+
? options.fn(obj)
|
|
92
|
+
: options.inverse(obj);
|
|
90
93
|
}
|
|
91
94
|
return v2.includes(v1.toString())
|
|
92
|
-
? options.fn(
|
|
93
|
-
: options.inverse(
|
|
95
|
+
? options.fn(obj)
|
|
96
|
+
: options.inverse(obj);
|
|
94
97
|
}
|
|
95
98
|
case 'not in': {
|
|
96
99
|
if (typeof v2 === 'string') v2 = v2.split(',').map(item => item.trim());
|
|
97
|
-
if (isEmpty(v1) || isEmpty(v2)) return options.inverse(
|
|
100
|
+
if (isEmpty(v1) || isEmpty(v2)) return options.inverse(obj);
|
|
98
101
|
|
|
99
102
|
return !v2.includes(v1.toString())
|
|
100
|
-
? options.fn(
|
|
101
|
-
: options.inverse(
|
|
103
|
+
? options.fn(obj)
|
|
104
|
+
: options.inverse(obj);
|
|
102
105
|
}
|
|
103
106
|
default:
|
|
104
|
-
return options.inverse(
|
|
107
|
+
return options.inverse(obj);
|
|
105
108
|
}
|
|
106
109
|
}
|
|
@@ -1,8 +1,23 @@
|
|
|
1
|
+
/* eslint-disable prefer-rest-params */
|
|
1
2
|
function intersect(a, b) {
|
|
2
|
-
|
|
3
|
-
|
|
3
|
+
let aN = [];
|
|
4
|
+
let bN = [];
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
if (Array.isArray(a)) {
|
|
7
|
+
aN = a;
|
|
8
|
+
}
|
|
9
|
+
else if (typeof a === 'string') {
|
|
10
|
+
aN = a.split(',');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (Array.isArray(b)) {
|
|
14
|
+
bN = b;
|
|
15
|
+
}
|
|
16
|
+
else if (typeof b === 'string') {
|
|
17
|
+
bN = b.split(',');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return aN.filter(e => bN.includes(e));
|
|
6
21
|
}
|
|
7
22
|
|
|
8
23
|
/**
|
|
@@ -31,9 +46,11 @@ export default function ifCondAnd() {
|
|
|
31
46
|
|
|
32
47
|
switch (operator) {
|
|
33
48
|
case '==':
|
|
49
|
+
// eslint-disable-next-line eqeqeq
|
|
34
50
|
conditions.push(v1 == v2);
|
|
35
51
|
break;
|
|
36
52
|
case '!=':
|
|
53
|
+
// eslint-disable-next-line eqeqeq
|
|
37
54
|
conditions.push(v1 != v2);
|
|
38
55
|
break;
|
|
39
56
|
case '===':
|
|
@@ -77,7 +94,7 @@ export default function ifCondAnd() {
|
|
|
77
94
|
if (Array.isArray(v1)) {
|
|
78
95
|
conditions.push(v1.some((value) => v2.includes(value.toString())));
|
|
79
96
|
}
|
|
80
|
-
|
|
97
|
+
else {
|
|
81
98
|
conditions.push(v2.includes(v1.toString()));
|
|
82
99
|
}
|
|
83
100
|
break;
|
|
@@ -1,8 +1,23 @@
|
|
|
1
|
+
/* eslint-disable prefer-rest-params */
|
|
1
2
|
function intersect(a, b) {
|
|
2
|
-
|
|
3
|
-
|
|
3
|
+
let aN = [];
|
|
4
|
+
let bN = [];
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
if (Array.isArray(a)) {
|
|
7
|
+
aN = a;
|
|
8
|
+
}
|
|
9
|
+
else if (typeof a === 'string') {
|
|
10
|
+
aN = a.split(',');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (Array.isArray(b)) {
|
|
14
|
+
bN = b;
|
|
15
|
+
}
|
|
16
|
+
else if (typeof b === 'string') {
|
|
17
|
+
bN = b.split(',');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return aN.filter(e => bN.includes(e));
|
|
6
21
|
}
|
|
7
22
|
|
|
8
23
|
/**
|
|
@@ -32,9 +47,11 @@ export default function ifCondOr() {
|
|
|
32
47
|
|
|
33
48
|
switch (operator) {
|
|
34
49
|
case '==':
|
|
50
|
+
// eslint-disable-next-line eqeqeq
|
|
35
51
|
conditions.push(v1 == v2);
|
|
36
52
|
break;
|
|
37
53
|
case '!=':
|
|
54
|
+
// eslint-disable-next-line eqeqeq
|
|
38
55
|
conditions.push(v1 != v2);
|
|
39
56
|
break;
|
|
40
57
|
case '===':
|
|
@@ -78,7 +95,7 @@ export default function ifCondOr() {
|
|
|
78
95
|
if (Array.isArray(v1)) {
|
|
79
96
|
conditions.push(v1.some((value) => v2.includes(value.toString())));
|
|
80
97
|
}
|
|
81
|
-
|
|
98
|
+
else {
|
|
82
99
|
conditions.push(v2.includes(v1.toString()));
|
|
83
100
|
}
|
|
84
101
|
break;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable no-restricted-globals */
|
|
1
2
|
/**
|
|
2
3
|
* Округлення числа до певної точності
|
|
3
4
|
*
|
|
@@ -15,14 +16,14 @@
|
|
|
15
16
|
* @returns {String} Returns HTML
|
|
16
17
|
*/
|
|
17
18
|
export default function round(data, options) {
|
|
18
|
-
const
|
|
19
|
-
if (isNaN(
|
|
19
|
+
const floatData = parseFloat(data);
|
|
20
|
+
if (isNaN(floatData)) return '';
|
|
20
21
|
|
|
21
22
|
const dec = options.hash.dec ? parseInt(options.hash.dec, 10) : 0;
|
|
22
23
|
|
|
23
24
|
if (options.hash.floor) {
|
|
24
|
-
return Math.floor(
|
|
25
|
+
return Math.floor(floatData).toFixed(dec);
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
return
|
|
28
|
+
return floatData.toFixed(dec);
|
|
28
29
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import getPG from '../../plugins/pg/funcs/getPG.js';
|
|
2
|
-
import getSelect from '../../plugins/table/funcs/getSelect.js';
|
|
2
|
+
import getSelect from '../../plugins/table/funcs/getSelect.js';
|
|
3
3
|
|
|
4
4
|
const pg = getPG();
|
|
5
5
|
|
|
@@ -19,7 +19,7 @@ export default async function select(ids, options) {
|
|
|
19
19
|
if (!classifier) return `Не знайдено класифікатор ${data}`;
|
|
20
20
|
|
|
21
21
|
const arr = classifier.arr || [];
|
|
22
|
-
if (classifier.sql && typeof classifier.sql === 'string') {
|
|
22
|
+
if (classifier.sql && typeof classifier.sql === 'string') {
|
|
23
23
|
const metaQuery = `SELECT * FROM (${classifier.sql})q LIMIT 0`;
|
|
24
24
|
const meta = await pg.query(metaQuery);
|
|
25
25
|
const idColumn = meta.fields[0].name;
|
|
@@ -29,18 +29,18 @@ export default async function select(ids, options) {
|
|
|
29
29
|
const values = [idsArray.map(id => String(id))];
|
|
30
30
|
|
|
31
31
|
const { rows } = await pg.query(q, values);
|
|
32
|
-
Object.assign(arr, rows);
|
|
32
|
+
Object.assign(arr, rows);
|
|
33
33
|
}
|
|
34
34
|
if (!arr.length) return idsArray;
|
|
35
35
|
|
|
36
36
|
const results = idsArray.map(id => {
|
|
37
|
-
const result = arr.find(el => String(el.id)
|
|
37
|
+
const result = arr.find(el => String(el.id) === String(id));
|
|
38
38
|
return result ? result.text : '';
|
|
39
39
|
});
|
|
40
40
|
|
|
41
41
|
return results.filter(Boolean).join(', ');
|
|
42
|
-
}
|
|
43
|
-
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
44
|
return `Сталася помилка.<!-- err: ${err.toString()} -->`;
|
|
45
45
|
}
|
|
46
46
|
}
|
package/server/helpers/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable prefer-rest-params */
|
|
1
2
|
import handlebarsSync from 'handlebars';
|
|
2
3
|
import promisedHandlebars from 'promised-handlebars';
|
|
3
4
|
|
|
@@ -54,14 +55,14 @@ function getKeysRecursive(obj, prefix = '') {
|
|
|
54
55
|
const fullKey = prefix ? `${prefix}.${curr}` : curr;
|
|
55
56
|
acc.push(curr);
|
|
56
57
|
if (obj1[curr] && typeof obj1[curr] === 'object' && curr !== 'coordinates') {
|
|
57
|
-
acc
|
|
58
|
+
acc.push(...(getKeysRecursive(obj1[curr], fullKey)));
|
|
58
59
|
}
|
|
59
60
|
return acc;
|
|
60
61
|
}, []);
|
|
61
62
|
}
|
|
62
63
|
|
|
63
64
|
// avoid unhandled exception if helper not registered
|
|
64
|
-
handlebars.registerHelper('helperMissing', function () {
|
|
65
|
+
handlebars.registerHelper('helperMissing', function hm() {
|
|
65
66
|
const options = arguments[arguments.length - 1];
|
|
66
67
|
const args = Array.prototype.slice.call(arguments, 0, arguments.length - 1);
|
|
67
68
|
const keys = getKeysRecursive(options.data?.root);
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
// }
|
|
5
5
|
|
|
6
6
|
const newColor = 'red';
|
|
7
|
-
export default function button(token
|
|
7
|
+
export default function button(token) {
|
|
8
8
|
return `<button onclick="window.v3plugin.$api({ api: '/api/table/${token}', method:'delete',confirm: { title:'Підтвердити операцію', text: 'Ви впевнені що хочете вилучити запис?', cancel: 'Скасувати', confirm : 'Виконати'} })"
|
|
9
9
|
class="group px-2 py-1 inline-flex border-solid justify-center items-center gap-2 rounded-md font-semibold focus:outline-none text-sm transition-all border border-transparent hover:text-white ring-offset-white bg-${newColor}-100 text-${newColor}-100 hover:bg-${newColor}-500 focus:ring-${newColor}-500">
|
|
10
10
|
<svg class="group-hover:fill-white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="13" height="13" fill="#ef4444"><path d="M135.2 17.7L128 32 32 32C14.3 32 0 46.3 0 64S14.3 96 32 96l384 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-96 0-7.2-14.3C307.4 6.8 296.3 0 284.2 0L163.8 0c-12.1 0-23.2 6.8-28.6 17.7zM416 128L32 128 53.2 467c1.6 25.3 22.6 45 47.9 45l245.8 0c25.3 0 46.3-19.7 47.9-45L416 128z"/></svg>
|
|
11
11
|
</button>`;
|
|
12
|
-
}
|
|
12
|
+
}
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
// }
|
|
5
5
|
|
|
6
6
|
const newColor = 'blue';
|
|
7
|
-
export default function button(token
|
|
7
|
+
export default function button(token) {
|
|
8
8
|
return `<button onclick="window.v3plugin.$form({ token: '${token}' })"
|
|
9
9
|
class="group px-2 py-1 inline-flex border-solid justify-center items-center gap-2 rounded-md font-semibold focus:outline-none text-sm transition-all border border-transparent hover:text-white ring-offset-white bg-${newColor}-100 text-${newColor}-100 hover:bg-${newColor}-500 focus:ring-${newColor}-500">
|
|
10
10
|
<svg class="group-hover:fill-white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="13" height="13" fill="#3b82f6"><path d="M471.6 21.7c-21.9-21.9-57.3-21.9-79.2 0L362.3 51.7l97.9 97.9 30.1-30.1c21.9-21.9 21.9-57.3 0-79.2L471.6 21.7zm-299.2 220c-6.1 6.1-10.8 13.6-13.5 21.9l-29.6 88.8c-2.9 8.6-.6 18.1 5.8 24.6s15.9 8.7 24.6 5.8l88.8-29.6c8.2-2.7 15.7-7.4 21.9-13.5L437.7 172.3 339.7 74.3 172.4 241.7zM96 64C43 64 0 107 0 160L0 416c0 53 43 96 96 96l256 0c53 0 96-43 96-96l0-96c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 96c0 17.7-14.3 32-32 32L96 448c-17.7 0-32-14.3-32-32l0-256c0-17.7 14.3-32 32-32l96 0c17.7 0 32-14.3 32-32s-14.3-32-32-32L96 64z"/></svg>
|
|
11
11
|
</button>`;
|
|
12
|
-
}
|
|
12
|
+
}
|
|
@@ -21,11 +21,19 @@
|
|
|
21
21
|
export default function coalesce(...args) {
|
|
22
22
|
const options = args.pop();
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
const value = args.find(arg => arg != null && arg !== '');
|
|
25
|
+
|
|
26
|
+
if (value !== undefined) {
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (options.fn) {
|
|
31
|
+
return options.fn(this);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (options.inverse) {
|
|
35
|
+
return options.inverse(this);
|
|
28
36
|
}
|
|
29
37
|
|
|
30
|
-
return
|
|
38
|
+
return '';
|
|
31
39
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
/* eslint-disable prefer-rest-params */
|
|
2
|
+
export default function paddingNumber(num) {
|
|
2
3
|
const padding = arguments.length === 3 ? arguments[1] : 6;
|
|
3
4
|
return num.toLocaleString('en', { minimumIntegerDigits: padding, useGrouping: false });
|
|
4
|
-
}
|
|
5
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import config from '../../../../config.js';
|
|
2
|
-
|
|
2
|
+
/* eslint-disable no-console */
|
|
3
|
+
// eslint-disable-next-line no-control-regex
|
|
3
4
|
const emailReg = /(?:[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-zA-Z0-9-]*[a-zA-Z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/g;
|
|
4
5
|
|
|
5
6
|
function checkField(key, val, options, idx, body) {
|
|
@@ -56,7 +57,8 @@ function checkBody({ body = {}, arr = [], idx }) {
|
|
|
56
57
|
acc.push(check);
|
|
57
58
|
return acc;
|
|
58
59
|
}, []);
|
|
59
|
-
|
|
60
|
+
// acc1.push(result);
|
|
61
|
+
acc1.push(...result);
|
|
60
62
|
return acc1;
|
|
61
63
|
}
|
|
62
64
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable no-promise-executor-return */
|
|
1
2
|
/* eslint-disable no-console */
|
|
2
3
|
|
|
3
4
|
import path from 'node:path';
|
|
@@ -108,6 +109,7 @@ const wrapGrpcCall = (methodName) => async (data) => new Promise((res, rej) => {
|
|
|
108
109
|
|
|
109
110
|
return res(response);
|
|
110
111
|
});
|
|
112
|
+
return null;
|
|
111
113
|
});
|
|
112
114
|
|
|
113
115
|
const grpcMethods = methodNames.reduce((acc, name) => {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable no-promise-executor-return */
|
|
1
2
|
/* eslint-disable no-console */
|
|
2
3
|
import path from 'node:path';
|
|
3
4
|
import { fileURLToPath } from 'url';
|
|
@@ -77,8 +78,9 @@ const officeToPdf = async (data) => new Promise((res, rej) => {
|
|
|
77
78
|
}
|
|
78
79
|
return rej(err);
|
|
79
80
|
}
|
|
80
|
-
res(data1);
|
|
81
|
+
return res(data1);
|
|
81
82
|
});
|
|
83
|
+
return null;
|
|
82
84
|
});
|
|
83
85
|
|
|
84
86
|
const getOffice = () => ({
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
/* eslint-disable no-param-reassign */
|
|
2
|
+
function handleData(data, curr, acc, titles, plain, splittype = 1) {
|
|
2
3
|
const titleStr = {
|
|
3
4
|
1: `${(titles?.[curr] || curr)}\n`, // for lists
|
|
4
5
|
2: `${(titles?.[curr] || curr)}: `, // one-liner
|
|
@@ -8,8 +9,8 @@ function handleData(data, curr, acc, titles = {}, plain, splittype = 1) {
|
|
|
8
9
|
if (Array.isArray(data[curr])) {
|
|
9
10
|
const str = `${plain ? '' : '\n\n### '}${titleStr}${data[curr].map(el => {
|
|
10
11
|
if (typeof el === 'object' && !Array.isArray(el)) {
|
|
11
|
-
const
|
|
12
|
-
return `\n - ${
|
|
12
|
+
const str1 = Object.keys(el).filter(item => item !== 'id').reduce((acc1, curr1) => handleData(el, curr1, acc1, {}, 1, 3), '');
|
|
13
|
+
return `\n - ${str1}`;
|
|
13
14
|
}
|
|
14
15
|
return `\n - ${el}`;
|
|
15
16
|
})}`;
|
|
@@ -5,7 +5,6 @@ import { readdirSync, existsSync } from 'node:fs';
|
|
|
5
5
|
import config from '../../../config.js';
|
|
6
6
|
import execSql from './exec.sql.js';
|
|
7
7
|
import pgClients from '../pg/pgClients.js';
|
|
8
|
-
// import getCallerDir from './get.caller.dir.js';
|
|
9
8
|
|
|
10
9
|
const time = Date.now();
|
|
11
10
|
const debug = config.debug || config.local;
|
|
@@ -3,9 +3,8 @@ import checkPolicy from './funcs/checkPolicy.js';
|
|
|
3
3
|
async function plugin(fastify) {
|
|
4
4
|
fastify.addHook('preParsing', async (request, reply) => {
|
|
5
5
|
const resp = checkPolicy(request, reply);
|
|
6
|
-
if (resp) {
|
|
7
|
-
|
|
8
|
-
}
|
|
6
|
+
if (resp) { return resp; }
|
|
7
|
+
return null;
|
|
9
8
|
});
|
|
10
9
|
}
|
|
11
10
|
|
|
@@ -49,7 +49,7 @@ export default async function getFilterSQL({
|
|
|
49
49
|
if (body?.table && !checkInline[body?.table] && body?.sql?.length) {
|
|
50
50
|
const filterSql = body.sql.filter(el => !el?.disabled && (el.inline ?? true));
|
|
51
51
|
const sqlTable = filterSql.map((el, i) => ` left join lateral (${el.sql}) ${el.name || `t${i}`} on 1=1 `)?.join('') || '';
|
|
52
|
-
const d = await Promise.all(filterSql.map((el, i) => pg.query(`select ${el.name || `t${i}`}.* from(select * from ${body.table})t ${sqlTable} limit 0`).then(
|
|
52
|
+
const d = await Promise.all(filterSql.map((el, i) => pg.query(`select ${el.name || `t${i}`}.* from(select * from ${body.table})t ${sqlTable} limit 0`).then(item => item.fields)));
|
|
53
53
|
d.forEach((el, i) => {
|
|
54
54
|
filterSql[i].inline = el.length === 1;
|
|
55
55
|
filterSql[i].fields = el.map(f => f.name);
|
|
@@ -97,7 +97,7 @@ export default async function getFilterSQL({
|
|
|
97
97
|
.concat(filterResponse?.list || [])
|
|
98
98
|
?.filter(el => el.id || el.name)
|
|
99
99
|
?.map(async (el) => {
|
|
100
|
-
el
|
|
100
|
+
Object.assign(el, { name: el.name || el.id });
|
|
101
101
|
|
|
102
102
|
if (el.name && extraColumns.find(item => item?.name === el?.name)) {
|
|
103
103
|
Object.assign(el, { extra: { table: extraDataTable, input: extraColumns.find(item => item?.name === el?.name)?.type } });
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable no-restricted-globals */
|
|
1
2
|
const dateTypeList = ['date', 'timestamp', 'timestamp without time zone', 'timestamp with time zone'];
|
|
2
3
|
const numberTypeList = ['float8', 'int4', 'int8', 'numeric', 'double precision', 'integer', 'bigint'];
|
|
3
4
|
|
|
@@ -136,14 +137,14 @@ export default function getRangeQuery(value, name, fieldType, filterType, sql, e
|
|
|
136
137
|
// default
|
|
137
138
|
if (max === 'max') {
|
|
138
139
|
return ['date', 'datepicker'].includes(filterType)
|
|
139
|
-
? `${name}
|
|
140
|
-
: `${name}
|
|
140
|
+
? `${name} >= '${min}'::date`
|
|
141
|
+
: `${name} >= ${min}`;
|
|
141
142
|
}
|
|
142
143
|
|
|
143
144
|
if (min === 'min') {
|
|
144
145
|
return ['date', 'datepicker'].includes(filterType)
|
|
145
|
-
? `${name}
|
|
146
|
-
: `${name}
|
|
146
|
+
? `${name} <= '${max}'::date`
|
|
147
|
+
: `${name} <= ${max}`;
|
|
147
148
|
}
|
|
148
149
|
|
|
149
150
|
if (['date', 'datepicker'].includes(filterType)) {
|
|
@@ -16,7 +16,7 @@ export default async function getSelect(name, pg = pgClients.client) {
|
|
|
16
16
|
const clsDataGIT = await getTemplate(['cls', 'select'], name);
|
|
17
17
|
const { type } = !clsDataGIT && pg.pk?.['admin.user_cls'] ? await pg.query('select type from admin.user_cls where parent is null and name=$1 union all select type from admin.cls where parent is null and name=$1 limit 1', [name]).then(el => el.rows?.[0] || {}) : {};
|
|
18
18
|
const q = !clsDataGIT && type && ['sql', 'json'].includes(type) ? sqls[type] : undefined;
|
|
19
|
-
const clsDataDB = q ? await pg.query(q, [name]).then(el => el.rows?.find(
|
|
19
|
+
const clsDataDB = q ? await pg.query(q, [name]).then(el => el.rows?.find(item => item?.data)?.data) : undefined;
|
|
20
20
|
const clsData = clsDataGIT || clsDataDB;
|
|
21
21
|
if (!clsData) return null;
|
|
22
22
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export default function flattenObject(obj
|
|
2
|
-
return Object.keys(obj).reduce((acc, key) => {
|
|
1
|
+
export default function flattenObject(obj, keys, parent = '') {
|
|
2
|
+
return Object.keys(obj || {}).reduce((acc, key) => {
|
|
3
3
|
const newKey = parent ? `${parent}.${key}` : key;
|
|
4
4
|
if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
|
|
5
5
|
Object.assign(acc, flattenObject(obj[key], keys, newKey));
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
/* eslint-disable no-restricted-globals */
|
|
1
3
|
/* eslint-disable no-param-reassign */
|
|
2
4
|
// import config from '../../../../config.js';
|
|
3
5
|
|
|
@@ -12,7 +14,7 @@ export default function unflattenObject(flatObj) {
|
|
|
12
14
|
nestedObj[part] = JSON.parse(flatObj[key]);
|
|
13
15
|
}
|
|
14
16
|
catch (err) {
|
|
15
|
-
|
|
17
|
+
console.warn(`Error parsing JSON for key ${key}:`, err.toString());
|
|
16
18
|
nestedObj[part] = flatObj[key]; // fallback to original value if parsing fails
|
|
17
19
|
}
|
|
18
20
|
}
|
|
@@ -21,7 +23,7 @@ export default function unflattenObject(flatObj) {
|
|
|
21
23
|
nestedObj[part] = JSON.parse(flatObj[key]);
|
|
22
24
|
}
|
|
23
25
|
catch (err) {
|
|
24
|
-
|
|
26
|
+
console.warn(`Error parsing JSON for key ${key}:`, err.toString());
|
|
25
27
|
nestedObj[part] = flatObj[key]; // fallback to original value if parsing fails
|
|
26
28
|
}
|
|
27
29
|
}
|
|
@@ -65,11 +65,6 @@ export default async function update(req, reply) {
|
|
|
65
65
|
Object.keys(body || {}).filter(key => !Object.keys(schema || {}).includes(key)).forEach(key => delete body[key]);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
if (tokenData?.obj) {
|
|
69
|
-
const objData = tokenData.obj?.split('#').reduce((p, el) => ({ ...p, [el.split('=')[0]]: el.split('=')[1] }), {}) || {};
|
|
70
|
-
Object.assign(body, objData);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
68
|
const xssCheck = checkXSS({ body, schema });
|
|
74
69
|
|
|
75
70
|
if (xssCheck.error && formData?.xssCheck !== false) {
|
|
@@ -89,6 +84,11 @@ export default async function update(req, reply) {
|
|
|
89
84
|
return reply.status(409).send('Дані не пройшли валідацію. Приберіть некоректні дані та спробуйте ще раз');
|
|
90
85
|
}
|
|
91
86
|
|
|
87
|
+
if (tokenData?.obj) {
|
|
88
|
+
const objData = tokenData.obj?.split('#').reduce((p, el) => ({ ...p, [el.split('=')[0]]: el.split('=')[1] }), {}) || {};
|
|
89
|
+
Object.assign(body, objData);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
92
|
const res = await dataUpdate({
|
|
93
93
|
pg,
|
|
94
94
|
table: loadTemplate?.table || table,
|
|
@@ -105,10 +105,10 @@ export default async function filterAPI(req, reply, iscalled) {
|
|
|
105
105
|
});
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
const sqlList = loadTable?.sql
|
|
108
|
+
/* const sqlList = loadTable?.sql
|
|
109
109
|
?.filter((el) => !el.disabled && el?.sql?.replace)
|
|
110
110
|
?.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 `)
|
|
111
|
-
?.join(' ') || '';
|
|
111
|
+
?.join(' ') || ''; */
|
|
112
112
|
|
|
113
113
|
// percentile_cont - alternative
|
|
114
114
|
await Promise.all(filters.filter((el) => el.name && el.type === 'Range' && fields?.find?.((item) => item?.name === el.name)).map(async (el) => {
|
|
@@ -119,7 +119,7 @@ export default async function filterAPI(req, reply, iscalled) {
|
|
|
119
119
|
percentile_disc(0.5) within group (order by ${el.name}),
|
|
120
120
|
percentile_disc(0.75) within group (order by ${el.name}),
|
|
121
121
|
max(${el.name})
|
|
122
|
-
] as range from ${table}
|
|
122
|
+
] as range from ${table} where ${tableQuery || '1=1'}`,
|
|
123
123
|
{ table },
|
|
124
124
|
).then(res => {
|
|
125
125
|
if (res.timeout) {
|
|
@@ -227,11 +227,13 @@ export default async function dataAPI(req, reply, called) {
|
|
|
227
227
|
|
|
228
228
|
if (uid && rows.length && !config.security?.disableToken && (editable || actions.includes('edit') || actions.includes('del'))) {
|
|
229
229
|
rows.forEach(row => {
|
|
230
|
-
row
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
230
|
+
Object.assign(row, {
|
|
231
|
+
token: setToken({
|
|
232
|
+
ids: [JSON.stringify({ id: row.id, table: tokenData?.table || hookData?.table || params.table, form: loadTable?.form })],
|
|
233
|
+
uid,
|
|
234
|
+
array: 1,
|
|
235
|
+
})?.[0],
|
|
236
|
+
});
|
|
235
237
|
});
|
|
236
238
|
}
|
|
237
239
|
|
|
@@ -308,7 +310,7 @@ export default async function dataAPI(req, reply, called) {
|
|
|
308
310
|
|
|
309
311
|
// conditions
|
|
310
312
|
panels?.filter(el => el.items).forEach(el => {
|
|
311
|
-
el
|
|
313
|
+
Object.assign(el, { items: el.items?.filter(item => conditions(item.conditions, rows[0])) });
|
|
312
314
|
});
|
|
313
315
|
|
|
314
316
|
// title, count
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
|
|
3
|
-
export default function getCallerDir() {
|
|
4
|
-
const originalFunc = Error.prepareStackTrace;
|
|
5
|
-
|
|
6
|
-
let callerfile;
|
|
7
|
-
try {
|
|
8
|
-
const err = new Error();
|
|
9
|
-
// let currentfile;
|
|
10
|
-
|
|
11
|
-
Error.prepareStackTrace = function (err, stack) { return stack; };
|
|
12
|
-
|
|
13
|
-
const currentfile = err.stack.shift().getFileName();
|
|
14
|
-
|
|
15
|
-
while (err.stack.length) {
|
|
16
|
-
callerfile = err.stack.shift().getFileName();
|
|
17
|
-
|
|
18
|
-
if (currentfile !== callerfile) break;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
catch (err) { }
|
|
22
|
-
|
|
23
|
-
Error.prepareStackTrace = originalFunc;
|
|
24
|
-
|
|
25
|
-
return path.dirname(callerfile);
|
|
26
|
-
}
|