diff --git a/.gitignore b/.gitignore index d27e6fa15..5b014fbc1 100644 --- a/.gitignore +++ b/.gitignore @@ -19,4 +19,3 @@ nezha-fronted/src/components/common/rightBox/tempRoghtBox.vue nezha-fronted/exportHtml/ nezha-fronted/src/a.txt nezha-fronted/src/components/common/testTopology.vue -nezha-fronted/static/ diff --git a/nezha-fronted/build/webpack.prod.conf.js b/nezha-fronted/build/webpack.prod.conf.js index 7f79c9983..58fcb43f8 100644 --- a/nezha-fronted/build/webpack.prod.conf.js +++ b/nezha-fronted/build/webpack.prod.conf.js @@ -8,9 +8,9 @@ const merge = require('webpack-merge') const baseWebpackConfig = require('./webpack.base.conf') const CopyWebpackPlugin = require('copy-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') -//const ExtractTextPlugin = require('extract-text-webpack-plugin') +// const ExtractTextPlugin = require('extract-text-webpack-plugin') const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') - const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin') +const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin') const fileManagerPlugin = require('filemanager-webpack-plugin') const WebpackZipPlugin = require('webpack-zip-plugin') const UglifyJsPlugin = require('uglifyjs-webpack-plugin') @@ -19,14 +19,13 @@ const GenerateAssetPlugin = require('generate-asset-webpack-plugin') const WebpackShellPlugin = require('webpack-shell-plugin') const HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin') const serverConfig = require('../static/config.json')// 引入根目录下的配置文件 -const SpeedMeasurePlugin = require("speed-measure-webpack-plugin"); +const SpeedMeasurePlugin = require('speed-measure-webpack-plugin') const CssMinimizerPlugin = require('css-minimizer-webpack-plugin') const MiniCssExtractPlugin = require('mini-css-extract-plugin') const TerserPlugin = require('terser-webpack-plugin') const { VueLoaderPlugin } = require('vue-loader') // const smp = new SpeedMeasurePlugin(); - // const gitRevisionPlugin = new GitRevisionPlugin(); const createJson = function () { // serverConfig.version=config.build.version +"-"+gitRevisionPlugin.commithash(); @@ -61,7 +60,7 @@ if (arg === 'html') { plugins: [ new VueLoaderPlugin(), new webpack.ProvidePlugin({ - introJs: ['intro.js'], + introJs: ['intro.js'] }), /* new GenerateAssetPlugin({ filename: 'config.json', @@ -76,7 +75,7 @@ if (arg === 'html') { }), new MiniCssExtractPlugin({ filename: utils.assetsPath('css/[name].[contenthash].css'), - chunkFilename: "[name].[contenthash].css" + chunkFilename: '[name].[contenthash].css' }), new UglifyJsPlugin({ uglifyOptions: { @@ -91,14 +90,14 @@ if (arg === 'html') { parallel: true }), // extract css into its own file - /*new ExtractTextPlugin({ + /* new ExtractTextPlugin({ filename: utils.assetsPath('css/[name].[contenthash].css'), // Setting the following option to `false` will not extract CSS from codesplit chunks. // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 allChunks: true - }),*/ + }), */ // Compress extracted CSS. We are using this plugin so that possible // duplicated CSS from different components can be deduped. new OptimizeCSSPlugin({ @@ -186,7 +185,7 @@ if (arg === 'html') { { from: path.resolve(__dirname, '../static'), to: config.build.assetsSubDirectory, - ignore: ['*'] + ignore: ['**/Titles/**'] } ]) ] @@ -240,11 +239,11 @@ if (arg === 'html') { new webpack.DefinePlugin({ 'process.env': env }), - new MiniCssExtractPlugin({ //替换 ExtractTextPlugin 用于css抽取 + new MiniCssExtractPlugin({ // 替换 ExtractTextPlugin 用于css抽取 filename: utils.assetsPath('css/[name].[contenthash].css') // chunkFilename: "[name].[contenthash].css" }), - /* new UglifyJsPlugin({ + /* new UglifyJsPlugin({ uglifyOptions: { compress: { warnings: false, @@ -255,16 +254,16 @@ if (arg === 'html') { exclude: /manifest.+js/, sourceMap: config.build.productionSourceMap, parallel: true - }),*/ + }), */ // extract css into its own file - /*new ExtractTextPlugin({ + /* new ExtractTextPlugin({ filename: utils.assetsPath('css/[name]_[md5:contenthash:hex:8].css'), // Setting the following option to `false` will not extract CSS from codesplit chunks. // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 allChunks: true - }),*/ + }), */ // Compress extracted CSS. We are using this plugin so that possible // duplicated CSS from different components can be deduped. // new OptimizeCSSPlugin({ @@ -289,7 +288,7 @@ if (arg === 'html') { // https://github.com/kangax/html-minifier#options-quick-reference }, // necessary to consistently work with multiple chunks via CommonsChunkPlugin - //chunksSortMode: 'auto', + // chunksSortMode: 'auto', excludeChunks: ['exportHtml'] }), new GenerateAssetPlugin({ @@ -303,7 +302,7 @@ if (arg === 'html') { // enable scope hoisting new webpack.optimize.ModuleConcatenationPlugin(), // split vendor js into its own file - /* new webpack.optimize.CommonsChunkPlugin({ + /* new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', minChunks (module) { // any required modules inside node_modules are extracted to vendor @@ -330,14 +329,14 @@ if (arg === 'html') { async: 'vendor-async', children: true, minChunks: 3 - }),*/ + }), */ // copy custom static assets new CopyWebpackPlugin([ { from: path.resolve(__dirname, '../static'), to: config.build.assetsSubDirectory, - ignore: ['*'] + ignore: ['**/Titles/**'] } ]) ], @@ -347,13 +346,13 @@ if (arg === 'html') { new TerserPlugin({ // 压缩JS代码 terserOptions: { compress: { - warnings: false, - drop_console: true, // 去除console - pure_funcs: ['console.log'] + warnings: false, + drop_console: true, // 去除console + pure_funcs: ['console.log'] } }, exclude: /manifest.+js/, - sourceMap: config.build.productionSourceMap, + sourceMap: config.build.productionSourceMap }) ], splitChunks: { // @@ -364,7 +363,7 @@ if (arg === 'html') { maxAsyncRequests: 5, maxInitialRequests: 3, automaticNameDelimiter: '~', - automaticNameMaxLength: 30, + automaticNameMaxLength: 30 } } }) @@ -380,7 +379,7 @@ if (process.env.NODE_ENV == 'development') { onEnd: [ { move: [ - { source: path.join(__dirname, '../dist', '/static/config.json'), destination: path.join(__dirname, '../dist/config.json') }, + { source: path.join(__dirname, '../dist', '/static/config.json'), destination: path.join(__dirname, '../dist/config.json') } // { source: path.join(__dirname, '../exportHtml', '/snapshot_template.html'), destination: path.join(__dirname, '../dist/snapshot_template.html') } ], @@ -414,7 +413,7 @@ if (process.env.NODE_ENV == 'development') { onEnd: [ { move: [ - { source: path.join(__dirname, '../dist', '/static/config.json'), destination: path.join(__dirname, '../dist/config.json') }, + { source: path.join(__dirname, '../dist', '/static/config.json'), destination: path.join(__dirname, '../dist/config.json') } // { source: path.join(__dirname, '../exportHtml', '/snapshot_template.html'), destination: path.join(__dirname, '../dist/snapshot_template.html') } ], diff --git a/nezha-fronted/package-lock.json b/nezha-fronted/package-lock.json index d277ba116..120aec352 100644 --- a/nezha-fronted/package-lock.json +++ b/nezha-fronted/package-lock.json @@ -14340,7 +14340,7 @@ }, "node-sass": { "version": "4.14.1", - "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.14.1.tgz", + "resolved": "https://registry.npmmirror.com/node-sass/-/node-sass-4.14.1.tgz", "integrity": "sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g==", "dev": true, "requires": { @@ -20727,7 +20727,7 @@ }, "webpack-bundle-analyzer": { "version": "2.13.1", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-2.13.1.tgz", + "resolved": "https://registry.npmmirror.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-2.13.1.tgz", "integrity": "sha512-rwxyfecTAxoarCC9VlHlIpfQCmmJ/qWD5bpbjkof+7HrNhTNZIwZITxN6CdlYL2axGmwNUQ+tFgcSOiNXMf/sQ==", "dev": true, "requires": { diff --git a/nezha-fronted/src/assets/css/common.scss b/nezha-fronted/src/assets/css/common.scss index 77aa08277..dd5fea04c 100644 --- a/nezha-fronted/src/assets/css/common.scss +++ b/nezha-fronted/src/assets/css/common.scss @@ -735,3 +735,11 @@ i.nz-icon-override{ .xterm .xterm-viewport { background-color: transparent !important; } +.downloading { + opacity: .6; + color: $--color-primary; + margin-left: 10px; +} +.el-form-item__error { + padding-top: 0; +} diff --git a/nezha-fronted/src/assets/css/components/common/latIngPicker.scss b/nezha-fronted/src/assets/css/components/common/latIngPicker.scss index a29e9f594..1510d47f3 100644 --- a/nezha-fronted/src/assets/css/components/common/latIngPicker.scss +++ b/nezha-fronted/src/assets/css/components/common/latIngPicker.scss @@ -41,4 +41,24 @@ width: 48px; } } +.append_unit{ + display: flex; + .el-input--small .el-input__inner { + border-radius: 4px 0 0 4px; + border-right: none; + } + &::after{ + content: attr(data-unit); + //position: absolute; + display: inline-block; + top: 0; + right: 100%; + padding: 0 20px; + color: $--color-text-secondary; + background-color: $--background-color-base; + border: 1px solid $--border-color-light; + border-radius:0 4px 4px 0; + width: auto; + } +} diff --git a/nezha-fronted/src/assets/css/components/common/rightBox/chartRightBox/chartRightBox.scss b/nezha-fronted/src/assets/css/components/common/rightBox/chartRightBox/chartRightBox.scss index 43a811571..0b079a253 100644 --- a/nezha-fronted/src/assets/css/components/common/rightBox/chartRightBox/chartRightBox.scss +++ b/nezha-fronted/src/assets/css/components/common/rightBox/chartRightBox/chartRightBox.scss @@ -375,4 +375,9 @@ .nz-icon-sort{ color: #FF8C0E !important; } -} \ No newline at end of file +} +.datasource-log { + .el-tabs__content { + overflow: unset; + } +} diff --git a/nezha-fronted/src/components/chart/chart/legend.vue b/nezha-fronted/src/components/chart/chart/legend.vue index 7dc086e99..e7f6f7593 100644 --- a/nezha-fronted/src/components/chart/chart/legend.vue +++ b/nezha-fronted/src/components/chart/chart/legend.vue @@ -198,7 +198,6 @@ export default { const series = this.$lodash.cloneDeep(this.series) const dataArg = series.filter((seriesItem, seriesIndex) => !this.isGrey[seriesIndex]) const option = this.renderYAxis(dataArg, chartInfo, 'legend') - console.log(option) getChart(this.chartId) && getChart(this.chartId).setOption({ yAxis: [ ...option.yAxis diff --git a/nezha-fronted/src/components/chart/chartList.vue b/nezha-fronted/src/components/chart/chartList.vue index 8d2c44b99..05b28f89f 100644 --- a/nezha-fronted/src/components/chart/chartList.vue +++ b/nezha-fronted/src/components/chart/chartList.vue @@ -594,7 +594,6 @@ export default { }) this.onScroll(this.scrollTop) }, - // group设置repeat 便利变量重复渲染图表 repeatVariableFn () { // 防止group中的chartList执行 @@ -742,7 +741,6 @@ export default { handler (newVal, oldVal) { // 比较变量 图表是否显示/隐藏 this.compareVariables() - this.repeatVariableFn() } }, @@ -785,7 +783,8 @@ export default { const position = getLayoutPosition(n) this.$store.commit('setChartLastPosition', position) } - const tempList = n.map(item => { + const cloneDataList = this.$lodash.cloneDeep(n) + const tempList = cloneDataList.map(item => { let param = '' let height = item.height || '' if (this.isPhone && item.type !== 'group') { @@ -848,11 +847,10 @@ export default { }) } this.$nextTick(() => { - this.copyDataList = JSON.parse(JSON.stringify(tempList)) + this.copyDataList = this.$lodash.cloneDeep(tempList) this.tempList = JSON.parse(JSON.stringify(this.copyDataList)) // 比较变量 图表是否显示/隐藏 this.compareVariables() - this.repeatVariableFn() setTimeout(() => { this.gridLayoutShow = true diff --git a/nezha-fronted/src/components/chart/renderChart.js b/nezha-fronted/src/components/chart/renderChart.js index 60383446c..f529d70c9 100644 --- a/nezha-fronted/src/components/chart/renderChart.js +++ b/nezha-fronted/src/components/chart/renderChart.js @@ -6,7 +6,6 @@ export default { methods: { renderYAxis (chartDatas, chartInfo, type) { let chartData = lodash.cloneDeep(chartDatas) - console.log(chartData) if (type === 'legend') { chartData.forEach(item => { item.values = item.data @@ -30,13 +29,12 @@ export default { ] } // 左y轴 - const leftData = chartData.filter(item => !item[0].yAxisIndex) + const leftData = chartData.filter(item => item[0] && !item[0].yAxisIndex) const leftInfo = this.getMinMaxFromData(leftData, chartInfo.unit, chartInfo.param) // - console.log(leftData, leftInfo) chartOption.yAxis[0].minInterval = chartDataFormat.Interval(leftInfo.maxValue, leftInfo.copies, leftInfo.unit.type, 'min') chartOption.yAxis[0].maxInterval = chartDataFormat.Interval(leftInfo.maxValue, leftInfo.copies, leftInfo.unit.type, 'max') * Math.ceil(this.series.length / 5) if (chartInfo.param.stack) { - chartOption.yAxis[0].maxInterval = chartOption.yAxis[0].maxInterval * (Math.ceil(chartOption.series.length / 5) + 1) + chartOption.yAxis[0].maxInterval = chartOption.yAxis[0].maxInterval * (Math.ceil(leftData.length / 5) + 1) } if (leftInfo.unit.type === 'Time' || leftInfo.unit.type === 'Date & Time') { delete chartOption.yAxis[0].minInterval @@ -64,13 +62,12 @@ export default { const unit = chartDataFormat.getUnit(lodash.get(chartInfo, 'param.rightYAxis.unit', 2)) const allRight = this.series.every(item => item.yAxisIndex == 1) chartOption.yAxis[1].splitLine.show = allRight - const rightData = chartData.filter(item => item[0].yAxisIndex) - console.log(rightData, unit) + const rightData = chartData.filter(item => item[0] && item[0].yAxisIndex) const rightInfo = this.getMinMaxFromData(rightData, lodash.get(chartInfo, 'param.rightYAxis.unit', 2), lodash.get(chartInfo, 'param.rightYAxis', {}))// chartOption.yAxis[1].minInterval = chartDataFormat.Interval(rightInfo.maxValue, rightInfo.copies, rightInfo.unit.type, 'min') chartOption.yAxis[1].maxInterval = chartDataFormat.Interval(rightInfo.maxValue, rightInfo.copies, rightInfo.unit.type, 'max') * Math.ceil(this.series.length / 5) if (chartInfo.param.stack) { - chartOption.yAxis[1].maxInterval = chartOption.yAxis[1].maxInterval * (Math.ceil(chartOption.series.length / 5) + 1) + chartOption.yAxis[1].maxInterval = chartOption.yAxis[1].maxInterval * (Math.ceil(rightData.length / 5) + 1) } if (unit.type === 'Time' || unit.type === 'Date & Time') { delete chartOption.yAxis[1].minInterval @@ -95,7 +92,6 @@ export default { delete chartOption.yAxis[1].max } } - console.log(chartOption) return chartOption }, getMinMaxFromData (originalDatas, chartUnit = 2, params) { diff --git a/nezha-fronted/src/components/cli/consoleNew.vue b/nezha-fronted/src/components/cli/consoleNew.vue index 70ad70fd9..1c536163f 100644 --- a/nezha-fronted/src/components/cli/consoleNew.vue +++ b/nezha-fronted/src/components/cli/consoleNew.vue @@ -114,9 +114,6 @@ export default { const consoleBox = document.getElementById('ternimalContainer' + this.idIndex) const width = document.body.clientWidth - 10// 可视宽度 const height = parseInt(consoleBox.offsetHeight) - 10 - console.log(width, height) - console.log(this.term.cols) - console.log(this.term.rows) const winStyle = { width: width, height: height, @@ -367,14 +364,12 @@ export default { // } }, renderTerminalSetting () { - console.log('renderTerminalSetting') this.showWatermark = this.terminalSetting.watermark this.wordSeparator = this.terminalSetting.wordSeparator this.term.options = { scrollback: this.terminalSetting.scrollbackLines, wordSeparator: this.terminalSetting.wordSeparator } - console.log(this.term) }, copySelection () { let str = this.term.getSelection() diff --git a/nezha-fronted/src/components/common/alert/terminalLogInfo.vue b/nezha-fronted/src/components/common/alert/terminalLogInfo.vue index 5ffe7e462..281cd9d95 100644 --- a/nezha-fronted/src/components/common/alert/terminalLogInfo.vue +++ b/nezha-fronted/src/components/common/alert/terminalLogInfo.vue @@ -160,7 +160,6 @@ export default { methods: { init () { this.loading = false - console.log(this.alertLabelData) }, getRemoteText (record) { return `${record.loginUser}@${record.host}:${record.port}` diff --git a/nezha-fronted/src/components/common/bottomBox/tabs/scrapeEndpoint.vue b/nezha-fronted/src/components/common/bottomBox/tabs/scrapeEndpoint.vue index 825ccb965..0782f0517 100644 --- a/nezha-fronted/src/components/common/bottomBox/tabs/scrapeEndpoint.vue +++ b/nezha-fronted/src/components/common/bottomBox/tabs/scrapeEndpoint.vue @@ -221,7 +221,6 @@ export default { if (simpleTemp.indexOf(',') !== -1) { simpleTemp = simpleTemp.substr(0, simpleTemp.length - 1) } - console.log(simpleTemp) tableData.tableDateAll = simpleTemp tableDates.push(tableData) } diff --git a/nezha-fronted/src/components/common/bottomBox/tabs/terminalLogMonitorTab.vue b/nezha-fronted/src/components/common/bottomBox/tabs/terminalLogMonitorTab.vue index 00b178320..ff503b899 100644 --- a/nezha-fronted/src/components/common/bottomBox/tabs/terminalLogMonitorTab.vue +++ b/nezha-fronted/src/components/common/bottomBox/tabs/terminalLogMonitorTab.vue @@ -81,7 +81,6 @@ export default { methods: { // 创建连接 create () { - console.log('create') const that = this if (this.terminalSocket) { this.terminalSocket.close() @@ -206,7 +205,6 @@ export default { }, consoleResize () { - console.log('consoleResize') this.$nextTick(() => { this.termFitAddon.fit() }) diff --git a/nezha-fronted/src/components/common/login.vue b/nezha-fronted/src/components/common/login.vue index f4d9c96e9..9c8d102c5 100644 --- a/nezha-fronted/src/components/common/login.vue +++ b/nezha-fronted/src/components/common/login.vue @@ -86,25 +86,37 @@ :show-close="true" width="620px" class="nz-dialog" >
{
diff --git a/nezha-fronted/src/components/page/dashboard/explore/exploreItem.vue b/nezha-fronted/src/components/page/dashboard/explore/exploreItem.vue
index 7426b8439..65cf0a327 100644
--- a/nezha-fronted/src/components/page/dashboard/explore/exploreItem.vue
+++ b/nezha-fronted/src/components/page/dashboard/explore/exploreItem.vue
@@ -3535,6 +3535,8 @@ import logTab from './logTab'
import promqlInputMixin from '@/components/common/mixin/promqlInput'
import chartRightBox from '@/components/common/rightBox/chart/chartRightBox'
import copy from '@/components/common/copy'
+import './promqlparser/wasm_exec.js'
+
export default {
name: 'exploreItem',
components: {
@@ -3624,19 +3626,33 @@ export default {
scrollbarWrap: null
}
},
- created () {
+ async created () {
this.getPanelData()
this.resetExpression()
+ await this.loadWebAssembly()
+ this.initQueryFromPath()
},
mounted () {
this.scrollbarWrap = this.$refs.exploreScrollbar
this.scrollbarWrap.addEventListener('scroll', this.onScroll)
- this.initQueryFromPath()
},
beforeDestroy () {
this.scrollbarWrap.removeEventListener('scroll', this.onScroll)
},
methods: {
+ async loadWebAssembly () {
+ try {
+ // eslint-disable-next-line no-undef
+ const go = new Go()
+ const result = await WebAssembly.instantiateStreaming(fetch('/static/wasm/promqlparser.wasm'), go.importObject)
+ go.run(result.instance)
+ // eslint-disable-next-line no-undef
+ this.parsePromQL = parsePromQL
+ } catch (error) {
+ console.error(error)
+ }
+ },
+ parsePromQL () {},
onScroll: bus.debounce(function () {
this.showTopBtn = this.scrollbarWrap.scrollTop > 50
}, 300),
@@ -3658,7 +3674,6 @@ export default {
},
setTimePickerRange () {
this.$nextTick(() => {
- console.log(this.timePickerLocked, !this.timePickerRange.nowTimeType)
if (!this.timePickerLocked || !this.timePickerRange.nowTimeType) {
return
}
@@ -3953,7 +3968,7 @@ export default {
} else {
if (response.error) {
this.$refs['promql-' + promqlIndex][0].setError(response.error)
- } else if(response.msg) {
+ } else if (response.msg) {
this.$refs['promql-' + promqlIndex][0].setError(response.msg)
} else {
this.$refs['promql-' + promqlIndex][0].setError(response)
@@ -4102,6 +4117,24 @@ export default {
this.setSearchTime(nowTimeType.type, nowTimeType.value)
}
if (this.expressions && this.expressions.length >= 1) {
+ let error = false
+ // 对 promql 格式校验及format
+ if (this.showMetrics) {
+ this.expressions.forEach((item, index) => {
+ if (item != '' && this.promqlKeys[index].state) {
+ const res = this.parsePromQL(item)
+ if (res.status === 'error') {
+ error = true
+ this.$refs['promql-' + index][0].setError(res.message)
+ } else {
+ this.$set(this.expressions, index, res.result)
+ this.$refs['promql-' + index][0].prettyCode()
+ this.$refs['promql-' + index][0].setError('')
+ }
+ }
+ })
+ }
+ if (error) { return }
if (this.showMetrics) {
this.queryTableData()
this.queryChartData()
diff --git a/nezha-fronted/src/components/page/dashboard/explore/promqlInput.vue b/nezha-fronted/src/components/page/dashboard/explore/promqlInput.vue
index 8b9fed6b8..acb67fda3 100644
--- a/nezha-fronted/src/components/page/dashboard/explore/promqlInput.vue
+++ b/nezha-fronted/src/components/page/dashboard/explore/promqlInput.vue
@@ -163,12 +163,13 @@
>
{{
type === "log"
@@ -1157,10 +1158,20 @@ export default {
this.expressionList[this.index] = insertTxt
this.codeMirrorValue[this.index] = insertTxt
this.initCodeMirror()
- }
+ },
/* setMsg:function(){
this.appendMsg
} */
+ prettyCode () {
+ this.$nextTick(() => {
+ const text = this.newView.state.doc.toString()
+ this.newView.dispatch(
+ this.newView.state.update({
+ changes: { from: 0, to: text.length, insert: this.codeMirrorValue[this.index] }
+ })
+ )
+ })
+ }
},
watch: {
dropDownVisible (n, o) {
diff --git a/nezha-fronted/src/components/page/dashboard/explore/promqlparser/go.mod b/nezha-fronted/src/components/page/dashboard/explore/promqlparser/go.mod
new file mode 100644
index 000000000..8ab16c81d
--- /dev/null
+++ b/nezha-fronted/src/components/page/dashboard/explore/promqlparser/go.mod
@@ -0,0 +1,30 @@
+module test.go
+
+go 1.20
+
+require (
+ github.com/beorn7/perks v1.0.1 // indirect
+ github.com/cespare/xxhash/v2 v2.2.0 // indirect
+ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
+ github.com/dennwc/varint v1.0.0 // indirect
+ github.com/go-kit/log v0.2.1 // indirect
+ github.com/go-logfmt/logfmt v0.6.0 // indirect
+ github.com/gogo/protobuf v1.3.2 // indirect
+ github.com/golang/protobuf v1.5.3 // indirect
+ github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect
+ github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
+ github.com/pkg/errors v0.9.1 // indirect
+ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
+ github.com/prometheus/client_golang v1.16.0 // indirect
+ github.com/prometheus/client_model v0.4.0 // indirect
+ github.com/prometheus/common v0.44.0 // indirect
+ github.com/prometheus/procfs v0.11.0 // indirect
+ github.com/prometheus/prometheus v0.46.0 // indirect
+ github.com/stretchr/testify v1.8.4 // indirect
+ go.uber.org/atomic v1.11.0 // indirect
+ go.uber.org/goleak v1.2.1 // indirect
+ golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect
+ golang.org/x/sys v0.10.0 // indirect
+ google.golang.org/protobuf v1.31.0 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
+)
diff --git a/nezha-fronted/src/components/page/dashboard/explore/promqlparser/go.sum b/nezha-fronted/src/components/page/dashboard/explore/promqlparser/go.sum
new file mode 100644
index 000000000..265df2532
--- /dev/null
+++ b/nezha-fronted/src/components/page/dashboard/explore/promqlparser/go.sum
@@ -0,0 +1,91 @@
+github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
+github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
+github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE=
+github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA=
+github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU=
+github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
+github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
+github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
+github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
+github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
+github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww=
+github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A=
+github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
+github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
+github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
+github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
+github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
+github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
+github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
+github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
+github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY=
+github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY=
+github.com/prometheus/procfs v0.11.0 h1:5EAgkfkMl659uZPbe9AS2N68a7Cc1TJbPEuGzFuRbyk=
+github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
+github.com/prometheus/prometheus v0.46.0 h1:9JSdXnsuT6YsbODEhSQMwxNkGwPExfmzqG73vCMk/Kw=
+github.com/prometheus/prometheus v0.46.0/go.mod h1:10L5IJE5CEsjee1FnOcVswYXlPIscDWWt3IJ2UDYrz4=
+github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
+go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
+go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
+go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw=
+golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
+golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
+google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/nezha-fronted/src/components/page/dashboard/explore/promqlparser/promqlparser.go b/nezha-fronted/src/components/page/dashboard/explore/promqlparser/promqlparser.go
new file mode 100644
index 000000000..54e16b2e0
--- /dev/null
+++ b/nezha-fronted/src/components/page/dashboard/explore/promqlparser/promqlparser.go
@@ -0,0 +1,33 @@
+// 编译为wasm文件 在页面中引入
+package main
+
+import (
+ "syscall/js"
+
+ "github.com/prometheus/prometheus/promql/parser"
+)
+
+func parsePromQL(this js.Value, args []js.Value) interface{} {
+ promql := args[0].String()
+ expr, err := parser.ParseExpr(promql)
+ if err != nil {
+ return map[string]interface{}{
+ "status": "error",
+ "message": err.Error(),
+ }
+ }
+
+ return map[string]interface{}{
+ "status": "success",
+ "result": expr.Pretty(0),
+ }
+}
+
+func main() {
+ c := make(chan struct{}, 0)
+
+ // 注册函数
+ js.Global().Set("parsePromQL", js.FuncOf(parsePromQL))
+
+ <-c
+}
diff --git a/nezha-fronted/src/components/page/dashboard/explore/promqlparser/promqlparser.wasm b/nezha-fronted/src/components/page/dashboard/explore/promqlparser/promqlparser.wasm
new file mode 100644
index 000000000..cc58605d0
Binary files /dev/null and b/nezha-fronted/src/components/page/dashboard/explore/promqlparser/promqlparser.wasm differ
diff --git a/nezha-fronted/src/components/page/dashboard/explore/promqlparser/wasm_exec.js b/nezha-fronted/src/components/page/dashboard/explore/promqlparser/wasm_exec.js
new file mode 100644
index 000000000..2f279c750
--- /dev/null
+++ b/nezha-fronted/src/components/page/dashboard/explore/promqlparser/wasm_exec.js
@@ -0,0 +1,554 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+'use strict';
+
+(() => {
+ const enosys = () => {
+ const err = new Error('not implemented')
+ err.code = 'ENOSYS'
+ return err
+ }
+
+ if (!globalThis.fs) {
+ let outputBuf = ''
+ globalThis.fs = {
+ constants: { O_WRONLY: -1, O_RDWR: -1, O_CREAT: -1, O_TRUNC: -1, O_APPEND: -1, O_EXCL: -1 }, // unused
+ writeSync (fd, buf) {
+ outputBuf += decoder.decode(buf)
+ const nl = outputBuf.lastIndexOf('\n')
+ if (nl != -1) {
+ console.log(outputBuf.substring(0, nl))
+ outputBuf = outputBuf.substring(nl + 1)
+ }
+ return buf.length
+ },
+ write (fd, buf, offset, length, position, callback) {
+ if (offset !== 0 || length !== buf.length || position !== null) {
+ callback(enosys())
+ return
+ }
+ const n = this.writeSync(fd, buf)
+ callback(null, n)
+ },
+ chmod (path, mode, callback) { callback(enosys()) },
+ chown (path, uid, gid, callback) { callback(enosys()) },
+ close (fd, callback) { callback(enosys()) },
+ fchmod (fd, mode, callback) { callback(enosys()) },
+ fchown (fd, uid, gid, callback) { callback(enosys()) },
+ fstat (fd, callback) { callback(enosys()) },
+ fsync (fd, callback) { callback(null) },
+ ftruncate (fd, length, callback) { callback(enosys()) },
+ lchown (path, uid, gid, callback) { callback(enosys()) },
+ link (path, link, callback) { callback(enosys()) },
+ lstat (path, callback) { callback(enosys()) },
+ mkdir (path, perm, callback) { callback(enosys()) },
+ open (path, flags, mode, callback) { callback(enosys()) },
+ read (fd, buffer, offset, length, position, callback) { callback(enosys()) },
+ readdir (path, callback) { callback(enosys()) },
+ readlink (path, callback) { callback(enosys()) },
+ rename (from, to, callback) { callback(enosys()) },
+ rmdir (path, callback) { callback(enosys()) },
+ stat (path, callback) { callback(enosys()) },
+ symlink (path, link, callback) { callback(enosys()) },
+ truncate (path, length, callback) { callback(enosys()) },
+ unlink (path, callback) { callback(enosys()) },
+ utimes (path, atime, mtime, callback) { callback(enosys()) }
+ }
+ }
+
+ if (!globalThis.process) {
+ globalThis.process = {
+ getuid () { return -1 },
+ getgid () { return -1 },
+ geteuid () { return -1 },
+ getegid () { return -1 },
+ getgroups () { throw enosys() },
+ pid: -1,
+ ppid: -1,
+ umask () { throw enosys() },
+ cwd () { throw enosys() },
+ chdir () { throw enosys() }
+ }
+ }
+
+ if (!globalThis.crypto) {
+ throw new Error('globalThis.crypto is not available, polyfill required (crypto.getRandomValues only)')
+ }
+
+ if (!globalThis.performance) {
+ throw new Error('globalThis.performance is not available, polyfill required (performance.now only)')
+ }
+
+ if (!globalThis.TextEncoder) {
+ throw new Error('globalThis.TextEncoder is not available, polyfill required')
+ }
+
+ if (!globalThis.TextDecoder) {
+ throw new Error('globalThis.TextDecoder is not available, polyfill required')
+ }
+
+ const encoder = new TextEncoder('utf-8')
+ const decoder = new TextDecoder('utf-8')
+
+ globalThis.Go = class {
+ constructor () {
+ this.argv = ['js']
+ this.env = {}
+ this.exit = (code) => {
+ if (code !== 0) {
+ console.warn('exit code:', code)
+ }
+ }
+ this._exitPromise = new Promise((resolve) => {
+ this._resolveExitPromise = resolve
+ })
+ this._pendingEvent = null
+ this._scheduledTimeouts = new Map()
+ this._nextCallbackTimeoutID = 1
+
+ const setInt64 = (addr, v) => {
+ this.mem.setUint32(addr + 0, v, true)
+ this.mem.setUint32(addr + 4, Math.floor(v / 4294967296), true)
+ }
+
+ const getInt64 = (addr) => {
+ const low = this.mem.getUint32(addr + 0, true)
+ const high = this.mem.getInt32(addr + 4, true)
+ return low + high * 4294967296
+ }
+
+ const loadValue = (addr) => {
+ const f = this.mem.getFloat64(addr, true)
+ if (f === 0) {
+ return undefined
+ }
+ if (!isNaN(f)) {
+ return f
+ }
+
+ const id = this.mem.getUint32(addr, true)
+ return this._values[id]
+ }
+
+ const storeValue = (addr, v) => {
+ const nanHead = 0x7FF80000
+
+ if (typeof v === 'number' && v !== 0) {
+ if (isNaN(v)) {
+ this.mem.setUint32(addr + 4, nanHead, true)
+ this.mem.setUint32(addr, 0, true)
+ return
+ }
+ this.mem.setFloat64(addr, v, true)
+ return
+ }
+
+ if (v === undefined) {
+ this.mem.setFloat64(addr, 0, true)
+ return
+ }
+
+ let id = this._ids.get(v)
+ if (id === undefined) {
+ id = this._idPool.pop()
+ if (id === undefined) {
+ id = this._values.length
+ }
+ this._values[id] = v
+ this._goRefCounts[id] = 0
+ this._ids.set(v, id)
+ }
+ this._goRefCounts[id]++
+ let typeFlag = 0
+ switch (typeof v) {
+ case 'object':
+ if (v !== null) {
+ typeFlag = 1
+ }
+ break
+ case 'string':
+ typeFlag = 2
+ break
+ case 'symbol':
+ typeFlag = 3
+ break
+ case 'function':
+ typeFlag = 4
+ break
+ }
+ this.mem.setUint32(addr + 4, nanHead | typeFlag, true)
+ this.mem.setUint32(addr, id, true)
+ }
+
+ const loadSlice = (addr) => {
+ const array = getInt64(addr + 0)
+ const len = getInt64(addr + 8)
+ return new Uint8Array(this._inst.exports.mem.buffer, array, len)
+ }
+
+ const loadSliceOfValues = (addr) => {
+ const array = getInt64(addr + 0)
+ const len = getInt64(addr + 8)
+ const a = new Array(len)
+ for (let i = 0; i < len; i++) {
+ a[i] = loadValue(array + i * 8)
+ }
+ return a
+ }
+
+ const loadString = (addr) => {
+ const saddr = getInt64(addr + 0)
+ const len = getInt64(addr + 8)
+ return decoder.decode(new DataView(this._inst.exports.mem.buffer, saddr, len))
+ }
+
+ const timeOrigin = Date.now() - performance.now()
+ this.importObject = {
+ go: {
+ // Go's SP does not change as long as no Go code is running. Some operations (e.g. calls, getters and setters)
+ // may synchronously trigger a Go event handler. This makes Go code get executed in the middle of the imported
+ // function. A goroutine can switch to a new stack if the current stack is too small (see morestack function).
+ // This changes the SP, thus we have to update the SP used by the imported function.
+
+ // func wasmExit(code int32)
+ 'runtime.wasmExit': (sp) => {
+ sp >>>= 0
+ const code = this.mem.getInt32(sp + 8, true)
+ this.exited = true
+ delete this._inst
+ delete this._values
+ delete this._goRefCounts
+ delete this._ids
+ delete this._idPool
+ this.exit(code)
+ },
+
+ // func wasmWrite(fd uintptr, p unsafe.Pointer, n int32)
+ 'runtime.wasmWrite': (sp) => {
+ sp >>>= 0
+ const fd = getInt64(sp + 8)
+ const p = getInt64(sp + 16)
+ const n = this.mem.getInt32(sp + 24, true)
+ fs.writeSync(fd, new Uint8Array(this._inst.exports.mem.buffer, p, n))
+ },
+
+ // func resetMemoryDataView()
+ 'runtime.resetMemoryDataView': (sp) => {
+ sp >>>= 0
+ this.mem = new DataView(this._inst.exports.mem.buffer)
+ },
+
+ // func nanotime1() int64
+ 'runtime.nanotime1': (sp) => {
+ sp >>>= 0
+ setInt64(sp + 8, (timeOrigin + performance.now()) * 1000000)
+ },
+
+ // func walltime() (sec int64, nsec int32)
+ 'runtime.walltime': (sp) => {
+ sp >>>= 0
+ const msec = (new Date()).getTime()
+ setInt64(sp + 8, msec / 1000)
+ this.mem.setInt32(sp + 16, (msec % 1000) * 1000000, true)
+ },
+
+ // func scheduleTimeoutEvent(delay int64) int32
+ 'runtime.scheduleTimeoutEvent': (sp) => {
+ sp >>>= 0
+ const id = this._nextCallbackTimeoutID
+ this._nextCallbackTimeoutID++
+ this._scheduledTimeouts.set(id, setTimeout(
+ () => {
+ this._resume()
+ while (this._scheduledTimeouts.has(id)) {
+ // for some reason Go failed to register the timeout event, log and try again
+ // (temporary workaround for https://github.com/golang/go/issues/28975)
+ console.warn('scheduleTimeoutEvent: missed timeout event')
+ this._resume()
+ }
+ },
+ getInt64(sp + 8) + 1 // setTimeout has been seen to fire up to 1 millisecond early
+ ))
+ this.mem.setInt32(sp + 16, id, true)
+ },
+
+ // func clearTimeoutEvent(id int32)
+ 'runtime.clearTimeoutEvent': (sp) => {
+ sp >>>= 0
+ const id = this.mem.getInt32(sp + 8, true)
+ clearTimeout(this._scheduledTimeouts.get(id))
+ this._scheduledTimeouts.delete(id)
+ },
+
+ // func getRandomData(r []byte)
+ 'runtime.getRandomData': (sp) => {
+ sp >>>= 0
+ crypto.getRandomValues(loadSlice(sp + 8))
+ },
+
+ // func finalizeRef(v ref)
+ 'syscall/js.finalizeRef': (sp) => {
+ sp >>>= 0
+ const id = this.mem.getUint32(sp + 8, true)
+ this._goRefCounts[id]--
+ if (this._goRefCounts[id] === 0) {
+ const v = this._values[id]
+ this._values[id] = null
+ this._ids.delete(v)
+ this._idPool.push(id)
+ }
+ },
+
+ // func stringVal(value string) ref
+ 'syscall/js.stringVal': (sp) => {
+ sp >>>= 0
+ storeValue(sp + 24, loadString(sp + 8))
+ },
+
+ // func valueGet(v ref, p string) ref
+ 'syscall/js.valueGet': (sp) => {
+ sp >>>= 0
+ const result = Reflect.get(loadValue(sp + 8), loadString(sp + 16))
+ sp = this._inst.exports.getsp() >>> 0 // see comment above
+ storeValue(sp + 32, result)
+ },
+
+ // func valueSet(v ref, p string, x ref)
+ 'syscall/js.valueSet': (sp) => {
+ sp >>>= 0
+ Reflect.set(loadValue(sp + 8), loadString(sp + 16), loadValue(sp + 32))
+ },
+
+ // func valueDelete(v ref, p string)
+ 'syscall/js.valueDelete': (sp) => {
+ sp >>>= 0
+ Reflect.deleteProperty(loadValue(sp + 8), loadString(sp + 16))
+ },
+
+ // func valueIndex(v ref, i int) ref
+ 'syscall/js.valueIndex': (sp) => {
+ sp >>>= 0
+ storeValue(sp + 24, Reflect.get(loadValue(sp + 8), getInt64(sp + 16)))
+ },
+
+ // valueSetIndex(v ref, i int, x ref)
+ 'syscall/js.valueSetIndex': (sp) => {
+ sp >>>= 0
+ Reflect.set(loadValue(sp + 8), getInt64(sp + 16), loadValue(sp + 24))
+ },
+
+ // func valueCall(v ref, m string, args []ref) (ref, bool)
+ 'syscall/js.valueCall': (sp) => {
+ sp >>>= 0
+ try {
+ const v = loadValue(sp + 8)
+ const m = Reflect.get(v, loadString(sp + 16))
+ const args = loadSliceOfValues(sp + 32)
+ const result = Reflect.apply(m, v, args)
+ sp = this._inst.exports.getsp() >>> 0 // see comment above
+ storeValue(sp + 56, result)
+ this.mem.setUint8(sp + 64, 1)
+ } catch (err) {
+ sp = this._inst.exports.getsp() >>> 0 // see comment above
+ storeValue(sp + 56, err)
+ this.mem.setUint8(sp + 64, 0)
+ }
+ },
+
+ // func valueInvoke(v ref, args []ref) (ref, bool)
+ 'syscall/js.valueInvoke': (sp) => {
+ sp >>>= 0
+ try {
+ const v = loadValue(sp + 8)
+ const args = loadSliceOfValues(sp + 16)
+ const result = Reflect.apply(v, undefined, args)
+ sp = this._inst.exports.getsp() >>> 0 // see comment above
+ storeValue(sp + 40, result)
+ this.mem.setUint8(sp + 48, 1)
+ } catch (err) {
+ sp = this._inst.exports.getsp() >>> 0 // see comment above
+ storeValue(sp + 40, err)
+ this.mem.setUint8(sp + 48, 0)
+ }
+ },
+
+ // func valueNew(v ref, args []ref) (ref, bool)
+ 'syscall/js.valueNew': (sp) => {
+ sp >>>= 0
+ try {
+ const v = loadValue(sp + 8)
+ const args = loadSliceOfValues(sp + 16)
+ const result = Reflect.construct(v, args)
+ sp = this._inst.exports.getsp() >>> 0 // see comment above
+ storeValue(sp + 40, result)
+ this.mem.setUint8(sp + 48, 1)
+ } catch (err) {
+ sp = this._inst.exports.getsp() >>> 0 // see comment above
+ storeValue(sp + 40, err)
+ this.mem.setUint8(sp + 48, 0)
+ }
+ },
+
+ // func valueLength(v ref) int
+ 'syscall/js.valueLength': (sp) => {
+ sp >>>= 0
+ setInt64(sp + 16, parseInt(loadValue(sp + 8).length))
+ },
+
+ // valuePrepareString(v ref) (ref, int)
+ 'syscall/js.valuePrepareString': (sp) => {
+ sp >>>= 0
+ const str = encoder.encode(String(loadValue(sp + 8)))
+ storeValue(sp + 16, str)
+ setInt64(sp + 24, str.length)
+ },
+
+ // valueLoadString(v ref, b []byte)
+ 'syscall/js.valueLoadString': (sp) => {
+ sp >>>= 0
+ const str = loadValue(sp + 8)
+ loadSlice(sp + 16).set(str)
+ },
+
+ // func valueInstanceOf(v ref, t ref) bool
+ 'syscall/js.valueInstanceOf': (sp) => {
+ sp >>>= 0
+ this.mem.setUint8(sp + 24, (loadValue(sp + 8) instanceof loadValue(sp + 16)) ? 1 : 0)
+ },
+
+ // func copyBytesToGo(dst []byte, src ref) (int, bool)
+ 'syscall/js.copyBytesToGo': (sp) => {
+ sp >>>= 0
+ const dst = loadSlice(sp + 8)
+ const src = loadValue(sp + 32)
+ if (!(src instanceof Uint8Array || src instanceof Uint8ClampedArray)) {
+ this.mem.setUint8(sp + 48, 0)
+ return
+ }
+ const toCopy = src.subarray(0, dst.length)
+ dst.set(toCopy)
+ setInt64(sp + 40, toCopy.length)
+ this.mem.setUint8(sp + 48, 1)
+ },
+
+ // func copyBytesToJS(dst ref, src []byte) (int, bool)
+ 'syscall/js.copyBytesToJS': (sp) => {
+ sp >>>= 0
+ const dst = loadValue(sp + 8)
+ const src = loadSlice(sp + 16)
+ if (!(dst instanceof Uint8Array || dst instanceof Uint8ClampedArray)) {
+ this.mem.setUint8(sp + 48, 0)
+ return
+ }
+ const toCopy = src.subarray(0, dst.length)
+ dst.set(toCopy)
+ setInt64(sp + 40, toCopy.length)
+ this.mem.setUint8(sp + 48, 1)
+ },
+
+ debug: (value) => {
+ console.log(value)
+ }
+ }
+ }
+ }
+
+ async run (instance) {
+ if (!(instance instanceof WebAssembly.Instance)) {
+ throw new Error('Go.run: WebAssembly.Instance expected')
+ }
+ this._inst = instance
+ this.mem = new DataView(this._inst.exports.mem.buffer)
+ this._values = [ // JS values that Go currently has references to, indexed by reference id
+ NaN,
+ 0,
+ null,
+ true,
+ false,
+ globalThis,
+ this
+ ]
+ this._goRefCounts = new Array(this._values.length).fill(Infinity) // number of references that Go has to a JS value, indexed by reference id
+ this._ids = new Map([ // mapping from JS values to reference ids
+ [0, 1],
+ [null, 2],
+ [true, 3],
+ [false, 4],
+ [globalThis, 5],
+ [this, 6]
+ ])
+ this._idPool = [] // unused ids that have been garbage collected
+ this.exited = false // whether the Go program has exited
+
+ // Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory.
+ let offset = 4096
+
+ const strPtr = (str) => {
+ const ptr = offset
+ const bytes = encoder.encode(str + '\0')
+ new Uint8Array(this.mem.buffer, offset, bytes.length).set(bytes)
+ offset += bytes.length
+ if (offset % 8 !== 0) {
+ offset += 8 - (offset % 8)
+ }
+ return ptr
+ }
+
+ const argc = this.argv.length
+
+ const argvPtrs = []
+ this.argv.forEach((arg) => {
+ argvPtrs.push(strPtr(arg))
+ })
+ argvPtrs.push(0)
+
+ const keys = Object.keys(this.env).sort()
+ keys.forEach((key) => {
+ argvPtrs.push(strPtr(`${key}=${this.env[key]}`))
+ })
+ argvPtrs.push(0)
+
+ const argv = offset
+ argvPtrs.forEach((ptr) => {
+ this.mem.setUint32(offset, ptr, true)
+ this.mem.setUint32(offset + 4, 0, true)
+ offset += 8
+ })
+
+ // The linker guarantees global data starts from at least wasmMinDataAddr.
+ // Keep in sync with cmd/link/internal/ld/data.go:wasmMinDataAddr.
+ const wasmMinDataAddr = 4096 + 8192
+ if (offset >= wasmMinDataAddr) {
+ throw new Error('total length of command line and environment variables exceeds limit')
+ }
+
+ this._inst.exports.run(argc, argv)
+ if (this.exited) {
+ this._resolveExitPromise()
+ }
+ await this._exitPromise
+ }
+
+ _resume () {
+ if (this.exited) {
+ throw new Error('Go program has already exited')
+ }
+ this._inst.exports.resume()
+ if (this.exited) {
+ this._resolveExitPromise()
+ }
+ }
+
+ _makeFuncWrapper (id) {
+ const go = this
+ return function () {
+ const event = { id: id, this: this, args: arguments }
+ go._pendingEvent = event
+ go._resume()
+ return event.result
+ }
+ }
+ }
+})()
diff --git a/nezha-fronted/src/components/page/integration/integration-tabs/manual.vue b/nezha-fronted/src/components/page/integration/integration-tabs/manual.vue
index bec71b6b9..0fa4a58be 100644
--- a/nezha-fronted/src/components/page/integration/integration-tabs/manual.vue
+++ b/nezha-fronted/src/components/page/integration/integration-tabs/manual.vue
@@ -16,6 +16,7 @@
+ {{$t('overall.downloading')}}