@opengis/bi 1.0.28 → 1.0.30
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/config.js +12 -12
- package/dist/bi.js +1 -1
- package/dist/bi.umd.cjs +110 -123
- package/dist/{import-file-nBKuPZWn.js → import-file-CGUzCAix.js} +17348 -17513
- package/dist/{map-component-mixin-eyru7mUO.js → map-component-mixin-BkEQzSdJ.js} +4839 -4839
- package/dist/{vs-donut-QxB7xUy1.js → vs-donut-DiNanKYo.js} +1 -1
- package/dist/{vs-funnel-bar-BBWwOerT.js → vs-funnel-bar-BM7WMuDM.js} +1 -1
- package/dist/{vs-map-DYBDyDP3.js → vs-map-DLALMtkA.js} +2 -2
- package/dist/{vs-map-cluster-BM_cd8Xs.js → vs-map-cluster-DLJPVkGz.js} +2 -2
- package/dist/{vs-number-amN4sYu6.js → vs-number-EfOaU6-B.js} +1 -1
- package/dist/{vs-table-Bm5TzNWN.js → vs-table-BdxjaLf1.js} +1 -1
- package/dist/{vs-text-DJpxMHE3.js → vs-text-DhA-8Fxf.js} +4 -4
- package/package.json +2 -2
- package/server/plugins/docs.js +48 -48
- package/server/plugins/hook.js +89 -89
- package/server/plugins/vite.js +69 -69
- package/server/routes/dashboard/controllers/utils/yaml.js +11 -11
- package/server/routes/data/controllers/data.js +1 -0
- package/server/routes/data/controllers/util/chartSQL.js +2 -1
- package/server/routes/data/controllers/util/normalizeData.js +61 -61
- package/server/routes/map/controllers/cluster.js +110 -110
- package/server/routes/map/controllers/clusterVtile.js +166 -166
- package/server/routes/map/controllers/geojson.js +127 -127
- package/server/routes/map/controllers/map.js +61 -61
- package/server/routes/map/controllers/utils/downloadClusterData.js +44 -44
- package/server/routes/map/controllers/vtile.js +183 -183
- package/utils.js +12 -12
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as y, c as D, i as g, a as c, b as h, P as l } from "./import-file-
|
|
1
|
+
import { _ as y, c as D, i as g, a as c, b as h, P as l } from "./import-file-CGUzCAix.js";
|
|
2
2
|
import { createElementBlock as b, openBlock as x } from "vue";
|
|
3
3
|
const _ = {
|
|
4
4
|
name: "VsPie",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as n, c, i as h, b as o, d as l, a as d } from "./import-file-
|
|
1
|
+
import { _ as n, c, i as h, b as o, d as l, a as d } from "./import-file-CGUzCAix.js";
|
|
2
2
|
import { createElementBlock as p, openBlock as u } from "vue";
|
|
3
3
|
const m = {
|
|
4
4
|
name: "VsFunnelBar",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { l as g, m as M } from "./map-component-mixin-
|
|
2
|
-
import { _ as w, c as y } from "./import-file-
|
|
1
|
+
import { l as g, m as M } from "./map-component-mixin-BkEQzSdJ.js";
|
|
2
|
+
import { _ as w, c as y } from "./import-file-CGUzCAix.js";
|
|
3
3
|
import { resolveComponent as i, createElementBlock as _, openBlock as u, createElementVNode as r, createBlock as V, createCommentVNode as v, createVNode as d } from "vue";
|
|
4
4
|
const x = {
|
|
5
5
|
mixins: [y, g, M],
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { l as w, m as V, p as _ } from "./map-component-mixin-
|
|
2
|
-
import { _ as v, c as C } from "./import-file-
|
|
1
|
+
import { l as w, m as V, p as _ } from "./map-component-mixin-BkEQzSdJ.js";
|
|
2
|
+
import { _ as v, c as C } from "./import-file-CGUzCAix.js";
|
|
3
3
|
import { resolveComponent as a, createElementBlock as $, openBlock as h, createVNode as s, createElementVNode as u, createBlock as x, createCommentVNode as L } from "vue";
|
|
4
4
|
const k = {
|
|
5
5
|
mixins: [C, w, V],
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as m, c as f, d as _, a as b } from "./import-file-
|
|
1
|
+
import { _ as m, c as f, d as _, a as b } from "./import-file-CGUzCAix.js";
|
|
2
2
|
import { createElementBlock as a, openBlock as r, createElementVNode as s, Fragment as n, renderList as c, toDisplayString as d } from "vue";
|
|
3
3
|
const x = {
|
|
4
4
|
name: "VsTable",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var ge = Object.defineProperty;
|
|
2
2
|
var ke = (c, e, t) => e in c ? ge(c, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : c[e] = t;
|
|
3
3
|
var k = (c, e, t) => ke(c, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
-
import { _ as de, c as xe } from "./import-file-
|
|
4
|
+
import { _ as de, c as xe } from "./import-file-CGUzCAix.js";
|
|
5
5
|
import { createElementBlock as V, openBlock as J, createCommentVNode as be } from "vue";
|
|
6
6
|
function Q() {
|
|
7
7
|
return {
|
|
@@ -282,7 +282,7 @@ ${p}` : p;
|
|
|
282
282
|
`, 1)[0], x = !p.trim(), d = 0;
|
|
283
283
|
if (this.options.pedantic ? (d = 2, a = p.trimStart()) : x ? d = t[1].length + 1 : (d = t[2].search(/[^ ]/), d = d > 4 ? 1 : d, a = p.slice(d), d += t[1].length), x && /^[ \t]*$/.test(g) && (h += g + `
|
|
284
284
|
`, e = e.substring(g.length + 1), o = !0), !o) {
|
|
285
|
-
const Z = new RegExp(`^ {0,${Math.min(3, d - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`), W = new RegExp(`^ {0,${Math.min(3, d - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`), X = new RegExp(`^ {0,${Math.min(3, d - 1)}}(?:\`\`\`|~~~)`), G = new RegExp(`^ {0,${Math.min(3, d - 1)}}#`), fe = new RegExp(`^ {0,${Math.min(3, d - 1)}}<
|
|
285
|
+
const Z = new RegExp(`^ {0,${Math.min(3, d - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`), W = new RegExp(`^ {0,${Math.min(3, d - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`), X = new RegExp(`^ {0,${Math.min(3, d - 1)}}(?:\`\`\`|~~~)`), G = new RegExp(`^ {0,${Math.min(3, d - 1)}}#`), fe = new RegExp(`^ {0,${Math.min(3, d - 1)}}<[a-z].*>`, "i");
|
|
286
286
|
for (; e; ) {
|
|
287
287
|
const M = e.split(`
|
|
288
288
|
`, 1)[0];
|
|
@@ -640,7 +640,7 @@ const Re = /^(?:[ \t]*(?:\n|$))+/, _e = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*
|
|
|
640
640
|
lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
|
|
641
641
|
paragraph: f(j).replace("hr", E).replace("heading", ` *#{1,6} *[^
|
|
642
642
|
]`).replace("lheading", oe).replace("|table", "").replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").replace("|tag", "").getRegex()
|
|
643
|
-
}, ce = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/, Pe = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/, he = /^( {2,}|\\)\n(?!\s*$)/, Ze = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/, L = "\\p{P}\\p{S}", Me = f(/^((?![*_])[\spunctuation])/, "u").replace(/punctuation/g, L).getRegex(), De = /\[[^[\]]*?\]\(
|
|
643
|
+
}, ce = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/, Pe = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/, he = /^( {2,}|\\)\n(?!\s*$)/, Ze = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/, L = "\\p{P}\\p{S}", Me = f(/^((?![*_])[\spunctuation])/, "u").replace(/punctuation/g, L).getRegex(), De = /\[[^[\]]*?\]\([^\(\)]*?\)|`[^`]*?`|<[^<>]*?>/g, Qe = f(/^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/, "u").replace(/punct/g, L).getRegex(), je = f("^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)[punct](\\*+)(?=[\\s]|$)|[^punct\\s](\\*+)(?!\\*)(?=[punct\\s]|$)|(?!\\*)[punct\\s](\\*+)(?=[^punct\\s])|[\\s](\\*+)(?!\\*)(?=[punct])|(?!\\*)[punct](\\*+)(?!\\*)(?=[punct])|[^punct\\s](\\*+)(?=[^punct\\s])", "gu").replace(/punct/g, L).getRegex(), Oe = f("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)[punct](_+)(?=[\\s]|$)|[^punct\\s](_+)(?!_)(?=[punct\\s]|$)|(?!_)[punct\\s](_+)(?=[^punct\\s])|[\\s](_+)(?!_)(?=[punct])|(?!_)[punct](_+)(?!_)(?=[punct])", "gu").replace(/punct/g, L).getRegex(), He = f(/\\([punct])/, "gu").replace(/punct/g, L).getRegex(), Ne = f(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme", /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email", /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(), Ue = f(H).replace("(?:-->|$)", "-->").getRegex(), Fe = f("^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment", Ue).replace("attribute", /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(), C = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/, We = f(/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/).replace("label", C).replace("href", /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/).replace("title", /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(), pe = f(/^!?\[(label)\]\[(ref)\]/).replace("label", C).replace("ref", O).getRegex(), ue = f(/^!?\[(ref)\](?:\[\])?/).replace("ref", O).getRegex(), Xe = f("reflink|nolink(?!\\()", "g").replace("reflink", pe).replace("nolink", ue).getRegex(), U = {
|
|
644
644
|
_backpedal: S,
|
|
645
645
|
// only used for GFM url
|
|
646
646
|
anyPunctuation: He,
|
|
@@ -670,7 +670,7 @@ const Re = /^(?:[ \t]*(?:\n|$))+/, _e = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*
|
|
|
670
670
|
escape: f(ce).replace("])", "~|])").getRegex(),
|
|
671
671
|
url: f(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, "i").replace("email", /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),
|
|
672
672
|
_backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
|
|
673
|
-
del: /^(~~?)(?=[^\s~])(
|
|
673
|
+
del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
|
|
674
674
|
text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/
|
|
675
675
|
}, Ve = {
|
|
676
676
|
...D,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengis/bi",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.30",
|
|
4
4
|
"description": "BI data visualization module",
|
|
5
5
|
"main": "dist/bi.js",
|
|
6
6
|
"browser": "dist/bi.umd.cjs",
|
|
@@ -94,4 +94,4 @@
|
|
|
94
94
|
"vitepress-sidebar": "1.30.2",
|
|
95
95
|
"vue-tsc": "^2.1.6"
|
|
96
96
|
}
|
|
97
|
-
}
|
|
97
|
+
}
|
package/server/plugins/docs.js
CHANGED
|
@@ -1,48 +1,48 @@
|
|
|
1
|
-
import path, { dirname } from 'path';
|
|
2
|
-
import { fileURLToPath } from 'url';
|
|
3
|
-
import fs from 'fs';
|
|
4
|
-
|
|
5
|
-
const dir = dirname(fileURLToPath(import.meta.url));
|
|
6
|
-
const root = `${dir}/../../`;
|
|
7
|
-
|
|
8
|
-
async function plugin(fastify, opts) {
|
|
9
|
-
fastify.get('/docs-dev*', async (req, reply) => {
|
|
10
|
-
if (!fs.existsSync(path.join(root, 'docs-dev/.vitepress/dist/'))) {
|
|
11
|
-
return reply.status(404).send('docs not exists');
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const { params } = req;
|
|
15
|
-
const url = params['*'];
|
|
16
|
-
|
|
17
|
-
const filePath =
|
|
18
|
-
url && url[url.length - 1] !== '/'
|
|
19
|
-
? path.join(root, 'docs-dev/.vitepress/dist/', url)
|
|
20
|
-
: path.join(root, 'docs-dev/.vitepress/dist/', url, 'index.html');
|
|
21
|
-
|
|
22
|
-
if (!fs.existsSync(filePath)) {
|
|
23
|
-
return reply.status(404).send('File not found');
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const ext = path.extname(filePath);
|
|
27
|
-
const mime = {
|
|
28
|
-
'.js': 'text/javascript',
|
|
29
|
-
'.css': 'text/css',
|
|
30
|
-
'.woff2': 'application/font-woff',
|
|
31
|
-
'.png': 'image/png',
|
|
32
|
-
'.svg': 'image/svg+xml',
|
|
33
|
-
'.jpg': 'image/jpg',
|
|
34
|
-
'.html': 'text/html',
|
|
35
|
-
'.json': 'application/json',
|
|
36
|
-
'.pdf': 'application/pdf',
|
|
37
|
-
}[ext];
|
|
38
|
-
|
|
39
|
-
const stream = fs.createReadStream(filePath);
|
|
40
|
-
stream.on('error', (err) => {
|
|
41
|
-
reply.status(500).send('Error reading file');
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
return mime ? reply.type(mime).send(stream) : reply.send(stream);
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export default plugin;
|
|
1
|
+
import path, { dirname } from 'path';
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
|
|
5
|
+
const dir = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const root = `${dir}/../../`;
|
|
7
|
+
|
|
8
|
+
async function plugin(fastify, opts) {
|
|
9
|
+
fastify.get('/docs-dev*', async (req, reply) => {
|
|
10
|
+
if (!fs.existsSync(path.join(root, 'docs-dev/.vitepress/dist/'))) {
|
|
11
|
+
return reply.status(404).send('docs not exists');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const { params } = req;
|
|
15
|
+
const url = params['*'];
|
|
16
|
+
|
|
17
|
+
const filePath =
|
|
18
|
+
url && url[url.length - 1] !== '/'
|
|
19
|
+
? path.join(root, 'docs-dev/.vitepress/dist/', url)
|
|
20
|
+
: path.join(root, 'docs-dev/.vitepress/dist/', url, 'index.html');
|
|
21
|
+
|
|
22
|
+
if (!fs.existsSync(filePath)) {
|
|
23
|
+
return reply.status(404).send('File not found');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const ext = path.extname(filePath);
|
|
27
|
+
const mime = {
|
|
28
|
+
'.js': 'text/javascript',
|
|
29
|
+
'.css': 'text/css',
|
|
30
|
+
'.woff2': 'application/font-woff',
|
|
31
|
+
'.png': 'image/png',
|
|
32
|
+
'.svg': 'image/svg+xml',
|
|
33
|
+
'.jpg': 'image/jpg',
|
|
34
|
+
'.html': 'text/html',
|
|
35
|
+
'.json': 'application/json',
|
|
36
|
+
'.pdf': 'application/pdf',
|
|
37
|
+
}[ext];
|
|
38
|
+
|
|
39
|
+
const stream = fs.createReadStream(filePath);
|
|
40
|
+
stream.on('error', (err) => {
|
|
41
|
+
reply.status(500).send('Error reading file');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return mime ? reply.type(mime).send(stream) : reply.send(stream);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export default plugin;
|
package/server/plugins/hook.js
CHANGED
|
@@ -1,89 +1,89 @@
|
|
|
1
|
-
import fp from 'fastify-plugin';
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
|
|
4
|
-
// the use of fastify-plugin is required to be able
|
|
5
|
-
// to export the decorators to the outer scope
|
|
6
|
-
|
|
7
|
-
async function plugin(fastify) {
|
|
8
|
-
// preSerialization
|
|
9
|
-
fastify.addHook('preSerialization', async (req, reply, payload) => {
|
|
10
|
-
if (!req.session?.passport?.user?.uid) {
|
|
11
|
-
// return reply.redirect('/login');
|
|
12
|
-
}
|
|
13
|
-
if (req.url.includes('/suggest/') && !req.query.json) {
|
|
14
|
-
return payload?.data;
|
|
15
|
-
}
|
|
16
|
-
if (payload.redirect) {
|
|
17
|
-
return reply.redirect(payload.redirect);
|
|
18
|
-
}
|
|
19
|
-
if (reply.sent) {
|
|
20
|
-
return null;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if ([200, 400, 403, 409, 404, 500].includes(payload.status)) {
|
|
24
|
-
reply.status(payload.status);
|
|
25
|
-
}
|
|
26
|
-
/* if (payload.headers) {
|
|
27
|
-
reply.headers(payload.headers);
|
|
28
|
-
} */
|
|
29
|
-
if (payload.buffer) {
|
|
30
|
-
return payload.buffer;
|
|
31
|
-
}
|
|
32
|
-
if (payload.file) {
|
|
33
|
-
// const buffer = await readFile(payload.file);
|
|
34
|
-
// return reply.send(buffer);
|
|
35
|
-
const stream = fs.createReadStream(payload.file);
|
|
36
|
-
return stream;
|
|
37
|
-
// return reply.send(stream);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (payload.message) {
|
|
41
|
-
return payload.message;
|
|
42
|
-
}
|
|
43
|
-
return payload;
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
// preValidation
|
|
47
|
-
fastify.addHook('preValidation', async (req) => {
|
|
48
|
-
const parseRawBody =
|
|
49
|
-
['POST', 'PUT'].includes(req.method) &&
|
|
50
|
-
req.body &&
|
|
51
|
-
typeof req.body === 'string' &&
|
|
52
|
-
req.body.trim(/\r\n/g).startsWith('{') &&
|
|
53
|
-
req.body.trim(/\r\n/g).endsWith('}');
|
|
54
|
-
if (parseRawBody) {
|
|
55
|
-
try {
|
|
56
|
-
req.body = JSON.parse(req.body || '{}');
|
|
57
|
-
} catch (err) {
|
|
58
|
-
// throw new Error('invalid body');
|
|
59
|
-
// return { error: 'invalid body', status: 400 };
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
// allow upload file
|
|
65
|
-
const kIsMultipart = Symbol.for('[FastifyMultipart.isMultipart]');
|
|
66
|
-
fastify.addContentTypeParser('multipart', (request, _, done) => {
|
|
67
|
-
request[kIsMultipart] = true;
|
|
68
|
-
done(null);
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
// parse Body
|
|
72
|
-
function contentParser(req, body, done) {
|
|
73
|
-
const parseBody = decodeURIComponent(body.toString())
|
|
74
|
-
.split('&')
|
|
75
|
-
.reduce((acc, el) => {
|
|
76
|
-
const [key, val] = el.split('=');
|
|
77
|
-
return { ...acc, [key]: val };
|
|
78
|
-
}, {});
|
|
79
|
-
done(null, parseBody);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
fastify.addContentTypeParser(
|
|
83
|
-
'application/x-www-form-urlencoded',
|
|
84
|
-
{ parseAs: 'buffer' },
|
|
85
|
-
contentParser
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export default fp(plugin);
|
|
1
|
+
import fp from 'fastify-plugin';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
|
|
4
|
+
// the use of fastify-plugin is required to be able
|
|
5
|
+
// to export the decorators to the outer scope
|
|
6
|
+
|
|
7
|
+
async function plugin(fastify) {
|
|
8
|
+
// preSerialization
|
|
9
|
+
fastify.addHook('preSerialization', async (req, reply, payload) => {
|
|
10
|
+
if (!req.session?.passport?.user?.uid) {
|
|
11
|
+
// return reply.redirect('/login');
|
|
12
|
+
}
|
|
13
|
+
if (req.url.includes('/suggest/') && !req.query.json) {
|
|
14
|
+
return payload?.data;
|
|
15
|
+
}
|
|
16
|
+
if (payload.redirect) {
|
|
17
|
+
return reply.redirect(payload.redirect);
|
|
18
|
+
}
|
|
19
|
+
if (reply.sent) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if ([200, 400, 403, 409, 404, 500].includes(payload.status)) {
|
|
24
|
+
reply.status(payload.status);
|
|
25
|
+
}
|
|
26
|
+
/* if (payload.headers) {
|
|
27
|
+
reply.headers(payload.headers);
|
|
28
|
+
} */
|
|
29
|
+
if (payload.buffer) {
|
|
30
|
+
return payload.buffer;
|
|
31
|
+
}
|
|
32
|
+
if (payload.file) {
|
|
33
|
+
// const buffer = await readFile(payload.file);
|
|
34
|
+
// return reply.send(buffer);
|
|
35
|
+
const stream = fs.createReadStream(payload.file);
|
|
36
|
+
return stream;
|
|
37
|
+
// return reply.send(stream);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (payload.message) {
|
|
41
|
+
return payload.message;
|
|
42
|
+
}
|
|
43
|
+
return payload;
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// preValidation
|
|
47
|
+
fastify.addHook('preValidation', async (req) => {
|
|
48
|
+
const parseRawBody =
|
|
49
|
+
['POST', 'PUT'].includes(req.method) &&
|
|
50
|
+
req.body &&
|
|
51
|
+
typeof req.body === 'string' &&
|
|
52
|
+
req.body.trim(/\r\n/g).startsWith('{') &&
|
|
53
|
+
req.body.trim(/\r\n/g).endsWith('}');
|
|
54
|
+
if (parseRawBody) {
|
|
55
|
+
try {
|
|
56
|
+
req.body = JSON.parse(req.body || '{}');
|
|
57
|
+
} catch (err) {
|
|
58
|
+
// throw new Error('invalid body');
|
|
59
|
+
// return { error: 'invalid body', status: 400 };
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// allow upload file
|
|
65
|
+
const kIsMultipart = Symbol.for('[FastifyMultipart.isMultipart]');
|
|
66
|
+
fastify.addContentTypeParser('multipart', (request, _, done) => {
|
|
67
|
+
request[kIsMultipart] = true;
|
|
68
|
+
done(null);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// parse Body
|
|
72
|
+
function contentParser(req, body, done) {
|
|
73
|
+
const parseBody = decodeURIComponent(body.toString())
|
|
74
|
+
.split('&')
|
|
75
|
+
.reduce((acc, el) => {
|
|
76
|
+
const [key, val] = el.split('=');
|
|
77
|
+
return { ...acc, [key]: val };
|
|
78
|
+
}, {});
|
|
79
|
+
done(null, parseBody);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
fastify.addContentTypeParser(
|
|
83
|
+
'application/x-www-form-urlencoded',
|
|
84
|
+
{ parseAs: 'buffer' },
|
|
85
|
+
contentParser
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export default fp(plugin);
|
package/server/plugins/vite.js
CHANGED
|
@@ -1,69 +1,69 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import config from '../../config.js';
|
|
4
|
-
|
|
5
|
-
const { disableAuth } = config;
|
|
6
|
-
const isProduction = process.env.NODE_ENV === 'production';
|
|
7
|
-
|
|
8
|
-
async function plugin(fastify) {
|
|
9
|
-
// vite server
|
|
10
|
-
if (!isProduction) {
|
|
11
|
-
const vite = await import('vite');
|
|
12
|
-
|
|
13
|
-
const viteServer = await vite.createServer({
|
|
14
|
-
server: {
|
|
15
|
-
middlewareMode: true,
|
|
16
|
-
},
|
|
17
|
-
});
|
|
18
|
-
// hot reload
|
|
19
|
-
viteServer.watcher.on('all', (d, t) => {
|
|
20
|
-
if (!t.includes('module') && !t.includes('templates')) return;
|
|
21
|
-
// console.log(d, t);
|
|
22
|
-
viteServer.ws.send({ type: 'full-reload' });
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
// this is middleware for vite's dev servert
|
|
26
|
-
fastify.addHook('onRequest', async (req, reply) => {
|
|
27
|
-
// const { user } = req.session?.passport || {};
|
|
28
|
-
const next = () => new Promise((resolve) => {
|
|
29
|
-
viteServer.middlewares(req.raw, reply.raw, () => resolve());
|
|
30
|
-
});
|
|
31
|
-
await next();
|
|
32
|
-
});
|
|
33
|
-
fastify.get('*', async () => {});
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// From Build
|
|
38
|
-
fastify.get('*', async (req, reply) => {
|
|
39
|
-
// console.log(disableAuth)
|
|
40
|
-
if (!req.user && !disableAuth) return reply.redirect('/login');
|
|
41
|
-
const stream = fs.createReadStream('dist/index.html');
|
|
42
|
-
return reply
|
|
43
|
-
.headers({ 'Cache-Control': 'public, no-cache' })
|
|
44
|
-
.type('text/html')
|
|
45
|
-
.send(stream);
|
|
46
|
-
});
|
|
47
|
-
fastify.get('/assets/:file', async (req, reply) => {
|
|
48
|
-
const stream = fs.createReadStream(`dist/assets/${req.params.file}`);
|
|
49
|
-
const ext = path.extname(req.params.file);
|
|
50
|
-
const mime = {
|
|
51
|
-
'.js': 'text/javascript',
|
|
52
|
-
'.css': 'text/css',
|
|
53
|
-
'.woff2': 'application/font-woff',
|
|
54
|
-
'.png': 'image/png',
|
|
55
|
-
}[ext];
|
|
56
|
-
// reply.cacheControl('max-age', '1d');
|
|
57
|
-
return mime
|
|
58
|
-
? reply
|
|
59
|
-
.headers({
|
|
60
|
-
'Cache-Control': 'public, max-age=3600',
|
|
61
|
-
'Content-Encoding': 'identity',
|
|
62
|
-
})
|
|
63
|
-
.type(mime)
|
|
64
|
-
.send(stream)
|
|
65
|
-
: stream;
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export default plugin;
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import config from '../../config.js';
|
|
4
|
+
|
|
5
|
+
const { disableAuth } = config;
|
|
6
|
+
const isProduction = process.env.NODE_ENV === 'production';
|
|
7
|
+
|
|
8
|
+
async function plugin(fastify) {
|
|
9
|
+
// vite server
|
|
10
|
+
if (!isProduction) {
|
|
11
|
+
const vite = await import('vite');
|
|
12
|
+
|
|
13
|
+
const viteServer = await vite.createServer({
|
|
14
|
+
server: {
|
|
15
|
+
middlewareMode: true,
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
// hot reload
|
|
19
|
+
viteServer.watcher.on('all', (d, t) => {
|
|
20
|
+
if (!t.includes('module') && !t.includes('templates')) return;
|
|
21
|
+
// console.log(d, t);
|
|
22
|
+
viteServer.ws.send({ type: 'full-reload' });
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// this is middleware for vite's dev servert
|
|
26
|
+
fastify.addHook('onRequest', async (req, reply) => {
|
|
27
|
+
// const { user } = req.session?.passport || {};
|
|
28
|
+
const next = () => new Promise((resolve) => {
|
|
29
|
+
viteServer.middlewares(req.raw, reply.raw, () => resolve());
|
|
30
|
+
});
|
|
31
|
+
await next();
|
|
32
|
+
});
|
|
33
|
+
fastify.get('*', async () => {});
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// From Build
|
|
38
|
+
fastify.get('*', async (req, reply) => {
|
|
39
|
+
// console.log(disableAuth)
|
|
40
|
+
if (!req.user && !disableAuth) return reply.redirect('/login');
|
|
41
|
+
const stream = fs.createReadStream('dist/index.html');
|
|
42
|
+
return reply
|
|
43
|
+
.headers({ 'Cache-Control': 'public, no-cache' })
|
|
44
|
+
.type('text/html')
|
|
45
|
+
.send(stream);
|
|
46
|
+
});
|
|
47
|
+
fastify.get('/assets/:file', async (req, reply) => {
|
|
48
|
+
const stream = fs.createReadStream(`dist/assets/${req.params.file}`);
|
|
49
|
+
const ext = path.extname(req.params.file);
|
|
50
|
+
const mime = {
|
|
51
|
+
'.js': 'text/javascript',
|
|
52
|
+
'.css': 'text/css',
|
|
53
|
+
'.woff2': 'application/font-woff',
|
|
54
|
+
'.png': 'image/png',
|
|
55
|
+
}[ext];
|
|
56
|
+
// reply.cacheControl('max-age', '1d');
|
|
57
|
+
return mime
|
|
58
|
+
? reply
|
|
59
|
+
.headers({
|
|
60
|
+
'Cache-Control': 'public, max-age=3600',
|
|
61
|
+
'Content-Encoding': 'identity',
|
|
62
|
+
})
|
|
63
|
+
.type(mime)
|
|
64
|
+
.send(stream)
|
|
65
|
+
: stream;
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export default plugin;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import yaml from 'js-yaml';
|
|
2
|
-
|
|
3
|
-
yaml.loadSafe = (yml) => {
|
|
4
|
-
try {
|
|
5
|
-
return yaml.load(yml);
|
|
6
|
-
} catch (err) {
|
|
7
|
-
return { error: err.toString() };
|
|
8
|
-
}
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export default yaml;
|
|
1
|
+
import yaml from 'js-yaml';
|
|
2
|
+
|
|
3
|
+
yaml.loadSafe = (yml) => {
|
|
4
|
+
try {
|
|
5
|
+
return yaml.load(yml);
|
|
6
|
+
} catch (err) {
|
|
7
|
+
return { error: err.toString() };
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default yaml;
|
|
@@ -100,6 +100,7 @@ export default async function dataAPI(req, reply) {
|
|
|
100
100
|
const sql = (chartSQL[type] || chartSQL.chart)({
|
|
101
101
|
where,
|
|
102
102
|
metric,
|
|
103
|
+
yType, // metric type
|
|
103
104
|
columns: widgetData.columns,
|
|
104
105
|
table: `(${optimizedSQL} ${samples ? 'limit 10' : ''})q`,
|
|
105
106
|
x,
|
|
@@ -11,6 +11,7 @@ function table({ columns = [], table, where, samples }) {
|
|
|
11
11
|
|
|
12
12
|
function chart({
|
|
13
13
|
metric,
|
|
14
|
+
yType, // metric type
|
|
14
15
|
where,
|
|
15
16
|
table,
|
|
16
17
|
x,
|
|
@@ -27,7 +28,7 @@ function chart({
|
|
|
27
28
|
?.filter(el => el.name)
|
|
28
29
|
?.map(
|
|
29
30
|
(el) =>
|
|
30
|
-
`${metric} filter (where ${
|
|
31
|
+
`${metric} filter (where '${el.name.toString().replace(/'/g, "''")}'=${yType?.includes('[]') ? `any(${groupby.replace(/'/g, "''")}::text[])` : groupby.replace(/'/g, "''")}) as "${el.name.toString().replace(/'/g, "''")}"`
|
|
31
32
|
)
|
|
32
33
|
.join(',') || `${metric} as metric`;
|
|
33
34
|
const sql = `select ${xCol} ${x && xType?.includes('[]') ? `as ${x}` : ''}, ${metricData}
|