@atmosx/event-product-parser 3.0.3 → 3.0.41
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 +11 -1
- package/dist/cjs/index.cjs +62 -59
- package/dist/esm/index.mjs +62 -59
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/package.json +5 -3
- package/src/@building/building.office.ts +1 -1
- package/src/@building/building.signature.ts +1 -1
- package/src/@building/building.tracking.ts +5 -5
- package/src/@building/building.validate.ts +1 -3
- package/src/@core/core.start.ts +3 -3
- package/src/@dictionaries/dictionaries.officeICAOs.ts +2 -0
- package/src/{@modules/@utilities/utilities.createWebhook.ts → @manager/manager.createWebhook.ts} +11 -9
- package/src/@manager/manager.mkEvent.ts +5 -12
- package/src/@manager/manager.setHash.ts +1 -1
- package/src/@manager/manager.updateWebhooks.ts +1 -1
- package/src/@modules/@utilities/utilities.setTimeoutAction.ts +1 -1
- package/src/@modules/@utilities/utilities.setWarning.ts +2 -2
- package/src/@modules/@xmpp/xmpp.xReconnect.ts +1 -1
- package/src/@parsers/@pvtec/pvtec.extract.ts +1 -1
- package/src/@parsers/@ugc/ugc.coordinates.ts +2 -2
- package/src/bootstrap.ts +1 -1
- package/src/index.ts +3 -3
package/README.md
CHANGED
|
@@ -153,6 +153,17 @@ const Client = new Manager({
|
|
|
153
153
|
|
|
154
154
|
## Events and Listeners
|
|
155
155
|
|
|
156
|
+
### Event `*`
|
|
157
|
+
Triggers for every event and product received by the parser. This is useful if you want to handle all events with a single listener.
|
|
158
|
+
```ts
|
|
159
|
+
Client.on(`*`, (data: any) => {
|
|
160
|
+
/*
|
|
161
|
+
event: string
|
|
162
|
+
data: object
|
|
163
|
+
*/
|
|
164
|
+
})
|
|
165
|
+
```
|
|
166
|
+
|
|
156
167
|
### Event `onServiceStatus`
|
|
157
168
|
Triggers when an update to the XMPP / API service status occurs.
|
|
158
169
|
```ts
|
|
@@ -333,7 +344,6 @@ await setEasTone(event.properties.description, event.properties.metadata.header)
|
|
|
333
344
|
[Contributing](/CONTRIBUTING.md) |
|
|
334
345
|
[License](/LICENSE) |
|
|
335
346
|
[Security](/SECURITY.md) |
|
|
336
|
-
[Changelogs](/CHANGELOGS.md) |
|
|
337
347
|
|
|
338
348
|
## Acknowledgements
|
|
339
349
|
- [k3yomi](https://github.com/k3yomi)
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -10509,7 +10509,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
10509
10509
|
var import_path = __toESM(require("path"));
|
|
10510
10510
|
var import_node_events = require("events");
|
|
10511
10511
|
var bootstrap = {
|
|
10512
|
-
version: `3.0.
|
|
10512
|
+
version: `3.0.41`,
|
|
10513
10513
|
isReady: true,
|
|
10514
10514
|
ratelimits: {},
|
|
10515
10515
|
session_xmpp: null,
|
|
@@ -10623,6 +10623,7 @@ var getSettings = () => {
|
|
|
10623
10623
|
// src/@parsers/@ugc/ugc.coordinates.ts
|
|
10624
10624
|
var import_polygon_clipping = require("polygon-clipping");
|
|
10625
10625
|
var getZonePolygon = (options) => {
|
|
10626
|
+
var _a, _b;
|
|
10626
10627
|
const list = [...new Set(options.zones.map((z) => z.trim()))].filter((z) => z === "XX000" ? false : true);
|
|
10627
10628
|
if (list.length === 0) return null;
|
|
10628
10629
|
const placeholders = list.map(() => "?").join(",");
|
|
@@ -10658,7 +10659,7 @@ var getZonePolygon = (options) => {
|
|
|
10658
10659
|
}
|
|
10659
10660
|
if (!bestPoly || bestPoly.length === 0) return null;
|
|
10660
10661
|
const outerRing = bestPoly[0];
|
|
10661
|
-
const skip = Math.max(1, parseInt(String(bootstrap.settings.GlobalSettings.ShapefileSkipPoints), 10)
|
|
10662
|
+
const skip = Math.max(1, (_a = parseInt(String(bootstrap.settings.GlobalSettings.ShapefileSkipPoints), 10)) != null ? _a : 1);
|
|
10662
10663
|
let skipped = outerRing.filter((_, idx) => idx % skip === 0);
|
|
10663
10664
|
if (skipped.length < 4) {
|
|
10664
10665
|
skipped = outerRing.slice();
|
|
@@ -10677,7 +10678,7 @@ var getZonePolygon = (options) => {
|
|
|
10677
10678
|
}
|
|
10678
10679
|
}
|
|
10679
10680
|
if (multi.length === 0) return null;
|
|
10680
|
-
const skip = Math.max(1, parseInt(String(bootstrap.settings.GlobalSettings.ShapefileSkipPoints), 10)
|
|
10681
|
+
const skip = Math.max(1, (_b = parseInt(String(bootstrap.settings.GlobalSettings.ShapefileSkipPoints), 10)) != null ? _b : 1);
|
|
10681
10682
|
if (skip > 1) {
|
|
10682
10683
|
for (let p = 0; p < multi.length; p++) {
|
|
10683
10684
|
for (let r = 0; r < multi[p].length; r++) {
|
|
@@ -10734,7 +10735,7 @@ var getCleanedEvent = (event) => {
|
|
|
10734
10735
|
|
|
10735
10736
|
// src/@modules/@utilities/utilities.setTimeoutAction.ts
|
|
10736
10737
|
var setTimeoutAction = (options) => {
|
|
10737
|
-
var _a, _b;
|
|
10738
|
+
var _a, _b, _c;
|
|
10738
10739
|
let target = (_b = (_a = bootstrap) == null ? void 0 : _a.ratelimits) == null ? void 0 : _b[options == null ? void 0 : options.identifier];
|
|
10739
10740
|
if (!target) {
|
|
10740
10741
|
bootstrap.ratelimits[options == null ? void 0 : options.identifier] = [];
|
|
@@ -10746,7 +10747,7 @@ var setTimeoutAction = (options) => {
|
|
|
10746
10747
|
}
|
|
10747
10748
|
const oldestTimestamp = target == null ? void 0 : target[0];
|
|
10748
10749
|
const getWait = oldestTimestamp ? Math.ceil((options == null ? void 0 : options.interval) * 1e3 - (Date.now() - oldestTimestamp)) : 0;
|
|
10749
|
-
const max = (options == null ? void 0 : options.max)
|
|
10750
|
+
const max = (_c = options == null ? void 0 : options.max) != null ? _c : 1;
|
|
10750
10751
|
if ((target == null ? void 0 : target.length) >= max && getWait > 0) {
|
|
10751
10752
|
return {
|
|
10752
10753
|
limited: true,
|
|
@@ -10762,9 +10763,9 @@ var setTimeoutAction = (options) => {
|
|
|
10762
10763
|
var setWarning = (options) => {
|
|
10763
10764
|
var _a, _b;
|
|
10764
10765
|
const settings = bootstrap.settings;
|
|
10765
|
-
bootstrap.listener.emit(`log`, `${(_a = options.title) != null ? _a : `[${bootstrap.ansi_colors.YELLOW}
|
|
10766
|
+
bootstrap.listener.emit(`log`, `${(_a = options.title) != null ? _a : `[${bootstrap.ansi_colors.YELLOW}@atmosx/product-parser${bootstrap.ansi_colors.RESET}]`} ${options.message}`);
|
|
10766
10767
|
if (settings.EnableJournal) {
|
|
10767
|
-
console.log(`${(_b = options.title) != null ? _b : `[${bootstrap.ansi_colors.YELLOW}
|
|
10768
|
+
console.log(`${(_b = options.title) != null ? _b : `[${bootstrap.ansi_colors.YELLOW}@atmosx/product-parser${bootstrap.ansi_colors.RESET}]`} ${options.message}`);
|
|
10768
10769
|
}
|
|
10769
10770
|
};
|
|
10770
10771
|
|
|
@@ -14078,6 +14079,7 @@ var getTextFromProduct = (options) => {
|
|
|
14078
14079
|
|
|
14079
14080
|
// src/@dictionaries/dictionaries.officeICAOs.ts
|
|
14080
14081
|
var officeICAOs = {
|
|
14082
|
+
"KLUB": "Lubbock, TX",
|
|
14081
14083
|
"KLCH": "Lake Charles, LA",
|
|
14082
14084
|
"TSTL": "St. Louis, MO",
|
|
14083
14085
|
"PABC": "Bethel, AK",
|
|
@@ -14313,14 +14315,15 @@ var officeICAOs = {
|
|
|
14313
14315
|
"KCAR": "Caribou, ME",
|
|
14314
14316
|
"KMFR": "Medford, OR",
|
|
14315
14317
|
"PGUM": "Guam, GU",
|
|
14318
|
+
"PACR": "Cordova, AK",
|
|
14316
14319
|
"PAJK": "Juneau, AK"
|
|
14317
14320
|
};
|
|
14318
14321
|
|
|
14319
14322
|
// src/@building/building.office.ts
|
|
14320
14323
|
var getEventOffice = (options) => {
|
|
14321
|
-
var _a, _b, _c, _d, _e, _f;
|
|
14322
|
-
const office = options.pVtec != null ? (_b = (_a = options.pVtec) == null ? void 0 : _a.tracking) == null ? void 0 : _b.split(`-`)[0] : ((_c = options.attributes) == null ? void 0 : _c.cccc)
|
|
14323
|
-
const name = (
|
|
14324
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
14325
|
+
const office = options.pVtec != null ? (_b = (_a = options.pVtec) == null ? void 0 : _a.tracking) == null ? void 0 : _b.split(`-`)[0] : (_e = (_c = options.attributes) == null ? void 0 : _c.cccc) != null ? _e : options.organization != null ? Array.isArray(options.organization) ? (_d = options.organization) == null ? void 0 : _d[0] : options.organization : null;
|
|
14326
|
+
const name = (_g = (_f = officeICAOs) == null ? void 0 : _f[office]) != null ? _g : null;
|
|
14324
14327
|
return { office, name };
|
|
14325
14328
|
};
|
|
14326
14329
|
|
|
@@ -14496,9 +14499,9 @@ var getEventTracking = (options) => {
|
|
|
14496
14499
|
if (options.type === `RAW`) {
|
|
14497
14500
|
const getWatchNumber = (_a = proprties.watch_parameters.watch_number) != null ? _a : null;
|
|
14498
14501
|
if (getWatchNumber) {
|
|
14499
|
-
return `${proprties.geocode.office.office}
|
|
14502
|
+
return `${proprties.geocode.office.office}.${stanza.getType.prefix}.A.${getWatchNumber}`;
|
|
14500
14503
|
}
|
|
14501
|
-
return `${proprties.geocode.office.office}
|
|
14504
|
+
return `${proprties.geocode.office.office}.${attributes.ttaaii}.${(_b = attributes.id.slice(-4).replace(`.`, ``)) != null ? _b : "0"}`;
|
|
14502
14505
|
}
|
|
14503
14506
|
if (options.type === `VTEC`) {
|
|
14504
14507
|
return vtec2.tracking;
|
|
@@ -14507,16 +14510,16 @@ var getEventTracking = (options) => {
|
|
|
14507
14510
|
if (options.vtec) {
|
|
14508
14511
|
const vtecValue = Array.isArray(options.vtec) ? options.vtec[0] : options.vtec;
|
|
14509
14512
|
const splitPVTEC = vtecValue.split(".");
|
|
14510
|
-
return `${splitPVTEC[2]}
|
|
14513
|
+
return `${splitPVTEC[2]}.${splitPVTEC[3]}.${splitPVTEC[4]}.${splitPVTEC[5]}`;
|
|
14511
14514
|
}
|
|
14512
14515
|
const wmoMatch = (_d = (_c = options.organization) == null ? void 0 : _c.wmoidentifier) == null ? void 0 : _d.match(/([A-Z]{4}\d{2})\s+([A-Z]{4})/);
|
|
14513
14516
|
const station = (_e = wmoMatch == null ? void 0 : wmoMatch[2]) != null ? _e : "N/A";
|
|
14514
14517
|
if (options.organization.featureId) {
|
|
14515
14518
|
const idMatch = options.organization.featureId.match(/([a-f0-9]+)\.(\d+)\.(\d+)$/);
|
|
14516
|
-
return `${station}
|
|
14519
|
+
return `${station}.${(_f = idMatch == null ? void 0 : idMatch[1]) != null ? _f : "N/A"}`;
|
|
14517
14520
|
}
|
|
14518
14521
|
const id2 = (_g = wmoMatch == null ? void 0 : wmoMatch[1]) != null ? _g : "N/A";
|
|
14519
|
-
return `${station}
|
|
14522
|
+
return `${station}.${id2}`;
|
|
14520
14523
|
}
|
|
14521
14524
|
};
|
|
14522
14525
|
|
|
@@ -14712,8 +14715,8 @@ var getEventSignature = (event) => {
|
|
|
14712
14715
|
const getProduct = (_f = (_e = vtec2 == null ? void 0 : vtec2.vtec) == null ? void 0 : _e.split(`.`)[0]) == null ? void 0 : _f.replace(`/`, ``);
|
|
14713
14716
|
const isTestProduct = eventProducts[getProduct] == `Test Product`;
|
|
14714
14717
|
if (isTestProduct || testSignatures.some((sig) => {
|
|
14715
|
-
var _a2, _b2, _c2;
|
|
14716
|
-
return ((_a2 = properties2.description) == null ? void 0 : _a2.toLowerCase().includes(sig.toLowerCase()))
|
|
14718
|
+
var _a2, _b2, _c2, _d2;
|
|
14719
|
+
return (_d2 = (_a2 = properties2.description) == null ? void 0 : _a2.toLowerCase().includes(sig.toLowerCase())) != null ? _d2 : (_c2 = (_b2 = properties2 == null ? void 0 : properties2.parameters) == null ? void 0 : _b2.instructions) == null ? void 0 : _c2.toLowerCase().includes(sig.toLowerCase());
|
|
14717
14720
|
})) {
|
|
14718
14721
|
properties2.status_metadata = __spreadProps(__spreadValues({}, properties2.status_metadata), { is_test: true });
|
|
14719
14722
|
}
|
|
@@ -14725,7 +14728,7 @@ var getEventSignature = (event) => {
|
|
|
14725
14728
|
};
|
|
14726
14729
|
|
|
14727
14730
|
// src/@manager/manager.setHash.ts
|
|
14728
|
-
var setHash = (event, entry) =>
|
|
14731
|
+
var setHash = (event, entry) => {
|
|
14729
14732
|
if (entry) {
|
|
14730
14733
|
entry.hashes.push(event.properties.metadata.hash);
|
|
14731
14734
|
entry.expires = event.properties.expires;
|
|
@@ -14736,7 +14739,7 @@ var setHash = (event, entry) => __async(null, null, function* () {
|
|
|
14736
14739
|
expires: event.properties.expires
|
|
14737
14740
|
});
|
|
14738
14741
|
}
|
|
14739
|
-
}
|
|
14742
|
+
};
|
|
14740
14743
|
|
|
14741
14744
|
// src/@modules/@utilities/utilities.createHttp.ts
|
|
14742
14745
|
var import_request = __toESM(require("request"));
|
|
@@ -14796,10 +14799,10 @@ var createHttp = (options) => __async(null, null, function* () {
|
|
|
14796
14799
|
});
|
|
14797
14800
|
});
|
|
14798
14801
|
|
|
14799
|
-
// src/@
|
|
14802
|
+
// src/@manager/manager.createWebhook.ts
|
|
14800
14803
|
var import_form_data = __toESM(require_form_data());
|
|
14801
14804
|
var createWebhook = (options) => __async(null, null, function* () {
|
|
14802
|
-
var _a, _b, _c, _d;
|
|
14805
|
+
var _a, _b, _c, _d, _e, _f;
|
|
14803
14806
|
const event = options.event.properties;
|
|
14804
14807
|
const settings = options.webhook;
|
|
14805
14808
|
let body = [
|
|
@@ -14817,7 +14820,7 @@ var createWebhook = (options) => __async(null, null, function* () {
|
|
|
14817
14820
|
var _a2, _b2;
|
|
14818
14821
|
const val = (_a2 = event.parameters.estimated_hail_size) != null ? _a2 : null;
|
|
14819
14822
|
const th = (_b2 = event.parameters.hail_threat) != null ? _b2 : null;
|
|
14820
|
-
return val
|
|
14823
|
+
return (val != null ? val : th) ? `**Hail Threat**: ${val} ${th ? `(${th})` : ""}` : null;
|
|
14821
14824
|
})(),
|
|
14822
14825
|
event.parameters.damage_threat ? `**Damage Threat**: ${event.parameters.damage_threat}` : null,
|
|
14823
14826
|
event.parameters.flood_threat ? `**Flood Threat**: ${event.parameters.flood_threat}` : null,
|
|
@@ -14838,14 +14841,19 @@ var createWebhook = (options) => __async(null, null, function* () {
|
|
|
14838
14841
|
event.watch_parameters.max_tops_x100feet ? `**Max Tops (x100 feet)**: ${event.watch_parameters.max_tops_x100feet}` : null,
|
|
14839
14842
|
((_a = event.parameters.tags) == null ? void 0 : _a.length) > 0 ? `**Tags**: ${event.parameters.tags.join(", ")}` : null,
|
|
14840
14843
|
(() => {
|
|
14841
|
-
var _a2, _b2, _c2, _d2,
|
|
14844
|
+
var _a2, _b2, _c2, _d2, _e2, _f2;
|
|
14842
14845
|
const val = (_c2 = (_b2 = (_a2 = event.geocode) == null ? void 0 : _a2.office) == null ? void 0 : _b2.name) != null ? _c2 : `N/A`;
|
|
14843
|
-
const th = (
|
|
14844
|
-
return val
|
|
14846
|
+
const th = (_f2 = (_e2 = (_d2 = event.geocode) == null ? void 0 : _d2.office) == null ? void 0 : _e2.office) != null ? _f2 : null;
|
|
14847
|
+
return (val != null ? val : th) ? `**Sender**: ${val} ${th ? `(${th})` : ""}` : null;
|
|
14845
14848
|
})(),
|
|
14846
14849
|
((_b = event.metadata) == null ? void 0 : _b.tracking) ? `**Tracking**: ${event.metadata.tracking}` : null,
|
|
14850
|
+
((_c = event.metadata.history) == null ? void 0 : _c.length) > 0 ? `**Updates**: ${event.metadata.history.length}` : null,
|
|
14847
14851
|
(() => {
|
|
14848
|
-
|
|
14852
|
+
var _a2;
|
|
14853
|
+
if (event.status == `expires`) {
|
|
14854
|
+
return null;
|
|
14855
|
+
}
|
|
14856
|
+
const desc = ((_a2 = event.description) != null ? _a2 : "").split("\n").map((l) => l.trim()).filter(Boolean).join("\n");
|
|
14849
14857
|
return desc ? "```\n" + desc + "\n```" : null;
|
|
14850
14858
|
})()
|
|
14851
14859
|
].filter(Boolean).join("\n");
|
|
@@ -14855,7 +14863,7 @@ var createWebhook = (options) => __async(null, null, function* () {
|
|
|
14855
14863
|
}
|
|
14856
14864
|
if (body.length > 1900) {
|
|
14857
14865
|
body = body.substring(0, 1900) + "\n\n[Message truncated due to length]";
|
|
14858
|
-
const blocks = (body.match(/```/g)
|
|
14866
|
+
const blocks = ((_d = body.match(/```/g)) != null ? _d : []).length;
|
|
14859
14867
|
if (blocks % 2 !== 0) body += "```";
|
|
14860
14868
|
}
|
|
14861
14869
|
const form = new import_form_data.default();
|
|
@@ -14867,8 +14875,8 @@ var createWebhook = (options) => __async(null, null, function* () {
|
|
|
14867
14875
|
footer: { text: settings.title }
|
|
14868
14876
|
};
|
|
14869
14877
|
form.append("payload_json", JSON.stringify({
|
|
14870
|
-
username: (
|
|
14871
|
-
content: (
|
|
14878
|
+
username: (_e = settings.title) != null ? _e : "AtmosphericX",
|
|
14879
|
+
content: (_f = settings.message) != null ? _f : "",
|
|
14872
14880
|
embeds: [embed]
|
|
14873
14881
|
}));
|
|
14874
14882
|
if (settings.upload) {
|
|
@@ -15080,22 +15088,16 @@ var updateNode = (selectedEvent) => __async(null, null, function* () {
|
|
|
15080
15088
|
|
|
15081
15089
|
// src/@manager/manager.mkEvent.ts
|
|
15082
15090
|
var mkEvent = (event) => __async(null, null, function* () {
|
|
15083
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w
|
|
15091
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w;
|
|
15084
15092
|
const settings = bootstrap.settings;
|
|
15085
15093
|
const features = bootstrap.cache.events.features;
|
|
15086
|
-
const map2 = /* @__PURE__ */ new Map();
|
|
15087
|
-
for (const f of features) {
|
|
15088
|
-
const key = (_b = (_a = f == null ? void 0 : f.properties) == null ? void 0 : _a.metadata) == null ? void 0 : _b.tracking;
|
|
15089
|
-
if (!key) continue;
|
|
15090
|
-
map2.set(key, f);
|
|
15091
|
-
}
|
|
15092
15094
|
const getHash = event.properties.metadata.hash;
|
|
15093
15095
|
const getTracking = event.properties.metadata.tracking;
|
|
15094
|
-
const isEntry = (
|
|
15095
|
-
const isHashed = (
|
|
15096
|
-
const getFeature =
|
|
15096
|
+
const isEntry = (_a = bootstrap.cache.hashes) == null ? void 0 : _a.find((hash) => hash.tracking === getTracking);
|
|
15097
|
+
const isHashed = (_c = (_b = isEntry == null ? void 0 : isEntry.hashes) == null ? void 0 : _b.includes(getHash)) != null ? _c : false;
|
|
15098
|
+
const getFeature = features.find((feature) => feature.properties.metadata.tracking === getTracking);
|
|
15097
15099
|
if (isHashed || event.properties.status_metadata.is_expired) return;
|
|
15098
|
-
|
|
15100
|
+
setHash(event, isEntry);
|
|
15099
15101
|
const isFilteredLocation = yield updateNode(event).then(() => event.properties.metadata.filtered_proximity);
|
|
15100
15102
|
if (!isFilteredLocation && settings.GlobalSettings.EventFiltering.NodeLocationFiltering) {
|
|
15101
15103
|
return;
|
|
@@ -15112,32 +15114,33 @@ var mkEvent = (event) => __async(null, null, function* () {
|
|
|
15112
15114
|
if (event.properties.status_metadata.is_issued || event.properties.status_metadata.is_updated) {
|
|
15113
15115
|
if (getFeature) {
|
|
15114
15116
|
const getIndex = features.indexOf(getFeature);
|
|
15115
|
-
const cHistory = (
|
|
15116
|
-
const cLocations = (
|
|
15117
|
-
const cUgc = (
|
|
15118
|
-
const iHistory = (
|
|
15119
|
-
const iLocations = (
|
|
15120
|
-
const iUgc = (
|
|
15117
|
+
const cHistory = (_f = (_e = (_d = getFeature == null ? void 0 : getFeature.properties) == null ? void 0 : _d.metadata) == null ? void 0 : _e.history) != null ? _f : [];
|
|
15118
|
+
const cLocations = (_i = (_h = (_g = getFeature == null ? void 0 : getFeature.properties) == null ? void 0 : _g.locations) == null ? void 0 : _h.split(";").map((l) => l.trim())) != null ? _i : [];
|
|
15119
|
+
const cUgc = (_l = (_k = (_j = getFeature == null ? void 0 : getFeature.properties) == null ? void 0 : _j.geocode) == null ? void 0 : _k.ugc) != null ? _l : [];
|
|
15120
|
+
const iHistory = (_o = (_n = (_m = event.properties) == null ? void 0 : _m.metadata) == null ? void 0 : _n.history) != null ? _o : [];
|
|
15121
|
+
const iLocations = (_r = (_q = (_p = event.properties) == null ? void 0 : _p.locations) == null ? void 0 : _q.split(";").map((l) => l.trim())) != null ? _r : [];
|
|
15122
|
+
const iUgc = (_u = (_t = (_s = event.properties) == null ? void 0 : _s.geocode) == null ? void 0 : _t.ugc) != null ? _u : [];
|
|
15121
15123
|
const mHistory = [...cHistory, ...iHistory].filter((v, i, a) => a.indexOf(v) === i);
|
|
15122
15124
|
const mLocations = [...cLocations, ...iLocations].filter((v, i, a) => a.indexOf(v) === i).join("; ");
|
|
15123
15125
|
const mUgc = [...cUgc, ...iUgc].filter((v, i, a) => a.indexOf(v) === i);
|
|
15124
15126
|
bootstrap.cache.events.features[getIndex] = __spreadProps(__spreadValues({}, event), {
|
|
15125
15127
|
properties: __spreadProps(__spreadValues({}, event.properties), {
|
|
15126
|
-
metadata: __spreadProps(__spreadValues({}, (
|
|
15128
|
+
metadata: __spreadProps(__spreadValues({}, (_v = event == null ? void 0 : event.properties) == null ? void 0 : _v.metadata), {
|
|
15127
15129
|
history: mHistory
|
|
15128
15130
|
}),
|
|
15129
15131
|
locations: mLocations,
|
|
15130
|
-
geocode: __spreadProps(__spreadValues({}, (
|
|
15132
|
+
geocode: __spreadProps(__spreadValues({}, (_w = event == null ? void 0 : event.properties) == null ? void 0 : _w.geocode), {
|
|
15131
15133
|
ugc: mUgc
|
|
15132
15134
|
})
|
|
15133
15135
|
})
|
|
15134
15136
|
});
|
|
15137
|
+
updateWebhooks(bootstrap.cache.events.features[getIndex]);
|
|
15135
15138
|
} else {
|
|
15136
15139
|
features.push(event);
|
|
15140
|
+
updateWebhooks(event);
|
|
15137
15141
|
}
|
|
15138
15142
|
}
|
|
15139
15143
|
}
|
|
15140
|
-
updateWebhooks(event);
|
|
15141
15144
|
});
|
|
15142
15145
|
|
|
15143
15146
|
// src/@manager/manager.rmEvent.ts
|
|
@@ -15199,7 +15202,7 @@ var validateEvents = (events) => __async(null, null, function* () {
|
|
|
15199
15202
|
delete filteredProperties.metadata.ms;
|
|
15200
15203
|
}
|
|
15201
15204
|
filteredProperties.metadata = (_a2 = filteredProperties.metadata) != null ? _a2 : {};
|
|
15202
|
-
|
|
15205
|
+
properties2.metadata.hash = (0, import_crypto.createHash)("sha256").update(JSON.stringify(filteredProperties)).digest("hex");
|
|
15203
15206
|
setEventEmit({ event: `onProductType${enhancedEventName.replace(/\s+/g, "")}`, metadata: define2 });
|
|
15204
15207
|
if (properties2.status_metadata.is_test) {
|
|
15205
15208
|
setEventEmit({ event: `onTestProduct`, metadata: define2 });
|
|
@@ -15586,7 +15589,7 @@ var pvExtract = (message) => {
|
|
|
15586
15589
|
vtecs.push({
|
|
15587
15590
|
vtec: vtec2,
|
|
15588
15591
|
product: eventProducts[sub[0]],
|
|
15589
|
-
tracking: `${sub[2]}
|
|
15592
|
+
tracking: `${sub[2]}.${sub[3]}.${sub[4]}.${sub[5]}`,
|
|
15590
15593
|
event: `${eventTypes[sub[3]]} ${eventActions[sub[4]]}`,
|
|
15591
15594
|
status: eventStatus[sub[1]],
|
|
15592
15595
|
organization: (_d = (_c = message.match(regExp.wmo)) == null ? void 0 : _c[0]) != null ? _d : null,
|
|
@@ -16049,7 +16052,7 @@ var xReconnect = (interval) => __async(null, null, function* () {
|
|
|
16049
16052
|
const settings = bootstrap.settings;
|
|
16050
16053
|
const lastStanza = Date.now() - bootstrap.cache.lastStanza;
|
|
16051
16054
|
if (interval < 15) {
|
|
16052
|
-
setWarning({ message: `Reconnection
|
|
16055
|
+
setWarning({ message: `Reconnection interval of ${interval} seconds is too low, setting to 15 seconds` });
|
|
16053
16056
|
interval = 15;
|
|
16054
16057
|
bootstrap.settings.NOAAWeatherWireServiceSettings.ReconnectionSettings.ReconnectionInterval = 15;
|
|
16055
16058
|
}
|
|
@@ -16148,13 +16151,13 @@ var updateEvents = (selectedEvent) => __async(null, null, function* () {
|
|
|
16148
16151
|
|
|
16149
16152
|
// src/@core/core.start.ts
|
|
16150
16153
|
var import_croner = require("croner");
|
|
16151
|
-
var startService = (
|
|
16154
|
+
var startService = (configurations) => __async(null, null, function* () {
|
|
16152
16155
|
if (!bootstrap.isReady) {
|
|
16153
16156
|
return setWarning({
|
|
16154
16157
|
message: `You can not create another instance without shutting down the current one first, please make sure to call the stop() method first!`
|
|
16155
16158
|
});
|
|
16156
16159
|
}
|
|
16157
|
-
setSettings(
|
|
16160
|
+
const settings = setSettings(configurations);
|
|
16158
16161
|
bootstrap.isReady = true;
|
|
16159
16162
|
yield initializeDatabase();
|
|
16160
16163
|
if (settings.EnableWireService) {
|
|
@@ -16166,7 +16169,7 @@ var startService = (settings) => __async(null, null, function* () {
|
|
|
16166
16169
|
yield setCronSchedule();
|
|
16167
16170
|
let scheduleInterval = !settings.EnableWireService ? settings.NationalWeatherServiceSettings.CallbackInterval : 1;
|
|
16168
16171
|
if (!settings.EnableWireService && scheduleInterval < 15) {
|
|
16169
|
-
setWarning({ message: `Schedule
|
|
16172
|
+
setWarning({ message: `Schedule interval of ${scheduleInterval} seconds is too low, setting to 15 seconds` });
|
|
16170
16173
|
bootstrap.settings.NationalWeatherServiceSettings.CallbackInterval = 15;
|
|
16171
16174
|
scheduleInterval = 15;
|
|
16172
16175
|
}
|
|
@@ -16673,13 +16676,13 @@ var Manager = class {
|
|
|
16673
16676
|
}
|
|
16674
16677
|
trycatch() {
|
|
16675
16678
|
process.on("uncaughtException", (err) => {
|
|
16676
|
-
var _a;
|
|
16677
|
-
const ignored = ["ETIMEDOUT", "ECONNRESET", "EHOSTUNREACH", "STARTTLS_FAILURE"];
|
|
16679
|
+
var _a, _b;
|
|
16680
|
+
const ignored = ["ETIMEDOUT", "ECONNRESET", "EHOSTUNREACH", "ENOTFOUND", "ECONNREFUSED", "EPIPE", "EADDRINUSE", "EALREADY", "EACCES", "EAGAIN", "EHOSTDOWN", "STARTTLS_FAILURE"];
|
|
16678
16681
|
if (ignored.includes(err == null ? void 0 : err.code)) {
|
|
16679
16682
|
setEventEmit({
|
|
16680
16683
|
event: `onServiceStatus`,
|
|
16681
16684
|
metadata: {
|
|
16682
|
-
message: `
|
|
16685
|
+
message: `Ignored Critical Error: ${(_a = err == null ? void 0 : err.code) != null ? _a : "Unknown error code"}. This may indicate a connection issue. Attempting to continue...`,
|
|
16683
16686
|
data: {},
|
|
16684
16687
|
type: `error`,
|
|
16685
16688
|
error: true
|
|
@@ -16687,7 +16690,7 @@ var Manager = class {
|
|
|
16687
16690
|
});
|
|
16688
16691
|
return;
|
|
16689
16692
|
}
|
|
16690
|
-
setWarning({ message: `Uncaught Exception: ${err instanceof Error ? err.stack
|
|
16693
|
+
setWarning({ message: `Uncaught Exception: ${err instanceof Error ? (_b = err.stack) != null ? _b : err.message : String(err)}` });
|
|
16691
16694
|
});
|
|
16692
16695
|
}
|
|
16693
16696
|
};
|
package/dist/esm/index.mjs
CHANGED
|
@@ -10491,7 +10491,7 @@ var require_form_data = __commonJS({
|
|
|
10491
10491
|
import path from "path";
|
|
10492
10492
|
import { EventEmitter } from "events";
|
|
10493
10493
|
var bootstrap = {
|
|
10494
|
-
version: `3.0.
|
|
10494
|
+
version: `3.0.41`,
|
|
10495
10495
|
isReady: true,
|
|
10496
10496
|
ratelimits: {},
|
|
10497
10497
|
session_xmpp: null,
|
|
@@ -10605,6 +10605,7 @@ var getSettings = () => {
|
|
|
10605
10605
|
// src/@parsers/@ugc/ugc.coordinates.ts
|
|
10606
10606
|
import { union } from "polygon-clipping";
|
|
10607
10607
|
var getZonePolygon = (options) => {
|
|
10608
|
+
var _a, _b;
|
|
10608
10609
|
const list = [...new Set(options.zones.map((z) => z.trim()))].filter((z) => z === "XX000" ? false : true);
|
|
10609
10610
|
if (list.length === 0) return null;
|
|
10610
10611
|
const placeholders = list.map(() => "?").join(",");
|
|
@@ -10640,7 +10641,7 @@ var getZonePolygon = (options) => {
|
|
|
10640
10641
|
}
|
|
10641
10642
|
if (!bestPoly || bestPoly.length === 0) return null;
|
|
10642
10643
|
const outerRing = bestPoly[0];
|
|
10643
|
-
const skip = Math.max(1, parseInt(String(bootstrap.settings.GlobalSettings.ShapefileSkipPoints), 10)
|
|
10644
|
+
const skip = Math.max(1, (_a = parseInt(String(bootstrap.settings.GlobalSettings.ShapefileSkipPoints), 10)) != null ? _a : 1);
|
|
10644
10645
|
let skipped = outerRing.filter((_, idx) => idx % skip === 0);
|
|
10645
10646
|
if (skipped.length < 4) {
|
|
10646
10647
|
skipped = outerRing.slice();
|
|
@@ -10659,7 +10660,7 @@ var getZonePolygon = (options) => {
|
|
|
10659
10660
|
}
|
|
10660
10661
|
}
|
|
10661
10662
|
if (multi.length === 0) return null;
|
|
10662
|
-
const skip = Math.max(1, parseInt(String(bootstrap.settings.GlobalSettings.ShapefileSkipPoints), 10)
|
|
10663
|
+
const skip = Math.max(1, (_b = parseInt(String(bootstrap.settings.GlobalSettings.ShapefileSkipPoints), 10)) != null ? _b : 1);
|
|
10663
10664
|
if (skip > 1) {
|
|
10664
10665
|
for (let p = 0; p < multi.length; p++) {
|
|
10665
10666
|
for (let r = 0; r < multi[p].length; r++) {
|
|
@@ -10716,7 +10717,7 @@ var getCleanedEvent = (event) => {
|
|
|
10716
10717
|
|
|
10717
10718
|
// src/@modules/@utilities/utilities.setTimeoutAction.ts
|
|
10718
10719
|
var setTimeoutAction = (options) => {
|
|
10719
|
-
var _a, _b;
|
|
10720
|
+
var _a, _b, _c;
|
|
10720
10721
|
let target = (_b = (_a = bootstrap) == null ? void 0 : _a.ratelimits) == null ? void 0 : _b[options == null ? void 0 : options.identifier];
|
|
10721
10722
|
if (!target) {
|
|
10722
10723
|
bootstrap.ratelimits[options == null ? void 0 : options.identifier] = [];
|
|
@@ -10728,7 +10729,7 @@ var setTimeoutAction = (options) => {
|
|
|
10728
10729
|
}
|
|
10729
10730
|
const oldestTimestamp = target == null ? void 0 : target[0];
|
|
10730
10731
|
const getWait = oldestTimestamp ? Math.ceil((options == null ? void 0 : options.interval) * 1e3 - (Date.now() - oldestTimestamp)) : 0;
|
|
10731
|
-
const max = (options == null ? void 0 : options.max)
|
|
10732
|
+
const max = (_c = options == null ? void 0 : options.max) != null ? _c : 1;
|
|
10732
10733
|
if ((target == null ? void 0 : target.length) >= max && getWait > 0) {
|
|
10733
10734
|
return {
|
|
10734
10735
|
limited: true,
|
|
@@ -10744,9 +10745,9 @@ var setTimeoutAction = (options) => {
|
|
|
10744
10745
|
var setWarning = (options) => {
|
|
10745
10746
|
var _a, _b;
|
|
10746
10747
|
const settings = bootstrap.settings;
|
|
10747
|
-
bootstrap.listener.emit(`log`, `${(_a = options.title) != null ? _a : `[${bootstrap.ansi_colors.YELLOW}
|
|
10748
|
+
bootstrap.listener.emit(`log`, `${(_a = options.title) != null ? _a : `[${bootstrap.ansi_colors.YELLOW}@atmosx/product-parser${bootstrap.ansi_colors.RESET}]`} ${options.message}`);
|
|
10748
10749
|
if (settings.EnableJournal) {
|
|
10749
|
-
console.log(`${(_b = options.title) != null ? _b : `[${bootstrap.ansi_colors.YELLOW}
|
|
10750
|
+
console.log(`${(_b = options.title) != null ? _b : `[${bootstrap.ansi_colors.YELLOW}@atmosx/product-parser${bootstrap.ansi_colors.RESET}]`} ${options.message}`);
|
|
10750
10751
|
}
|
|
10751
10752
|
};
|
|
10752
10753
|
|
|
@@ -14060,6 +14061,7 @@ var getTextFromProduct = (options) => {
|
|
|
14060
14061
|
|
|
14061
14062
|
// src/@dictionaries/dictionaries.officeICAOs.ts
|
|
14062
14063
|
var officeICAOs = {
|
|
14064
|
+
"KLUB": "Lubbock, TX",
|
|
14063
14065
|
"KLCH": "Lake Charles, LA",
|
|
14064
14066
|
"TSTL": "St. Louis, MO",
|
|
14065
14067
|
"PABC": "Bethel, AK",
|
|
@@ -14295,14 +14297,15 @@ var officeICAOs = {
|
|
|
14295
14297
|
"KCAR": "Caribou, ME",
|
|
14296
14298
|
"KMFR": "Medford, OR",
|
|
14297
14299
|
"PGUM": "Guam, GU",
|
|
14300
|
+
"PACR": "Cordova, AK",
|
|
14298
14301
|
"PAJK": "Juneau, AK"
|
|
14299
14302
|
};
|
|
14300
14303
|
|
|
14301
14304
|
// src/@building/building.office.ts
|
|
14302
14305
|
var getEventOffice = (options) => {
|
|
14303
|
-
var _a, _b, _c, _d, _e, _f;
|
|
14304
|
-
const office = options.pVtec != null ? (_b = (_a = options.pVtec) == null ? void 0 : _a.tracking) == null ? void 0 : _b.split(`-`)[0] : ((_c = options.attributes) == null ? void 0 : _c.cccc)
|
|
14305
|
-
const name = (
|
|
14306
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
14307
|
+
const office = options.pVtec != null ? (_b = (_a = options.pVtec) == null ? void 0 : _a.tracking) == null ? void 0 : _b.split(`-`)[0] : (_e = (_c = options.attributes) == null ? void 0 : _c.cccc) != null ? _e : options.organization != null ? Array.isArray(options.organization) ? (_d = options.organization) == null ? void 0 : _d[0] : options.organization : null;
|
|
14308
|
+
const name = (_g = (_f = officeICAOs) == null ? void 0 : _f[office]) != null ? _g : null;
|
|
14306
14309
|
return { office, name };
|
|
14307
14310
|
};
|
|
14308
14311
|
|
|
@@ -14478,9 +14481,9 @@ var getEventTracking = (options) => {
|
|
|
14478
14481
|
if (options.type === `RAW`) {
|
|
14479
14482
|
const getWatchNumber = (_a = proprties.watch_parameters.watch_number) != null ? _a : null;
|
|
14480
14483
|
if (getWatchNumber) {
|
|
14481
|
-
return `${proprties.geocode.office.office}
|
|
14484
|
+
return `${proprties.geocode.office.office}.${stanza.getType.prefix}.A.${getWatchNumber}`;
|
|
14482
14485
|
}
|
|
14483
|
-
return `${proprties.geocode.office.office}
|
|
14486
|
+
return `${proprties.geocode.office.office}.${attributes.ttaaii}.${(_b = attributes.id.slice(-4).replace(`.`, ``)) != null ? _b : "0"}`;
|
|
14484
14487
|
}
|
|
14485
14488
|
if (options.type === `VTEC`) {
|
|
14486
14489
|
return vtec2.tracking;
|
|
@@ -14489,16 +14492,16 @@ var getEventTracking = (options) => {
|
|
|
14489
14492
|
if (options.vtec) {
|
|
14490
14493
|
const vtecValue = Array.isArray(options.vtec) ? options.vtec[0] : options.vtec;
|
|
14491
14494
|
const splitPVTEC = vtecValue.split(".");
|
|
14492
|
-
return `${splitPVTEC[2]}
|
|
14495
|
+
return `${splitPVTEC[2]}.${splitPVTEC[3]}.${splitPVTEC[4]}.${splitPVTEC[5]}`;
|
|
14493
14496
|
}
|
|
14494
14497
|
const wmoMatch = (_d = (_c = options.organization) == null ? void 0 : _c.wmoidentifier) == null ? void 0 : _d.match(/([A-Z]{4}\d{2})\s+([A-Z]{4})/);
|
|
14495
14498
|
const station = (_e = wmoMatch == null ? void 0 : wmoMatch[2]) != null ? _e : "N/A";
|
|
14496
14499
|
if (options.organization.featureId) {
|
|
14497
14500
|
const idMatch = options.organization.featureId.match(/([a-f0-9]+)\.(\d+)\.(\d+)$/);
|
|
14498
|
-
return `${station}
|
|
14501
|
+
return `${station}.${(_f = idMatch == null ? void 0 : idMatch[1]) != null ? _f : "N/A"}`;
|
|
14499
14502
|
}
|
|
14500
14503
|
const id2 = (_g = wmoMatch == null ? void 0 : wmoMatch[1]) != null ? _g : "N/A";
|
|
14501
|
-
return `${station}
|
|
14504
|
+
return `${station}.${id2}`;
|
|
14502
14505
|
}
|
|
14503
14506
|
};
|
|
14504
14507
|
|
|
@@ -14694,8 +14697,8 @@ var getEventSignature = (event) => {
|
|
|
14694
14697
|
const getProduct = (_f = (_e = vtec2 == null ? void 0 : vtec2.vtec) == null ? void 0 : _e.split(`.`)[0]) == null ? void 0 : _f.replace(`/`, ``);
|
|
14695
14698
|
const isTestProduct = eventProducts[getProduct] == `Test Product`;
|
|
14696
14699
|
if (isTestProduct || testSignatures.some((sig) => {
|
|
14697
|
-
var _a2, _b2, _c2;
|
|
14698
|
-
return ((_a2 = properties2.description) == null ? void 0 : _a2.toLowerCase().includes(sig.toLowerCase()))
|
|
14700
|
+
var _a2, _b2, _c2, _d2;
|
|
14701
|
+
return (_d2 = (_a2 = properties2.description) == null ? void 0 : _a2.toLowerCase().includes(sig.toLowerCase())) != null ? _d2 : (_c2 = (_b2 = properties2 == null ? void 0 : properties2.parameters) == null ? void 0 : _b2.instructions) == null ? void 0 : _c2.toLowerCase().includes(sig.toLowerCase());
|
|
14699
14702
|
})) {
|
|
14700
14703
|
properties2.status_metadata = __spreadProps(__spreadValues({}, properties2.status_metadata), { is_test: true });
|
|
14701
14704
|
}
|
|
@@ -14707,7 +14710,7 @@ var getEventSignature = (event) => {
|
|
|
14707
14710
|
};
|
|
14708
14711
|
|
|
14709
14712
|
// src/@manager/manager.setHash.ts
|
|
14710
|
-
var setHash = (event, entry) =>
|
|
14713
|
+
var setHash = (event, entry) => {
|
|
14711
14714
|
if (entry) {
|
|
14712
14715
|
entry.hashes.push(event.properties.metadata.hash);
|
|
14713
14716
|
entry.expires = event.properties.expires;
|
|
@@ -14718,7 +14721,7 @@ var setHash = (event, entry) => __async(null, null, function* () {
|
|
|
14718
14721
|
expires: event.properties.expires
|
|
14719
14722
|
});
|
|
14720
14723
|
}
|
|
14721
|
-
}
|
|
14724
|
+
};
|
|
14722
14725
|
|
|
14723
14726
|
// src/@modules/@utilities/utilities.createHttp.ts
|
|
14724
14727
|
import request from "request";
|
|
@@ -14778,10 +14781,10 @@ var createHttp = (options) => __async(null, null, function* () {
|
|
|
14778
14781
|
});
|
|
14779
14782
|
});
|
|
14780
14783
|
|
|
14781
|
-
// src/@
|
|
14784
|
+
// src/@manager/manager.createWebhook.ts
|
|
14782
14785
|
var import_form_data = __toESM(require_form_data());
|
|
14783
14786
|
var createWebhook = (options) => __async(null, null, function* () {
|
|
14784
|
-
var _a, _b, _c, _d;
|
|
14787
|
+
var _a, _b, _c, _d, _e, _f;
|
|
14785
14788
|
const event = options.event.properties;
|
|
14786
14789
|
const settings = options.webhook;
|
|
14787
14790
|
let body = [
|
|
@@ -14799,7 +14802,7 @@ var createWebhook = (options) => __async(null, null, function* () {
|
|
|
14799
14802
|
var _a2, _b2;
|
|
14800
14803
|
const val = (_a2 = event.parameters.estimated_hail_size) != null ? _a2 : null;
|
|
14801
14804
|
const th = (_b2 = event.parameters.hail_threat) != null ? _b2 : null;
|
|
14802
|
-
return val
|
|
14805
|
+
return (val != null ? val : th) ? `**Hail Threat**: ${val} ${th ? `(${th})` : ""}` : null;
|
|
14803
14806
|
})(),
|
|
14804
14807
|
event.parameters.damage_threat ? `**Damage Threat**: ${event.parameters.damage_threat}` : null,
|
|
14805
14808
|
event.parameters.flood_threat ? `**Flood Threat**: ${event.parameters.flood_threat}` : null,
|
|
@@ -14820,14 +14823,19 @@ var createWebhook = (options) => __async(null, null, function* () {
|
|
|
14820
14823
|
event.watch_parameters.max_tops_x100feet ? `**Max Tops (x100 feet)**: ${event.watch_parameters.max_tops_x100feet}` : null,
|
|
14821
14824
|
((_a = event.parameters.tags) == null ? void 0 : _a.length) > 0 ? `**Tags**: ${event.parameters.tags.join(", ")}` : null,
|
|
14822
14825
|
(() => {
|
|
14823
|
-
var _a2, _b2, _c2, _d2,
|
|
14826
|
+
var _a2, _b2, _c2, _d2, _e2, _f2;
|
|
14824
14827
|
const val = (_c2 = (_b2 = (_a2 = event.geocode) == null ? void 0 : _a2.office) == null ? void 0 : _b2.name) != null ? _c2 : `N/A`;
|
|
14825
|
-
const th = (
|
|
14826
|
-
return val
|
|
14828
|
+
const th = (_f2 = (_e2 = (_d2 = event.geocode) == null ? void 0 : _d2.office) == null ? void 0 : _e2.office) != null ? _f2 : null;
|
|
14829
|
+
return (val != null ? val : th) ? `**Sender**: ${val} ${th ? `(${th})` : ""}` : null;
|
|
14827
14830
|
})(),
|
|
14828
14831
|
((_b = event.metadata) == null ? void 0 : _b.tracking) ? `**Tracking**: ${event.metadata.tracking}` : null,
|
|
14832
|
+
((_c = event.metadata.history) == null ? void 0 : _c.length) > 0 ? `**Updates**: ${event.metadata.history.length}` : null,
|
|
14829
14833
|
(() => {
|
|
14830
|
-
|
|
14834
|
+
var _a2;
|
|
14835
|
+
if (event.status == `expires`) {
|
|
14836
|
+
return null;
|
|
14837
|
+
}
|
|
14838
|
+
const desc = ((_a2 = event.description) != null ? _a2 : "").split("\n").map((l) => l.trim()).filter(Boolean).join("\n");
|
|
14831
14839
|
return desc ? "```\n" + desc + "\n```" : null;
|
|
14832
14840
|
})()
|
|
14833
14841
|
].filter(Boolean).join("\n");
|
|
@@ -14837,7 +14845,7 @@ var createWebhook = (options) => __async(null, null, function* () {
|
|
|
14837
14845
|
}
|
|
14838
14846
|
if (body.length > 1900) {
|
|
14839
14847
|
body = body.substring(0, 1900) + "\n\n[Message truncated due to length]";
|
|
14840
|
-
const blocks = (body.match(/```/g)
|
|
14848
|
+
const blocks = ((_d = body.match(/```/g)) != null ? _d : []).length;
|
|
14841
14849
|
if (blocks % 2 !== 0) body += "```";
|
|
14842
14850
|
}
|
|
14843
14851
|
const form = new import_form_data.default();
|
|
@@ -14849,8 +14857,8 @@ var createWebhook = (options) => __async(null, null, function* () {
|
|
|
14849
14857
|
footer: { text: settings.title }
|
|
14850
14858
|
};
|
|
14851
14859
|
form.append("payload_json", JSON.stringify({
|
|
14852
|
-
username: (
|
|
14853
|
-
content: (
|
|
14860
|
+
username: (_e = settings.title) != null ? _e : "AtmosphericX",
|
|
14861
|
+
content: (_f = settings.message) != null ? _f : "",
|
|
14854
14862
|
embeds: [embed]
|
|
14855
14863
|
}));
|
|
14856
14864
|
if (settings.upload) {
|
|
@@ -15062,22 +15070,16 @@ var updateNode = (selectedEvent) => __async(null, null, function* () {
|
|
|
15062
15070
|
|
|
15063
15071
|
// src/@manager/manager.mkEvent.ts
|
|
15064
15072
|
var mkEvent = (event) => __async(null, null, function* () {
|
|
15065
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w
|
|
15073
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w;
|
|
15066
15074
|
const settings = bootstrap.settings;
|
|
15067
15075
|
const features = bootstrap.cache.events.features;
|
|
15068
|
-
const map2 = /* @__PURE__ */ new Map();
|
|
15069
|
-
for (const f of features) {
|
|
15070
|
-
const key = (_b = (_a = f == null ? void 0 : f.properties) == null ? void 0 : _a.metadata) == null ? void 0 : _b.tracking;
|
|
15071
|
-
if (!key) continue;
|
|
15072
|
-
map2.set(key, f);
|
|
15073
|
-
}
|
|
15074
15076
|
const getHash = event.properties.metadata.hash;
|
|
15075
15077
|
const getTracking = event.properties.metadata.tracking;
|
|
15076
|
-
const isEntry = (
|
|
15077
|
-
const isHashed = (
|
|
15078
|
-
const getFeature =
|
|
15078
|
+
const isEntry = (_a = bootstrap.cache.hashes) == null ? void 0 : _a.find((hash) => hash.tracking === getTracking);
|
|
15079
|
+
const isHashed = (_c = (_b = isEntry == null ? void 0 : isEntry.hashes) == null ? void 0 : _b.includes(getHash)) != null ? _c : false;
|
|
15080
|
+
const getFeature = features.find((feature) => feature.properties.metadata.tracking === getTracking);
|
|
15079
15081
|
if (isHashed || event.properties.status_metadata.is_expired) return;
|
|
15080
|
-
|
|
15082
|
+
setHash(event, isEntry);
|
|
15081
15083
|
const isFilteredLocation = yield updateNode(event).then(() => event.properties.metadata.filtered_proximity);
|
|
15082
15084
|
if (!isFilteredLocation && settings.GlobalSettings.EventFiltering.NodeLocationFiltering) {
|
|
15083
15085
|
return;
|
|
@@ -15094,32 +15096,33 @@ var mkEvent = (event) => __async(null, null, function* () {
|
|
|
15094
15096
|
if (event.properties.status_metadata.is_issued || event.properties.status_metadata.is_updated) {
|
|
15095
15097
|
if (getFeature) {
|
|
15096
15098
|
const getIndex = features.indexOf(getFeature);
|
|
15097
|
-
const cHistory = (
|
|
15098
|
-
const cLocations = (
|
|
15099
|
-
const cUgc = (
|
|
15100
|
-
const iHistory = (
|
|
15101
|
-
const iLocations = (
|
|
15102
|
-
const iUgc = (
|
|
15099
|
+
const cHistory = (_f = (_e = (_d = getFeature == null ? void 0 : getFeature.properties) == null ? void 0 : _d.metadata) == null ? void 0 : _e.history) != null ? _f : [];
|
|
15100
|
+
const cLocations = (_i = (_h = (_g = getFeature == null ? void 0 : getFeature.properties) == null ? void 0 : _g.locations) == null ? void 0 : _h.split(";").map((l) => l.trim())) != null ? _i : [];
|
|
15101
|
+
const cUgc = (_l = (_k = (_j = getFeature == null ? void 0 : getFeature.properties) == null ? void 0 : _j.geocode) == null ? void 0 : _k.ugc) != null ? _l : [];
|
|
15102
|
+
const iHistory = (_o = (_n = (_m = event.properties) == null ? void 0 : _m.metadata) == null ? void 0 : _n.history) != null ? _o : [];
|
|
15103
|
+
const iLocations = (_r = (_q = (_p = event.properties) == null ? void 0 : _p.locations) == null ? void 0 : _q.split(";").map((l) => l.trim())) != null ? _r : [];
|
|
15104
|
+
const iUgc = (_u = (_t = (_s = event.properties) == null ? void 0 : _s.geocode) == null ? void 0 : _t.ugc) != null ? _u : [];
|
|
15103
15105
|
const mHistory = [...cHistory, ...iHistory].filter((v, i, a) => a.indexOf(v) === i);
|
|
15104
15106
|
const mLocations = [...cLocations, ...iLocations].filter((v, i, a) => a.indexOf(v) === i).join("; ");
|
|
15105
15107
|
const mUgc = [...cUgc, ...iUgc].filter((v, i, a) => a.indexOf(v) === i);
|
|
15106
15108
|
bootstrap.cache.events.features[getIndex] = __spreadProps(__spreadValues({}, event), {
|
|
15107
15109
|
properties: __spreadProps(__spreadValues({}, event.properties), {
|
|
15108
|
-
metadata: __spreadProps(__spreadValues({}, (
|
|
15110
|
+
metadata: __spreadProps(__spreadValues({}, (_v = event == null ? void 0 : event.properties) == null ? void 0 : _v.metadata), {
|
|
15109
15111
|
history: mHistory
|
|
15110
15112
|
}),
|
|
15111
15113
|
locations: mLocations,
|
|
15112
|
-
geocode: __spreadProps(__spreadValues({}, (
|
|
15114
|
+
geocode: __spreadProps(__spreadValues({}, (_w = event == null ? void 0 : event.properties) == null ? void 0 : _w.geocode), {
|
|
15113
15115
|
ugc: mUgc
|
|
15114
15116
|
})
|
|
15115
15117
|
})
|
|
15116
15118
|
});
|
|
15119
|
+
updateWebhooks(bootstrap.cache.events.features[getIndex]);
|
|
15117
15120
|
} else {
|
|
15118
15121
|
features.push(event);
|
|
15122
|
+
updateWebhooks(event);
|
|
15119
15123
|
}
|
|
15120
15124
|
}
|
|
15121
15125
|
}
|
|
15122
|
-
updateWebhooks(event);
|
|
15123
15126
|
});
|
|
15124
15127
|
|
|
15125
15128
|
// src/@manager/manager.rmEvent.ts
|
|
@@ -15181,7 +15184,7 @@ var validateEvents = (events) => __async(null, null, function* () {
|
|
|
15181
15184
|
delete filteredProperties.metadata.ms;
|
|
15182
15185
|
}
|
|
15183
15186
|
filteredProperties.metadata = (_a2 = filteredProperties.metadata) != null ? _a2 : {};
|
|
15184
|
-
|
|
15187
|
+
properties2.metadata.hash = createHash("sha256").update(JSON.stringify(filteredProperties)).digest("hex");
|
|
15185
15188
|
setEventEmit({ event: `onProductType${enhancedEventName.replace(/\s+/g, "")}`, metadata: define2 });
|
|
15186
15189
|
if (properties2.status_metadata.is_test) {
|
|
15187
15190
|
setEventEmit({ event: `onTestProduct`, metadata: define2 });
|
|
@@ -15568,7 +15571,7 @@ var pvExtract = (message) => {
|
|
|
15568
15571
|
vtecs.push({
|
|
15569
15572
|
vtec: vtec2,
|
|
15570
15573
|
product: eventProducts[sub[0]],
|
|
15571
|
-
tracking: `${sub[2]}
|
|
15574
|
+
tracking: `${sub[2]}.${sub[3]}.${sub[4]}.${sub[5]}`,
|
|
15572
15575
|
event: `${eventTypes[sub[3]]} ${eventActions[sub[4]]}`,
|
|
15573
15576
|
status: eventStatus[sub[1]],
|
|
15574
15577
|
organization: (_d = (_c = message.match(regExp.wmo)) == null ? void 0 : _c[0]) != null ? _d : null,
|
|
@@ -16031,7 +16034,7 @@ var xReconnect = (interval) => __async(null, null, function* () {
|
|
|
16031
16034
|
const settings = bootstrap.settings;
|
|
16032
16035
|
const lastStanza = Date.now() - bootstrap.cache.lastStanza;
|
|
16033
16036
|
if (interval < 15) {
|
|
16034
|
-
setWarning({ message: `Reconnection
|
|
16037
|
+
setWarning({ message: `Reconnection interval of ${interval} seconds is too low, setting to 15 seconds` });
|
|
16035
16038
|
interval = 15;
|
|
16036
16039
|
bootstrap.settings.NOAAWeatherWireServiceSettings.ReconnectionSettings.ReconnectionInterval = 15;
|
|
16037
16040
|
}
|
|
@@ -16130,13 +16133,13 @@ var updateEvents = (selectedEvent) => __async(null, null, function* () {
|
|
|
16130
16133
|
|
|
16131
16134
|
// src/@core/core.start.ts
|
|
16132
16135
|
import { Cron } from "croner";
|
|
16133
|
-
var startService = (
|
|
16136
|
+
var startService = (configurations) => __async(null, null, function* () {
|
|
16134
16137
|
if (!bootstrap.isReady) {
|
|
16135
16138
|
return setWarning({
|
|
16136
16139
|
message: `You can not create another instance without shutting down the current one first, please make sure to call the stop() method first!`
|
|
16137
16140
|
});
|
|
16138
16141
|
}
|
|
16139
|
-
setSettings(
|
|
16142
|
+
const settings = setSettings(configurations);
|
|
16140
16143
|
bootstrap.isReady = true;
|
|
16141
16144
|
yield initializeDatabase();
|
|
16142
16145
|
if (settings.EnableWireService) {
|
|
@@ -16148,7 +16151,7 @@ var startService = (settings) => __async(null, null, function* () {
|
|
|
16148
16151
|
yield setCronSchedule();
|
|
16149
16152
|
let scheduleInterval = !settings.EnableWireService ? settings.NationalWeatherServiceSettings.CallbackInterval : 1;
|
|
16150
16153
|
if (!settings.EnableWireService && scheduleInterval < 15) {
|
|
16151
|
-
setWarning({ message: `Schedule
|
|
16154
|
+
setWarning({ message: `Schedule interval of ${scheduleInterval} seconds is too low, setting to 15 seconds` });
|
|
16152
16155
|
bootstrap.settings.NationalWeatherServiceSettings.CallbackInterval = 15;
|
|
16153
16156
|
scheduleInterval = 15;
|
|
16154
16157
|
}
|
|
@@ -16655,13 +16658,13 @@ var Manager = class {
|
|
|
16655
16658
|
}
|
|
16656
16659
|
trycatch() {
|
|
16657
16660
|
process.on("uncaughtException", (err) => {
|
|
16658
|
-
var _a;
|
|
16659
|
-
const ignored = ["ETIMEDOUT", "ECONNRESET", "EHOSTUNREACH", "STARTTLS_FAILURE"];
|
|
16661
|
+
var _a, _b;
|
|
16662
|
+
const ignored = ["ETIMEDOUT", "ECONNRESET", "EHOSTUNREACH", "ENOTFOUND", "ECONNREFUSED", "EPIPE", "EADDRINUSE", "EALREADY", "EACCES", "EAGAIN", "EHOSTDOWN", "STARTTLS_FAILURE"];
|
|
16660
16663
|
if (ignored.includes(err == null ? void 0 : err.code)) {
|
|
16661
16664
|
setEventEmit({
|
|
16662
16665
|
event: `onServiceStatus`,
|
|
16663
16666
|
metadata: {
|
|
16664
|
-
message: `
|
|
16667
|
+
message: `Ignored Critical Error: ${(_a = err == null ? void 0 : err.code) != null ? _a : "Unknown error code"}. This may indicate a connection issue. Attempting to continue...`,
|
|
16665
16668
|
data: {},
|
|
16666
16669
|
type: `error`,
|
|
16667
16670
|
error: true
|
|
@@ -16669,7 +16672,7 @@ var Manager = class {
|
|
|
16669
16672
|
});
|
|
16670
16673
|
return;
|
|
16671
16674
|
}
|
|
16672
|
-
setWarning({ message: `Uncaught Exception: ${err instanceof Error ? err.stack
|
|
16675
|
+
setWarning({ message: `Uncaught Exception: ${err instanceof Error ? (_b = err.stack) != null ? _b : err.message : String(err)}` });
|
|
16673
16676
|
});
|
|
16674
16677
|
}
|
|
16675
16678
|
};
|
package/dist/index.d.mts
CHANGED
|
@@ -202,7 +202,7 @@ declare const getEventGeometry: (event: TypeEvent) => Promise<GetGeometryRespons
|
|
|
202
202
|
|
|
203
203
|
declare const getCleanedEvent: <T extends Record<string, any>>(event: T) => T;
|
|
204
204
|
|
|
205
|
-
declare const startService: (
|
|
205
|
+
declare const startService: (configurations: TypeSettings) => Promise<void>;
|
|
206
206
|
|
|
207
207
|
declare const stopService: () => Promise<void>;
|
|
208
208
|
|
package/dist/index.d.ts
CHANGED
|
@@ -202,7 +202,7 @@ declare const getEventGeometry: (event: TypeEvent) => Promise<GetGeometryRespons
|
|
|
202
202
|
|
|
203
203
|
declare const getCleanedEvent: <T extends Record<string, any>>(event: T) => T;
|
|
204
204
|
|
|
205
|
-
declare const startService: (
|
|
205
|
+
declare const startService: (configurations: TypeSettings) => Promise<void>;
|
|
206
206
|
|
|
207
207
|
declare const stopService: () => Promise<void>;
|
|
208
208
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atmosx/event-product-parser",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.41",
|
|
4
4
|
"description": "NOAA Weather Wire & NWS API Parser - Built for standalone and Project AtmosphericX Integration.",
|
|
5
5
|
"main": "dist/cjs/index.cjs",
|
|
6
6
|
"module": "dist/esm/index.mjs",
|
|
@@ -33,12 +33,14 @@
|
|
|
33
33
|
},
|
|
34
34
|
"homepage": "https://github.com/AtmosphericX/event-product-parser#readme",
|
|
35
35
|
"dependencies": {
|
|
36
|
+
"express-ws": "5.0.2",
|
|
37
|
+
"express": "5.2.1",
|
|
36
38
|
"@xmpp/client": "0.14.0",
|
|
37
|
-
"better-sqlite3": "12.
|
|
39
|
+
"better-sqlite3": "12.9.0",
|
|
38
40
|
"croner": "10.0.1",
|
|
39
41
|
"jszip": "3.10.1",
|
|
40
42
|
"polygon-clipping": "0.15.7",
|
|
41
|
-
"request": "
|
|
43
|
+
"request": "2.88.2",
|
|
42
44
|
"say": "0.16.0",
|
|
43
45
|
"shapefile": "0.6.6",
|
|
44
46
|
"typescript": "5.9.3",
|
|
@@ -34,7 +34,7 @@ interface GetOfficeResponse {
|
|
|
34
34
|
|
|
35
35
|
export const getEventOffice = (options: GetOfficeOptions): GetOfficeResponse => {
|
|
36
36
|
const office = options.pVtec != null
|
|
37
|
-
? options.pVtec?.tracking?.split(`-`)[0] : (options.attributes?.cccc
|
|
37
|
+
? options.pVtec?.tracking?.split(`-`)[0] : (options.attributes?.cccc ??
|
|
38
38
|
(options.organization != null ?
|
|
39
39
|
(Array.isArray(options.organization) ? options.organization?.[0] : options.organization)
|
|
40
40
|
: null));
|
|
@@ -47,7 +47,7 @@ export const getEventSignature = (event: TypeEvent): TypeEvent => {
|
|
|
47
47
|
|
|
48
48
|
const getProduct = vtec?.vtec?.split(`.`)[0]?.replace(`/`, ``)
|
|
49
49
|
const isTestProduct = eventProducts[getProduct] == `Test Product`
|
|
50
|
-
if (isTestProduct || testSignatures.some(sig => properties.description?.toLowerCase().includes(sig.toLowerCase())
|
|
50
|
+
if (isTestProduct || testSignatures.some(sig => properties.description?.toLowerCase().includes(sig.toLowerCase()) ?? properties?.parameters?.instructions?.toLowerCase().includes(sig.toLowerCase()))) {
|
|
51
51
|
properties.status_metadata = { ...properties.status_metadata, is_test: true }
|
|
52
52
|
}
|
|
53
53
|
|
|
@@ -42,9 +42,9 @@ export const getEventTracking = (options: GetTrackingOptions): string => {
|
|
|
42
42
|
if (options.type === `RAW`) {
|
|
43
43
|
const getWatchNumber = proprties.watch_parameters.watch_number ?? null
|
|
44
44
|
if (getWatchNumber) {
|
|
45
|
-
return `${proprties.geocode.office.office}
|
|
45
|
+
return `${proprties.geocode.office.office}.${stanza.getType.prefix}.A.${getWatchNumber}`
|
|
46
46
|
}
|
|
47
|
-
return `${proprties.geocode.office.office}
|
|
47
|
+
return `${proprties.geocode.office.office}.${attributes.ttaaii}.${attributes.id.slice(-4).replace(`.`, ``) ?? '0'}`
|
|
48
48
|
}
|
|
49
49
|
if (options.type === `VTEC`) {
|
|
50
50
|
return vtec.tracking;
|
|
@@ -54,15 +54,15 @@ export const getEventTracking = (options: GetTrackingOptions): string => {
|
|
|
54
54
|
const vtecValue = Array.isArray(options.vtec)
|
|
55
55
|
? options.vtec[0] : options.vtec;
|
|
56
56
|
const splitPVTEC = vtecValue.split('.');
|
|
57
|
-
return `${splitPVTEC[2]}
|
|
57
|
+
return `${splitPVTEC[2]}.${splitPVTEC[3]}.${splitPVTEC[4]}.${splitPVTEC[5]}`;
|
|
58
58
|
}
|
|
59
59
|
const wmoMatch = options.organization?.wmoidentifier?.match(/([A-Z]{4}\d{2})\s+([A-Z]{4})/);
|
|
60
60
|
const station = wmoMatch?.[2] ?? 'N/A';
|
|
61
61
|
if (options.organization.featureId) {
|
|
62
62
|
const idMatch = options.organization.featureId.match(/([a-f0-9]+)\.(\d+)\.(\d+)$/);
|
|
63
|
-
return `${station}
|
|
63
|
+
return `${station}.${idMatch?.[1] ?? 'N/A'}`;
|
|
64
64
|
}
|
|
65
65
|
const id = wmoMatch?.[1] ?? 'N/A';
|
|
66
|
-
return `${station}
|
|
66
|
+
return `${station}.${id}`;
|
|
67
67
|
}
|
|
68
68
|
}
|
|
@@ -51,8 +51,7 @@ export const validateEvents = async (events: TypeEvent[]): Promise<void> => {
|
|
|
51
51
|
delete filteredProperties.metadata.ms;
|
|
52
52
|
}
|
|
53
53
|
filteredProperties.metadata = filteredProperties.metadata ?? {} as any;
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
properties.metadata.hash = createHash("sha256").update(JSON.stringify(filteredProperties)).digest("hex")
|
|
56
55
|
setEventEmit({ event: `onProductType${enhancedEventName.replace(/\s+/g, '')}`, metadata: define });
|
|
57
56
|
|
|
58
57
|
if (properties.status_metadata.is_test) {
|
|
@@ -76,7 +75,6 @@ export const validateEvents = async (events: TypeEvent[]): Promise<void> => {
|
|
|
76
75
|
return false
|
|
77
76
|
}
|
|
78
77
|
}
|
|
79
|
-
|
|
80
78
|
|
|
81
79
|
for (const key in sets) {
|
|
82
80
|
const setting = sets[key]
|
package/src/@core/core.start.ts
CHANGED
|
@@ -29,13 +29,13 @@ import { updateNode } from "../@manager/manager.updateNodes";
|
|
|
29
29
|
import { updateEvents } from "../@manager/manager.updateEvents";
|
|
30
30
|
import { Cron } from "croner";
|
|
31
31
|
|
|
32
|
-
export const startService = async (
|
|
32
|
+
export const startService = async (configurations: TypeSettings): Promise<void> => {
|
|
33
33
|
if (!bootstrap.isReady) {
|
|
34
34
|
return setWarning({
|
|
35
35
|
message: `You can not create another instance without shutting down the current one first, please make sure to call the stop() method first!`
|
|
36
36
|
})
|
|
37
37
|
}
|
|
38
|
-
setSettings(
|
|
38
|
+
const settings = setSettings(configurations);
|
|
39
39
|
bootstrap.isReady = true;
|
|
40
40
|
await initializeDatabase();
|
|
41
41
|
if (settings.EnableWireService) {
|
|
@@ -47,7 +47,7 @@ export const startService = async (settings: TypeSettings): Promise<void> => {
|
|
|
47
47
|
await setCronSchedule()
|
|
48
48
|
let scheduleInterval = !settings.EnableWireService ? settings.NationalWeatherServiceSettings.CallbackInterval : 1;
|
|
49
49
|
if (!settings.EnableWireService && scheduleInterval < 15) {
|
|
50
|
-
setWarning({ message: `Schedule
|
|
50
|
+
setWarning({ message: `Schedule interval of ${scheduleInterval} seconds is too low, setting to 15 seconds` })
|
|
51
51
|
bootstrap.settings.NationalWeatherServiceSettings.CallbackInterval = 15;
|
|
52
52
|
scheduleInterval = 15;
|
|
53
53
|
}
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
20
|
export const officeICAOs: Record<string, string> = {
|
|
21
|
+
"KLUB": "Lubbock, TX",
|
|
21
22
|
"KLCH": "Lake Charles, LA",
|
|
22
23
|
"TSTL": "St. Louis, MO",
|
|
23
24
|
"PABC": "Bethel, AK",
|
|
@@ -253,5 +254,6 @@ export const officeICAOs: Record<string, string> = {
|
|
|
253
254
|
"KCAR": "Caribou, ME",
|
|
254
255
|
"KMFR": "Medford, OR",
|
|
255
256
|
"PGUM": "Guam, GU",
|
|
257
|
+
"PACR": "Cordova, AK",
|
|
256
258
|
"PAJK": "Juneau, AK"
|
|
257
259
|
};
|
package/src/{@modules/@utilities/utilities.createWebhook.ts → @manager/manager.createWebhook.ts}
RENAMED
|
@@ -17,11 +17,11 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { TypeEvent } from "
|
|
21
|
-
import { setTimeoutAction } from "
|
|
22
|
-
import { createHttp } from "
|
|
23
|
-
import { TypeWebhook } from "
|
|
24
|
-
import { getCleanedEvent } from "
|
|
20
|
+
import { TypeEvent } from "../@types/type.event";
|
|
21
|
+
import { setTimeoutAction } from "../@modules/@utilities/utilities.setTimeoutAction"
|
|
22
|
+
import { createHttp } from "../@modules/@utilities/utilities.createHttp"
|
|
23
|
+
import { TypeWebhook } from "../@types/types.webhook";
|
|
24
|
+
import { getCleanedEvent } from "../@building/building.clean";
|
|
25
25
|
import FormData from "form-data";
|
|
26
26
|
|
|
27
27
|
interface CreateWebhookOptions {
|
|
@@ -46,7 +46,7 @@ export const createWebhook = async (options: CreateWebhookOptions): Promise<void
|
|
|
46
46
|
(() => {
|
|
47
47
|
const val = event.parameters.estimated_hail_size ?? null
|
|
48
48
|
const th = event.parameters.hail_threat ?? null
|
|
49
|
-
return (val
|
|
49
|
+
return (val ?? th) ? `**Hail Threat**: ${val} ${th ? `(${th})` : ''}` : null;
|
|
50
50
|
})(),
|
|
51
51
|
event.parameters.damage_threat ? `**Damage Threat**: ${event.parameters.damage_threat}` : null,
|
|
52
52
|
event.parameters.flood_threat ? `**Flood Threat**: ${event.parameters.flood_threat}` : null,
|
|
@@ -69,11 +69,13 @@ export const createWebhook = async (options: CreateWebhookOptions): Promise<void
|
|
|
69
69
|
(() => {
|
|
70
70
|
const val = event.geocode?.office?.name ?? `N/A`
|
|
71
71
|
const th = event.geocode?.office?.office ?? null
|
|
72
|
-
return (val
|
|
72
|
+
return (val ?? th) ? `**Sender**: ${val} ${th ? `(${th})` : ''}` : null;
|
|
73
73
|
})(),
|
|
74
74
|
event.metadata?.tracking ? `**Tracking**: ${event.metadata.tracking}` : null,
|
|
75
|
+
event.metadata.history?.length > 0 ? `**Updates**: ${event.metadata.history.length}` : null,
|
|
75
76
|
(() => {
|
|
76
|
-
|
|
77
|
+
if (event.status == `expires`) { return null }
|
|
78
|
+
const desc = (event.description ?? '').split('\n').map(l => l.trim()).filter(Boolean).join('\n');
|
|
77
79
|
return desc ? '```' + '\n' + desc + '\n' + '```' : null;
|
|
78
80
|
})(),
|
|
79
81
|
].filter(Boolean).join('\n');
|
|
@@ -83,7 +85,7 @@ export const createWebhook = async (options: CreateWebhookOptions): Promise<void
|
|
|
83
85
|
|
|
84
86
|
if (body.length > 1900) {
|
|
85
87
|
body = body.substring(0, 1900) + "\n\n[Message truncated due to length]";
|
|
86
|
-
const blocks = (body.match(/```/g)
|
|
88
|
+
const blocks = (body.match(/```/g) ?? []).length;
|
|
87
89
|
if (blocks % 2 !== 0) body += "```";
|
|
88
90
|
}
|
|
89
91
|
const form = new FormData();
|
|
@@ -28,22 +28,14 @@ import { TypeSettings } from "../@types/types.settings";
|
|
|
28
28
|
export const mkEvent = async (event: TypeEvent): Promise<void> => {
|
|
29
29
|
const settings = bootstrap.settings as TypeSettings;
|
|
30
30
|
const features = bootstrap.cache.events.features;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
for (const f of features) {
|
|
34
|
-
const key = f?.properties?.metadata?.tracking;
|
|
35
|
-
if (!key) continue;
|
|
36
|
-
map.set(key, f);
|
|
37
|
-
}
|
|
38
|
-
|
|
31
|
+
|
|
39
32
|
const getHash = event.properties.metadata.hash;
|
|
40
33
|
const getTracking = event.properties.metadata.tracking;
|
|
41
34
|
const isEntry = bootstrap.cache.hashes?.find(hash => hash.tracking === getTracking)
|
|
42
35
|
const isHashed = isEntry?.hashes?.includes(getHash) ?? false;
|
|
43
|
-
const getFeature =
|
|
44
|
-
|
|
36
|
+
const getFeature = features.find(feature => feature.properties.metadata.tracking === getTracking);
|
|
45
37
|
if (isHashed || event.properties.status_metadata.is_expired) return
|
|
46
|
-
|
|
38
|
+
setHash(event, isEntry)
|
|
47
39
|
const isFilteredLocation = await updateNode(event).then(() => event.properties.metadata.filtered_proximity);
|
|
48
40
|
if (!isFilteredLocation && settings.GlobalSettings.EventFiltering.NodeLocationFiltering) { return }
|
|
49
41
|
|
|
@@ -86,10 +78,11 @@ export const mkEvent = async (event: TypeEvent): Promise<void> => {
|
|
|
86
78
|
},
|
|
87
79
|
}
|
|
88
80
|
};
|
|
81
|
+
updateWebhooks(bootstrap.cache.events.features[getIndex])
|
|
89
82
|
} else {
|
|
90
83
|
features.push(event)
|
|
84
|
+
updateWebhooks(event)
|
|
91
85
|
}
|
|
92
86
|
}
|
|
93
87
|
}
|
|
94
|
-
updateWebhooks(event)
|
|
95
88
|
}
|
|
@@ -22,7 +22,7 @@ import { TypeHash } from "../@types/types.hash"
|
|
|
22
22
|
import { bootstrap } from "../bootstrap"
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
export const setHash =
|
|
25
|
+
export const setHash = (event: TypeEvent, entry: TypeHash): void => {
|
|
26
26
|
if (entry) {
|
|
27
27
|
entry.hashes.push(event.properties.metadata.hash);
|
|
28
28
|
entry.expires = event.properties.expires;
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { createWebhook } from "
|
|
20
|
+
import { createWebhook } from "./manager.createWebhook";
|
|
21
21
|
import { TypeEvent } from "../@types/type.event";
|
|
22
22
|
import { TypeWebhook } from "../@types/types.webhook";
|
|
23
23
|
import { bootstrap } from "../bootstrap"
|
|
@@ -45,7 +45,7 @@ export const setTimeoutAction = (options: SetTimeoutActionOptions): SetTimeoutAc
|
|
|
45
45
|
|
|
46
46
|
const oldestTimestamp = target?.[0];
|
|
47
47
|
const getWait = oldestTimestamp ? Math.ceil((options?.interval * 1000) - (Date.now() - oldestTimestamp)) : 0;
|
|
48
|
-
const max = options?.max
|
|
48
|
+
const max = options?.max ?? 1;
|
|
49
49
|
|
|
50
50
|
if (target?.length >= max && getWait > 0) {
|
|
51
51
|
return {
|
|
@@ -27,8 +27,8 @@ interface SetWarningOptions {
|
|
|
27
27
|
|
|
28
28
|
export const setWarning = (options: SetWarningOptions): void => {
|
|
29
29
|
const settings = bootstrap.settings as TypeSettings;
|
|
30
|
-
bootstrap.listener.emit(`log`, `${options.title ?? `[${bootstrap.ansi_colors.YELLOW}
|
|
30
|
+
bootstrap.listener.emit(`log`, `${options.title ?? `[${bootstrap.ansi_colors.YELLOW}@atmosx/product-parser${bootstrap.ansi_colors.RESET}]`} ${options.message}`)
|
|
31
31
|
if (settings.EnableJournal) {
|
|
32
|
-
console.log(`${options.title ?? `[${bootstrap.ansi_colors.YELLOW}
|
|
32
|
+
console.log(`${options.title ?? `[${bootstrap.ansi_colors.YELLOW}@atmosx/product-parser${bootstrap.ansi_colors.RESET}]`} ${options.message}`)
|
|
33
33
|
}
|
|
34
34
|
}
|
|
@@ -26,7 +26,7 @@ export const xReconnect = async (interval: number): Promise<void> => {
|
|
|
26
26
|
const settings = bootstrap.settings as TypeSettings;
|
|
27
27
|
const lastStanza = Date.now() - bootstrap.cache.lastStanza
|
|
28
28
|
if (interval < 15) {
|
|
29
|
-
setWarning({ message: `Reconnection
|
|
29
|
+
setWarning({ message: `Reconnection interval of ${interval} seconds is too low, setting to 15 seconds` })
|
|
30
30
|
interval = 15;
|
|
31
31
|
bootstrap.settings.NOAAWeatherWireServiceSettings.ReconnectionSettings.ReconnectionInterval = 15;
|
|
32
32
|
}
|
|
@@ -35,7 +35,7 @@ export const pvExtract = (message: string): TypePVTEC[] | null => {
|
|
|
35
35
|
vtecs.push({
|
|
36
36
|
vtec: vtec,
|
|
37
37
|
product: eventProducts[sub[0]],
|
|
38
|
-
tracking: `${sub[2]}
|
|
38
|
+
tracking: `${sub[2]}.${sub[3]}.${sub[4]}.${sub[5]}`,
|
|
39
39
|
event: `${eventTypes[sub[3]]} ${eventActions[sub[4]]}`,
|
|
40
40
|
status: eventStatus[sub[1]],
|
|
41
41
|
organization: message.match(regExp.wmo)?.[0] ?? null,
|
|
@@ -70,7 +70,7 @@ export const getZonePolygon = (options: CoordinatesOptions): CoordinatesResponse
|
|
|
70
70
|
}
|
|
71
71
|
if (!bestPoly || bestPoly.length === 0) return null;
|
|
72
72
|
const outerRing = bestPoly[0];
|
|
73
|
-
const skip = Math.max(1, parseInt(String(bootstrap.settings.GlobalSettings.ShapefileSkipPoints), 10)
|
|
73
|
+
const skip = Math.max(1, parseInt(String(bootstrap.settings.GlobalSettings.ShapefileSkipPoints), 10) ?? 1);
|
|
74
74
|
let skipped = outerRing.filter((_: any, idx: number) => idx % skip === 0);
|
|
75
75
|
if (skipped.length < 4) {
|
|
76
76
|
skipped = outerRing.slice();
|
|
@@ -89,7 +89,7 @@ export const getZonePolygon = (options: CoordinatesOptions): CoordinatesResponse
|
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
if (multi.length === 0) return null;
|
|
92
|
-
const skip = Math.max(1, parseInt(String(bootstrap.settings.GlobalSettings.ShapefileSkipPoints), 10)
|
|
92
|
+
const skip = Math.max(1, parseInt(String(bootstrap.settings.GlobalSettings.ShapefileSkipPoints), 10) ?? 1);
|
|
93
93
|
if (skip > 1) {
|
|
94
94
|
for (let p = 0; p < multi.length; p++) {
|
|
95
95
|
for (let r = 0; r < multi[p].length; r++) {
|
package/src/bootstrap.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -42,12 +42,12 @@ export class Manager {
|
|
|
42
42
|
|
|
43
43
|
trycatch() {
|
|
44
44
|
process.on('uncaughtException', (err: any) => {
|
|
45
|
-
const ignored = ['ETIMEDOUT', 'ECONNRESET', 'EHOSTUNREACH', 'STARTTLS_FAILURE'];
|
|
45
|
+
const ignored = ['ETIMEDOUT', 'ECONNRESET', 'EHOSTUNREACH', 'ENOTFOUND', 'ECONNREFUSED', 'EPIPE', 'EADDRINUSE', 'EALREADY', 'EACCES', 'EAGAIN', 'EHOSTDOWN', 'STARTTLS_FAILURE'];
|
|
46
46
|
if (ignored.includes(err?.code)) {
|
|
47
47
|
setEventEmit({
|
|
48
48
|
event: `onServiceStatus`,
|
|
49
49
|
metadata: {
|
|
50
|
-
message: `
|
|
50
|
+
message: `Ignored Critical Error: ${err?.code ?? 'Unknown error code'}. This may indicate a connection issue. Attempting to continue...`,
|
|
51
51
|
data: {},
|
|
52
52
|
type: `error`,
|
|
53
53
|
error: true
|
|
@@ -55,7 +55,7 @@ export class Manager {
|
|
|
55
55
|
})
|
|
56
56
|
return;
|
|
57
57
|
}
|
|
58
|
-
setWarning({message: `Uncaught Exception: ${err instanceof Error ? err.stack
|
|
58
|
+
setWarning({message: `Uncaught Exception: ${err instanceof Error ? err.stack ?? err.message : String(err)}`})
|
|
59
59
|
})
|
|
60
60
|
}
|
|
61
61
|
}
|