{"version":3,"file":"prom-query-field.ff217c474ea457bdd65e.js","mappings":"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","sources":["webpack://grafana/./public/app/plugins/datasource/loki/components/monaco-query-field/monaco-completion-provider/validation.ts","webpack://grafana/./public/app/plugins/datasource/loki/querybuilder/parsingUtils.ts","webpack://grafana/./node_modules/monaco-promql/promql/promql.contribution.js","webpack://grafana/./public/app/plugins/datasource/prometheus/components/monaco-query-field/getOverrideServices.ts","webpack://grafana/./public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/util.ts","webpack://grafana/./public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/completions.ts","webpack://grafana/./public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/situation.ts","webpack://grafana/./public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/index.ts","webpack://grafana/./public/app/plugins/datasource/prometheus/components/monaco-query-field/MonacoQueryField.tsx","webpack://grafana/./node_modules/react-use/esm/useLatest.js"],"sourcesContent":["import { SyntaxNode } from '@lezer/common';\nimport { LRParser } from '@lezer/lr';\n\nimport { ErrorId } from '../../../querybuilder/parsingUtils';\n\ninterface ParserErrorBoundary {\n startLineNumber: number;\n startColumn: number;\n endLineNumber: number;\n endColumn: number;\n error: string;\n}\n\ninterface ParseError {\n text: string;\n node: SyntaxNode;\n}\n\n/**\n * Conceived to work in combination with the MonacoQueryField component.\n * Given an original query, and it's interpolated version, it will return an array of ParserErrorBoundary\n * objects containing nodes which are actual errors. The interpolated version (even with placeholder variables)\n * is required because variables look like errors for Lezer.\n * @internal\n */\nexport function validateQuery(\n query: string,\n interpolatedQuery: string,\n queryLines: string[],\n parser: LRParser\n): ParserErrorBoundary[] | false {\n if (!query) {\n return false;\n }\n\n /**\n * To provide support to variable interpolation in query validation, we run the parser in the interpolated\n * query. If there are errors there, we trace them back to the original unparsed query, so we can more\n * accurately highlight the error in the query, since it's likely that the variable name and variable value\n * have different lengths. With this, we also exclude irrelevant parser errors that are produced by\n * lezer not understanding $variables and $__variables, which usually generate 2 or 3 error SyntaxNode.\n */\n const interpolatedErrors: ParseError[] = parseQuery(interpolatedQuery, parser);\n if (!interpolatedErrors.length) {\n return false;\n }\n\n let parseErrors: ParseError[] = interpolatedErrors;\n if (query !== interpolatedQuery) {\n const queryErrors: ParseError[] = parseQuery(query, parser);\n parseErrors = interpolatedErrors.flatMap(\n (interpolatedError) =>\n queryErrors.filter((queryError) => interpolatedError.text === queryError.text) || interpolatedError\n );\n }\n\n return parseErrors.map((parseError) => findErrorBoundary(query, queryLines, parseError)).filter(isErrorBoundary);\n}\n\nfunction parseQuery(query: string, parser: LRParser) {\n const parseErrors: ParseError[] = [];\n const tree = parser.parse(query);\n tree.iterate({\n enter: (nodeRef): false | void => {\n if (nodeRef.type.id === ErrorId) {\n const node = nodeRef.node;\n parseErrors.push({\n node: node,\n text: query.substring(node.from, node.to),\n });\n }\n },\n });\n return parseErrors;\n}\n\nfunction findErrorBoundary(query: string, queryLines: string[], parseError: ParseError): ParserErrorBoundary | null {\n if (queryLines.length === 1) {\n const isEmptyString = parseError.node.from === parseError.node.to;\n const errorNode = isEmptyString && parseError.node.parent ? parseError.node.parent : parseError.node;\n const error = isEmptyString ? query.substring(errorNode.from, errorNode.to) : parseError.text;\n return {\n startLineNumber: 1,\n startColumn: errorNode.from + 1,\n endLineNumber: 1,\n endColumn: errorNode.to + 1,\n error,\n };\n }\n\n let startPos = 0,\n endPos = 0;\n for (let line = 0; line < queryLines.length; line++) {\n endPos = startPos + queryLines[line].length;\n\n if (parseError.node.from > endPos) {\n startPos += queryLines[line].length + 1;\n continue;\n }\n\n return {\n startLineNumber: line + 1,\n startColumn: parseError.node.from - startPos + 1,\n endLineNumber: line + 1,\n endColumn: parseError.node.to - startPos + 1,\n error: parseError.text,\n };\n }\n\n return null;\n}\n\nfunction isErrorBoundary(boundary: ParserErrorBoundary | null): boundary is ParserErrorBoundary {\n return boundary !== null;\n}\n\nexport const placeHolderScopedVars = {\n __interval: { text: '1s', value: '1s' },\n __rate_interval: { text: '1s', value: '1s' },\n __auto: { text: '1s', value: '1s' },\n __interval_ms: { text: '1000', value: 1000 },\n __range_ms: { text: '1000', value: 1000 },\n __range_s: { text: '1', value: 1 },\n __range: { text: '1s', value: '1s' },\n};\n","import { SyntaxNode, TreeCursor } from '@lezer/common';\n\nimport { QueryBuilderOperation, QueryBuilderOperationParamValue } from '@grafana/experimental';\n\n// Although 0 isn't explicitly provided in the @grafana/lezer-logql library as the error node ID, it does appear to be the ID of error nodes within lezer.\nexport const ErrorId = 0;\n\nexport function getLeftMostChild(cur: SyntaxNode): SyntaxNode {\n return cur.firstChild ? getLeftMostChild(cur.firstChild) : cur;\n}\n\nexport function makeError(expr: string, node: SyntaxNode) {\n return {\n text: getString(expr, node),\n // TODO: this are positions in the string with the replaced variables. Means it cannot be used to show exact\n // placement of the error for the user. We need some translation table to positions before the variable\n // replace.\n from: node.from,\n to: node.to,\n parentType: node.parent?.name,\n };\n}\n\n// Taken from template_srv, but copied so to not mess with the regex.index which is manipulated in the service\n/*\n * This regex matches 3 types of variable reference with an optional format specifier\n * \\$(\\w+) $var1\n * \\[\\[([\\s\\S]+?)(?::(\\w+))?\\]\\] [[var2]] or [[var2:fmt2]]\n * \\${(\\w+)(?::(\\w+))?} ${var3} or ${var3:fmt3}\n */\nexport const variableRegex = /\\$(\\w+)|\\[\\[([\\s\\S]+?)(?::(\\w+))?\\]\\]|\\${(\\w+)(?:\\.([^:^\\}]+))?(?::([^\\}]+))?}/g;\n\n/**\n * As variables with $ are creating parsing errors, we first replace them with magic string that is parsable and at\n * the same time we can get the variable and its format back from it.\n * @param expr\n */\nexport function replaceVariables(expr: string) {\n return expr.replace(variableRegex, (match, var1, var2, fmt2, var3, fieldPath, fmt3) => {\n const fmt = fmt2 || fmt3;\n let variable = var1;\n let varType = '0';\n\n if (var2) {\n variable = var2;\n varType = '1';\n }\n\n if (var3) {\n variable = var3;\n varType = '2';\n }\n\n return `__V_${varType}__` + variable + '__V__' + (fmt ? '__F__' + fmt + '__F__' : '');\n });\n}\n\nconst varTypeFunc = [\n (v: string, f?: string) => `\\$${v}`,\n (v: string, f?: string) => `[[${v}${f ? `:${f}` : ''}]]`,\n (v: string, f?: string) => `\\$\\{${v}${f ? `:${f}` : ''}\\}`,\n];\n\n/**\n * Get back the text with variables in their original format.\n * @param expr\n */\nexport function returnVariables(expr: string) {\n return expr.replace(/__V_(\\d)__(.+?)__V__(?:__F__(\\w+)__F__)?/g, (match, type, v, f) => {\n return varTypeFunc[parseInt(type, 10)](v, f);\n });\n}\n\n/**\n * Get the actual string of the expression. That is not stored in the tree so we have to get the indexes from the node\n * and then based on that get it from the expression.\n * @param expr\n * @param node\n */\nexport function getString(expr: string, node: SyntaxNode | TreeCursor | null | undefined) {\n if (!node) {\n return '';\n }\n return returnVariables(expr.substring(node.from, node.to));\n}\n\n/**\n * Create simple scalar binary op object.\n * @param opDef - definition of the op to be created\n * @param expr\n * @param numberNode - the node for the scalar\n * @param hasBool - whether operation has a bool modifier. Is used only for ops for which it makes sense.\n */\nexport function makeBinOp(\n opDef: { id: string; comparison?: boolean },\n expr: string,\n numberNode: SyntaxNode,\n hasBool: boolean\n): QueryBuilderOperation {\n const params: QueryBuilderOperationParamValue[] = [parseFloat(getString(expr, numberNode))];\n if (opDef.comparison) {\n params.push(hasBool);\n }\n return {\n id: opDef.id,\n params,\n };\n}\n\n/**\n * Get all nodes with type in the tree. This traverses the tree so it is safe only when you know there shouldn't be\n * too much nesting but you just want to skip some of the wrappers. For example getting function args this way would\n * not be safe is it would also find arguments of nested functions.\n * @param expr\n * @param cur\n * @param type - can be string or number, some data-sources (loki) haven't migrated over to using numeric constants defined in the lezer parsing library (e.g. lezer-promql).\n * @todo Remove string type definition when all data-sources have migrated to numeric constants\n */\nexport function getAllByType(expr: string, cur: SyntaxNode, type: number | string): string[] {\n if (cur.type.id === type || cur.name === type) {\n return [getString(expr, cur)];\n }\n const values: string[] = [];\n let pos = 0;\n let child = cur.childAfter(pos);\n while (child) {\n values.push(...getAllByType(expr, child, type));\n pos = child.to;\n child = cur.childAfter(pos);\n }\n return values;\n}\n\n/**\n * There aren't any spaces in the metric names, so let's introduce a wildcard into the regex for each space to better facilitate a fuzzy search\n */\nexport const regexifyLabelValuesQueryString = (query: string) => {\n const queryArray = query.split(' ');\n return queryArray.map((query) => `${query}.*`).join('');\n};\n","// The MIT License (MIT)\n//\n// Copyright (c) Celian Garcia and Augustin Husson @ Amadeus IT Group\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n'use strict';\n// noinspection JSUnusedGlobalSymbols\nexport var promLanguageDefinition = {\n id: 'promql',\n extensions: ['.promql'],\n aliases: ['Prometheus', 'prometheus', 'prom', 'Prom', 'promql', 'Promql', 'promQL', 'PromQL'],\n mimetypes: [],\n loader: function () { return import('./promql'); } // eslint-disable-line @typescript-eslint/explicit-function-return-type\n};\n","import { monacoTypes } from '@grafana/ui';\n\n// this thing here is a workaround in a way.\n// what we want to achieve, is that when the autocomplete-window\n// opens, the \"second, extra popup\" with the extra help,\n// also opens automatically.\n// but there is no API to achieve it.\n// the way to do it is to implement the `storageService`\n// interface, and provide our custom implementation,\n// which will default to `true` for the correct string-key.\n// unfortunately, while the typescript-interface exists,\n// it is not exported from monaco-editor,\n// so we cannot rely on typescript to make sure\n// we do it right. all we can do is to manually\n// lookup the interface, and make sure we code our code right.\n// our code is a \"best effort\" approach,\n// i am not 100% how the `scope` and `target` things work,\n// but so far it seems to work ok.\n// i would use an another approach, if there was one available.\n\nfunction makeStorageService() {\n // we need to return an object that fulfills this interface:\n // https://github.com/microsoft/vscode/blob/ff1e16eebb93af79fd6d7af1356c4003a120c563/src/vs/platform/storage/common/storage.ts#L37\n // unfortunately it is not export from monaco-editor\n\n const strings = new Map();\n\n // we want this to be true by default\n strings.set('expandSuggestionDocs', true.toString());\n\n return {\n // we do not implement the on* handlers\n onDidChangeValue: (data: unknown): void => undefined,\n onDidChangeTarget: (data: unknown): void => undefined,\n onWillSaveState: (data: unknown): void => undefined,\n\n get: (key: string, scope: unknown, fallbackValue?: string): string | undefined => {\n return strings.get(key) ?? fallbackValue;\n },\n\n getBoolean: (key: string, scope: unknown, fallbackValue?: boolean): boolean | undefined => {\n const val = strings.get(key);\n if (val !== undefined) {\n // the interface-docs say the value will be converted\n // to a boolean but do not specify how, so we improvise\n return val === 'true';\n } else {\n return fallbackValue;\n }\n },\n\n getNumber: (key: string, scope: unknown, fallbackValue?: number): number | undefined => {\n const val = strings.get(key);\n if (val !== undefined) {\n return parseInt(val, 10);\n } else {\n return fallbackValue;\n }\n },\n\n store: (\n key: string,\n value: string | boolean | number | undefined | null,\n scope: unknown,\n target: unknown\n ): void => {\n // the interface-docs say if the value is nullish, it should act as delete\n if (value === null || value === undefined) {\n strings.delete(key);\n } else {\n strings.set(key, value.toString());\n }\n },\n\n remove: (key: string, scope: unknown): void => {\n strings.delete(key);\n },\n\n keys: (scope: unknown, target: unknown): string[] => {\n return Array.from(strings.keys());\n },\n\n logStorage: (): void => {\n console.log('logStorage: not implemented');\n },\n\n migrate: (): Promise => {\n // we do not implement this\n return Promise.resolve(undefined);\n },\n\n isNew: (scope: unknown): boolean => {\n // we create a new storage for every session, we do not persist it,\n // so we return `true`.\n return true;\n },\n\n flush: (reason?: unknown): Promise => {\n // we do not implement this\n return Promise.resolve(undefined);\n },\n };\n}\n\nlet overrideServices: monacoTypes.editor.IEditorOverrideServices | null = null;\n\nexport function getOverrideServices(): monacoTypes.editor.IEditorOverrideServices {\n // only have one instance of this for every query editor\n if (overrideServices === null) {\n overrideServices = {\n storageService: makeStorageService(),\n };\n }\n\n return overrideServices;\n}\n","// this helper class is used to make typescript warn you when you forget\n// a case-block in a switch statement.\n// example code that triggers the typescript-error:\n//\n// const x:'A'|'B'|'C' = 'A';\n//\n// switch(x) {\n// case 'A':\n// // something\n// case 'B':\n// // something\n// default:\n// throw new NeverCaseError(x);\n// }\n//\n//\n// typescript will show an error in this case,\n// when you add the missing `case 'C'` code,\n// the problem will be fixed.\n\nexport class NeverCaseError extends Error {\n constructor(value: never) {\n super('should never happen');\n }\n}\n","import { escapeLabelValueInExactSelector } from '../../../language_utils';\nimport { FUNCTIONS } from '../../../promql';\n\nimport type { Situation, Label } from './situation';\nimport { NeverCaseError } from './util';\n// FIXME: we should not load this from the \"outside\", but we cannot do that while we have the \"old\" query-field too\n\nexport type CompletionType = 'HISTORY' | 'FUNCTION' | 'METRIC_NAME' | 'DURATION' | 'LABEL_NAME' | 'LABEL_VALUE';\n\ntype Completion = {\n type: CompletionType;\n label: string;\n insertText: string;\n detail?: string;\n documentation?: string;\n triggerOnInsert?: boolean;\n};\n\ntype Metric = {\n name: string;\n help: string;\n type: string;\n};\n\nexport type DataProvider = {\n getHistory: () => Promise;\n getAllMetricNames: () => Promise;\n getAllLabelNames: () => Promise;\n getLabelValues: (labelName: string) => Promise;\n getSeriesValues: (name: string, match: string) => Promise;\n getSeriesLabels: (selector: string, otherLabels: Label[]) => Promise;\n};\n\n// we order items like: history, functions, metrics\n\nasync function getAllMetricNamesCompletions(dataProvider: DataProvider): Promise {\n const metrics = await dataProvider.getAllMetricNames();\n return metrics.map((metric) => ({\n type: 'METRIC_NAME',\n label: metric.name,\n insertText: metric.name,\n detail: `${metric.name} : ${metric.type}`,\n documentation: metric.help,\n }));\n}\n\nconst FUNCTION_COMPLETIONS: Completion[] = FUNCTIONS.map((f) => ({\n type: 'FUNCTION',\n label: f.label,\n insertText: f.insertText ?? '', // i don't know what to do when this is nullish. it should not be.\n detail: f.detail,\n documentation: f.documentation,\n}));\n\nasync function getAllFunctionsAndMetricNamesCompletions(dataProvider: DataProvider): Promise {\n const metricNames = await getAllMetricNamesCompletions(dataProvider);\n return [...FUNCTION_COMPLETIONS, ...metricNames];\n}\n\nconst DURATION_COMPLETIONS: Completion[] = [\n '$__interval',\n '$__range',\n '$__rate_interval',\n '1m',\n '5m',\n '10m',\n '30m',\n '1h',\n '1d',\n].map((text) => ({\n type: 'DURATION',\n label: text,\n insertText: text,\n}));\n\nasync function getAllHistoryCompletions(dataProvider: DataProvider): Promise {\n // function getAllHistoryCompletions(queryHistory: PromHistoryItem[]): Completion[] {\n // NOTE: the typescript types are wrong. historyItem.query.expr can be undefined\n const allHistory = await dataProvider.getHistory();\n // FIXME: find a better history-limit\n return allHistory.slice(0, 10).map((expr) => ({\n type: 'HISTORY',\n label: expr,\n insertText: expr,\n }));\n}\n\nfunction makeSelector(metricName: string | undefined, labels: Label[]): string {\n const allLabels = [...labels];\n\n // we transform the metricName to a label, if it exists\n if (metricName !== undefined) {\n allLabels.push({ name: '__name__', value: metricName, op: '=' });\n }\n\n const allLabelTexts = allLabels.map(\n (label) => `${label.name}${label.op}\"${escapeLabelValueInExactSelector(label.value)}\"`\n );\n\n return `{${allLabelTexts.join(',')}}`;\n}\n\nasync function getLabelNames(\n metric: string | undefined,\n otherLabels: Label[],\n dataProvider: DataProvider\n): Promise {\n if (metric === undefined && otherLabels.length === 0) {\n // if there is no filtering, we have to use a special endpoint\n return dataProvider.getAllLabelNames();\n } else {\n const selector = makeSelector(metric, otherLabels);\n return await dataProvider.getSeriesLabels(selector, otherLabels);\n }\n}\n\nasync function getLabelNamesForCompletions(\n metric: string | undefined,\n suffix: string,\n triggerOnInsert: boolean,\n otherLabels: Label[],\n dataProvider: DataProvider\n): Promise {\n const labelNames = await getLabelNames(metric, otherLabels, dataProvider);\n return labelNames.map((text) => ({\n type: 'LABEL_NAME',\n label: text,\n insertText: `${text}${suffix}`,\n triggerOnInsert,\n }));\n}\n\nasync function getLabelNamesForSelectorCompletions(\n metric: string | undefined,\n otherLabels: Label[],\n dataProvider: DataProvider\n): Promise {\n return getLabelNamesForCompletions(metric, '=', true, otherLabels, dataProvider);\n}\nasync function getLabelNamesForByCompletions(\n metric: string | undefined,\n otherLabels: Label[],\n dataProvider: DataProvider\n): Promise {\n return getLabelNamesForCompletions(metric, '', false, otherLabels, dataProvider);\n}\n\nasync function getLabelValues(\n metric: string | undefined,\n labelName: string,\n otherLabels: Label[],\n dataProvider: DataProvider\n): Promise {\n if (metric === undefined && otherLabels.length === 0) {\n // if there is no filtering, we have to use a special endpoint\n return dataProvider.getLabelValues(labelName);\n } else {\n const selector = makeSelector(metric, otherLabels);\n return await dataProvider.getSeriesValues(labelName, selector);\n }\n}\n\nasync function getLabelValuesForMetricCompletions(\n metric: string | undefined,\n labelName: string,\n betweenQuotes: boolean,\n otherLabels: Label[],\n dataProvider: DataProvider\n): Promise {\n const values = await getLabelValues(metric, labelName, otherLabels, dataProvider);\n return values.map((text) => ({\n type: 'LABEL_VALUE',\n label: text,\n insertText: betweenQuotes ? text : `\"${text}\"`, // FIXME: escaping strange characters?\n }));\n}\n\nexport async function getCompletions(situation: Situation, dataProvider: DataProvider): Promise {\n switch (situation.type) {\n case 'IN_DURATION':\n return DURATION_COMPLETIONS;\n case 'IN_FUNCTION':\n return getAllFunctionsAndMetricNamesCompletions(dataProvider);\n case 'AT_ROOT': {\n return getAllFunctionsAndMetricNamesCompletions(dataProvider);\n }\n case 'EMPTY': {\n const metricNames = await getAllMetricNamesCompletions(dataProvider);\n const historyCompletions = await getAllHistoryCompletions(dataProvider);\n return [...historyCompletions, ...FUNCTION_COMPLETIONS, ...metricNames];\n }\n case 'IN_LABEL_SELECTOR_NO_LABEL_NAME':\n return getLabelNamesForSelectorCompletions(situation.metricName, situation.otherLabels, dataProvider);\n case 'IN_GROUPING':\n return getLabelNamesForByCompletions(situation.metricName, situation.otherLabels, dataProvider);\n case 'IN_LABEL_SELECTOR_WITH_LABEL_NAME':\n return getLabelValuesForMetricCompletions(\n situation.metricName,\n situation.labelName,\n situation.betweenQuotes,\n situation.otherLabels,\n dataProvider\n );\n default:\n throw new NeverCaseError(situation);\n }\n}\n","import type { SyntaxNode, Tree } from '@lezer/common';\nimport {\n AggregateExpr,\n AggregateModifier,\n EqlRegex,\n EqlSingle,\n FunctionCallBody,\n GroupingLabels,\n Identifier,\n LabelMatcher,\n LabelMatchers,\n LabelMatchList,\n LabelName,\n MatchOp,\n MatrixSelector,\n MetricIdentifier,\n Neq,\n NeqRegex,\n parser,\n PromQL,\n StringLiteral,\n VectorSelector,\n} from '@prometheus-io/lezer-promql';\n\nimport { NeverCaseError } from './util';\n\ntype Direction = 'parent' | 'firstChild' | 'lastChild' | 'nextSibling';\n\ntype NodeTypeId =\n | 0 // this is used as error-id\n | typeof AggregateExpr\n | typeof AggregateModifier\n | typeof FunctionCallBody\n | typeof GroupingLabels\n | typeof Identifier\n | typeof LabelMatcher\n | typeof LabelMatchers\n | typeof LabelMatchList\n | typeof LabelName\n | typeof MetricIdentifier\n | typeof PromQL\n | typeof StringLiteral\n | typeof VectorSelector\n | typeof MatrixSelector\n | typeof MatchOp\n | typeof EqlSingle\n | typeof Neq\n | typeof EqlRegex\n | typeof NeqRegex;\n\ntype Path = Array<[Direction, NodeTypeId]>;\n\nfunction move(node: SyntaxNode, direction: Direction): SyntaxNode | null {\n switch (direction) {\n case 'parent':\n return node.parent;\n case 'firstChild':\n return node.firstChild;\n case 'lastChild':\n return node.lastChild;\n case 'nextSibling':\n return node.nextSibling;\n default:\n throw new NeverCaseError(direction);\n }\n}\n\nfunction walk(node: SyntaxNode, path: Path): SyntaxNode | null {\n let current: SyntaxNode | null = node;\n for (const [direction, expectedType] of path) {\n current = move(current, direction);\n if (current === null) {\n // we could not move in the direction, we stop\n return null;\n }\n if (current.type.id !== expectedType) {\n // the reached node has wrong type, we stop\n return null;\n }\n }\n return current;\n}\n\nfunction getNodeText(node: SyntaxNode, text: string): string {\n return text.slice(node.from, node.to);\n}\n\nfunction parsePromQLStringLiteral(text: string): string {\n // if it is a string-literal, it is inside quotes of some kind\n const inside = text.slice(1, text.length - 1);\n\n // FIXME: support https://prometheus.io/docs/prometheus/latest/querying/basics/#string-literals\n // FIXME: maybe check other promql code, if all is supported or not\n\n // for now we do only some very simple un-escaping\n\n // we start with double-quotes\n if (text.startsWith('\"') && text.endsWith('\"')) {\n // NOTE: this is not 100% perfect, we only unescape the double-quote,\n // there might be other characters too\n return inside.replace(/\\\\\"/, '\"');\n }\n\n // then single-quote\n if (text.startsWith(\"'\") && text.endsWith(\"'\")) {\n // NOTE: this is not 100% perfect, we only unescape the single-quote,\n // there might be other characters too\n return inside.replace(/\\\\'/, \"'\");\n }\n\n // then backticks\n if (text.startsWith('`') && text.endsWith('`')) {\n return inside;\n }\n\n throw new Error('FIXME: invalid string literal');\n}\n\ntype LabelOperator = '=' | '!=' | '=~' | '!~';\n\nexport type Label = {\n name: string;\n value: string;\n op: LabelOperator;\n};\n\nexport type Situation =\n | {\n type: 'IN_FUNCTION';\n }\n | {\n type: 'AT_ROOT';\n }\n | {\n type: 'EMPTY';\n }\n | {\n type: 'IN_DURATION';\n }\n | {\n type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME';\n metricName?: string;\n otherLabels: Label[];\n }\n | {\n type: 'IN_GROUPING';\n metricName: string;\n otherLabels: Label[];\n }\n | {\n type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME';\n metricName?: string;\n labelName: string;\n betweenQuotes: boolean;\n otherLabels: Label[];\n };\n\ntype Resolver = {\n path: NodeTypeId[];\n fun: (node: SyntaxNode, text: string, pos: number) => Situation | null;\n};\n\nfunction isPathMatch(resolverPath: NodeTypeId[], cursorPath: number[]): boolean {\n return resolverPath.every((item, index) => item === cursorPath[index]);\n}\n\nconst ERROR_NODE_NAME: NodeTypeId = 0; // this is used as error-id\n\nconst RESOLVERS: Resolver[] = [\n {\n path: [LabelMatchers, VectorSelector],\n fun: resolveLabelKeysWithEquals,\n },\n {\n path: [PromQL],\n fun: resolveTopLevel,\n },\n {\n path: [FunctionCallBody],\n fun: resolveInFunction,\n },\n {\n path: [StringLiteral, LabelMatcher],\n fun: resolveLabelMatcher,\n },\n {\n path: [ERROR_NODE_NAME, LabelMatcher],\n fun: resolveLabelMatcher,\n },\n {\n path: [ERROR_NODE_NAME, MatrixSelector],\n fun: resolveDurations,\n },\n {\n path: [GroupingLabels],\n fun: resolveLabelsForGrouping,\n },\n];\n\nconst LABEL_OP_MAP = new Map([\n [EqlSingle, '='],\n [EqlRegex, '=~'],\n [Neq, '!='],\n [NeqRegex, '!~'],\n]);\n\nfunction getLabelOp(opNode: SyntaxNode): LabelOperator | null {\n const opChild = opNode.firstChild;\n if (opChild === null) {\n return null;\n }\n\n return LABEL_OP_MAP.get(opChild.type.id) ?? null;\n}\n\nfunction getLabel(labelMatcherNode: SyntaxNode, text: string): Label | null {\n if (labelMatcherNode.type.id !== LabelMatcher) {\n return null;\n }\n\n const nameNode = walk(labelMatcherNode, [['firstChild', LabelName]]);\n\n if (nameNode === null) {\n return null;\n }\n\n const opNode = walk(nameNode, [['nextSibling', MatchOp]]);\n if (opNode === null) {\n return null;\n }\n\n const op = getLabelOp(opNode);\n if (op === null) {\n return null;\n }\n\n const valueNode = walk(labelMatcherNode, [['lastChild', StringLiteral]]);\n\n if (valueNode === null) {\n return null;\n }\n\n const name = getNodeText(nameNode, text);\n const value = parsePromQLStringLiteral(getNodeText(valueNode, text));\n\n return { name, value, op };\n}\n\nfunction getLabels(labelMatchersNode: SyntaxNode, text: string): Label[] {\n if (labelMatchersNode.type.id !== LabelMatchers) {\n return [];\n }\n\n let listNode: SyntaxNode | null = walk(labelMatchersNode, [['firstChild', LabelMatchList]]);\n\n const labels: Label[] = [];\n\n while (listNode !== null) {\n const matcherNode = walk(listNode, [['lastChild', LabelMatcher]]);\n if (matcherNode === null) {\n // unexpected, we stop\n return [];\n }\n\n const label = getLabel(matcherNode, text);\n if (label !== null) {\n labels.push(label);\n }\n\n // there might be more labels\n listNode = walk(listNode, [['firstChild', LabelMatchList]]);\n }\n\n // our labels-list is last-first, so we reverse it\n labels.reverse();\n\n return labels;\n}\n\nfunction getNodeChildren(node: SyntaxNode): SyntaxNode[] {\n let child: SyntaxNode | null = node.firstChild;\n const children: SyntaxNode[] = [];\n while (child !== null) {\n children.push(child);\n child = child.nextSibling;\n }\n return children;\n}\n\nfunction getNodeInSubtree(node: SyntaxNode, typeId: NodeTypeId): SyntaxNode | null {\n // first we try the current node\n if (node.type.id === typeId) {\n return node;\n }\n\n // then we try the children\n const children = getNodeChildren(node);\n for (const child of children) {\n const n = getNodeInSubtree(child, typeId);\n if (n !== null) {\n return n;\n }\n }\n\n return null;\n}\n\nfunction resolveLabelsForGrouping(node: SyntaxNode, text: string, pos: number): Situation | null {\n const aggrExpNode = walk(node, [\n ['parent', AggregateModifier],\n ['parent', AggregateExpr],\n ]);\n if (aggrExpNode === null) {\n return null;\n }\n const bodyNode = aggrExpNode.getChild(FunctionCallBody);\n if (bodyNode === null) {\n return null;\n }\n\n const metricIdNode = getNodeInSubtree(bodyNode, MetricIdentifier);\n if (metricIdNode === null) {\n return null;\n }\n\n const idNode = walk(metricIdNode, [['firstChild', Identifier]]);\n if (idNode === null) {\n return null;\n }\n\n const metricName = getNodeText(idNode, text);\n return {\n type: 'IN_GROUPING',\n metricName,\n otherLabels: [],\n };\n}\n\nfunction resolveLabelMatcher(node: SyntaxNode, text: string, pos: number): Situation | null {\n // we can arrive here in two situation. `node` is either:\n // - a StringNode (like in `{job=\"^\"}`)\n // - or an error node (like in `{job=^}`)\n const inStringNode = !node.type.isError;\n\n const parent = walk(node, [['parent', LabelMatcher]]);\n if (parent === null) {\n return null;\n }\n\n const labelNameNode = walk(parent, [['firstChild', LabelName]]);\n if (labelNameNode === null) {\n return null;\n }\n\n const labelName = getNodeText(labelNameNode, text);\n\n // now we need to go up, to the parent of LabelMatcher,\n // there can be one or many `LabelMatchList` parents, we have\n // to go through all of them\n\n const firstListNode = walk(parent, [['parent', LabelMatchList]]);\n if (firstListNode === null) {\n return null;\n }\n\n let listNode = firstListNode;\n\n // we keep going through the parent-nodes\n // as long as they are LabelMatchList.\n // as soon as we reawch LabelMatchers, we stop\n let labelMatchersNode: SyntaxNode | null = null;\n while (labelMatchersNode === null) {\n const p = listNode.parent;\n if (p === null) {\n return null;\n }\n\n const { id } = p.type;\n\n switch (id) {\n case LabelMatchList:\n //we keep looping\n listNode = p;\n continue;\n case LabelMatchers:\n // we reached the end, we can stop the loop\n labelMatchersNode = p;\n continue;\n default:\n // we reached some other node, we stop\n return null;\n }\n }\n\n // now we need to find the other names\n const allLabels = getLabels(labelMatchersNode, text);\n\n // we need to remove \"our\" label from all-labels, if it is in there\n const otherLabels = allLabels.filter((label) => label.name !== labelName);\n\n const metricNameNode = walk(labelMatchersNode, [\n ['parent', VectorSelector],\n ['firstChild', MetricIdentifier],\n ['firstChild', Identifier],\n ]);\n\n if (metricNameNode === null) {\n // we are probably in a situation without a metric name\n return {\n type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',\n labelName,\n betweenQuotes: inStringNode,\n otherLabels,\n };\n }\n\n const metricName = getNodeText(metricNameNode, text);\n\n return {\n type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',\n metricName,\n labelName,\n betweenQuotes: inStringNode,\n otherLabels,\n };\n}\n\nfunction resolveTopLevel(node: SyntaxNode, text: string, pos: number): Situation {\n return {\n type: 'AT_ROOT',\n };\n}\n\nfunction resolveInFunction(node: SyntaxNode, text: string, pos: number): Situation {\n return {\n type: 'IN_FUNCTION',\n };\n}\n\nfunction resolveDurations(node: SyntaxNode, text: string, pos: number): Situation {\n return {\n type: 'IN_DURATION',\n };\n}\n\nfunction subTreeHasError(node: SyntaxNode): boolean {\n return getNodeInSubtree(node, ERROR_NODE_NAME) !== null;\n}\n\nfunction resolveLabelKeysWithEquals(node: SyntaxNode, text: string, pos: number): Situation | null {\n // for example `something{^}`\n\n // there are some false positives that can end up in this situation, that we want\n // to eliminate:\n // `something{a~^}` (if this subtree contains any error-node, we stop)\n if (subTreeHasError(node)) {\n return null;\n }\n\n // next false positive:\n // `something{a=\"1\"^}`\n const child = walk(node, [['firstChild', LabelMatchList]]);\n if (child !== null) {\n // means the label-matching part contains at least one label already.\n //\n // in this case, we will need to have a `,` character at the end,\n // to be able to suggest adding the next label.\n // the area between the end-of-the-child-node and the cursor-pos\n // must contain a `,` in this case.\n const textToCheck = text.slice(child.to, pos);\n\n if (!textToCheck.includes(',')) {\n return null;\n }\n }\n\n const metricNameNode = walk(node, [\n ['parent', VectorSelector],\n ['firstChild', MetricIdentifier],\n ['firstChild', Identifier],\n ]);\n\n const otherLabels = getLabels(node, text);\n\n if (metricNameNode === null) {\n // we are probably in a situation without a metric name.\n return {\n type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',\n otherLabels,\n };\n }\n\n const metricName = getNodeText(metricNameNode, text);\n\n return {\n type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',\n metricName,\n otherLabels,\n };\n}\n\n// we find the first error-node in the tree that is at the cursor-position.\n// NOTE: this might be too slow, might need to optimize it\n// (ideas: we do not need to go into every subtree, based on from/to)\n// also, only go to places that are in the sub-tree of the node found\n// by default by lezer. problem is, `next()` will go upward too,\n// and we do not want to go higher than our node\nfunction getErrorNode(tree: Tree, pos: number): SyntaxNode | null {\n const cur = tree.cursorAt(pos);\n while (true) {\n if (cur.from === pos && cur.to === pos) {\n const { node } = cur;\n if (node.type.isError) {\n return node;\n }\n }\n\n if (!cur.next()) {\n break;\n }\n }\n return null;\n}\n\nexport function getSituation(text: string, pos: number): Situation | null {\n // there is a special-case when we are at the start of writing text,\n // so we handle that case first\n\n if (text === '') {\n return {\n type: 'EMPTY',\n };\n }\n\n /*\n\tPromQL\n Expr\n VectorSelector\n LabelMatchers\n */\n const tree = parser.parse(text);\n\n // if the tree contains error, it is very probable that\n // our node is one of those error-nodes.\n // also, if there are errors, the node lezer finds us,\n // might not be the best node.\n // so first we check if there is an error-node at the cursor-position\n const maybeErrorNode = getErrorNode(tree, pos);\n\n const cur = maybeErrorNode != null ? maybeErrorNode.cursor() : tree.cursorAt(pos);\n const currentNode = cur.node;\n\n const ids = [cur.type.id];\n while (cur.parent()) {\n ids.push(cur.type.id);\n }\n\n for (let resolver of RESOLVERS) {\n // i do not use a foreach because i want to stop as soon\n // as i find something\n if (isPathMatch(resolver.path, ids)) {\n return resolver.fun(currentNode, text, pos);\n }\n }\n\n return null;\n}\n","import type { Monaco, monacoTypes } from '@grafana/ui';\n\nimport { getCompletions, DataProvider, CompletionType } from './completions';\nimport { getSituation } from './situation';\nimport { NeverCaseError } from './util';\n\nexport function getSuggestOptions(): monacoTypes.editor.ISuggestOptions {\n return {\n // monaco-editor sometimes provides suggestions automatically, i am not\n // sure based on what, seems to be by analyzing the words already\n // written.\n // to try it out:\n // - enter `go_goroutines{job~`\n // - have the cursor at the end of the string\n // - press ctrl-enter\n // - you will get two suggestions\n // those were not provided by grafana, they are offered automatically.\n // i want to remove those. the only way i found is:\n // - every suggestion-item has a `kind` attribute,\n // that controls the icon to the left of the suggestion.\n // - items auto-generated by monaco have `kind` set to `text`.\n // - we make sure grafana-provided suggestions do not have `kind` set to `text`.\n // - and then we tell monaco not to show suggestions of kind `text`\n showWords: false,\n };\n}\n\nfunction getMonacoCompletionItemKind(type: CompletionType, monaco: Monaco): monacoTypes.languages.CompletionItemKind {\n switch (type) {\n case 'DURATION':\n return monaco.languages.CompletionItemKind.Unit;\n case 'FUNCTION':\n return monaco.languages.CompletionItemKind.Variable;\n case 'HISTORY':\n return monaco.languages.CompletionItemKind.Snippet;\n case 'LABEL_NAME':\n return monaco.languages.CompletionItemKind.Enum;\n case 'LABEL_VALUE':\n return monaco.languages.CompletionItemKind.EnumMember;\n case 'METRIC_NAME':\n return monaco.languages.CompletionItemKind.Constructor;\n default:\n throw new NeverCaseError(type);\n }\n}\n\nexport function getCompletionProvider(\n monaco: Monaco,\n dataProvider: DataProvider\n): monacoTypes.languages.CompletionItemProvider {\n const provideCompletionItems = (\n model: monacoTypes.editor.ITextModel,\n position: monacoTypes.Position\n ): monacoTypes.languages.ProviderResult => {\n const word = model.getWordAtPosition(position);\n const range =\n word != null\n ? monaco.Range.lift({\n startLineNumber: position.lineNumber,\n endLineNumber: position.lineNumber,\n startColumn: word.startColumn,\n endColumn: word.endColumn,\n })\n : monaco.Range.fromPositions(position);\n // documentation says `position` will be \"adjusted\" in `getOffsetAt`\n // i don't know what that means, to be sure i clone it\n\n const positionClone = {\n column: position.column,\n lineNumber: position.lineNumber,\n };\n\n // Check to see if the browser supports window.getSelection()\n if (window.getSelection) {\n const selectedText = window.getSelection()?.toString();\n // If the user has selected text, adjust the cursor position to be at the start of the selection, instead of the end\n if (selectedText && selectedText.length > 0) {\n positionClone.column = positionClone.column - selectedText.length;\n }\n }\n\n const offset = model.getOffsetAt(positionClone);\n const situation = getSituation(model.getValue(), offset);\n const completionsPromise = situation != null ? getCompletions(situation, dataProvider) : Promise.resolve([]);\n return completionsPromise.then((items) => {\n // monaco by-default alphabetically orders the items.\n // to stop it, we use a number-as-string sortkey,\n // so that monaco keeps the order we use\n const maxIndexDigits = items.length.toString().length;\n const suggestions: monacoTypes.languages.CompletionItem[] = items.map((item, index) => ({\n kind: getMonacoCompletionItemKind(item.type, monaco),\n label: item.label,\n insertText: item.insertText,\n detail: item.detail,\n documentation: item.documentation,\n sortText: index.toString().padStart(maxIndexDigits, '0'), // to force the order we have\n range,\n command: item.triggerOnInsert\n ? {\n id: 'editor.action.triggerSuggest',\n title: '',\n }\n : undefined,\n }));\n return { suggestions };\n });\n };\n\n return {\n triggerCharacters: ['{', ',', '[', '(', '=', '~', ' ', '\"'],\n provideCompletionItems,\n };\n}\n","import { css } from '@emotion/css';\nimport { parser } from '@prometheus-io/lezer-promql';\nimport { debounce } from 'lodash';\nimport { promLanguageDefinition } from 'monaco-promql';\nimport React, { useRef, useEffect } from 'react';\nimport { useLatest } from 'react-use';\nimport { v4 as uuidv4 } from 'uuid';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { selectors } from '@grafana/e2e-selectors';\nimport { useTheme2, ReactMonacoEditor, Monaco, monacoTypes } from '@grafana/ui';\nimport {\n placeHolderScopedVars,\n validateQuery,\n} from 'app/plugins/datasource/loki/components/monaco-query-field/monaco-completion-provider/validation';\n\nimport { Props } from './MonacoQueryFieldProps';\nimport { getOverrideServices } from './getOverrideServices';\nimport { getCompletionProvider, getSuggestOptions } from './monaco-completion-provider';\n\nconst options: monacoTypes.editor.IStandaloneEditorConstructionOptions = {\n codeLens: false,\n contextmenu: false,\n // we need `fixedOverflowWidgets` because otherwise in grafana-dashboards\n // the popup is clipped by the panel-visualizations.\n fixedOverflowWidgets: true,\n folding: false,\n fontSize: 14,\n lineDecorationsWidth: 8, // used as \"padding-left\"\n lineNumbers: 'off',\n minimap: { enabled: false },\n overviewRulerBorder: false,\n overviewRulerLanes: 0,\n padding: {\n // these numbers were picked so that visually this matches the previous version\n // of the query-editor the best\n top: 4,\n bottom: 5,\n },\n renderLineHighlight: 'none',\n scrollbar: {\n vertical: 'hidden',\n verticalScrollbarSize: 8, // used as \"padding-right\"\n horizontal: 'hidden',\n horizontalScrollbarSize: 0,\n alwaysConsumeMouseWheel: false,\n },\n scrollBeyondLastLine: false,\n suggest: getSuggestOptions(),\n suggestFontSize: 12,\n wordWrap: 'on',\n};\n\n// this number was chosen by testing various values. it might be necessary\n// because of the width of the border, not sure.\n//it needs to do 2 things:\n// 1. when the editor is single-line, it should make the editor height be visually correct\n// 2. when the editor is multi-line, the editor should not be \"scrollable\" (meaning,\n// you do a scroll-movement in the editor, and it will scroll the content by a couple pixels\n// up & down. this we want to avoid)\nconst EDITOR_HEIGHT_OFFSET = 2;\n\nconst PROMQL_LANG_ID = promLanguageDefinition.id;\n\n// we must only run the promql-setup code once\nlet PROMQL_SETUP_STARTED = false;\n\nfunction ensurePromQL(monaco: Monaco) {\n if (PROMQL_SETUP_STARTED === false) {\n PROMQL_SETUP_STARTED = true;\n const { aliases, extensions, mimetypes, loader } = promLanguageDefinition;\n monaco.languages.register({ id: PROMQL_LANG_ID, aliases, extensions, mimetypes });\n\n loader().then((mod) => {\n monaco.languages.setMonarchTokensProvider(PROMQL_LANG_ID, mod.language);\n monaco.languages.setLanguageConfiguration(PROMQL_LANG_ID, mod.languageConfiguration);\n });\n }\n}\n\nconst getStyles = (theme: GrafanaTheme2, placeholder: string) => {\n return {\n container: css`\n border-radius: ${theme.shape.radius.default};\n border: 1px solid ${theme.components.input.borderColor};\n `,\n placeholder: css`\n ::after {\n content: '${placeholder}';\n font-family: ${theme.typography.fontFamilyMonospace};\n opacity: 0.6;\n }\n `,\n };\n};\n\nconst MonacoQueryField = (props: Props) => {\n const id = uuidv4();\n\n // we need only one instance of `overrideServices` during the lifetime of the react component\n const overrideServicesRef = useRef(getOverrideServices());\n const containerRef = useRef(null);\n const { languageProvider, history, onBlur, onRunQuery, initialValue, placeholder, onChange, datasource } = props;\n\n const lpRef = useLatest(languageProvider);\n const historyRef = useLatest(history);\n const onRunQueryRef = useLatest(onRunQuery);\n const onBlurRef = useLatest(onBlur);\n const onChangeRef = useLatest(onChange);\n\n const autocompleteDisposeFun = useRef<(() => void) | null>(null);\n\n const theme = useTheme2();\n const styles = getStyles(theme, placeholder);\n\n useEffect(() => {\n // when we unmount, we unregister the autocomplete-function, if it was registered\n return () => {\n autocompleteDisposeFun.current?.();\n };\n }, []);\n\n return (\n \n {\n ensurePromQL(monaco);\n }}\n onMount={(editor, monaco) => {\n const isEditorFocused = editor.createContextKey('isEditorFocused' + id, false);\n // we setup on-blur\n editor.onDidBlurEditorWidget(() => {\n isEditorFocused.set(false);\n onBlurRef.current(editor.getValue());\n });\n editor.onDidFocusEditorText(() => {\n isEditorFocused.set(true);\n });\n\n // we construct a DataProvider object\n const getHistory = () =>\n Promise.resolve(historyRef.current.map((h) => h.query.expr).filter((expr) => expr !== undefined));\n\n const getAllMetricNames = () => {\n const { metrics, metricsMetadata } = lpRef.current;\n const result = metrics.map((m) => {\n const metaItem = metricsMetadata?.[m];\n return {\n name: m,\n help: metaItem?.help ?? '',\n type: metaItem?.type ?? '',\n };\n });\n\n return Promise.resolve(result);\n };\n\n const getAllLabelNames = () => Promise.resolve(lpRef.current.getLabelKeys());\n\n const getLabelValues = (labelName: string) => lpRef.current.getLabelValues(labelName);\n\n const getSeriesValues = lpRef.current.getSeriesValues;\n\n const getSeriesLabels = lpRef.current.getSeriesLabels;\n\n const dataProvider = {\n getHistory,\n getAllMetricNames,\n getAllLabelNames,\n getLabelValues,\n getSeriesValues,\n getSeriesLabels,\n };\n const completionProvider = getCompletionProvider(monaco, dataProvider);\n\n // completion-providers in monaco are not registered directly to editor-instances,\n // they are registered to languages. this makes it hard for us to have\n // separate completion-providers for every query-field-instance\n // (but we need that, because they might connect to different datasources).\n // the trick we do is, we wrap the callback in a \"proxy\",\n // and in the proxy, the first thing is, we check if we are called from\n // \"our editor instance\", and if not, we just return nothing. if yes,\n // we call the completion-provider.\n const filteringCompletionProvider: monacoTypes.languages.CompletionItemProvider = {\n ...completionProvider,\n provideCompletionItems: (model, position, context, token) => {\n // if the model-id does not match, then this call is from a different editor-instance,\n // not \"our instance\", so return nothing\n if (editor.getModel()?.id !== model.id) {\n return { suggestions: [] };\n }\n return completionProvider.provideCompletionItems(model, position, context, token);\n },\n };\n\n const { dispose } = monaco.languages.registerCompletionItemProvider(\n PROMQL_LANG_ID,\n filteringCompletionProvider\n );\n\n autocompleteDisposeFun.current = dispose;\n // this code makes the editor resize itself so that the content fits\n // (it will grow taller when necessary)\n // FIXME: maybe move this functionality into CodeEditor, like:\n // \n const updateElementHeight = () => {\n const containerDiv = containerRef.current;\n if (containerDiv !== null) {\n const pixelHeight = editor.getContentHeight();\n containerDiv.style.height = `${pixelHeight + EDITOR_HEIGHT_OFFSET}px`;\n containerDiv.style.width = '100%';\n const pixelWidth = containerDiv.clientWidth;\n editor.layout({ width: pixelWidth, height: pixelHeight });\n }\n };\n\n editor.onDidContentSizeChange(updateElementHeight);\n updateElementHeight();\n\n // Whenever the editor changes, lets save the last value so the next query for this editor will be up-to-date.\n // This change is being introduced to fix a bug where you can submit a query via shift+enter:\n // If you clicked into another field and haven't un-blurred the active field,\n // then the query that is run will be stale, as the reference is only updated\n // with the value of the last blurred input.\n // This can run quite slowly, so we're debouncing this which should accomplish two things\n // 1. Should prevent this function from blocking the current call stack by pushing into the web API callback queue\n // 2. Should prevent a bunch of duplicates of this function being called as the user is typing\n const updateCurrentEditorValue = debounce(() => {\n const editorValue = editor.getValue();\n onChangeRef.current(editorValue);\n }, lpRef.current.datasource.getDebounceTimeInMilliseconds());\n\n editor.getModel()?.onDidChangeContent(() => {\n updateCurrentEditorValue();\n });\n\n // handle: shift + enter\n // FIXME: maybe move this functionality into CodeEditor?\n editor.addCommand(\n monaco.KeyMod.Shift | monaco.KeyCode.Enter,\n () => {\n onRunQueryRef.current(editor.getValue());\n },\n 'isEditorFocused' + id\n );\n\n /* Something in this configuration of monaco doesn't bubble up [mod]+K, which the\n command palette uses. Pass the event out of monaco manually\n */\n editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyK, function () {\n global.dispatchEvent(new KeyboardEvent('keydown', { key: 'k', metaKey: true }));\n });\n\n if (placeholder) {\n const placeholderDecorators = [\n {\n range: new monaco.Range(1, 1, 1, 1),\n options: {\n className: styles.placeholder,\n isWholeLine: true,\n },\n },\n ];\n\n let decorators: string[] = [];\n\n const checkDecorators: () => void = () => {\n const model = editor.getModel();\n\n if (!model) {\n return;\n }\n\n const newDecorators = model.getValueLength() === 0 ? placeholderDecorators : [];\n decorators = model.deltaDecorations(decorators, newDecorators);\n };\n\n checkDecorators();\n editor.onDidChangeModelContent(checkDecorators);\n\n editor.onDidChangeModelContent((e) => {\n const model = editor.getModel();\n if (!model) {\n return;\n }\n const query = model.getValue();\n const errors =\n validateQuery(\n query,\n datasource.interpolateString(query, placeHolderScopedVars),\n model.getLinesContent(),\n parser\n ) || [];\n\n const markers = errors.map(({ error, ...boundary }) => ({\n message: `${\n error ? `Error parsing \"${error}\"` : 'Parse error'\n }. The query appears to be incorrect and could fail to be executed.`,\n severity: monaco.MarkerSeverity.Error,\n ...boundary,\n }));\n\n monaco.editor.setModelMarkers(model, 'owner', markers);\n });\n }\n }}\n />\n \n );\n};\n\n// we will lazy-load this module using React.lazy,\n// and that only supports default-exports,\n// so we have to default-export this, even if\n// it is against the style-guidelines.\n\nexport default MonacoQueryField;\n","import { useRef } from 'react';\nvar useLatest = function (value) {\n var ref = useRef(value);\n ref.current = value;\n return ref;\n};\nexport default useLatest;\n"],"names":["validateQuery","query","interpolatedQuery","queryLines","parser","interpolatedErrors","parseQuery","parseErrors","queryErrors","interpolatedError","queryError","parseError","findErrorBoundary","isErrorBoundary","nodeRef","node","isEmptyString","errorNode","error","startPos","endPos","line","boundary","placeHolderScopedVars","ErrorId","getLeftMostChild","cur","makeError","expr","getString","variableRegex","replaceVariables","match","var1","var2","fmt2","var3","fieldPath","fmt3","fmt","variable","varType","varTypeFunc","v","f","returnVariables","type","makeBinOp","opDef","numberNode","hasBool","params","getAllByType","values","pos","child","regexifyLabelValuesQueryString","promLanguageDefinition","makeStorageService","strings","data","key","scope","fallbackValue","val","value","target","reason","overrideServices","getOverrideServices","NeverCaseError","getAllMetricNamesCompletions","dataProvider","metric","FUNCTION_COMPLETIONS","getAllFunctionsAndMetricNamesCompletions","metricNames","DURATION_COMPLETIONS","text","getAllHistoryCompletions","makeSelector","metricName","labels","allLabels","label","getLabelNames","otherLabels","selector","getLabelNamesForCompletions","suffix","triggerOnInsert","getLabelNamesForSelectorCompletions","getLabelNamesForByCompletions","getLabelValues","labelName","getLabelValuesForMetricCompletions","betweenQuotes","getCompletions","situation","move","direction","walk","path","current","expectedType","getNodeText","parsePromQLStringLiteral","inside","isPathMatch","resolverPath","cursorPath","item","index","ERROR_NODE_NAME","RESOLVERS","resolveLabelKeysWithEquals","resolveTopLevel","resolveInFunction","resolveLabelMatcher","resolveDurations","resolveLabelsForGrouping","LABEL_OP_MAP","getLabelOp","opNode","opChild","getLabel","labelMatcherNode","nameNode","op","valueNode","name","getLabels","labelMatchersNode","listNode","matcherNode","getNodeChildren","children","getNodeInSubtree","typeId","n","aggrExpNode","bodyNode","metricIdNode","idNode","inStringNode","parent","labelNameNode","firstListNode","p","id","metricNameNode","subTreeHasError","getErrorNode","tree","getSituation","maybeErrorNode","currentNode","ids","resolver","getSuggestOptions","getMonacoCompletionItemKind","monaco","getCompletionProvider","model","position","word","range","positionClone","selectedText","offset","items","maxIndexDigits","options","EDITOR_HEIGHT_OFFSET","PROMQL_LANG_ID","PROMQL_SETUP_STARTED","ensurePromQL","aliases","extensions","mimetypes","loader","mod","getStyles","theme","placeholder","props","overrideServicesRef","containerRef","languageProvider","history","onBlur","onRunQuery","initialValue","onChange","datasource","lpRef","useLatest","historyRef","onRunQueryRef","onBlurRef","onChangeRef","autocompleteDisposeFun","styles","selectors","editor","isEditorFocused","getHistory","h","getAllMetricNames","metrics","metricsMetadata","result","m","metaItem","getAllLabelNames","getSeriesValues","getSeriesLabels","completionProvider","filteringCompletionProvider","context","token","dispose","updateElementHeight","containerDiv","pixelHeight","pixelWidth","updateCurrentEditorValue","editorValue","placeholderDecorators","decorators","checkDecorators","newDecorators","e","markers","ref"],"sourceRoot":""}