@opengis/fastify-table 2.5.22 → 2.5.23

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 (39) hide show
  1. package/dist/server/plugins/pg/funcs/autoIndex.d.ts.map +1 -1
  2. package/dist/server/plugins/pg/funcs/autoIndex.js +8 -3
  3. package/dist/server/plugins/table/funcs/getFilterSQL/index.js +1 -1
  4. package/dist/server/plugins/table/funcs/getFilterSQLParametrized/formatValue.d.ts +2 -0
  5. package/dist/server/plugins/table/funcs/getFilterSQLParametrized/formatValue.d.ts.map +1 -0
  6. package/dist/server/plugins/table/funcs/getFilterSQLParametrized/formatValue.js +211 -0
  7. package/dist/server/plugins/table/funcs/getFilterSQLParametrized/getFilterList.d.ts +8 -0
  8. package/dist/server/plugins/table/funcs/getFilterSQLParametrized/getFilterList.d.ts.map +1 -0
  9. package/dist/server/plugins/table/funcs/getFilterSQLParametrized/getFilterList.js +90 -0
  10. package/dist/server/plugins/table/funcs/getFilterSQLParametrized/getFilterQuery.d.ts +17 -0
  11. package/dist/server/plugins/table/funcs/getFilterSQLParametrized/getFilterQuery.d.ts.map +1 -0
  12. package/dist/server/plugins/table/funcs/getFilterSQLParametrized/getFilterQuery.js +90 -0
  13. package/dist/server/plugins/table/funcs/getFilterSQLParametrized/getRangeQuery.d.ts +17 -0
  14. package/dist/server/plugins/table/funcs/getFilterSQLParametrized/getRangeQuery.d.ts.map +1 -0
  15. package/dist/server/plugins/table/funcs/getFilterSQLParametrized/getRangeQuery.js +340 -0
  16. package/dist/server/plugins/table/funcs/getFilterSQLParametrized/getTableSql.d.ts +9 -0
  17. package/dist/server/plugins/table/funcs/getFilterSQLParametrized/getTableSql.d.ts.map +1 -0
  18. package/dist/server/plugins/table/funcs/getFilterSQLParametrized/getTableSql.js +40 -0
  19. package/dist/server/plugins/table/funcs/getFilterSQLParametrized/index.d.ts +19 -0
  20. package/dist/server/plugins/table/funcs/getFilterSQLParametrized/index.d.ts.map +1 -0
  21. package/dist/server/plugins/table/funcs/getFilterSQLParametrized/index.js +156 -0
  22. package/dist/server/routes/table/functions/getData.d.ts.map +1 -1
  23. package/dist/server/routes/table/functions/getData.js +35 -29
  24. package/dist/server/routes/table/functions/prettify.d.ts +2 -0
  25. package/dist/server/routes/table/functions/prettify.d.ts.map +1 -0
  26. package/dist/server/routes/table/functions/prettify.js +11 -0
  27. package/dist/utils.d.ts +1 -0
  28. package/dist/utils.d.ts.map +1 -1
  29. package/dist/utils.js +1 -0
  30. package/package.json +1 -1
  31. package/dist/server/plugins/policy/funcs/checkSQL.d.ts +0 -8
  32. package/dist/server/plugins/policy/funcs/checkSQL.d.ts.map +0 -1
  33. package/dist/server/plugins/policy/funcs/checkSQL.js +0 -19
  34. package/dist/server/plugins/policy/sqlInjection.d.ts +0 -3
  35. package/dist/server/plugins/policy/sqlInjection.d.ts.map +0 -1
  36. package/dist/server/plugins/policy/sqlInjection.js +0 -33
  37. package/dist/server/plugins/table/funcs/getData.d.ts +0 -2
  38. package/dist/server/plugins/table/funcs/getData.d.ts.map +0 -1
  39. package/dist/server/plugins/table/funcs/getData.js +0 -25
