@perses-dev/prometheus-plugin 0.48.0 → 0.49.0-rc.0
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/dist/cjs/components/PromQLEditor.js +209 -0
- package/dist/cjs/components/TreeNode.js +147 -0
- package/dist/cjs/components/index.js +1 -1
- package/dist/cjs/components/parse.js +42 -0
- package/dist/cjs/components/promql/ast.js +143 -0
- package/dist/cjs/components/promql/format.js +432 -0
- package/dist/cjs/components/promql/utils.js +109 -0
- package/dist/cjs/model/prometheus-client.js +10 -2
- package/dist/cjs/plugins/PrometheusDatasourceEditor.js +4 -0
- package/dist/cjs/plugins/prometheus-datasource.js +4 -0
- package/dist/cjs/plugins/prometheus-time-series-query/PrometheusTimeSeriesQueryEditor.js +6 -5
- package/dist/cjs/plugins/prometheus-variables.js +4 -2
- package/dist/components/PromQLEditor.d.ts +9 -0
- package/dist/components/PromQLEditor.d.ts.map +1 -0
- package/dist/components/PromQLEditor.js +196 -0
- package/dist/components/PromQLEditor.js.map +1 -0
- package/dist/components/TreeNode.d.ts +10 -0
- package/dist/components/TreeNode.d.ts.map +1 -0
- package/dist/components/TreeNode.js +139 -0
- package/dist/components/TreeNode.js.map +1 -0
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/index.js.map +1 -1
- package/dist/components/parse.d.ts +4 -0
- package/dist/components/parse.d.ts.map +1 -0
- package/dist/components/parse.js +34 -0
- package/dist/components/parse.js.map +1 -0
- package/dist/components/promql/ast.d.ts +161 -0
- package/dist/components/promql/ast.d.ts.map +1 -0
- package/dist/components/promql/ast.js +106 -0
- package/dist/components/promql/ast.js.map +1 -0
- package/dist/components/promql/format.d.ts +5 -0
- package/dist/components/promql/format.d.ts.map +1 -0
- package/dist/components/promql/format.js +411 -0
- package/dist/components/promql/format.js.map +1 -0
- package/dist/components/promql/utils.d.ts +5 -0
- package/dist/components/promql/utils.d.ts.map +1 -0
- package/dist/components/promql/utils.js +90 -0
- package/dist/components/promql/utils.js.map +1 -0
- package/dist/model/api-types.d.ts +5 -0
- package/dist/model/api-types.d.ts.map +1 -1
- package/dist/model/api-types.js.map +1 -1
- package/dist/model/prometheus-client.d.ts +6 -1
- package/dist/model/prometheus-client.d.ts.map +1 -1
- package/dist/model/prometheus-client.js +9 -2
- package/dist/model/prometheus-client.js.map +1 -1
- package/dist/plugins/PrometheusDatasourceEditor.d.ts.map +1 -1
- package/dist/plugins/PrometheusDatasourceEditor.js +4 -0
- package/dist/plugins/PrometheusDatasourceEditor.js.map +1 -1
- package/dist/plugins/prometheus-datasource.d.ts.map +1 -1
- package/dist/plugins/prometheus-datasource.js +5 -1
- package/dist/plugins/prometheus-datasource.js.map +1 -1
- package/dist/plugins/prometheus-time-series-query/PrometheusTimeSeriesQueryEditor.d.ts.map +1 -1
- package/dist/plugins/prometheus-time-series-query/PrometheusTimeSeriesQueryEditor.js +6 -5
- package/dist/plugins/prometheus-time-series-query/PrometheusTimeSeriesQueryEditor.js.map +1 -1
- package/dist/plugins/prometheus-variables.d.ts.map +1 -1
- package/dist/plugins/prometheus-variables.js +4 -2
- package/dist/plugins/prometheus-variables.js.map +1 -1
- package/package.json +4 -4
- package/dist/cjs/components/PromQL.js +0 -58
- package/dist/components/PromQL.d.ts +0 -7
- package/dist/components/PromQL.d.ts.map +0 -1
- package/dist/components/PromQL.js +0 -45
- package/dist/components/PromQL.js.map +0 -1
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
// Copyright 2024 The Perses Authors
|
|
2
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
// you may not use this file except in compliance with the License.
|
|
4
|
+
// You may obtain a copy of the License at
|
|
5
|
+
//
|
|
6
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
//
|
|
8
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
// See the License for the specific language governing permissions and
|
|
12
|
+
// limitations under the License.
|
|
13
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
14
|
+
import CodeMirror from '@uiw/react-codemirror';
|
|
15
|
+
import { PromQLExtension } from '@prometheus-io/codemirror-promql';
|
|
16
|
+
import { EditorView } from '@codemirror/view';
|
|
17
|
+
import { useTheme, CircularProgress, InputLabel, Stack, IconButton, Tooltip } from '@mui/material';
|
|
18
|
+
import FileTreeIcon from 'mdi-material-ui/FileTree';
|
|
19
|
+
import { useMemo, useState } from 'react';
|
|
20
|
+
import { ErrorAlert } from '@perses-dev/components';
|
|
21
|
+
import CloseIcon from 'mdi-material-ui/Close';
|
|
22
|
+
import { useReplaceVariablesInString } from '@perses-dev/plugin-system';
|
|
23
|
+
import { useParseQuery } from './parse';
|
|
24
|
+
import TreeNode from './TreeNode';
|
|
25
|
+
const treeViewStr = 'Tree View';
|
|
26
|
+
const treeViewOpenStr = 'Open ' + treeViewStr;
|
|
27
|
+
const treeViewCloseStr = 'Close ' + treeViewStr;
|
|
28
|
+
// Process the error to identify if it's a generic one & adjust the message in some cases
|
|
29
|
+
// TODO: This should be removed when properly tackling query error at query editor level (https://github.com/perses/perses/issues/1419)
|
|
30
|
+
// Here this was kinda a quick-win to do it like this with the implementation of the Tree view.
|
|
31
|
+
// Once #1419 will be tackled, any error reported by the query to the parse endpoint here should be treated the same (= display
|
|
32
|
+
// the error in the debug/tree view & always let the buttons accessible to show/hide it).
|
|
33
|
+
function processError(error) {
|
|
34
|
+
// Specific errors that user should be able to hide
|
|
35
|
+
const apiNotAvailableError = '404 page not found';
|
|
36
|
+
const apiNotAvailableErrorRephrased = `${treeViewStr} is available only for datasources whose APIs comply with Prometheus 3.0 specifications`;
|
|
37
|
+
const blockedByProxyError = 'forbidden access: you are not allowed to use this endpoint "/api/v1/parse_query" with the HTTP method POST';
|
|
38
|
+
const blockedByProxyErrorRephrased = `Your datasource configuration is blocking the ${treeViewStr} feature: the datasource should allow POST requests to "/api/v1/parse_query"`;
|
|
39
|
+
let errorMessage = 'An unknown error occurred';
|
|
40
|
+
let isGenericError = false;
|
|
41
|
+
if (error && error instanceof Error) {
|
|
42
|
+
errorMessage = error.message.trim();
|
|
43
|
+
if (errorMessage === apiNotAvailableError) {
|
|
44
|
+
errorMessage = apiNotAvailableErrorRephrased;
|
|
45
|
+
} else if (errorMessage === blockedByProxyError) {
|
|
46
|
+
errorMessage = blockedByProxyErrorRephrased;
|
|
47
|
+
} else {
|
|
48
|
+
isGenericError = true;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
errorMessage,
|
|
53
|
+
isGenericError
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export function PromQLEditor({ completeConfig, datasource, ...rest }) {
|
|
57
|
+
const theme = useTheme();
|
|
58
|
+
const isDarkMode = theme.palette.mode === 'dark';
|
|
59
|
+
const [isTreeViewVisible, setTreeViewVisible] = useState(false);
|
|
60
|
+
const promQLExtension = useMemo(()=>{
|
|
61
|
+
return new PromQLExtension().activateLinter(false).setComplete(completeConfig).asExtension();
|
|
62
|
+
}, [
|
|
63
|
+
completeConfig
|
|
64
|
+
]);
|
|
65
|
+
const queryExpr = useReplaceVariablesInString(rest.value);
|
|
66
|
+
const { data: parseQueryResponse, isLoading, error } = useParseQuery(queryExpr !== null && queryExpr !== void 0 ? queryExpr : '', datasource);
|
|
67
|
+
const { errorMessage, isGenericError } = useMemo(()=>processError(error), [
|
|
68
|
+
error
|
|
69
|
+
]);
|
|
70
|
+
const handleShowTreeView = ()=>{
|
|
71
|
+
setTreeViewVisible(!isTreeViewVisible);
|
|
72
|
+
};
|
|
73
|
+
return /*#__PURE__*/ _jsxs(Stack, {
|
|
74
|
+
position: "relative",
|
|
75
|
+
children: [
|
|
76
|
+
/*#__PURE__*/ _jsx(InputLabel // reproduce the same kind of input label that regular MUI TextFields have
|
|
77
|
+
, {
|
|
78
|
+
shrink: true,
|
|
79
|
+
sx: {
|
|
80
|
+
position: 'absolute',
|
|
81
|
+
top: '-8px',
|
|
82
|
+
left: '10px',
|
|
83
|
+
padding: '0 4px',
|
|
84
|
+
color: theme.palette.text.primary,
|
|
85
|
+
zIndex: 1
|
|
86
|
+
},
|
|
87
|
+
children: "PromQL Expression"
|
|
88
|
+
}),
|
|
89
|
+
/*#__PURE__*/ _jsx(CodeMirror, {
|
|
90
|
+
...rest,
|
|
91
|
+
style: {
|
|
92
|
+
border: `1px solid ${theme.palette.divider}`
|
|
93
|
+
},
|
|
94
|
+
theme: isDarkMode ? 'dark' : 'light',
|
|
95
|
+
basicSetup: {
|
|
96
|
+
highlightActiveLine: false,
|
|
97
|
+
highlightActiveLineGutter: false,
|
|
98
|
+
foldGutter: false
|
|
99
|
+
},
|
|
100
|
+
extensions: [
|
|
101
|
+
EditorView.lineWrapping,
|
|
102
|
+
promQLExtension,
|
|
103
|
+
EditorView.theme({
|
|
104
|
+
'.cm-content': {
|
|
105
|
+
paddingTop: '8px',
|
|
106
|
+
paddingBottom: '8px',
|
|
107
|
+
paddingRight: '40px'
|
|
108
|
+
}
|
|
109
|
+
})
|
|
110
|
+
],
|
|
111
|
+
placeholder: "Example: sum(rate(http_requests_total[5m]))"
|
|
112
|
+
}),
|
|
113
|
+
queryExpr && /*#__PURE__*/ _jsx(_Fragment, {
|
|
114
|
+
children: isGenericError ? // Display the error without any close button, tree view etc when it's a generic error
|
|
115
|
+
/*#__PURE__*/ _jsx("div", {
|
|
116
|
+
style: {
|
|
117
|
+
border: `1px solid ${theme.palette.divider}`
|
|
118
|
+
},
|
|
119
|
+
children: /*#__PURE__*/ _jsx(ErrorAlert, {
|
|
120
|
+
error: {
|
|
121
|
+
name: 'Parse query error',
|
|
122
|
+
message: errorMessage
|
|
123
|
+
}
|
|
124
|
+
})
|
|
125
|
+
}) : // Otherwise include the logic to show/hide the tree view
|
|
126
|
+
/*#__PURE__*/ _jsxs(_Fragment, {
|
|
127
|
+
children: [
|
|
128
|
+
/*#__PURE__*/ _jsx(Tooltip, {
|
|
129
|
+
title: isTreeViewVisible ? treeViewCloseStr : treeViewOpenStr,
|
|
130
|
+
children: /*#__PURE__*/ _jsx(IconButton, {
|
|
131
|
+
"aria-label": isTreeViewVisible ? treeViewCloseStr : treeViewOpenStr,
|
|
132
|
+
onClick: handleShowTreeView,
|
|
133
|
+
sx: {
|
|
134
|
+
position: 'absolute',
|
|
135
|
+
right: '5px',
|
|
136
|
+
top: '5px'
|
|
137
|
+
},
|
|
138
|
+
size: "small",
|
|
139
|
+
children: /*#__PURE__*/ _jsx(FileTreeIcon, {
|
|
140
|
+
sx: {
|
|
141
|
+
fontSize: '18px'
|
|
142
|
+
}
|
|
143
|
+
})
|
|
144
|
+
})
|
|
145
|
+
}),
|
|
146
|
+
isTreeViewVisible && /*#__PURE__*/ _jsxs("div", {
|
|
147
|
+
style: {
|
|
148
|
+
border: `1px solid ${theme.palette.divider}`,
|
|
149
|
+
position: 'relative'
|
|
150
|
+
},
|
|
151
|
+
children: [
|
|
152
|
+
/*#__PURE__*/ _jsx(Tooltip, {
|
|
153
|
+
title: treeViewCloseStr,
|
|
154
|
+
children: /*#__PURE__*/ _jsx(IconButton, {
|
|
155
|
+
"aria-label": treeViewCloseStr,
|
|
156
|
+
onClick: ()=>setTreeViewVisible(false),
|
|
157
|
+
sx: {
|
|
158
|
+
position: 'absolute',
|
|
159
|
+
top: '5px',
|
|
160
|
+
right: '5px'
|
|
161
|
+
},
|
|
162
|
+
size: "small",
|
|
163
|
+
children: /*#__PURE__*/ _jsx(CloseIcon, {
|
|
164
|
+
sx: {
|
|
165
|
+
fontSize: '18px'
|
|
166
|
+
}
|
|
167
|
+
})
|
|
168
|
+
})
|
|
169
|
+
}),
|
|
170
|
+
error ? // Here the user is able to hide the error alert
|
|
171
|
+
/*#__PURE__*/ _jsx(ErrorAlert, {
|
|
172
|
+
error: {
|
|
173
|
+
name: `${treeViewStr} not available`,
|
|
174
|
+
message: errorMessage
|
|
175
|
+
}
|
|
176
|
+
}) : /*#__PURE__*/ _jsx("div", {
|
|
177
|
+
style: {
|
|
178
|
+
padding: `${theme.spacing(1.5)} ${theme.spacing(1.5)} 0 ${theme.spacing(1.5)}`,
|
|
179
|
+
overflowX: 'auto',
|
|
180
|
+
backgroundColor: theme.palette.background.default
|
|
181
|
+
},
|
|
182
|
+
children: isLoading ? /*#__PURE__*/ _jsx(CircularProgress, {}) : (parseQueryResponse === null || parseQueryResponse === void 0 ? void 0 : parseQueryResponse.data) ? /*#__PURE__*/ _jsx(TreeNode, {
|
|
183
|
+
node: parseQueryResponse.data,
|
|
184
|
+
reverse: false
|
|
185
|
+
}) : null
|
|
186
|
+
})
|
|
187
|
+
]
|
|
188
|
+
})
|
|
189
|
+
]
|
|
190
|
+
})
|
|
191
|
+
})
|
|
192
|
+
]
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
//# sourceMappingURL=PromQLEditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/PromQLEditor.tsx"],"sourcesContent":["// Copyright 2024 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport CodeMirror, { ReactCodeMirrorProps } from '@uiw/react-codemirror';\nimport { PromQLExtension, CompleteConfiguration } from '@prometheus-io/codemirror-promql';\nimport { EditorView } from '@codemirror/view';\nimport { useTheme, CircularProgress, InputLabel, Stack, IconButton, Tooltip } from '@mui/material';\nimport FileTreeIcon from 'mdi-material-ui/FileTree';\nimport { useMemo, useState } from 'react';\nimport { ErrorAlert } from '@perses-dev/components';\nimport CloseIcon from 'mdi-material-ui/Close';\nimport { useReplaceVariablesInString } from '@perses-dev/plugin-system';\nimport { PrometheusDatasourceSelector } from '../model';\nimport { useParseQuery } from './parse';\nimport TreeNode from './TreeNode';\n\nconst treeViewStr = 'Tree View';\nconst treeViewOpenStr = 'Open ' + treeViewStr;\nconst treeViewCloseStr = 'Close ' + treeViewStr;\n\n// Process the error to identify if it's a generic one & adjust the message in some cases\n// TODO: This should be removed when properly tackling query error at query editor level (https://github.com/perses/perses/issues/1419)\n// Here this was kinda a quick-win to do it like this with the implementation of the Tree view.\n// Once #1419 will be tackled, any error reported by the query to the parse endpoint here should be treated the same (= display\n// the error in the debug/tree view & always let the buttons accessible to show/hide it).\nfunction processError(error: unknown): { errorMessage: string; isGenericError: boolean } {\n // Specific errors that user should be able to hide\n const apiNotAvailableError = '404 page not found';\n const apiNotAvailableErrorRephrased = `${treeViewStr} is available only for datasources whose APIs comply with Prometheus 3.0 specifications`;\n\n const blockedByProxyError =\n 'forbidden access: you are not allowed to use this endpoint \"/api/v1/parse_query\" with the HTTP method POST';\n const blockedByProxyErrorRephrased = `Your datasource configuration is blocking the ${treeViewStr} feature: the datasource should allow POST requests to \"/api/v1/parse_query\"`;\n\n let errorMessage = 'An unknown error occurred';\n let isGenericError = false;\n if (error && error instanceof Error) {\n errorMessage = error.message.trim();\n if (errorMessage === apiNotAvailableError) {\n errorMessage = apiNotAvailableErrorRephrased;\n } else if (errorMessage === blockedByProxyError) {\n errorMessage = blockedByProxyErrorRephrased;\n } else {\n isGenericError = true;\n }\n }\n\n return { errorMessage, isGenericError };\n}\n\nexport type PromQLEditorProps = {\n completeConfig: CompleteConfiguration;\n datasource: PrometheusDatasourceSelector;\n} & Omit<ReactCodeMirrorProps, 'theme' | 'extensions'>;\n\nexport function PromQLEditor({ completeConfig, datasource, ...rest }: PromQLEditorProps) {\n const theme = useTheme();\n const isDarkMode = theme.palette.mode === 'dark';\n const [isTreeViewVisible, setTreeViewVisible] = useState(false);\n\n const promQLExtension = useMemo(() => {\n return new PromQLExtension().activateLinter(false).setComplete(completeConfig).asExtension();\n }, [completeConfig]);\n\n const queryExpr = useReplaceVariablesInString(rest.value);\n\n const { data: parseQueryResponse, isLoading, error } = useParseQuery(queryExpr ?? '', datasource);\n const { errorMessage, isGenericError } = useMemo(() => processError(error), [error]);\n\n const handleShowTreeView = () => {\n setTreeViewVisible(!isTreeViewVisible);\n };\n\n return (\n <Stack position=\"relative\">\n <InputLabel // reproduce the same kind of input label that regular MUI TextFields have\n shrink\n sx={{\n position: 'absolute',\n top: '-8px',\n left: '10px',\n padding: '0 4px',\n color: theme.palette.text.primary,\n zIndex: 1,\n }}\n >\n PromQL Expression\n </InputLabel>\n <CodeMirror\n {...rest}\n style={{ border: `1px solid ${theme.palette.divider}` }}\n theme={isDarkMode ? 'dark' : 'light'}\n basicSetup={{\n highlightActiveLine: false,\n highlightActiveLineGutter: false,\n foldGutter: false,\n }}\n extensions={[\n EditorView.lineWrapping,\n promQLExtension,\n EditorView.theme({\n '.cm-content': {\n paddingTop: '8px',\n paddingBottom: '8px',\n paddingRight: '40px', // offset for the tree view button\n },\n }),\n ]}\n placeholder=\"Example: sum(rate(http_requests_total[5m]))\"\n />\n {queryExpr && (\n <>\n {isGenericError ? (\n // Display the error without any close button, tree view etc when it's a generic error\n <div style={{ border: `1px solid ${theme.palette.divider}` }}>\n <ErrorAlert error={{ name: 'Parse query error', message: errorMessage }} />\n </div>\n ) : (\n // Otherwise include the logic to show/hide the tree view\n <>\n <Tooltip title={isTreeViewVisible ? treeViewCloseStr : treeViewOpenStr}>\n <IconButton\n aria-label={isTreeViewVisible ? treeViewCloseStr : treeViewOpenStr}\n onClick={handleShowTreeView}\n sx={{ position: 'absolute', right: '5px', top: '5px' }}\n size=\"small\"\n >\n <FileTreeIcon sx={{ fontSize: '18px' }} />\n </IconButton>\n </Tooltip>\n {isTreeViewVisible && (\n <div style={{ border: `1px solid ${theme.palette.divider}`, position: 'relative' }}>\n <Tooltip title={treeViewCloseStr}>\n <IconButton\n aria-label={treeViewCloseStr}\n onClick={() => setTreeViewVisible(false)}\n sx={{ position: 'absolute', top: '5px', right: '5px' }}\n size=\"small\"\n >\n <CloseIcon sx={{ fontSize: '18px' }} />\n </IconButton>\n </Tooltip>\n {error ? (\n // Here the user is able to hide the error alert\n <ErrorAlert\n error={{\n name: `${treeViewStr} not available`,\n message: errorMessage,\n }}\n />\n ) : (\n <div\n style={{\n padding: `${theme.spacing(1.5)} ${theme.spacing(1.5)} 0 ${theme.spacing(1.5)}`, // let paddingBottom at 0 because nodes have margin-bottom\n overflowX: 'auto',\n backgroundColor: theme.palette.background.default,\n }}\n >\n {isLoading ? (\n <CircularProgress />\n ) : parseQueryResponse?.data ? (\n <TreeNode node={parseQueryResponse.data} reverse={false} />\n ) : null}\n </div>\n )}\n </div>\n )}\n </>\n )}\n </>\n )}\n </Stack>\n );\n}\n"],"names":["CodeMirror","PromQLExtension","EditorView","useTheme","CircularProgress","InputLabel","Stack","IconButton","Tooltip","FileTreeIcon","useMemo","useState","ErrorAlert","CloseIcon","useReplaceVariablesInString","useParseQuery","TreeNode","treeViewStr","treeViewOpenStr","treeViewCloseStr","processError","error","apiNotAvailableError","apiNotAvailableErrorRephrased","blockedByProxyError","blockedByProxyErrorRephrased","errorMessage","isGenericError","Error","message","trim","PromQLEditor","completeConfig","datasource","rest","theme","isDarkMode","palette","mode","isTreeViewVisible","setTreeViewVisible","promQLExtension","activateLinter","setComplete","asExtension","queryExpr","value","data","parseQueryResponse","isLoading","handleShowTreeView","position","shrink","sx","top","left","padding","color","text","primary","zIndex","style","border","divider","basicSetup","highlightActiveLine","highlightActiveLineGutter","foldGutter","extensions","lineWrapping","paddingTop","paddingBottom","paddingRight","placeholder","div","name","title","aria-label","onClick","right","size","fontSize","spacing","overflowX","backgroundColor","background","default","node","reverse"],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import ASTNode from './promql/ast';
|
|
3
|
+
interface TreeNodeProps {
|
|
4
|
+
node: ASTNode;
|
|
5
|
+
parentEl?: HTMLDivElement | null;
|
|
6
|
+
reverse: boolean;
|
|
7
|
+
}
|
|
8
|
+
declare const TreeNode: React.FC<TreeNodeProps>;
|
|
9
|
+
export default TreeNode;
|
|
10
|
+
//# sourceMappingURL=TreeNode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TreeNode.d.ts","sourceRoot":"","sources":["../../src/components/TreeNode.tsx"],"names":[],"mappings":";AAiBA,OAAO,OAAqB,MAAM,cAAc,CAAC;AAQjD,UAAU,aAAa;IAErB,IAAI,EAAE,OAAO,CAAC;IAEd,QAAQ,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAEjC,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,QAAA,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA0GrC,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// Copyright 2024 The Perses Authors
|
|
2
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
// you may not use this file except in compliance with the License.
|
|
4
|
+
// You may obtain a copy of the License at
|
|
5
|
+
//
|
|
6
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
//
|
|
8
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
// See the License for the specific language governing permissions and
|
|
12
|
+
// limitations under the License.
|
|
13
|
+
// Forked from https://github.com/prometheus/prometheus/blob/65f610353919b1c7b42d3776c3a95b68046a6bba/web/ui/mantine-ui/src/pages/query/TreeNode.tsx
|
|
14
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
15
|
+
import { Box, useTheme } from '@mui/material';
|
|
16
|
+
import { useCallback, useLayoutEffect, useState } from 'react';
|
|
17
|
+
import { nodeType } from './promql/ast';
|
|
18
|
+
import { getNodeChildren } from './promql/utils';
|
|
19
|
+
import { formatNode } from './promql/format';
|
|
20
|
+
// The indentation factor for each level of the tree.
|
|
21
|
+
const nodeIndent = 5;
|
|
22
|
+
const connectorWidth = nodeIndent * 5;
|
|
23
|
+
const TreeNode = ({ node, parentEl, reverse })=>{
|
|
24
|
+
const theme = useTheme();
|
|
25
|
+
const children = getNodeChildren(node);
|
|
26
|
+
// A normal ref won't work properly here because the ref's `current` property
|
|
27
|
+
// going from `null` to defined won't trigger a re-render of the child
|
|
28
|
+
// component, since it's not a React state update. So we manually have to
|
|
29
|
+
// create a state update using a callback ref. See also
|
|
30
|
+
// https://tkdodo.eu/blog/avoiding-use-effect-with-callback-refs
|
|
31
|
+
const [nodeEl, setNodeEl] = useState(null);
|
|
32
|
+
const nodeRef = useCallback((node)=>setNodeEl(node), []);
|
|
33
|
+
const [connectorStyle, setConnectorStyle] = useState({
|
|
34
|
+
borderColor: theme.palette.grey['500'],
|
|
35
|
+
borderLeftStyle: 'solid',
|
|
36
|
+
borderLeftWidth: 2,
|
|
37
|
+
width: connectorWidth,
|
|
38
|
+
left: -connectorWidth
|
|
39
|
+
});
|
|
40
|
+
// Update the size and position of tree connector lines based on the node's and its parent's position.
|
|
41
|
+
useLayoutEffect(()=>{
|
|
42
|
+
if (parentEl === undefined) {
|
|
43
|
+
// We're the root node.
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (parentEl === null || nodeEl === null) {
|
|
47
|
+
// Either of the two connected nodes hasn't been rendered yet.
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const parentRect = parentEl.getBoundingClientRect();
|
|
51
|
+
const nodeRect = nodeEl.getBoundingClientRect();
|
|
52
|
+
if (reverse) {
|
|
53
|
+
setConnectorStyle((prevStyle)=>({
|
|
54
|
+
...prevStyle,
|
|
55
|
+
top: 'calc(50% - 1px)',
|
|
56
|
+
bottom: nodeRect.bottom - parentRect.top,
|
|
57
|
+
borderTopLeftRadius: 10,
|
|
58
|
+
borderTopStyle: 'solid',
|
|
59
|
+
borderBottomLeftRadius: undefined
|
|
60
|
+
}));
|
|
61
|
+
} else {
|
|
62
|
+
setConnectorStyle((prevStyle)=>({
|
|
63
|
+
...prevStyle,
|
|
64
|
+
top: parentRect.bottom - nodeRect.top,
|
|
65
|
+
bottom: 'calc(50% - 1px)',
|
|
66
|
+
borderBottomLeftRadius: 10,
|
|
67
|
+
borderBottomStyle: 'solid',
|
|
68
|
+
borderTopLeftRadius: undefined
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
71
|
+
}, [
|
|
72
|
+
parentEl,
|
|
73
|
+
nodeEl,
|
|
74
|
+
reverse,
|
|
75
|
+
nodeRef,
|
|
76
|
+
setConnectorStyle
|
|
77
|
+
]);
|
|
78
|
+
const innerNode = /*#__PURE__*/ _jsxs(Box, {
|
|
79
|
+
ref: nodeRef,
|
|
80
|
+
sx: {
|
|
81
|
+
position: 'relative',
|
|
82
|
+
display: 'inline-block',
|
|
83
|
+
padding: 1,
|
|
84
|
+
marginBottom: 1.5,
|
|
85
|
+
borderRadius: 2,
|
|
86
|
+
backgroundColor: theme.palette.background.code
|
|
87
|
+
},
|
|
88
|
+
children: [
|
|
89
|
+
parentEl !== undefined && // Connector line between this node and its parent.
|
|
90
|
+
/*#__PURE__*/ _jsx(Box, {
|
|
91
|
+
sx: {
|
|
92
|
+
position: 'absolute',
|
|
93
|
+
display: 'inline-block',
|
|
94
|
+
...connectorStyle
|
|
95
|
+
}
|
|
96
|
+
}),
|
|
97
|
+
formatNode(node, false, 1)
|
|
98
|
+
]
|
|
99
|
+
});
|
|
100
|
+
if (node.type === nodeType.binaryExpr) {
|
|
101
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
102
|
+
children: [
|
|
103
|
+
/*#__PURE__*/ _jsx(Box, {
|
|
104
|
+
ml: nodeIndent,
|
|
105
|
+
children: /*#__PURE__*/ _jsx(TreeNode, {
|
|
106
|
+
node: children[0],
|
|
107
|
+
parentEl: nodeEl,
|
|
108
|
+
reverse: true
|
|
109
|
+
})
|
|
110
|
+
}),
|
|
111
|
+
innerNode,
|
|
112
|
+
/*#__PURE__*/ _jsx(Box, {
|
|
113
|
+
ml: nodeIndent,
|
|
114
|
+
children: /*#__PURE__*/ _jsx(TreeNode, {
|
|
115
|
+
node: children[1],
|
|
116
|
+
parentEl: nodeEl,
|
|
117
|
+
reverse: false
|
|
118
|
+
})
|
|
119
|
+
})
|
|
120
|
+
]
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
124
|
+
children: [
|
|
125
|
+
innerNode,
|
|
126
|
+
children.map((child, idx)=>/*#__PURE__*/ _jsx(Box, {
|
|
127
|
+
ml: nodeIndent,
|
|
128
|
+
children: /*#__PURE__*/ _jsx(TreeNode, {
|
|
129
|
+
node: child,
|
|
130
|
+
parentEl: nodeEl,
|
|
131
|
+
reverse: false
|
|
132
|
+
})
|
|
133
|
+
}, idx))
|
|
134
|
+
]
|
|
135
|
+
});
|
|
136
|
+
};
|
|
137
|
+
export default TreeNode;
|
|
138
|
+
|
|
139
|
+
//# sourceMappingURL=TreeNode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/TreeNode.tsx"],"sourcesContent":["// Copyright 2024 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Forked from https://github.com/prometheus/prometheus/blob/65f610353919b1c7b42d3776c3a95b68046a6bba/web/ui/mantine-ui/src/pages/query/TreeNode.tsx\n\nimport { Box, useTheme } from '@mui/material';\nimport { useCallback, useLayoutEffect, useState } from 'react';\nimport ASTNode, { nodeType } from './promql/ast';\nimport { getNodeChildren } from './promql/utils';\nimport { formatNode } from './promql/format';\n\n// The indentation factor for each level of the tree.\nconst nodeIndent = 5;\nconst connectorWidth = nodeIndent * 5;\n\ninterface TreeNodeProps {\n // The AST node to render.\n node: ASTNode;\n // The parent element of this node.\n parentEl?: HTMLDivElement | null;\n // used to compute the position of the connector line between this node and its parent.\n reverse: boolean;\n}\n\nconst TreeNode: React.FC<TreeNodeProps> = ({ node, parentEl, reverse }) => {\n const theme = useTheme();\n const children = getNodeChildren(node);\n\n // A normal ref won't work properly here because the ref's `current` property\n // going from `null` to defined won't trigger a re-render of the child\n // component, since it's not a React state update. So we manually have to\n // create a state update using a callback ref. See also\n // https://tkdodo.eu/blog/avoiding-use-effect-with-callback-refs\n const [nodeEl, setNodeEl] = useState<HTMLDivElement | null>(null);\n const nodeRef = useCallback((node: HTMLDivElement) => setNodeEl(node), []);\n\n const [connectorStyle, setConnectorStyle] = useState({\n borderColor: theme.palette.grey['500'],\n borderLeftStyle: 'solid',\n borderLeftWidth: 2,\n width: connectorWidth,\n left: -connectorWidth,\n });\n\n // Update the size and position of tree connector lines based on the node's and its parent's position.\n useLayoutEffect(() => {\n if (parentEl === undefined) {\n // We're the root node.\n return;\n }\n\n if (parentEl === null || nodeEl === null) {\n // Either of the two connected nodes hasn't been rendered yet.\n return;\n }\n\n const parentRect = parentEl.getBoundingClientRect();\n const nodeRect = nodeEl.getBoundingClientRect();\n if (reverse) {\n setConnectorStyle((prevStyle) => ({\n ...prevStyle,\n top: 'calc(50% - 1px)',\n bottom: nodeRect.bottom - parentRect.top,\n borderTopLeftRadius: 10,\n borderTopStyle: 'solid',\n borderBottomLeftRadius: undefined,\n }));\n } else {\n setConnectorStyle((prevStyle) => ({\n ...prevStyle,\n top: parentRect.bottom - nodeRect.top,\n bottom: 'calc(50% - 1px)',\n borderBottomLeftRadius: 10,\n borderBottomStyle: 'solid',\n borderTopLeftRadius: undefined,\n }));\n }\n }, [parentEl, nodeEl, reverse, nodeRef, setConnectorStyle]);\n\n const innerNode = (\n <Box\n ref={nodeRef}\n sx={{\n position: 'relative',\n display: 'inline-block',\n padding: 1,\n marginBottom: 1.5,\n borderRadius: 2,\n backgroundColor: theme.palette.background.code,\n }}\n >\n {parentEl !== undefined && (\n // Connector line between this node and its parent.\n <Box\n sx={{\n position: 'absolute',\n display: 'inline-block',\n ...connectorStyle,\n }}\n />\n )}\n {/* The node (visible box) itself. */}\n {formatNode(node, false, 1)}\n </Box>\n );\n\n if (node.type === nodeType.binaryExpr) {\n return (\n <div>\n <Box ml={nodeIndent}>\n <TreeNode node={children[0]!} parentEl={nodeEl} reverse={true} />\n </Box>\n {innerNode}\n <Box ml={nodeIndent}>\n <TreeNode node={children[1]!} parentEl={nodeEl} reverse={false} />\n </Box>\n </div>\n );\n }\n\n return (\n <div>\n {innerNode}\n {children.map((child, idx) => (\n <Box ml={nodeIndent} key={idx}>\n <TreeNode node={child} parentEl={nodeEl} reverse={false} />\n </Box>\n ))}\n </div>\n );\n};\n\nexport default TreeNode;\n"],"names":["Box","useTheme","useCallback","useLayoutEffect","useState","nodeType","getNodeChildren","formatNode","nodeIndent","connectorWidth","TreeNode","node","parentEl","reverse","theme","children","nodeEl","setNodeEl","nodeRef","connectorStyle","setConnectorStyle","borderColor","palette","grey","borderLeftStyle","borderLeftWidth","width","left","undefined","parentRect","getBoundingClientRect","nodeRect","prevStyle","top","bottom","borderTopLeftRadius","borderTopStyle","borderBottomLeftRadius","borderBottomStyle","innerNode","ref","sx","position","display","padding","marginBottom","borderRadius","backgroundColor","background","code","type","binaryExpr","div","ml","map","child","idx"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './
|
|
1
|
+
export * from './PromQLEditor';
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAaA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAaA,cAAc,gBAAgB,CAAC"}
|
package/dist/components/index.js
CHANGED
|
@@ -10,6 +10,6 @@
|
|
|
10
10
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
|
-
export * from './
|
|
13
|
+
export * from './PromQLEditor';
|
|
14
14
|
|
|
15
15
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/index.ts"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nexport * from './
|
|
1
|
+
{"version":3,"sources":["../../src/components/index.ts"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nexport * from './PromQLEditor';\n"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,cAAc,iBAAiB"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { DatasourceSelector } from '@perses-dev/core';
|
|
2
|
+
import { ParseQueryResponse } from '../model';
|
|
3
|
+
export declare function useParseQuery(content: string, datasource: DatasourceSelector): import("@tanstack/react-query").UseQueryResult<ParseQueryResponse, unknown>;
|
|
4
|
+
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/components/parse.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,OAAO,EAA+B,kBAAkB,EAAoB,MAAM,UAAU,CAAC;AAE7F,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,kBAAkB,+EAY5E"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Copyright 2024 The Perses Authors
|
|
2
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
// you may not use this file except in compliance with the License.
|
|
4
|
+
// You may obtain a copy of the License at
|
|
5
|
+
//
|
|
6
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
//
|
|
8
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
// See the License for the specific language governing permissions and
|
|
12
|
+
// limitations under the License.
|
|
13
|
+
import { useDatasourceClient } from '@perses-dev/plugin-system';
|
|
14
|
+
import { useQuery } from '@tanstack/react-query';
|
|
15
|
+
export function useParseQuery(content, datasource) {
|
|
16
|
+
const { data: client } = useDatasourceClient(datasource);
|
|
17
|
+
return useQuery({
|
|
18
|
+
enabled: !!client,
|
|
19
|
+
queryKey: [
|
|
20
|
+
'parseQuery',
|
|
21
|
+
content,
|
|
22
|
+
'datasource',
|
|
23
|
+
datasource
|
|
24
|
+
],
|
|
25
|
+
queryFn: async ()=>{
|
|
26
|
+
const params = {
|
|
27
|
+
query: content
|
|
28
|
+
};
|
|
29
|
+
return await client.parseQuery(params);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/parse.ts"],"sourcesContent":["// Copyright 2024 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { useDatasourceClient } from '@perses-dev/plugin-system';\nimport { DatasourceSelector } from '@perses-dev/core';\nimport { useQuery } from '@tanstack/react-query';\nimport { ParseQueryRequestParameters, ParseQueryResponse, PrometheusClient } from '../model';\n\nexport function useParseQuery(content: string, datasource: DatasourceSelector) {\n const { data: client } = useDatasourceClient<PrometheusClient>(datasource);\n\n return useQuery<ParseQueryResponse>({\n enabled: !!client,\n queryKey: ['parseQuery', content, 'datasource', datasource],\n queryFn: async () => {\n const params: ParseQueryRequestParameters = { query: content };\n\n return await client!.parseQuery(params);\n },\n });\n}\n"],"names":["useDatasourceClient","useQuery","useParseQuery","content","datasource","data","client","enabled","queryKey","queryFn","params","query","parseQuery"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAASA,mBAAmB,QAAQ,4BAA4B;AAEhE,SAASC,QAAQ,QAAQ,wBAAwB;AAGjD,OAAO,SAASC,cAAcC,OAAe,EAAEC,UAA8B;IAC3E,MAAM,EAAEC,MAAMC,MAAM,EAAE,GAAGN,oBAAsCI;IAE/D,OAAOH,SAA6B;QAClCM,SAAS,CAAC,CAACD;QACXE,UAAU;YAAC;YAAcL;YAAS;YAAcC;SAAW;QAC3DK,SAAS;YACP,MAAMC,SAAsC;gBAAEC,OAAOR;YAAQ;YAE7D,OAAO,MAAMG,OAAQM,UAAU,CAACF;QAClC;IACF;AACF"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
export declare enum nodeType {
|
|
2
|
+
aggregation = "aggregation",
|
|
3
|
+
binaryExpr = "binaryExpr",
|
|
4
|
+
call = "call",
|
|
5
|
+
matrixSelector = "matrixSelector",
|
|
6
|
+
subquery = "subquery",
|
|
7
|
+
numberLiteral = "numberLiteral",
|
|
8
|
+
parenExpr = "parenExpr",
|
|
9
|
+
stringLiteral = "stringLiteral",
|
|
10
|
+
unaryExpr = "unaryExpr",
|
|
11
|
+
vectorSelector = "vectorSelector",
|
|
12
|
+
placeholder = "placeholder"
|
|
13
|
+
}
|
|
14
|
+
export declare enum aggregationType {
|
|
15
|
+
sum = "sum",
|
|
16
|
+
min = "min",
|
|
17
|
+
max = "max",
|
|
18
|
+
avg = "avg",
|
|
19
|
+
stddev = "stddev",
|
|
20
|
+
stdvar = "stdvar",
|
|
21
|
+
count = "count",
|
|
22
|
+
group = "group",
|
|
23
|
+
countValues = "count_values",
|
|
24
|
+
bottomk = "bottomk",
|
|
25
|
+
topk = "topk",
|
|
26
|
+
quantile = "quantile",
|
|
27
|
+
limitK = "limitk",
|
|
28
|
+
limitRatio = "limit_ratio"
|
|
29
|
+
}
|
|
30
|
+
export declare enum binaryOperatorType {
|
|
31
|
+
add = "+",
|
|
32
|
+
sub = "-",
|
|
33
|
+
mul = "*",
|
|
34
|
+
div = "/",
|
|
35
|
+
mod = "%",
|
|
36
|
+
pow = "^",
|
|
37
|
+
eql = "==",
|
|
38
|
+
neq = "!=",
|
|
39
|
+
gtr = ">",
|
|
40
|
+
lss = "<",
|
|
41
|
+
gte = ">=",
|
|
42
|
+
lte = "<=",
|
|
43
|
+
and = "and",
|
|
44
|
+
or = "or",
|
|
45
|
+
unless = "unless",
|
|
46
|
+
atan2 = "atan2"
|
|
47
|
+
}
|
|
48
|
+
export declare const compOperatorTypes: binaryOperatorType[];
|
|
49
|
+
export declare const setOperatorTypes: binaryOperatorType[];
|
|
50
|
+
export declare enum unaryOperatorType {
|
|
51
|
+
plus = "+",
|
|
52
|
+
minus = "-"
|
|
53
|
+
}
|
|
54
|
+
export declare enum vectorMatchCardinality {
|
|
55
|
+
oneToOne = "one-to-one",
|
|
56
|
+
manyToOne = "many-to-one",
|
|
57
|
+
oneToMany = "one-to-many",
|
|
58
|
+
manyToMany = "many-to-many"
|
|
59
|
+
}
|
|
60
|
+
export declare enum valueType {
|
|
61
|
+
none = "none",
|
|
62
|
+
vector = "vector",
|
|
63
|
+
scalar = "scalar",
|
|
64
|
+
matrix = "matrix",
|
|
65
|
+
string = "string"
|
|
66
|
+
}
|
|
67
|
+
export declare enum matchType {
|
|
68
|
+
equal = "=",
|
|
69
|
+
notEqual = "!=",
|
|
70
|
+
matchRegexp = "=~",
|
|
71
|
+
matchNotRegexp = "!~"
|
|
72
|
+
}
|
|
73
|
+
export interface Func {
|
|
74
|
+
name: string;
|
|
75
|
+
argTypes: valueType[];
|
|
76
|
+
variadic: number;
|
|
77
|
+
returnType: valueType;
|
|
78
|
+
}
|
|
79
|
+
export interface LabelMatcher {
|
|
80
|
+
type: matchType;
|
|
81
|
+
name: string;
|
|
82
|
+
value: string;
|
|
83
|
+
}
|
|
84
|
+
export interface VectorMatching {
|
|
85
|
+
card: vectorMatchCardinality;
|
|
86
|
+
labels: string[];
|
|
87
|
+
on: boolean;
|
|
88
|
+
include: string[];
|
|
89
|
+
}
|
|
90
|
+
export type StartOrEnd = 'start' | 'end' | null;
|
|
91
|
+
export interface Aggregation {
|
|
92
|
+
type: nodeType.aggregation;
|
|
93
|
+
expr: ASTNode;
|
|
94
|
+
op: aggregationType;
|
|
95
|
+
param: ASTNode | null;
|
|
96
|
+
grouping: string[];
|
|
97
|
+
without: boolean;
|
|
98
|
+
}
|
|
99
|
+
export interface BinaryExpr {
|
|
100
|
+
type: nodeType.binaryExpr;
|
|
101
|
+
op: binaryOperatorType;
|
|
102
|
+
lhs: ASTNode;
|
|
103
|
+
rhs: ASTNode;
|
|
104
|
+
matching: VectorMatching | null;
|
|
105
|
+
bool: boolean;
|
|
106
|
+
}
|
|
107
|
+
export interface Call {
|
|
108
|
+
type: nodeType.call;
|
|
109
|
+
func: Func;
|
|
110
|
+
args: ASTNode[];
|
|
111
|
+
}
|
|
112
|
+
export interface MatrixSelector {
|
|
113
|
+
type: nodeType.matrixSelector;
|
|
114
|
+
name: string;
|
|
115
|
+
matchers: LabelMatcher[];
|
|
116
|
+
range: number;
|
|
117
|
+
offset: number;
|
|
118
|
+
timestamp: number | null;
|
|
119
|
+
startOrEnd: StartOrEnd;
|
|
120
|
+
}
|
|
121
|
+
export interface Subquery {
|
|
122
|
+
type: nodeType.subquery;
|
|
123
|
+
expr: ASTNode;
|
|
124
|
+
range: number;
|
|
125
|
+
offset: number;
|
|
126
|
+
step: number;
|
|
127
|
+
timestamp: number | null;
|
|
128
|
+
startOrEnd: StartOrEnd;
|
|
129
|
+
}
|
|
130
|
+
export interface NumberLiteral {
|
|
131
|
+
type: nodeType.numberLiteral;
|
|
132
|
+
val: string;
|
|
133
|
+
}
|
|
134
|
+
export interface ParenExpr {
|
|
135
|
+
type: nodeType.parenExpr;
|
|
136
|
+
expr: ASTNode;
|
|
137
|
+
}
|
|
138
|
+
export interface StringLiteral {
|
|
139
|
+
type: nodeType.stringLiteral;
|
|
140
|
+
val: string;
|
|
141
|
+
}
|
|
142
|
+
export interface UnaryExpr {
|
|
143
|
+
type: nodeType.unaryExpr;
|
|
144
|
+
op: unaryOperatorType;
|
|
145
|
+
expr: ASTNode;
|
|
146
|
+
}
|
|
147
|
+
export interface VectorSelector {
|
|
148
|
+
type: nodeType.vectorSelector;
|
|
149
|
+
name: string;
|
|
150
|
+
matchers: LabelMatcher[];
|
|
151
|
+
offset: number;
|
|
152
|
+
timestamp: number | null;
|
|
153
|
+
startOrEnd: StartOrEnd;
|
|
154
|
+
}
|
|
155
|
+
export interface Placeholder {
|
|
156
|
+
type: nodeType.placeholder;
|
|
157
|
+
children: ASTNode[];
|
|
158
|
+
}
|
|
159
|
+
type ASTNode = Aggregation | BinaryExpr | Call | MatrixSelector | Subquery | NumberLiteral | ParenExpr | StringLiteral | UnaryExpr | VectorSelector | Placeholder;
|
|
160
|
+
export default ASTNode;
|
|
161
|
+
//# sourceMappingURL=ast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../../src/components/promql/ast.ts"],"names":[],"mappings":"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"}
|