@@ -19,28 +19,31 @@ import {
1919 MyVariableQuery ,
2020 MultiValueVariable ,
2121 TextValuePair ,
22+ RequestFactory ,
2223} from './types' ;
2324import { dateTime , MutableDataFrame , FieldType , DataFrame } from '@grafana/data' ;
2425import { getTemplateSrv } from '@grafana/runtime' ;
25- import _ from 'lodash' ;
2626import { isEqual } from 'lodash' ;
2727import { flatten , isRFC3339_ISO6801 } from './util' ;
28+ import { GraphQLObjectType , isObjectType } from 'graphql' ;
29+ import { Schema } from './schema' ;
2830
2931const supportedVariableTypes = [ 'constant' , 'custom' , 'query' , 'textbox' ] ;
3032
31- export class DataSource extends DataSourceApi < MyQuery , MyDataSourceOptions > {
32- basicAuth : string | undefined ;
33- withCredentials : boolean | undefined ;
34- url : string | undefined ;
35-
36- constructor ( instanceSettings : DataSourceInstanceSettings < MyDataSourceOptions > , private backendSrv : any ) {
37- super ( instanceSettings ) ;
38- this . basicAuth = instanceSettings . basicAuth ;
39- this . withCredentials = instanceSettings . withCredentials ;
40- this . url = instanceSettings . url ;
33+ class _RequestFactory implements RequestFactory {
34+ constructor (
35+ private basicAuth : string | undefined ,
36+ private withCredentials : boolean | undefined ,
37+ private url : string ,
38+ private backendSrv : any
39+ ) {
40+ this . basicAuth = basicAuth ;
41+ this . withCredentials = withCredentials ;
42+ this . url = url ;
43+ this . backendSrv = backendSrv ;
4144 }
4245
43- private request ( data : string ) {
46+ request ( data : string ) : Promise < any > {
4447 const options : any = {
4548 url : this . url ,
4649 method : 'POST' ,
@@ -60,9 +63,26 @@ export class DataSource extends DataSourceApi<MyQuery, MyDataSourceOptions> {
6063
6164 return this . backendSrv . datasourceRequest ( options ) ;
6265 }
66+ }
67+
68+ export class DataSource extends DataSourceApi < MyQuery , MyDataSourceOptions > {
69+ private schema : Schema ;
70+ private requestFactory : RequestFactory ;
71+
72+ constructor ( instanceSettings : DataSourceInstanceSettings < MyDataSourceOptions > , backendSrv : any ) {
73+ super ( instanceSettings ) ;
74+ this . requestFactory = new _RequestFactory (
75+ instanceSettings . basicAuth ,
76+ instanceSettings . withCredentials ,
77+ instanceSettings . url as string ,
78+ backendSrv
79+ ) ;
80+ this . schema = new Schema ( this . requestFactory ) ;
81+ }
6382
6483 private postQuery ( query : Partial < MyQuery > , payload : string ) {
65- return this . request ( payload )
84+ return this . requestFactory
85+ . request ( payload )
6686 . then ( ( results : any ) => {
6787 return { query, results } ;
6888 } )
@@ -138,12 +158,15 @@ export class DataSource extends DataSourceApi<MyQuery, MyDataSourceOptions> {
138158 }
139159
140160 async query ( options : DataQueryRequest < MyQuery > ) : Promise < DataQueryResponse > {
141- return Promise . all (
142- options . targets . map ( ( target ) => {
143- return this . createQuery ( defaults ( target , defaultQuery ) , options . range , options . scopedVars ) ;
144- } )
145- ) . then ( ( results : any ) => {
161+ let promises : Array < Promise < any > > = options . targets . map ( ( target ) => {
162+ return this . createQuery ( defaults ( target , defaultQuery ) , options . range , options . scopedVars ) ;
163+ } ) ;
164+ promises . push ( this . schema . getQuery ( ) ) ;
165+
166+ return Promise . all ( promises ) . then ( ( results : any [ ] ) => {
146167 const dataFrameArray : DataFrame [ ] = [ ] ;
168+ let queryType : GraphQLObjectType = results . pop ( ) ;
169+
147170 for ( let res of results ) {
148171 const dataPathArray : string [ ] = DataSource . getDataPathArray ( res . query . dataPath ) ;
149172 const { timePath, timeFormat, groupBy, aliasBy } = res . query ;
@@ -157,6 +180,10 @@ export class DataSource extends DataSourceApi<MyQuery, MyDataSourceOptions> {
157180 }
158181 for ( const dataPath of dataPathArray ) {
159182 const docs : any [ ] = DataSource . getDocs ( res . results . data , dataPath ) ;
183+ let dataType = Schema . getTypeOfDescendant ( queryType , dataPath ) ;
184+ if ( ! isObjectType ( dataType ) ) {
185+ throw `Data path ${ dataPath } has type ${ dataType . name } , expected object type` ;
186+ }
160187
161188 const dataFrameMap = new Map < string , MutableDataFrame > ( ) ;
162189 for ( const doc of docs ) {
@@ -180,9 +207,13 @@ export class DataSource extends DataSourceApi<MyQuery, MyDataSourceOptions> {
180207 let t : FieldType = FieldType . string ;
181208 if ( fieldName === timePath || isRFC3339_ISO6801 ( String ( doc [ fieldName ] ) ) ) {
182209 t = FieldType . time ;
183- } else if ( _ . isNumber ( doc [ fieldName ] ) ) {
184- t = FieldType . number ;
210+ } else {
211+ let fieldType = Schema . getTypeOfDescendant ( dataType , fieldName ) ;
212+ if ( Schema . isNumericType ( fieldType ) ) {
213+ t = FieldType . number ;
214+ }
185215 }
216+
186217 let title ;
187218 if ( identifiers . length !== 0 ) {
188219 // if we have any identifiers
0 commit comments