@alteriom/mqtt-schema 0.3.0 → 0.3.1
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 +149 -60
- package/dist/cjs/schema_data.d.ts +181 -0
- package/dist/cjs/schema_data.js +214 -1
- package/dist/cjs/schemas/ota/ota-manifest.schema.json +187 -0
- package/dist/esm/schema_data.js +213 -0
- package/dist/esm/schemas/ota/ota-manifest.schema.json +187 -0
- package/package.json +10 -1
- package/schemas/control_response.schema.json +15 -0
- package/schemas/envelope.schema.json +16 -0
- package/schemas/firmware_status.schema.json +17 -0
- package/schemas/gateway_info.schema.json +21 -0
- package/schemas/gateway_metrics.schema.json +26 -0
- package/schemas/mqtt_v1_bundle.json +14 -0
- package/schemas/ota/ota-manifest.schema.json +187 -0
- package/schemas/sensor_data.schema.json +33 -0
- package/schemas/sensor_heartbeat.schema.json +14 -0
- package/schemas/sensor_status.schema.json +14 -0
- package/schemas/validation_rules.md +44 -0
package/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# @alteriom/mqtt-schema
|
2
2
|
|
3
3
|

|
4
|
+

|
5
|
+

|
4
6
|

|
5
7
|

|
6
8
|

|
@@ -10,62 +12,10 @@
|
|
10
12
|

