{"version":3,"file":"language_provider.cjs","sources":["../../src/language_provider.ts"],"sourcesContent":["// Core Grafana history https://github.com/grafana/grafana/blob/v11.0.0-preview/public/app/plugins/datasource/prometheus/language_provider.ts\nimport Prism from 'prismjs';\n\nimport {\n  type AbstractLabelMatcher,\n  AbstractLabelOperator,\n  type AbstractQuery,\n  type AdHocVariableFilter,\n  getDefaultTimeRange,\n  type Scope,\n  scopeFilterOperatorMap,\n  type ScopeSpecFilter,\n  type TimeRange,\n} from '@grafana/data';\nimport { type BackendSrvRequest } from '@grafana/runtime';\n\nimport { buildCacheHeaders, getDaysToCacheMetadata, getDefaultCacheHeaders } from './caching';\nimport { type PrometheusDatasource } from './datasource';\nimport { extractLabelMatchers, fixSummariesMetadata, toPromLikeQuery } from './language_utils';\nimport { promqlGrammar } from './promql';\nimport { buildVisualQueryFromString } from './querybuilder/parsing';\nimport { LabelsApiClient, type ResourceApiClient, SeriesApiClient } from './resource_clients';\nimport { type PromMetricsMetadata, type PromQuery } from './types';\n\ninterface PrometheusBaseLanguageProvider {\n  datasource: PrometheusDatasource;\n\n  /**\n   * When no timeRange provided, we will use the default time range (now/now-6h)\n   * @param timeRange\n   */\n  start: (timeRange?: TimeRange) => Promise<unknown[]>;\n\n  request: (url: string, params?: any, options?: Partial<BackendSrvRequest>) => Promise<any>;\n\n  fetchSuggestions: (\n    timeRange?: TimeRange,\n    queries?: PromQuery[],\n    scopes?: Scope[],\n    adhocFilters?: AdHocVariableFilter[],\n    labelName?: string,\n    limit?: number,\n    requestId?: string\n  ) => Promise<string[]>;\n}\n\n/**\n * Modern implementation of the Prometheus language provider that abstracts API endpoint selection.\n *\n * Features:\n * - Automatically selects the most efficient API endpoint based on Prometheus version and configuration\n * - Supports both labels and series endpoints for backward compatibility\n * - Handles match[] parameters for filtering time series data\n * - Implements automatic request limiting (default: 40,000 series if not configured otherwise)\n * - Provides unified interface for both modern and legacy Prometheus versions\n * - Provides caching mechanism based on time range, limit, and match parameters\n *\n * @see LabelsApiClient For modern Prometheus versions using the labels API\n * @see SeriesApiClient For legacy Prometheus versions using the series API\n */\nexport interface PrometheusLanguageProviderInterface extends PrometheusBaseLanguageProvider {\n  /**\n   * Initializes the language provider by fetching metrics, label keys, and metrics metadata using Resource Clients.\n   * All calls use the limit parameter from datasource configuration (default: 40,000 if not set).\n   *\n   * For backward compatibility, it calls _backwardCompatibleStart.\n   * Some places still rely on deprecated fields. Until we replace them, we need _backwardCompatibleStart method.\n   */\n  start: (timeRange?: TimeRange) => Promise<unknown[]>;\n\n  /**\n   * Returns already cached metrics metadata including type and help information.\n   * If there is no cached metadata, it returns an empty object.\n   * To get fresh metadata, use queryMetricsMetadata instead.\n   */\n  retrieveMetricsMetadata: () => PromMetricsMetadata;\n\n  /**\n   * Returns already cached list of histogram metrics (identified by '_bucket' suffix).\n   * If there are no cached histogram metrics, it returns an empty array.\n   */\n  retrieveHistogramMetrics: () => string[];\n\n  /**\n   * Returns already cached list of all available metric names.\n   * If there are no cached metrics, it returns an empty array.\n   */\n  retrieveMetrics: () => string[];\n\n  /**\n   * Returns already cached list of available label keys.\n   * If there are no cached label keys, it returns an empty array.\n   */\n  retrieveLabelKeys: () => string[];\n\n  /**\n   * Fetches fresh metrics metadata from Prometheus with optional limit.\n   * Uses datasource's default limit if not specified.\n   */\n  queryMetricsMetadata: (limit?: number) => Promise<PromMetricsMetadata>;\n\n  /**\n   * Queries Prometheus for label keys within time range, optionally filtered by match selector.\n   * Automatically selects labels or series endpoint based on datasource configuration.\n   * If no limit is provided, uses the datasource's default limit configuration.\n   * Use zero (0) to fetch all label keys, but this might return huge amounts of data.\n   */\n  queryLabelKeys: (timeRange: TimeRange, match?: string, limit?: number) => Promise<string[]>;\n\n  /**\n   * Queries Prometheus for values of a specific label key, optionally filtered by match selector.\n   * Automatically selects labels or series endpoint based on datasource configuration.\n   * If no limit is provided, uses the datasource's default limit configuration.\n   * Use zero (0) to fetch all label values, but this might return huge amounts of data.\n   */\n  queryLabelValues: (timeRange: TimeRange, labelKey: string, match?: string, limit?: number) => Promise<string[]>;\n}\n\nexport class PrometheusLanguageProvider implements PrometheusLanguageProviderInterface {\n  public datasource: PrometheusDatasource;\n\n  private _metricsMetadata?: PromMetricsMetadata;\n  private _resourceClient?: ResourceApiClient;\n\n  constructor(datasource: PrometheusDatasource) {\n    this.datasource = datasource;\n  }\n\n  request = async (url: string, params = {}, options?: Partial<BackendSrvRequest>) => {\n    try {\n      const res = await this.datasource.metadataRequest(url, params, options);\n      return res.data.data;\n    } catch (error) {\n      if (!isCancelledError(error)) {\n        console.error(error);\n      }\n    }\n\n    return undefined;\n  };\n\n  /**\n   * Lazily initializes and returns the appropriate resource client based on Prometheus version.\n   *\n   * The client selection logic:\n   * - For Prometheus v2.6+ with labels API: Uses LabelsApiClient for efficient label-based queries\n   * - For older versions: Falls back to SeriesApiClient for backward compatibility\n   *\n   * The client instance is cached after first initialization to avoid repeated creation.\n   *\n   * @returns {ResourceApiClient} An instance of either LabelsApiClient or SeriesApiClient\n   */\n  private get resourceClient(): ResourceApiClient {\n    if (!this._resourceClient) {\n      this._resourceClient = this.datasource.hasLabelsMatchAPISupport()\n        ? new LabelsApiClient(this.request, this.datasource)\n        : new SeriesApiClient(this.request, this.datasource);\n    }\n\n    return this._resourceClient;\n  }\n\n  /**\n   * Same start logic but it uses resource clients. Backward compatibility it calls _backwardCompatibleStart.\n   * Some places still relies on deprecated fields. Until we replace them we need _backwardCompatibleStart method\n   */\n  start = async (timeRange: TimeRange = getDefaultTimeRange()): Promise<unknown[]> => {\n    if (this.datasource.lookupsDisabled) {\n      return [];\n    }\n    return await Promise.all([\n      this.resourceClient.start(timeRange),\n      this.queryMetricsMetadata(this.datasource.seriesLimit),\n    ]);\n  };\n\n  /**\n   * Fetches metadata for metrics from Prometheus.\n   * Sets cache headers based on the configured metadata cache duration.\n   *\n   * @returns {Promise<PromMetricsMetadata>} Promise that resolves when metadata has been fetched\n   */\n  private _queryMetadata = async (limit?: number): Promise<PromMetricsMetadata> => {\n    const secondsInDay = 86400;\n    const headers = buildCacheHeaders(getDaysToCacheMetadata(this.datasource.cacheLevel) * secondsInDay);\n    const metadata = await this.request(\n      `/api/v1/metadata`,\n      { limit: limit ?? this.datasource.seriesLimit },\n      {\n        showErrorAlert: false,\n        ...headers,\n      }\n    );\n    return fixSummariesMetadata(metadata);\n  };\n\n  /**\n   * Retrieves the cached Prometheus metrics metadata.\n   * This metadata includes type information (counter, gauge, etc.) and help text for metrics.\n   *\n   * @returns {PromMetricsMetadata} Cached metadata or empty object if not yet fetched\n   */\n  public retrieveMetricsMetadata = (): PromMetricsMetadata => {\n    return this._metricsMetadata ?? {};\n  };\n\n  /**\n   * Retrieves the list of histogram metrics from the current resource client.\n   * Histogram metrics are identified by the '_bucket' suffix and are used for percentile calculations.\n   *\n   * @returns {string[]} Array of histogram metric names\n   */\n  public retrieveHistogramMetrics = (): string[] => {\n    return this.resourceClient?.histogramMetrics;\n  };\n\n  /**\n   * Retrieves the complete list of available metrics from the current resource client.\n   * This includes all metric names regardless of their type (counter, gauge, histogram).\n   *\n   * @returns {string[]} Array of all metric names\n   */\n  public retrieveMetrics = (): string[] => {\n    return this.resourceClient?.metrics;\n  };\n\n  /**\n   * Retrieves the list of available label keys from the current resource client.\n   * Label keys are the names of labels that can be used to filter and group metrics.\n   *\n   * @returns {string[]} Array of label key names\n   */\n  public retrieveLabelKeys = (): string[] => {\n    return this.resourceClient?.labelKeys;\n  };\n\n  /**\n   * Fetches fresh metrics metadata from Prometheus and updates the cache.\n   * This includes querying for metric types, help text, and unit information.\n   * If the fetch fails, the cache is set to an empty object to prevent stale data.\n   *\n   * @returns {Promise<PromMetricsMetadata>} Promise that resolves to the fetched metadata\n   */\n  public queryMetricsMetadata = async (limit?: number): Promise<PromMetricsMetadata> => {\n    try {\n      this._metricsMetadata = (await this._queryMetadata(limit)) ?? {};\n    } catch (error) {\n      this._metricsMetadata = {};\n    }\n    return this._metricsMetadata;\n  };\n\n  /**\n   * Fetches all available label keys that match the specified criteria.\n   *\n   * This method queries Prometheus for label keys within the specified time range.\n   * The results can be filtered using the match parameter and limited in size.\n   * Uses either the labels API (Prometheus v2.6+) or series API based on version.\n   *\n   * @param {TimeRange} timeRange - Time range to search for label keys\n   * @param {string} [match] - Optional PromQL selector to filter label keys (e.g., '{job=\"grafana\"}')\n   * @param {string} [limit] - Optional maximum number of label keys to return\n   * @returns {Promise<string[]>} Array of matching label key names, sorted alphabetically\n   */\n  public queryLabelKeys = async (timeRange: TimeRange, match?: string, limit?: number): Promise<string[]> => {\n    const interpolatedMatch = match ? this.datasource.interpolateString(match) : match;\n    return await this.resourceClient.queryLabelKeys(timeRange, interpolatedMatch, limit);\n  };\n\n  /**\n   * Fetches all values for a specific label key that match the specified criteria.\n   *\n   * This method queries Prometheus for label values within the specified time range.\n   * Results can be filtered using the match parameter to find values in specific contexts.\n   * Supports both modern (labels API) and legacy (series API) Prometheus versions.\n   *\n   * The method automatically handles UTF-8 encoded label keys by properly escaping them\n   * before making API requests. This means you can safely pass label keys containing\n   * special characters like dots, colons, or Unicode characters (e.g., 'http.status:code',\n   * 'μs', 'response.time').\n   *\n   * @param {TimeRange} timeRange - Time range to search for label values\n   * @param {string} labelKey - The label key to fetch values for (e.g., 'job', 'instance', 'http.status:code')\n   * @param {string} [match] - Optional PromQL selector to filter values (e.g., '{job=\"grafana\"}')\n   * @param {string} [limit] - Optional maximum number of values to return\n   * @returns {Promise<string[]>} Array of matching label values, sorted alphabetically\n   * @example\n   * // Fetch all values for the 'job' label\n   * const values = await queryLabelValues(timeRange, 'job');\n   * // Fetch 'instance' values only for jobs matching 'grafana'\n   * const instances = await queryLabelValues(timeRange, 'instance', '{job=\"grafana\"}');\n   * // Fetch values for a label key with special characters\n   * const statusCodes = await queryLabelValues(timeRange, 'http.status:code');\n   */\n  public queryLabelValues = async (\n    timeRange: TimeRange,\n    labelKey: string,\n    match?: string,\n    limit?: number\n  ): Promise<string[]> => {\n    const interpolatedMatch = match ? this.datasource.interpolateString(match) : match;\n    return await this.resourceClient.queryLabelValues(\n      timeRange,\n      this.datasource.interpolateString(labelKey),\n      interpolatedMatch,\n      limit\n    );\n  };\n\n  /**\n   * Fetch labels or values for a label based on the queries, scopes, filters and time range\n   */\n  fetchSuggestions = async (\n    timeRange?: TimeRange,\n    queries?: PromQuery[],\n    scopes?: Scope[],\n    adhocFilters?: AdHocVariableFilter[],\n    labelName?: string,\n    limit?: number,\n    requestId?: string\n  ): Promise<string[]> => {\n    if (!timeRange) {\n      timeRange = getDefaultTimeRange();\n    }\n\n    const url = '/suggestions';\n    const timeParams = this.datasource.getAdjustedInterval(timeRange);\n    const value = await this.request(\n      url,\n      {\n        labelName,\n        queries: queries?.map((q) =>\n          this.datasource.interpolateString(q.expr, {\n            ...this.datasource.getIntervalVars(),\n            ...this.datasource.getRangeScopedVars(timeRange),\n          })\n        ),\n        scopes: scopes?.reduce<ScopeSpecFilter[]>((acc, scope) => {\n          if (scope.spec.filters) {\n            acc.push(...scope.spec.filters);\n          }\n\n          return acc;\n        }, []),\n        adhocFilters: adhocFilters?.map((filter) => ({\n          key: filter.key,\n          operator: scopeFilterOperatorMap[filter.operator],\n          value: filter.value,\n          values: filter.values,\n        })),\n        limit,\n        ...timeParams,\n      },\n      {\n        ...(requestId && { requestId }),\n        headers: {\n          ...getDefaultCacheHeaders(this.datasource.cacheLevel)?.headers,\n          'Content-Type': 'application/json',\n        },\n        method: 'POST',\n      }\n    );\n\n    return value ?? [];\n  };\n}\n\nexport const importFromAbstractQuery = (labelBasedQuery: AbstractQuery): PromQuery => {\n  return toPromLikeQuery(labelBasedQuery);\n};\n\nexport const exportToAbstractQuery = (query: PromQuery): AbstractQuery => {\n  const promQuery = query.expr;\n  if (!promQuery || promQuery.length === 0) {\n    return { refId: query.refId, labelMatchers: [] };\n  }\n  const tokens = Prism.tokenize(promQuery, promqlGrammar);\n  const labelMatchers: AbstractLabelMatcher[] = extractLabelMatchers(tokens);\n  const nameLabelValue = getNameLabelValue(promQuery, tokens);\n  if (nameLabelValue && nameLabelValue.length > 0) {\n    labelMatchers.push({\n      name: '__name__',\n      operator: AbstractLabelOperator.Equal,\n      value: nameLabelValue,\n    });\n  }\n\n  return {\n    refId: query.refId,\n    labelMatchers,\n  };\n};\n\n/**\n * Checks if an error is a cancelled request error.\n * Used to avoid logging cancelled request errors.\n *\n * @param {unknown} error - Error to check\n * @returns {boolean} True if the error is a cancelled request error\n */\nfunction isCancelledError(error: unknown): error is {\n  cancelled: boolean;\n} {\n  return typeof error === 'object' && error !== null && 'cancelled' in error && error.cancelled === true;\n}\n\nfunction getNameLabelValue(promQuery: string, tokens: Array<string | Prism.Token>): string {\n  let nameLabelValue = '';\n\n  for (const token of tokens) {\n    if (typeof token === 'string') {\n      nameLabelValue = token;\n      break;\n    }\n  }\n  return nameLabelValue;\n}\n\n/**\n * Extracts metrics from queries and populates match parameters.\n * This is used to filter time series data based on existing queries.\n * Handles UTF8 metrics by properly escaping them.\n *\n * @param {PromQuery[]} queries - Array of Prometheus queries\n * @returns {string[]} Metric names as a regex matcher inside the array for easy handling\n */\nexport const populateMatchParamsFromQueries = (queries?: PromQuery[]): string[] => {\n  if (!queries) {\n    return [];\n  }\n\n  const metrics = (queries ?? []).reduce<string[]>((params, query) => {\n    const visualQuery = buildVisualQueryFromString(query.expr);\n    if (visualQuery.query.metric !== '') {\n      params.push(visualQuery.query.metric);\n    }\n    if (visualQuery.query.binaryQueries) {\n      visualQuery.query.binaryQueries.forEach((bq) => {\n        if (bq.query.metric !== '') {\n          params.push(bq.query.metric);\n        }\n      });\n    }\n    return params;\n  }, []);\n\n  return metrics.length === 0 ? [] : [`__name__=~\"${metrics.join('|')}\"`];\n};\n"],"names":["getDefaultTimeRange","buildCacheHeaders","getDaysToCacheMetadata","fixSummariesMetadata","scopeFilterOperatorMap","getDefaultCacheHeaders","LabelsApiClient","SeriesApiClient","toPromLikeQuery","Prism","promqlGrammar","extractLabelMatchers","AbstractLabelOperator","buildVisualQueryFromString"],"mappings":"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"}