@bueno-analytics/node-sdk
v6.0.0
Published
A Node.js package for interacting with the Bueno HTTP API.
Readme
node-sdk
A Node.js package for interacting with the Bueno HTTP API.
🌏 Bueno Website | ⚙️ API Documentation (HTTP) | 📗 Changelog | 💳 License
Prerequisites
- Node.js >=20.19.x <25
Install
yarn add @bueno-analytics/node-sdk
npm install @bueno-analytics/node-sdkUsage
// Import the API client
import { BuenoAPI } from '@bueno-analytics/node-sdk'
// Create a new instance of the client
const client = new BuenoAPI({
apiUrl: 'https://au.api.bueno-analytics.com',
})
// Request data!
const sites = await client.getSitesByOrganisationId(
'00000000-0000-0000-0000-000000000000',
)
console.log(sites)Retrieving the token
getToken() returns a token that is valid at the moment of the call. The client logs in when no token is cached, and logs in again when the cached token expired.
const res = await fetch('https://au.api.bueno-analytics.com/v2/organisations', {
headers: { Authorization: `Bearer ${await client.getToken()}` },
})Use it when a request happens outside the SDK: a WebSocket handshake, an endpoint the SDK does not wrap, or a call that another service makes on behalf of the same user.
[!WARNING] The return value is a bearer credential. The holder of the token acts as the authenticated user until the token expires. Do not log it, and do not put it in a URL or a query string. Do not copy it into a cache of your own — call
getToken()again each time that you need a token. The SDK caches the token and refreshes it on expiry. To make the cache outlive the process, configure a token store instead.
The client itself is safe to print. console.log(client) and JSON.stringify(client) render a redacted view, so the email, the password and the token stay out of logs and error reports.
Custom token storage
By default, each BuenoAPI instance caches the login token in memory for its own lifetime — there's no persistence across processes. To share tokens across processes (or runs of a CLI), pass an explicit tokenStore.
Built-in stores
import { BuenoAPI } from '@bueno-analytics/node-sdk'
import { DiskStore, MemoryStore } from '@bueno-analytics/node-sdk/store'
// Persist to disk (full file path; `~` is expanded against $HOME)
const client = new BuenoAPI({
apiUrl: 'https://au.api.bueno-analytics.com',
tokenStore: new DiskStore({ path: '~/.bueno/token.txt' }),
})
// Explicit in-memory (same as omitting the option)
new BuenoAPI({ tokenStore: new MemoryStore() })DiskStore takes a full file path, not a directory. To keep tokens for different environments isolated, use distinct paths (e.g. ~/.bueno/token.prod.txt, ~/.bueno/token.staging.txt).
Custom store (Redis recipe)
For shared caching, extend TokenStore:
import { BuenoAPI } from '@bueno-analytics/node-sdk'
import { TokenStore } from '@bueno-analytics/node-sdk/store'
import { createClient, type RedisClientType } from 'redis'
class RedisTokenStore extends TokenStore {
constructor(
private readonly client: RedisClientType,
private readonly key: string,
) {
super()
}
async read() {
return (await this.client.get(this.key)) ?? undefined
}
async write(token: string) {
await this.client.set(this.key, token)
}
}
const redis = createClient()
await redis.connect()
const client = new BuenoAPI({
apiUrl: 'https://au.api.bueno-analytics.com',
tokenStore: new RedisTokenStore(redis, 'bueno-token'),
})The SDK still owns the login flow (POST /v2/login with email/password) and JWT exp-based refresh. tokenStore only controls where the cached token lives. If read() rejects, the SDK logs at debug level and falls through to a fresh login. If write() rejects, the request still succeeds — the token remains cached in memory for this instance's lifetime, but the store is not retried until the next login (e.g. on JWT expiry).
Migration from dataDir
ClientOptions.dataDir was removed in v2. Update call sites as follows:
| Before (v1) | After (v2) |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| new BuenoAPI() | new BuenoAPI({ tokenStore: new DiskStore({ path: '~/.bueno/token.txt' }) }) to keep disk caching, or just new BuenoAPI() for in-memory |
| new BuenoAPI({ dataDir: false }) | new BuenoAPI() (in-memory is now the default) |
| new BuenoAPI({ dataDir: '/tmp' }) | new BuenoAPI({ tokenStore: new DiskStore({ path: '/tmp/token.txt' }) }) |
The on-disk file path also changes from <dataDir>/token-<urlHash>.txt to whatever path you pass. Existing cached tokens are not migrated; consumers re-login on first run after upgrading.
Exports
There are several exports this package provides which may come in handy when working with our data model.
// root, the main API client
import { BuenoAPI } from '@bueno-analytics/node-sdk'
// lib, useful library functions
import {} from /* */ '@bueno-analytics/node-sdk/lib'
// store, TokenStore base class plus MemoryStore and DiskStore
import {
TokenStore,
MemoryStore,
DiskStore,
} from '@bueno-analytics/node-sdk/store'
// types, publicly available types for our data model
import {} from /* */ '@bueno-analytics/node-sdk/types'Logging
Internally we use Winston for logging. Output can be configured using the LOG_LEVEL environment variable using the log level values here. The default is debug.
LOG_LEVEL=warn node my-script.jsDocumentation & TypeScript
@bueno-analytics/node-sdk ships with TypeScript types built-in to every available method, links to the relevant API documentation, and descriptions of each method via JSDoc.
