@opengis/fastify-table 1.3.52 → 1.3.54
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/package.json +19 -18
- package/server/migrations/template.sql +18 -9
- package/server/plugins/md/funcs/formatMdoc.js +40 -0
- package/server/plugins/md/funcs/mdToHTML.js +17 -0
- package/server/plugins/table/funcs/getTemplate.js +18 -2
- package/server/routes/table/controllers/data.js +5 -2
- package/server/routes/table/controllers/filter.js +1 -1
- package/utils.js +6 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengis/fastify-table",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.54",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "core-plugins",
|
|
6
6
|
"keywords": [
|
|
@@ -32,32 +32,33 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@fastify/http-proxy": "9.5.0",
|
|
35
|
-
"@fastify/sensible": "
|
|
35
|
+
"@fastify/sensible": "5.0.0",
|
|
36
36
|
"@fastify/url-data": "5.4.0",
|
|
37
|
-
"fastify": "
|
|
38
|
-
"fastify-plugin": "
|
|
37
|
+
"fastify": "4.26.1",
|
|
38
|
+
"fastify-plugin": "4.0.0",
|
|
39
|
+
"handlebars": "4.7.8",
|
|
39
40
|
"ioredis": "5.3.2",
|
|
40
41
|
"js-yaml": "4.1.0",
|
|
42
|
+
"markdown-it": "14.1.0",
|
|
41
43
|
"pg": "8.11.3",
|
|
42
44
|
"pino": "9.5.0",
|
|
43
45
|
"pino-abstract-transport": "2.0.0",
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"qrcode": "^1.5.4"
|
|
46
|
+
"promised-handlebars": "2.0.1",
|
|
47
|
+
"qrcode": "1.5.4",
|
|
48
|
+
"uglify-js": "3.19.3"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
50
|
-
"@panzoom/panzoom": "
|
|
51
|
-
"eslint": "
|
|
52
|
-
"eslint-config-airbnb": "
|
|
53
|
-
"markdown-it-abbr": "
|
|
54
|
-
"mermaid": "
|
|
51
|
+
"@panzoom/panzoom": "4.5.1",
|
|
52
|
+
"eslint": "8.49.0",
|
|
53
|
+
"eslint-config-airbnb": "19.0.4",
|
|
54
|
+
"markdown-it-abbr": "2.0.0",
|
|
55
|
+
"mermaid": "10.9.3",
|
|
55
56
|
"sass": "1.72.0",
|
|
56
|
-
"vitepress": "
|
|
57
|
-
"vitepress-plugin-mermaid": "
|
|
58
|
-
"vitepress-plugin-tabs": "
|
|
59
|
-
"vitepress-sidebar": "
|
|
60
|
-
"vue": "
|
|
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"
|
|
61
62
|
},
|
|
62
63
|
"author": "Softpro",
|
|
63
64
|
"license": "ISC"
|
|
@@ -9,16 +9,21 @@ ALTER TABLE admin.templates DROP CONSTRAINT if exists admin_templates_name_type_
|
|
|
9
9
|
ALTER TABLE admin.templates add column if not exists name text;
|
|
10
10
|
ALTER TABLE admin.templates add column if not exists title text;
|
|
11
11
|
ALTER TABLE admin.templates add column if not exists type text;
|
|
12
|
+
ALTER TABLE admin.templates add column if not exists category text;
|
|
12
13
|
ALTER TABLE admin.templates add column if not exists route_id text;
|
|
13
|
-
ALTER TABLE admin.templates add column if not exists
|
|
14
|
-
ALTER TABLE admin.templates alter column
|
|
14
|
+
ALTER TABLE admin.templates add column if not exists is_active boolean;
|
|
15
|
+
ALTER TABLE admin.templates alter column is_active set default true;
|
|
15
16
|
ALTER TABLE admin.templates add column if not exists body text;
|
|
17
|
+
ALTER TABLE admin.templates add column if not exists description text;
|
|
18
|
+
ALTER TABLE admin.templates add column if not exists placeholders json;
|
|
19
|
+
ALTER TABLE admin.templates add column if not exists version numeric;
|
|
16
20
|
|
|
17
|
-
ALTER TABLE admin.templates add column if not exists
|
|
18
|
-
ALTER TABLE admin.templates add column if not exists
|
|
19
|
-
ALTER TABLE admin.templates alter column
|
|
20
|
-
ALTER TABLE admin.templates add column if not exists
|
|
21
|
-
ALTER TABLE admin.templates add column if not exists
|
|
21
|
+
ALTER TABLE admin.templates add column if not exists created_by text;
|
|
22
|
+
ALTER TABLE admin.templates add column if not exists created_at timestamp without time zone;
|
|
23
|
+
ALTER TABLE admin.templates alter column created_at set DEFAULT date_trunc('seconds'::text, now());
|
|
24
|
+
ALTER TABLE admin.templates add column if not exists updated_by text;
|
|
25
|
+
ALTER TABLE admin.templates add column if not exists updated_at timestamp without time zone;
|
|
26
|
+
ALTER TABLE admin.templates alter column updated_at set DEFAULT date_trunc('seconds'::text, now());
|
|
22
27
|
|
|
23
28
|
ALTER TABLE admin.templates add CONSTRAINT admin_templates_template_id_pkey PRIMARY KEY (template_id);
|
|
24
29
|
ALTER TABLE admin.templates add CONSTRAINT admin_templates_name_type_unique UNIQUE (name, type);
|
|
@@ -30,6 +35,10 @@ COMMENT ON COLUMN admin.templates.uid IS 'ID користувача';
|
|
|
30
35
|
COMMENT ON COLUMN admin.templates.name IS 'Систамна назва шаблону';
|
|
31
36
|
COMMENT ON COLUMN admin.templates.title IS 'Назва шаблону українською';
|
|
32
37
|
COMMENT ON COLUMN admin.templates.type IS 'Тип вихідних даних шаблону (demo/user)';
|
|
38
|
+
COMMENT ON COLUMN admin.templates.category IS 'Категорія або тип документа';
|
|
33
39
|
COMMENT ON COLUMN admin.templates.route_id IS 'ID інтерфейсу';
|
|
34
|
-
COMMENT ON COLUMN admin.templates.
|
|
35
|
-
COMMENT ON COLUMN admin.templates.body IS 'Body HTML';
|
|
40
|
+
COMMENT ON COLUMN admin.templates.is_active IS 'Чи доступний шаблон для використання';
|
|
41
|
+
COMMENT ON COLUMN admin.templates.body IS 'Body HTML';
|
|
42
|
+
COMMENT ON COLUMN admin.templates.description IS 'Короткий опис шаблону';
|
|
43
|
+
COMMENT ON COLUMN admin.templates.placeholders IS 'Список змінних, які можна вставляти';
|
|
44
|
+
COMMENT ON COLUMN admin.templates.version IS 'Версія шаблону';
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
function handleData(data, curr, acc, titles = {}, plain, splittype = 1) {
|
|
2
|
+
|
|
3
|
+
const titleStr = {
|
|
4
|
+
1: `${(titles?.[curr] || curr)}\n`, // for lists
|
|
5
|
+
2: `${(titles?.[curr] || curr)}: `, // one-liner
|
|
6
|
+
3: '' // for nested lists w/ one property
|
|
7
|
+
}[splittype];
|
|
8
|
+
|
|
9
|
+
if (Array.isArray(data[curr])) {
|
|
10
|
+
const str = `${plain ? '' : '\n\n### '}${titleStr}${data[curr].map(el => {
|
|
11
|
+
if (typeof el === 'object' && !Array.isArray(el)) {
|
|
12
|
+
const str = Object.keys(el).filter(el => el !== 'id').reduce((acc1, curr1) => handleData(el, curr1, acc1, {}, 1, 3), '');
|
|
13
|
+
return `\n - ${str}`;
|
|
14
|
+
}
|
|
15
|
+
return `\n - ${el}`;
|
|
16
|
+
})}`;
|
|
17
|
+
acc += `${str}`;
|
|
18
|
+
return acc;
|
|
19
|
+
} else if (typeof data[curr] === 'object') {
|
|
20
|
+
const str = `${plain ? '' : '\n\n### '} ${titleStr}${JSON.stringify(data[curr])}`;
|
|
21
|
+
acc += str;
|
|
22
|
+
return acc;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
acc += `${plain ? '' : '\n\n### '}${titleStr}${data[curr] || ''}`;
|
|
26
|
+
return acc;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default function formatMdoc(data, titles = {}, headerColumns = [], descriptionColumns = []) {
|
|
30
|
+
if (!data) return 'empty data';
|
|
31
|
+
if (typeof data !== 'object' || Array.isArray(data)) return 'invalid data';
|
|
32
|
+
if (headerColumns && !Array.isArray(headerColumns)) return 'invalid headerColumns';
|
|
33
|
+
if (descriptionColumns && !Array.isArray(descriptionColumns)) return 'invalid descriptionColumns';
|
|
34
|
+
|
|
35
|
+
const header = Object.keys(data).filter(key => headerColumns.includes(key) && data[key]).reduce((acc, curr) => handleData(data, curr, acc, titles, 1, 2), '');
|
|
36
|
+
|
|
37
|
+
const description = Object.keys(data).filter(key => descriptionColumns.includes(key) && data[key]).reduce((acc, curr) => handleData(data, curr, acc, titles), '');
|
|
38
|
+
|
|
39
|
+
return `---\n${header}\n---${description}`.replace(/,,/g, ',');
|
|
40
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import md from 'markdown-it';
|
|
2
|
+
|
|
3
|
+
const md1 = md({ html: true });
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Перетворення з файла readme.md до формату HTML.
|
|
7
|
+
* Потрабно вставити в хелпер шлях до файла або текст readme.md і за допомогою бібліотеки markdown-it перетвориться в HTML.
|
|
8
|
+
|
|
9
|
+
* @returns {String} Returns HTML
|
|
10
|
+
*/
|
|
11
|
+
export default function mdToHTML(data, options) {
|
|
12
|
+
// auto detect HTML or MD
|
|
13
|
+
// const result = md().render(data);
|
|
14
|
+
if (!data) return 'empty data';
|
|
15
|
+
const result = md1.render(data);
|
|
16
|
+
return result;
|
|
17
|
+
};
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import path from 'path';
|
|
1
|
+
import path from 'node:path';
|
|
2
2
|
import yaml from 'js-yaml';
|
|
3
3
|
|
|
4
|
-
import { readdir, readFile } from 'fs/promises';
|
|
4
|
+
import { readdir, readFile } from 'node:fs/promises';
|
|
5
5
|
|
|
6
6
|
import getTemplatePath from './getTemplatePath.js';
|
|
7
7
|
import loadTemplate from './loadTemplate.js';
|
|
8
|
+
import mdToHTML from '../../md/funcs/mdToHTML.js';
|
|
8
9
|
|
|
9
10
|
async function readFileData(file) {
|
|
10
11
|
const data = await readFile(file, 'utf-8');
|
|
@@ -16,6 +17,21 @@ async function readFileData(file) {
|
|
|
16
17
|
if (ext === 'json') {
|
|
17
18
|
return JSON.parse(data);
|
|
18
19
|
}
|
|
20
|
+
if (ext === 'md') {
|
|
21
|
+
const match = data.match(/^---\r?\n([\s\S]*?)---\r?\n([\s\S]*)$/);
|
|
22
|
+
|
|
23
|
+
const parseLinesRecursively = (lines, index = 0, result = {}) => index >= lines.length
|
|
24
|
+
? result
|
|
25
|
+
: (([key, ...rest]) => key && rest.length
|
|
26
|
+
? parseLinesRecursively(lines, index + 1, { ...result, [key.trim()]: rest.join(':').trim() })
|
|
27
|
+
: parseLinesRecursively(lines, index + 1, result))((lines[index] || '').split(':'));
|
|
28
|
+
|
|
29
|
+
const header = parseLinesRecursively(match[1]?.split?.(/\r?\n/) || []);
|
|
30
|
+
const body = match[2]?.replace(/\r\n/g, '')?.startsWith('```html') ? match[2]?.match?.(/```html\r?\n([\s\S]*?)```/)?.[1] : match[2];
|
|
31
|
+
|
|
32
|
+
return { ...header, html: mdToHTML(body) };
|
|
33
|
+
|
|
34
|
+
}
|
|
19
35
|
return data;
|
|
20
36
|
}
|
|
21
37
|
|
|
@@ -155,7 +155,7 @@ export default async function dataAPI(req, reply, called) {
|
|
|
155
155
|
${params.id || query.key ? '*' : sqlColumns || cols || '*'}
|
|
156
156
|
${metaCols}
|
|
157
157
|
|
|
158
|
-
${dbColumns.
|
|
158
|
+
${dbColumns.filter((el) => pg.pgType?.[el.dataTypeID] === 'geometry').length ? `,${dbColumns.filter((el) => pg.pgType?.[el.dataTypeID] === 'geometry').map(el => `st_asgeojson("${el.name.replace(/'/g, "''")}")::json as "${el.name.replace(/'/g, "''")}"`).join(',')}` : ''}
|
|
159
159
|
from (select * ${sql?.filter(el => el.inline).map(el => `,(${el.sql})`).join('') || ''} from ${table} t ${sqlTable} ) t
|
|
160
160
|
|
|
161
161
|
${params.id ? cardSqlTable : ''}
|
|
@@ -167,7 +167,10 @@ export default async function dataAPI(req, reply, called) {
|
|
|
167
167
|
if (config.trace) console.log(q);
|
|
168
168
|
if (query.sql === '1') { return q; }
|
|
169
169
|
|
|
170
|
-
const { rows = [] } = await pg.query(q, (tokenData?.id || hookData?.id || params.id ? [tokenData?.id || hookData?.id || params.id] : null) || (query.key && loadTable.key ? [query.key] : []))
|
|
170
|
+
const { rows = [] } = await pg.query(q, (tokenData?.id || hookData?.id || params.id ? [tokenData?.id || hookData?.id || params.id] : null) || (query.key && loadTable.key ? [query.key] : [])).catch(err => {
|
|
171
|
+
console.error(err.toString());
|
|
172
|
+
throw new Error(err.toString());
|
|
173
|
+
});
|
|
171
174
|
|
|
172
175
|
timeArr.push(Date.now())
|
|
173
176
|
|
|
@@ -36,7 +36,7 @@ export default async function filterAPI(req) {
|
|
|
36
36
|
|
|
37
37
|
filters?.forEach?.(el => Object.assign(el, { id: el.id || el.name, title: el.title || el.ua, extra: extraColumns.includes(el.id || el.name) }));
|
|
38
38
|
|
|
39
|
-
await Promise.all(filters.filter((el) => el.data && el.id && el.type !== 'Autocomplete').map(async (el) => {
|
|
39
|
+
await Promise.all(filters.filter((el) => el.data && el.id && el.type !== 'Autocomplete' && !el.sql).map(async (el) => {
|
|
40
40
|
const cls = await getSelect(el.data, pg);
|
|
41
41
|
|
|
42
42
|
if (!cls || !loadTable.table) return;
|
package/utils.js
CHANGED
|
@@ -76,6 +76,9 @@ import logChanges from './server/plugins/crud/funcs/utils/logChanges.js';
|
|
|
76
76
|
import yml2json from './server/plugins/yml/funcs/yml2json.js';
|
|
77
77
|
import json2yml from './server/plugins/yml/funcs/json2yml.js';
|
|
78
78
|
|
|
79
|
+
import formatMdoc from './server/plugins/md/funcs/formatMdoc.js';
|
|
80
|
+
import mdToHTML from './server/plugins/md/funcs/mdToHTML.js';
|
|
81
|
+
|
|
79
82
|
export default null;
|
|
80
83
|
export {
|
|
81
84
|
config,
|
|
@@ -146,4 +149,7 @@ export {
|
|
|
146
149
|
|
|
147
150
|
yml2json,
|
|
148
151
|
json2yml,
|
|
152
|
+
|
|
153
|
+
formatMdoc,
|
|
154
|
+
mdToHTML,
|
|
149
155
|
};
|