@opengis/fastify-table 1.3.61 → 1.3.63
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/index.js +3 -2
- package/package.json +2 -14
- package/server/migrations/context.sql +1 -0
- package/server/migrations/log.sql +2 -0
- package/server/migrations/properties.sql +1 -0
- package/server/migrations/template.sql +1 -1
- package/server/plugins/logger/getLogger.js +2 -2
- package/server/plugins/migration/exec.migrations.js +3 -2
- package/server/plugins/migration/exec.sql.js +9 -3
- package/server/plugins/pg/funcs/getMeta.js +2 -2
- package/server/plugins/pg/funcs/getPG.js +2 -0
- package/server/plugins/pg/funcs/getPGAsync.js +2 -0
- package/server/plugins/pg/funcs/init.js +10 -5
- package/server/plugins/policy/funcs/checkPolicy.js +1 -1
- package/server/routes/crud/controllers/insert.js +1 -1
package/index.js
CHANGED
|
@@ -33,6 +33,7 @@ import addTemplateDir from './server/plugins/table/funcs/addTemplateDir.js';
|
|
|
33
33
|
import execMigrations from './server/plugins/migration/exec.migrations.js';
|
|
34
34
|
|
|
35
35
|
import locales from './server/routes/table/controllers/utils/locales.js';
|
|
36
|
+
import pgClients from './server/plugins/pg/pgClients.js';
|
|
36
37
|
|
|
37
38
|
// core templates && cls
|
|
38
39
|
const filename = fileURLToPath(import.meta.url);
|
|
@@ -76,7 +77,7 @@ async function plugin(fastify, opt) {
|
|
|
76
77
|
});
|
|
77
78
|
|
|
78
79
|
// core migrations (second argument for core only)
|
|
79
|
-
execMigrations(path.join(cwd, 'server/migrations'), true).catch(err => console.log(err));
|
|
80
|
+
execMigrations(path.join(cwd, 'server/migrations'), pgClients.client, true).catch(err => console.log(err));
|
|
80
81
|
|
|
81
82
|
// core templates && cls
|
|
82
83
|
config.templates?.forEach(el => addTemplateDir(el));
|
|
@@ -103,4 +104,4 @@ async function plugin(fastify, opt) {
|
|
|
103
104
|
utilRoutes(fastify, opt);
|
|
104
105
|
fastify.get('/api/test-proxy', {}, (req) => req.headers);
|
|
105
106
|
}
|
|
106
|
-
export default fp(plugin);
|
|
107
|
+
export default fp(plugin);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengis/fastify-table",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.63",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "core-plugins",
|
|
6
6
|
"keywords": [
|
|
@@ -25,9 +25,6 @@
|
|
|
25
25
|
"test:helpers": "node --test .\\test\\helpers",
|
|
26
26
|
"test:routes": "node --test .\\test\\routes",
|
|
27
27
|
"test:functions": "node --test .\\test\\functions",
|
|
28
|
-
"docs:dev": "vitepress dev docs",
|
|
29
|
-
"docs:build": "vitepress build docs",
|
|
30
|
-
"docs:preview": "vitepress preview docs",
|
|
31
28
|
"compress": "node compress.js"
|
|
32
29
|
},
|
|
33
30
|
"dependencies": {
|
|
@@ -48,17 +45,8 @@
|
|
|
48
45
|
"uglify-js": "3.19.3"
|
|
49
46
|
},
|
|
50
47
|
"devDependencies": {
|
|
51
|
-
"@panzoom/panzoom": "4.5.1",
|
|
52
48
|
"eslint": "8.49.0",
|
|
53
|
-
"eslint-config-airbnb": "19.0.4"
|
|
54
|
-
"markdown-it-abbr": "2.0.0",
|
|
55
|
-
"mermaid": "10.9.3",
|
|
56
|
-
"sass": "1.72.0",
|
|
57
|
-
"vitepress": "1.3.4",
|
|
58
|
-
"vitepress-plugin-mermaid": "2.0.16",
|
|
59
|
-
"vitepress-plugin-tabs": "0.5.0",
|
|
60
|
-
"vitepress-sidebar": "1.25.0",
|
|
61
|
-
"vue": "3.4.27"
|
|
49
|
+
"eslint-config-airbnb": "19.0.4"
|
|
62
50
|
},
|
|
63
51
|
"author": "Softpro",
|
|
64
52
|
"license": "ISC"
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
CREATE SCHEMA IF NOT EXISTS admin;
|
|
2
2
|
|
|
3
3
|
CREATE TABLE IF NOT EXISTS admin.rules();
|
|
4
|
+
CREATE TABLE IF NOT EXISTS admin.users( uid text not null constraint admin_user_uid_pkey PRIMARY KEY DEFAULT next_id() );
|
|
4
5
|
ALTER TABLE admin.rules DROP CONSTRAINT IF EXISTS admin_rules_pkey cascade;
|
|
5
6
|
ALTER TABLE admin.rules add column if not exists rule_id text NOT NULL DEFAULT next_id();
|
|
6
7
|
|
|
@@ -38,6 +38,7 @@ ALTER TABLE log.user_auth ADD COLUMN IF NOT EXISTS cdate timestamp without time
|
|
|
38
38
|
ALTER TABLE log.user_auth ADD COLUMN IF NOT EXISTS editor_id text;
|
|
39
39
|
ALTER TABLE log.user_auth ADD COLUMN IF NOT EXISTS editor_date timestamp without time zone;
|
|
40
40
|
ALTER TABLE log.user_auth ADD COLUMN IF NOT EXISTS auth_data json;
|
|
41
|
+
ALTER TABLE log.user_auth ADD COLUMN IF NOT EXISTS ip text;
|
|
41
42
|
|
|
42
43
|
COMMENT ON TABLE log.table_changes IS 'Логи подій змін в БД';
|
|
43
44
|
COMMENT ON COLUMN log.table_changes.change_type IS 'Тип події (insert / update / delete)';
|
|
@@ -57,6 +58,7 @@ COMMENT ON COLUMN log.user_auth.user_id IS 'ID користувача';
|
|
|
57
58
|
COMMENT ON COLUMN log.user_auth.auth_date IS 'Дата авторизації';
|
|
58
59
|
COMMENT ON COLUMN log.user_auth.auth_type IS 'Тип авторизації';
|
|
59
60
|
COMMENT ON COLUMN log.user_auth.auth_data IS 'Дані про користувача';
|
|
61
|
+
COMMENT ON COLUMN log.user_auth.ip IS 'IP адреса користувача';
|
|
60
62
|
|
|
61
63
|
ALTER TABLE log.table_changes DROP CONSTRAINT IF EXISTS log_table_changes_pkey cascade;
|
|
62
64
|
ALTER TABLE log.table_changes_data DROP CONSTRAINT IF EXISTS log_table_changes_data_pkey;
|
|
@@ -55,6 +55,7 @@ ALTER TABLE admin.user_properties ADD COLUMN IF NOT EXISTS property_title text;
|
|
|
55
55
|
COMMENT ON COLUMN admin.user_properties.property_title IS 'Назва';
|
|
56
56
|
|
|
57
57
|
ALTER TABLE admin.user_properties ADD COLUMN IF NOT EXISTS private boolean;
|
|
58
|
+
update admin.user_properties set private = true where private is null;
|
|
58
59
|
ALTER TABLE admin.user_properties ALTER COLUMN private SET NOT NULL;
|
|
59
60
|
ALTER TABLE admin.user_properties ALTER COLUMN private SET default true;
|
|
60
61
|
COMMENT ON COLUMN admin.user_properties.private IS 'Доступ лише для користувача, який додав дане налаштування';
|
|
@@ -30,7 +30,7 @@ ALTER TABLE admin.templates add CONSTRAINT admin_templates_name_type_unique UNIQ
|
|
|
30
30
|
|
|
31
31
|
COMMENT ON TABLE admin.templates IS 'Шаблони для друку';
|
|
32
32
|
|
|
33
|
-
COMMENT ON COLUMN admin.templates.
|
|
33
|
+
COMMENT ON COLUMN admin.templates.created_by IS 'ID користувача';
|
|
34
34
|
|
|
35
35
|
COMMENT ON COLUMN admin.templates.name IS 'Систамна назва шаблону';
|
|
36
36
|
COMMENT ON COLUMN admin.templates.title IS 'Назва шаблону українською';
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import pino from 'pino';
|
|
2
2
|
// import path from 'node:path';
|
|
3
3
|
|
|
4
|
-
import
|
|
4
|
+
import config from '../../../config.js';
|
|
5
|
+
import getRedis from '../redis/funcs/getRedis.js';
|
|
5
6
|
import redactionList from '../../../redactionList.js';
|
|
6
7
|
|
|
7
8
|
// utils
|
|
@@ -45,7 +46,6 @@ if (config.debug) {
|
|
|
45
46
|
logger.file('test/redaction', { clientId: 'should be redacted', clientSecret: 'should be redacted' });
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
|
|
49
49
|
logger.metrics = function metrics(key, val, dbName) {
|
|
50
50
|
const dbname = dbName || config.pg?.database;
|
|
51
51
|
if (!dbname && !isServer) return;
|
|
@@ -3,11 +3,12 @@ import { readdirSync, existsSync } from 'node:fs';
|
|
|
3
3
|
|
|
4
4
|
import config from '../../../config.js';
|
|
5
5
|
import execSql from './exec.sql.js';
|
|
6
|
+
import pgClients from '../pg/pgClients.js';
|
|
6
7
|
// import getCallerDir from './get.caller.dir.js';
|
|
7
8
|
|
|
8
9
|
const time = Date.now();
|
|
9
10
|
|
|
10
|
-
export default async function execMigrations(dirPath, iscore) {
|
|
11
|
+
export default async function execMigrations(dirPath, pg = pgClients.client, iscore = false) {
|
|
11
12
|
if (
|
|
12
13
|
!dirPath
|
|
13
14
|
|| (config.migrationsCore === false && iscore)
|
|
@@ -30,7 +31,7 @@ export default async function execMigrations(dirPath, iscore) {
|
|
|
30
31
|
|
|
31
32
|
// execute sql files
|
|
32
33
|
if (content?.length) {
|
|
33
|
-
await content.reduce((promise, filename) => promise.then(() => execSql(path.join(dirPath, filename))), Promise.resolve());
|
|
34
|
+
await content.reduce((promise, filename) => promise.then(() => execSql(path.join(dirPath, filename), pg)), Promise.resolve());
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
|
|
@@ -2,14 +2,20 @@ import path from 'node:path';
|
|
|
2
2
|
import { createHash } from 'node:crypto';
|
|
3
3
|
import { existsSync, readFileSync } from 'node:fs';
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import config from '../../../config.js';
|
|
6
|
+
|
|
7
|
+
import pgClients from '../pg/pgClients.js';
|
|
8
|
+
|
|
9
|
+
import logger from '../logger/getLogger.js';
|
|
10
|
+
|
|
11
|
+
import getRedis from '../redis/funcs/getRedis.js';
|
|
6
12
|
|
|
7
13
|
const rclient = getRedis();
|
|
8
14
|
|
|
9
15
|
export default async function execSql(filepath, pg = pgClients.client) {
|
|
10
16
|
const start = Date.now();
|
|
11
17
|
|
|
12
|
-
if (!filepath) return null;
|
|
18
|
+
if (!pg || !filepath) return null;
|
|
13
19
|
|
|
14
20
|
const filename = path.basename(filepath);
|
|
15
21
|
|
|
@@ -55,4 +61,4 @@ export default async function execSql(filepath, pg = pgClients.client) {
|
|
|
55
61
|
});
|
|
56
62
|
return err.toString();
|
|
57
63
|
}
|
|
58
|
-
}
|
|
64
|
+
}
|
|
@@ -7,9 +7,9 @@ export default async function getMeta(opt, nocache) {
|
|
|
7
7
|
const pg = opt?.pg || getPG({ name: 'client' });
|
|
8
8
|
const table = opt?.table || opt;
|
|
9
9
|
|
|
10
|
-
if (pg
|
|
10
|
+
if (pg?.options?.database && data[pg.options.database]?.[table] && !nocache) return data[pg.options.database][table];
|
|
11
11
|
|
|
12
|
-
if (!pg
|
|
12
|
+
if (!pg?.tlist?.includes(table?.replace?.(/"/g, ''))) {
|
|
13
13
|
return { error: `${table} - not found`, status: 400 };
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -7,6 +7,9 @@ import logger from '../../logger/getLogger.js';
|
|
|
7
7
|
const rclient = getRedis({ db: 0 });
|
|
8
8
|
|
|
9
9
|
async function init(client) {
|
|
10
|
+
if (!client.options?.database) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
10
13
|
const textQuery = `select
|
|
11
14
|
(select json_object_agg(conrelid::regclass ,(SELECT attname FROM pg_attribute WHERE attrelid = c.conrelid and attnum = c.conkey[1]))
|
|
12
15
|
from pg_constraint c where contype='p' and connamespace::regnamespace::text not in ('sde')) as pk,
|
|
@@ -20,15 +23,16 @@ async function init(client) {
|
|
|
20
23
|
from pg_class where relkind in ('r','v')`);
|
|
21
24
|
const relkinds = rows.reduce((acc, curr) => Object.assign(acc, { [curr.tname]: curr.relkind }), {});
|
|
22
25
|
|
|
23
|
-
async function query(q, args = [],
|
|
26
|
+
async function query(q, args = [], isstream) {
|
|
24
27
|
try {
|
|
25
|
-
if (
|
|
26
|
-
await client.query('set statement_timeout to
|
|
28
|
+
if (isstream) {
|
|
29
|
+
await client.query('set statement_timeout to 100000000');
|
|
27
30
|
}
|
|
28
31
|
const data = await client.query(q, args);
|
|
29
32
|
await client.query('set statement_timeout to 0');
|
|
30
33
|
return data;
|
|
31
|
-
}
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
32
36
|
await client.query('set statement_timeout to 0');
|
|
33
37
|
if (err.message === 'canceling statement due to statement timeout') {
|
|
34
38
|
logger.file('timeout/query', { q, stack: err.stack });
|
|
@@ -39,7 +43,8 @@ async function init(client) {
|
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
async function querySafe(q, param = {}) {
|
|
42
|
-
const
|
|
46
|
+
const { args, isstream } = param;
|
|
47
|
+
const data = await query(q, args, isstream);
|
|
43
48
|
return data;
|
|
44
49
|
}
|
|
45
50
|
|
|
@@ -88,7 +88,7 @@ export default function checkPolicy(req, reply) {
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
/* === 3. policy: user === */
|
|
91
|
-
if (!validToken && !user && policy.includes('user') && !skipCheckPolicy(path)) {
|
|
91
|
+
if (!validToken && !user && policy.includes('user') && config.pg && !config.auth?.disable && !skipCheckPolicy(path)) {
|
|
92
92
|
logger.file('policy/user', {
|
|
93
93
|
path, method, params, query, body, message: 'access restricted: 3',
|
|
94
94
|
});
|
|
@@ -8,7 +8,7 @@ export default async function insert(req) {
|
|
|
8
8
|
} = req || {};
|
|
9
9
|
if (!user) return { message: 'access restricted', status: 403 };
|
|
10
10
|
|
|
11
|
-
const hookData = await applyHook('preInsert', { pg, table: params?.table, user });
|
|
11
|
+
const hookData = await applyHook('preInsert', { pg, table: params?.table, user, body });
|
|
12
12
|
|
|
13
13
|
if (hookData?.message && hookData?.status) {
|
|
14
14
|
return { message: hookData?.message, status: hookData?.status };
|