@tachybase/plugin-block-charts 0.23.8
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/.turbo/turbo-build.log +9 -0
- package/README.md +88 -0
- package/client.d.ts +3 -0
- package/client.js +65 -0
- package/dist/client/block/ChartBlock.d.ts +2 -0
- package/dist/client/block/ChartBlockDesigner.d.ts +2 -0
- package/dist/client/block/ChartBlockInitializer.d.ts +4 -0
- package/dist/client/block/ChartDataProvider.d.ts +16 -0
- package/dist/client/block/formatters.d.ts +15 -0
- package/dist/client/block/index.d.ts +3 -0
- package/dist/client/block/transformers.d.ts +10 -0
- package/dist/client/chart/antd/GroupedTable.d.ts +6 -0
- package/dist/client/chart/antd/antd.d.ts +7 -0
- package/dist/client/chart/antd/index.d.ts +5 -0
- package/dist/client/chart/antd/statistic.d.ts +7 -0
- package/dist/client/chart/antd/table.d.ts +6 -0
- package/dist/client/chart/chart.d.ts +77 -0
- package/dist/client/chart/configs.d.ts +79 -0
- package/dist/client/chart/g2plot/AntChart.d.ts +2 -0
- package/dist/client/chart/g2plot/bar.d.ts +6 -0
- package/dist/client/chart/g2plot/configs.d.ts +40 -0
- package/dist/client/chart/g2plot/dualAxes.d.ts +7 -0
- package/dist/client/chart/g2plot/g2plot.d.ts +10 -0
- package/dist/client/chart/g2plot/index.d.ts +3 -0
- package/dist/client/chart/g2plot/pie.d.ts +7 -0
- package/dist/client/chart/group.d.ts +32 -0
- package/dist/client/configure/ChartConfigProvider.d.ts +18 -0
- package/dist/client/configure/ChartConfigure.d.ts +18 -0
- package/dist/client/configure/FilterDynamicComponent.d.ts +2 -0
- package/dist/client/configure/index.d.ts +2 -0
- package/dist/client/configure/schemas/configure.d.ts +4 -0
- package/dist/client/filter/CollectionFieldInitializer.d.ts +2 -0
- package/dist/client/filter/FilterActionInitializers.d.ts +15 -0
- package/dist/client/filter/FilterBlockDesigner.d.ts +2 -0
- package/dist/client/filter/FilterBlockInitializer.d.ts +3 -0
- package/dist/client/filter/FilterBlockProvider.d.ts +2 -0
- package/dist/client/filter/FilterCheckbox.d.ts +2 -0
- package/dist/client/filter/FilterForm.d.ts +2 -0
- package/dist/client/filter/FilterItemDesigner.d.ts +2 -0
- package/dist/client/filter/FilterItemInitializers.d.ts +7 -0
- package/dist/client/filter/FilterProvider.d.ts +30 -0
- package/dist/client/filter/FilterVariableInput.d.ts +2 -0
- package/dist/client/filter/index.d.ts +6 -0
- package/dist/client/filter/utils.d.ts +59 -0
- package/dist/client/hooks/filter.d.ts +225 -0
- package/dist/client/hooks/index.d.ts +4 -0
- package/dist/client/hooks/query.d.ts +52 -0
- package/dist/client/hooks/transformer.d.ts +12 -0
- package/dist/client/hooks/useDateVariable.d.ts +14 -0
- package/dist/client/hooks/useUserVariable.d.ts +8 -0
- package/dist/client/hooks/useVariableOptions.d.ts +10 -0
- package/dist/client/index.d.ts +13 -0
- package/dist/client/index.js +234 -0
- package/dist/client/locale/index.d.ts +3 -0
- package/dist/client/renderer/ChartRenderer.d.ts +4 -0
- package/dist/client/renderer/ChartRendererProvider.d.ts +49 -0
- package/dist/client/renderer/index.d.ts +2 -0
- package/dist/client/utils.d.ts +44 -0
- package/dist/externalVersion.js +18 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +39 -0
- package/dist/locale/en-US.json +89 -0
- package/dist/locale/ko_KR.json +85 -0
- package/dist/locale/zh-CN.json +90 -0
- package/dist/node_modules/fs-extra/LICENSE +15 -0
- package/dist/node_modules/fs-extra/lib/copy/copy-sync.js +161 -0
- package/dist/node_modules/fs-extra/lib/copy/copy.js +177 -0
- package/dist/node_modules/fs-extra/lib/copy/index.js +7 -0
- package/dist/node_modules/fs-extra/lib/empty/index.js +39 -0
- package/dist/node_modules/fs-extra/lib/ensure/file.js +66 -0
- package/dist/node_modules/fs-extra/lib/ensure/index.js +23 -0
- package/dist/node_modules/fs-extra/lib/ensure/link.js +64 -0
- package/dist/node_modules/fs-extra/lib/ensure/symlink-paths.js +101 -0
- package/dist/node_modules/fs-extra/lib/ensure/symlink-type.js +34 -0
- package/dist/node_modules/fs-extra/lib/ensure/symlink.js +67 -0
- package/dist/node_modules/fs-extra/lib/fs/index.js +140 -0
- package/dist/node_modules/fs-extra/lib/index.js +1 -0
- package/dist/node_modules/fs-extra/lib/json/index.js +16 -0
- package/dist/node_modules/fs-extra/lib/json/jsonfile.js +11 -0
- package/dist/node_modules/fs-extra/lib/json/output-json-sync.js +12 -0
- package/dist/node_modules/fs-extra/lib/json/output-json.js +12 -0
- package/dist/node_modules/fs-extra/lib/mkdirs/index.js +14 -0
- package/dist/node_modules/fs-extra/lib/mkdirs/make-dir.js +27 -0
- package/dist/node_modules/fs-extra/lib/mkdirs/utils.js +21 -0
- package/dist/node_modules/fs-extra/lib/move/index.js +7 -0
- package/dist/node_modules/fs-extra/lib/move/move-sync.js +55 -0
- package/dist/node_modules/fs-extra/lib/move/move.js +59 -0
- package/dist/node_modules/fs-extra/lib/output-file/index.js +31 -0
- package/dist/node_modules/fs-extra/lib/path-exists/index.js +12 -0
- package/dist/node_modules/fs-extra/lib/remove/index.js +17 -0
- package/dist/node_modules/fs-extra/lib/util/stat.js +158 -0
- package/dist/node_modules/fs-extra/lib/util/utimes.js +36 -0
- package/dist/node_modules/fs-extra/package.json +1 -0
- package/dist/node_modules/koa-compose/index.js +1 -0
- package/dist/node_modules/koa-compose/package.json +1 -0
- package/dist/server/actions/formatter.d.ts +4 -0
- package/dist/server/actions/formatter.js +67 -0
- package/dist/server/actions/query.d.ts +8 -0
- package/dist/server/actions/query.js +320 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +33 -0
- package/dist/server/migrations/20230926211750-rename-charttype.d.ts +5 -0
- package/dist/server/migrations/20230926211750-rename-charttype.js +51 -0
- package/dist/server/plugin.d.ts +13 -0
- package/dist/server/plugin.js +83 -0
- package/dist/server/services/sql-loader.d.ts +10 -0
- package/dist/server/services/sql-loader.js +134 -0
- package/dist/server/sqls/view_load_function.sql +17 -0
- package/dist/server/utils/multiprocess.d.ts +2 -0
- package/dist/server/utils/multiprocess.js +38 -0
- package/dist/swagger/index.d.ts +8 -0
- package/dist/swagger/index.js +29 -0
- package/package.json +44 -0
- package/server.d.ts +3 -0
- package/server.js +65 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const fs = require('../fs')
|
|
4
|
+
const path = require('path')
|
|
5
|
+
const u = require('universalify').fromPromise
|
|
6
|
+
|
|
7
|
+
function getStats (src, dest, opts) {
|
|
8
|
+
const statFunc = opts.dereference
|
|
9
|
+
? (file) => fs.stat(file, { bigint: true })
|
|
10
|
+
: (file) => fs.lstat(file, { bigint: true })
|
|
11
|
+
return Promise.all([
|
|
12
|
+
statFunc(src),
|
|
13
|
+
statFunc(dest).catch(err => {
|
|
14
|
+
if (err.code === 'ENOENT') return null
|
|
15
|
+
throw err
|
|
16
|
+
})
|
|
17
|
+
]).then(([srcStat, destStat]) => ({ srcStat, destStat }))
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function getStatsSync (src, dest, opts) {
|
|
21
|
+
let destStat
|
|
22
|
+
const statFunc = opts.dereference
|
|
23
|
+
? (file) => fs.statSync(file, { bigint: true })
|
|
24
|
+
: (file) => fs.lstatSync(file, { bigint: true })
|
|
25
|
+
const srcStat = statFunc(src)
|
|
26
|
+
try {
|
|
27
|
+
destStat = statFunc(dest)
|
|
28
|
+
} catch (err) {
|
|
29
|
+
if (err.code === 'ENOENT') return { srcStat, destStat: null }
|
|
30
|
+
throw err
|
|
31
|
+
}
|
|
32
|
+
return { srcStat, destStat }
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function checkPaths (src, dest, funcName, opts) {
|
|
36
|
+
const { srcStat, destStat } = await getStats(src, dest, opts)
|
|
37
|
+
if (destStat) {
|
|
38
|
+
if (areIdentical(srcStat, destStat)) {
|
|
39
|
+
const srcBaseName = path.basename(src)
|
|
40
|
+
const destBaseName = path.basename(dest)
|
|
41
|
+
if (funcName === 'move' &&
|
|
42
|
+
srcBaseName !== destBaseName &&
|
|
43
|
+
srcBaseName.toLowerCase() === destBaseName.toLowerCase()) {
|
|
44
|
+
return { srcStat, destStat, isChangingCase: true }
|
|
45
|
+
}
|
|
46
|
+
throw new Error('Source and destination must not be the same.')
|
|
47
|
+
}
|
|
48
|
+
if (srcStat.isDirectory() && !destStat.isDirectory()) {
|
|
49
|
+
throw new Error(`Cannot overwrite non-directory '${dest}' with directory '${src}'.`)
|
|
50
|
+
}
|
|
51
|
+
if (!srcStat.isDirectory() && destStat.isDirectory()) {
|
|
52
|
+
throw new Error(`Cannot overwrite directory '${dest}' with non-directory '${src}'.`)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (srcStat.isDirectory() && isSrcSubdir(src, dest)) {
|
|
57
|
+
throw new Error(errMsg(src, dest, funcName))
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return { srcStat, destStat }
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function checkPathsSync (src, dest, funcName, opts) {
|
|
64
|
+
const { srcStat, destStat } = getStatsSync(src, dest, opts)
|
|
65
|
+
|
|
66
|
+
if (destStat) {
|
|
67
|
+
if (areIdentical(srcStat, destStat)) {
|
|
68
|
+
const srcBaseName = path.basename(src)
|
|
69
|
+
const destBaseName = path.basename(dest)
|
|
70
|
+
if (funcName === 'move' &&
|
|
71
|
+
srcBaseName !== destBaseName &&
|
|
72
|
+
srcBaseName.toLowerCase() === destBaseName.toLowerCase()) {
|
|
73
|
+
return { srcStat, destStat, isChangingCase: true }
|
|
74
|
+
}
|
|
75
|
+
throw new Error('Source and destination must not be the same.')
|
|
76
|
+
}
|
|
77
|
+
if (srcStat.isDirectory() && !destStat.isDirectory()) {
|
|
78
|
+
throw new Error(`Cannot overwrite non-directory '${dest}' with directory '${src}'.`)
|
|
79
|
+
}
|
|
80
|
+
if (!srcStat.isDirectory() && destStat.isDirectory()) {
|
|
81
|
+
throw new Error(`Cannot overwrite directory '${dest}' with non-directory '${src}'.`)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (srcStat.isDirectory() && isSrcSubdir(src, dest)) {
|
|
86
|
+
throw new Error(errMsg(src, dest, funcName))
|
|
87
|
+
}
|
|
88
|
+
return { srcStat, destStat }
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// recursively check if dest parent is a subdirectory of src.
|
|
92
|
+
// It works for all file types including symlinks since it
|
|
93
|
+
// checks the src and dest inodes. It starts from the deepest
|
|
94
|
+
// parent and stops once it reaches the src parent or the root path.
|
|
95
|
+
async function checkParentPaths (src, srcStat, dest, funcName) {
|
|
96
|
+
const srcParent = path.resolve(path.dirname(src))
|
|
97
|
+
const destParent = path.resolve(path.dirname(dest))
|
|
98
|
+
if (destParent === srcParent || destParent === path.parse(destParent).root) return
|
|
99
|
+
|
|
100
|
+
let destStat
|
|
101
|
+
try {
|
|
102
|
+
destStat = await fs.stat(destParent, { bigint: true })
|
|
103
|
+
} catch (err) {
|
|
104
|
+
if (err.code === 'ENOENT') return
|
|
105
|
+
throw err
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (areIdentical(srcStat, destStat)) {
|
|
109
|
+
throw new Error(errMsg(src, dest, funcName))
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return checkParentPaths(src, srcStat, destParent, funcName)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function checkParentPathsSync (src, srcStat, dest, funcName) {
|
|
116
|
+
const srcParent = path.resolve(path.dirname(src))
|
|
117
|
+
const destParent = path.resolve(path.dirname(dest))
|
|
118
|
+
if (destParent === srcParent || destParent === path.parse(destParent).root) return
|
|
119
|
+
let destStat
|
|
120
|
+
try {
|
|
121
|
+
destStat = fs.statSync(destParent, { bigint: true })
|
|
122
|
+
} catch (err) {
|
|
123
|
+
if (err.code === 'ENOENT') return
|
|
124
|
+
throw err
|
|
125
|
+
}
|
|
126
|
+
if (areIdentical(srcStat, destStat)) {
|
|
127
|
+
throw new Error(errMsg(src, dest, funcName))
|
|
128
|
+
}
|
|
129
|
+
return checkParentPathsSync(src, srcStat, destParent, funcName)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function areIdentical (srcStat, destStat) {
|
|
133
|
+
return destStat.ino && destStat.dev && destStat.ino === srcStat.ino && destStat.dev === srcStat.dev
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// return true if dest is a subdir of src, otherwise false.
|
|
137
|
+
// It only checks the path strings.
|
|
138
|
+
function isSrcSubdir (src, dest) {
|
|
139
|
+
const srcArr = path.resolve(src).split(path.sep).filter(i => i)
|
|
140
|
+
const destArr = path.resolve(dest).split(path.sep).filter(i => i)
|
|
141
|
+
return srcArr.every((cur, i) => destArr[i] === cur)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function errMsg (src, dest, funcName) {
|
|
145
|
+
return `Cannot ${funcName} '${src}' to a subdirectory of itself, '${dest}'.`
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
module.exports = {
|
|
149
|
+
// checkPaths
|
|
150
|
+
checkPaths: u(checkPaths),
|
|
151
|
+
checkPathsSync,
|
|
152
|
+
// checkParent
|
|
153
|
+
checkParentPaths: u(checkParentPaths),
|
|
154
|
+
checkParentPathsSync,
|
|
155
|
+
// Misc
|
|
156
|
+
isSrcSubdir,
|
|
157
|
+
areIdentical
|
|
158
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const fs = require('../fs')
|
|
4
|
+
const u = require('universalify').fromPromise
|
|
5
|
+
|
|
6
|
+
async function utimesMillis (path, atime, mtime) {
|
|
7
|
+
// if (!HAS_MILLIS_RES) return fs.utimes(path, atime, mtime, callback)
|
|
8
|
+
const fd = await fs.open(path, 'r+')
|
|
9
|
+
|
|
10
|
+
let closeErr = null
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
await fs.futimes(fd, atime, mtime)
|
|
14
|
+
} finally {
|
|
15
|
+
try {
|
|
16
|
+
await fs.close(fd)
|
|
17
|
+
} catch (e) {
|
|
18
|
+
closeErr = e
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (closeErr) {
|
|
23
|
+
throw closeErr
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function utimesMillisSync (path, atime, mtime) {
|
|
28
|
+
const fd = fs.openSync(path, 'r+')
|
|
29
|
+
fs.futimesSync(fd, atime, mtime)
|
|
30
|
+
return fs.closeSync(fd)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
module.exports = {
|
|
34
|
+
utimesMillis: u(utimesMillis),
|
|
35
|
+
utimesMillisSync
|
|
36
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"name":"fs-extra","version":"11.2.0","description":"fs-extra contains methods that aren't included in the vanilla Node.js fs package. Such as recursive mkdir, copy, and remove.","engines":{"node":">=14.14"},"homepage":"https://github.com/jprichardson/node-fs-extra","repository":{"type":"git","url":"https://github.com/jprichardson/node-fs-extra"},"keywords":["fs","file","file system","copy","directory","extra","mkdirp","mkdir","mkdirs","recursive","json","read","write","extra","delete","remove","touch","create","text","output","move","promise"],"author":"JP Richardson <jprichardson@gmail.com>","license":"MIT","dependencies":{"graceful-fs":"^4.2.0","jsonfile":"^6.0.1","universalify":"^2.0.0"},"devDependencies":{"klaw":"^2.1.1","klaw-sync":"^3.0.2","minimist":"^1.1.1","mocha":"^10.1.0","nyc":"^15.0.0","proxyquire":"^2.0.1","read-dir-files":"^0.1.1","standard":"^17.0.0"},"main":"./lib/index.js","exports":{".":"./lib/index.js","./esm":"./lib/esm.mjs"},"files":["lib/","!lib/**/__tests__/"],"scripts":{"lint":"standard","test-find":"find ./lib/**/__tests__ -name *.test.js | xargs mocha","test":"npm run lint && npm run unit && npm run unit-esm","unit":"nyc node test.js","unit-esm":"node test.mjs"},"sideEffects":false,"_lastModified":"2024-12-22T16:06:01.213Z"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(){"use strict";var e={943:function(e){e.exports=compose;function compose(e){if(!Array.isArray(e))throw new TypeError("Middleware stack must be an array!");for(const r of e){if(typeof r!=="function")throw new TypeError("Middleware must be composed of functions!")}return function(r,t){let i=-1;return dispatch(0);function dispatch(n){if(n<=i)return Promise.reject(new Error("next() called multiple times"));i=n;let o=e[n];if(n===e.length)o=t;if(!o)return Promise.resolve();try{return Promise.resolve(o(r,dispatch.bind(null,n+1)))}catch(e){return Promise.reject(e)}}}}}};var r={};function __nccwpck_require__(t){var i=r[t];if(i!==undefined){return i.exports}var n=r[t]={exports:{}};var o=true;try{e[t](n,n.exports,__nccwpck_require__);o=false}finally{if(o)delete r[t]}return n.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var t=__nccwpck_require__(943);module.exports=t})();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"name":"koa-compose","description":"compose Koa middleware","repository":"koajs/compose","version":"4.1.0","keywords":["koa","middleware","compose"],"files":["index.js"],"dependencies":{},"devDependencies":{"codecov":"^3.0.0","jest":"^21.0.0","matcha":"^0.7.0","standard":"^10.0.3"},"scripts":{"bench":"matcha bench/bench.js","lint":"standard --fix .","test":"jest --forceExit --coverage"},"jest":{"testEnvironment":"node"},"license":"MIT","_lastModified":"2024-12-22T16:06:01.005Z"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Sequelize } from 'sequelize';
|
|
2
|
+
export declare const dateFormatFn: (sequelize: Sequelize, dialect: string, field: string, format: string, timezone: string) => import("sequelize/lib/utils").Col | import("sequelize/lib/utils").Fn;
|
|
3
|
+
export declare const formatFn: (sequelize: Sequelize, dialect: string, field: string, format: string) => string | import("sequelize/lib/utils").Fn;
|
|
4
|
+
export declare const formatter: (sequelize: Sequelize, type: string, field: string, format: string, timezone: string) => string | import("sequelize/lib/utils").Col | import("sequelize/lib/utils").Fn;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var formatter_exports = {};
|
|
19
|
+
__export(formatter_exports, {
|
|
20
|
+
dateFormatFn: () => dateFormatFn,
|
|
21
|
+
formatFn: () => formatFn,
|
|
22
|
+
formatter: () => formatter
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(formatter_exports);
|
|
25
|
+
const dateFormatFn = (sequelize, dialect, field, format, timezone) => {
|
|
26
|
+
const reversedTimezone = timezone[0] === "+" ? "-" + timezone.slice(1) : "+" + timezone.slice(1);
|
|
27
|
+
switch (dialect) {
|
|
28
|
+
case "sqlite":
|
|
29
|
+
format = format.replace(/YYYY/g, "%Y").replace(/MM/g, "%m").replace(/DD/g, "%d").replace(/hh/g, "%H").replace(/mm/g, "%M").replace(/ss/g, "%S");
|
|
30
|
+
return sequelize.fn("strftime", format, sequelize.col(field));
|
|
31
|
+
case "mysql":
|
|
32
|
+
case "mariadb":
|
|
33
|
+
format = format.replace(/YYYY/g, "%Y").replace(/MM/g, "%m").replace(/DD/g, "%d").replace(/hh/g, "%H").replace(/mm/g, "%i").replace(/ss/g, "%S");
|
|
34
|
+
return sequelize.fn("date_format", sequelize.col(field), format);
|
|
35
|
+
case "postgres":
|
|
36
|
+
format = format.replace(/hh/g, "HH24").replace(/mm/g, "MI").replace(/ss/g, "SS");
|
|
37
|
+
return sequelize.fn("format_timestamp_with_timezone", sequelize.col(field), reversedTimezone, format);
|
|
38
|
+
default:
|
|
39
|
+
return sequelize.col(field);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const formatFn = (sequelize, dialect, field, format) => {
|
|
43
|
+
switch (dialect) {
|
|
44
|
+
case "sqlite":
|
|
45
|
+
case "postgres":
|
|
46
|
+
return sequelize.fn("format", format, sequelize.col(field));
|
|
47
|
+
default:
|
|
48
|
+
return field;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const formatter = (sequelize, type, field, format, timezone) => {
|
|
52
|
+
const dialect = sequelize.getDialect();
|
|
53
|
+
switch (type) {
|
|
54
|
+
case "date":
|
|
55
|
+
case "datetime":
|
|
56
|
+
case "time":
|
|
57
|
+
return dateFormatFn(sequelize, dialect, field, format, timezone);
|
|
58
|
+
default:
|
|
59
|
+
return formatFn(sequelize, dialect, field, format);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
63
|
+
0 && (module.exports = {
|
|
64
|
+
dateFormatFn,
|
|
65
|
+
formatFn,
|
|
66
|
+
formatter
|
|
67
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Context, Next } from '@tachybase/actions';
|
|
2
|
+
export declare const postProcess: (ctx: Context, next: Next) => Promise<void>;
|
|
3
|
+
export declare const queryData: (ctx: Context, next: Next) => Promise<void>;
|
|
4
|
+
export declare const parseBuilder: (ctx: Context, next: Next) => Promise<void>;
|
|
5
|
+
export declare const parseFieldAndAssociations: (ctx: Context, next: Next) => Promise<void>;
|
|
6
|
+
export declare const parseVariables: (ctx: Context, next: Next) => Promise<any>;
|
|
7
|
+
export declare const cacheMiddleware: (ctx: Context, next: Next) => Promise<void>;
|
|
8
|
+
export declare const query: (ctx: Context, next: Next) => Promise<void>;
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
var query_exports = {};
|
|
29
|
+
__export(query_exports, {
|
|
30
|
+
cacheMiddleware: () => cacheMiddleware,
|
|
31
|
+
parseBuilder: () => parseBuilder,
|
|
32
|
+
parseFieldAndAssociations: () => parseFieldAndAssociations,
|
|
33
|
+
parseVariables: () => parseVariables,
|
|
34
|
+
postProcess: () => postProcess,
|
|
35
|
+
query: () => query,
|
|
36
|
+
queryData: () => queryData
|
|
37
|
+
});
|
|
38
|
+
module.exports = __toCommonJS(query_exports);
|
|
39
|
+
var import_database = require("@tachybase/database");
|
|
40
|
+
var import_utils = require("@tachybase/utils");
|
|
41
|
+
var import_koa_compose = __toESM(require("koa-compose"));
|
|
42
|
+
var import_formatter = require("./formatter");
|
|
43
|
+
const getDB = (ctx, dataSource) => {
|
|
44
|
+
const ds = ctx.app.dataSourceManager.dataSources.get(dataSource);
|
|
45
|
+
return ds == null ? void 0 : ds.collectionManager.db;
|
|
46
|
+
};
|
|
47
|
+
const postProcess = async (ctx, next) => {
|
|
48
|
+
const { data, fieldMap } = ctx.action.params.values;
|
|
49
|
+
ctx.body = data.map((record) => {
|
|
50
|
+
Object.entries(record).forEach(([key, value]) => {
|
|
51
|
+
if (!value) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const { type } = fieldMap[key] || {};
|
|
55
|
+
switch (type) {
|
|
56
|
+
case "bigInt":
|
|
57
|
+
case "integer":
|
|
58
|
+
case "float":
|
|
59
|
+
case "double":
|
|
60
|
+
record[key] = Number(value);
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
return record;
|
|
65
|
+
});
|
|
66
|
+
await next();
|
|
67
|
+
};
|
|
68
|
+
const queryData = async (ctx, next) => {
|
|
69
|
+
const { dataSource, collection, queryParams, fieldMap } = ctx.action.params.values;
|
|
70
|
+
const db = getDB(ctx, dataSource) || ctx.db;
|
|
71
|
+
const model = db.getModel(collection);
|
|
72
|
+
const data = await model.findAll(queryParams);
|
|
73
|
+
ctx.action.params.values = {
|
|
74
|
+
data,
|
|
75
|
+
fieldMap
|
|
76
|
+
};
|
|
77
|
+
await next();
|
|
78
|
+
};
|
|
79
|
+
const parseBuilder = async (ctx, next) => {
|
|
80
|
+
const { dataSource, measures, dimensions, orders, include, where, limit } = ctx.action.params.values;
|
|
81
|
+
const db = getDB(ctx, dataSource) || ctx.db;
|
|
82
|
+
const { sequelize } = db;
|
|
83
|
+
const attributes = [];
|
|
84
|
+
const group = [];
|
|
85
|
+
const order = [];
|
|
86
|
+
const fieldMap = {};
|
|
87
|
+
let hasAgg = false;
|
|
88
|
+
measures.forEach((measure) => {
|
|
89
|
+
const { field, aggregation, alias } = measure;
|
|
90
|
+
const attribute = [];
|
|
91
|
+
const col = sequelize.col(field);
|
|
92
|
+
if (aggregation) {
|
|
93
|
+
hasAgg = true;
|
|
94
|
+
attribute.push(sequelize.fn(aggregation, col));
|
|
95
|
+
} else {
|
|
96
|
+
attribute.push(col);
|
|
97
|
+
}
|
|
98
|
+
if (alias) {
|
|
99
|
+
attribute.push(alias);
|
|
100
|
+
}
|
|
101
|
+
attributes.push(attribute.length > 1 ? attribute : attribute[0]);
|
|
102
|
+
fieldMap[alias || field] = measure;
|
|
103
|
+
});
|
|
104
|
+
dimensions.forEach((dimension) => {
|
|
105
|
+
const { field, format, alias, type } = dimension;
|
|
106
|
+
const attribute = [];
|
|
107
|
+
const col = sequelize.col(field);
|
|
108
|
+
if (format) {
|
|
109
|
+
attribute.push((0, import_formatter.formatter)(sequelize, type, field, format, ctx.get("x-timezone")));
|
|
110
|
+
} else {
|
|
111
|
+
attribute.push(col);
|
|
112
|
+
}
|
|
113
|
+
if (alias) {
|
|
114
|
+
attribute.push(alias);
|
|
115
|
+
}
|
|
116
|
+
attributes.push(attribute.length > 1 ? attribute : attribute[0]);
|
|
117
|
+
if (hasAgg) {
|
|
118
|
+
group.push(attribute[0]);
|
|
119
|
+
}
|
|
120
|
+
fieldMap[alias || field] = dimension;
|
|
121
|
+
});
|
|
122
|
+
orders.forEach((item) => {
|
|
123
|
+
const alias = sequelize.getQueryInterface().quoteIdentifier(item.alias);
|
|
124
|
+
const name = hasAgg ? sequelize.literal(alias) : sequelize.col(item.field);
|
|
125
|
+
order.push([name, item.order || "ASC"]);
|
|
126
|
+
});
|
|
127
|
+
ctx.action.params.values = {
|
|
128
|
+
...ctx.action.params.values,
|
|
129
|
+
queryParams: {
|
|
130
|
+
where,
|
|
131
|
+
attributes,
|
|
132
|
+
include,
|
|
133
|
+
group,
|
|
134
|
+
order,
|
|
135
|
+
limit: limit || 2e3,
|
|
136
|
+
subQuery: false,
|
|
137
|
+
raw: true
|
|
138
|
+
},
|
|
139
|
+
fieldMap
|
|
140
|
+
};
|
|
141
|
+
await next();
|
|
142
|
+
};
|
|
143
|
+
const parseFieldAndAssociations = async (ctx, next) => {
|
|
144
|
+
const {
|
|
145
|
+
dataSource,
|
|
146
|
+
collection: collectionName,
|
|
147
|
+
measures,
|
|
148
|
+
dimensions,
|
|
149
|
+
orders,
|
|
150
|
+
filter
|
|
151
|
+
} = ctx.action.params.values;
|
|
152
|
+
const db = getDB(ctx, dataSource) || ctx.db;
|
|
153
|
+
const collection = db.getCollection(collectionName);
|
|
154
|
+
const fields = collection.fields;
|
|
155
|
+
const models = {};
|
|
156
|
+
const parseField = (selected) => {
|
|
157
|
+
var _a, _b, _c, _d;
|
|
158
|
+
let target;
|
|
159
|
+
let name;
|
|
160
|
+
if (!Array.isArray(selected.field)) {
|
|
161
|
+
name = selected.field;
|
|
162
|
+
} else if (selected.field.length === 1) {
|
|
163
|
+
name = selected.field[0];
|
|
164
|
+
} else if (selected.field.length > 1) {
|
|
165
|
+
[target, name] = selected.field;
|
|
166
|
+
}
|
|
167
|
+
const rawAttributes = collection.model.getAttributes();
|
|
168
|
+
let field = ((_a = rawAttributes[name]) == null ? void 0 : _a.field) || name;
|
|
169
|
+
let fieldType = (_b = fields.get(name)) == null ? void 0 : _b.type;
|
|
170
|
+
if (target) {
|
|
171
|
+
const targetField = fields.get(target);
|
|
172
|
+
const targetCollection = db.getCollection(targetField.target);
|
|
173
|
+
const targetFields = targetCollection.fields;
|
|
174
|
+
fieldType = (_c = targetFields.get(name)) == null ? void 0 : _c.type;
|
|
175
|
+
field = `${target}.${field}`;
|
|
176
|
+
name = `${target}.${name}`;
|
|
177
|
+
const targetType = (_d = fields.get(target)) == null ? void 0 : _d.type;
|
|
178
|
+
if (!models[target]) {
|
|
179
|
+
models[target] = { type: targetType };
|
|
180
|
+
}
|
|
181
|
+
} else {
|
|
182
|
+
field = `${collectionName}.${field}`;
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
...selected,
|
|
186
|
+
field,
|
|
187
|
+
name,
|
|
188
|
+
type: fieldType,
|
|
189
|
+
alias: selected.alias || name
|
|
190
|
+
};
|
|
191
|
+
};
|
|
192
|
+
const parsedMeasures = (measures == null ? void 0 : measures.map(parseField)) || [];
|
|
193
|
+
const parsedDimensions = (dimensions == null ? void 0 : dimensions.map(parseField)) || [];
|
|
194
|
+
const parsedOrders = (orders == null ? void 0 : orders.map(parseField)) || [];
|
|
195
|
+
const include = Object.entries(models).map(([target, { type }]) => ({
|
|
196
|
+
association: target,
|
|
197
|
+
attributes: [],
|
|
198
|
+
...type === "belongsToMany" ? { through: { attributes: [] } } : {}
|
|
199
|
+
}));
|
|
200
|
+
const filterParser = new import_database.FilterParser(filter, {
|
|
201
|
+
collection
|
|
202
|
+
});
|
|
203
|
+
const { where, include: filterInclude } = filterParser.toSequelizeParams();
|
|
204
|
+
const parsedFilterInclude = filterInclude == null ? void 0 : filterInclude.map((item) => {
|
|
205
|
+
var _a;
|
|
206
|
+
if (((_a = fields.get(item.association)) == null ? void 0 : _a.type) === "belongsToMany") {
|
|
207
|
+
item.through = { attributes: [] };
|
|
208
|
+
}
|
|
209
|
+
return item;
|
|
210
|
+
});
|
|
211
|
+
ctx.action.params.values = {
|
|
212
|
+
...ctx.action.params.values,
|
|
213
|
+
where,
|
|
214
|
+
measures: parsedMeasures,
|
|
215
|
+
dimensions: parsedDimensions,
|
|
216
|
+
orders: parsedOrders,
|
|
217
|
+
include: [...include, ...parsedFilterInclude || []]
|
|
218
|
+
};
|
|
219
|
+
await next();
|
|
220
|
+
};
|
|
221
|
+
const parseVariables = async (ctx, next) => {
|
|
222
|
+
const { filter } = ctx.action.params.values;
|
|
223
|
+
if (!filter) {
|
|
224
|
+
return next();
|
|
225
|
+
}
|
|
226
|
+
const isNumeric = (str) => {
|
|
227
|
+
if (typeof str === "number") return true;
|
|
228
|
+
if (typeof str != "string") return false;
|
|
229
|
+
return !isNaN(str) && !isNaN(parseFloat(str));
|
|
230
|
+
};
|
|
231
|
+
const getUser = () => {
|
|
232
|
+
return async ({ fields }) => {
|
|
233
|
+
var _a, _b;
|
|
234
|
+
const userFields = fields.filter((f) => f && ctx.db.getFieldByPath("users." + f));
|
|
235
|
+
(_a = ctx.logger) == null ? void 0 : _a.info("parse filter variables", { userFields, method: "parseVariables" });
|
|
236
|
+
if (!ctx.state.currentUser) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
if (!userFields.length) {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
const user = await ctx.db.getRepository("users").findOne({
|
|
243
|
+
filterByTk: ctx.state.currentUser.id,
|
|
244
|
+
fields: userFields
|
|
245
|
+
});
|
|
246
|
+
(_b = ctx.logger) == null ? void 0 : _b.info("parse filter variables", {
|
|
247
|
+
$user: user == null ? void 0 : user.toJSON(),
|
|
248
|
+
method: "parseVariables"
|
|
249
|
+
});
|
|
250
|
+
return user;
|
|
251
|
+
};
|
|
252
|
+
};
|
|
253
|
+
ctx.action.params.values.filter = await (0, import_utils.parseFilter)(filter, {
|
|
254
|
+
timezone: ctx.get("x-timezone"),
|
|
255
|
+
now: (/* @__PURE__ */ new Date()).toISOString(),
|
|
256
|
+
getField: (path) => {
|
|
257
|
+
const fieldPath = path.split(".").filter((p) => !p.startsWith("$") && !isNumeric(p)).join(".");
|
|
258
|
+
const { resourceName } = ctx.action;
|
|
259
|
+
return ctx.db.getFieldByPath(`${resourceName}.${fieldPath}`);
|
|
260
|
+
},
|
|
261
|
+
vars: {
|
|
262
|
+
$nDate: (0, import_utils.getDateVars)(),
|
|
263
|
+
$user: getUser()
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
await next();
|
|
267
|
+
};
|
|
268
|
+
const cacheMiddleware = async (ctx, next) => {
|
|
269
|
+
const { uid, cache: cacheConfig, refresh } = ctx.action.params.values;
|
|
270
|
+
const cache = ctx.app.cacheManager.getCache("data-visualization");
|
|
271
|
+
const useCache = (cacheConfig == null ? void 0 : cacheConfig.enabled) && uid;
|
|
272
|
+
if (useCache && !refresh) {
|
|
273
|
+
const data = await cache.get(uid);
|
|
274
|
+
if (data) {
|
|
275
|
+
ctx.body = data;
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
await next();
|
|
280
|
+
if (useCache) {
|
|
281
|
+
await cache.set(uid, ctx.body, (cacheConfig == null ? void 0 : cacheConfig.ttl) * 1e3);
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
const checkPermission = (ctx, next) => {
|
|
285
|
+
if (ctx.action.params.values === void 0) {
|
|
286
|
+
ctx.action.params.values = ctx.action.params;
|
|
287
|
+
}
|
|
288
|
+
const { collection } = ctx.action.params.values;
|
|
289
|
+
const roleName = ctx.state.currentRole || "anonymous";
|
|
290
|
+
const can = ctx.app.acl.can({ role: roleName, resource: collection, action: "list" });
|
|
291
|
+
if (!can && roleName !== "root") {
|
|
292
|
+
ctx.throw(403, "No permissions");
|
|
293
|
+
}
|
|
294
|
+
return next();
|
|
295
|
+
};
|
|
296
|
+
const query = async (ctx, next) => {
|
|
297
|
+
try {
|
|
298
|
+
await (0, import_koa_compose.default)([
|
|
299
|
+
checkPermission,
|
|
300
|
+
cacheMiddleware,
|
|
301
|
+
parseVariables,
|
|
302
|
+
parseFieldAndAssociations,
|
|
303
|
+
parseBuilder,
|
|
304
|
+
queryData,
|
|
305
|
+
postProcess
|
|
306
|
+
])(ctx, next);
|
|
307
|
+
} catch (err) {
|
|
308
|
+
ctx.throw(500, err);
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
312
|
+
0 && (module.exports = {
|
|
313
|
+
cacheMiddleware,
|
|
314
|
+
parseBuilder,
|
|
315
|
+
parseFieldAndAssociations,
|
|
316
|
+
parseVariables,
|
|
317
|
+
postProcess,
|
|
318
|
+
query,
|
|
319
|
+
queryData
|
|
320
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './plugin';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
var server_exports = {};
|
|
29
|
+
__export(server_exports, {
|
|
30
|
+
default: () => import_plugin.default
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(server_exports);
|
|
33
|
+
var import_plugin = __toESM(require("./plugin"));
|