@opengis/fastify-table 2.0.106 → 2.0.107

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 (102) hide show
  1. package/dist/config.d.ts.map +1 -1
  2. package/dist/script/adduser +15 -0
  3. package/dist/script/dump.js +176 -0
  4. package/dist/script/migrate.js +25 -0
  5. package/dist/server/plugins/auth/funcs/verifyPassword.d.ts.map +1 -1
  6. package/dist/server/plugins/auth/funcs/verifyPassword.js +3 -1
  7. package/dist/server/plugins/crud/funcs/dataInsert.js +1 -1
  8. package/dist/server/plugins/crud/funcs/dataUpdate.d.ts.map +1 -1
  9. package/dist/server/plugins/crud/funcs/dataUpdate.js +7 -4
  10. package/dist/server/plugins/logger/getLogger.d.ts.map +1 -1
  11. package/dist/server/plugins/logger/getLogger.js +13 -10
  12. package/dist/server/plugins/logger/index.d.ts.map +1 -1
  13. package/dist/server/plugins/logger/index.js +2 -1
  14. package/dist/server/plugins/pg/funcs/getPG.d.ts.map +1 -1
  15. package/dist/server/plugins/pg/funcs/getPG.js +1 -0
  16. package/dist/server/plugins/pg/funcs/getPGAsync.js +1 -1
  17. package/dist/server/plugins/pg/funcs/init.d.ts +1 -1
  18. package/dist/server/plugins/pg/funcs/init.d.ts.map +1 -1
  19. package/dist/server/plugins/pg/funcs/init.js +20 -5
  20. package/dist/server/plugins/pg/funcs/pool.d.ts.map +1 -1
  21. package/dist/server/plugins/pg/funcs/pool.js +10 -16
  22. package/dist/server/plugins/pg/index.d.ts.map +1 -1
  23. package/dist/server/plugins/pg/index.js +3 -2
  24. package/dist/server/plugins/redis/funcs/getRedis.d.ts.map +1 -1
  25. package/dist/server/plugins/redis/funcs/getRedis.js +6 -4
  26. package/dist/server/plugins/redis/index.d.ts.map +1 -1
  27. package/dist/server/plugins/redis/index.js +4 -1
  28. package/dist/server/plugins/sqlite/index.d.ts.map +1 -1
  29. package/dist/server/plugins/sqlite/index.js +7 -3
  30. package/dist/server/plugins/table/funcs/getFilter.d.ts +1 -1
  31. package/dist/server/plugins/table/funcs/getFilter.d.ts.map +1 -1
  32. package/dist/server/plugins/table/funcs/getFilter.js +14 -1
  33. package/dist/server/plugins/table/funcs/getSelectMeta.d.ts.map +1 -1
  34. package/dist/server/plugins/table/funcs/getSelectMeta.js +2 -4
  35. package/dist/server/plugins/table/funcs/gisIRColumn.d.ts +2 -2
  36. package/dist/server/plugins/table/funcs/gisIRColumn.js +1 -1
  37. package/dist/server/plugins/util/funcs/unflattenObject.d.ts.map +1 -1
  38. package/dist/server/plugins/util/funcs/unflattenObject.js +3 -1
  39. package/dist/server/routes/access/controllers/access.group.d.ts +2 -2
  40. package/dist/server/routes/access/controllers/access.group.d.ts.map +1 -1
  41. package/dist/server/routes/access/controllers/access.group.js +0 -1
  42. package/dist/server/routes/access/controllers/access.group.post.d.ts +2 -2
  43. package/dist/server/routes/access/controllers/access.group.post.d.ts.map +1 -1
  44. package/dist/server/routes/access/controllers/access.group.post.js +0 -1
  45. package/dist/server/routes/auth/controllers/core/registration.d.ts +1 -4
  46. package/dist/server/routes/auth/controllers/core/registration.d.ts.map +1 -1
  47. package/dist/server/routes/auth/controllers/core/registration.js +28 -9
  48. package/dist/server/routes/auth/controllers/core/updateUserInfo.js +1 -1
  49. package/dist/server/routes/auth/controllers/jwt/authorize.js +5 -5
  50. package/dist/server/routes/auth/controllers/jwt/token.d.ts.map +1 -1
  51. package/dist/server/routes/auth/controllers/jwt/token.js +10 -12
  52. package/dist/server/routes/cron/controllers/cronApi.d.ts +1 -1
  53. package/dist/server/routes/cron/controllers/cronApi.d.ts.map +1 -1
  54. package/dist/server/routes/cron/controllers/cronApi.js +5 -3
  55. package/dist/server/routes/crud/controllers/insert.d.ts +1 -4
  56. package/dist/server/routes/crud/controllers/insert.d.ts.map +1 -1
  57. package/dist/server/routes/crud/controllers/insert.js +24 -16
  58. package/dist/server/routes/crud/controllers/table.d.ts.map +1 -1
  59. package/dist/server/routes/crud/controllers/table.js +13 -6
  60. package/dist/server/routes/crud/controllers/update.d.ts.map +1 -1
  61. package/dist/server/routes/crud/controllers/update.js +23 -15
  62. package/dist/server/routes/file/controllers/delete.d.ts +1 -15
  63. package/dist/server/routes/file/controllers/delete.d.ts.map +1 -1
  64. package/dist/server/routes/file/controllers/delete.js +13 -20
  65. package/dist/server/routes/file/controllers/download.d.ts +2 -2
  66. package/dist/server/routes/file/controllers/download.d.ts.map +1 -1
  67. package/dist/server/routes/file/controllers/download.js +39 -30
  68. package/dist/server/routes/file/controllers/files.d.ts +2 -1
  69. package/dist/server/routes/file/controllers/files.d.ts.map +1 -1
  70. package/dist/server/routes/file/controllers/files.js +15 -11
  71. package/dist/server/routes/file/controllers/resize.d.ts +1 -2
  72. package/dist/server/routes/file/controllers/resize.d.ts.map +1 -1
  73. package/dist/server/routes/file/controllers/resize.js +17 -6
  74. package/dist/server/routes/file/controllers/upload.d.ts.map +1 -1
  75. package/dist/server/routes/file/controllers/upload.js +17 -16
  76. package/dist/server/routes/file/controllers/uploadImage.d.ts +11 -13
  77. package/dist/server/routes/file/controllers/uploadImage.d.ts.map +1 -1
  78. package/dist/server/routes/file/controllers/uploadImage.js +13 -15
  79. package/dist/server/routes/logger/controllers/logger.file.js +1 -1
  80. package/dist/server/routes/menu/controllers/interfaces.d.ts +1 -7
  81. package/dist/server/routes/menu/controllers/interfaces.d.ts.map +1 -1
  82. package/dist/server/routes/table/controllers/card.d.ts +1 -1
  83. package/dist/server/routes/table/controllers/card.d.ts.map +1 -1
  84. package/dist/server/routes/table/controllers/card.js +15 -9
  85. package/dist/server/routes/table/controllers/filter.d.ts +1 -1
  86. package/dist/server/routes/table/controllers/filter.d.ts.map +1 -1
  87. package/dist/server/routes/table/controllers/filter.js +2 -2
  88. package/dist/server/routes/table/controllers/form.d.ts +1 -1
  89. package/dist/server/routes/table/controllers/form.d.ts.map +1 -1
  90. package/dist/server/routes/table/controllers/form.js +8 -5
  91. package/dist/server/routes/table/controllers/search.d.ts +1 -1
  92. package/dist/server/routes/table/controllers/search.d.ts.map +1 -1
  93. package/dist/server/routes/table/controllers/search.js +5 -6
  94. package/dist/server/routes/table/controllers/suggest.d.ts +1 -1
  95. package/dist/server/routes/table/controllers/suggest.d.ts.map +1 -1
  96. package/dist/server/routes/table/controllers/suggest.js +30 -15
  97. package/dist/server/routes/table/functions/getData.d.ts +1 -1
  98. package/dist/server/routes/table/functions/getData.d.ts.map +1 -1
  99. package/dist/server/routes/table/functions/getData.js +60 -34
  100. package/dist/server/types/core.d.ts +7 -0
  101. package/dist/server/types/core.d.ts.map +1 -1
  102. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../config.ts"],"names":[],"mappings":"AAWA,QAAA,MAAM,MAAM,KAA8D,CAAC;AAoC3E,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../config.ts"],"names":[],"mappings":"AAWA,QAAA,MAAM,MAAM,KAA8D,CAAC;AAqC3E,eAAe,MAAM,CAAC"}
