@sierragridteam/sdk 0.0.0-stage → 0.1.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.
Files changed (42) hide show
  1. package/README.md +49 -2
  2. package/dist/fixtures-data.d.ts +609 -0
  3. package/dist/fixtures-data.js +2676 -0
  4. package/dist/fixtures.d.ts +12 -0
  5. package/dist/fixtures.js +139 -0
  6. package/dist/generated/client/client.gen.d.ts +2 -0
  7. package/dist/generated/client/client.gen.js +216 -0
  8. package/dist/generated/client/index.d.ts +10 -0
  9. package/dist/generated/client/index.js +6 -0
  10. package/dist/generated/client/types.gen.d.ts +120 -0
  11. package/dist/generated/client/types.gen.js +2 -0
  12. package/dist/generated/client/utils.gen.d.ts +37 -0
  13. package/dist/generated/client/utils.gen.js +228 -0
  14. package/dist/generated/client.gen.d.ts +12 -0
  15. package/dist/generated/client.gen.js +3 -0
  16. package/dist/generated/core/auth.gen.d.ts +25 -0
  17. package/dist/generated/core/auth.gen.js +14 -0
  18. package/dist/generated/core/bodySerializer.gen.d.ts +25 -0
  19. package/dist/generated/core/bodySerializer.gen.js +57 -0
  20. package/dist/generated/core/params.gen.d.ts +43 -0
  21. package/dist/generated/core/params.gen.js +109 -0
  22. package/dist/generated/core/pathSerializer.gen.d.ts +33 -0
  23. package/dist/generated/core/pathSerializer.gen.js +106 -0
  24. package/dist/generated/core/queryKeySerializer.gen.d.ts +18 -0
  25. package/dist/generated/core/queryKeySerializer.gen.js +92 -0
  26. package/dist/generated/core/serverSentEvents.gen.d.ts +71 -0
  27. package/dist/generated/core/serverSentEvents.gen.js +132 -0
  28. package/dist/generated/core/types.gen.d.ts +83 -0
  29. package/dist/generated/core/types.gen.js +2 -0
  30. package/dist/generated/core/utils.gen.d.ts +19 -0
  31. package/dist/generated/core/utils.gen.js +87 -0
  32. package/dist/generated/index.d.ts +2 -0
  33. package/dist/generated/index.js +2 -0
  34. package/dist/generated/sdk.gen.d.ts +210 -0
  35. package/dist/generated/sdk.gen.js +336 -0
  36. package/dist/generated/types.gen.d.ts +3474 -0
  37. package/dist/generated/types.gen.js +2 -0
  38. package/dist/generated/zod.gen.d.ts +6537 -0
  39. package/dist/generated/zod.gen.js +1849 -0
  40. package/dist/index.d.ts +1287 -0
  41. package/dist/index.js +99 -0
  42. package/package.json +42 -4
