Compare commits
2 Commits
fb055785a5
...
913406d1b9
Author | SHA1 | Date | |
---|---|---|---|
913406d1b9 | |||
1f1c0e9881 |
1
mqtt/.npmrc
Normal file
1
mqtt/.npmrc
Normal file
@ -0,0 +1 @@
|
|||||||
|
@jsr:registry=https://npm.jsr.io
|
147
mqtt/index.js
147
mqtt/index.js
@ -1,11 +1,12 @@
|
|||||||
const crypto = require("crypto");
|
const crypto = require("crypto");
|
||||||
const path = require("path");
|
|
||||||
const mqtt = require("mqtt");
|
const mqtt = require("mqtt");
|
||||||
const protobufjs = require("protobufjs");
|
|
||||||
const commandLineArgs = require("command-line-args");
|
const commandLineArgs = require("command-line-args");
|
||||||
const commandLineUsage = require("command-line-usage");
|
const commandLineUsage = require("command-line-usage");
|
||||||
const PositionUtil = require("./utils/position_util");
|
const PositionUtil = require("./utils/position_util");
|
||||||
|
|
||||||
|
const { Mesh, Mqtt, Portnums, Telemetry } = require("@meshtastic/protobufs");
|
||||||
|
const { fromBinary } = require("@bufbuild/protobuf");
|
||||||
|
|
||||||
// create prisma db client
|
// create prisma db client
|
||||||
const { PrismaClient } = require("@prisma/client");
|
const { PrismaClient } = require("@prisma/client");
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
@ -209,8 +210,8 @@ if(options.help){
|
|||||||
const mqttBrokerUrl = options["mqtt-broker-url"] ?? "mqtt://mqtt.meshtastic.org";
|
const mqttBrokerUrl = options["mqtt-broker-url"] ?? "mqtt://mqtt.meshtastic.org";
|
||||||
const mqttUsername = options["mqtt-username"] ?? "meshdev";
|
const mqttUsername = options["mqtt-username"] ?? "meshdev";
|
||||||
const mqttPassword = options["mqtt-password"] ?? "large4cats";
|
const mqttPassword = options["mqtt-password"] ?? "large4cats";
|
||||||
const mqttClientId = options["mqtt-client-id"] ?? null;
|
const mqttClientId = options["mqtt-client-id"] ?? "mqttx_1bc723c7";
|
||||||
const mqttTopics = options["mqtt-topic"] ?? ["msh/#"];
|
const mqttTopics = options["mqtt-topic"] ?? ["msh/US/#"];
|
||||||
const allowedPortnums = options["allowed-portnums"] ?? null;
|
const allowedPortnums = options["allowed-portnums"] ?? null;
|
||||||
const logUnknownPortnums = options["log-unknown-portnums"] ?? false;
|
const logUnknownPortnums = options["log-unknown-portnums"] ?? false;
|
||||||
const collectServiceEnvelopes = options["collect-service-envelopes"] ?? false;
|
const collectServiceEnvelopes = options["collect-service-envelopes"] ?? false;
|
||||||
@ -247,20 +248,6 @@ const client = mqtt.connect(mqttBrokerUrl, {
|
|||||||
clientId: mqttClientId,
|
clientId: mqttClientId,
|
||||||
});
|
});
|
||||||
|
|
||||||
// load protobufs
|
|
||||||
const root = new protobufjs.Root();
|
|
||||||
root.resolvePath = (origin, target) => path.join(__dirname, "protos", target);
|
|
||||||
root.loadSync('meshtastic/mqtt.proto');
|
|
||||||
const Data = root.lookupType("Data");
|
|
||||||
const ServiceEnvelope = root.lookupType("ServiceEnvelope");
|
|
||||||
const MapReport = root.lookupType("MapReport");
|
|
||||||
const NeighborInfo = root.lookupType("NeighborInfo");
|
|
||||||
const Position = root.lookupType("Position");
|
|
||||||
const RouteDiscovery = root.lookupType("RouteDiscovery");
|
|
||||||
const Telemetry = root.lookupType("Telemetry");
|
|
||||||
const User = root.lookupType("User");
|
|
||||||
const Waypoint = root.lookupType("Waypoint");
|
|
||||||
|
|
||||||
// run automatic purge if configured
|
// run automatic purge if configured
|
||||||
if(purgeIntervalSeconds){
|
if(purgeIntervalSeconds){
|
||||||
setInterval(async () => {
|
setInterval(async () => {
|
||||||
@ -634,7 +621,6 @@ function decrypt(packet) {
|
|||||||
// attempt to decrypt with all available decryption keys
|
// attempt to decrypt with all available decryption keys
|
||||||
for(const decryptionKey of decryptionKeys){
|
for(const decryptionKey of decryptionKeys){
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// convert encryption key to buffer
|
// convert encryption key to buffer
|
||||||
const key = Buffer.from(decryptionKey, "base64");
|
const key = Buffer.from(decryptionKey, "base64");
|
||||||
|
|
||||||
@ -657,10 +643,10 @@ function decrypt(packet) {
|
|||||||
const decipher = crypto.createDecipheriv(algorithm, key, nonceBuffer);
|
const decipher = crypto.createDecipheriv(algorithm, key, nonceBuffer);
|
||||||
|
|
||||||
// decrypt encrypted packet
|
// decrypt encrypted packet
|
||||||
const decryptedBuffer = Buffer.concat([decipher.update(packet.encrypted), decipher.final()]);
|
const decryptedBuffer = Buffer.concat([decipher.update(packet.payloadVariant.value), decipher.final()]);
|
||||||
|
|
||||||
// parse as data message
|
// parse as data message
|
||||||
return Data.decode(decryptedBuffer);
|
return fromBinary(Mesh.DataSchema, decryptedBuffer);
|
||||||
|
|
||||||
} catch(e){}
|
} catch(e){}
|
||||||
}
|
}
|
||||||
@ -689,55 +675,40 @@ client.on("connect", () => {
|
|||||||
// handle message received
|
// handle message received
|
||||||
client.on("message", async (topic, message) => {
|
client.on("message", async (topic, message) => {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// decode service envelope
|
// decode service envelope
|
||||||
const envelope = ServiceEnvelope.decode(message);
|
let envelope = null;
|
||||||
if(!envelope.packet){
|
try {
|
||||||
|
envelope = fromBinary(Mqtt.ServiceEnvelopeSchema, message);
|
||||||
|
} catch(e) { }
|
||||||
|
if (!envelope) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let dataPacket = envelope.packet.payloadVariant.value;
|
||||||
// attempt to decrypt encrypted packets
|
// attempt to decrypt encrypted packets
|
||||||
const isEncrypted = envelope.packet.encrypted?.length > 0;
|
if (envelope.packet.payloadVariant.case === 'encrypted') {
|
||||||
if(isEncrypted){
|
dataPacket = decrypt(envelope.packet);
|
||||||
const decoded = decrypt(envelope.packet);
|
|
||||||
if(decoded){
|
|
||||||
envelope.packet.decoded = decoded;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get portnum from decoded packet
|
if (dataPacket !== null) {
|
||||||
const portnum = envelope.packet?.decoded?.portnum;
|
const bitfield = dataPacket.payload.bitfield ?? null;
|
||||||
|
|
||||||
// get bitfield from decoded packet
|
|
||||||
// bitfield was added in v2.5 of meshtastic firmware
|
|
||||||
// this value will be null for packets from v2.4.x and below, and will be an integer in v2.5.x and above
|
|
||||||
const bitfield = envelope.packet?.decoded?.bitfield;
|
|
||||||
|
|
||||||
// check if we can see the decrypted packet data
|
|
||||||
if(envelope.packet.decoded != null){
|
|
||||||
|
|
||||||
// check if bitfield is available (v2.5.x firmware or newer)
|
// check if bitfield is available (v2.5.x firmware or newer)
|
||||||
if(bitfield != null){
|
if (bitfield != null){
|
||||||
|
|
||||||
// drop packets where "OK to MQTT" is false
|
// drop packets where "OK to MQTT" is false
|
||||||
const isOkToMqtt = bitfield & BITFIELD_OK_TO_MQTT_MASK;
|
const isOkToMqtt = bitfield & BITFIELD_OK_TO_MQTT_MASK;
|
||||||
if(dropPacketsNotOkToMqtt && !isOkToMqtt){
|
if (dropPacketsNotOkToMqtt && !isOkToMqtt) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if bitfield is not available for this packet, check if we want to drop this portnum
|
// if bitfield is not available for this packet, check if we want to drop this portnum
|
||||||
if(bitfield == null){
|
if (bitfield == null) {
|
||||||
|
|
||||||
// drop packet if portnum is in drop list
|
// drop packet if portnum is in drop list
|
||||||
// this is useful for dropping specific packet types from firmware older than v2.5
|
// this is useful for dropping specific packet types from firmware older than v2.5
|
||||||
if(dropPortnumsWithoutBitfield != null && dropPortnumsWithoutBitfield.includes(portnum)){
|
if (dropPortnumsWithoutBitfield != null && dropPortnumsWithoutBitfield.includes(portnum)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create service envelope in db
|
// create service envelope in db
|
||||||
@ -774,6 +745,19 @@ client.on("message", async (topic, message) => {
|
|||||||
// don't care if updating mqtt timestamp fails
|
// don't care if updating mqtt timestamp fails
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bail if we don't have a usable Data packet
|
||||||
|
if (dataPacket === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload = dataPacket.payload;
|
||||||
|
// get portnum from decoded packet
|
||||||
|
const portnum = dataPacket.portnum;
|
||||||
|
// get bitfield from decoded packet
|
||||||
|
// bitfield was added in v2.5 of meshtastic firmware
|
||||||
|
// this value will be null for packets from v2.4.x and below, and will be an integer in v2.5.x and above
|
||||||
|
const bitfield = dataPacket.bitfield;
|
||||||
|
|
||||||
const logKnownPacketTypes = false;
|
const logKnownPacketTypes = false;
|
||||||
|
|
||||||
// if allowed portnums are configured, ignore portnums that are not in the list
|
// if allowed portnums are configured, ignore portnums that are not in the list
|
||||||
@ -781,7 +765,7 @@ client.on("message", async (topic, message) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(portnum === 1) {
|
if(portnum === Portnums.PortNum.TEXT_MESSAGE_APP) {
|
||||||
|
|
||||||
if(!collectTextMessages){
|
if(!collectTextMessages){
|
||||||
return;
|
return;
|
||||||
@ -796,7 +780,7 @@ client.on("message", async (topic, message) => {
|
|||||||
console.log("TEXT_MESSAGE_APP", {
|
console.log("TEXT_MESSAGE_APP", {
|
||||||
to: envelope.packet.to.toString(16),
|
to: envelope.packet.to.toString(16),
|
||||||
from: envelope.packet.from.toString(16),
|
from: envelope.packet.from.toString(16),
|
||||||
text: envelope.packet.decoded.payload.toString(),
|
text: payload.toString(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -809,7 +793,7 @@ client.on("message", async (topic, message) => {
|
|||||||
packet_id: envelope.packet.id,
|
packet_id: envelope.packet.id,
|
||||||
channel_id: envelope.channelId,
|
channel_id: envelope.channelId,
|
||||||
gateway_id: envelope.gatewayId ? convertHexIdToNumericId(envelope.gatewayId) : null,
|
gateway_id: envelope.gatewayId ? convertHexIdToNumericId(envelope.gatewayId) : null,
|
||||||
text: envelope.packet.decoded.payload.toString(),
|
text: payload.toString(),
|
||||||
rx_time: envelope.packet.rxTime,
|
rx_time: envelope.packet.rxTime,
|
||||||
rx_snr: envelope.packet.rxSnr,
|
rx_snr: envelope.packet.rxSnr,
|
||||||
rx_rssi: envelope.packet.rxRssi,
|
rx_rssi: envelope.packet.rxRssi,
|
||||||
@ -822,9 +806,8 @@ client.on("message", async (topic, message) => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(portnum === 3) {
|
else if(portnum === Portnums.PortNum.POSITION_APP) {
|
||||||
|
const position = fromBinary(Mesh.PositionSchema, payload);
|
||||||
const position = Position.decode(envelope.packet.decoded.payload);
|
|
||||||
|
|
||||||
if(logKnownPacketTypes){
|
if(logKnownPacketTypes){
|
||||||
console.log("POSITION_APP", {
|
console.log("POSITION_APP", {
|
||||||
@ -911,9 +894,9 @@ client.on("message", async (topic, message) => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(portnum === 4) {
|
else if(portnum === Portnums.PortNum.NODEINFO_APP) {
|
||||||
|
|
||||||
const user = User.decode(envelope.packet.decoded.payload);
|
const user = fromBinary(Mesh.UserSchema, payload);
|
||||||
|
|
||||||
if(logKnownPacketTypes) {
|
if(logKnownPacketTypes) {
|
||||||
console.log("NODEINFO_APP", {
|
console.log("NODEINFO_APP", {
|
||||||
@ -950,13 +933,13 @@ client.on("message", async (topic, message) => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(portnum === 8) {
|
else if(portnum === Portnums.PortNum.WAYPOINT_APP) {
|
||||||
|
|
||||||
if(!collectWaypoints){
|
if(!collectWaypoints){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const waypoint = Waypoint.decode(envelope.packet.decoded.payload);
|
const waypoint = fromBinary(Mesh.WaypointSchema, payload);
|
||||||
|
|
||||||
if(logKnownPacketTypes) {
|
if(logKnownPacketTypes) {
|
||||||
console.log("WAYPOINT_APP", {
|
console.log("WAYPOINT_APP", {
|
||||||
@ -991,9 +974,9 @@ client.on("message", async (topic, message) => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(portnum === 71) {
|
else if(portnum === Portnums.PortNum.NEIGHBORINFO_APP) {
|
||||||
|
|
||||||
const neighbourInfo = NeighborInfo.decode(envelope.packet.decoded.payload);
|
const neighbourInfo = fromBinary(Mesh.NeighborInfoSchema, payload);
|
||||||
|
|
||||||
if(logKnownPacketTypes) {
|
if(logKnownPacketTypes) {
|
||||||
console.log("NEIGHBORINFO_APP", {
|
console.log("NEIGHBORINFO_APP", {
|
||||||
@ -1048,9 +1031,9 @@ client.on("message", async (topic, message) => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(portnum === 67) {
|
else if(portnum === Portnums.PortNum.TELEMETRY_APP) {
|
||||||
|
|
||||||
const telemetry = Telemetry.decode(envelope.packet.decoded.payload);
|
const telemetry = fromBinary(Telemetry.TelemetrySchema, payload);
|
||||||
|
|
||||||
if(logKnownPacketTypes) {
|
if(logKnownPacketTypes) {
|
||||||
console.log("TELEMETRY_APP", {
|
console.log("TELEMETRY_APP", {
|
||||||
@ -1232,15 +1215,15 @@ client.on("message", async (topic, message) => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(portnum === 70) {
|
else if(portnum === Portnums.PortNum.TRACEROUTE_APP) {
|
||||||
|
|
||||||
const routeDiscovery = RouteDiscovery.decode(envelope.packet.decoded.payload);
|
const routeDiscovery = fromBinary(Mesh.RouteDiscoverySchema, payload);
|
||||||
|
|
||||||
if(logKnownPacketTypes) {
|
if(logKnownPacketTypes) {
|
||||||
console.log("TRACEROUTE_APP", {
|
console.log("TRACEROUTE_APP", {
|
||||||
to: envelope.packet.to.toString(16),
|
to: envelope.packet.to.toString(16),
|
||||||
from: envelope.packet.from.toString(16),
|
from: envelope.packet.from.toString(16),
|
||||||
want_response: envelope.packet.decoded.wantResponse,
|
want_response: payload.wantResponse,
|
||||||
route_discovery: routeDiscovery,
|
route_discovery: routeDiscovery,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1267,9 +1250,9 @@ client.on("message", async (topic, message) => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(portnum === 73) {
|
else if(portnum === Portnums.PortNum.MAP_REPORT_APP) {
|
||||||
|
|
||||||
const mapReport = MapReport.decode(envelope.packet.decoded.payload);
|
const mapReport = fromBinary(Mqtt.MapReportSchema, payload);
|
||||||
|
|
||||||
if(logKnownPacketTypes) {
|
if(logKnownPacketTypes) {
|
||||||
console.log("MAP_REPORT_APP", {
|
console.log("MAP_REPORT_APP", {
|
||||||
@ -1362,23 +1345,21 @@ client.on("message", async (topic, message) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
if(logUnknownPortnums){
|
if (logUnknownPortnums) {
|
||||||
|
const ignoredPortnums = [
|
||||||
|
Portnums.PortNum.UNKNOWN_APP,
|
||||||
|
Portnums.PortNum.TEXT_MESSAGE_COMPRESSED_APP,
|
||||||
|
Portnums.PortNum.ROUTING_APP,
|
||||||
|
Portnums.PortNum.PAXCOUNTER_APP,
|
||||||
|
Portnums.PortNum.STORE_FORWARD_APP,
|
||||||
|
Portnums.PortNum.RANGE_TEST_APP,
|
||||||
|
Portnums.PortNum.ATAK_PLUGIN,
|
||||||
|
Portnums.PortNum.ATAK_FORWARDER,
|
||||||
|
];
|
||||||
// ignore packets we don't want to see for now
|
// ignore packets we don't want to see for now
|
||||||
if(portnum === undefined // ignore failed to decrypt
|
if (portnum === undefined || ignoredPortnums.includes(portnum) || portnum > 511) {
|
||||||
|| portnum === 0 // ignore UNKNOWN_APP
|
|
||||||
|| portnum === 1 // ignore TEXT_MESSAGE_APP
|
|
||||||
|| portnum === 5 // ignore ROUTING_APP
|
|
||||||
|| portnum === 34 // ignore PAXCOUNTER_APP
|
|
||||||
|| portnum === 65 // ignore STORE_FORWARD_APP
|
|
||||||
|| portnum === 66 // ignore RANGE_TEST_APP
|
|
||||||
|| portnum === 72 // ignore ATAK_PLUGIN
|
|
||||||
|| portnum === 257 // ignore ATAK_FORWARDER
|
|
||||||
|| portnum > 511 // ignore above MAX
|
|
||||||
){
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(portnum, envelope);
|
console.log(portnum, envelope);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
114
mqtt/package-lock.json
generated
114
mqtt/package-lock.json
generated
@ -9,11 +9,12 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@bufbuild/protobuf": "^2.2.5",
|
||||||
|
"@meshtastic/protobufs": "npm:@jsr/meshtastic__protobufs@^2.6.2",
|
||||||
"@prisma/client": "^5.11.0",
|
"@prisma/client": "^5.11.0",
|
||||||
"command-line-args": "^5.2.1",
|
"command-line-args": "^5.2.1",
|
||||||
"command-line-usage": "^7.0.1",
|
"command-line-usage": "^7.0.1",
|
||||||
"mqtt": "^5.11.0",
|
"mqtt": "^5.11.0"
|
||||||
"protobufjs": "^7.5.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"prisma": "^5.10.2"
|
"prisma": "^5.10.2"
|
||||||
@ -31,6 +32,21 @@
|
|||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@bufbuild/protobuf": {
|
||||||
|
"version": "2.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.2.5.tgz",
|
||||||
|
"integrity": "sha512-/g5EzJifw5GF8aren8wZ/G5oMuPoGeS6MQD3ca8ddcvdXR5UELUfdTZITCGNhNXynY/AYl3Z4plmxdj/tRl/hQ==",
|
||||||
|
"license": "(Apache-2.0 AND BSD-3-Clause)"
|
||||||
|
},
|
||||||
|
"node_modules/@meshtastic/protobufs": {
|
||||||
|
"name": "@jsr/meshtastic__protobufs",
|
||||||
|
"version": "2.6.2",
|
||||||
|
"resolved": "https://npm.jsr.io/~/11/@jsr/meshtastic__protobufs/2.6.2.tgz",
|
||||||
|
"integrity": "sha512-bIENtFnUEru28GrAeSdiBS9skp0hN/3HZunMbF/IjvUrXOlx2fptKVj3b+pzjOWnLBZxllrByV/W+XDmrxqJ6g==",
|
||||||
|
"dependencies": {
|
||||||
|
"@bufbuild/protobuf": "^2.2.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@prisma/client": {
|
"node_modules/@prisma/client": {
|
||||||
"version": "5.22.0",
|
"version": "5.22.0",
|
||||||
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.22.0.tgz",
|
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.22.0.tgz",
|
||||||
@ -99,70 +115,6 @@
|
|||||||
"@prisma/debug": "5.22.0"
|
"@prisma/debug": "5.22.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@protobufjs/aspromise": {
|
|
||||||
"version": "1.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
|
||||||
"integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
|
|
||||||
"license": "BSD-3-Clause"
|
|
||||||
},
|
|
||||||
"node_modules/@protobufjs/base64": {
|
|
||||||
"version": "1.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
|
|
||||||
"integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
|
|
||||||
"license": "BSD-3-Clause"
|
|
||||||
},
|
|
||||||
"node_modules/@protobufjs/codegen": {
|
|
||||||
"version": "2.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
|
|
||||||
"integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==",
|
|
||||||
"license": "BSD-3-Clause"
|
|
||||||
},
|
|
||||||
"node_modules/@protobufjs/eventemitter": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
|
|
||||||
"integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==",
|
|
||||||
"license": "BSD-3-Clause"
|
|
||||||
},
|
|
||||||
"node_modules/@protobufjs/fetch": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
|
|
||||||
"integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"dependencies": {
|
|
||||||
"@protobufjs/aspromise": "^1.1.1",
|
|
||||||
"@protobufjs/inquire": "^1.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@protobufjs/float": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
|
|
||||||
"license": "BSD-3-Clause"
|
|
||||||
},
|
|
||||||
"node_modules/@protobufjs/inquire": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
|
|
||||||
"integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==",
|
|
||||||
"license": "BSD-3-Clause"
|
|
||||||
},
|
|
||||||
"node_modules/@protobufjs/path": {
|
|
||||||
"version": "1.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
|
|
||||||
"integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
|
|
||||||
"license": "BSD-3-Clause"
|
|
||||||
},
|
|
||||||
"node_modules/@protobufjs/pool": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
|
|
||||||
"integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
|
|
||||||
"license": "BSD-3-Clause"
|
|
||||||
},
|
|
||||||
"node_modules/@protobufjs/utf8": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
|
|
||||||
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==",
|
|
||||||
"license": "BSD-3-Clause"
|
|
||||||
},
|
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "22.14.1",
|
"version": "22.14.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.1.tgz",
|
||||||
@ -572,12 +524,6 @@
|
|||||||
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
|
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/long": {
|
|
||||||
"version": "5.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/long/-/long-5.3.1.tgz",
|
|
||||||
"integrity": "sha512-ka87Jz3gcx/I7Hal94xaN2tZEOPoUOEVftkQqZx2EeQRN7LGdfLlI3FvZ+7WDplm+vK2Urx9ULrvSowtdCieng==",
|
|
||||||
"license": "Apache-2.0"
|
|
||||||
},
|
|
||||||
"node_modules/lru-cache": {
|
"node_modules/lru-cache": {
|
||||||
"version": "10.4.3",
|
"version": "10.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
|
||||||
@ -688,30 +634,6 @@
|
|||||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
|
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/protobufjs": {
|
|
||||||
"version": "7.5.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.0.tgz",
|
|
||||||
"integrity": "sha512-Z2E/kOY1QjoMlCytmexzYfDm/w5fKAiRwpSzGtdnXW1zC88Z2yXazHHrOtwCzn+7wSxyE8PYM4rvVcMphF9sOA==",
|
|
||||||
"hasInstallScript": true,
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"dependencies": {
|
|
||||||
"@protobufjs/aspromise": "^1.1.2",
|
|
||||||
"@protobufjs/base64": "^1.1.2",
|
|
||||||
"@protobufjs/codegen": "^2.0.4",
|
|
||||||
"@protobufjs/eventemitter": "^1.1.0",
|
|
||||||
"@protobufjs/fetch": "^1.1.0",
|
|
||||||
"@protobufjs/float": "^1.0.2",
|
|
||||||
"@protobufjs/inquire": "^1.1.0",
|
|
||||||
"@protobufjs/path": "^1.1.2",
|
|
||||||
"@protobufjs/pool": "^1.1.0",
|
|
||||||
"@protobufjs/utf8": "^1.1.0",
|
|
||||||
"@types/node": ">=13.7.0",
|
|
||||||
"long": "^5.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/readable-stream": {
|
"node_modules/readable-stream": {
|
||||||
"version": "4.7.0",
|
"version": "4.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
|
||||||
|
@ -6,11 +6,12 @@
|
|||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"description": "",
|
"description": "",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@bufbuild/protobuf": "^2.2.5",
|
||||||
|
"@meshtastic/protobufs": "npm:@jsr/meshtastic__protobufs@^2.6.2",
|
||||||
"@prisma/client": "^5.11.0",
|
"@prisma/client": "^5.11.0",
|
||||||
"command-line-args": "^5.2.1",
|
"command-line-args": "^5.2.1",
|
||||||
"command-line-usage": "^7.0.1",
|
"command-line-usage": "^7.0.1",
|
||||||
"mqtt": "^5.11.0",
|
"mqtt": "^5.11.0"
|
||||||
"protobufjs": "^7.5.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"prisma": "^5.10.2"
|
"prisma": "^5.10.2"
|
||||||
|
Reference in New Issue
Block a user