@@ -0,0 +1,15 @@
1
+ #!/bin/bash
2
+ rootDir=`echo $(dirname "$0")`
3
+ echo "$rootDir/passwd"
4
+
5
+ if [ -e "$rootDir/../passwd" ]
6
+ then
7
+ password=`echo -n "$2" | sha1sum | awk '{print $1}'`
8
+ echo "$1:$password"
9
+ echo "$1:$password" >> "$rootDir/../passwd"
10
+ else
11
+ > passwd
12
+ password=`echo -n "$2" | sha1sum | awk '{print $1}'`
13
+ echo "$1:$password"
14
+ echo "$1:$password" > "$rootDir/../passwd"
15
+ fi
@@ -0,0 +1,176 @@
1
+ // Вигрузка схеми бд
2
+ // Usage examples:
3
+ // bun .\script\dump.js --table=bpmn.tasks
4
+ // bun .\script\dump.js --schema=bpmn
5
+
6
+ import path from 'node:path';
7
+ import { existsSync } from 'node:fs';
8
+ import { mkdir, writeFile, rm, rmdir, stat } from 'node:fs/promises';
9
+
10
+ import { config, handlebars, pgClients, getTemplate } from '../utils.js';
11
+
12
+ import { build, teardown } from '../helper.js';
13
+
14
+ const app = build();
15
+ app.addHook('onClose', async () => teardown());
16
+ dumpMigrateSQL();
17
+ // app.close();
18
+
19
+ const debug = false;
20
+
21
+ export default async function dumpMigrateSQL() {
22
+ try {
23
+ // const { database, host, port, user, password } = config.pg;
24
+
25
+ if (!config.pg) {
26
+ console.error('empty config.pg, skip...');
27
+ return null;
28
+ }
29
+
30
+ if (!Bun.argv[2]) {
31
+ console.error('missing schema / table name, skip...');
32
+ }
33
+
34
+ const [key, value] = Bun.argv[2].substring(2).split('=');
35
+ const tableName = key === 'table' ? value : null;
36
+ const schemaName = key === 'schema' ? value : value.split('.').shift();
37
+
38
+ const pg = pgClients.client;
39
+ // const pg = await getPGAsync({ database, host, port, user, password });
40
+ await pg.query(`select 1`);
41
+
42
+ const schemaExists = await pg.query(`SELECT 1 FROM information_schema.schemata WHERE schema_name = $1`, [schemaName]).then(el => el.rowCount);
43
+
44
+ if (!schemaExists) {
45
+ console.error('Вказаної схеми не існує', config.pg?.database);
46
+ return null;
47
+ }
48
+
49
+ // if (tableName && !pg.pk?.[tableName]) {
50
+ // console.error('Вказаної таблиці не існує', config.pg?.database);
51
+ // return null;
52
+ // }
53
+
54
+ const dump = await schemaItem({
55
+ pg,
56
+ table: tableName,
57
+ schema: schemaName,
58
+ debug,
59
+ is_erd: false
60
+ });
61
+
62
+ if (debug) {
63
+ console.log(dump);
64
+ return null;
65
+ }
66
+
67
+ const filepath = await saveFile(dump, tableName || schemaName);
68
+ console.log('sucess', filepath);
69
+ } catch (err) {
70
+ console.error(err);
71
+ } finally {
72
+ app.close();
73
+ }
74
+ }
75
+
76
+ async function saveFile(data, filename) {
77
+ if (!data) throw new Error(`no data - ${filename}`);
78
+
79
+ const filepath = path.join('log/dump', `${filename}.sql`);
80
+ const fileExists = existsSync(filepath);
81
+
82
+ // overwrite old file
83
+ if (fileExists) {
84
+ const stats = await stat(filepath);
85
+ if (stats.isDirectory()) {
86
+ await rmdir(filepath, { force: true, recursive: true });
87
+ } else {
88
+ await rm(filepath)
89
+ }
90
+ }
91
+
92
+ await mkdir(path.dirname(filepath), { recursive: true });
93
+ await writeFile(filepath, Buffer.from(data, 'utf-8'));
94
+
95
+ return filepath;
96
+ }
97
+
98
+ async function schemaItem({
99
+ pg, table, schema, debug
100
+ }) {
101
+ if (!schema && !table) return new Error('param schema is required');
102
+
103
+ const { rows: schemaInfo } = await pg.query(`select c.oid,relname,nspname,obj_description(c.oid) as description,
104
+ (
105
+ select json_agg(row_to_json(q))
106
+ from (
107
+ select
108
+ column_name,
109
+ case
110
+ when data_type='USER-DEFINED' AND udt_name='geometry' THEN 'geometry'
111
+ when data_type='ARRAY' AND udt_name='_text' THEN 'text[]'
112
+ when data_type='ARRAY' AND udt_name='_int4' THEN 'integer[]'
113
+ else data_type
114
+ end as data_type,
115
+ ordinal_position,
116
+ column_default,
117
+ is_nullable,
118
+ case
119
+ when column_name='uid' then 'ідентифікатор автора запису в БД'
120
+ when column_name='cdate' then 'Дата створення запису в БД'
121
+ when column_name='editor_id' then 'Ідентифікатор автора, який останій вніс зміни в запис'
122
+ when column_name='editor_date' then 'Час останії зміни в записі'
123
+ when column_name='files' then 'Системна колонка'
124
+ when column_name='doc_status' then 'Статус документа'
125
+ when column_name='reg_status' then 'Статус реєстрації'
126
+ when column_name='obj_version' then 'Версія запису'
127
+ else col_description(a.attrelid,ordinal_position)
128
+ end as description
129
+ from information_schema.columns col
130
+ LEFT JOIN pg_attribute a ON col.column_name=a.attname and c.oid = a.attrelid
131
+ where col.table_schema=nspname and col.table_name=relname
132
+ )q
133
+ ) as columns
134
+ from pg_class c
135
+ LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
136
+ where ${table ? `nspname||'.'||relname='${table}'` : `'${schema}'=nspname`} and relam=2
137
+ order by nspname,relname`);
138
+
139
+ if (!schemaInfo?.length) throw new Error('invalid params');
140
+
141
+ const { rows: constraints } = await pg.query(`select con.conrelid::regclass as constraint_table, a.column_name,
142
+ con.conname as constraint_name,contype as constraint_type, con.confrelid::regclass as foreign_table,
143
+ con.confupdtype, con.confdeltype, con.confmatchtype, u.column_name as foreign_column from pg_constraint con
144
+ left join pg_class c ON c.oid = con.conrelid
145
+ left join pg_namespace n ON n.oid = c.relnamespace
146
+ left join lateral (
147
+ select string_agg(a.attname,',') as column_name from pg_attribute a
148
+ where con.conrelid = a.attrelid and a.attnum = any(con.conkey) limit 1
149
+ )a on 1=1
150
+ left join lateral (
151
+ select column_name from information_schema.constraint_column_usage u
152
+ where conname=u.constraint_name limit 1
153
+ )u on 1=1
154
+ where ${table ? `conrelid::regclass::text = '${table}'` : `nspname = '${schema}'`}`);
155
+
156
+ // add table constraints, mermaid
157
+ schemaInfo?.forEach((row) => {
158
+ // constraint type to column
159
+ row?.columns?.forEach((col) => {
160
+ const { constraint_type } = constraints?.find((con) => con?.column_name === col?.column_name && con.constraint_table === `${row.nspname}.${row.relname}`) || {};
161
+ Object.assign(col, { constraint_type });
162
+ });
163
+
164
+ // table relations
165
+ const tableConstraints = constraints?.filter((el) => el?.constraint_table === `${row.nspname}.${row.relname}`);
166
+ Object.assign(row, { constraints: tableConstraints });
167
+ });
168
+
169
+ if (debug) return schemaInfo;
170
+
171
+ const body = await getTemplate('pt', 'schemaItem.pt');
172
+
173
+ const schemaContent = await handlebars.compile(body?.hbs || 'template not found: schemaItem.pt')({ nspname: schema, rows: schemaInfo, constraints });
174
+
175
+ return schemaContent.replace(/'/g, "'");
176
+ }
@@ -0,0 +1,25 @@
1
+ import Fastify from 'fastify';
2
+
3
+ import config from '../config.js';
4
+ import plugin from '../index.js';
5
+
6
+ const timeoutMs = +(config.migrationTimeout || 5000);
7
+
8
+ process.env.PORT = process.env.PORT || config.port || 3000;
9
+
10
+ const app = Fastify();
11
+
12
+ app.register(plugin, config);
13
+
14
+ app.listen({ host: '0.0.0.0', port: process.env.PORT }, (err) => {
15
+ console.log(`Server started via port: ${process.env.PORT}`);
16
+ setTimeout(() => {
17
+ console.log('Server closed after timeout', timeoutMs);
18
+ app.close();
19
+ process.exit(0);
20
+ }, timeoutMs);
21
+ if (err) {
22
+ console.error('migrations error', err.toString());
23
+ process.exit(1);
24
+ }
25
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"verifyPassword.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/auth/funcs/verifyPassword.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAWpD,wBAA8B,cAAc,CAAC,EAC3C,EAAE,EACF,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,EAAE,EAAE,UAAU,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;;;;;;eA+BA"}
1
+ {"version":3,"file":"verifyPassword.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/auth/funcs/verifyPassword.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAWpD,wBAA8B,cAAc,CAAC,EAC3C,EAAE,EACF,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,EAAE,EAAE,UAAU,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;;;;;;eAiCA"}
@@ -12,7 +12,9 @@ export default async function verifyPassword({ pg, username, password, }) {
12
12
  if (!password || password === "")
13
13
  return { message: "not enough params: password" };
14
14
  const query = "select * from admin.users where $1 in (login,email,phone) and enabled limit 1";
15
- const json = await pg.query(query, [username]).then((res) => res.rows[0]);
15
+ const json = await pg
16
+ .query(query, [username])
17
+ .then((el) => el.rows?.[0] || {});
16
18
  if (!json)
17
19
  return { message: "user not found" };
18
20
  let hash = "";
@@ -103,7 +103,7 @@ export default async function dataInsert({ id, table: table1, referer, data, pg:
103
103
  uid,
104
104
  type: "INSERT",
105
105
  });
106
- if (config.redis) {
106
+ if (config.redis && rclient?.status !== "end") {
107
107
  rclient.incr(`pg:${table}:crud`);
108
108
  }
109
109
  if (!isClient) {
@@ -1 +1 @@
1
- {"version":3,"file":"dataUpdate.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/crud/funcs/dataUpdate.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAepD,wBAA8B,UAAU,CAAC,EACvC,KAAK,EACL,SAAS,EACT,OAAO,EACP,EAAE,EACF,IAAI,EACJ,EAAE,EAAE,GAAG,EACP,GAAG,GACJ,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1B,EAAE,CAAC,EAAE,UAAU,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,gBA4OA"}
1
+ {"version":3,"file":"dataUpdate.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/crud/funcs/dataUpdate.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAepD,wBAA8B,UAAU,CAAC,EACvC,KAAK,EACL,SAAS,EACT,OAAO,EACP,EAAE,EACF,IAAI,EACJ,EAAE,EAAE,GAAG,EACP,GAAG,GACJ,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1B,EAAE,CAAC,EAAE,UAAU,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,gBAkPA"}
@@ -20,11 +20,13 @@ function assignValue(key, i, srid = 4326, columnType = "text") {
20
20
  return `"${key}"=$${i + 2}`;
21
21
  }
22
22
  export default async function dataUpdate({ table, tokenData, referer, id, data, pg: pg1, uid, }) {
23
- if (!data || !table || !id)
23
+ if (!data || !table || !id) {
24
24
  return null;
25
+ }
25
26
  const pg = pg1 || getPG({ name: "client" });
26
- if (!pg)
27
+ if (!pg) {
27
28
  return null;
29
+ }
28
30
  // pg client single transaction support
29
31
  if (!pg?.pk && config.pg) {
30
32
  pg.options = pgClients.client?.options;
@@ -34,8 +36,9 @@ export default async function dataUpdate({ table, tokenData, referer, id, data,
34
36
  pg.pk = pgClients.client?.pk;
35
37
  }
36
38
  const { columns, pk } = await getMeta({ pg, table });
37
- if (!columns)
39
+ if (!columns) {
38
40
  return null;
41
+ }
39
42
  const names = columns.map((el) => el.name);
40
43
  const types = columns.reduce((acc, { name, dataTypeID }) => ({
41
44
  ...acc,
@@ -167,7 +170,7 @@ export default async function dataUpdate({ table, tokenData, referer, id, data,
167
170
  uid,
168
171
  type: "UPDATE",
169
172
  });
170
- if (config.redis) {
173
+ if (config.redis && rclient?.status !== "end") {
171
174
  rclient.incr(`pg:${table}:crud`);
172
175
  }
173
176
  if (!isClient) {
@@ -1 +1 @@
1
- {"version":3,"file":"getLogger.d.ts","sourceRoot":"","sources":["../../../../server/plugins/logger/getLogger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,UAAU,cAAe,SAAQ,IAAI,CAAC,MAAM;IAC1C,IAAI,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,cAAc,KAAK,IAAI,CAAC;IAClE,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5D;AAgDD,QAAA,MAAM,MAAM,EAAE,cAAgD,CAAC;AA+B/D,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"getLogger.d.ts","sourceRoot":"","sources":["../../../../server/plugins/logger/getLogger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,UAAU,cAAe,SAAQ,IAAI,CAAC,MAAM;IAC1C,IAAI,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,cAAc,KAAK,IAAI,CAAC;IAClE,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5D;AAmDD,QAAA,MAAM,MAAM,EAAE,cAAgD,CAAC;AA+B/D,eAAe,MAAM,CAAC"}
@@ -9,16 +9,19 @@ import timestampWithTimeZone from "./timestampWithTimeZone.js";
9
9
  const isServer = process.argv[2];
10
10
  const level = process.env.LOG_LEVEL || "info";
11
11
  console.log(`log level: ${level}`);
12
- const targets = [
13
- {
14
- target: "./createFileStream.js", // path.resolve('utils/createFileStream.js')
15
- },
16
- {
17
- level: "error",
18
- target: "pino/file",
19
- options: { destination: 1 },
20
- },
21
- ];
12
+ // skip logging during npx vitest run
13
+ const targets = process.env.VITEST
14
+ ? []
15
+ : [
16
+ {
17
+ target: "./createFileStream.js", // path.resolve('utils/createFileStream.js')
18
+ },
19
+ {
20
+ level: "error",
21
+ target: "pino/file",
22
+ options: { destination: 1 },
23
+ },
24
+ ];
22
25
  // push trace logs to console (those would not be saved to file)
23
26
  if (["trace", "debug"].includes(level)) {
24
27
  targets.push({
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/plugins/logger/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AAsC7E,iBAAe,MAAM,CAAC,OAAO,EAAE,eAAe,iBAwC7C;AACD,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/plugins/logger/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AAyC7E,iBAAe,MAAM,CAAC,OAAO,EAAE,eAAe,iBAwC7C;AACD,eAAe,MAAM,CAAC"}
@@ -21,7 +21,8 @@ process.on("unhandledRejection", (err) => {
21
21
  console.warn("Ignored pg connection timeout / close:", err.toString());
22
22
  return;
23
23
  }
24
- if (err.message === "Connection is closed.") {
24
+ if (err.message === "Connection is closed." ||
25
+ err.message.includes("maxRetriesPerRequest")) {
25
26
  logger.file("redis", { error: err.message });
26
27
  console.warn("Ignored redis connection close:", err.toString());
27
28
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"getPG.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/pg/funcs/getPG.ts"],"names":[],"mappings":"AAQA,iBAAS,KAAK,CAAC,KAAK,GAAE,GAAQ,OAuD7B;AAMD,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"getPG.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/pg/funcs/getPG.ts"],"names":[],"mappings":"AAQA,iBAAS,KAAK,CAAC,KAAK,GAAE,GAAQ,OAyD7B;AAMD,eAAe,KAAK,CAAC"}
@@ -5,6 +5,7 @@ import dblist from "../../../../dblist.js";
5
5
  import pgClients from "../pgClients.js";
6
6
  import getDBParams from "./getDBParams.js";
7
7
  function getPG(param = {}) {
8
+ // console.log("config.pg", config.pg, process.env); // ! process.env.VITEST always in uppercase, debug to properly test via npx vitest run
8
9
  if (!config.pg)
9
10
  return null;
10
11
  const dbListParams = dblist.find((el) => el.key === param?.key) ||
@@ -2,7 +2,7 @@ import init from "./init.js";
2
2
  import getPG from "./getPG.js";
3
3
  async function getPGAsync(param) {
4
4
  const client = getPG(param);
5
- const { host, port, database } = client.options || {};
5
+ const { host, port, database } = client?.options || {};
6
6
  if (client && !client.tlist) {
7
7
  // force init
8
8
  await init(client).catch((err) => console.warn("PG client init error", host, port, database));
@@ -1,4 +1,4 @@
1
1
  import { ExtendedPG } from "../../../types/core.js";
2
- declare function init(client: ExtendedPG): Promise<void>;
2
+ declare function init(client?: ExtendedPG): Promise<void>;
3
3
  export default init;
4
4
  //# sourceMappingURL=init.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/pg/funcs/init.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAIpD,iBAAe,IAAI,CAAC,MAAM,EAAE,UAAU,iBAsMrC;AAGD,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/pg/funcs/init.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAIpD,iBAAe,IAAI,CAAC,MAAM,CAAC,EAAE,UAAU,iBAuNtC;AAGD,eAAe,IAAI,CAAC"}
@@ -5,7 +5,17 @@ import getRedis from "../../redis/funcs/getRedis.js";
5
5
  import logger from "../../logger/getLogger.js";
6
6
  const rclient = getRedis({ db: 0 });
7
7
  async function init(client) {
8
- if (!client?.options?.database) {
8
+ if (!client)
9
+ return;
10
+ // for unit tests
11
+ const options = client.options || {
12
+ database: client.database,
13
+ user: client.user,
14
+ password: client.password,
15
+ port: client.port,
16
+ host: client.host,
17
+ };
18
+ if (!client || !client.query || !client.connect) {
9
19
  return;
10
20
  }
11
21
  const { pgType, pk } = await client
@@ -72,6 +82,8 @@ async function init(client) {
72
82
  .then((el) => el.rows || []);
73
83
  const relkinds = rows.reduce((acc, curr) => Object.assign(acc, { [curr.tname]: curr.relkind }), {});
74
84
  async function query(q, args = []) {
85
+ if (!client)
86
+ throw new Error("empty pg client");
75
87
  try {
76
88
  const data = await client.query(q, args);
77
89
  return data;
@@ -86,7 +98,7 @@ async function init(client) {
86
98
  }
87
99
  async function querySafe(q, param) {
88
100
  const pg1 = new pg.Pool({
89
- ...client.options,
101
+ ...options,
90
102
  statement_timeout: param?.timeout || 100000000,
91
103
  });
92
104
  try {
@@ -114,6 +126,8 @@ async function init(client) {
114
126
  return result;
115
127
  }
116
128
  async function queryNotice(q, args, cb = () => { }) {
129
+ if (!client)
130
+ throw new Error("empty pg client");
117
131
  const clientCb = await client.connect();
118
132
  clientCb.on("notice", (e) => {
119
133
  cb(e.message);
@@ -159,6 +173,8 @@ async function init(client) {
159
173
  return data;
160
174
  }
161
175
  Object.assign(client, {
176
+ ...options,
177
+ options,
162
178
  one,
163
179
  pgType,
164
180
  pk,
@@ -168,11 +184,10 @@ async function init(client) {
168
184
  queryNotice,
169
185
  querySafe,
170
186
  });
171
- // client.init = undefined;
172
- console.log("New client init finished", client.options?.database);
187
+ console.log("New client init finished", client.database);
173
188
  logger.file("pg", {
174
189
  message: "client init finished",
175
- database: client.options?.database,
190
+ database: client.database,
176
191
  });
177
192
  }
178
193
  // export default client;
@@ -1 +1 @@
1
- {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/pg/funcs/pool.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,CAAC;yBAK7B,QAAO,GAAQ;AAA/B,wBAsEE"}
1
+ {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/pg/funcs/pool.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,CAAC;yBAE7B,QAAO,GAAQ;AAA/B,wBAgEE"}
@@ -6,9 +6,8 @@ types.setTypeParser(1114, (stringValue) => stringValue);
6
6
  import pgClients from "../pgClients.js";
7
7
  import init from "./init.js";
8
8
  import config from "../../../../config.js";
9
+ config.ready = config.ready || {};
9
10
  export const Pools = {};
10
- const errored = {};
11
- const inited = {};
12
11
  export default (param = {}) => {
13
12
  if (!config.pg)
14
13
  return null;
@@ -27,7 +26,7 @@ export default (param = {}) => {
27
26
  });
28
27
  pool.on("error", (err) => {
29
28
  console.warn("Unexpected error on idle client", param.database);
30
- errored[param.database] = 1;
29
+ config.ready[`pg:${param.database}`] = false;
31
30
  logger.file("pg", {
32
31
  error: err.toString(),
33
32
  database: param.database,
@@ -36,14 +35,14 @@ export default (param = {}) => {
36
35
  console.warn("Unexpected error on idle client details:", err.toString(), err.stack);
37
36
  }
38
37
  });
39
- pool.on("connect", (client) => {
38
+ pool.on("connect", () => {
40
39
  // skip auto drops and reconnects handled by pg internally
41
- if (!inited[param.database] || errored[param.database]) {
40
+ if (!config.ready[`pg:${param.database}`]) {
42
41
  logger.file("pg", {
43
42
  message: "client connected",
44
43
  database: param.database,
45
44
  });
46
- inited[param.database] = 1;
45
+ config.ready[`pg:${param.database}`] = true;
47
46
  }
48
47
  if (config.trace) {
49
48
  console.log("PG client connected", param.database);
@@ -52,17 +51,12 @@ export default (param = {}) => {
52
51
  if (pgClients[name] && !pgClients[name]?.tlist) {
53
52
  init(Pools[name]);
54
53
  }
55
- Pools[name] = client;
54
+ Pools[name] = pool;
56
55
  });
57
- pool.on("acquire", () => {
58
- if (config.trace) {
59
- console.log("PG client acquired", param.database);
60
- }
61
- });
62
- pool.on("remove", () => {
63
- if (config.trace) {
56
+ if (config.trace) {
57
+ pool.on("remove", () => {
64
58
  console.log("PG Client removed from the pool.", param.database);
65
- }
66
- });
59
+ });
60
+ }
67
61
  return pool;
68
62
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/plugins/pg/index.ts"],"names":[],"mappings":"AA+BA,iBAAS,MAAM,CAAC,OAAO,EAAE,GAAG,QAwB3B;AAED,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/plugins/pg/index.ts"],"names":[],"mappings":"AAgCA,iBAAS,MAAM,CAAC,OAAO,EAAE,GAAG,QAwB3B;AAED,eAAe,MAAM,CAAC"}
@@ -3,8 +3,9 @@ import pgClients from "./pgClients.js";
3
3
  import getPGAsync from "./funcs/getPGAsync.js";
4
4
  import logger from "../logger/getLogger.js";
5
5
  function close() {
6
- Object.keys(pgClients).forEach((el) => {
7
- pgClients[el].end();
6
+ Object.keys(pgClients).forEach((key) => {
7
+ console.log("Closing pg client", key);
8
+ pgClients[key].end();
8
9
  });
9
10
  }
10
11
  async function getHeadersPG(req) {
@@ -1 +1 @@
1
- {"version":3,"file":"getRedis.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/redis/funcs/getRedis.ts"],"names":[],"mappings":"AAQA,iBAAS,QAAQ,CACf,EACE,EAAE,EACF,IAAI,EACJ,IAAI,EACJ,WAAkB,EAClB,aAAwB,EACxB,kBAAyB,EACzB,WAAkB,EAClB,cAAqB,EACrB,oBAAwB,GACzB,GAAE;IACD,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,GAAG,CAAC;IACpB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CACnB,OAwCd;AAED,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"getRedis.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/redis/funcs/getRedis.ts"],"names":[],"mappings":"AAQA,iBAAS,QAAQ,CACf,EACE,EAAE,EACF,IAAI,EACJ,IAAI,EACJ,WAAmB,EACnB,aAA8D,EAC9D,kBAAyB,EACzB,WAAkB,EAClB,cAAqB,EACrB,oBAAwB,GACzB,GAAE;IACD,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,GAAG,CAAC;IACpB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CACnB,OA6Cd;AAED,eAAe,QAAQ,CAAC"}
@@ -3,10 +3,15 @@ import config from "../../../../config.js";
3
3
  import logger from "../../logger/getLogger.js";
4
4
  import redisClients from "./redisClients.js";
5
5
  config.ready = config.ready || {};
6
- function getRedis({ db, host, port, closeClient = true, retryStrategy = () => { }, enableOfflineQueue = true, lazyConnect = true, connectTimeout = 2000, maxRetriesPerRequest = 0, } = { db: 0 }) {
6
+ function getRedis({ db, host, port, closeClient = false, retryStrategy = (times) => Math.min(times * 500, 5000), enableOfflineQueue = true, lazyConnect = true, connectTimeout = 2000, maxRetriesPerRequest = 1, } = { db: 0 }) {
7
7
  if (!config.redis && !host)
8
8
  return null;
9
9
  const key = host || port ? [host, port, db].join("-") : db;
10
+ // try to reconnect after connection error / disconnect
11
+ if (redisClients[key]?.status === "end" &&
12
+ typeof redisClients[key].connect === "function") {
13
+ redisClients[key].connect();
14
+ }
10
15
  if (redisClients[key]) {
11
16
  return redisClients[key];
12
17
  }
@@ -30,9 +35,6 @@ function getRedis({ db, host, port, closeClient = true, retryStrategy = () => {
30
35
  redisClients[key].on("error", (err) => {
31
36
  console.warn("Ignored redis error:", err.message);
32
37
  logger.file("redis", { error: err.toString() });
33
- if (err.code === "ETIMEDOUT") {
34
- // redisClients[key].disconnect();
35
- }
36
38
  });
37
39
  console.log("redis connected", db, host, port);
38
40
  return redisClients[key];
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/plugins/redis/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,SAAS,CAAC;AAQ/C,iBAAe,MAAM,CAAC,OAAO,EAAE,eAAe,iBAE7C;AAED,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/plugins/redis/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,SAAS,CAAC;AAW/C,iBAAe,MAAM,CAAC,OAAO,EAAE,eAAe,iBAE7C;AAED,eAAe,MAAM,CAAC"}
@@ -1,6 +1,9 @@
1
1
  import redisClients from "./funcs/redisClients.js";
2
2
  function close() {
3
- Object.keys(redisClients).forEach((key) => redisClients[key].quit());
3
+ Object.keys(redisClients).forEach((key) => {
4
+ console.log("Closing redis client", key);
5
+ redisClients[key].quit();
6
+ });
4
7
  }
5
8
  async function plugin(fastify) {
6
9
  fastify.addHook("onClose", close);
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/plugins/sqlite/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAM1C,iBAAe,QAAQ,CAAC,GAAG,EAAE,eAAe,iBAI3C;;AAED,wBAA4B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/plugins/sqlite/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAa1C,iBAAe,QAAQ,CAAC,GAAG,EAAE,eAAe,iBAE3C;;AAED,wBAA4B"}
@@ -1,8 +1,12 @@
1
1
  import fp from "fastify-plugin";
2
2
  import sqliteClients from "./sqliteClients.js";
3
- async function dbPlugin(app) {
4
- app.addHook("onClose", async () => {
5
- Object.keys(sqliteClients).forEach((key) => sqliteClients[key].close());
3
+ function close() {
4
+ Object.keys(sqliteClients).forEach((key) => {
5
+ console.log("Closing sqlite client", key);
6
+ sqliteClients[key].close();
6
7
  });
7
8
  }
9
+ async function dbPlugin(app) {
10
+ app.addHook("onClose", close);
11
+ }
8
12
  export default fp(dbPlugin);
@@ -7,5 +7,5 @@ export default function getFilter({ pg, table, filter, custom, state, search, us
7
7
  state?: string;
8
8
  search?: string;
9
9
  user?: Record<string, any>;
10
- }, reply: any): Promise<any>;
10
+ }, reply?: any): Promise<any>;
11
11
  //# sourceMappingURL=getFilter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getFilter.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/table/funcs/getFilter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGzD,wBAA8B,SAAS,CACrC,EACE,EAAqB,EACrB,KAAK,EACL,MAAM,EACN,MAAM,EACN,KAAK,EACL,MAAM,EACN,IAAI,GACL,EAAE;IACD,EAAE,EAAE,UAAU,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC5B,EACD,KAAK,EAAE,GAAG,gBAoBX"}
1
+ {"version":3,"file":"getFilter.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/table/funcs/getFilter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAmBzD,wBAA8B,SAAS,CACrC,EACE,EAAqB,EACrB,KAAK,EACL,MAAM,EACN,MAAM,EACN,KAAK,EACL,MAAM,EACN,IAAI,GACL,EAAE;IACD,EAAE,EAAE,UAAU,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC5B,EACD,KAAK,CAAC,EAAE,GAAG,gBAoBZ"}