@atmosx/event-product-parser 3.0.2 → 3.0.3

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 CHANGED
@@ -56,6 +56,7 @@ const Client = new Manager({
56
56
  webhook: "https://discord.com/api/webhooks/XXXXXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
57
57
  title: "AtmosphericX - (@atmosx/event-product-parser)",
58
58
  message: ``,
59
+ upload: true,
59
60
  events: [`Severe Thunderstorm Warning`, `Radar Indicated Tornado Warning`, `*Warning`, `*Thunderstorm*`],
60
61
  rate: 5,
61
62
  }
@@ -124,6 +125,7 @@ const Client = new Manager({
124
125
  - **webhook**: The URL of the webhook you want to send messages to.
125
126
  - **title**: The title of the message you want to send.
126
127
  - **message**: The message content you want to send. You can use placeholders like `<@&role_id>` to mention roles in Discord.
128
+ - **upload**: Whether to upload a JSON file as well with the message containing the event data.
127
129
  - **events**: An array of event types that will trigger the webhook when they are received by the parser. If this array is empty, the webhook will be triggered for all events.
128
130
  - **rate**: The rate limit in seconds for how often the webhook can be triggered. This is to prevent spamming the webhook with too many messages in a short period of time.
129
131
 
@@ -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.2`,
10512
+ version: `3.0.3`,
10513
10513
  isReady: true,
10514
10514
  ratelimits: {},
10515
10515
  session_xmpp: null,
@@ -14388,7 +14388,16 @@ var eventTags = {
14388
14388
  "SLOW DOWN AND ALLOW EXTRA TIME": "Slow Down and Allow Extra Time",
14389
14389
  "SHOULD EXERCISE CAUTION": "Should Exercise Caution",
14390
14390
  "LAKE EFFECT SNOW EXPECTED": "Lake Effect Snow Expected",
14391
- "MODERATE LAKE EFFECT SNOWFALL RATES AND BLOWING SNOW": "Moderate Lake Effect Snowfall and Blowing Snow"
14391
+ "MODERATE LAKE EFFECT SNOWFALL RATES AND BLOWING SNOW": "Moderate Lake Effect Snowfall and Blowing Snow",
14392
+ "NO TSUNAMI THREAT": "No Active Tsunami Threat",
14393
+ "NO SIGNIFICANT TSUNAMI THREAT": "No Significant Tsunami Threat",
14394
+ "NO TSUNAMI IMPACTS ARE EXPECTED": "No Tsunami Impacts Expected",
14395
+ "A TSUNAMI THREAT EXISTS": "Tsunami Threat Exists",
14396
+ "TSUNAMI THREAT": "Active Tsunami Threat",
14397
+ "HEAT ILLNESSES": "Can cause heat illness",
14398
+ "WATCH POSSIBLE": "Watch Possible",
14399
+ "INTENSIFYING": "Intensifying",
14400
+ "CAPABLE OF PRODUCING A LANDSPOUT": "Landspout Possible"
14392
14401
  };
14393
14402
 
14394
14403
  // src/@building/building.tags.ts
@@ -14458,8 +14467,8 @@ var getEventHeader = (options) => {
14458
14467
  return `ZCZC-ATMOSX-${options.getType.prefix}-${ugc2}-${(_b = vtec2 == null ? void 0 : vtec2.status) != null ? _b : `Issued`}-${(/* @__PURE__ */ new Date()).toISOString().replace(/[-:]/g, "").split(".")[0]}-${(_c = properties2.geocode.office.office) != null ? _c : `KWNS`}`;
14459
14468
  };
14460
14469
 
14461
- // src/@dictionaries/dictionaries.eventsOffshore.ts
14462
- var eventsOffshore = {
14470
+ // src/@dictionaries/dictionaries.eventsMatchText.ts
14471
+ var eventsMatchText = {
14463
14472
  "Special Weather Statement": "Special Weather Statement",
14464
14473
  "Hurricane Warning": "Hurricane Warning",
14465
14474
  "Hurricane Force Wind Warning": "Hurricane Force Wind Warning",
@@ -14469,7 +14478,12 @@ var eventsOffshore = {
14469
14478
  "High Wind Warning": "High Wind Warning",
14470
14479
  "Gale Warning": "Gale Warning",
14471
14480
  "Small Craft Advisory": "Small Craft Advisory",
14472
- "Small Craft Warning": "Small Craft Warning"
14481
+ "Small Craft Warning": "Small Craft Warning",
14482
+ "Tsunami Warning": "Tsunami Warning",
14483
+ "Tsunami Watch": "Tsunami Watch",
14484
+ "Tsunami Advisory": "Tsunami Advisory",
14485
+ "Tsunami Information Statement": "Tsunami Information Statement",
14486
+ "Subscribers:": "National Weather Service Policy"
14473
14487
  };
14474
14488
 
14475
14489
  // src/@building/building.tracking.ts
@@ -14528,6 +14542,16 @@ var betterEventNames = {
14528
14542
  },
14529
14543
  "Radar Indicated Tornado Warning": {}
14530
14544
  },
14545
+ "Blizzard Warning": {
14546
+ "PDS Blizzard Warning": {
14547
+ description: "particularly dangerous situation"
14548
+ }
14549
+ },
14550
+ "Ice Storm Warning": {
14551
+ "PDS Ice Storm Warning": {
14552
+ description: "particularly dangerous situation"
14553
+ }
14554
+ },
14531
14555
  "Special Marine Warning": {
14532
14556
  "Special Marine Warning (TPROB)": {
14533
14557
  tornado: `POSSIBLE`
@@ -14775,13 +14799,13 @@ var createHttp = (options) => __async(null, null, function* () {
14775
14799
  // src/@modules/@utilities/utilities.createWebhook.ts
14776
14800
  var import_form_data = __toESM(require_form_data());
14777
14801
  var createWebhook = (options) => __async(null, null, function* () {
14778
- var _a, _b, _c, _d, _e, _f, _g, _h;
14802
+ var _a, _b, _c, _d;
14779
14803
  const event = options.event.properties;
14780
14804
  const settings = options.webhook;
14781
14805
  let body = [
14782
14806
  event.locations ? `**Locations**: ${event.locations.slice(0, 100)}` : null,
14783
14807
  event.issued ? `**Issued**: <t:${Math.floor(new Date(event.issued).getTime() / 1e3)}:R>` : null,
14784
- event.expires ? `**Expires**: <t:${Math.floor(new Date(event.expires).getTime() / 1e3)}:R>` : null,
14808
+ event.expires && event.status != `Statement` ? `**Expires**: <t:${Math.floor(new Date(event.expires).getTime() / 1e3)}:R>` : null,
14785
14809
  (() => {
14786
14810
  var _a2, _b2;
14787
14811
  const val = (_a2 = event.parameters.estimated_wind_gusts) != null ? _a2 : null;
@@ -14798,16 +14822,28 @@ var createWebhook = (options) => __async(null, null, function* () {
14798
14822
  event.parameters.damage_threat ? `**Damage Threat**: ${event.parameters.damage_threat}` : null,
14799
14823
  event.parameters.flood_threat ? `**Flood Threat**: ${event.parameters.flood_threat}` : null,
14800
14824
  event.parameters.tornado_threat ? `**Tornado Threat**: ${event.parameters.tornado_threat}` : null,
14825
+ event.spc_parameters.spc_max_tornado ? `**Max Tornado Threat**: ${event.spc_parameters.spc_max_tornado}` : null,
14826
+ event.spc_parameters.spc_max_hail ? `**Max Hail Threat**: ${event.spc_parameters.spc_max_hail}` : null,
14827
+ event.spc_parameters.spc_max_wind ? `**Max Wind Threat**: ${event.spc_parameters.spc_max_wind}` : null,
14828
+ event.spc_parameters.spc_watch_issuance ? `**Watch Issuance**: ${event.spc_parameters.spc_watch_issuance}%` : null,
14829
+ event.watch_parameters.watch_number ? `**Watch Number**: ${event.watch_parameters.watch_number}` : null,
14830
+ event.watch_parameters.strong_tornadoes_probability ? `**Strong Tornadoes Probability**: ${event.watch_parameters.strong_tornadoes_probability}%` : null,
14831
+ event.watch_parameters.additional_tornadoes_probability ? `**Additional Tornadoes Probability**: ${event.watch_parameters.additional_tornadoes_probability}%` : null,
14832
+ event.watch_parameters.combined_hail_wind_probability ? `**Combined Hail/Wind Probability**: ${event.watch_parameters.combined_hail_wind_probability}%` : null,
14833
+ event.watch_parameters.severe_hail_probability ? `**Severe Hail Probability**: ${event.watch_parameters.severe_hail_probability}%` : null,
14834
+ event.watch_parameters.hail_2in_probability ? `**Hail \u22652in Probability**: ${event.watch_parameters.hail_2in_probability}%` : null,
14835
+ event.watch_parameters.max_hail_in ? `**Max Hail Inches**: ${event.watch_parameters.max_hail_in}` : null,
14836
+ event.watch_parameters.severe_wind_probability ? `**Severe Wind Probability**: ${event.watch_parameters.severe_wind_probability}%` : null,
14837
+ event.watch_parameters.max_wind_surface ? `**Max Surface Wind**: ${event.watch_parameters.max_wind_surface}` : null,
14838
+ event.watch_parameters.max_tops_x100feet ? `**Max Tops (x100 feet)**: ${event.watch_parameters.max_tops_x100feet}` : null,
14801
14839
  ((_a = event.parameters.tags) == null ? void 0 : _a.length) > 0 ? `**Tags**: ${event.parameters.tags.join(", ")}` : null,
14802
14840
  (() => {
14803
- var _a2, _b2, _c2, _d2, _e2, _f2;
14841
+ var _a2, _b2, _c2, _d2, _e, _f;
14804
14842
  const val = (_c2 = (_b2 = (_a2 = event.geocode) == null ? void 0 : _a2.office) == null ? void 0 : _b2.name) != null ? _c2 : `N/A`;
14805
- const th = (_f2 = (_e2 = (_d2 = event.geocode) == null ? void 0 : _d2.office) == null ? void 0 : _e2.office) != null ? _f2 : null;
14843
+ const th = (_f = (_e = (_d2 = event.geocode) == null ? void 0 : _d2.office) == null ? void 0 : _e.office) != null ? _f : null;
14806
14844
  return val || th ? `**Sender**: ${val} ${th ? `(${th})` : ""}` : null;
14807
14845
  })(),
14808
14846
  ((_b = event.metadata) == null ? void 0 : _b.tracking) ? `**Tracking**: ${event.metadata.tracking}` : null,
14809
- ((_d = (_c = event.metadata) == null ? void 0 : _c.vtec) == null ? void 0 : _d.vtec) ? `**VTEC**: ${(_e = event.metadata.vtec) == null ? void 0 : _e.vtec}` : null,
14810
- ((_f = event.metadata) == null ? void 0 : _f.filtered_proximity) != null ? `**Currently in polygon (Node)**: ${event.metadata.filtered_proximity ? "Yes" : "No"}` : null,
14811
14847
  (() => {
14812
14848
  const desc = (event.description || "").split("\n").map((l) => l.trim()).filter(Boolean).join("\n");
14813
14849
  return desc ? "```\n" + desc + "\n```" : null;
@@ -14831,14 +14867,16 @@ var createWebhook = (options) => __async(null, null, function* () {
14831
14867
  footer: { text: settings.title }
14832
14868
  };
14833
14869
  form.append("payload_json", JSON.stringify({
14834
- username: (_g = settings.title) != null ? _g : "AtmosphericX",
14835
- content: (_h = settings.message) != null ? _h : "",
14870
+ username: (_c = settings.title) != null ? _c : "AtmosphericX",
14871
+ content: (_d = settings.message) != null ? _d : "",
14836
14872
  embeds: [embed]
14837
14873
  }));
14838
- form.append("file", Buffer.from(JSON.stringify({ type: "FeatureCollection", features: [getCleanedEvent(options.event)] }, null, 2)), {
14839
- filename: `${event.event}_${event.status}_${event.metadata.tracking}.json`,
14840
- contentType: "application/json"
14841
- });
14874
+ if (settings.upload) {
14875
+ form.append("file", Buffer.from(JSON.stringify(getCleanedEvent(event), null, 2)), {
14876
+ filename: `${event.event}_${event.status}_${event.metadata.tracking}.json`,
14877
+ contentType: "application/json"
14878
+ });
14879
+ }
14842
14880
  yield createHttp({
14843
14881
  url: settings.webhook,
14844
14882
  timeout: 2e3,
@@ -15260,7 +15298,7 @@ var text = (stanza) => __async(null, null, function* () {
15260
15298
  const header = getEventHeader({ properties: props, getType: stanza.getType });
15261
15299
  const issued = new Date(attributes.issue);
15262
15300
  const expires = new Date(issued.getTime() + 12 * 60 * 60 * 1e3);
15263
- let event = Object.keys(eventsOffshore).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
15301
+ let event = Object.keys(eventsMatchText).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
15264
15302
  let isStatement = false;
15265
15303
  if (!event) {
15266
15304
  event = stanza.getType.type.split(`-`).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `);
@@ -15277,7 +15315,7 @@ var text = (stanza) => __async(null, null, function* () {
15277
15315
  parent: event,
15278
15316
  status: isStatement ? `Statement` : `Issued`,
15279
15317
  issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
15280
- expires: isStatement ? new Date(issued.getTime() + 5 * 1e3).toISOString() : !isNaN(expires.getTime()) ? expires.toISOString() : new Date(Date.now() + 60 * 60 * 1e3).toISOString()
15318
+ expires: isStatement ? new Date(issued.getTime() + 120 * 1e3).toISOString() : !isNaN(expires.getTime()) ? expires.toISOString() : new Date(Date.now() + 60 * 60 * 1e3).toISOString()
15281
15319
  }, props), {
15282
15320
  metadata: {
15283
15321
  ms: performance.now() - tick,
@@ -15394,11 +15432,13 @@ var ugc = (stanza) => __async(null, null, function* () {
15394
15432
  if (ugc2 != null) {
15395
15433
  const props = properties({ message, attributes, ugc: ugc2 });
15396
15434
  const issued = new Date(attributes.issue);
15397
- const expires = new Date(ugc2.expires).toISOString();
15435
+ const expires = new Date(ugc2.expires);
15398
15436
  const header = getEventHeader({ properties: props, getType: stanza.getType });
15399
- let event = Object.keys(eventsOffshore).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
15437
+ let event = Object.keys(eventsMatchText).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
15438
+ let isStatement = false;
15400
15439
  if (!event) {
15401
15440
  event = stanza.getType.type.split(`-`).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `);
15441
+ isStatement = true;
15402
15442
  }
15403
15443
  processed.push({
15404
15444
  type: `Feature`,
@@ -15409,9 +15449,9 @@ var ugc = (stanza) => __async(null, null, function* () {
15409
15449
  properties: __spreadProps(__spreadValues({
15410
15450
  event,
15411
15451
  parent: event,
15412
- status: `Issued`,
15452
+ status: isStatement ? `Statement` : `Issued`,
15413
15453
  issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
15414
- expires: !isNaN(new Date(ugc2.expires).getTime()) ? expires : new Date(Date.now() + 60 * 60 * 1e3).toISOString()
15454
+ expires: isStatement ? new Date(issued.getTime() + 120 * 1e3).toISOString() : !isNaN(expires.getTime()) ? expires.toISOString() : new Date(Date.now() + 60 * 60 * 1e3).toISOString()
15415
15455
  }, props), {
15416
15456
  metadata: {
15417
15457
  ms: performance.now() - tick,
@@ -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.2`,
10494
+ version: `3.0.3`,
10495
10495
  isReady: true,
10496
10496
  ratelimits: {},
10497
10497
  session_xmpp: null,
@@ -14370,7 +14370,16 @@ var eventTags = {
14370
14370
  "SLOW DOWN AND ALLOW EXTRA TIME": "Slow Down and Allow Extra Time",
14371
14371
  "SHOULD EXERCISE CAUTION": "Should Exercise Caution",
14372
14372
  "LAKE EFFECT SNOW EXPECTED": "Lake Effect Snow Expected",
14373
- "MODERATE LAKE EFFECT SNOWFALL RATES AND BLOWING SNOW": "Moderate Lake Effect Snowfall and Blowing Snow"
14373
+ "MODERATE LAKE EFFECT SNOWFALL RATES AND BLOWING SNOW": "Moderate Lake Effect Snowfall and Blowing Snow",
14374
+ "NO TSUNAMI THREAT": "No Active Tsunami Threat",
14375
+ "NO SIGNIFICANT TSUNAMI THREAT": "No Significant Tsunami Threat",
14376
+ "NO TSUNAMI IMPACTS ARE EXPECTED": "No Tsunami Impacts Expected",
14377
+ "A TSUNAMI THREAT EXISTS": "Tsunami Threat Exists",
14378
+ "TSUNAMI THREAT": "Active Tsunami Threat",
14379
+ "HEAT ILLNESSES": "Can cause heat illness",
14380
+ "WATCH POSSIBLE": "Watch Possible",
14381
+ "INTENSIFYING": "Intensifying",
14382
+ "CAPABLE OF PRODUCING A LANDSPOUT": "Landspout Possible"
14374
14383
  };
14375
14384
 
14376
14385
  // src/@building/building.tags.ts
@@ -14440,8 +14449,8 @@ var getEventHeader = (options) => {
14440
14449
  return `ZCZC-ATMOSX-${options.getType.prefix}-${ugc2}-${(_b = vtec2 == null ? void 0 : vtec2.status) != null ? _b : `Issued`}-${(/* @__PURE__ */ new Date()).toISOString().replace(/[-:]/g, "").split(".")[0]}-${(_c = properties2.geocode.office.office) != null ? _c : `KWNS`}`;
14441
14450
  };
14442
14451
 
14443
- // src/@dictionaries/dictionaries.eventsOffshore.ts
14444
- var eventsOffshore = {
14452
+ // src/@dictionaries/dictionaries.eventsMatchText.ts
14453
+ var eventsMatchText = {
14445
14454
  "Special Weather Statement": "Special Weather Statement",
14446
14455
  "Hurricane Warning": "Hurricane Warning",
14447
14456
  "Hurricane Force Wind Warning": "Hurricane Force Wind Warning",
@@ -14451,7 +14460,12 @@ var eventsOffshore = {
14451
14460
  "High Wind Warning": "High Wind Warning",
14452
14461
  "Gale Warning": "Gale Warning",
14453
14462
  "Small Craft Advisory": "Small Craft Advisory",
14454
- "Small Craft Warning": "Small Craft Warning"
14463
+ "Small Craft Warning": "Small Craft Warning",
14464
+ "Tsunami Warning": "Tsunami Warning",
14465
+ "Tsunami Watch": "Tsunami Watch",
14466
+ "Tsunami Advisory": "Tsunami Advisory",
14467
+ "Tsunami Information Statement": "Tsunami Information Statement",
14468
+ "Subscribers:": "National Weather Service Policy"
14455
14469
  };
14456
14470
 
14457
14471
  // src/@building/building.tracking.ts
@@ -14510,6 +14524,16 @@ var betterEventNames = {
14510
14524
  },
14511
14525
  "Radar Indicated Tornado Warning": {}
14512
14526
  },
14527
+ "Blizzard Warning": {
14528
+ "PDS Blizzard Warning": {
14529
+ description: "particularly dangerous situation"
14530
+ }
14531
+ },
14532
+ "Ice Storm Warning": {
14533
+ "PDS Ice Storm Warning": {
14534
+ description: "particularly dangerous situation"
14535
+ }
14536
+ },
14513
14537
  "Special Marine Warning": {
14514
14538
  "Special Marine Warning (TPROB)": {
14515
14539
  tornado: `POSSIBLE`
@@ -14757,13 +14781,13 @@ var createHttp = (options) => __async(null, null, function* () {
14757
14781
  // src/@modules/@utilities/utilities.createWebhook.ts
14758
14782
  var import_form_data = __toESM(require_form_data());
14759
14783
  var createWebhook = (options) => __async(null, null, function* () {
14760
- var _a, _b, _c, _d, _e, _f, _g, _h;
14784
+ var _a, _b, _c, _d;
14761
14785
  const event = options.event.properties;
14762
14786
  const settings = options.webhook;
14763
14787
  let body = [
14764
14788
  event.locations ? `**Locations**: ${event.locations.slice(0, 100)}` : null,
14765
14789
  event.issued ? `**Issued**: <t:${Math.floor(new Date(event.issued).getTime() / 1e3)}:R>` : null,
14766
- event.expires ? `**Expires**: <t:${Math.floor(new Date(event.expires).getTime() / 1e3)}:R>` : null,
14790
+ event.expires && event.status != `Statement` ? `**Expires**: <t:${Math.floor(new Date(event.expires).getTime() / 1e3)}:R>` : null,
14767
14791
  (() => {
14768
14792
  var _a2, _b2;
14769
14793
  const val = (_a2 = event.parameters.estimated_wind_gusts) != null ? _a2 : null;
@@ -14780,16 +14804,28 @@ var createWebhook = (options) => __async(null, null, function* () {
14780
14804
  event.parameters.damage_threat ? `**Damage Threat**: ${event.parameters.damage_threat}` : null,
14781
14805
  event.parameters.flood_threat ? `**Flood Threat**: ${event.parameters.flood_threat}` : null,
14782
14806
  event.parameters.tornado_threat ? `**Tornado Threat**: ${event.parameters.tornado_threat}` : null,
14807
+ event.spc_parameters.spc_max_tornado ? `**Max Tornado Threat**: ${event.spc_parameters.spc_max_tornado}` : null,
14808
+ event.spc_parameters.spc_max_hail ? `**Max Hail Threat**: ${event.spc_parameters.spc_max_hail}` : null,
14809
+ event.spc_parameters.spc_max_wind ? `**Max Wind Threat**: ${event.spc_parameters.spc_max_wind}` : null,
14810
+ event.spc_parameters.spc_watch_issuance ? `**Watch Issuance**: ${event.spc_parameters.spc_watch_issuance}%` : null,
14811
+ event.watch_parameters.watch_number ? `**Watch Number**: ${event.watch_parameters.watch_number}` : null,
14812
+ event.watch_parameters.strong_tornadoes_probability ? `**Strong Tornadoes Probability**: ${event.watch_parameters.strong_tornadoes_probability}%` : null,
14813
+ event.watch_parameters.additional_tornadoes_probability ? `**Additional Tornadoes Probability**: ${event.watch_parameters.additional_tornadoes_probability}%` : null,
14814
+ event.watch_parameters.combined_hail_wind_probability ? `**Combined Hail/Wind Probability**: ${event.watch_parameters.combined_hail_wind_probability}%` : null,
14815
+ event.watch_parameters.severe_hail_probability ? `**Severe Hail Probability**: ${event.watch_parameters.severe_hail_probability}%` : null,
14816
+ event.watch_parameters.hail_2in_probability ? `**Hail \u22652in Probability**: ${event.watch_parameters.hail_2in_probability}%` : null,
14817
+ event.watch_parameters.max_hail_in ? `**Max Hail Inches**: ${event.watch_parameters.max_hail_in}` : null,
14818
+ event.watch_parameters.severe_wind_probability ? `**Severe Wind Probability**: ${event.watch_parameters.severe_wind_probability}%` : null,
14819
+ event.watch_parameters.max_wind_surface ? `**Max Surface Wind**: ${event.watch_parameters.max_wind_surface}` : null,
14820
+ event.watch_parameters.max_tops_x100feet ? `**Max Tops (x100 feet)**: ${event.watch_parameters.max_tops_x100feet}` : null,
14783
14821
  ((_a = event.parameters.tags) == null ? void 0 : _a.length) > 0 ? `**Tags**: ${event.parameters.tags.join(", ")}` : null,
14784
14822
  (() => {
14785
- var _a2, _b2, _c2, _d2, _e2, _f2;
14823
+ var _a2, _b2, _c2, _d2, _e, _f;
14786
14824
  const val = (_c2 = (_b2 = (_a2 = event.geocode) == null ? void 0 : _a2.office) == null ? void 0 : _b2.name) != null ? _c2 : `N/A`;
14787
- const th = (_f2 = (_e2 = (_d2 = event.geocode) == null ? void 0 : _d2.office) == null ? void 0 : _e2.office) != null ? _f2 : null;
14825
+ const th = (_f = (_e = (_d2 = event.geocode) == null ? void 0 : _d2.office) == null ? void 0 : _e.office) != null ? _f : null;
14788
14826
  return val || th ? `**Sender**: ${val} ${th ? `(${th})` : ""}` : null;
14789
14827
  })(),
14790
14828
  ((_b = event.metadata) == null ? void 0 : _b.tracking) ? `**Tracking**: ${event.metadata.tracking}` : null,
14791
- ((_d = (_c = event.metadata) == null ? void 0 : _c.vtec) == null ? void 0 : _d.vtec) ? `**VTEC**: ${(_e = event.metadata.vtec) == null ? void 0 : _e.vtec}` : null,
14792
- ((_f = event.metadata) == null ? void 0 : _f.filtered_proximity) != null ? `**Currently in polygon (Node)**: ${event.metadata.filtered_proximity ? "Yes" : "No"}` : null,
14793
14829
  (() => {
14794
14830
  const desc = (event.description || "").split("\n").map((l) => l.trim()).filter(Boolean).join("\n");
14795
14831
  return desc ? "```\n" + desc + "\n```" : null;
@@ -14813,14 +14849,16 @@ var createWebhook = (options) => __async(null, null, function* () {
14813
14849
  footer: { text: settings.title }
14814
14850
  };
14815
14851
  form.append("payload_json", JSON.stringify({
14816
- username: (_g = settings.title) != null ? _g : "AtmosphericX",
14817
- content: (_h = settings.message) != null ? _h : "",
14852
+ username: (_c = settings.title) != null ? _c : "AtmosphericX",
14853
+ content: (_d = settings.message) != null ? _d : "",
14818
14854
  embeds: [embed]
14819
14855
  }));
14820
- form.append("file", Buffer.from(JSON.stringify({ type: "FeatureCollection", features: [getCleanedEvent(options.event)] }, null, 2)), {
14821
- filename: `${event.event}_${event.status}_${event.metadata.tracking}.json`,
14822
- contentType: "application/json"
14823
- });
14856
+ if (settings.upload) {
14857
+ form.append("file", Buffer.from(JSON.stringify(getCleanedEvent(event), null, 2)), {
14858
+ filename: `${event.event}_${event.status}_${event.metadata.tracking}.json`,
14859
+ contentType: "application/json"
14860
+ });
14861
+ }
14824
14862
  yield createHttp({
14825
14863
  url: settings.webhook,
14826
14864
  timeout: 2e3,
@@ -15242,7 +15280,7 @@ var text = (stanza) => __async(null, null, function* () {
15242
15280
  const header = getEventHeader({ properties: props, getType: stanza.getType });
15243
15281
  const issued = new Date(attributes.issue);
15244
15282
  const expires = new Date(issued.getTime() + 12 * 60 * 60 * 1e3);
15245
- let event = Object.keys(eventsOffshore).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
15283
+ let event = Object.keys(eventsMatchText).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
15246
15284
  let isStatement = false;
15247
15285
  if (!event) {
15248
15286
  event = stanza.getType.type.split(`-`).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `);
@@ -15259,7 +15297,7 @@ var text = (stanza) => __async(null, null, function* () {
15259
15297
  parent: event,
15260
15298
  status: isStatement ? `Statement` : `Issued`,
15261
15299
  issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
15262
- expires: isStatement ? new Date(issued.getTime() + 5 * 1e3).toISOString() : !isNaN(expires.getTime()) ? expires.toISOString() : new Date(Date.now() + 60 * 60 * 1e3).toISOString()
15300
+ expires: isStatement ? new Date(issued.getTime() + 120 * 1e3).toISOString() : !isNaN(expires.getTime()) ? expires.toISOString() : new Date(Date.now() + 60 * 60 * 1e3).toISOString()
15263
15301
  }, props), {
15264
15302
  metadata: {
15265
15303
  ms: performance.now() - tick,
@@ -15376,11 +15414,13 @@ var ugc = (stanza) => __async(null, null, function* () {
15376
15414
  if (ugc2 != null) {
15377
15415
  const props = properties({ message, attributes, ugc: ugc2 });
15378
15416
  const issued = new Date(attributes.issue);
15379
- const expires = new Date(ugc2.expires).toISOString();
15417
+ const expires = new Date(ugc2.expires);
15380
15418
  const header = getEventHeader({ properties: props, getType: stanza.getType });
15381
- let event = Object.keys(eventsOffshore).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
15419
+ let event = Object.keys(eventsMatchText).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
15420
+ let isStatement = false;
15382
15421
  if (!event) {
15383
15422
  event = stanza.getType.type.split(`-`).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `);
15423
+ isStatement = true;
15384
15424
  }
15385
15425
  processed.push({
15386
15426
  type: `Feature`,
@@ -15391,9 +15431,9 @@ var ugc = (stanza) => __async(null, null, function* () {
15391
15431
  properties: __spreadProps(__spreadValues({
15392
15432
  event,
15393
15433
  parent: event,
15394
- status: `Issued`,
15434
+ status: isStatement ? `Statement` : `Issued`,
15395
15435
  issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
15396
- expires: !isNaN(new Date(ugc2.expires).getTime()) ? expires : new Date(Date.now() + 60 * 60 * 1e3).toISOString()
15436
+ expires: isStatement ? new Date(issued.getTime() + 120 * 1e3).toISOString() : !isNaN(expires.getTime()) ? expires.toISOString() : new Date(Date.now() + 60 * 60 * 1e3).toISOString()
15397
15437
  }, props), {
15398
15438
  metadata: {
15399
15439
  ms: performance.now() - tick,
package/dist/index.d.mts CHANGED
@@ -2,6 +2,7 @@ type TypeWebhook = {
2
2
  webhook: string;
3
3
  title: string;
4
4
  message: string;
5
+ upload: boolean;
5
6
  rate: number;
6
7
  events: string[];
7
8
  };
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ type TypeWebhook = {
2
2
  webhook: string;
3
3
  title: string;
4
4
  message: string;
5
+ upload: boolean;
5
6
  rate: number;
6
7
  events: string[];
7
8
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atmosx/event-product-parser",
3
- "version": "3.0.2",
3
+ "version": "3.0.3",
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",
@@ -42,6 +42,16 @@ export const betterEventNames: Record<string, Record<string, EnhancedEventType>>
42
42
  },
43
43
  "Radar Indicated Tornado Warning": { },
44
44
  },
45
+ "Blizzard Warning": {
46
+ "PDS Blizzard Warning": {
47
+ description: "particularly dangerous situation",
48
+ },
49
+ },
50
+ "Ice Storm Warning": {
51
+ "PDS Ice Storm Warning": {
52
+ description: "particularly dangerous situation",
53
+ },
54
+ },
45
55
  "Special Marine Warning": {
46
56
  "Special Marine Warning (TPROB)": {
47
57
  tornado: `POSSIBLE`
@@ -81,4 +81,13 @@ export const eventTags: Record<string, string> = {
81
81
  "SHOULD EXERCISE CAUTION": "Should Exercise Caution",
82
82
  "LAKE EFFECT SNOW EXPECTED": "Lake Effect Snow Expected",
83
83
  "MODERATE LAKE EFFECT SNOWFALL RATES AND BLOWING SNOW": "Moderate Lake Effect Snowfall and Blowing Snow",
84
+ "NO TSUNAMI THREAT": "No Active Tsunami Threat",
85
+ "NO SIGNIFICANT TSUNAMI THREAT": "No Significant Tsunami Threat",
86
+ "NO TSUNAMI IMPACTS ARE EXPECTED": "No Tsunami Impacts Expected",
87
+ "A TSUNAMI THREAT EXISTS": "Tsunami Threat Exists",
88
+ "TSUNAMI THREAT": "Active Tsunami Threat",
89
+ "HEAT ILLNESSES": "Can cause heat illness",
90
+ "WATCH POSSIBLE": "Watch Possible",
91
+ "INTENSIFYING": "Intensifying",
92
+ "CAPABLE OF PRODUCING A LANDSPOUT": "Landspout Possible",
84
93
  }
@@ -17,7 +17,7 @@
17
17
 
18
18
  */
19
19
 
20
- export const eventsOffshore: Record<string, string> = {
20
+ export const eventsMatchText: Record<string, string> = {
21
21
  "Special Weather Statement": "Special Weather Statement",
22
22
  "Hurricane Warning": "Hurricane Warning",
23
23
  "Hurricane Force Wind Warning": "Hurricane Force Wind Warning",
@@ -28,4 +28,9 @@ export const eventsOffshore: Record<string, string> = {
28
28
  "Gale Warning": "Gale Warning",
29
29
  "Small Craft Advisory": "Small Craft Advisory",
30
30
  "Small Craft Warning": "Small Craft Warning",
31
+ "Tsunami Warning": "Tsunami Warning",
32
+ "Tsunami Watch": "Tsunami Watch",
33
+ "Tsunami Advisory": "Tsunami Advisory",
34
+ "Tsunami Information Statement": "Tsunami Information Statement",
35
+ "Subscribers:": "National Weather Service Policy",
31
36
  };
@@ -22,7 +22,7 @@ import { TypeStanzaCompiled } from "../@types/types.compiled"
22
22
  import { TypeEvent } from "../@types/type.event";
23
23
  import { properties } from "../@building/building.properties";
24
24
  import { getEventHeader } from "../@building/building.headers";
25
- import { eventsOffshore } from "../@dictionaries/dictionaries.eventsOffshore";
25
+ import { eventsMatchText } from "../@dictionaries/dictionaries.eventsMatchText";
26
26
  import { getEventTracking } from "../@building/building.tracking";
27
27
  import { validateEvents } from "../@building/building.validate";
28
28
 
@@ -40,7 +40,7 @@ export const text = async (stanza: TypeStanzaCompiled): Promise<void> => {
40
40
  const header = getEventHeader({properties: props, getType: stanza.getType})
41
41
  const issued = new Date(attributes.issue)
42
42
  const expires = new Date(issued.getTime() + 12 * 60 * 60 * 1000)
43
- let event = Object.keys(eventsOffshore).find(event => message.toLowerCase().includes(event.toLowerCase()));
43
+ let event = Object.keys(eventsMatchText).find(event => message.toLowerCase().includes(event.toLowerCase()));
44
44
  let isStatement = false;
45
45
  if (!event) {
46
46
  event = stanza.getType.type.split(`-`).map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `)
@@ -57,7 +57,7 @@ export const text = async (stanza: TypeStanzaCompiled): Promise<void> => {
57
57
  parent: event,
58
58
  status: isStatement ? `Statement` : `Issued`,
59
59
  issued: (!isNaN(issued.getTime())) ? issued.toISOString() : new Date().toISOString(),
60
- expires: isStatement ? new Date(issued.getTime() + 5 * 1000).toISOString() : (!isNaN(expires.getTime())) ? expires.toISOString() : new Date(Date.now() + 60 * 60 * 1000).toISOString(),
60
+ expires: isStatement ? new Date(issued.getTime() + 120 * 1000).toISOString() : (!isNaN(expires.getTime())) ? expires.toISOString() : new Date(Date.now() + 60 * 60 * 1000).toISOString(),
61
61
  ...props,
62
62
  metadata: {
63
63
  ms: performance.now() - tick,
@@ -20,7 +20,7 @@
20
20
  import { TypeAttributes } from "../@types/types.attributes";
21
21
  import { TypeStanzaCompiled } from "../@types/types.compiled"
22
22
  import { TypeEvent } from "../@types/type.event";
23
- import { eventsOffshore } from "../@dictionaries/dictionaries.eventsOffshore";
23
+ import { eventsMatchText } from "../@dictionaries/dictionaries.eventsMatchText";
24
24
  import { ugcExtract } from "../@parsers/@ugc/ugc.extract";
25
25
  import { properties } from "../@building/building.properties";
26
26
  import { getEventHeader } from "../@building/building.headers";
@@ -41,11 +41,13 @@ export const ugc = async (stanza: TypeStanzaCompiled): Promise<void> => {
41
41
  if (ugc != null ) {
42
42
  const props = properties({ message, attributes, ugc: ugc })
43
43
  const issued = new Date(attributes.issue)
44
- const expires = new Date(ugc.expires).toISOString()
44
+ const expires = new Date(ugc.expires)
45
45
  const header = getEventHeader({properties: props, getType: stanza.getType })
46
- let event = Object.keys(eventsOffshore).find(event => message.toLowerCase().includes(event.toLowerCase()));
46
+ let event = Object.keys(eventsMatchText).find(event => message.toLowerCase().includes(event.toLowerCase()));
47
+ let isStatement = false;
47
48
  if (!event) {
48
49
  event = stanza.getType.type.split(`-`).map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `)
50
+ isStatement = true;
49
51
  }
50
52
  processed.push({
51
53
  type: `Feature`,
@@ -56,9 +58,9 @@ export const ugc = async (stanza: TypeStanzaCompiled): Promise<void> => {
56
58
  properties: {
57
59
  event: event,
58
60
  parent: event,
59
- status: `Issued`,
61
+ status: isStatement ? `Statement` : `Issued`,
60
62
  issued: (!isNaN(issued.getTime())) ? issued.toISOString() : new Date().toISOString(),
61
- expires: (!isNaN(new Date(ugc.expires).getTime())) ? expires : new Date(Date.now() + 60 * 60 * 1000).toISOString(),
63
+ expires: isStatement ? new Date(issued.getTime() + 120 * 1000).toISOString() : (!isNaN(expires.getTime())) ? expires.toISOString() : new Date(Date.now() + 60 * 60 * 1000).toISOString(),
62
64
  ...props,
63
65
  metadata: {
64
66
  ms: performance.now() - tick,
@@ -32,10 +32,11 @@ interface CreateWebhookOptions {
32
32
  export const createWebhook = async (options: CreateWebhookOptions): Promise<void> => {
33
33
  const event = options.event.properties;
34
34
  const settings = options.webhook;
35
+
35
36
  let body = [
36
37
  event.locations ? `**Locations**: ${event.locations.slice(0,100)}` : null,
37
38
  event.issued ? `**Issued**: <t:${Math.floor(new Date(event.issued).getTime()/1000)}:R>` : null,
38
- event.expires ? `**Expires**: <t:${Math.floor(new Date(event.expires).getTime()/1000)}:R>` : null,
39
+ event.expires && event.status != `Statement` ? `**Expires**: <t:${Math.floor(new Date(event.expires).getTime()/1000)}:R>` : null,
39
40
  (() => {
40
41
  const val = event.parameters.estimated_wind_gusts ?? null
41
42
  const th = event.parameters.wind_threat ?? null
@@ -50,6 +51,20 @@ export const createWebhook = async (options: CreateWebhookOptions): Promise<void
50
51
  event.parameters.damage_threat ? `**Damage Threat**: ${event.parameters.damage_threat}` : null,
51
52
  event.parameters.flood_threat ? `**Flood Threat**: ${event.parameters.flood_threat}` : null,
52
53
  event.parameters.tornado_threat ? `**Tornado Threat**: ${event.parameters.tornado_threat}` : null,
54
+ event.spc_parameters.spc_max_tornado ? `**Max Tornado Threat**: ${event.spc_parameters.spc_max_tornado}` : null,
55
+ event.spc_parameters.spc_max_hail ? `**Max Hail Threat**: ${event.spc_parameters.spc_max_hail}` : null,
56
+ event.spc_parameters.spc_max_wind ? `**Max Wind Threat**: ${event.spc_parameters.spc_max_wind}` : null,
57
+ event.spc_parameters.spc_watch_issuance ? `**Watch Issuance**: ${event.spc_parameters.spc_watch_issuance}%` : null,
58
+ event.watch_parameters.watch_number ? `**Watch Number**: ${event.watch_parameters.watch_number}` : null,
59
+ event.watch_parameters.strong_tornadoes_probability ? `**Strong Tornadoes Probability**: ${event.watch_parameters.strong_tornadoes_probability}%` : null,
60
+ event.watch_parameters.additional_tornadoes_probability ? `**Additional Tornadoes Probability**: ${event.watch_parameters.additional_tornadoes_probability}%` : null,
61
+ event.watch_parameters.combined_hail_wind_probability ? `**Combined Hail/Wind Probability**: ${event.watch_parameters.combined_hail_wind_probability}%` : null,
62
+ event.watch_parameters.severe_hail_probability ? `**Severe Hail Probability**: ${event.watch_parameters.severe_hail_probability}%` : null,
63
+ event.watch_parameters.hail_2in_probability ? `**Hail ≥2in Probability**: ${event.watch_parameters.hail_2in_probability}%` : null,
64
+ event.watch_parameters.max_hail_in ? `**Max Hail Inches**: ${event.watch_parameters.max_hail_in}` : null,
65
+ event.watch_parameters.severe_wind_probability ? `**Severe Wind Probability**: ${event.watch_parameters.severe_wind_probability}%` : null,
66
+ event.watch_parameters.max_wind_surface ? `**Max Surface Wind**: ${event.watch_parameters.max_wind_surface}` : null,
67
+ event.watch_parameters.max_tops_x100feet ? `**Max Tops (x100 feet)**: ${event.watch_parameters.max_tops_x100feet}` : null,
53
68
  (event.parameters.tags?.length > 0) ? `**Tags**: ${event.parameters.tags.join(', ')}` : null,
54
69
  (() => {
55
70
  const val = event.geocode?.office?.name ?? `N/A`
@@ -57,8 +72,6 @@ export const createWebhook = async (options: CreateWebhookOptions): Promise<void
57
72
  return (val || th) ? `**Sender**: ${val} ${th ? `(${th})` : ''}` : null;
58
73
  })(),
59
74
  event.metadata?.tracking ? `**Tracking**: ${event.metadata.tracking}` : null,
60
- event.metadata?.vtec?.vtec ? `**VTEC**: ${event.metadata.vtec?.vtec}` : null,
61
- event.metadata?.filtered_proximity != null ? `**Currently in polygon (Node)**: ${event.metadata.filtered_proximity ? 'Yes' : 'No'}` : null,
62
75
  (() => {
63
76
  const desc = (event.description || '').split('\n').map(l => l.trim()).filter(Boolean).join('\n');
64
77
  return desc ? '```' + '\n' + desc + '\n' + '```' : null;
@@ -86,10 +99,12 @@ export const createWebhook = async (options: CreateWebhookOptions): Promise<void
86
99
  content: settings.message ?? "",
87
100
  embeds: [embed]
88
101
  }));
89
- form.append("file", Buffer.from(JSON.stringify({ type: "FeatureCollection", features: [(getCleanedEvent(options.event))] }, null, 2)), {
90
- filename: `${event.event}_${event.status}_${event.metadata.tracking}.json`,
91
- contentType: "application/json"
92
- });
102
+ if (settings.upload) {
103
+ form.append("file", Buffer.from(JSON.stringify((getCleanedEvent(event)), null, 2)), {
104
+ filename: `${event.event}_${event.status}_${event.metadata.tracking}.json`,
105
+ contentType: "application/json"
106
+ });
107
+ }
93
108
  await createHttp({
94
109
  url: settings.webhook,
95
110
  timeout: 2000,
@@ -21,6 +21,7 @@ export type TypeWebhook = {
21
21
  webhook: string
22
22
  title: string
23
23
  message: string
24
+ upload: boolean
24
25
  rate: number
25
26
  events: string[]
26
27
  }
package/src/bootstrap.ts CHANGED
@@ -21,7 +21,7 @@ import path from 'path'
21
21
  import { EventEmitter } from 'node:events';
22
22
 
23
23
  export const bootstrap = {
24
- version: `3.0.2`,
24
+ version: `3.0.3`,
25
25
  isReady: true,
26
26
  ratelimits: {},
27
27
  session_xmpp: null,
package/test.js CHANGED
@@ -34,6 +34,7 @@ const NOAAWeatherWireService = new Manager({
34
34
  webhook: "https://discord.com/api/webhooks/XXXXXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
35
35
  title: "AtmosphericX - (Severe Weather Events)",
36
36
  message: `<@user_id>`,
37
+ upload: true,
37
38
  events: [`Severe Thunderstorm Warning`, `Radar Indicated Tornado Warning`],
38
39
  rate: 1,
39
40
  },
@@ -41,6 +42,7 @@ const NOAAWeatherWireService = new Manager({
41
42
  webhook: "https://discord.com/api/webhooks/XXXXXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
42
43
  title: "AtmosphericX - (All Events)",
43
44
  message: `<@user_id>`,
45
+ upload: false,
44
46
  events: [],
45
47
  rate: 5,
46
48
  }