import { isoOrTimeToDate , TimePrecision } from "./grammar" ; /**
 * A ResultError is thrown when a query generates errorful results from Influx.
 */ export class ResultError extends Error { constructor ( message ) { super ( ) ; this . message = `Error from InfluxDB: ${ message }` ; } } /**
 * InfluxResults describes the result structure received from InfluxDB.
 *
 * NOTE: if you're poking around in Influx, use curl, not the `json` formatter
 * provided by the CLI. As of 1.0 this formatter changes the result structure
 * and it will confuse you, as it did me ;)
 */ export interface IResponse { results : IResultEntry [ ] ; } export interface IResultEntry { series ? : IResponseSeries [ ] ; error ? : string ; } export type Tags = { [ name ] : string ; } ; export type Row = any ; export interface IResponseSeries { name ? : string ; columns : string [ ] ; tags ? : Tags ; values ? : Row [ ] ; } function groupMethod ( this , matcher ) { const srcKeys = this . groupsTagsKeys ; const dstKeys = Object . keys ( matcher ) ; if ( srcKeys . length === 0 || srcKeys . length !== dstKeys . length ) { return [ ] ; } L : for ( let row of this . groupRows ) { for ( let src of srcKeys ) { if ( row . tags [ src ] !== matcher [ src ] ) { continue L ; } } return row . rows ; } return [ ] ; } function groupsMethod ( this ) { return this . groupRows ; } /**
 * Inner parsing function which unpacks the series into a table and attaches
 * methods to the array. This is quite optimized and a bit of a mess to read,
 * but it's all fairly easy procedural logic.
 *
 * We do this instead of subclassing Array since subclassing has some
 * undesirable side-effects. For example, calling .slice() on the array
 * makes it impossible to preserve groups as would be necessary if it's
 * subclassed.
 */ function parseInner ( series = [ ] , precision ? ) { const results = [ ] ; results . groupsTagsKeys = series . length && series [ 0 ] . tags ? Object . keys ( series [ 0 ] . tags ) : [ ] ; const tags = results . groupsTagsKeys ; let nextGroup = [ ] ; results . groupRows = new Array ( series . length ) ; for ( let i = 0 ; i < series . length ; i += 1 , results . length ) { const { columns = [ ] , values = [ ] } = series [ i ] ; for ( let value of values ) { const obj = { } ; for ( let j = 0 ; j < columns . length ; j += 1 ) { if ( columns [ j ] === "time" ) { obj . time = isoOrTimeToDate ( value [ j ] as number | string , precision ) ; } else { obj [ columns [ j ] ] = value [ j ] ; } } for ( let tag of tags ) { obj [ tag ] = series [ i ] . tags [ tag ] ; } results . push ( obj ) ; nextGroup . push ( obj ) ; } results . groupRows [ i ] = { name : series [ i ] . name , rows : nextGroup , tags : series [ i ] . tags || { } , } ; nextGroup = [ ] ; } results . group = groupMethod ; results . groups = groupsMethod ; return results ; } /**
 * IResultsParser is a user-friendly results tables from raw Influx responses.
 */ export interface IResults < T > extends Array < T > { param matcher return example group : ( matcher : Tags ) => T [ ] ; returns example groups : ( ) => Array < { name : string ; tags : Tags ; rows : T [ ] ; } > ; } private throws export function assertNoErrors ( res ) { for ( let result of res . results ) { const { error } = result ; if ( error ) { throw new ResultError ( error ) ; } } return res ; } private export function parse < T > ( res , precision ? ) { assertNoErrors ( res ) ; if ( res . results . length === 1 ) { return parseInner ( res . results [ 0 ] . series , precision ) ; } return res . results . map ( ( result ) => parseInner ( result . series , precision ) ) ; } throws private export function parseSingle < T > ( res , precision ? ) { assertNoErrors ( res ) ; if ( res . results . length !== 1 ) { throw new Error ( "node-influx expected the results length to equal 1, but " + `it was ${ 0 }. Please report this here: https://git.io/influx-err` ) ; } return parseInner ( res . results [ 0 ] . series , precision ) ; }