├── .npmignore ├── .nvmrc ├── .prettierignore ├── packages ├── core │ ├── src │ │ ├── query │ │ │ └── index.ts │ │ ├── impl │ │ │ ├── version.ts │ │ │ ├── browser │ │ │ │ ├── .eslintrc.json │ │ │ │ └── tsconfig.json │ │ │ ├── node │ │ │ │ └── nodeChunkCombiner.ts │ │ │ ├── completeCommunicationObserver.ts │ │ │ └── retryStrategy.ts │ │ ├── observable │ │ │ ├── index.ts │ │ │ ├── symbol.ts │ │ │ └── types.ts │ │ ├── results │ │ │ ├── Cancellable.ts │ │ │ ├── index.ts │ │ │ ├── stringToLines.ts │ │ │ ├── FluxResultObserver.ts │ │ │ ├── CommunicationObserver.ts │ │ │ ├── chunksToLinesIterable.ts │ │ │ ├── chunkCombiner.ts │ │ │ ├── linesToRowsIterable.ts │ │ │ ├── LineSplitter.ts │ │ │ ├── ObservableQuery.ts │ │ │ ├── AnnotatedCSVResponse.ts │ │ │ ├── linesToTables.ts │ │ │ └── AnnotatedCSVResponseImpl.ts │ │ ├── util │ │ │ ├── logger.ts │ │ │ ├── utf8Length.ts │ │ │ └── escape.ts │ │ ├── index.ts │ │ ├── WriteApi.ts │ │ └── transport.ts │ ├── .npmignore │ ├── tsconfig.json │ ├── .nycrc │ ├── test │ │ ├── fixture │ │ │ ├── query │ │ │ │ ├── response3.txt │ │ │ │ ├── simpleResponse.txt │ │ │ │ ├── response2.txt │ │ │ │ ├── simpleResponseLines.json │ │ │ │ └── response3.parsed.json │ │ │ ├── lineSplitterTables.json │ │ │ ├── escapeTables.json │ │ │ └── chunksToLinesTables.json │ │ ├── unit │ │ │ ├── util │ │ │ │ ├── utf8Length.test.ts │ │ │ │ ├── escape.test.ts │ │ │ │ ├── waitForCondition.ts │ │ │ │ ├── CollectLinesObserver.ts │ │ │ │ ├── CollectTablesObserver.ts │ │ │ │ ├── logger.test.ts │ │ │ │ └── currentTime.test.ts │ │ │ └── results │ │ │ │ ├── stringToLines.test.ts │ │ │ │ ├── LineSplitter.test.ts │ │ │ │ ├── chunkCombiner.test.ts │ │ │ │ ├── chunksToLinesIterable.test.ts │ │ │ │ ├── linesToRowsIterable.test.ts │ │ │ │ └── linesToTables.test.ts │ │ ├── util.ts │ │ └── integration │ │ │ └── rxjs │ │ │ └── QueryApi.test.ts │ ├── README.md │ ├── tsup.config.ts │ ├── tsup.config.browser.ts │ └── package.json ├── apis │ ├── src │ │ ├── custom │ │ │ ├── index.ts │ │ │ └── FluxScriptInvocationAPI.ts │ │ ├── generated │ │ │ ├── PingAPI.ts │ │ │ ├── SignoutAPI.ts │ │ │ ├── MetricsAPI.ts │ │ │ ├── RootAPI.ts │ │ │ ├── ReadyAPI.ts │ │ │ ├── ConfigAPI.ts │ │ │ ├── HealthAPI.ts │ │ │ ├── SigninAPI.ts │ │ │ ├── FlagsAPI.ts │ │ │ ├── ResourcesAPI.ts │ │ │ ├── TelegrafAPI.ts │ │ │ ├── index.ts │ │ │ ├── MeAPI.ts │ │ │ ├── SetupAPI.ts │ │ │ ├── TemplatesAPI.ts │ │ │ ├── WriteAPI.ts │ │ │ ├── BackupAPI.ts │ │ │ └── DeleteAPI.ts │ │ ├── index.ts │ │ └── APIBase.ts │ ├── .prettierrc.json │ ├── README.md │ ├── .eslintrc.json │ ├── tsconfig.json │ ├── .npmignore │ ├── generator │ │ ├── logger.ts │ │ ├── format.ts │ │ ├── operationType.ts │ │ ├── typesCollector.ts │ │ └── index.ts │ ├── scripts │ │ ├── patchSwagger.js │ │ └── fetchSwaggerFiles.js │ ├── DEVELOPMENT.md │ ├── tsup.config.ts │ ├── tsup.config.browser.ts │ ├── test │ │ └── unit │ │ │ └── typesCollector.test.ts │ └── package.json ├── core-browser │ ├── .npmignore │ ├── README.md │ └── package.json ├── .eslintrc.json └── giraffe │ ├── .npmignore │ ├── tsconfig.json │ ├── .nycrc │ ├── README.md │ ├── src │ ├── index.ts │ └── queryTable.ts │ ├── tsup.config.ts │ ├── package.json │ └── test │ └── unit │ └── newTable.ts ├── scripts ├── gh-pages_config.yml ├── require-yarn.js ├── change-version.js └── esbuild-gzip-js.ts ├── .circleci ├── setup-npmjs.sh ├── deploy-nightly-version.sh └── config.yml ├── .prettierrc.json ├── .vscode ├── settings.json └── launch.json ├── .gitignore ├── .github ├── dependabot.yml ├── workflows │ └── semantic.yml ├── PULL_REQUEST_TEMPLATE └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── BUG_REPORT.yml ├── examples ├── .gitignore ├── tsconfig.json ├── env.mjs ├── env_browser.mjs ├── ping.mjs ├── .eslintrc.json ├── package.json ├── scripts │ ├── server.mjs │ └── monitor.mjs ├── onboarding.mjs ├── queryWithParams.mjs ├── query.deno.ts ├── httpErrorHandled.mjs ├── rxjs-query.ts ├── delete.ts ├── influxdb-1.8.ts ├── write.mjs ├── createBucket.mjs ├── follow-redirects.mjs ├── README.md ├── invokableScripts.mjs └── tokens.mjs ├── lerna.json ├── .gitattributes ├── tsconfig.base.json ├── typedoc.json ├── LICENSE ├── .eslintrc.json ├── Makefile └── package.json /.npmignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v18 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | **/*.d.ts -------------------------------------------------------------------------------- /packages/core/src/query/index.ts: -------------------------------------------------------------------------------- 1 | export * from './flux' 2 | -------------------------------------------------------------------------------- /scripts/gh-pages_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-minimal 2 | -------------------------------------------------------------------------------- /packages/apis/src/custom/index.ts: -------------------------------------------------------------------------------- 1 | export * from './FluxScriptInvocationAPI' 2 | -------------------------------------------------------------------------------- /packages/core/src/impl/version.ts: -------------------------------------------------------------------------------- 1 | export const CLIENT_LIB_VERSION = '1.35.0' 2 | -------------------------------------------------------------------------------- /packages/core/src/observable/index.ts: -------------------------------------------------------------------------------- 1 | export * from './symbol' 2 | export * from './types' 3 | -------------------------------------------------------------------------------- /.circleci/setup-npmjs.sh: -------------------------------------------------------------------------------- 1 | echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc 2 | chmod 0600 ~/.npmrc 3 | -------------------------------------------------------------------------------- /packages/core/src/impl/browser/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "node": false, 4 | "browser": true 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "semi": false, 4 | "trailingComma": "es5", 5 | "bracketSpacing": false 6 | } 7 | -------------------------------------------------------------------------------- /packages/core-browser/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | .rpt2_cache 4 | .DS_Store 5 | .nyc_output 6 | *.lcov 7 | yarn-error.log 8 | 9 | -------------------------------------------------------------------------------- /packages/apis/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "semi": false, 4 | "trailingComma": "es5", 5 | "bracketSpacing": false 6 | } 7 | -------------------------------------------------------------------------------- /packages/apis/README.md: -------------------------------------------------------------------------------- 1 | # @influxdata/influxdb-client-apis 2 | 3 | Contains client APIs for InfluxDB v2.x. See https://github.com/influxdata/influxdb-client-js to know more. 4 | -------------------------------------------------------------------------------- /packages/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "node": true 4 | }, 5 | "rules": { 6 | "no-console": "warn" 7 | }, 8 | "ignorePatterns": ["dist/*.js"] 9 | } 10 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | // enforce prettier on save 3 | "editor.formatOnSave": true, 4 | // comments in json files are OK 5 | "files.associations": {"*.json": "jsonc"} 6 | } 7 | -------------------------------------------------------------------------------- /packages/core/src/impl/browser/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.json", 3 | "compilerOptions": { 4 | "lib": ["DOM", "es2018"] 5 | }, 6 | "include": ["*.ts"] 7 | } 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | dist 4 | coverage 5 | doc 6 | .rpt2_cache 7 | .DS_Store 8 | .nyc_output 9 | *.lcov 10 | reports 11 | yarn-error.log 12 | .idea/ 13 | /temp 14 | /docs 15 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: 'npm' 4 | directory: '/' 5 | schedule: 6 | interval: 'monthly' 7 | day: 'sunday' 8 | open-pull-requests-limit: 10 9 | -------------------------------------------------------------------------------- /examples/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | dist 4 | coverage 5 | doc 6 | .rpt2_cache 7 | .DS_Store 8 | .nyc_output 9 | *.lcov 10 | reports 11 | yarn-error.log 12 | package-lock.json 13 | yarn.lock 14 | pnpm-lock.yaml 15 | -------------------------------------------------------------------------------- /examples/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "esnext", 4 | "moduleResolution": "node", 5 | "target": "ES2018", 6 | "allowJs": true 7 | }, 8 | "exclude": ["**/*.js", "**/*.mjs"] 9 | } 10 | -------------------------------------------------------------------------------- /scripts/require-yarn.js: -------------------------------------------------------------------------------- 1 | // see `yarn run env` vs `npm run env` 2 | if (!/yarn\//.test(process.env.npm_config_user_agent)) { 3 | throw new Error( 4 | `Use yarn in place of '${process.env.npm_config_user_agent}' !` 5 | ) 6 | } 7 | -------------------------------------------------------------------------------- /packages/apis/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "overrides": [ 3 | { 4 | "files": ["src/generated/*.ts"], 5 | "excludedFiles": "*.test.js", 6 | "rules": { 7 | "tsdoc/syntax": "warn" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/core/src/results/Cancellable.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Allows to cancel a running execution. 3 | */ 4 | export interface Cancellable { 5 | /** 6 | * Cancels execution. 7 | */ 8 | cancel(): void 9 | isCancelled(): boolean 10 | } 11 | -------------------------------------------------------------------------------- /packages/core/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | coverage 4 | doc 5 | .rpt2_cache 6 | .DS_Store 7 | .nyc_output 8 | *.lcov 9 | reports 10 | yarn-error.log 11 | /tsconfig.* 12 | /tsup.* 13 | /.prettierrc.json 14 | /src 15 | /test 16 | .nycrc 17 | 18 | -------------------------------------------------------------------------------- /packages/giraffe/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | coverage 4 | doc 5 | .rpt2_cache 6 | .DS_Store 7 | .nyc_output 8 | *.lcov 9 | reports 10 | yarn-error.log 11 | /tsconfig.* 12 | /tsup.* 13 | /.prettierrc.json 14 | /src 15 | /test 16 | .nycrc 17 | 18 | -------------------------------------------------------------------------------- /packages/apis/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "resolveJsonModule": true, 5 | "lib": ["es2018"] 6 | }, 7 | "include": ["src/**/*.ts", "generator/*.ts"], 8 | "exclude": ["**/*.js"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/giraffe/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "resolveJsonModule": true, 5 | "lib": ["es2018"] 6 | }, 7 | "include": ["src/**/*.ts", "test/**/*.ts"], 8 | "exclude": ["*.js"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "resolveJsonModule": true, 5 | "lib": ["DOM", "es2018"] 6 | }, 7 | "include": ["src/**/*.ts", "test/**/*.ts"], 8 | "exclude": ["*.js"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/apis/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | coverage 4 | doc 5 | .rpt2_cache 6 | .DS_Store 7 | .nyc_output 8 | *.lcov 9 | reports 10 | yarn-error.log 11 | /tsconfig.* 12 | /tsup.* 13 | /.prettierrc.json 14 | /generator 15 | /resources 16 | /src 17 | /test 18 | 19 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.35.0", 3 | "npmClient": "yarn", 4 | "packages": ["packages/*"], 5 | "command": { 6 | "version": { 7 | "message": "chore(release): publish %s [skip CI]" 8 | } 9 | }, 10 | "$schema": "node_modules/lerna/schemas/lerna-schema.json" 11 | } 12 | -------------------------------------------------------------------------------- /packages/core/.nycrc: -------------------------------------------------------------------------------- 1 | { 2 | "cache": false, 3 | "check-coverage": false, 4 | "extension": [".ts"], 5 | "include": ["src/**/*.ts"], 6 | "exclude": ["src/index.ts"], 7 | "sourceMap": true, 8 | "reporter": ["html", "text", "text-summary"], 9 | "all": true, 10 | "instrument": true 11 | } 12 | -------------------------------------------------------------------------------- /packages/giraffe/.nycrc: -------------------------------------------------------------------------------- 1 | { 2 | "cache": false, 3 | "check-coverage": false, 4 | "extension": [".ts"], 5 | "include": ["src/**/*.ts"], 6 | "exclude": ["src/index.ts"], 7 | "sourceMap": true, 8 | "reporter": ["html", "text", "text-summary"], 9 | "all": true, 10 | "instrument": true 11 | } 12 | -------------------------------------------------------------------------------- /.github/workflows/semantic.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Semantic PR and Commit Messages" 3 | 4 | on: 5 | pull_request: 6 | types: [opened, reopened, synchronize, edited] 7 | branches: 8 | - master 9 | 10 | jobs: 11 | semantic: 12 | uses: influxdata/validate-semantic-github-messages/.github/workflows/semantic.yml@main 13 | with: 14 | CHECK_PR_TITLE_OR_ONE_COMMIT: true 15 | 16 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Rush's JSON config files use JavaScript-style code comments. The rule below prevents pedantic 2 | # syntax highlighters such as GitHub's from highlighting these comments as errors. Your text editor 3 | # may also require a special configuration to allow comments in JSON. 4 | # 5 | # For more information, see this issue: https://github.com/microsoft/rushstack/issues/1088 6 | # 7 | *.json linguist-language=JSON-with-Comments -------------------------------------------------------------------------------- /packages/core/test/fixture/query/response3.txt: -------------------------------------------------------------------------------- 1 | 2 | result,table,_start,_stop,_time,_value,_field,_measurement,location 3 | ,0,1970-01-01T00:00:00Z,2019-12-12T09:05:37.96237406Z,1970-01-01T00:26:15.995033574Z,55,value,temperature,west 4 | ,0,1970-01-01T00:00:00Z,2019-12-12T09:05:37.96237406Z,1970-01-01T00:26:16.063594313Z,55,value,temperature,west 5 | ,0,1970-01-01T00:00:00Z,2019-12-12T09:05:37.96237406Z,1970-01-01T00:26:16.069518557Z,55,value,temperature,west 6 | -------------------------------------------------------------------------------- /packages/core/test/unit/util/utf8Length.test.ts: -------------------------------------------------------------------------------- 1 | import {expect} from 'chai' 2 | import utf8Length from '../../../src/util/utf8Length' 3 | 4 | describe('utf8Length', () => { 5 | ;[ 6 | {s: ''}, 7 | {s: 'hi'}, 8 | {s: 'šraňka'}, 9 | {s: 'love\u2665'}, 10 | {s: '\u{1f0a1}'}, 11 | ].forEach(({s}) => { 12 | const length = new TextEncoder().encode(s).length 13 | it(`${s} has length ${length}`, () => { 14 | expect(utf8Length(s)).equals(length) 15 | }) 16 | }) 17 | }) 18 | -------------------------------------------------------------------------------- /tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2018", 4 | "lib": ["es2018"], 5 | "allowJs": false, 6 | "declaration": true, 7 | "declarationMap": true, 8 | "outDir": "./dist", 9 | "removeComments": false, 10 | "strict": true, 11 | "strictPropertyInitialization": false, 12 | "noUnusedLocals": true, 13 | "moduleResolution": "node", 14 | "esModuleInterop": true, 15 | "sourceMap": true, 16 | "resolveJsonModule": true 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/apis/generator/logger.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | const logger = { 3 | warn(message: string, ...otherParameters: any[]): void { 4 | message = `\u001b[33m${message}\u001b[0m` // wrap to yellow 5 | if (otherParameters.length) { 6 | console.warn(message, ...otherParameters) 7 | } else { 8 | console.warn(message) 9 | } 10 | }, 11 | info(message: string, ...otherParameters: any[]): void { 12 | console.info(message, ...otherParameters) 13 | }, 14 | } 15 | 16 | export default logger 17 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE: -------------------------------------------------------------------------------- 1 | Fixes # 2 | 3 | ## Proposed Changes 4 | 5 | _Briefly describe your proposed changes:_ 6 | 7 | ## Checklist 8 | 9 | 10 | 11 | - [ ] CHANGELOG.md updated 12 | - [ ] Rebased/mergeable 13 | - [ ] A test has been added if appropriate 14 | - [ ] `yarn test` completes successfully 15 | - [ ] Commit messages are [conventional](https://www.conventionalcommits.org/en/v1.0.0/) 16 | - [ ] Sign [CLA](https://www.influxdata.com/legal/cla/) (if not already signed) 17 | -------------------------------------------------------------------------------- /packages/core/src/observable/symbol.ts: -------------------------------------------------------------------------------- 1 | /* Observable interop typing. Taken from https://github.com/ReactiveX/rxjs */ 2 | 3 | /* Note: This will add Symbol.observable globally for all TypeScript users */ 4 | declare global { 5 | interface SymbolConstructor { 6 | readonly observable: symbol 7 | } 8 | } 9 | 10 | /** Symbol.observable or a string "\@\@observable". Used for interop */ 11 | export const symbolObservable = ((): 12 | | typeof Symbol.observable 13 | | '@@observable' => 14 | (typeof Symbol === 'function' && Symbol.observable) || '@@observable')() 15 | -------------------------------------------------------------------------------- /packages/core/src/results/index.ts: -------------------------------------------------------------------------------- 1 | export * from './chunkCombiner' 2 | export * from './chunksToLines' 3 | export * from './chunksToLinesIterable' 4 | export * from './Cancellable' 5 | export * from './CommunicationObserver' 6 | export * from './linesToTables' 7 | export * from './linesToRowsIterable' 8 | export * from './LineSplitter' 9 | export * from './FluxTableMetaData' 10 | export * from './FluxResultObserver' 11 | export * from './FluxTableColumn' 12 | export * from './stringToLines' 13 | export * from './AnnotatedCSVResponse' 14 | export {APIExecutor} from './ObservableQuery' 15 | -------------------------------------------------------------------------------- /examples/env.mjs: -------------------------------------------------------------------------------- 1 | /** InfluxDB v2 URL */ 2 | const url = process.env['INFLUX_URL'] || 'http://localhost:8086' 3 | /** InfluxDB authorization token */ 4 | const token = process.env['INFLUX_TOKEN'] || 'my-token' 5 | /** Organization within InfluxDB */ 6 | const org = process.env['INFLUX_ORG'] || 'my-org' 7 | /**InfluxDB bucket used in examples */ 8 | const bucket = 'my-bucket' 9 | // ONLY onboarding example 10 | /**InfluxDB user */ 11 | const username = 'my-user' 12 | /**InfluxDB password */ 13 | const password = 'my-password' 14 | 15 | export {url, token, org, bucket, username, password} 16 | -------------------------------------------------------------------------------- /packages/core/test/unit/util/escape.test.ts: -------------------------------------------------------------------------------- 1 | import {expect} from 'chai' 2 | import {escape} from '../../../src' 3 | import escapeTables from '../../fixture/escapeTables.json' 4 | 5 | describe('escape', () => { 6 | Object.keys(escapeTables).forEach((escaper: string) => { 7 | describe(String(escaper), () => { 8 | ;(escapeTables as any)[escaper].forEach((test: [string, string]) => { 9 | it(`escapes \`${test[0]}\` as \`${test[1]}\``, () => { 10 | expect((escape as any)[escaper](test[0])).to.equal(test[1]) 11 | }) 12 | }) 13 | }) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /scripts/change-version.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/no-var-requires 2 | const {readFileSync, writeFileSync} = require('fs') 3 | const VERSION = process.env.VERSION 4 | 5 | if (!VERSION) { 6 | console.error('VERSION environment variable is not defined!') 7 | process.exit(1) 8 | } 9 | 10 | const fileName = __dirname + '/../packages/core/src/impl/version.ts' 11 | const content = readFileSync(fileName, 'utf-8') 12 | const updatedVersion = content.replace( 13 | /CLIENT_LIB_VERSION = '[^']*'/, 14 | `CLIENT_LIB_VERSION = '${VERSION}'` 15 | ) 16 | writeFileSync(fileName, updatedVersion, 'utf8') 17 | -------------------------------------------------------------------------------- /packages/apis/scripts/patchSwagger.js: -------------------------------------------------------------------------------- 1 | // Patch function is used by oats tool to modify a swagger document before generating API code. 2 | exports.patch = async (doc, SwaggerParser) => { 3 | // Merges Resource enum values so that the client contains also values from cloud spec 4 | const cloudApi = await SwaggerParser.bundle('./resources/cloud.yml') 5 | const cloudTypes = 6 | cloudApi.components.schemas['Resource']['properties']['type'] 7 | const ossTypes = doc.components.schemas['Resource']['properties']['type'] 8 | ossTypes.enum = ossTypes.enum.concat( 9 | cloudTypes.enum.filter((cloudType) => !ossTypes.enum.includes(cloudType)) 10 | ) 11 | 12 | return doc 13 | } 14 | -------------------------------------------------------------------------------- /packages/core/src/impl/node/nodeChunkCombiner.ts: -------------------------------------------------------------------------------- 1 | import {Buffer} from 'buffer' 2 | import {ChunkCombiner} from '../../results' 3 | 4 | const nodeChunkCombiner: ChunkCombiner = { 5 | concat(first: Uint8Array, second: Uint8Array): Uint8Array { 6 | return Buffer.concat([first, second]) 7 | }, 8 | toUtf8String(chunk: Uint8Array, start: number, end: number): string { 9 | return (chunk as Buffer).toString('utf-8', start, end) 10 | }, 11 | copy(chunk: Uint8Array, start: number, end: number): Uint8Array { 12 | const retVal = Buffer.allocUnsafe(end - start) 13 | ;(chunk as Buffer).copy(retVal, 0, start, end) 14 | return retVal 15 | }, 16 | } 17 | 18 | export default nodeChunkCombiner 19 | -------------------------------------------------------------------------------- /examples/env_browser.mjs: -------------------------------------------------------------------------------- 1 | /* This file contains InfluxDB configuration for the browser example. */ 2 | 3 | /** InfluxDB v2 URL, '/influxdb' relies upon proxy to forward to the target influxDB */ 4 | export const url = '/influx' //'http://localhost:8086', 5 | /** InfluxDB authorization token */ 6 | export const token = 'my-token' 7 | /** InfluxDB organization */ 8 | export const org = 'my-org' 9 | /** InfluxDB bucket used for onboarding and write requests. */ 10 | export const bucket = 'my-bucket' 11 | 12 | /** The following properties are used ONLY in the onboarding example */ 13 | /** InfluxDB user */ 14 | export const username = 'my-user' 15 | /** InfluxDB password */ 16 | export const password = 'my-password' 17 | -------------------------------------------------------------------------------- /packages/apis/DEVELOPMENT.md: -------------------------------------------------------------------------------- 1 | # influxdb-client-apis 2 | 3 | Contains generated client APIs for InfluxDB v2.x. See https://github.com/influxdata/influxdb-client-js to know more. 4 | 5 | ## Build 6 | 7 | ```bash 8 | $ yarn build 9 | ``` 10 | 11 | ## Re-generate APIs code 12 | 13 | ``` 14 | yarn regenerate 15 | ``` 16 | 17 | It performs the following steps: 18 | 19 | - fetch latest versions of openapi files 20 | - re-generate src/generated/types.ts and resources/operations.json using [oats](https://github.com/influxdata/oats) 21 | - generate src/generated APIs from resources/operations.json 22 | - validates the generated output 23 | 24 | Create a new git branch with the regenerated code and submit a new pull request to review the changes. 25 | -------------------------------------------------------------------------------- /packages/apis/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'tsup' 2 | import {esbuildGzipOutJsPlugin} from '../../scripts/esbuild-gzip-js' 3 | import pkg from './package.json' 4 | 5 | const minify = !(process.env.ESBUILD_MINIFY === '0') 6 | 7 | const outFiles = { 8 | esm: pkg.exports['.'].import, 9 | cjs: pkg.exports['.'].require, 10 | } 11 | export default defineConfig({ 12 | entry: ['src/index.ts'], 13 | sourcemap: true, 14 | dts: true, 15 | format: ['cjs', 'esm'], 16 | minify, 17 | target: ['es2018'], 18 | platform: 'node', 19 | splitting: false, 20 | esbuildOptions(options, {format}) { 21 | options.outdir = undefined 22 | options.outfile = outFiles[format] 23 | }, 24 | esbuildPlugins: [esbuildGzipOutJsPlugin], 25 | }) 26 | -------------------------------------------------------------------------------- /typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "highlightLanguages": [ 3 | "javascript", 4 | "typescript", 5 | "sh", 6 | "powershell", 7 | "console", 8 | "json", 9 | "jsx" 10 | ], 11 | "entryPointStrategy": "packages", 12 | "entryPoints": [ 13 | "packages/apis/", 14 | "packages/core/", 15 | "packages/giraffe/" 16 | ], 17 | "packageOptions": { 18 | "entryPoints": ["src/index.ts"] 19 | }, 20 | "cleanOutputDir": true, 21 | "validation": { 22 | "notExported": false, 23 | "invalidLink": true, 24 | "rewrittenLink": false, 25 | "notDocumented": false, 26 | "unusedMergeModuleWith": false 27 | }, 28 | "blockTags": ["@param", "@returns", "@generated", "@throws", "@defaultValue", "@example", "@remarks"] 29 | } -------------------------------------------------------------------------------- /packages/core/README.md: -------------------------------------------------------------------------------- 1 | # @influxdata/influxdb-client 2 | 3 | The reference javascript client for InfluxDB 2.x. Both node and browser environments are supported. The package.json 4 | 5 | - **main** points to node.js CJS distribution 6 | - **module** points to node.js ESM distribution 7 | - **browser** points to browser (UMD) distribution 8 | 9 | Node.js distributions do not work in browser and vice versa, because different platform APIs are used. Use `@influxdata/influxdb-client-browser` to import browser ESM module. See https://github.com/influxdata/influxdb-client-js to know more. 10 | 11 | **Note: This library is for use with InfluxDB 2.x or 1.8+. For connecting to InfluxDB 1.x instances, see [node-influx](https://github.com/node-influx/node-influx).** 12 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Core Tests", 9 | "type": "node", 10 | "request": "launch", 11 | "cwd": "${workspaceRoot}/packages/core", 12 | "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha", 13 | "args": [ 14 | "--require", 15 | "esbuild-runner/register", 16 | "--timeout", 17 | "15000", 18 | "--colors", 19 | "test/**/*.test.ts" 20 | ], 21 | "internalConsoleOptions": "openOnSessionStart" 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /packages/core/test/unit/util/waitForCondition.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Wait for the supplied `condition` to become truethy 3 | * for at most `timeout` milliseconds. The `condition` 4 | * every `step` milliseconds. 5 | * @param condition - condition to validate 6 | * @param timeout - maximum wait time 7 | * @param step - interval to validate the condition 8 | */ 9 | export async function waitForCondition( 10 | condition: () => any, 11 | message = 'timeouted', 12 | timeout = 100, 13 | step = 5 14 | ): Promise { 15 | for (;;) { 16 | await new Promise((resolve) => setTimeout(resolve, step)) 17 | timeout -= step 18 | if (timeout <= 0) { 19 | break 20 | } 21 | if (condition()) return 22 | } 23 | return Promise.reject(`WARN:waitForCondition: ${message}`) 24 | } 25 | -------------------------------------------------------------------------------- /examples/ping.mjs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | /* 3 | This example shows how to check state InfluxDB instance. 4 | InfluxDB OSS APIs are available through '@influxdata/influxdb-client-apis' package. 5 | 6 | See https://docs.influxdata.com/influxdb/latest/api/ 7 | */ 8 | import {InfluxDB} from '@influxdata/influxdb-client' 9 | import {PingAPI} from '@influxdata/influxdb-client-apis' 10 | import {url} from './env.mjs' 11 | 12 | const timeout = 10 * 1000 // timeout for ping 13 | 14 | console.log('*** PING STATUS ***') 15 | const influxDB = new InfluxDB({url, timeout}) 16 | const pingAPI = new PingAPI(influxDB) 17 | 18 | pingAPI 19 | .getPing() 20 | .then(() => { 21 | console.log('\nPing SUCCESS') 22 | }) 23 | .catch((error) => { 24 | console.error(error) 25 | console.log('\nFinished ERROR') 26 | }) 27 | -------------------------------------------------------------------------------- /packages/core/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'tsup' 2 | import {esbuildGzipOutJsPlugin} from '../../scripts/esbuild-gzip-js' 3 | import pkg from './package.json' 4 | 5 | const minify = !(process.env.ESBUILD_MINIFY === '0') 6 | 7 | const outFiles = { 8 | esm: pkg.exports['.'].import, 9 | cjs: pkg.exports['.'].require, 10 | } 11 | export default defineConfig({ 12 | entry: ['src/index.ts'], 13 | sourcemap: true, 14 | dts: true, 15 | format: ['cjs', 'esm'], 16 | minify, 17 | target: ['es2018'], 18 | platform: 'node', 19 | splitting: false, 20 | esbuildOptions(options, {format}) { 21 | options.outdir = undefined 22 | options.outfile = outFiles[format] 23 | }, 24 | define: { 25 | 'process.env.BUILD_BROWSER': 'false', 26 | }, 27 | esbuildPlugins: [esbuildGzipOutJsPlugin], 28 | }) 29 | -------------------------------------------------------------------------------- /packages/core-browser/README.md: -------------------------------------------------------------------------------- 1 | # @influxdata/influxdb-client-browser 2 | 3 | The reference InfluxDB 2.x JavaScript client for browser and [Deno](https://deno.land/) environments. 4 | 5 | The package.json 6 | 7 | - **main** and **browser** point to the browser UMD distribution of @influxdata/influxdb-client 8 | - **module** points to the browser ESM distribution of @influxdata/influxdb-client 9 | 10 | Browser distributions do not work in Node.js and vice versa because they use different APIs. Use `@influxdata/influxdb-client` in Node.js environments. 11 | For more information, see [influxdb-client-js](https://github.com/influxdata/influxdb-client-js). 12 | 13 | **Note: This library is for use with InfluxDB 2.x or 1.8+. For connecting to InfluxDB 1.x instances, see [node-influx](https://github.com/node-influx/node-influx).** 14 | -------------------------------------------------------------------------------- /.circleci/deploy-nightly-version.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | 3 | SCRIPT_PATH="$( cd "$(dirname "$0")" || exit ; pwd -P )" 4 | 5 | # Update Version 6 | VERSION=$(cat packages/core/src/impl/version.ts | sed 's/[^0-9.]*//g' | awk -F. '{$2+=1; OFS="."; print $1"."$2"."$3}') 7 | sed -i -e "s/CLIENT_LIB_VERSION = '.*'/CLIENT_LIB_VERSION = '${VERSION}.nightly'/" packages/core/src/impl/version.ts 8 | yarn lerna version "$VERSION"-nightly."$CIRCLE_BUILD_NUM" --no-git-tag-version --yes 9 | git config user.name "CircleCI Builder" 10 | git config user.email "noreply@influxdata.com" 11 | git commit -am "chore(release): prepare to release influxdb-client-js-${VERSION}.nightly" 12 | 13 | # Build Core 14 | cd "${SCRIPT_PATH}"/.. 15 | yarn build 16 | 17 | # Publish 18 | yarn lerna publish --canary from-package --no-git-tag-version --force-publish --preid nightly --yes 19 | -------------------------------------------------------------------------------- /examples/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "parserOptions": { 4 | "sourceType": "module", 5 | "ecmaFeatures": {} 6 | }, 7 | "plugins": ["@typescript-eslint", "prettier"], 8 | "env": { 9 | "node": true 10 | }, 11 | "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"], 12 | "rules": { 13 | "no-console": "off", 14 | "@typescript-eslint/no-var-requires": "off" 15 | }, 16 | "overrides": [ 17 | { 18 | "files": ["*.js", "*.mjs"], 19 | "rules": { 20 | "@typescript-eslint/explicit-function-return-type": "off", 21 | "@typescript-eslint/naming-convention": ["off"] 22 | } 23 | }, 24 | { 25 | "files": ["query.deno.ts"], 26 | "rules": { 27 | "prettier/prettier": "off" 28 | } 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Opening a feature request kicks off a discussion 4 | --- 5 | 6 | 14 | 15 | __Proposal:__ 16 | Short summary of the feature. 17 | 18 | __Current behavior:__ 19 | Describe what currently happens. 20 | 21 | __Desired behavior:__ 22 | Describe what you want. 23 | 24 | __Alternatives considered:__ 25 | Describe other solutions or features you considered. 26 | 27 | __Use case:__ 28 | Why is this important (helps with prioritizing requests)? 29 | -------------------------------------------------------------------------------- /packages/giraffe/README.md: -------------------------------------------------------------------------------- 1 | # @influxdata/influxdb-client-giraffe 2 | 3 | This package provides an efficient `queryToTable` function that queries 4 | InfluxDB (v2) and returns a Table that is then directly suitable as a data input 5 | of various [Giraffe](https://github.com/influxdata/giraffe) visualizations. 6 | 7 | ```js 8 | import {InfluxDB} from '@influxdata/influxdb-client' 9 | import {queryToTable} from '@influxdata/influxdb-client-giraffe' 10 | import {newTable, Plot} from '@influxdata/giraffe' 11 | ... 12 | const queryApi = new InfluxDB({url, token}).getQueryApi(org) 13 | const table = await queryToTable( 14 | api, 15 | 'from(bucket: "my-bucket") |> range(start: -30d)', 16 | newTable, 17 | {maxTableRows: 5000} 18 | ) 19 | ... 20 | 21 | ... 22 | ``` 23 | 24 | See https://github.com/influxdata/influxdb-client-js to know more. 25 | -------------------------------------------------------------------------------- /packages/core/test/unit/util/CollectLinesObserver.ts: -------------------------------------------------------------------------------- 1 | import {CommunicationObserver} from '../../../src/results' 2 | 3 | export class CollectLinesObserver implements CommunicationObserver { 4 | lines: string[] = [] 5 | completed = 0 6 | failed = 0 7 | cancellableSet = false 8 | resolve?: (value?: void) => void 9 | reject?: (reason?: any) => void 10 | 11 | next(data: string): void { 12 | this.lines.push(data) 13 | } 14 | error(error: Error): void { 15 | this.failed++ 16 | if (this.reject) this.reject(error) 17 | } 18 | complete(): void { 19 | this.completed++ 20 | if (this.resolve) this.resolve() 21 | } 22 | 23 | attach( 24 | resolve?: (value?: void) => void, 25 | reject?: (reason?: any) => void 26 | ): CollectLinesObserver { 27 | this.resolve = resolve 28 | this.reject = reject 29 | return this 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/core/test/fixture/lineSplitterTables.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "result": [] 4 | }, 5 | { 6 | "line": null, 7 | "result": [] 8 | }, 9 | { 10 | "line": "", 11 | "result": [""] 12 | }, 13 | { 14 | "line": "\",\",", 15 | "result": [",", ""] 16 | }, 17 | { 18 | "line": "a, b,c", 19 | "result": ["a", " b", "c"] 20 | }, 21 | { 22 | "line": "\",\n,\",", 23 | "result": [",\n,", ""] 24 | }, 25 | { 26 | "line": "\"5\"\"1\"\"2\"\"3\",", 27 | "result": ["5\"1\"2\"3", ""] 28 | }, 29 | { 30 | "line": ",,0,GO506_20_6431,25.463641400535032,\"-73.68691 40.820317, -73.690054 40.815413\",GO506_20_6431", 31 | "result": [ 32 | "", 33 | "", 34 | "0", 35 | "GO506_20_6431", 36 | "25.463641400535032", 37 | "-73.68691 40.820317, -73.690054 40.815413", 38 | "GO506_20_6431" 39 | ] 40 | } 41 | ] 42 | -------------------------------------------------------------------------------- /examples/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "license": "MIT", 4 | "scripts": { 5 | "browser": "node scripts/server.mjs", 6 | "clean": "echo 'nothing to clean'", 7 | "build": "echo 'nothing to build'", 8 | "test": "echo 'run examples to test'", 9 | "esr": "esr" 10 | }, 11 | "dependencies": { 12 | "@influxdata/influxdb-client": "link:../packages/core", 13 | "@influxdata/influxdb-client-apis": "link:../packages/apis" 14 | }, 15 | "devDependencies": { 16 | "@types/express": "^4.17.2", 17 | "@types/express-http-proxy": "^1.5.12", 18 | "@types/node": "^16", 19 | "esbuild": "0.14.25", 20 | "esbuild-runner": "^2.2.1", 21 | "express": "^4.17.1", 22 | "express-http-proxy": "^1.6.0", 23 | "follow-redirects": "^1.14.3", 24 | "open": "^7.0.0", 25 | "response-time": "^2.3.2", 26 | "rxjs": "^6.5.5", 27 | "typescript": "^4.8.2" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/scripts/server.mjs: -------------------------------------------------------------------------------- 1 | import express from 'express' 2 | import proxy from 'express-http-proxy' 3 | import open from 'open' 4 | import {fileURLToPath} from 'node:url' 5 | import {url} from '../env.mjs' 6 | import monitor from './monitor.mjs' 7 | 8 | const port = 3001 9 | const proxyPath = '/influx' 10 | 11 | const app = express() 12 | // monitor express response time in InfluxDB 13 | monitor(app) 14 | // serve all files of the git repository 15 | const dirName = fileURLToPath(new URL('../..', import.meta.url)) 16 | app.use(express.static(dirName, {index: false})) 17 | // create also proxy to InfluxDB 18 | app.use(proxyPath, proxy(url)) 19 | app.listen(port, () => { 20 | console.log(`listening on http://localhost:${port}`) 21 | console.log(`forwarding ${proxyPath}/* to ${url}/*`) 22 | console.log(`opening http://localhost:${port}/examples/index.html`) 23 | open(`http://localhost:${port}/examples/index.html`) 24 | }) 25 | -------------------------------------------------------------------------------- /packages/core/test/unit/results/stringToLines.test.ts: -------------------------------------------------------------------------------- 1 | import {expect} from 'chai' 2 | import {stringToLines} from '../../../src/results' 3 | import {CollectLinesObserver} from '../util/CollectLinesObserver' 4 | import chunksToLinesTables from '../../fixture/chunksToLinesTables.json' 5 | 6 | interface StringToLinesTest { 7 | name: string 8 | source: string 9 | lines: string[] 10 | } 11 | 12 | describe('chunksToLines', () => { 13 | const tests = chunksToLinesTables 14 | .filter((x) => x.chunks.indexOf('error') === -1) 15 | .map((x) => ({...x, source: x.chunks.join('')})) 16 | tests.forEach((test: StringToLinesTest) => { 17 | it(test.name, () => { 18 | const target = new CollectLinesObserver() 19 | stringToLines(test.source, target) 20 | expect(test.lines).deep.equal(target.lines) 21 | expect(target.failed).equal(0) 22 | expect(target.completed).equal(1) 23 | }) 24 | }) 25 | }) 26 | -------------------------------------------------------------------------------- /packages/core/test/fixture/escapeTables.json: -------------------------------------------------------------------------------- 1 | { 2 | "tag": [ 3 | ["ab", "ab"], 4 | ["a\\b", "a\\b"], 5 | ["a\\\\b", "a\\\\b"], 6 | ["a,", "a\\,"], 7 | ["a,b", "a\\,b"], 8 | ["a=b", "a\\=b"], 9 | ["a b", "a\\ b"], 10 | ["a b=c", "a\\ b\\=c"], 11 | ["'a' \\b=c\\,\\\\\"d\"", "'a'\\ \\b\\=c\\\\,\\\\\"d\""], 12 | ["new\nline", "new\\nline"], 13 | ["carriage\rreturn", "carriage\\rreturn"], 14 | ["t\tab", "t\\tab"] 15 | ], 16 | "measurement": [ 17 | ["ab", "ab"], 18 | ["a,", "a\\,"], 19 | ["a,b", "a\\,b"], 20 | ["a b", "a\\ b"], 21 | ["a b,c", "a\\ b\\,c"], 22 | ["new\nline", "new\\nline"], 23 | ["carriage\rreturn", "carriage\\rreturn"], 24 | ["t\tab", "t\\tab"], 25 | ["equ=al", "equ=al"] 26 | ], 27 | "quoted": [ 28 | ["ab", "\"ab\""], 29 | ["a\"", "\"a\\\"\""], 30 | ["a\"b", "\"a\\\"b\""], 31 | ["a\"b\"c", "\"a\\\"b\\\"c\""] 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /packages/apis/src/generated/PingAPI.ts: -------------------------------------------------------------------------------- 1 | import {InfluxDB} from '../../../core/src' 2 | import {APIBase, RequestOptions} from '../APIBase' 3 | 4 | export interface GetPingRequest {} 5 | /** 6 | * Ping API 7 | */ 8 | export class PingAPI { 9 | // internal 10 | private base: APIBase 11 | 12 | /** 13 | * Creates PingAPI 14 | * @param influxDB - an instance that knows how to communicate with InfluxDB server 15 | */ 16 | constructor(influxDB: InfluxDB) { 17 | this.base = new APIBase(influxDB) 18 | } 19 | /** 20 | * Get the status and version of the instance. 21 | * See {@link https://docs.influxdata.com/influxdb/v2.4/api/#operation/GetPing } 22 | * @param request - request parameters and body (if supported) 23 | * @param requestOptions - optional transport options 24 | * @returns promise of response 25 | */ 26 | getPing( 27 | request?: GetPingRequest, 28 | requestOptions?: RequestOptions 29 | ): Promise { 30 | return this.base.request('GET', `/ping`, request, requestOptions) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/apis/src/generated/SignoutAPI.ts: -------------------------------------------------------------------------------- 1 | import {InfluxDB} from '../../../core/src' 2 | import {APIBase, RequestOptions} from '../APIBase' 3 | 4 | export interface PostSignoutRequest {} 5 | /** 6 | * Signout API 7 | */ 8 | export class SignoutAPI { 9 | // internal 10 | private base: APIBase 11 | 12 | /** 13 | * Creates SignoutAPI 14 | * @param influxDB - an instance that knows how to communicate with InfluxDB server 15 | */ 16 | constructor(influxDB: InfluxDB) { 17 | this.base = new APIBase(influxDB) 18 | } 19 | /** 20 | * Expire the current UI session. 21 | * See {@link https://docs.influxdata.com/influxdb/v2.4/api/#operation/PostSignout } 22 | * @param request - request parameters and body (if supported) 23 | * @param requestOptions - optional transport options 24 | * @returns promise of response 25 | */ 26 | postSignout( 27 | request?: PostSignoutRequest, 28 | requestOptions?: RequestOptions 29 | ): Promise { 30 | return this.base.request('POST', `/api/v2/signout`, request, requestOptions) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/apis/src/generated/MetricsAPI.ts: -------------------------------------------------------------------------------- 1 | import {InfluxDB} from '../../../core/src' 2 | import {APIBase, RequestOptions} from '../APIBase' 3 | 4 | export interface GetMetricsRequest {} 5 | /** 6 | * Metrics API 7 | */ 8 | export class MetricsAPI { 9 | // internal 10 | private base: APIBase 11 | 12 | /** 13 | * Creates MetricsAPI 14 | * @param influxDB - an instance that knows how to communicate with InfluxDB server 15 | */ 16 | constructor(influxDB: InfluxDB) { 17 | this.base = new APIBase(influxDB) 18 | } 19 | /** 20 | * Retrieve workload performance metrics. 21 | * See {@link https://docs.influxdata.com/influxdb/v2.4/api/#operation/GetMetrics } 22 | * @param request - request parameters and body (if supported) 23 | * @param requestOptions - optional transport options 24 | * @returns promise of response 25 | */ 26 | getMetrics( 27 | request?: GetMetricsRequest, 28 | requestOptions?: RequestOptions 29 | ): Promise { 30 | return this.base.request('GET', `/api/v2/metrics`, request, requestOptions) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/apis/src/generated/RootAPI.ts: -------------------------------------------------------------------------------- 1 | import {InfluxDB} from '../../../core/src' 2 | import {APIBase, RequestOptions} from '../APIBase' 3 | import {Routes} from './types' 4 | 5 | export interface GetRoutesRequest {} 6 | /** 7 | * Root API 8 | */ 9 | export class RootAPI { 10 | // internal 11 | private base: APIBase 12 | 13 | /** 14 | * Creates RootAPI 15 | * @param influxDB - an instance that knows how to communicate with InfluxDB server 16 | */ 17 | constructor(influxDB: InfluxDB) { 18 | this.base = new APIBase(influxDB) 19 | } 20 | /** 21 | * List all top level routes. 22 | * See {@link https://docs.influxdata.com/influxdb/v2.4/api/#operation/GetRoutes } 23 | * @param request - request parameters and body (if supported) 24 | * @param requestOptions - optional transport options 25 | * @returns promise of response 26 | */ 27 | getRoutes( 28 | request?: GetRoutesRequest, 29 | requestOptions?: RequestOptions 30 | ): Promise { 31 | return this.base.request('GET', `/api/v2/`, request, requestOptions) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/onboarding.mjs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | /* 3 | This example setups a new INFLUXDB database with user,organization 4 | and bucket that can be then used in examples. All values that used 5 | for onboarding are defined in ./env.ts . 6 | */ 7 | 8 | import {InfluxDB} from '@influxdata/influxdb-client' 9 | import {SetupAPI} from '@influxdata/influxdb-client-apis' 10 | import {url, username, password, org, bucket, token} from './env.mjs' 11 | 12 | console.log('*** ONBOARDING ***') 13 | const setupApi = new SetupAPI(new InfluxDB({url})) 14 | try { 15 | const {allowed} = await setupApi.getSetup() 16 | if (allowed) { 17 | await setupApi.postSetup({ 18 | body: { 19 | org, 20 | bucket, 21 | username, 22 | password, 23 | token, 24 | }, 25 | }) 26 | console.log(`InfluxDB '${url}' is now onboarded.`) 27 | } else { 28 | console.log(`InfluxDB '${url}' has been already onboarded.`) 29 | } 30 | console.log('\nFinished SUCCESS') 31 | } catch (e) { 32 | console.error(e) 33 | console.log('\nFinished ERROR') 34 | } 35 | -------------------------------------------------------------------------------- /packages/apis/src/generated/ReadyAPI.ts: -------------------------------------------------------------------------------- 1 | import {InfluxDB} from '../../../core/src' 2 | import {APIBase, RequestOptions} from '../APIBase' 3 | import {Ready} from './types' 4 | 5 | export interface GetReadyRequest {} 6 | /** 7 | * Ready API 8 | */ 9 | export class ReadyAPI { 10 | // internal 11 | private base: APIBase 12 | 13 | /** 14 | * Creates ReadyAPI 15 | * @param influxDB - an instance that knows how to communicate with InfluxDB server 16 | */ 17 | constructor(influxDB: InfluxDB) { 18 | this.base = new APIBase(influxDB) 19 | } 20 | /** 21 | * Get the readiness of an instance at startup. 22 | * See {@link https://docs.influxdata.com/influxdb/v2.4/api/#operation/GetReady } 23 | * @param request - request parameters and body (if supported) 24 | * @param requestOptions - optional transport options 25 | * @returns promise of response 26 | */ 27 | getReady( 28 | request?: GetReadyRequest, 29 | requestOptions?: RequestOptions 30 | ): Promise { 31 | return this.base.request('GET', `/ready`, request, requestOptions) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/apis/src/generated/ConfigAPI.ts: -------------------------------------------------------------------------------- 1 | import {InfluxDB} from '../../../core/src' 2 | import {APIBase, RequestOptions} from '../APIBase' 3 | import {Config} from './types' 4 | 5 | export interface GetConfigRequest {} 6 | /** 7 | * Config API 8 | */ 9 | export class ConfigAPI { 10 | // internal 11 | private base: APIBase 12 | 13 | /** 14 | * Creates ConfigAPI 15 | * @param influxDB - an instance that knows how to communicate with InfluxDB server 16 | */ 17 | constructor(influxDB: InfluxDB) { 18 | this.base = new APIBase(influxDB) 19 | } 20 | /** 21 | * Retrieve runtime configuration. 22 | * See {@link https://docs.influxdata.com/influxdb/v2.4/api/#operation/GetConfig } 23 | * @param request - request parameters and body (if supported) 24 | * @param requestOptions - optional transport options 25 | * @returns promise of response 26 | */ 27 | getConfig( 28 | request?: GetConfigRequest, 29 | requestOptions?: RequestOptions 30 | ): Promise { 31 | return this.base.request('GET', `/api/v2/config`, request, requestOptions) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/apis/src/generated/HealthAPI.ts: -------------------------------------------------------------------------------- 1 | import {InfluxDB} from '../../../core/src' 2 | import {APIBase, RequestOptions} from '../APIBase' 3 | import {HealthCheck} from './types' 4 | 5 | export interface GetHealthRequest {} 6 | /** 7 | * Health API 8 | */ 9 | export class HealthAPI { 10 | // internal 11 | private base: APIBase 12 | 13 | /** 14 | * Creates HealthAPI 15 | * @param influxDB - an instance that knows how to communicate with InfluxDB server 16 | */ 17 | constructor(influxDB: InfluxDB) { 18 | this.base = new APIBase(influxDB) 19 | } 20 | /** 21 | * Retrieve the health of the instance. 22 | * See {@link https://docs.influxdata.com/influxdb/v2.4/api/#operation/GetHealth } 23 | * @param request - request parameters and body (if supported) 24 | * @param requestOptions - optional transport options 25 | * @returns promise of response 26 | */ 27 | getHealth( 28 | request?: GetHealthRequest, 29 | requestOptions?: RequestOptions 30 | ): Promise { 31 | return this.base.request('GET', `/health`, request, requestOptions) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/apis/src/generated/SigninAPI.ts: -------------------------------------------------------------------------------- 1 | import {InfluxDB} from '../../../core/src' 2 | import {APIBase, RequestOptions} from '../APIBase' 3 | 4 | export interface PostSigninRequest { 5 | auth?: {user: string; password: string} 6 | } 7 | /** 8 | * Signin API 9 | */ 10 | export class SigninAPI { 11 | // internal 12 | private base: APIBase 13 | 14 | /** 15 | * Creates SigninAPI 16 | * @param influxDB - an instance that knows how to communicate with InfluxDB server 17 | */ 18 | constructor(influxDB: InfluxDB) { 19 | this.base = new APIBase(influxDB) 20 | } 21 | /** 22 | * Create a user session. 23 | * See {@link https://docs.influxdata.com/influxdb/v2.4/api/#operation/PostSignin } 24 | * @param request - request parameters and body (if supported) 25 | * @param requestOptions - optional transport options 26 | * @returns promise of response 27 | */ 28 | postSignin( 29 | request: PostSigninRequest, 30 | requestOptions?: RequestOptions 31 | ): Promise { 32 | return this.base.request('POST', `/api/v2/signin`, request, requestOptions) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/core/src/util/logger.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Logging interface. 3 | */ 4 | export interface Logger { 5 | error(message: string, err?: any): void 6 | warn(message: string, err?: any): void 7 | } 8 | 9 | /** 10 | * Logger that logs to console.out 11 | */ 12 | export const consoleLogger: Logger = { 13 | error(message, error) { 14 | // eslint-disable-next-line no-console 15 | console.error('ERROR: ' + message, error ? error : '') 16 | }, 17 | warn(message, error) { 18 | // eslint-disable-next-line no-console 19 | console.warn('WARN: ' + message, error ? error : '') 20 | }, 21 | } 22 | let provider: Logger = consoleLogger 23 | 24 | export const Log: Logger = { 25 | error(message, error) { 26 | provider.error(message, error) 27 | }, 28 | warn(message, error) { 29 | provider.warn(message, error) 30 | }, 31 | } 32 | 33 | /** 34 | * Sets custom logger. 35 | * @param logger - logger to use 36 | * @returns previous logger 37 | */ 38 | export function setLogger(logger: Logger): Logger { 39 | const previous = provider 40 | provider = logger 41 | return previous 42 | } 43 | -------------------------------------------------------------------------------- /packages/apis/src/generated/FlagsAPI.ts: -------------------------------------------------------------------------------- 1 | import {InfluxDB} from '../../../core/src' 2 | import {APIBase, RequestOptions} from '../APIBase' 3 | import {Flags} from './types' 4 | 5 | export interface GetFlagsRequest {} 6 | /** 7 | * Flags API 8 | */ 9 | export class FlagsAPI { 10 | // internal 11 | private base: APIBase 12 | 13 | /** 14 | * Creates FlagsAPI 15 | * @param influxDB - an instance that knows how to communicate with InfluxDB server 16 | */ 17 | constructor(influxDB: InfluxDB) { 18 | this.base = new APIBase(influxDB) 19 | } 20 | /** 21 | * Return the feature flags for the currently authenticated user. 22 | * See {@link https://docs.influxdata.com/influxdb/v2.4/api/#operation/GetFlags } 23 | * @param request - request parameters and body (if supported) 24 | * @param requestOptions - optional transport options 25 | * @returns promise of response 26 | */ 27 | getFlags( 28 | request?: GetFlagsRequest, 29 | requestOptions?: RequestOptions 30 | ): Promise { 31 | return this.base.request('GET', `/api/v2/flags`, request, requestOptions) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/queryWithParams.mjs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | ////////////////////////////////////////// 3 | // Shows how to use InfluxDB query API. // 4 | ////////////////////////////////////////// 5 | 6 | import {InfluxDB, flux, fluxDuration} from '@influxdata/influxdb-client' 7 | import {url, token, org} from './env.mjs' 8 | 9 | const queryApi = new InfluxDB({url, token}).getQueryApi(org) 10 | const start = fluxDuration('-1m') 11 | const measurement = 'temperature' 12 | const fluxQuery = flux`from(bucket:"my-bucket") 13 | |> range(start: ${start}) 14 | |> filter(fn: (r) => r._measurement == ${measurement})` 15 | console.log('query:', fluxQuery.toString()) 16 | 17 | console.log('*** QUERY ROWS ***') 18 | try { 19 | for await (const {values, tableMeta} of queryApi.iterateRows(fluxQuery)) { 20 | const o = tableMeta.toObject(values) 21 | // console.log(JSON.stringify(o, null, 2)) 22 | console.log( 23 | `${o._time} ${o._measurement} in '${o.location}' (${o.example}): ${o._field}=${o._value}` 24 | ) 25 | } 26 | console.log('\nFinished SUCCESS') 27 | } catch (e) { 28 | console.log('\nFinished ERROR') 29 | } 30 | -------------------------------------------------------------------------------- /examples/query.deno.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env -S deno run --allow-net 2 | ////////////////////////////////////////////////////// 3 | // A modified query.ts example that works with deno // 4 | ////////////////////////////////////////////////////// 5 | 6 | import {InfluxDB} from 'https://cdn.skypack.dev/@influxdata/influxdb-client-browser?dts' 7 | 8 | const url = 'http://localhost:8086' 9 | const token = 'my-token' 10 | const org = 'my-org' 11 | 12 | const queryApi = new InfluxDB({url, token}).getQueryApi(org) 13 | const fluxQuery = 14 | 'from(bucket:"my-bucket" ) |> range(start: 0) |> filter(fn: (r) => r._measurement == "temperature")' 15 | 16 | console.log('** QUERY ROWS ***') 17 | try { 18 | for await (const {values, tableMeta} of queryApi.iterateRows(fluxQuery)) { 19 | const o = tableMeta.toObject(values) 20 | // console.log(JSON.stringify(o, null, 2)) 21 | console.log( 22 | `${o._time} ${o._measurement} in '${o.location}' (${o.example}): ${o._field}=${o._value}` 23 | ) 24 | } 25 | console.log('\nFinished SUCCESS') 26 | } catch (error) { 27 | console.error(error) 28 | console.log('\nFinished ERROR') 29 | } 30 | -------------------------------------------------------------------------------- /scripts/esbuild-gzip-js.ts: -------------------------------------------------------------------------------- 1 | import {mkdir, writeFile} from 'fs/promises' 2 | import {dirname} from 'path' 3 | import {promisify} from 'util' 4 | import {gzip} from 'zlib' 5 | 6 | const compressGz = promisify(gzip) 7 | 8 | export interface BuildResult { 9 | outputFiles?: Array<{path: string; contents: Uint8Array}> 10 | } 11 | /** 12 | * ESBuild onEnd callback that additionally gzips all produced JS files. 13 | */ 14 | export async function esbuildGzipOnEnd(result: BuildResult): Promise { 15 | // gzip js files 16 | await Promise.all( 17 | (result.outputFiles || []) 18 | .filter((x) => x.path.endsWith('js')) 19 | .map(async ({path, contents}) => { 20 | await mkdir(dirname(path), {recursive: true}) 21 | await writeFile(path + '.gz', await compressGz(contents, {level: 9})) 22 | }) 23 | ) 24 | } 25 | 26 | /** ESBuild plugin that gzips output js files */ 27 | export const esbuildGzipOutJsPlugin = { 28 | name: 'gzipJsFiles', 29 | setup: (build: { 30 | onEnd: (callback: (result: BuildResult) => Promise) => void 31 | }) => { 32 | build.onEnd(esbuildGzipOnEnd) 33 | }, 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 InfluxData 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /packages/apis/src/generated/ResourcesAPI.ts: -------------------------------------------------------------------------------- 1 | import {InfluxDB} from '../../../core/src' 2 | import {APIBase, RequestOptions} from '../APIBase' 3 | 4 | export interface GetResourcesRequest {} 5 | /** 6 | * Resources API 7 | */ 8 | export class ResourcesAPI { 9 | // internal 10 | private base: APIBase 11 | 12 | /** 13 | * Creates ResourcesAPI 14 | * @param influxDB - an instance that knows how to communicate with InfluxDB server 15 | */ 16 | constructor(influxDB: InfluxDB) { 17 | this.base = new APIBase(influxDB) 18 | } 19 | /** 20 | * List all known resources. 21 | * See {@link https://docs.influxdata.com/influxdb/v2.4/api/#operation/GetResources } 22 | * @param request - request parameters and body (if supported) 23 | * @param requestOptions - optional transport options 24 | * @returns promise of response 25 | */ 26 | getResources( 27 | request?: GetResourcesRequest, 28 | requestOptions?: RequestOptions 29 | ): Promise { 30 | return this.base.request( 31 | 'GET', 32 | `/api/v2/resources`, 33 | request, 34 | requestOptions 35 | ) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/apis/generator/format.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | import {Operation} from './operationType' 3 | import logger from './logger' 4 | 5 | export function capitalize1(name: string): string { 6 | return name.charAt(0).toUpperCase() + name.slice(1) 7 | } 8 | export function decapitalize1(name: string): string { 9 | return name.charAt(0).toLowerCase() + name.slice(1) 10 | } 11 | // remember what was computed to issue at most one warning 12 | const computedIds: {[key: string]: string} = {} 13 | export function getOperationId(operation: Operation): string { 14 | if (operation.operationId) return operation.operationId as string 15 | else { 16 | let retVal = computedIds[operation.path] 17 | if (!retVal) { 18 | retVal = operation.path 19 | .split('/') 20 | .map((v: string, i: number) => (i ? v : operation.operation)) 21 | .map(capitalize1) 22 | .join('') 23 | logger.warn( 24 | `no operationId defined for: ${operation.operation} ${operation.path} , using: ${retVal})` 25 | ) 26 | computedIds[operation.path] = retVal 27 | } 28 | return retVal 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/apis/generator/operationType.ts: -------------------------------------------------------------------------------- 1 | // type of the operation os operations.json's array 2 | export interface Parameter { 3 | name: string //"Zap-Trace-Span", 4 | description?: string // "OpenTracing span context", 5 | required?: boolean // false, 6 | type: string // "string" 7 | mediaType?: string // "application/json", 8 | } 9 | export interface ResponseBody { 10 | mediaType: string // "application/json", 11 | type: string //"OnboardingResponse" 12 | } 13 | export interface Response { 14 | code: string // "201", "default" 15 | description?: string //"Created default user, bucket, org", 16 | mediaTypes: Array 17 | } 18 | export interface Operation { 19 | server: string //"/api/v2", 20 | path: string //"path": "/setup", 21 | operation: string //"operation": "post", 22 | operationId?: string // "PostSetup", 23 | basicAuth?: boolean //false, 24 | summary?: string // "Set up initial user, org and bucket", 25 | positionalParams: Array 26 | headerParams: Array 27 | queryParams: Array 28 | bodyParam: Omit | null 29 | responses: Array 30 | } 31 | -------------------------------------------------------------------------------- /packages/core/test/fixture/query/simpleResponse.txt: -------------------------------------------------------------------------------- 1 | #datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,dateTime:RFC3339,double,string,string,string 2 | #group,false,false,true,true,false,false,true,true,true 3 | #default,_result,,,,,,,, 4 | ,result,table,_start,_stop,_time,_value,_field,_measurement,location 5 | ,,0,1970-01-01T00:00:00Z,2019-12-12T09:05:37.96237406Z,1970-01-01T00:26:15.995033574Z,55,value,temperature,west 6 | ,,0,1970-01-01T00:00:00Z,2019-12-12T09:05:37.96237406Z,1970-01-01T00:26:16.063594313Z,55,value,temperature,west 7 | ,,0,1970-01-01T00:00:00Z,2019-12-12T09:05:37.96237406Z,1970-01-01T00:26:16.069518557Z,55,value,temperature,west 8 | 9 | #datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,dateTime:RFC3339,string,string,string,string 10 | #group,false,false,true,true,false,false,true,true,true 11 | #default,_result,,,,,,,, 12 | ,result,table,_start,_stop,_time,_value,_field,_measurement,location 13 | ,,1,1970-01-01T00:00:00Z,2019-12-12T09:05:37.96237406Z,1970-01-01T00:26:16.063594313Z,"a,b, 14 | ,c",text,temperature,west 15 | ,,1,1970-01-01T00:00:00Z,2019-12-12T09:05:37.96237406Z,1970-01-01T00:26:16.069518557Z,"a,b, 16 | ,""c",text,temperature,west -------------------------------------------------------------------------------- /packages/core/test/fixture/query/response2.txt: -------------------------------------------------------------------------------- 1 | #datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,dateTime:RFC3339,double,string,string,string 2 | #group,false,false,true,true,false,false,true,true,true 3 | #default,_result,,,,,,,, 4 | ,result,table,_start,_stop,_time,_value,_field,_measurement,location 5 | ,,0,1970-01-01T00:00:00Z,2019-12-12T09:05:37.96237406Z,1970-01-01T00:26:15.995033574Z,55,value,temperature,west 6 | ,,0,1970-01-01T00:00:00Z,2019-12-12T09:05:37.96237406Z,1970-01-01T00:26:16.063594313Z,55,value,temperature,west 7 | ,,0,1970-01-01T00:00:00Z,2019-12-12T09:05:37.96237406Z,1970-01-01T00:26:16.069518557Z,55,value,temperature,west 8 | 9 | #datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,dateTime:RFC3339,string,string,string,string 10 | #group,false,false,true,true,false,false,true,true,true 11 | #default,_result,,,,,,,, 12 | #unsupportedAnnotation 13 | ,result,table,_start,_stop,_time,_value,_field,_measurement,location 14 | ,,1,1970-01-01T00:00:00Z,2019-12-12T09:05:37.96237406Z,1970-01-01T00:26:16.063594313Z,"a,b, 15 | ,c",text,temperature,west 16 | ,,1,1970-01-01T00:00:00Z,2019-12-12T09:05:37.96237406Z,1970-01-01T00:26:16.069518557Z,"a,b, 17 | ,""c",text,temperature,west -------------------------------------------------------------------------------- /packages/core/src/util/utf8Length.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Utf8Length returns an expected length of a string when UTF-8 encoded. 3 | * @param s - input string 4 | * @returns expected count of bytes 5 | */ 6 | export default function utf8Length(s: string): number { 7 | let retVal = s.length 8 | // extends the size with code points (https://en.wikipedia.org/wiki/UTF-8#Encoding) 9 | for (let i = 0; i < s.length; i++) { 10 | const code = s.charCodeAt(i) 11 | /* istanbul ignore else - JS does not count with 4-bytes UNICODE characters at the moment */ 12 | if (code < 0x80) { 13 | continue 14 | } else if (code >= 0x80 && code <= 0x7ff) { 15 | retVal++ 16 | } else if (code >= 0x800 && code <= 0xffff) { 17 | if (code >= 0xd800 && code <= 0xdfff) { 18 | // node.js represents unicode characters above 0xffff by two UTF-16 surrogate halves 19 | // see https://en.wikipedia.org/wiki/UTF-8#Codepage_layout 20 | retVal++ 21 | } else { 22 | retVal += 2 23 | } 24 | } else { 25 | // never happens in node.js 14, the situation can vary in the futures or in deno/browsers 26 | retVal += 3 27 | } 28 | } 29 | return retVal 30 | } 31 | -------------------------------------------------------------------------------- /packages/core/test/unit/util/CollectTablesObserver.ts: -------------------------------------------------------------------------------- 1 | import {FluxResultObserver, FluxTableMetaData} from '../../../src/results' 2 | 3 | export class CollectTablesObserver implements FluxResultObserver { 4 | tables: Array<{index: number; meta: FluxTableMetaData}> = [] 5 | rows: Array<{index: number; row: string[]}> = [] 6 | completed = 0 7 | failed = 0 8 | cancellableSet = false 9 | index = 0 10 | lastMeta: FluxTableMetaData 11 | 12 | resolve?: (value?: void) => void 13 | reject?: (reason?: any) => void 14 | 15 | next(row: string[], meta: FluxTableMetaData): void { 16 | if (this.lastMeta !== meta) { 17 | this.tables.push({index: this.index++, meta}) 18 | this.lastMeta = meta 19 | } 20 | this.rows.push({index: this.index++, row}) 21 | } 22 | 23 | error(error: Error): void { 24 | this.failed++ 25 | if (this.reject) this.reject(error) 26 | } 27 | complete(): void { 28 | this.completed++ 29 | if (this.resolve) this.resolve() 30 | } 31 | 32 | attach( 33 | resolve?: (value?: void) => void, 34 | reject?: (reason?: any) => void 35 | ): CollectTablesObserver { 36 | this.resolve = resolve 37 | this.reject = reject 38 | return this 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/core/test/fixture/query/simpleResponseLines.json: -------------------------------------------------------------------------------- 1 | [ 2 | "#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,dateTime:RFC3339,double,string,string,string", 3 | "#group,false,false,true,true,false,false,true,true,true", 4 | "#default,_result,,,,,,,,", 5 | ",result,table,_start,_stop,_time,_value,_field,_measurement,location", 6 | ",,0,1970-01-01T00:00:00Z,2019-12-12T09:05:37.96237406Z,1970-01-01T00:26:15.995033574Z,55,value,temperature,west", 7 | ",,0,1970-01-01T00:00:00Z,2019-12-12T09:05:37.96237406Z,1970-01-01T00:26:16.063594313Z,55,value,temperature,west", 8 | ",,0,1970-01-01T00:00:00Z,2019-12-12T09:05:37.96237406Z,1970-01-01T00:26:16.069518557Z,55,value,temperature,west", 9 | "", 10 | "#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,dateTime:RFC3339,string,string,string,string", 11 | "#group,false,false,true,true,false,false,true,true,true", 12 | "#default,_result,,,,,,,,", 13 | ",result,table,_start,_stop,_time,_value,_field,_measurement,location", 14 | ",,1,1970-01-01T00:00:00Z,2019-12-12T09:05:37.96237406Z,1970-01-01T00:26:16.063594313Z,\"a,b,\n,c\",text,temperature,west", 15 | ",,1,1970-01-01T00:00:00Z,2019-12-12T09:05:37.96237406Z,1970-01-01T00:26:16.069518557Z,\"a,b,\n,\"\"c\",text,temperature,west" 16 | ] 17 | -------------------------------------------------------------------------------- /packages/core/src/results/stringToLines.ts: -------------------------------------------------------------------------------- 1 | import {CommunicationObserver} from './CommunicationObserver' 2 | 3 | /** 4 | * StringToLines is a transformation that emmits strings for each CSV 5 | * line in the supplied source string. 6 | * @param source - source string 7 | * @param target - target to emmit CSV lines to 8 | * @returns communication obrver to accept Uint8Arrays 9 | */ 10 | export function stringToLines( 11 | source: string, 12 | target: CommunicationObserver 13 | ): void { 14 | let quoted = false 15 | let start = 0 16 | let index = 0 17 | 18 | while (index < source.length) { 19 | const c = source.charCodeAt(index) 20 | if (c === 10) { 21 | if (!quoted) { 22 | /* do not emit CR+LR or LF line ending */ 23 | const end = 24 | index > 0 && source.charCodeAt(index - 1) === 13 ? index - 1 : index 25 | // do not emmit more lines if the processing is already finished 26 | target.next(source.substring(start, end)) 27 | start = index + 1 28 | } 29 | } else if (c === 34 /* " */) { 30 | quoted = !quoted 31 | } 32 | index++ 33 | } 34 | if (start < index) { 35 | target.next(source.substring(start, index)) 36 | } 37 | target.complete() 38 | } 39 | -------------------------------------------------------------------------------- /packages/core/src/results/FluxResultObserver.ts: -------------------------------------------------------------------------------- 1 | import {Cancellable} from '../results/Cancellable' 2 | import {FluxTableMetaData} from './FluxTableMetaData' 3 | 4 | /** 5 | * Observes results of a flux query. 6 | */ 7 | export interface FluxResultObserver { 8 | /** 9 | * Inform about a next record in a table. 10 | * @param row - flux result 11 | * @param tableMeta - actual table metata for the row supplied 12 | * @returns when `false` value is returned and {@link FluxResultObserver.useResume} is defined, 13 | * future calls to `next` are paused until resume is called. 14 | */ 15 | next(row: T, tableMeta: FluxTableMetaData): void | boolean 16 | /** 17 | * Signalizes processing error. 18 | */ 19 | error(error: Error): void 20 | /** 21 | * Signalizes completition. 22 | */ 23 | complete(): void 24 | /** 25 | * Setups cancellable that can abort flux result processing. 26 | */ 27 | useCancellable?: (cancellable: Cancellable) => void 28 | 29 | /** 30 | * Setups a callback that resumes reading of next data, it is called whenever 31 | * {@link FluxResultObserver.next} returns `false`. 32 | * 33 | * @param resume - a function that will resume reading of next data when called 34 | */ 35 | useResume?: (resume: () => void) => void 36 | } 37 | -------------------------------------------------------------------------------- /examples/httpErrorHandled.mjs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | /////////////////////////////////////////////////////////// 3 | // Shows how to handle InfluxDB write API - HTTP Errors. // 4 | // To be run against cloud account // 5 | /////////////////////////////////////////////////////////// 6 | 7 | import {InfluxDB} from '@influxdata/influxdb-client' 8 | import {url, token, org, bucket} from './env.mjs' 9 | 10 | console.log('*** FORCE AND HANDLE HTTP ERROR ***') 11 | 12 | const writeApi = new InfluxDB({url, token}).getWriteApi(org, bucket, 'ns') 13 | 14 | try { 15 | await writeApi.writeRecord('asdf') //invalid lineprotocol 16 | await writeApi.close() 17 | } catch (e) { 18 | if (e.statusCode !== 400) { 19 | throw new Error(`Expected HTTP 400 but received ${e.statusCode}`) 20 | } 21 | console.log() 22 | console.log('Handle HTTP Error') 23 | console.log(`Caught expected HTTP ${e.statusCode}`) 24 | console.log(` At: ${e.headers.date}`) 25 | console.log(` During request: ${e.headers['x-influxdb-request-id']}`) 26 | console.log(` On build: ${e.headers['x-influxdb-build']}`) 27 | console.log(` Traceable: ${e.headers['trace-id']}`) 28 | console.log( 29 | ` Can retry: ${e._retryAfter === 0 ? false : e._retryAfter}` 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /packages/apis/src/generated/TelegrafAPI.ts: -------------------------------------------------------------------------------- 1 | import {InfluxDB} from '../../../core/src' 2 | import {APIBase, RequestOptions} from '../APIBase' 3 | import {TelegrafPlugins} from './types' 4 | 5 | export interface GetTelegrafPluginsRequest { 6 | /** The type of plugin desired. */ 7 | type?: string 8 | } 9 | /** 10 | * Telegraf API 11 | */ 12 | export class TelegrafAPI { 13 | // internal 14 | private base: APIBase 15 | 16 | /** 17 | * Creates TelegrafAPI 18 | * @param influxDB - an instance that knows how to communicate with InfluxDB server 19 | */ 20 | constructor(influxDB: InfluxDB) { 21 | this.base = new APIBase(influxDB) 22 | } 23 | /** 24 | * List all Telegraf plugins. 25 | * See {@link https://docs.influxdata.com/influxdb/v2.4/api/#operation/GetTelegrafPlugins } 26 | * @param request - request parameters and body (if supported) 27 | * @param requestOptions - optional transport options 28 | * @returns promise of response 29 | */ 30 | getTelegrafPlugins( 31 | request?: GetTelegrafPluginsRequest, 32 | requestOptions?: RequestOptions 33 | ): Promise { 34 | return this.base.request( 35 | 'GET', 36 | `/api/v2/telegraf/plugins${this.base.queryString(request, ['type'])}`, 37 | request, 38 | requestOptions 39 | ) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/apis/generator/typesCollector.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Collects types that must be imported for a generated API. 3 | */ 4 | export default class TypesCollector { 5 | types: {[key: string]: boolean} = {} 6 | add(type: string): void { 7 | if (type && type.charAt(0).toUpperCase() === type.charAt(0)) { 8 | if (type.startsWith('{') || type.startsWith('Array<{')) { 9 | // anonymous type; process references to custom types in it 10 | // see typesCollector.test.ts 11 | const customTypeRegExp = / ([A-Z][A-Za-z0-9-_| ]*);\n/g 12 | let match: RegExpExecArray | null 13 | while ((match = customTypeRegExp.exec(type)) !== null) { 14 | // console.log('match[1]', match[1], customTypeRegExp.lastIndex) 15 | this.add(match[1]) 16 | } 17 | } else if (type.endsWith('[]')) { 18 | this.types[type.substring(0, type.length - 2)] = true 19 | } else if (type.includes('|')) { 20 | type 21 | .split('|') 22 | .map((x) => x.trim()) 23 | .forEach((x) => this.add(x)) 24 | } else { 25 | this.types[type] = true 26 | } 27 | } 28 | } 29 | toString(): string { 30 | return Object.keys(this.types).sort().join(', ') 31 | } 32 | hasTypes(): boolean { 33 | return !!Object.keys(this.types).length 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/apis/src/generated/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types' 2 | export * from './RootAPI' 3 | export * from './AuthorizationsAPI' 4 | export * from './BackupAPI' 5 | export * from './BucketsAPI' 6 | export * from './ChecksAPI' 7 | export * from './ConfigAPI' 8 | export * from './DashboardsAPI' 9 | export * from './DbrpsAPI' 10 | export * from './DebugAPI' 11 | export * from './DeleteAPI' 12 | export * from './FlagsAPI' 13 | export * from './HealthAPI' 14 | export * from './LabelsAPI' 15 | export * from './MeAPI' 16 | export * from './MetricsAPI' 17 | export * from './NotificationEndpointsAPI' 18 | export * from './NotificationRulesAPI' 19 | export * from './OrgsAPI' 20 | export * from './PingAPI' 21 | export * from './QueryAPI' 22 | export * from './ReadyAPI' 23 | export * from './RemotesAPI' 24 | export * from './ReplicationsAPI' 25 | export * from './ResourcesAPI' 26 | export * from './RestoreAPI' 27 | export * from './ScrapersAPI' 28 | export * from './ScriptsAPI' 29 | export * from './SetupAPI' 30 | export * from './SigninAPI' 31 | export * from './SignoutAPI' 32 | export * from './SourcesAPI' 33 | export * from './StacksAPI' 34 | export * from './TasksAPI' 35 | export * from './TelegrafAPI' 36 | export * from './TelegrafsAPI' 37 | export * from './TemplatesAPI' 38 | export * from './UsersAPI' 39 | export * from './VariablesAPI' 40 | export * from './WriteAPI' 41 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "parserOptions": { 4 | "sourceType": "module", 5 | "ecmaFeatures": {} 6 | }, 7 | "plugins": [ 8 | "@typescript-eslint/eslint-plugin", 9 | "prettier", 10 | "eslint-plugin-tsdoc" 11 | ], 12 | "env": { 13 | "node": true, 14 | "es6": true, 15 | "mocha": true 16 | }, 17 | "extends": [ 18 | "eslint:recommended", 19 | "plugin:@typescript-eslint/recommended", 20 | "plugin:prettier/recommended" 21 | ], 22 | "rules": { 23 | "no-console": "off", 24 | "@typescript-eslint/naming-convention": [ 25 | "error", 26 | { 27 | "selector": "variable", 28 | "format": ["camelCase", "UPPER_CASE"], 29 | "filter": { 30 | "regex": "^DEFAULT_|^Log$", 31 | "match": false 32 | }, 33 | "leadingUnderscore": "allow", 34 | "trailingUnderscore": "allow" 35 | }, 36 | { 37 | "selector": "typeLike", 38 | "format": ["PascalCase"] 39 | } 40 | ], 41 | "@typescript-eslint/no-explicit-any": "off", 42 | "@typescript-eslint/no-unused-vars": [ 43 | "error", 44 | {"varsIgnorePattern": "^_", "argsIgnorePattern": "^_"} 45 | ], 46 | "@typescript-eslint/no-empty-function": "off", 47 | "tsdoc/syntax": "warn", 48 | "@typescript-eslint/no-empty-interface": "off" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /packages/giraffe/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * The `@influxdata/influxdb-client-giraffe` package transforms InfluxDB (Flux) query results 3 | * to a format that is used by {@link https://github.com/influxdata/giraffe | Giraffe } to visualize the data. 4 | * 5 | * @remarks 6 | * The main goal of this package is to provide an efficient {@link @influxdata/influxdb-client-giraffe!queryToTable} 7 | * function that executes a Flux query against InfluxDB (v2) and returns a Table that is then directly suitable 8 | * as a data input of various Giraffe visualizations. 9 | * 10 | * ```jsx 11 | * import {InfluxDB} from '@influxdata/influxdb-client' 12 | * import {queryToTable} from '@influxdata/influxdb-client-giraffe' 13 | * import {newTable, Plot} from '@influxdata/giraffe' 14 | * ... 15 | * const queryApi = new InfluxDB({url, token}).getQueryApi(org) 16 | * const table = await queryToTable( 17 | * api, 18 | * 'from(bucket: "my-bucket") |> range(start: -30d)', 19 | * newTable 20 | * ) 21 | * ... 22 | * const config = {table, ...} 23 | * 24 | * ... 25 | * ``` 26 | * 27 | * See also {@link https://github.com/influxdata/influxdb-client-js/tree/master/examples | InfluxDB v2 client examples} 28 | * and {@link https://influxdata.github.io/giraffe/ | Giraffe storybook }. 29 | * 30 | * @packageDocumentation 31 | */ 32 | export * from './queryTable' 33 | export * from './csvToTable' 34 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # **Releasing a new version** 2 | # Ensure that: 3 | # - You have administrator access to this repo on GitHub 4 | # - You have permissions to publish to the [influxdata](https://www.npmjs.com/org/influxdata) organization on npm 5 | # - You are on `master` and the working tree is clean 6 | # Then run the publish target with VERSION specified: 7 | # ``` 8 | # make publish VERSION=1.8.0 9 | # ``` 10 | .DEFAULT_GOAL := help 11 | 12 | help: 13 | @echo "Please use \`make ' where is one of" 14 | @echo "" 15 | @echo " publish to publish packages to specified version by VERSION property. make publish VERSION=1.1.0" 16 | @echo "" 17 | 18 | publish: 19 | $(if $(VERSION),,$(error VERSION is not defined. Pass via "make publish VERSION=1.1.0")) 20 | git checkout master 21 | git pull 22 | yarn install --frozen-lockfile 23 | node scripts/change-version.js 24 | yarn run build 25 | yarn run test 26 | @echo "Publishing $(VERSION)..." 27 | git commit -am "chore(release): prepare to release influxdb-client-js-$(VERSION)" 28 | npx lerna publish $(VERSION) 29 | @echo "Publish successful" 30 | @echo "" 31 | @echo "Next steps:" 32 | @echo " - publish updated API documentation by: \"yarn apidoc && yarn apidoc:gh-pages\"" 33 | @echo " - add new version to CHANGELOG.md" 34 | @echo " - push changes to repository by : \"git commit -am 'chore(release): prepare to next development iteration [skip CI]' && git push\"" 35 | @echo "" 36 | -------------------------------------------------------------------------------- /examples/rxjs-query.ts: -------------------------------------------------------------------------------- 1 | #!./node_modules/.bin/esr 2 | //////////////////////////////////////////////////// 3 | // Shows how to use InfluxDB query API with rxjs. // 4 | //////////////////////////////////////////////////// 5 | 6 | import {InfluxDB} from '@influxdata/influxdb-client' 7 | import {from} from 'rxjs' 8 | import {map} from 'rxjs/operators' 9 | import {url, token, org} from './env.mjs' 10 | 11 | const queryApi = new InfluxDB({url, token}).getQueryApi(org) 12 | 13 | const fluxQuery = 14 | 'from(bucket:"my-bucket") |> range(start: -1d) |> filter(fn: (r) => r._measurement == "temperature")' 15 | 16 | console.log('*** QUERY ROWS ***') 17 | // performs query and receive line table metadata and rows 18 | // https://docs.influxdata.com/influxdb/latest/reference/syntax/annotated-csv/ 19 | from(queryApi.rows(fluxQuery)) 20 | .pipe(map(({values, tableMeta}) => tableMeta.toObject(values))) 21 | .subscribe({ 22 | next(o) { 23 | console.log( 24 | `${o._time} ${o._measurement} in '${o.location}' (${o.example}): ${o._field}=${o._value}` 25 | ) 26 | }, 27 | error(e) { 28 | console.error(e) 29 | console.log('\nFinished ERROR') 30 | }, 31 | complete() { 32 | console.log('\nFinished SUCCESS') 33 | }, 34 | }) 35 | 36 | // performs query and receive line results in annotated csv format 37 | // https://docs.influxdata.com/influxdb/latest/reference/syntax/annotated-csv/ 38 | // from(queryApi.lines(fluxQuery)).forEach(console.log) 39 | -------------------------------------------------------------------------------- /packages/core/src/observable/types.ts: -------------------------------------------------------------------------------- 1 | /** Type of {@link Observer.next} */ 2 | export type ObserverNext = (value: T) => void 3 | /** Type of {@link Observer.error} */ 4 | export type ObserverError = (e: any) => void 5 | /** Type of {@link Observer.complete} */ 6 | export type ObserverComplete = () => void 7 | 8 | /** Observer mimics Observer from ECMAScript TC39 Observable proposal */ 9 | export interface Observer { 10 | next: ObserverNext 11 | error: ObserverError 12 | complete: ObserverComplete 13 | } 14 | 15 | export interface Subscribable { 16 | subscribe(observer: Partial>): Subscription 17 | } 18 | 19 | /** 20 | * An observable that aligns with the 21 | * {@link https://github.com/tc39/proposal-observable | TC39 observable proposal} and 22 | * can be consumed by other observable libraries like 23 | * {@link https://github.com/ReactiveX/rxjs | rx js} or 24 | * {@link https://github.com/zenparsing/zen-observable | zen-observable}. 25 | */ 26 | export interface Observable { 27 | subscribe(): Subscription 28 | subscribe(observer: Partial>): Subscription 29 | subscribe( 30 | next: ObserverNext, 31 | error?: ObserverError, 32 | complete?: ObserverComplete 33 | ): Subscription 34 | [Symbol.observable](): Subscribable 35 | } 36 | 37 | /** Subscription mimics Subscription from ECMAScript TC39 Observable proposal */ 38 | export interface Subscription { 39 | readonly closed: boolean 40 | unsubscribe(): void 41 | } 42 | -------------------------------------------------------------------------------- /packages/core/test/unit/results/LineSplitter.test.ts: -------------------------------------------------------------------------------- 1 | import {expect} from 'chai' 2 | import {LineSplitter} from '../../../src/results' 3 | import lineSplitterTables from '../../fixture/lineSplitterTables.json' 4 | 5 | interface LineSplitterTest { 6 | line?: string 7 | result: string[] 8 | } 9 | 10 | describe('LineSplitter', () => { 11 | it('does not reuse OOTB', () => { 12 | const subject = new LineSplitter() 13 | expect(subject.reuse).to.be.false 14 | }) 15 | ;[true, false].forEach((reuse: boolean) => { 16 | describe(`with reuse=${reuse}`, () => { 17 | const subject = new LineSplitter() 18 | let last: string[] | undefined = undefined 19 | ;(lineSplitterTables as Array).forEach( 20 | (test: LineSplitterTest) => { 21 | subject.reuse = reuse 22 | expect(subject.reuse).to.be.equal(reuse) 23 | it(`creates values from: ${test.line}`, () => { 24 | const values = subject.splitLine(test.line) 25 | let result: string[] 26 | if (reuse) { 27 | if (last) expect(values).to.be.equal(values) 28 | result = values.slice(0, subject.lastSplitLength) 29 | } else { 30 | expect(subject.lastSplitLength).to.equal(test.result.length) 31 | result = values 32 | } 33 | expect(result).to.deep.equal(test.result) 34 | last = result 35 | }) 36 | } 37 | ) 38 | }) 39 | }) 40 | }) 41 | -------------------------------------------------------------------------------- /packages/core/src/util/escape.ts: -------------------------------------------------------------------------------- 1 | function createEscaper( 2 | characters: string, 3 | replacements: string[] 4 | ): (value: string) => string { 5 | return function (value: string): string { 6 | let retVal = '' 7 | let from = 0 8 | let i = 0 9 | while (i < value.length) { 10 | const found = characters.indexOf(value[i]) 11 | if (found >= 0) { 12 | retVal += value.substring(from, i) 13 | retVal += replacements[found] 14 | from = i + 1 15 | } 16 | i++ 17 | } 18 | if (from == 0) { 19 | return value 20 | } else if (from < value.length) { 21 | retVal += value.substring(from, value.length) 22 | } 23 | return retVal 24 | } 25 | } 26 | function createQuotedEscaper( 27 | characters: string, 28 | replacements: string[] 29 | ): (value: string) => string { 30 | const escaper = createEscaper(characters, replacements) 31 | return (value: string): string => '"' + escaper(value) + '"' 32 | } 33 | 34 | /** 35 | * Provides functions escape specific parts in InfluxDB line protocol. 36 | */ 37 | export const escape = { 38 | /** 39 | * Measurement escapes measurement names. 40 | */ 41 | measurement: createEscaper(', \n\r\t', ['\\,', '\\ ', '\\n', '\\r', '\\t']), 42 | /** 43 | * Quoted escapes quoted values, such as database names. 44 | */ 45 | quoted: createQuotedEscaper('"\\', ['\\"', '\\\\']), 46 | 47 | /** 48 | * TagEscaper escapes tag keys, tag values, and field keys. 49 | */ 50 | tag: createEscaper(', =\n\r\t', ['\\,', '\\ ', '\\=', '\\n', '\\r', '\\t']), 51 | } 52 | -------------------------------------------------------------------------------- /packages/core/test/unit/util/logger.test.ts: -------------------------------------------------------------------------------- 1 | import {expect} from 'chai' 2 | import {Log, setLogger, consoleLogger} from '../../../src/util/logger' 3 | 4 | describe('Logger', () => { 5 | ;[{message: ' hey', error: 'you'}, {message: ' hey'}].forEach( 6 | (data) => { 7 | it(`uses custom logger's error (${Object.keys(data).length})`, () => { 8 | let args: Array | undefined 9 | setLogger({ 10 | error(message, error): void { 11 | // eslint-disable-next-line prefer-rest-params 12 | args = Array.from(arguments) 13 | consoleLogger.error(message, error) 14 | }, 15 | warn(message, error): void { 16 | consoleLogger.warn(message, error) 17 | }, 18 | }) 19 | Log.error.call(Log, data.message, data.error) 20 | expect(args).to.be.deep.equal([data.message, data.error]) 21 | }) 22 | it(`uses custom logger's warn (${Object.keys(data).length})`, () => { 23 | let args: Array | undefined 24 | setLogger({ 25 | error(message, error): void { 26 | consoleLogger.error(message, error) 27 | }, 28 | warn(message, error): void { 29 | // eslint-disable-next-line prefer-rest-params 30 | args = Array.from(arguments) 31 | consoleLogger.warn(message, error) 32 | }, 33 | }) 34 | 35 | Log.warn.call(Log, data.message, data.error) 36 | expect(args).to.be.deep.equal([data.message, data.error]) 37 | }) 38 | } 39 | ) 40 | }) 41 | -------------------------------------------------------------------------------- /packages/core-browser/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@influxdata/influxdb-client-browser", 3 | "version": "1.35.0", 4 | "description": "InfluxDB 2.x client for browser", 5 | "scripts": { 6 | "apidoc:extract": "echo \"Nothing to do\"", 7 | "test": "echo \"Nothing to do\"", 8 | "test:ci": "echo \"Nothing to do\"", 9 | "build": "yarn run clean && cpr ../core/dist ./dist", 10 | "clean": "rimraf dist" 11 | }, 12 | "main": "dist/index.browser.js", 13 | "module": "dist/index.browser.mjs", 14 | "module:browser": "dist/index.browser.mjs", 15 | "browser": "dist/index.browser.js", 16 | "types": "dist/index.d.ts", 17 | "exports": { 18 | ".": { 19 | "types": "./dist/index.d.ts", 20 | "browser": { 21 | "import": "./dist/index.browser.mjs", 22 | "require": "./dist/index.browser.js", 23 | "script": "./dist/influxdb.js", 24 | "umd": "./dist/index.browser.js" 25 | }, 26 | "deno": "./dist/index.browser.mjs", 27 | "import": "./dist/index.browser.mjs", 28 | "require": "./dist/index.browser.js" 29 | } 30 | }, 31 | "homepage": "https://github.com/influxdata/influxdb-client-js", 32 | "repository": { 33 | "type": "git", 34 | "url": "git+https://github.com/influxdata/influxdb-client-js", 35 | "directory": "packages/core-browser" 36 | }, 37 | "keywords": [ 38 | "influxdb", 39 | "influxdata" 40 | ], 41 | "author": { 42 | "name": "Pavel Zavora" 43 | }, 44 | "license": "MIT", 45 | "devDependencies": { 46 | "@influxdata/influxdb-client": "^1.35.0", 47 | "cpr": "^3.0.1", 48 | "rimraf": "^5.0.1" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /packages/giraffe/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'tsup' 2 | import {esbuildGzipOutJsPlugin} from '../../scripts/esbuild-gzip-js' 3 | import pkg from './package.json' 4 | 5 | const minify = !(process.env.ESBUILD_MINIFY === '0') 6 | 7 | const outFiles = { 8 | esm: pkg.exports['.'].import, 9 | cjs: pkg.exports['.'].require, 10 | } 11 | 12 | export default defineConfig({ 13 | entry: ['src/index.ts'], 14 | sourcemap: true, 15 | format: ['cjs', 'esm'], 16 | globalName: 'g', 17 | dts: true, 18 | minify, 19 | target: ['es2018'], 20 | platform: 'node', 21 | splitting: false, 22 | esbuildOptions(options, {format}) { 23 | options.outdir = undefined 24 | options.outfile = outFiles[format] 25 | if (format === 'cjs') { 26 | // esbuild does not generate UMD format OOTB, see https://github.com/evanw/esbuild/issues/507 27 | // the following code is a trick to generate UMD output in place of cjs 28 | options.format = 'iife' 29 | options.banner = { 30 | js: `(function (global, factory) { 31 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 32 | typeof define === 'function' && define.amd ? define(['exports'], factory) : 33 | (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["@influxdata/influxdb-client-giraffe"] = {})); 34 | })(this, (function (exports) {`, 35 | } 36 | options.footer = { 37 | js: `Object.defineProperty(exports, '__esModule', { value: true });Object.assign(exports, ${options.globalName});}));`, 38 | } 39 | } 40 | }, 41 | esbuildPlugins: [esbuildGzipOutJsPlugin], 42 | }) 43 | -------------------------------------------------------------------------------- /packages/apis/generator/index.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | import fs from 'fs' 3 | import path from 'path' 4 | import {Operation} from './operationType' 5 | import {generateApi} from './generateApi' 6 | import logger from './logger' 7 | 8 | const operations: Array = JSON.parse( 9 | fs.readFileSync( 10 | path.join( 11 | __dirname, 12 | '..', 13 | 'resources', 14 | process.argv[2] || 'operations.json' 15 | ), 16 | 'utf-8' 17 | ) 18 | ) as Array 19 | 20 | const targetDir = path.join( 21 | __dirname, 22 | '..', 23 | 'src', 24 | process.argv[3] || 'generated' 25 | ) 26 | 27 | // reduce operations to apis 28 | const apis = operations.reduce( 29 | (acc: {[api: string]: Array}, val: Operation) => { 30 | if ( 31 | val.path === '/ready' || 32 | val.path === '/health' || 33 | val.path === '/ping' 34 | ) { 35 | // due to a bug in the swagger parser, we don't have correct server path's 36 | val.server = '' 37 | } 38 | const apiName = val.path.split('/')[1] 39 | ;(acc[apiName] || (acc[apiName] = [])).push(val) 40 | return acc 41 | }, 42 | {} as {[api: string]: Array} 43 | ) 44 | const indexContent = ["export * from './types'"] 45 | for (const key of Object.keys(apis).sort()) { 46 | const {apiName, code} = generateApi(key, apis[key]) 47 | logger.info(apiName + '.ts') 48 | indexContent.push(`export * from './${apiName}'`) 49 | fs.writeFileSync(path.join(targetDir, apiName + '.ts'), code) 50 | } 51 | logger.info('index.ts') 52 | fs.writeFileSync( 53 | path.join(targetDir, 'index.ts'), 54 | indexContent.join('\n') + '\n' 55 | ) 56 | -------------------------------------------------------------------------------- /packages/apis/tsup.config.browser.ts: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'tsup' 2 | import {esbuildGzipOutJsPlugin} from '../../scripts/esbuild-gzip-js' 3 | import pkg from './package.json' 4 | 5 | const minify = !(process.env.ESBUILD_MINIFY === '0') 6 | 7 | const outFiles = { 8 | cjs: pkg.exports['.'].browser.umd, 9 | iife: pkg.exports['.'].browser.script, 10 | } 11 | 12 | export default defineConfig({ 13 | entry: ['src/index.ts'], 14 | sourcemap: true, 15 | format: ['cjs', 'iife'], 16 | globalName: 'influxdbApis', 17 | dts: false, 18 | minify, 19 | target: ['es2018'], 20 | platform: 'browser', 21 | splitting: false, 22 | esbuildOptions(options, {format}) { 23 | options.outdir = undefined 24 | options.outfile = outFiles[format] 25 | if (format === 'cjs') { 26 | // esbuild does not generate UMD format OOTB, see https://github.com/evanw/esbuild/issues/507 27 | // the following code is a trick to generate UMD output in place of cjs 28 | options.format = 'iife' 29 | options.banner = { 30 | js: `(function (global, factory) { 31 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 32 | typeof define === 'function' && define.amd ? define(['exports'], factory) : 33 | (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["@influxdata/influxdb-client-apis"] = {})); 34 | })(this, (function (exports) {`, 35 | } 36 | options.footer = { 37 | js: `Object.defineProperty(exports, '__esModule', { value: true });Object.assign(exports, ${options.globalName});}));`, 38 | } 39 | } 40 | }, 41 | esbuildPlugins: [esbuildGzipOutJsPlugin], 42 | }) 43 | -------------------------------------------------------------------------------- /packages/core/src/results/CommunicationObserver.ts: -------------------------------------------------------------------------------- 1 | import {Cancellable} from './Cancellable' 2 | /** 3 | * Type of HTTP headers. 4 | */ 5 | export type HttpHeaders = {[header: string]: string | string[] | undefined} 6 | export {HttpHeaders as Headers} 7 | 8 | /** 9 | * Informs about a start of response processing. 10 | * @param headers - response HTTP headers 11 | * @param statusCode - response status code 12 | */ 13 | export type ResponseStartedFn = ( 14 | headers: HttpHeaders, 15 | statusCode?: number 16 | ) => void 17 | 18 | /** 19 | * Observes communication with the server. 20 | */ 21 | export interface CommunicationObserver { 22 | /** 23 | * Data chunk received, can be called multiple times. 24 | * @param data - data 25 | * @returns when `false` value is returned and {@link CommunicationObserver.useResume} is defined, 26 | * future calls to `next` are paused until resume is called. 27 | */ 28 | next(data: T): void | boolean 29 | /** 30 | * Communication ended with an error. 31 | */ 32 | error(error: Error): void 33 | /** 34 | * Communication was successful. 35 | */ 36 | complete(): void 37 | /** 38 | * Informs about a start of response processing. 39 | */ 40 | responseStarted?: ResponseStartedFn 41 | /** 42 | * Setups cancelllable for this communication. 43 | */ 44 | useCancellable?: (cancellable: Cancellable) => void 45 | /** 46 | * Setups a callback that resumes reading of next data, it is called whenever 47 | * {@link CommunicationObserver.next} returns `false`. 48 | * 49 | * @param resume - a function that will resume reading of next data when called 50 | */ 51 | useResume?: (resume: () => void) => void 52 | } 53 | -------------------------------------------------------------------------------- /packages/core/src/results/chunksToLinesIterable.ts: -------------------------------------------------------------------------------- 1 | import {ChunkCombiner, createTextDecoderCombiner} from './chunkCombiner' 2 | 3 | /** 4 | * ChunksToLinesIterable is a transformation that accepts 5 | * an iterable of Uint8Array instances and returns iterable of lines. 6 | * @param source - iterable of transport buffers 7 | * @param chunkCombiner - chunk combiner 8 | * @returns iterable of lines 9 | */ 10 | export async function* chunksToLinesIterable( 11 | source: AsyncIterable, 12 | chunkCombiner?: ChunkCombiner 13 | ): AsyncIterableIterator { 14 | const chunks = chunkCombiner ?? createTextDecoderCombiner() 15 | let previous: Uint8Array | undefined 16 | let quoted = false 17 | 18 | for await (let chunk of source) { 19 | let index: number 20 | let start = 0 21 | if (previous) { 22 | index = previous.length 23 | chunk = chunks.concat(previous, chunk) 24 | } else { 25 | index = 0 26 | } 27 | while (index < chunk.length) { 28 | const c = chunk[index] 29 | if (c === 10) { 30 | if (!quoted) { 31 | /* do not emit CR+LR or LF line ending */ 32 | const end = index > 0 && chunk[index - 1] === 13 ? index - 1 : index 33 | yield chunks.toUtf8String(chunk, start, end) 34 | start = index + 1 35 | } 36 | } else if (c === 34 /* " */) { 37 | quoted = !quoted 38 | } 39 | index++ 40 | } 41 | if (start < chunk.length) { 42 | previous = chunks.copy(chunk, start, chunk.length) 43 | } else { 44 | previous = undefined 45 | } 46 | } 47 | if (previous) { 48 | yield chunks.toUtf8String(previous, 0, previous.length) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /packages/core/src/impl/completeCommunicationObserver.ts: -------------------------------------------------------------------------------- 1 | import {CommunicationObserver, Headers} from '../results' 2 | 3 | type CompleteObserver = Omit< 4 | Required>, 5 | 'useCancellable' | 'useResume' 6 | > & 7 | Pick, 'useResume' | 'useCancellable'> 8 | 9 | export default function completeCommunicationObserver( 10 | callbacks: Partial> = {} 11 | ): CompleteObserver { 12 | let state = 0 13 | const retVal: CompleteObserver = { 14 | next: (data: any): void | boolean => { 15 | if ( 16 | state === 0 && 17 | callbacks.next && 18 | data !== null && 19 | data !== undefined 20 | ) { 21 | return callbacks.next(data) 22 | } 23 | }, 24 | error: (error: Error): void => { 25 | /* istanbul ignore else propagate error at most once */ 26 | if (state === 0) { 27 | state = 1 28 | /* istanbul ignore else safety check */ 29 | if (callbacks.error) callbacks.error(error) 30 | } 31 | }, 32 | complete: (): void => { 33 | if (state === 0) { 34 | state = 2 35 | /* istanbul ignore else safety check */ 36 | if (callbacks.complete) callbacks.complete() 37 | } 38 | }, 39 | responseStarted: (headers: Headers, statusCode?: number): void => { 40 | if (callbacks.responseStarted) 41 | callbacks.responseStarted(headers, statusCode) 42 | }, 43 | } 44 | if (callbacks.useCancellable) { 45 | retVal.useCancellable = callbacks.useCancellable.bind(callbacks) 46 | } 47 | if (callbacks.useResume) { 48 | retVal.useResume = callbacks.useResume.bind(callbacks) 49 | } 50 | return retVal 51 | } 52 | -------------------------------------------------------------------------------- /packages/apis/scripts/fetchSwaggerFiles.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-var-requires */ 2 | /* eslint-disable no-console */ 3 | /* eslint-disable @typescript-eslint/explicit-function-return-type */ 4 | const https = require('https') 5 | const path = require('path') 6 | const {writeFile} = require('fs/promises') 7 | 8 | function downloadFile(url) { 9 | return new Promise((resolve, reject) => { 10 | https 11 | .get(url, function (res) { 12 | const data = [] 13 | res 14 | .on('data', (chunk) => { 15 | data.push(chunk) 16 | }) 17 | .on('end', () => { 18 | resolve(Buffer.concat(data)) 19 | }) 20 | }) 21 | .on('error', reject) 22 | }) 23 | } 24 | 25 | const FILES = [ 26 | { 27 | file: 'resources/oss.yml', 28 | url: 'https://raw.githubusercontent.com/influxdata/openapi/master/contracts/oss.yml', 29 | }, 30 | { 31 | file: 'resources/invocable-scripts.yml', 32 | url: 'https://raw.githubusercontent.com/influxdata/openapi/master/contracts/invocable-scripts.yml', 33 | }, 34 | { 35 | file: 'resources/cloud.yml', 36 | url: 'https://raw.githubusercontent.com/influxdata/openapi/master/contracts/cloud.yml', 37 | }, 38 | ] 39 | async function downloadFiles() { 40 | for (const {file, url} of FILES) { 41 | console.info(url) 42 | const content = await downloadFile(url) 43 | const fullPath = path.join(__dirname, '..', file) 44 | await writeFile(fullPath, content) 45 | console.log('=>', fullPath, content.length) 46 | } 47 | } 48 | 49 | downloadFiles() 50 | .then(() => console.log('\nFinished SUCCESS')) 51 | .catch((error) => { 52 | console.error(error) 53 | console.log('\nFinished ERROR') 54 | process.exitCode = 1 55 | }) 56 | -------------------------------------------------------------------------------- /packages/core/test/unit/results/chunkCombiner.test.ts: -------------------------------------------------------------------------------- 1 | import {expect} from 'chai' 2 | import {createTextDecoderCombiner} from '../../../src/results' 3 | 4 | describe('createTextDecoderCombiner', () => { 5 | const pureJsChunkCombiner = createTextDecoderCombiner() 6 | it('concatenates chunks', () => { 7 | expect( 8 | pureJsChunkCombiner.concat( 9 | Uint8Array.from([1, 2]), 10 | Uint8Array.from([3, 4]) 11 | ) 12 | ).is.deep.equal(Uint8Array.from([1, 2, 3, 4])) 13 | expect( 14 | pureJsChunkCombiner.concat(Uint8Array.from([]), Uint8Array.from([3, 4])) 15 | ).is.deep.equal(Uint8Array.from([3, 4])) 16 | }) 17 | it('copies chunks', () => { 18 | const src = Uint8Array.from([1, 2]) 19 | const copy = pureJsChunkCombiner.copy(src, 1, 2) 20 | expect(copy).is.deep.equal(Uint8Array.from([2])) 21 | src[1] = 3 22 | expect(copy[0]).is.equal(2) 23 | }) 24 | // see examples in https://en.wikipedia.org/wiki/UTF-8 25 | const chunks = [ 26 | ...[0, 1, 2, 3, 4, 5, 6, 7].map((num) => [ 27 | String.fromCharCode(num << 4), 28 | Uint8Array.from([num << 4]), 29 | ]), 30 | ['$', Uint8Array.from([0x24])], 31 | ['\u{A2}', Uint8Array.from([0xc2, 0xa2])], 32 | ['\u{4FF}', Uint8Array.from([0xd3, 0xbf])], 33 | ['\u{939}', Uint8Array.from([0xe0, 0xa4, 0xb9])], 34 | ['\u{10348}', Uint8Array.from([0xf0, 0x90, 0x8d, 0x88])], 35 | ] 36 | chunks.forEach(([str, chunk]) => { 37 | it(`utf-8 encodes chunk ${JSON.stringify(str)}`, () => { 38 | // console.log(Buffer.from(str as string, 'utf8')) 39 | const encoded = pureJsChunkCombiner.toUtf8String( 40 | chunk as Uint8Array, 41 | 0, 42 | chunk.length 43 | ) 44 | expect(encoded).equals(str) 45 | }) 46 | }) 47 | }) 48 | -------------------------------------------------------------------------------- /examples/delete.ts: -------------------------------------------------------------------------------- 1 | #!./node_modules/.bin/esr 2 | 3 | ///////////////////////////////////////////////////////////////////////// 4 | // Shows how to delete data from InfluxDB. See // 5 | // https://docs.influxdata.com/influxdb/latest/write-data/delete-data/ // 6 | ///////////////////////////////////////////////////////////////////////// 7 | 8 | import {InfluxDB} from '@influxdata/influxdb-client' 9 | import {DeleteAPI} from '@influxdata/influxdb-client-apis' 10 | import {url, token, org, bucket} from './env.mjs' 11 | const influxDB = new InfluxDB({url, token}) 12 | 13 | /* 14 | The functionality of the DeleteAPI is fully demonstrated with 15 | the following sequence of examples: 16 | - write.mjs 17 | - query.ts 18 | - delete.ts 19 | - query.ts 20 | 21 | Note: You can also delete and re-create the whole bucket, 22 | see ./createBucket.js example. 23 | */ 24 | 25 | async function deleteData(): Promise { 26 | console.log('*** DELETE DATA ***') 27 | const deleteAPI = new DeleteAPI(influxDB) 28 | // define time interval for delete operation 29 | const stop = new Date() 30 | const start = new Date(stop.getTime() - /* an hour */ 60 * 60 * 1000) 31 | 32 | await deleteAPI.postDelete({ 33 | org, 34 | bucket, 35 | // you can better specify orgID, bucketID in place or org, bucket if you already know them 36 | body: { 37 | start: start.toISOString(), 38 | stop: stop.toISOString(), 39 | // see https://docs.influxdata.com/influxdb/latest/reference/syntax/delete-predicate/ 40 | predicate: '_measurement="temperature"', 41 | }, 42 | }) 43 | } 44 | 45 | deleteData() 46 | .then(() => console.log('\nFinished SUCCESS')) 47 | .catch((error) => { 48 | console.error(error) 49 | console.log('\nFinished ERROR') 50 | }) 51 | -------------------------------------------------------------------------------- /packages/apis/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * The `@influxdata/influxdb-client-apis` package provides InfluxDB APIs, which are 3 | * {@link https://github.com/influxdata/influxdb-client-js/blob/master/packages/apis/DEVELOPMENT.md | generated from OpenAPI specifications }. 4 | * 5 | * @remarks 6 | * These APIs allow to manage the domain objects of InfluxDB (such as buckets, sources, tasks, authorizations). 7 | * The APIs are constructed with `InfluxDB` instance that is populated with InfluxDB server parameters. All API 8 | * operations return Promise of response data, the majority of them relies upon simple exchange of JSON data. 9 | * For example: 10 | * 11 | * ``` 12 | * ... 13 | * const {InfluxDB} = require('@influxdata/influxdb-client') 14 | * const {OrgsAPI} = require('@influxdata/influxdb-client-apis') 15 | * const influxDB = new InfluxDB({ 16 | * url: "http://localhost:8086", 17 | * token: "my-token" 18 | * }) 19 | * ... 20 | * async function getOrg() { 21 | * const orgsAPI = new OrgsAPI(influxDB) 22 | * const organizations = await orgsAPI.getOrgs({ 23 | * org: "my-org" 24 | * }) 25 | * ... 26 | * } 27 | * ... 28 | * ``` 29 | 30 | * Generated APIs that write or query InfluxDB are also herein, but it is recommended to use 31 | * {@link @influxdata/influxdb-client!WriteApi} and {@link @influxdata/influxdb-client!QueryApi} 32 | * from `@influxdata/influxdb-client`, they are much easier to use and offer specialized features 33 | * (write failover, line protocol serialization, flux results parsing, ...). 34 | * 35 | * See also {@link https://github.com/influxdata/influxdb-client-js/tree/master/examples | examples} to know more. 36 | * 37 | * @packageDocumentation 38 | */ 39 | export * from './generated' 40 | export {RequestOptions} from './APIBase' 41 | export * from './custom' 42 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "description": "InfluxDB 2.x client", 4 | "workspaces": { 5 | "packages": [ 6 | "packages/core", 7 | "packages/core-browser", 8 | "packages/apis", 9 | "packages/giraffe" 10 | ] 11 | }, 12 | "scripts": { 13 | "typedoc": "typedoc --skipErrorChecking", 14 | "typedoc:gh-pages": "yarn typedoc && gh-pages -d ./docs -m 'docs: updates documentation [skip CI]' --dotfiles", 15 | "preinstall": "node ./scripts/require-yarn.js", 16 | "clean": "rimraf temp docs && yarn workspaces run clean", 17 | "build": "yarn workspaces run build", 18 | "test": "yarn --cwd packages/core build && yarn workspaces run test && yarn lint:examples", 19 | "test:ci": "yarn workspaces run test:ci && yarn lint:examples:ci", 20 | "coverage": "cd packages/core && yarn build && yarn coverage && cd ../giraffe && yarn coverage", 21 | "coverage:ci": "cd packages/core && yarn build && yarn coverage:ci && cd ../giraffe && yarn coverage:ci", 22 | "lint:examples": "yarn eslint --ignore-pattern node_modules ./examples", 23 | "lint:examples:ci": "yarn lint:examples --format junit --output-file ./reports/examples_eslint/eslint.xml" 24 | }, 25 | "homepage": "https://github.com/influxdata/influxdb-client-js", 26 | "repository": { 27 | "type": "git", 28 | "url": "git+https://github.com/influxdata/influxdb-client-js" 29 | }, 30 | "keywords": [ 31 | "influxdb", 32 | "influxdata" 33 | ], 34 | "author": { 35 | "name": "InfluxData" 36 | }, 37 | "license": "MIT", 38 | "devDependencies": { 39 | "@microsoft/api-documenter": "^7.19.12", 40 | "@types/node": "^24", 41 | "gh-pages": "^6.0.0", 42 | "lerna": "^8.0.2", 43 | "prettier": "^3.0.3", 44 | "rimraf": "^5.0.1", 45 | "typedoc": "^0.27.5" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /packages/core/test/util.ts: -------------------------------------------------------------------------------- 1 | import {expect} from 'chai' 2 | import {setLogger} from '../src/util/logger' 3 | 4 | let previous: any 5 | 6 | export interface CollectedLogs { 7 | error: Array> 8 | warn: Array> 9 | } 10 | 11 | export const collectLogging = { 12 | replace(): CollectedLogs { 13 | const retVal: CollectedLogs = { 14 | error: [], 15 | warn: [], 16 | } 17 | previous = setLogger({ 18 | error: function (...args) { 19 | retVal.error.push(args) 20 | }, 21 | warn: function (...args) { 22 | retVal.warn.push(args) 23 | }, 24 | }) 25 | return retVal 26 | }, 27 | decorate(): CollectedLogs { 28 | const retVal: CollectedLogs = { 29 | error: [], 30 | warn: [], 31 | } 32 | const previous = setLogger({ 33 | error: function (...args) { 34 | ;(previous.error as any).apply(previous, args) 35 | retVal.error.push(args) 36 | }, 37 | warn: function (...args) { 38 | ;(previous.warn as any).apply(previous, args) 39 | retVal.warn.push(args) 40 | }, 41 | }) 42 | return retVal 43 | }, 44 | after(): void { 45 | if (previous) { 46 | setLogger(previous) 47 | previous = undefined 48 | } 49 | }, 50 | } 51 | 52 | let rejections: Array = [] 53 | function addRejection(e: any) { 54 | rejections.push(e) 55 | } 56 | 57 | /** 58 | * Used by unit tests to check that no unhandled promise rejection occurs. 59 | */ 60 | export const unhandledRejections = { 61 | before(): void { 62 | rejections = [] 63 | process.on('unhandledRejection', addRejection) 64 | }, 65 | after(): void { 66 | process.off('unhandledRejection', addRejection) 67 | expect(rejections, 'Unhandled Promise rejections detected').deep.equals([]) 68 | }, 69 | } 70 | -------------------------------------------------------------------------------- /packages/apis/src/generated/MeAPI.ts: -------------------------------------------------------------------------------- 1 | import {InfluxDB} from '../../../core/src' 2 | import {APIBase, RequestOptions} from '../APIBase' 3 | import {PasswordResetBody, UserResponse} from './types' 4 | 5 | export interface GetMeRequest {} 6 | export interface PutMePasswordRequest { 7 | auth?: {user: string; password: string} 8 | /** The new password. */ 9 | body: PasswordResetBody 10 | } 11 | /** 12 | * Me API 13 | */ 14 | export class MeAPI { 15 | // internal 16 | private base: APIBase 17 | 18 | /** 19 | * Creates MeAPI 20 | * @param influxDB - an instance that knows how to communicate with InfluxDB server 21 | */ 22 | constructor(influxDB: InfluxDB) { 23 | this.base = new APIBase(influxDB) 24 | } 25 | /** 26 | * Retrieve the currently authenticated user. 27 | * See {@link https://docs.influxdata.com/influxdb/v2.4/api/#operation/GetMe } 28 | * @param request - request parameters and body (if supported) 29 | * @param requestOptions - optional transport options 30 | * @returns promise of response 31 | */ 32 | getMe( 33 | request?: GetMeRequest, 34 | requestOptions?: RequestOptions 35 | ): Promise { 36 | return this.base.request('GET', `/api/v2/me`, request, requestOptions) 37 | } 38 | /** 39 | * Update a password. 40 | * See {@link https://docs.influxdata.com/influxdb/v2.4/api/#operation/PutMePassword } 41 | * @param request - request parameters and body (if supported) 42 | * @param requestOptions - optional transport options 43 | * @returns promise of response 44 | */ 45 | putMePassword( 46 | request: PutMePasswordRequest, 47 | requestOptions?: RequestOptions 48 | ): Promise { 49 | return this.base.request( 50 | 'PUT', 51 | `/api/v2/me/password`, 52 | request, 53 | requestOptions, 54 | 'application/json' 55 | ) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /packages/apis/src/generated/SetupAPI.ts: -------------------------------------------------------------------------------- 1 | import {InfluxDB} from '../../../core/src' 2 | import {APIBase, RequestOptions} from '../APIBase' 3 | import {IsOnboarding, OnboardingRequest, OnboardingResponse} from './types' 4 | 5 | export interface GetSetupRequest {} 6 | export interface PostSetupRequest { 7 | /** Source to create */ 8 | body: OnboardingRequest 9 | } 10 | /** 11 | * Setup API 12 | */ 13 | export class SetupAPI { 14 | // internal 15 | private base: APIBase 16 | 17 | /** 18 | * Creates SetupAPI 19 | * @param influxDB - an instance that knows how to communicate with InfluxDB server 20 | */ 21 | constructor(influxDB: InfluxDB) { 22 | this.base = new APIBase(influxDB) 23 | } 24 | /** 25 | * Check if database has default user, org, bucket. 26 | * See {@link https://docs.influxdata.com/influxdb/v2.4/api/#operation/GetSetup } 27 | * @param request - request parameters and body (if supported) 28 | * @param requestOptions - optional transport options 29 | * @returns promise of response 30 | */ 31 | getSetup( 32 | request?: GetSetupRequest, 33 | requestOptions?: RequestOptions 34 | ): Promise { 35 | return this.base.request('GET', `/api/v2/setup`, request, requestOptions) 36 | } 37 | /** 38 | * Set up initial user, org and bucket. 39 | * See {@link https://docs.influxdata.com/influxdb/v2.4/api/#operation/PostSetup } 40 | * @param request - request parameters and body (if supported) 41 | * @param requestOptions - optional transport options 42 | * @returns promise of response 43 | */ 44 | postSetup( 45 | request: PostSetupRequest, 46 | requestOptions?: RequestOptions 47 | ): Promise { 48 | return this.base.request( 49 | 'POST', 50 | `/api/v2/setup`, 51 | request, 52 | requestOptions, 53 | 'application/json' 54 | ) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /packages/core/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * The `@influxdata/influxdb-client` package provides optimized APIs that write or query InfluxDB v2. 3 | * 4 | * @remarks 5 | * The entry point of this package is the {@link @influxdata/influxdb-client!InfluxDB } class. It is 6 | * initialized with options that tells how to communicate with InfluxDB. The simple usage pattern is: 7 | * 8 | * ``` 9 | * import {InfluxDB} = from('@influxdata/influxdb-client') 10 | * const influxDB = new InfluxDB({ 11 | * url: "http://localhost:8086", 12 | * token: "your-api-token" 13 | * }) 14 | * ``` 15 | * 16 | * The influxDB object let you create two essential API instances, {@link @influxdata/influxdb-client!InfluxDB.getWriteApi } 17 | * and {@link @influxdata/influxdb-client!InfluxDB.getQueryApi }. The {@link @influxdata/influxdb-client!WriteApi} 18 | * asynchronously writes measurement points on background, in batches to optimize network traffic, and with retries 19 | * upon failures. The {@link @influxdata/influxdb-client!QueryApi} let you execute a flux query against InfluxDB 20 | * and offers several ways to stream query results. 21 | * 22 | * The influxDB object is also used to create more specialized InfluxDB management API instances in 23 | * {@link @influxdata/influxdb-client-apis! | @influxdata/influxdb-client-apis} . 24 | * 25 | * See also {@link https://github.com/influxdata/influxdb-client-js/tree/master/examples | examples} to know more. 26 | * 27 | * @packageDocumentation 28 | */ 29 | export * from './results' 30 | export * from './options' 31 | export * from './errors' 32 | export * from './util/escape' 33 | export * from './util/currentTime' 34 | export * from './util/logger' 35 | export * from './query' 36 | export * from './transport' 37 | export * from './observable' 38 | export * from './Point' 39 | export {default as InfluxDB} from './InfluxDB' 40 | export {default as QueryApi, QueryOptions} from './QueryApi' 41 | export {default as WriteApi} from './WriteApi' 42 | -------------------------------------------------------------------------------- /packages/core/test/fixture/chunksToLinesTables.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "1 chunk, one line", 4 | "chunks": ["abdc, efg"], 5 | "lines": ["abdc, efg"], 6 | "withCancellable": true 7 | }, 8 | { 9 | "name": "1 chunk, two lines lf-terminated", 10 | "chunks": ["abdc\nefg\n"], 11 | "lines": ["abdc", "efg"] 12 | }, 13 | { 14 | "name": "1 chunk, two lines cr+lf-terminated", 15 | "chunks": ["abdc\r\nefg\r\n"], 16 | "lines": ["abdc", "efg"] 17 | }, 18 | { 19 | "name": "1 chunk, one line with escaped new line", 20 | "chunks": ["\"ab\"\"dc\",\"\nefg\""], 21 | "lines": ["\"ab\"\"dc\",\"\nefg\""] 22 | }, 23 | { 24 | "name": "2 chunks, 3 lines", 25 | "chunks": ["ab\ncd\nef", "gh"], 26 | "lines": ["ab", "cd", "efgh"] 27 | }, 28 | { 29 | "name": "2 chunks, error after 1st chunk", 30 | "chunks": ["ab\ncd", "error", "ef"], 31 | "lines": ["ab"] 32 | }, 33 | { 34 | "name": "https://github.com/influxdata/influxdb-client-js/issues/179", 35 | "chunks": [ 36 | "#group,false,false,true,false,false,true\n", 37 | "#datatype,string,long,string,double,string,string\n", 38 | "#default,_result,,,,,\n", 39 | ",result,table,id,st_length,st_linestring,trip_id\n", 40 | ",,0,GO506_20_6431,25.463641400535032,\"-73.68691 40.820317, -73.690054 40.815413\",GO506_20_6431\n" 41 | ], 42 | "lines": [ 43 | "#group,false,false,true,false,false,true", 44 | "#datatype,string,long,string,double,string,string", 45 | "#default,_result,,,,,", 46 | ",result,table,id,st_length,st_linestring,trip_id", 47 | ",,0,GO506_20_6431,25.463641400535032,\"-73.68691 40.820317, -73.690054 40.815413\",GO506_20_6431" 48 | ] 49 | }, 50 | { 51 | "name": "2 chunks breaks quoted data, 1 line", 52 | "chunks": ["ab\"\ncd\nef", "g\"h"], 53 | "lines": ["ab\"\ncd\nefg\"h"] 54 | }, 55 | { 56 | "name": "2 chunks breaks quoted data, 2 lines", 57 | "chunks": ["ab\"", "c\"\nd"], 58 | "lines": ["ab\"c\"", "d"] 59 | } 60 | ] 61 | -------------------------------------------------------------------------------- /packages/core/test/unit/results/chunksToLinesIterable.test.ts: -------------------------------------------------------------------------------- 1 | import {expect} from 'chai' 2 | import {ChunkCombiner, chunksToLinesIterable} from '../../../src/results' 3 | import chunksToLinesTables from '../../fixture/chunksToLinesTables.json' 4 | import nodeChunkCombiner from '../../../src/impl/node/nodeChunkCombiner' 5 | import {Buffer} from 'buffer' 6 | 7 | interface ChunkTest { 8 | name: string 9 | chunks: string[] 10 | lines: string[] 11 | withCancellable?: boolean // use observer with cancellable implementation 12 | } 13 | 14 | describe('chunksToLinesIterable', () => { 15 | const combiners: Array<{name: string; value?: ChunkCombiner}> = [ 16 | {name: 'default', value: undefined as undefined}, 17 | {name: 'nodeChunkCombiner', value: nodeChunkCombiner}, 18 | ] 19 | combiners.forEach(({name, value: combiner}) => { 20 | describe(`with ${name} chunk combiner`, () => { 21 | ;(chunksToLinesTables as Array).forEach((test: ChunkTest) => { 22 | it(`iterates correct lines from test set '${test.name}'`, async () => { 23 | let error = false 24 | const source = async function* (): AsyncIterableIterator { 25 | for (let i = 0; i < test.chunks.length; i++) { 26 | const chunk = test.chunks[i] 27 | if (chunk === 'error') { 28 | error = true 29 | throw new Error() 30 | } else { 31 | yield Buffer.from(chunk, 'utf8') 32 | } 33 | } 34 | } 35 | const lines = [] 36 | let failed = false 37 | try { 38 | for await (const line of chunksToLinesIterable( 39 | source(), 40 | combiner 41 | )) { 42 | lines.push(line) 43 | } 44 | } catch (e) { 45 | failed = true 46 | } 47 | expect(test.lines).deep.equal(lines) 48 | expect(error).equal(failed) 49 | }) 50 | }) 51 | }) 52 | }) 53 | }) 54 | -------------------------------------------------------------------------------- /examples/influxdb-1.8.ts: -------------------------------------------------------------------------------- 1 | #!./node_modules/.bin/esr 2 | //////////////////////////////////////////////////////////////////// 3 | // Shows how to use forward compatibility APIs from InfluxDB 1.8. // 4 | //////////////////////////////////////////////////////////////////// 5 | // [InfluxDB 2.0 API compatibility endpoints](https://docs.influxdata.com/influxdb/v1.8/tools/api/#influxdb-2-0-api-compatibility-endpoints) 6 | // are part of the InfluxDB 1.x line since InfluxDB 1.8.0. This allows you to leverage InfluxDB 2.x client libraries for both writing and 7 | // querying data with Flux. 8 | // https://docs.influxdata.com/influxdb/v1.8/about_the_project/releasenotes-changelog/#forward-compatibility 9 | 10 | import {ClientOptions, InfluxDB, Point} from '@influxdata/influxdb-client' 11 | 12 | const username = 'username' 13 | const password = 'password' 14 | 15 | const database = 'telegraf' 16 | const retentionPolicy = 'autogen' 17 | 18 | const bucket = `${database}/${retentionPolicy}` 19 | 20 | const clientOptions: ClientOptions = { 21 | url: 'http://localhost:8086', 22 | token: `${username}:${password}`, 23 | } 24 | 25 | const influxDB = new InfluxDB(clientOptions) 26 | 27 | async function writePoints(): Promise { 28 | console.log('*** WRITE POINTS ***') 29 | const writeAPI = influxDB.getWriteApi('', bucket) 30 | const point = new Point('mem') 31 | .tag('host', 'host1') 32 | .floatField('used_percent', 23.43234543) 33 | writeAPI.writePoint(point) 34 | await writeAPI.close() 35 | } 36 | 37 | async function queryRows(): Promise { 38 | console.log('*** QUERY ROWS ***') 39 | const queryAPI = influxDB.getQueryApi('') 40 | const query = `from(bucket: "${bucket}") |> range(start: -1h)` 41 | for await (const {values, tableMeta} of queryAPI.iterateRows(query)) { 42 | const o = tableMeta.toObject(values) 43 | console.log(`${o._time} ${o._measurement} : ${o._field}=${o._value}`) 44 | } 45 | console.log('\nQuery FINISHED') 46 | } 47 | 48 | writePoints() 49 | .then(queryRows) 50 | .catch((e) => console.error(e)) 51 | -------------------------------------------------------------------------------- /packages/core/test/fixture/query/response3.parsed.json: -------------------------------------------------------------------------------- 1 | { 2 | "tables": [ 3 | { 4 | "index": 0, 5 | "meta": { 6 | "columns": [ 7 | { 8 | "index": 0, 9 | "label": "result" 10 | }, 11 | { 12 | "index": 1, 13 | "label": "table" 14 | }, 15 | { 16 | "index": 2, 17 | "label": "_start" 18 | }, 19 | { 20 | "index": 3, 21 | "label": "_stop" 22 | }, 23 | { 24 | "index": 4, 25 | "label": "_time" 26 | }, 27 | { 28 | "index": 5, 29 | "label": "_value" 30 | }, 31 | { 32 | "index": 6, 33 | "label": "_field" 34 | }, 35 | { 36 | "index": 7, 37 | "label": "_measurement" 38 | }, 39 | { 40 | "index": 8, 41 | "label": "location" 42 | } 43 | ] 44 | } 45 | } 46 | ], 47 | "rows": [ 48 | { 49 | "index": 1, 50 | "row": [ 51 | "", 52 | "0", 53 | "1970-01-01T00:00:00Z", 54 | "2019-12-12T09:05:37.96237406Z", 55 | "1970-01-01T00:26:15.995033574Z", 56 | "55", 57 | "value", 58 | "temperature", 59 | "west" 60 | ] 61 | }, 62 | { 63 | "index": 2, 64 | "row": [ 65 | "", 66 | "0", 67 | "1970-01-01T00:00:00Z", 68 | "2019-12-12T09:05:37.96237406Z", 69 | "1970-01-01T00:26:16.063594313Z", 70 | "55", 71 | "value", 72 | "temperature", 73 | "west" 74 | ] 75 | }, 76 | { 77 | "index": 3, 78 | "row": [ 79 | "", 80 | "0", 81 | "1970-01-01T00:00:00Z", 82 | "2019-12-12T09:05:37.96237406Z", 83 | "1970-01-01T00:26:16.069518557Z", 84 | "55", 85 | "value", 86 | "temperature", 87 | "west" 88 | ] 89 | } 90 | ] 91 | } 92 | -------------------------------------------------------------------------------- /packages/giraffe/src/queryTable.ts: -------------------------------------------------------------------------------- 1 | import {ParameterizedQuery, QueryApi} from '../../core/src' 2 | import {Table, FromFluxResult} from '@influxdata/giraffe' 3 | import {createCollector, GiraffeTableFactory, TableOptions} from './csvToTable' 4 | 5 | /** 6 | * Executes a flux query and collects results into a Giraffe's Table. 7 | * 8 | * @param queryApi - InfluxDB client's QueryApi instance 9 | * @param query - query to execute 10 | * @param tableFactory - creates a new Giraffe table 11 | * @param tableOptions - tableOptions allows to filter or even stop the processing of rows, specify maximum rows or restrict the columns to collect. 12 | * @returns Promise with query results 13 | */ 14 | export function queryToTable( 15 | queryApi: QueryApi, 16 | query: string | ParameterizedQuery, 17 | tableFactory: GiraffeTableFactory, 18 | tableOptions?: TableOptions 19 | ): Promise { 20 | return new Promise((resolve, reject) => { 21 | queryApi.queryRows( 22 | query, 23 | createCollector(resolve, reject, tableFactory, tableOptions) 24 | ) 25 | }).then((result) => result.table) 26 | } 27 | 28 | /** 29 | * Executes a flux query and iterrativelly collects results into a Giraffe's FromFluxResult. 30 | * 31 | * @param queryApi - InfluxDB client's QueryApi instance 32 | * @param query - query to execute 33 | * @param tableFactory - creates a new Giraffe table 34 | * @param tableOptions - tableOptions allows to filter or even stop the processing of rows, specify maximum rows or restrict the columns to collect 35 | * @returns a Promise with query results 36 | */ 37 | export function queryToFromFluxResult( 38 | queryApi: QueryApi, 39 | query: string | ParameterizedQuery, 40 | tableFactory: GiraffeTableFactory, 41 | tableOptions?: TableOptions 42 | ): Promise { 43 | return new Promise((resolve, reject) => { 44 | queryApi.queryRows( 45 | query, 46 | createCollector(resolve, reject, tableFactory, { 47 | ...tableOptions, 48 | computeFluxGroupKeyUnion: true, 49 | }) 50 | ) 51 | }) 52 | } 53 | -------------------------------------------------------------------------------- /examples/write.mjs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | ////////////////////////////////////////// 3 | // Shows how to use InfluxDB write API. // 4 | ////////////////////////////////////////// 5 | 6 | import {InfluxDB, Point, HttpError} from '@influxdata/influxdb-client' 7 | import {url, token, org, bucket} from './env.mjs' 8 | import {hostname} from 'node:os' 9 | 10 | console.log('*** WRITE POINTS ***') 11 | // create a write API, expecting point timestamps in nanoseconds (can be also 's', 'ms', 'us') 12 | const writeApi = new InfluxDB({url, token}).getWriteApi(org, bucket, 'ns') 13 | // setup default tags for all writes through this API 14 | writeApi.useDefaultTags({location: hostname()}) 15 | 16 | // write point with the current (client-side) timestamp 17 | const point1 = new Point('temperature') 18 | .tag('example', 'write.ts') 19 | .floatField('value', 20 + Math.round(100 * Math.random()) / 10) 20 | writeApi.writePoint(point1) 21 | console.log(` ${point1}`) 22 | // write point with a custom timestamp 23 | const point2 = new Point('temperature') 24 | .tag('example', 'write.ts') 25 | .floatField('value', 10 + Math.round(100 * Math.random()) / 10) 26 | .timestamp(new Date()) // can be also a number, but in writeApi's precision units (s, ms, us, ns)! 27 | writeApi.writePoint(point2) 28 | console.log(` ${point2.toLineProtocol(writeApi)}`) 29 | 30 | // WriteApi always buffer data into batches to optimize data transfer to InfluxDB server. 31 | // writeApi.flush() can be called to flush the buffered data. The data is always written 32 | // asynchronously, Moreover, a failed write (caused by a temporary networking or server failure) 33 | // is retried automatically. Read `writeAdvanced.js` for better explanation and details. 34 | // 35 | // close() flushes the remaining buffered data and then cancels pending retries. 36 | try { 37 | await writeApi.close() 38 | console.log('FINISHED ... now try ./query.ts') 39 | } catch (e) { 40 | console.error(e) 41 | if (e instanceof HttpError && e.statusCode === 401) { 42 | console.log('Run ./onboarding.js to setup a new InfluxDB database.') 43 | } 44 | console.log('\nFinished ERROR') 45 | } 46 | -------------------------------------------------------------------------------- /examples/createBucket.mjs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | /* 3 | This example creates a new bucket. If a bucket of the same name already exists, 4 | it is deleted and then created again. 5 | */ 6 | 7 | import {InfluxDB, HttpError} from '@influxdata/influxdb-client' 8 | import {OrgsAPI, BucketsAPI} from '@influxdata/influxdb-client-apis' 9 | import {url, org, token} from './env.mjs' 10 | const influxDB = new InfluxDB({url, token}) 11 | 12 | async function recreateBucket(name) { 13 | console.log('*** Get organization by name ***') 14 | const orgsAPI = new OrgsAPI(influxDB) 15 | const organizations = await orgsAPI.getOrgs({org}) 16 | if (!organizations || !organizations.orgs || !organizations.orgs.length) { 17 | console.error(`No organization named "${org}" found!`) 18 | } 19 | const orgID = organizations.orgs[0].id 20 | console.log(`Using organization "${org}" identified by "${orgID}"`) 21 | 22 | console.log('*** Get buckets by name ***') 23 | const bucketsAPI = new BucketsAPI(influxDB) 24 | try { 25 | const buckets = await bucketsAPI.getBuckets({orgID, name}) 26 | if (buckets && buckets.buckets && buckets.buckets.length) { 27 | console.log(`Bucket named "${name}" already exists"`) 28 | const bucketID = buckets.buckets[0].id 29 | console.log(`*** Delete Bucket "${name}" identified by "${bucketID}" ***`) 30 | await bucketsAPI.deleteBucketsID({bucketID}) 31 | } 32 | } catch (e) { 33 | if (e instanceof HttpError && e.statusCode == 404) { 34 | // OK, bucket not found 35 | } else { 36 | throw e 37 | } 38 | } 39 | 40 | console.log(`*** Create Bucket "${name}" ***`) 41 | // creates a bucket, entity properties are specified in the "body" property 42 | const bucket = await bucketsAPI.postBuckets({body: {orgID, name}}) 43 | console.log( 44 | JSON.stringify( 45 | bucket, 46 | (key, value) => (key === 'links' ? undefined : value), 47 | 2 48 | ) 49 | ) 50 | } 51 | 52 | try { 53 | await recreateBucket('example-bucket') 54 | console.log('\nFinished SUCCESS') 55 | } catch (e) { 56 | console.error(e) 57 | console.log('\nFinished ERROR') 58 | } 59 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/BUG_REPORT.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: Create a bug report to help us improve 3 | labels: ["bug"] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | Thanks for taking time to fill out this bug report! We reserve this repository issues for bugs with reproducible problems. 9 | Please redirect any questions about the JavaScript client usage to our [Community Slack](https://app.slack.com/client/TH8RGQX5Z/C03TNRVRFB2) or [Community Page](https://community.influxdata.com/) we have a lot of talented community members there who could help answer your question more quickly. 10 | 11 | * Please add a :+1: or comment on a similar existing bug report instead of opening a new one. 12 | * Please check whether the bug can be reproduced with the latest release. 13 | - type: textarea 14 | id: specifications 15 | attributes: 16 | label: Specifications 17 | description: Describe the steps to reproduce the bug. 18 | value: | 19 | * Client Version: 20 | * InfluxDB Version: 21 | * Platform: 22 | validations: 23 | required: true 24 | - type: textarea 25 | id: reproduce 26 | attributes: 27 | label: Code sample to reproduce problem 28 | description: Provide a code sample that reproduces the problem 29 | value: | 30 | ```javascript 31 | ``` 32 | validations: 33 | required: true 34 | - type: textarea 35 | id: expected-behavior 36 | attributes: 37 | label: Expected behavior 38 | description: Describe what you expected to happen when you performed the above steps. 39 | validations: 40 | required: true 41 | - type: textarea 42 | id: actual-behavior 43 | attributes: 44 | label: Actual behavior 45 | description: Describe what actually happened when you performed the above steps. 46 | validations: 47 | required: true 48 | - type: textarea 49 | id: additional-info 50 | attributes: 51 | label: Additional info 52 | description: Include gist of relevant config, logs, etc. 53 | validations: 54 | required: false 55 | -------------------------------------------------------------------------------- /packages/apis/test/unit/typesCollector.test.ts: -------------------------------------------------------------------------------- 1 | import {expect} from 'chai' 2 | import TypesCollector from '../../generator/typesCollector' 3 | 4 | interface TypesCollectorTest { 5 | name: string 6 | toAdd: Array 7 | result: string 8 | } 9 | 10 | describe('TypesCollector', () => { 11 | const tests: TypesCollectorTest[] = [ 12 | { 13 | name: 'collect built-in types', 14 | toAdd: ['string', 'any', 'boolean', 'void'], 15 | result: '', 16 | }, 17 | { 18 | name: 'collect custom types', 19 | toAdd: ['C', 'B', 'A', 'B'], 20 | result: 'A, B, C', 21 | }, 22 | { 23 | name: 'collect custom alternative types', 24 | toAdd: ['C | B | A', 'B'], 25 | result: 'A, B, C', 26 | }, 27 | { 28 | name: 'collect anonymous type 1', 29 | toAdd: [ 30 | '{\n /** optional, when provided will replace the name */\n name?: string;\n /** optional, when provided will replace the description */\n description?: string;\n /** optional, when provided will replace all existing cells with the cells provided */\n cells?: CellWithViewProperties;\n}', 31 | ], 32 | result: 'CellWithViewProperties', 33 | }, 34 | { 35 | name: 'collect anonymous type 2', 36 | toAdd: ['{\n d?: D | C;\n description?: A;\n name?: string;\n}'], 37 | result: 'A, C, D', 38 | }, 39 | { 40 | name: 'collect anonymous type 2', 41 | toAdd: [ 42 | 'Array<{\n d?: D | C;\n description?: A;\n name?: string;\n}>', 43 | ], 44 | result: 'A, C, D', 45 | }, 46 | { 47 | name: 'collect ListItem[]', 48 | toAdd: ['ListItem[]'], 49 | result: 'ListItem', 50 | }, 51 | { 52 | name: 'collect string[]', 53 | toAdd: ['string[]'], 54 | result: '', 55 | }, 56 | ] 57 | tests.forEach((test) => { 58 | it(test.name, () => { 59 | const collector = new TypesCollector() 60 | test.toAdd.forEach(collector.add.bind(collector)) 61 | const result = collector.toString() 62 | expect(result).equals(test.result) 63 | expect(collector.hasTypes()).equals(result !== '') 64 | }) 65 | }) 66 | }) 67 | -------------------------------------------------------------------------------- /packages/apis/src/generated/TemplatesAPI.ts: -------------------------------------------------------------------------------- 1 | import {InfluxDB} from '../../../core/src' 2 | import {APIBase, RequestOptions} from '../APIBase' 3 | import { 4 | Template, 5 | TemplateApply, 6 | TemplateExportByID, 7 | TemplateExportByName, 8 | TemplateSummary, 9 | } from './types' 10 | 11 | export interface ApplyTemplateRequest { 12 | /** Parameters for applying templates. 13 | */ 14 | body: TemplateApply 15 | } 16 | export interface ExportTemplateRequest { 17 | /** Export resources as an InfluxDB template. */ 18 | body: TemplateExportByID | TemplateExportByName 19 | } 20 | /** 21 | * Templates API 22 | */ 23 | export class TemplatesAPI { 24 | // internal 25 | private base: APIBase 26 | 27 | /** 28 | * Creates TemplatesAPI 29 | * @param influxDB - an instance that knows how to communicate with InfluxDB server 30 | */ 31 | constructor(influxDB: InfluxDB) { 32 | this.base = new APIBase(influxDB) 33 | } 34 | /** 35 | * Apply or dry-run a template. 36 | * See {@link https://docs.influxdata.com/influxdb/v2.4/api/#operation/ApplyTemplate } 37 | * @param request - request parameters and body (if supported) 38 | * @param requestOptions - optional transport options 39 | * @returns promise of response 40 | */ 41 | applyTemplate( 42 | request: ApplyTemplateRequest, 43 | requestOptions?: RequestOptions 44 | ): Promise { 45 | return this.base.request( 46 | 'POST', 47 | `/api/v2/templates/apply`, 48 | request, 49 | requestOptions, 50 | 'application/json' 51 | ) 52 | } 53 | /** 54 | * Export a new template. 55 | * See {@link https://docs.influxdata.com/influxdb/v2.4/api/#operation/ExportTemplate } 56 | * @param request - request parameters and body (if supported) 57 | * @param requestOptions - optional transport options 58 | * @returns promise of response 59 | */ 60 | exportTemplate( 61 | request: ExportTemplateRequest, 62 | requestOptions?: RequestOptions 63 | ): Promise