{"version":3,"file":"language_utils.mjs","sources":["../../src/language_utils.ts"],"sourcesContent":["// Core Grafana history https://github.com/grafana/grafana/blob/v11.0.0-preview/public/app/plugins/datasource/prometheus/language_utils.ts\nimport { invert } from 'lodash';\nimport { Token } from 'prismjs';\n\nimport {\n  type AbstractLabelMatcher,\n  AbstractLabelOperator,\n  type AbstractQuery,\n  type DataQuery,\n  dateMath,\n  type DateTime,\n  incrRoundDn,\n  type TimeRange,\n} from '@grafana/data';\n\nimport { addLabelToQuery } from './add_label_to_query';\nimport { getCacheDurationInMinutes } from './caching';\nimport { PROMETHEUS_QUERY_BUILDER_MAX_RESULTS } from './constants';\nimport {\n  PrometheusCacheLevel,\n  type PromMetricsMetadata,\n  type PromMetricsMetadataItem,\n  type RecordingRuleIdentifier,\n} from './types';\n\nexport const processHistogramMetrics = (metrics: string[]) => {\n  const resultSet: Set<string> = new Set();\n  const regexp = new RegExp('_bucket($|:)');\n  for (let index = 0; index < metrics.length; index++) {\n    const metric = metrics[index];\n    const isHistogramValue = regexp.test(metric);\n    if (isHistogramValue) {\n      resultSet.add(metric);\n    }\n  }\n  return [...resultSet];\n};\n\n// This will capture 4 groups. Example label filter => {instance=\"10.4.11.4:9003\"}\n// 1. label:    instance\n// 2. operator: =\n// 3. value:    \"10.4.11.4:9003\"\n// 4. comma:    if there is a comma it will give ,\n// 5. space:    if there is a space after comma it will give the whole space\n// comma and space is useful for addLabelsToExpression function\nconst labelRegexp = /\\b(\\w+)(!?=~?)(\"[^\"\\n]*?\")(,)?(\\s*)?/g;\n\nexport function expandRecordingRules(query: string, mapping: { [name: string]: RecordingRuleIdentifier }): string {\n  const getRuleRegex = (ruleName: string) => new RegExp(`(\\\\s|\\\\(|^)(${ruleName})(\\\\s|$|\\\\(|\\\\[|\\\\{)`, 'ig');\n\n  // For each mapping key we iterate over the query and split them in parts.\n  // recording:rule{label=~\"/label/value\"} * some:other:rule{other_label=\"value\"}\n  // We want to keep parts in here like this:\n  // recording:rule\n  // {label=~\"/label/value\"} *\n  // some:other:rule\n  // {other_label=\"value\"}\n  const tmpSplitParts = Object.keys(mapping).reduce<string[]>(\n    (prev, curr) => {\n      let parts: string[] = [];\n      let tmpParts: string[] = [];\n      let removeIdx: number[] = [];\n\n      // we iterate over prev because it might be like this after first loop\n      // recording:rule and {label=~\"/label/value\"} * some:other:rule{other_label=\"value\"}\n      // so we need to split the second part too\n      prev.filter(Boolean).forEach((p, i) => {\n        const doesMatch = p.match(getRuleRegex(curr));\n        if (doesMatch) {\n          parts = p.split(curr);\n          if (parts.length === 2) {\n            // this is the case when we have such result for this query\n            // max (metric{label=\"value\"})\n            // \"max(\", \"{label=\"value\"}\"\n            removeIdx.push(i);\n            tmpParts.push(...[parts[0], curr, parts[1]].filter(Boolean));\n          } else if (parts.length > 2) {\n            // this is the case when we have such query\n            // metric + metric\n            // when we split it we have such data\n            // \"\", \" + \", \"\"\n            removeIdx.push(i);\n            parts = parts.map((p) => (p === '' ? curr : p));\n            tmpParts.push(...parts);\n          }\n        }\n      });\n\n      // if we have idx to remove that means we split the value in that index.\n      // No need to keep it. Have the new split values instead.\n      removeIdx.forEach((ri) => (prev[ri] = ''));\n      prev = prev.filter(Boolean);\n      prev.push(...tmpParts);\n\n      return prev;\n    },\n    [query]\n  );\n\n  // we have the separate parts. we need to replace the metric and apply the labels if there is any\n  let labelFound = false;\n  const trulyExpandedQuery = tmpSplitParts.map((tsp, i) => {\n    // if we know this loop tsp is a label, not the metric we want to expand\n    if (labelFound) {\n      labelFound = false;\n      return '';\n    }\n\n    // check if the mapping is there\n    if (mapping[tsp]) {\n      const { expandedQuery: recordingRule, identifierValue, identifier } = mapping[tsp];\n      // it is a recording rule. if the following is a label then apply it\n      if (i + 1 !== tmpSplitParts.length && tmpSplitParts[i + 1].match(labelRegexp)) {\n        // the next value in the loop is label. Let's apply labels to the metric\n        labelFound = true;\n        const regexp = new RegExp(`(,)?(\\\\s)?(${identifier}=\\\\\"${identifierValue}\\\\\")(,)?(\\\\s)?`, 'g');\n        const labels = tmpSplitParts[i + 1].replace(regexp, '');\n        const invalidLabelsRegex = /(\\)\\{|\\}\\{|\\]\\{)/;\n        return addLabelsToExpression(recordingRule + labels, invalidLabelsRegex);\n      } else {\n        // it is not a recording rule and might be a binary operation in between two recording rules\n        // So no need to do anything. just return it.\n        return recordingRule;\n      }\n    }\n\n    return tsp;\n  });\n\n  // Remove empty strings and merge them\n  return trulyExpandedQuery.filter(Boolean).join('');\n}\n\nfunction addLabelsToExpression(expr: string, invalidLabelsRegexp: RegExp) {\n  const match = expr.match(invalidLabelsRegexp);\n  if (!match) {\n    return expr;\n  }\n\n  // Split query into 2 parts - before the invalidLabelsRegex match and after.\n  const indexOfRegexMatch = match.index ?? 0;\n  const exprBeforeRegexMatch = expr.slice(0, indexOfRegexMatch + 1);\n  const exprAfterRegexMatch = expr.slice(indexOfRegexMatch + 1);\n\n  // Create arrayOfLabelObjects with label objects that have key, operator and value.\n  const arrayOfLabelObjects: Array<{\n    key: string;\n    operator: string;\n    value: string;\n    comma?: string;\n    space?: string;\n  }> = [];\n  exprAfterRegexMatch.replace(labelRegexp, (label, key, operator, value, comma, space) => {\n    arrayOfLabelObjects.push({ key, operator, value, comma, space });\n    return '';\n  });\n\n  // Loop through all label objects and add them to query.\n  // As a starting point we have valid query without the labels.\n  let result = exprBeforeRegexMatch;\n  arrayOfLabelObjects.filter(Boolean).forEach((obj) => {\n    // Remove extra set of quotes from obj.value\n    const value = obj.value.slice(1, -1);\n    result = addLabelToQuery(result, obj.key, value, obj.operator);\n  });\n\n  // reconstruct the labels\n  let existingLabel = arrayOfLabelObjects.reduce((prev, curr) => {\n    prev += `${curr.key}${curr.operator}${curr.value}${curr.comma ?? ''}${curr.space ?? ''}`;\n    return prev;\n  }, '');\n\n  // Check if there is anything besides labels\n  // Useful for this kind of metrics sum (recording_rule_metric{label1=\"value1\"}) by (env)\n  // if we don't check this part, ) by (env) part will be lost\n  existingLabel = '{' + existingLabel + '}';\n  const potentialLeftOver = exprAfterRegexMatch.replace(existingLabel, '');\n\n  return result + potentialLeftOver;\n}\n\n/**\n * Adds metadata for synthetic metrics for which the API does not provide metadata.\n * See https://github.com/grafana/grafana/issues/22337 for details.\n *\n * @param metadata HELP and TYPE metadata from /api/v1/metadata\n */\nexport function fixSummariesMetadata(metadata: { [metric: string]: PromMetricsMetadataItem[] }): PromMetricsMetadata {\n  if (!metadata) {\n    return metadata;\n  }\n  const baseMetadata: PromMetricsMetadata = {};\n  const summaryMetadata: PromMetricsMetadata = {};\n  for (const metric in metadata) {\n    // NOTE: based on prometheus-documentation, we can receive\n    // multiple metadata-entries for the given metric, it seems\n    // it happens when the same metric is on multiple targets\n    // and their help-text differs\n    // (https://prometheus.io/docs/prometheus/latest/querying/api/#querying-metric-metadata)\n    // for now we just use the first entry.\n    const item = metadata[metric][0];\n    baseMetadata[metric] = item;\n\n    if (item.type === 'histogram') {\n      summaryMetadata[`${metric}_bucket`] = {\n        type: 'counter',\n        help: `Cumulative counters for the observation buckets (${item.help})`,\n      };\n      summaryMetadata[`${metric}_count`] = {\n        type: 'counter',\n        help: `Count of events that have been observed for the histogram metric (${item.help})`,\n      };\n      summaryMetadata[`${metric}_sum`] = {\n        type: 'counter',\n        help: `Total sum of all observed values for the histogram metric (${item.help})`,\n      };\n    }\n    if (item.type === 'summary') {\n      summaryMetadata[`${metric}_count`] = {\n        type: 'counter',\n        help: `Count of events that have been observed for the base metric (${item.help})`,\n      };\n      summaryMetadata[`${metric}_sum`] = {\n        type: 'counter',\n        help: `Total sum of all observed values for the base metric (${item.help})`,\n      };\n    }\n  }\n  // Synthetic series\n  const syntheticMetadata: PromMetricsMetadata = {};\n  syntheticMetadata['ALERTS'] = {\n    type: 'gauge',\n    help: 'Time series showing pending and firing alerts. The sample value is set to 1 as long as the alert is in the indicated active (pending or firing) state.',\n  };\n\n  return { ...baseMetadata, ...summaryMetadata, ...syntheticMetadata };\n}\n\nexport function roundMsToMin(milliseconds: number): number {\n  return roundSecToMin(milliseconds / 1000);\n}\n\nfunction roundSecToMin(seconds: number): number {\n  return Math.floor(seconds / 60);\n}\n\n// Returns number of minutes rounded up to the nearest nth minute\nfunction roundSecToNextMin(seconds: number, secondsToRound = 1): number {\n  return Math.ceil(seconds / 60) - (Math.ceil(seconds / 60) % secondsToRound);\n}\n\nconst FromPromLikeMap: Record<string, AbstractLabelOperator> = {\n  '=': AbstractLabelOperator.Equal,\n  '!=': AbstractLabelOperator.NotEqual,\n  '=~': AbstractLabelOperator.EqualRegEx,\n  '!~': AbstractLabelOperator.NotEqualRegEx,\n};\n\nconst ToPromLikeMap: Record<AbstractLabelOperator, string> = invert(FromPromLikeMap) as Record<\n  AbstractLabelOperator,\n  string\n>;\n\nfunction toPromLikeExpr(labelBasedQuery: AbstractQuery): string {\n  const expr = labelBasedQuery.labelMatchers\n    .map((selector: AbstractLabelMatcher) => {\n      const operator = ToPromLikeMap[selector.operator];\n      if (operator) {\n        return `${selector.name}${operator}\"${selector.value}\"`;\n      } else {\n        return '';\n      }\n    })\n    .filter((e: string) => e !== '')\n    .join(', ');\n\n  return expr ? `{${expr}}` : '';\n}\n\nexport function toPromLikeQuery(labelBasedQuery: AbstractQuery): PromLikeQuery {\n  return {\n    refId: labelBasedQuery.refId,\n    expr: toPromLikeExpr(labelBasedQuery),\n    range: true,\n  };\n}\n\ninterface PromLikeQuery extends DataQuery {\n  expr: string;\n  range: boolean;\n}\n\nfunction getMaybeTokenStringContent(token: Token): string {\n  if (typeof token.content === 'string') {\n    return token.content;\n  }\n\n  return '';\n}\n\nexport function extractLabelMatchers(tokens: Array<string | Token>): AbstractLabelMatcher[] {\n  const labelMatchers: AbstractLabelMatcher[] = [];\n\n  for (const token of tokens) {\n    if (!(token instanceof Token)) {\n      continue;\n    }\n\n    if (token.type === 'context-labels') {\n      let labelKey = '';\n      let labelValue = '';\n      let labelOperator = '';\n\n      const contentTokens = Array.isArray(token.content) ? token.content : [token.content];\n\n      for (let currentToken of contentTokens) {\n        if (typeof currentToken === 'string') {\n          let currentStr: string;\n          currentStr = currentToken;\n          if (currentStr === '=' || currentStr === '!=' || currentStr === '=~' || currentStr === '!~') {\n            labelOperator = currentStr;\n          }\n        } else if (currentToken instanceof Token) {\n          switch (currentToken.type) {\n            case 'label-key':\n              labelKey = getMaybeTokenStringContent(currentToken);\n              break;\n            case 'label-value':\n              labelValue = getMaybeTokenStringContent(currentToken);\n              labelValue = labelValue.substring(1, labelValue.length - 1);\n              const labelComparator = FromPromLikeMap[labelOperator];\n              if (labelComparator) {\n                labelMatchers.push({ name: labelKey, operator: labelComparator, value: labelValue });\n              }\n              break;\n          }\n        }\n      }\n    }\n  }\n\n  return labelMatchers;\n}\n\n/**\n * Calculates new interval \"snapped\" to the closest Nth minute, depending on cache level datasource setting\n * @param cacheLevel\n * @param range\n */\nexport function getRangeSnapInterval(\n  cacheLevel: PrometheusCacheLevel,\n  range: TimeRange\n): {\n  start: string;\n  end: string;\n} {\n  // Don't round the range if we're not caching\n  if (cacheLevel === PrometheusCacheLevel.None) {\n    return {\n      start: getPrometheusTime(range.from, false).toString(),\n      end: getPrometheusTime(range.to, true).toString(),\n    };\n  }\n  // Otherwise round down to the nearest nth minute for the start time\n  const startTime = getPrometheusTime(range.from, false);\n  const startTimeQuantizedSeconds = incrRoundDn(startTime, getCacheDurationInMinutes(cacheLevel) * 60);\n\n  // And round up to the nearest nth minute for the end time\n  const endTime = getPrometheusTime(range.to, true);\n  const endTimeQuantizedSeconds = roundSecToNextMin(endTime, getCacheDurationInMinutes(cacheLevel)) * 60;\n\n  // If the interval was too short, we could have rounded both start and end to the same time, if so let's add one step to the end\n  if (startTimeQuantizedSeconds === endTimeQuantizedSeconds) {\n    const endTimePlusOneStep = endTimeQuantizedSeconds + getCacheDurationInMinutes(cacheLevel) * 60;\n    return { start: startTimeQuantizedSeconds.toString(), end: endTimePlusOneStep.toString() };\n  }\n\n  const start = startTimeQuantizedSeconds.toString();\n  const end = endTimeQuantizedSeconds.toString();\n\n  return { start, end };\n}\n\nexport function getPrometheusTime(date: string | DateTime, roundUp: boolean) {\n  if (typeof date === 'string') {\n    date = dateMath.parse(date, roundUp)!;\n  }\n\n  return Math.ceil(date.valueOf() / 1000);\n}\n\n/**\n * Used to truncate metrics, label names and label value in the query builder select components\n * to improve frontend performance. This is best used with an async select component including\n * the loadOptions property where we should still allow users to search all results with a string.\n * This can be done either storing the total results or querying an api that allows for matching a query.\n *\n * @param array\n * @param limit\n * @returns\n */\nexport function truncateResult<T>(array: T[], limit?: number): T[] {\n  if (limit === undefined) {\n    limit = PROMETHEUS_QUERY_BUILDER_MAX_RESULTS;\n  }\n  array.length = Math.min(array.length, limit);\n  return array;\n}\n\n/**\n * Removes quotes from a string if they exist.\n * Used to handle utf8 label keys in Prometheus queries.\n *\n * @param {string} input - Input string that may have surrounding quotes\n * @returns {string} String with surrounding quotes removed if they existed\n */\nexport function removeQuotesIfExist(input: string): string {\n  const match = input.match(/^\"(.*)\"$/); // extract the content inside the quotes\n  return match?.[1] ?? input;\n}\n"],"names":["p","_a"],"mappings":"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"}