فهرست منبع

noImplicitAny: Sub 3000 errors (#17821)

* noImplicitAny Stackdriver

* Sub 3000 noImplicitAny

* Update error count limit

* Add DataQueryRequest type
Tobias Skarhed 6 سال پیش
والد
کامیت
4e27ba9646
38فایلهای تغییر یافته به همراه388 افزوده شده و 302 حذف شده
  1. 4 1
      packages/grafana-ui/src/types/datasource.ts
  2. 11 10
      public/app/plugins/datasource/mssql/response_parser.ts
  3. 16 14
      public/app/plugins/datasource/mssql/specs/datasource.test.ts
  4. 21 11
      public/app/plugins/datasource/mysql/datasource.ts
  5. 2 2
      public/app/plugins/datasource/mysql/meta_query.ts
  6. 10 8
      public/app/plugins/datasource/mysql/mysql_query.ts
  7. 53 43
      public/app/plugins/datasource/mysql/query_ctrl.ts
  8. 10 9
      public/app/plugins/datasource/mysql/response_parser.ts
  9. 11 10
      public/app/plugins/datasource/mysql/specs/datasource.test.ts
  10. 2 2
      public/app/plugins/datasource/mysql/sql_part.ts
  11. 1 1
      public/app/plugins/datasource/opentsdb/config_ctrl.ts
  12. 48 35
      public/app/plugins/datasource/opentsdb/datasource.ts
  13. 12 11
      public/app/plugins/datasource/opentsdb/query_ctrl.ts
  14. 12 11
      public/app/plugins/datasource/opentsdb/specs/datasource.test.ts
  15. 1 1
      public/app/plugins/datasource/opentsdb/specs/query_ctrl.test.ts
  16. 5 4
      public/app/plugins/datasource/postgres/config_ctrl.ts
  17. 19 9
      public/app/plugins/datasource/postgres/datasource.ts
  18. 4 2
      public/app/plugins/datasource/postgres/meta_query.ts
  19. 10 8
      public/app/plugins/datasource/postgres/postgres_query.ts
  20. 53 43
      public/app/plugins/datasource/postgres/query_ctrl.ts
  21. 10 9
      public/app/plugins/datasource/postgres/response_parser.ts
  22. 18 10
      public/app/plugins/datasource/postgres/specs/datasource.test.ts
  23. 4 2
      public/app/plugins/datasource/postgres/specs/postgres_query.test.ts
  24. 2 2
      public/app/plugins/datasource/postgres/sql_part.ts
  25. 1 1
      public/app/plugins/datasource/prometheus/components/PromLink.tsx
  26. 1 1
      public/app/plugins/datasource/prometheus/components/PromQueryEditor.tsx
  27. 17 15
      public/app/plugins/datasource/stackdriver/StackdriverMetricFindQuery.ts
  28. 2 2
      public/app/plugins/datasource/stackdriver/annotations_query_ctrl.ts
  29. 4 3
      public/app/plugins/datasource/stackdriver/components/Aggregations.test.tsx
  30. 2 2
      public/app/plugins/datasource/stackdriver/components/Aggregations.tsx
  31. 4 4
      public/app/plugins/datasource/stackdriver/components/AliasBy.tsx
  32. 1 1
      public/app/plugins/datasource/stackdriver/components/AlignmentPeriods.tsx
  33. 1 1
      public/app/plugins/datasource/stackdriver/components/Alignments.tsx
  34. 3 3
      public/app/plugins/datasource/stackdriver/components/AnnotationQueryEditor.tsx
  35. 5 5
      public/app/plugins/datasource/stackdriver/components/Filter.tsx
  36. 3 1
      public/app/plugins/datasource/stackdriver/components/Help.tsx
  37. 4 4
      public/app/plugins/datasource/stackdriver/components/Metrics.tsx
  38. 1 1
      scripts/ci-frontend-metrics.sh

+ 4 - 1
packages/grafana-ui/src/types/datasource.ts

@@ -1,5 +1,5 @@
 import { ComponentType, ComponentClass } from 'react';
-import { TimeRange } from './time';
+import { TimeRange, RawTimeRange } from './time';
 import { PluginMeta, GrafanaPlugin } from './plugin';
 import { TableData, TimeSeries, SeriesData, LoadingState } from './data';
 import { PanelData } from './panel';
@@ -356,6 +356,8 @@ export interface DataQuery {
    * For non mixed scenarios this is undefined.
    */
   datasource?: string | null;
+
+  metric?: any;
 }
 
 export interface DataQueryError {
@@ -383,6 +385,7 @@ export interface DataQueryRequest<TQuery extends DataQuery = DataQuery> {
   requestId: string; // Used to identify results and optionally cancel the request in backendSrv
   timezone: string;
   range: TimeRange;
+  rangeRaw?: RawTimeRange;
   timeInfo?: string; // The query time description (blue text in the upper right)
   targets: TQuery[];
   panelId: number;

+ 11 - 10
public/app/plugins/datasource/mssql/response_parser.ts

@@ -1,13 +1,14 @@
 import _ from 'lodash';
+import { IQService } from 'angular';
 
 export default class ResponseParser {
-  constructor(private $q) {}
+  constructor(private $q: IQService) {}
 
-  processQueryResult(res) {
-    const data = [];
+  processQueryResult(res: any) {
+    const data: any[] = [];
 
     if (!res.data.results) {
-      return { data: data };
+      return { data };
     }
 
     for (const key in res.data.results) {
@@ -37,7 +38,7 @@ export default class ResponseParser {
     return { data: data };
   }
 
-  parseMetricFindQueryResult(refId, results) {
+  parseMetricFindQueryResult(refId: string, results: any) {
     if (!results || results.data.length === 0 || results.data.results[refId].meta.rowCount === 0) {
       return [];
     }
@@ -54,7 +55,7 @@ export default class ResponseParser {
     return this.transformToSimpleList(rows);
   }
 
-  transformToKeyValueList(rows, textColIndex, valueColIndex) {
+  transformToKeyValueList(rows: any, textColIndex: number, valueColIndex: number) {
     const res = [];
 
     for (let i = 0; i < rows.length; i++) {
@@ -66,7 +67,7 @@ export default class ResponseParser {
     return res;
   }
 
-  transformToSimpleList(rows) {
+  transformToSimpleList(rows: any) {
     const res = [];
 
     for (let i = 0; i < rows.length; i++) {
@@ -83,7 +84,7 @@ export default class ResponseParser {
     });
   }
 
-  findColIndex(columns, colName) {
+  findColIndex(columns: any[], colName: string) {
     for (let i = 0; i < columns.length; i++) {
       if (columns[i].text === colName) {
         return i;
@@ -93,7 +94,7 @@ export default class ResponseParser {
     return -1;
   }
 
-  containsKey(res, key) {
+  containsKey(res: any[], key: any) {
     for (let i = 0; i < res.length; i++) {
       if (res[i].text === key) {
         return true;
@@ -102,7 +103,7 @@ export default class ResponseParser {
     return false;
   }
 
-  transformAnnotationResponse(options, data) {
+  transformAnnotationResponse(options: any, data: any) {
     const table = data.data.results[options.annotation.name].tables[0];
 
     let timeColumnIndex = -1;

+ 16 - 14
public/app/plugins/datasource/mssql/specs/datasource.test.ts

@@ -1,12 +1,14 @@
 import { MssqlDatasource } from '../datasource';
 import { TemplateSrvStub, TimeSrvStub } from 'test/specs/helpers';
 import { CustomVariable } from 'app/features/templating/custom_variable';
+// @ts-ignore
 import q from 'q';
 import { dateTime } from '@grafana/ui/src/utils/moment_wrapper';
 
 describe('MSSQLDatasource', () => {
   const ctx: any = {
     backendSrv: {},
+    // @ts-ignore
     templateSrv: new TemplateSrvStub(),
     timeSrv: new TimeSrvStub(),
   };
@@ -19,7 +21,7 @@ describe('MSSQLDatasource', () => {
   });
 
   describe('When performing annotationQuery', () => {
-    let results;
+    let results: any;
 
     const annotationName = 'MyAnno';
 
@@ -53,11 +55,11 @@ describe('MSSQLDatasource', () => {
     };
 
     beforeEach(() => {
-      ctx.backendSrv.datasourceRequest = options => {
+      ctx.backendSrv.datasourceRequest = (options: any) => {
         return ctx.$q.when({ data: response, status: 200 });
       };
 
-      return ctx.ds.annotationQuery(options).then(data => {
+      return ctx.ds.annotationQuery(options).then((data: any) => {
         results = data;
       });
     });
@@ -77,7 +79,7 @@ describe('MSSQLDatasource', () => {
   });
 
   describe('When performing metricFindQuery', () => {
-    let results;
+    let results: any;
     const query = 'select * from atable';
     const response = {
       results: {
@@ -97,11 +99,11 @@ describe('MSSQLDatasource', () => {
     };
 
     beforeEach(() => {
-      ctx.backendSrv.datasourceRequest = options => {
+      ctx.backendSrv.datasourceRequest = (options: any) => {
         return ctx.$q.when({ data: response, status: 200 });
       };
 
-      return ctx.ds.metricFindQuery(query).then(data => {
+      return ctx.ds.metricFindQuery(query).then((data: any) => {
         results = data;
       });
     });
@@ -114,7 +116,7 @@ describe('MSSQLDatasource', () => {
   });
 
   describe('When performing metricFindQuery with key, value columns', () => {
-    let results;
+    let results: any;
     const query = 'select * from atable';
     const response = {
       results: {
@@ -134,11 +136,11 @@ describe('MSSQLDatasource', () => {
     };
 
     beforeEach(() => {
-      ctx.backendSrv.datasourceRequest = options => {
+      ctx.backendSrv.datasourceRequest = (options: any) => {
         return ctx.$q.when({ data: response, status: 200 });
       };
 
-      return ctx.ds.metricFindQuery(query).then(data => {
+      return ctx.ds.metricFindQuery(query).then((data: any) => {
         results = data;
       });
     });
@@ -153,7 +155,7 @@ describe('MSSQLDatasource', () => {
   });
 
   describe('When performing metricFindQuery with key, value columns and with duplicate keys', () => {
-    let results;
+    let results: any;
     const query = 'select * from atable';
     const response = {
       results: {
@@ -173,11 +175,11 @@ describe('MSSQLDatasource', () => {
     };
 
     beforeEach(() => {
-      ctx.backendSrv.datasourceRequest = options => {
+      ctx.backendSrv.datasourceRequest = (options: any) => {
         return ctx.$q.when({ data: response, status: 200 });
       };
 
-      return ctx.ds.metricFindQuery(query).then(data => {
+      return ctx.ds.metricFindQuery(query).then((data: any) => {
         results = data;
       });
     });
@@ -190,7 +192,7 @@ describe('MSSQLDatasource', () => {
   });
 
   describe('When performing metricFindQuery', () => {
-    let results;
+    let results: any;
     const query = 'select * from atable';
     const response = {
       results: {
@@ -216,7 +218,7 @@ describe('MSSQLDatasource', () => {
     beforeEach(() => {
       ctx.timeSrv.setTime(time);
 
-      ctx.backendSrv.datasourceRequest = options => {
+      ctx.backendSrv.datasourceRequest = (options: any) => {
         results = options.data;
         return ctx.$q.when({ data: response, status: 200 });
       };

+ 21 - 11
public/app/plugins/datasource/mysql/datasource.ts

@@ -1,6 +1,10 @@
 import _ from 'lodash';
 import ResponseParser from './response_parser';
 import MysqlQuery from 'app/plugins/datasource/mysql/mysql_query';
+import { BackendSrv } from 'app/core/services/backend_srv';
+import { IQService } from 'angular';
+import { TemplateSrv } from 'app/features/templating/template_srv';
+import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
 
 export class MysqlDatasource {
   id: any;
@@ -10,7 +14,13 @@ export class MysqlDatasource {
   interval: string;
 
   /** @ngInject */
-  constructor(instanceSettings, private backendSrv, private $q, private templateSrv, private timeSrv) {
+  constructor(
+    instanceSettings: any,
+    private backendSrv: BackendSrv,
+    private $q: IQService,
+    private templateSrv: TemplateSrv,
+    private timeSrv: TimeSrv
+  ) {
     this.name = instanceSettings.name;
     this.id = instanceSettings.id;
     this.responseParser = new ResponseParser(this.$q);
@@ -18,7 +28,7 @@ export class MysqlDatasource {
     this.interval = (instanceSettings.jsonData || {}).timeInterval || '1m';
   }
 
-  interpolateVariable = (value, variable) => {
+  interpolateVariable = (value: string, variable: any) => {
     if (typeof value === 'string') {
       if (variable.multi || variable.includeAll) {
         return this.queryModel.quoteLiteral(value);
@@ -31,13 +41,13 @@ export class MysqlDatasource {
       return value;
     }
 
-    const quotedValues = _.map(value, v => {
+    const quotedValues = _.map(value, (v: any) => {
       return this.queryModel.quoteLiteral(v);
     });
     return quotedValues.join(',');
   };
 
-  query(options) {
+  query(options: any) {
     const queries = _.filter(options.targets, target => {
       return target.hide !== true;
     }).map(target => {
@@ -48,7 +58,7 @@ export class MysqlDatasource {
         intervalMs: options.intervalMs,
         maxDataPoints: options.maxDataPoints,
         datasourceId: this.id,
-        rawSql: queryModel.render(this.interpolateVariable),
+        rawSql: queryModel.render(this.interpolateVariable as any),
         format: target.format,
       };
     });
@@ -70,7 +80,7 @@ export class MysqlDatasource {
       .then(this.responseParser.processQueryResult);
   }
 
-  annotationQuery(options) {
+  annotationQuery(options: any) {
     if (!options.annotation.rawQuery) {
       return this.$q.reject({
         message: 'Query missing in annotation definition',
@@ -94,10 +104,10 @@ export class MysqlDatasource {
           queries: [query],
         },
       })
-      .then(data => this.responseParser.transformAnnotationResponse(options, data));
+      .then((data: any) => this.responseParser.transformAnnotationResponse(options, data));
   }
 
-  metricFindQuery(query, optionalOptions) {
+  metricFindQuery(query: string, optionalOptions: any) {
     let refId = 'tempvar';
     if (optionalOptions && optionalOptions.variable && optionalOptions.variable.name) {
       refId = optionalOptions.variable.name;
@@ -130,7 +140,7 @@ export class MysqlDatasource {
         method: 'POST',
         data: data,
       })
-      .then(data => this.responseParser.parseMetricFindQueryResult(refId, data));
+      .then((data: any) => this.responseParser.parseMetricFindQueryResult(refId, data));
   }
 
   testDatasource() {
@@ -153,10 +163,10 @@ export class MysqlDatasource {
           ],
         },
       })
-      .then(res => {
+      .then((res: any) => {
         return { status: 'success', message: 'Database Connection OK' };
       })
-      .catch(err => {
+      .catch((err: any) => {
         console.log(err);
         if (err.data && err.data.message) {
           return { status: 'error', message: err.data.message };

+ 2 - 2
public/app/plugins/datasource/mysql/meta_query.ts

@@ -1,5 +1,5 @@
 export class MysqlMetaQuery {
-  constructor(private target, private queryModel) {}
+  constructor(private target: any, private queryModel: any) {}
 
   getOperators(datatype: string) {
     switch (datatype) {
@@ -22,7 +22,7 @@ export class MysqlMetaQuery {
   }
 
   // quote identifier as literal to use in metadata queries
-  quoteIdentAsLiteral(value) {
+  quoteIdentAsLiteral(value: string) {
     return this.queryModel.quoteLiteral(this.queryModel.unquoteIdentifier(value));
   }
 

+ 10 - 8
public/app/plugins/datasource/mysql/mysql_query.ts

@@ -1,4 +1,6 @@
 import _ from 'lodash';
+import { TemplateSrv } from 'app/features/templating/template_srv';
+import { ScopedVars } from '@grafana/ui';
 
 export default class MysqlQuery {
   target: any;
@@ -6,7 +8,7 @@ export default class MysqlQuery {
   scopedVars: any;
 
   /** @ngInject */
-  constructor(target, templateSrv?, scopedVars?) {
+  constructor(target: any, templateSrv?: TemplateSrv, scopedVars?: ScopedVars) {
     this.target = target;
     this.templateSrv = templateSrv;
     this.scopedVars = scopedVars;
@@ -35,7 +37,7 @@ export default class MysqlQuery {
   }
 
   // remove identifier quoting from identifier to use in metadata queries
-  unquoteIdentifier(value) {
+  unquoteIdentifier(value: string) {
     if (value[0] === '"' && value[value.length - 1] === '"') {
       return value.substring(1, value.length - 1).replace(/""/g, '"');
     } else {
@@ -43,15 +45,15 @@ export default class MysqlQuery {
     }
   }
 
-  quoteIdentifier(value) {
+  quoteIdentifier(value: string) {
     return '"' + value.replace(/"/g, '""') + '"';
   }
 
-  quoteLiteral(value) {
+  quoteLiteral(value: string) {
     return "'" + value.replace(/'/g, "''") + "'";
   }
 
-  escapeLiteral(value) {
+  escapeLiteral(value: any) {
     return String(value).replace(/'/g, "''");
   }
 
@@ -63,7 +65,7 @@ export default class MysqlQuery {
     return this.target.metricColumn !== 'none';
   }
 
-  interpolateQueryStr(value, variable, defaultFormatFn) {
+  interpolateQueryStr(value: string, variable: { multi: any; includeAll: any }, defaultFormatFn: any) {
     // if no multi or include all do not regexEscape
     if (!variable.multi && !variable.includeAll) {
       return this.escapeLiteral(value);
@@ -77,7 +79,7 @@ export default class MysqlQuery {
     return escapedValues.join(',');
   }
 
-  render(interpolate?) {
+  render(interpolate?: boolean) {
     const target = this.target;
 
     // new query with no table set yet
@@ -146,7 +148,7 @@ export default class MysqlQuery {
     return query;
   }
 
-  buildValueColumn(column) {
+  buildValueColumn(column: any) {
     let query = '';
 
     const columnName: any = _.find(column, (g: any) => g.type === 'column');

+ 53 - 43
public/app/plugins/datasource/mysql/query_ctrl.ts

@@ -5,6 +5,8 @@ import { QueryCtrl } from 'app/plugins/sdk';
 import { SqlPart } from 'app/core/components/sql_part/sql_part';
 import MysqlQuery from './mysql_query';
 import sqlPart from './sql_part';
+import { auto, IQService } from 'angular';
+import { TemplateSrv } from 'app/features/templating/template_srv';
 
 export interface QueryMeta {
   sql: string;
@@ -41,7 +43,13 @@ export class MysqlQueryCtrl extends QueryCtrl {
   groupAdd: any;
 
   /** @ngInject */
-  constructor($scope, $injector, private templateSrv, private $q, private uiSegmentSrv) {
+  constructor(
+    $scope: any,
+    $injector: auto.IInjectorService,
+    private templateSrv: TemplateSrv,
+    private $q: IQService,
+    private uiSegmentSrv: any
+  ) {
     super($scope, $injector);
 
     this.target = this.target;
@@ -59,7 +67,7 @@ export class MysqlQueryCtrl extends QueryCtrl {
         this.target.rawQuery = true;
       } else {
         this.target.rawSql = defaultQuery;
-        this.datasource.metricFindQuery(this.metaBuilder.findMetricTable()).then(result => {
+        this.datasource.metricFindQuery(this.metaBuilder.findMetricTable()).then((result: any) => {
           if (result.length > 0) {
             this.target.table = result[0].text;
             let segment = this.uiSegmentSrv.newSegment(this.target.table);
@@ -156,7 +164,7 @@ export class MysqlQueryCtrl extends QueryCtrl {
     }
   }
 
-  resetPlusButton(button) {
+  resetPlusButton(button: { html: any; value: any }) {
     const plusButton = this.uiSegmentSrv.newPlusButton();
     button.html = plusButton.html;
     button.value = plusButton.value;
@@ -180,7 +188,7 @@ export class MysqlQueryCtrl extends QueryCtrl {
     this.metricColumnSegment.value = segment.value;
     this.target.metricColumn = 'none';
 
-    const task1 = this.datasource.metricFindQuery(this.metaBuilder.buildColumnQuery('time')).then(result => {
+    const task1 = this.datasource.metricFindQuery(this.metaBuilder.buildColumnQuery('time')).then((result: any) => {
       // check if time column is still valid
       if (result.length > 0 && !_.find(result, (r: any) => r.text === this.target.timeColumn)) {
         const segment = this.uiSegmentSrv.newSegment(result[0].text);
@@ -189,7 +197,7 @@ export class MysqlQueryCtrl extends QueryCtrl {
       }
       return this.timeColumnChanged(false);
     });
-    const task2 = this.datasource.metricFindQuery(this.metaBuilder.buildColumnQuery('value')).then(result => {
+    const task2 = this.datasource.metricFindQuery(this.metaBuilder.buildColumnQuery('value')).then((result: any) => {
       if (result.length > 0) {
         this.target.select = [[{ type: 'column', params: [result[0].text] }]];
         this.updateProjection();
@@ -210,31 +218,33 @@ export class MysqlQueryCtrl extends QueryCtrl {
 
   timeColumnChanged(refresh?: boolean) {
     this.target.timeColumn = this.timeColumnSegment.value;
-    return this.datasource.metricFindQuery(this.metaBuilder.buildDatatypeQuery(this.target.timeColumn)).then(result => {
-      if (result.length === 1) {
-        if (this.target.timeColumnType !== result[0].text) {
-          this.target.timeColumnType = result[0].text;
-        }
-        let partModel;
-        if (this.queryModel.hasUnixEpochTimecolumn()) {
-          partModel = sqlPart.create({ type: 'macro', name: '$__unixEpochFilter', params: [] });
-        } else {
-          partModel = sqlPart.create({ type: 'macro', name: '$__timeFilter', params: [] });
-        }
+    return this.datasource
+      .metricFindQuery(this.metaBuilder.buildDatatypeQuery(this.target.timeColumn))
+      .then((result: any) => {
+        if (result.length === 1) {
+          if (this.target.timeColumnType !== result[0].text) {
+            this.target.timeColumnType = result[0].text;
+          }
+          let partModel;
+          if (this.queryModel.hasUnixEpochTimecolumn()) {
+            partModel = sqlPart.create({ type: 'macro', name: '$__unixEpochFilter', params: [] });
+          } else {
+            partModel = sqlPart.create({ type: 'macro', name: '$__timeFilter', params: [] });
+          }
 
-        if (this.whereParts.length >= 1 && this.whereParts[0].def.type === 'macro') {
-          // replace current macro
-          this.whereParts[0] = partModel;
-        } else {
-          this.whereParts.splice(0, 0, partModel);
+          if (this.whereParts.length >= 1 && this.whereParts[0].def.type === 'macro') {
+            // replace current macro
+            this.whereParts[0] = partModel;
+          } else {
+            this.whereParts.splice(0, 0, partModel);
+          }
         }
-      }
 
-      this.updatePersistedParts();
-      if (refresh !== false) {
-        this.panelCtrl.refresh();
-      }
-    });
+        this.updatePersistedParts();
+        if (refresh !== false) {
+          this.panelCtrl.refresh();
+        }
+      });
   }
 
   getMetricColumnSegments() {
@@ -249,7 +259,7 @@ export class MysqlQueryCtrl extends QueryCtrl {
     this.panelCtrl.refresh();
   }
 
-  onDataReceived(dataList) {
+  onDataReceived(dataList: any) {
     this.lastQueryMeta = null;
     this.lastQueryError = null;
 
@@ -259,7 +269,7 @@ export class MysqlQueryCtrl extends QueryCtrl {
     }
   }
 
-  onDataError(err) {
+  onDataError(err: any) {
     if (err.data && err.data.results) {
       const queryRes = err.data.results[this.target.refId];
       if (queryRes) {
@@ -269,8 +279,8 @@ export class MysqlQueryCtrl extends QueryCtrl {
     }
   }
 
-  transformToSegments(config) {
-    return results => {
+  transformToSegments(config: any) {
+    return (results: any) => {
       const segments = _.map(results, segment => {
         return this.uiSegmentSrv.newSegment({
           value: segment.text,
@@ -304,15 +314,15 @@ export class MysqlQueryCtrl extends QueryCtrl {
     };
   }
 
-  findAggregateIndex(selectParts) {
+  findAggregateIndex(selectParts: any) {
     return _.findIndex(selectParts, (p: any) => p.def.type === 'aggregate' || p.def.type === 'percentile');
   }
 
-  findWindowIndex(selectParts) {
+  findWindowIndex(selectParts: any) {
     return _.findIndex(selectParts, (p: any) => p.def.type === 'window' || p.def.type === 'moving_window');
   }
 
-  addSelectPart(selectParts, item, subItem) {
+  addSelectPart(selectParts: any[], item: { value: any }, subItem: { type: any; value: any }) {
     let partType = item.value;
     if (subItem && subItem.type) {
       partType = subItem.type;
@@ -384,7 +394,7 @@ export class MysqlQueryCtrl extends QueryCtrl {
     this.panelCtrl.refresh();
   }
 
-  removeSelectPart(selectParts, part) {
+  removeSelectPart(selectParts: any, part: { def: { type: string } }) {
     if (part.def.type === 'column') {
       // remove all parts of column unless its last column
       if (this.selectParts.length > 1) {
@@ -399,7 +409,7 @@ export class MysqlQueryCtrl extends QueryCtrl {
     this.updatePersistedParts();
   }
 
-  handleSelectPartEvent(selectParts, part, evt) {
+  handleSelectPartEvent(selectParts: any, part: { def: any }, evt: { name: any }) {
     switch (evt.name) {
       case 'get-param-options': {
         switch (part.def.type) {
@@ -431,7 +441,7 @@ export class MysqlQueryCtrl extends QueryCtrl {
     }
   }
 
-  handleGroupPartEvent(part, index, evt) {
+  handleGroupPartEvent(part: any, index: any, evt: { name: any }) {
     switch (evt.name) {
       case 'get-param-options': {
         return this.datasource
@@ -455,7 +465,7 @@ export class MysqlQueryCtrl extends QueryCtrl {
     }
   }
 
-  addGroup(partType, value) {
+  addGroup(partType: string, value: string) {
     let params = [value];
     if (partType === 'time') {
       params = ['$__interval', 'none'];
@@ -484,7 +494,7 @@ export class MysqlQueryCtrl extends QueryCtrl {
     this.updatePersistedParts();
   }
 
-  removeGroup(part, index) {
+  removeGroup(part: { def: { type: string } }, index: number) {
     if (part.def.type === 'time') {
       // remove aggregations
       this.selectParts = _.map(this.selectParts, (s: any) => {
@@ -501,7 +511,7 @@ export class MysqlQueryCtrl extends QueryCtrl {
     this.updatePersistedParts();
   }
 
-  handleWherePartEvent(whereParts, part, evt, index) {
+  handleWherePartEvent(whereParts: any, part: any, evt: any, index: any) {
     switch (evt.name) {
       case 'get-param-options': {
         switch (evt.param.name) {
@@ -567,7 +577,7 @@ export class MysqlQueryCtrl extends QueryCtrl {
     return this.$q.when(options);
   }
 
-  addWhereAction(part, index) {
+  addWhereAction(part: any, index: number) {
     switch (this.whereAdd.type) {
       case 'macro': {
         const partModel = sqlPart.create({ type: 'macro', name: this.whereAdd.value, params: [] });
@@ -592,7 +602,7 @@ export class MysqlQueryCtrl extends QueryCtrl {
   getGroupOptions() {
     return this.datasource
       .metricFindQuery(this.metaBuilder.buildColumnQuery('group'))
-      .then(tags => {
+      .then((tags: any) => {
         const options = [];
         if (!this.queryModel.hasTimeGroup()) {
           options.push(this.uiSegmentSrv.newSegment({ type: 'time', value: 'time($__interval,none)' }));
@@ -616,7 +626,7 @@ export class MysqlQueryCtrl extends QueryCtrl {
     this.panelCtrl.refresh();
   }
 
-  handleQueryError(err) {
+  handleQueryError(err: any): any[] {
     this.error = err.message || 'Failed to issue metric query';
     return [];
   }

+ 10 - 9
public/app/plugins/datasource/mysql/response_parser.ts

@@ -1,10 +1,11 @@
 import _ from 'lodash';
+import { IQService } from 'angular';
 
 export default class ResponseParser {
-  constructor(private $q) {}
+  constructor(private $q: IQService) {}
 
-  processQueryResult(res) {
-    const data = [];
+  processQueryResult(res: any) {
+    const data: any[] = [];
 
     if (!res.data.results) {
       return { data: data };
@@ -37,7 +38,7 @@ export default class ResponseParser {
     return { data: data };
   }
 
-  parseMetricFindQueryResult(refId, results) {
+  parseMetricFindQueryResult(refId: string, results: any) {
     if (!results || results.data.length === 0 || results.data.results[refId].meta.rowCount === 0) {
       return [];
     }
@@ -54,7 +55,7 @@ export default class ResponseParser {
     return this.transformToSimpleList(rows);
   }
 
-  transformToKeyValueList(rows, textColIndex, valueColIndex) {
+  transformToKeyValueList(rows: any, textColIndex: number, valueColIndex: number) {
     const res = [];
 
     for (let i = 0; i < rows.length; i++) {
@@ -69,7 +70,7 @@ export default class ResponseParser {
     return res;
   }
 
-  transformToSimpleList(rows) {
+  transformToSimpleList(rows: any) {
     const res = [];
 
     for (let i = 0; i < rows.length; i++) {
@@ -86,7 +87,7 @@ export default class ResponseParser {
     });
   }
 
-  findColIndex(columns, colName) {
+  findColIndex(columns: any[], colName: string) {
     for (let i = 0; i < columns.length; i++) {
       if (columns[i].text === colName) {
         return i;
@@ -96,7 +97,7 @@ export default class ResponseParser {
     return -1;
   }
 
-  containsKey(res, key) {
+  containsKey(res: any[], key: any) {
     for (let i = 0; i < res.length; i++) {
       if (res[i].text === key) {
         return true;
@@ -105,7 +106,7 @@ export default class ResponseParser {
     return false;
   }
 
-  transformAnnotationResponse(options, data) {
+  transformAnnotationResponse(options: any, data: any) {
     const table = data.data.results[options.annotation.name].tables[0];
 
     let timeColumnIndex = -1;

+ 11 - 10
public/app/plugins/datasource/mysql/specs/datasource.test.ts

@@ -1,11 +1,12 @@
 import { MysqlDatasource } from '../datasource';
 import { CustomVariable } from 'app/features/templating/custom_variable';
 import { toUtc, dateTime } from '@grafana/ui/src/utils/moment_wrapper';
+import { BackendSrv } from 'app/core/services/backend_srv';
 
 describe('MySQLDatasource', () => {
   const instanceSettings = { name: 'mysql' };
   const backendSrv = {};
-  const templateSrv = {
+  const templateSrv: any = {
     replace: jest.fn(text => text),
   };
 
@@ -25,11 +26,11 @@ describe('MySQLDatasource', () => {
   } as any;
 
   beforeEach(() => {
-    ctx.ds = new MysqlDatasource(instanceSettings, backendSrv, {}, templateSrv, ctx.timeSrvMock);
+    ctx.ds = new MysqlDatasource(instanceSettings, backendSrv as BackendSrv, {} as any, templateSrv, ctx.timeSrvMock);
   });
 
   describe('When performing annotationQuery', () => {
-    let results;
+    let results: any;
 
     const annotationName = 'MyAnno';
 
@@ -66,7 +67,7 @@ describe('MySQLDatasource', () => {
       ctx.backendSrv.datasourceRequest = jest.fn(options => {
         return Promise.resolve({ data: response, status: 200 });
       });
-      ctx.ds.annotationQuery(options).then(data => {
+      ctx.ds.annotationQuery(options).then((data: any) => {
         results = data;
       });
     });
@@ -86,7 +87,7 @@ describe('MySQLDatasource', () => {
   });
 
   describe('When performing metricFindQuery', () => {
-    let results;
+    let results: any;
     const query = 'select * from atable';
     const response = {
       results: {
@@ -109,7 +110,7 @@ describe('MySQLDatasource', () => {
       ctx.backendSrv.datasourceRequest = jest.fn(options => {
         return Promise.resolve({ data: response, status: 200 });
       });
-      ctx.ds.metricFindQuery(query).then(data => {
+      ctx.ds.metricFindQuery(query).then((data: any) => {
         results = data;
       });
     });
@@ -122,7 +123,7 @@ describe('MySQLDatasource', () => {
   });
 
   describe('When performing metricFindQuery with key, value columns', () => {
-    let results;
+    let results: any;
     const query = 'select * from atable';
     const response = {
       results: {
@@ -145,7 +146,7 @@ describe('MySQLDatasource', () => {
       ctx.backendSrv.datasourceRequest = jest.fn(options => {
         return Promise.resolve({ data: response, status: 200 });
       });
-      ctx.ds.metricFindQuery(query).then(data => {
+      ctx.ds.metricFindQuery(query).then((data: any) => {
         results = data;
       });
     });
@@ -160,7 +161,7 @@ describe('MySQLDatasource', () => {
   });
 
   describe('When performing metricFindQuery with key, value columns and with duplicate keys', () => {
-    let results;
+    let results: any;
     const query = 'select * from atable';
     const response = {
       results: {
@@ -183,7 +184,7 @@ describe('MySQLDatasource', () => {
       ctx.backendSrv.datasourceRequest = jest.fn(options => {
         return Promise.resolve({ data: response, status: 200 });
       });
-      ctx.ds.metricFindQuery(query).then(data => {
+      ctx.ds.metricFindQuery(query).then((data: any) => {
         results = data;
       });
     });

+ 2 - 2
public/app/plugins/datasource/mysql/sql_part.ts

@@ -1,8 +1,8 @@
 import { SqlPartDef, SqlPart } from 'app/core/components/sql_part/sql_part';
 
-const index = [];
+const index: any[] = [];
 
-function createPart(part): any {
+function createPart(part: any): any {
   const def = index[part.type];
   if (!def) {
     return null;

+ 1 - 1
public/app/plugins/datasource/opentsdb/config_ctrl.ts

@@ -3,7 +3,7 @@ export class OpenTsConfigCtrl {
   current: any;
 
   /** @ngInject */
-  constructor($scope) {
+  constructor($scope: any) {
     this.current.jsonData = this.current.jsonData || {};
     this.current.jsonData.tsdbVersion = this.current.jsonData.tsdbVersion || 1;
     this.current.jsonData.tsdbResolution = this.current.jsonData.tsdbResolution || 1;

+ 48 - 35
public/app/plugins/datasource/opentsdb/datasource.ts

@@ -1,6 +1,9 @@
-import angular from 'angular';
+import angular, { IQService } from 'angular';
 import _ from 'lodash';
 import * as dateMath from '@grafana/ui/src/utils/datemath';
+import { BackendSrv } from 'app/core/services/backend_srv';
+import { TemplateSrv } from 'app/features/templating/template_srv';
+import { DataQueryRequest } from '@grafana/ui';
 
 export default class OpenTsDatasource {
   type: any;
@@ -16,7 +19,12 @@ export default class OpenTsDatasource {
   filterTypesPromise: any;
 
   /** @ngInject */
-  constructor(instanceSettings, private $q, private backendSrv, private templateSrv) {
+  constructor(
+    instanceSettings: any,
+    private $q: IQService,
+    private backendSrv: BackendSrv,
+    private templateSrv: TemplateSrv
+  ) {
     this.type = 'opentsdb';
     this.url = instanceSettings.url;
     this.name = instanceSettings.name;
@@ -32,10 +40,10 @@ export default class OpenTsDatasource {
   }
 
   // Called once per panel (graph)
-  query(options) {
+  query(options: DataQueryRequest) {
     const start = this.convertToTSDBTime(options.rangeRaw.from, false, options.timezone);
     const end = this.convertToTSDBTime(options.rangeRaw.to, true, options.timezone);
-    const qs = [];
+    const qs: any[] = [];
 
     _.each(options.targets, target => {
       if (!target.metric) {
@@ -53,7 +61,7 @@ export default class OpenTsDatasource {
       return d.promise;
     }
 
-    const groupByTags = {};
+    const groupByTags: any = {};
     _.each(queries, query => {
       if (query.filters && query.filters.length > 0) {
         _.each(query.filters, val => {
@@ -70,7 +78,7 @@ export default class OpenTsDatasource {
       return query.hide !== true;
     });
 
-    return this.performTimeSeriesQuery(queries, start, end).then(response => {
+    return this.performTimeSeriesQuery(queries, start, end).then((response: any) => {
       const metricToTargetMapping = this.mapMetricsToTargets(response.data, options, this.tsdbVersion);
       const result = _.map(response.data, (metricData: any, index: number) => {
         index = metricToTargetMapping[index];
@@ -85,17 +93,17 @@ export default class OpenTsDatasource {
     });
   }
 
-  annotationQuery(options) {
+  annotationQuery(options: any) {
     const start = this.convertToTSDBTime(options.rangeRaw.from, false, options.timezone);
     const end = this.convertToTSDBTime(options.rangeRaw.to, true, options.timezone);
     const qs = [];
-    const eventList = [];
+    const eventList: any[] = [];
 
     qs.push({ aggregator: 'sum', metric: options.annotation.target });
 
     const queries = _.compact(qs);
 
-    return this.performTimeSeriesQuery(queries, start, end).then(results => {
+    return this.performTimeSeriesQuery(queries, start, end).then((results: any) => {
       if (results.data[0]) {
         let annotationObject = results.data[0].annotations;
         if (options.annotation.isGlobal) {
@@ -117,7 +125,7 @@ export default class OpenTsDatasource {
     });
   }
 
-  targetContainsTemplate(target) {
+  targetContainsTemplate(target: any) {
     if (target.filters && target.filters.length > 0) {
       for (let i = 0; i < target.filters.length; i++) {
         if (this.templateSrv.variableExists(target.filters[i].filter)) {
@@ -137,7 +145,7 @@ export default class OpenTsDatasource {
     return false;
   }
 
-  performTimeSeriesQuery(queries, start, end) {
+  performTimeSeriesQuery(queries: any[], start: any, end: any) {
     let msResolution = false;
     if (this.tsdbResolution === 2) {
       msResolution = true;
@@ -167,11 +175,11 @@ export default class OpenTsDatasource {
     return this.backendSrv.datasourceRequest(options);
   }
 
-  suggestTagKeys(metric) {
+  suggestTagKeys(metric: string | number) {
     return this.$q.when(this.tagKeys[metric] || []);
   }
 
-  _saveTagKeys(metricData) {
+  _saveTagKeys(metricData: { tags: {}; aggregateTags: any; metric: string | number }) {
     const tagKeys = Object.keys(metricData.tags);
     _.each(metricData.aggregateTags, tag => {
       tagKeys.push(tag);
@@ -180,18 +188,18 @@ export default class OpenTsDatasource {
     this.tagKeys[metricData.metric] = tagKeys;
   }
 
-  _performSuggestQuery(query, type) {
-    return this._get('/api/suggest', { type: type, q: query, max: 1000 }).then(result => {
+  _performSuggestQuery(query: string, type: string) {
+    return this._get('/api/suggest', { type, q: query, max: 1000 }).then((result: any) => {
       return result.data;
     });
   }
 
-  _performMetricKeyValueLookup(metric, keys) {
+  _performMetricKeyValueLookup(metric: string, keys: any) {
     if (!metric || !keys) {
       return this.$q.when([]);
     }
 
-    const keysArray = keys.split(',').map(key => {
+    const keysArray = keys.split(',').map((key: any) => {
       return key.trim();
     });
     const key = keysArray[0];
@@ -203,9 +211,9 @@ export default class OpenTsDatasource {
 
     const m = metric + '{' + keysQuery + '}';
 
-    return this._get('/api/search/lookup', { m: m, limit: 3000 }).then(result => {
+    return this._get('/api/search/lookup', { m: m, limit: 3000 }).then((result: any) => {
       result = result.data.results;
-      const tagvs = [];
+      const tagvs: any[] = [];
       _.each(result, r => {
         if (tagvs.indexOf(r.tags[key]) === -1) {
           tagvs.push(r.tags[key]);
@@ -215,14 +223,14 @@ export default class OpenTsDatasource {
     });
   }
 
-  _performMetricKeyLookup(metric) {
+  _performMetricKeyLookup(metric: any) {
     if (!metric) {
       return this.$q.when([]);
     }
 
-    return this._get('/api/search/lookup', { m: metric, limit: 1000 }).then(result => {
+    return this._get('/api/search/lookup', { m: metric, limit: 1000 }).then((result: any) => {
       result = result.data.results;
-      const tagks = [];
+      const tagks: any[] = [];
       _.each(result, r => {
         _.each(r.tags, (tagv, tagk) => {
           if (tagks.indexOf(tagk) === -1) {
@@ -234,7 +242,7 @@ export default class OpenTsDatasource {
     });
   }
 
-  _get(relativeUrl, params?) {
+  _get(relativeUrl: string, params?: { type?: string; q?: string; max?: number; m?: any; limit?: number }) {
     const options = {
       method: 'GET',
       url: this.url + relativeUrl,
@@ -246,7 +254,7 @@ export default class OpenTsDatasource {
     return this.backendSrv.datasourceRequest(options);
   }
 
-  _addCredentialOptions(options) {
+  _addCredentialOptions(options: any) {
     if (this.basicAuth || this.withCredentials) {
       options.withCredentials = true;
     }
@@ -255,7 +263,7 @@ export default class OpenTsDatasource {
     }
   }
 
-  metricFindQuery(query) {
+  metricFindQuery(query: string) {
     if (!query) {
       return this.$q.when([]);
     }
@@ -267,7 +275,7 @@ export default class OpenTsDatasource {
       return this.$q.reject(err);
     }
 
-    const responseTransform = result => {
+    const responseTransform = (result: any) => {
       return _.map(result, value => {
         return { text: value };
       });
@@ -318,7 +326,7 @@ export default class OpenTsDatasource {
       return this.aggregatorsPromise;
     }
 
-    this.aggregatorsPromise = this._get('/api/aggregators').then(result => {
+    this.aggregatorsPromise = this._get('/api/aggregators').then((result: any) => {
       if (result.data && _.isArray(result.data)) {
         return result.data.sort();
       }
@@ -332,7 +340,7 @@ export default class OpenTsDatasource {
       return this.filterTypesPromise;
     }
 
-    this.filterTypesPromise = this._get('/api/config/filters').then(result => {
+    this.filterTypesPromise = this._get('/api/config/filters').then((result: any) => {
       if (result.data) {
         return Object.keys(result.data).sort();
       }
@@ -341,9 +349,9 @@ export default class OpenTsDatasource {
     return this.filterTypesPromise;
   }
 
-  transformMetricData(md, groupByTags, target, options, tsdbResolution) {
+  transformMetricData(md: { dps: any }, groupByTags: any, target: any, options: any, tsdbResolution: number) {
     const metricLabel = this.createMetricLabel(md, target, groupByTags, options);
-    const dps = [];
+    const dps: any[] = [];
 
     // TSDB returns datapoints has a hash of ts => value.
     // Can't use _.pairs(invert()) because it stringifies keys/values
@@ -358,7 +366,12 @@ export default class OpenTsDatasource {
     return { target: metricLabel, datapoints: dps };
   }
 
-  createMetricLabel(md, target, groupByTags, options) {
+  createMetricLabel(
+    md: { dps?: any; tags?: any; metric?: any },
+    target: { alias: string },
+    groupByTags: any,
+    options: { scopedVars: any }
+  ) {
     if (target.alias) {
       const scopedVars = _.clone(options.scopedVars || {});
       _.each(md.tags, (value, key) => {
@@ -368,7 +381,7 @@ export default class OpenTsDatasource {
     }
 
     let label = md.metric;
-    const tagData = [];
+    const tagData: any[] = [];
 
     if (!_.isEmpty(md.tags)) {
       _.each(_.toPairs(md.tags), tag => {
@@ -385,7 +398,7 @@ export default class OpenTsDatasource {
     return label;
   }
 
-  convertTargetToQuery(target, options, tsdbVersion) {
+  convertTargetToQuery(target: any, options: any, tsdbVersion: number) {
     if (!target.metric || target.hide) {
       return null;
     }
@@ -460,7 +473,7 @@ export default class OpenTsDatasource {
     return query;
   }
 
-  mapMetricsToTargets(metrics, options, tsdbVersion) {
+  mapMetricsToTargets(metrics: any, options: any, tsdbVersion: number) {
     let interpolatedTagValue, arrTagV;
     return _.map(metrics, metricData => {
       if (tsdbVersion === 3) {
@@ -484,7 +497,7 @@ export default class OpenTsDatasource {
     });
   }
 
-  convertToTSDBTime(date, roundUp, timezone) {
+  convertToTSDBTime(date: any, roundUp: any, timezone: any) {
     if (date === 'now') {
       return null;
     }

+ 12 - 11
public/app/plugins/datasource/opentsdb/query_ctrl.ts

@@ -1,6 +1,7 @@
 import _ from 'lodash';
 import kbn from 'app/core/utils/kbn';
 import { QueryCtrl } from 'app/plugins/sdk';
+import { auto } from 'angular';
 
 export class OpenTsQueryCtrl extends QueryCtrl {
   static templateUrl = 'partials/query.editor.html';
@@ -20,7 +21,7 @@ export class OpenTsQueryCtrl extends QueryCtrl {
   addFilterMode: boolean;
 
   /** @ngInject */
-  constructor($scope, $injector) {
+  constructor($scope: any, $injector: auto.IInjectorService) {
     super($scope, $injector);
 
     this.errors = this.validateTarget();
@@ -50,31 +51,31 @@ export class OpenTsQueryCtrl extends QueryCtrl {
       this.target.downsampleFillPolicy = 'none';
     }
 
-    this.datasource.getAggregators().then(aggs => {
+    this.datasource.getAggregators().then((aggs: { length: number }) => {
       if (aggs.length !== 0) {
         this.aggregators = aggs;
       }
     });
 
-    this.datasource.getFilterTypes().then(filterTypes => {
+    this.datasource.getFilterTypes().then((filterTypes: { length: number }) => {
       if (filterTypes.length !== 0) {
         this.filterTypes = filterTypes;
       }
     });
 
     // needs to be defined here as it is called from typeahead
-    this.suggestMetrics = (query, callback) => {
+    this.suggestMetrics = (query: string, callback: any) => {
       this.datasource
         .metricFindQuery('metrics(' + query + ')')
         .then(this.getTextValues)
         .then(callback);
     };
 
-    this.suggestTagKeys = (query, callback) => {
+    this.suggestTagKeys = (query: any, callback: any) => {
       this.datasource.suggestTagKeys(this.target.metric).then(callback);
     };
 
-    this.suggestTagValues = (query, callback) => {
+    this.suggestTagValues = (query: string, callback: any) => {
       this.datasource
         .metricFindQuery('suggest_tagv(' + query + ')')
         .then(this.getTextValues)
@@ -87,7 +88,7 @@ export class OpenTsQueryCtrl extends QueryCtrl {
     this.refresh();
   }
 
-  getTextValues(metricFindResult) {
+  getTextValues(metricFindResult: any) {
     return _.map(metricFindResult, value => {
       return value.text;
     });
@@ -119,12 +120,12 @@ export class OpenTsQueryCtrl extends QueryCtrl {
     this.addTagMode = false;
   }
 
-  removeTag(key) {
+  removeTag(key: string | number) {
     delete this.target.tags[key];
     this.targetBlur();
   }
 
-  editTag(key, value) {
+  editTag(key: string | number, value: any) {
     this.removeTag(key);
     this.target.currentTagKey = key;
     this.target.currentTagValue = value;
@@ -178,12 +179,12 @@ export class OpenTsQueryCtrl extends QueryCtrl {
     this.addFilterMode = false;
   }
 
-  removeFilter(index) {
+  removeFilter(index: number) {
     this.target.filters.splice(index, 1);
     this.targetBlur();
   }
 
-  editFilter(fil, index) {
+  editFilter(fil: { tagk: any; filter: any; type: any; groupBy: any }, index: number) {
     this.removeFilter(index);
     this.target.currentFilterKey = fil.tagk;
     this.target.currentFilterValue = fil.filter;

+ 12 - 11
public/app/plugins/datasource/opentsdb/specs/datasource.test.ts

@@ -1,4 +1,5 @@
 import OpenTsDatasource from '../datasource';
+// @ts-ignore
 import $q from 'q';
 
 describe('opentsdb', () => {
@@ -6,7 +7,7 @@ describe('opentsdb', () => {
     backendSrv: {},
     ds: {},
     templateSrv: {
-      replace: str => str,
+      replace: (str: string) => str,
     },
   } as any;
   const instanceSettings = { url: '', jsonData: { tsdbVersion: 1 } };
@@ -16,11 +17,11 @@ describe('opentsdb', () => {
   });
 
   describe('When performing metricFindQuery', () => {
-    let results;
-    let requestOptions;
+    let results: any;
+    let requestOptions: any;
 
     beforeEach(async () => {
-      ctx.backendSrv.datasourceRequest = await (options => {
+      ctx.backendSrv.datasourceRequest = await ((options: any) => {
         requestOptions = options;
         return Promise.resolve({
           data: [{ target: 'prod1.count', datapoints: [[10, 1], [12, 1]] }],
@@ -29,7 +30,7 @@ describe('opentsdb', () => {
     });
 
     it('metrics() should generate api suggest query', () => {
-      ctx.ctrl.metricFindQuery('metrics(pew)').then(data => {
+      ctx.ctrl.metricFindQuery('metrics(pew)').then((data: any) => {
         results = data;
       });
       expect(requestOptions.url).toBe('/api/suggest');
@@ -39,7 +40,7 @@ describe('opentsdb', () => {
     });
 
     it('tag_names(cpu) should generate lookup query', () => {
-      ctx.ctrl.metricFindQuery('tag_names(cpu)').then(data => {
+      ctx.ctrl.metricFindQuery('tag_names(cpu)').then((data: any) => {
         results = data;
       });
       expect(requestOptions.url).toBe('/api/search/lookup');
@@ -47,7 +48,7 @@ describe('opentsdb', () => {
     });
 
     it('tag_values(cpu, test) should generate lookup query', () => {
-      ctx.ctrl.metricFindQuery('tag_values(cpu, hostname)').then(data => {
+      ctx.ctrl.metricFindQuery('tag_values(cpu, hostname)').then((data: any) => {
         results = data;
       });
       expect(requestOptions.url).toBe('/api/search/lookup');
@@ -55,7 +56,7 @@ describe('opentsdb', () => {
     });
 
     it('tag_values(cpu, test) should generate lookup query', () => {
-      ctx.ctrl.metricFindQuery('tag_values(cpu, hostname, env=$env)').then(data => {
+      ctx.ctrl.metricFindQuery('tag_values(cpu, hostname, env=$env)').then((data: any) => {
         results = data;
       });
       expect(requestOptions.url).toBe('/api/search/lookup');
@@ -63,7 +64,7 @@ describe('opentsdb', () => {
     });
 
     it('tag_values(cpu, test) should generate lookup query', () => {
-      ctx.ctrl.metricFindQuery('tag_values(cpu, hostname, env=$env, region=$region)').then(data => {
+      ctx.ctrl.metricFindQuery('tag_values(cpu, hostname, env=$env, region=$region)').then((data: any) => {
         results = data;
       });
       expect(requestOptions.url).toBe('/api/search/lookup');
@@ -71,7 +72,7 @@ describe('opentsdb', () => {
     });
 
     it('suggest_tagk() should generate api suggest query', () => {
-      ctx.ctrl.metricFindQuery('suggest_tagk(foo)').then(data => {
+      ctx.ctrl.metricFindQuery('suggest_tagk(foo)').then((data: any) => {
         results = data;
       });
       expect(requestOptions.url).toBe('/api/suggest');
@@ -80,7 +81,7 @@ describe('opentsdb', () => {
     });
 
     it('suggest_tagv() should generate api suggest query', () => {
-      ctx.ctrl.metricFindQuery('suggest_tagv(bar)').then(data => {
+      ctx.ctrl.metricFindQuery('suggest_tagv(bar)').then((data: any) => {
         results = data;
       });
       expect(requestOptions.url).toBe('/api/suggest');

+ 1 - 1
public/app/plugins/datasource/opentsdb/specs/query_ctrl.test.ts

@@ -20,7 +20,7 @@ describe('OpenTsQueryCtrl', () => {
   OpenTsQueryCtrl.prototype = Object.assign(OpenTsQueryCtrl.prototype, ctx);
 
   beforeEach(() => {
-    ctx.ctrl = new OpenTsQueryCtrl({}, {});
+    ctx.ctrl = new OpenTsQueryCtrl({}, {} as any);
   });
 
   describe('init query_ctrl variables', () => {

+ 5 - 4
public/app/plugins/datasource/postgres/config_ctrl.ts

@@ -4,6 +4,7 @@ import {
   createResetHandler,
   PasswordFieldEnum,
 } from '../../../features/datasources/utils/passwordHandlers';
+import DatasourceSrv from 'app/features/plugins/datasource_srv';
 
 export class PostgresConfigCtrl {
   static templateUrl = 'partials/config.html';
@@ -15,7 +16,7 @@ export class PostgresConfigCtrl {
   onPasswordChange: ReturnType<typeof createChangeHandler>;
 
   /** @ngInject */
-  constructor($scope, datasourceSrv) {
+  constructor($scope: any, datasourceSrv: DatasourceSrv) {
     this.datasourceSrv = datasourceSrv;
     this.current.jsonData.sslmode = this.current.jsonData.sslmode || 'verify-full';
     this.current.jsonData.postgresVersion = this.current.jsonData.postgresVersion || 903;
@@ -30,13 +31,13 @@ export class PostgresConfigCtrl {
       return;
     }
 
-    this.datasourceSrv.loadDatasource(this.current.name).then(ds => {
-      return ds.getVersion().then(version => {
+    this.datasourceSrv.loadDatasource(this.current.name).then((ds: any) => {
+      return ds.getVersion().then((version: any) => {
         version = Number(version[0].text);
 
         // timescaledb is only available for 9.6+
         if (version >= 906) {
-          ds.getTimescaleDBVersion().then(version => {
+          ds.getTimescaleDBVersion().then((version: any) => {
             if (version.length === 1) {
               this.current.jsonData.timescaledb = true;
             }

+ 19 - 9
public/app/plugins/datasource/postgres/datasource.ts

@@ -1,6 +1,10 @@
 import _ from 'lodash';
 import ResponseParser from './response_parser';
 import PostgresQuery from 'app/plugins/datasource/postgres/postgres_query';
+import { IQService } from 'angular';
+import { BackendSrv } from 'app/core/services/backend_srv';
+import { TemplateSrv } from 'app/features/templating/template_srv';
+import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
 
 export class PostgresDatasource {
   id: any;
@@ -11,7 +15,13 @@ export class PostgresDatasource {
   interval: string;
 
   /** @ngInject */
-  constructor(instanceSettings, private backendSrv, private $q, private templateSrv, private timeSrv) {
+  constructor(
+    instanceSettings: { name: any; id?: any; jsonData?: any },
+    private backendSrv: BackendSrv,
+    private $q: IQService,
+    private templateSrv: TemplateSrv,
+    private timeSrv: TimeSrv
+  ) {
     this.name = instanceSettings.name;
     this.id = instanceSettings.id;
     this.jsonData = instanceSettings.jsonData;
@@ -20,7 +30,7 @@ export class PostgresDatasource {
     this.interval = (instanceSettings.jsonData || {}).timeInterval || '1m';
   }
 
-  interpolateVariable = (value, variable) => {
+  interpolateVariable = (value: string, variable: { multi: any; includeAll: any }) => {
     if (typeof value === 'string') {
       if (variable.multi || variable.includeAll) {
         return this.queryModel.quoteLiteral(value);
@@ -39,7 +49,7 @@ export class PostgresDatasource {
     return quotedValues.join(',');
   };
 
-  query(options) {
+  query(options: any) {
     const queries = _.filter(options.targets, target => {
       return target.hide !== true;
     }).map(target => {
@@ -72,7 +82,7 @@ export class PostgresDatasource {
       .then(this.responseParser.processQueryResult);
   }
 
-  annotationQuery(options) {
+  annotationQuery(options: any) {
     if (!options.annotation.rawQuery) {
       return this.$q.reject({
         message: 'Query missing in annotation definition',
@@ -96,10 +106,10 @@ export class PostgresDatasource {
           queries: [query],
         },
       })
-      .then(data => this.responseParser.transformAnnotationResponse(options, data));
+      .then((data: any) => this.responseParser.transformAnnotationResponse(options, data));
   }
 
-  metricFindQuery(query, optionalOptions) {
+  metricFindQuery(query: string, optionalOptions: { variable?: any }) {
     let refId = 'tempvar';
     if (optionalOptions && optionalOptions.variable && optionalOptions.variable.name) {
       refId = optionalOptions.variable.name;
@@ -125,7 +135,7 @@ export class PostgresDatasource {
         method: 'POST',
         data: data,
       })
-      .then(data => this.responseParser.parseMetricFindQueryResult(refId, data));
+      .then((data: any) => this.responseParser.parseMetricFindQueryResult(refId, data));
   }
 
   getVersion() {
@@ -138,10 +148,10 @@ export class PostgresDatasource {
 
   testDatasource() {
     return this.metricFindQuery('SELECT 1', {})
-      .then(res => {
+      .then((res: any) => {
         return { status: 'success', message: 'Database Connection OK' };
       })
-      .catch(err => {
+      .catch((err: any) => {
         console.log(err);
         if (err.data && err.data.message) {
           return { status: 'error', message: err.data.message };

+ 4 - 2
public/app/plugins/datasource/postgres/meta_query.ts

@@ -1,5 +1,7 @@
+import QueryModel from './postgres_query';
+
 export class PostgresMetaQuery {
-  constructor(private target, private queryModel) {}
+  constructor(private target: { table: string; timeColumn: string }, private queryModel: QueryModel) {}
 
   getOperators(datatype: string) {
     switch (datatype) {
@@ -19,7 +21,7 @@ export class PostgresMetaQuery {
   }
 
   // quote identifier as literal to use in metadata queries
-  quoteIdentAsLiteral(value) {
+  quoteIdentAsLiteral(value: string) {
     return this.queryModel.quoteLiteral(this.queryModel.unquoteIdentifier(value));
   }
 

+ 10 - 8
public/app/plugins/datasource/postgres/postgres_query.ts

@@ -1,4 +1,6 @@
 import _ from 'lodash';
+import { TemplateSrv } from 'app/features/templating/template_srv';
+import { ScopedVars } from '@grafana/ui';
 
 export default class PostgresQuery {
   target: any;
@@ -6,7 +8,7 @@ export default class PostgresQuery {
   scopedVars: any;
 
   /** @ngInject */
-  constructor(target, templateSrv?, scopedVars?) {
+  constructor(target: any, templateSrv?: TemplateSrv, scopedVars?: ScopedVars) {
     this.target = target;
     this.templateSrv = templateSrv;
     this.scopedVars = scopedVars;
@@ -35,7 +37,7 @@ export default class PostgresQuery {
   }
 
   // remove identifier quoting from identifier to use in metadata queries
-  unquoteIdentifier(value) {
+  unquoteIdentifier(value: string) {
     if (value[0] === '"' && value[value.length - 1] === '"') {
       return value.substring(1, value.length - 1).replace(/""/g, '"');
     } else {
@@ -43,15 +45,15 @@ export default class PostgresQuery {
     }
   }
 
-  quoteIdentifier(value) {
+  quoteIdentifier(value: any) {
     return '"' + String(value).replace(/"/g, '""') + '"';
   }
 
-  quoteLiteral(value) {
+  quoteLiteral(value: any) {
     return "'" + String(value).replace(/'/g, "''") + "'";
   }
 
-  escapeLiteral(value) {
+  escapeLiteral(value: any) {
     return String(value).replace(/'/g, "''");
   }
 
@@ -63,7 +65,7 @@ export default class PostgresQuery {
     return this.target.metricColumn !== 'none';
   }
 
-  interpolateQueryStr(value, variable, defaultFormatFn) {
+  interpolateQueryStr(value: any, variable: { multi: any; includeAll: any }, defaultFormatFn: any) {
     // if no multi or include all do not regexEscape
     if (!variable.multi && !variable.includeAll) {
       return this.escapeLiteral(value);
@@ -77,7 +79,7 @@ export default class PostgresQuery {
     return escapedValues.join(',');
   }
 
-  render(interpolate?) {
+  render(interpolate?: any) {
     const target = this.target;
 
     // new query with no table set yet
@@ -146,7 +148,7 @@ export default class PostgresQuery {
     return query;
   }
 
-  buildValueColumn(column) {
+  buildValueColumn(column: any) {
     let query = '';
 
     const columnName: any = _.find(column, (g: any) => g.type === 'column');

+ 53 - 43
public/app/plugins/datasource/postgres/query_ctrl.ts

@@ -5,6 +5,8 @@ import { QueryCtrl } from 'app/plugins/sdk';
 import { SqlPart } from 'app/core/components/sql_part/sql_part';
 import PostgresQuery from './postgres_query';
 import sqlPart from './sql_part';
+import { auto, IQService } from 'angular';
+import { TemplateSrv } from 'app/features/templating/template_srv';
 
 export interface QueryMeta {
   sql: string;
@@ -40,7 +42,13 @@ export class PostgresQueryCtrl extends QueryCtrl {
   groupAdd: any;
 
   /** @ngInject */
-  constructor($scope, $injector, private templateSrv, private $q, private uiSegmentSrv) {
+  constructor(
+    $scope: any,
+    $injector: auto.IInjectorService,
+    private templateSrv: TemplateSrv,
+    private $q: IQService,
+    private uiSegmentSrv: any
+  ) {
     super($scope, $injector);
     this.target = this.target;
     this.queryModel = new PostgresQuery(this.target, templateSrv, this.panel.scopedVars);
@@ -57,7 +65,7 @@ export class PostgresQueryCtrl extends QueryCtrl {
         this.target.rawQuery = true;
       } else {
         this.target.rawSql = defaultQuery;
-        this.datasource.metricFindQuery(this.metaBuilder.findMetricTable()).then(result => {
+        this.datasource.metricFindQuery(this.metaBuilder.findMetricTable()).then((result: any) => {
           if (result.length > 0) {
             this.target.table = result[0].text;
             let segment = this.uiSegmentSrv.newSegment(this.target.table);
@@ -187,7 +195,7 @@ export class PostgresQueryCtrl extends QueryCtrl {
     }
   }
 
-  resetPlusButton(button) {
+  resetPlusButton(button: { html: any; value: any }) {
     const plusButton = this.uiSegmentSrv.newPlusButton();
     button.html = plusButton.html;
     button.value = plusButton.value;
@@ -211,7 +219,7 @@ export class PostgresQueryCtrl extends QueryCtrl {
     this.metricColumnSegment.value = segment.value;
     this.target.metricColumn = 'none';
 
-    const task1 = this.datasource.metricFindQuery(this.metaBuilder.buildColumnQuery('time')).then(result => {
+    const task1 = this.datasource.metricFindQuery(this.metaBuilder.buildColumnQuery('time')).then((result: any) => {
       // check if time column is still valid
       if (result.length > 0 && !_.find(result, (r: any) => r.text === this.target.timeColumn)) {
         const segment = this.uiSegmentSrv.newSegment(result[0].text);
@@ -220,7 +228,7 @@ export class PostgresQueryCtrl extends QueryCtrl {
       }
       return this.timeColumnChanged(false);
     });
-    const task2 = this.datasource.metricFindQuery(this.metaBuilder.buildColumnQuery('value')).then(result => {
+    const task2 = this.datasource.metricFindQuery(this.metaBuilder.buildColumnQuery('value')).then((result: any) => {
       if (result.length > 0) {
         this.target.select = [[{ type: 'column', params: [result[0].text] }]];
         this.updateProjection();
@@ -241,31 +249,33 @@ export class PostgresQueryCtrl extends QueryCtrl {
 
   timeColumnChanged(refresh?: boolean) {
     this.target.timeColumn = this.timeColumnSegment.value;
-    return this.datasource.metricFindQuery(this.metaBuilder.buildDatatypeQuery(this.target.timeColumn)).then(result => {
-      if (result.length === 1) {
-        if (this.target.timeColumnType !== result[0].text) {
-          this.target.timeColumnType = result[0].text;
-        }
-        let partModel;
-        if (this.queryModel.hasUnixEpochTimecolumn()) {
-          partModel = sqlPart.create({ type: 'macro', name: '$__unixEpochFilter', params: [] });
-        } else {
-          partModel = sqlPart.create({ type: 'macro', name: '$__timeFilter', params: [] });
-        }
+    return this.datasource
+      .metricFindQuery(this.metaBuilder.buildDatatypeQuery(this.target.timeColumn))
+      .then((result: any) => {
+        if (result.length === 1) {
+          if (this.target.timeColumnType !== result[0].text) {
+            this.target.timeColumnType = result[0].text;
+          }
+          let partModel;
+          if (this.queryModel.hasUnixEpochTimecolumn()) {
+            partModel = sqlPart.create({ type: 'macro', name: '$__unixEpochFilter', params: [] });
+          } else {
+            partModel = sqlPart.create({ type: 'macro', name: '$__timeFilter', params: [] });
+          }
 
-        if (this.whereParts.length >= 1 && this.whereParts[0].def.type === 'macro') {
-          // replace current macro
-          this.whereParts[0] = partModel;
-        } else {
-          this.whereParts.splice(0, 0, partModel);
+          if (this.whereParts.length >= 1 && this.whereParts[0].def.type === 'macro') {
+            // replace current macro
+            this.whereParts[0] = partModel;
+          } else {
+            this.whereParts.splice(0, 0, partModel);
+          }
         }
-      }
 
-      this.updatePersistedParts();
-      if (refresh !== false) {
-        this.panelCtrl.refresh();
-      }
-    });
+        this.updatePersistedParts();
+        if (refresh !== false) {
+          this.panelCtrl.refresh();
+        }
+      });
   }
 
   getMetricColumnSegments() {
@@ -280,7 +290,7 @@ export class PostgresQueryCtrl extends QueryCtrl {
     this.panelCtrl.refresh();
   }
 
-  onDataReceived(dataList) {
+  onDataReceived(dataList: any) {
     this.lastQueryMeta = null;
     this.lastQueryError = null;
 
@@ -290,7 +300,7 @@ export class PostgresQueryCtrl extends QueryCtrl {
     }
   }
 
-  onDataError(err) {
+  onDataError(err: any) {
     if (err.data && err.data.results) {
       const queryRes = err.data.results[this.target.refId];
       if (queryRes) {
@@ -300,8 +310,8 @@ export class PostgresQueryCtrl extends QueryCtrl {
     }
   }
 
-  transformToSegments(config) {
-    return results => {
+  transformToSegments(config: { addNone?: any; addTemplateVars?: any; templateQuoter?: any }) {
+    return (results: any) => {
       const segments = _.map(results, segment => {
         return this.uiSegmentSrv.newSegment({
           value: segment.text,
@@ -335,15 +345,15 @@ export class PostgresQueryCtrl extends QueryCtrl {
     };
   }
 
-  findAggregateIndex(selectParts) {
+  findAggregateIndex(selectParts: any) {
     return _.findIndex(selectParts, (p: any) => p.def.type === 'aggregate' || p.def.type === 'percentile');
   }
 
-  findWindowIndex(selectParts) {
+  findWindowIndex(selectParts: any) {
     return _.findIndex(selectParts, (p: any) => p.def.type === 'window' || p.def.type === 'moving_window');
   }
 
-  addSelectPart(selectParts, item, subItem) {
+  addSelectPart(selectParts: any[], item: { value: any }, subItem: { type: any; value: any }) {
     let partType = item.value;
     if (subItem && subItem.type) {
       partType = subItem.type;
@@ -415,7 +425,7 @@ export class PostgresQueryCtrl extends QueryCtrl {
     this.panelCtrl.refresh();
   }
 
-  removeSelectPart(selectParts, part) {
+  removeSelectPart(selectParts: any, part: { def: { type: string } }) {
     if (part.def.type === 'column') {
       // remove all parts of column unless its last column
       if (this.selectParts.length > 1) {
@@ -430,7 +440,7 @@ export class PostgresQueryCtrl extends QueryCtrl {
     this.updatePersistedParts();
   }
 
-  handleSelectPartEvent(selectParts, part, evt) {
+  handleSelectPartEvent(selectParts: any, part: { def: any }, evt: { name: any }) {
     switch (evt.name) {
       case 'get-param-options': {
         switch (part.def.type) {
@@ -462,7 +472,7 @@ export class PostgresQueryCtrl extends QueryCtrl {
     }
   }
 
-  handleGroupPartEvent(part, index, evt) {
+  handleGroupPartEvent(part: any, index: any, evt: { name: any }) {
     switch (evt.name) {
       case 'get-param-options': {
         return this.datasource
@@ -486,7 +496,7 @@ export class PostgresQueryCtrl extends QueryCtrl {
     }
   }
 
-  addGroup(partType, value) {
+  addGroup(partType: string, value: string) {
     let params = [value];
     if (partType === 'time') {
       params = ['$__interval', 'none'];
@@ -515,7 +525,7 @@ export class PostgresQueryCtrl extends QueryCtrl {
     this.updatePersistedParts();
   }
 
-  removeGroup(part, index) {
+  removeGroup(part: { def: { type: string } }, index: number) {
     if (part.def.type === 'time') {
       // remove aggregations
       this.selectParts = _.map(this.selectParts, (s: any) => {
@@ -532,7 +542,7 @@ export class PostgresQueryCtrl extends QueryCtrl {
     this.updatePersistedParts();
   }
 
-  handleWherePartEvent(whereParts, part, evt, index) {
+  handleWherePartEvent(whereParts: any, part: any, evt: any, index: any) {
     switch (evt.name) {
       case 'get-param-options': {
         switch (evt.param.name) {
@@ -598,7 +608,7 @@ export class PostgresQueryCtrl extends QueryCtrl {
     return this.$q.when(options);
   }
 
-  addWhereAction(part, index) {
+  addWhereAction(part: any, index: any) {
     switch (this.whereAdd.type) {
       case 'macro': {
         const partModel = sqlPart.create({ type: 'macro', name: this.whereAdd.value, params: [] });
@@ -623,7 +633,7 @@ export class PostgresQueryCtrl extends QueryCtrl {
   getGroupOptions() {
     return this.datasource
       .metricFindQuery(this.metaBuilder.buildColumnQuery('group'))
-      .then(tags => {
+      .then((tags: any) => {
         const options = [];
         if (!this.queryModel.hasTimeGroup()) {
           options.push(this.uiSegmentSrv.newSegment({ type: 'time', value: 'time($__interval,none)' }));
@@ -647,7 +657,7 @@ export class PostgresQueryCtrl extends QueryCtrl {
     this.panelCtrl.refresh();
   }
 
-  handleQueryError(err) {
+  handleQueryError(err: any): any[] {
     this.error = err.message || 'Failed to issue metric query';
     return [];
   }

+ 10 - 9
public/app/plugins/datasource/postgres/response_parser.ts

@@ -1,10 +1,11 @@
 import _ from 'lodash';
+import { IQService } from 'angular';
 
 export default class ResponseParser {
-  constructor(private $q) {}
+  constructor(private $q: IQService) {}
 
-  processQueryResult(res) {
-    const data = [];
+  processQueryResult(res: any) {
+    const data: any[] = [];
 
     if (!res.data.results) {
       return { data: data };
@@ -37,7 +38,7 @@ export default class ResponseParser {
     return { data: data };
   }
 
-  parseMetricFindQueryResult(refId, results) {
+  parseMetricFindQueryResult(refId: string, results: any) {
     if (!results || results.data.length === 0 || results.data.results[refId].meta.rowCount === 0) {
       return [];
     }
@@ -54,7 +55,7 @@ export default class ResponseParser {
     return this.transformToSimpleList(rows);
   }
 
-  transformToKeyValueList(rows, textColIndex, valueColIndex) {
+  transformToKeyValueList(rows: any, textColIndex: number, valueColIndex: number) {
     const res = [];
 
     for (let i = 0; i < rows.length; i++) {
@@ -69,7 +70,7 @@ export default class ResponseParser {
     return res;
   }
 
-  transformToSimpleList(rows) {
+  transformToSimpleList(rows: any[][]) {
     const res = [];
 
     for (let i = 0; i < rows.length; i++) {
@@ -86,7 +87,7 @@ export default class ResponseParser {
     });
   }
 
-  findColIndex(columns, colName) {
+  findColIndex(columns: any[], colName: string) {
     for (let i = 0; i < columns.length; i++) {
       if (columns[i].text === colName) {
         return i;
@@ -96,7 +97,7 @@ export default class ResponseParser {
     return -1;
   }
 
-  containsKey(res, key) {
+  containsKey(res: any, key: any) {
     for (let i = 0; i < res.length; i++) {
       if (res[i].text === key) {
         return true;
@@ -105,7 +106,7 @@ export default class ResponseParser {
     return false;
   }
 
-  transformAnnotationResponse(options, data) {
+  transformAnnotationResponse(options: any, data: any) {
     const table = data.data.results[options.annotation.name].tables[0];
 
     let timeColumnIndex = -1;

+ 18 - 10
public/app/plugins/datasource/postgres/specs/datasource.test.ts

@@ -1,12 +1,14 @@
 import { PostgresDatasource } from '../datasource';
 import { CustomVariable } from 'app/features/templating/custom_variable';
 import { toUtc, dateTime } from '@grafana/ui/src/utils/moment_wrapper';
+import { BackendSrv } from 'app/core/services/backend_srv';
+import { IQService } from 'angular';
 
 describe('PostgreSQLDatasource', () => {
   const instanceSettings = { name: 'postgresql' };
 
   const backendSrv = {};
-  const templateSrv = {
+  const templateSrv: any = {
     replace: jest.fn(text => text),
   };
   const raw = {
@@ -25,11 +27,17 @@ describe('PostgreSQLDatasource', () => {
   } as any;
 
   beforeEach(() => {
-    ctx.ds = new PostgresDatasource(instanceSettings, backendSrv, {}, templateSrv, ctx.timeSrvMock);
+    ctx.ds = new PostgresDatasource(
+      instanceSettings,
+      backendSrv as BackendSrv,
+      {} as IQService,
+      templateSrv,
+      ctx.timeSrvMock
+    );
   });
 
   describe('When performing annotationQuery', () => {
-    let results;
+    let results: any;
 
     const annotationName = 'MyAnno';
 
@@ -66,7 +74,7 @@ describe('PostgreSQLDatasource', () => {
       ctx.backendSrv.datasourceRequest = jest.fn(options => {
         return Promise.resolve({ data: response, status: 200 });
       });
-      ctx.ds.annotationQuery(options).then(data => {
+      ctx.ds.annotationQuery(options).then((data: any) => {
         results = data;
       });
     });
@@ -86,7 +94,7 @@ describe('PostgreSQLDatasource', () => {
   });
 
   describe('When performing metricFindQuery', () => {
-    let results;
+    let results: any;
     const query = 'select * from atable';
     const response = {
       results: {
@@ -109,7 +117,7 @@ describe('PostgreSQLDatasource', () => {
       ctx.backendSrv.datasourceRequest = jest.fn(options => {
         return Promise.resolve({ data: response, status: 200 });
       });
-      ctx.ds.metricFindQuery(query).then(data => {
+      ctx.ds.metricFindQuery(query).then((data: any) => {
         results = data;
       });
     });
@@ -122,7 +130,7 @@ describe('PostgreSQLDatasource', () => {
   });
 
   describe('When performing metricFindQuery with key, value columns', () => {
-    let results;
+    let results: any;
     const query = 'select * from atable';
     const response = {
       results: {
@@ -145,7 +153,7 @@ describe('PostgreSQLDatasource', () => {
       ctx.backendSrv.datasourceRequest = jest.fn(options => {
         return Promise.resolve({ data: response, status: 200 });
       });
-      ctx.ds.metricFindQuery(query).then(data => {
+      ctx.ds.metricFindQuery(query).then((data: any) => {
         results = data;
       });
     });
@@ -160,7 +168,7 @@ describe('PostgreSQLDatasource', () => {
   });
 
   describe('When performing metricFindQuery with key, value columns and with duplicate keys', () => {
-    let results;
+    let results: any;
     const query = 'select * from atable';
     const response = {
       results: {
@@ -183,7 +191,7 @@ describe('PostgreSQLDatasource', () => {
       ctx.backendSrv.datasourceRequest = jest.fn(options => {
         return Promise.resolve({ data: response, status: 200 });
       });
-      ctx.ds.metricFindQuery(query).then(data => {
+      ctx.ds.metricFindQuery(query).then((data: any) => {
         results = data;
       });
       //ctx.$rootScope.$apply();

+ 4 - 2
public/app/plugins/datasource/postgres/specs/postgres_query.test.ts

@@ -1,7 +1,9 @@
 import PostgresQuery from '../postgres_query';
+import { TemplateSrv } from 'app/features/templating/template_srv';
 
 describe('PostgresQuery', () => {
-  const templateSrv = {
+  // @ts-ignore
+  const templateSrv: TemplateSrv = {
     replace: jest.fn(text => text),
   };
 
@@ -142,7 +144,7 @@ describe('PostgresQuery', () => {
   });
 
   describe('When generating complete statement', () => {
-    const target = {
+    const target: any = {
       timeColumn: 't',
       table: 'table',
       select: [[{ type: 'column', params: ['value'] }]],

+ 2 - 2
public/app/plugins/datasource/postgres/sql_part.ts

@@ -1,8 +1,8 @@
 import { SqlPartDef, SqlPart } from 'app/core/components/sql_part/sql_part';
 
-const index = [];
+const index: any[] = [];
 
-function createPart(part): any {
+function createPart(part: any): any {
   const def = index[part.type];
   if (!def) {
     return null;

+ 1 - 1
public/app/plugins/datasource/prometheus/components/PromLink.tsx

@@ -27,7 +27,7 @@ export default class PromLink extends Component<Props, State> {
 
   async getExternalLink(): Promise<string> {
     const { query, panelData } = this.props;
-    const target = panelData.request.targets.length > 0 ? panelData.request.targets[0] : { datasource: null };
+    const target = panelData.request.targets.length > 0 ? panelData.request.targets[0] : ({ datasource: null } as any);
     const datasourceName = target.datasource;
     const datasource: PrometheusDatasource = datasourceName
       ? (((await getDatasourceSrv().get(datasourceName)) as any) as PrometheusDatasource)

+ 1 - 1
public/app/plugins/datasource/prometheus/components/PromQueryEditor.tsx

@@ -54,7 +54,7 @@ export class PromQueryEditor extends PureComponent<Props, State> {
     };
   }
 
-  onFieldChange = (query: PromQuery, override?) => {
+  onFieldChange = (query: PromQuery, override?: any) => {
     this.query.expr = query.expr;
   };
 

+ 17 - 15
public/app/plugins/datasource/stackdriver/StackdriverMetricFindQuery.ts

@@ -10,7 +10,7 @@ import {
 } from './functions';
 
 export default class StackdriverMetricFindQuery {
-  constructor(private datasource) {}
+  constructor(private datasource: any) {}
 
   async execute(query: any) {
     try {
@@ -50,19 +50,21 @@ export default class StackdriverMetricFindQuery {
     }));
   }
 
-  async handleMetricTypesQuery({ selectedService }) {
+  async handleMetricTypesQuery({ selectedService }: any) {
     if (!selectedService) {
       return [];
     }
     const metricDescriptors = await this.datasource.getMetricTypes(this.datasource.projectName);
-    return getMetricTypesByService(metricDescriptors, this.datasource.templateSrv.replace(selectedService)).map(s => ({
-      text: s.displayName,
-      value: s.type,
-      expandable: true,
-    }));
+    return getMetricTypesByService(metricDescriptors, this.datasource.templateSrv.replace(selectedService)).map(
+      (s: any) => ({
+        text: s.displayName,
+        value: s.type,
+        expandable: true,
+      })
+    );
   }
 
-  async handleLabelKeysQuery({ selectedMetricType }) {
+  async handleLabelKeysQuery({ selectedMetricType }: any) {
     if (!selectedMetricType) {
       return [];
     }
@@ -70,7 +72,7 @@ export default class StackdriverMetricFindQuery {
     return labelKeys.map(this.toFindQueryResult);
   }
 
-  async handleLabelValuesQuery({ selectedMetricType, labelKey }) {
+  async handleLabelValuesQuery({ selectedMetricType, labelKey }: any) {
     if (!selectedMetricType) {
       return [];
     }
@@ -88,7 +90,7 @@ export default class StackdriverMetricFindQuery {
     return values.map(this.toFindQueryResult);
   }
 
-  async handleResourceTypeQuery({ selectedMetricType }) {
+  async handleResourceTypeQuery({ selectedMetricType }: any) {
     if (!selectedMetricType) {
       return [];
     }
@@ -97,24 +99,24 @@ export default class StackdriverMetricFindQuery {
     return response.meta.resourceTypes ? response.meta.resourceTypes.map(this.toFindQueryResult) : [];
   }
 
-  async handleAlignersQuery({ selectedMetricType }) {
+  async handleAlignersQuery({ selectedMetricType }: any) {
     if (!selectedMetricType) {
       return [];
     }
     const metricDescriptors = await this.datasource.getMetricTypes(this.datasource.projectName);
     const { valueType, metricKind } = metricDescriptors.find(
-      m => m.type === this.datasource.templateSrv.replace(selectedMetricType)
+      (m: any) => m.type === this.datasource.templateSrv.replace(selectedMetricType)
     );
     return getAlignmentOptionsByMetric(valueType, metricKind).map(this.toFindQueryResult);
   }
 
-  async handleAggregationQuery({ selectedMetricType }) {
+  async handleAggregationQuery({ selectedMetricType }: any) {
     if (!selectedMetricType) {
       return [];
     }
     const metricDescriptors = await this.datasource.getMetricTypes(this.datasource.projectName);
     const { valueType, metricKind } = metricDescriptors.find(
-      m => m.type === this.datasource.templateSrv.replace(selectedMetricType)
+      (m: any) => m.type === this.datasource.templateSrv.replace(selectedMetricType)
     );
     return getAggregationOptionsByMetric(valueType, metricKind).map(this.toFindQueryResult);
   }
@@ -123,7 +125,7 @@ export default class StackdriverMetricFindQuery {
     return alignmentPeriods.map(this.toFindQueryResult);
   }
 
-  toFindQueryResult(x) {
+  toFindQueryResult(x: any) {
     return isString(x) ? { text: x, expandable: true } : { ...x, expandable: true };
   }
 }

+ 2 - 2
public/app/plugins/datasource/stackdriver/annotations_query_ctrl.ts

@@ -6,13 +6,13 @@ export class StackdriverAnnotationsQueryCtrl {
   templateSrv: TemplateSrv;
 
   /** @ngInject */
-  constructor(templateSrv) {
+  constructor(templateSrv: TemplateSrv) {
     this.templateSrv = templateSrv;
     this.annotation.target = this.annotation.target || {};
     this.onQueryChange = this.onQueryChange.bind(this);
   }
 
-  onQueryChange(target) {
+  onQueryChange(target: any) {
     Object.assign(this.annotation.target, target);
   }
 }

+ 4 - 3
public/app/plugins/datasource/stackdriver/components/Aggregations.test.tsx

@@ -7,6 +7,7 @@ import { TemplateSrvStub } from 'test/specs/helpers';
 
 const props: Props = {
   onChange: () => {},
+  // @ts-ignore
   templateSrv: new TemplateSrvStub(),
   metricDescriptor: {
     valueType: '',
@@ -18,7 +19,7 @@ const props: Props = {
 };
 
 describe('Aggregations', () => {
-  let wrapper;
+  let wrapper: any;
   it('renders correctly', () => {
     const tree = renderer.create(<Aggregations {...props} />).toJSON();
     expect(tree).toMatchSnapshot();
@@ -33,7 +34,7 @@ describe('Aggregations', () => {
       it('', () => {
         const options = wrapper.state().aggOptions[0].options;
         expect(options.length).toEqual(11);
-        expect(options.map(o => o.value)).toEqual(
+        expect(options.map((o: any) => o.value)).toEqual(
           expect.not.arrayContaining(['REDUCE_COUNT_TRUE', 'REDUCE_COUNT_FALSE'])
         );
       });
@@ -51,7 +52,7 @@ describe('Aggregations', () => {
         const options = wrapper.state().aggOptions[0].options;
 
         expect(options.length).toEqual(10);
-        expect(options.map(o => o.value)).toEqual(expect.arrayContaining(['REDUCE_NONE']));
+        expect(options.map((o: any) => o.value)).toEqual(expect.arrayContaining(['REDUCE_NONE']));
       });
     });
   });

+ 2 - 2
public/app/plugins/datasource/stackdriver/components/Aggregations.tsx

@@ -7,7 +7,7 @@ import { TemplateSrv } from 'app/features/templating/template_srv';
 import { ValueTypes, MetricKind } from '../constants';
 
 export interface Props {
-  onChange: (metricDescriptor) => void;
+  onChange: (metricDescriptor: any) => void;
   templateSrv: TemplateSrv;
   metricDescriptor: {
     valueType: string;
@@ -38,7 +38,7 @@ export class Aggregations extends React.Component<Props, State> {
   }
 
   setAggOptions({ metricDescriptor }: Props) {
-    let aggOptions = [];
+    let aggOptions: any[] = [];
     if (metricDescriptor) {
       aggOptions = [
         {

+ 4 - 4
public/app/plugins/datasource/stackdriver/components/AliasBy.tsx

@@ -3,7 +3,7 @@ import { debounce } from 'lodash';
 import { Input } from '@grafana/ui';
 
 export interface Props {
-  onChange: (alignmentPeriod) => void;
+  onChange: (alignmentPeriod: any) => void;
   value: string;
 }
 
@@ -12,9 +12,9 @@ export interface State {
 }
 
 export class AliasBy extends Component<Props, State> {
-  propagateOnChange: (value) => void;
+  propagateOnChange: (value: any) => void;
 
-  constructor(props) {
+  constructor(props: Props) {
     super(props);
     this.propagateOnChange = debounce(this.props.onChange, 500);
     this.state = { value: '' };
@@ -30,7 +30,7 @@ export class AliasBy extends Component<Props, State> {
     }
   }
 
-  onChange = e => {
+  onChange = (e: any) => {
     this.setState({ value: e.target.value });
     this.propagateOnChange(e.target.value);
   };

+ 1 - 1
public/app/plugins/datasource/stackdriver/components/AlignmentPeriods.tsx

@@ -7,7 +7,7 @@ import { alignmentPeriods, alignOptions } from '../constants';
 import { TemplateSrv } from 'app/features/templating/template_srv';
 
 export interface Props {
-  onChange: (alignmentPeriod) => void;
+  onChange: (alignmentPeriod: any) => void;
   templateSrv: TemplateSrv;
   alignmentPeriod: string;
   perSeriesAligner: string;

+ 1 - 1
public/app/plugins/datasource/stackdriver/components/Alignments.tsx

@@ -6,7 +6,7 @@ import { TemplateSrv } from 'app/features/templating/template_srv';
 import { SelectOptionItem } from '@grafana/ui';
 
 export interface Props {
-  onChange: (perSeriesAligner) => void;
+  onChange: (perSeriesAligner: any) => void;
   templateSrv: TemplateSrv;
   alignOptions: Array<SelectOptionItem<string>>;
   perSeriesAligner: string;

+ 3 - 3
public/app/plugins/datasource/stackdriver/components/AnnotationQueryEditor.tsx

@@ -6,7 +6,7 @@ import { TemplateSrv } from 'app/features/templating/template_srv';
 import StackdriverDatasource from '../datasource';
 import { Metrics } from './Metrics';
 import { Filter } from './Filter';
-import { AnnotationTarget } from '../types';
+import { AnnotationTarget, MetricDescriptor } from '../types';
 import { AnnotationsHelp } from './AnnotationsHelp';
 
 export interface Props {
@@ -40,7 +40,7 @@ export class AnnotationQueryEditor extends React.Component<Props, State> {
     });
   }
 
-  onMetricTypeChange = ({ valueType, metricKind, type, unit }) => {
+  onMetricTypeChange = ({ valueType, metricKind, type, unit }: MetricDescriptor) => {
     const { onQueryChange } = this.props;
     this.setState(
       {
@@ -55,7 +55,7 @@ export class AnnotationQueryEditor extends React.Component<Props, State> {
     );
   };
 
-  onChange(prop, value) {
+  onChange(prop: string, value: string | string[]) {
     this.setState({ [prop]: value }, () => {
       this.props.onQueryChange(this.state);
     });

+ 5 - 5
public/app/plugins/datasource/stackdriver/components/Filter.tsx

@@ -25,7 +25,7 @@ interface State {
   loading: Promise<any>;
 }
 
-const labelData = {
+const labelData: any = {
   metricLabels: {},
   resourceLabels: {},
   resourceTypes: [],
@@ -43,15 +43,15 @@ export class Filter extends React.Component<Props, State> {
     const { groupBys, filters, hideGroupBys } = this.props;
     const loader = getAngularLoader();
 
-    const filtersChanged = filters => {
+    const filtersChanged = (filters: string[]) => {
       this.props.filtersChanged(filters);
     };
 
-    const groupBysChanged = groupBys => {
+    const groupBysChanged = (groupBys: string[]) => {
       this.props.groupBysChanged(groupBys);
     };
 
-    const scopeProps = {
+    const scopeProps: any = {
       loading: null,
       labelData,
       groupBys,
@@ -91,7 +91,7 @@ export class Filter extends React.Component<Props, State> {
     }
   }
 
-  async loadLabels(scope) {
+  async loadLabels(scope: any) {
     return new Promise(async resolve => {
       try {
         if (!this.props.metricType) {

+ 3 - 1
public/app/plugins/datasource/stackdriver/components/Help.tsx

@@ -1,11 +1,13 @@
 import React from 'react';
 import { Project } from './Project';
 import StackdriverDatasource from '../datasource';
+import { MetricDescriptor } from '../types';
 
 export interface Props {
   datasource: StackdriverDatasource;
   rawQuery: string;
   lastQueryError: string;
+  metricDescriptor?: MetricDescriptor;
 }
 
 interface State {
@@ -27,7 +29,7 @@ export class Help extends React.Component<Props, State> {
     this.setState({ displaRawQuery: !this.state.displaRawQuery });
   };
 
-  shouldComponentUpdate(nextProps) {
+  shouldComponentUpdate(nextProps: Props) {
     return nextProps.metricDescriptor !== null;
   }
 

+ 4 - 4
public/app/plugins/datasource/stackdriver/components/Metrics.tsx

@@ -37,7 +37,7 @@ export class Metrics extends React.Component<Props, State> {
     defaultProject: '',
   };
 
-  constructor(props) {
+  constructor(props: Props) {
     super(props);
   }
 
@@ -83,7 +83,7 @@ export class Metrics extends React.Component<Props, State> {
     this.setState({ metricDescriptors, services, metrics, service: service, metricDescriptor });
   }
 
-  getSelectedMetricDescriptor(metricType) {
+  getSelectedMetricDescriptor(metricType: string) {
     return this.state.metricDescriptors.find(md => md.type === this.props.templateSrv.replace(metricType));
   }
 
@@ -103,7 +103,7 @@ export class Metrics extends React.Component<Props, State> {
     return metricsByService;
   }
 
-  onServiceChange = service => {
+  onServiceChange = (service: any) => {
     const { metricDescriptors } = this.state;
     const { templateSrv, metricType } = this.props;
 
@@ -123,7 +123,7 @@ export class Metrics extends React.Component<Props, State> {
     }
   };
 
-  onMetricTypeChange = value => {
+  onMetricTypeChange = (value: any) => {
     const metricDescriptor = this.getSelectedMetricDescriptor(value);
     this.setState({ metricDescriptor });
     this.props.onChange({ ...metricDescriptor, type: value });

+ 1 - 1
scripts/ci-frontend-metrics.sh

@@ -3,7 +3,7 @@
 echo -e "Collecting code stats (typescript errors & more)"
 
 
-ERROR_COUNT_LIMIT=3440
+ERROR_COUNT_LIMIT=3000
 DIRECTIVES_LIMIT=172
 CONTROLLERS_LIMIT=139