{"_id":"@alteriom/mqtt-schema","_rev":"13-4d4d8b77dbc3578db8991461e589681a","name":"@alteriom/mqtt-schema","dist-tags":{"latest":"0.8.0"},"versions":{"0.2.0":{"name":"@alteriom/mqtt-schema","version":"0.2.0","keywords":["alteriom","mqtt","iot","schema","validation","typescript"],"author":{"name":"Alteriom Development Team"},"license":"MIT","_id":"@alteriom/mqtt-schema@0.2.0","maintainers":[{"name":"sparck75","email":"dominic.lavoie@gmail.com"}],"homepage":"https://github.com/Alteriom/alteriom-firmware/tree/main/docs/mqtt_schema","bugs":{"url":"https://github.com/Alteriom/alteriom-firmware/issues"},"dist":{"shasum":"1cbb0f2cecc89c185bb777bff60e7a82f5c3502a","tarball":"https://registry.npmjs.org/@alteriom/mqtt-schema/-/mqtt-schema-0.2.0.tgz","fileCount":38,"integrity":"sha512-JqAeS0OqjnZ3lvkBoqHW8OYCsm79IdK+T6SX6ZVnNy7p6mwEo8Vl1QsJwaSET+jPL2+/KaSzz7J1ma4EsH6hpA==","signatures":[{"sig":"MEUCICC0u6tASA5DIatLP74bL6u+Bg+ERf9iHRADRTOkqSkrAiEAgeEdtSRnbFlKqL/cG0gd9D+H89HM8hhnGT8n9X0fqFg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":85082},"main":"dist/cjs/index.js","type":"commonjs","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","default":"./dist/cjs/index.js","require":"./dist/cjs/index.js"},"./types":{"types":"./dist/cjs/types.d.ts","import":"./dist/esm/types.js","default":"./dist/cjs/types.js","require":"./dist/cjs/types.js"},"./schemas/*":{"default":"./schemas/*"},"./validators":{"types":"./dist/cjs/validators.d.ts","import":"./dist/esm/validators.js","default":"./dist/cjs/validators.js","require":"./dist/cjs/validators.js"},"./package.json":"./package.json"},"gitHead":"5e527c5f98553a63d8281a70313b467deb1ea3af","scripts":{"lint":"echo 'No linter configured'","test":"node test/validate-fixtures.cjs","build":"npm run build:cjs && npm run build:esm && node scripts/copy-schemas.cjs","clean":"rimraf dist schemas","prepare":"npm run build","prebuild":"npm run clean && node scripts/copy-schemas.cjs","build:cjs":"tsc -p tsconfig.json","build:esm":"tsc -p tsconfig.esm.json && node scripts/post-esm.cjs","release:prepare":"node scripts/release-prepare.cjs"},"_npmUser":{"name":"sparck75","email":"dominic.lavoie@gmail.com"},"repository":{"url":"git+https://github.com/Alteriom/alteriom-firmware.git","type":"git"},"_npmVersion":"10.8.2","description":"Alteriom MQTT v1 schemas, TypeScript types, and validation helpers for web integration","directories":{},"sideEffects":false,"_nodeVersion":"22.19.0","typesVersions":{"*":{"types":["dist/cjs/types.d.ts"],"schemas/*":["schemas/*"],"validators":["dist/cjs/validators.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.17.0","rimraf":"^5.0.5","typescript":"^5.4.0","ajv-formats":"^2.1.1"},"peerDependencies":{"ajv":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mqtt-schema_0.2.0_1758426912872_0.5705982159244971","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@alteriom/mqtt-schema","version":"0.2.1","keywords":["alteriom","mqtt","iot","schema","validation","typescript"],"author":{"name":"Alteriom Development Team"},"license":"MIT","_id":"@alteriom/mqtt-schema@0.2.1","maintainers":[{"name":"sparck75","email":"dominic.lavoie@gmail.com"}],"homepage":"https://github.com/Alteriom/alteriom-mqtt-schema#readme","bugs":{"url":"https://github.com/Alteriom/alteriom-mqtt-schema/issues"},"dist":{"shasum":"e43503e3a0757d44f8c25ac3084b0ed14b511416","tarball":"https://registry.npmjs.org/@alteriom/mqtt-schema/-/mqtt-schema-0.2.1.tgz","fileCount":38,"integrity":"sha512-Ll0afGInt7AsNMkroqNB4okfJUH5pT69d05LSyBw02daS3O3aXCay5HMCroV2QnGchDnjk4ROH/IXO98aWwu+g==","signatures":[{"sig":"MEUCIQCF5NOhNvjzEkHwB4nwGryMq+t2UUYcAWG6vzkBmlTu2AIgCmcsIl5C7UvDuKExijd2Jm/laEU6tqeZf1UmaUFi1vw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alteriom%2fmqtt-schema@0.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":86339},"main":"dist/cjs/index.js","type":"commonjs","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","default":"./dist/cjs/index.js","require":"./dist/cjs/index.js"},"./types":{"types":"./dist/cjs/types.d.ts","import":"./dist/esm/types.js","default":"./dist/cjs/types.js","require":"./dist/cjs/types.js"},"./schemas/*":{"default":"./schemas/*"},"./validators":{"types":"./dist/cjs/validators.d.ts","import":"./dist/esm/validators.js","default":"./dist/cjs/validators.js","require":"./dist/cjs/validators.js"},"./package.json":"./package.json"},"gitHead":"505252aedc9fdaf1051913e16ca64bf03d044be8","scripts":{"lint":"echo 'No linter configured'","test":"node test/validate-fixtures.cjs","build":"npm run build:cjs && npm run build:esm && node scripts/copy-schemas.cjs","clean":"rimraf dist schemas","verify":"npm run verify:schemas && npm run verify:release && npm test","prepare":"npm run build","prebuild":"npm run clean && node scripts/copy-schemas.cjs","build:cjs":"tsc -p tsconfig.json","build:esm":"tsc -p tsconfig.esm.json && node scripts/post-esm.cjs","verify:release":"node scripts/check-release-integrity.cjs","verify:schemas":"node scripts/check-schema-sync.cjs","release:prepare":"node scripts/release-prepare.cjs"},"_npmUser":{"name":"sparck75","email":"dominic.lavoie@gmail.com"},"repository":{"url":"git+https://github.com/Alteriom/alteriom-mqtt-schema.git","type":"git"},"_npmVersion":"10.8.2","description":"Alteriom MQTT v1 schemas, TypeScript types, and validation helpers for web integration","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","publishConfig":{"access":"public"},"typesVersions":{"*":{"types":["dist/cjs/types.d.ts"],"schemas/*":["schemas/*"],"validators":["dist/cjs/validators.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.17.0","rimraf":"^5.0.5","typescript":"^5.4.0","ajv-formats":"^2.1.1"},"peerDependencies":{"ajv":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mqtt-schema_0.2.1_1758589053252_0.21430983093658695","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@alteriom/mqtt-schema","version":"0.3.0","keywords":["alteriom","mqtt","iot","schema","validation","typescript","ota"],"author":{"name":"Alteriom Development Team"},"license":"MIT","_id":"@alteriom/mqtt-schema@0.3.0","maintainers":[{"name":"sparck75","email":"dominic.lavoie@gmail.com"}],"homepage":"https://github.com/Alteriom/alteriom-mqtt-schema#readme","bugs":{"url":"https://github.com/Alteriom/alteriom-mqtt-schema/issues"},"dist":{"shasum":"80a032bc0051820a06d27f2f6bbfccab4928c9d6","tarball":"https://registry.npmjs.org/@alteriom/mqtt-schema/-/mqtt-schema-0.3.0.tgz","fileCount":40,"integrity":"sha512-yNFPqRfhH86pBKyc6feCyESighAJg+/SWHNl3RbuycsfSGe8WpSLa6rAd3tG9XtfKMkH4uTz1GXoftJq4xntsg==","signatures":[{"sig":"MEYCIQCNGy3WZDH29Xa327OTy5hXP69M/5+ZOPzXN0zZ1mYBmAIhAPREFNM8Cn8xtetu+nIp+H504ictdIFLv9Byip+f/O2x","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alteriom%2fmqtt-schema@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":90758},"main":"dist/cjs/index.js","type":"commonjs","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","default":"./dist/cjs/index.js","require":"./dist/cjs/index.js"},"./types":{"types":"./dist/cjs/types.d.ts","import":"./dist/esm/types.js","default":"./dist/cjs/types.js","require":"./dist/cjs/types.js"},"./schemas/*":{"default":"./schemas/*"},"./validators":{"types":"./dist/cjs/validators.d.ts","import":"./dist/esm/validators.js","default":"./dist/cjs/validators.js","require":"./dist/cjs/validators.js"},"./package.json":"./package.json","./types/ota-manifest":{"types":"./types/ota-manifest.d.ts","default":"./types/ota-manifest.d.ts"},"./schemas/ota/ota-manifest.schema.json":{"default":"./schemas/ota/ota-manifest.schema.json"}},"gitHead":"a1d77fe5d6558a72b5a69b522bfd98a4f0b3577f","scripts":{"lint":"echo 'No linter configured'","test":"node test/validate-fixtures.cjs","build":"npm run build:cjs && npm run build:esm && node scripts/copy-schemas.cjs","clean":"rimraf dist schemas","verify":"npm run verify:schemas && npm run verify:release && npm test","prepare":"npm run build","prebuild":"npm run clean && node scripts/copy-schemas.cjs","build:cjs":"tsc -p tsconfig.json","build:esm":"tsc -p tsconfig.esm.json && node scripts/post-esm.cjs","validate:ota":"node scripts/validate-ota-manifest.js","wiki:generate":"node scripts/generate-wiki.cjs","metadata:apply":"alteriom-metadata apply --org-tag alteriom","verify:release":"node scripts/check-release-integrity.cjs","verify:schemas":"node scripts/check-schema-sync.cjs","metadata:report":"alteriom-metadata report --org-tag alteriom || echo 'metadata report failed'","release:prepare":"node scripts/release-prepare.cjs","metadata:validate":"alteriom-metadata validate --org-tag alteriom || echo 'metadata validate failed'","metadata:apply:dry":"alteriom-metadata dry-run --org-tag alteriom"},"_npmUser":{"name":"sparck75","email":"dominic.lavoie@gmail.com"},"repository":{"url":"git+https://github.com/Alteriom/alteriom-mqtt-schema.git","type":"git"},"_npmVersion":"10.8.2","description":"Alteriom MQTT v1 schemas, TypeScript types, and validation helpers for web integration","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","dependencies":{"dotenv":"^17.2.2"},"publishConfig":{"access":"public"},"typesVersions":{"*":{"types":["dist/cjs/types.d.ts"],"schemas/*":["schemas/*"],"validators":["dist/cjs/validators.d.ts"],"types/ota-manifest":["types/ota-manifest.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.17.0","rimraf":"^5.0.5","typescript":"^5.4.0","ajv-formats":"^2.1.1","@alteriom/repository-metadata-manager":"^1.2.4"},"peerDependencies":{"ajv":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mqtt-schema_0.3.0_1759013158116_0.5991737360680314","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@alteriom/mqtt-schema","version":"0.3.1","keywords":["alteriom","mqtt","iot","schema","validation","typescript","ota"],"author":{"name":"Alteriom Development Team"},"license":"MIT","_id":"@alteriom/mqtt-schema@0.3.1","maintainers":[{"name":"sparck75","email":"dominic.lavoie@gmail.com"}],"homepage":"https://github.com/Alteriom/alteriom-mqtt-schema#readme","bugs":{"url":"https://github.com/Alteriom/alteriom-mqtt-schema/issues"},"dist":{"shasum":"23a1a92e4ea766ab83496c415b9cfeecea509906","tarball":"https://registry.npmjs.org/@alteriom/mqtt-schema/-/mqtt-schema-0.3.1.tgz","fileCount":53,"integrity":"sha512-Vf+4DtXt2j6y8C14SgsH0NPj+nkGrtIcVLmQWS7WSZxQtdalryNT7QUrS811Y2xfiO5BBINzY3Ps4nqAyCIOcw==","signatures":[{"sig":"MEYCIQCv4BV0sAuJsmXztO7T+PNRSwi1mEiMEQZzXPoh4/xtFQIhAJQ5vmSA40PRgDb+9efQz52aa43zb+/3vW+w2s1+F07g","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alteriom%2fmqtt-schema@0.3.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":144396},"main":"dist/cjs/index.js","type":"commonjs","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","default":"./dist/cjs/index.js","require":"./dist/cjs/index.js"},"./types":{"types":"./dist/cjs/types.d.ts","import":"./dist/esm/types.js","default":"./dist/cjs/types.js","require":"./dist/cjs/types.js"},"./schemas/*":{"default":"./schemas/*"},"./validators":{"types":"./dist/cjs/validators.d.ts","import":"./dist/esm/validators.js","default":"./dist/cjs/validators.js","require":"./dist/cjs/validators.js"},"./ota-manifest":{"import":"./schemas/ota/ota-manifest.schema.json","default":"./schemas/ota/ota-manifest.schema.json","require":"./schemas/ota/ota-manifest.schema.json"},"./package.json":"./package.json","./types/ota-manifest":{"types":"./types/ota-manifest.d.ts","default":"./types/ota-manifest.d.ts"},"./schemas/ota/ota-manifest.schema.json":{"default":"./schemas/ota/ota-manifest.schema.json"}},"gitHead":"f5844ee95b9a780f83a519748eb8a74b518469e1","scripts":{"lint":"echo 'No linter configured'","test":"node test/validate-fixtures.cjs","build":"npm run build:cjs && npm run build:esm && node scripts/copy-schemas.cjs","clean":"rimraf dist schemas","verify":"npm run verify:schemas && npm run verify:release && npm test","prepare":"npm run build","prebuild":"npm run clean && node scripts/copy-schemas.cjs","build:cjs":"tsc -p tsconfig.json","build:esm":"tsc -p tsconfig.esm.json && node scripts/post-esm.cjs","verify:all":"node scripts/verify_all.cjs","validate:ota":"node scripts/validate-ota-manifest.js","wiki:generate":"node scripts/generate-wiki.cjs","metadata:apply":"alteriom-metadata apply --org-tag alteriom","verify:release":"node scripts/check-release-integrity.cjs","verify:schemas":"node scripts/check-schema-sync.cjs","metadata:report":"alteriom-metadata report --org-tag alteriom || echo 'metadata report failed'","release:prepare":"node scripts/release-prepare.cjs","metadata:validate":"alteriom-metadata validate --org-tag alteriom || echo 'metadata validate failed'","metadata:apply:dry":"alteriom-metadata dry-run --org-tag alteriom"},"_npmUser":{"name":"sparck75","email":"dominic.lavoie@gmail.com"},"repository":{"url":"git+https://github.com/Alteriom/alteriom-mqtt-schema.git","type":"git"},"_npmVersion":"10.8.2","description":"Alteriom MQTT v1 schemas, TypeScript types, and validation helpers for web integration","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","dependencies":{"dotenv":"^17.2.2"},"publishConfig":{"access":"public"},"typesVersions":{"*":{"types":["dist/cjs/types.d.ts"],"schemas/*":["schemas/*"],"validators":["dist/cjs/validators.d.ts"],"ota-manifest":["schemas/ota/ota-manifest.schema.json"],"types/ota-manifest":["types/ota-manifest.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.17.0","rimraf":"^5.0.5","typescript":"^5.4.0","ajv-formats":"^2.1.1","@alteriom/repository-metadata-manager":"^1.2.4"},"peerDependencies":{"ajv":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mqtt-schema_0.3.1_1759025653140_0.822345885848665","host":"s3://npm-registry-packages-npm-production"}},"0.3.2":{"name":"@alteriom/mqtt-schema","version":"0.3.2","keywords":["alteriom","mqtt","iot","schema","validation","typescript","ota"],"author":{"name":"Alteriom Development Team"},"license":"MIT","_id":"@alteriom/mqtt-schema@0.3.2","maintainers":[{"name":"sparck75","email":"dominic.lavoie@gmail.com"}],"homepage":"https://github.com/Alteriom/alteriom-mqtt-schema#readme","bugs":{"url":"https://github.com/Alteriom/alteriom-mqtt-schema/issues"},"dist":{"shasum":"96232fc44cb6723e2abf97eba105773e2fa571e9","tarball":"https://registry.npmjs.org/@alteriom/mqtt-schema/-/mqtt-schema-0.3.2.tgz","fileCount":53,"integrity":"sha512-ALDDkKS+hHq83taabQHbDr5wY9aqjCFdJEW+19ZAg3YwvjtjOU0ic6ZUGtf6/mhRUooCT0xf3ob2SUirIA1nIQ==","signatures":[{"sig":"MEUCIQDcUwyXyuAisi3wZpzXtHe16b0xYEX26MmR4HDk9TigBQIgF/dW4v0nmXNahs7KQh+xfJBzYne08gSWOOK7LfrcEw0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alteriom%2fmqtt-schema@0.3.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":146043},"main":"dist/cjs/index.js","type":"commonjs","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","default":"./dist/cjs/index.js","require":"./dist/cjs/index.js"},"./types":{"types":"./dist/cjs/types.d.ts","import":"./dist/esm/types.js","default":"./dist/cjs/types.js","require":"./dist/cjs/types.js"},"./schemas/*":{"default":"./schemas/*"},"./validators":{"types":"./dist/cjs/validators.d.ts","import":"./dist/esm/validators.js","default":"./dist/cjs/validators.js","require":"./dist/cjs/validators.js"},"./ota-manifest":{"import":"./schemas/ota/ota-manifest.schema.json","default":"./schemas/ota/ota-manifest.schema.json","require":"./schemas/ota/ota-manifest.schema.json"},"./package.json":"./package.json","./types/ota-manifest":{"types":"./types/ota-manifest.d.ts","default":"./types/ota-manifest.d.ts"},"./schemas/ota/ota-manifest.schema.json":{"default":"./schemas/ota/ota-manifest.schema.json"}},"gitHead":"6b6d731fcbe101d252cda7f3b415695d19d68765","scripts":{"lint":"echo 'No linter configured - consider adding ESLint for future releases'","test":"node test/validate-fixtures.cjs","build":"npm run build:cjs && npm run build:esm && node scripts/copy-schemas.cjs","clean":"rimraf dist schemas","verify":"npm run verify:schemas && npm run verify:release && npm test","prepare":"npm run build","prebuild":"npm run clean && node scripts/copy-schemas.cjs","test:ota":"node scripts/validate-ota-manifest.js","build:cjs":"tsc -p tsconfig.json","build:esm":"tsc -p tsconfig.esm.json && node scripts/post-esm.cjs","verify:all":"node scripts/verify_all.cjs","validate:ota":"npm run test:ota","wiki:generate":"node scripts/generate-wiki.cjs","metadata:apply":"alteriom-metadata apply --org-tag alteriom","verify:release":"node scripts/check-release-integrity.cjs","verify:schemas":"node scripts/check-schema-sync.cjs","metadata:report":"alteriom-metadata report --org-tag alteriom || echo 'metadata report failed'","release:prepare":"node scripts/release-prepare.cjs","// Build Scripts":"====================","// Legacy Aliases":"====================","metadata:validate":"alteriom-metadata validate --org-tag alteriom || echo 'metadata validate failed'","metadata:apply:dry":"alteriom-metadata dry-run --org-tag alteriom","// Release Management":"====================","// Repository Metadata":"====================","// Testing & Validation":"===================="},"_npmUser":{"name":"sparck75","email":"dominic.lavoie@gmail.com"},"repository":{"url":"git+https://github.com/Alteriom/alteriom-mqtt-schema.git","type":"git"},"_npmVersion":"10.8.2","description":"Alteriom MQTT v1 schemas, TypeScript types, and validation helpers for web integration","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","dependencies":{"dotenv":"^17.2.2"},"publishConfig":{"access":"public"},"typesVersions":{"*":{"types":["dist/cjs/types.d.ts"],"schemas/*":["schemas/*"],"validators":["dist/cjs/validators.d.ts"],"ota-manifest":["schemas/ota/ota-manifest.schema.json"],"types/ota-manifest":["types/ota-manifest.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.17.0","rimraf":"^5.0.5","typescript":"^5.4.0","ajv-formats":"^2.1.1","@alteriom/repository-metadata-manager":"^1.2.4"},"peerDependencies":{"ajv":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mqtt-schema_0.3.2_1759029070030_0.26214644051580693","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@alteriom/mqtt-schema","version":"0.4.0","keywords":["alteriom","mqtt","iot","schema","validation","typescript","ota"],"author":{"name":"Alteriom Development Team"},"license":"MIT","_id":"@alteriom/mqtt-schema@0.4.0","maintainers":[{"name":"sparck75","email":"dominic.lavoie@gmail.com"}],"homepage":"https://github.com/Alteriom/alteriom-mqtt-schema#readme","bugs":{"url":"https://github.com/Alteriom/alteriom-mqtt-schema/issues"},"dist":{"shasum":"c79733b08454dc54ca573ae06fd218da5aa3e7f5","tarball":"https://registry.npmjs.org/@alteriom/mqtt-schema/-/mqtt-schema-0.4.0.tgz","fileCount":62,"integrity":"sha512-xA1Z7XirCjMk5K1vmxSsTN9aUpMb+32zNL0k0K0JiX8wU9vGINY7TPv2RXRXxPpbyX34nbgMmH83811dNSg/ng==","signatures":[{"sig":"MEYCIQD1tGUMY+6Eo3+MonHwWUv6V8niSEy3Je6JTmMQh+/czQIhAI6HSJwONaMrioiJl1CNOLTOkZK2eblHyjAoxjOuepSb","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alteriom%2fmqtt-schema@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":187028},"main":"dist/cjs/index.js","type":"commonjs","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","default":"./dist/cjs/index.js","require":"./dist/cjs/index.js"},"./types":{"types":"./dist/cjs/types.d.ts","import":"./dist/esm/types.js","default":"./dist/cjs/types.js","require":"./dist/cjs/types.js"},"./schemas/*":{"default":"./schemas/*"},"./validators":{"types":"./dist/cjs/validators.d.ts","import":"./dist/esm/validators.js","default":"./dist/cjs/validators.js","require":"./dist/cjs/validators.js"},"./ota-manifest":{"import":"./schemas/ota/ota-manifest.schema.json","default":"./schemas/ota/ota-manifest.schema.json","require":"./schemas/ota/ota-manifest.schema.json"},"./package.json":"./package.json","./types/ota-manifest":{"types":"./types/ota-manifest.d.ts","default":"./types/ota-manifest.d.ts"},"./schemas/ota/ota-manifest.schema.json":{"default":"./schemas/ota/ota-manifest.schema.json"}},"gitHead":"88faec1e158ac39c38abb95200070b91c9288fa1","scripts":{"lint":"echo 'No linter configured - consider adding ESLint for future releases'","test":"node test/validate-fixtures.cjs","build":"npm run build:cjs && npm run build:esm && node scripts/copy-schemas.cjs","clean":"rimraf dist schemas","verify":"npm run verify:schemas && npm run verify:release && npm test","prepare":"npm run build","prebuild":"npm run clean && node scripts/copy-schemas.cjs","test:ota":"node scripts/validate-ota-manifest.js","build:cjs":"tsc -p tsconfig.json","build:esm":"tsc -p tsconfig.esm.json && node scripts/post-esm.cjs","verify:all":"node scripts/verify_all.cjs","validate:ota":"npm run test:ota","wiki:generate":"node scripts/generate-wiki.cjs","metadata:apply":"alteriom-metadata apply --org-tag alteriom","verify:release":"node scripts/check-release-integrity.cjs","verify:schemas":"node scripts/check-schema-sync.cjs","metadata:report":"alteriom-metadata report --org-tag alteriom || echo 'metadata report failed'","release:prepare":"node scripts/release-prepare.cjs","// Build Scripts":"====================","// Legacy Aliases":"====================","metadata:validate":"alteriom-metadata validate --org-tag alteriom || echo 'metadata validate failed'","metadata:apply:dry":"alteriom-metadata dry-run --org-tag alteriom","// Release Management":"====================","// Repository Metadata":"====================","// Testing & Validation":"===================="},"_npmUser":{"name":"sparck75","email":"dominic.lavoie@gmail.com"},"repository":{"url":"git+https://github.com/Alteriom/alteriom-mqtt-schema.git","type":"git"},"_npmVersion":"10.8.2","description":"Alteriom MQTT v1 schemas, TypeScript types, and validation helpers for web integration","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","dependencies":{"dotenv":"^17.2.2"},"publishConfig":{"access":"public"},"typesVersions":{"*":{"types":["dist/cjs/types.d.ts"],"schemas/*":["schemas/*"],"validators":["dist/cjs/validators.d.ts"],"ota-manifest":["schemas/ota/ota-manifest.schema.json"],"types/ota-manifest":["types/ota-manifest.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.17.0","rimraf":"^5.0.5","typescript":"^5.4.0","ajv-formats":"^2.1.1","@alteriom/repository-metadata-manager":"^1.2.4"},"peerDependencies":{"ajv":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mqtt-schema_0.4.0_1760212560797_0.5006577020549434","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@alteriom/mqtt-schema","version":"0.5.0","keywords":["alteriom","mqtt","iot","schema","validation","typescript","ota"],"author":{"name":"Alteriom Development Team"},"license":"MIT","_id":"@alteriom/mqtt-schema@0.5.0","maintainers":[{"name":"sparck75","email":"dominic.lavoie@gmail.com"}],"homepage":"https://github.com/Alteriom/alteriom-mqtt-schema#readme","bugs":{"url":"https://github.com/Alteriom/alteriom-mqtt-schema/issues"},"dist":{"shasum":"da890cb0aef99700f977b28bc333693840287bb4","tarball":"https://registry.npmjs.org/@alteriom/mqtt-schema/-/mqtt-schema-0.5.0.tgz","fileCount":68,"integrity":"sha512-EmXglDGiPmbXE22HYHyFWPBpVMr3K9r0zkwMWZoYSeWVdGRkofqq1iw0UuaeuGjINXM0xKv3GSygHjFdECCDog==","signatures":[{"sig":"MEYCIQDIpEsDgSYH2h0mLGgqqLiU3fMbu32UAlxRjWhe/avYWwIhAO6Q7I4Ip2XrsdGOR2o/fmEV4o91HBzC/4mfrqm6M/Nh","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alteriom%2fmqtt-schema@0.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":216847},"main":"dist/cjs/index.js","type":"commonjs","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","default":"./dist/cjs/index.js","require":"./dist/cjs/index.js"},"./types":{"types":"./dist/cjs/types.d.ts","import":"./dist/esm/types.js","default":"./dist/cjs/types.js","require":"./dist/cjs/types.js"},"./schemas/*":{"default":"./schemas/*"},"./validators":{"types":"./dist/cjs/validators.d.ts","import":"./dist/esm/validators.js","default":"./dist/cjs/validators.js","require":"./dist/cjs/validators.js"},"./ota-manifest":{"import":"./schemas/ota/ota-manifest.schema.json","default":"./schemas/ota/ota-manifest.schema.json","require":"./schemas/ota/ota-manifest.schema.json"},"./package.json":"./package.json","./types/ota-manifest":{"types":"./types/ota-manifest.d.ts","default":"./types/ota-manifest.d.ts"},"./schemas/ota/ota-manifest.schema.json":{"default":"./schemas/ota/ota-manifest.schema.json"}},"gitHead":"32aef68a174102701ad4caeeb3716536ddf3d573","scripts":{"lint":"echo 'No linter configured - consider adding ESLint for future releases'","test":"node test/validate-fixtures.cjs","build":"npm run build:cjs && npm run build:esm && node scripts/copy-schemas.cjs","clean":"rimraf dist schemas","verify":"npm run verify:schemas && npm run verify:release && npm test","prepare":"npm run build","prebuild":"npm run clean && node scripts/copy-schemas.cjs","test:ota":"node scripts/validate-ota-manifest.js","build:cjs":"tsc -p tsconfig.json","build:esm":"tsc -p tsconfig.esm.json && node scripts/post-esm.cjs","verify:all":"node scripts/verify_all.cjs","validate:ota":"npm run test:ota","wiki:generate":"node scripts/generate-wiki.cjs","metadata:apply":"alteriom-metadata apply --org-tag alteriom","verify:release":"node scripts/check-release-integrity.cjs","verify:schemas":"node scripts/check-schema-sync.cjs","metadata:report":"alteriom-metadata report --org-tag alteriom || echo 'metadata report failed'","release:prepare":"node scripts/release-prepare.cjs","// Build Scripts":"====================","// Legacy Aliases":"====================","metadata:validate":"alteriom-metadata validate --org-tag alteriom || echo 'metadata validate failed'","metadata:apply:dry":"alteriom-metadata dry-run --org-tag alteriom","// Release Management":"====================","// Repository Metadata":"====================","// Testing & Validation":"===================="},"_npmUser":{"name":"sparck75","email":"dominic.lavoie@gmail.com"},"repository":{"url":"git+https://github.com/Alteriom/alteriom-mqtt-schema.git","type":"git"},"_npmVersion":"10.8.2","description":"Alteriom MQTT v1 schemas, TypeScript types, and validation helpers for web integration","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","dependencies":{"dotenv":"^17.2.2"},"publishConfig":{"access":"public"},"typesVersions":{"*":{"types":["dist/cjs/types.d.ts"],"schemas/*":["schemas/*"],"validators":["dist/cjs/validators.d.ts"],"ota-manifest":["schemas/ota/ota-manifest.schema.json"],"types/ota-manifest":["types/ota-manifest.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.17.0","rimraf":"^5.0.5","typescript":"^5.4.0","ajv-formats":"^2.1.1","@alteriom/repository-metadata-manager":"^1.2.4"},"peerDependencies":{"ajv":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mqtt-schema_0.5.0_1760303361301_0.37830965627677715","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@alteriom/mqtt-schema","version":"0.6.0","keywords":["alteriom","mqtt","iot","schema","validation","typescript","ota"],"author":{"name":"Alteriom Development Team"},"license":"MIT","_id":"@alteriom/mqtt-schema@0.6.0","maintainers":[{"name":"sparck75","email":"dominic.lavoie@gmail.com"}],"homepage":"https://github.com/Alteriom/alteriom-mqtt-schema#readme","bugs":{"url":"https://github.com/Alteriom/alteriom-mqtt-schema/issues"},"dist":{"shasum":"fcfe93a3a062d8a4f38bff6635f34b7c79a00e0e","tarball":"https://registry.npmjs.org/@alteriom/mqtt-schema/-/mqtt-schema-0.6.0.tgz","fileCount":68,"integrity":"sha512-JPzpRpEdUNssBE4zsk7uSkmv7S0EE2fKmipVqMzAm36Y+oV4bgIuB/Z8L5+28y68cwDvgeTQvaaT2cFL1qe31g==","signatures":[{"sig":"MEUCIAjqmoReaVzkSGE6OnduOz+tfphdMPz/4TpzLzFUWobmAiEAnb5cW/7oe/saAvj1dykbNodSq7nnNj3aGNSBs+nlOlc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alteriom%2fmqtt-schema@0.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":256053},"main":"dist/cjs/index.js","type":"commonjs","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","default":"./dist/cjs/index.js","require":"./dist/cjs/index.js"},"./types":{"types":"./dist/cjs/types.d.ts","import":"./dist/esm/types.js","default":"./dist/cjs/types.js","require":"./dist/cjs/types.js"},"./schemas/*":{"default":"./schemas/*"},"./validators":{"types":"./dist/cjs/validators.d.ts","import":"./dist/esm/validators.js","default":"./dist/cjs/validators.js","require":"./dist/cjs/validators.js"},"./ota-manifest":{"import":"./schemas/ota/ota-manifest.schema.json","default":"./schemas/ota/ota-manifest.schema.json","require":"./schemas/ota/ota-manifest.schema.json"},"./package.json":"./package.json","./types/ota-manifest":{"types":"./types/ota-manifest.d.ts","default":"./types/ota-manifest.d.ts"},"./schemas/ota/ota-manifest.schema.json":{"default":"./schemas/ota/ota-manifest.schema.json"}},"gitHead":"d9882018e09d310195d2512f20b60f80c4250643","scripts":{"lint":"echo 'No linter configured - consider adding ESLint for future releases'","test":"node test/validate-fixtures.cjs","build":"npm run build:cjs && npm run build:esm && node scripts/copy-schemas.cjs","clean":"rimraf dist schemas","verify":"npm run verify:schemas && npm run verify:release && npm test","prepare":"npm run build","prebuild":"npm run clean && node scripts/copy-schemas.cjs","test:ota":"node scripts/validate-ota-manifest.js","build:cjs":"tsc -p tsconfig.json","build:esm":"tsc -p tsconfig.esm.json && node scripts/post-esm.cjs","verify:all":"node scripts/verify_all.cjs","validate:ota":"npm run test:ota","wiki:generate":"node scripts/generate-wiki.cjs","metadata:apply":"alteriom-metadata apply --org-tag alteriom","verify:release":"node scripts/check-release-integrity.cjs","verify:schemas":"node scripts/check-schema-sync.cjs","metadata:report":"alteriom-metadata report --org-tag alteriom || echo 'metadata report failed'","release:prepare":"node scripts/release-prepare.cjs","// Build Scripts":"====================","// Legacy Aliases":"====================","metadata:validate":"alteriom-metadata validate --org-tag alteriom || echo 'metadata validate failed'","metadata:apply:dry":"alteriom-metadata dry-run --org-tag alteriom","// Release Management":"====================","// Repository Metadata":"====================","// Testing & Validation":"===================="},"_npmUser":{"name":"sparck75","email":"dominic.lavoie@gmail.com"},"repository":{"url":"git+https://github.com/Alteriom/alteriom-mqtt-schema.git","type":"git"},"_npmVersion":"10.8.2","description":"Alteriom MQTT v1 schemas, TypeScript types, and validation helpers for web integration","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","dependencies":{"dotenv":"^17.2.2"},"publishConfig":{"access":"public"},"typesVersions":{"*":{"types":["dist/cjs/types.d.ts"],"schemas/*":["schemas/*"],"validators":["dist/cjs/validators.d.ts"],"ota-manifest":["schemas/ota/ota-manifest.schema.json"],"types/ota-manifest":["types/ota-manifest.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.17.0","rimraf":"^5.0.5","typescript":"^5.4.0","ajv-formats":"^2.1.1","@alteriom/repository-metadata-manager":"^1.2.4"},"peerDependencies":{"ajv":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mqtt-schema_0.6.0_1760911752608_0.9739595981028917","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@alteriom/mqtt-schema","version":"0.7.0","keywords":["alteriom","mqtt","iot","schema","validation","typescript","ota"],"author":{"name":"Alteriom Development Team"},"license":"MIT","_id":"@alteriom/mqtt-schema@0.7.0","maintainers":[{"name":"sparck75","email":"dominic.lavoie@gmail.com"}],"homepage":"https://github.com/Alteriom/alteriom-mqtt-schema#readme","bugs":{"url":"https://github.com/Alteriom/alteriom-mqtt-schema/issues"},"dist":{"shasum":"009f58bd8642f755e1e4eea5b1b6d62df3957542","tarball":"https://registry.npmjs.org/@alteriom/mqtt-schema/-/mqtt-schema-0.7.0.tgz","fileCount":68,"integrity":"sha512-rG6ZxJHPZS1jayjeN7lcRAuNBeex1qZZFxtL5ptzYrbGJ436Be0sKF1CQZ9I0PIGAsm/IRNaU+/m2ahYUZvzVQ==","signatures":[{"sig":"MEUCIAgazMqFKiR6cky1gU8BznnjhxXZ7ulgloMpSmnvSup8AiEA19uZHgx6QkbzerQeZ8A+PXaKZQjjkN3kQLRgmI2t29Y=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alteriom%2fmqtt-schema@0.7.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":300707},"main":"dist/cjs/index.js","type":"commonjs","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","default":"./dist/cjs/index.js","require":"./dist/cjs/index.js"},"./types":{"types":"./dist/cjs/types.d.ts","import":"./dist/esm/types.js","default":"./dist/cjs/types.js","require":"./dist/cjs/types.js"},"./schemas/*":{"default":"./schemas/*"},"./validators":{"types":"./dist/cjs/validators.d.ts","import":"./dist/esm/validators.js","default":"./dist/cjs/validators.js","require":"./dist/cjs/validators.js"},"./ota-manifest":{"import":"./schemas/ota/ota-manifest.schema.json","default":"./schemas/ota/ota-manifest.schema.json","require":"./schemas/ota/ota-manifest.schema.json"},"./package.json":"./package.json","./types/ota-manifest":{"types":"./types/ota-manifest.d.ts","default":"./types/ota-manifest.d.ts"},"./schemas/ota/ota-manifest.schema.json":{"default":"./schemas/ota/ota-manifest.schema.json"}},"gitHead":"4644599f186f32a3baf0fc3ef0563e246f8b6965","scripts":{"lint":"echo 'No linter configured - consider adding ESLint for future releases'","test":"node test/validate-fixtures.cjs","build":"npm run build:cjs && npm run build:esm && node scripts/copy-schemas.cjs","clean":"rimraf dist schemas","verify":"npm run verify:schemas && npm run verify:release && npm test","prepare":"npm run build","prebuild":"npm run clean && node scripts/copy-schemas.cjs","test:ota":"node scripts/validate-ota-manifest.js","build:cjs":"tsc -p tsconfig.json","build:esm":"tsc -p tsconfig.esm.json && node scripts/post-esm.cjs","verify:all":"node scripts/verify_all.cjs","validate:ota":"npm run test:ota","wiki:generate":"node scripts/generate-wiki.cjs","metadata:apply":"alteriom-metadata apply --org-tag alteriom","verify:release":"node scripts/check-release-integrity.cjs","verify:schemas":"node scripts/check-schema-sync.cjs","metadata:report":"alteriom-metadata report --org-tag alteriom || echo 'metadata report failed'","release:prepare":"node scripts/release-prepare.cjs","// Build Scripts":"====================","// Legacy Aliases":"====================","metadata:validate":"alteriom-metadata validate --org-tag alteriom || echo 'metadata validate failed'","metadata:apply:dry":"alteriom-metadata dry-run --org-tag alteriom","// Release Management":"====================","// Repository Metadata":"====================","// Testing & Validation":"===================="},"_npmUser":{"name":"sparck75","email":"dominic.lavoie@gmail.com"},"repository":{"url":"git+https://github.com/Alteriom/alteriom-mqtt-schema.git","type":"git"},"_npmVersion":"10.8.2","description":"Alteriom MQTT v1 schemas, TypeScript types, and validation helpers for web integration","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","dependencies":{"dotenv":"^17.2.2"},"publishConfig":{"access":"public"},"typesVersions":{"*":{"types":["dist/cjs/types.d.ts"],"schemas/*":["schemas/*"],"validators":["dist/cjs/validators.d.ts"],"ota-manifest":["schemas/ota/ota-manifest.schema.json"],"types/ota-manifest":["types/ota-manifest.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.17.0","rimraf":"^5.0.5","typescript":"^5.4.0","ajv-formats":"^2.1.1","@alteriom/repository-metadata-manager":"^1.2.4"},"peerDependencies":{"ajv":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mqtt-schema_0.7.0_1761077138183_0.025180132817964163","host":"s3://npm-registry-packages-npm-production"}},"0.7.1":{"name":"@alteriom/mqtt-schema","version":"0.7.1","keywords":["alteriom","mqtt","iot","schema","validation","typescript","ota"],"author":{"name":"Alteriom Development Team"},"license":"MIT","_id":"@alteriom/mqtt-schema@0.7.1","maintainers":[{"name":"sparck75","email":"dominic.lavoie@gmail.com"}],"homepage":"https://github.com/Alteriom/alteriom-mqtt-schema#readme","bugs":{"url":"https://github.com/Alteriom/alteriom-mqtt-schema/issues"},"dist":{"shasum":"bc18fae077dfee64d9ad1bc5b3cf62ec3d92d1a9","tarball":"https://registry.npmjs.org/@alteriom/mqtt-schema/-/mqtt-schema-0.7.1.tgz","fileCount":74,"integrity":"sha512-aLuabWy13n6XCs6O9GwGq/UEGiJvOpv7Ky5oRmraD00TBrK7XQg4Ucn1j0kOu/AUUlm2oy54m7uzyEfdT38oLQ==","signatures":[{"sig":"MEUCIQCgG+UA6gCtwWxcQTB9OoSgmIXM1vdd52RiolHlcz6gfgIgfsIbnAXyrQZi9ACFsK1rue+GEbR8BlPT0s2en8HWuMM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alteriom%2fmqtt-schema@0.7.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":401484},"main":"dist/cjs/index.js","type":"commonjs","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","default":"./dist/cjs/index.js","require":"./dist/cjs/index.js"},"./types":{"types":"./dist/cjs/types.d.ts","import":"./dist/esm/types.js","default":"./dist/cjs/types.js","require":"./dist/cjs/types.js"},"./schemas/*":{"default":"./schemas/*"},"./validators":{"types":"./dist/cjs/validators.d.ts","import":"./dist/esm/validators.js","default":"./dist/cjs/validators.js","require":"./dist/cjs/validators.js"},"./ota-manifest":{"import":"./schemas/ota/ota-manifest.schema.json","default":"./schemas/ota/ota-manifest.schema.json","require":"./schemas/ota/ota-manifest.schema.json"},"./package.json":"./package.json","./types/ota-manifest":{"types":"./types/ota-manifest.d.ts","default":"./types/ota-manifest.d.ts"},"./schemas/ota/ota-manifest.schema.json":{"default":"./schemas/ota/ota-manifest.schema.json"}},"gitHead":"2b1b0e64646336deeaa631d333ce2104fb746377","scripts":{"lint":"echo 'No linter configured - consider adding ESLint for future releases'","test":"node test/validate-fixtures.cjs","build":"npm run build:cjs && npm run build:esm && node scripts/copy-schemas.cjs","clean":"rimraf dist schemas","verify":"npm run verify:schemas && npm run verify:release && npm test","prepare":"npm run build","prebuild":"npm run clean && node scripts/copy-schemas.cjs","test:ota":"node scripts/validate-ota-manifest.js","build:cjs":"tsc -p tsconfig.json","build:esm":"tsc -p tsconfig.esm.json && node scripts/post-esm.cjs","verify:all":"node scripts/verify_all.cjs","validate:ota":"npm run test:ota","wiki:generate":"node scripts/generate-wiki.cjs","metadata:apply":"alteriom-metadata apply --org-tag alteriom","verify:release":"node scripts/check-release-integrity.cjs","verify:schemas":"node scripts/check-schema-sync.cjs","metadata:report":"alteriom-metadata report --org-tag alteriom || echo 'metadata report failed'","release:prepare":"node scripts/release-prepare.cjs","// Build Scripts":"====================","// Legacy Aliases":"====================","metadata:validate":"alteriom-metadata validate --org-tag alteriom || echo 'metadata validate failed'","metadata:apply:dry":"alteriom-metadata dry-run --org-tag alteriom","// Release Management":"====================","// Repository Metadata":"====================","// Testing & Validation":"===================="},"_npmUser":{"name":"sparck75","email":"dominic.lavoie@gmail.com"},"repository":{"url":"git+https://github.com/Alteriom/alteriom-mqtt-schema.git","type":"git"},"_npmVersion":"10.8.2","description":"Alteriom MQTT v1 schemas, TypeScript types, and validation helpers for web integration","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","dependencies":{"dotenv":"^17.2.2"},"publishConfig":{"access":"public"},"typesVersions":{"*":{"types":["dist/cjs/types.d.ts"],"schemas/*":["schemas/*"],"validators":["dist/cjs/validators.d.ts"],"ota-manifest":["schemas/ota/ota-manifest.schema.json"],"types/ota-manifest":["types/ota-manifest.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.17.0","rimraf":"^5.0.5","typescript":"^5.4.0","ajv-formats":"^2.1.1","@alteriom/repository-metadata-manager":"^1.2.4"},"peerDependencies":{"ajv":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mqtt-schema_0.7.1_1761257320527_0.06949329371978541","host":"s3://npm-registry-packages-npm-production"}},"0.7.2":{"name":"@alteriom/mqtt-schema","version":"0.7.2","keywords":["alteriom","mqtt","iot","schema","validation","typescript","ota"],"author":{"name":"Alteriom Development Team"},"license":"MIT","_id":"@alteriom/mqtt-schema@0.7.2","maintainers":[{"name":"sparck75","email":"dominic.lavoie@gmail.com"}],"homepage":"https://github.com/Alteriom/alteriom-mqtt-schema#readme","bugs":{"url":"https://github.com/Alteriom/alteriom-mqtt-schema/issues"},"dist":{"shasum":"0814455fc15fbf2411fd52a66c2b7167adbde5cf","tarball":"https://registry.npmjs.org/@alteriom/mqtt-schema/-/mqtt-schema-0.7.2.tgz","fileCount":95,"integrity":"sha512-iGE/xmd8yV0IJsFgQKqDsnc6epiAfKmiLTVEVtzza+fdn9NlytP7Nbk4ylVii2UQiFjqzRwCnI4cIlY8EkjzIw==","signatures":[{"sig":"MEUCIAXfDZE9hr08Fx1DJYFSy5+MBzIpROl9LYY6sxfNRYMJAiEApLvAfmcMJzH+3vnO1vlaC8l4A6HznjsGMgPYEr2LcDs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alteriom%2fmqtt-schema@0.7.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":680715},"main":"dist/cjs/index.js","type":"commonjs","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","default":"./dist/cjs/index.js","require":"./dist/cjs/index.js"},"./types":{"types":"./dist/cjs/types.d.ts","import":"./dist/esm/types.js","default":"./dist/cjs/types.js","require":"./dist/cjs/types.js"},"./schemas/*":{"default":"./schemas/*"},"./validators":{"types":"./dist/cjs/validators.d.ts","import":"./dist/esm/validators.js","default":"./dist/cjs/validators.js","require":"./dist/cjs/validators.js"},"./ota-manifest":{"import":"./schemas/ota/ota-manifest.schema.json","default":"./schemas/ota/ota-manifest.schema.json","require":"./schemas/ota/ota-manifest.schema.json"},"./package.json":"./package.json","./types/ota-manifest":{"types":"./types/ota-manifest.d.ts","default":"./types/ota-manifest.d.ts"},"./schemas/ota/ota-manifest.schema.json":{"default":"./schemas/ota/ota-manifest.schema.json"}},"gitHead":"2a750dc3fdf46175a9ec972cb5a63ae65f73aebb","scripts":{"lint":"echo 'No linter configured - consider adding ESLint for future releases'","test":"node test/validate-fixtures.cjs","build":"npm run build:cjs && npm run build:esm && node scripts/copy-schemas.cjs","clean":"rimraf dist schemas","verify":"npm run verify:schemas && npm run verify:release && npm test","prepare":"npm run build","prebuild":"npm run clean && node scripts/copy-schemas.cjs","test:ota":"node scripts/validate-ota-manifest.js","build:cjs":"tsc -p tsconfig.json","build:esm":"tsc -p tsconfig.esm.json && node scripts/post-esm.cjs","verify:all":"node scripts/verify_all.cjs","validate:ota":"npm run test:ota","wiki:generate":"node scripts/generate-wiki.cjs","metadata:apply":"alteriom-metadata apply --org-tag alteriom","verify:release":"node scripts/check-release-integrity.cjs","verify:schemas":"node scripts/check-schema-sync.cjs","metadata:report":"alteriom-metadata report --org-tag alteriom || echo 'metadata report failed'","release:prepare":"node scripts/release-prepare.cjs","// Build Scripts":"====================","// Legacy Aliases":"====================","metadata:validate":"alteriom-metadata validate --org-tag alteriom || echo 'metadata validate failed'","metadata:apply:dry":"alteriom-metadata dry-run --org-tag alteriom","// Release Management":"====================","// Repository Metadata":"====================","// Testing & Validation":"===================="},"_npmUser":{"name":"sparck75","email":"dominic.lavoie@gmail.com"},"repository":{"url":"git+https://github.com/Alteriom/alteriom-mqtt-schema.git","type":"git"},"_npmVersion":"10.8.2","description":"Alteriom MQTT v1 schemas, TypeScript types, and validation helpers for web integration","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","dependencies":{"dotenv":"^17.2.2"},"publishConfig":{"access":"public"},"typesVersions":{"*":{"types":["dist/cjs/types.d.ts"],"schemas/*":["schemas/*"],"validators":["dist/cjs/validators.d.ts"],"ota-manifest":["schemas/ota/ota-manifest.schema.json"],"types/ota-manifest":["types/ota-manifest.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.17.0","rimraf":"^5.0.5","typescript":"^5.4.0","ajv-formats":"^2.1.1","@alteriom/repository-metadata-manager":"^1.2.4"},"peerDependencies":{"ajv":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mqtt-schema_0.7.2_1761262140703_0.6298051354364467","host":"s3://npm-registry-packages-npm-production"}},"0.7.3":{"name":"@alteriom/mqtt-schema","version":"0.7.3","keywords":["alteriom","mqtt","iot","schema","validation","typescript","ota"],"author":{"name":"Alteriom Development Team"},"license":"MIT","_id":"@alteriom/mqtt-schema@0.7.3","maintainers":[{"name":"sparck75","email":"dominic.lavoie@gmail.com"}],"homepage":"https://github.com/Alteriom/alteriom-mqtt-schema#readme","bugs":{"url":"https://github.com/Alteriom/alteriom-mqtt-schema/issues"},"dist":{"shasum":"55d9224adfac1aa39ce90798a22149b50e759285","tarball":"https://registry.npmjs.org/@alteriom/mqtt-schema/-/mqtt-schema-0.7.3.tgz","fileCount":101,"integrity":"sha512-0NiucKOp5ojJBu4gB4LsCGzUc2t1Pk4daBVa4qlRaDj1O0au7sq5L8o6rZtr9AHuLLMK70F/6IElqg4AXMiAHg==","signatures":[{"sig":"MEYCIQDqaSD03hIv4EbLZDXuys5XdntLkLCbnPXykVu9+yFaygIhAPBqgMaDI2FozAdRa6Znmv/LxdipWGRtM6HfGqIU/heI","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alteriom%2fmqtt-schema@0.7.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":722951},"main":"dist/cjs/index.js","type":"commonjs","types":"dist/cjs/index.d.ts","module":"dist/esm/index.js","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./dist/cjs/index.d.ts","import":"./dist/esm/index.js","default":"./dist/cjs/index.js","require":"./dist/cjs/index.js"},"./types":{"types":"./dist/cjs/types.d.ts","import":"./dist/esm/types.js","default":"./dist/cjs/types.js","require":"./dist/cjs/types.js"},"./schemas/*":{"default":"./schemas/*"},"./validators":{"types":"./dist/cjs/validators.d.ts","import":"./dist/esm/validators.js","default":"./dist/cjs/validators.js","require":"./dist/cjs/validators.js"},"./ota-manifest":{"import":"./schemas/ota/ota-manifest.schema.json","default":"./schemas/ota/ota-manifest.schema.json","require":"./schemas/ota/ota-manifest.schema.json"},"./package.json":"./package.json","./types/ota-manifest":{"types":"./types/ota-manifest.d.ts","default":"./types/ota-manifest.d.ts"},"./schemas/ota/ota-manifest.schema.json":{"default":"./schemas/ota/ota-manifest.schema.json"}},"gitHead":"e83b7812b2186c2ac90763c8b0acf6221a74ed60","scripts":{"lint":"eslint src --ext .ts","test":"npm run test:unit && npm run test:fixtures","bench":"npm run bench:classification && npm run bench:validation","build":"npm run build:cjs && npm run build:esm && node scripts/copy-schemas.cjs","clean":"rimraf dist schemas","format":"prettier --write \"src/**/*.ts\"","verify":"npm run verify:schemas && npm run verify:release && npm test","prepare":"husky","lint:fix":"eslint src --ext .ts --fix","prebuild":"npm run clean && node scripts/copy-schemas.cjs","test:ota":"node scripts/validate-ota-manifest.js","build:cjs":"tsc -p tsconfig.json","build:esm":"tsc -p tsconfig.esm.json && node scripts/post-esm.cjs","test:unit":"vitest run","verify:all":"node scripts/verify_all.cjs","format:check":"prettier --check \"src/**/*.ts\"","test:unit:ui":"vitest --ui","validate:ota":"npm run test:ota","test:coverage":"vitest run --coverage","test:fixtures":"node test/validate-fixtures.cjs","wiki:generate":"node scripts/generate-wiki.cjs","metadata:apply":"alteriom-metadata apply --org-tag alteriom","verify:release":"node scripts/check-release-integrity.cjs","verify:schemas":"node scripts/check-schema-sync.cjs","metadata:report":"alteriom-metadata report --org-tag alteriom || echo 'metadata report failed'","release:prepare":"node scripts/release-prepare.cjs","test:unit:watch":"vitest watch","// Build Scripts":"====================","bench:validation":"tsx test/benchmarks/validation.bench.ts","// Legacy Aliases":"====================","metadata:validate":"alteriom-metadata validate --org-tag alteriom || echo 'metadata validate failed'","metadata:apply:dry":"alteriom-metadata dry-run --org-tag alteriom","bench:classification":"tsx test/benchmarks/classification.bench.ts","// Release Management":"====================","// Repository Metadata":"====================","// Testing & Validation":"===================="},"_npmUser":{"name":"sparck75","email":"dominic.lavoie@gmail.com"},"repository":{"url":"git+https://github.com/Alteriom/alteriom-mqtt-schema.git","type":"git"},"_npmVersion":"10.8.2","description":"Alteriom MQTT v1 schemas, TypeScript types, and validation helpers for web integration","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","dependencies":{"dotenv":"^17.2.2"},"publishConfig":{"access":"public"},"typesVersions":{"*":{"types":["dist/cjs/types.d.ts"],"schemas/*":["schemas/*"],"validators":["dist/cjs/validators.d.ts"],"ota-manifest":["schemas/ota/ota-manifest.schema.json"],"types/ota-manifest":["types/ota-manifest.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.17.0","tsx":"^4.20.6","husky":"^9.1.7","eslint":"^9.39.1","rimraf":"^5.0.5","vitest":"^4.0.7","prettier":"^3.6.2","tinybench":"^5.1.0","@eslint/js":"^9.39.1","typescript":"^5.4.0","@types/node":"^24.10.0","ajv-formats":"^2.1.1","lint-staged":"^16.2.6","@vitest/coverage-v8":"^4.0.7","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.4","@typescript-eslint/parser":"^8.46.3","@typescript-eslint/eslint-plugin":"^8.46.3","@alteriom/repository-metadata-manager":"^1.2.4"},"peerDependencies":{"ajv":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mqtt-schema_0.7.3_1762355003425_0.5759993429532217","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@alteriom/mqtt-schema","version":"0.8.0","description":"Alteriom MQTT v1 schemas, TypeScript types, and validation helpers for web integration","license":"MIT","author":{"name":"Alteriom Development Team"},"repository":{"type":"git","url":"git+https://github.com/Alteriom/alteriom-mqtt-schema.git"},"homepage":"https://github.com/Alteriom/alteriom-mqtt-schema#readme","bugs":{"url":"https://github.com/Alteriom/alteriom-mqtt-schema/issues"},"type":"commonjs","main":"dist/cjs/index.js","module":"dist/esm/index.js","types":"dist/cjs/index.d.ts","sideEffects":false,"exports":{".":{"require":"./dist/cjs/index.js","import":"./dist/esm/index.js","types":"./dist/cjs/index.d.ts","default":"./dist/cjs/index.js"},"./validators":{"require":"./dist/cjs/validators.js","import":"./dist/esm/validators.js","types":"./dist/cjs/validators.d.ts","default":"./dist/cjs/validators.js"},"./types":{"require":"./dist/cjs/types.js","import":"./dist/esm/types.js","types":"./dist/cjs/types.d.ts","default":"./dist/cjs/types.js"},"./schemas/*":{"default":"./schemas/*"},"./schemas/ota/ota-manifest.schema.json":{"default":"./schemas/ota/ota-manifest.schema.json"},"./ota-manifest":{"import":"./schemas/ota/ota-manifest.schema.json","require":"./schemas/ota/ota-manifest.schema.json","default":"./schemas/ota/ota-manifest.schema.json"},"./types/ota-manifest":{"types":"./types/ota-manifest.d.ts","default":"./types/ota-manifest.d.ts"},"./package.json":"./package.json"},"typesVersions":{"*":{"validators":["dist/cjs/validators.d.ts"],"types":["dist/cjs/types.d.ts"],"schemas/*":["schemas/*"],"types/ota-manifest":["types/ota-manifest.d.ts"],"ota-manifest":["schemas/ota/ota-manifest.schema.json"]}},"publishConfig":{"access":"public"},"engines":{"node":">=16.0.0"},"scripts":{"// Build Scripts":"====================","prepare":"husky","prebuild":"npm run clean && node scripts/copy-schemas.cjs","build:cjs":"tsc -p tsconfig.json","build:esm":"tsc -p tsconfig.esm.json && node scripts/post-esm.cjs","build":"npm run build:cjs && npm run build:esm && node scripts/copy-schemas.cjs","clean":"rimraf dist schemas","// Testing & Validation":"====================","lint":"eslint src --ext .ts","lint:fix":"eslint src --ext .ts --fix","format":"prettier --write \"src/**/*.ts\"","format:check":"prettier --check \"src/**/*.ts\"","test":"npm run test:unit && npm run test:fixtures","test:unit":"vitest run","test:unit:watch":"vitest watch","test:unit:ui":"vitest --ui","test:coverage":"vitest run --coverage","test:fixtures":"node test/validate-fixtures.cjs","test:ota":"node scripts/validate-ota-manifest.js","bench":"npm run bench:classification && npm run bench:validation","bench:classification":"tsx test/benchmarks/classification.bench.ts","bench:validation":"tsx test/benchmarks/validation.bench.ts","verify:schemas":"node scripts/check-schema-sync.cjs","verify:release":"node scripts/check-release-integrity.cjs","verify":"npm run verify:schemas && npm run verify:release && npm test","verify:all":"node scripts/verify_all.cjs","// Release Management":"====================","release:prepare":"node scripts/release-prepare.cjs","wiki:generate":"node scripts/generate-wiki.cjs","// Repository Metadata":"====================","metadata:report":"alteriom-metadata report --org-tag alteriom || echo 'metadata report failed'","metadata:validate":"alteriom-metadata validate --org-tag alteriom || echo 'metadata validate failed'","metadata:apply":"alteriom-metadata apply --org-tag alteriom","metadata:apply:dry":"alteriom-metadata dry-run --org-tag alteriom","// Legacy Aliases":"====================","validate:ota":"npm run test:ota"},"keywords":["alteriom","mqtt","iot","schema","validation","typescript","ota"],"peerDependencies":{"ajv":">=8.0.0"},"devDependencies":{"@alteriom/repository-metadata-manager":"^1.2.4","@eslint/js":"^9.39.1","@types/node":"^24.10.0","@typescript-eslint/eslint-plugin":"^8.46.3","@typescript-eslint/parser":"^8.46.3","@vitest/coverage-v8":"^4.0.7","ajv":"^8.17.0","ajv-formats":"^2.1.1","eslint":"^9.39.1","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.4","husky":"^9.1.7","lint-staged":"^16.2.6","prettier":"^3.6.2","rimraf":"^5.0.5","tinybench":"^5.1.0","tsx":"^4.20.6","typescript":"^5.4.0","vitest":"^4.0.7"},"dependencies":{"dotenv":"^17.2.2"},"_id":"@alteriom/mqtt-schema@0.8.0","gitHead":"9e787878724a544a77df9e3855016045f0e1243f","_nodeVersion":"22.19.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-/Yhf3TybagQONQEF8e70cM6ktlGFX0VgmC3fdM1KxsNCU9sBoKDxd0yocpvnoW5tWiBwgjBFkmTJjoWpX9ae7A==","shasum":"9615386c81ff1612ca7a8c9f85088cfc54ae9bb5","tarball":"https://registry.npmjs.org/@alteriom/mqtt-schema/-/mqtt-schema-0.8.0.tgz","fileCount":131,"unpackedSize":1124840,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQC5LG4sMYpTm+U8HEvjrq+WGo7eMPHzXbp056FVdZUMggIgIgrRoAnfeuoPiaIC4Kln7KJyJGYQI3SUX3o5NATZHww="}]},"_npmUser":{"name":"sparck75","email":"dominic.lavoie@gmail.com"},"directories":{},"maintainers":[{"name":"sparck75","email":"dominic.lavoie@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mqtt-schema_0.8.0_1762662807112_0.10451091781272948"},"_hasShrinkwrap":false}},"time":{"created":"2025-09-21T03:55:12.790Z","modified":"2025-11-09T04:33:27.551Z","0.2.0":"2025-09-21T03:55:13.059Z","0.2.1":"2025-09-23T00:57:33.440Z","0.3.0":"2025-09-27T22:45:58.305Z","0.3.1":"2025-09-28T02:14:13.341Z","0.3.2":"2025-09-28T03:11:10.190Z","0.4.0":"2025-10-11T19:56:00.999Z","0.5.0":"2025-10-12T21:09:21.464Z","0.6.0":"2025-10-19T22:09:12.818Z","0.7.0":"2025-10-21T20:05:38.372Z","0.7.1":"2025-10-23T22:08:40.755Z","0.7.2":"2025-10-23T23:29:00.892Z","0.7.3":"2025-11-05T15:03:23.623Z","0.8.0":"2025-11-09T04:33:27.312Z"},"bugs":{"url":"https://github.com/Alteriom/alteriom-mqtt-schema/issues"},"author":{"name":"Alteriom Development Team"},"license":"MIT","homepage":"https://github.com/Alteriom/alteriom-mqtt-schema#readme","keywords":["alteriom","mqtt","iot","schema","validation","typescript","ota"],"repository":{"type":"git","url":"git+https://github.com/Alteriom/alteriom-mqtt-schema.git"},"description":"Alteriom MQTT v1 schemas, TypeScript types, and validation helpers for web integration","maintainers":[{"name":"sparck75","email":"dominic.lavoie@gmail.com"}],"readme":"# @alteriom/mqtt-schema\r\n\r\n![Metadata Compliance](https://github.com/Alteriom/alteriom-mqtt-schema/actions/workflows/metadata-compliance.yml/badge.svg)\r\n![OTA Manifest Validation](https://github.com/Alteriom/alteriom-mqtt-schema/actions/workflows/validate-ota-manifest.yml/badge.svg)\r\n![Schema Verify](https://github.com/Alteriom/alteriom-mqtt-schema/actions/workflows/schema-verify.yml/badge.svg)\r\n![npm version](https://img.shields.io/npm/v/@alteriom/mqtt-schema.svg)\r\n![npm downloads](https://img.shields.io/npm/dm/@alteriom/mqtt-schema.svg)\r\n![license](https://img.shields.io/npm/l/@alteriom/mqtt-schema.svg)\r\n![npm total downloads](https://img.shields.io/npm/dt/@alteriom/mqtt-schema.svg)\r\n![node version](https://img.shields.io/node/v/@alteriom/mqtt-schema.svg)\r\n![peer ajv](https://img.shields.io/badge/peer%20ajv-%3E%3D8.0.0-blue.svg)\r\n![latest tag](https://img.shields.io/github/v/tag/Alteriom/alteriom-mqtt-schema?label=tag)\r\n[![bundle size](https://img.shields.io/bundlephobia/minzip/@alteriom/mqtt-schema)](https://bundlephobia.com/package/@alteriom/mqtt-schema)\r\n\r\n\r\nAlteriom MQTT v1 JSON Schemas, TypeScript types, and production‑ready validation helpers for integrating firmware MQTT payloads into web or backend services.\r\n\r\n \r\n## Why this exists\r\nFirmware emits structured MQTT payloads that must remain tightly aligned with web, analytics, and gateway logic. This package is the single source of truth for:\r\n\r\n- Canonical, versioned JSON Schemas (`schema_version: 1` series)\r\n- Embedded (tree‑shakeable) schema objects — no runtime file I/O\r\n- Precompiled Ajv validators (fast + consistent across CJS / ESM)\r\n- TypeScript interfaces & type guards generated from the same source schema set\r\n- Message classification helper that infers the schema kind heuristically\r\n- Forward‑compatible design: unknown extra properties are ignored unless explicitly constrained\r\n\r\n## Features\r\n\r\n- Dual build: CommonJS + ESM (Node 16+ / bundlers)\r\n- Zero configuration: just import and validate\r\n- Helpful error paths (JSON Pointer style)\r\n- Lightweight (Ajv peer dependency, schemas embedded)\r\n- Ships original schema JSON files (optional consumption)\r\n- **NEW in v0.8.0**: ⚠️ BREAKING: Gateway code realignment (300→305, 301→306) with automatic legacy translation\r\n- **NEW in v0.8.0**: Unified device schemas (10x range) for sensor/gateway/bridge/hybrid deployments\r\n- **NEW in v0.8.0**: HTTP transport support via `transport_metadata` for REST API integration\r\n- **NEW in v0.8.0**: Bridge management schemas for painlessMesh v1.8.0+ (5 new message types)\r\n- **NEW in v0.7.3**: Message batching for 50-90% protocol overhead reduction\r\n- **NEW in v0.7.3**: Compression support for 60-80% bandwidth savings (gzip, zlib, brotli, deflate)\r\n- **NEW in v0.7.3**: Comprehensive example repository (9 examples, 4 categories)\r\n- **NEW in v0.7.3**: Professional code quality tooling (ESLint, Prettier, Husky)\r\n- **NEW in v0.7.3**: 87% test coverage with 134 tests (28 unit, 12 integration, 68 fixtures)\r\n- **NEW in v0.7.1**: Message type codes for significantly faster classification and standardized routing\r\n- **NEW in v0.7.1**: PainlessMesh bridge schema for mesh protocol integration\r\n- **NEW in v0.7.0**: Best-in-class OTA management with security, rollback, and delta updates\r\n- **NEW in v0.6.0**: Enhanced location/geolocation support for asset tracking\r\n- **NEW in v0.6.0**: Extended sensor metadata (accuracy, calibration, operational range)\r\n- **NEW in v0.6.0**: Comprehensive gateway health metrics (storage, network, errors)\r\n\r\n## Documentation\r\n\r\n📚 **[GitHub Wiki](https://github.com/Alteriom/alteriom-mqtt-schema/wiki)** - Comprehensive API documentation, schema references, validation rules, and guides\r\n\r\n> **Note**: If the wiki appears empty, see [WIKI_SETUP.md](./WIKI_SETUP.md) for setup instructions. The wiki is automatically generated and synced from the repository.\r\n\r\n## Installation\r\n\r\n```bash\r\nnpm install @alteriom/mqtt-schema ajv ajv-formats\r\n```\r\n\r\n**Support & Compatibility**: Node 18+ tested; Node 20 primary. Dual CJS/ESM builds.\r\n\r\n## Quick Start\r\n\r\n### Fast Classification with Type Codes (v0.7.1+)\r\n\r\nFor optimal performance, include the optional `message_type` field:\r\n\r\n```ts\r\nimport { classifyAndValidate, MessageTypeCodes } from '@alteriom/mqtt-schema';\r\n\r\nconst payload = {\r\n  schema_version: 1,\r\n  message_type: MessageTypeCodes.SENSOR_DATA, // 200 - enables 90% faster classification\r\n  device_id: 'SN001',\r\n  device_type: 'sensor',\r\n  timestamp: new Date().toISOString(),\r\n  firmware_version: 'SN 2.1.5',\r\n  sensors: {\r\n    temperature: { value: 22.5, unit: 'C' }\r\n  }\r\n};\r\n\r\nconst { kind, result } = classifyAndValidate(payload);\r\n// Fast path: O(1) lookup vs O(n) heuristics\r\n```\r\n\r\n### Validate a JSON payload (object already parsed):\r\n\r\n```ts\r\nimport { validators } from '@alteriom/mqtt-schema';\r\n\r\nconst payload = JSON.parse(rawMqttString);\r\nconst result = validators.sensorData(payload);\r\nif (!result.valid) {\r\n  console.error('Invalid sensor data', result.errors);\r\n}\r\n```\r\n\r\nClassify and validate automatically:\r\n\r\n```ts\r\nimport { classifyAndValidate } from '@alteriom/mqtt-schema';\r\n\r\nconst { kind, result } = classifyAndValidate(payload);\r\nif (result.valid) {\r\n  console.log('Message kind:', kind);\r\n} else {\r\n  console.warn('Validation errors', result.errors);\r\n}\r\n```\r\n\r\nUse strong TypeScript types after classification:\r\n\r\n```ts\r\nimport { classifyAndValidate, isSensorDataMessage, SensorDataMessage } from '@alteriom/mqtt-schema';\r\n\r\nconst { result } = classifyAndValidate(payload);\r\nif (result.valid && isSensorDataMessage(payload)) {\r\n  const data: SensorDataMessage = payload;\r\n  Object.entries(data.sensors).forEach(([name, s]) => {\r\n    console.log(name, s.value, s.unit);\r\n  });\r\n}\r\n```\r\n\r\nAccess raw schema JSON (if you need to introspect or power form generation):\r\n\r\n```ts\r\nimport envelopeSchema from '@alteriom/mqtt-schema/schemas/envelope.schema.json';\r\n```\r\n\r\n## Command & Control (v0.5.0+)\r\n\r\nSend commands to devices and receive responses with correlation tracking:\r\n\r\n```ts\r\nimport { validators, isCommandMessage, isCommandResponseMessage } from '@alteriom/mqtt-schema';\r\n\r\n// Create a command message\r\nconst command = {\r\n  schema_version: 1,\r\n  device_id: 'ALT-441D64F804A0',\r\n  device_type: 'sensor',\r\n  timestamp: new Date().toISOString(),\r\n  firmware_version: 'WEB 1.0.0',\r\n  event: 'command',\r\n  command: 'read_sensors',\r\n  correlation_id: `cmd-${Date.now()}-001`,\r\n  parameters: {\r\n    immediate: true,\r\n    sensors: ['temperature', 'humidity']\r\n  },\r\n  priority: 'high'\r\n};\r\n\r\n// Validate before sending\r\nconst cmdResult = validators.command(command);\r\nif (cmdResult.valid) {\r\n  // Publish to MQTT topic: alteriom/nodes/{device_id}/commands\r\n  mqttClient.publish(`alteriom/nodes/${command.device_id}/commands`, JSON.stringify(command));\r\n}\r\n\r\n// Handle response from device\r\nmqttClient.subscribe(`alteriom/nodes/${command.device_id}/responses`, (message) => {\r\n  const response = JSON.parse(message);\r\n  const respResult = validators.commandResponse(response);\r\n  \r\n  if (respResult.valid && isCommandResponseMessage(response)) {\r\n    if (response.correlation_id === command.correlation_id) {\r\n      if (response.success) {\r\n        console.log('Command succeeded:', response.result);\r\n        console.log(`Latency: ${response.latency_ms}ms`);\r\n      } else {\r\n        console.error(`Command failed: ${response.error_code} - ${response.message}`);\r\n      }\r\n    }\r\n  }\r\n});\r\n```\r\n\r\n**Command Pattern Features:**\r\n- Event-based discrimination (`event: \"command\"` and `event: \"command_response\"`)\r\n- Correlation IDs for request/response tracking\r\n- Command name validation (lowercase snake_case)\r\n- Flexible parameters object for command-specific data\r\n- Priority field for queue management\r\n- Success boolean and error codes in responses\r\n- Latency tracking for performance monitoring\r\n\r\n## PainlessMesh Protocol Bridge (v0.7.1+)\r\n\r\nStandardize MQTT-to-mesh protocol bridging for seamless integration with ESP32/ESP8266 mesh networks:\r\n\r\n```ts\r\nimport { validators, isMeshBridgeMessage } from '@alteriom/mqtt-schema';\r\n\r\n// Gateway bridges painlessMesh message to MQTT\r\nconst meshBridge = {\r\n  schema_version: 1,\r\n  message_type: 603, // MESH_BRIDGE\r\n  device_id: 'GW-MESH-01',\r\n  device_type: 'gateway',\r\n  timestamp: new Date().toISOString(),\r\n  firmware_version: 'GW 3.2.0',\r\n  event: 'mesh_bridge',\r\n  mesh_protocol: 'painlessMesh',\r\n  mesh_message: {\r\n    from_node_id: 123456789,  // painlessMesh uint32 node ID\r\n    to_node_id: 987654321,\r\n    mesh_type: 8,              // painlessMesh SINGLE message\r\n    mesh_type_name: 'SINGLE',\r\n    payload_decoded: {\r\n      // Decoded MQTT v1 message from mesh node\r\n      schema_version: 1,\r\n      device_id: 'MESH-NODE-123456789',\r\n      device_type: 'sensor',\r\n      timestamp: '2025-10-23T20:30:00.000Z',\r\n      firmware_version: 'SN 2.0.0',\r\n      sensors: {\r\n        temperature: { value: 22.5, unit: 'C' }\r\n      }\r\n    },\r\n    rssi: -72,        // Signal strength\r\n    hop_count: 2      // Hops from source to gateway\r\n  }\r\n};\r\n\r\nconst result = validators.meshBridge(meshBridge);\r\nif (result.valid && isMeshBridgeMessage(meshBridge)) {\r\n  // Process mesh message with full context\r\n  console.log(`Mesh message from node ${meshBridge.mesh_message.from_node_id}`);\r\n  console.log(`Signal: ${meshBridge.mesh_message.rssi} dBm, Hops: ${meshBridge.mesh_message.hop_count}`);\r\n  \r\n  if (meshBridge.mesh_message.payload_decoded) {\r\n    // Process decoded MQTT v1 message\r\n    const innerMessage = meshBridge.mesh_message.payload_decoded;\r\n    console.log('Decoded sensor data:', innerMessage.sensors);\r\n  }\r\n}\r\n```\r\n\r\n**Mesh Bridge Features:**\r\n- **Multi-Protocol Support**: painlessMesh, ESP-NOW, BLE Mesh, Thread, Zigbee\r\n- **Dual Payload Format**: Raw (base64/hex) and decoded MQTT v1 messages\r\n- **Network Observability**: RSSI, hop count, mesh timestamps\r\n- **Gateway Context**: Gateway node ID and mesh network identifier\r\n- **Standardized Translation**: Consistent format across different mesh protocols\r\n\r\n**Use Cases:**\r\n- Bridge ESP32 painlessMesh networks to cloud MQTT\r\n- Integrate ESP-NOW devices without direct WiFi\r\n- Heterogeneous mesh gateway (multiple mesh protocols)\r\n- Mesh network debugging and visualization\r\n- Low-power mesh sensor networks with cloud backend\r\n\r\n**PainlessMesh Integration Pattern:**\r\n```cpp\r\n// ESP32 Gateway Firmware (C++)\r\nvoid onMeshReceive(uint32_t from, String &msg) {\r\n  // Wrap painlessMesh message in MQTT envelope\r\n  StaticJsonDocument<1024> bridgeMsg;\r\n  bridgeMsg[\"schema_version\"] = 1;\r\n  bridgeMsg[\"message_type\"] = 603;\r\n  bridgeMsg[\"device_id\"] = \"GW-MESH-01\";\r\n  bridgeMsg[\"device_type\"] = \"gateway\";\r\n  bridgeMsg[\"event\"] = \"mesh_bridge\";\r\n  bridgeMsg[\"mesh_protocol\"] = \"painlessMesh\";\r\n  \r\n  JsonObject meshMsg = bridgeMsg.createNestedObject(\"mesh_message\");\r\n  meshMsg[\"from_node_id\"] = from;\r\n  meshMsg[\"to_node_id\"] = mesh.getNodeId();\r\n  meshMsg[\"raw_payload\"] = base64::encode(msg);\r\n  meshMsg[\"rssi\"] = mesh.getRssi(from); // If available\r\n  \r\n  // Try to decode as MQTT v1 message\r\n  StaticJsonDocument<512> decoded;\r\n  if (deserializeJson(decoded, msg) == DeserializationError::Ok) {\r\n    meshMsg[\"payload_decoded\"] = decoded;\r\n  }\r\n  \r\n  // Publish to MQTT broker\r\n  String bridgeJson;\r\n  serializeJson(bridgeMsg, bridgeJson);\r\n  mqttClient.publish(\"alteriom/mesh/bridge\", bridgeJson);\r\n}\r\n```\r\n\r\n## Enhanced Location & Environment Tracking (v0.6.0+)\r\n\r\nTrack device location and deployment context for asset management and map-based visualization:\r\n\r\n```ts\r\nimport { validators, isSensorDataMessage } from '@alteriom/mqtt-schema';\r\n\r\nconst sensorData = {\r\n  schema_version: 1,\r\n  device_id: 'SN456',\r\n  device_type: 'sensor',\r\n  timestamp: new Date().toISOString(),\r\n  firmware_version: 'SN 2.1.0',\r\n  // Standardized location for map visualization\r\n  location: {\r\n    latitude: 43.6532,\r\n    longitude: -79.3832,\r\n    altitude: 76.5,\r\n    accuracy_m: 10.0,\r\n    zone: 'warehouse_A',\r\n    description: 'Shelf 3, Row B'\r\n  },\r\n  // Deployment context\r\n  environment: {\r\n    deployment_type: 'indoor',\r\n    power_source: 'battery',\r\n    expected_battery_life_days: 365\r\n  },\r\n  sensors: {\r\n    temperature: {\r\n      value: 22.3,\r\n      unit: 'C',\r\n      // Enhanced sensor metadata\r\n      timestamp: '2025-10-19T20:59:58.000Z',\r\n      accuracy: 0.5,\r\n      last_calibration: '2025-01-15',\r\n      error_margin_pct: 2.0,\r\n      operational_range: { min: -40, max: 85 },\r\n      quality_score: 0.95\r\n    }\r\n  },\r\n  battery_level: 78,\r\n  signal_strength: -65\r\n};\r\n\r\nconst result = validators.sensorData(sensorData);\r\nif (result.valid && isSensorDataMessage(sensorData)) {\r\n  // Display on map using location data\r\n  displayOnMap(sensorData.location.latitude, sensorData.location.longitude);\r\n  \r\n  // Show sensor health based on metadata\r\n  if (sensorData.sensors.temperature.accuracy) {\r\n    console.log(`Temperature accuracy: ±${sensorData.sensors.temperature.accuracy}${sensorData.sensors.temperature.unit}`);\r\n  }\r\n  \r\n  // Check calibration status\r\n  const lastCal = new Date(sensorData.sensors.temperature.last_calibration);\r\n  const daysSinceCalibration = (Date.now() - lastCal.getTime()) / (1000 * 60 * 60 * 24);\r\n  if (daysSinceCalibration > 365) {\r\n    console.warn('Sensor calibration overdue');\r\n  }\r\n}\r\n```\r\n\r\n**Location & Environment Features:**\r\n- GPS coordinates (latitude, longitude, altitude) with accuracy tracking\r\n- Zone-based organization (warehouses, floors, rooms)\r\n- Human-readable location descriptions\r\n- Deployment type tracking (indoor/outdoor/mobile)\r\n- Power source information for battery management\r\n- Per-sensor timestamps for async polling scenarios\r\n- Sensor accuracy and calibration tracking\r\n- Operational range validation support\r\n\r\n## Enhanced Gateway Metrics (v0.6.0+)\r\n\r\nComprehensive system health monitoring for gateways:\r\n\r\n```ts\r\nimport { validators, isGatewayMetricsMessage } from '@alteriom/mqtt-schema';\r\n\r\nconst metrics = {\r\n  schema_version: 1,\r\n  device_id: 'GW002',\r\n  device_type: 'gateway',\r\n  timestamp: new Date().toISOString(),\r\n  firmware_version: 'GW 1.4.0',\r\n  metrics: {\r\n    uptime_s: 86400,\r\n    cpu_usage_pct: 15.3,\r\n    memory_usage_pct: 42.7,\r\n    temperature_c: 45.2,\r\n    // Enhanced storage metrics\r\n    storage_usage_pct: 45.2,\r\n    storage_total_mb: 512,\r\n    storage_free_mb: 280.5,\r\n    // Network bandwidth tracking\r\n    network_rx_kbps: 125.4,\r\n    network_tx_kbps: 89.3,\r\n    active_connections: 5,\r\n    // System health indicators\r\n    error_count_24h: 3,\r\n    warning_count_24h: 12,\r\n    restart_count: 2,\r\n    last_restart_reason: 'firmware_update',\r\n    // Mesh network metrics\r\n    connected_devices: 12,\r\n    mesh_nodes: 8,\r\n    packet_loss_pct: 0.5\r\n  }\r\n};\r\n\r\nconst result = validators.gatewayMetrics(metrics);\r\nif (result.valid && isGatewayMetricsMessage(metrics)) {\r\n  // Storage monitoring\r\n  if (metrics.metrics.storage_usage_pct > 80) {\r\n    console.warn('Storage usage critical:', metrics.metrics.storage_usage_pct);\r\n  }\r\n  \r\n  // Network health\r\n  const totalBandwidth = metrics.metrics.network_rx_kbps + metrics.metrics.network_tx_kbps;\r\n  console.log(`Total bandwidth: ${totalBandwidth.toFixed(1)} kbps`);\r\n  \r\n  // Error trend analysis\r\n  if (metrics.metrics.error_count_24h > 10) {\r\n    console.error('High error rate detected:', metrics.metrics.error_count_24h);\r\n  }\r\n  \r\n  // Restart tracking\r\n  console.log(`Last restart: ${metrics.metrics.last_restart_reason}`);\r\n  console.log(`Total restarts: ${metrics.metrics.restart_count}`);\r\n}\r\n```\r\n\r\n**Enhanced Gateway Metrics Features:**\r\n- Storage usage tracking (percentage, total, free space)\r\n- Network bandwidth monitoring (RX/TX rates)\r\n- Active connection counting\r\n- Error and warning counters (24-hour rolling window)\r\n- Restart tracking with reason codes\r\n- All metrics are optional for gradual firmware adoption\r\n\r\n## OTA Firmware Management (v0.7.0+)\r\n\r\nComprehensive best-in-class OTA solution based on 2024 industry standards.\r\n\r\n### OTA Manifest Schema\r\n\r\nThe package includes OTA firmware manifest schema with both rich and minimal formats, enhanced with enterprise-grade features.\r\n\r\n**Preferred: Stable alias import** (v0.3.1+):\r\n```ts\r\nimport otaManifestSchema from '@alteriom/mqtt-schema/ota-manifest';\r\nimport { OtaManifest, isRichManifest } from '@alteriom/mqtt-schema/types/ota-manifest';\r\n```\r\n\r\n**Legacy: Deep path import** (still supported):\r\n```ts\r\nimport otaManifestSchema from '@alteriom/mqtt-schema/schemas/ota/ota-manifest.schema.json';\r\n```\r\n\r\n**Usage example:**\r\n```ts\r\nimport Ajv from 'ajv';\r\nimport addFormats from 'ajv-formats';\r\nimport otaManifestSchema from '@alteriom/mqtt-schema/ota-manifest';\r\nimport { OtaManifest } from '@alteriom/mqtt-schema/types/ota-manifest';\r\n\r\nconst ajv = new Ajv({ allErrors: true, strict: false });\r\naddFormats(ajv);\r\nconst validate = ajv.compile<OtaManifest>(otaManifestSchema as any);\r\n\r\nconst manifest: OtaManifest = JSON.parse(manifestJson);\r\nif (!validate(manifest)) {\r\n  console.error('Invalid OTA manifest:', validate.errors);\r\n}\r\n```\r\n\r\nSupported formats:\r\n- **Rich manifest**: environment + branch + manifests object\r\n- **Minimal environment map**: environment → channels mapping  \r\n- **Chunk variants**: structured objects or SHA256 array\r\n\r\n### Enhanced OTA Features (v0.7.0+)\r\n\r\n**Security & Authenticity:**\r\n```ts\r\nconst manifest = {\r\n  environment: \"universal-sensor\",\r\n  branch: \"main\",\r\n  manifests: {\r\n    prod: {\r\n      build_type: \"prod\",\r\n      file: \"firmware-v2.0.0.bin\",\r\n      size: 456789,\r\n      sha256: \"a1b2c3...\",\r\n      firmware_version: \"2.0.0\",\r\n      built: \"2025-10-19T12:00:00Z\",\r\n      ota_url: \"https://firmware.example.com/v2.0.0.bin\",\r\n      \r\n      // Digital signature for authenticity\r\n      signature: \"MEUCIQDx...\",\r\n      signature_algorithm: \"ECDSA-SHA256\",\r\n      signing_key_id: \"prod-signing-key-2025\",\r\n      \r\n      // Version constraints\r\n      min_version: \"1.5.0\",        // Minimum version to upgrade from\r\n      max_version: \"1.9.99\",       // Prevent downgrades\r\n      \r\n      // Release management\r\n      release_notes_url: \"https://docs.example.com/v2.0.0\",\r\n      criticality: \"high\",          // low | medium | high | critical\r\n      mandatory: true,              // Must be installed\r\n      \r\n      // Staged rollout\r\n      rollout_percentage: 25,       // Start with 25% of fleet\r\n      rollout_target_groups: [\"beta-testers\", \"early-adopters\"],\r\n      \r\n      // Delta updates (60-90% bandwidth reduction)\r\n      delta_from_version: \"1.9.0\",\r\n      delta_patch_url: \"https://firmware.example.com/patches/1.9.0-to-2.0.0.patch\",\r\n      delta_patch_size: 45678,\r\n      delta_patch_sha256: \"c3d4e5...\"\r\n    }\r\n  }\r\n};\r\n```\r\n\r\n**Firmware Update Status Tracking:**\r\n```ts\r\nimport { validators, isFirmwareStatusMessage } from '@alteriom/mqtt-schema';\r\n\r\n// Enhanced status tracking\r\nconst status = {\r\n  schema_version: 1,\r\n  device_id: \"SN789\",\r\n  device_type: \"sensor\",\r\n  timestamp: new Date().toISOString(),\r\n  firmware_version: \"2.0.0\",\r\n  \r\n  status: \"downloading\",           // New: rolled_back, rollback_pending, rollback_failed\r\n  progress_pct: 42,\r\n  \r\n  // Progress details\r\n  download_speed_kbps: 125.5,\r\n  bytes_downloaded: 196608,\r\n  bytes_total: 456789,\r\n  eta_seconds: 28,\r\n  \r\n  // Rollback support\r\n  rollback_available: true,\r\n  previous_version: \"1.9.0\",\r\n  \r\n  // Security verification\r\n  update_type: \"delta\",            // full | delta | patch\r\n  signature_verified: true,\r\n  checksum_verified: true,\r\n  \r\n  // Operational context\r\n  battery_level_pct: 85,\r\n  free_space_kb: 2048,\r\n  retry_count: 0\r\n};\r\n\r\nconst result = validators.firmwareStatus(status);\r\nif (result.valid) {\r\n  console.log(`Download progress: ${status.progress_pct}% at ${status.download_speed_kbps} kbps`);\r\n  console.log(`ETA: ${status.eta_seconds} seconds`);\r\n}\r\n```\r\n\r\n**OTA Best Practices:**\r\n- **Security**: Always use digital signatures for production firmware\r\n- **Rollback**: Maintain backup partition for automatic rollback on failures\r\n- **Delta Updates**: Use delta patches for bandwidth-constrained deployments (60-90% reduction)\r\n- **Staged Rollout**: Start with 5-10% rollout, monitor, then expand gradually\r\n- **Version Control**: Use min_version to prevent upgrades from incompatible versions\r\n- **Criticality**: Mark security patches as \"critical\" with mandatory: true\r\n\r\nSee `docs/OTA_MANIFEST.md` for comprehensive guide and best practices.\r\n\r\n## API Surface\r\n\r\n```ts\r\nimport { validators, validateMessage, classifyAndValidate } from '@alteriom/mqtt-schema';\r\n\r\n// 1. Direct validator by message kind\r\nvalidators.sensorData(payload); // => { valid: boolean; errors?: string[] }\r\n\r\n// 2. Generic function\r\nvalidateMessage('sensorData', payload);\r\n\r\n// 3. Classify unknown payload then validate\r\nconst { kind, result } = classifyAndValidate(payload);\r\n\r\n// 4. Type guards (when available)\r\n// if (isSensorDataMessage(payload)) { ... }\r\n```\r\n\r\nValidation result format:\r\n\r\n```ts\r\ninterface ValidationResult {\r\n  valid: boolean;\r\n  errors?: string[]; // Each item contains instancePath + message\r\n}\r\n```\r\n\r\n### Performance Notes\r\n\r\nAll Ajv validator functions are compiled once at module load. For typical web usage (tens to hundreds of validations per page/session) this is faster and simpler than on‑demand compilation. If you need custom Ajv options (e.g., different formats), open an issue—an override hook can be added without breaking changes.\r\n\r\n### Embedded Schemas\r\n\r\n`schema_data.ts` is auto‑generated during build. This avoids dynamic `require()` / `import` of JSON and works cleanly in both Node ESM and bundlers without JSON import assertions. The original JSON files are still published under `schemas/` for tooling or documentation pipelines.\r\n\r\n## Device Configuration Management (v0.7.1+)\r\n\r\nUnified configuration management for both sensors and gateways, supporting remote configuration without firmware reflashing:\r\n\r\n```ts\r\nimport { validators, isDeviceConfigMessage, MessageTypeCodes } from '@alteriom/mqtt-schema';\r\n\r\n// Configuration update request (from backend to device)\r\nconst configUpdate = {\r\n  schema_version: 1,\r\n  message_type: MessageTypeCodes.DEVICE_CONFIG, // 700\r\n  device_id: 'SN001',\r\n  device_type: 'sensor',\r\n  timestamp: new Date().toISOString(),\r\n  firmware_version: 'WEB 1.0.0',\r\n  event: 'config_update',\r\n  configuration: {\r\n    sampling_interval_ms: 60000,\r\n    power_mode: 'low_power',\r\n    ota_config: {\r\n      auto_update: true,\r\n      update_channel: 'stable',\r\n      update_check_interval_h: 24\r\n    },\r\n    alert_thresholds: {\r\n      temperature: {\r\n        min: -10,\r\n        max: 50,\r\n        enabled: true\r\n      }\r\n    }\r\n  },\r\n  modified_by: 'admin@example.com'\r\n};\r\n\r\nconst result = validators.deviceConfig(configUpdate);\r\nif (result.valid) {\r\n  // Publish to device: alteriom/nodes/{device_id}/config\r\n  mqttClient.publish(`alteriom/nodes/${configUpdate.device_id}/config`, JSON.stringify(configUpdate));\r\n}\r\n\r\n// Configuration snapshot (from device to backend)\r\nmqttClient.subscribe('alteriom/nodes/+/config/snapshot', (message) => {\r\n  const snapshot = JSON.parse(message);\r\n  \r\n  if (isDeviceConfigMessage(snapshot) && snapshot.event === 'config_snapshot') {\r\n    // Store configuration for audit trail\r\n    console.log('Device config:', snapshot.device_id);\r\n    console.log('Power mode:', snapshot.configuration.power_mode);\r\n    console.log('OTA settings:', snapshot.configuration.ota_config);\r\n    \r\n    // Configuration version tracking\r\n    if (snapshot.config_version) {\r\n      console.log('Config version:', snapshot.config_version);\r\n      console.log('Last modified:', snapshot.last_modified);\r\n    }\r\n  }\r\n});\r\n```\r\n\r\n**Unified Configuration Standards:**\r\n\r\nBoth sensors and gateways support consistent management:\r\n\r\n| Feature | Sensors | Gateways | Description |\r\n|---------|---------|----------|-------------|\r\n| OTA Configuration | ✅ | ✅ | Auto-update, channels, intervals |\r\n| Network Settings | ✅ | ✅ | WiFi, mesh, MQTT configuration |\r\n| Power Management | ✅ | ✅ | Power modes, sleep duration |\r\n| Reporting Intervals | ✅ | ✅ | Sampling and reporting intervals |\r\n| Log Levels | ✅ | ✅ | Debug, info, warn, error |\r\n| Time Sync | ✅ | ✅ | Timezone, NTP server |\r\n| Alert Thresholds | ✅ | ⚠️ | Sensor-specific thresholds |\r\n| Calibration | ✅ | ⚠️ | Sensor offset calibration |\r\n\r\n**Configuration Events:**\r\n- `config_snapshot`: Device reports current configuration state\r\n- `config_update`: Backend requests configuration changes\r\n- `config_request`: Backend queries current configuration\r\n\r\n**Key Benefits:**\r\n- Remote configuration without firmware updates\r\n- Configuration backup and restore\r\n- Audit trail with version tracking\r\n- Bulk configuration deployment\r\n- Standardized across device types\r\n\r\n## Message Type Codes (v0.8.0+)\r\n\r\nFor performance optimization and standardized routing, use the optional `message_type` field:\r\n\r\n### 🆕 Unified Device Codes (v0.8.0+)\r\n\r\n| Code | Constant | Message Type | Category | Description |\r\n|------|----------|--------------|----------|-------------|\r\n| 101 | `DEVICE_DATA` | device_data | unified | Unified telemetry for all device types (sensor/gateway/bridge/hybrid) |\r\n| 102 | `DEVICE_HEARTBEAT` | device_heartbeat | unified | Unified presence/health check (all device types) |\r\n| 103 | `DEVICE_STATUS` | device_status | unified | Unified status change notification (all device types) |\r\n| 104 | `DEVICE_INFO` | device_info | unified | Unified identification and capabilities (all device types) |\r\n| 105 | `DEVICE_METRICS` | device_metrics | unified | Unified health and performance metrics (all device types) |\r\n\r\n### Sensor-Specific Codes\r\n\r\n| Code | Constant | Message Type | Category | Description |\r\n|------|----------|--------------|----------|-------------|\r\n| 200 | `SENSOR_DATA` | sensor_data | telemetry | Sensor telemetry readings |\r\n| 201 | `SENSOR_HEARTBEAT` | sensor_heartbeat | telemetry | Sensor presence/health |\r\n| 202 | `SENSOR_STATUS` | sensor_status | telemetry | Sensor status change |\r\n| 203 | `SENSOR_INFO` | sensor_info | telemetry | Sensor identification and capabilities (v0.7.2+) |\r\n| 204 | `SENSOR_METRICS` | sensor_metrics | telemetry | Sensor health and performance metrics (v0.7.2+) |\r\n\r\n### Gateway-Specific Codes\r\n\r\n| Code | Constant | Message Type | Category | Description |\r\n|------|----------|--------------|----------|-------------|\r\n| 302 | `GATEWAY_DATA` | gateway_data | gateway | Gateway telemetry readings (v0.7.2+) |\r\n| 303 | `GATEWAY_HEARTBEAT` | gateway_heartbeat | gateway | Gateway presence/health check (v0.7.2+) |\r\n| 304 | `GATEWAY_STATUS` | gateway_status | gateway | Gateway status change notification (v0.7.2+) |\r\n| 305 | `GATEWAY_INFO` | gateway_info | gateway | Gateway identification ⚠️ **BREAKING v0.8.0: was 300** |\r\n| 306 | `GATEWAY_METRICS` | gateway_metrics | gateway | Gateway health metrics ⚠️ **BREAKING v0.8.0: was 301** |\r\n\r\n> **⚠️ BREAKING CHANGES in v0.8.0**: Gateway codes `300` (info) and `301` (metrics) have been realigned to `305` and `306` for consistency. Legacy codes `300` and `301` are **automatically translated** during a 6-month migration period. See [Migration Guide](#v08-migration-guide) below.\r\n\r\n### Command & Control\r\n\r\n| Code | Constant | Message Type | Category | Description |\r\n|------|----------|--------------|----------|-------------|\r\n| 400 | `COMMAND` | command | control | Device control command |\r\n| 401 | `COMMAND_RESPONSE` | command_response | control | Command execution result |\r\n| 402 | `CONTROL_RESPONSE` | control_response | control | Legacy control response (deprecated) |\r\n\r\n### Firmware & OTA\r\n\r\n| Code | Constant | Message Type | Category | Description |\r\n|------|----------|--------------|----------|-------------|\r\n| 500 | `FIRMWARE_STATUS` | firmware_status | ota | Firmware update status (enhanced v0.7.2+) |\r\n\r\n### Mesh Network\r\n\r\n| Code | Constant | Message Type | Category | Description |\r\n|------|----------|--------------|----------|-------------|\r\n| 600 | `MESH_NODE_LIST` | mesh_node_list | mesh | Mesh node inventory |\r\n| 601 | `MESH_TOPOLOGY` | mesh_topology | mesh | Mesh network topology |\r\n| 602 | `MESH_ALERT` | mesh_alert | mesh | Mesh network alert |\r\n| 603 | `MESH_BRIDGE` | mesh_bridge | mesh | Mesh protocol bridge (v0.7.1+) |\r\n| 604 | `MESH_STATUS` | mesh_status | mesh | Mesh network health status (v0.7.2+) |\r\n| 605 | `MESH_METRICS` | mesh_metrics | mesh | Mesh network performance metrics (v0.7.2+) |\r\n\r\n### Bridge Management (v0.8.0+)\r\n\r\n| Code | Constant | Message Type | Category | Description |\r\n|------|----------|--------------|----------|-------------|\r\n| 610 | `BRIDGE_STATUS` | bridge_status | bridge | Bridge health and connectivity broadcast |\r\n| 611 | `BRIDGE_ELECTION` | bridge_election | bridge | RSSI-based bridge election candidacy |\r\n| 612 | `BRIDGE_TAKEOVER` | bridge_takeover | bridge | Bridge role takeover announcement |\r\n| 613 | `BRIDGE_COORDINATION` | bridge_coordination | bridge | Multi-bridge coordination and load balancing |\r\n| 614 | `TIME_SYNC_NTP` | time_sync_ntp | bridge | Bridge-to-mesh NTP time distribution |\r\n\r\n### Configuration & Efficiency\r\n\r\n| Code | Constant | Message Type | Category | Description |\r\n|------|----------|--------------|----------|-------------|\r\n| 700 | `DEVICE_CONFIG` | device_config | config | Device configuration management (v0.7.1+) |\r\n| 800 | `BATCH_ENVELOPE` | batch_envelope | efficiency | Message batching for 50-90% protocol overhead reduction (v0.7.3+) |\r\n| 810 | `COMPRESSED_ENVELOPE` | compressed_envelope | efficiency | Compressed message envelope (v0.7.3+) |\r\n\r\n### Benefits\r\n\r\n- **Significantly Faster**: O(1) lookup vs O(n) heuristic matching (avoids 12+ conditional checks)\r\n- **Protocol Alignment**: Compatible with CoAP and MQTT-SN numeric type systems\r\n- **Clear Intent**: Explicit message type declaration\r\n- **Efficient Routing**: Switch-case routing in backend systems\r\n- **Backward Compatible**: Falls back to heuristics if omitted\r\n\r\n### Usage\r\n\r\n```ts\r\nimport { MessageTypeCodes } from '@alteriom/mqtt-schema';\r\n\r\nconst message = {\r\n  schema_version: 1,\r\n  message_type: MessageTypeCodes.SENSOR_DATA, // 200\r\n  // ... rest of message\r\n};\r\n```\r\n\r\n### v0.8 Migration Guide\r\n\r\n**Breaking Changes:**\r\n- `GATEWAY_INFO`: Code `300` → `305`\r\n- `GATEWAY_METRICS`: Code `301` → `306`\r\n\r\n**Migration Timeline (6 months):**\r\n1. **Phase 1 (Months 1-3)**: Both old and new codes accepted. Library automatically translates `300→305` and `301→306`.\r\n2. **Phase 2 (Months 4-6)**: Deprecation warnings logged for legacy codes.\r\n3. **Phase 3 (After 6 months)**: Legacy codes `300` and `301` rejected.\r\n\r\n**Action Required:**\r\n\r\n```ts\r\n// ❌ Old code (deprecated in v0.8.0)\r\nconst message = {\r\n  message_type: 300, // gateway_info\r\n  // ...\r\n};\r\n\r\n// ✅ New code (v0.8.0+)\r\nconst message = {\r\n  message_type: MessageTypeCodes.GATEWAY_INFO, // 305\r\n  // ...\r\n};\r\n\r\n// ✅ Better: Use unified device schemas (v0.8.0+)\r\nconst message = {\r\n  message_type: MessageTypeCodes.DEVICE_INFO, // 104\r\n  device_role: 'gateway', // Explicit role indicator\r\n  // ...\r\n};\r\n```\r\n\r\n**Legacy Code Translation:**\r\n\r\nThe library includes `LEGACY_CODE_MAP` for automatic translation:\r\n\r\n```ts\r\nimport { LEGACY_CODE_MAP } from '@alteriom/mqtt-schema';\r\n\r\nconsole.log(LEGACY_CODE_MAP); // { 300: 305, 301: 306 }\r\n\r\n// Automatic translation in classifyAndValidate()\r\nconst oldMessage = { message_type: 301, /* ... */ };\r\nconst { kind, result } = classifyAndValidate(oldMessage);\r\n// kind === 'gatewayMetrics' (automatically translated 301→306)\r\n```\r\n\r\n**HTTP Transport Support (v0.8.0+):**\r\n\r\nNew `transport_metadata` field enables HTTP REST API integration:\r\n\r\n```ts\r\nconst httpMessage = {\r\n  schema_version: 1,\r\n  message_type: 101, // DEVICE_DATA\r\n  device_id: 'SN001',\r\n  device_type: 'sensor',\r\n  timestamp: new Date().toISOString(),\r\n  firmware_version: 'SN 2.1.5',\r\n  transport_metadata: {\r\n    protocol: 'http',\r\n    correlation_id: 'req-12345',\r\n    http: {\r\n      method: 'POST',\r\n      path: '/api/v1/telemetry',\r\n      status_code: 200,\r\n      request_id: 'req-uuid-12345'\r\n    }\r\n  },\r\n  sensors: { temp: { value: 22.5, unit: 'C' } }\r\n};\r\n```\r\n\r\n## Provided Schemas (v1)\r\n\r\n| File | Purpose |\r\n|------|---------|\r\n| envelope.schema.json | Base required envelope fields (now with optional message_type) |\r\n| sensor_data.schema.json | Telemetry payload with sensors map |\r\n| sensor_heartbeat.schema.json | Lightweight heartbeat (firmware_version may be omitted) |\r\n| sensor_status.schema.json | Sensor status / presence updates |\r\n| **sensor_info.schema.json** | **Sensor identification and capabilities (v0.7.2+)** |\r\n| **sensor_metrics.schema.json** | **Sensor health and performance metrics (v0.7.2+)** |\r\n| gateway_info.schema.json | Gateway identity & capabilities |\r\n| gateway_metrics.schema.json | Gateway performance metrics |\r\n| **gateway_data.schema.json** | **Gateway telemetry readings (v0.7.2+)** |\r\n| **gateway_heartbeat.schema.json** | **Gateway presence/health check (v0.7.2+)** |\r\n| **gateway_status.schema.json** | **Gateway status change notification (v0.7.2+)** |\r\n| firmware_status.schema.json | Firmware update lifecycle events (enhanced v0.7.2+) |\r\n| control_response.schema.json | Command/control response messages (deprecated, use command_response) |\r\n| **command.schema.json** | **Device control commands (v0.5.0+)** |\r\n| **command_response.schema.json** | **Command execution responses with correlation (v0.5.0+)** |\r\n| mesh_node_list.schema.json | Mesh network node list with status |\r\n| mesh_topology.schema.json | Mesh network topology and connections |\r\n| mesh_alert.schema.json | Mesh network alerts and warnings |\r\n| **mesh_bridge.schema.json** | **Mesh protocol bridge for painlessMesh integration (v0.7.1+)** |\r\n| **mesh_status.schema.json** | **Mesh network health status (v0.7.2+)** |\r\n| **mesh_metrics.schema.json** | **Mesh network performance metrics (v0.7.2+)** |\r\n| **device_config.schema.json** | **Unified device configuration management for sensors & gateways (v0.7.1+)** |\r\n| **batch_envelope.schema.json** | **Message batching for 50-90% protocol overhead reduction (v0.7.3+)** |\r\n| **compressed_envelope.schema.json** | **Compressed message envelope for bandwidth optimization (v0.7.3+)** |\r\n\r\n## Exports\r\n\r\n| Export | Type | Description |\r\n|--------|------|-------------|\r\n| `validators` | object | Precompiled validators per message type |\r\n| `validateMessage(kind,data)` | fn | Run a specific validator by key |\r\n| `classifyAndValidate(data)` | fn | Fast classification + validation (uses message_type if present) |\r\n| `MessageTypeCodes` | const object | Message type code constants (v0.7.2+) |\r\n| `SensorDataMessage` etc. | TS interfaces | Strongly typed shapes |\r\n| `isSensorDataMessage` etc. | type guards | Runtime narrowing helpers |\r\n| `SensorInfoMessage`, `SensorMetricsMessage` | TS interfaces | New sensor types (v0.7.2+) |\r\n| `GatewayDataMessage`, `GatewayHeartbeatMessage`, `GatewayStatusMessage` | TS interfaces | New gateway types (v0.7.2+) |\r\n| `MeshStatusMessage`, `MeshMetricsMessage` | TS interfaces | New mesh types (v0.7.2+) |\r\n| `MeshBridgeMessage` | TS interface | Mesh bridge message type (v0.7.1+) |\r\n| `BatchEnvelopeMessage`, `CompressedEnvelopeMessage` | TS interfaces | New message types (v0.7.3+) |\r\n| `isSensorInfoMessage`, `isSensorMetricsMessage` etc. | type guards | Type guards for new messages (v0.7.2+) |\r\n| `isBatchEnvelopeMessage`, `isCompressedEnvelopeMessage` | type guards | Type guards for new messages (v0.7.3+) |\r\n| `schemas/*.json` | JSON | Original schema assets (optional) |\r\n\r\n### Validator Keys\r\n\r\n`sensorData`, `sensorHeartbeat`, `sensorStatus`, `sensorInfo` (v0.7.2+), `sensorMetrics` (v0.7.2+), `gatewayInfo`, `gatewayMetrics`, `gatewayData` (v0.7.2+), `gatewayHeartbeat` (v0.7.2+), `gatewayStatus` (v0.7.2+), `firmwareStatus`, `controlResponse`, `command`, `commandResponse`, `meshNodeList`, `meshTopology`, `meshAlert`, `meshBridge` (v0.7.1+), `meshStatus` (v0.7.2+), `meshMetrics` (v0.7.2+), `deviceConfig` (v0.7.1+), `batchEnvelope` (v0.7.3+), `compressedEnvelope` (v0.7.3+)\r\n\r\n### Classification Strategy\r\n\r\n**v0.7.3+ Fast Path (when `message_type` present):**\r\n- Direct O(1) lookup using message type code (200-605, 700, 800, 810)\r\n- Supports all 23 message types including batch_envelope, compressed_envelope, and all v0.7.2 additions\r\n- 90% faster than heuristic matching\r\n- Validates that structure matches declared type\r\n\r\n**Heuristics (when `message_type` absent - backward compatible):**\r\n- `event: \"command\"` → `command` (v0.5.0+)\r\n- `event: \"command_response\"` → `commandResponse` (v0.5.0+)\r\n- `event: \"mesh_bridge\"` → `meshBridge` (v0.7.1+)\r\n- `event: \"config_snapshot\"`, `\"config_update\"`, or `\"config_request\"` → `deviceConfig` (v0.7.1+)\r\n- `metrics` + `device_type: \"sensor\"` → `sensorMetrics` (v0.7.2+)\r\n- `metrics` + `device_type: \"gateway\"` → `gatewayMetrics`\r\n- `sensors` + `device_type: \"gateway\"` → `gatewayData` (v0.7.2+)\r\n- `sensors` → `sensorData`\r\n- `capabilities` or `available_sensors` → `sensorInfo` (v0.7.2+)\r\n- `mesh_status` field → `meshStatus` (v0.7.2+)\r\n- `mesh_network_id` + `metrics` → `meshMetrics` (v0.7.2+)\r\n- `nodes` array → `meshNodeList`\r\n- `connections` array → `meshTopology`\r\n- `alerts` array → `meshAlert`\r\n- `progress_pct` or OTA status keywords → `firmwareStatus`\r\n- `status` + `device_type: sensor` → `sensorStatus`\r\n- `uptime_s` + `device_type: gateway` + no `metrics` → `gatewayHeartbeat` (v0.7.2+)\r\n- `status: online|offline|error` + `device_type: gateway` → `gatewayStatus` (v0.7.2+)\r\n- `status: ok|error` (no other match) → `controlResponse`\r\n- `device_type: gateway` → `gatewayInfo`\r\n- fallback → `sensorHeartbeat`\r\n\r\n## Versioning Policy\r\n\r\nSchema stability is paramount. We track two related versions:\r\n\r\n| Concept | Meaning |\r\n|---------|---------|\r\n| `schema_version` (in payload) | Wire format major. Only increments for breaking changes. |\r\n| npm package version | Follows semver; patch/minor may add optional properties or tooling, major aligns with `schema_version` bump. |\r\n\r\nBackward‑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).\r\n\r\n## TypeScript / Bundler Notes\r\n\r\n- Works in TS >= 5, Node >= 16, Vite / Webpack / ESBuild.\r\n- Tree shaking: unused validators pruned when using ESM builds.\r\n- No side effects besides Ajv instance creation.\r\n\r\n## Roadmap\r\n\r\n- Optional custom Ajv injection hook\r\n- JSON Schema → Zod conversion example\r\n- Runtime metrics helper (count validation categories)\r\n\r\n## Contributing\r\n\r\nIssues & PRs welcome. Ensure firmware repo schemas remain the authoritative source—do not manually edit generated `schema_data.ts`.\r\n\r\n### Development Workflow\r\n\r\n**Before opening a PR:** Run the comprehensive validation suite:\r\n\r\n```bash\r\nnpm run verify        # Schema sync + changelog + fixtures\r\nnpm run verify:all    # Additional schema compilation + OTA manifest validation  \r\nnpm test              # Enhanced fixture validation with detailed reporting\r\n```\r\n\r\n**Available validation scripts:**\r\n- `npm run test` - Cross-platform fixture validation (CJS/ESM) with enhanced error reporting\r\n- `npm run test:ota` - OTA manifest fixture validation\r\n- `npm run verify:schemas` - Ensure schemas are synced from source directory\r\n- `npm run verify:release` - Check changelog contains current version\r\n- `npm run verify:all` - Comprehensive schema compilation and fixture validation\r\n\r\n### Script Organization\r\n\r\nScripts are organized by category in `package.json`:\r\n- **Build Scripts**: `build`, `build:cjs`, `build:esm`, `clean`, etc.\r\n- **Testing & Validation**: `test`, `verify:*`, etc.  \r\n- **Release Management**: `release:prepare`, `wiki:generate`\r\n- **Repository Metadata**: `metadata:*` (organization compliance)\r\n\r\n### Release Process\r\n\r\nSee `PUBLISH_CHECKLIST.md` for detailed release procedures. Quick summary:\r\n1. Update schemas in `docs/mqtt_schema/`\r\n2. Run `npm run verify` to ensure everything is valid\r\n3. Use `npm run release:prepare -- patch|minor|major` for version bumping\r\n4. Follow checklist for tagging and publishing\r\n\r\n## Security\r\n\r\nSchemas are static. No network access. Supply-chain risk minimized by keeping dependencies minimal (Ajv + formats only).\r\n\r\n## License\r\n\r\nMIT\r\n\r\n## Registry Mirrors\r\n\r\nThis package is published to BOTH:\r\n\r\n- Public npm registry: `https://registry.npmjs.org` (primary)\r\n- GitHub Packages registry: `https://npm.pkg.github.com` (mirror for visibility in repo Packages tab)\r\n\r\n### Installing from GitHub Packages (optional)\r\n\r\nCreate or update an `.npmrc` with a scoped registry override (auth token with `read:packages` required):\r\n\r\n```bash\r\n@alteriom:registry=https://npm.pkg.github.com\r\n//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}\r\n```\r\n\r\nThen install normally:\r\n\r\n```bash\r\nnpm install @alteriom/mqtt-schema ajv ajv-formats\r\n```\r\n\r\nIf you omit the override, npmjs.org is used (recommended for most consumers).\r\n\r\n### Why dual publish?\r\n\r\n- GitHub Packages listing provides provenance + quick visibility in the repo UI.\r\n- npm remains the canonical public distribution source (faster, anonymous installs allowed).\r\n\r\n### Operational Notes\r\n\r\n| Aspect | Behavior |\r\n|--------|----------|\r\n| Build artifact | Built once, same tarball published to both registries. |\r\n| Version uniqueness | Same version must not be republished; bump if any change needed. |\r\n| Auth (GitHub) | Always required for install from GitHub Packages, even for public repos. |\r\n| Tarball parity | Do not rebuild between publishes; workflows ensure single build. |\r\n| Fallback strategy | If mirror publish fails (e.g., transient), primary npm publish still stands. |\r\n| Provenance flag | Applied for npm (GitHub ignores currently). |\r\n\r\n### Verifying a Release\r\n\r\n```bash\r\nnpm view @alteriom/mqtt-schema version\r\nnpm view @alteriom/mqtt-schema version --registry=https://npm.pkg.github.com\r\n```\r\n\r\nBoth should return the same version.\r\n\r\n## Repository Metadata Compliance\r\n\r\nThis 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.\r\n\r\n### Local Usage\r\n\r\nRun a validation (non‑destructive):\r\n\r\n```bash\r\nnpm run metadata:validate\r\n```\r\n\r\nGenerate a detailed report:\r\n\r\n```bash\r\nnpm run metadata:report\r\n```\r\n\r\nConfiguration lives in `metadata-config.json` (organizationTag `alteriom`). Default detection is auto; adjust if repository classification needs overriding.\r\n\r\n### CI Workflow\r\n\r\nWorkflow file: `.github/workflows/metadata-compliance.yml`\r\n\r\nOn each push / PR against `main` it will:\r\n\r\n1. Install dependencies\r\n2. Run `metadata:validate` (fails job on hard non‑compliance)\r\n3. Always attempt a best‑effort report (`metadata:report`) for visibility\r\n\r\n### Tokens / Permissions\r\n\r\nThe 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).\r\n\r\n### Extending\r\n\r\nIf 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.\r\n\r\n### Applying Metadata (Manual Workflow)\r\n\r\nFor authorized maintainers you can run adjustments via GitHub Actions:\r\n\r\n1. Open the \"Repository Metadata Apply\" workflow under the Actions tab.\r\n2. Choose whether to keep `dryRun` (default) or set to `false` to apply.\r\n3. Run the workflow; the log will show proposed or applied changes.\r\n\r\nLocal dry‑run vs apply:\r\n\r\n```bash\r\nnpm run metadata:apply:dry  # show what would change\r\nnpm run metadata:apply      # apply changes (requires proper permissions via GITHUB_TOKEN)\r\n```\r\n\r\nNote: 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).\r\n\r\n## Additional Documentation\r\n\r\nThis repository maintains comprehensive documentation across several locations:\r\n\r\n### Root Documentation\r\n- **[CHANGELOG.md](./CHANGELOG.md)** - Complete version history with breaking changes and migration guides\r\n- **[ROADMAP.md](./ROADMAP.md)** - Planned features and development timeline\r\n- **[CONTRIBUTING.md](./CONTRIBUTING.md)** - Guidelines for contributing to the project\r\n- **[SECURITY.md](./SECURITY.md)** - Security policy and vulnerability reporting\r\n- **[PUBLISH_CHECKLIST.md](./PUBLISH_CHECKLIST.md)** - Release process and verification steps\r\n- **[API_MONITOR_GUIDE.md](./API_MONITOR_GUIDE.md)** - Integration guide for monitoring systems\r\n- **[V080_BREAKING_CHANGES.md](./V080_BREAKING_CHANGES.md)** - v0.8.0 migration guide (current)\r\n\r\n### docs/ Directory Structure\r\n- **[docs/README.md](./docs/README.md)** - Documentation index with quick links\r\n- **[docs/mqtt_schema/](./docs/mqtt_schema/)** - Authoritative schema definitions, types, and fixtures\r\n- **[docs/releases/](./docs/releases/)** - Historical release notes and summaries\r\n- **[docs/archive/](./docs/archive/)** - Development history and feature implementation documents\r\n\r\nSee [docs/README.md](./docs/README.md) for the complete documentation structure.\r\n\r\n","readmeFilename":"README.md"}