@elastic/monaco-esql 3.1.16 → 3.1.17
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/README.md +1 -3
- package/lib/definitions.js +1 -0
- package/lib/monarch.js +43 -7
- package/lib/promql.d.ts +36 -0
- package/lib/promql.js +112 -0
- package/package.json +24 -17
package/README.md
CHANGED
|
@@ -19,9 +19,7 @@ monaco.languages.setMonarchTokensProvider("esql", monarchLanguage);
|
|
|
19
19
|
|
|
20
20
|
## Releasing
|
|
21
21
|
|
|
22
|
-
To release a new version add a `publish` label to the PR.
|
|
23
|
-
|
|
24
|
-
There is no need to bump the version manually, release-it does it automatically.
|
|
22
|
+
To release a new version, bump the `version` field in the `package.json` and add a `publish` label to the PR.
|
|
25
23
|
|
|
26
24
|
## License
|
|
27
25
|
|
package/lib/definitions.js
CHANGED
package/lib/monarch.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
11
|
exports.create = void 0;
|
|
12
|
+
const promql_1 = require("./promql");
|
|
12
13
|
const create = (deps = {}) => {
|
|
13
14
|
const { headerCommands = [], sourceCommands = [], processingCommands = [], options = [], literals = [], functions = [], delimiters = [], temporalUnits = [], } = deps;
|
|
14
15
|
const timeUnits = withLowercaseVariants(temporalUnits.flat()).sort((a, b) => a > b ? -1 : 1);
|
|
@@ -42,7 +43,30 @@ const create = (deps = {}) => {
|
|
|
42
43
|
{ open: "<", close: ">", token: "delimiter.angle" },
|
|
43
44
|
],
|
|
44
45
|
tokenizer: {
|
|
45
|
-
root: [
|
|
46
|
+
root: [{ include: "@firstCommandName" }, { include: "@restOfQuery" }],
|
|
47
|
+
// This block matches the first command name in the query, and identifies it as a source command.
|
|
48
|
+
// Except if it's a header command.
|
|
49
|
+
// This is useful to color querys that starts with "From" instead of "FROM".
|
|
50
|
+
firstCommandName: [
|
|
51
|
+
{ include: "@whitespace" },
|
|
52
|
+
[
|
|
53
|
+
/[a-zA-Z]+/,
|
|
54
|
+
{
|
|
55
|
+
cases: {
|
|
56
|
+
"PROMQL|promql": {
|
|
57
|
+
token: "keyword.command.source.promql",
|
|
58
|
+
switchTo: "@promQLCommand",
|
|
59
|
+
},
|
|
60
|
+
"@headerCommands": { token: "keyword.command.header.$0" },
|
|
61
|
+
"@default": {
|
|
62
|
+
token: "keyword.command.source.$0",
|
|
63
|
+
switchTo: "@restOfQuery",
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
],
|
|
69
|
+
restOfQuery: [
|
|
46
70
|
{ include: "@whitespace" },
|
|
47
71
|
// Keywords
|
|
48
72
|
[
|
|
@@ -64,6 +88,9 @@ const create = (deps = {}) => {
|
|
|
64
88
|
},
|
|
65
89
|
],
|
|
66
90
|
{ include: "@expression" },
|
|
91
|
+
// If we found a semicolon, means a header command finished.
|
|
92
|
+
// We go back to root to parse the query.
|
|
93
|
+
[/;/, { token: "delimiter", switchTo: "@root" }],
|
|
67
94
|
{ include: "@processingCommand" },
|
|
68
95
|
[/\[|\(|\)|\]/, "@brackets"],
|
|
69
96
|
[
|
|
@@ -115,25 +142,32 @@ const create = (deps = {}) => {
|
|
|
115
142
|
["", { token: "", switchTo: "@commandName" }],
|
|
116
143
|
],
|
|
117
144
|
exactCommandName: [
|
|
145
|
+
[
|
|
146
|
+
"PROMQL|promql",
|
|
147
|
+
{
|
|
148
|
+
token: "keyword.command.source.promql",
|
|
149
|
+
switchTo: "@promQLCommand",
|
|
150
|
+
},
|
|
151
|
+
],
|
|
118
152
|
[
|
|
119
153
|
withLowercaseVariants(headerCommands).join("|"),
|
|
120
|
-
{ token: "keyword.command.header.$0", switchTo: "@
|
|
154
|
+
{ token: "keyword.command.header.$0", switchTo: "@restOfQuery" },
|
|
121
155
|
],
|
|
122
156
|
[
|
|
123
157
|
withLowercaseVariants(sourceCommands).join("|"),
|
|
124
|
-
{ token: "keyword.command.source.$0", switchTo: "@
|
|
158
|
+
{ token: "keyword.command.source.$0", switchTo: "@restOfQuery" },
|
|
125
159
|
],
|
|
126
160
|
[
|
|
127
161
|
withLowercaseVariants(processingCommands).join("|"),
|
|
128
|
-
{ token: "keyword.command.processing.$0", switchTo: "@
|
|
162
|
+
{ token: "keyword.command.processing.$0", switchTo: "@restOfQuery" },
|
|
129
163
|
],
|
|
130
164
|
],
|
|
131
165
|
firstCommandNameInSubQuery: [
|
|
132
166
|
{ include: "@whitespace" },
|
|
133
167
|
// Try to match an exact command name
|
|
134
168
|
{ include: "@exactCommandName" },
|
|
135
|
-
// If not matched, go to
|
|
136
|
-
{ include: "@
|
|
169
|
+
// If not matched, go to restOfQuery
|
|
170
|
+
{ include: "@restOfQuery" },
|
|
137
171
|
],
|
|
138
172
|
// Matches *command name*, i.e. the mnemonic.
|
|
139
173
|
commandName: [
|
|
@@ -142,7 +176,7 @@ const create = (deps = {}) => {
|
|
|
142
176
|
// If command name is not well known, just matches the first word.
|
|
143
177
|
[
|
|
144
178
|
/\w+\b/,
|
|
145
|
-
{ token: "keyword.command.processing.$0", switchTo: "@
|
|
179
|
+
{ token: "keyword.command.processing.$0", switchTo: "@restOfQuery" },
|
|
146
180
|
],
|
|
147
181
|
],
|
|
148
182
|
// ------------------------------------------------------------- Expressions
|
|
@@ -208,6 +242,8 @@ const create = (deps = {}) => {
|
|
|
208
242
|
[/\\./, "string.escape.invalid"],
|
|
209
243
|
[/`/, "string", "@pop"],
|
|
210
244
|
],
|
|
245
|
+
// ------------------------------------------------------------- PROMQL
|
|
246
|
+
...promql_1.promQLStates,
|
|
211
247
|
},
|
|
212
248
|
};
|
|
213
249
|
};
|
package/lib/promql.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { languages } from "monaco-editor";
|
|
2
|
+
/**
|
|
3
|
+
* In order to handle the PROMQL command we need to solve two problems:
|
|
4
|
+
* 1. Detect when the params section ends and the query starts, so we can apply the promql query embedding.
|
|
5
|
+
* For this we tokenize the params section with dedicated states, before delegating to the promql query embedding.
|
|
6
|
+
*
|
|
7
|
+
* 2. We need to correctly tokenize ES|QL comments syntax within a promql query.
|
|
8
|
+
* For this we use the promQLQuery state, which is applied while tokenizing the query content.
|
|
9
|
+
* It will tell the embedded language when the query ends (when a pipe is found).
|
|
10
|
+
* And will switch to dedicated states for handling comments.
|
|
11
|
+
*/
|
|
12
|
+
/** Main state for PROMQL command. */
|
|
13
|
+
export declare const promQLCommand: languages.IMonarchLanguageRule[];
|
|
14
|
+
/**
|
|
15
|
+
* State to tokenize param name, then switch to value
|
|
16
|
+
*/
|
|
17
|
+
export declare const promqlParam: languages.IMonarchLanguageRule[];
|
|
18
|
+
/**
|
|
19
|
+
* State to parse param values.
|
|
20
|
+
* The way of detecting a param value ended is by detecting whitespaces that are not followed by a comma.
|
|
21
|
+
* Example of a value that contains a list of indexes: index-*, `index`, index::selector, ?param, "index"
|
|
22
|
+
*/
|
|
23
|
+
export declare const promqlParamValue: languages.IMonarchLanguageRule[];
|
|
24
|
+
/**
|
|
25
|
+
* These rules are applied while tokenizing the query content (inside the embedding language).
|
|
26
|
+
* They run "in parallel" with the rules from the embedded language.
|
|
27
|
+
* We use them the tell the embedded language when the query ends (when a pipe is found).
|
|
28
|
+
* And to be able to tokenize ES|QL comments within the PROMQL query.
|
|
29
|
+
*/
|
|
30
|
+
export declare const promQLQuery: languages.IMonarchLanguageRule[];
|
|
31
|
+
/**
|
|
32
|
+
* All PromQL tokenizer states needed to tokenize a PROMQL command bundled in one object.
|
|
33
|
+
*/
|
|
34
|
+
export declare const promQLStates: {
|
|
35
|
+
[name: string]: languages.IMonarchLanguageRule[];
|
|
36
|
+
};
|
package/lib/promql.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.promQLStates = exports.promQLQuery = exports.promqlParamValue = exports.promqlParam = exports.promQLCommand = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* In order to handle the PROMQL command we need to solve two problems:
|
|
6
|
+
* 1. Detect when the params section ends and the query starts, so we can apply the promql query embedding.
|
|
7
|
+
* For this we tokenize the params section with dedicated states, before delegating to the promql query embedding.
|
|
8
|
+
*
|
|
9
|
+
* 2. We need to correctly tokenize ES|QL comments syntax within a promql query.
|
|
10
|
+
* For this we use the promQLQuery state, which is applied while tokenizing the query content.
|
|
11
|
+
* It will tell the embedded language when the query ends (when a pipe is found).
|
|
12
|
+
* And will switch to dedicated states for handling comments.
|
|
13
|
+
*/
|
|
14
|
+
/** Main state for PROMQL command. */
|
|
15
|
+
exports.promQLCommand = [
|
|
16
|
+
{ include: "@whitespace" },
|
|
17
|
+
// Match param pattern: paramName = ...
|
|
18
|
+
[/[a-zA-Z0-9_*?"`-]+\s*=\s*/, { token: "@rematch", next: "@promqlParam" }],
|
|
19
|
+
// Start PromQL query embedding (no more params)
|
|
20
|
+
[
|
|
21
|
+
/.+/,
|
|
22
|
+
{ token: "@rematch", switchTo: "@promQLQuery", nextEmbedded: "promql" },
|
|
23
|
+
],
|
|
24
|
+
];
|
|
25
|
+
/**
|
|
26
|
+
* State to tokenize param name, then switch to value
|
|
27
|
+
*/
|
|
28
|
+
exports.promqlParam = [
|
|
29
|
+
// Match param name
|
|
30
|
+
{ include: "@expression" },
|
|
31
|
+
// Tokenize assignment and go to value
|
|
32
|
+
[/=\s*/, { token: "delimiter.assignment", switchTo: "@promqlParamValue" }],
|
|
33
|
+
];
|
|
34
|
+
/**
|
|
35
|
+
* State to parse param values.
|
|
36
|
+
* The way of detecting a param value ended is by detecting whitespaces that are not followed by a comma.
|
|
37
|
+
* Example of a value that contains a list of indexes: index-*, `index`, index::selector, ?param, "index"
|
|
38
|
+
*/
|
|
39
|
+
exports.promqlParamValue = [
|
|
40
|
+
// Whitespace handling: comma continues list, otherwise pop
|
|
41
|
+
[/\s+(?=,)/, ""], // Whitespace before comma - continue
|
|
42
|
+
[/\s+/, { token: "", next: "@pop" }], // Whitespace not before comma - pop (query or next param)
|
|
43
|
+
// Match value content
|
|
44
|
+
{ include: "@expression" },
|
|
45
|
+
// Comma continues the list
|
|
46
|
+
[/,\s*/, "delimiter.comma"],
|
|
47
|
+
// Fallback: pop if nothing else matches
|
|
48
|
+
["", { token: "", next: "@pop" }],
|
|
49
|
+
];
|
|
50
|
+
/**
|
|
51
|
+
* These rules are applied while tokenizing the query content (inside the embedding language).
|
|
52
|
+
* They run "in parallel" with the rules from the embedded language.
|
|
53
|
+
* We use them the tell the embedded language when the query ends (when a pipe is found).
|
|
54
|
+
* And to be able to tokenize ES|QL comments within the PROMQL query.
|
|
55
|
+
*/
|
|
56
|
+
exports.promQLQuery = [
|
|
57
|
+
// Rules to delegate comments to ES|QL
|
|
58
|
+
[
|
|
59
|
+
/\/\*\*(?!\/)/,
|
|
60
|
+
{
|
|
61
|
+
token: "comment.doc",
|
|
62
|
+
next: "@promqlDocComment",
|
|
63
|
+
nextEmbedded: "@pop",
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
[/\/\*/, { token: "comment", next: "@promqlComment", nextEmbedded: "@pop" }],
|
|
67
|
+
[
|
|
68
|
+
/\/\//,
|
|
69
|
+
{
|
|
70
|
+
token: "comment",
|
|
71
|
+
next: "@promqlLineComment",
|
|
72
|
+
nextEmbedded: "@pop",
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
// Exit condition
|
|
76
|
+
[
|
|
77
|
+
/\|/,
|
|
78
|
+
{
|
|
79
|
+
token: "delimiter.pipe",
|
|
80
|
+
switchTo: "@beforeMnemonicWhitespace",
|
|
81
|
+
nextEmbedded: "@pop",
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
];
|
|
85
|
+
/**
|
|
86
|
+
* These states are used for returning the control the promql embedding after a comment ends.
|
|
87
|
+
*/
|
|
88
|
+
const promQLQueryOverrideRules = {
|
|
89
|
+
promqlDocComment: [
|
|
90
|
+
[/[^/*]+/, "comment.doc"],
|
|
91
|
+
[/\*\//, { token: "comment.doc", next: "@pop", nextEmbedded: "promql" }],
|
|
92
|
+
[/[/*]/, "comment.doc"],
|
|
93
|
+
],
|
|
94
|
+
promqlComment: [
|
|
95
|
+
[/[^/*]+/, "comment"],
|
|
96
|
+
[/\*\//, { token: "comment", next: "@pop", nextEmbedded: "promql" }],
|
|
97
|
+
[/[/*]/, "comment"],
|
|
98
|
+
],
|
|
99
|
+
promqlLineComment: [
|
|
100
|
+
[/.*$/, { token: "comment", next: "@pop", nextEmbedded: "promql" }],
|
|
101
|
+
],
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* All PromQL tokenizer states needed to tokenize a PROMQL command bundled in one object.
|
|
105
|
+
*/
|
|
106
|
+
exports.promQLStates = {
|
|
107
|
+
promQLCommand: exports.promQLCommand,
|
|
108
|
+
promqlParam: exports.promqlParam,
|
|
109
|
+
promqlParamValue: exports.promqlParamValue,
|
|
110
|
+
promQLQuery: exports.promQLQuery,
|
|
111
|
+
...promQLQueryOverrideRules,
|
|
112
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elastic/monaco-esql",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.17",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"build": "yarn build:es2020",
|
|
25
25
|
"storybook": "storybook dev -p 6006",
|
|
26
26
|
"build-storybook": "storybook build",
|
|
27
|
-
"release": "npx release-it --ci",
|
|
27
|
+
"release": "npx release-it --ci --no-increment",
|
|
28
28
|
"prepare": "husky"
|
|
29
29
|
},
|
|
30
30
|
"license": "MIT",
|
|
@@ -49,35 +49,42 @@
|
|
|
49
49
|
},
|
|
50
50
|
"homepage": "https://github.com/elastic/monaco-esql",
|
|
51
51
|
"peerDependencies": {
|
|
52
|
-
"monaco-editor": "*"
|
|
52
|
+
"monaco-editor": "*",
|
|
53
|
+
"monaco-promql": "*"
|
|
54
|
+
},
|
|
55
|
+
"peerDependenciesMeta": {
|
|
56
|
+
"monaco-promql": {
|
|
57
|
+
"optional": true
|
|
58
|
+
}
|
|
53
59
|
},
|
|
54
60
|
"devDependencies": {
|
|
55
|
-
"@babel/eslint-parser": "7.28.
|
|
61
|
+
"@babel/eslint-parser": "7.28.6",
|
|
56
62
|
"@biomejs/biome": "2.3.11",
|
|
57
|
-
"@chromatic-com/storybook": "
|
|
63
|
+
"@chromatic-com/storybook": "5.0.0",
|
|
58
64
|
"@eslint/js": "9.39.2",
|
|
59
65
|
"@monaco-editor/react": "4.7.0",
|
|
60
|
-
"@storybook/addon-docs": "10.
|
|
61
|
-
"@storybook/addon-onboarding": "10.
|
|
62
|
-
"@storybook/addon-vitest": "10.
|
|
63
|
-
"@storybook/react-vite": "10.
|
|
64
|
-
"@types/react": "19.2.
|
|
65
|
-
"@vitest/browser": "4.0.
|
|
66
|
-
"@vitest/browser-playwright": "4.0.
|
|
67
|
-
"@vitest/coverage-v8": "4.0.
|
|
66
|
+
"@storybook/addon-docs": "10.2.6",
|
|
67
|
+
"@storybook/addon-onboarding": "10.2.6",
|
|
68
|
+
"@storybook/addon-vitest": "10.2.6",
|
|
69
|
+
"@storybook/react-vite": "10.2.6",
|
|
70
|
+
"@types/react": "19.2.9",
|
|
71
|
+
"@vitest/browser": "4.0.18",
|
|
72
|
+
"@vitest/browser-playwright": "4.0.18",
|
|
73
|
+
"@vitest/coverage-v8": "4.0.18",
|
|
68
74
|
"eslint": "9.39.2",
|
|
69
75
|
"eslint-plugin-react": "7.37.5",
|
|
70
|
-
"globals": "17.
|
|
76
|
+
"globals": "17.3.0",
|
|
71
77
|
"husky": "9.1.7",
|
|
72
78
|
"lint-staged": "16.2.7",
|
|
73
79
|
"monaco-editor": "0.55.1",
|
|
80
|
+
"monaco-promql": "1.8.0",
|
|
74
81
|
"playwright": "1.57.0",
|
|
75
82
|
"react": "19.2.3",
|
|
76
83
|
"react-dom": "19.2.3",
|
|
77
|
-
"storybook": "10.
|
|
84
|
+
"storybook": "10.2.6",
|
|
78
85
|
"typescript": "5.9.3",
|
|
79
|
-
"typescript-eslint": "8.
|
|
80
|
-
"vitest": "4.0.
|
|
86
|
+
"typescript-eslint": "8.54.0",
|
|
87
|
+
"vitest": "4.0.18"
|
|
81
88
|
},
|
|
82
89
|
"lint-staged": {
|
|
83
90
|
"*.{js,ts,tsx,mjs}": [
|