package/README.md CHANGED
@@ -1,3 +1,50 @@
1
- # Temporary Holding Version
1
+ # SIERRA SDK
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Public, read-only clients for the [SIERRA Grid API](https://data.sierragridteam.org/api/openapi.json). TypeScript is available first; Python and Go will share the same versioned OpenAPI and fixture contracts in this repository. All rights reserved; public source visibility is not a license grant.
4
+
5
+ ```ts
6
+ import {createSierraClient, paginate} from '@sierragridteam/sdk';
7
+ const grid = createSierraClient();
8
+ const nodes = await grid.listEvents({layer:['MESH'], pageSize:50});
9
+ if (!nodes.notModified) console.log(nodes.data.events);
10
+ const topology = await grid.listMeshLinks({window:'72h'});
11
+ const archive = await grid.getMeshTelemetry({node:'1'.repeat(64),
12
+ from:'2026-11-06T00:00:00Z', to:'2026-11-07T00:00:00Z'});
13
+ for await (const page of paginate(pageToken => grid.listHistory({
14
+ from:'2026-11-06T00:00:00Z',to:'2026-11-07T00:00:00Z',pageToken
15
+ }))) console.log(page.revisions, page.nextPageToken);
16
+ ```
17
+
18
+ Install with `pnpm add @sierragridteam/sdk`. ESM; modern browsers and Node 22+. Consumers choose their own rendering and chart libraries. No framework hooks or shared UI are included.
19
+
20
+ The facade includes `listEvents`, `getEvent(id)`, `getEventHistory(id, query)`, `listHistory(query)`, `listPlaces`, `getPlace(place)`, `resolvePlace(query)`, `getPlaceSummary(place)`, `getConditions`, `listCameras`, `listScanners`, `listSources`, `getMapLayer(place, layer, query)`, `listMeshLinks`, and `getMeshTelemetry(query)`. Query fields and response fields follow the API. Every response is Zod-validated. `@sierragridteam/sdk/generated` exposes the lower-level generated fetch SDK; `/schemas` exposes generated Zod schemas.
21
+
22
+ `createSierraClient({baseUrl, fetch, timeoutMs})` supports injected transports. The last argument of each method accepts `{signal, etag, timeoutMs}`. Default deadline is 20 seconds, covering body consumption. No requests retry automatically. `ApiResult` discriminates 304 (`notModified: true`, no data) from a validated body. `SierraApiError` preserves HTTP status, codeName, retryAfter and error body, including plain-text deployment failures. Schema validation errors remain Zod errors. Raw generated functions have their own Hey API result/error conventions; use the facade for consistent 304/deadline handling.
23
+
24
+ Geometry defaults to OBJECT; decimal int64 counters remain strings and nullable gauges remain null. Convert counters deliberately for charts. Event revisions use their declared numeric wire type. Event detail blocks are optional; narrow on layer and check the matching block. Missing, stale and unavailable data must not be presented as zero or an all-clear. Keep provenance/official-source links visible.
25
+
26
+ History requires explicit `from < to`. Pagination ends only at an empty continuation token. `paginate` yields at most 100 pages by default; if the final yielded page has a nonempty token, results are incomplete. It does not download unlimited archives. A short page is not the end. Telemetry is separately capped by the server: retain `coverage`, `truncated`, `cadenceSeconds` and `reboots` in analysis. History describes revisions, not continuously refreshed radio liveness; current liveness is lastRelayedAt/lastHeardAt.
27
+
28
+ ## Shared synthetic fixtures
29
+
30
+ ```ts
31
+ import {createSierraClient} from '@sierragridteam/sdk';
32
+ import {createFixtureFetch, FIXTURE_NOW, FIXTURE_LABEL, fixtureNodes} from '@sierragridteam/sdk/fixtures';
33
+ const grid = createSierraClient({fetch:createFixtureFetch({scenario:'partial'})});
34
+ // Display FIXTURE_LABEL prominently. Use FIXTURE_NOW as the demo chart clock.
35
+ ```
36
+
37
+ Scenarios: `normal`, `empty`, `stale`, `partial`, `unavailable`. Six synthetic nodes include zero/null batteries, a sampling gap, reboot counter reset, unmonitored node and truncated archive. Links include an outside endpoint. A synthetic road incident, places and source states support context. These are invented fixtures, never a saved production response. `/fixtures` is a separate import so ordinary clients do not bundle demo data.
38
+
39
+ Fixture event filters support place/layer/status/severityMin/since, pageSize and pageToken. History applies explicit time bounds and event filters; telemetry applies bounds and preserves overall coverage. Fixtures use indexed continuation tokens (not the server's opaque keyset implementation); do not reuse a token with changed filters. Partial scenarios deliberately produce short pages and telemetry truncation; Valley Relay (`fixtureNodes[2]`) telemetry fails with JSON 503 while other nodes succeed. Unavailable returns JSON 503 for event lists/details/history and telemetry, and plain-text 503 for links; each includes Retry-After. Source diagnostics and map metadata remain readable as UNAVAILABLE. Stale exercises source-health freshness: source/summary last-success and map last-update are two days before FIXTURE_NOW, with STALE status. Event and telemetry fixture series remain the shared deterministic dataset rather than being rewritten by this source-health scenario. Only OBJECT geometry is supported. Fixture topology durations support h/m/s units. Only mesh_node, mesh_link and road_incident map layers are implemented; other layers return 404 rather than a misleading healthy empty map. Address resolution, other unimplemented endpoints and unsupported parameters return explicit errors. Fixtures are not a general replacement server; conditions/camera/scanner datasets are intentionally empty. They perform no network requests.
40
+
41
+ ## Maintenance and provenance
42
+
43
+ - `schema/openapi.json` is the immutable upstream snapshot; `schema/source.json` records source commit and SHA256, which generation verifies against the exact snapshot bytes.
44
+ - `scripts/prepare-schema.mjs` creates the generation-only overlay: public data GETs only; URI annotations become strings because protobuf defaults allow empty strings; int64/uint64 formats retain declared JSON type rather than Hey API's default BigInt coercion (decimal strings gain signed/unsigned patterns while existing tighter patterns are retained). No upstream file is rewritten.
45
+ - Hey API `0.99.0` and Zod `4.6.7` are pinned. Generated imports are normalized to explicit ESM extensions. `fixtures/scenarios.json` is the language-neutral synthetic data source.
46
+ - `pnpm install --frozen-lockfile`, `pnpm verify`, `pnpm drift`; optional `pnpm smoke` performs three small public GETs. CI never needs API credentials.
47
+ - Update the spec and source manifest together, regenerate, run the example/fixture/transport checks and review drift before releasing. Upstream schema fixes belong in sierra-data; generation accommodations are documented here.
48
+ - Future Python and Go packages belong under `packages/python` and `packages/go`, each with its own release workflow. They must preserve these same wire/nullability, pagination and coverage semantics. No placeholder package claims those implementations exist.
49
+
50
+ Build/package only includes `dist` plus package metadata/readme. No credentials, live captures, servers, or internal workspace files belong in this repository or the npm tarball. Releases require review. `.github/workflows/publish-typescript.yml` publishes only an explicit `typescript-vX.Y.Z` tag (or manual dispatch selecting that existing tag), validates package/tag equality, and uses npm trusted publishing with provenance. Configure the `npm` GitHub environment and npm trusted publisher for this exact workflow before a release. Python/Go will use separate tag namespaces and workflows. No long-lived npm credential is stored.
@@ -0,0 +1,609 @@
1
+ export declare const fixtureData: {
2
+ now: string;
3
+ places: {
4
+ geometry: {
5
+ bbox: {
6
+ minLat: number;
7
+ maxLat: number;
8
+ minLng: number;
9
+ maxLng: number;
10
+ };
11
+ centroid: {
12
+ lat: number;
13
+ lng: number;
14
+ };
15
+ geojson: string;
16
+ object: {
17
+ type: string;
18
+ coordinates: number[];
19
+ };
20
+ };
21
+ id: string;
22
+ kind: string;
23
+ name: string;
24
+ parentId: string;
25
+ slug: string;
26
+ }[];
27
+ events: ({
28
+ areaLabel: string;
29
+ canonicalUrl: string;
30
+ category: string;
31
+ description: string;
32
+ effective: null;
33
+ enhancement: null;
34
+ expires: null;
35
+ geometry: {
36
+ bbox: {
37
+ minLat: number;
38
+ maxLat: number;
39
+ minLng: number;
40
+ maxLng: number;
41
+ };
42
+ centroid: {
43
+ lat: number;
44
+ lng: number;
45
+ };
46
+ geojson: string;
47
+ object: {
48
+ type: string;
49
+ coordinates: number[];
50
+ };
51
+ };
52
+ headline: string;
53
+ id: string;
54
+ ingestedAt: string;
55
+ layer: string;
56
+ observedAt: string;
57
+ placeIds: string[];
58
+ provenance: {
59
+ attribution: string;
60
+ fetchedAt: string;
61
+ sourceId: string;
62
+ sourceName: string;
63
+ sourceUrl: string;
64
+ };
65
+ revision: number;
66
+ severity: string;
67
+ status: string;
68
+ summary: string;
69
+ mesh: {
70
+ name: string;
71
+ nodeType: string;
72
+ publicKey: string;
73
+ reachability: string;
74
+ telemetry: {
75
+ admin: {
76
+ airtimeMs: string;
77
+ batteryPercent: number;
78
+ batteryPercentSource: string;
79
+ batteryVolts: number;
80
+ directDups: string;
81
+ floodDups: string;
82
+ fullEvents: string;
83
+ humidity: null;
84
+ lastAttemptAt: string;
85
+ lastRssiDbm: null;
86
+ lastSnrDb: null;
87
+ lastSuccessAt: string;
88
+ noiseFloorDbm: number;
89
+ packetsReceived: string;
90
+ packetsSent: string;
91
+ pressure: null;
92
+ recvDirect: string;
93
+ recvErrors: string;
94
+ recvFlood: string;
95
+ reportedAt: string;
96
+ reporterId: string;
97
+ rxAirtimeMs: string;
98
+ sentDirect: string;
99
+ sentFlood: string;
100
+ temperatureC: number;
101
+ txQueueLen: null;
102
+ uptimeSeconds: string;
103
+ };
104
+ gateways: never[];
105
+ hopCount: number;
106
+ lastAdvertAt: null;
107
+ lastHeardAt: string;
108
+ lastRelayedAt: string;
109
+ rssi: number;
110
+ snr: number;
111
+ };
112
+ };
113
+ roadIncident?: undefined;
114
+ } | {
115
+ areaLabel: string;
116
+ canonicalUrl: string;
117
+ category: string;
118
+ description: string;
119
+ effective: null;
120
+ enhancement: null;
121
+ expires: null;
122
+ geometry: {
123
+ bbox: {
124
+ minLat: number;
125
+ maxLat: number;
126
+ minLng: number;
127
+ maxLng: number;
128
+ };
129
+ centroid: {
130
+ lat: number;
131
+ lng: number;
132
+ };
133
+ geojson: string;
134
+ object: {
135
+ type: string;
136
+ coordinates: number[];
137
+ };
138
+ };
139
+ headline: string;
140
+ id: string;
141
+ ingestedAt: string;
142
+ layer: string;
143
+ observedAt: string;
144
+ placeIds: string[];
145
+ provenance: {
146
+ attribution: string;
147
+ fetchedAt: string;
148
+ sourceId: string;
149
+ sourceName: string;
150
+ sourceUrl: string;
151
+ };
152
+ revision: number;
153
+ severity: string;
154
+ status: string;
155
+ summary: string;
156
+ mesh: {
157
+ name: string;
158
+ nodeType: string;
159
+ publicKey: string;
160
+ reachability: string;
161
+ telemetry: {
162
+ admin: {
163
+ airtimeMs: string;
164
+ batteryPercent: null;
165
+ batteryPercentSource: string;
166
+ batteryVolts: number;
167
+ directDups: string;
168
+ floodDups: string;
169
+ fullEvents: string;
170
+ humidity: null;
171
+ lastAttemptAt: string;
172
+ lastRssiDbm: null;
173
+ lastSnrDb: null;
174
+ lastSuccessAt: string;
175
+ noiseFloorDbm: number;
176
+ packetsReceived: string;
177
+ packetsSent: string;
178
+ pressure: null;
179
+ recvDirect: string;
180
+ recvErrors: string;
181
+ recvFlood: string;
182
+ reportedAt: string;
183
+ reporterId: string;
184
+ rxAirtimeMs: string;
185
+ sentDirect: string;
186
+ sentFlood: string;
187
+ temperatureC: number;
188
+ txQueueLen: null;
189
+ uptimeSeconds: string;
190
+ };
191
+ gateways: never[];
192
+ hopCount: number;
193
+ lastAdvertAt: null;
194
+ lastHeardAt: string;
195
+ lastRelayedAt: string;
196
+ rssi: number;
197
+ snr: number;
198
+ };
199
+ };
200
+ roadIncident?: undefined;
201
+ } | {
202
+ areaLabel: string;
203
+ canonicalUrl: string;
204
+ category: string;
205
+ description: string;
206
+ effective: null;
207
+ enhancement: null;
208
+ expires: null;
209
+ geometry: {
210
+ bbox: {
211
+ minLat: number;
212
+ maxLat: number;
213
+ minLng: number;
214
+ maxLng: number;
215
+ };
216
+ centroid: {
217
+ lat: number;
218
+ lng: number;
219
+ };
220
+ geojson: string;
221
+ object: {
222
+ type: string;
223
+ coordinates: number[];
224
+ };
225
+ };
226
+ headline: string;
227
+ id: string;
228
+ ingestedAt: string;
229
+ layer: string;
230
+ observedAt: string;
231
+ placeIds: string[];
232
+ provenance: {
233
+ attribution: string;
234
+ fetchedAt: string;
235
+ sourceId: string;
236
+ sourceName: string;
237
+ sourceUrl: string;
238
+ };
239
+ revision: number;
240
+ severity: string;
241
+ status: string;
242
+ summary: string;
243
+ mesh: {
244
+ name: string;
245
+ nodeType: string;
246
+ publicKey: string;
247
+ reachability: string;
248
+ telemetry: {
249
+ admin: null;
250
+ gateways: never[];
251
+ hopCount: number;
252
+ lastAdvertAt: null;
253
+ lastHeardAt: string;
254
+ lastRelayedAt: string;
255
+ rssi: number;
256
+ snr: number;
257
+ };
258
+ };
259
+ roadIncident?: undefined;
260
+ } | {
261
+ areaLabel: string;
262
+ canonicalUrl: string;
263
+ category: string;
264
+ description: string;
265
+ effective: null;
266
+ enhancement: null;
267
+ expires: null;
268
+ geometry: {
269
+ bbox: {
270
+ minLat: number;
271
+ maxLat: number;
272
+ minLng: number;
273
+ maxLng: number;
274
+ };
275
+ centroid: {
276
+ lat: number;
277
+ lng: number;
278
+ };
279
+ geojson: string;
280
+ object: {
281
+ type: string;
282
+ coordinates: number[];
283
+ };
284
+ };
285
+ headline: string;
286
+ id: string;
287
+ ingestedAt: string;
288
+ layer: string;
289
+ observedAt: string;
290
+ placeIds: string[];
291
+ provenance: {
292
+ attribution: string;
293
+ fetchedAt: string;
294
+ sourceId: string;
295
+ sourceName: string;
296
+ sourceUrl: string;
297
+ };
298
+ revision: number;
299
+ severity: string;
300
+ status: string;
301
+ summary: string;
302
+ roadIncident: {
303
+ closure: null;
304
+ duration: string;
305
+ impact: string;
306
+ logNumber: string;
307
+ metadata: {};
308
+ };
309
+ mesh?: undefined;
310
+ })[];
311
+ links: {
312
+ a: string;
313
+ b: string;
314
+ bestSnr: number;
315
+ daysActive: number;
316
+ firstSeen: string;
317
+ lastSeen: string;
318
+ observations: number;
319
+ }[];
320
+ telemetry: {
321
+ "1111111111111111111111111111111111111111111111111111111111111111": {
322
+ cadenceSeconds: string;
323
+ coverage: {
324
+ from: string;
325
+ samples: number;
326
+ to: string;
327
+ };
328
+ from: string;
329
+ node: string;
330
+ reboots: never[];
331
+ samples: {
332
+ reading: {
333
+ airtimeMs: string;
334
+ batteryPercent: number;
335
+ batteryPercentSource: string;
336
+ batteryVolts: number;
337
+ directDups: string;
338
+ floodDups: string;
339
+ fullEvents: string;
340
+ humidity: null;
341
+ lastAttemptAt: string;
342
+ lastRssiDbm: null;
343
+ lastSnrDb: null;
344
+ lastSuccessAt: string;
345
+ noiseFloorDbm: number;
346
+ packetsReceived: string;
347
+ packetsSent: string;
348
+ pressure: null;
349
+ recvDirect: string;
350
+ recvErrors: string;
351
+ recvFlood: string;
352
+ reportedAt: string;
353
+ reporterId: string;
354
+ rxAirtimeMs: string;
355
+ sentDirect: string;
356
+ sentFlood: string;
357
+ temperatureC: number;
358
+ txQueueLen: null;
359
+ uptimeSeconds: string;
360
+ };
361
+ receivedAt: string;
362
+ }[];
363
+ to: string;
364
+ truncated: boolean;
365
+ };
366
+ "2222222222222222222222222222222222222222222222222222222222222222": {
367
+ cadenceSeconds: string;
368
+ coverage: {
369
+ from: string;
370
+ samples: number;
371
+ to: string;
372
+ };
373
+ from: string;
374
+ node: string;
375
+ reboots: never[];
376
+ samples: {
377
+ reading: {
378
+ airtimeMs: string;
379
+ batteryPercent: number;
380
+ batteryPercentSource: string;
381
+ batteryVolts: number;
382
+ directDups: string;
383
+ floodDups: string;
384
+ fullEvents: string;
385
+ humidity: null;
386
+ lastAttemptAt: string;
387
+ lastRssiDbm: null;
388
+ lastSnrDb: null;
389
+ lastSuccessAt: string;
390
+ noiseFloorDbm: number;
391
+ packetsReceived: string;
392
+ packetsSent: string;
393
+ pressure: null;
394
+ recvDirect: string;
395
+ recvErrors: string;
396
+ recvFlood: string;
397
+ reportedAt: string;
398
+ reporterId: string;
399
+ rxAirtimeMs: string;
400
+ sentDirect: string;
401
+ sentFlood: string;
402
+ temperatureC: number;
403
+ txQueueLen: null;
404
+ uptimeSeconds: string;
405
+ };
406
+ receivedAt: string;
407
+ }[];
408
+ to: string;
409
+ truncated: boolean;
410
+ };
411
+ "3333333333333333333333333333333333333333333333333333333333333333": {
412
+ cadenceSeconds: string;
413
+ coverage: {
414
+ from: string;
415
+ samples: number;
416
+ to: string;
417
+ };
418
+ from: string;
419
+ node: string;
420
+ reboots: never[];
421
+ samples: {
422
+ reading: {
423
+ airtimeMs: string;
424
+ batteryPercent: null;
425
+ batteryPercentSource: string;
426
+ batteryVolts: number;
427
+ directDups: string;
428
+ floodDups: string;
429
+ fullEvents: string;
430
+ humidity: null;
431
+ lastAttemptAt: string;
432
+ lastRssiDbm: null;
433
+ lastSnrDb: null;
434
+ lastSuccessAt: string;
435
+ noiseFloorDbm: number;
436
+ packetsReceived: string;
437
+ packetsSent: string;
438
+ pressure: null;
439
+ recvDirect: string;
440
+ recvErrors: string;
441
+ recvFlood: string;
442
+ reportedAt: string;
443
+ reporterId: string;
444
+ rxAirtimeMs: string;
445
+ sentDirect: string;
446
+ sentFlood: string;
447
+ temperatureC: number;
448
+ txQueueLen: null;
449
+ uptimeSeconds: string;
450
+ };
451
+ receivedAt: string;
452
+ }[];
453
+ to: string;
454
+ truncated: boolean;
455
+ };
456
+ "4444444444444444444444444444444444444444444444444444444444444444": {
457
+ cadenceSeconds: string;
458
+ coverage: {
459
+ from: string;
460
+ samples: number;
461
+ to: string;
462
+ };
463
+ from: string;
464
+ node: string;
465
+ reboots: string[];
466
+ samples: {
467
+ reading: {
468
+ airtimeMs: string;
469
+ batteryPercent: number;
470
+ batteryPercentSource: string;
471
+ batteryVolts: number;
472
+ directDups: string;
473
+ floodDups: string;
474
+ fullEvents: string;
475
+ humidity: null;
476
+ lastAttemptAt: string;
477
+ lastRssiDbm: null;
478
+ lastSnrDb: null;
479
+ lastSuccessAt: string;
480
+ noiseFloorDbm: number;
481
+ packetsReceived: string;
482
+ packetsSent: string;
483
+ pressure: null;
484
+ recvDirect: string;
485
+ recvErrors: string;
486
+ recvFlood: string;
487
+ reportedAt: string;
488
+ reporterId: string;
489
+ rxAirtimeMs: string;
490
+ sentDirect: string;
491
+ sentFlood: string;
492
+ temperatureC: number;
493
+ txQueueLen: null;
494
+ uptimeSeconds: string;
495
+ };
496
+ receivedAt: string;
497
+ }[];
498
+ to: string;
499
+ truncated: boolean;
500
+ };
501
+ "5555555555555555555555555555555555555555555555555555555555555555": {
502
+ cadenceSeconds: null;
503
+ coverage: {
504
+ from: null;
505
+ samples: number;
506
+ to: null;
507
+ };
508
+ from: string;
509
+ node: string;
510
+ reboots: never[];
511
+ samples: never[];
512
+ to: string;
513
+ truncated: boolean;
514
+ };
515
+ "6666666666666666666666666666666666666666666666666666666666666666": {
516
+ cadenceSeconds: string;
517
+ coverage: {
518
+ from: string;
519
+ samples: number;
520
+ to: string;
521
+ };
522
+ from: string;
523
+ node: string;
524
+ reboots: never[];
525
+ samples: {
526
+ reading: {
527
+ airtimeMs: string;
528
+ batteryPercent: number;
529
+ batteryPercentSource: string;
530
+ batteryVolts: number;
531
+ directDups: string;
532
+ floodDups: string;
533
+ fullEvents: string;
534
+ humidity: null;
535
+ lastAttemptAt: string;
536
+ lastRssiDbm: null;
537
+ lastSnrDb: null;
538
+ lastSuccessAt: string;
539
+ noiseFloorDbm: number;
540
+ packetsReceived: string;
541
+ packetsSent: string;
542
+ pressure: null;
543
+ recvDirect: string;
544
+ recvErrors: string;
545
+ recvFlood: string;
546
+ reportedAt: string;
547
+ reporterId: string;
548
+ rxAirtimeMs: string;
549
+ sentDirect: string;
550
+ sentFlood: string;
551
+ temperatureC: number;
552
+ txQueueLen: null;
553
+ uptimeSeconds: string;
554
+ };
555
+ receivedAt: string;
556
+ }[];
557
+ to: string;
558
+ truncated: boolean;
559
+ };
560
+ };
561
+ sources: {
562
+ attribution: string;
563
+ expireAfterSeconds: number;
564
+ homepageUrl: string;
565
+ id: string;
566
+ kind: string;
567
+ lastAttemptAt: null;
568
+ lastError: string;
569
+ lastSuccessAt: null;
570
+ name: string;
571
+ pollIntervalSeconds: number;
572
+ staleAfterSeconds: number;
573
+ status: string;
574
+ }[];
575
+ summary: {
576
+ domains: never[];
577
+ generatedAt: string;
578
+ mode: string;
579
+ place: string;
580
+ placeId: string;
581
+ placeName: string;
582
+ sources: never[];
583
+ summary: {
584
+ activeEvacuations: null;
585
+ evacuationSourceUrl: string;
586
+ evacuationStatus: string;
587
+ highestSeverity: string;
588
+ highestSeverityRank: number;
589
+ severityCounts: {};
590
+ topEvents: never[];
591
+ totalActive: number;
592
+ };
593
+ };
594
+ conditions: {
595
+ fireWeather: null;
596
+ forecast: never[];
597
+ lastUpdated: null;
598
+ weather: never[];
599
+ };
600
+ cameras: {
601
+ attribution: string;
602
+ cameras: never[];
603
+ lastSourceUpdate: null;
604
+ sourceStatus: string;
605
+ };
606
+ scanners: {
607
+ scanners: never[];
608
+ };
609
+ };