import { convertTimeToNanos } from './util/currentTime' ; import { escape } from './util/escape' ; /**
 * Settings that control the way of how a  Point is serialized
 * to a protocol line.
  export interface PointSettings { /** default tags to add to every point */ defaultTags ? : { [ key ] : string ; } ; /** convertTime serializes Point's timestamp to a line protocol value */ convertTime ? : ( value : string | number | Date | undefined ) => string | undefined ; } /**
 * Point defines values of a single measurement.
 */ export class Point { private name : string ; private tags : { [ key ] : string ; } = { } ; /** escaped field values */ public fields : { [ key ] : string ; } = { } ; private time : string | number | Date | undefined ; param measurementName constructor ( measurementName ? ) { if ( measurementName ) this . name = measurementName ; } param name returns public measurement ( name ) { this . name = name ; return this ; } param name param value returns public tag ( name , value ) { this . tags [ name ] = value ; return this ; } param field param value returns public booleanField ( name , value ) { this . fields [ name ] = value ? 'T' : 'F' ; return this ; } param name param value returns throws public intField ( name , value ) { let val ; if ( typeof value === 'number' ) { val = value ; } else { val = parseInt ( String ( value ) ) ; } if ( isNaN ( val ) || val <= - 9223372036854776e3 || val >= 9223372036854776e3 ) { throw new Error ( `invalid integer value for field '${ name }': '${ value }'!` ) ; } this . fields [ name ] = `${ Math . floor ( val ) }i` ; return this ; } param name param value returns throws public uintField ( name , value ) { if ( typeof value === 'number' ) { if ( isNaN ( value ) || value < 0 || value > Number . MAX_SAFE_INTEGER ) { throw new Error ( `uint value for field '${ name }' out of range: ${ value }` ) ; } this . fields [ name ] = `${ Math . floor ( value as number ) }u` ; } else { const strVal = String ( value ) ; for ( let i = 0 ; i < strVal . length ; i ++ ) { const code = strVal . charCodeAt ( i ) ; if ( code < 48 || code > 57 ) { throw new Error ( `uint value has an unsupported character at pos ${ i }: ${ value }` ) ; } } if ( strVal . length > 20 || ( strVal . length === 20 && strVal . localeCompare ( '18446744073709551615' ) > 0 ) ) { throw new Error ( `uint value for field '${ name }' out of range: ${ strVal }` ) ; } this . fields [ name ] = `${ strVal }u` ; } return this ; } param name param value returns throws public floatField ( name , value ) { let val ; if ( typeof value === 'number' ) { val = value ; } else { val = parseFloat ( value ) ; } if ( ! isFinite ( val ) ) { throw new Error ( `invalid float value for field '${ name }': ${ value }` ) ; } this . fields [ name ] = String ( val ) ; return this ; } param name param value returns public stringField ( name , value ) { if ( value !== null && value !== undefined ) { if ( typeof value !== 'string' ) value = String ( value ) ; this . fields [ name ] = escape . quoted ( value ) ; } return this ; } /**
     * Sets point timestamp. Timestamp can be specified as a Date (preferred), number, string
     * or an undefined value. An undefined value instructs to assign a local timestamp using
     * the client's clock. An empty string can be used to let the server assign
     * the timestamp. A number value represents time as a count of time units since epoch, the
     * exact time unit then depends on the  InfluxDB . getWriteApi of the API
     * that writes the point.
     *
     * Beware that the current time in nanoseconds can't precisely fit into a JS number,
     * which can hold at most 2^53 integer number. Nanosecond precision numbers are thus supplied as
     * a (base-10) string. An application can also use ES2020 BigInt to represent nanoseconds,
     * BigInt's `toString()` returns the required high-precision string.
     *
     * Note that InfluxDB requires the timestamp to fit into int64 data type.
     *
     *  param value returns public timestamp ( value ) { this . time = value ; return this ; } param settings returns public toLineProtocol ( settings ? ) { if ( ! this . name ) return undefined ; let fieldsLine = '' ; Object . keys ( this . fields ) . sort ( ) . forEach ( x => { if ( x ) { const val = this . fields [ x ] ; if ( fieldsLine . length > 0 ) fieldsLine += ',' ; fieldsLine += `${ escape . tag ( x ) }=${ val }` ; } } ) ; if ( fieldsLine . length === 0 ) return undefined ; let tagsLine = '' ; const tags = settings && settings . defaultTags ? { ... settings . defaultTags , ... this . tags } : this . tags ; Object . keys ( tags ) . sort ( ) . forEach ( x => { if ( x ) { const val = tags [ x ] ; if ( val ) { tagsLine += ',' ; tagsLine += `${ escape . tag ( x ) }=${ escape . tag ( val ) }` ; } } } ) ; let time = this . time ; if ( settings && settings . convertTime ) { time = settings . convertTime ( time ) ; } else { time = convertTimeToNanos ( time ) ; } return `${ escape . measurement ( this . name ) }${ tagsLine } ${ fieldsLine }${ time !== undefined ? ' ' + time : '' }` ; } toString ( ) { const line = this . toLineProtocol ( undefined ) ; return line ? line : `invalid point: ${ JSON . stringify ( this , undefined ) }` ; } }