@influxdata/influxdb-client-browser 1.18.0 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.browser.js","sources":["../src/results/chunkCombiner.ts","../src/results/chunksToLines.ts","../src/results/LineSplitter.ts","../src/results/FluxTableColumn.ts","../src/errors.ts","../src/results/FluxTableMetaData.ts","../src/results/linesToTables.ts","../src/options.ts","../src/util/escape.ts","../src/util/currentTime.ts","../src/util/logger.ts","../src/query/flux.ts","../src/observable/symbol.ts","../src/impl/retryStrategy.ts","../src/impl/RetryBuffer.ts","../src/impl/WriteApiImpl.ts","../src/impl/browser/FetchTransport.ts","../src/impl/completeCommunicationObserver.ts","../src/QueryApi.ts","../src/impl/ObservableQuery.ts","../src/impl/QueryApiImpl.ts","../src/InfluxDB.ts","../src/Point.ts","../src/results/stringToLines.ts"],"sourcesContent":["/**\n * ChunkCombiner is a simplified platform-neutral manipulation of Uint8arrays\n * that allows to process text data on the fly. The implementation can be optimized\n * for the target platform (node vs browser).\n */\nexport interface ChunkCombiner {\n /**\n * Concatenates first and second chunk.\n * @param first - first chunk\n * @param second - second chunk\n * @returns first + second\n */\n concat(first: Uint8Array, second: Uint8Array): Uint8Array\n\n /**\n * Converts chunk into a string.\n * @param chunk - chunk\n * @param start - start index\n * @param end - end index\n * @returns string representation of chunk slice\n */\n toUtf8String(chunk: Uint8Array, start: number, end: number): string\n\n /**\n * Creates a new chunk from the supplied chunk.\n * @param chunk - chunk to copy\n * @param start - start index\n * @param end - end index\n * @returns a copy of a chunk slice\n */\n copy(chunk: Uint8Array, start: number, end: number): Uint8Array\n}\n\n// TextDecoder is available since node v8.3.0 and in all modern browsers\ndeclare const TextDecoder: any\n\n/**\n * Creates a chunk combiner instance that uses UTF-8\n * TextDecoder to decode Uint8Arrays into strings.\n */\nexport function createTextDecoderCombiner(): ChunkCombiner {\n const decoder = new TextDecoder('utf-8')\n return {\n concat(first: Uint8Array, second: Uint8Array): Uint8Array {\n const retVal = new Uint8Array(first.length + second.length)\n retVal.set(first)\n retVal.set(second, first.length)\n return retVal\n },\n copy(chunk: Uint8Array, start: number, end: number): Uint8Array {\n const retVal = new Uint8Array(end - start)\n retVal.set(chunk.subarray(start, end))\n return retVal\n },\n toUtf8String(chunk: Uint8Array, start: number, end: number): string {\n return decoder.decode(chunk.subarray(start, end))\n },\n }\n}\n","import {ChunkCombiner, createTextDecoderCombiner} from './chunkCombiner'\nimport {CommunicationObserver} from './CommunicationObserver'\nimport {Cancellable} from './Cancellable'\n\n/**\n * ChunksToLines is a transformation that accepts Uint8Array instances\n * and emmits strings representing CSV lines.\n * @param target - target to emmit CSV lines to\n * @param chunks - chunk combiner\n * @returns communication obrver to accept Uint8Arrays\n */\nexport function chunksToLines(\n target: CommunicationObserver<string>,\n chunkCombiner?: ChunkCombiner\n): CommunicationObserver<Uint8Array> {\n const chunks = chunkCombiner ?? createTextDecoderCombiner()\n let previous: Uint8Array | undefined\n let finished = false\n let quoted = false\n\n function bufferReceived(chunk: Uint8Array): void {\n let index: number\n let start = 0\n if (previous) {\n chunk = chunks.concat(previous, chunk)\n index = (previous as Buffer).length\n } else {\n index = 0\n }\n while (index < chunk.length) {\n const c = chunk[index]\n if (c === 10) {\n if (!quoted) {\n /* do not emit CR+LR or LF line ending */\n const end = index > 0 && chunk[index - 1] === 13 ? index - 1 : index\n // do not emmit more lines if the processing is already finished\n if (finished) {\n return\n }\n target.next(chunks.toUtf8String(chunk, start, end))\n start = index + 1\n }\n } else if (c === 34 /* \" */) {\n quoted = !quoted\n }\n index++\n }\n if (start < index) {\n previous = chunks.copy(chunk, start, index)\n } else {\n previous = undefined\n }\n }\n\n return {\n next(chunk: Uint8Array): void {\n if (finished) return\n try {\n bufferReceived(chunk)\n } catch (e) {\n this.error(e)\n }\n },\n error(error: Error): void {\n if (!finished) {\n finished = true\n target.error(error)\n }\n },\n complete(): void {\n if (!finished) {\n if (previous) {\n target.next(chunks.toUtf8String(previous, 0, previous.length))\n }\n finished = true\n target.complete()\n }\n },\n useCancellable(cancellable: Cancellable): void {\n if (target.useCancellable) {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this\n target.useCancellable({\n cancel(): void {\n cancellable.cancel()\n previous = undefined // do not emit more lines\n self.complete()\n },\n isCancelled(): boolean {\n return cancellable.isCancelled()\n },\n })\n }\n },\n }\n}\n","/**\n * Optimized tokenizer of a single CSV line.\n */\nexport class LineSplitter {\n /** returned value when reused */\n reusedValues: string[]\n /** last length of elements in */\n lastSplitLength: number\n private _reuse = false\n\n /**\n * Reuse returned array between consecutive calls.\n */\n get reuse(): boolean {\n return this._reuse\n }\n set reuse(val: boolean) {\n if (val && !this.reusedValues) {\n this.reusedValues = new Array(10)\n }\n this._reuse = val\n }\n\n /**\n * Sets the reuse flag and returns this.\n */\n withReuse(): LineSplitter {\n this.reuse = true\n return this\n }\n\n /**\n * Splits the supplied line to elements that are separated by\n * comma with values possibly escaped within double quotes (\"value\")\n * @param line - line\n * @returns array of splitted parts\n */\n splitLine(line: string | undefined | null): string[] {\n if (line === null || line === undefined) {\n this.lastSplitLength = 0\n return []\n }\n let quoteCount = 0\n let startIndex = 0\n const values = this._reuse ? this.reusedValues : []\n let count = 0\n for (let i = 0; i < line.length; i++) {\n const c = line[i]\n if (c === ',') {\n if (quoteCount % 2 === 0) {\n const val = this.getValue(line, startIndex, i, quoteCount)\n if (this._reuse) {\n values[count++] = val\n } else {\n values.push(val)\n }\n startIndex = i + 1\n quoteCount = 0\n }\n } else if (c === '\"') {\n quoteCount++\n }\n }\n const val = this.getValue(line, startIndex, line.length, quoteCount)\n if (this._reuse) {\n values[count] = val\n this.lastSplitLength = count + 1\n } else {\n values.push(val)\n this.lastSplitLength = values.length\n }\n\n return values\n }\n\n private getValue(\n line: string,\n start: number,\n end: number,\n quoteCount: number\n ): string {\n if (start === line.length) {\n return ''\n } else if (quoteCount === 0) {\n return line.substring(start, end)\n } else if (quoteCount === 2) {\n return line.substring(start + 1, end - 1)\n } else {\n // quoteCount >= 4\n return line.substring(start + 1, end - 1).replace(/\"\"/gi, '\"')\n }\n }\n}\n","/**\n * Type of query result column, see {@link https://v2.docs.influxdata.com/v2.0/reference/syntax/annotated-csv/#valid-data-types }\n */\nexport type ColumnType =\n | 'boolean'\n | 'unsignedLong'\n | 'long'\n | 'double'\n | 'string'\n | 'base64Binary'\n | 'dateTime:RFC3339'\n | 'duration'\n | string\n\n/**\n * Column metadata class of a {@link http://bit.ly/flux-spec#table | flux table} column.\n */\nexport interface FluxTableColumn {\n /**\n * Label (e.g., \"_start\", \"_stop\", \"_time\").\n */\n label: string\n\n /**\n * The data type of column (e.g., \"string\", \"long\", \"dateTime:RFC3339\").\n */\n dataType: ColumnType\n\n /**\n * Boolean flag indicating if the column is a part of the table's group key.\n */\n group: boolean\n\n /**\n * Default value to be used for rows whose string value is an empty string.\n */\n defaultValue: string\n\n /**\n * Index of this column in a row array.\n */\n index: number\n}\n\n/**\n * FluxTableColumn implementation.\n */\nclass FluxTableColumnImpl implements FluxTableColumn {\n label: string\n dataType: ColumnType\n group: boolean\n defaultValue: string\n index: number\n}\n\n/**\n * Creates a new flux table column.\n * @returns column instance\n */\nexport function newFluxTableColumn(): FluxTableColumn {\n return new FluxTableColumnImpl()\n}\n\n/**\n * Creates a flux table column from a partial FluxTableColumn.\n * @param object - source object\n * @returns column instance\n */\nexport function createFluxTableColumn(\n object: Partial<FluxTableColumn>\n): FluxTableColumn {\n const retVal = new FluxTableColumnImpl()\n retVal.label = String(object.label)\n retVal.dataType = object.dataType as ColumnType\n retVal.group = Boolean(object.group)\n retVal.defaultValue = object.defaultValue ?? ''\n retVal.index = object.index ?? 0\n return retVal\n}\n","/**\n * Strategy for calculating retry delays.\n */\nexport interface RetryDelayStrategy {\n /**\n * Returns delay for a next retry\n * @param error - reason for retrying\n * @param failedAttempts - a count of already failed attempts, 1 being the first\n * @returns milliseconds to wait before retrying\n */\n nextDelay(error?: Error, failedAttempts?: number): number\n /** Implementation should reset its state, this is mandatory to call upon success. */\n success(): void\n}\n\n/**\n * Interface for errors to inform that an associated operation can be retried.\n */\nexport interface RetriableDecision {\n /**\n * Informs whether this can be retried.\n */\n canRetry(): boolean\n /**\n * Get the delay in milliseconds to retry the action.\n * @returns 0 to let the implementation decide, miliseconds delay otherwise\n */\n retryAfter(): number\n}\n\nconst retriableStatusCodes = [404, 408, 425, 429, 500, 502, 503, 504]\n/** isStatusCodeRetriable checks whether the supplied HTTP status code is retriable. */\nexport function isStatusCodeRetriable(statusCode: number): boolean {\n return retriableStatusCodes.includes(statusCode)\n}\n\n/** IllegalArgumentError is thrown when illegal argument is supplied. */\nexport class IllegalArgumentError extends Error {\n /* istanbul ignore next */\n constructor(message: string) {\n super(message)\n this.name = 'IllegalArgumentError'\n Object.setPrototypeOf(this, IllegalArgumentError.prototype)\n }\n}\n\n/**\n * A general HTTP error.\n */\nexport class HttpError extends Error implements RetriableDecision {\n private _retryAfter: number\n /** application error code, when available */\n public code: string | undefined\n /** json error response */\n public json: any\n\n /* istanbul ignore next because of super() not being covered*/\n constructor(\n readonly statusCode: number,\n readonly statusMessage: string | undefined,\n readonly body?: string,\n retryAfter?: string | undefined | null,\n readonly contentType?: string | undefined | null,\n message?: string\n ) {\n super()\n Object.setPrototypeOf(this, HttpError.prototype)\n if (message) {\n this.message = message\n } else if (body) {\n if (contentType?.startsWith('application/json')) {\n try {\n this.json = JSON.parse(body)\n this.message = this.json.message\n this.code = this.json.code\n } catch (e) {\n // silently ignore, body string is still available\n }\n }\n if (!this.message) {\n this.message = `${statusCode} ${statusMessage} : ${body}`\n }\n } else {\n this.message = `${statusCode} ${statusMessage}`\n }\n this.name = 'HttpError'\n this.setRetryAfter(retryAfter)\n }\n\n private setRetryAfter(retryAfter?: string | undefined | null): void {\n if (typeof retryAfter === 'string') {\n // try to parse the supplied number as milliseconds\n if (/^[0-9]+$/.test(retryAfter)) {\n this._retryAfter = parseInt(retryAfter)\n } else {\n this._retryAfter = 0\n }\n } else {\n this._retryAfter = 0\n }\n }\n\n canRetry(): boolean {\n return isStatusCodeRetriable(this.statusCode)\n }\n retryAfter(): number {\n return this._retryAfter\n }\n}\n\n//see https://nodejs.org/api/errors.html\nconst RETRY_CODES = [\n 'ECONNRESET',\n 'ENOTFOUND',\n 'ESOCKETTIMEDOUT',\n 'ETIMEDOUT',\n 'ECONNREFUSED',\n 'EHOSTUNREACH',\n 'EPIPE',\n]\n\n/**\n * Tests the error in order to know if an HTTP call can be retried.\n * @param error - error to test\n * @returns true for a retriable error\n */\nexport function canRetryHttpCall(error: any): boolean {\n if (!error) {\n return false\n } else if (typeof (error as any).canRetry === 'function') {\n return !!((error as any).canRetry as () => boolean)()\n } else if ((error as any).code && RETRY_CODES.includes((error as any).code)) {\n return true\n }\n return false\n}\n\n/**\n * Gets retry delay from the supplied error, possibly using random number up to retryJitter.\n */\nexport function getRetryDelay(error?: Error, retryJitter?: number): number {\n if (!error) {\n return 0\n } else {\n let retVal\n if (typeof (error as any).retryAfter === 'function') {\n return ((error as any).retryAfter as () => number)()\n } else {\n retVal = 0\n }\n if (retryJitter && retryJitter > 0) {\n return retVal + Math.round(Math.random() * retryJitter)\n } else {\n return retVal\n }\n }\n}\n\n/** RequestTimedOutError indicates request timeout in the communication with the server */\nexport class RequestTimedOutError extends Error implements RetriableDecision {\n /* istanbul ignore next because of super() not being covered */\n constructor() {\n super()\n Object.setPrototypeOf(this, RequestTimedOutError.prototype)\n this.name = 'RequestTimedOutError'\n this.message = 'Request timed out'\n }\n canRetry(): boolean {\n return true\n }\n retryAfter(): number {\n return 0\n }\n}\n\n/** AbortError indicates that the communication with the server was aborted */\nexport class AbortError extends Error implements RetriableDecision {\n /* istanbul ignore next because of super() not being covered */\n constructor() {\n super()\n this.name = 'AbortError'\n Object.setPrototypeOf(this, AbortError.prototype)\n this.message = 'Response aborted'\n }\n canRetry(): boolean {\n return true\n }\n retryAfter(): number {\n return 0\n }\n}\n","import {FluxTableColumn, ColumnType} from './FluxTableColumn'\nimport {IllegalArgumentError} from '../errors'\n\nconst identity = (x: string): any => x\n/**\n * A dictionary of serializers of particular types returned by a flux query.\n * See {@link https://v2.docs.influxdata.com/v2.0/reference/syntax/annotated-csv/#valid-data-types }\n */\nexport const typeSerializers: Record<ColumnType, (val: string) => any> = {\n boolean: (x: string): any => x === 'true',\n unsignedLong: (x: string): any => (x === '' ? null : +x),\n long: (x: string): any => (x === '' ? null : +x),\n double(x: string): any {\n switch (x) {\n case '':\n return null\n case '+Inf':\n return Number.POSITIVE_INFINITY\n case '-Inf':\n return Number.NEGATIVE_INFINITY\n default:\n return +x\n }\n },\n string: identity,\n base64Binary: identity,\n duration: (x: string): any => (x === '' ? null : x),\n 'dateTime:RFC3339': (x: string): any => (x === '' ? null : x),\n}\n\n/**\n * serializeDateTimeAsDate changes type serializers to return JavaScript Date instances\n * for 'dateTime:RFC3339' query result data type. Empty value is converted to null.\n * @remarks\n * Please note that the result has millisecond precision whereas InfluxDB returns dateTime\n * in nanosecond precision.\n */\nexport function serializeDateTimeAsDate(): void {\n typeSerializers['dateTime:RFC3339'] = (x: string): any =>\n x === '' ? null : new Date(Date.parse(x))\n}\n/**\n * serializeDateTimeAsNumber changes type serializers to return milliseconds since epoch\n * for 'dateTime:RFC3339' query result data type. Empty value is converted to null.\n * @remarks\n * Please note that the result has millisecond precision whereas InfluxDB returns dateTime\n * in nanosecond precision.\n */\nexport function serializeDateTimeAsNumber(): void {\n typeSerializers['dateTime:RFC3339'] = (x: string): any =>\n x === '' ? null : Date.parse(x)\n}\n/**\n * serializeDateTimeAsString changes type serializers to return string values\n * for `dateTime:RFC3339` query result data type. Empty value is converted to null.\n */\nexport function serializeDateTimeAsString(): void {\n typeSerializers['dateTime:RFC3339'] = (x: string): any =>\n x === '' ? null : x\n}\n\n/**\n * Represents metadata of a {@link http://bit.ly/flux-spec#table | flux table}.\n */\nexport interface FluxTableMetaData {\n /**\n * Table columns.\n */\n columns: Array<FluxTableColumn>\n\n /**\n * Gets columns by name\n * @param label - column label\n * @returns table column\n * @throws IllegalArgumentError if column is not found\n **/\n column(label: string): FluxTableColumn\n\n /**\n * Creates an object out of the supplied values with the help of columns .\n * @param values - a row with data for each column\n */\n toObject(values: string[]): {[key: string]: any}\n}\n\n/**\n * FluxTableMetaData Implementation.\n */\nclass FluxTableMetaDataImpl implements FluxTableMetaData {\n columns: Array<FluxTableColumn>\n constructor(columns: FluxTableColumn[]) {\n columns.forEach((col, i) => (col.index = i))\n this.columns = columns\n }\n column(label: string): FluxTableColumn {\n for (let i = 0; i < this.columns.length; i++) {\n const col = this.columns[i]\n if (col.label === label) return col\n }\n throw new IllegalArgumentError(`Column ${label} not found!`)\n }\n toObject(values: string[]): {[key: string]: any} {\n const acc: any = {}\n for (let i = 0; i < this.columns.length && i < values.length; i++) {\n let val = values[i]\n const column = this.columns[i]\n if (val === '' && column.defaultValue) {\n val = column.defaultValue\n }\n acc[column.label] = (typeSerializers[column.dataType] ?? identity)(val)\n }\n return acc\n }\n}\n\n/**\n * Created FluxTableMetaData from the columns supplied.\n * @param columns - columns\n * @returns - instance\n */\nexport function createFluxTableMetaData(\n columns: FluxTableColumn[]\n): FluxTableMetaData {\n return new FluxTableMetaDataImpl(columns)\n}\n","import {CommunicationObserver} from './CommunicationObserver'\nimport {Cancellable} from './Cancellable'\nimport {LineSplitter} from './LineSplitter'\nimport {FluxResultObserver} from './FluxResultObserver'\nimport {\n FluxTableColumn,\n ColumnType,\n newFluxTableColumn,\n} from './FluxTableColumn'\nimport {FluxTableMetaData, createFluxTableMetaData} from './FluxTableMetaData'\n\n/**\n * linesToTables creates a transformationthat accepts (flux) annotated CSV lines\n * and emits rows together with table metadata.\n */\nexport function linesToTables(\n consumer: FluxResultObserver<string[]>\n): CommunicationObserver<string> {\n const splitter = new LineSplitter().withReuse()\n let columns: FluxTableColumn[] | undefined\n let expectMeta = true\n let firstColumnIndex = 0\n let lastMeta: FluxTableMetaData\n return {\n error(error: Error): void {\n consumer.error(error)\n },\n next(line: string): void {\n if (line === '') {\n expectMeta = true\n columns = undefined\n } else {\n const values = splitter.splitLine(line)\n const size = splitter.lastSplitLength\n if (expectMeta) {\n // create columns\n if (!columns) {\n columns = new Array(size)\n for (let i = 0; i < size; i++) {\n columns[i] = newFluxTableColumn()\n }\n }\n if (!values[0].startsWith('#')) {\n // fill in column names\n if (values[0] === '') {\n firstColumnIndex = 1\n columns = columns.slice(1)\n } else {\n firstColumnIndex = 0\n }\n for (let i = firstColumnIndex; i < size; i++) {\n columns[i - firstColumnIndex].label = values[i]\n }\n lastMeta = createFluxTableMetaData(columns)\n expectMeta = false\n } else if (values[0] === '#datatype') {\n for (let i = 1; i < size; i++) {\n columns[i].dataType = values[i] as ColumnType\n }\n } else if (values[0] === '#default') {\n for (let i = 1; i < size; i++) {\n columns[i].defaultValue = values[i]\n }\n } else if (values[0] === '#group') {\n for (let i = 1; i < size; i++) {\n columns[i].group = values[i][0] === 't'\n }\n }\n } else {\n consumer.next(values.slice(firstColumnIndex, size), lastMeta)\n }\n }\n },\n complete(): void {\n consumer.complete()\n },\n useCancellable(cancellable: Cancellable): void {\n if (consumer.useCancellable) consumer.useCancellable(cancellable)\n },\n }\n}\n","import {Transport} from './transport'\nimport WriteApi from './WriteApi'\n\n/**\n * Option for the communication with InfluxDB server.\n */\nexport interface ConnectionOptions {\n /** base URL */\n url: string\n /** authentication token */\n token?: string\n /**\n * socket timeout, 10000 milliseconds by default in node.js\n * @defaultValue 10000\n */\n timeout?: number\n /**\n * TransportOptions supply extra options for the transport layer, they differ between node.js and browser/deno.\n * Node.js transport accepts options specified in {@link https://nodejs.org/api/http.html#http_http_request_options_callback | http.request } or\n * {@link https://nodejs.org/api/https.html#https_https_request_options_callback | https.request }. For example, an `agent` property can be set to\n * {@link https://www.npmjs.com/package/proxy-http-agent | setup HTTP/HTTPS proxy }, {@link https://nodejs.org/api/tls.html#tls_tls_connect_options_callback | rejectUnauthorized }\n * property can disable TLS server certificate verification. Additionally,\n * {@link https://github.com/follow-redirects/follow-redirects | follow-redirects } property can be also specified\n * in order to follow redirects in node.js.\n * {@link https://developer.mozilla.org/en-US/docs/Web/API/fetch | fetch } is used under the hood in browser/deno.\n * For example,\n * {@link https://developer.mozilla.org/en-US/docs/Web/API/fetch | redirect } property can be set to 'error' to abort request if a redirect occurs.\n */\n transportOptions?: {[key: string]: any}\n}\n\n/** default connection options */\nexport const DEFAULT_ConnectionOptions: Partial<ConnectionOptions> = {\n timeout: 10000,\n}\n\n/**\n * Options that configure strategy for retrying failed requests.\n */\nexport interface RetryDelayStrategyOptions {\n /** add `random(retryJitter)` milliseconds delay when retrying HTTP calls */\n retryJitter: number\n /** minimum delay when retrying write (milliseconds) */\n minRetryDelay: number\n /** maximum delay when retrying write (milliseconds) */\n maxRetryDelay: number\n /** base for the exponential retry delay */\n exponentialBase: number\n /**\n * randomRetry indicates whether the next retry delay is deterministic (false) or random (true).\n * The deterministic delay starts with `minRetryDelay * exponentialBase` and it is multiplied\n * by `exponentialBase` until it exceeds `maxRetryDelay`.\n * When random is `true`, the next delay is computed as a random number between next retry attempt (upper)\n * and the lower number in the deterministic sequence. `random(retryJitter)` is added to every returned value.\n */\n randomRetry: boolean\n}\n\n/**\n * Options that configure strategy for retrying failed InfluxDB write operations.\n */\nexport interface WriteRetryOptions extends RetryDelayStrategyOptions {\n /**\n * WriteFailed is called to inform about write errors.\n * @param this - the instance of the API that failed\n * @param error - write error\n * @param lines - failed lines\n * @param attempts - a number of failed attempts to write the lines\n * @returns a Promise to force the API to use it as a result of the flush operation,\n * void/undefined to continue with default retry mechanism\n */\n writeFailed(\n this: WriteApi,\n error: Error,\n lines: Array<string>,\n attempts: number\n ): Promise<void> | void\n\n /**\n * WriteSuccess is informed about successfully written lines.\n * @param this - the instance of the API in use\n * @param lines - written lines\n */\n writeSuccess(this: WriteApi, lines: Array<string>): void\n\n /** max number of retries when write fails */\n maxRetries: number\n /** max time (millis) that can be spent with retries */\n maxRetryTime: number\n /** the maximum size of retry-buffer (in lines) */\n maxBufferLines: number\n}\n\n/**\n * Options used by {@link WriteApi} .\n */\nexport interface WriteOptions extends WriteRetryOptions {\n /** max number of records to send in a batch */\n batchSize: number\n /** delay between data flushes in milliseconds, at most `batch size` records are sent during flush */\n flushInterval: number\n /** default tags, unescaped */\n defaultTags?: Record<string, string>\n /** HTTP headers that will be sent with every write request */\n headers?: {[key: string]: string}\n /** When specified, write bodies larger than the threshold are gzipped */\n gzipThreshold?: number\n}\n\n/** default RetryDelayStrategyOptions */\nexport const DEFAULT_RetryDelayStrategyOptions = {\n retryJitter: 200,\n minRetryDelay: 5000,\n maxRetryDelay: 125000,\n exponentialBase: 5,\n randomRetry: true,\n}\n\n/** default writeOptions */\nexport const DEFAULT_WriteOptions: WriteOptions = {\n batchSize: 1000,\n flushInterval: 60000,\n writeFailed: function() {},\n writeSuccess: function() {},\n maxRetries: 5,\n maxRetryTime: 180_000,\n maxBufferLines: 32_000,\n // a copy of DEFAULT_RetryDelayStrategyOptions, so that DEFAULT_WriteOptions could be tree-shaken\n retryJitter: 200,\n minRetryDelay: 5000,\n maxRetryDelay: 125000,\n exponentialBase: 2,\n gzipThreshold: 1000,\n randomRetry: true,\n}\n\n/**\n * Options used by {@link InfluxDB} .\n */\nexport interface ClientOptions extends ConnectionOptions {\n /** supplies and overrides default writing options */\n writeOptions?: Partial<WriteOptions>\n /** specifies custom transport */\n transport?: Transport\n}\n\n/**\n * Timestamp precision used in write operations.\n * See {@link https://v2.docs.influxdata.com/v2.0/api/#operation/PostWrite }\n */\nexport type WritePrecisionType = 'ns' | 'us' | 'ms' | 's'\n","function createEscaper(\n characters: string,\n replacements: string[]\n): (value: string) => string {\n return function(value: string): string {\n let retVal = ''\n let from = 0\n let i = 0\n while (i < value.length) {\n const found = characters.indexOf(value[i])\n if (found >= 0) {\n retVal += value.substring(from, i)\n retVal += replacements[found]\n from = i + 1\n }\n i++\n }\n if (from == 0) {\n return value\n } else if (from < value.length) {\n retVal += value.substring(from, value.length)\n }\n return retVal\n }\n}\nfunction createQuotedEscaper(\n characters: string,\n replacements: string[]\n): (value: string) => string {\n const escaper = createEscaper(characters, replacements)\n return (value: string): string => '\"' + escaper(value) + '\"'\n}\n\n/**\n * Provides functions escape specific parts in InfluxDB line protocol.\n */\nexport const escape = {\n /**\n * Measurement escapes measurement names.\n */\n measurement: createEscaper(', \\n\\r\\t', ['\\\\,', '\\\\ ', '\\\\n', '\\\\r', '\\\\t']),\n /**\n * Quoted escapes quoted values, such as database names.\n */\n quoted: createQuotedEscaper('\"\\\\', ['\\\\\"', '\\\\\\\\']),\n\n /**\n * TagEscaper escapes tag keys, tag values, and field keys.\n */\n tag: createEscaper(', =\\n\\r\\t', ['\\\\,', '\\\\ ', '\\\\=', '\\\\n', '\\\\r', '\\\\t']),\n}\n","declare let process: any\nconst zeroPadding = '000000000'\nlet useHrTime = false\n\nexport function useProcessHrtime(use: boolean): boolean {\n /* istanbul ignore else */\n if (!process.env.ROLLUP_BROWSER) {\n return (useHrTime = use && process && typeof process.hrtime === 'function')\n } else {\n return false\n }\n}\nuseProcessHrtime(true) // preffer node\n\nlet startHrMillis: number | undefined = undefined\nlet startHrTime: [number, number] | undefined = undefined\nlet lastMillis = Date.now()\nlet stepsInMillis = 0\nfunction nanos(): string {\n if (!process.env.ROLLUP_BROWSER && useHrTime) {\n const hrTime = process.hrtime() as [number, number]\n let millis = Date.now()\n if (!startHrTime) {\n startHrTime = hrTime\n startHrMillis = millis\n } else {\n hrTime[0] = hrTime[0] - startHrTime[0]\n hrTime[1] = hrTime[1] - startHrTime[1]\n // istanbul ignore next \"cannot mock system clock, manually reviewed\"\n if (hrTime[1] < 0) {\n hrTime[0] -= 1\n hrTime[1] += 1000_000_000\n }\n millis =\n (startHrMillis as number) +\n hrTime[0] * 1000 +\n Math.floor(hrTime[1] / 1000_000)\n }\n const nanos = String(hrTime[1] % 1000_000)\n return String(millis) + zeroPadding.substr(0, 6 - nanos.length) + nanos\n } else {\n const millis = Date.now()\n if (millis !== lastMillis) {\n lastMillis = millis\n stepsInMillis = 0\n } else {\n stepsInMillis++\n }\n const nanos = String(stepsInMillis)\n return String(millis) + zeroPadding.substr(0, 6 - nanos.length) + nanos\n }\n}\n\nfunction micros(): string {\n if (!process.env.ROLLUP_BROWSER && useHrTime) {\n const hrTime = process.hrtime() as [number, number]\n const micros = String(Math.trunc(hrTime[1] / 1000) % 1000)\n return (\n String(Date.now()) + zeroPadding.substr(0, 3 - micros.length) + micros\n )\n } else {\n return String(Date.now()) + zeroPadding.substr(0, 3)\n }\n}\nfunction millis(): string {\n return String(Date.now())\n}\nfunction seconds(): string {\n return String(Math.floor(Date.now() / 1000))\n}\n\n/**\n * Exposes functions that creates strings that represent a timestamp that\n * can be used in the line protocol. Micro and nano timestamps are emulated\n * depending on the js platform in use.\n */\nexport const currentTime = {\n s: seconds as () => string,\n ms: millis as () => string,\n us: micros as () => string,\n ns: nanos as () => string,\n seconds: seconds as () => string,\n millis: millis as () => string,\n micros: micros as () => string,\n nanos: nanos as () => string,\n}\n\n/**\n * dateToProtocolTimestamp provides converters for JavaScript Date to InfluxDB Write Protocol Timestamp. Keys are supported precisions.\n */\nexport const dateToProtocolTimestamp = {\n s: (d: Date): string => `${Math.floor(d.getTime() / 1000)}`,\n ms: (d: Date): string => `${d.getTime()}`,\n us: (d: Date): string => `${d.getTime()}000`,\n ns: (d: Date): string => `${d.getTime()}000000`,\n}\n\n/**\n * convertTimeToNanos converts of Point's timestamp to a string\n * @param value - supported timestamp value\n * @returns line protocol value\n */\nexport function convertTimeToNanos(\n value: string | number | Date | undefined\n): string | undefined {\n if (value === undefined) {\n return nanos()\n } else if (typeof value === 'string') {\n return value.length > 0 ? value : undefined\n } else if (value instanceof Date) {\n return `${value.getTime()}000000`\n } else if (typeof value === 'number') {\n return String(Math.floor(value))\n } else {\n return String(value)\n }\n}\n","/**\n * Logging interface.\n */\nexport interface Logger {\n error(message: string, err?: any): void\n warn(message: string, err?: any): void\n}\n\n/**\n * Logger that logs to console.out\n */\nexport const consoleLogger: Logger = {\n error(message, error) {\n // eslint-disable-next-line no-console\n console.error('ERROR: ' + message, error ? error : '')\n },\n warn(message, error) {\n // eslint-disable-next-line no-console\n console.warn('WARN: ' + message, error ? error : '')\n },\n}\nlet provider: Logger = consoleLogger\n\nexport const Logger: Logger = {\n error(message, error) {\n provider.error(message, error)\n },\n warn(message, error) {\n provider.warn(message, error)\n },\n}\n\n/**\n * Sets custom logger.\n * @param logger - logger to use\n * @returns previous logger\n */\nexport function setLogger(logger: Logger): Logger {\n const previous = provider\n provider = logger\n return previous\n}\n","/** Property that offers a function that returns flux-sanitized value of an object. */\nexport const FLUX_VALUE = Symbol('FLUX_VALUE')\n\n/**\n * A flux parameter can print its (sanitized) flux value.\n */\nexport interface FluxParameterLike {\n [FLUX_VALUE](): string\n}\n\n/**\n * Represents a parameterized query.\n */\nexport interface ParameterizedQuery {\n /**\n * Returns flux query with sanitized parameters.\n */\n toString(): string\n}\n\nclass FluxParameter implements FluxParameterLike, ParameterizedQuery {\n constructor(private fluxValue: string) {}\n toString(): string {\n return this.fluxValue\n }\n [FLUX_VALUE](): string {\n return this.fluxValue\n }\n}\n\n/**\n * Checks if the supplied object is FluxParameterLike\n * @param value - any value\n * @returns true if it is\n */\nfunction isFluxParameterLike(value: any): boolean {\n return typeof value === 'object' && typeof value[FLUX_VALUE] === 'function'\n}\n\n/**\n * Escapes content of the supplied string so it can be wrapped into double qoutes\n * to become a [flux string literal](https://docs.influxdata.com/flux/v0.65/language/lexical-elements/#string-literals).\n * @param value - string value\n * @returns sanitized string\n */\nfunction sanitizeString(value: any): string {\n if (value === null || value === undefined) return ''\n value = value.toString()\n let retVal: any = undefined\n let i = 0\n function prepareRetVal(): void {\n if (retVal === undefined) {\n retVal = value.substring(0, i)\n }\n }\n for (; i < value.length; i++) {\n const c = value.charAt(i)\n switch (c) {\n case '\\r':\n prepareRetVal()\n retVal += '\\\\r'\n break\n case '\\n':\n prepareRetVal()\n retVal += '\\\\n'\n break\n case '\\t':\n prepareRetVal()\n retVal += '\\\\t'\n break\n case '\"':\n case '\\\\':\n prepareRetVal()\n retVal = retVal + '\\\\' + c\n break\n case '$':\n // escape ${\n if (i + 1 < value.length && value.charAt(i + 1) === '{') {\n prepareRetVal()\n i++\n retVal += '\\\\${'\n break\n }\n // append $\n if (retVal != undefined) {\n retVal += c\n }\n break\n default:\n if (retVal != undefined) {\n retVal += c\n }\n }\n }\n if (retVal !== undefined) {\n return retVal\n }\n return value\n}\n\n/**\n * Creates a flux string literal.\n */\nexport function fluxString(value: any): FluxParameterLike {\n return new FluxParameter(`\"${sanitizeString(value)}\"`)\n}\n\n/**\n * Sanitizes float value to avoid injections.\n * @param value - InfluxDB float literal\n * @returns sanitized float value\n * @throws Error if the the value cannot be sanitized\n */\nexport function sanitizeFloat(value: any): string {\n if (typeof value === 'number') {\n if (!isFinite(value)) {\n throw new Error(`not a flux float: ${value}`)\n }\n return value.toString()\n }\n const val = String(value)\n let dot = false\n for (const c of val) {\n if (c === '.') {\n if (dot) throw new Error(`not a flux float: ${val}`)\n dot = !dot\n continue\n }\n if (c !== '.' && c !== '-' && (c < '0' || c > '9'))\n throw new Error(`not a flux float: ${val}`)\n }\n return val\n}\n/**\n * Creates a flux float literal.\n */\nexport function fluxFloat(value: any): FluxParameterLike {\n return new FluxParameter(sanitizeFloat(value))\n}\n\n/**\n * Creates a flux integer literal.\n */\nexport function fluxInteger(value: any): FluxParameterLike {\n const val = sanitizeFloat(value)\n for (const c of val) {\n if (c === '.') {\n throw new Error(`not a flux integer: ${val}`)\n }\n }\n return new FluxParameter(val)\n}\n\nfunction sanitizeDateTime(value: any): string {\n return `time(v: \"${sanitizeString(value)}\")`\n}\n\n/**\n * Creates flux date-time literal.\n */\nexport function fluxDateTime(value: any): FluxParameterLike {\n return new FluxParameter(sanitizeDateTime(value))\n}\n\n/**\n * Creates flux date-time literal.\n */\nexport function fluxDuration(value: any): FluxParameterLike {\n return new FluxParameter(`duration(v: \"${sanitizeString(value)}\")`)\n}\n\nfunction sanitizeRegExp(value: any): string {\n return `regexp.compile(v: \"${sanitizeString(value)}\")`\n}\n\n/**\n * Creates flux regexp literal.\n */\nexport function fluxRegExp(value: any): FluxParameterLike {\n // let the server decide if it can be parsed\n return new FluxParameter(sanitizeRegExp(value))\n}\n\n/**\n * Creates flux boolean literal.\n */\nexport function fluxBool(value: any): FluxParameterLike {\n if (value === 'true' || value === 'false') {\n return new FluxParameter(value)\n }\n return new FluxParameter((!!value).toString())\n}\n\n/**\n * Assumes that the supplied value is flux expression or literal that does not need sanitizing.\n *\n * @param value - any value\n * @returns the supplied value as-is\n */\nexport function fluxExpression(value: any): FluxParameterLike {\n return new FluxParameter(String(value))\n}\n\n/**\n * Escapes content of the supplied parameter so that it can be safely embedded into flux query.\n * @param value - parameter value\n * @returns sanitized flux value or an empty string if it cannot be converted\n */\nexport function toFluxValue(value: any): string {\n if (value === undefined) {\n return ''\n } else if (value === null) {\n return 'null'\n } else if (typeof value === 'boolean') {\n return value.toString()\n } else if (typeof value === 'string') {\n return `\"${sanitizeString(value)}\"`\n } else if (typeof value === 'number') {\n return sanitizeFloat(value)\n } else if (typeof value === 'object') {\n if (typeof value[FLUX_VALUE] === 'function') {\n return value[FLUX_VALUE]()\n } else if (value instanceof Date) {\n return value.toISOString()\n } else if (value instanceof RegExp) {\n return sanitizeRegExp(value)\n } else if (Array.isArray(value)) {\n return `[${value.map(toFluxValue).join(',')}]`\n }\n }\n // use toString value for unrecognized object, bigint, symbol\n return toFluxValue(value.toString())\n}\n\n/**\n * Flux is a tagged template that sanitizes supplied parameters\n * to avoid injection attacks in flux.\n */\nexport function flux(\n strings: TemplateStringsArray,\n ...values: any\n): ParameterizedQuery {\n if (strings.length == 1 && values.length === 0) {\n return fluxExpression(strings[0]) // the simplest case\n }\n const parts = new Array<string>(strings.length + values.length)\n let partIndex = 0\n for (let i = 0; i < strings.length; i++) {\n const text = strings[i]\n parts[partIndex++] = text\n if (i < values.length) {\n const val = values[i]\n let sanitized: string\n if (\n text.endsWith('\"') &&\n i + 1 < strings.length &&\n strings[i + 1].startsWith('\"')\n ) {\n // parameter is wrapped into flux double quotes\n sanitized = sanitizeString(val)\n } else {\n sanitized = toFluxValue(val)\n if (sanitized === '') {\n // do not allow to insert empty strings, unless it is FluxParameterLike\n if (!isFluxParameterLike(val)) {\n throw new Error(\n `Unsupported parameter literal '${val}' at index: ${i}, type: ${typeof val}`\n )\n }\n }\n }\n parts[partIndex++] = sanitized\n } else if (i < strings.length - 1) {\n throw new Error('Too few parameters supplied!')\n }\n }\n // return flux expression so that flux can be embedded into another flux as-is\n return fluxExpression(parts.join(''))\n}\n","/* Observable interop typing. Taken from https://github.com/ReactiveX/rxjs */\n\n/* Note: This will add Symbol.observable globally for all TypeScript users */\ndeclare global {\n interface SymbolConstructor {\n readonly observable: symbol\n }\n}\n\n/** Symbol.observable or a string \"\\@\\@observable\". Used for interop */\nexport const symbolObservable = (():\n | typeof Symbol.observable\n | '@@observable' =>\n (typeof Symbol === 'function' && Symbol.observable) || '@@observable')()\n","import {getRetryDelay, RetryDelayStrategy} from '../errors'\nimport {\n RetryDelayStrategyOptions,\n DEFAULT_RetryDelayStrategyOptions,\n} from '../options'\n\n/**\n * Applies a variant of exponential backoff with initial and max delay and a random\n * jitter delay. It also respects `retry delay` when specified together with an error.\n */\nexport class RetryStrategyImpl implements RetryDelayStrategy {\n options: RetryDelayStrategyOptions\n currentDelay: number | undefined\n\n constructor(options?: Partial<RetryDelayStrategyOptions>) {\n this.options = {...DEFAULT_RetryDelayStrategyOptions, ...options}\n this.success()\n }\n\n nextDelay(error?: Error, failedAttempts?: number): number {\n const delay = getRetryDelay(error)\n if (delay && delay > 0) {\n return delay + Math.round(Math.random() * this.options.retryJitter)\n } else {\n if (failedAttempts && failedAttempts > 0) {\n // compute delay\n if (this.options.randomRetry) {\n // random delay between deterministic delays\n let delay = Math.max(this.options.minRetryDelay, 1)\n let nextDelay = delay * this.options.exponentialBase\n for (let i = 1; i < failedAttempts; i++) {\n delay = nextDelay\n nextDelay = nextDelay * this.options.exponentialBase\n if (nextDelay >= this.options.maxRetryDelay) {\n nextDelay = this.options.maxRetryDelay\n break\n }\n }\n return (\n delay +\n Math.round(\n Math.random() * (nextDelay - delay) +\n Math.random() * this.options.retryJitter\n )\n )\n }\n // deterministric delay otherwise\n let delay = Math.max(this.options.minRetryDelay, 1)\n for (let i = 1; i < failedAttempts; i++) {\n delay = delay * this.options.exponentialBase\n if (delay >= this.options.maxRetryDelay) {\n delay = this.options.maxRetryDelay\n break\n }\n }\n return delay + Math.round(Math.random() * this.options.retryJitter)\n } else if (this.currentDelay) {\n this.currentDelay = Math.min(\n Math.max(this.currentDelay * this.options.exponentialBase, 1) +\n Math.round(Math.random() * this.options.retryJitter),\n this.options.maxRetryDelay\n )\n } else {\n this.currentDelay =\n this.options.minRetryDelay +\n Math.round(Math.random() * this.options.retryJitter)\n }\n return this.currentDelay\n }\n }\n success(): void {\n this.currentDelay = undefined\n }\n}\n\n/**\n * Creates a new instance of retry strategy.\n * @param options - retry options\n * @returns retry strategy implementation\n */\nexport function createRetryDelayStrategy(\n options?: Partial<RetryDelayStrategyOptions>\n): RetryDelayStrategy {\n return new RetryStrategyImpl(options)\n}\n","import {Logger} from '../util/logger'\n\n/* interval between successful retries */\nconst RETRY_INTERVAL = 1\n\ninterface RetryItem {\n lines: string[]\n retryCount: number\n expires: number\n next?: RetryItem\n}\n\n/**\n * Retries lines up to a limit of max buffer size.\n */\nexport default class RetryBuffer {\n first?: RetryItem\n last?: RetryItem\n size = 0\n nextRetryTime = 0\n closed = false\n private _timeoutHandle: any = undefined\n\n constructor(\n private maxLines: number,\n private retryLines: (\n lines: string[],\n retryCountdown: number,\n started: number\n ) => Promise<void>\n ) {}\n\n addLines(\n lines: string[],\n retryCount: number,\n delay: number,\n expires: number\n ): void {\n if (this.closed) return\n if (!lines.length) return\n let retryTime = Date.now() + delay\n if (expires < retryTime) {\n delay = expires - Date.now()\n retryTime = expires\n }\n if (retryTime > this.nextRetryTime) this.nextRetryTime = retryTime\n // ensure at most maxLines are in the Buffer\n if (this.first && this.size + lines.length > this.maxLines) {\n const origSize = this.size\n const newSize = origSize * 0.7 // reduce to 70 %\n do {\n const newFirst = this.first.next as RetryItem\n this.size -= this.first.lines.length\n this.first.next = undefined\n this.first = newFirst\n if (!this.first) {\n this.last = undefined\n }\n } while (this.first && this.size + lines.length > newSize)\n Logger.error(\n `RetryBuffer: ${origSize -\n this\n .size} oldest lines removed to keep buffer size under the limit of ${\n this.maxLines\n } lines`\n )\n }\n const toAdd: RetryItem = {\n lines,\n retryCount,\n expires,\n }\n if (this.last) {\n this.last.next = toAdd\n this.last = toAdd\n } else {\n this.first = toAdd\n this.last = toAdd\n this.scheduleRetry(delay)\n }\n this.size += lines.length\n }\n\n removeLines(): RetryItem | undefined {\n if (this.first) {\n const toRetry = this.first\n this.first = this.first.next\n toRetry.next = undefined\n this.size -= toRetry.lines.length\n if (!this.first) this.last = undefined\n return toRetry\n }\n return undefined\n }\n\n scheduleRetry(delay: number): void {\n this._timeoutHandle = setTimeout(() => {\n const toRetry = this.removeLines()\n if (toRetry) {\n this.retryLines(toRetry.lines, toRetry.retryCount, toRetry.expires)\n .then(() => {\n // continue with successfull retry\n this.scheduleRetry(RETRY_INTERVAL)\n })\n .catch(_e => {\n // already logged\n this.scheduleRetry(this.nextRetryTime - Date.now())\n })\n } else {\n this._timeoutHandle = undefined\n }\n }, Math.max(delay, 0))\n }\n\n async flush(): Promise<void> {\n let toRetry\n while ((toRetry = this.removeLines())) {\n await this.retryLines(toRetry.lines, toRetry.retryCount, toRetry.expires)\n }\n }\n\n close(): number {\n if (this._timeoutHandle) {\n clearTimeout(this._timeoutHandle)\n this._timeoutHandle = undefined\n }\n this.closed = true\n return this.size\n }\n}\n","import WriteApi from '../WriteApi'\nimport {\n DEFAULT_WriteOptions,\n WriteOptions,\n WritePrecisionType,\n} from '../options'\nimport {Transport, SendOptions} from '../transport'\nimport {Headers} from '../results'\nimport {Logger} from '../util/logger'\nimport {HttpError, RetryDelayStrategy} from '../errors'\nimport {Point} from '../Point'\nimport {escape} from '../util/escape'\nimport {currentTime, dateToProtocolTimestamp} from '../util/currentTime'\nimport {createRetryDelayStrategy} from './retryStrategy'\nimport RetryBuffer from './RetryBuffer'\n\nclass WriteBuffer {\n length = 0\n lines: string[]\n\n constructor(\n private maxChunkRecords: number,\n private flushFn: (lines: string[]) => Promise<void>,\n private scheduleSend: () => void\n ) {\n this.lines = new Array<string>(maxChunkRecords)\n }\n\n add(record: string): void {\n if (this.length === 0) {\n this.scheduleSend()\n }\n this.lines[this.length] = record\n this.length++\n if (this.length >= this.maxChunkRecords) {\n this.flush().catch(_e => {\n // an error is logged in case of failure, avoid UnhandledPromiseRejectionWarning\n })\n }\n }\n flush(): Promise<void> {\n const lines = this.reset()\n if (lines.length > 0) {\n return this.flushFn(lines)\n } else {\n return Promise.resolve()\n }\n }\n reset(): string[] {\n const retVal = this.lines.slice(0, this.length)\n this.length = 0\n return retVal\n }\n}\n\nexport default class WriteApiImpl implements WriteApi {\n private writeBuffer: WriteBuffer\n private closed = false\n private httpPath: string\n private writeOptions: WriteOptions\n private sendOptions: SendOptions\n private _timeoutHandle: any = undefined\n private currentTime: () => string\n private dateToProtocolTimestamp: (d: Date) => string\n\n retryBuffer: RetryBuffer\n retryStrategy: RetryDelayStrategy\n\n constructor(\n private transport: Transport,\n org: string,\n bucket: string,\n precision: WritePrecisionType,\n writeOptions?: Partial<WriteOptions>\n ) {\n this.httpPath = `/api/v2/write?org=${encodeURIComponent(\n org\n )}&bucket=${encodeURIComponent(bucket)}&precision=${precision}`\n this.writeOptions = {\n ...DEFAULT_WriteOptions,\n ...writeOptions,\n }\n this.currentTime = currentTime[precision]\n this.dateToProtocolTimestamp = dateToProtocolTimestamp[precision]\n if (this.writeOptions.defaultTags) {\n this.useDefaultTags(this.writeOptions.defaultTags)\n }\n this.sendOptions = {\n method: 'POST',\n headers: {\n 'content-type': 'text/plain; charset=utf-8',\n ...writeOptions?.headers,\n },\n gzipThreshold: this.writeOptions.gzipThreshold,\n }\n\n const scheduleNextSend = (): void => {\n if (this.writeOptions.flushInterval > 0) {\n this._clearFlushTimeout()\n /* istanbul ignore else manually reviewed, hard to reproduce */\n if (!this.closed) {\n this._timeoutHandle = setTimeout(\n () =>\n this.sendBatch(\n this.writeBuffer.reset(),\n this.writeOptions.maxRetries + 1\n ).catch(_e => {\n // an error is logged in case of failure, avoid UnhandledPromiseRejectionWarning\n }),\n this.writeOptions.flushInterval\n )\n }\n }\n }\n // write buffer\n this.writeBuffer = new WriteBuffer(\n this.writeOptions.batchSize,\n lines => {\n this._clearFlushTimeout()\n return this.sendBatch(lines, this.writeOptions.maxRetries + 1)\n },\n scheduleNextSend\n )\n this.sendBatch = this.sendBatch.bind(this)\n // retry buffer\n this.retryStrategy = createRetryDelayStrategy(this.writeOptions)\n this.retryBuffer = new RetryBuffer(\n this.writeOptions.maxBufferLines,\n this.sendBatch\n )\n }\n\n sendBatch(\n lines: string[],\n attempts: number,\n expires: number = Date.now() + this.writeOptions.maxRetryTime\n ): Promise<void> {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self: WriteApiImpl = this\n const failedAttempts = self.writeOptions.maxRetries + 2 - attempts\n if (!this.closed && lines.length > 0) {\n if (expires <= Date.now()) {\n const error = new Error('Max retry time exceeded.')\n Logger.error(\n `Write to InfluxDB failed (attempt: ${failedAttempts}).`,\n error\n )\n return Promise.reject(error)\n }\n return new Promise<void>((resolve, reject) => {\n let responseStatusCode: number | undefined\n const callbacks = {\n responseStarted(_headers: Headers, statusCode?: number): void {\n responseStatusCode = statusCode\n },\n error(error: Error): void {\n // call the writeFailed listener and check if we can retry\n const onRetry = self.writeOptions.writeFailed.call(\n self,\n error,\n lines,\n failedAttempts\n )\n if (onRetry) {\n onRetry.then(resolve, reject)\n return\n }\n if (\n !self.closed &&\n attempts > 1 &&\n (!(error instanceof HttpError) ||\n (error as HttpError).statusCode >= 429)\n ) {\n Logger.warn(\n `Write to InfluxDB failed (attempt: ${failedAttempts}).`,\n error\n )\n self.retryBuffer.addLines(\n lines,\n attempts - 1,\n self.retryStrategy.nextDelay(error, failedAttempts),\n expires\n )\n reject(error)\n return\n }\n Logger.error(`Write to InfluxDB failed.`, error)\n reject(error)\n },\n complete(): void {\n // older implementations of transport do not report status code\n if (responseStatusCode == 204 || responseStatusCode == undefined) {\n self.writeOptions.writeSuccess.call(self, lines)\n self.retryStrategy.success()\n resolve()\n } else {\n const message = `204 HTTP response status code expected, but ${responseStatusCode} returned`\n const error = new HttpError(\n responseStatusCode,\n message,\n undefined,\n '0'\n )\n error.message = message\n callbacks.error(error)\n }\n },\n }\n this.transport.send(\n this.httpPath,\n lines.join('\\n'),\n this.sendOptions,\n callbacks\n )\n })\n } else {\n return Promise.resolve()\n }\n }\n\n private _clearFlushTimeout(): void {\n if (this._timeoutHandle !== undefined) {\n clearTimeout(this._timeoutHandle)\n this._timeoutHandle = undefined\n }\n }\n\n writeRecord(record: string): void {\n if (this.closed) {\n throw new Error('writeApi: already closed!')\n }\n this.writeBuffer.add(record)\n }\n writeRecords(records: ArrayLike<string>): void {\n if (this.closed) {\n throw new Error('writeApi: already closed!')\n }\n for (let i = 0; i < records.length; i++) {\n this.writeBuffer.add(records[i])\n }\n }\n writePoint(point: Point): void {\n if (this.closed) {\n throw new Error('writeApi: already closed!')\n }\n const line = point.toLineProtocol(this)\n if (line) this.writeBuffer.add(line)\n }\n writePoints(points: ArrayLike<Point>): void {\n if (this.closed) {\n throw new Error('writeApi: already closed!')\n }\n for (let i = 0; i < points.length; i++) {\n const line = points[i].toLineProtocol(this)\n if (line) this.writeBuffer.add(line)\n }\n }\n async flush(withRetryBuffer?: boolean): Promise<void> {\n await this.writeBuffer.flush()\n if (withRetryBuffer) {\n return await this.retryBuffer.flush()\n }\n }\n close(): Promise<void> {\n const retVal = this.writeBuffer.flush().finally(() => {\n const remaining = this.retryBuffer.close()\n if (remaining) {\n Logger.error(\n `Retry buffer closed with ${remaining} items that were not written to InfluxDB!`,\n null\n )\n }\n this.closed = true\n })\n return retVal\n }\n dispose(): number {\n this._clearFlushTimeout()\n this.closed = true\n return this.retryBuffer.close() + this.writeBuffer.length\n }\n\n // PointSettings\n defaultTags: {[key: string]: string} | undefined\n useDefaultTags(tags: {[key: string]: string}): WriteApi {\n this.defaultTags = undefined\n Object.keys(tags).forEach((key: string) => {\n ;(this.defaultTags || (this.defaultTags = {}))[key] = escape.tag(\n tags[key]\n )\n })\n return this\n }\n convertTime(value: string | number | Date | undefined): string | undefined {\n if (value === undefined) {\n return this.currentTime()\n } else if (typeof value === 'string') {\n return value.length > 0 ? value : undefined\n } else if (value instanceof Date) {\n return this.dateToProtocolTimestamp(value)\n } else if (typeof value === 'number') {\n return String(Math.floor(value))\n } else {\n return String(value)\n }\n }\n}\n","import {Transport, SendOptions} from '../../transport'\nimport {ConnectionOptions} from '../../options'\nimport {HttpError} from '../../errors'\nimport completeCommunicationObserver from '../completeCommunicationObserver'\nimport {Logger} from '../../util/logger'\nimport {\n ChunkCombiner,\n CommunicationObserver,\n createTextDecoderCombiner,\n Headers,\n ResponseStartedFn,\n} from '../../results'\n\nfunction getResponseHeaders(response: Response): Headers {\n const headers: Headers = {}\n response.headers.forEach((value: string, key: string) => {\n const previous = headers[key]\n if (previous === undefined) {\n headers[key] = value\n } else if (Array.isArray(previous)) {\n previous.push(value)\n } else {\n headers[key] = [previous, value]\n }\n })\n return headers\n}\n\n/**\n * Transport layer that use browser fetch.\n */\nexport default class FetchTransport implements Transport {\n chunkCombiner: ChunkCombiner = createTextDecoderCombiner()\n private defaultHeaders: {[key: string]: string}\n private url: string\n constructor(private connectionOptions: ConnectionOptions) {\n this.defaultHeaders = {\n 'content-type': 'application/json; charset=utf-8',\n // 'User-Agent': `influxdb-client-js/${CLIENT_LIB_VERSION}`, // user-agent can hardly be customized https://github.com/influxdata/influxdb-client-js/issues/262\n }\n if (this.connectionOptions.token) {\n this.defaultHeaders['Authorization'] =\n 'Token ' + this.connectionOptions.token\n }\n this.url = String(this.connectionOptions.url)\n if (this.url.endsWith('/')) {\n this.url = this.url.substring(0, this.url.length - 1)\n }\n // https://github.com/influxdata/influxdb-client-js/issues/263\n // don't allow /api/v2 suffix to avoid future problems\n if (this.url.endsWith('/api/v2')) {\n this.url = this.url.substring(0, this.url.length - '/api/v2'.length)\n Logger.warn(\n `Please remove '/api/v2' context path from InfluxDB base url, using ${this.url} !`\n )\n }\n }\n send(\n path: string,\n body: string,\n options: SendOptions,\n callbacks?: Partial<CommunicationObserver<Uint8Array>> | undefined\n ): void {\n const observer = completeCommunicationObserver(callbacks)\n let cancelled = false\n let signal = (options as any).signal\n if (callbacks && callbacks.useCancellable) {\n const controller = new AbortController()\n if (!signal) {\n signal = controller.signal\n options = {...(options as object), ...signal} as SendOptions\n }\n callbacks.useCancellable({\n cancel() {\n cancelled = true\n controller.abort()\n },\n isCancelled() {\n return cancelled || signal.aborted\n },\n })\n }\n this.fetch(path, body, options)\n .then(async response => {\n if (callbacks?.responseStarted) {\n observer.responseStarted(\n getResponseHeaders(response),\n response.status\n )\n }\n if (response.status >= 300) {\n return response\n .text()\n .then((text: string) => {\n if (!text) {\n const headerError = response.headers.get('x-influxdb-error')\n if (headerError) {\n text = headerError\n }\n }\n observer.error(\n new HttpError(\n response.status,\n response.statusText,\n text,\n response.headers.get('retry-after'),\n response.headers.get('content-type')\n )\n )\n })\n .catch((e: Error) => {\n Logger.warn('Unable to receive error body', e)\n observer.error(\n new HttpError(\n response.status,\n response.statusText,\n undefined,\n response.headers.get('retry-after'),\n response.headers.get('content-type')\n )\n )\n })\n } else {\n if (response.body) {\n const reader = response.body.getReader()\n let chunk: ReadableStreamDefaultReadResult<Uint8Array>\n do {\n chunk = await reader.read()\n observer.next(chunk.value)\n } while (!chunk.done)\n } else if (response.arrayBuffer) {\n const buffer = await response.arrayBuffer()\n observer.next(new Uint8Array(buffer))\n } else {\n const text = await response.text()\n observer.next(new TextEncoder().encode(text))\n }\n }\n })\n .catch(e => {\n if (!cancelled) {\n observer.error(e)\n }\n })\n .finally(() => observer.complete())\n }\n async request(\n path: string,\n body: any,\n options: SendOptions,\n responseStarted?: ResponseStartedFn\n ): Promise<any> {\n const response = await this.fetch(path, body, options)\n const {status, headers} = response\n const responseContentType = headers.get('content-type') || ''\n if (responseStarted) {\n responseStarted(getResponseHeaders(response), response.status)\n }\n\n if (status >= 300) {\n let data = await response.text()\n if (!data) {\n const headerError = headers.get('x-influxdb-error')\n if (headerError) {\n data = headerError\n }\n }\n throw new HttpError(\n status,\n response.statusText,\n data,\n response.headers.get('retry-after'),\n response.headers.get('content-type')\n )\n }\n const responseType = options.headers?.accept ?? responseContentType\n if (responseType.includes('json')) {\n return await response.json()\n } else if (\n responseType.includes('text') ||\n responseType.startsWith('application/csv')\n ) {\n return await response.text()\n }\n }\n\n private fetch(\n path: string,\n body: any,\n options: SendOptions\n ): Promise<Response> {\n const {method, headers, ...other} = options\n const url = `${this.url}${path}`\n const request: RequestInit = {\n method: method,\n body:\n method === 'GET' || method === 'HEAD'\n ? undefined\n : typeof body === 'string'\n ? body\n : JSON.stringify(body),\n headers: {\n ...this.defaultHeaders,\n ...headers,\n },\n credentials: 'omit' as 'omit',\n // allow to specify custom options, such as signal, in SendOptions\n ...other,\n }\n this.requestDecorator(request, options, url)\n return fetch(url, request)\n }\n\n /**\n * RequestDecorator allows to modify requests before sending.\n *\n * The following example shows a function that adds gzip\n * compression of requests using pako.js.\n *\n * ```ts\n * const client = new InfluxDB({url: 'http://a'})\n * client.transport.requestDecorator = function(request, options) {\n * const body = request.body\n * if (\n * typeof body === 'string' &&\n * options.gzipThreshold !== undefined &&\n * body.length > options.gzipThreshold\n * ) {\n * request.headers['content-encoding'] = 'gzip'\n * request.body = pako.gzip(body)\n * }\n * }\n * ```\n */\n public requestDecorator: (\n request: RequestInit,\n options: SendOptions,\n url: string\n ) => void = function() {}\n}\n","import {CommunicationObserver, Headers} from '../results'\n\nexport default function completeCommunicationObserver(\n callbacks: Partial<CommunicationObserver<any>> = {}\n): Omit<Required<CommunicationObserver<any>>, 'useCancellable'> {\n let state = 0\n const retVal = {\n next: (data: any): void => {\n if (\n state === 0 &&\n callbacks.next &&\n data !== null &&\n data !== undefined\n ) {\n callbacks.next(data)\n }\n },\n error: (error: Error): void => {\n /* istanbul ignore else propagate error at most once */\n if (state === 0) {\n state = 1\n /* istanbul ignore else safety check */\n if (callbacks.error) callbacks.error(error)\n }\n },\n complete: (): void => {\n if (state === 0) {\n state = 2\n /* istanbul ignore else safety check */\n if (callbacks.complete) callbacks.complete()\n }\n },\n responseStarted: (headers: Headers, statusCode?: number): void => {\n if (callbacks.responseStarted)\n callbacks.responseStarted(headers, statusCode)\n },\n }\n return retVal\n}\n","import {Observable} from './observable'\nimport {ParameterizedQuery} from './query'\nimport {\n CommunicationObserver,\n FluxResultObserver,\n FluxTableMetaData,\n} from './results'\n\nexport function defaultRowMapping(\n values: string[],\n tableMeta: FluxTableMetaData\n): Record<string, any> {\n return tableMeta.toObject(values)\n}\n\n/** QueryOptions contains QueryApi configuration options. */\nexport interface QueryOptions {\n /**\n * Specifies the name of the organization executing the query. Takes either the ID or Name interchangeably.\n */\n org: string\n /**\n * Type of the query, default is \"flux\"\n */\n type?: 'flux'\n /**\n * Requests gzip encoded response.\n */\n gzip?: boolean\n /**\n * Specifies the time that should be reported as \"now\" in the query. RFC3339 value must be returned,\n * for example `new Date().toISOString()`.\n */\n now?: () => string\n /**\n * HTTP headers that will be sent with every query request.\n */\n headers?: {[key: string]: string}\n}\n\n/** Wraps values and associated metadata of a query result row */\nexport interface Row {\n values: string[]\n tableMeta: FluxTableMetaData\n}\n\n/**\n * Query InfluxDB 2.0. Provides methods that notify abouts result lines of the executed query.\n * See {@link https://v2.docs.influxdata.com/v2.0/api/#operation/PostQuery }\n */\nexport default interface QueryApi {\n /**\n * Returns a new query API with extra options applied.\n * @param options - query options to use\n * @returns queryApi instance with the supplied options\n */\n with(options: Partial<QueryOptions>): QueryApi\n\n /**\n * Creates a cold observable of the lines returned by the given query.\n *\n * @param query - query\n * @returns observable of CSV result lines\n */\n lines(query: string | ParameterizedQuery): Observable<string>\n\n /**\n * Creates a cold observable of the rows returned by the given query.\n *\n * @param query - query\n * @returns observable of result rows\n */\n rows(query: string | ParameterizedQuery): Observable<Row>\n\n /**\n * Executes the query and receives result lines (including empty and annotation lines)\n * through the supplied consumer. See [annotated-csv](https://v2.docs.influxdata.com/v2.0/reference/syntax/annotated-csv/).\n *\n * @param query - query\n * @param consumer - csv result lines and error consumer\n */\n queryLines(\n query: string | ParameterizedQuery,\n consumer: CommunicationObserver<string>\n ): void\n\n /**\n * Executes the query and receives table metadata and rows through the supplied consumer.\n *\n * @param query - query\n * @param consumer - result rows and error consumer\n */\n queryRows(\n query: string | ParameterizedQuery,\n consumer: FluxResultObserver<string[]>\n ): void\n\n /**\n * QueryRaw executes a query and returns the full response as a string.\n * Use with caution, a possibly huge stream is copied to memory.\n *\n * @param query - query\n * @returns Promise of response text\n */\n queryRaw(query: string | ParameterizedQuery): Promise<string>\n\n /**\n * CollectRows executes the query and collects all the results in the returned Promise.\n * This method is suitable to collect simple results. Use with caution,\n * a possibly huge stream of results is copied to memory.\n *\n * @param query - query\n * @param rowMapper - maps the supplied row to an item that is then collected,\n * undefined return values are not collected. If no rowMapper is supplied,\n * `row => row.tableMeta.toObject(row.values)` is used.\n * @returns Promise of mapped results\n */\n collectRows<T>(\n query: string | ParameterizedQuery,\n rowMapper?: (\n values: string[],\n tableMeta: FluxTableMetaData\n ) => T | undefined\n ): Promise<Array<T>>\n\n /**\n * CollectLines executes the query and collects all result lines in the returned Promise.\n * This method is suitable to collect simple results. Use with caution,\n * a possibly huge stream of lines is copied to memory.\n *\n * @param query - query\n * @returns Promise of returned csv lines\n */\n collectLines(query: string | ParameterizedQuery): Promise<Array<string>>\n}\n","import {\n Observable,\n Observer,\n ObserverComplete,\n ObserverError,\n ObserverNext,\n Subscription,\n symbolObservable,\n} from '../observable'\nimport {Cancellable, CommunicationObserver} from '../results'\n\nexport type QueryExecutor = (consumer: CommunicationObserver<string>) => void\n\ntype Decorator<T> = (observer: Observer<T>) => Observer<string>\n\nclass QuerySubscription implements Subscription {\n private cancellable?: Cancellable\n private isClosed = false\n\n public constructor(observer: Observer<string>, executor: QueryExecutor) {\n try {\n executor({\n next: value => {\n observer.next(value)\n },\n error: e => {\n this.isClosed = true\n observer.error(e)\n },\n complete: () => {\n this.isClosed = true\n observer.complete()\n },\n useCancellable: c => {\n this.cancellable = c\n },\n })\n } catch (e) {\n this.isClosed = true\n observer.error(e)\n }\n }\n\n public get closed(): boolean {\n return this.isClosed\n }\n\n public unsubscribe(): void {\n this.cancellable?.cancel()\n this.isClosed = true\n }\n}\n\nfunction noop(): void {}\n\nfunction completeObserver<T>(observer: Partial<Observer<T>>): Observer<T> {\n const {next, error, complete} = observer\n\n return {\n next: next ? next.bind(observer) : noop,\n error: error ? error.bind(observer) : noop,\n complete: complete ? complete.bind(observer) : noop,\n }\n}\n\nexport default class ObservableQuery<T> implements Observable<T> {\n public constructor(\n private readonly executor: QueryExecutor,\n private readonly decorator: Decorator<T>\n ) {}\n\n public subscribe(\n observerOrNext?: Partial<Observer<T>> | ObserverNext<T>,\n error?: ObserverError,\n complete?: ObserverComplete\n ): Subscription {\n const observer = completeObserver(\n typeof observerOrNext !== 'object' || observerOrNext === null\n ? {next: observerOrNext, error, complete}\n : observerOrNext\n )\n\n return new QuerySubscription(this.decorator(observer), this.executor)\n }\n\n public [symbolObservable](): this {\n return this\n }\n\n // this makes sure we satisfy the interface, while using a possibly polyfilled\n // [symbolObservable] above for the actual implementation\n public declare [Symbol.observable]: () => this\n}\n","import {Observable} from '../observable'\nimport QueryApi, {QueryOptions, Row, defaultRowMapping} from '../QueryApi'\nimport {Transport} from '../transport'\nimport {chunksToLines} from '../results'\nimport {\n CommunicationObserver,\n FluxResultObserver,\n FluxTableMetaData,\n linesToTables,\n} from '../results'\nimport ObservableQuery, {QueryExecutor} from './ObservableQuery'\nimport {ParameterizedQuery} from '../query/flux'\n\nconst DEFAULT_dialect: any = {\n header: true,\n delimiter: ',',\n quoteChar: '\"',\n commentPrefix: '#',\n annotations: ['datatype', 'group', 'default'],\n}\nconst identity = <T>(value: T): T => value\n\nexport class QueryApiImpl implements QueryApi {\n private options: QueryOptions\n constructor(private transport: Transport, org: string | QueryOptions) {\n this.options = typeof org === 'string' ? {org} : org\n }\n\n with(options: Partial<QueryOptions>): QueryApi {\n return new QueryApiImpl(this.transport, {...this.options, ...options})\n }\n\n lines(query: string | ParameterizedQuery): Observable<string> {\n return new ObservableQuery(this.createExecutor(query), identity)\n }\n\n rows(query: string | ParameterizedQuery): Observable<Row> {\n return new ObservableQuery(this.createExecutor(query), observer => {\n return linesToTables({\n next(values, tableMeta) {\n observer.next({values, tableMeta})\n },\n error(e) {\n observer.error(e)\n },\n complete() {\n observer.complete()\n },\n })\n })\n }\n\n queryLines(\n query: string | ParameterizedQuery,\n consumer: CommunicationObserver<string>\n ): void {\n this.createExecutor(query)(consumer)\n }\n\n queryRows(\n query: string | ParameterizedQuery,\n consumer: FluxResultObserver<string[]>\n ): void {\n this.createExecutor(query)(linesToTables(consumer))\n }\n\n collectRows<T>(\n query: string | ParameterizedQuery,\n rowMapper: (\n values: string[],\n tableMeta: FluxTableMetaData\n ) => T | undefined = defaultRowMapping as (\n values: string[],\n tableMeta: FluxTableMetaData\n ) => T | undefined\n ): Promise<Array<T>> {\n const retVal: Array<T> = []\n return new Promise((resolve, reject) => {\n this.queryRows(query, {\n next(values: string[], tableMeta: FluxTableMetaData): void {\n const toAdd = rowMapper.call(this, values, tableMeta)\n if (toAdd !== undefined) {\n retVal.push(toAdd)\n }\n },\n error(error: Error): void {\n reject(error)\n },\n complete(): void {\n resolve(retVal)\n },\n })\n })\n }\n\n collectLines(query: string | ParameterizedQuery): Promise<Array<string>> {\n const retVal: Array<string> = []\n return new Promise((resolve, reject) => {\n this.queryLines(query, {\n next(line: string): void {\n retVal.push(line)\n },\n error(error: Error): void {\n reject(error)\n },\n complete(): void {\n resolve(retVal)\n },\n })\n })\n }\n\n queryRaw(query: string | ParameterizedQuery): Promise<string> {\n const {org, type, gzip, headers} = this.options\n return this.transport.request(\n `/api/v2/query?org=${encodeURIComponent(org)}`,\n JSON.stringify(\n this.decorateRequest({\n query: query.toString(),\n dialect: DEFAULT_dialect,\n type,\n })\n ),\n {\n method: 'POST',\n headers: {\n accept: 'text/csv',\n 'accept-encoding': gzip ? 'gzip' : 'identity',\n 'content-type': 'application/json; encoding=utf-8',\n ...headers,\n },\n }\n )\n }\n\n private createExecutor(query: string | ParameterizedQuery): QueryExecutor {\n const {org, type, gzip, headers} = this.options\n\n return (consumer): void => {\n this.transport.send(\n `/api/v2/query?org=${encodeURIComponent(org)}`,\n JSON.stringify(\n this.decorateRequest({\n query: query.toString(),\n dialect: DEFAULT_dialect,\n type,\n })\n ),\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json; encoding=utf-8',\n 'accept-encoding': gzip ? 'gzip' : 'identity',\n ...headers,\n },\n },\n chunksToLines(consumer, this.transport.chunkCombiner)\n )\n }\n }\n private decorateRequest(request: any): any {\n if (typeof this.options.now === 'function') {\n request.now = this.options.now()\n }\n // https://v2.docs.influxdata.com/v2.0/api/#operation/PostQuery requires type\n request.type = this.options.type ?? 'flux'\n return request\n }\n}\n\nexport default QueryApiImpl\n","import WriteApi from './WriteApi'\nimport {ClientOptions, WriteOptions, WritePrecisionType} from './options'\nimport WriteApiImpl from './impl/WriteApiImpl'\nimport {IllegalArgumentError} from './errors'\nimport {Transport} from './transport'\n// replaced by ./impl/browser/FetchTransport in browser builds\nimport TransportImpl from './impl/node/NodeHttpTransport'\nimport QueryApi, {QueryOptions} from './QueryApi'\nimport QueryApiImpl from './impl/QueryApiImpl'\n\n/**\n * InfluxDB 2.0 entry point that configures communication with InfluxDB server\n * and provide APIs to write and query data.\n */\nexport default class InfluxDB {\n private _options: ClientOptions\n readonly transport: Transport\n\n /**\n * Creates influxdb client options from an options object or url.\n * @param options - client options\n */\n constructor(options: ClientOptions | string) {\n if (typeof options === 'string') {\n this._options = {url: options}\n } else if (options !== null && typeof options === 'object') {\n this._options = options\n } else {\n throw new IllegalArgumentError('No url or configuration specified!')\n }\n const url = this._options.url\n if (typeof url !== 'string')\n throw new IllegalArgumentError('No url specified!')\n if (url.endsWith('/')) this._options.url = url.substring(0, url.length - 1)\n this.transport = this._options.transport ?? new TransportImpl(this._options)\n }\n\n /**\n * Creates WriteApi for the supplied organization and bucket. BEWARE that returned instances must be closed\n * in order to flush the remaining data and close already scheduled retry executions.\n *\n * @remarks\n * Inspect the {@link WriteOptions} to control also advanced options, such retries of failure, retry strategy options, data chunking\n * and flushing windows. See {@link DEFAULT_WriteOptions} to see the defaults.\n *\n * See also {@link https://github.com/influxdata/influxdb-client-js/blob/master/examples/write.js | write.js example},\n * {@link https://github.com/influxdata/influxdb-client-js/blob/master/examples/writeAdvanced.js | writeAdvanced.js example},\n * and {@link https://github.com/influxdata/influxdb-client-js/blob/master/examples/index.html | browser example}.\n *\n * @param org - Specifies the destination organization for writes. Takes either the ID or Name interchangeably.\n * @param bucket - The destination bucket for writes.\n * @param precision - Timestamp precision for line items.\n * @param writeOptions - Custom write options.\n * @returns WriteApi instance\n */\n getWriteApi(\n org: string,\n bucket: string,\n precision: WritePrecisionType = 'ns',\n writeOptions?: Partial<WriteOptions>\n ): WriteApi {\n return new WriteApiImpl(\n this.transport,\n org,\n bucket,\n precision,\n writeOptions ?? this._options.writeOptions\n )\n }\n\n /**\n * Creates QueryApi for the supplied organization .\n *\n * @remarks\n * See also {@link https://github.com/influxdata/influxdb-client-js/blob/master/examples/query.ts | query.ts example},\n * {@link https://github.com/influxdata/influxdb-client-js/blob/master/examples/queryWithParams.ts | queryWithParams.ts example},\n * {@link https://github.com/influxdata/influxdb-client-js/blob/master/examples/rxjs-query.ts | rxjs-query.ts example},\n * and {@link https://github.com/influxdata/influxdb-client-js/blob/master/examples/index.html | browser example},\n *\n * @param org - organization or query options\n * @returns QueryApi instance\n */\n getQueryApi(org: string | QueryOptions): QueryApi {\n return new QueryApiImpl(this.transport, org)\n }\n}\n","import {convertTimeToNanos} from './util/currentTime'\nimport {escape} from './util/escape'\n\n/**\n * Settings that control the way of how a {@link Point} is serialized\n * to a protocol line.\n */\nexport interface PointSettings {\n /** default tags to add to every point */\n defaultTags?: {[key: string]: string}\n /** convertTime serializes Point's timestamp to a line protocol value */\n convertTime?: (\n value: string | number | Date | undefined\n ) => string | undefined\n}\n\n/**\n * Point defines values of a single measurement.\n */\nexport class Point {\n private name: string\n private tags: {[key: string]: string} = {}\n /** escaped field values */\n public fields: {[key: string]: string} = {}\n private time: string | number | Date | undefined\n\n /**\n * Create a new Point with specified a measurement name.\n *\n * @param measurementName - the measurement name\n */\n constructor(measurementName?: string) {\n if (measurementName) this.name = measurementName\n }\n\n /**\n * Sets point's measurement.\n *\n * @param name - measurement name\n * @returns this\n */\n public measurement(name: string): Point {\n this.name = name\n return this\n }\n\n /**\n * Adds a tag. The caller has to ensure that both name and value are not empty\n * and do not end with backslash.\n *\n * @param name - tag name\n * @param value - tag value\n * @returns this\n */\n public tag(name: string, value: string): Point {\n this.tags[name] = value\n return this\n }\n\n /**\n * Adds a boolean field.\n *\n * @param field - field name\n * @param value - field value\n * @returns this\n */\n public booleanField(name: string, value: boolean | any): Point {\n this.fields[name] = value ? 'T' : 'F'\n return this\n }\n\n /**\n * Adds an integer field.\n *\n * @param name - field name\n * @param value - field value\n * @returns this\n */\n public intField(name: string, value: number | any): Point {\n if (typeof value !== 'number') {\n let val: number\n if (isNaN((val = parseInt(String(value))))) {\n throw new Error(\n `Expected integer value for field ${name}, but got '${value}'!`\n )\n }\n value = val\n }\n this.fields[name] = `${Math.floor(value as number)}i`\n return this\n }\n\n /**\n * Adds an unsigned integer field.\n *\n * @param name - field name\n * @param value - field value\n * @returns this\n */\n public uintField(name: string, value: number | any): Point {\n if (typeof value === 'number') {\n if (value < 0 || value > Number.MAX_SAFE_INTEGER) {\n throw new Error(`uint value out of js unsigned integer range: ${value}`)\n }\n this.fields[name] = `${Math.floor(value as number)}u`\n } else {\n const strVal = String(value)\n for (let i = 0; i < strVal.length; i++) {\n const code = strVal.charCodeAt(i)\n if (code < 48 || code > 57) {\n throw new Error(\n `uint value has an unsupported character at pos ${i}: ${value}`\n )\n }\n }\n if (\n strVal.length > 20 ||\n (strVal.length === 20 &&\n strVal.localeCompare('18446744073709551615') > 0)\n ) {\n throw new Error(`uint value out of range: ${strVal}`)\n }\n this.fields[name] = `${strVal}u`\n }\n return this\n }\n\n /**\n * Adds a number field.\n *\n * @param name - field name\n * @param value - field value\n * @returns this\n */\n public floatField(name: string, value: number | any): Point {\n if (typeof value !== 'number') {\n let val: number\n if (isNaN((val = parseFloat(value)))) {\n throw new Error(\n `Expected float value for field ${name}, but got '${value}'!`\n )\n }\n value = val\n }\n this.fields[name] = String(value)\n return this\n }\n\n /**\n * Adds a string field.\n *\n * @param name - field name\n * @param value - field value\n * @returns this\n */\n public stringField(name: string, value: string | any): Point {\n if (value !== null && value !== undefined) {\n if (typeof value !== 'string') value = String(value)\n this.fields[name] = escape.quoted(value)\n }\n return this\n }\n\n /**\n * Sets point timestamp. Timestamp can be specified as a Date (preferred), number, string\n * or an undefined value. An undefined value instructs to assign a local timestamp using\n * the client's clock. An empty string can be used to let the server assign\n * the timestamp. A number value represents time as a count of time units since epoch, the\n * exact time unit then depends on the {@link InfluxDB.getWriteApi | precision} of the API\n * that writes the point.\n *\n * Beware that the current time in nanoseconds can't precisely fit into a JS number,\n * which can hold at most 2^53 integer number. Nanosecond precision numbers are thus supplied as\n * a (base-10) string. An application can also use ES2020 BigInt to represent nanoseconds,\n * BigInt's `toString()` returns the required high-precision string.\n *\n * Note that InfluxDB requires the timestamp to fit into int64 data type.\n *\n * @param value - point time\n * @returns this\n */\n public timestamp(value: Date | number | string | undefined): Point {\n this.time = value\n return this\n }\n\n /**\n * Creates an InfluxDB protocol line out of this instance.\n * @param settings - settings control serialization of a point timestamp and can also add default tags,\n * nanosecond timestamp precision is used when no `settings` or no `settings.convertTime` is supplied.\n * @returns an InfluxDB protocol line out of this instance\n */\n public toLineProtocol(settings?: Partial<PointSettings>): string | undefined {\n if (!this.name) return undefined\n let fieldsLine = ''\n Object.keys(this.fields)\n .sort()\n .forEach(x => {\n if (x) {\n const val = this.fields[x]\n if (fieldsLine.length > 0) fieldsLine += ','\n fieldsLine += `${escape.tag(x)}=${val}`\n }\n })\n if (fieldsLine.length === 0) return undefined // no fields present\n let tagsLine = ''\n const tags =\n settings && settings.defaultTags\n ? {...settings.defaultTags, ...this.tags}\n : this.tags\n Object.keys(tags)\n .sort()\n .forEach(x => {\n if (x) {\n const val = tags[x]\n if (val) {\n tagsLine += ','\n tagsLine += `${escape.tag(x)}=${escape.tag(val)}`\n }\n }\n })\n let time = this.time\n if (settings && settings.convertTime) {\n time = settings.convertTime(time)\n } else {\n time = convertTimeToNanos(time)\n }\n\n return `${escape.measurement(this.name)}${tagsLine} ${fieldsLine}${\n time !== undefined ? ' ' + time : ''\n }`\n }\n\n toString(): string {\n const line = this.toLineProtocol(undefined)\n return line ? line : `invalid point: ${JSON.stringify(this, undefined)}`\n }\n}\n","import {CommunicationObserver} from './CommunicationObserver'\n\n/**\n * StringToLines is a transformation that emmits strings for each CSV\n * line in the supplied source string.\n * @param source - source string\n * @param target - target to emmit CSV lines to\n * @returns communication obrver to accept Uint8Arrays\n */\nexport function stringToLines(\n source: string,\n target: CommunicationObserver<string>\n): void {\n let quoted = false\n let start = 0\n let index = 0\n\n while (index < source.length) {\n const c = source.charCodeAt(index)\n if (c === 10) {\n if (!quoted) {\n /* do not emit CR+LR or LF line ending */\n const end =\n index > 0 && source.charCodeAt(index - 1) === 13 ? index - 1 : index\n // do not emmit more lines if the processing is already finished\n target.next(source.substring(start, end))\n start = index + 1\n }\n } else if (c === 34 /* \" */) {\n quoted = !quoted\n }\n index++\n }\n if (start < index) {\n target.next(source.substring(start, index))\n }\n target.complete()\n}\n"],"names":["createTextDecoderCombiner","decoder","TextDecoder","[object Object]","first","second","retVal","Uint8Array","length","set","chunk","start","end","subarray","toUtf8String","decode","chunksToLines","target","chunkCombiner","chunks","previous","finished","quoted","index","concat","c","next","copy","undefined","bufferReceived","e","this","error","complete","cancellable","useCancellable","self","cancel","isCancelled","LineSplitter","reuse","_reuse","val","reusedValues","Array","line","lastSplitLength","quoteCount","startIndex","values","count","i","getValue","push","substring","replace","FluxTableColumnImpl","newFluxTableColumn","retriableStatusCodes","isStatusCodeRetriable","statusCode","includes","IllegalArgumentError","Error","message","super","name","Object","setPrototypeOf","prototype","HttpError","statusMessage","body","retryAfter","contentType","startsWith","json","JSON","parse","code","setRetryAfter","test","_retryAfter","parseInt","RETRY_CODES","getRetryDelay","retryJitter","Math","round","random","RequestTimedOutError","AbortError","identity","x","typeSerializers","boolean","unsignedLong","long","Number","POSITIVE_INFINITY","NEGATIVE_INFINITY","string","base64Binary","duration","dateTime:RFC3339","FluxTableMetaDataImpl","columns","forEach","col","label","acc","column","defaultValue","dataType","createFluxTableMetaData","linesToTables","consumer","splitter","withReuse","lastMeta","expectMeta","firstColumnIndex","splitLine","size","group","slice","DEFAULT_RetryDelayStrategyOptions","minRetryDelay","maxRetryDelay","exponentialBase","randomRetry","DEFAULT_WriteOptions","batchSize","flushInterval","writeFailed","writeSuccess","maxRetries","maxRetryTime","maxBufferLines","gzipThreshold","createEscaper","characters","replacements","value","from","found","indexOf","escape","measurement","escaper","createQuotedEscaper","tag","lastMillis","Date","now","stepsInMillis","nanos","millis","String","substr","micros","seconds","floor","currentTime","s","ms","us","ns","dateToProtocolTimestamp","d","getTime","convertTimeToNanos","consoleLogger","console","warn","provider","Logger","FLUX_VALUE","Symbol","FluxParameter","fluxValue","sanitizeString","toString","prepareRetVal","charAt","sanitizeFloat","isFinite","dot","sanitizeRegExp","fluxExpression","toFluxValue","toISOString","RegExp","isArray","map","join","symbolObservable","observable","RetryStrategyImpl","options","success","failedAttempts","delay","max","nextDelay","currentDelay","min","RetryBuffer","maxLines","retryLines","lines","retryCount","expires","closed","retryTime","nextRetryTime","origSize","newSize","newFirst","last","toAdd","scheduleRetry","toRetry","_timeoutHandle","setTimeout","removeLines","then","catch","_e","clearTimeout","WriteBuffer","maxChunkRecords","flushFn","scheduleSend","record","flush","reset","Promise","resolve","WriteApiImpl","transport","org","bucket","precision","writeOptions","httpPath","encodeURIComponent","defaultTags","useDefaultTags","sendOptions","method","headers","content-type","writeBuffer","_clearFlushTimeout","sendBatch","bind","retryStrategy","retryBuffer","attempts","reject","responseStatusCode","callbacks","_headers","onRetry","call","addLines","send","add","records","point","toLineProtocol","points","withRetryBuffer","finally","remaining","close","tags","keys","key","getResponseHeaders","response","FetchTransport","connectionOptions","defaultHeaders","token","url","endsWith","path","observer","state","data","responseStarted","completeCommunicationObserver","cancelled","signal","controller","AbortController","abort","aborted","fetch","status","text","headerError","get","statusText","reader","getReader","read","done","arrayBuffer","buffer","TextEncoder","encode","responseContentType","responseType","accept","other","request","stringify","credentials","requestDecorator","defaultRowMapping","tableMeta","toObject","QuerySubscription","executor","isClosed","noop","ObservableQuery","decorator","observerOrNext","completeObserver","DEFAULT_dialect","header","delimiter","quoteChar","commentPrefix","annotations","QueryApiImpl","query","createExecutor","rowMapper","queryRows","queryLines","type","gzip","decorateRequest","dialect","accept-encoding","timeout","_options","TransportImpl","measurementName","fields","isNaN","MAX_SAFE_INTEGER","strVal","charCodeAt","localeCompare","parseFloat","time","settings","fieldsLine","sort","tagsLine","convertTime","canRetry","object","Boolean","strings","parts","partIndex","sanitized","sanitizeDateTime","logger","source","use"],"mappings":"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"}
1
+ {"version":3,"file":"index.browser.js","sources":["../src/results/chunkCombiner.ts","../src/results/chunksToLines.ts","../src/results/LineSplitter.ts","../src/results/FluxTableColumn.ts","../src/errors.ts","../src/results/FluxTableMetaData.ts","../src/results/linesToTables.ts","../src/options.ts","../src/util/escape.ts","../src/util/currentTime.ts","../src/util/logger.ts","../src/query/flux.ts","../src/observable/symbol.ts","../src/impl/retryStrategy.ts","../src/impl/RetryBuffer.ts","../src/impl/WriteApiImpl.ts","../src/impl/browser/FetchTransport.ts","../src/impl/completeCommunicationObserver.ts","../src/QueryApi.ts","../src/impl/ObservableQuery.ts","../src/impl/QueryApiImpl.ts","../src/InfluxDB.ts","../src/Point.ts","../src/results/stringToLines.ts"],"sourcesContent":["/**\n * ChunkCombiner is a simplified platform-neutral manipulation of Uint8arrays\n * that allows to process text data on the fly. The implementation can be optimized\n * for the target platform (node vs browser).\n */\nexport interface ChunkCombiner {\n /**\n * Concatenates first and second chunk.\n * @param first - first chunk\n * @param second - second chunk\n * @returns first + second\n */\n concat(first: Uint8Array, second: Uint8Array): Uint8Array\n\n /**\n * Converts chunk into a string.\n * @param chunk - chunk\n * @param start - start index\n * @param end - end index\n * @returns string representation of chunk slice\n */\n toUtf8String(chunk: Uint8Array, start: number, end: number): string\n\n /**\n * Creates a new chunk from the supplied chunk.\n * @param chunk - chunk to copy\n * @param start - start index\n * @param end - end index\n * @returns a copy of a chunk slice\n */\n copy(chunk: Uint8Array, start: number, end: number): Uint8Array\n}\n\n// TextDecoder is available since node v8.3.0 and in all modern browsers\ndeclare const TextDecoder: any\n\n/**\n * Creates a chunk combiner instance that uses UTF-8\n * TextDecoder to decode Uint8Arrays into strings.\n */\nexport function createTextDecoderCombiner(): ChunkCombiner {\n const decoder = new TextDecoder('utf-8')\n return {\n concat(first: Uint8Array, second: Uint8Array): Uint8Array {\n const retVal = new Uint8Array(first.length + second.length)\n retVal.set(first)\n retVal.set(second, first.length)\n return retVal\n },\n copy(chunk: Uint8Array, start: number, end: number): Uint8Array {\n const retVal = new Uint8Array(end - start)\n retVal.set(chunk.subarray(start, end))\n return retVal\n },\n toUtf8String(chunk: Uint8Array, start: number, end: number): string {\n return decoder.decode(chunk.subarray(start, end))\n },\n }\n}\n","import {ChunkCombiner, createTextDecoderCombiner} from './chunkCombiner'\nimport {CommunicationObserver} from './CommunicationObserver'\nimport {Cancellable} from './Cancellable'\n\n/**\n * ChunksToLines is a transformation that accepts Uint8Array instances\n * and emmits strings representing CSV lines.\n * @param target - target to emmit CSV lines to\n * @param chunks - chunk combiner\n * @returns communication obrver to accept Uint8Arrays\n */\nexport function chunksToLines(\n target: CommunicationObserver<string>,\n chunkCombiner?: ChunkCombiner\n): CommunicationObserver<Uint8Array> {\n const chunks = chunkCombiner ?? createTextDecoderCombiner()\n let previous: Uint8Array | undefined\n let finished = false\n let quoted = false\n\n function bufferReceived(chunk: Uint8Array): void {\n let index: number\n let start = 0\n if (previous) {\n chunk = chunks.concat(previous, chunk)\n index = (previous as Buffer).length\n } else {\n index = 0\n }\n while (index < chunk.length) {\n const c = chunk[index]\n if (c === 10) {\n if (!quoted) {\n /* do not emit CR+LR or LF line ending */\n const end = index > 0 && chunk[index - 1] === 13 ? index - 1 : index\n // do not emmit more lines if the processing is already finished\n if (finished) {\n return\n }\n target.next(chunks.toUtf8String(chunk, start, end))\n start = index + 1\n }\n } else if (c === 34 /* \" */) {\n quoted = !quoted\n }\n index++\n }\n if (start < index) {\n previous = chunks.copy(chunk, start, index)\n } else {\n previous = undefined\n }\n }\n\n return {\n next(chunk: Uint8Array): void {\n if (finished) return\n try {\n bufferReceived(chunk)\n } catch (e) {\n this.error(e)\n }\n },\n error(error: Error): void {\n if (!finished) {\n finished = true\n target.error(error)\n }\n },\n complete(): void {\n if (!finished) {\n if (previous) {\n target.next(chunks.toUtf8String(previous, 0, previous.length))\n }\n finished = true\n target.complete()\n }\n },\n useCancellable(cancellable: Cancellable): void {\n if (target.useCancellable) {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this\n target.useCancellable({\n cancel(): void {\n cancellable.cancel()\n previous = undefined // do not emit more lines\n self.complete()\n },\n isCancelled(): boolean {\n return cancellable.isCancelled()\n },\n })\n }\n },\n }\n}\n","/**\n * Optimized tokenizer of a single CSV line.\n */\nexport class LineSplitter {\n /** returned value when reused */\n reusedValues: string[]\n /** last length of elements in */\n lastSplitLength: number\n private _reuse = false\n\n /**\n * Reuse returned array between consecutive calls.\n */\n get reuse(): boolean {\n return this._reuse\n }\n set reuse(val: boolean) {\n if (val && !this.reusedValues) {\n this.reusedValues = new Array(10)\n }\n this._reuse = val\n }\n\n /**\n * Sets the reuse flag and returns this.\n */\n withReuse(): LineSplitter {\n this.reuse = true\n return this\n }\n\n /**\n * Splits the supplied line to elements that are separated by\n * comma with values possibly escaped within double quotes (\"value\")\n * @param line - line\n * @returns array of splitted parts\n */\n splitLine(line: string | undefined | null): string[] {\n if (line === null || line === undefined) {\n this.lastSplitLength = 0\n return []\n }\n let quoteCount = 0\n let startIndex = 0\n const values = this._reuse ? this.reusedValues : []\n let count = 0\n for (let i = 0; i < line.length; i++) {\n const c = line[i]\n if (c === ',') {\n if (quoteCount % 2 === 0) {\n const val = this.getValue(line, startIndex, i, quoteCount)\n if (this._reuse) {\n values[count++] = val\n } else {\n values.push(val)\n }\n startIndex = i + 1\n quoteCount = 0\n }\n } else if (c === '\"') {\n quoteCount++\n }\n }\n const val = this.getValue(line, startIndex, line.length, quoteCount)\n if (this._reuse) {\n values[count] = val\n this.lastSplitLength = count + 1\n } else {\n values.push(val)\n this.lastSplitLength = values.length\n }\n\n return values\n }\n\n private getValue(\n line: string,\n start: number,\n end: number,\n quoteCount: number\n ): string {\n if (start === line.length) {\n return ''\n } else if (quoteCount === 0) {\n return line.substring(start, end)\n } else if (quoteCount === 2) {\n return line.substring(start + 1, end - 1)\n } else {\n // quoteCount >= 4\n return line.substring(start + 1, end - 1).replace(/\"\"/gi, '\"')\n }\n }\n}\n","/**\n * Type of query result column, see {@link https://v2.docs.influxdata.com/v2.0/reference/syntax/annotated-csv/#valid-data-types }\n */\nexport type ColumnType =\n | 'boolean'\n | 'unsignedLong'\n | 'long'\n | 'double'\n | 'string'\n | 'base64Binary'\n | 'dateTime:RFC3339'\n | 'duration'\n | string\n\n/**\n * Column metadata class of a {@link http://bit.ly/flux-spec#table | flux table} column.\n */\nexport interface FluxTableColumn {\n /**\n * Label (e.g., \"_start\", \"_stop\", \"_time\").\n */\n label: string\n\n /**\n * The data type of column (e.g., \"string\", \"long\", \"dateTime:RFC3339\").\n */\n dataType: ColumnType\n\n /**\n * Boolean flag indicating if the column is a part of the table's group key.\n */\n group: boolean\n\n /**\n * Default value to be used for rows whose string value is an empty string.\n */\n defaultValue: string\n\n /**\n * Index of this column in a row array.\n */\n index: number\n}\n\n/**\n * FluxTableColumn implementation.\n */\nclass FluxTableColumnImpl implements FluxTableColumn {\n label: string\n dataType: ColumnType\n group: boolean\n defaultValue: string\n index: number\n}\n\n/**\n * Creates a new flux table column.\n * @returns column instance\n */\nexport function newFluxTableColumn(): FluxTableColumn {\n return new FluxTableColumnImpl()\n}\n\n/**\n * Creates a flux table column from a partial FluxTableColumn.\n * @param object - source object\n * @returns column instance\n */\nexport function createFluxTableColumn(\n object: Partial<FluxTableColumn>\n): FluxTableColumn {\n const retVal = new FluxTableColumnImpl()\n retVal.label = String(object.label)\n retVal.dataType = object.dataType as ColumnType\n retVal.group = Boolean(object.group)\n retVal.defaultValue = object.defaultValue ?? ''\n retVal.index = object.index ?? 0\n return retVal\n}\n","/**\n * Strategy for calculating retry delays.\n */\nexport interface RetryDelayStrategy {\n /**\n * Returns delay for a next retry\n * @param error - reason for retrying\n * @param failedAttempts - a count of already failed attempts, 1 being the first\n * @returns milliseconds to wait before retrying\n */\n nextDelay(error?: Error, failedAttempts?: number): number\n /** Implementation should reset its state, this is mandatory to call upon success. */\n success(): void\n}\n\n/**\n * Interface for errors to inform that an associated operation can be retried.\n */\nexport interface RetriableDecision {\n /**\n * Informs whether this can be retried.\n */\n canRetry(): boolean\n /**\n * Get the delay in milliseconds to retry the action.\n * @returns 0 to let the implementation decide, miliseconds delay otherwise\n */\n retryAfter(): number\n}\n\nconst retriableStatusCodes = [404, 408, 425, 429, 500, 502, 503, 504]\n/** isStatusCodeRetriable checks whether the supplied HTTP status code is retriable. */\nexport function isStatusCodeRetriable(statusCode: number): boolean {\n return retriableStatusCodes.includes(statusCode)\n}\n\n/** IllegalArgumentError is thrown when illegal argument is supplied. */\nexport class IllegalArgumentError extends Error {\n /* istanbul ignore next */\n constructor(message: string) {\n super(message)\n this.name = 'IllegalArgumentError'\n Object.setPrototypeOf(this, IllegalArgumentError.prototype)\n }\n}\n\n/**\n * A general HTTP error.\n */\nexport class HttpError extends Error implements RetriableDecision {\n private _retryAfter: number\n /** application error code, when available */\n public code: string | undefined\n /** json error response */\n public json: any\n\n /* istanbul ignore next because of super() not being covered*/\n constructor(\n readonly statusCode: number,\n readonly statusMessage: string | undefined,\n readonly body?: string,\n retryAfter?: string | undefined | null,\n readonly contentType?: string | undefined | null,\n message?: string\n ) {\n super()\n Object.setPrototypeOf(this, HttpError.prototype)\n if (message) {\n this.message = message\n } else if (body) {\n if (contentType?.startsWith('application/json')) {\n try {\n this.json = JSON.parse(body)\n this.message = this.json.message\n this.code = this.json.code\n } catch (e) {\n // silently ignore, body string is still available\n }\n }\n if (!this.message) {\n this.message = `${statusCode} ${statusMessage} : ${body}`\n }\n } else {\n this.message = `${statusCode} ${statusMessage}`\n }\n this.name = 'HttpError'\n this.setRetryAfter(retryAfter)\n }\n\n private setRetryAfter(retryAfter?: string | undefined | null): void {\n if (typeof retryAfter === 'string') {\n // try to parse the supplied number as milliseconds\n if (/^[0-9]+$/.test(retryAfter)) {\n this._retryAfter = parseInt(retryAfter)\n } else {\n this._retryAfter = 0\n }\n } else {\n this._retryAfter = 0\n }\n }\n\n canRetry(): boolean {\n return isStatusCodeRetriable(this.statusCode)\n }\n retryAfter(): number {\n return this._retryAfter\n }\n}\n\n//see https://nodejs.org/api/errors.html\nconst RETRY_CODES = [\n 'ECONNRESET',\n 'ENOTFOUND',\n 'ESOCKETTIMEDOUT',\n 'ETIMEDOUT',\n 'ECONNREFUSED',\n 'EHOSTUNREACH',\n 'EPIPE',\n]\n\n/**\n * Tests the error in order to know if an HTTP call can be retried.\n * @param error - error to test\n * @returns true for a retriable error\n */\nexport function canRetryHttpCall(error: any): boolean {\n if (!error) {\n return false\n } else if (typeof (error as any).canRetry === 'function') {\n return !!((error as any).canRetry as () => boolean)()\n } else if ((error as any).code && RETRY_CODES.includes((error as any).code)) {\n return true\n }\n return false\n}\n\n/**\n * Gets retry delay from the supplied error, possibly using random number up to retryJitter.\n */\nexport function getRetryDelay(error?: Error, retryJitter?: number): number {\n if (!error) {\n return 0\n } else {\n let retVal\n if (typeof (error as any).retryAfter === 'function') {\n return ((error as any).retryAfter as () => number)()\n } else {\n retVal = 0\n }\n if (retryJitter && retryJitter > 0) {\n return retVal + Math.round(Math.random() * retryJitter)\n } else {\n return retVal\n }\n }\n}\n\n/** RequestTimedOutError indicates request timeout in the communication with the server */\nexport class RequestTimedOutError extends Error implements RetriableDecision {\n /* istanbul ignore next because of super() not being covered */\n constructor() {\n super()\n Object.setPrototypeOf(this, RequestTimedOutError.prototype)\n this.name = 'RequestTimedOutError'\n this.message = 'Request timed out'\n }\n canRetry(): boolean {\n return true\n }\n retryAfter(): number {\n return 0\n }\n}\n\n/** AbortError indicates that the communication with the server was aborted */\nexport class AbortError extends Error implements RetriableDecision {\n /* istanbul ignore next because of super() not being covered */\n constructor() {\n super()\n this.name = 'AbortError'\n Object.setPrototypeOf(this, AbortError.prototype)\n this.message = 'Response aborted'\n }\n canRetry(): boolean {\n return true\n }\n retryAfter(): number {\n return 0\n }\n}\n","import {FluxTableColumn, ColumnType} from './FluxTableColumn'\nimport {IllegalArgumentError} from '../errors'\n\nconst identity = (x: string): any => x\n/**\n * A dictionary of serializers of particular types returned by a flux query.\n * See {@link https://v2.docs.influxdata.com/v2.0/reference/syntax/annotated-csv/#valid-data-types }\n */\nexport const typeSerializers: Record<ColumnType, (val: string) => any> = {\n boolean: (x: string): any => x === 'true',\n unsignedLong: (x: string): any => (x === '' ? null : +x),\n long: (x: string): any => (x === '' ? null : +x),\n double(x: string): any {\n switch (x) {\n case '':\n return null\n case '+Inf':\n return Number.POSITIVE_INFINITY\n case '-Inf':\n return Number.NEGATIVE_INFINITY\n default:\n return +x\n }\n },\n string: identity,\n base64Binary: identity,\n duration: (x: string): any => (x === '' ? null : x),\n 'dateTime:RFC3339': (x: string): any => (x === '' ? null : x),\n}\n\n/**\n * serializeDateTimeAsDate changes type serializers to return JavaScript Date instances\n * for 'dateTime:RFC3339' query result data type. Empty value is converted to null.\n * @remarks\n * Please note that the result has millisecond precision whereas InfluxDB returns dateTime\n * in nanosecond precision.\n */\nexport function serializeDateTimeAsDate(): void {\n typeSerializers['dateTime:RFC3339'] = (x: string): any =>\n x === '' ? null : new Date(Date.parse(x))\n}\n/**\n * serializeDateTimeAsNumber changes type serializers to return milliseconds since epoch\n * for 'dateTime:RFC3339' query result data type. Empty value is converted to null.\n * @remarks\n * Please note that the result has millisecond precision whereas InfluxDB returns dateTime\n * in nanosecond precision.\n */\nexport function serializeDateTimeAsNumber(): void {\n typeSerializers['dateTime:RFC3339'] = (x: string): any =>\n x === '' ? null : Date.parse(x)\n}\n/**\n * serializeDateTimeAsString changes type serializers to return string values\n * for `dateTime:RFC3339` query result data type. Empty value is converted to null.\n */\nexport function serializeDateTimeAsString(): void {\n typeSerializers['dateTime:RFC3339'] = (x: string): any =>\n x === '' ? null : x\n}\n\n/**\n * Represents metadata of a {@link http://bit.ly/flux-spec#table | flux table}.\n */\nexport interface FluxTableMetaData {\n /**\n * Table columns.\n */\n columns: Array<FluxTableColumn>\n\n /**\n * Gets columns by name\n * @param label - column label\n * @returns table column\n * @throws IllegalArgumentError if column is not found\n **/\n column(label: string): FluxTableColumn\n\n /**\n * Creates an object out of the supplied values with the help of columns .\n * @param values - a row with data for each column\n */\n toObject(values: string[]): {[key: string]: any}\n}\n\n/**\n * FluxTableMetaData Implementation.\n */\nclass FluxTableMetaDataImpl implements FluxTableMetaData {\n columns: Array<FluxTableColumn>\n constructor(columns: FluxTableColumn[]) {\n columns.forEach((col, i) => (col.index = i))\n this.columns = columns\n }\n column(label: string): FluxTableColumn {\n for (let i = 0; i < this.columns.length; i++) {\n const col = this.columns[i]\n if (col.label === label) return col\n }\n throw new IllegalArgumentError(`Column ${label} not found!`)\n }\n toObject(values: string[]): {[key: string]: any} {\n const acc: any = {}\n for (let i = 0; i < this.columns.length && i < values.length; i++) {\n let val = values[i]\n const column = this.columns[i]\n if (val === '' && column.defaultValue) {\n val = column.defaultValue\n }\n acc[column.label] = (typeSerializers[column.dataType] ?? identity)(val)\n }\n return acc\n }\n}\n\n/**\n * Created FluxTableMetaData from the columns supplied.\n * @param columns - columns\n * @returns - instance\n */\nexport function createFluxTableMetaData(\n columns: FluxTableColumn[]\n): FluxTableMetaData {\n return new FluxTableMetaDataImpl(columns)\n}\n","import {CommunicationObserver} from './CommunicationObserver'\nimport {Cancellable} from './Cancellable'\nimport {LineSplitter} from './LineSplitter'\nimport {FluxResultObserver} from './FluxResultObserver'\nimport {\n FluxTableColumn,\n ColumnType,\n newFluxTableColumn,\n} from './FluxTableColumn'\nimport {FluxTableMetaData, createFluxTableMetaData} from './FluxTableMetaData'\n\n/**\n * linesToTables creates a transformationthat accepts (flux) annotated CSV lines\n * and emits rows together with table metadata.\n */\nexport function linesToTables(\n consumer: FluxResultObserver<string[]>\n): CommunicationObserver<string> {\n const splitter = new LineSplitter().withReuse()\n let columns: FluxTableColumn[] | undefined\n let expectMeta = true\n let firstColumnIndex = 0\n let lastMeta: FluxTableMetaData\n return {\n error(error: Error): void {\n consumer.error(error)\n },\n next(line: string): void {\n if (line === '') {\n expectMeta = true\n columns = undefined\n } else {\n const values = splitter.splitLine(line)\n const size = splitter.lastSplitLength\n if (expectMeta) {\n // create columns\n if (!columns) {\n columns = new Array(size)\n for (let i = 0; i < size; i++) {\n columns[i] = newFluxTableColumn()\n }\n }\n if (!values[0].startsWith('#')) {\n // fill in column names\n if (values[0] === '') {\n firstColumnIndex = 1\n columns = columns.slice(1)\n } else {\n firstColumnIndex = 0\n }\n for (let i = firstColumnIndex; i < size; i++) {\n columns[i - firstColumnIndex].label = values[i]\n }\n lastMeta = createFluxTableMetaData(columns)\n expectMeta = false\n } else if (values[0] === '#datatype') {\n for (let i = 1; i < size; i++) {\n columns[i].dataType = values[i] as ColumnType\n }\n } else if (values[0] === '#default') {\n for (let i = 1; i < size; i++) {\n columns[i].defaultValue = values[i]\n }\n } else if (values[0] === '#group') {\n for (let i = 1; i < size; i++) {\n columns[i].group = values[i][0] === 't'\n }\n }\n } else {\n consumer.next(values.slice(firstColumnIndex, size), lastMeta)\n }\n }\n },\n complete(): void {\n consumer.complete()\n },\n useCancellable(cancellable: Cancellable): void {\n if (consumer.useCancellable) consumer.useCancellable(cancellable)\n },\n }\n}\n","import {Transport} from './transport'\nimport WriteApi from './WriteApi'\n\n/**\n * Option for the communication with InfluxDB server.\n */\nexport interface ConnectionOptions {\n /** base URL */\n url: string\n /** authentication token */\n token?: string\n /**\n * socket timeout, 10000 milliseconds by default in node.js\n * @defaultValue 10000\n */\n timeout?: number\n /**\n * TransportOptions supply extra options for the transport layer, they differ between node.js and browser/deno.\n * Node.js transport accepts options specified in {@link https://nodejs.org/api/http.html#http_http_request_options_callback | http.request } or\n * {@link https://nodejs.org/api/https.html#https_https_request_options_callback | https.request }. For example, an `agent` property can be set to\n * {@link https://www.npmjs.com/package/proxy-http-agent | setup HTTP/HTTPS proxy }, {@link https://nodejs.org/api/tls.html#tls_tls_connect_options_callback | rejectUnauthorized }\n * property can disable TLS server certificate verification. Additionally,\n * {@link https://github.com/follow-redirects/follow-redirects | follow-redirects } property can be also specified\n * in order to follow redirects in node.js.\n * {@link https://developer.mozilla.org/en-US/docs/Web/API/fetch | fetch } is used under the hood in browser/deno.\n * For example,\n * {@link https://developer.mozilla.org/en-US/docs/Web/API/fetch | redirect } property can be set to 'error' to abort request if a redirect occurs.\n */\n transportOptions?: {[key: string]: any}\n}\n\n/** default connection options */\nexport const DEFAULT_ConnectionOptions: Partial<ConnectionOptions> = {\n timeout: 10000,\n}\n\n/**\n * Options that configure strategy for retrying failed requests.\n */\nexport interface RetryDelayStrategyOptions {\n /** add `random(retryJitter)` milliseconds delay when retrying HTTP calls */\n retryJitter: number\n /** minimum delay when retrying write (milliseconds) */\n minRetryDelay: number\n /** maximum delay when retrying write (milliseconds) */\n maxRetryDelay: number\n /** base for the exponential retry delay */\n exponentialBase: number\n /**\n * randomRetry indicates whether the next retry delay is deterministic (false) or random (true).\n * The deterministic delay starts with `minRetryDelay * exponentialBase` and it is multiplied\n * by `exponentialBase` until it exceeds `maxRetryDelay`.\n * When random is `true`, the next delay is computed as a random number between next retry attempt (upper)\n * and the lower number in the deterministic sequence. `random(retryJitter)` is added to every returned value.\n */\n randomRetry: boolean\n}\n\n/**\n * Options that configure strategy for retrying failed InfluxDB write operations.\n */\nexport interface WriteRetryOptions extends RetryDelayStrategyOptions {\n /**\n * WriteFailed is called to inform about write errors.\n * @param this - the instance of the API that failed\n * @param error - write error\n * @param lines - failed lines\n * @param attempts - a number of failed attempts to write the lines\n * @returns a Promise to force the API to use it as a result of the flush operation,\n * void/undefined to continue with default retry mechanism\n */\n writeFailed(\n this: WriteApi,\n error: Error,\n lines: Array<string>,\n attempts: number\n ): Promise<void> | void\n\n /**\n * WriteSuccess is informed about successfully written lines.\n * @param this - the instance of the API in use\n * @param lines - written lines\n */\n writeSuccess(this: WriteApi, lines: Array<string>): void\n\n /** max number of retries when write fails */\n maxRetries: number\n /** max time (millis) that can be spent with retries */\n maxRetryTime: number\n /** the maximum size of retry-buffer (in lines) */\n maxBufferLines: number\n}\n\n/**\n * Options used by {@link WriteApi} .\n */\nexport interface WriteOptions extends WriteRetryOptions {\n /** max number of records to send in a batch */\n batchSize: number\n /** delay between data flushes in milliseconds, at most `batch size` records are sent during flush */\n flushInterval: number\n /** default tags, unescaped */\n defaultTags?: Record<string, string>\n /** HTTP headers that will be sent with every write request */\n headers?: {[key: string]: string}\n /** When specified, write bodies larger than the threshold are gzipped */\n gzipThreshold?: number\n}\n\n/** default RetryDelayStrategyOptions */\nexport const DEFAULT_RetryDelayStrategyOptions = {\n retryJitter: 200,\n minRetryDelay: 5000,\n maxRetryDelay: 125000,\n exponentialBase: 5,\n randomRetry: true,\n}\n\n/** default writeOptions */\nexport const DEFAULT_WriteOptions: WriteOptions = {\n batchSize: 1000,\n flushInterval: 60000,\n writeFailed: function() {},\n writeSuccess: function() {},\n maxRetries: 5,\n maxRetryTime: 180_000,\n maxBufferLines: 32_000,\n // a copy of DEFAULT_RetryDelayStrategyOptions, so that DEFAULT_WriteOptions could be tree-shaken\n retryJitter: 200,\n minRetryDelay: 5000,\n maxRetryDelay: 125000,\n exponentialBase: 2,\n gzipThreshold: 1000,\n randomRetry: true,\n}\n\n/**\n * Options used by {@link InfluxDB} .\n */\nexport interface ClientOptions extends ConnectionOptions {\n /** supplies and overrides default writing options */\n writeOptions?: Partial<WriteOptions>\n /** specifies custom transport */\n transport?: Transport\n}\n\n/**\n * Timestamp precision used in write operations.\n * See {@link https://v2.docs.influxdata.com/v2.0/api/#operation/PostWrite }\n */\nexport type WritePrecisionType = 'ns' | 'us' | 'ms' | 's'\n","function createEscaper(\n characters: string,\n replacements: string[]\n): (value: string) => string {\n return function(value: string): string {\n let retVal = ''\n let from = 0\n let i = 0\n while (i < value.length) {\n const found = characters.indexOf(value[i])\n if (found >= 0) {\n retVal += value.substring(from, i)\n retVal += replacements[found]\n from = i + 1\n }\n i++\n }\n if (from == 0) {\n return value\n } else if (from < value.length) {\n retVal += value.substring(from, value.length)\n }\n return retVal\n }\n}\nfunction createQuotedEscaper(\n characters: string,\n replacements: string[]\n): (value: string) => string {\n const escaper = createEscaper(characters, replacements)\n return (value: string): string => '\"' + escaper(value) + '\"'\n}\n\n/**\n * Provides functions escape specific parts in InfluxDB line protocol.\n */\nexport const escape = {\n /**\n * Measurement escapes measurement names.\n */\n measurement: createEscaper(', \\n\\r\\t', ['\\\\,', '\\\\ ', '\\\\n', '\\\\r', '\\\\t']),\n /**\n * Quoted escapes quoted values, such as database names.\n */\n quoted: createQuotedEscaper('\"\\\\', ['\\\\\"', '\\\\\\\\']),\n\n /**\n * TagEscaper escapes tag keys, tag values, and field keys.\n */\n tag: createEscaper(', =\\n\\r\\t', ['\\\\,', '\\\\ ', '\\\\=', '\\\\n', '\\\\r', '\\\\t']),\n}\n","declare let process: any\nconst zeroPadding = '000000000'\nlet useHrTime = false\n\nexport function useProcessHrtime(use: boolean): boolean {\n /* istanbul ignore else */\n if (!process.env.ROLLUP_BROWSER) {\n return (useHrTime = use && process && typeof process.hrtime === 'function')\n } else {\n return false\n }\n}\nuseProcessHrtime(true) // preffer node\n\nlet startHrMillis: number | undefined = undefined\nlet startHrTime: [number, number] | undefined = undefined\nlet lastMillis = Date.now()\nlet stepsInMillis = 0\nfunction nanos(): string {\n if (!process.env.ROLLUP_BROWSER && useHrTime) {\n const hrTime = process.hrtime() as [number, number]\n let millis = Date.now()\n if (!startHrTime) {\n startHrTime = hrTime\n startHrMillis = millis\n } else {\n hrTime[0] = hrTime[0] - startHrTime[0]\n hrTime[1] = hrTime[1] - startHrTime[1]\n // istanbul ignore next \"cannot mock system clock, manually reviewed\"\n if (hrTime[1] < 0) {\n hrTime[0] -= 1\n hrTime[1] += 1000_000_000\n }\n millis =\n (startHrMillis as number) +\n hrTime[0] * 1000 +\n Math.floor(hrTime[1] / 1000_000)\n }\n const nanos = String(hrTime[1] % 1000_000)\n return String(millis) + zeroPadding.substr(0, 6 - nanos.length) + nanos\n } else {\n const millis = Date.now()\n if (millis !== lastMillis) {\n lastMillis = millis\n stepsInMillis = 0\n } else {\n stepsInMillis++\n }\n const nanos = String(stepsInMillis)\n return String(millis) + zeroPadding.substr(0, 6 - nanos.length) + nanos\n }\n}\n\nfunction micros(): string {\n if (!process.env.ROLLUP_BROWSER && useHrTime) {\n const hrTime = process.hrtime() as [number, number]\n const micros = String(Math.trunc(hrTime[1] / 1000) % 1000)\n return (\n String(Date.now()) + zeroPadding.substr(0, 3 - micros.length) + micros\n )\n } else {\n return String(Date.now()) + zeroPadding.substr(0, 3)\n }\n}\nfunction millis(): string {\n return String(Date.now())\n}\nfunction seconds(): string {\n return String(Math.floor(Date.now() / 1000))\n}\n\n/**\n * Exposes functions that creates strings that represent a timestamp that\n * can be used in the line protocol. Micro and nano timestamps are emulated\n * depending on the js platform in use.\n */\nexport const currentTime = {\n s: seconds as () => string,\n ms: millis as () => string,\n us: micros as () => string,\n ns: nanos as () => string,\n seconds: seconds as () => string,\n millis: millis as () => string,\n micros: micros as () => string,\n nanos: nanos as () => string,\n}\n\n/**\n * dateToProtocolTimestamp provides converters for JavaScript Date to InfluxDB Write Protocol Timestamp. Keys are supported precisions.\n */\nexport const dateToProtocolTimestamp = {\n s: (d: Date): string => `${Math.floor(d.getTime() / 1000)}`,\n ms: (d: Date): string => `${d.getTime()}`,\n us: (d: Date): string => `${d.getTime()}000`,\n ns: (d: Date): string => `${d.getTime()}000000`,\n}\n\n/**\n * convertTimeToNanos converts of Point's timestamp to a string\n * @param value - supported timestamp value\n * @returns line protocol value\n */\nexport function convertTimeToNanos(\n value: string | number | Date | undefined\n): string | undefined {\n if (value === undefined) {\n return nanos()\n } else if (typeof value === 'string') {\n return value.length > 0 ? value : undefined\n } else if (value instanceof Date) {\n return `${value.getTime()}000000`\n } else if (typeof value === 'number') {\n return String(Math.floor(value))\n } else {\n return String(value)\n }\n}\n","/**\n * Logging interface.\n */\nexport interface Logger {\n error(message: string, err?: any): void\n warn(message: string, err?: any): void\n}\n\n/**\n * Logger that logs to console.out\n */\nexport const consoleLogger: Logger = {\n error(message, error) {\n // eslint-disable-next-line no-console\n console.error('ERROR: ' + message, error ? error : '')\n },\n warn(message, error) {\n // eslint-disable-next-line no-console\n console.warn('WARN: ' + message, error ? error : '')\n },\n}\nlet provider: Logger = consoleLogger\n\nexport const Logger: Logger = {\n error(message, error) {\n provider.error(message, error)\n },\n warn(message, error) {\n provider.warn(message, error)\n },\n}\n\n/**\n * Sets custom logger.\n * @param logger - logger to use\n * @returns previous logger\n */\nexport function setLogger(logger: Logger): Logger {\n const previous = provider\n provider = logger\n return previous\n}\n","/** Property that offers a function that returns flux-sanitized value of an object. */\nexport const FLUX_VALUE = Symbol('FLUX_VALUE')\n\n/**\n * A flux parameter can print its (sanitized) flux value.\n */\nexport interface FluxParameterLike {\n [FLUX_VALUE](): string\n}\n\n/**\n * Represents a parameterized query.\n */\nexport interface ParameterizedQuery {\n /**\n * Returns flux query with sanitized parameters.\n */\n toString(): string\n}\n\nclass FluxParameter implements FluxParameterLike, ParameterizedQuery {\n constructor(private fluxValue: string) {}\n toString(): string {\n return this.fluxValue\n }\n [FLUX_VALUE](): string {\n return this.fluxValue\n }\n}\n\n/**\n * Checks if the supplied object is FluxParameterLike\n * @param value - any value\n * @returns true if it is\n */\nfunction isFluxParameterLike(value: any): boolean {\n return typeof value === 'object' && typeof value[FLUX_VALUE] === 'function'\n}\n\n/**\n * Escapes content of the supplied string so it can be wrapped into double qoutes\n * to become a [flux string literal](https://docs.influxdata.com/flux/v0.65/language/lexical-elements/#string-literals).\n * @param value - string value\n * @returns sanitized string\n */\nfunction sanitizeString(value: any): string {\n if (value === null || value === undefined) return ''\n value = value.toString()\n let retVal: any = undefined\n let i = 0\n function prepareRetVal(): void {\n if (retVal === undefined) {\n retVal = value.substring(0, i)\n }\n }\n for (; i < value.length; i++) {\n const c = value.charAt(i)\n switch (c) {\n case '\\r':\n prepareRetVal()\n retVal += '\\\\r'\n break\n case '\\n':\n prepareRetVal()\n retVal += '\\\\n'\n break\n case '\\t':\n prepareRetVal()\n retVal += '\\\\t'\n break\n case '\"':\n case '\\\\':\n prepareRetVal()\n retVal = retVal + '\\\\' + c\n break\n case '$':\n // escape ${\n if (i + 1 < value.length && value.charAt(i + 1) === '{') {\n prepareRetVal()\n i++\n retVal += '\\\\${'\n break\n }\n // append $\n if (retVal != undefined) {\n retVal += c\n }\n break\n default:\n if (retVal != undefined) {\n retVal += c\n }\n }\n }\n if (retVal !== undefined) {\n return retVal\n }\n return value\n}\n\n/**\n * Creates a flux string literal.\n */\nexport function fluxString(value: any): FluxParameterLike {\n return new FluxParameter(`\"${sanitizeString(value)}\"`)\n}\n\n/**\n * Sanitizes float value to avoid injections.\n * @param value - InfluxDB float literal\n * @returns sanitized float value\n * @throws Error if the the value cannot be sanitized\n */\nexport function sanitizeFloat(value: any): string {\n if (typeof value === 'number') {\n if (!isFinite(value)) {\n throw new Error(`not a flux float: ${value}`)\n }\n return value.toString()\n }\n const val = String(value)\n let dot = false\n for (const c of val) {\n if (c === '.') {\n if (dot) throw new Error(`not a flux float: ${val}`)\n dot = !dot\n continue\n }\n if (c !== '.' && c !== '-' && (c < '0' || c > '9'))\n throw new Error(`not a flux float: ${val}`)\n }\n return val\n}\n/**\n * Creates a flux float literal.\n */\nexport function fluxFloat(value: any): FluxParameterLike {\n return new FluxParameter(sanitizeFloat(value))\n}\n\n/**\n * Creates a flux integer literal.\n */\nexport function fluxInteger(value: any): FluxParameterLike {\n const val = sanitizeFloat(value)\n for (const c of val) {\n if (c === '.') {\n throw new Error(`not a flux integer: ${val}`)\n }\n }\n return new FluxParameter(val)\n}\n\nfunction sanitizeDateTime(value: any): string {\n return `time(v: \"${sanitizeString(value)}\")`\n}\n\n/**\n * Creates flux date-time literal.\n */\nexport function fluxDateTime(value: any): FluxParameterLike {\n return new FluxParameter(sanitizeDateTime(value))\n}\n\n/**\n * Creates flux date-time literal.\n */\nexport function fluxDuration(value: any): FluxParameterLike {\n return new FluxParameter(`duration(v: \"${sanitizeString(value)}\")`)\n}\n\nfunction sanitizeRegExp(value: any): string {\n return `regexp.compile(v: \"${sanitizeString(value)}\")`\n}\n\n/**\n * Creates flux regexp literal.\n */\nexport function fluxRegExp(value: any): FluxParameterLike {\n // let the server decide if it can be parsed\n return new FluxParameter(sanitizeRegExp(value))\n}\n\n/**\n * Creates flux boolean literal.\n */\nexport function fluxBool(value: any): FluxParameterLike {\n if (value === 'true' || value === 'false') {\n return new FluxParameter(value)\n }\n return new FluxParameter((!!value).toString())\n}\n\n/**\n * Assumes that the supplied value is flux expression or literal that does not need sanitizing.\n *\n * @param value - any value\n * @returns the supplied value as-is\n */\nexport function fluxExpression(value: any): FluxParameterLike {\n return new FluxParameter(String(value))\n}\n\n/**\n * Escapes content of the supplied parameter so that it can be safely embedded into flux query.\n * @param value - parameter value\n * @returns sanitized flux value or an empty string if it cannot be converted\n */\nexport function toFluxValue(value: any): string {\n if (value === undefined) {\n return ''\n } else if (value === null) {\n return 'null'\n } else if (typeof value === 'boolean') {\n return value.toString()\n } else if (typeof value === 'string') {\n return `\"${sanitizeString(value)}\"`\n } else if (typeof value === 'number') {\n return sanitizeFloat(value)\n } else if (typeof value === 'object') {\n if (typeof value[FLUX_VALUE] === 'function') {\n return value[FLUX_VALUE]()\n } else if (value instanceof Date) {\n return value.toISOString()\n } else if (value instanceof RegExp) {\n return sanitizeRegExp(value)\n } else if (Array.isArray(value)) {\n return `[${value.map(toFluxValue).join(',')}]`\n }\n }\n // use toString value for unrecognized object, bigint, symbol\n return toFluxValue(value.toString())\n}\n\n/**\n * Flux is a tagged template that sanitizes supplied parameters\n * to avoid injection attacks in flux.\n */\nexport function flux(\n strings: TemplateStringsArray,\n ...values: any\n): ParameterizedQuery {\n if (strings.length == 1 && values.length === 0) {\n return fluxExpression(strings[0]) // the simplest case\n }\n const parts = new Array<string>(strings.length + values.length)\n let partIndex = 0\n for (let i = 0; i < strings.length; i++) {\n const text = strings[i]\n parts[partIndex++] = text\n if (i < values.length) {\n const val = values[i]\n let sanitized: string\n if (\n text.endsWith('\"') &&\n i + 1 < strings.length &&\n strings[i + 1].startsWith('\"')\n ) {\n // parameter is wrapped into flux double quotes\n sanitized = sanitizeString(val)\n } else {\n sanitized = toFluxValue(val)\n if (sanitized === '') {\n // do not allow to insert empty strings, unless it is FluxParameterLike\n if (!isFluxParameterLike(val)) {\n throw new Error(\n `Unsupported parameter literal '${val}' at index: ${i}, type: ${typeof val}`\n )\n }\n }\n }\n parts[partIndex++] = sanitized\n } else if (i < strings.length - 1) {\n throw new Error('Too few parameters supplied!')\n }\n }\n // return flux expression so that flux can be embedded into another flux as-is\n return fluxExpression(parts.join(''))\n}\n","/* Observable interop typing. Taken from https://github.com/ReactiveX/rxjs */\n\n/* Note: This will add Symbol.observable globally for all TypeScript users */\ndeclare global {\n interface SymbolConstructor {\n readonly observable: symbol\n }\n}\n\n/** Symbol.observable or a string \"\\@\\@observable\". Used for interop */\nexport const symbolObservable = (():\n | typeof Symbol.observable\n | '@@observable' =>\n (typeof Symbol === 'function' && Symbol.observable) || '@@observable')()\n","import {getRetryDelay, RetryDelayStrategy} from '../errors'\nimport {\n RetryDelayStrategyOptions,\n DEFAULT_RetryDelayStrategyOptions,\n} from '../options'\n\n/**\n * Applies a variant of exponential backoff with initial and max delay and a random\n * jitter delay. It also respects `retry delay` when specified together with an error.\n */\nexport class RetryStrategyImpl implements RetryDelayStrategy {\n options: RetryDelayStrategyOptions\n currentDelay: number | undefined\n\n constructor(options?: Partial<RetryDelayStrategyOptions>) {\n this.options = {...DEFAULT_RetryDelayStrategyOptions, ...options}\n this.success()\n }\n\n nextDelay(error?: Error, failedAttempts?: number): number {\n const delay = getRetryDelay(error)\n if (delay && delay > 0) {\n return delay + Math.round(Math.random() * this.options.retryJitter)\n } else {\n if (failedAttempts && failedAttempts > 0) {\n // compute delay\n if (this.options.randomRetry) {\n // random delay between deterministic delays\n let delay = Math.max(this.options.minRetryDelay, 1)\n let nextDelay = delay * this.options.exponentialBase\n for (let i = 1; i < failedAttempts; i++) {\n delay = nextDelay\n nextDelay = nextDelay * this.options.exponentialBase\n if (nextDelay >= this.options.maxRetryDelay) {\n nextDelay = this.options.maxRetryDelay\n break\n }\n }\n return (\n delay +\n Math.round(\n Math.random() * (nextDelay - delay) +\n Math.random() * this.options.retryJitter\n )\n )\n }\n // deterministric delay otherwise\n let delay = Math.max(this.options.minRetryDelay, 1)\n for (let i = 1; i < failedAttempts; i++) {\n delay = delay * this.options.exponentialBase\n if (delay >= this.options.maxRetryDelay) {\n delay = this.options.maxRetryDelay\n break\n }\n }\n return delay + Math.round(Math.random() * this.options.retryJitter)\n } else if (this.currentDelay) {\n this.currentDelay = Math.min(\n Math.max(this.currentDelay * this.options.exponentialBase, 1) +\n Math.round(Math.random() * this.options.retryJitter),\n this.options.maxRetryDelay\n )\n } else {\n this.currentDelay =\n this.options.minRetryDelay +\n Math.round(Math.random() * this.options.retryJitter)\n }\n return this.currentDelay\n }\n }\n success(): void {\n this.currentDelay = undefined\n }\n}\n\n/**\n * Creates a new instance of retry strategy.\n * @param options - retry options\n * @returns retry strategy implementation\n */\nexport function createRetryDelayStrategy(\n options?: Partial<RetryDelayStrategyOptions>\n): RetryDelayStrategy {\n return new RetryStrategyImpl(options)\n}\n","import {Logger} from '../util/logger'\n\n/* interval between successful retries */\nconst RETRY_INTERVAL = 1\n\ninterface RetryItem {\n lines: string[]\n retryCount: number\n expires: number\n next?: RetryItem\n}\n\n/**\n * Retries lines up to a limit of max buffer size.\n */\nexport default class RetryBuffer {\n first?: RetryItem\n last?: RetryItem\n size = 0\n nextRetryTime = 0\n closed = false\n private _timeoutHandle: any = undefined\n\n constructor(\n private maxLines: number,\n private retryLines: (\n lines: string[],\n retryCountdown: number,\n started: number\n ) => Promise<void>\n ) {}\n\n addLines(\n lines: string[],\n retryCount: number,\n delay: number,\n expires: number\n ): void {\n if (this.closed) return\n if (!lines.length) return\n let retryTime = Date.now() + delay\n if (expires < retryTime) {\n delay = expires - Date.now()\n retryTime = expires\n }\n if (retryTime > this.nextRetryTime) this.nextRetryTime = retryTime\n // ensure at most maxLines are in the Buffer\n if (this.first && this.size + lines.length > this.maxLines) {\n const origSize = this.size\n const newSize = origSize * 0.7 // reduce to 70 %\n do {\n const newFirst = this.first.next as RetryItem\n this.size -= this.first.lines.length\n this.first.next = undefined\n this.first = newFirst\n if (!this.first) {\n this.last = undefined\n }\n } while (this.first && this.size + lines.length > newSize)\n Logger.error(\n `RetryBuffer: ${origSize -\n this\n .size} oldest lines removed to keep buffer size under the limit of ${\n this.maxLines\n } lines`\n )\n }\n const toAdd: RetryItem = {\n lines,\n retryCount,\n expires,\n }\n if (this.last) {\n this.last.next = toAdd\n this.last = toAdd\n } else {\n this.first = toAdd\n this.last = toAdd\n this.scheduleRetry(delay)\n }\n this.size += lines.length\n }\n\n removeLines(): RetryItem | undefined {\n if (this.first) {\n const toRetry = this.first\n this.first = this.first.next\n toRetry.next = undefined\n this.size -= toRetry.lines.length\n if (!this.first) this.last = undefined\n return toRetry\n }\n return undefined\n }\n\n scheduleRetry(delay: number): void {\n this._timeoutHandle = setTimeout(() => {\n const toRetry = this.removeLines()\n if (toRetry) {\n this.retryLines(toRetry.lines, toRetry.retryCount, toRetry.expires)\n .then(() => {\n // continue with successfull retry\n this.scheduleRetry(RETRY_INTERVAL)\n })\n .catch(_e => {\n // already logged\n this.scheduleRetry(this.nextRetryTime - Date.now())\n })\n } else {\n this._timeoutHandle = undefined\n }\n }, Math.max(delay, 0))\n }\n\n async flush(): Promise<void> {\n let toRetry\n while ((toRetry = this.removeLines())) {\n await this.retryLines(toRetry.lines, toRetry.retryCount, toRetry.expires)\n }\n }\n\n close(): number {\n if (this._timeoutHandle) {\n clearTimeout(this._timeoutHandle)\n this._timeoutHandle = undefined\n }\n this.closed = true\n return this.size\n }\n}\n","import WriteApi from '../WriteApi'\nimport {\n DEFAULT_WriteOptions,\n WriteOptions,\n WritePrecisionType,\n} from '../options'\nimport {Transport, SendOptions} from '../transport'\nimport {Headers} from '../results'\nimport {Logger} from '../util/logger'\nimport {HttpError, RetryDelayStrategy} from '../errors'\nimport {Point} from '../Point'\nimport {escape} from '../util/escape'\nimport {currentTime, dateToProtocolTimestamp} from '../util/currentTime'\nimport {createRetryDelayStrategy} from './retryStrategy'\nimport RetryBuffer from './RetryBuffer'\n\nclass WriteBuffer {\n length = 0\n lines: string[]\n\n constructor(\n private maxChunkRecords: number,\n private flushFn: (lines: string[]) => Promise<void>,\n private scheduleSend: () => void\n ) {\n this.lines = new Array<string>(maxChunkRecords)\n }\n\n add(record: string): void {\n if (this.length === 0) {\n this.scheduleSend()\n }\n this.lines[this.length] = record\n this.length++\n if (this.length >= this.maxChunkRecords) {\n this.flush().catch(_e => {\n // an error is logged in case of failure, avoid UnhandledPromiseRejectionWarning\n })\n }\n }\n flush(): Promise<void> {\n const lines = this.reset()\n if (lines.length > 0) {\n return this.flushFn(lines)\n } else {\n return Promise.resolve()\n }\n }\n reset(): string[] {\n const retVal = this.lines.slice(0, this.length)\n this.length = 0\n return retVal\n }\n}\n\nexport default class WriteApiImpl implements WriteApi {\n private writeBuffer: WriteBuffer\n private closed = false\n private httpPath: string\n private writeOptions: WriteOptions\n private sendOptions: SendOptions\n private _timeoutHandle: any = undefined\n private currentTime: () => string\n private dateToProtocolTimestamp: (d: Date) => string\n\n retryBuffer: RetryBuffer\n retryStrategy: RetryDelayStrategy\n\n constructor(\n private transport: Transport,\n org: string,\n bucket: string,\n precision: WritePrecisionType,\n writeOptions?: Partial<WriteOptions>\n ) {\n this.httpPath = `/api/v2/write?org=${encodeURIComponent(\n org\n )}&bucket=${encodeURIComponent(bucket)}&precision=${precision}`\n this.writeOptions = {\n ...DEFAULT_WriteOptions,\n ...writeOptions,\n }\n this.currentTime = currentTime[precision]\n this.dateToProtocolTimestamp = dateToProtocolTimestamp[precision]\n if (this.writeOptions.defaultTags) {\n this.useDefaultTags(this.writeOptions.defaultTags)\n }\n this.sendOptions = {\n method: 'POST',\n headers: {\n 'content-type': 'text/plain; charset=utf-8',\n ...writeOptions?.headers,\n },\n gzipThreshold: this.writeOptions.gzipThreshold,\n }\n\n const scheduleNextSend = (): void => {\n if (this.writeOptions.flushInterval > 0) {\n this._clearFlushTimeout()\n /* istanbul ignore else manually reviewed, hard to reproduce */\n if (!this.closed) {\n this._timeoutHandle = setTimeout(\n () =>\n this.sendBatch(\n this.writeBuffer.reset(),\n this.writeOptions.maxRetries + 1\n ).catch(_e => {\n // an error is logged in case of failure, avoid UnhandledPromiseRejectionWarning\n }),\n this.writeOptions.flushInterval\n )\n }\n }\n }\n // write buffer\n this.writeBuffer = new WriteBuffer(\n this.writeOptions.batchSize,\n lines => {\n this._clearFlushTimeout()\n return this.sendBatch(lines, this.writeOptions.maxRetries + 1)\n },\n scheduleNextSend\n )\n this.sendBatch = this.sendBatch.bind(this)\n // retry buffer\n this.retryStrategy = createRetryDelayStrategy(this.writeOptions)\n this.retryBuffer = new RetryBuffer(\n this.writeOptions.maxBufferLines,\n this.sendBatch\n )\n }\n\n sendBatch(\n lines: string[],\n attempts: number,\n expires: number = Date.now() + this.writeOptions.maxRetryTime\n ): Promise<void> {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self: WriteApiImpl = this\n const failedAttempts = self.writeOptions.maxRetries + 2 - attempts\n if (!this.closed && lines.length > 0) {\n if (expires <= Date.now()) {\n const error = new Error('Max retry time exceeded.')\n Logger.error(\n `Write to InfluxDB failed (attempt: ${failedAttempts}).`,\n error\n )\n return Promise.reject(error)\n }\n return new Promise<void>((resolve, reject) => {\n let responseStatusCode: number | undefined\n const callbacks = {\n responseStarted(_headers: Headers, statusCode?: number): void {\n responseStatusCode = statusCode\n },\n error(error: Error): void {\n // call the writeFailed listener and check if we can retry\n const onRetry = self.writeOptions.writeFailed.call(\n self,\n error,\n lines,\n failedAttempts\n )\n if (onRetry) {\n onRetry.then(resolve, reject)\n return\n }\n if (\n !self.closed &&\n attempts > 1 &&\n (!(error instanceof HttpError) ||\n (error as HttpError).statusCode >= 429)\n ) {\n Logger.warn(\n `Write to InfluxDB failed (attempt: ${failedAttempts}).`,\n error\n )\n self.retryBuffer.addLines(\n lines,\n attempts - 1,\n self.retryStrategy.nextDelay(error, failedAttempts),\n expires\n )\n reject(error)\n return\n }\n Logger.error(`Write to InfluxDB failed.`, error)\n reject(error)\n },\n complete(): void {\n // older implementations of transport do not report status code\n if (responseStatusCode == 204 || responseStatusCode == undefined) {\n self.writeOptions.writeSuccess.call(self, lines)\n self.retryStrategy.success()\n resolve()\n } else {\n const message = `204 HTTP response status code expected, but ${responseStatusCode} returned`\n const error = new HttpError(\n responseStatusCode,\n message,\n undefined,\n '0'\n )\n error.message = message\n callbacks.error(error)\n }\n },\n }\n this.transport.send(\n this.httpPath,\n lines.join('\\n'),\n this.sendOptions,\n callbacks\n )\n })\n } else {\n return Promise.resolve()\n }\n }\n\n private _clearFlushTimeout(): void {\n if (this._timeoutHandle !== undefined) {\n clearTimeout(this._timeoutHandle)\n this._timeoutHandle = undefined\n }\n }\n\n writeRecord(record: string): void {\n if (this.closed) {\n throw new Error('writeApi: already closed!')\n }\n this.writeBuffer.add(record)\n }\n writeRecords(records: ArrayLike<string>): void {\n if (this.closed) {\n throw new Error('writeApi: already closed!')\n }\n for (let i = 0; i < records.length; i++) {\n this.writeBuffer.add(records[i])\n }\n }\n writePoint(point: Point): void {\n if (this.closed) {\n throw new Error('writeApi: already closed!')\n }\n const line = point.toLineProtocol(this)\n if (line) this.writeBuffer.add(line)\n }\n writePoints(points: ArrayLike<Point>): void {\n if (this.closed) {\n throw new Error('writeApi: already closed!')\n }\n for (let i = 0; i < points.length; i++) {\n const line = points[i].toLineProtocol(this)\n if (line) this.writeBuffer.add(line)\n }\n }\n async flush(withRetryBuffer?: boolean): Promise<void> {\n await this.writeBuffer.flush()\n if (withRetryBuffer) {\n return await this.retryBuffer.flush()\n }\n }\n close(): Promise<void> {\n const retVal = this.writeBuffer.flush().finally(() => {\n const remaining = this.retryBuffer.close()\n if (remaining) {\n Logger.error(\n `Retry buffer closed with ${remaining} items that were not written to InfluxDB!`,\n null\n )\n }\n this.closed = true\n })\n return retVal\n }\n dispose(): number {\n this._clearFlushTimeout()\n this.closed = true\n return this.retryBuffer.close() + this.writeBuffer.length\n }\n\n // PointSettings\n defaultTags: {[key: string]: string} | undefined\n useDefaultTags(tags: {[key: string]: string}): WriteApi {\n this.defaultTags = undefined\n Object.keys(tags).forEach((key: string) => {\n ;(this.defaultTags || (this.defaultTags = {}))[key] = escape.tag(\n tags[key]\n )\n })\n return this\n }\n convertTime(value: string | number | Date | undefined): string | undefined {\n if (value === undefined) {\n return this.currentTime()\n } else if (typeof value === 'string') {\n return value.length > 0 ? value : undefined\n } else if (value instanceof Date) {\n return this.dateToProtocolTimestamp(value)\n } else if (typeof value === 'number') {\n return String(Math.floor(value))\n } else {\n return String(value)\n }\n }\n}\n","import {Transport, SendOptions} from '../../transport'\nimport {ConnectionOptions} from '../../options'\nimport {HttpError} from '../../errors'\nimport completeCommunicationObserver from '../completeCommunicationObserver'\nimport {Logger} from '../../util/logger'\nimport {\n ChunkCombiner,\n CommunicationObserver,\n createTextDecoderCombiner,\n Headers,\n ResponseStartedFn,\n} from '../../results'\n\nfunction getResponseHeaders(response: Response): Headers {\n const headers: Headers = {}\n response.headers.forEach((value: string, key: string) => {\n const previous = headers[key]\n if (previous === undefined) {\n headers[key] = value\n } else if (Array.isArray(previous)) {\n previous.push(value)\n } else {\n headers[key] = [previous, value]\n }\n })\n return headers\n}\n\n/**\n * Transport layer that use browser fetch.\n */\nexport default class FetchTransport implements Transport {\n chunkCombiner: ChunkCombiner = createTextDecoderCombiner()\n private defaultHeaders: {[key: string]: string}\n private url: string\n constructor(private connectionOptions: ConnectionOptions) {\n this.defaultHeaders = {\n 'content-type': 'application/json; charset=utf-8',\n // 'User-Agent': `influxdb-client-js/${CLIENT_LIB_VERSION}`, // user-agent can hardly be customized https://github.com/influxdata/influxdb-client-js/issues/262\n }\n if (this.connectionOptions.token) {\n this.defaultHeaders['Authorization'] =\n 'Token ' + this.connectionOptions.token\n }\n this.url = String(this.connectionOptions.url)\n if (this.url.endsWith('/')) {\n this.url = this.url.substring(0, this.url.length - 1)\n }\n // https://github.com/influxdata/influxdb-client-js/issues/263\n // don't allow /api/v2 suffix to avoid future problems\n if (this.url.endsWith('/api/v2')) {\n this.url = this.url.substring(0, this.url.length - '/api/v2'.length)\n Logger.warn(\n `Please remove '/api/v2' context path from InfluxDB base url, using ${this.url} !`\n )\n }\n }\n send(\n path: string,\n body: string,\n options: SendOptions,\n callbacks?: Partial<CommunicationObserver<Uint8Array>> | undefined\n ): void {\n const observer = completeCommunicationObserver(callbacks)\n let cancelled = false\n let signal = (options as any).signal\n if (callbacks && callbacks.useCancellable) {\n const controller = new AbortController()\n if (!signal) {\n signal = controller.signal\n options = {...(options as object), ...signal} as SendOptions\n }\n callbacks.useCancellable({\n cancel() {\n cancelled = true\n controller.abort()\n },\n isCancelled() {\n return cancelled || signal.aborted\n },\n })\n }\n this.fetch(path, body, options)\n .then(async response => {\n if (callbacks?.responseStarted) {\n observer.responseStarted(\n getResponseHeaders(response),\n response.status\n )\n }\n if (response.status >= 300) {\n return response\n .text()\n .then((text: string) => {\n if (!text) {\n const headerError = response.headers.get('x-influxdb-error')\n if (headerError) {\n text = headerError\n }\n }\n observer.error(\n new HttpError(\n response.status,\n response.statusText,\n text,\n response.headers.get('retry-after'),\n response.headers.get('content-type')\n )\n )\n })\n .catch((e: Error) => {\n Logger.warn('Unable to receive error body', e)\n observer.error(\n new HttpError(\n response.status,\n response.statusText,\n undefined,\n response.headers.get('retry-after'),\n response.headers.get('content-type')\n )\n )\n })\n } else {\n if (response.body) {\n const reader = response.body.getReader()\n let chunk: ReadableStreamDefaultReadResult<Uint8Array>\n do {\n chunk = await reader.read()\n observer.next(chunk.value)\n } while (!chunk.done)\n } else if (response.arrayBuffer) {\n const buffer = await response.arrayBuffer()\n observer.next(new Uint8Array(buffer))\n } else {\n const text = await response.text()\n observer.next(new TextEncoder().encode(text))\n }\n }\n })\n .catch(e => {\n if (!cancelled) {\n observer.error(e)\n }\n })\n .finally(() => observer.complete())\n }\n async request(\n path: string,\n body: any,\n options: SendOptions,\n responseStarted?: ResponseStartedFn\n ): Promise<any> {\n const response = await this.fetch(path, body, options)\n const {status, headers} = response\n const responseContentType = headers.get('content-type') || ''\n if (responseStarted) {\n responseStarted(getResponseHeaders(response), response.status)\n }\n\n if (status >= 300) {\n let data = await response.text()\n if (!data) {\n const headerError = headers.get('x-influxdb-error')\n if (headerError) {\n data = headerError\n }\n }\n throw new HttpError(\n status,\n response.statusText,\n data,\n response.headers.get('retry-after'),\n response.headers.get('content-type')\n )\n }\n const responseType = options.headers?.accept ?? responseContentType\n if (responseType.includes('json')) {\n return await response.json()\n } else if (\n responseType.includes('text') ||\n responseType.startsWith('application/csv')\n ) {\n return await response.text()\n }\n }\n\n private fetch(\n path: string,\n body: any,\n options: SendOptions\n ): Promise<Response> {\n const {method, headers, ...other} = options\n const url = `${this.url}${path}`\n const request: RequestInit = {\n method: method,\n body:\n method === 'GET' || method === 'HEAD'\n ? undefined\n : typeof body === 'string'\n ? body\n : JSON.stringify(body),\n headers: {\n ...this.defaultHeaders,\n ...headers,\n },\n credentials: 'omit' as 'omit',\n // allow to specify custom options, such as signal, in SendOptions\n ...other,\n }\n this.requestDecorator(request, options, url)\n return fetch(url, request)\n }\n\n /**\n * RequestDecorator allows to modify requests before sending.\n *\n * The following example shows a function that adds gzip\n * compression of requests using pako.js.\n *\n * ```ts\n * const client = new InfluxDB({url: 'http://a'})\n * client.transport.requestDecorator = function(request, options) {\n * const body = request.body\n * if (\n * typeof body === 'string' &&\n * options.gzipThreshold !== undefined &&\n * body.length > options.gzipThreshold\n * ) {\n * request.headers['content-encoding'] = 'gzip'\n * request.body = pako.gzip(body)\n * }\n * }\n * ```\n */\n public requestDecorator: (\n request: RequestInit,\n options: SendOptions,\n url: string\n ) => void = function() {}\n}\n","import {CommunicationObserver, Headers} from '../results'\n\nexport default function completeCommunicationObserver(\n callbacks: Partial<CommunicationObserver<any>> = {}\n): Omit<Required<CommunicationObserver<any>>, 'useCancellable'> {\n let state = 0\n const retVal = {\n next: (data: any): void => {\n if (\n state === 0 &&\n callbacks.next &&\n data !== null &&\n data !== undefined\n ) {\n callbacks.next(data)\n }\n },\n error: (error: Error): void => {\n /* istanbul ignore else propagate error at most once */\n if (state === 0) {\n state = 1\n /* istanbul ignore else safety check */\n if (callbacks.error) callbacks.error(error)\n }\n },\n complete: (): void => {\n if (state === 0) {\n state = 2\n /* istanbul ignore else safety check */\n if (callbacks.complete) callbacks.complete()\n }\n },\n responseStarted: (headers: Headers, statusCode?: number): void => {\n if (callbacks.responseStarted)\n callbacks.responseStarted(headers, statusCode)\n },\n }\n return retVal\n}\n","import {Observable} from './observable'\nimport {ParameterizedQuery} from './query'\nimport {\n CommunicationObserver,\n FluxResultObserver,\n FluxTableMetaData,\n} from './results'\n\nexport function defaultRowMapping(\n values: string[],\n tableMeta: FluxTableMetaData\n): Record<string, any> {\n return tableMeta.toObject(values)\n}\n\n/** QueryOptions contains QueryApi configuration options. */\nexport interface QueryOptions {\n /**\n * Specifies the name of the organization executing the query. Takes either the ID or Name interchangeably.\n */\n org: string\n /**\n * Type of the query, default is \"flux\"\n */\n type?: 'flux'\n /**\n * Requests gzip encoded response.\n */\n gzip?: boolean\n /**\n * Specifies the time that should be reported as \"now\" in the query. RFC3339 value must be returned,\n * for example `new Date().toISOString()`.\n */\n now?: () => string\n /**\n * HTTP headers that will be sent with every query request.\n */\n headers?: {[key: string]: string}\n}\n\n/** Wraps values and associated metadata of a query result row */\nexport interface Row {\n values: string[]\n tableMeta: FluxTableMetaData\n}\n\n/**\n * Query InfluxDB 2.0. Provides methods that notify abouts result lines of the executed query.\n * See {@link https://v2.docs.influxdata.com/v2.0/api/#operation/PostQuery }\n */\nexport default interface QueryApi {\n /**\n * Returns a new query API with extra options applied.\n * @param options - query options to use\n * @returns queryApi instance with the supplied options\n */\n with(options: Partial<QueryOptions>): QueryApi\n\n /**\n * Creates a cold observable of the lines returned by the given query.\n *\n * @param query - query\n * @returns observable of CSV result lines\n */\n lines(query: string | ParameterizedQuery): Observable<string>\n\n /**\n * Creates a cold observable of the rows returned by the given query.\n *\n * @param query - query\n * @returns observable of result rows\n */\n rows(query: string | ParameterizedQuery): Observable<Row>\n\n /**\n * Executes the query and receives result lines (including empty and annotation lines)\n * through the supplied consumer. See [annotated-csv](https://v2.docs.influxdata.com/v2.0/reference/syntax/annotated-csv/).\n *\n * @param query - query\n * @param consumer - csv result lines and error consumer\n */\n queryLines(\n query: string | ParameterizedQuery,\n consumer: CommunicationObserver<string>\n ): void\n\n /**\n * Executes the query and receives table metadata and rows through the supplied consumer.\n *\n * @param query - query\n * @param consumer - result rows and error consumer\n */\n queryRows(\n query: string | ParameterizedQuery,\n consumer: FluxResultObserver<string[]>\n ): void\n\n /**\n * QueryRaw executes a query and returns the full response as a string.\n * Use with caution, a possibly huge stream is copied to memory.\n *\n * @param query - query\n * @returns Promise of response text\n */\n queryRaw(query: string | ParameterizedQuery): Promise<string>\n\n /**\n * CollectRows executes the query and collects all the results in the returned Promise.\n * This method is suitable to collect simple results. Use with caution,\n * a possibly huge stream of results is copied to memory.\n *\n * @param query - query\n * @param rowMapper - maps the supplied row to an item that is then collected,\n * undefined return values are not collected. If no rowMapper is supplied,\n * `row => row.tableMeta.toObject(row.values)` is used.\n * @returns Promise of mapped results\n */\n collectRows<T>(\n query: string | ParameterizedQuery,\n rowMapper?: (\n values: string[],\n tableMeta: FluxTableMetaData\n ) => T | undefined\n ): Promise<Array<T>>\n\n /**\n * CollectLines executes the query and collects all result lines in the returned Promise.\n * This method is suitable to collect simple results. Use with caution,\n * a possibly huge stream of lines is copied to memory.\n *\n * @param query - query\n * @returns Promise of returned csv lines\n */\n collectLines(query: string | ParameterizedQuery): Promise<Array<string>>\n}\n","import {\n Observable,\n Observer,\n ObserverComplete,\n ObserverError,\n ObserverNext,\n Subscription,\n symbolObservable,\n} from '../observable'\nimport {Cancellable, CommunicationObserver} from '../results'\n\nexport type QueryExecutor = (consumer: CommunicationObserver<string>) => void\n\ntype Decorator<T> = (observer: Observer<T>) => Observer<string>\n\nclass QuerySubscription implements Subscription {\n private cancellable?: Cancellable\n private isClosed = false\n\n public constructor(observer: Observer<string>, executor: QueryExecutor) {\n try {\n executor({\n next: value => {\n observer.next(value)\n },\n error: e => {\n this.isClosed = true\n observer.error(e)\n },\n complete: () => {\n this.isClosed = true\n observer.complete()\n },\n useCancellable: c => {\n this.cancellable = c\n },\n })\n } catch (e) {\n this.isClosed = true\n observer.error(e)\n }\n }\n\n public get closed(): boolean {\n return this.isClosed\n }\n\n public unsubscribe(): void {\n this.cancellable?.cancel()\n this.isClosed = true\n }\n}\n\nfunction noop(): void {}\n\nfunction completeObserver<T>(observer: Partial<Observer<T>>): Observer<T> {\n const {next, error, complete} = observer\n\n return {\n next: next ? next.bind(observer) : noop,\n error: error ? error.bind(observer) : noop,\n complete: complete ? complete.bind(observer) : noop,\n }\n}\n\nexport default class ObservableQuery<T> implements Observable<T> {\n public constructor(\n private readonly executor: QueryExecutor,\n private readonly decorator: Decorator<T>\n ) {}\n\n public subscribe(\n observerOrNext?: Partial<Observer<T>> | ObserverNext<T>,\n error?: ObserverError,\n complete?: ObserverComplete\n ): Subscription {\n const observer = completeObserver(\n typeof observerOrNext !== 'object' || observerOrNext === null\n ? {next: observerOrNext, error, complete}\n : observerOrNext\n )\n\n return new QuerySubscription(this.decorator(observer), this.executor)\n }\n\n public [symbolObservable](): this {\n return this\n }\n\n // this makes sure we satisfy the interface, while using a possibly polyfilled\n // [symbolObservable] above for the actual implementation\n public declare [Symbol.observable]: () => this\n}\n","import {Observable} from '../observable'\nimport QueryApi, {QueryOptions, Row, defaultRowMapping} from '../QueryApi'\nimport {Transport} from '../transport'\nimport {chunksToLines} from '../results'\nimport {\n CommunicationObserver,\n FluxResultObserver,\n FluxTableMetaData,\n linesToTables,\n} from '../results'\nimport ObservableQuery, {QueryExecutor} from './ObservableQuery'\nimport {ParameterizedQuery} from '../query/flux'\n\nconst DEFAULT_dialect: any = {\n header: true,\n delimiter: ',',\n quoteChar: '\"',\n commentPrefix: '#',\n annotations: ['datatype', 'group', 'default'],\n}\nconst identity = <T>(value: T): T => value\n\nexport class QueryApiImpl implements QueryApi {\n private options: QueryOptions\n constructor(private transport: Transport, org: string | QueryOptions) {\n this.options = typeof org === 'string' ? {org} : org\n }\n\n with(options: Partial<QueryOptions>): QueryApi {\n return new QueryApiImpl(this.transport, {...this.options, ...options})\n }\n\n lines(query: string | ParameterizedQuery): Observable<string> {\n return new ObservableQuery(this.createExecutor(query), identity)\n }\n\n rows(query: string | ParameterizedQuery): Observable<Row> {\n return new ObservableQuery(this.createExecutor(query), observer => {\n return linesToTables({\n next(values, tableMeta) {\n observer.next({values, tableMeta})\n },\n error(e) {\n observer.error(e)\n },\n complete() {\n observer.complete()\n },\n })\n })\n }\n\n queryLines(\n query: string | ParameterizedQuery,\n consumer: CommunicationObserver<string>\n ): void {\n this.createExecutor(query)(consumer)\n }\n\n queryRows(\n query: string | ParameterizedQuery,\n consumer: FluxResultObserver<string[]>\n ): void {\n this.createExecutor(query)(linesToTables(consumer))\n }\n\n collectRows<T>(\n query: string | ParameterizedQuery,\n rowMapper: (\n values: string[],\n tableMeta: FluxTableMetaData\n ) => T | undefined = defaultRowMapping as (\n values: string[],\n tableMeta: FluxTableMetaData\n ) => T | undefined\n ): Promise<Array<T>> {\n const retVal: Array<T> = []\n return new Promise((resolve, reject) => {\n this.queryRows(query, {\n next(values: string[], tableMeta: FluxTableMetaData): void {\n const toAdd = rowMapper.call(this, values, tableMeta)\n if (toAdd !== undefined) {\n retVal.push(toAdd)\n }\n },\n error(error: Error): void {\n reject(error)\n },\n complete(): void {\n resolve(retVal)\n },\n })\n })\n }\n\n collectLines(query: string | ParameterizedQuery): Promise<Array<string>> {\n const retVal: Array<string> = []\n return new Promise((resolve, reject) => {\n this.queryLines(query, {\n next(line: string): void {\n retVal.push(line)\n },\n error(error: Error): void {\n reject(error)\n },\n complete(): void {\n resolve(retVal)\n },\n })\n })\n }\n\n queryRaw(query: string | ParameterizedQuery): Promise<string> {\n const {org, type, gzip, headers} = this.options\n return this.transport.request(\n `/api/v2/query?org=${encodeURIComponent(org)}`,\n JSON.stringify(\n this.decorateRequest({\n query: query.toString(),\n dialect: DEFAULT_dialect,\n type,\n })\n ),\n {\n method: 'POST',\n headers: {\n accept: 'text/csv',\n 'accept-encoding': gzip ? 'gzip' : 'identity',\n 'content-type': 'application/json; encoding=utf-8',\n ...headers,\n },\n }\n )\n }\n\n private createExecutor(query: string | ParameterizedQuery): QueryExecutor {\n const {org, type, gzip, headers} = this.options\n\n return (consumer): void => {\n this.transport.send(\n `/api/v2/query?org=${encodeURIComponent(org)}`,\n JSON.stringify(\n this.decorateRequest({\n query: query.toString(),\n dialect: DEFAULT_dialect,\n type,\n })\n ),\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json; encoding=utf-8',\n 'accept-encoding': gzip ? 'gzip' : 'identity',\n ...headers,\n },\n },\n chunksToLines(consumer, this.transport.chunkCombiner)\n )\n }\n }\n private decorateRequest(request: any): any {\n if (typeof this.options.now === 'function') {\n request.now = this.options.now()\n }\n // https://v2.docs.influxdata.com/v2.0/api/#operation/PostQuery requires type\n request.type = this.options.type ?? 'flux'\n return request\n }\n}\n\nexport default QueryApiImpl\n","import WriteApi from './WriteApi'\nimport {ClientOptions, WriteOptions, WritePrecisionType} from './options'\nimport WriteApiImpl from './impl/WriteApiImpl'\nimport {IllegalArgumentError} from './errors'\nimport {Transport} from './transport'\n// replaced by ./impl/browser/FetchTransport in browser builds\nimport TransportImpl from './impl/node/NodeHttpTransport'\nimport QueryApi, {QueryOptions} from './QueryApi'\nimport QueryApiImpl from './impl/QueryApiImpl'\n\n/**\n * InfluxDB 2.0 entry point that configures communication with InfluxDB server\n * and provide APIs to write and query data.\n */\nexport default class InfluxDB {\n private _options: ClientOptions\n readonly transport: Transport\n\n /**\n * Creates influxdb client options from an options object or url.\n * @param options - client options\n */\n constructor(options: ClientOptions | string) {\n if (typeof options === 'string') {\n this._options = {url: options}\n } else if (options !== null && typeof options === 'object') {\n this._options = options\n } else {\n throw new IllegalArgumentError('No url or configuration specified!')\n }\n const url = this._options.url\n if (typeof url !== 'string')\n throw new IllegalArgumentError('No url specified!')\n if (url.endsWith('/')) this._options.url = url.substring(0, url.length - 1)\n this.transport = this._options.transport ?? new TransportImpl(this._options)\n }\n\n /**\n * Creates WriteApi for the supplied organization and bucket. BEWARE that returned instances must be closed\n * in order to flush the remaining data and close already scheduled retry executions.\n *\n * @remarks\n * Inspect the {@link WriteOptions} to control also advanced options, such retries of failure, retry strategy options, data chunking\n * and flushing windows. See {@link DEFAULT_WriteOptions} to see the defaults.\n *\n * See also {@link https://github.com/influxdata/influxdb-client-js/blob/master/examples/write.js | write.js example},\n * {@link https://github.com/influxdata/influxdb-client-js/blob/master/examples/writeAdvanced.js | writeAdvanced.js example},\n * and {@link https://github.com/influxdata/influxdb-client-js/blob/master/examples/index.html | browser example}.\n *\n * @param org - Specifies the destination organization for writes. Takes either the ID or Name interchangeably.\n * @param bucket - The destination bucket for writes.\n * @param precision - Timestamp precision for line items.\n * @param writeOptions - Custom write options.\n * @returns WriteApi instance\n */\n getWriteApi(\n org: string,\n bucket: string,\n precision: WritePrecisionType = 'ns',\n writeOptions?: Partial<WriteOptions>\n ): WriteApi {\n return new WriteApiImpl(\n this.transport,\n org,\n bucket,\n precision,\n writeOptions ?? this._options.writeOptions\n )\n }\n\n /**\n * Creates QueryApi for the supplied organization .\n *\n * @remarks\n * See also {@link https://github.com/influxdata/influxdb-client-js/blob/master/examples/query.ts | query.ts example},\n * {@link https://github.com/influxdata/influxdb-client-js/blob/master/examples/queryWithParams.ts | queryWithParams.ts example},\n * {@link https://github.com/influxdata/influxdb-client-js/blob/master/examples/rxjs-query.ts | rxjs-query.ts example},\n * and {@link https://github.com/influxdata/influxdb-client-js/blob/master/examples/index.html | browser example},\n *\n * @param org - organization or query options\n * @returns QueryApi instance\n */\n getQueryApi(org: string | QueryOptions): QueryApi {\n return new QueryApiImpl(this.transport, org)\n }\n}\n","import {convertTimeToNanos} from './util/currentTime'\nimport {escape} from './util/escape'\n\n/**\n * Settings that control the way of how a {@link Point} is serialized\n * to a protocol line.\n */\nexport interface PointSettings {\n /** default tags to add to every point */\n defaultTags?: {[key: string]: string}\n /** convertTime serializes Point's timestamp to a line protocol value */\n convertTime?: (\n value: string | number | Date | undefined\n ) => string | undefined\n}\n\n/**\n * Point defines values of a single measurement.\n */\nexport class Point {\n private name: string\n private tags: {[key: string]: string} = {}\n /** escaped field values */\n public fields: {[key: string]: string} = {}\n private time: string | number | Date | undefined\n\n /**\n * Create a new Point with specified a measurement name.\n *\n * @param measurementName - the measurement name\n */\n constructor(measurementName?: string) {\n if (measurementName) this.name = measurementName\n }\n\n /**\n * Sets point's measurement.\n *\n * @param name - measurement name\n * @returns this\n */\n public measurement(name: string): Point {\n this.name = name\n return this\n }\n\n /**\n * Adds a tag. The caller has to ensure that both name and value are not empty\n * and do not end with backslash.\n *\n * @param name - tag name\n * @param value - tag value\n * @returns this\n */\n public tag(name: string, value: string): Point {\n this.tags[name] = value\n return this\n }\n\n /**\n * Adds a boolean field.\n *\n * @param field - field name\n * @param value - field value\n * @returns this\n */\n public booleanField(name: string, value: boolean | any): Point {\n this.fields[name] = value ? 'T' : 'F'\n return this\n }\n\n /**\n * Adds an integer field.\n *\n * @param name - field name\n * @param value - field value\n * @returns this\n * @throws NaN or out of int64 range value is supplied\n */\n public intField(name: string, value: number | any): Point {\n let val: number\n if (typeof value === 'number') {\n val = value\n } else {\n val = parseInt(String(value))\n }\n if (isNaN(val) || val <= -9223372036854776e3 || val >= 9223372036854776e3) {\n throw new Error(`invalid integer value for field '${name}': '${value}'!`)\n }\n this.fields[name] = `${Math.floor(val)}i`\n return this\n }\n\n /**\n * Adds an unsigned integer field.\n *\n * @param name - field name\n * @param value - field value\n * @returns this\n * @throws NaN out of range value is supplied\n */\n public uintField(name: string, value: number | any): Point {\n if (typeof value === 'number') {\n if (isNaN(value) || value < 0 || value > Number.MAX_SAFE_INTEGER) {\n throw new Error(`uint value for field '${name}' out of range: ${value}`)\n }\n this.fields[name] = `${Math.floor(value as number)}u`\n } else {\n const strVal = String(value)\n for (let i = 0; i < strVal.length; i++) {\n const code = strVal.charCodeAt(i)\n if (code < 48 || code > 57) {\n throw new Error(\n `uint value has an unsupported character at pos ${i}: ${value}`\n )\n }\n }\n if (\n strVal.length > 20 ||\n (strVal.length === 20 &&\n strVal.localeCompare('18446744073709551615') > 0)\n ) {\n throw new Error(\n `uint value for field '${name}' out of range: ${strVal}`\n )\n }\n this.fields[name] = `${strVal}u`\n }\n return this\n }\n\n /**\n * Adds a number field.\n *\n * @param name - field name\n * @param value - field value\n * @returns this\n * @throws NaN/Infinity/-Infinity is supplied\n */\n public floatField(name: string, value: number | any): Point {\n let val: number\n if (typeof value === 'number') {\n val = value\n } else {\n val = parseFloat(value)\n }\n if (!isFinite(val)) {\n throw new Error(`invalid float value for field '${name}': ${value}`)\n }\n\n this.fields[name] = String(val)\n return this\n }\n\n /**\n * Adds a string field.\n *\n * @param name - field name\n * @param value - field value\n * @returns this\n */\n public stringField(name: string, value: string | any): Point {\n if (value !== null && value !== undefined) {\n if (typeof value !== 'string') value = String(value)\n this.fields[name] = escape.quoted(value)\n }\n return this\n }\n\n /**\n * Sets point timestamp. Timestamp can be specified as a Date (preferred), number, string\n * or an undefined value. An undefined value instructs to assign a local timestamp using\n * the client's clock. An empty string can be used to let the server assign\n * the timestamp. A number value represents time as a count of time units since epoch, the\n * exact time unit then depends on the {@link InfluxDB.getWriteApi | precision} of the API\n * that writes the point.\n *\n * Beware that the current time in nanoseconds can't precisely fit into a JS number,\n * which can hold at most 2^53 integer number. Nanosecond precision numbers are thus supplied as\n * a (base-10) string. An application can also use ES2020 BigInt to represent nanoseconds,\n * BigInt's `toString()` returns the required high-precision string.\n *\n * Note that InfluxDB requires the timestamp to fit into int64 data type.\n *\n * @param value - point time\n * @returns this\n */\n public timestamp(value: Date | number | string | undefined): Point {\n this.time = value\n return this\n }\n\n /**\n * Creates an InfluxDB protocol line out of this instance.\n * @param settings - settings control serialization of a point timestamp and can also add default tags,\n * nanosecond timestamp precision is used when no `settings` or no `settings.convertTime` is supplied.\n * @returns an InfluxDB protocol line out of this instance\n */\n public toLineProtocol(settings?: Partial<PointSettings>): string | undefined {\n if (!this.name) return undefined\n let fieldsLine = ''\n Object.keys(this.fields)\n .sort()\n .forEach(x => {\n if (x) {\n const val = this.fields[x]\n if (fieldsLine.length > 0) fieldsLine += ','\n fieldsLine += `${escape.tag(x)}=${val}`\n }\n })\n if (fieldsLine.length === 0) return undefined // no fields present\n let tagsLine = ''\n const tags =\n settings && settings.defaultTags\n ? {...settings.defaultTags, ...this.tags}\n : this.tags\n Object.keys(tags)\n .sort()\n .forEach(x => {\n if (x) {\n const val = tags[x]\n if (val) {\n tagsLine += ','\n tagsLine += `${escape.tag(x)}=${escape.tag(val)}`\n }\n }\n })\n let time = this.time\n if (settings && settings.convertTime) {\n time = settings.convertTime(time)\n } else {\n time = convertTimeToNanos(time)\n }\n\n return `${escape.measurement(this.name)}${tagsLine} ${fieldsLine}${\n time !== undefined ? ' ' + time : ''\n }`\n }\n\n toString(): string {\n const line = this.toLineProtocol(undefined)\n return line ? line : `invalid point: ${JSON.stringify(this, undefined)}`\n }\n}\n","import {CommunicationObserver} from './CommunicationObserver'\n\n/**\n * StringToLines is a transformation that emmits strings for each CSV\n * line in the supplied source string.\n * @param source - source string\n * @param target - target to emmit CSV lines to\n * @returns communication obrver to accept Uint8Arrays\n */\nexport function stringToLines(\n source: string,\n target: CommunicationObserver<string>\n): void {\n let quoted = false\n let start = 0\n let index = 0\n\n while (index < source.length) {\n const c = source.charCodeAt(index)\n if (c === 10) {\n if (!quoted) {\n /* do not emit CR+LR or LF line ending */\n const end =\n index > 0 && source.charCodeAt(index - 1) === 13 ? index - 1 : index\n // do not emmit more lines if the processing is already finished\n target.next(source.substring(start, end))\n start = index + 1\n }\n } else if (c === 34 /* \" */) {\n quoted = !quoted\n }\n index++\n }\n if (start < index) {\n target.next(source.substring(start, index))\n }\n target.complete()\n}\n"],"names":["createTextDecoderCombiner","decoder","TextDecoder","[object Object]","first","second","retVal","Uint8Array","length","set","chunk","start","end","subarray","toUtf8String","decode","chunksToLines","target","chunkCombiner","chunks","previous","finished","quoted","index","concat","c","next","copy","undefined","bufferReceived","e","this","error","complete","cancellable","useCancellable","self","cancel","isCancelled","LineSplitter","reuse","_reuse","val","reusedValues","Array","line","lastSplitLength","quoteCount","startIndex","values","count","i","getValue","push","substring","replace","FluxTableColumnImpl","newFluxTableColumn","retriableStatusCodes","isStatusCodeRetriable","statusCode","includes","IllegalArgumentError","Error","message","super","name","Object","setPrototypeOf","prototype","HttpError","statusMessage","body","retryAfter","contentType","startsWith","json","JSON","parse","code","setRetryAfter","test","_retryAfter","parseInt","RETRY_CODES","getRetryDelay","retryJitter","Math","round","random","RequestTimedOutError","AbortError","identity","x","typeSerializers","boolean","unsignedLong","long","Number","POSITIVE_INFINITY","NEGATIVE_INFINITY","string","base64Binary","duration","dateTime:RFC3339","FluxTableMetaDataImpl","columns","forEach","col","label","acc","column","defaultValue","dataType","createFluxTableMetaData","linesToTables","consumer","splitter","withReuse","lastMeta","expectMeta","firstColumnIndex","splitLine","size","group","slice","DEFAULT_RetryDelayStrategyOptions","minRetryDelay","maxRetryDelay","exponentialBase","randomRetry","DEFAULT_WriteOptions","batchSize","flushInterval","writeFailed","writeSuccess","maxRetries","maxRetryTime","maxBufferLines","gzipThreshold","createEscaper","characters","replacements","value","from","found","indexOf","escape","measurement","escaper","createQuotedEscaper","tag","lastMillis","Date","now","stepsInMillis","nanos","millis","String","substr","micros","seconds","floor","currentTime","s","ms","us","ns","dateToProtocolTimestamp","d","getTime","convertTimeToNanos","consoleLogger","console","warn","provider","Logger","FLUX_VALUE","Symbol","FluxParameter","fluxValue","sanitizeString","toString","prepareRetVal","charAt","sanitizeFloat","isFinite","dot","sanitizeRegExp","fluxExpression","toFluxValue","toISOString","RegExp","isArray","map","join","symbolObservable","observable","RetryStrategyImpl","options","success","failedAttempts","delay","max","nextDelay","currentDelay","min","RetryBuffer","maxLines","retryLines","lines","retryCount","expires","closed","retryTime","nextRetryTime","origSize","newSize","newFirst","last","toAdd","scheduleRetry","toRetry","_timeoutHandle","setTimeout","removeLines","then","catch","_e","clearTimeout","WriteBuffer","maxChunkRecords","flushFn","scheduleSend","record","flush","reset","Promise","resolve","WriteApiImpl","transport","org","bucket","precision","writeOptions","httpPath","encodeURIComponent","defaultTags","useDefaultTags","sendOptions","method","headers","content-type","writeBuffer","_clearFlushTimeout","sendBatch","bind","retryStrategy","retryBuffer","attempts","reject","responseStatusCode","callbacks","_headers","onRetry","call","addLines","send","add","records","point","toLineProtocol","points","withRetryBuffer","finally","remaining","close","tags","keys","key","getResponseHeaders","response","FetchTransport","connectionOptions","defaultHeaders","token","url","endsWith","path","observer","state","data","responseStarted","completeCommunicationObserver","cancelled","signal","controller","AbortController","abort","aborted","fetch","status","text","headerError","get","statusText","reader","getReader","read","done","arrayBuffer","buffer","TextEncoder","encode","responseContentType","responseType","accept","other","request","stringify","credentials","requestDecorator","defaultRowMapping","tableMeta","toObject","QuerySubscription","executor","isClosed","noop","ObservableQuery","decorator","observerOrNext","completeObserver","DEFAULT_dialect","header","delimiter","quoteChar","commentPrefix","annotations","QueryApiImpl","query","createExecutor","rowMapper","queryRows","queryLines","type","gzip","decorateRequest","dialect","accept-encoding","timeout","_options","TransportImpl","measurementName","fields","isNaN","MAX_SAFE_INTEGER","strVal","charCodeAt","localeCompare","parseFloat","time","settings","fieldsLine","sort","tagsLine","convertTime","canRetry","object","Boolean","strings","parts","partIndex","sanitized","sanitizeDateTime","logger","source","use"],"mappings":"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"}