fireboard-api-client 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -34
- package/dist/client.d.ts +12 -9
- package/dist/client.js +10 -3
- package/dist/device-cache.d.ts +11 -0
- package/dist/device-cache.js +40 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/schemas.d.ts +9 -8
- package/dist/schemas.js +6 -5
- package/dist/types.d.ts +7 -0
- package/dist/validation.d.ts +1 -1
- package/dist/validation.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,25 +22,29 @@ const token = await login({
|
|
|
22
22
|
|
|
23
23
|
const fireboard = new FireboardClient({ token });
|
|
24
24
|
const devices = await fireboard.getDevices();
|
|
25
|
-
|
|
25
|
+
|
|
26
|
+
for (const device of devices) {
|
|
27
|
+
console.log(device.uuid, device.title, device.channels);
|
|
28
|
+
}
|
|
26
29
|
```
|
|
27
30
|
|
|
28
|
-
If you already have a token, pass it directly to `new FireboardClient({ token })`. Reuse one client per account. The
|
|
31
|
+
If you already have a token, pass it directly to `new FireboardClient({ token })`. Reuse one client per account: device lists are cached for two minutes by default. The client supplies Fireboard’s required User-Agent header and does not store login credentials.
|
|
29
32
|
|
|
30
|
-
API reference: [Fireboard
|
|
33
|
+
API reference: [Fireboard API](https://docs.fireboard.io/app/app-api/).
|
|
31
34
|
|
|
32
35
|
## Methods
|
|
33
36
|
|
|
34
|
-
|
|
37
|
+
Read and write methods are called on `FireboardClient`. `login` is a standalone function. Read methods return promises of the listed types.
|
|
35
38
|
|
|
36
39
|
### Read methods
|
|
37
40
|
|
|
38
41
|
| Method | What it does | Returns |
|
|
39
42
|
| ------------------------------------------- | ------------------------------------------------------------------------------- | ----------------------- |
|
|
40
43
|
| `getDevices()` | Lists the account’s devices with channels, temperatures, and available metadata | `RawDevice[]` |
|
|
44
|
+
| `getDevicesWithCache()` | Lists devices with cache freshness metadata | `DeviceListResult` |
|
|
41
45
|
| `getDevice(deviceUuid)` | Retrieves detailed information for one device | `RawDevice` |
|
|
42
|
-
| `getDeviceTemperatures(deviceUuid)` | Retrieves
|
|
43
|
-
| `getDriveLog(deviceUuid)` | Retrieves a Drive log
|
|
46
|
+
| `getDeviceTemperatures(deviceUuid)` | Retrieves the latest available readings | `RawDeviceTemperatures` |
|
|
47
|
+
| `getDriveLog(deviceUuid)` | Retrieves a recent Drive log or an empty object | `RawDriveLogResponse` |
|
|
44
48
|
| `getSessions()` | Lists current and historical account sessions | `RawSessionSummary[]` |
|
|
45
49
|
| `getSessionDetail(sessionId)` | Retrieves a session’s metadata, devices, and available notes | `RawSessionDetail` |
|
|
46
50
|
| `getSessionChart(sessionId, includeDrive?)` | Retrieves temperature time-series, optionally including Drive data | `RawChartChannel[]` |
|
|
@@ -63,35 +67,35 @@ Options are `loginUrl`, `timeoutMs`, `fetch`, and `userAgent`. Store the returne
|
|
|
63
67
|
|
|
64
68
|
### `getDevices()`
|
|
65
69
|
|
|
66
|
-
Returns an array of devices.
|
|
70
|
+
Returns an array of devices, cached for two minutes by default. Pass a device’s `uuid`, not its numeric `id`, to device reads and Drive controls.
|
|
67
71
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
72
|
+
### `getDevicesWithCache()`
|
|
73
|
+
|
|
74
|
+
Returns `{ data, fromCache, cacheAgeSeconds }`, where `data` is `RawDevice[]`. Shares the cache with `getDevices()`. Newly fetched responses have `fromCache: false` and age `0`; cached responses report their rounded age in seconds. This age describes the cached response, not the readings within it.
|
|
71
75
|
|
|
72
76
|
### `getDevice(deviceUuid)`
|
|
73
77
|
|
|
74
|
-
|
|
78
|
+
Returns the device and its available channel metadata without using the device-list cache.
|
|
75
79
|
|
|
76
80
|
### `getDeviceTemperatures(deviceUuid)`
|
|
77
81
|
|
|
78
|
-
Retrieves the latest channel temperatures
|
|
79
|
-
|
|
80
|
-
```typescript
|
|
81
|
-
const readings = await fireboard.getDeviceTemperatures("your-device-uuid");
|
|
82
|
-
```
|
|
82
|
+
Retrieves the latest available channel temperatures. Fireboard documents a one-minute freshness cutoff, but live checks returned older data after power-off. Check reading timestamps before treating values as current.
|
|
83
83
|
|
|
84
84
|
Fireboard does not document this response’s JSON shape. `RawDeviceTemperatures` preserves the returned JSON; narrow the result before accessing its fields.
|
|
85
85
|
|
|
86
86
|
### `getDriveLog(deviceUuid)`
|
|
87
87
|
|
|
88
|
-
Returns a recent Drive log
|
|
88
|
+
Returns a recent Drive log with `driveper`, `setpoint`, `modetype`, `tiedchannel`, `degreetype`, and `created` fields, or `{}` when no recent log is available.
|
|
89
|
+
|
|
90
|
+
Check for an empty object before accessing log fields. Incomplete non-empty logs and other response shapes raise `INVALID_RESPONSE`.
|
|
89
91
|
|
|
90
92
|
```typescript
|
|
91
93
|
const drive = await fireboard.getDriveLog("your-device-uuid");
|
|
92
|
-
```
|
|
93
94
|
|
|
94
|
-
|
|
95
|
+
if (Object.keys(drive).length === 0) {
|
|
96
|
+
console.log("No recent Drive data");
|
|
97
|
+
}
|
|
98
|
+
```
|
|
95
99
|
|
|
96
100
|
### `getSessions()`
|
|
97
101
|
|
|
@@ -105,15 +109,13 @@ Pass a non-negative integer session ID. Returns metadata, linked devices, and co
|
|
|
105
109
|
|
|
106
110
|
### `getSessionChart(sessionId, includeDrive = false)`
|
|
107
111
|
|
|
108
|
-
Returns an array of channel series. Each includes `x` timestamps, `y` temperature values or Drive percentages, `device`, `label`, and `degreetype
|
|
112
|
+
Returns an array of channel series. Each includes `x` Unix timestamps in seconds, `y` temperature values or Drive percentages, `device`, `label`, and `degreetype`. `channel_id` is optional; numeric identifiers become strings.
|
|
109
113
|
|
|
110
114
|
```typescript
|
|
111
115
|
const temperatures = await fireboard.getSessionChart(42);
|
|
112
116
|
const temperaturesAndDrive = await fireboard.getSessionChart(42, true);
|
|
113
117
|
```
|
|
114
118
|
|
|
115
|
-
Passing `true` includes Drive data.
|
|
116
|
-
|
|
117
119
|
### `setDriveSetpoint(deviceUuid, options)`
|
|
118
120
|
|
|
119
121
|
Pass a finite numeric `setpoint`, a positive integer `channel`, or both. At least one is required, and all arguments are validated before any write is sent.
|
|
@@ -136,7 +138,7 @@ Pass a finite percentage between `0` and `100`. This puts Drive in manual mode a
|
|
|
136
138
|
await fireboard.setDriveSpeed("your-device-uuid", 50);
|
|
137
139
|
```
|
|
138
140
|
|
|
139
|
-
A value of `0` stops the fan. Use `setDriveOff`
|
|
141
|
+
A value of `0` stops the fan. Use `setDriveOff()` to clear the setpoint as well.
|
|
140
142
|
|
|
141
143
|
### `setDriveOff(deviceUuid)`
|
|
142
144
|
|
|
@@ -148,24 +150,31 @@ await fireboard.setDriveOff("your-device-uuid");
|
|
|
148
150
|
|
|
149
151
|
### Response validation
|
|
150
152
|
|
|
151
|
-
Responses retain Fireboard’s field names and
|
|
153
|
+
Responses retain Fireboard’s field names and extra fields, including nested fields. Zod validates known fields; extra fields are preserved without individual validation or specific TypeScript types. Missing alerts and notes become empty arrays, and numeric chart `channel_id` values become strings.
|
|
154
|
+
|
|
155
|
+
Use each reading or chart series’ `degreetype` to interpret temperatures: `1` is Celsius and `2` is Fahrenheit. Device-level unit metadata may differ from the reading’s unit. Channels remain listed when probes are unplugged, but reading fields may be omitted.
|
|
156
|
+
|
|
157
|
+
The exported TypeScript types describe the client’s validated fields, including observed fields not covered by Fireboard’s public reference.
|
|
152
158
|
|
|
153
159
|
## Options
|
|
154
160
|
|
|
155
|
-
`new FireboardClient({ token, baseUrl?, timeoutMs?, fetch?, userAgent? })`
|
|
161
|
+
`new FireboardClient({ token, baseUrl?, deviceCacheTtlMs?, timeoutMs?, fetch?, userAgent? })`
|
|
156
162
|
|
|
157
163
|
- `baseUrl`: defaults to `https://fireboard.io/api/v1`.
|
|
164
|
+
- `deviceCacheTtlMs`: device-list cache TTL; defaults to 120,000 ms. Set `0` to disable caching and shared in-flight reads.
|
|
158
165
|
- `timeoutMs`: defaults to 15,000 ms and covers fetching the response body.
|
|
159
166
|
- `fetch`: injectable for testing or custom transports.
|
|
160
167
|
- `userAgent`: optional application identification; defaults to `fireboard-api-client/<version>`.
|
|
161
168
|
|
|
162
169
|
`login` accepts `loginUrl`, `timeoutMs`, `fetch`, and `userAgent` separately. URL overrides must use HTTP(S), without credentials, query strings, or fragments. Redirects are rejected to avoid forwarding credentials.
|
|
163
170
|
|
|
164
|
-
##
|
|
171
|
+
## Caching and rate limits
|
|
172
|
+
|
|
173
|
+
Only `getDevices()` and `getDevicesWithCache()` are cached. Each client has its own cache, and concurrent cache misses share a request. The TTL starts when a valid response arrives; failures are never cached. Returned data is copied so caller mutations do not affect the cache.
|
|
165
174
|
|
|
166
|
-
|
|
175
|
+
Other reads and all writes are uncached. Writes do not invalidate cached device data. Nested temperature and Drive readings can remain stale until expiry; use `deviceCacheTtlMs: 0` for fresh device-list reads.
|
|
167
176
|
|
|
168
|
-
|
|
177
|
+
The client does not schedule requests or retry failures. Consuming applications remain responsible for rate-limit mitigation.
|
|
169
178
|
|
|
170
179
|
Fireboard limits each user to **17 API calls within any five-minute period**. After a rate-limit error, pause requests: continued calls can extend the block. Access generally resumes after approximately five minutes, once the request rate falls below the threshold.
|
|
171
180
|
|
|
@@ -209,11 +218,13 @@ All public exports are imported from `"fireboard-api-client"`; no internal file
|
|
|
209
218
|
| `FireboardClientOptions` | Constructor options, including the required token |
|
|
210
219
|
| `RequestOptions` | Shared transport options: `fetch`, `timeoutMs`, and `userAgent` |
|
|
211
220
|
| `LoginOptions` | Login transport options and optional `loginUrl` |
|
|
221
|
+
| `DeviceListResult` | Device-list data and cache freshness metadata |
|
|
212
222
|
| `DriveSetpointOptions` | A setpoint, a control channel, or both for `setDriveSetpoint` |
|
|
213
223
|
| `FireboardErrorCode` | The union of error codes listed above |
|
|
214
224
|
| `RawDevice` | One parsed device and its available metadata/channels |
|
|
215
225
|
| `RawDeviceTemperatures` | JSON returned by the temperature read, without an assumed field schema |
|
|
216
226
|
| `RawAlert` | An observed channel-alert model |
|
|
227
|
+
| `RawDriveLogResponse` | A populated `RawDriveLog` or an empty object |
|
|
217
228
|
| `RawDriveLog` | An observed Drive-log model |
|
|
218
229
|
| `RawSessionSummary` | A session-list entry |
|
|
219
230
|
| `RawSessionDetail` | Detailed session metadata, devices, and notes |
|
|
@@ -221,11 +232,12 @@ All public exports are imported from `"fireboard-api-client"`; no internal file
|
|
|
221
232
|
|
|
222
233
|
### Default constants
|
|
223
234
|
|
|
224
|
-
| Constant
|
|
225
|
-
|
|
|
226
|
-
| `DEFAULT_BASE_URL`
|
|
227
|
-
| `DEFAULT_LOGIN_URL`
|
|
228
|
-
| `
|
|
235
|
+
| Constant | Value |
|
|
236
|
+
| ----------------------------- | ------------------------------------------- |
|
|
237
|
+
| `DEFAULT_BASE_URL` | `https://fireboard.io/api/v1` |
|
|
238
|
+
| `DEFAULT_LOGIN_URL` | `https://fireboard.io/api/rest-auth/login/` |
|
|
239
|
+
| `DEFAULT_DEVICE_CACHE_TTL_MS` | `120_000` |
|
|
240
|
+
| `DEFAULT_TIMEOUT_MS` | `15_000` |
|
|
229
241
|
|
|
230
242
|
### Zod validators
|
|
231
243
|
|
|
@@ -236,7 +248,7 @@ The client already validates responses. These exports are also available if you
|
|
|
236
248
|
| `deviceSchema` | One device |
|
|
237
249
|
| `devicesResponseSchema` | An array of devices |
|
|
238
250
|
| `deviceTemperaturesResponseSchema` | JSON temperature data without an assumed response shape |
|
|
239
|
-
| `driveLogResponseSchema` |
|
|
251
|
+
| `driveLogResponseSchema` | A populated Drive log or an empty object |
|
|
240
252
|
| `sessionsResponseSchema` | An array of session summaries |
|
|
241
253
|
| `sessionDetailSchema` | One detailed session |
|
|
242
254
|
| `chartChannelSchema` | One chart channel |
|
package/dist/client.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import type { z } from "zod";
|
|
2
|
-
import type { DriveSetpointOptions, FireboardClientOptions } from "./types.js";
|
|
2
|
+
import type { DeviceListResult, DriveSetpointOptions, FireboardClientOptions } from "./types.js";
|
|
3
3
|
export declare const DEFAULT_BASE_URL = "https://fireboard.io/api/v1";
|
|
4
4
|
export declare class FireboardClient {
|
|
5
5
|
#private;
|
|
6
6
|
private readonly baseUrl;
|
|
7
7
|
private readonly drive;
|
|
8
|
+
private readonly deviceCache;
|
|
8
9
|
constructor(options: FireboardClientOptions);
|
|
9
10
|
private get;
|
|
10
|
-
/** Lists account devices
|
|
11
|
+
/** Lists account devices using the per-client device cache. */
|
|
11
12
|
getDevices(): Promise<{
|
|
12
13
|
[x: string]: unknown;
|
|
13
14
|
uuid: string;
|
|
@@ -57,14 +58,16 @@ export declare class FireboardClient {
|
|
|
57
58
|
created: string;
|
|
58
59
|
} | null | undefined;
|
|
59
60
|
active?: boolean | undefined;
|
|
60
|
-
last_battery_reading?: number | undefined;
|
|
61
|
+
last_battery_reading?: number | null | undefined;
|
|
61
62
|
model_name?: string | undefined;
|
|
62
63
|
created?: string | undefined;
|
|
63
64
|
hardware_id?: string | undefined;
|
|
64
65
|
latest_temps?: unknown[] | undefined;
|
|
65
|
-
device_log?: Record<string, unknown> | undefined;
|
|
66
|
-
last_templog?: string | undefined;
|
|
66
|
+
device_log?: Record<string, unknown> | null | undefined;
|
|
67
|
+
last_templog?: string | null | undefined;
|
|
67
68
|
}[]>;
|
|
69
|
+
/** Lists devices with cache freshness metadata. */
|
|
70
|
+
getDevicesWithCache(): Promise<DeviceListResult>;
|
|
68
71
|
/** Retrieves one device and its available metadata. */
|
|
69
72
|
getDevice(uuid: string): Promise<{
|
|
70
73
|
[x: string]: unknown;
|
|
@@ -115,13 +118,13 @@ export declare class FireboardClient {
|
|
|
115
118
|
created: string;
|
|
116
119
|
} | null | undefined;
|
|
117
120
|
active?: boolean | undefined;
|
|
118
|
-
last_battery_reading?: number | undefined;
|
|
121
|
+
last_battery_reading?: number | null | undefined;
|
|
119
122
|
model_name?: string | undefined;
|
|
120
123
|
created?: string | undefined;
|
|
121
124
|
hardware_id?: string | undefined;
|
|
122
125
|
latest_temps?: unknown[] | undefined;
|
|
123
|
-
device_log?: Record<string, unknown> | undefined;
|
|
124
|
-
last_templog?: string | undefined;
|
|
126
|
+
device_log?: Record<string, unknown> | null | undefined;
|
|
127
|
+
last_templog?: string | null | undefined;
|
|
125
128
|
}>;
|
|
126
129
|
/** Retrieves recent temperatures; the official reference does not define their JSON fields. */
|
|
127
130
|
getDeviceTemperatures(uuid: string): Promise<z.core.util.JSONType>;
|
|
@@ -134,7 +137,7 @@ export declare class FireboardClient {
|
|
|
134
137
|
tiedchannel: number;
|
|
135
138
|
degreetype: number;
|
|
136
139
|
created: string;
|
|
137
|
-
}
|
|
140
|
+
} | Record<string, never>>;
|
|
138
141
|
/** Lists account sessions; the API does not document their ordering. */
|
|
139
142
|
getSessions(): Promise<{
|
|
140
143
|
[x: string]: unknown;
|
package/dist/client.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DeviceCache, DEFAULT_DEVICE_CACHE_TTL_MS } from "./device-cache.js";
|
|
1
2
|
import { DriveControls } from "./drive.js";
|
|
2
3
|
import { decode, headers, request, DEFAULT_TIMEOUT_MS } from "./request.js";
|
|
3
4
|
import { chartResponseSchema, devicesResponseSchema, deviceSchema, deviceTemperaturesResponseSchema, driveLogResponseSchema, sessionDetailSchema, sessionsResponseSchema, } from "./schemas.js";
|
|
@@ -7,11 +8,13 @@ export class FireboardClient {
|
|
|
7
8
|
#options;
|
|
8
9
|
baseUrl;
|
|
9
10
|
drive;
|
|
11
|
+
deviceCache;
|
|
10
12
|
constructor(options) {
|
|
11
13
|
if (typeof options?.token !== "string" || !options.token.trim()) {
|
|
12
14
|
throw new TypeError("Fireboard token is required");
|
|
13
15
|
}
|
|
14
16
|
validateTiming(options.timeoutMs ?? DEFAULT_TIMEOUT_MS, "timeoutMs");
|
|
17
|
+
this.deviceCache = new DeviceCache(validateTiming(options.deviceCacheTtlMs ?? DEFAULT_DEVICE_CACHE_TTL_MS, "deviceCacheTtlMs", true));
|
|
15
18
|
this.baseUrl = validateEndpoint(options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
16
19
|
this.#options = { ...options };
|
|
17
20
|
this.drive = new DriveControls(this.baseUrl, this.#options);
|
|
@@ -20,9 +23,13 @@ export class FireboardClient {
|
|
|
20
23
|
const response = await request(`${this.baseUrl}${path}`, { headers: headers(this.#options, this.#options.token) }, this.#options);
|
|
21
24
|
return decode(response, schema);
|
|
22
25
|
}
|
|
23
|
-
/** Lists account devices
|
|
24
|
-
getDevices() {
|
|
25
|
-
return this.
|
|
26
|
+
/** Lists account devices using the per-client device cache. */
|
|
27
|
+
async getDevices() {
|
|
28
|
+
return (await this.getDevicesWithCache()).data;
|
|
29
|
+
}
|
|
30
|
+
/** Lists devices with cache freshness metadata. */
|
|
31
|
+
getDevicesWithCache() {
|
|
32
|
+
return this.deviceCache.get(() => this.get("/devices.json", devicesResponseSchema));
|
|
26
33
|
}
|
|
27
34
|
/** Retrieves one device and its available metadata. */
|
|
28
35
|
getDevice(uuid) {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { RawDevice } from "./schemas.js";
|
|
2
|
+
import type { DeviceListResult } from "./types.js";
|
|
3
|
+
export declare const DEFAULT_DEVICE_CACHE_TTL_MS = 120000;
|
|
4
|
+
export declare class DeviceCache {
|
|
5
|
+
private readonly ttlMs;
|
|
6
|
+
private cached;
|
|
7
|
+
private pending;
|
|
8
|
+
constructor(ttlMs: number);
|
|
9
|
+
get(load: () => Promise<RawDevice[]>): Promise<DeviceListResult>;
|
|
10
|
+
private fetch;
|
|
11
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export const DEFAULT_DEVICE_CACHE_TTL_MS = 120_000;
|
|
2
|
+
export class DeviceCache {
|
|
3
|
+
ttlMs;
|
|
4
|
+
cached;
|
|
5
|
+
pending;
|
|
6
|
+
constructor(ttlMs) {
|
|
7
|
+
this.ttlMs = ttlMs;
|
|
8
|
+
}
|
|
9
|
+
async get(load) {
|
|
10
|
+
if (this.ttlMs === 0) {
|
|
11
|
+
return { data: await load(), fromCache: false, cacheAgeSeconds: 0 };
|
|
12
|
+
}
|
|
13
|
+
const now = Date.now();
|
|
14
|
+
if (this.cached && now - this.cached.fetchedAt < this.ttlMs) {
|
|
15
|
+
return {
|
|
16
|
+
data: structuredClone(this.cached.data),
|
|
17
|
+
fromCache: true,
|
|
18
|
+
cacheAgeSeconds: Math.round((now - this.cached.fetchedAt) / 1000),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
if (!this.pending) {
|
|
22
|
+
this.pending = this.fetch(load);
|
|
23
|
+
}
|
|
24
|
+
const pending = this.pending;
|
|
25
|
+
try {
|
|
26
|
+
const result = await pending;
|
|
27
|
+
return { ...result, data: structuredClone(result.data) };
|
|
28
|
+
}
|
|
29
|
+
finally {
|
|
30
|
+
if (this.pending === pending) {
|
|
31
|
+
this.pending = undefined;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async fetch(load) {
|
|
36
|
+
const data = await load();
|
|
37
|
+
this.cached = { data, fetchedAt: Date.now() };
|
|
38
|
+
return { data, fromCache: false, cacheAgeSeconds: 0 };
|
|
39
|
+
}
|
|
40
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export { FireboardClient, DEFAULT_BASE_URL } from "./client.js";
|
|
2
|
+
export { DEFAULT_DEVICE_CACHE_TTL_MS } from "./device-cache.js";
|
|
2
3
|
export { login, DEFAULT_LOGIN_URL } from "./login.js";
|
|
3
4
|
export { DEFAULT_TIMEOUT_MS } from "./request.js";
|
|
4
5
|
export { FireboardError } from "./errors.js";
|
|
5
6
|
export type { FireboardErrorCode } from "./errors.js";
|
|
6
|
-
export type { FireboardClientOptions, RequestOptions, LoginOptions, DriveSetpointOptions, } from "./types.js";
|
|
7
|
+
export type { FireboardClientOptions, RequestOptions, LoginOptions, DriveSetpointOptions, DeviceListResult, } from "./types.js";
|
|
7
8
|
export * from "./schemas.js";
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { FireboardClient, DEFAULT_BASE_URL } from "./client.js";
|
|
2
|
+
export { DEFAULT_DEVICE_CACHE_TTL_MS } from "./device-cache.js";
|
|
2
3
|
export { login, DEFAULT_LOGIN_URL } from "./login.js";
|
|
3
4
|
export { DEFAULT_TIMEOUT_MS } from "./request.js";
|
|
4
5
|
export { FireboardError } from "./errors.js";
|
package/dist/schemas.d.ts
CHANGED
|
@@ -68,13 +68,13 @@ export declare const deviceSchema: z.ZodObject<{
|
|
|
68
68
|
created: z.ZodString;
|
|
69
69
|
}, z.core.$loose>>>;
|
|
70
70
|
active: z.ZodOptional<z.ZodBoolean>;
|
|
71
|
-
last_battery_reading: z.ZodOptional<z.ZodNumber
|
|
71
|
+
last_battery_reading: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
72
72
|
model_name: z.ZodOptional<z.ZodString>;
|
|
73
73
|
created: z.ZodOptional<z.ZodString>;
|
|
74
74
|
hardware_id: z.ZodOptional<z.ZodString>;
|
|
75
75
|
latest_temps: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
76
|
-
device_log: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown
|
|
77
|
-
last_templog: z.ZodOptional<z.ZodString
|
|
76
|
+
device_log: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
77
|
+
last_templog: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
78
78
|
}, z.core.$loose>;
|
|
79
79
|
export declare const devicesResponseSchema: z.ZodArray<z.ZodObject<{
|
|
80
80
|
uuid: z.ZodString;
|
|
@@ -120,23 +120,23 @@ export declare const devicesResponseSchema: z.ZodArray<z.ZodObject<{
|
|
|
120
120
|
created: z.ZodString;
|
|
121
121
|
}, z.core.$loose>>>;
|
|
122
122
|
active: z.ZodOptional<z.ZodBoolean>;
|
|
123
|
-
last_battery_reading: z.ZodOptional<z.ZodNumber
|
|
123
|
+
last_battery_reading: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
124
124
|
model_name: z.ZodOptional<z.ZodString>;
|
|
125
125
|
created: z.ZodOptional<z.ZodString>;
|
|
126
126
|
hardware_id: z.ZodOptional<z.ZodString>;
|
|
127
127
|
latest_temps: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
128
|
-
device_log: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown
|
|
129
|
-
last_templog: z.ZodOptional<z.ZodString
|
|
128
|
+
device_log: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
129
|
+
last_templog: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
130
130
|
}, z.core.$loose>>;
|
|
131
131
|
export declare const deviceTemperaturesResponseSchema: z.ZodJSONSchema;
|
|
132
|
-
export declare const driveLogResponseSchema: z.ZodObject<{
|
|
132
|
+
export declare const driveLogResponseSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
133
133
|
driveper: z.ZodNumber;
|
|
134
134
|
setpoint: z.ZodNumber;
|
|
135
135
|
modetype: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
136
136
|
tiedchannel: z.ZodNumber;
|
|
137
137
|
degreetype: z.ZodNumber;
|
|
138
138
|
created: z.ZodString;
|
|
139
|
-
}, z.core.$loose>;
|
|
139
|
+
}, z.core.$loose>, z.ZodObject<{}, z.core.$strict>]>;
|
|
140
140
|
declare const sessionSummarySchema: z.ZodObject<{
|
|
141
141
|
id: z.ZodNumber;
|
|
142
142
|
title: z.ZodString;
|
|
@@ -207,5 +207,6 @@ export type RawSessionSummary = z.infer<typeof sessionSummarySchema>;
|
|
|
207
207
|
export type RawSessionDetail = z.infer<typeof sessionDetailSchema>;
|
|
208
208
|
export type RawChartChannel = z.infer<typeof chartChannelSchema>;
|
|
209
209
|
export type RawDriveLog = z.infer<typeof driveLogSchema>;
|
|
210
|
+
export type RawDriveLogResponse = z.infer<typeof driveLogResponseSchema>;
|
|
210
211
|
export type RawDeviceTemperatures = z.infer<typeof deviceTemperaturesResponseSchema>;
|
|
211
212
|
export {};
|
package/dist/schemas.js
CHANGED
|
@@ -96,13 +96,13 @@ export const deviceSchema = z.looseObject({
|
|
|
96
96
|
channels: z.array(deviceChannelSchema),
|
|
97
97
|
last_drivelog: driveLogSchema.nullable().optional(),
|
|
98
98
|
active: z.boolean().optional(),
|
|
99
|
-
last_battery_reading: z.number().optional(),
|
|
99
|
+
last_battery_reading: z.number().nullable().optional(),
|
|
100
100
|
model_name: z.string().optional(),
|
|
101
101
|
created: z.string().optional(),
|
|
102
102
|
hardware_id: z.string().optional(),
|
|
103
103
|
latest_temps: z.array(z.unknown()).optional(),
|
|
104
|
-
device_log: z.record(z.string(), z.unknown()).optional(),
|
|
105
|
-
last_templog: z.string().optional(),
|
|
104
|
+
device_log: z.record(z.string(), z.unknown()).nullable().optional(),
|
|
105
|
+
last_templog: z.string().nullable().optional(),
|
|
106
106
|
});
|
|
107
107
|
// GET /api/v1/devices.json
|
|
108
108
|
// Returns all devices associated with the authenticated account.
|
|
@@ -132,8 +132,9 @@ export const deviceTemperaturesResponseSchema = z.json();
|
|
|
132
132
|
// GET /api/v1/devices/{uuid}/drivelog.json
|
|
133
133
|
// Official docs: returns the latest Drive log if it is less than one minute old.
|
|
134
134
|
// A single-object response and the fields above are based on observed responses;
|
|
135
|
-
//
|
|
136
|
-
|
|
135
|
+
// Observed with Drive disconnected or the device offline: HTTP 200 with {}.
|
|
136
|
+
// Keep an empty response unchanged, and reject incomplete non-empty logs.
|
|
137
|
+
export const driveLogResponseSchema = z.union([driveLogSchema, z.strictObject({})]);
|
|
137
138
|
// Represents a session summary as returned in the sessions list.
|
|
138
139
|
// Used as an element in GET /api/v1/sessions.json.
|
|
139
140
|
//
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RawDevice } from "./schemas.js";
|
|
1
2
|
export interface RequestOptions {
|
|
2
3
|
fetch?: typeof globalThis.fetch;
|
|
3
4
|
timeoutMs?: number;
|
|
@@ -6,6 +7,7 @@ export interface RequestOptions {
|
|
|
6
7
|
export interface FireboardClientOptions extends RequestOptions {
|
|
7
8
|
token: string;
|
|
8
9
|
baseUrl?: string;
|
|
10
|
+
deviceCacheTtlMs?: number;
|
|
9
11
|
}
|
|
10
12
|
export interface LoginOptions extends RequestOptions {
|
|
11
13
|
loginUrl?: string;
|
|
@@ -17,3 +19,8 @@ export type DriveSetpointOptions = {
|
|
|
17
19
|
setpoint?: number;
|
|
18
20
|
channel: number;
|
|
19
21
|
};
|
|
22
|
+
export interface DeviceListResult {
|
|
23
|
+
data: RawDevice[];
|
|
24
|
+
fromCache: boolean;
|
|
25
|
+
cacheAgeSeconds: number;
|
|
26
|
+
}
|
package/dist/validation.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export declare function validateEndpoint(value: string): string;
|
|
2
|
-
export declare function validateTiming(value: number, name: string): number;
|
|
2
|
+
export declare function validateTiming(value: number, name: string, allowZero?: boolean): number;
|
|
3
3
|
export declare function encodeDeviceId(uuid: string): string;
|
|
4
4
|
export declare function validateSessionId(id: number): number;
|
package/dist/validation.js
CHANGED
|
@@ -9,8 +9,8 @@ export function validateEndpoint(value) {
|
|
|
9
9
|
}
|
|
10
10
|
return url.href;
|
|
11
11
|
}
|
|
12
|
-
export function validateTiming(value, name) {
|
|
13
|
-
if (!Number.isFinite(value) || value < 1 || value > 2_147_483_647) {
|
|
12
|
+
export function validateTiming(value, name, allowZero = false) {
|
|
13
|
+
if (!Number.isFinite(value) || value < (allowZero ? 0 : 1) || value > 2_147_483_647) {
|
|
14
14
|
throw new TypeError(`Invalid ${name}`);
|
|
15
15
|
}
|
|
16
16
|
return value;
|