Ver código fonte

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/**/*
Hugo Häggmark 6 anos atrás
pai
commit
3424b64299

+ 13 - 13
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,
             },
           ],

+ 7 - 3
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;
       }
     }

+ 5 - 5
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<any, any>;
+    let result: any;
 
     describe('and call succeeds', () => {
       beforeEach(async () => {

+ 9 - 7
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<LokiQuery, LokiOptions> {
     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<LokiQuery, LokiOptions> {
     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<LokiQuery, LokiOptions> {
     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<LokiQuery, LokiOptions> {
 
   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<LokiQuery, LokiOptions> {
             '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;

+ 13 - 6
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);
 

+ 1 - 1
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)"

+ 43 - 24
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--) {

+ 1 - 1
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';
   }
 }

+ 50 - 33
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<PromQuery, PromOptions> {
   type: string;
@@ -106,7 +118,7 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
       }
     } 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<PromQuery, PromOptions>
     });
 
     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<PromQuery, PromOptions>
     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<PromQuery, PromOptions>
     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<PromQuery, PromOptions>
     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<PromQuery, PromOptions>
       );
     }
 
-    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<PromQuery, PromOptions>
     });
   }
 
-  metricFindQuery(query) {
+  metricFindQuery(query: string) {
     if (!query) {
       return this.$q.when([]);
     }
@@ -481,7 +497,7 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
     };
   }
 
-  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<PromQuery, PromOptions>
     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<PromQuery, PromOptions>
           })
           .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<PromQuery, PromOptions>
     });
   }
 
-  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<PromQuery, PromOptions>
 
   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<PromQuery, PromOptions>
 
   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<PromQuery, PromOptions>
     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<PromQuery, PromOptions>
     };
   }
 
-  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, '\\\\$&'));
   }

+ 19 - 16
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,

+ 3 - 2
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);
   }
 

+ 8 - 8
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,
       });
     }
   }

+ 11 - 10
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

+ 8 - 8
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');
       });
     });

+ 24 - 23
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<PromOptions>;
 
   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', () => {

+ 2 - 1
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', () => {

+ 2 - 1
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: () => ({

+ 6 - 5
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();

+ 1 - 0
public/app/plugins/datasource/prometheus/types.ts

@@ -29,4 +29,5 @@ export interface PromQueryRequest extends PromQuery {
   requestId?: string;
   start: number;
   end: number;
+  headers?: any;
 }