|
11
13
|
[](https://bundlephobia.com/package/@alteriom/mqtt-schema)
|
12
14
|
|
13
|
-
Alteriom MQTT v1 JSON Schemas, TypeScript types, and production‑ready validation helpers for integrating firmware MQTT payloads into web or backend services.
|
14
|
-
|
15
|
-
> NOTE: OTA manifest CI validation workflow file could not be added via automated API due to path constraints; it can be added manually post-merge if still absent.
|
16
|
-
|
17
|
-
See also: `docs/SCHEMA_MAP.md` for complete schema listing.
|
18
|
-
|
19
|
-
## OTA Firmware Manifest Schema (NEW in 0.3.0)
|
20
|
-
|
21
|
-
The package now includes the OTA firmware manifest schema used by build + deployment tooling.
|
22
|
-
|
23
|
-
Import the schema JSON directly:
|
24
|
-
```ts
|
25
|
-
import otaManifestSchema from '@alteriom/mqtt-schema/schemas/ota/ota-manifest.schema.json';
|
26
|
-
```
|
27
|
-
|
28
|
-
Types:
|
29
|
-
```ts
|
30
|
-
import { OtaManifest, isRichManifest } from '@alteriom/mqtt-schema/types/ota-manifest';
|
31
|
-
```
|
32
15
|
|
33
|
-
|
34
|
-
- Rich manifest:
|
35
|
-
```json
|
36
|
-
{
|
37
|
-
"environment": "universal-sensor",
|
38
|
-
"branch": "main",
|
39
|
-
"manifests": { "dev": { /* richEntry */ }, "prod": { /* richEntry */ } }
|
40
|
-
}
|
41
|
-
```
|
42
|
-
- Minimal environment map:
|
43
|
-
```json
|
44
|
-
{
|
45
|
-
"universal-sensor": { "dev": { /* minimalChannel */ } }
|
46
|
-
}
|
47
|
-
```
|
48
|
-
|
49
|
-
Chunk hashing variants (mutually exclusive):
|
50
|
-
1. Structured objects (offset + size + sha256)
|
51
|
-
2. Array of lowercase sha256 strings
|
52
|
-
|
53
|
-
Validation example:
|
54
|
-
```ts
|
55
|
-
import Ajv from 'ajv';
|
56
|
-
import schema from '@alteriom/mqtt-schema/schemas/ota/ota-manifest.schema.json';
|
57
|
-
import { OtaManifest } from '@alteriom/mqtt-schema/types/ota-manifest';
|
58
|
-
|
59
|
-
const ajv = new Ajv({ allErrors: true });
|
60
|
-
const validate = ajv.compile<OtaManifest>(schema as any);
|
61
|
-
const manifest: OtaManifest = JSON.parse(raw);
|
62
|
-
if (!validate(manifest)) {
|
63
|
-
console.error(validate.errors);
|
64
|
-
}
|
65
|
-
```
|
66
|
-
|
67
|
-
---
|
16
|
+
Alteriom MQTT v1 JSON Schemas, TypeScript types, and production‑ready validation helpers for integrating firmware MQTT payloads into web or backend services.
|
68
17
|
|
18
|
+
|
69
19
|
## Why this exists
|
70
20
|
Firmware emits structured MQTT payloads that must remain tightly aligned with web, analytics, and gateway logic. This package is the single source of truth for:
|
71
21
|
|
@@ -90,6 +40,8 @@ Firmware emits structured MQTT payloads that must remain tightly aligned with we
|
|
90
40
|
npm install @alteriom/mqtt-schema ajv ajv-formats
|
91
41
|
```
|
92
42
|
|
43
|
+
**Support & Compatibility**: Node 18+ tested; Node 20 primary. Dual CJS/ESM builds.
|
44
|
+
|
93
45
|
## Quick Start
|
94
46
|
|
95
47
|
Validate a JSON payload (object already parsed):
|
@@ -137,6 +89,43 @@ Access raw schema JSON (if you need to introspect or power form generation):
|
|
137
89
|
import envelopeSchema from '@alteriom/mqtt-schema/schemas/envelope.schema.json';
|
138
90
|
```
|
139
91
|
|
92
|
+
## OTA Firmware Manifest Schema (v0.3.1+)
|
93
|
+
|
94
|
+
The package includes OTA firmware manifest schema with both rich and minimal formats.
|
95
|
+
|
96
|
+
**Preferred: Stable alias import** (v0.3.1+):
|
97
|
+
```ts
|
98
|
+
import otaManifestSchema from '@alteriom/mqtt-schema/ota-manifest';
|
99
|
+
import { OtaManifest, isRichManifest } from '@alteriom/mqtt-schema/types/ota-manifest';
|
100
|
+
```
|
101
|
+
|
102
|
+
**Legacy: Deep path import** (still supported):
|
103
|
+
```ts
|
104
|
+
import otaManifestSchema from '@alteriom/mqtt-schema/schemas/ota/ota-manifest.schema.json';
|
105
|
+
```
|
106
|
+
|
107
|
+
**Usage example:**
|
108
|
+
```ts
|
109
|
+
import Ajv from 'ajv';
|
110
|
+
import addFormats from 'ajv-formats';
|
111
|
+
import otaManifestSchema from '@alteriom/mqtt-schema/ota-manifest';
|
112
|
+
import { OtaManifest } from '@alteriom/mqtt-schema/types/ota-manifest';
|
113
|
+
|
114
|
+
const ajv = new Ajv({ allErrors: true, strict: false });
|
115
|
+
addFormats(ajv);
|
116
|
+
const validate = ajv.compile<OtaManifest>(otaManifestSchema as any);
|
117
|
+
|
118
|
+
const manifest: OtaManifest = JSON.parse(manifestJson);
|
119
|
+
if (!validate(manifest)) {
|
120
|
+
console.error('Invalid OTA manifest:', validate.errors);
|
121
|
+
}
|
122
|
+
```
|
123
|
+
|
124
|
+
Supported formats:
|
125
|
+
- **Rich manifest**: environment + branch + manifests object
|
126
|
+
- **Minimal environment map**: environment → channels mapping
|
127
|
+
- **Chunk variants**: structured objects or SHA256 array
|
128
|
+
|
140
129
|
## API Surface
|
141
130
|
|
142
131
|
```ts
|
@@ -195,8 +184,6 @@ All Ajv validator functions are compiled once at module load. For typical web us
|
|
195
184
|
| `SensorDataMessage` etc. | TS interfaces | Strongly typed shapes |
|
196
185
|
| `isSensorDataMessage` etc. | type guards | Runtime narrowing helpers |
|
197
186
|
| `schemas/*.json` | JSON | Original schema assets (optional) |
|
198
|
-
| `schemas/ota/ota-manifest.schema.json` | JSON | OTA firmware manifest schema (rich + minimal) |
|
199
|
-
| `types/ota-manifest` | TS types | OtaManifest union + helpers |
|
200
187
|
|
201
188
|
### Validator Keys
|
202
189
|
|
@@ -223,8 +210,6 @@ Schema stability is paramount. We track two related versions:
|
|
223
210
|
|
224
211
|
Backward‑compatible additions: new optional properties or enums, documented in CHANGELOG. Breaking: new required fields, structural changes, or removed properties (triggers parallel `v2` schema path & coordinated firmware rollout).
|
225
212
|
|
226
|
-
Backward-compatible schema additions to OTA manifest WILL use minor bumps.
|
227
|
-
|
228
213
|
## TypeScript / Bundler Notes
|
229
214
|
|
230
215
|
- Works in TS >= 5, Node >= 16, Vite / Webpack / ESBuild.
|
@@ -236,13 +221,13 @@ Backward-compatible schema additions to OTA manifest WILL use minor bumps.
|
|
236
221
|
- Optional custom Ajv injection hook
|
237
222
|
- JSON Schema → Zod conversion example
|
238
223
|
- Runtime metrics helper (count validation categories)
|
239
|
-
- Signed OTA manifest extension
|
240
|
-
- Delta / compressed OTA metadata fields
|
241
224
|
|
242
225
|
## Contributing
|
243
226
|
|
244
227
|
Issues & PRs welcome. Ensure firmware repo schemas remain the authoritative source—do not manually edit generated `schema_data.ts`.
|
245
228
|
|
229
|
+
**Before opening a PR:** Run `npm run verify` to validate schemas, changelog, and tests.
|
230
|
+
|
246
231
|
## Security
|
247
232
|
|
248
233
|
Schemas are static. No network access. Supply-chain risk minimized by keeping dependencies minimal (Ajv + formats only).
|
@@ -250,3 +235,107 @@ Schemas are static. No network access. Supply-chain risk minimized by keeping de
|
|
250
235
|
## License
|
251
236
|
|
252
237
|
MIT
|
238
|
+
|
239
|
+
## Registry Mirrors
|
240
|
+
|
241
|
+
This package is published to BOTH:
|
242
|
+
|
243
|
+
- Public npm registry: `https://registry.npmjs.org` (primary)
|
244
|
+
- GitHub Packages registry: `https://npm.pkg.github.com` (mirror for visibility in repo Packages tab)
|
245
|
+
|
246
|
+
### Installing from GitHub Packages (optional)
|
247
|
+
|
248
|
+
Create or update an `.npmrc` with a scoped registry override (auth token with `read:packages` required):
|
249
|
+
|
250
|
+
```bash
|
251
|
+
@alteriom:registry=https://npm.pkg.github.com
|
252
|
+
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}
|
253
|
+
```
|
254
|
+
|
255
|
+
Then install normally:
|
256
|
+
|
257
|
+
```bash
|
258
|
+
npm install @alteriom/mqtt-schema ajv ajv-formats
|
259
|
+
```
|
260
|
+
|
261
|
+
If you omit the override, npmjs.org is used (recommended for most consumers).
|
262
|
+
|
263
|
+
### Why dual publish?
|
264
|
+
|
265
|
+
- GitHub Packages listing provides provenance + quick visibility in the repo UI.
|
266
|
+
- npm remains the canonical public distribution source (faster, anonymous installs allowed).
|
267
|
+
|
268
|
+
### Operational Notes
|
269
|
+
|
270
|
+
| Aspect | Behavior |
|
271
|
+
|--------|----------|
|
272
|
+
| Build artifact | Built once, same tarball published to both registries. |
|
273
|
+
| Version uniqueness | Same version must not be republished; bump if any change needed. |
|
274
|
+
| Auth (GitHub) | Always required for install from GitHub Packages, even for public repos. |
|
275
|
+
| Tarball parity | Do not rebuild between publishes; workflows ensure single build. |
|
276
|
+
| Fallback strategy | If mirror publish fails (e.g., transient), primary npm publish still stands. |
|
277
|
+
| Provenance flag | Applied for npm (GitHub ignores currently). |
|
278
|
+
|
279
|
+
### Verifying a Release
|
280
|
+
|
281
|
+
```bash
|
282
|
+
npm view @alteriom/mqtt-schema version
|
283
|
+
npm view @alteriom/mqtt-schema version --registry=https://npm.pkg.github.com
|
284
|
+
```
|
285
|
+
|
286
|
+
Both should return the same version.
|
287
|
+
|
288
|
+
## Repository Metadata Compliance
|
289
|
+
|
290
|
+
This repository integrates the `@alteriom/repository-metadata-manager` tooling to continuously validate and report on repository metadata health (description, topics, documentation signals, etc.) within the Alteriom organization standards.
|
291
|
+
|
292
|
+
### Local Usage
|
293
|
+
|
294
|
+
Run a validation (non‑destructive):
|
295
|
+
|
296
|
+
```bash
|
297
|
+
npm run metadata:validate
|
298
|
+
```
|
299
|
+
|
300
|
+
Generate a detailed report:
|
301
|
+
|
302
|
+
```bash
|
303
|
+
npm run metadata:report
|
304
|
+
```
|
305
|
+
|
306
|
+
Configuration lives in `metadata-config.json` (organizationTag `alteriom`). Default detection is auto; adjust if repository classification needs overriding.
|
307
|
+
|
308
|
+
### CI Workflow
|
309
|
+
|
310
|
+
Workflow file: `.github/workflows/metadata-compliance.yml`
|
311
|
+
|
312
|
+
On each push / PR against `main` it will:
|
313
|
+
|
314
|
+
1. Install dependencies
|
315
|
+
2. Run `metadata:validate` (fails job on hard non‑compliance)
|
316
|
+
3. Always attempt a best‑effort report (`metadata:report`) for visibility
|
317
|
+
|
318
|
+
### Tokens / Permissions
|
319
|
+
|
320
|
+
The workflow relies only on the default `GITHUB_TOKEN` for read operations. If future auto‑apply operations are desired, a token with elevated repo scope would be needed and the `metadata:apply` script could be wired (currently omitted to keep CI read‑only).
|
321
|
+
|
322
|
+
### Extending
|
323
|
+
|
324
|
+
If you add new categories of tooling or documentation, re‑run the report to see updated recommendations. For cross‑repo analytics or policy generation, use the original project directly.
|
325
|
+
|
326
|
+
### Applying Metadata (Manual Workflow)
|
327
|
+
|
328
|
+
For authorized maintainers you can run adjustments via GitHub Actions:
|
329
|
+
|
330
|
+
1. Open the "Repository Metadata Apply" workflow under the Actions tab.
|
331
|
+
2. Choose whether to keep `dryRun` (default) or set to `false` to apply.
|
332
|
+
3. Run the workflow; the log will show proposed or applied changes.
|
333
|
+
|
334
|
+
Local dry‑run vs apply:
|
335
|
+
|
336
|
+
```bash
|
337
|
+
npm run metadata:apply:dry # show what would change
|
338
|
+
npm run metadata:apply # apply changes (requires proper permissions via GITHUB_TOKEN)
|
339
|
+
```
|
340
|
+
|
341
|
+
Note: Applying metadata modifies repository settings (description, topics) through the GitHub API; ensure the default token has the necessary repo scopes (in public repositories the workflow GITHUB_TOKEN normally suffices for these fields).
|
@@ -317,3 +317,184 @@ export declare const mqtt_v1_bundle_json: {
|
|
317
317
|
readonly control_response: "control_response.schema.json";
|
318
318
|
};
|
319
319
|
};
|
320
|
+
export declare const ota_ota_manifest_schema: {
|
321
|
+
readonly $id: "https://schemas.alteriom.com/ota/ota-manifest.schema.json";
|
322
|
+
readonly title: "Alteriom OTA Firmware Manifest";
|
323
|
+
readonly description: "Schema for Alteriom OTA firmware manifests supporting both rich and minimal variants";
|
324
|
+
readonly type: "object";
|
325
|
+
readonly oneOf: readonly [{
|
326
|
+
readonly title: "Rich Manifest";
|
327
|
+
readonly description: "Rich manifest format with environment, branch, and manifests object";
|
328
|
+
readonly type: "object";
|
329
|
+
readonly properties: {
|
330
|
+
readonly environment: {
|
331
|
+
readonly type: "string";
|
332
|
+
readonly description: "Target environment (e.g., universal-sensor)";
|
333
|
+
};
|
334
|
+
readonly branch: {
|
335
|
+
readonly type: "string";
|
336
|
+
readonly description: "Source control branch the build originated from";
|
337
|
+
};
|
338
|
+
readonly manifests: {
|
339
|
+
readonly type: "object";
|
340
|
+
readonly description: "Build variants keyed by type (dev, prod, etc.)";
|
341
|
+
readonly patternProperties: {
|
342
|
+
readonly "^[a-z][a-z0-9-]*$": {
|
343
|
+
readonly $ref: "#/$defs/richEntry";
|
344
|
+
};
|
345
|
+
};
|
346
|
+
readonly additionalProperties: false;
|
347
|
+
readonly minProperties: 1;
|
348
|
+
};
|
349
|
+
};
|
350
|
+
readonly required: readonly ["environment", "branch", "manifests"];
|
351
|
+
readonly additionalProperties: true;
|
352
|
+
}, {
|
353
|
+
readonly title: "Minimal Environment Map";
|
354
|
+
readonly description: "Minimal manifest format as environment -> channels mapping";
|
355
|
+
readonly type: "object";
|
356
|
+
readonly patternProperties: {
|
357
|
+
readonly "^[a-z][a-z0-9-]*$": {
|
358
|
+
readonly type: "object";
|
359
|
+
readonly description: "Environment entry with channel mappings";
|
360
|
+
readonly patternProperties: {
|
361
|
+
readonly "^[a-z][a-z0-9-]*$": {
|
362
|
+
readonly $ref: "#/$defs/minimalChannel";
|
363
|
+
};
|
364
|
+
};
|
365
|
+
readonly additionalProperties: false;
|
366
|
+
readonly minProperties: 1;
|
367
|
+
};
|
368
|
+
};
|
369
|
+
readonly additionalProperties: false;
|
370
|
+
readonly minProperties: 1;
|
371
|
+
}];
|
372
|
+
readonly $defs: {
|
373
|
+
readonly richEntry: {
|
374
|
+
readonly title: "Rich Build Entry";
|
375
|
+
readonly description: "Rich manifest build entry (dev or prod)";
|
376
|
+
readonly type: "object";
|
377
|
+
readonly properties: {
|
378
|
+
readonly build_type: {
|
379
|
+
readonly type: "string";
|
380
|
+
readonly enum: readonly ["dev", "prod"];
|
381
|
+
readonly description: "Build type identifier";
|
382
|
+
};
|
383
|
+
readonly file: {
|
384
|
+
readonly type: "string";
|
385
|
+
readonly description: "Firmware binary filename";
|
386
|
+
};
|
387
|
+
readonly size: {
|
388
|
+
readonly type: "integer";
|
389
|
+
readonly minimum: 1;
|
390
|
+
readonly description: "Total firmware size in bytes";
|
391
|
+
};
|
392
|
+
readonly sha256: {
|
393
|
+
readonly type: "string";
|
394
|
+
readonly pattern: "^[a-f0-9]{64}$";
|
395
|
+
readonly description: "SHA256 hash of the full firmware binary (lowercase hex)";
|
396
|
+
};
|
397
|
+
readonly firmware_version: {
|
398
|
+
readonly type: "string";
|
399
|
+
readonly description: "Semantic or build version string";
|
400
|
+
};
|
401
|
+
readonly built: {
|
402
|
+
readonly type: "string";
|
403
|
+
readonly format: "date-time";
|
404
|
+
readonly description: "ISO8601 timestamp when built";
|
405
|
+
};
|
406
|
+
readonly ota_url: {
|
407
|
+
readonly type: "string";
|
408
|
+
readonly format: "uri";
|
409
|
+
readonly description: "Absolute or relative URL to fetch the firmware";
|
410
|
+
};
|
411
|
+
readonly chunk_size: {
|
412
|
+
readonly type: "integer";
|
413
|
+
readonly minimum: 1;
|
414
|
+
readonly description: "Size of each chunk except possibly the last";
|
415
|
+
};
|
416
|
+
readonly chunks: {
|
417
|
+
readonly description: "Either structured chunk objects or array of SHA256 strings";
|
418
|
+
readonly oneOf: readonly [{
|
419
|
+
readonly type: "array";
|
420
|
+
readonly items: {
|
421
|
+
readonly $ref: "#/$defs/chunkObject";
|
422
|
+
};
|
423
|
+
readonly description: "Array of structured chunk objects with metadata";
|
424
|
+
}, {
|
425
|
+
readonly type: "array";
|
426
|
+
readonly items: {
|
427
|
+
readonly type: "string";
|
428
|
+
readonly pattern: "^[a-f0-9]{64}$";
|
429
|
+
readonly description: "SHA256 hash of chunk (lowercase hex)";
|
430
|
+
};
|
431
|
+
readonly description: "Array of SHA256 strings for chunks";
|
432
|
+
}];
|
433
|
+
};
|
434
|
+
};
|
435
|
+
readonly required: readonly ["build_type", "file", "size", "sha256", "firmware_version", "built", "ota_url"];
|
436
|
+
readonly additionalProperties: true;
|
437
|
+
};
|
438
|
+
readonly chunkObject: {
|
439
|
+
readonly title: "OTA Chunk Object";
|
440
|
+
readonly description: "Structured chunk metadata with offset and size";
|
441
|
+
readonly type: "object";
|
442
|
+
readonly properties: {
|
443
|
+
readonly index: {
|
444
|
+
readonly type: "integer";
|
445
|
+
readonly minimum: 0;
|
446
|
+
readonly description: "0-based sequential chunk index";
|
447
|
+
};
|
448
|
+
readonly offset: {
|
449
|
+
readonly type: "integer";
|
450
|
+
readonly minimum: 0;
|
451
|
+
readonly description: "Byte offset within firmware binary";
|
452
|
+
};
|
453
|
+
readonly size: {
|
454
|
+
readonly type: "integer";
|
455
|
+
readonly minimum: 1;
|
456
|
+
readonly description: "Chunk size in bytes";
|
457
|
+
};
|
458
|
+
readonly sha256: {
|
459
|
+
readonly type: "string";
|
460
|
+
readonly pattern: "^[a-f0-9]{64}$";
|
461
|
+
readonly description: "SHA256 hash of the chunk (lowercase hex)";
|
462
|
+
};
|
463
|
+
};
|
464
|
+
readonly required: readonly ["index", "offset", "size", "sha256"];
|
465
|
+
readonly additionalProperties: true;
|
466
|
+
};
|
467
|
+
readonly minimalChannel: {
|
468
|
+
readonly title: "Minimal Channel Entry";
|
469
|
+
readonly description: "Minimal manifest channel entry";
|
470
|
+
readonly type: "object";
|
471
|
+
readonly properties: {
|
472
|
+
readonly file: {
|
473
|
+
readonly type: "string";
|
474
|
+
readonly description: "Firmware binary filename";
|
475
|
+
};
|
476
|
+
readonly size: {
|
477
|
+
readonly type: "integer";
|
478
|
+
readonly minimum: 1;
|
479
|
+
readonly description: "Total firmware size in bytes";
|
480
|
+
};
|
481
|
+
readonly sha256: {
|
482
|
+
readonly type: "string";
|
483
|
+
readonly pattern: "^[a-f0-9]{64}$";
|
484
|
+
readonly description: "SHA256 hash of the firmware binary (lowercase hex)";
|
485
|
+
};
|
486
|
+
readonly version: {
|
487
|
+
readonly type: "string";
|
488
|
+
readonly description: "Firmware version string";
|
489
|
+
};
|
490
|
+
readonly timestamp: {
|
491
|
+
readonly type: "string";
|
492
|
+
readonly format: "date-time";
|
493
|
+
readonly description: "ISO8601 timestamp";
|
494
|
+
};
|
495
|
+
};
|
496
|
+
readonly required: readonly ["file", "size", "sha256", "version", "timestamp"];
|
497
|
+
readonly additionalProperties: true;
|
498
|
+
};
|
499
|
+
};
|
500
|
+
};
|
package/dist/cjs/schema_data.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.mqtt_v1_bundle_json = exports.control_response_schema = exports.firmware_status_schema = exports.gateway_metrics_schema = exports.gateway_info_schema = exports.sensor_status_schema = exports.sensor_heartbeat_schema = exports.sensor_data_schema = exports.envelope_schema = void 0;
|
3
|
+
exports.ota_ota_manifest_schema = exports.mqtt_v1_bundle_json = exports.control_response_schema = exports.firmware_status_schema = exports.gateway_metrics_schema = exports.gateway_info_schema = exports.sensor_status_schema = exports.sensor_heartbeat_schema = exports.sensor_data_schema = exports.envelope_schema = void 0;
|
4
4
|
// AUTO-GENERATED by copy-schemas.cjs. Do not edit manually.
|
5
5
|
/* eslint-disable */
|
6
6
|
exports.envelope_schema = {
|
@@ -400,3 +400,216 @@ exports.mqtt_v1_bundle_json = {
|
|
400
400
|
"control_response": "control_response.schema.json"
|
401
401
|
}
|
402
402
|
};
|
403
|
+
exports.ota_ota_manifest_schema = {
|
404
|
+
"$id": "https://schemas.alteriom.com/ota/ota-manifest.schema.json",
|
405
|
+
"title": "Alteriom OTA Firmware Manifest",
|
406
|
+
"description": "Schema for Alteriom OTA firmware manifests supporting both rich and minimal variants",
|
407
|
+
"type": "object",
|
408
|
+
"oneOf": [
|
409
|
+
{
|
410
|
+
"title": "Rich Manifest",
|
411
|
+
"description": "Rich manifest format with environment, branch, and manifests object",
|
412
|
+
"type": "object",
|
413
|
+
"properties": {
|
414
|
+
"environment": {
|
415
|
+
"type": "string",
|
416
|
+
"description": "Target environment (e.g., universal-sensor)"
|
417
|
+
},
|
418
|
+
"branch": {
|
419
|
+
"type": "string",
|
420
|
+
"description": "Source control branch the build originated from"
|
421
|
+
},
|
422
|
+
"manifests": {
|
423
|
+
"type": "object",
|
424
|
+
"description": "Build variants keyed by type (dev, prod, etc.)",
|
425
|
+
"patternProperties": {
|
426
|
+
"^[a-z][a-z0-9-]*$": {
|
427
|
+
"$ref": "#/$defs/richEntry"
|
428
|
+
}
|
429
|
+
},
|
430
|
+
"additionalProperties": false,
|
431
|
+
"minProperties": 1
|
432
|
+
}
|
433
|
+
},
|
434
|
+
"required": [
|
435
|
+
"environment",
|
436
|
+
"branch",
|
437
|
+
"manifests"
|
438
|
+
],
|
439
|
+
"additionalProperties": true
|
440
|
+
},
|
441
|
+
{
|
442
|
+
"title": "Minimal Environment Map",
|
443
|
+
"description": "Minimal manifest format as environment -> channels mapping",
|
444
|
+
"type": "object",
|
445
|
+
"patternProperties": {
|
446
|
+
"^[a-z][a-z0-9-]*$": {
|
447
|
+
"type": "object",
|
448
|
+
"description": "Environment entry with channel mappings",
|
449
|
+
"patternProperties": {
|
450
|
+
"^[a-z][a-z0-9-]*$": {
|
451
|
+
"$ref": "#/$defs/minimalChannel"
|
452
|
+
}
|
453
|
+
},
|
454
|
+
"additionalProperties": false,
|
455
|
+
"minProperties": 1
|
456
|
+
}
|
457
|
+
},
|
458
|
+
"additionalProperties": false,
|
459
|
+
"minProperties": 1
|
460
|
+
}
|
461
|
+
],
|
462
|
+
"$defs": {
|
463
|
+
"richEntry": {
|
464
|
+
"title": "Rich Build Entry",
|
465
|
+
"description": "Rich manifest build entry (dev or prod)",
|
466
|
+
"type": "object",
|
467
|
+
"properties": {
|
468
|
+
"build_type": {
|
469
|
+
"type": "string",
|
470
|
+
"enum": [
|
471
|
+
"dev",
|
472
|
+
"prod"
|
473
|
+
],
|
474
|
+
"description": "Build type identifier"
|
475
|
+
},
|
476
|
+
"file": {
|
477
|
+
"type": "string",
|
478
|
+
"description": "Firmware binary filename"
|
479
|
+
},
|
480
|
+
"size": {
|
481
|
+
"type": "integer",
|
482
|
+
"minimum": 1,
|
483
|
+
"description": "Total firmware size in bytes"
|
484
|
+
},
|
485
|
+
"sha256": {
|
486
|
+
"type": "string",
|
487
|
+
"pattern": "^[a-f0-9]{64}$",
|
488
|
+
"description": "SHA256 hash of the full firmware binary (lowercase hex)"
|
489
|
+
},
|
490
|
+
"firmware_version": {
|
491
|
+
"type": "string",
|
492
|
+
"description": "Semantic or build version string"
|
493
|
+
},
|
494
|
+
"built": {
|
495
|
+
"type": "string",
|
496
|
+
"format": "date-time",
|
497
|
+
"description": "ISO8601 timestamp when built"
|
498
|
+
},
|
499
|
+
"ota_url": {
|
500
|
+
"type": "string",
|
501
|
+
"format": "uri",
|
502
|
+
"description": "Absolute or relative URL to fetch the firmware"
|
503
|
+
},
|
504
|
+
"chunk_size": {
|
505
|
+
"type": "integer",
|
506
|
+
"minimum": 1,
|
507
|
+
"description": "Size of each chunk except possibly the last"
|
508
|
+
},
|
509
|
+
"chunks": {
|
510
|
+
"description": "Either structured chunk objects or array of SHA256 strings",
|
511
|
+
"oneOf": [
|
512
|
+
{
|
513
|
+
"type": "array",
|
514
|
+
"items": {
|
515
|
+
"$ref": "#/$defs/chunkObject"
|
516
|
+
},
|
517
|
+
"description": "Array of structured chunk objects with metadata"
|
518
|
+
},
|
519
|
+
{
|
520
|
+
"type": "array",
|
521
|
+
"items": {
|
522
|
+
"type": "string",
|
523
|
+
"pattern": "^[a-f0-9]{64}$",
|
524
|
+
"description": "SHA256 hash of chunk (lowercase hex)"
|
525
|
+
},
|
526
|
+
"description": "Array of SHA256 strings for chunks"
|
527
|
+
}
|
528
|
+
]
|
529
|
+
}
|
530
|
+
},
|
531
|
+
"required": [
|
532
|
+
"build_type",
|
533
|
+
"file",
|
534
|
+
"size",
|
535
|
+
"sha256",
|
536
|
+
"firmware_version",
|
537
|
+
"built",
|
538
|
+
"ota_url"
|
539
|
+
],
|
540
|
+
"additionalProperties": true
|
541
|
+
},
|
542
|
+
"chunkObject": {
|
543
|
+
"title": "OTA Chunk Object",
|
544
|
+
"description": "Structured chunk metadata with offset and size",
|
545
|
+
"type": "object",
|
546
|
+
"properties": {
|
547
|
+
"index": {
|
548
|
+
"type": "integer",
|
549
|
+
"minimum": 0,
|
550
|
+
"description": "0-based sequential chunk index"
|
551
|
+
},
|
552
|
+
"offset": {
|
553
|
+
"type": "integer",
|
554
|
+
"minimum": 0,
|
555
|
+
"description": "Byte offset within firmware binary"
|
556
|
+
},
|
557
|
+
"size": {
|
558
|
+
"type": "integer",
|
559
|
+
"minimum": 1,
|
560
|
+
"description": "Chunk size in bytes"
|
561
|
+
},
|
562
|
+
"sha256": {
|
563
|
+
"type": "string",
|
564
|
+
"pattern": "^[a-f0-9]{64}$",
|
565
|
+
"description": "SHA256 hash of the chunk (lowercase hex)"
|
566
|
+
}
|
567
|
+
},
|
568
|
+
"required": [
|
569
|
+
"index",
|
570
|
+
"offset",
|
571
|
+
"size",
|
572
|
+
"sha256"
|
573
|
+
],
|
574
|
+
"additionalProperties": true
|
575
|
+
},
|
576
|
+
"minimalChannel": {
|
577
|
+
"title": "Minimal Channel Entry",
|
578
|
+
"description": "Minimal manifest channel entry",
|
579
|
+
"type": "object",
|
580
|
+
"properties": {
|
581
|
+
"file": {
|
582
|
+
"type": "string",
|
583
|
+
"description": "Firmware binary filename"
|
584
|
+
},
|
585
|
+
"size": {
|
586
|
+
"type": "integer",
|
587
|
+
"minimum": 1,
|
588
|
+
"description": "Total firmware size in bytes"
|
589
|
+
},
|
590
|
+
"sha256": {
|
591
|
+
"type": "string",
|
592
|
+
"pattern": "^[a-f0-9]{64}$",
|
593
|
+
"description": "SHA256 hash of the firmware binary (lowercase hex)"
|
594
|
+
},
|
595
|
+
"version": {
|
596
|
+
"type": "string",
|
597
|
+
"description": "Firmware version string"
|
598
|
+
},
|
599
|
+
"timestamp": {
|
600
|
+
"type": "string",
|
601
|
+
"format": "date-time",
|
602
|
+
"description": "ISO8601 timestamp"
|
603
|
+
}
|
604
|
+
},
|
605
|
+
"required": [
|
606
|
+
"file",
|
607
|
+
"size",
|
608
|
+
"sha256",
|
609
|
+
"version",
|
610
|
+
"timestamp"
|
611
|
+
],
|
612
|
+
"additionalProperties": true
|
613
|
+
}
|
614
|
+
}
|
615
|
+
};
|