From 3424b642992e6626fcc3b326178cb109f65bb398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=A4ggmark?= Date: Tue, 18 Jun 2019 11:01:12 +0200 Subject: [PATCH] Typescript: Removes implicit anys (#17625) * Chore: Remove implicit anys from ResultProcessor and tests * Chore: Removes implicit anys for /loki/**/*.ts * Chore: Removes implicit anys for prometheus/**/* --- .../explore/utils/ResultProcessor.test.ts | 26 +++--- .../features/explore/utils/ResultProcessor.ts | 10 ++- .../datasource/loki/datasource.test.ts | 10 +-- .../app/plugins/datasource/loki/datasource.ts | 16 ++-- .../datasource/loki/language_provider.test.ts | 19 +++-- .../prometheus/add_label_to_query.ts | 2 +- .../datasource/prometheus/completer.ts | 67 +++++++++------ .../datasource/prometheus/config_ctrl.ts | 2 +- .../datasource/prometheus/datasource.ts | 83 +++++++++++-------- .../prometheus/metric_find_query.ts | 35 ++++---- .../datasource/prometheus/query_ctrl.ts | 5 +- .../datasource/prometheus/query_hints.ts | 16 ++-- .../prometheus/result_transformer.ts | 21 ++--- .../prometheus/specs/completer.test.ts | 16 ++-- .../prometheus/specs/datasource.test.ts | 47 ++++++----- .../specs/language_provider.test.ts | 3 +- .../specs/metric_find_query.test.ts | 3 +- .../specs/result_transformer.test.ts | 11 +-- .../plugins/datasource/prometheus/types.ts | 1 + 19 files changed, 226 insertions(+), 167 deletions(-) diff --git a/public/app/features/explore/utils/ResultProcessor.test.ts b/public/app/features/explore/utils/ResultProcessor.test.ts index 4979afa538c..4420450c221 100644 --- a/public/app/features/explore/utils/ResultProcessor.test.ts +++ b/public/app/features/explore/utils/ResultProcessor.test.ts @@ -11,7 +11,7 @@ jest.mock('@grafana/ui/src/utils/moment_wrapper', () => ({ import { ResultProcessor } from './ResultProcessor'; import { ExploreItemState, ExploreMode } from 'app/types/explore'; import TableModel from 'app/core/table_model'; -import { toFixed } from '@grafana/ui'; +import { toFixed, TimeSeries, LogRowModel, LogsMetaItem } from '@grafana/ui'; const testContext = (options: any = {}) => { const response = [ @@ -47,9 +47,9 @@ const testContext = (options: any = {}) => { mode: ExploreMode.Metrics, replacePreviousResults: true, result: { data: response }, - graphResult: [], + graphResult: [] as TimeSeries[], tableResult: new TableModel(), - logsResult: { hasUniqueLabels: false, rows: [] }, + logsResult: { hasUniqueLabels: false, rows: [] as LogRowModel[] }, }; const combinedOptions = { ...defaultOptions, ...options }; const state = ({ @@ -174,7 +174,7 @@ describe('ResultProcessor', () => { labels: undefined, logLevel: 'unknown', raw: 'This is a message', - searchWords: [], + searchWords: [] as string[], timeEpochMs: 1559038519831, timeFromNow: 'fromNow() jest mocked', timeLocal: 'format() jest mocked', @@ -187,7 +187,7 @@ describe('ResultProcessor', () => { labels: undefined, logLevel: 'unknown', raw: 'This is a message', - searchWords: [], + searchWords: [] as string[], timeEpochMs: 1559038518831, timeFromNow: 'fromNow() jest mocked', timeLocal: 'format() jest mocked', @@ -317,7 +317,7 @@ describe('ResultProcessor', () => { labels: { cluster: 'some-cluster' }, logLevel: 'unknown', raw: 'This is a previous message 1', - searchWords: [], + searchWords: [] as string[], timeEpochMs: 1558038519831, timeFromNow: 'fromNow() jest mocked', timeLocal: 'format() jest mocked', @@ -331,7 +331,7 @@ describe('ResultProcessor', () => { labels: { cluster: 'some-cluster' }, logLevel: 'unknown', raw: 'This is a previous message 2', - searchWords: [], + searchWords: [] as string[], timeEpochMs: 1558038518831, timeFromNow: 'fromNow() jest mocked', timeLocal: 'format() jest mocked', @@ -362,7 +362,7 @@ describe('ResultProcessor', () => { const theResult = resultProcessor.getLogsResult(); const expected = { hasUniqueLabels: false, - meta: [], + meta: [] as LogsMetaItem[], rows: [ { entry: 'This is a previous message 1', @@ -371,7 +371,7 @@ describe('ResultProcessor', () => { labels: { cluster: 'some-cluster' }, logLevel: 'unknown', raw: 'This is a previous message 1', - searchWords: [], + searchWords: [] as string[], timeEpochMs: 1558038519831, timeFromNow: 'fromNow() jest mocked', timeLocal: 'format() jest mocked', @@ -385,7 +385,7 @@ describe('ResultProcessor', () => { labels: { cluster: 'some-cluster' }, logLevel: 'unknown', raw: 'This is a previous message 2', - searchWords: [], + searchWords: [] as string[], timeEpochMs: 1558038518831, timeFromNow: 'fromNow() jest mocked', timeLocal: 'format() jest mocked', @@ -399,7 +399,7 @@ describe('ResultProcessor', () => { labels: undefined, logLevel: 'unknown', raw: 'This is a message', - searchWords: [], + searchWords: [] as string[], timeEpochMs: 1559038519831, timeFromNow: 'fromNow() jest mocked', timeLocal: 'format() jest mocked', @@ -413,7 +413,7 @@ describe('ResultProcessor', () => { labels: undefined, logLevel: 'unknown', raw: 'This is a message', - searchWords: [], + searchWords: [] as string[], timeEpochMs: 1559038518831, timeFromNow: 'fromNow() jest mocked', timeLocal: 'format() jest mocked', @@ -440,7 +440,7 @@ describe('ResultProcessor', () => { [39.91264531864214, 1559038518831], [40.35179822906545, 1559038519831], ], - unit: undefined, + unit: undefined as string, valueFormater: toFixed, }, ], diff --git a/public/app/features/explore/utils/ResultProcessor.ts b/public/app/features/explore/utils/ResultProcessor.ts index 2521c4914f8..7c4c27c5b22 100644 --- a/public/app/features/explore/utils/ResultProcessor.ts +++ b/public/app/features/explore/utils/ResultProcessor.ts @@ -66,7 +66,7 @@ export class ResultProcessor { return new TableModel(); } - const prevTableResults = this.state.tableResult || []; + const prevTableResults: any[] | TableModel = this.state.tableResult || []; const tablesToMerge = this.replacePreviousResults ? this.tables : [].concat(prevTableResults, this.tables); return mergeTablesIntoModel(new TableModel(), ...tablesToMerge); @@ -116,13 +116,17 @@ export class ResultProcessor { private isSameTimeSeries = (a: TimeSeries | TimeSeries2, b: TimeSeries | TimeSeries2) => { if (a.hasOwnProperty('id') && b.hasOwnProperty('id')) { - if (a['id'] !== undefined && b['id'] !== undefined && a['id'] === b['id']) { + const aValue = (a as TimeSeries2).id; + const bValue = (b as TimeSeries2).id; + if (aValue !== undefined && bValue !== undefined && aValue === bValue) { return true; } } if (a.hasOwnProperty('alias') && b.hasOwnProperty('alias')) { - if (a['alias'] !== undefined && b['alias'] !== undefined && a['alias'] === b['alias']) { + const aValue = (a as TimeSeries2).alias; + const bValue = (b as TimeSeries2).alias; + if (aValue !== undefined && bValue !== undefined && aValue === bValue) { return true; } } diff --git a/public/app/plugins/datasource/loki/datasource.test.ts b/public/app/plugins/datasource/loki/datasource.test.ts index 8200cf0f4a1..2a9c8a01f25 100644 --- a/public/app/plugins/datasource/loki/datasource.test.ts +++ b/public/app/plugins/datasource/loki/datasource.test.ts @@ -1,7 +1,7 @@ import LokiDatasource from './datasource'; import { LokiQuery } from './types'; import { getQueryOptions } from 'test/helpers/getQueryOptions'; -import { SeriesData } from '@grafana/ui'; +import { SeriesData, DataSourceApi } from '@grafana/ui'; import { BackendSrv } from 'app/core/services/backend_srv'; import { TemplateSrv } from 'app/features/templating/template_srv'; @@ -26,8 +26,8 @@ describe('LokiDatasource', () => { const backendSrv = (backendSrvMock as unknown) as BackendSrv; const templateSrvMock = ({ - getAdhocFilters: () => [], - replace: a => a, + getAdhocFilters: (): any[] => [], + replace: (a: string) => a, } as unknown) as TemplateSrv; test('should use default max lines when no limit given', () => { @@ -75,8 +75,8 @@ describe('LokiDatasource', () => { }); describe('when performing testDataSource', () => { - let ds; - let result; + let ds: DataSourceApi; + let result: any; describe('and call succeeds', () => { beforeEach(async () => { diff --git a/public/app/plugins/datasource/loki/datasource.ts b/public/app/plugins/datasource/loki/datasource.ts index b689d02ba13..55bb4f52609 100644 --- a/public/app/plugins/datasource/loki/datasource.ts +++ b/public/app/plugins/datasource/loki/datasource.ts @@ -23,6 +23,8 @@ import { DataStreamObserver, LoadingState, DataStreamState, + DataQueryResponse, + DateTime, } from '@grafana/ui'; import { LokiQuery, LokiOptions } from './types'; import { BackendSrv } from 'app/core/services/backend_srv'; @@ -70,7 +72,7 @@ export class LokiDatasource extends DataSourceApi { this.subscriptions = {}; } - _request(apiUrl: string, data?, options?: any) { + _request(apiUrl: string, data?: any, options?: any) { const baseUrl = this.instanceSettings.url; const params = data ? serializeParams(data) : ''; const url = `${baseUrl}${apiUrl}?${params}`; @@ -254,11 +256,11 @@ export class LokiDatasource extends DataSourceApi { return this.languageProvider.importQueries(queries, originMeta.id); } - metadataRequest(url) { + metadataRequest(url: string) { // HACK to get label values for {job=|}, will be replaced when implementing LokiQueryField const apiUrl = url.replace('v1', 'prom'); - return this._request(apiUrl, { silent: true }).then(res => { - const data = { data: { data: res.data.values || [] } }; + return this._request(apiUrl, { silent: true }).then((res: DataQueryResponse) => { + const data: any = { data: { data: res.data.values || [] } }; return data; }); } @@ -282,7 +284,7 @@ export class LokiDatasource extends DataSourceApi { return getHighlighterExpressionsFromQuery(query.expr); } - getTime(date, roundUp) { + getTime(date: string | DateTime, roundUp: boolean) { if (_.isString(date)) { date = dateMath.parse(date, roundUp); } @@ -357,7 +359,7 @@ export class LokiDatasource extends DataSourceApi { testDatasource() { return this._request('/api/prom/label') - .then(res => { + .then((res: DataQueryResponse) => { if (res && res.data && res.data.values && res.data.values.length > 0) { return { status: 'success', message: 'Data source connected and labels found.' }; } @@ -367,7 +369,7 @@ export class LokiDatasource extends DataSourceApi { 'Data source connected, but no labels received. Verify that Loki and Promtail is configured properly.', }; }) - .catch(err => { + .catch((err: any) => { let message = 'Loki: '; if (err.statusText) { message += err.statusText; diff --git a/public/app/plugins/datasource/loki/language_provider.test.ts b/public/app/plugins/datasource/loki/language_provider.test.ts index 53a3d37b0ac..301fbb30fcd 100644 --- a/public/app/plugins/datasource/loki/language_provider.test.ts +++ b/public/app/plugins/datasource/loki/language_provider.test.ts @@ -1,12 +1,14 @@ +// @ts-ignore import Plain from 'slate-plain-serializer'; import LanguageProvider, { LABEL_REFRESH_INTERVAL } from './language_provider'; import { advanceTo, clear, advanceBy } from 'jest-date-mock'; import { beforeEach } from 'test/lib/common'; +import { DataQueryResponseData } from '@grafana/ui'; describe('Language completion provider', () => { const datasource = { - metadataRequest: () => ({ data: { data: [] } }), + metadataRequest: () => ({ data: { data: [] as DataQueryResponseData[] } }), }; describe('empty query suggestions', () => { @@ -91,7 +93,7 @@ describe('Language completion provider', () => { describe('Query imports', () => { const datasource = { - metadataRequest: () => ({ data: { data: [] } }), + metadataRequest: () => ({ data: { data: [] as DataQueryResponseData[] } }), }; it('returns empty queries for unknown origin datasource', async () => { @@ -109,7 +111,8 @@ describe('Query imports', () => { it('returns empty query from selector query if label is not available', async () => { const datasourceWithLabels = { - metadataRequest: url => (url === '/api/prom/label' ? { data: { data: ['other'] } } : { data: { data: [] } }), + metadataRequest: (url: string) => + url === '/api/prom/label' ? { data: { data: ['other'] } } : { data: { data: [] as DataQueryResponseData[] } }, }; const instance = new LanguageProvider(datasourceWithLabels); const result = await instance.importPrometheusQuery('{foo="bar"}'); @@ -118,7 +121,8 @@ describe('Query imports', () => { it('returns selector query from selector query with common labels', async () => { const datasourceWithLabels = { - metadataRequest: url => (url === '/api/prom/label' ? { data: { data: ['foo'] } } : { data: { data: [] } }), + metadataRequest: (url: string) => + url === '/api/prom/label' ? { data: { data: ['foo'] } } : { data: { data: [] as DataQueryResponseData[] } }, }; const instance = new LanguageProvider(datasourceWithLabels); const result = await instance.importPrometheusQuery('metric{foo="bar",baz="42"}'); @@ -127,7 +131,10 @@ describe('Query imports', () => { it('returns selector query from selector query with all labels if logging label list is empty', async () => { const datasourceWithLabels = { - metadataRequest: url => (url === '/api/prom/label' ? { data: { data: [] } } : { data: { data: [] } }), + metadataRequest: (url: string) => + url === '/api/prom/label' + ? { data: { data: [] as DataQueryResponseData[] } } + : { data: { data: [] as DataQueryResponseData[] } }, }; const instance = new LanguageProvider(datasourceWithLabels); const result = await instance.importPrometheusQuery('metric{foo="bar",baz="42"}'); @@ -138,7 +145,7 @@ describe('Query imports', () => { describe('Labels refresh', () => { const datasource = { - metadataRequest: () => ({ data: { data: [] } }), + metadataRequest: () => ({ data: { data: [] as DataQueryResponseData[] } }), }; const instance = new LanguageProvider(datasource); diff --git a/public/app/plugins/datasource/prometheus/add_label_to_query.ts b/public/app/plugins/datasource/prometheus/add_label_to_query.ts index 190439492e2..8b5cc758a76 100644 --- a/public/app/plugins/datasource/prometheus/add_label_to_query.ts +++ b/public/app/plugins/datasource/prometheus/add_label_to_query.ts @@ -25,7 +25,7 @@ export function addLabelToQuery(query: string, key: string, value: string, opera } // Add empty selectors to bare metric names - let previousWord; + let previousWord: string; query = query.replace(metricNameRegexp, (match, word, offset) => { const insideSelector = isPositionInsideChars(query, offset, '{', '}'); // Handle "sum by (key) (metric)" diff --git a/public/app/plugins/datasource/prometheus/completer.ts b/public/app/plugins/datasource/prometheus/completer.ts index ebfb6670f40..ae52d94ca7b 100644 --- a/public/app/plugins/datasource/prometheus/completer.ts +++ b/public/app/plugins/datasource/prometheus/completer.ts @@ -1,5 +1,24 @@ import { PrometheusDatasource } from './datasource'; import _ from 'lodash'; +import { TemplateSrv } from 'app/features/templating/template_srv'; + +export interface CompleterPosition { + row: number; + column: number; +} + +export interface CompleterToken { + type: string; + value: string; + row: number; + column: number; + index: number; +} + +export interface CompleterSession { + getTokenAt: (row: number, column: number) => CompleterToken; + getTokens: (row: number) => CompleterToken[]; +} export class PromCompleter { labelQueryCache: any; @@ -9,11 +28,11 @@ export class PromCompleter { identifierRegexps = [/\[/, /[a-zA-Z0-9_:]/]; - constructor(private datasource: PrometheusDatasource, private templateSrv) { + constructor(private datasource: PrometheusDatasource, private templateSrv: TemplateSrv) { this.labelQueryCache = {}; this.labelNameCache = {}; this.labelValueCache = {}; - this.templateVariableCompletions = this.templateSrv.variables.map(variable => { + this.templateVariableCompletions = this.templateSrv.variables.map((variable: any) => { return { caption: '$' + variable.name, value: '$' + variable.name, @@ -23,8 +42,8 @@ export class PromCompleter { }); } - getCompletions(editor, session, pos, prefix, callback) { - const wrappedCallback = (err, completions) => { + getCompletions(editor: any, session: CompleterSession, pos: CompleterPosition, prefix: string, callback: Function) { + const wrappedCallback = (err: any, completions: any[]) => { completions = completions.concat(this.templateVariableCompletions); return callback(err, completions); }; @@ -79,7 +98,7 @@ export class PromCompleter { const query = prefix; - return this.datasource.performSuggestQuery(query, true).then(metricNames => { + return this.datasource.performSuggestQuery(query, true).then((metricNames: string[]) => { wrappedCallback( null, metricNames.map(name => { @@ -98,7 +117,7 @@ export class PromCompleter { }); } - getCompletionsForLabelMatcherName(session, pos) { + getCompletionsForLabelMatcherName(session: CompleterSession, pos: CompleterPosition) { const metricName = this.findMetricName(session, pos.row, pos.column); if (!metricName) { return Promise.resolve(this.transformToCompletions(['__name__', 'instance', 'job'], 'label name')); @@ -112,7 +131,7 @@ export class PromCompleter { const labelNames = this.transformToCompletions( _.uniq( _.flatten( - result.map(r => { + result.map((r: any) => { return Object.keys(r); }) ) @@ -124,7 +143,7 @@ export class PromCompleter { }); } - getCompletionsForLabelMatcherValue(session, pos) { + getCompletionsForLabelMatcherValue(session: CompleterSession, pos: CompleterPosition) { const metricName = this.findMetricName(session, pos.row, pos.column); if (!metricName) { return Promise.resolve([]); @@ -150,7 +169,7 @@ export class PromCompleter { return this.getLabelNameAndValueForExpression(metricName, 'metricName').then(result => { const labelValues = this.transformToCompletions( _.uniq( - result.map(r => { + result.map((r: any) => { return r[labelName]; }) ), @@ -162,12 +181,12 @@ export class PromCompleter { }); } - getCompletionsForBinaryOperator(session, pos) { + getCompletionsForBinaryOperator(session: CompleterSession, pos: CompleterPosition) { const keywordOperatorToken = this.findToken(session, pos.row, pos.column, 'keyword.control', null, 'identifier'); if (!keywordOperatorToken) { return Promise.resolve([]); } - let rparenToken, expr; + let rparenToken: CompleterToken, expr: string; switch (keywordOperatorToken.value) { case 'by': case 'without': @@ -190,7 +209,7 @@ export class PromCompleter { const labelNames = this.transformToCompletions( _.uniq( _.flatten( - result.map(r => { + result.map((r: any) => { return Object.keys(r); }) ) @@ -232,7 +251,7 @@ export class PromCompleter { const labelNames = this.transformToCompletions( _.uniq( _.flatten( - result.map(r => { + result.map((r: any) => { return Object.keys(r); }) ) @@ -248,7 +267,7 @@ export class PromCompleter { const labelNames = this.transformToCompletions( _.uniq( _.flatten( - result.map(r => { + result.map((r: any) => { return Object.keys(r); }) ) @@ -278,27 +297,27 @@ export class PromCompleter { } const { start, end } = this.datasource.getTimeRange(); const url = '/api/v1/series?match[]=' + encodeURIComponent(query) + '&start=' + start + '&end=' + end; - return this.datasource.metadataRequest(url).then(response => { + return this.datasource.metadataRequest(url).then((response: any) => { this.labelQueryCache[expr] = response.data.data; return response.data.data; }); } - transformToCompletions(words, meta) { + transformToCompletions(words: string[], meta: any) { return words.map(name => { return { caption: name, value: name, - meta: meta, + meta, score: Number.MAX_VALUE, }; }); } - findMetricName(session, row, column) { + findMetricName(session: CompleterSession, row: number, column: number) { let metricName = ''; - let tokens; + let tokens: CompleterToken[]; const nameLabelNameToken = this.findToken( session, row, @@ -324,11 +343,11 @@ export class PromCompleter { return metricName; } - findToken(session, row, column, target, value, guard) { - let tokens, idx; + findToken(session: CompleterSession, row: number, column: number, target: string, value: string, guard: string) { + let tokens: CompleterToken[], idx: number; // find index and get column of previous token for (let r = row; r >= 0; r--) { - let c; + let c: number; tokens = session.getTokens(r); if (r === row) { // current row @@ -368,8 +387,8 @@ export class PromCompleter { return null; } - findExpressionMatchedParen(session, row, column) { - let tokens, idx; + findExpressionMatchedParen(session: CompleterSession, row: number, column: number) { + let tokens: CompleterToken[], idx: number; let deep = 1; let expression = ')'; for (let r = row; r >= 0; r--) { diff --git a/public/app/plugins/datasource/prometheus/config_ctrl.ts b/public/app/plugins/datasource/prometheus/config_ctrl.ts index f7949ec9824..0385b92f3f5 100644 --- a/public/app/plugins/datasource/prometheus/config_ctrl.ts +++ b/public/app/plugins/datasource/prometheus/config_ctrl.ts @@ -3,7 +3,7 @@ export class PrometheusConfigCtrl { current: any; /** @ngInject */ - constructor($scope) { + constructor($scope: any) { this.current.jsonData.httpMethod = this.current.jsonData.httpMethod || 'GET'; } } diff --git a/public/app/plugins/datasource/prometheus/datasource.ts b/public/app/plugins/datasource/prometheus/datasource.ts index e870e175b8a..c12aef1cfd6 100644 --- a/public/app/plugins/datasource/prometheus/datasource.ts +++ b/public/app/plugins/datasource/prometheus/datasource.ts @@ -25,12 +25,24 @@ import { DataQueryError, DataStreamObserver, LoadingState, + DataQueryResponseData, } from '@grafana/ui/src/types'; import { ExploreUrlState } from 'app/types/explore'; import { safeStringifyValue } from 'app/core/utils/explore'; import { TemplateSrv } from 'app/features/templating/template_srv'; import { TimeSrv } from 'app/features/dashboard/services/TimeSrv'; -import { TimeRange } from '@grafana/ui/src'; +import { TimeRange, DateTime } from '@grafana/ui/src'; + +export interface PromDataQueryResponse { + data: { + status: string; + data: { + resultType: string; + results?: DataQueryResponseData[]; + result?: DataQueryResponseData[]; + }; + }; +} export class PrometheusDatasource extends DataSourceApi { type: string; @@ -106,7 +118,7 @@ export class PrometheusDatasource extends DataSourceApi } } else { options.headers['Content-Type'] = 'application/x-www-form-urlencoded'; - options.transformRequest = data => { + options.transformRequest = (data: any) => { return $.param(data); }; options.data = data; @@ -279,9 +291,9 @@ export class PrometheusDatasource extends DataSourceApi }); const allPromise = this.$q.all(allQueryPromise).then((responseList: any) => { - let result = []; + let result: any[] = []; - _.each(responseList, (response, index) => { + _.each(responseList, (response, index: number) => { if (response.cancelled) { return; } @@ -361,7 +373,7 @@ export class PrometheusDatasource extends DataSourceApi return query; } - adjustInterval(interval, minInterval, range, intervalFactor) { + adjustInterval(interval: number, minInterval: number, range: number, intervalFactor: number) { // Prometheus will drop queries that might return more than 11000 data points. // Calibrate interval if it is too small. if (interval !== 0 && range / intervalFactor / interval > 11000) { @@ -370,35 +382,39 @@ export class PrometheusDatasource extends DataSourceApi return Math.max(interval * intervalFactor, minInterval, 1); } - performTimeSeriesQuery(query, start, end) { + performTimeSeriesQuery(query: PromQueryRequest, start: number, end: number) { if (start > end) { throw { message: 'Invalid time range' }; } const url = '/api/v1/query_range'; - const data = { + const data: any = { query: query.expr, - start: start, - end: end, + start, + end, step: query.step, }; + if (this.queryTimeout) { data['timeout'] = this.queryTimeout; } + return this._request(url, data, { requestId: query.requestId, headers: query.headers }).catch((err: any) => this.handleErrors(err, query) ); } - performInstantQuery(query, time) { + performInstantQuery(query: PromQueryRequest, time: number) { const url = '/api/v1/query'; - const data = { + const data: any = { query: query.expr, - time: time, + time, }; + if (this.queryTimeout) { data['timeout'] = this.queryTimeout; } + return this._request(url, data, { requestId: query.requestId, headers: query.headers }).catch((err: any) => this.handleErrors(err, query) ); @@ -432,7 +448,7 @@ export class PrometheusDatasource extends DataSourceApi throw error; }; - performSuggestQuery(query, cache = false) { + performSuggestQuery(query: string, cache = false) { const url = '/api/v1/label/__name__/values'; if (cache && this.metricsNameCache && this.metricsNameCache.expire > Date.now()) { @@ -443,7 +459,7 @@ export class PrometheusDatasource extends DataSourceApi ); } - return this.metadataRequest(url).then(result => { + return this.metadataRequest(url).then((result: PromDataQueryResponse) => { this.metricsNameCache = { data: result.data.data, expire: Date.now() + 60 * 1000, @@ -454,7 +470,7 @@ export class PrometheusDatasource extends DataSourceApi }); } - metricFindQuery(query) { + metricFindQuery(query: string) { if (!query) { return this.$q.when([]); } @@ -481,7 +497,7 @@ export class PrometheusDatasource extends DataSourceApi }; } - annotationQuery(options) { + annotationQuery(options: any) { const annotation = options.annotation; const expr = annotation.expr || ''; let tagKeys = annotation.tagKeys || ''; @@ -504,8 +520,8 @@ export class PrometheusDatasource extends DataSourceApi const query = this.createQuery({ expr, interval: minStep, refId: 'X' }, queryOptions, start, end); const self = this; - return this.performTimeSeriesQuery(query, query.start, query.end).then(results => { - const eventList = []; + return this.performTimeSeriesQuery(query, query.start, query.end).then((results: PromDataQueryResponse) => { + const eventList: AnnotationEvent[] = []; tagKeys = tagKeys.split(','); _.each(results.data.data.result, series => { @@ -515,7 +531,7 @@ export class PrometheusDatasource extends DataSourceApi }) .value(); - const dupCheck = {}; + const dupCheck: { [key: number]: boolean } = {}; for (const value of series.values) { const valueIsTrue = value[1] === '1'; // e.g. ALERTS if (valueIsTrue || annotation.useValueForTime) { @@ -546,18 +562,18 @@ export class PrometheusDatasource extends DataSourceApi }); } - getTagKeys(options) { + getTagKeys(options: any = {}) { const url = '/api/v1/labels'; - return this.metadataRequest(url).then(result => { + return this.metadataRequest(url).then((result: any) => { return _.map(result.data.data, value => { return { text: value }; }); }); } - getTagValues(options) { + getTagValues(options: any = {}) { const url = '/api/v1/label/' + options.key + '/values'; - return this.metadataRequest(url).then(result => { + return this.metadataRequest(url).then((result: any) => { return _.map(result.data.data, value => { return { text: value }; }); @@ -566,7 +582,8 @@ export class PrometheusDatasource extends DataSourceApi testDatasource() { const now = new Date().getTime(); - return this.performInstantQuery({ expr: '1+1' }, now / 1000).then(response => { + const query = { expr: '1+1' } as PromQueryRequest; + return this.performInstantQuery(query, now / 1000).then((response: any) => { if (response.data.status === 'success') { return { status: 'success', message: 'Data source is working' }; } else { @@ -601,14 +618,14 @@ export class PrometheusDatasource extends DataSourceApi loadRules() { this.metadataRequest('/api/v1/rules') - .then(res => res.data || res.json()) - .then(body => { + .then((res: any) => res.data || res.json()) + .then((body: any) => { const groups = _.get(body, ['data', 'groups']); if (groups) { this.ruleMappings = extractRuleMappingFromGroups(groups); } }) - .catch(e => { + .catch((e: any) => { console.log('Rules API is experimental. Ignore next error.'); console.error(e); }); @@ -645,7 +662,7 @@ export class PrometheusDatasource extends DataSourceApi return { ...query, expr: expression }; } - getPrometheusTime(date, roundUp) { + getPrometheusTime(date: string | DateTime, roundUp: boolean) { if (_.isString(date)) { date = dateMath.parse(date, roundUp); } @@ -660,7 +677,7 @@ export class PrometheusDatasource extends DataSourceApi }; } - getOriginalMetricName(labelData) { + getOriginalMetricName(labelData: { [key: string]: string }) { return this.resultTransformer.getOriginalMetricName(labelData); } } @@ -685,9 +702,9 @@ export function extractRuleMappingFromGroups(groups: any[]) { return groups.reduce( (mapping, group) => group.rules - .filter(rule => rule.type === 'recording') + .filter((rule: any) => rule.type === 'recording') .reduce( - (acc, rule) => ({ + (acc: { [key: string]: string }, rule: any) => ({ ...acc, [rule.name]: rule.query, }), @@ -697,14 +714,14 @@ export function extractRuleMappingFromGroups(groups: any[]) { ); } -export function prometheusRegularEscape(value) { +export function prometheusRegularEscape(value: any) { if (typeof value === 'string') { return value.replace(/'/g, "\\\\'"); } return value; } -export function prometheusSpecialRegexEscape(value) { +export function prometheusSpecialRegexEscape(value: any) { if (typeof value === 'string') { return prometheusRegularEscape(value.replace(/\\/g, '\\\\\\\\').replace(/[$^*{}\[\]+?.()|]/g, '\\\\$&')); } diff --git a/public/app/plugins/datasource/prometheus/metric_find_query.ts b/public/app/plugins/datasource/prometheus/metric_find_query.ts index 5992efbf61c..60f7c15f3b9 100644 --- a/public/app/plugins/datasource/prometheus/metric_find_query.ts +++ b/public/app/plugins/datasource/prometheus/metric_find_query.ts @@ -1,11 +1,13 @@ import _ from 'lodash'; +import { TimeRange } from '@grafana/ui'; +import { TimeSrv } from 'app/features/dashboard/services/TimeSrv'; +import { PrometheusDatasource, PromDataQueryResponse } from './datasource'; +import { PromQueryRequest } from './types'; export default class PrometheusMetricFindQuery { - datasource: any; - query: any; - range: any; + range: TimeRange; - constructor(datasource, query, timeSrv) { + constructor(private datasource: PrometheusDatasource, private query: string, timeSrv: TimeSrv) { this.datasource = datasource; this.query = query; this.range = timeSrv.timeRange(); @@ -47,21 +49,21 @@ export default class PrometheusMetricFindQuery { labelNamesQuery() { const url = '/api/v1/labels'; - return this.datasource.metadataRequest(url).then(result => { + return this.datasource.metadataRequest(url).then((result: any) => { return _.map(result.data.data, value => { return { text: value }; }); }); } - labelValuesQuery(label, metric) { - let url; + labelValuesQuery(label: string, metric?: string) { + let url: string; if (!metric) { // return label values globally url = '/api/v1/label/' + label + '/values'; - return this.datasource.metadataRequest(url).then(result => { + return this.datasource.metadataRequest(url).then((result: any) => { return _.map(result.data.data, value => { return { text: value }; }); @@ -71,7 +73,7 @@ export default class PrometheusMetricFindQuery { const end = this.datasource.getPrometheusTime(this.range.to, true); url = '/api/v1/series?match[]=' + encodeURIComponent(metric) + '&start=' + start + '&end=' + end; - return this.datasource.metadataRequest(url).then(result => { + return this.datasource.metadataRequest(url).then((result: any) => { const _labels = _.map(result.data.data, metric => { return metric[label] || ''; }).filter(label => { @@ -88,10 +90,10 @@ export default class PrometheusMetricFindQuery { } } - metricNameQuery(metricFilterPattern) { + metricNameQuery(metricFilterPattern: string) { const url = '/api/v1/label/__name__/values'; - return this.datasource.metadataRequest(url).then(result => { + return this.datasource.metadataRequest(url).then((result: any) => { return _.chain(result.data.data) .filter(metricName => { const r = new RegExp(metricFilterPattern); @@ -107,9 +109,10 @@ export default class PrometheusMetricFindQuery { }); } - queryResultQuery(query) { + queryResultQuery(query: string) { const end = this.datasource.getPrometheusTime(this.range.to, true); - return this.datasource.performInstantQuery({ expr: query }, end).then(result => { + const instantQuery: PromQueryRequest = { expr: query } as PromQueryRequest; + return this.datasource.performInstantQuery(instantQuery, end).then((result: PromDataQueryResponse) => { return _.map(result.data.data.result, metricData => { let text = metricData.metric.__name__ || ''; delete metricData.metric.__name__; @@ -129,14 +132,14 @@ export default class PrometheusMetricFindQuery { }); } - metricNameAndLabelsQuery(query) { + metricNameAndLabelsQuery(query: string) { const start = this.datasource.getPrometheusTime(this.range.from, false); const end = this.datasource.getPrometheusTime(this.range.to, true); const url = '/api/v1/series?match[]=' + encodeURIComponent(query) + '&start=' + start + '&end=' + end; const self = this; - return this.datasource.metadataRequest(url).then(result => { - return _.map(result.data.data, metric => { + return this.datasource.metadataRequest(url).then((result: PromDataQueryResponse) => { + return _.map(result.data.data, (metric: { [key: string]: string }) => { return { text: self.datasource.getOriginalMetricName(metric), expandable: true, diff --git a/public/app/plugins/datasource/prometheus/query_ctrl.ts b/public/app/plugins/datasource/prometheus/query_ctrl.ts index c463a308927..aa15da12e64 100644 --- a/public/app/plugins/datasource/prometheus/query_ctrl.ts +++ b/public/app/plugins/datasource/prometheus/query_ctrl.ts @@ -4,6 +4,7 @@ import { QueryCtrl } from 'app/plugins/sdk'; import { PromCompleter } from './completer'; import './mode-prometheus'; import './snippets/prometheus'; +import { TemplateSrv } from 'app/features/templating/template_srv'; class PrometheusQueryCtrl extends QueryCtrl { static templateUrl = 'partials/query.editor.html'; @@ -18,7 +19,7 @@ class PrometheusQueryCtrl extends QueryCtrl { linkToPrometheus: any; /** @ngInject */ - constructor($scope, $injector, private templateSrv) { + constructor($scope: any, $injector: angular.auto.IInjectorService, private templateSrv: TemplateSrv) { super($scope, $injector); const target = this.target; @@ -42,7 +43,7 @@ class PrometheusQueryCtrl extends QueryCtrl { this.updateLink(); } - getCompleter(query) { + getCompleter(query: string) { return new PromCompleter(this.datasource, this.templateSrv); } diff --git a/public/app/plugins/datasource/prometheus/query_hints.ts b/public/app/plugins/datasource/prometheus/query_hints.ts index 06c60c596a2..734090f8abb 100644 --- a/public/app/plugins/datasource/prometheus/query_hints.ts +++ b/public/app/plugins/datasource/prometheus/query_hints.ts @@ -1,12 +1,12 @@ import _ from 'lodash'; -import { QueryHint } from '@grafana/ui/src/types'; +import { QueryHint, QueryFix } from '@grafana/ui/src/types'; /** * Number of time series results needed before starting to suggest sum aggregation hints */ export const SUM_HINT_THRESHOLD_COUNT = 20; -export function getQueryHints(query: string, series?: any[], datasource?: any): QueryHint[] { +export function getQueryHints(query: string, series?: any[], datasource?: any): QueryHint[] | null { const hints = []; // ..._bucket metric needs a histogram_quantile() @@ -22,7 +22,7 @@ export function getQueryHints(query: string, series?: any[], datasource?: any): type: 'ADD_HISTOGRAM_QUANTILE', query, }, - }, + } as QueryFix, }); } @@ -44,7 +44,7 @@ export function getQueryHints(query: string, series?: any[], datasource?: any): if (increasing && monotonic) { const simpleMetric = query.trim().match(/^\w+$/); let label = 'Time series is monotonically increasing.'; - let fix; + let fix: QueryFix; if (simpleMetric) { fix = { label: 'Fix by adding rate().', @@ -52,7 +52,7 @@ export function getQueryHints(query: string, series?: any[], datasource?: any): type: 'ADD_RATE', query, }, - }; + } as QueryFix; } else { label = `${label} Try applying a rate() function.`; } @@ -83,14 +83,14 @@ export function getQueryHints(query: string, series?: any[], datasource?: any): hints.push({ type: 'EXPAND_RULES', label, - fix: { + fix: ({ label: 'Expand rules', action: { type: 'EXPAND_RULES', query, mapping: mappingForQuery, }, - }, + } as any) as QueryFix, }); } } @@ -108,7 +108,7 @@ export function getQueryHints(query: string, series?: any[], datasource?: any): query: query, preventSubmit: true, }, - }, + } as QueryFix, }); } } diff --git a/public/app/plugins/datasource/prometheus/result_transformer.ts b/public/app/plugins/datasource/prometheus/result_transformer.ts index fa7cc73bbc7..92027dd2717 100644 --- a/public/app/plugins/datasource/prometheus/result_transformer.ts +++ b/public/app/plugins/datasource/prometheus/result_transformer.ts @@ -1,9 +1,10 @@ import _ from 'lodash'; import TableModel from 'app/core/table_model'; import { TimeSeries, FieldType } from '@grafana/ui'; +import { TemplateSrv } from 'app/features/templating/template_srv'; export class ResultTransformer { - constructor(private templateSrv) {} + constructor(private templateSrv: TemplateSrv) {} transform(response: any, options: any): any[] { const prometheusResult = response.data.data.result; @@ -39,7 +40,7 @@ export class ResultTransformer { return []; } - transformMetricData(metricData, options, start, end) { + transformMetricData(metricData: any, options: any, start: number, end: number) { const dps = []; let metricLabel = null; @@ -78,10 +79,10 @@ export class ResultTransformer { }; } - transformMetricDataToTable(md, resultCount: number, refId: string, valueWithRefId?: boolean) { + transformMetricDataToTable(md: any, resultCount: number, refId: string, valueWithRefId?: boolean) { const table = new TableModel(); - let i, j; - const metricLabels = {}; + let i: number, j: number; + const metricLabels: { [key: string]: number } = {}; if (!md || md.length === 0) { return table; @@ -134,7 +135,7 @@ export class ResultTransformer { return table; } - transformInstantMetricData(md, options) { + transformInstantMetricData(md: any, options: any) { const dps = []; let metricLabel = null; metricLabel = this.createMetricLabel(md.metric, options); @@ -142,7 +143,7 @@ export class ResultTransformer { return { target: metricLabel, datapoints: dps, labels: md.metric }; } - createMetricLabel(labelData, options) { + createMetricLabel(labelData: { [key: string]: string }, options: any) { let label = ''; if (_.isUndefined(options) || _.isEmpty(options.legendFormat)) { label = this.getOriginalMetricName(labelData); @@ -155,7 +156,7 @@ export class ResultTransformer { return label; } - renderTemplate(aliasPattern, aliasData) { + renderTemplate(aliasPattern: string, aliasData: { [key: string]: string }) { const aliasRegex = /\{\{\s*(.+?)\s*\}\}/g; return aliasPattern.replace(aliasRegex, (match, g1) => { if (aliasData[g1]) { @@ -165,7 +166,7 @@ export class ResultTransformer { }); } - getOriginalMetricName(labelData) { + getOriginalMetricName(labelData: { [key: string]: string }) { const metricName = labelData.__name__ || ''; delete labelData.__name__; const labelPart = _.map(_.toPairs(labelData), label => { @@ -174,7 +175,7 @@ export class ResultTransformer { return metricName + '{' + labelPart + '}'; } - transformToHistogramOverTime(seriesList) { + transformToHistogramOverTime(seriesList: TimeSeries[]) { /* t1 = timestamp1, t2 = timestamp2 etc. t1 t2 t3 t1 t2 t3 le10 10 10 0 => 10 10 0 diff --git a/public/app/plugins/datasource/prometheus/specs/completer.test.ts b/public/app/plugins/datasource/prometheus/specs/completer.test.ts index 8a7b3b8c7c3..9d1d66cbbf0 100644 --- a/public/app/plugins/datasource/prometheus/specs/completer.test.ts +++ b/public/app/plugins/datasource/prometheus/specs/completer.test.ts @@ -10,7 +10,7 @@ jest.mock('../datasource'); jest.mock('@grafana/ui'); describe('Prometheus editor completer', () => { - function getSessionStub(data) { + function getSessionStub(data: any) { return { getTokenAt: jest.fn(() => data.currentToken), getTokens: jest.fn(() => data.tokens), @@ -37,14 +37,14 @@ describe('Prometheus editor completer', () => { }); datasourceStub.performSuggestQuery = jest.fn(() => Promise.resolve(['node_cpu'])); - const templateSrv = { + const templateSrv: TemplateSrv = ({ variables: [ { name: 'var_name', options: [{ text: 'foo', value: 'foo', selected: false }, { text: 'bar', value: 'bar', selected: true }], }, ], - }; + } as any) as TemplateSrv; const completer = new PromCompleter(datasourceStub, templateSrv); describe('When inside brackets', () => { @@ -55,7 +55,7 @@ describe('Prometheus editor completer', () => { line: 'node_cpu[', }); - return completer.getCompletions(editor, session, { row: 0, column: 10 }, '[', (s, res) => { + return completer.getCompletions(editor, session, { row: 0, column: 10 }, '[', (s: any, res: any) => { expect(res[0].caption).toEqual('$__interval'); expect(res[0].value).toEqual('[$__interval'); expect(res[0].meta).toEqual('range vector'); @@ -86,7 +86,7 @@ describe('Prometheus editor completer', () => { line: 'node_cpu{j}', }); - return completer.getCompletions(editor, session, { row: 0, column: 10 }, 'j', (s, res) => { + return completer.getCompletions(editor, session, { row: 0, column: 10 }, 'j', (s: any, res: any) => { expect(res[0].meta).toEqual('label name'); }); }); @@ -118,7 +118,7 @@ describe('Prometheus editor completer', () => { line: '{__name__=~"node_cpu",j}', }); - return completer.getCompletions(editor, session, { row: 0, column: 23 }, 'j', (s, res) => { + return completer.getCompletions(editor, session, { row: 0, column: 23 }, 'j', (s: any, res: any) => { expect(res[0].meta).toEqual('label name'); }); }); @@ -149,7 +149,7 @@ describe('Prometheus editor completer', () => { line: 'node_cpu{job="n"}', }); - return completer.getCompletions(editor, session, { row: 0, column: 15 }, 'n', (s, res) => { + return completer.getCompletions(editor, session, { row: 0, column: 15 }, 'n', (s: any, res: any) => { expect(res[0].meta).toEqual('label value'); }); }); @@ -185,7 +185,7 @@ describe('Prometheus editor completer', () => { line: '(count(node_cpu)) by (m)', }); - return completer.getCompletions(editor, session, { row: 0, column: 23 }, 'm', (s, res) => { + return completer.getCompletions(editor, session, { row: 0, column: 23 }, 'm', (s: any, res: any) => { expect(res[0].meta).toEqual('label name'); }); }); diff --git a/public/app/plugins/datasource/prometheus/specs/datasource.test.ts b/public/app/plugins/datasource/prometheus/specs/datasource.test.ts index 8fab195a5d9..91949c69bd0 100644 --- a/public/app/plugins/datasource/prometheus/specs/datasource.test.ts +++ b/public/app/plugins/datasource/prometheus/specs/datasource.test.ts @@ -1,4 +1,5 @@ import _ from 'lodash'; +// @ts-ignore import q from 'q'; import { alignRange, @@ -8,7 +9,7 @@ import { prometheusSpecialRegexEscape, } from '../datasource'; import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; -import { DataSourceInstanceSettings } from '@grafana/ui'; +import { DataSourceInstanceSettings, DataQueryResponseData } from '@grafana/ui'; import { PromOptions } from '../types'; import { TemplateSrv } from 'app/features/templating/template_srv'; import { TimeSrv } from 'app/features/dashboard/services/TimeSrv'; @@ -17,8 +18,8 @@ import { CustomVariable } from 'app/features/templating/custom_variable'; jest.mock('../metric_find_query'); const DEFAULT_TEMPLATE_SRV_MOCK = { - getAdhocFilters: () => [], - replace: a => a, + getAdhocFilters: () => [] as any[], + replace: (a: string) => a, }; describe('PrometheusDatasource', () => { @@ -179,7 +180,7 @@ describe('PrometheusDatasource', () => { ]; ctx.ds.performTimeSeriesQuery = jest.fn().mockReturnValue(responseMock); - return ctx.ds.query(ctx.query).then(result => { + return ctx.ds.query(ctx.query).then((result: any) => { const results = result.data; return expect(results).toMatchObject(expected); }); @@ -209,7 +210,7 @@ describe('PrometheusDatasource', () => { const expected = ['1', '2', '4', '+Inf']; ctx.ds.performTimeSeriesQuery = jest.fn().mockReturnValue(responseMock); - return ctx.ds.query(ctx.query).then(result => { + return ctx.ds.query(ctx.query).then((result: any) => { const seriesLabels = _.map(result.data, 'target'); return expect(seriesLabels).toEqual(expected); }); @@ -412,7 +413,7 @@ const backendSrv = { } as any; const templateSrv = ({ - getAdhocFilters: () => [], + getAdhocFilters: (): any[] => [], replace: jest.fn(str => str), } as unknown) as TemplateSrv; @@ -424,7 +425,7 @@ const timeSrv = ({ describe('PrometheusDatasource', () => { describe('When querying prometheus with one target using query editor target spec', () => { - let results; + let results: any; const query = { range: { from: time({ seconds: 63 }), to: time({ seconds: 183 }) }, targets: [{ expr: 'test{job="testjob"}', format: 'time_series' }], @@ -452,7 +453,7 @@ describe('PrometheusDatasource', () => { backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response)); ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv as any, timeSrv as any); - await ctx.ds.query(query).then(data => { + await ctx.ds.query(query).then((data: any) => { results = data; }); }); @@ -468,7 +469,7 @@ describe('PrometheusDatasource', () => { }); }); describe('When querying prometheus with one target which returns multiple series', () => { - let results; + let results: any; const start = 60; const end = 360; const step = 60; @@ -502,7 +503,7 @@ describe('PrometheusDatasource', () => { backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response)); ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv as any, timeSrv as any); - await ctx.ds.query(query).then(data => { + await ctx.ds.query(query).then((data: any) => { results = data; }); }); @@ -536,7 +537,7 @@ describe('PrometheusDatasource', () => { }); }); describe('When querying prometheus with one target and instant = true', () => { - let results; + let results: any; const urlExpected = 'proxied/api/v1/query?query=' + encodeURIComponent('test{job="testjob"}') + '&time=123'; const query = { range: { from: time({ seconds: 63 }), to: time({ seconds: 123 }) }, @@ -563,7 +564,7 @@ describe('PrometheusDatasource', () => { backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response)); ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv as any, timeSrv as any); - await ctx.ds.query(query).then(data => { + await ctx.ds.query(query).then((data: any) => { results = data; }); }); @@ -578,7 +579,7 @@ describe('PrometheusDatasource', () => { }); }); describe('When performing annotationQuery', () => { - let results; + let results: any; const options: any = { annotation: { @@ -620,7 +621,7 @@ describe('PrometheusDatasource', () => { backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response)); ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv as any, timeSrv as any); - await ctx.ds.annotationQuery(options).then(data => { + await ctx.ds.annotationQuery(options).then((data: any) => { results = data; }); }); @@ -640,7 +641,7 @@ describe('PrometheusDatasource', () => { backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response)); ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv as any, timeSrv as any); - await ctx.ds.annotationQuery(options).then(data => { + await ctx.ds.annotationQuery(options).then((data: any) => { results = data; }); }); @@ -725,7 +726,7 @@ describe('PrometheusDatasource', () => { }); describe('When resultFormat is table and instant = true', () => { - let results; + let results: any; const query = { range: { from: time({ seconds: 63 }), to: time({ seconds: 123 }) }, targets: [{ expr: 'test{job="testjob"}', format: 'time_series', instant: true }], @@ -750,7 +751,7 @@ describe('PrometheusDatasource', () => { backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response)); ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv as any, timeSrv as any); - await ctx.ds.query(query).then(data => { + await ctx.ds.query(query).then((data: any) => { results = data; }); }); @@ -766,7 +767,7 @@ describe('PrometheusDatasource', () => { data: { data: { resultType: 'matrix', - result: [], + result: [] as DataQueryResponseData[], }, }, }; @@ -963,7 +964,7 @@ describe('PrometheusDatasource', () => { data: { data: { resultType: 'matrix', - result: [], + result: [] as DataQueryResponseData[], }, }, }; @@ -1232,7 +1233,7 @@ describe('PrometheusDatasource', () => { data: { data: { resultType: 'matrix', - result: [], + result: [] as DataQueryResponseData[], }, }, }; @@ -1293,7 +1294,7 @@ describe('PrometheusDatasource for POST', () => { } as unknown) as DataSourceInstanceSettings; describe('When querying prometheus with one target using query editor target spec', () => { - let results; + let results: any; const urlExpected = 'proxied/api/v1/query_range'; const dataExpected = { query: 'test{job="testjob"}', @@ -1324,7 +1325,7 @@ describe('PrometheusDatasource for POST', () => { }; backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response)); ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv as any, timeSrv as any); - await ctx.ds.query(query).then(data => { + await ctx.ds.query(query).then((data: any) => { results = data; }); }); @@ -1344,7 +1345,7 @@ describe('PrometheusDatasource for POST', () => { const options = { dashboardId: 1, panelId: 2 }; const httpOptions = { - headers: {}, + headers: {} as { [key: string]: number | undefined }, }; it('with proxy access tracing headers should be added', () => { diff --git a/public/app/plugins/datasource/prometheus/specs/language_provider.test.ts b/public/app/plugins/datasource/prometheus/specs/language_provider.test.ts index 1d114a7ef28..59f6a7f6a27 100644 --- a/public/app/plugins/datasource/prometheus/specs/language_provider.test.ts +++ b/public/app/plugins/datasource/prometheus/specs/language_provider.test.ts @@ -1,10 +1,11 @@ +// @ts-ignore import Plain from 'slate-plain-serializer'; import LanguageProvider from '../language_provider'; describe('Language completion provider', () => { const datasource = { - metadataRequest: () => ({ data: { data: [] } }), + metadataRequest: () => ({ data: { data: [] as any[] } }), }; describe('empty query suggestions', () => { diff --git a/public/app/plugins/datasource/prometheus/specs/metric_find_query.test.ts b/public/app/plugins/datasource/prometheus/specs/metric_find_query.test.ts index aacfc5dd904..e3c3b27ad3b 100644 --- a/public/app/plugins/datasource/prometheus/specs/metric_find_query.test.ts +++ b/public/app/plugins/datasource/prometheus/specs/metric_find_query.test.ts @@ -1,5 +1,6 @@ import { PrometheusDatasource } from '../datasource'; import PrometheusMetricFindQuery from '../metric_find_query'; +//@ts-ignore import q from 'q'; import { toUtc } from '@grafana/ui/src/utils/moment_wrapper'; import { DataSourceInstanceSettings } from '@grafana/ui'; @@ -22,7 +23,7 @@ describe('PrometheusMetricFindQuery', () => { datasourceRequest: jest.fn(() => Promise.resolve({})), }, templateSrvMock: { - replace: a => a, + replace: (a: string) => a, }, timeSrvMock: { timeRange: () => ({ diff --git a/public/app/plugins/datasource/prometheus/specs/result_transformer.test.ts b/public/app/plugins/datasource/prometheus/specs/result_transformer.test.ts index 3c376334187..c651650e83f 100644 --- a/public/app/plugins/datasource/prometheus/specs/result_transformer.test.ts +++ b/public/app/plugins/datasource/prometheus/specs/result_transformer.test.ts @@ -1,11 +1,12 @@ import { ResultTransformer } from '../result_transformer'; +import { DataQueryResponseData } from '@grafana/ui'; describe('Prometheus Result Transformer', () => { const ctx: any = {}; beforeEach(() => { ctx.templateSrv = { - replace: str => str, + replace: (str: string) => str, }; ctx.resultTransformer = new ResultTransformer(ctx.templateSrv); }); @@ -16,7 +17,7 @@ describe('Prometheus Result Transformer', () => { status: 'success', data: { resultType: '', - result: null, + result: null as DataQueryResponseData[], }, }; const series = ctx.resultTransformer.transform({ data: response }, {}); @@ -27,7 +28,7 @@ describe('Prometheus Result Transformer', () => { status: 'success', data: { resultType: '', - result: null, + result: null as DataQueryResponseData[], }, }; const table = ctx.resultTransformer.transform({ data: response }, { format: 'table' }); @@ -168,7 +169,7 @@ describe('Prometheus Result Transformer', () => { }); it('should throw error when data in wrong format', () => { - const seriesList = [{ rows: [] }, { datapoints: [] }]; + const seriesList = [{ rows: [] as any[] }, { datapoints: [] as any[] }]; expect(() => { ctx.resultTransformer.transformToHistogramOverTime(seriesList); }).toThrow(); @@ -176,7 +177,7 @@ describe('Prometheus Result Transformer', () => { it('should throw error when prometheus returned non-timeseries', () => { // should be { metric: {}, values: [] } for timeseries - const metricData = { metric: {}, value: [] }; + const metricData = { metric: {}, value: [] as any[] }; expect(() => { ctx.resultTransformer.transformMetricData(metricData, { step: 1 }, 1000, 2000); }).toThrow(); diff --git a/public/app/plugins/datasource/prometheus/types.ts b/public/app/plugins/datasource/prometheus/types.ts index 7971ad65bde..6ea155b4d7b 100644 --- a/public/app/plugins/datasource/prometheus/types.ts +++ b/public/app/plugins/datasource/prometheus/types.ts @@ -29,4 +29,5 @@ export interface PromQueryRequest extends PromQuery { requestId?: string; start: number; end: number; + headers?: any; }