@@ -0,0 +1,340 @@
1
+ /* eslint-disable no-restricted-globals */
2
+ const dateTypeList = [
3
+ "date",
4
+ "timestamp",
5
+ "timestamp without time zone",
6
+ "timestamp with time zone",
7
+ ];
8
+ const numberTypeList = [
9
+ "float8",
10
+ "int4",
11
+ "int8",
12
+ "numeric",
13
+ "double precision",
14
+ "integer",
15
+ "bigint",
16
+ ];
17
+ const isValidDate = (dateStr) => {
18
+ if (!dateStr) {
19
+ return false;
20
+ }
21
+ if (["min", "max", "cd", "cw", "cm", "cq", "cy"].includes(dateStr)) {
22
+ return true;
23
+ }
24
+ // iso date: 2024-01-01
25
+ if (dateStr.includes("-")) {
26
+ return new Date(dateStr).toString() !== "Invalid Date";
27
+ }
28
+ // locale date: 01.01.2024
29
+ const [dd, mm, yyyy] = dateStr.split(".");
30
+ return new Date(`${yyyy}-${mm}-${dd}`).toString() !== "Invalid Date";
31
+ };
32
+ const isValidNumber = (numStr) => ["min", "max"].includes(numStr) ? true : !isNaN(numStr);
33
+ function dt(y, m, d) {
34
+ return new Date(Date.UTC(y, m, d)).toISOString().slice(0, 10);
35
+ }
36
+ const dp = {
37
+ d: new Date().getDate(),
38
+ w: new Date().getDate() - (new Date().getDay() || 7) + 1,
39
+ m: new Date().getMonth(),
40
+ q: parseFloat((new Date().getMonth() / 4).toFixed()) * 3,
41
+ y: new Date().getFullYear(),
42
+ };
43
+ function formatDateISOString(date) {
44
+ if (!date?.includes("."))
45
+ return date;
46
+ const [day, month, year] = date.split(".");
47
+ return `${year}-${month}-${day}`;
48
+ }
49
+ function checkValid(value, fieldType, filterType, sql, extra) {
50
+ const sep = (value.includes(",") ? "," : null) ||
51
+ (value.includes("_") ? "_" : null) ||
52
+ (value.includes("-") ? "-" : null);
53
+ // number range w/o valid separator => skip invalid filter
54
+ if (filterType === "range" && !sep) {
55
+ return { isvalid: false };
56
+ }
57
+ // date range, specific options: current day, week, month, year etc.
58
+ if (["date", "datepicker"].includes(filterType) && value === "cd") {
59
+ return {
60
+ min: dt(dp.y, dp.m, dp.d),
61
+ max: dt(dp.y, dp.m, dp.d),
62
+ isvalid: true,
63
+ };
64
+ }
65
+ if (["date", "datepicker"].includes(filterType) && value === "cw") {
66
+ return {
67
+ min: dt(dp.y, dp.m, dp.w),
68
+ max: dt(dp.y, dp.m, dp.w + 6),
69
+ isvalid: true,
70
+ };
71
+ }
72
+ if (["date", "datepicker"].includes(filterType) && value === "cm") {
73
+ return {
74
+ min: dt(dp.y, dp.m, 1),
75
+ max: dt(dp.y, dp.m + 1, 0),
76
+ isvalid: true,
77
+ };
78
+ }
79
+ if (["date", "datepicker"].includes(filterType) && value === "cq") {
80
+ return {
81
+ min: dt(dp.y, dp.q, 1),
82
+ max: dt(dp.y, dp.q + 3, 0),
83
+ isvalid: true,
84
+ };
85
+ }
86
+ if (["date", "datepicker"].includes(filterType) && value === "cy") {
87
+ return {
88
+ min: dt(dp.y, 0, 1),
89
+ max: dt(dp.y, 11, 31),
90
+ isvalid: true,
91
+ };
92
+ }
93
+ // specific period from now - days, months, years
94
+ if (["date", "datepicker"].includes(filterType) &&
95
+ value.match(/^(?<val>[1-9]\d*)(?<unit>d|m|y)$/)?.groups?.unit) {
96
+ const { val, unit } = value.match(/^(?<val>[1-9]\d*)(?<unit>d|m|y)$/)?.groups || {};
97
+ const min = (unit === "d" ? dt(dp.y, dp.m, dp.d - +val) : null) ||
98
+ (unit === "m" ? dt(dp.y, dp.m - +val, dp.d) : null) ||
99
+ (unit === "y" ? dt(dp.y - +val, dp.m, dp.d) : null);
100
+ return {
101
+ min,
102
+ max: dt(dp.y, dp.m, dp.d),
103
+ isvalid: isValidDate(min),
104
+ };
105
+ }
106
+ // specific quarter - before skip date value validation
107
+ if (["date", "datepicker"].includes(filterType) &&
108
+ value.match(/^(?<year>\d{4})-q(?<quarter>[1-4])$/)?.groups?.quarter) {
109
+ const { year, quarter } = value.match(/^(?<year>\d{4})-q(?<quarter>[1-4])$/)?.groups || {};
110
+ const startMonth = +quarter * 3;
111
+ return {
112
+ min: dt(year, startMonth - 3, 1),
113
+ max: dt(year, startMonth, 0),
114
+ isvalid: true,
115
+ };
116
+ }
117
+ // date value validation
118
+ if (["date", "datepicker"].includes(filterType) &&
119
+ !sep &&
120
+ !isValidDate(value)) {
121
+ return { isvalid: false };
122
+ }
123
+ // specific date / day
124
+ if (["date", "datepicker"].includes(filterType) &&
125
+ value.match(/^\d{4}-\d{2}-\d{2}$/)?.[0]) {
126
+ return {
127
+ min: new Date(value).toISOString().split("T")[0],
128
+ max: new Date(value).toISOString().split("T")[0],
129
+ isvalid: true,
130
+ };
131
+ }
132
+ // specific month
133
+ if (["date", "datepicker"].includes(filterType) &&
134
+ value.match(/^\d{4}-\d{2}$/)?.[0]) {
135
+ return {
136
+ min: new Date(value).toISOString().split("T")[0],
137
+ max: dt(new Date(value).getFullYear(), new Date(value).getMonth() + 1, 0),
138
+ isvalid: true,
139
+ };
140
+ }
141
+ // specific year
142
+ if (["date", "datepicker"].includes(filterType) &&
143
+ value.match(/^\d{4}$/)?.[0]) {
144
+ return {
145
+ min: dt(value, 0, 1),
146
+ max: dt(value, 11, 31),
147
+ isvalid: true,
148
+ };
149
+ }
150
+ if (sep) {
151
+ const [minValue = "min", maxValue = "max"] = value.split(sep);
152
+ // range for numbers
153
+ if (filterType === "range" && fieldType) {
154
+ const isvalid = (numberTypeList.includes(fieldType) || sql || extra) &&
155
+ isValidNumber(minValue) &&
156
+ isValidNumber(maxValue);
157
+ return { min: minValue, max: maxValue, isvalid };
158
+ }
159
+ // date range, example: 01.01.2024-31.12.2024
160
+ if (["date", "datepicker"].includes(filterType)) {
161
+ const min = minValue === "min" ? minValue : formatDateISOString(minValue);
162
+ const max = maxValue === "max" ? maxValue : formatDateISOString(maxValue);
163
+ const isvalid = fieldType &&
164
+ (dateTypeList.includes(fieldType) || sql || extra) &&
165
+ isValidDate(min) &&
166
+ isValidDate(max);
167
+ return { min, max, isvalid };
168
+ }
169
+ }
170
+ return { isvalid: false };
171
+ }
172
+ export default function getRangeQuery({ value, name, fieldType, filterType, sql, extra, pk, args: argsParams, }) {
173
+ const { min, max, isvalid } = checkValid(value, fieldType, filterType, sql, extra);
174
+ if (!isvalid) {
175
+ return { query: "false" };
176
+ }
177
+ const args = Array.from(argsParams || []);
178
+ const checkBoth = sql && typeof sql === "string" && sql.includes("$1") && sql.includes("$2");
179
+ // with sql subquery
180
+ if (filterType &&
181
+ ["date", "datepicker"].includes(filterType) &&
182
+ typeof sql === "string") {
183
+ if (checkBoth) {
184
+ args.push(min);
185
+ args.push(max);
186
+ }
187
+ else {
188
+ args.push(min || max);
189
+ }
190
+ return {
191
+ query: sql
192
+ .replace(/\$1/g, `$${checkBoth ? args.length - 1 : args.length}::date`)
193
+ .replace(/\$2/g, `$${args.length}::date`),
194
+ values: checkBoth ? [min, max] : [min || max],
195
+ };
196
+ }
197
+ // with sql subquery
198
+ if (filterType && ["range"].includes(filterType) && sql) {
199
+ if (checkBoth) {
200
+ args.push(min);
201
+ args.push(max);
202
+ }
203
+ else {
204
+ args.push(min || max);
205
+ }
206
+ return {
207
+ query: sql
208
+ .replace(/\$1/g, `${checkBoth ? args.length - 1 : args.length}`)
209
+ .replace(/\$2/g, `${args.length}`),
210
+ values: checkBoth ? [min, max] : [min || max],
211
+ };
212
+ }
213
+ // preset date values
214
+ if (filterType &&
215
+ ["date", "datepicker"].includes(filterType) &&
216
+ ["cd", "cw", "cm", "cq", "cy"].includes(value)) {
217
+ if (value === "cd") {
218
+ args.push(min);
219
+ }
220
+ else {
221
+ args.push(min);
222
+ args.push(max);
223
+ }
224
+ const query = value === "cd"
225
+ ? `${name}::date = $${args.length}::date`
226
+ : `${name}::date between $${args.length - 1}::date and $${args.length}::date`;
227
+ return { query, values: value === "cd" ? [min] : [min, max] };
228
+ }
229
+ // extra columns, example: crm.extra_data
230
+ if (filterType &&
231
+ ["date", "datepicker"].includes(filterType) &&
232
+ extra?.table &&
233
+ pk) {
234
+ const where = [];
235
+ const values = [];
236
+ args.push(name);
237
+ const nameIdx = args.length;
238
+ if (max && min && min === max) {
239
+ args.push(value);
240
+ values.push(value);
241
+ where.push(`value_date::date > $${args.length}::date`);
242
+ }
243
+ else if (max === "max") {
244
+ args.push(min);
245
+ values.push(min);
246
+ where.push(`value_date::date > $${args.length}::date`);
247
+ }
248
+ else if (min === "min") {
249
+ args.push(max);
250
+ values.push(max);
251
+ where.push(`value_date::date < $${args.length}::date`);
252
+ }
253
+ else {
254
+ args.push(min);
255
+ values.push(min);
256
+ args.push(max);
257
+ values.push(max);
258
+ where.push(`value_date::date between $${args.length - 1}::date and $${args.length}::date`);
259
+ }
260
+ const query = `${pk} in (select object_id from ${extra.table} where property_key=$${nameIdx} and ${where.join(" AND ") || "true"})`;
261
+ return { query, values };
262
+ }
263
+ // extra columns, example: crm.extra_data
264
+ if (filterType && ["range"].includes(filterType) && extra?.table && pk) {
265
+ const where = [];
266
+ const values = [];
267
+ args.push(name);
268
+ const nameIdx = args.length;
269
+ if (max && min && min === max) {
270
+ args.push(value);
271
+ values.push(value);
272
+ where.push(`value_text::numeric > $${args.length}`);
273
+ }
274
+ else if (max === "max") {
275
+ args.push(min);
276
+ values.push(min);
277
+ where.push(`value_text::numeric > $${args.length}`);
278
+ }
279
+ else if (min === "min") {
280
+ args.push(max);
281
+ values.push(max);
282
+ where.push(`value_text::numeric < $${args.length}`);
283
+ }
284
+ else {
285
+ args.push(min);
286
+ values.push(min);
287
+ args.push(max);
288
+ values.push(max);
289
+ where.push(`value_text::numeric between $${args.length - 1} and $${args.length}`);
290
+ }
291
+ const query = `${pk} in (select object_id from ${extra.table} where property_key=$${nameIdx} and ${where.join(" AND ") || "true"} )`;
292
+ return { query, values };
293
+ }
294
+ // same date
295
+ if (filterType &&
296
+ ["date", "datepicker"].includes(filterType) &&
297
+ max &&
298
+ min &&
299
+ min === max) {
300
+ args.push(min);
301
+ return { query: `${name}::date = $${args.length}::date`, values: [min] };
302
+ }
303
+ // skip, same as 1=1
304
+ if (filterType &&
305
+ ["range"].includes(filterType) &&
306
+ min === "min" &&
307
+ max === "max") {
308
+ return { query: "true" };
309
+ }
310
+ // default
311
+ if (filterType && max === "max") {
312
+ args.push(min);
313
+ const query = ["date", "datepicker"].includes(filterType)
314
+ ? `${name} >= $${args.length}::date`
315
+ : `${name} >= $${args.length}`;
316
+ return {
317
+ query,
318
+ values: [min],
319
+ };
320
+ }
321
+ if (filterType && min === "min") {
322
+ args.push(max);
323
+ const query = ["date", "datepicker"].includes(filterType)
324
+ ? `${name} <= $${args.length}::date`
325
+ : `${name} <= $${args.length}`;
326
+ return { query, values: [max] };
327
+ }
328
+ if (filterType && ["date", "datepicker"].includes(filterType)) {
329
+ args.push(min);
330
+ args.push(max);
331
+ return {
332
+ query: `${name}::date between $${args.length - 1}::date and $${args.length}::date`,
333
+ values: [min, max],
334
+ };
335
+ }
336
+ return {
337
+ query: `${name} between $${args.length - 1} and $${args.length}`,
338
+ values: [min, max],
339
+ };
340
+ }
@@ -0,0 +1,9 @@
1
+ import { type ExtendedPG } from "../../../../types/core.js";
2
+ declare function getTableSql({ pg, body, table, fields, }: {
3
+ pg: ExtendedPG;
4
+ body: Record<string, any>;
5
+ table: string;
6
+ fields: any[];
7
+ }): Promise<any>;
8
+ export default getTableSql;
9
+ //# sourceMappingURL=getTableSql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getTableSql.d.ts","sourceRoot":"","sources":["../../../../../../server/plugins/table/funcs/getFilterSQLParametrized/getTableSql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAqB5D,iBAAe,WAAW,CAAC,EACzB,EAAqB,EACrB,IAAI,EACJ,KAAK,EACL,MAAM,GACP,EAAE;IACD,EAAE,EAAE,UAAU,CAAC;IACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,GAAG,EAAE,CAAC;CACf,gBA8BA;AAED,eAAe,WAAW,CAAC"}
@@ -0,0 +1,40 @@
1
+ import pgClients from "../../../pg/pgClients.js";
2
+ function getTable(table) {
3
+ const result = table
4
+ ?.toLowerCase()
5
+ ?.replace(/[\n\r]+/g, " ")
6
+ ?.split(" from ")
7
+ ?.filter((el) => /^[a-z0-9_]+\.[a-z0-9_]+/.test(el))
8
+ ?.map((el) => el.split(/[ )]/)[0]);
9
+ return result;
10
+ }
11
+ /**
12
+ * @param {Number} opt.json - (1|0) 1 - Результат - Object, 0 - String
13
+ * @param {String} opt.query - запит до таблиці
14
+ * @param {String} opt.hash - інформація з хешу по запиту
15
+ */
16
+ const tableSql = {};
17
+ async function getTableSql({ pg = pgClients.client, body, table, fields, }) {
18
+ if (tableSql[table])
19
+ return tableSql[table];
20
+ const fieldList = fields.map((el) => el.name);
21
+ const tableList = body?.sql
22
+ ?.map((el) => getTable(el.sql))
23
+ .reduce((acc, el) => acc.concat(el), [])
24
+ .filter((el) => fieldList.includes(pg.pk?.[el]));
25
+ if (!tableList) {
26
+ tableSql[table] = [];
27
+ return [];
28
+ }
29
+ const data = await Promise.all(tableList?.map(async (tableEl) => {
30
+ const { fields: fieldsEl } = await pg.query(`select * from ${tableEl} limit 0`);
31
+ return fieldsEl.map((el) => ({
32
+ name: el.name,
33
+ table: tableEl,
34
+ pk: pg.pk?.[tableEl],
35
+ }));
36
+ }));
37
+ tableSql[table] = data.reduce((acc, el) => acc.concat(el), []);
38
+ return tableSql[table];
39
+ }
40
+ export default getTableSql;
@@ -0,0 +1,19 @@
1
+ import { type ExtendedPG } from "../../../../types/core.js";
2
+ export default function getFilterSQLParametrized({ table, filter, pg, search, searchColumn: searchColumn1, filterList, query, custom, state, uid, objectId, }: {
3
+ table: string | undefined;
4
+ filter?: string;
5
+ pg: ExtendedPG;
6
+ search?: string;
7
+ searchColumn?: string;
8
+ filterList?: any[];
9
+ query?: string;
10
+ custom?: string;
11
+ state?: string;
12
+ uid?: string;
13
+ objectId?: string;
14
+ order?: string;
15
+ }): Promise<{
16
+ q: string;
17
+ args: any[];
18
+ }>;
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../server/plugins/table/funcs/getFilterSQLParametrized/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAgD5D,wBAA8B,wBAAwB,CAAC,EACrD,KAAK,EACL,MAAM,EACN,EAAqB,EACrB,MAAM,EACN,YAAY,EAAE,aAAa,EAC3B,UAAU,EACV,KAAK,EACL,MAAM,EACN,KAAK,EACL,GAAG,EACH,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,UAAU,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;;;GAoMA"}
@@ -0,0 +1,156 @@
1
+ import { BadRequestError } from "../../../../../errors.js";
2
+ import getTemplate from "../getTemplate.js";
3
+ import pgClients from "../../../pg/pgClients.js";
4
+ import config from "../../../../../config.js";
5
+ // filter util
6
+ import getTableSql from "./getTableSql.js";
7
+ import getFilterQuery from "./getFilterQuery.js";
8
+ import getFilterList from "./getFilterList.js";
9
+ const checkInline = {};
10
+ const defaultTable = "crm.extra_data";
11
+ function getExtraQuery({ columns, schema, table, pk, args, }) {
12
+ const extraColumns = Object.keys(schema || {})
13
+ .filter((key) => !columns.map((el) => el?.name).includes(key))
14
+ .map((key) => ({ name: key, type: schema[key]?.type }));
15
+ extraColumns.forEach((col) => args.push(col.name));
16
+ const q = extraColumns.reduce((acc, curr) => {
17
+ args.push(curr.name);
18
+ return acc.push(`,(select value_text as "${curr.name}" from ${table} where property_key=$${args.length} and object_id=t.${pk} limit 1)`);
19
+ }, []);
20
+ return {
21
+ q,
22
+ args,
23
+ extraColumns,
24
+ };
25
+ }
26
+ export default async function getFilterSQLParametrized({ table, filter, pg = pgClients.client, search, searchColumn: searchColumn1, filterList, query, custom, state, uid, objectId, }) {
27
+ if (!table) {
28
+ throw BadRequestError("param table is required");
29
+ }
30
+ const args = [];
31
+ const body = await getTemplate("table", table);
32
+ const loadTemplate = body?.form
33
+ ? await getTemplate("form", body?.form)
34
+ : null;
35
+ const { extra } = loadTemplate || {};
36
+ const extraDataTable = extra
37
+ ? config.extraData?.[body.table] ||
38
+ config.extraData?.[body.table.split(".").shift()] ||
39
+ config.extraData?.default ||
40
+ config.extraData ||
41
+ defaultTable
42
+ : undefined;
43
+ const fieldsModel = body?.table && pg.pk?.[body.table]
44
+ ? await pg
45
+ .query(`select * from ${body.table} limit 0`)
46
+ .then((r) => r.fields || [])
47
+ : [];
48
+ const { q: extraSqlColumns, extraColumns = [] } = extraDataTable && pg.pk?.[extraDataTable] && pg.pk?.[body.table || table]
49
+ ? getExtraQuery({
50
+ columns: fieldsModel,
51
+ schema: loadTemplate?.schema,
52
+ table: extraDataTable,
53
+ pk: pg.pk[body.table || table],
54
+ args,
55
+ })
56
+ : { q: null };
57
+ // check sql inline fields count
58
+ if (body?.table && !checkInline[body?.table] && body?.sql?.length) {
59
+ const filterSql = body.sql.filter((el) => !el?.disabled && (el.inline ?? true));
60
+ const sqlTable = filterSql
61
+ .map((el, i) => ` left join lateral (${el.sql}) ${el.name || `t${i}`} on 1=1 `)
62
+ ?.join("") || "";
63
+ const d = await Promise.all(filterSql.map((el, i) => pg
64
+ .query(`select ${el.name || `t${i}`}.* from(select * from ${body.table})t ${sqlTable} limit 0`)
65
+ .then((item) => item.fields)));
66
+ d.forEach((el, i) => {
67
+ filterSql[i].inline = el.length === 1;
68
+ filterSql[i].fields = el.map((f) => f.name);
69
+ });
70
+ checkInline[body?.table] = body.sql;
71
+ }
72
+ else if (checkInline[body?.table]) {
73
+ body.sql = checkInline[body?.table];
74
+ }
75
+ const sqlTable = body?.sql?.length
76
+ ? body.sql
77
+ .filter((el) => !el?.disabled &&
78
+ !el.inline &&
79
+ el?.sql?.replace &&
80
+ (!el.sql.includes("{{uid}}") || uid))
81
+ .map((el, i) => ` left join lateral (${el.sql.replace("{{uid}}", uid)}) ${el.name || `t${i}`} on 1=1 `)
82
+ .join("")
83
+ : null;
84
+ const sqlInline = body?.sql
85
+ ?.filter?.((el) => el.inline)
86
+ .map((el) => `,(${el.sql})`)
87
+ .join("");
88
+ const fieldQuery = `select * ${extraSqlColumns || ""} ${sqlInline || ""} from ${body?.table || table} t ${sqlTable || ""} limit 0`;
89
+ const fields = await pg.query(fieldQuery).then((r) => r.fields || []);
90
+ const autoSearchColumn = fields
91
+ ?.filter((el) => pg.pgType?.[el.dataTypeID] === "text")
92
+ ?.map((el) => `"${el.name}"`)
93
+ .join(",");
94
+ const searchColumn = searchColumn1 ||
95
+ body?.search_column ||
96
+ body?.meta?.search ||
97
+ autoSearchColumn;
98
+ const fieldsList = (fieldsModel || fields)?.map((el) => el.name);
99
+ const where = [];
100
+ try {
101
+ const tableSQL = await getTableSql({
102
+ pg,
103
+ body,
104
+ table,
105
+ fields,
106
+ });
107
+ if (search && searchColumn && typeof search === "string") {
108
+ args.push(`%${decodeURIComponent(search.replace(/%/g, "%25")).replace(/%/g, "\\%")}%`);
109
+ where.push(`(${searchColumn
110
+ .split(",")
111
+ ?.map((name) => {
112
+ const { pk } = tableSQL.find((el) => el.name === name) || {};
113
+ return pk && !fieldsList.includes(name)
114
+ ? `${pk} in (select ${pk} from (${fieldQuery.replace(/limit 0/g, "")} where ${name} ilike $${args.length} )q where 1=1)`
115
+ : `${name}::text ilike $${args.length}`;
116
+ })
117
+ .join(" or ")})`);
118
+ }
119
+ const filterList1 = await getFilterList({
120
+ table,
121
+ uid,
122
+ filterList,
123
+ extraColumns,
124
+ extraDataTable,
125
+ }, pg);
126
+ const modelQuery = body?.model || body?.table || table;
127
+ const filters = getFilterQuery({
128
+ filter,
129
+ table: modelQuery,
130
+ tableSQL,
131
+ fields,
132
+ filterList: filterList1,
133
+ uid,
134
+ objectId,
135
+ args,
136
+ }, pg);
137
+ if (body?.filterCustom?.length && custom) {
138
+ where.push(body.filterCustom?.find((el) => el.name === custom)?.sql);
139
+ }
140
+ if (body?.filterState?.length && state) {
141
+ where.push(body.filterState?.find((el) => el.name === state)?.sql);
142
+ }
143
+ const filterQuery = filters
144
+ .filter((el) => el.query)
145
+ .map((el) => `${el.query}`)
146
+ .join(" and ");
147
+ const q = where
148
+ .concat([body?.query, query, filterQuery])
149
+ .filter(Boolean)
150
+ .join(" and ");
151
+ return { q, args };
152
+ }
153
+ catch (err) {
154
+ throw err;
155
+ }
156
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"getData.d.ts","sourceRoot":"","sources":["../../../../../server/routes/table/functions/getData.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAwFzD,wBAA8B,OAAO,CACnC,EACE,EAAqB,EACrB,MAAM,EACN,KAAK,EACL,EAAE,EACF,OAAY,EACZ,KAAU,EACV,IAAS,EACT,YAAY,EACZ,YAAY,EACZ,KAAY,EACZ,UAAU,EACV,OAAO,EAAE,YAAY,EACrB,WAAW,EAAE,gBAAgB,EAC7B,OAAO,EAAE,YAAY,EACrB,QAAgB,GACjB,EAAE;IACD,EAAE,CAAC,EAAE,UAAU,CAAC;IAChB,MAAM,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,EACD,KAAK,CAAC,EAAE,YAAY,EACpB,MAAM,CAAC,EAAE,GAAG,gBAw4Bb"}
1
+ {"version":3,"file":"getData.d.ts","sourceRoot":"","sources":["../../../../../server/routes/table/functions/getData.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AA0FzD,wBAA8B,OAAO,CACnC,EACE,EAAqB,EACrB,MAAM,EACN,KAAK,EACL,EAAE,EACF,OAAY,EACZ,KAAU,EACV,IAAS,EACT,YAAY,EACZ,YAAY,EACZ,KAAY,EACZ,UAAU,EACV,OAAO,EAAE,YAAY,EACrB,WAAW,EAAE,gBAAgB,EAC7B,OAAO,EAAE,YAAY,EACrB,QAAgB,GACjB,EAAE;IACD,EAAE,CAAC,EAAE,UAAU,CAAC;IAChB,MAAM,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,EACD,KAAK,CAAC,EAAE,YAAY,EACpB,MAAM,CAAC,EAAE,GAAG,gBA64Bb"}