atmosx-nwws-parser 1.0.19 → 1.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +182 -64
- package/dist/cjs/index.cjs +3799 -0
- package/dist/esm/index.mjs +3757 -0
- package/package.json +49 -37
- package/src/bootstrap.ts +196 -0
- package/src/database.ts +148 -0
- package/src/dictionaries/awips.ts +342 -0
- package/src/dictionaries/events.ts +142 -0
- package/src/dictionaries/icao.ts +237 -0
- package/src/dictionaries/offshore.ts +12 -0
- package/src/dictionaries/signatures.ts +107 -0
- package/src/eas.ts +493 -0
- package/src/index.ts +229 -0
- package/src/parsers/events/api.ts +151 -0
- package/src/parsers/events/cap.ts +138 -0
- package/src/parsers/events/text.ts +106 -0
- package/src/parsers/events/ugc.ts +109 -0
- package/src/parsers/events/vtec.ts +78 -0
- package/src/parsers/events.ts +367 -0
- package/src/parsers/hvtec.ts +46 -0
- package/src/parsers/pvtec.ts +71 -0
- package/src/parsers/stanza.ts +132 -0
- package/src/parsers/text.ts +166 -0
- package/src/parsers/ugc.ts +197 -0
- package/src/types.ts +251 -0
- package/src/utils.ts +314 -0
- package/src/xmpp.ts +144 -0
- package/test.js +58 -34
- package/tsconfig.json +12 -5
- package/tsup.config.ts +14 -0
- package/bootstrap.ts +0 -122
- package/dist/bootstrap.js +0 -153
- package/dist/src/events.js +0 -585
- package/dist/src/helper.js +0 -463
- package/dist/src/stanza.js +0 -147
- package/dist/src/text-parser.js +0 -119
- package/dist/src/ugc.js +0 -214
- package/dist/src/vtec.js +0 -125
- package/src/events.ts +0 -394
- package/src/helper.ts +0 -298
- package/src/stanza.ts +0 -102
- package/src/text-parser.ts +0 -120
- package/src/ugc.ts +0 -122
- package/src/vtec.ts +0 -99
package/dist/src/helper.js
DELETED
|
@@ -1,463 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
_ _ __ __
|
|
4
|
-
/\ | | | | (_) \ \ / /
|
|
5
|
-
/ \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
|
|
6
|
-
/ /\ \| __| '_ ` _ \ / _ \/ __| '_ \| '_ \ / _ \ '__| |/ __| > <
|
|
7
|
-
/ ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
|
|
8
|
-
/_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
|
|
9
|
-
| |
|
|
10
|
-
|_|
|
|
11
|
-
|
|
12
|
-
Written by: k3yomi@GitHub
|
|
13
|
-
*/
|
|
14
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
15
|
-
if (k2 === undefined) k2 = k;
|
|
16
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
17
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
18
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
19
|
-
}
|
|
20
|
-
Object.defineProperty(o, k2, desc);
|
|
21
|
-
}) : (function(o, m, k, k2) {
|
|
22
|
-
if (k2 === undefined) k2 = k;
|
|
23
|
-
o[k2] = m[k];
|
|
24
|
-
}));
|
|
25
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
26
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
27
|
-
}) : function(o, v) {
|
|
28
|
-
o["default"] = v;
|
|
29
|
-
});
|
|
30
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
31
|
-
var ownKeys = function(o) {
|
|
32
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
33
|
-
var ar = [];
|
|
34
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
35
|
-
return ar;
|
|
36
|
-
};
|
|
37
|
-
return ownKeys(o);
|
|
38
|
-
};
|
|
39
|
-
return function (mod) {
|
|
40
|
-
if (mod && mod.__esModule) return mod;
|
|
41
|
-
var result = {};
|
|
42
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
43
|
-
__setModuleDefault(result, mod);
|
|
44
|
-
return result;
|
|
45
|
-
};
|
|
46
|
-
})();
|
|
47
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
48
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
49
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
50
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
51
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
52
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
53
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
54
|
-
});
|
|
55
|
-
};
|
|
56
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
57
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
58
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
59
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
60
|
-
function step(op) {
|
|
61
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
62
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
63
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
64
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
65
|
-
switch (op[0]) {
|
|
66
|
-
case 0: case 1: t = op; break;
|
|
67
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
68
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
69
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
70
|
-
default:
|
|
71
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
72
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
73
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
74
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
75
|
-
if (t[2]) _.ops.pop();
|
|
76
|
-
_.trys.pop(); continue;
|
|
77
|
-
}
|
|
78
|
-
op = body.call(thisArg, _);
|
|
79
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
80
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
84
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
85
|
-
};
|
|
86
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
87
|
-
exports.Parser = void 0;
|
|
88
|
-
var loader = __importStar(require("../bootstrap"));
|
|
89
|
-
var stanza_1 = __importDefault(require("./stanza"));
|
|
90
|
-
var Parser = /** @class */ (function () {
|
|
91
|
-
function Parser(metadata) {
|
|
92
|
-
var _this = this;
|
|
93
|
-
/**
|
|
94
|
-
* @function initalizeDatabase
|
|
95
|
-
* @description Initalizes the database and creates the shapefiles table if it does not exist.
|
|
96
|
-
* Also imports shapefiles into the database if the table is created.
|
|
97
|
-
*
|
|
98
|
-
* @param {string} database - The path to the database file.
|
|
99
|
-
*/
|
|
100
|
-
this.initalizeDatabase = function (database) { return __awaiter(_this, void 0, void 0, function () {
|
|
101
|
-
var _a, fs, sqlite3, path, shapefile, db, parseShapefiles, isExisting;
|
|
102
|
-
var _this = this;
|
|
103
|
-
return __generator(this, function (_b) {
|
|
104
|
-
switch (_b.label) {
|
|
105
|
-
case 0:
|
|
106
|
-
_a = this.packages, fs = _a.fs, sqlite3 = _a.sqlite3, path = _a.path, shapefile = _a.shapefile;
|
|
107
|
-
if (!fs.existsSync(database)) { // If the database file DOES NOT exist, create it with empty content
|
|
108
|
-
fs.writeFileSync(database, '', 'utf8');
|
|
109
|
-
}
|
|
110
|
-
db = new sqlite3(database);
|
|
111
|
-
loader.statics.db = db;
|
|
112
|
-
parseShapefiles = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
113
|
-
var shapefiles, _i, shapefiles_1, shape, id, file, filepath, features, _a, features_1, feature, properties, geometry, equals, location_1, importStatement;
|
|
114
|
-
return __generator(this, function (_b) {
|
|
115
|
-
switch (_b.label) {
|
|
116
|
-
case 0:
|
|
117
|
-
shapefiles = [{ id: "C", file: "USCounties" }, { id: "Z", file: "ForecastZones" }, { id: "Z", file: "FireZones" }, { id: "Z", file: "OffShoreZones" }, { id: "Z", file: "FireCounties" }, { id: "Z", file: "Marine" }];
|
|
118
|
-
_i = 0, shapefiles_1 = shapefiles;
|
|
119
|
-
_b.label = 1;
|
|
120
|
-
case 1:
|
|
121
|
-
if (!(_i < shapefiles_1.length)) return [3 /*break*/, 8];
|
|
122
|
-
shape = shapefiles_1[_i];
|
|
123
|
-
id = shape.id, file = shape.file;
|
|
124
|
-
filepath = path.join(__dirname, "../../shapefiles", file);
|
|
125
|
-
return [4 /*yield*/, shapefile.read(filepath, filepath)];
|
|
126
|
-
case 2:
|
|
127
|
-
features = (_b.sent()).features;
|
|
128
|
-
console.log("Importing ".concat(features.length, " features from ").concat(file, "..."));
|
|
129
|
-
_a = 0, features_1 = features;
|
|
130
|
-
_b.label = 3;
|
|
131
|
-
case 3:
|
|
132
|
-
if (!(_a < features_1.length)) return [3 /*break*/, 6];
|
|
133
|
-
feature = features_1[_a];
|
|
134
|
-
properties = feature.properties, geometry = feature.geometry;
|
|
135
|
-
equals = void 0, location_1 = void 0;
|
|
136
|
-
if (properties.FIPS) {
|
|
137
|
-
equals = "".concat(properties.STATE).concat(id).concat(properties.FIPS.substring(2));
|
|
138
|
-
location_1 = "".concat(properties.COUNTYNAME, ", ").concat(properties.STATE);
|
|
139
|
-
}
|
|
140
|
-
else if (properties.FULLSTAID) {
|
|
141
|
-
equals = "".concat(properties.ST).concat(id).concat(properties.WFO);
|
|
142
|
-
location_1 = "".concat(properties.CITY, ", ").concat(properties.STATE);
|
|
143
|
-
}
|
|
144
|
-
else if (properties.STATE) {
|
|
145
|
-
equals = "".concat(properties.STATE).concat(id).concat(properties.ZONE);
|
|
146
|
-
location_1 = "".concat(properties.NAME, ", ").concat(properties.STATE);
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
equals = properties.ID;
|
|
150
|
-
location_1 = properties.NAME;
|
|
151
|
-
}
|
|
152
|
-
importStatement = "INSERT OR REPLACE INTO shapefiles (id, location, geometry) VALUES (?, ?, ?)";
|
|
153
|
-
return [4 /*yield*/, db.prepare(importStatement).run(equals, location_1, JSON.stringify(geometry))];
|
|
154
|
-
case 4:
|
|
155
|
-
_b.sent();
|
|
156
|
-
_b.label = 5;
|
|
157
|
-
case 5:
|
|
158
|
-
_a++;
|
|
159
|
-
return [3 /*break*/, 3];
|
|
160
|
-
case 6:
|
|
161
|
-
console.log("Finished importing ".concat(file, "."));
|
|
162
|
-
_b.label = 7;
|
|
163
|
-
case 7:
|
|
164
|
-
_i++;
|
|
165
|
-
return [3 /*break*/, 1];
|
|
166
|
-
case 8: return [2 /*return*/];
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
}); };
|
|
170
|
-
isExisting = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
171
|
-
var checkStatement;
|
|
172
|
-
return __generator(this, function (_a) {
|
|
173
|
-
switch (_a.label) {
|
|
174
|
-
case 0:
|
|
175
|
-
checkStatement = "SELECT name FROM sqlite_master WHERE type='table' AND name='shapefiles'";
|
|
176
|
-
if (!!db.prepare(checkStatement).get()) return [3 /*break*/, 2];
|
|
177
|
-
db.prepare("CREATE TABLE shapefiles (id TEXT PRIMARY KEY, location TEXT, geometry TEXT)").run();
|
|
178
|
-
console.log(loader.definitions.messages.shapefile_creation);
|
|
179
|
-
return [4 /*yield*/, parseShapefiles()];
|
|
180
|
-
case 1:
|
|
181
|
-
_a.sent();
|
|
182
|
-
console.log(loader.definitions.messages.shapefile_creation_finished);
|
|
183
|
-
_a.label = 2;
|
|
184
|
-
case 2: return [2 /*return*/];
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
}); };
|
|
188
|
-
return [4 /*yield*/, isExisting()];
|
|
189
|
-
case 1:
|
|
190
|
-
_b.sent();
|
|
191
|
-
this.initalizeSession(this.metadata);
|
|
192
|
-
return [2 /*return*/];
|
|
193
|
-
}
|
|
194
|
-
});
|
|
195
|
-
}); };
|
|
196
|
-
/**
|
|
197
|
-
* @function initalizeClient
|
|
198
|
-
* @description Initalizes the XMPP client and sets up event listeners.
|
|
199
|
-
*
|
|
200
|
-
* @param {object} metadata - The metadata object containing authentication information.
|
|
201
|
-
*/
|
|
202
|
-
this.initalizeClient = function (metadata) {
|
|
203
|
-
if (loader.settings.database == null) {
|
|
204
|
-
throw new Error("error-database-not-configured");
|
|
205
|
-
}
|
|
206
|
-
loader.statics.session = loader.packages.xmpp.client({
|
|
207
|
-
service: "xmpp://nwws-oi.weather.gov",
|
|
208
|
-
domain: "nwws-oi.weather.gov",
|
|
209
|
-
username: metadata.authentication.username || null,
|
|
210
|
-
password: metadata.authentication.password || null,
|
|
211
|
-
});
|
|
212
|
-
};
|
|
213
|
-
/**
|
|
214
|
-
* @function initalizeSession
|
|
215
|
-
* @description Initalizes the XMPP session and sets up event listeners for connection, disconnection, errors, and incoming stanzas.
|
|
216
|
-
*
|
|
217
|
-
* @param {object} metadata - The metadata object containing authentication information.
|
|
218
|
-
*
|
|
219
|
-
* @emits onConnection - Emitted when the client successfully connects to the XMPP server.
|
|
220
|
-
* @emits onStanza - Emitted when a valid stanza is received from the XMPP server.
|
|
221
|
-
* @emits onError - Emitted when an error occurs.
|
|
222
|
-
* @emits onReconnect - Emitted when the client attempts to reconnect to the XMPP server.
|
|
223
|
-
* @throws Will throw an error if the database is not configured, if the client is reconnecting too fast, or if the connection to the XMPP server is lost.
|
|
224
|
-
*/
|
|
225
|
-
this.initalizeSession = function (metadata) { return __awaiter(_this, void 0, void 0, function () {
|
|
226
|
-
var _this = this;
|
|
227
|
-
return __generator(this, function (_a) {
|
|
228
|
-
switch (_a.label) {
|
|
229
|
-
case 0:
|
|
230
|
-
if (this.metadata.authentication.display == undefined)
|
|
231
|
-
this.metadata.authentication.display = this.metadata.authentication.username || "No Username Provided";
|
|
232
|
-
this.initalizeClient(this.metadata);
|
|
233
|
-
loader.statics.session.on("online", function (address) { return __awaiter(_this, void 0, void 0, function () {
|
|
234
|
-
var _this = this;
|
|
235
|
-
return __generator(this, function (_a) {
|
|
236
|
-
if (loader.cache.lastConnect && (new Date().getTime() - loader.cache.lastConnect) < 10 * 1000) {
|
|
237
|
-
setTimeout(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
238
|
-
return __generator(this, function (_a) {
|
|
239
|
-
switch (_a.label) {
|
|
240
|
-
case 0: return [4 /*yield*/, loader.statics.session.stop().catch(function () { })];
|
|
241
|
-
case 1:
|
|
242
|
-
_a.sent();
|
|
243
|
-
return [4 /*yield*/, loader.statics.session.start().catch(function () { })];
|
|
244
|
-
case 2:
|
|
245
|
-
_a.sent();
|
|
246
|
-
return [2 /*return*/];
|
|
247
|
-
}
|
|
248
|
-
});
|
|
249
|
-
}); }, 2 * 1000);
|
|
250
|
-
loader.cache.sigHault = true;
|
|
251
|
-
throw new Error("error-reconnecting-too-fast"); // Patch v1.0.14 - Prevents reconnecting too fast
|
|
252
|
-
}
|
|
253
|
-
loader.statics.session.send(loader.packages.xmpp.xml('presence', { to: "nwws@conference.nwws-oi.weather.gov/".concat(this.metadata.authentication.display), xmlns: 'http://jabber.org/protocol/muc' }));
|
|
254
|
-
loader.statics.session.send(loader.packages.xmpp.xml('presence', { to: "nwws@conference.nwws-oi.weather.gov", type: 'available' }));
|
|
255
|
-
loader.statics.events.emit("onConnection", this.metadata.authentication.display);
|
|
256
|
-
loader.cache.lastConnect = new Date().getTime();
|
|
257
|
-
loader.cache.sigHault = false;
|
|
258
|
-
loader.cache.isConnected = true;
|
|
259
|
-
if (loader.cache.attemptingReconnect) {
|
|
260
|
-
setTimeout(function () { loader.cache.attemptingReconnect = false; }, 15 * 1000);
|
|
261
|
-
}
|
|
262
|
-
return [2 /*return*/];
|
|
263
|
-
});
|
|
264
|
-
}); });
|
|
265
|
-
loader.statics.session.on("offline", function () {
|
|
266
|
-
loader.cache.isConnected = false;
|
|
267
|
-
loader.cache.sigHault = true;
|
|
268
|
-
loader.cache.attemptingReconnect = false;
|
|
269
|
-
throw new Error("error-connection-lost");
|
|
270
|
-
});
|
|
271
|
-
loader.statics.session.on("error", function (err) {
|
|
272
|
-
loader.cache.isConnected = false;
|
|
273
|
-
loader.cache.sigHault = true;
|
|
274
|
-
loader.cache.attemptingReconnect = false;
|
|
275
|
-
throw new Error(err.message || "error-connection-lost");
|
|
276
|
-
});
|
|
277
|
-
loader.statics.session.on("stanza", function (stanza) {
|
|
278
|
-
loader.cache.lastStanza = new Date().getTime();
|
|
279
|
-
if (stanza.is("message")) {
|
|
280
|
-
var sValid = stanza_1.default.validate(stanza);
|
|
281
|
-
if (sValid.ignore || (sValid.isCap && !loader.settings.alertSettings.onlyCap) || (!sValid.isCap && loader.settings.alertSettings.onlyCap) || (sValid.isCap && !sValid.hasCapDescription))
|
|
282
|
-
return;
|
|
283
|
-
loader.statics.events.emit("onMessage", sValid.message);
|
|
284
|
-
stanza_1.default.create(sValid);
|
|
285
|
-
}
|
|
286
|
-
if (stanza.is('presence') && stanza.attrs.from && stanza.attrs.from.startsWith('nwws@conference.nwws-oi.weather.gov/')) {
|
|
287
|
-
var occupant = stanza.attrs.from.split('/').slice(1).join('/');
|
|
288
|
-
loader.statics.events.emit('onOccupant', { occupant: occupant, type: stanza.attrs.type === 'unavailable' ? 'unavailable' : 'available' });
|
|
289
|
-
}
|
|
290
|
-
});
|
|
291
|
-
return [4 /*yield*/, loader.statics.session.start()];
|
|
292
|
-
case 1:
|
|
293
|
-
_a.sent();
|
|
294
|
-
return [2 /*return*/];
|
|
295
|
-
}
|
|
296
|
-
});
|
|
297
|
-
}); };
|
|
298
|
-
/**
|
|
299
|
-
* @function initalizeCache
|
|
300
|
-
* @description Initalizes the cache by reading cached stanzas from files in the cache directory.
|
|
301
|
-
* The function checks the alert settings to determine which files to read and processes each file by validating and creating stanzas.
|
|
302
|
-
* If the cache directory is not set or reading from cache is disabled, the function returns without performing any actions.
|
|
303
|
-
*/
|
|
304
|
-
this.initalizeCache = function () {
|
|
305
|
-
if (loader.settings.cacheSettings.readCache && loader.settings.cacheSettings.cacheDir) {
|
|
306
|
-
var dir = loader.settings.cacheSettings.cacheDir;
|
|
307
|
-
var dict = [
|
|
308
|
-
{ file: "".concat(dir, "/category-defaults-raw-vtec.bin"), attributes: { awipsid: 'alert', isCap: false, raw: true, issue: undefined } },
|
|
309
|
-
{ file: "".concat(dir, "/category-defaults-cap-vtec.bin"), attributes: { awipsid: 'alert', isCap: true, raw: false, issue: undefined } },
|
|
310
|
-
{ file: "".concat(dir, "/category-special-weather-statements-raw.bin"), attributes: { awipsid: 'SPS001', isCap: false, raw: true, issue: undefined } },
|
|
311
|
-
{ file: "".concat(dir, "/category-mesoscale-discussions-raw.bin"), attributes: { awipsid: 'SWOMCD001', isCap: false, raw: true, issue: undefined } },
|
|
312
|
-
{ file: "".concat(dir, "/category-local-storm-reports.bin"), attributes: { awipsid: 'LSR001', isCap: false, raw: true, issue: undefined } },
|
|
313
|
-
];
|
|
314
|
-
for (var _i = 0, dict_1 = dict; _i < dict_1.length; _i++) {
|
|
315
|
-
var file = dict_1[_i];
|
|
316
|
-
if (file.attributes.isCap && !loader.settings.alertSettings.onlyCap)
|
|
317
|
-
continue;
|
|
318
|
-
if (!file.attributes.isCap && loader.settings.alertSettings.onlyCap)
|
|
319
|
-
continue;
|
|
320
|
-
if (!_this.packages.fs.existsSync(file.file))
|
|
321
|
-
continue;
|
|
322
|
-
var read = _this.packages.fs.readFileSync(file.file, 'utf8');
|
|
323
|
-
var sValid = stanza_1.default.validate(read, file.attributes);
|
|
324
|
-
stanza_1.default.create(sValid);
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
};
|
|
328
|
-
/**
|
|
329
|
-
* @function errorHandler
|
|
330
|
-
* @description Sets up a global error handler to catch uncaught exceptions and emit an 'onError' event with the error details.
|
|
331
|
-
* The function checks if the error message matches any predefined halting conditions and includes the corresponding message and code in the emitted event.
|
|
332
|
-
* This helps in logging and handling errors gracefully within the application.
|
|
333
|
-
*/
|
|
334
|
-
this.errorHandler = function () {
|
|
335
|
-
process.on('uncaughtException', function (error) {
|
|
336
|
-
var hault = loader.definitions.haultingConditions.find(function (e) { return error.message.includes(e.error); });
|
|
337
|
-
if (hault) {
|
|
338
|
-
loader.statics.events.emit("onError", { error: "".concat(hault ? hault.message : error.message), code: hault.code });
|
|
339
|
-
}
|
|
340
|
-
loader.statics.events.emit("onError", { error: error.stack || error.message || "An unknown error occurred", code: "uncaught-exception" });
|
|
341
|
-
});
|
|
342
|
-
};
|
|
343
|
-
/**
|
|
344
|
-
* @function garabeCollector
|
|
345
|
-
* @description Cleans up cache files in the specified cache directory that exceed the maximum allowed size.
|
|
346
|
-
* The function traverses the cache directory and its subdirectories, checking the size of each file.
|
|
347
|
-
* If a file exceeds the specified maximum size in megabytes, it is deleted.
|
|
348
|
-
*
|
|
349
|
-
* @param {number} maxMegabytes - The maximum allowed size for cache files in megabytes.
|
|
350
|
-
*/
|
|
351
|
-
this.garabeCollector = function (maxMegabytes) {
|
|
352
|
-
if (!loader.settings.cacheSettings.cacheDir)
|
|
353
|
-
return;
|
|
354
|
-
var maxBytes = maxMegabytes * 1024 * 1024;
|
|
355
|
-
var directory = loader.settings.cacheSettings.cacheDir;
|
|
356
|
-
var stackFiles = [directory], files = [];
|
|
357
|
-
var _loop_1 = function () {
|
|
358
|
-
var currentDirectory = stackFiles.pop();
|
|
359
|
-
if (!currentDirectory || typeof currentDirectory !== "string")
|
|
360
|
-
return "continue";
|
|
361
|
-
loader.packages.fs.readdirSync(currentDirectory).forEach(function (file) {
|
|
362
|
-
var filePath = loader.packages.path.join(currentDirectory, file);
|
|
363
|
-
if (loader.packages.fs.statSync(filePath).isDirectory()) {
|
|
364
|
-
stackFiles.push(filePath);
|
|
365
|
-
}
|
|
366
|
-
else {
|
|
367
|
-
files.push({ file: filePath, size: loader.packages.fs.statSync(filePath).size });
|
|
368
|
-
}
|
|
369
|
-
});
|
|
370
|
-
};
|
|
371
|
-
while (stackFiles.length) {
|
|
372
|
-
_loop_1();
|
|
373
|
-
}
|
|
374
|
-
if (!files.length)
|
|
375
|
-
return;
|
|
376
|
-
files.forEach(function (_a) {
|
|
377
|
-
var file = _a.file, size = _a.size;
|
|
378
|
-
if (size > maxBytes) {
|
|
379
|
-
loader.packages.fs.unlinkSync(file);
|
|
380
|
-
}
|
|
381
|
-
});
|
|
382
|
-
return;
|
|
383
|
-
};
|
|
384
|
-
/**
|
|
385
|
-
* @function isReconnectEligible
|
|
386
|
-
* @description Checks if the client is eligible to reconnect based on the specified interval.
|
|
387
|
-
* If the client is not connected and the last stanza received was longer than the specified interval ago,
|
|
388
|
-
* the function attempts to reconnect the client.
|
|
389
|
-
*
|
|
390
|
-
* @param {number} interval - The minimum interval in seconds between reconnection attempts.
|
|
391
|
-
* @returns {object} An object containing the connection status and session information.
|
|
392
|
-
*/
|
|
393
|
-
this.isReconnectEligible = function (interval) { return __awaiter(_this, void 0, void 0, function () {
|
|
394
|
-
var minSeconds, lastStanza;
|
|
395
|
-
return __generator(this, function (_a) {
|
|
396
|
-
switch (_a.label) {
|
|
397
|
-
case 0:
|
|
398
|
-
minSeconds = interval;
|
|
399
|
-
if (!((loader.cache.isConnected || loader.cache.sigHault === true) && loader.statics.session)) return [3 /*break*/, 3];
|
|
400
|
-
lastStanza = new Date().getTime() - loader.cache.lastStanza;
|
|
401
|
-
if (!(lastStanza > minSeconds * 1000)) return [3 /*break*/, 3];
|
|
402
|
-
if (!!loader.cache.attemptingReconnect) return [3 /*break*/, 3];
|
|
403
|
-
loader.cache.attemptingReconnect = true;
|
|
404
|
-
loader.cache.isConnected = false;
|
|
405
|
-
loader.cache.totalReconnects += 1;
|
|
406
|
-
loader.statics.events.emit("onReconnect", { reconnects: loader.cache.totalReconnects, lastStanza: lastStanza / 1000, lastName: this.metadata.authentication.display });
|
|
407
|
-
return [4 /*yield*/, loader.statics.session.stop().catch(function () { })];
|
|
408
|
-
case 1:
|
|
409
|
-
_a.sent();
|
|
410
|
-
return [4 /*yield*/, loader.statics.session.start().catch(function () { })];
|
|
411
|
-
case 2:
|
|
412
|
-
_a.sent();
|
|
413
|
-
_a.label = 3;
|
|
414
|
-
case 3: return [2 /*return*/, {
|
|
415
|
-
message: "Session is not connected or session is not available",
|
|
416
|
-
isConnected: loader.cache.isConnected,
|
|
417
|
-
session: loader.statics.session
|
|
418
|
-
}];
|
|
419
|
-
}
|
|
420
|
-
});
|
|
421
|
-
}); };
|
|
422
|
-
/**
|
|
423
|
-
* @function setDisplayName
|
|
424
|
-
* @description Sets the display name for the XMPP session.
|
|
425
|
-
*
|
|
426
|
-
* @param {string} name - The display name to set for the session.
|
|
427
|
-
*/
|
|
428
|
-
this.setDisplayName = function (name) { return __awaiter(_this, void 0, void 0, function () {
|
|
429
|
-
return __generator(this, function (_a) {
|
|
430
|
-
this.metadata.authentication.display = name;
|
|
431
|
-
return [2 /*return*/];
|
|
432
|
-
});
|
|
433
|
-
}); };
|
|
434
|
-
/**
|
|
435
|
-
* @function onEvent
|
|
436
|
-
* @description Registers an event listener for the specified event and returns a function to remove the listener.
|
|
437
|
-
*
|
|
438
|
-
* @param {string} event - The name of the event to listen for.
|
|
439
|
-
* @param {function} callback - The callback function to execute when the event is emitted.
|
|
440
|
-
* @returns {function} A function that removes the event listener when called.
|
|
441
|
-
*/
|
|
442
|
-
this.onEvent = function (event, callback) {
|
|
443
|
-
loader.statics.events.on(event, callback);
|
|
444
|
-
return function () { loader.statics.events.off(event, callback); };
|
|
445
|
-
};
|
|
446
|
-
this.packages = loader.packages;
|
|
447
|
-
this.metadata = metadata;
|
|
448
|
-
Object.assign(loader.settings, metadata);
|
|
449
|
-
this.errorHandler();
|
|
450
|
-
this.initalizeDatabase(this.metadata.database);
|
|
451
|
-
this.initalizeCache();
|
|
452
|
-
setInterval(function () {
|
|
453
|
-
if (loader.settings.cacheSettings.cacheDir) {
|
|
454
|
-
_this.garabeCollector(loader.settings.cacheSettings.maxMegabytes);
|
|
455
|
-
}
|
|
456
|
-
if (loader.settings.xmpp.reconnect) {
|
|
457
|
-
_this.isReconnectEligible(loader.settings.xmpp.reconnectInterval);
|
|
458
|
-
}
|
|
459
|
-
}, 1 * 1000);
|
|
460
|
-
}
|
|
461
|
-
return Parser;
|
|
462
|
-
}());
|
|
463
|
-
exports.Parser = Parser;
|
package/dist/src/stanza.js
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
_ _ __ __
|
|
4
|
-
/\ | | | | (_) \ \ / /
|
|
5
|
-
/ \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
|
|
6
|
-
/ /\ \| __| '_ ` _ \ / _ \/ __| '_ \| '_ \ / _ \ '__| |/ __| > <
|
|
7
|
-
/ ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
|
|
8
|
-
/_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
|
|
9
|
-
| |
|
|
10
|
-
|_|
|
|
11
|
-
|
|
12
|
-
Written by: k3yomi@GitHub
|
|
13
|
-
*/
|
|
14
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
15
|
-
if (k2 === undefined) k2 = k;
|
|
16
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
17
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
18
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
19
|
-
}
|
|
20
|
-
Object.defineProperty(o, k2, desc);
|
|
21
|
-
}) : (function(o, m, k, k2) {
|
|
22
|
-
if (k2 === undefined) k2 = k;
|
|
23
|
-
o[k2] = m[k];
|
|
24
|
-
}));
|
|
25
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
26
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
27
|
-
}) : function(o, v) {
|
|
28
|
-
o["default"] = v;
|
|
29
|
-
});
|
|
30
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
31
|
-
var ownKeys = function(o) {
|
|
32
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
33
|
-
var ar = [];
|
|
34
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
35
|
-
return ar;
|
|
36
|
-
};
|
|
37
|
-
return ownKeys(o);
|
|
38
|
-
};
|
|
39
|
-
return function (mod) {
|
|
40
|
-
if (mod && mod.__esModule) return mod;
|
|
41
|
-
var result = {};
|
|
42
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
43
|
-
__setModuleDefault(result, mod);
|
|
44
|
-
return result;
|
|
45
|
-
};
|
|
46
|
-
})();
|
|
47
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
48
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
49
|
-
};
|
|
50
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
51
|
-
exports.mStanza = void 0;
|
|
52
|
-
var loader = __importStar(require("../bootstrap"));
|
|
53
|
-
var events_1 = __importDefault(require("./events"));
|
|
54
|
-
var mStanza = /** @class */ (function () {
|
|
55
|
-
function mStanza() {
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* @function validate
|
|
59
|
-
* @description Validates an incoming XMPP stanza to determine if it contains relevant weather alert information.
|
|
60
|
-
* If valid, it extracts and returns key details such as the message content, attributes, and alert type.
|
|
61
|
-
*
|
|
62
|
-
* @param {any} stanza - The incoming XMPP stanza to validate.
|
|
63
|
-
* @param {any} isDebug - Optional parameter for debugging purposes. If provided, it treats the input as a debug object.
|
|
64
|
-
*
|
|
65
|
-
*/
|
|
66
|
-
mStanza.validate = function (stanza, isDebug) {
|
|
67
|
-
if (isDebug === void 0) { isDebug = false; }
|
|
68
|
-
if (isDebug != false) {
|
|
69
|
-
var message = stanza;
|
|
70
|
-
var attributes = isDebug;
|
|
71
|
-
var isCap = isDebug.isCap;
|
|
72
|
-
var hasCapDescription = stanza.includes("<areaDesc>");
|
|
73
|
-
var hasVTEC = stanza.match(loader.definitions.expressions.vtec) != null;
|
|
74
|
-
var getAwipsType = this.getAwipsType(isDebug);
|
|
75
|
-
return { message: message, attributes: attributes, isDebug: isDebug, isCap: isCap, hasCapDescription: hasCapDescription, hasVTEC: hasVTEC, getAwipsType: getAwipsType, ignore: false };
|
|
76
|
-
}
|
|
77
|
-
if (stanza.is("message")) {
|
|
78
|
-
var cb = stanza.getChild("x");
|
|
79
|
-
if (cb === null || cb === void 0 ? void 0 : cb.children) {
|
|
80
|
-
var message = cb.children[0];
|
|
81
|
-
var attributes = cb.attrs;
|
|
82
|
-
var isCap = message.includes("<?xml version=\"1.0\"");
|
|
83
|
-
var hasCapDescription = message.includes("<areaDesc>");
|
|
84
|
-
var hasVTEC = message.match(loader.definitions.expressions.vtec) != null;
|
|
85
|
-
var getAwipsType = this.getAwipsType(attributes);
|
|
86
|
-
this.saveToCache({ message: message, attributes: attributes, isCap: isCap, hasVTEC: hasVTEC, getAwipsType: getAwipsType });
|
|
87
|
-
return { message: message, attributes: attributes, isCap: isCap, hasCapDescription: hasCapDescription, hasVTEC: hasVTEC, getAwipsType: getAwipsType, ignore: false };
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return { ignore: true };
|
|
91
|
-
};
|
|
92
|
-
/**
|
|
93
|
-
* @function getAwipsType
|
|
94
|
-
* @description Determines the AWIPS type of a weather alert based on its attributes.
|
|
95
|
-
* It checks the 'awipsid' attribute against known prefixes to classify the alert type.
|
|
96
|
-
*
|
|
97
|
-
* @param {any} attributes - The attributes of the weather alert stanza.
|
|
98
|
-
*/
|
|
99
|
-
mStanza.getAwipsType = function (attributes) {
|
|
100
|
-
if (!attributes || !attributes.awipsid)
|
|
101
|
-
return "unknown";
|
|
102
|
-
for (var _i = 0, _a = Object.entries(loader.definitions.awips); _i < _a.length; _i++) {
|
|
103
|
-
var _b = _a[_i], prefix = _b[0], type = _b[1];
|
|
104
|
-
if (attributes.awipsid.startsWith(prefix))
|
|
105
|
-
return type;
|
|
106
|
-
}
|
|
107
|
-
return "default";
|
|
108
|
-
};
|
|
109
|
-
/**
|
|
110
|
-
* @function create
|
|
111
|
-
* @description Processes a validated weather alert stanza and triggers the appropriate event based on its type.
|
|
112
|
-
*
|
|
113
|
-
* @param {any} stanzaData - The validated weather alert stanza data.
|
|
114
|
-
*/
|
|
115
|
-
mStanza.create = function (stanzaData) {
|
|
116
|
-
if (stanzaData.getAwipsType == "default" && stanzaData.hasVTEC && stanzaData.isCap) {
|
|
117
|
-
events_1.default.newCapAlerts(stanzaData);
|
|
118
|
-
} // Default alert - CAP Only
|
|
119
|
-
if (stanzaData.getAwipsType == "default" && stanzaData.hasVTEC && !stanzaData.isCap) {
|
|
120
|
-
events_1.default.newRawAlerts(stanzaData);
|
|
121
|
-
} // Default alert - NonCAP
|
|
122
|
-
if (stanzaData.getAwipsType == "special-weather-statement") {
|
|
123
|
-
events_1.default.newSpecialWeatherStatement(stanzaData);
|
|
124
|
-
} // SPW (Special Weather Statement)
|
|
125
|
-
if (stanzaData.getAwipsType == "mesoscale-discussion") {
|
|
126
|
-
events_1.default.newMesoscaleDiscussion(stanzaData);
|
|
127
|
-
} // MD (Mesoscale Discussion)
|
|
128
|
-
if (stanzaData.getAwipsType == "local-storm-report") {
|
|
129
|
-
events_1.default.newLocalStormReport(stanzaData);
|
|
130
|
-
} // LSR (Local Storm Report)
|
|
131
|
-
};
|
|
132
|
-
/**
|
|
133
|
-
* @function saveToCache
|
|
134
|
-
* @description Saves the weather alert stanza to a cache file for record-keeping and debugging purposes.
|
|
135
|
-
*
|
|
136
|
-
* @param {any} stanzaData - The weather alert stanza data to be saved.
|
|
137
|
-
*/
|
|
138
|
-
mStanza.saveToCache = function (stanzaData) {
|
|
139
|
-
if (!loader.settings.cacheSettings.cacheDir)
|
|
140
|
-
return;
|
|
141
|
-
stanzaData.message = stanzaData.message.replace(/\$\$/g, "\nISSUED TIME...".concat(new Date().toISOString(), "\n$$$\n"));
|
|
142
|
-
loader.packages.fs.appendFileSync("".concat(loader.settings.cacheSettings.cacheDir, "/category-").concat(stanzaData.getAwipsType, "s-").concat(stanzaData.isCap ? "cap" : "raw").concat(stanzaData.hasVTEC ? "-vtec" : "", ".bin"), "=================================================\n".concat(new Date().toISOString().replace(/[:.]/g, '-'), "\n=================================================\n").concat(stanzaData.message), 'utf8');
|
|
143
|
-
};
|
|
144
|
-
return mStanza;
|
|
145
|
-
}());
|
|
146
|
-
exports.mStanza = mStanza;
|
|
147
|
-
exports.default = mStanza;
|