The service now keeps a node database built from the initial sync (FromRadio nodeInfo entries) plus live POSITION_APP packets, and exposes it over the API:
GET /api/nodes — all known nodes as { num, longName?, shortName?, hwModel?, batteryLevel?, lastHeard: number|null, position?: { lat, lon, alt? } }[]
GET /api/nodes/:id — lookup by exact node number/numeric string, then case-insensitive exact long/short name, else unique substring; 404 when missing or ambiguous
Details
mesh.service.ts: nodeMap reset on each connect, upserted from nodeInfo, POSITION_APP packets create stub entries for unknown nodes; public nodes() / node(idOrName) with JSDoc on all public methods; ready-log includes node count
codec.ts: decodePosition() (live positions arrive as a serialized Position inside Data.payload — there is no Data.position field in @meshtastic/protobufs v2.8), hw-model enum → name reverse lookup
Controller: full Swagger annotations on all 5 endpoints, @ApiTags('Mesh'), tag description via DocumentBuilder (v12 ApiTagOptions has no description field)
README + AGENTS.md endpoint lists updated
Verification
npm run build ✓
npm test — 18/18 passed (was 13, +5 new: node upsert, position stub, lookup resolution order, 404 paths)
v0.2.0, CHANGELOG entry added
## What
The service now keeps a node database built from the initial sync (FromRadio `nodeInfo` entries) plus live POSITION_APP packets, and exposes it over the API:
- `GET /api/nodes` — all known nodes as `{ num, longName?, shortName?, hwModel?, batteryLevel?, lastHeard: number|null, position?: { lat, lon, alt? } }[]`
- `GET /api/nodes/:id` — lookup by exact node number/numeric string, then case-insensitive exact long/short name, else unique substring; 404 when missing or ambiguous
## Details
- `mesh.service.ts`: nodeMap reset on each connect, upserted from `nodeInfo`, POSITION_APP packets create stub entries for unknown nodes; public `nodes()` / `node(idOrName)` with JSDoc on all public methods; ready-log includes node count
- `codec.ts`: `decodePosition()` (live positions arrive as a serialized Position inside `Data.payload` — there is no `Data.position` field in @meshtastic/protobufs v2.8), hw-model enum → name reverse lookup
- Controller: full Swagger annotations on all 5 endpoints, `@ApiTags('Mesh')`, tag description via DocumentBuilder (v12 ApiTagOptions has no description field)
- README + AGENTS.md endpoint lists updated
## Verification
- `npm run build` ✓
- `npm test` — 18/18 passed (was 13, +5 new: node upsert, position stub, lookup resolution order, 404 paths)
- v0.2.0, CHANGELOG entry added
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
What
The service now keeps a node database built from the initial sync (FromRadio
nodeInfoentries) plus live POSITION_APP packets, and exposes it over the API:GET /api/nodes— all known nodes as{ num, longName?, shortName?, hwModel?, batteryLevel?, lastHeard: number|null, position?: { lat, lon, alt? } }[]GET /api/nodes/:id— lookup by exact node number/numeric string, then case-insensitive exact long/short name, else unique substring; 404 when missing or ambiguousDetails
mesh.service.ts: nodeMap reset on each connect, upserted fromnodeInfo, POSITION_APP packets create stub entries for unknown nodes; publicnodes()/node(idOrName)with JSDoc on all public methods; ready-log includes node countcodec.ts:decodePosition()(live positions arrive as a serialized Position insideData.payload— there is noData.positionfield in @meshtastic/protobufs v2.8), hw-model enum → name reverse lookup@ApiTags('Mesh'), tag description via DocumentBuilder (v12 ApiTagOptions has no description field)Verification
npm run build✓npm test— 18/18 passed (was 13, +5 new: node upsert, position stub, lookup resolution order, 404 paths)