@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.
@@ -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: 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;