@opengis/fastify-table 2.0.126 → 2.0.127

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.
@@ -1 +1 @@
1
- {"version":3,"file":"getSelectMeta.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/table/funcs/getSelectMeta.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAWzD,wBAA8B,aAAa,CAAC,EAC1C,IAAI,EACJ,UAAU,EACV,GAAG,EACH,OAAO,EACP,MAAM,EACN,EAAqB,GACtB,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,EAAE,CAAC,EAAE,UAAU,CAAC;CACjB,gBA8GA"}
1
+ {"version":3,"file":"getSelectMeta.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/table/funcs/getSelectMeta.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAWzD,wBAA8B,aAAa,CAAC,EAC1C,IAAI,EACJ,UAAU,EACV,GAAG,EACH,OAAO,EACP,MAAM,EACN,EAAqB,GACtB,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,EAAE,CAAC,EAAE,UAAU,CAAC;CACjB,gBA6GA"}
@@ -16,9 +16,8 @@ export default async function getSelectMeta({ name, startsWith, key, nocache, pa
16
16
  return { ...selectMeta[name], searchQuery };
17
17
  }
18
18
  const cls = await getSelect(name, pg, nocache);
19
- const db = typeof cls?.db === "string" ? { database: cls.db } : cls?.db;
20
19
  const pg1 = cls?.db
21
- ? await getPGAsync({ database: db, port: cls?.port })
20
+ ? await getPGAsync({ database: cls.db, port: cls?.port })
22
21
  : pg;
23
22
  if (!cls)
24
23
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../../../../server/routes/file/controllers/export.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAgCzD;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,wBAA8B,WAAW,CACvC,EACE,EAAqB,EACrB,OAAO,EACP,IAAI,EACJ,OAAO,EAAE,QAAQ,EACjB,GAAG,EACH,KAAU,EACV,IAAkB,EAClB,QAAQ,EACR,UAAU,GACX,EAAE;IACD,EAAE,EAAE,UAAU,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,EACD,KAAK,EAAE,YAAY,gBAsYpB"}
1
+ {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../../../../server/routes/file/controllers/export.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAgCzD;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,wBAA8B,WAAW,CACvC,EACE,EAAqB,EACrB,OAAO,EACP,IAAI,EACJ,OAAO,EAAE,QAAQ,EACjB,GAAG,EACH,KAAU,EACV,IAAkB,EAClB,QAAQ,EACR,UAAU,GACX,EAAE;IACD,EAAE,EAAE,UAAU,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,EACD,KAAK,EAAE,YAAY,gBA0YpB"}
@@ -187,7 +187,8 @@ export default async function exportTable({ pg = pgClients.client, headers, user
187
187
  let page = 1;
188
188
  let seq = 0;
189
189
  send(`Всього в реєстрі: ${result.total} (${filtered} з урахуванням фільтрів)`);
190
- if (!cacheFileJSON || nocache || config.disableCache) {
190
+ const writeNewJsonl = !cacheFileJSON || nocache || config.disableCache;
191
+ if (writeNewJsonl) {
191
192
  // delete old json line file, prevent append
192
193
  if (existsSync(filePathJSON.replace(/.json$/, ".jsonl"))) {
193
194
  await rm(filePathJSON.replace(/.json$/, ".jsonl"), {
@@ -250,7 +251,9 @@ export default async function exportTable({ pg = pgClients.client, headers, user
250
251
  }
251
252
  }
252
253
  // convert json line to json array
253
- await jsonlToJsonFile(filePathJSON.replace(/.json$/, ".jsonl"));
254
+ if (writeNewJsonl) {
255
+ await jsonlToJsonFile(filePathJSON.replace(/.json$/, ".jsonl"));
256
+ }
254
257
  clearInterval(interval);
255
258
  if (res.error) {
256
259
  send("finish");
@@ -1 +1 @@
1
- {"version":3,"file":"suggest.d.ts","sourceRoot":"","sources":["../../../../../server/routes/table/controllers/suggest.ts"],"names":[],"mappings":"AAmEA,wBAA8B,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,gBAsWzD"}
1
+ {"version":3,"file":"suggest.d.ts","sourceRoot":"","sources":["../../../../../server/routes/table/controllers/suggest.ts"],"names":[],"mappings":"AAiHA,wBAA8B,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,gBA6WzD"}
@@ -1,21 +1,46 @@
1
1
  import path from "node:path";
2
2
  import { existsSync, readFileSync } from "node:fs";
3
- import { config, getPGAsync, getTemplate, getSelectMeta, getMeta, applyHook, getSelectVal, logger, getSelect, metaFormat, getColumnCLS, pgClients, } from "../../../../utils.js";
3
+ import { config, getPGAsync, getTemplate, getSelectMeta, getMeta, applyHook, getSelectVal, logger, getSelect, metaFormat, getColumnCLS, pgClients, getFilter, } from "../../../../utils.js";
4
4
  const defaultLimit = 50;
5
5
  async function getTableColumnMeta({ table, template, column, selectName, filtered, startsWith, key, pg = pgClients.client, }) {
6
6
  if (!table || !column) {
7
7
  return null;
8
8
  }
9
- const { columns, table: tableName } = template
10
- ? await getTemplate("table", template)
11
- : { table, columns: [] };
9
+ const metaColumns = await getMeta({
10
+ pg,
11
+ table,
12
+ }).then((el) => el?.columns || []);
13
+ const { dataTypeID } = (metaColumns || []).find((col) => col?.name === column) || {};
14
+ const { columns, table: tableName, sql, } = template ? await getTemplate("table", template) : { table, columns: [] };
15
+ const filters = template
16
+ ? await getFilter({ pg, table: template }).then((el) => el.list)
17
+ : null;
12
18
  const { data: clsName } = selectName
13
19
  ? { data: selectName }
14
- : columns.find((el) => el.name === column) || {};
15
- const { arr } = (await getSelect(clsName || column, pg)) || {};
20
+ : (columns || []).find((el) => el.name === column) ||
21
+ (filters || []).find((el) => el.name === column) ||
22
+ {};
23
+ const { arr, sql: select } = (await getSelect(clsName || column, pg)) || {};
24
+ const sqlTable = (sql || [])
25
+ .filter((el) => !el.disabled && el.sql && el.sql.includes(column) && false)
26
+ .map((el, i) => ` left join lateral (${el.sql}) ${el.name || `t${i}`} on 1=1 `)
27
+ ?.join("") || "";
28
+ if (pg.pgType?.[dataTypeID]?.includes("[]")) {
29
+ const original = filtered
30
+ ? `with c(id,text) as (select id, id as text from (select unnest(${column}) as id from ${tableName} t ${sqlTable})q group by id) select id, text from c`
31
+ : `with c(id,text) as (select id, id as text, count(*) from (select unnest(${column}) as id from ${tableName} t ${sqlTable})q group by id limit ${defaultLimit}) select * from c`;
32
+ return {
33
+ arr,
34
+ original,
35
+ searchQuery: startsWith && key
36
+ ? `(left(lower("text"::text),${key.length}) = $1 )`
37
+ : '(lower("text"::text) ~ $1 )',
38
+ pk: "id",
39
+ };
40
+ }
16
41
  const original = filtered
17
- ? `with c(id,text) as (select ${column} as id, ${column} as text from ${tableName} group by ${column}) select id, text from c`
18
- : `with c(id,text) as (select ${column} as id, ${column} as text, count(*) from ${tableName} group by ${column} limit ${defaultLimit}) select * from c`;
42
+ ? `with c(id,text) as (select ${column} as id, ${column} as text from ${tableName} t ${sqlTable} group by ${column}) select id, text from c`
43
+ : `with c(id,text) as (select ${column} as id, ${column} as text, count(*) from ${tableName} t ${sqlTable} group by ${column} limit ${defaultLimit}) select * from c`;
19
44
  return {
20
45
  arr,
21
46
  original,
@@ -43,15 +68,8 @@ export default async function suggest(req, reply) {
43
68
  const [table1, column1] = params.data?.includes(":")
44
69
  ? params.data.split(":")
45
70
  : [query.token, query.column];
46
- const selectName = query.sel || params.data;
47
71
  const table = table1 || query.token;
48
72
  const column = column1 || query.column;
49
- if (!selectName) {
50
- return reply.status(400).send({
51
- error: "name is required",
52
- code: 400,
53
- });
54
- }
55
73
  const { body: hookBody } = table
56
74
  ? (await applyHook("preSuggest", {
57
75
  pg: pg1,
@@ -66,6 +84,12 @@ export default async function suggest(req, reply) {
66
84
  code: 400,
67
85
  });
68
86
  }
87
+ const selectName = query.sel ||
88
+ (tableName && column && body
89
+ ? body.columns?.find((el) => el.name === column)?.data ||
90
+ body.meta?.cls?.[column]
91
+ : null) ||
92
+ params.data;
69
93
  const meta = tableName && column
70
94
  ? await getTableColumnMeta({
71
95
  table: tableName,
@@ -103,13 +127,18 @@ export default async function suggest(req, reply) {
103
127
  code: 400,
104
128
  });
105
129
  }
106
- const columns = hookBody?.columns || body?.columns
107
- ? hookBody?.columns || body?.columns
108
- : await getMeta({
109
- pg,
110
- table: tableName,
111
- }).then((el) => el?.columns || []);
112
- const { name: columnName, dataTypeID } = (columns || []).find((col) => col?.name === column) || {};
130
+ const columns = hookBody?.columns || body?.columns;
131
+ const metaColumns = await getMeta({
132
+ pg,
133
+ table: tableName,
134
+ }).then((el) => el?.columns || []);
135
+ const { name: columnName } = (columns || []).find((col) => col?.name === column) ||
136
+ (metaColumns || []).find((col) => col?.name === column) ||
137
+ {};
138
+ const { dataTypeID } = (metaColumns || []).find((col) => col?.name === column) || {};
139
+ // const filters =
140
+ // hookBody?.filters ||
141
+ // (body ? await getFilter({ pg, table }).then((el) => el.list) : null);
113
142
  if (table && (!column || !columnName)) {
114
143
  return reply.status(400).send({
115
144
  error: "param name is invalid: 2",
@@ -126,7 +155,8 @@ export default async function suggest(req, reply) {
126
155
  return meta;
127
156
  }
128
157
  const { arr, searchQuery } = meta;
129
- if (arr && table && column) {
158
+ // table:column + cls
159
+ if (arr && tableName && column) {
130
160
  const sqlCls = query.count
131
161
  ? `select value, count(*) from (select ${pg.pgType?.[dataTypeID]?.includes("[]")
132
162
  ? `unnest(${columnName})`
@@ -181,6 +211,7 @@ export default async function suggest(req, reply) {
181
211
  };
182
212
  }
183
213
  }
214
+ // cls
184
215
  if (arr) {
185
216
  const lower = query.key?.toLowerCase();
186
217
  const data1 = query.key || query.val
@@ -207,32 +238,30 @@ export default async function suggest(req, reply) {
207
238
  data,
208
239
  };
209
240
  }
210
- // search
241
+ // select, with search by text support
211
242
  const search = query.key ? searchQuery : null;
212
- // val
213
- // const pk = meta.originalCols.split(',')[0];
214
- // return meta;
243
+ // filter by value
215
244
  const val = query.val
216
- ? ` ${meta.pk}=any('{${query.val.replace(/'/g, "''")}}')`
245
+ ? `${meta.pk}=any('{${query.val.replace(/'/g, "''")}}')`
217
246
  : "";
218
- const where = [search, val, meta.pk ? `${meta.pk} is not null` : null]
219
- .filter(Boolean)
220
- .join(" and ") || "true";
221
- const filter = table && pg.pk?.[table] && columnName && dataTypeID
247
+ const filter = tableName && pg.pk?.[tableName] && columnName && dataTypeID
222
248
  ? `id in (select ${pg.pgType[dataTypeID]?.includes("[]")
223
249
  ? `unnest(${columnName})`
224
- : columnName} from ${table.replace(/'/g, "''")})`
250
+ : columnName} from ${tableName.replace(/'/g, "''")})`
225
251
  : "true";
252
+ const where = [search, val, filter, meta.pk ? `${meta.pk} is not null` : null]
253
+ .filter(Boolean)
254
+ .join(" and ") || "true";
226
255
  const sqlSuggest = `with c(id,text) as ( ${meta.original.replace(/{{parent}}/gi, parent)} where ${where} ${meta.original.includes("order by") ? "" : "order by 2"}) select * from c where ${filter} limit ${Math.min(query.limit || meta.limit || limit, limit)}`.replace(/{{uid}}/g, user?.uid || "0");
227
256
  if (query.sql && debugMode) {
228
257
  return sqlSuggest;
229
258
  }
230
- // query
231
259
  const { rows: dataNew } = await pg.query(sqlSuggest, query.key ? [query.key.toLowerCase()] : []);
232
260
  // in case id / text = Boolean
233
261
  const data = dataNew.filter((el) => Object.hasOwn(el, "id") && Object.hasOwn(el, "text"));
262
+ // table:column + select
234
263
  if (tableName && column) {
235
- const { name = query.sel || column, type = "select" } = getColumnCLS(tableName, column) || {};
264
+ const { name = selectName || column, type = "select" } = getColumnCLS(tableName, column) || {};
236
265
  await metaFormat({
237
266
  rows: data,
238
267
  table: tableName,
@@ -270,7 +299,6 @@ export default async function suggest(req, reply) {
270
299
  data,
271
300
  dataNew,
272
301
  sqlSuggest,
273
- // ids,
274
302
  });
275
303
  }
276
304
  const message = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengis/fastify-table",
3
- "version": "2.0.126",
3
+ "version": "2.0.127",
4
4
  "type": "module",
5
5
  "description": "core-plugins",
6
6
  "keywords": [