@fc-components/monaco-editor 0.1.26 → 0.2.1
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/monaco-editor.cjs.development.js +87 -21
- package/dist/monaco-editor.cjs.development.js.map +1 -1
- package/dist/monaco-editor.cjs.production.min.js +1 -1
- package/dist/monaco-editor.cjs.production.min.js.map +1 -1
- package/dist/monaco-editor.esm.js +88 -22
- package/dist/monaco-editor.esm.js.map +1 -1
- package/dist/promql/completion/situation.d.ts +3 -0
- package/dist/promql/index.d.ts +0 -1
- package/package.json +2 -2
- package/src/promql/__tests__/completions.test.ts +72 -0
- package/src/promql/__tests__/situation.test.ts +85 -0
- package/src/promql/completion/completions.ts +11 -2
- package/src/promql/completion/getCompletionProvider.ts +15 -1
- package/src/promql/completion/situation.ts +73 -1
- package/src/promql/index.tsx +0 -18
- package/src/promql/promql.ts +3 -1
|
@@ -346,6 +346,7 @@ for (var _i = 0, aggregations_1 = aggregations; _i < aggregations_1.length; _i++
|
|
|
346
346
|
// PromQL vector matching + the by and without clauses
|
|
347
347
|
// (https://prometheus.io/docs/prometheus/latest/querying/operators/#vector-matching)
|
|
348
348
|
var vectorMatching = ['on', 'ignoring', 'group_right', 'group_left', 'by', 'without'];
|
|
349
|
+
var cteKeywords = ['with'];
|
|
349
350
|
// Produce a regex matching elements : (elt1|elt2|...)
|
|
350
351
|
var vectorMatchingRegex = '(' + /*#__PURE__*/vectorMatching.reduce(function (prev, curr) {
|
|
351
352
|
return prev + '|' + curr;
|
|
@@ -357,7 +358,7 @@ var operators = ['+', '-', '*', '/', '%', '^', '==', '!=', '>', '<', '>=', '<=',
|
|
|
357
358
|
// (https://prometheus.io/docs/prometheus/latest/querying/basics/#offset-modifier)
|
|
358
359
|
var offsetModifier = ['offset'];
|
|
359
360
|
// Merging all the keywords in one list
|
|
360
|
-
var keywords = /*#__PURE__*/aggregations.concat(functions).concat(aggregationsOverTime).concat(vectorMatching).concat(offsetModifier);
|
|
361
|
+
var keywords = /*#__PURE__*/aggregations.concat(functions).concat(aggregationsOverTime).concat(vectorMatching).concat(offsetModifier).concat(cteKeywords);
|
|
361
362
|
// noinspection JSUnusedGlobalSymbols
|
|
362
363
|
var language = {
|
|
363
364
|
ignoreCase: false,
|
|
@@ -1295,6 +1296,15 @@ var RESOLVERS = [{
|
|
|
1295
1296
|
}, {
|
|
1296
1297
|
path: [lezerMetricsql.GroupingLabels],
|
|
1297
1298
|
fun: resolveLabelsForGrouping
|
|
1299
|
+
}, {
|
|
1300
|
+
path: [lezerMetricsql.WithExpr],
|
|
1301
|
+
fun: resolveWithExpr
|
|
1302
|
+
}, {
|
|
1303
|
+
path: [lezerMetricsql.WithExpr, lezerMetricsql.PromQL],
|
|
1304
|
+
fun: resolveWithExpr
|
|
1305
|
+
}, {
|
|
1306
|
+
path: [lezerMetricsql.WithAssignment, lezerMetricsql.WithExpr],
|
|
1307
|
+
fun: resolveWithExpr
|
|
1298
1308
|
}];
|
|
1299
1309
|
var LABEL_OP_MAP = /*#__PURE__*/new Map([[lezerMetricsql.EqlSingle, '='], [lezerMetricsql.EqlRegex, '=~'], [lezerMetricsql.Neq, '!='], [lezerMetricsql.NeqRegex, '!~']]);
|
|
1300
1310
|
function getLabelOp(opNode) {
|
|
@@ -1392,6 +1402,10 @@ function resolveLabelMatcher(node, text, _pos) {
|
|
|
1392
1402
|
// - a StringNode (like in `{job="^"}`)
|
|
1393
1403
|
// - or an error node (like in `{job=^}`)
|
|
1394
1404
|
var inStringNode = !node.type.isError;
|
|
1405
|
+
// calculate where the value starts
|
|
1406
|
+
// for string nodes, it's after the opening quote
|
|
1407
|
+
// for error nodes, it's at the node start
|
|
1408
|
+
var valueStartPos = inStringNode ? node.from + 1 : node.from;
|
|
1395
1409
|
var parent = walk(node, [['parent', lezerMetricsql.UnquotedLabelMatcher]]);
|
|
1396
1410
|
if (parent === null) {
|
|
1397
1411
|
return null;
|
|
@@ -1418,7 +1432,8 @@ function resolveLabelMatcher(node, text, _pos) {
|
|
|
1418
1432
|
type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',
|
|
1419
1433
|
labelName: labelName,
|
|
1420
1434
|
betweenQuotes: inStringNode,
|
|
1421
|
-
otherLabels: otherLabels
|
|
1435
|
+
otherLabels: otherLabels,
|
|
1436
|
+
valueStartPos: valueStartPos
|
|
1422
1437
|
};
|
|
1423
1438
|
}
|
|
1424
1439
|
var metricName = getNodeText(metricNameNode, text);
|
|
@@ -1427,7 +1442,8 @@ function resolveLabelMatcher(node, text, _pos) {
|
|
|
1427
1442
|
metricName: metricName,
|
|
1428
1443
|
labelName: labelName,
|
|
1429
1444
|
betweenQuotes: inStringNode,
|
|
1430
|
-
otherLabels: otherLabels
|
|
1445
|
+
otherLabels: otherLabels,
|
|
1446
|
+
valueStartPos: valueStartPos
|
|
1431
1447
|
};
|
|
1432
1448
|
}
|
|
1433
1449
|
function resolveErrorInLabelMatcher(node, text, pos) {
|
|
@@ -1461,6 +1477,25 @@ function resolveInFunction() {
|
|
|
1461
1477
|
type: 'IN_FUNCTION'
|
|
1462
1478
|
};
|
|
1463
1479
|
}
|
|
1480
|
+
function resolveWithExpr(node, text, pos) {
|
|
1481
|
+
// Find the containing WithExpr node (node may be a WithAssignment child)
|
|
1482
|
+
var withExprNode = node.type.id === lezerMetricsql.WithExpr ? node : node.parent;
|
|
1483
|
+
while (withExprNode && withExprNode.type.id !== lezerMetricsql.WithExpr) {
|
|
1484
|
+
withExprNode = withExprNode.parent;
|
|
1485
|
+
}
|
|
1486
|
+
if (!withExprNode) return null;
|
|
1487
|
+
// Only return IN_WITH_BODY when cursor is in the body expression (after the closing ')')
|
|
1488
|
+
var children = getNodeChildren(withExprNode);
|
|
1489
|
+
var closeParen = children.find(function (c) {
|
|
1490
|
+
return getNodeText(c, text) === ')';
|
|
1491
|
+
});
|
|
1492
|
+
if (closeParen && pos > closeParen.to) {
|
|
1493
|
+
return {
|
|
1494
|
+
type: 'IN_WITH_BODY'
|
|
1495
|
+
};
|
|
1496
|
+
}
|
|
1497
|
+
return null;
|
|
1498
|
+
}
|
|
1464
1499
|
function resolveDurations() {
|
|
1465
1500
|
return {
|
|
1466
1501
|
type: 'IN_DURATION'
|
|
@@ -1570,6 +1605,25 @@ function getErrorNode(tree, pos) {
|
|
|
1570
1605
|
}
|
|
1571
1606
|
return null;
|
|
1572
1607
|
}
|
|
1608
|
+
function findMatchingParen(text, openPos) {
|
|
1609
|
+
var depth = 0;
|
|
1610
|
+
for (var i = openPos; i < text.length; i++) {
|
|
1611
|
+
if (text[i] === '(') depth++;
|
|
1612
|
+
if (text[i] === ')') {
|
|
1613
|
+
depth--;
|
|
1614
|
+
if (depth === 0) return i;
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
return -1;
|
|
1618
|
+
}
|
|
1619
|
+
function isInWithBody(text, pos) {
|
|
1620
|
+
var withMatch = text.match(/^with\s*\(/i);
|
|
1621
|
+
if (!withMatch) return false;
|
|
1622
|
+
var openParenPos = withMatch[0].length - 1;
|
|
1623
|
+
var closeParenPos = findMatchingParen(text, openParenPos);
|
|
1624
|
+
if (closeParenPos === -1) return false;
|
|
1625
|
+
return pos > closeParenPos;
|
|
1626
|
+
}
|
|
1573
1627
|
function getSituation(text, pos) {
|
|
1574
1628
|
// there is a special-case when we are at the start of writing text,
|
|
1575
1629
|
// so we handle that case first
|
|
@@ -1578,6 +1632,12 @@ function getSituation(text, pos) {
|
|
|
1578
1632
|
type: 'EMPTY'
|
|
1579
1633
|
};
|
|
1580
1634
|
}
|
|
1635
|
+
// text-based check for with body (fallback until grammar supports WithExpr)
|
|
1636
|
+
if (isInWithBody(text, pos)) {
|
|
1637
|
+
return {
|
|
1638
|
+
type: 'IN_WITH_BODY'
|
|
1639
|
+
};
|
|
1640
|
+
}
|
|
1581
1641
|
/**
|
|
1582
1642
|
PromQL
|
|
1583
1643
|
Expr
|
|
@@ -1660,12 +1720,19 @@ function _getAllFunctionsAndMetricNamesCompletions() {
|
|
|
1660
1720
|
while (1) switch (_context.n) {
|
|
1661
1721
|
case 0:
|
|
1662
1722
|
metricNames = getAllMetricNamesCompletions(dataProvider);
|
|
1663
|
-
return _context.a(2, [].concat(FUNCTION_COMPLETIONS, metricNames));
|
|
1723
|
+
return _context.a(2, [CTE_KEYWORD_COMPLETION].concat(FUNCTION_COMPLETIONS, metricNames));
|
|
1664
1724
|
}
|
|
1665
1725
|
}, _callee);
|
|
1666
1726
|
}));
|
|
1667
1727
|
return _getAllFunctionsAndMetricNamesCompletions.apply(this, arguments);
|
|
1668
1728
|
}
|
|
1729
|
+
var CTE_KEYWORD_COMPLETION = {
|
|
1730
|
+
type: 'FUNCTION',
|
|
1731
|
+
label: 'with',
|
|
1732
|
+
insertText: 'with (',
|
|
1733
|
+
detail: 'with (cte_name = expr, ...) expr',
|
|
1734
|
+
documentation: 'Define Common Table Expressions (CTEs) for use in the query. MetricsQL extension.'
|
|
1735
|
+
};
|
|
1669
1736
|
var DURATION_COMPLETIONS = /*#__PURE__*/['1m', '5m', '10m', '30m', '1h', '1d'].map(function (text) {
|
|
1670
1737
|
return {
|
|
1671
1738
|
type: 'DURATION',
|
|
@@ -1907,6 +1974,7 @@ function getCompletions(situation, dataProvider) {
|
|
|
1907
1974
|
return Promise.resolve(DURATION_COMPLETIONS);
|
|
1908
1975
|
case 'IN_FUNCTION':
|
|
1909
1976
|
return getAllFunctionsAndMetricNamesCompletions(dataProvider);
|
|
1977
|
+
case 'IN_WITH_BODY':
|
|
1910
1978
|
case 'AT_ROOT':
|
|
1911
1979
|
{
|
|
1912
1980
|
return getAllFunctionsAndMetricNamesCompletions(dataProvider);
|
|
@@ -1915,7 +1983,7 @@ function getCompletions(situation, dataProvider) {
|
|
|
1915
1983
|
{
|
|
1916
1984
|
var metricNames = getAllMetricNamesCompletions(dataProvider);
|
|
1917
1985
|
var historyCompletions = getAllHistoryCompletions();
|
|
1918
|
-
return Promise.resolve([].concat(historyCompletions, FUNCTION_COMPLETIONS, metricNames));
|
|
1986
|
+
return Promise.resolve([].concat(historyCompletions, [CTE_KEYWORD_COMPLETION], FUNCTION_COMPLETIONS, metricNames));
|
|
1919
1987
|
}
|
|
1920
1988
|
case 'IN_LABEL_SELECTOR_NO_LABEL_NAME':
|
|
1921
1989
|
return getLabelNamesForSelectorCompletions(situation.metricName, situation.hasOperator, situation.otherLabels, dataProvider);
|
|
@@ -1979,6 +2047,18 @@ function getCompletionProvider(monaco, dataProvider) {
|
|
|
1979
2047
|
// to stop it, we use a number-as-string sortkey,
|
|
1980
2048
|
// so that monaco keeps the order we use
|
|
1981
2049
|
var maxIndexDigits = items.length.toString().length;
|
|
2050
|
+
// Determine the completion range based on situation type
|
|
2051
|
+
var completionRange = range;
|
|
2052
|
+
if (situation && situation.type === 'IN_LABEL_SELECTOR_WITH_LABEL_NAME' && situation.betweenQuotes) {
|
|
2053
|
+
// For label values within quotes, replace from the start of the value to the current position
|
|
2054
|
+
var valueStartPosition = model.getPositionAt(situation.valueStartPos);
|
|
2055
|
+
completionRange = monaco.Range.lift({
|
|
2056
|
+
startLineNumber: valueStartPosition.lineNumber,
|
|
2057
|
+
endLineNumber: position.lineNumber,
|
|
2058
|
+
startColumn: valueStartPosition.column,
|
|
2059
|
+
endColumn: position.column
|
|
2060
|
+
});
|
|
2061
|
+
}
|
|
1982
2062
|
var suggestions = items.map(function (item, index) {
|
|
1983
2063
|
return {
|
|
1984
2064
|
kind: getMonacoCompletionItemKind(item.type, monaco),
|
|
@@ -1987,7 +2067,7 @@ function getCompletionProvider(monaco, dataProvider) {
|
|
|
1987
2067
|
detail: item.detail,
|
|
1988
2068
|
documentation: item.documentation,
|
|
1989
2069
|
sortText: index.toString().padStart(maxIndexDigits, '0'),
|
|
1990
|
-
range:
|
|
2070
|
+
range: completionRange,
|
|
1991
2071
|
command: item.triggerOnInsert ? {
|
|
1992
2072
|
id: 'editor.action.triggerSuggest',
|
|
1993
2073
|
title: ''
|
|
@@ -2136,9 +2216,7 @@ function PromQLEditor(props) {
|
|
|
2136
2216
|
onChange = props.onChange,
|
|
2137
2217
|
onEnter = props.onEnter,
|
|
2138
2218
|
onBlur = props.onBlur,
|
|
2139
|
-
editorDidMount = props.editorDidMount
|
|
2140
|
-
_props$debugEscKey = props.debugEscKey,
|
|
2141
|
-
debugEscKey = _props$debugEscKey === void 0 ? false : _props$debugEscKey;
|
|
2219
|
+
editorDidMount = props.editorDidMount;
|
|
2142
2220
|
var autocompleteDisposeFun = React.useRef(null);
|
|
2143
2221
|
var containerRef = React.useRef(null);
|
|
2144
2222
|
var dataProviderRef = React.useRef(null);
|
|
@@ -2228,18 +2306,6 @@ function PromQLEditor(props) {
|
|
|
2228
2306
|
editor.addCommand(monaco.KeyCode.Enter, function () {
|
|
2229
2307
|
onEnter == null || onEnter(editor.getValue());
|
|
2230
2308
|
}, '!suggestWidgetVisible && isEditorFocused' + id);
|
|
2231
|
-
editor.addCommand(monaco.KeyCode.Escape, function () {
|
|
2232
|
-
if (debugEscKey) {
|
|
2233
|
-
var _editor$_contextKeySe;
|
|
2234
|
-
var suggestWidgetVisible = editor == null || (_editor$_contextKeySe = editor._contextKeyService) == null || _editor$_contextKeySe.getContextKeyValue == null ? void 0 : _editor$_contextKeySe.getContextKeyValue('suggestWidgetVisible');
|
|
2235
|
-
// eslint-disable-next-line no-console
|
|
2236
|
-
console.log('[PromQLEditor][ESC]', {
|
|
2237
|
-
suggestWidgetVisible: suggestWidgetVisible,
|
|
2238
|
-
valueLength: editor.getValue().length
|
|
2239
|
-
});
|
|
2240
|
-
}
|
|
2241
|
-
editor.trigger('keyboard', 'hideSuggestWidget', {});
|
|
2242
|
-
}, 'suggestWidgetVisible && isEditorFocused' + id);
|
|
2243
2309
|
// Initialize previous content tracking
|
|
2244
2310
|
previousContentRef.current = editor.getValue();
|
|
2245
2311
|
lastDeletionTriggerTimeRef.current = 0;
|