@atmosx/event-product-parser 3.0.42 → 3.0.46
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 +70 -22
- package/SUPPORTED_EVENTS.md +369 -0
- package/dist/cjs/index.cjs +1990 -1758
- package/dist/esm/index.mjs +1560 -1329
- package/dist/index.d.mts +44 -20
- package/dist/index.d.ts +44 -20
- package/package.json +1 -1
- package/src/@building/building.attachments.ts +42 -0
- package/src/@building/building.create.ts +2 -2
- package/src/@building/building.enhance.ts +8 -4
- package/src/@building/building.geometry.ts +1 -1
- package/src/@building/building.headers.ts +1 -1
- package/src/@building/building.office.ts +4 -4
- package/src/@building/building.properties.ts +15 -13
- package/src/@building/building.signature.ts +11 -11
- package/src/@building/building.tags.ts +2 -2
- package/src/@building/building.tracking.ts +6 -6
- package/src/@building/building.validate.ts +5 -3
- package/src/@core/core.createEvent.ts +82 -0
- package/src/@core/core.query.ts +1 -1
- package/src/@core/core.start.ts +1 -1
- package/src/@dictionaries/{dictionaries.eventActions.ts → dictionaries.actions.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventAwipAbreviations.ts → dictionaries.awips.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventCancelMessages.ts → dictionaries.cancellation.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventCauses.ts → dictionaries.causes.ts} +1 -1
- package/src/@dictionaries/{dictionaries.statusCorrelationText.ts → dictionaries.correlations.ts} +1 -1
- package/src/@dictionaries/{dictionaries.betterEventNames.ts → dictionaries.enhanced.ts} +13 -2
- package/src/@dictionaries/{dictionaries.eventTypes.ts → dictionaries.events.ts} +1 -1
- package/src/@dictionaries/{dictionaries.regExp.ts → dictionaries.expressions.ts} +1 -1
- package/src/@dictionaries/{dictionaries.hailStrings.ts → dictionaries.hail.ts} +4 -1
- package/src/@dictionaries/{dictionaries.officeICAOs.ts → dictionaries.icao.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventsMatchText.ts → dictionaries.matches.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventProducts.ts → dictionaries.products.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventRecords.ts → dictionaries.records.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventSeverity.ts → dictionaries.severity.ts} +1 -1
- package/src/@dictionaries/{dictionaries.shapefileLinks.ts → dictionaries.shapefiles.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventStatus.ts → dictionaries.status.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventTags.ts → dictionaries.tags.ts} +1 -1
- package/src/@dictionaries/{dictionaries.testSignatures.ts → dictionaries.test.ts} +3 -2
- package/src/@events/events.api.ts +19 -14
- package/src/@events/events.text.ts +5 -4
- package/src/@events/events.ugc.ts +5 -4
- package/src/@events/events.vtec.ts +5 -4
- package/src/@manager/manager.mkEvent.ts +4 -4
- package/src/@manager/manager.rmEvent.ts +3 -2
- package/src/@manager/manager.setHash.ts +1 -1
- package/src/@manager/manager.updateListener.ts +124 -0
- package/src/@modules/@database/database.cache.ts +1 -1
- package/src/@modules/@database/database.init.ts +1 -1
- package/src/@modules/@database/database.shapefiles.ts +3 -3
- package/src/@modules/@database/database.stanza.ts +2 -2
- package/src/@modules/@eas/eas.getCleanDescription.ts +91 -0
- package/src/@modules/@eas/eas.getTTS.ts +54 -0
- package/src/@modules/@eas/eas.setEasTone.ts +40 -30
- package/src/@modules/@stanza/stanza.getAwipsType.ts +3 -3
- package/src/@modules/@stanza/stanza.validate.ts +5 -5
- package/src/@modules/@utilities/utilities.getLatestIssuance.ts +32 -0
- package/src/@modules/@utilities/utilities.getSettings.ts +1 -1
- package/src/@modules/@utilities/utilities.setCronSchedule.ts +30 -2
- package/src/@modules/@utilities/utilities.setSettings.ts +1 -1
- package/src/@modules/@utilities/utilities.setWarning.ts +1 -1
- package/src/@modules/@xmpp/xmpp.xDeploy.ts +1 -1
- package/src/@modules/@xmpp/xmpp.xReconnect.ts +1 -1
- package/src/@modules/@xmpp/xmpp.xStanza.ts +1 -1
- package/src/@parsers/@hvtec/hvtec.extract.ts +9 -9
- package/src/@parsers/@pvtec/pvtec.extract.ts +13 -13
- package/src/@parsers/@text/text.getDescriptionFromProduct.ts +2 -2
- package/src/@parsers/@text/text.getEmbed.ts +60 -0
- package/src/@parsers/@ugc/ugc.extract.ts +1 -1
- package/src/@parsers/@ugc/ugc.header.ts +3 -3
- package/src/@types/{types.compiled.ts → type.compiled.ts} +1 -1
- package/src/@types/type.event.ts +6 -4
- package/src/@types/{types.webhook.ts → type.listener.ts} +11 -6
- package/src/@types/type.properties.ts +10 -8
- package/src/@types/{types.settings.ts → type.settings.ts} +7 -5
- package/src/bootstrap.ts +7 -5
- package/src/index.ts +3 -2
- package/test.js +19 -19
- package/src/@dictionaries/dictionaries.transcribedMessageReplacements.ts +0 -68
- package/src/@manager/manager.createWebhook.ts +0 -117
- package/src/@manager/manager.updateWebhooks.ts +0 -49
- /package/src/@types/{types.attributes.ts → type.attributes.ts} +0 -0
- /package/src/@types/{types.hash.ts → type.hash.ts} +0 -0
- /package/src/@types/{types.hvtec.ts → type.hvtec.ts} +0 -0
- /package/src/@types/{types.pvtec.ts → type.pvtec.ts} +0 -0
- /package/src/@types/{types.stanza.ts → type.stanza.ts} +0 -0
- /package/src/@types/{types.ugc.ts → type.ugc.ts} +0 -0
|
@@ -17,23 +17,23 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { TypeHVTEC } from "../../@types/
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
20
|
+
import { TypeHVTEC } from "../../@types/type.hvtec";
|
|
21
|
+
import { dict_causes } from "../../@dictionaries/dictionaries.causes";
|
|
22
|
+
import { dict_records } from "../../@dictionaries/dictionaries.records";
|
|
23
|
+
import { dict_expressions } from "../../@dictionaries/dictionaries.expressions";
|
|
24
|
+
import { dict_severity } from "../../@dictionaries/dictionaries.severity";
|
|
25
25
|
|
|
26
26
|
export const hvExtract = (message: string): TypeHVTEC[] | null => {
|
|
27
|
-
const getHVTECs = message.match(
|
|
27
|
+
const getHVTECs = message.match(dict_expressions.hvtec) ?? [];
|
|
28
28
|
const vtecs: TypeHVTEC[] = [];
|
|
29
29
|
for (const vtec of getHVTECs) {
|
|
30
30
|
const sub = vtec.split(`.`);
|
|
31
31
|
if (sub.length < 7) continue;
|
|
32
32
|
vtecs.push({
|
|
33
33
|
hvtec: vtec,
|
|
34
|
-
severity:
|
|
35
|
-
cause:
|
|
36
|
-
record:
|
|
34
|
+
severity: dict_severity[sub[1]],
|
|
35
|
+
cause: dict_causes[sub[2]],
|
|
36
|
+
record: dict_records[sub[6]]
|
|
37
37
|
})
|
|
38
38
|
}
|
|
39
39
|
return vtecs.length > 0 ? vtecs : null;
|
|
@@ -17,16 +17,17 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { TypePVTEC } from "../../@types/
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
20
|
+
import { TypePVTEC } from "../../@types/type.pvtec";
|
|
21
|
+
import { dict_expressions } from "../../@dictionaries/dictionaries.expressions";
|
|
22
|
+
import { dict_products } from "../../@dictionaries/dictionaries.products";
|
|
23
|
+
import { dict_events } from "../../@dictionaries/dictionaries.events";
|
|
24
|
+
import { dict_actions } from "../../@dictionaries/dictionaries.actions";
|
|
25
|
+
import { dict_status } from "../../@dictionaries/dictionaries.status";
|
|
26
26
|
import { getExpiry } from "./pvtec.expires";
|
|
27
27
|
|
|
28
28
|
export const pvExtract = (message: string): TypePVTEC[] | null => {
|
|
29
|
-
|
|
29
|
+
if (!message) return null;
|
|
30
|
+
const getVTECs = message.match(dict_expressions.pvtec) ?? [];
|
|
30
31
|
const vtecs: TypePVTEC[] = [];
|
|
31
32
|
for (const vtec of getVTECs) {
|
|
32
33
|
const sub = vtec.split(`.`);
|
|
@@ -34,15 +35,14 @@ export const pvExtract = (message: string): TypePVTEC[] | null => {
|
|
|
34
35
|
const dates = sub[6]?.split(`-`);
|
|
35
36
|
vtecs.push({
|
|
36
37
|
vtec: vtec,
|
|
37
|
-
product:
|
|
38
|
+
product: dict_products[sub[0]],
|
|
38
39
|
tracking: `${sub[2]}.${sub[3]}.${sub[4]}.${sub[5]}`,
|
|
39
|
-
event: `${
|
|
40
|
-
status:
|
|
41
|
-
organization: message.match(
|
|
40
|
+
event: `${dict_events[sub[3]]} ${dict_actions[sub[4]]}`,
|
|
41
|
+
status: dict_status[sub[1]],
|
|
42
|
+
organization: message.match(dict_expressions.wmo)?.[0] ?? null,
|
|
42
43
|
expires: getExpiry(dates),
|
|
43
44
|
is_watch: (sub[4] == `A` || sub[4] == `Y`) && (sub[3] == `TO` || sub[3] == `SV`),
|
|
44
|
-
prediction_center: sub[2] == `KWNS`
|
|
45
|
-
? true : false
|
|
45
|
+
prediction_center: sub[2] == `KWNS` ? true : false
|
|
46
46
|
})
|
|
47
47
|
}
|
|
48
48
|
return vtecs.length > 0 ? vtecs : null;
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import {
|
|
20
|
+
import { dict_expressions } from "../../@dictionaries/dictionaries.expressions";
|
|
21
21
|
|
|
22
22
|
interface GetDescriptionFromProductOptions {
|
|
23
23
|
message: string
|
|
@@ -26,7 +26,7 @@ interface GetDescriptionFromProductOptions {
|
|
|
26
26
|
|
|
27
27
|
export const getDescriptionFromProduct = (options: GetDescriptionFromProductOptions): string => {
|
|
28
28
|
let message = options.message;
|
|
29
|
-
const dates = Array.from(message.matchAll(
|
|
29
|
+
const dates = Array.from(message.matchAll(dict_expressions.dateline));
|
|
30
30
|
if (dates.length) {
|
|
31
31
|
const lastMatch = dates[dates.length - 1][0];
|
|
32
32
|
const sIndx = message.lastIndexOf(lastMatch);
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/*
|
|
2
|
+
_ _ _ __ __
|
|
3
|
+
/\ | | | | (_) \ \ / /
|
|
4
|
+
/ \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
|
|
5
|
+
/ /\ \| __| '_ ` _ \ / _ \/ __| '_ \| '_ \ / _ \ '__| |/ __| > <
|
|
6
|
+
/ ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
|
|
7
|
+
/_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
|
|
8
|
+
| |
|
|
9
|
+
|_|
|
|
10
|
+
|
|
11
|
+
Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
|
|
12
|
+
Discord: https://atmosphericx-discord.scriptkitty.cafe
|
|
13
|
+
Ko-Fi: https://ko-fi.com/k3yomi
|
|
14
|
+
Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
|
|
15
|
+
|
|
16
|
+
Internal Package: @atmosx/event-product-parser
|
|
17
|
+
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { TypeEvent } from "../../@types/type.event"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
export const getEmebed = (event: TypeEvent): string => {
|
|
25
|
+
const line = (label: string, value: unknown, condition = true) => condition && value ? `${label} ${value}` : null;
|
|
26
|
+
const isStatement = event.properties.status_metadata.is_statement;
|
|
27
|
+
const isExpired = event.properties.status_metadata.is_expired;
|
|
28
|
+
return [
|
|
29
|
+
line(`**Locations:**`, event?.properties?.locations?.slice(0, 100)),
|
|
30
|
+
line(`**Issued:**`, `<t:${Math.floor(new Date(event.properties.issued).getTime() / 1000)}:R>`, !isExpired),
|
|
31
|
+
line(`**Expires:**`, `<t:${Math.floor(new Date(event.properties.expires).getTime() / 1000)}:R>`, !isStatement),
|
|
32
|
+
line(`**Damage Threat:**`, event?.properties?.parameters?.damage_threat, !isExpired),
|
|
33
|
+
line(`**Flood Threat:**`, event?.properties?.parameters?.flood_threat, !isExpired),
|
|
34
|
+
line(`**Tornado Threat:**`, event?.properties?.parameters?.tornado_threat, !isExpired),
|
|
35
|
+
line(`**Estimated Wind Gusts:**`, `${event?.properties?.parameters?.estimated_wind_gusts} ${event?.properties?.parameters?.wind_threat ? ` (${event?.properties?.parameters?.wind_threat})` : ''}`, !isExpired && event?.properties?.parameters?.estimated_wind_gusts != null),
|
|
36
|
+
line(`**Estimated Hail Size:**`, `${event?.properties?.parameters?.estimated_hail_size} ${event?.properties?.parameters?.hail_threat ? ` (${event?.properties?.parameters?.hail_threat})` : ''}`, !isExpired && event?.properties?.parameters?.estimated_hail_size != null),
|
|
37
|
+
line(`**Discussion:**`, event?.properties?.discussion_parameters?.discussion_number, !isExpired),
|
|
38
|
+
line(`**Concern:**`, event?.properties?.discussion_parameters?.discussion_concerning, !isExpired),
|
|
39
|
+
line(`**SPC Max Tornado Threat:**`, event?.properties?.discussion_parameters?.discussion_max_tornado, !isExpired),
|
|
40
|
+
line(`**SPC Max Hail Threat:**`, event?.properties?.discussion_parameters?.discussion_max_hail, !isExpired),
|
|
41
|
+
line(`**SPC Max Wind Threat:**`, event?.properties?.discussion_parameters?.discussion_max_wind, !isExpired),
|
|
42
|
+
line(`**SPC Watch Issuance Probability:**`, event?.properties?.discussion_parameters?.discussion_watch_issuance ? `${event?.properties?.discussion_parameters?.discussion_watch_issuance}%` : null, !isExpired),
|
|
43
|
+
line(`**Watch Number:**`, event?.properties?.watch_parameters?.watch_number, !isExpired),
|
|
44
|
+
line(`**Strong Tornadoes Probability:**`, event?.properties?.watch_parameters?.strong_tornadoes_probability ? `${event?.properties?.watch_parameters?.strong_tornadoes_probability}%` : null, !isExpired),
|
|
45
|
+
line(`**Additional Tornadoes Probability:**`, event?.properties?.watch_parameters?.additional_tornadoes_probability ? `${event?.properties?.watch_parameters?.additional_tornadoes_probability}%` : null, !isExpired),
|
|
46
|
+
line(`**Combined Hail/Wind Probability:**`, event?.properties?.watch_parameters?.combined_hail_wind_probability ? `${event?.properties?.watch_parameters?.combined_hail_wind_probability}%` : null, !isExpired),
|
|
47
|
+
line(`**Severe Hail Probability:**`, event?.properties?.watch_parameters?.severe_hail_probability ? `${event?.properties?.watch_parameters?.severe_hail_probability}%` : null, !isExpired),
|
|
48
|
+
line(`**Hail >2in Probability:**`, event?.properties?.watch_parameters?.hail_2in_probability ? `${event?.properties?.watch_parameters?.hail_2in_probability}%` : null, !isExpired),
|
|
49
|
+
line(`**Max Hail Inches:**`, event?.properties?.watch_parameters?.max_hail_in, !isExpired),
|
|
50
|
+
line(`**Severe Wind Probability:**`, event?.properties?.watch_parameters?.severe_wind_probability ? `${event?.properties?.watch_parameters?.severe_wind_probability}%` : null, !isExpired),
|
|
51
|
+
line(`**Max Surface Wind:**`, event?.properties?.watch_parameters?.max_wind_surface, !isExpired),
|
|
52
|
+
line(`**Max Tops (x100 feet):**`, event?.properties?.watch_parameters?.max_tops_x100feet, !isExpired),
|
|
53
|
+
line(`**Tags:**`, event?.properties?.parameters?.tags?.length > 0 ? event?.properties?.parameters?.tags.join(', ') : null, !isExpired),
|
|
54
|
+
line(`**Sender:**`, event?.properties?.geocode?.office?.name ? `${event?.properties?.geocode?.office?.name} (${event?.properties?.geocode?.office?.office})` : event?.properties?.geocode?.office?.office),
|
|
55
|
+
line(`**Tracking:**`, event?.properties?.metadata?.tracking),
|
|
56
|
+
line(`**Logs:**`, event?.properties?.metadata?.history?.length > 0 ? event?.properties?.metadata?.history.length : null),
|
|
57
|
+
line(``, event?.properties?.metadata?.attachments?.length > 0 ? `**Attachments:** ${event?.properties?.metadata?.attachments.map(attachment => `[Attachment #${event?.properties?.metadata?.attachments.indexOf(attachment) + 1}](${attachment})`).join(' | ')}` : null),
|
|
58
|
+
line(``, event?.properties?.description ? '```' + '\n' + event?.properties?.description.split('\n').map(l => l.trim()).filter(Boolean).join('\n') + '\n' + '```' : null, !isExpired),
|
|
59
|
+
].filter(Boolean).join('\n');
|
|
60
|
+
}
|
|
@@ -17,12 +17,12 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import {
|
|
20
|
+
import { dict_expressions } from "../../@dictionaries/dictionaries.expressions"
|
|
21
21
|
|
|
22
22
|
export const getUGCHeader = (message: string): string | null => {
|
|
23
|
-
const start = message.search(
|
|
23
|
+
const start = message.search(dict_expressions.ugc1)
|
|
24
24
|
const sub = message.substring(start)
|
|
25
|
-
const end = sub.search(
|
|
25
|
+
const end = sub.search(dict_expressions.ugc2)
|
|
26
26
|
const fin = sub.substring(0, end)
|
|
27
27
|
.replace(/\s+/g, '')
|
|
28
28
|
.slice(0, -1);
|
package/src/@types/type.event.ts
CHANGED
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
20
|
import { TypeEventProperties as BaseTypeEventProperties } from "./type.properties";
|
|
21
|
-
import { TypeHVTEC } from "
|
|
22
|
-
import { TypePVTEC } from "./
|
|
21
|
+
import { TypeHVTEC } from "./type.hvtec";
|
|
22
|
+
import { TypePVTEC } from "./type.pvtec";
|
|
23
23
|
|
|
24
24
|
export type TypeEvent = {
|
|
25
25
|
type: string
|
|
@@ -46,8 +46,8 @@ export type TypeEvent = {
|
|
|
46
46
|
tracking: string
|
|
47
47
|
hash?: string
|
|
48
48
|
header: string
|
|
49
|
-
vtec
|
|
50
|
-
hvtec
|
|
49
|
+
vtec?: TypePVTEC | null
|
|
50
|
+
hvtec?: TypeHVTEC[] | null
|
|
51
51
|
nodes?: {
|
|
52
52
|
id?: string | number
|
|
53
53
|
coordinates: [number, number]
|
|
@@ -63,6 +63,8 @@ export type TypeEvent = {
|
|
|
63
63
|
issued: string
|
|
64
64
|
status: string
|
|
65
65
|
}[]
|
|
66
|
+
attachments?: string[]
|
|
67
|
+
raw: string
|
|
66
68
|
}
|
|
67
69
|
} & BaseTypeEventProperties
|
|
68
70
|
}
|
|
@@ -17,11 +17,16 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
export type
|
|
21
|
-
webhook: string
|
|
22
|
-
title: string
|
|
23
|
-
message: string
|
|
24
|
-
upload: boolean
|
|
25
|
-
rate: number
|
|
20
|
+
export type TypeListener = {
|
|
26
21
|
events: string[]
|
|
22
|
+
webhook?: {
|
|
23
|
+
enabled: boolean
|
|
24
|
+
destination: string
|
|
25
|
+
ratelimit: number
|
|
26
|
+
title: string
|
|
27
|
+
message: string
|
|
28
|
+
}
|
|
29
|
+
uploads?: {
|
|
30
|
+
file?: boolean, eas?: boolean
|
|
31
|
+
}
|
|
27
32
|
}
|
|
@@ -17,12 +17,12 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { TypeAttributes } from "./
|
|
20
|
+
import { TypeAttributes } from "./type.attributes";
|
|
21
21
|
|
|
22
22
|
export type TypeEventProperties = {
|
|
23
23
|
locations: string
|
|
24
24
|
description: string
|
|
25
|
-
attributes
|
|
25
|
+
attributes?: TypeAttributes
|
|
26
26
|
geocode: {
|
|
27
27
|
office: {
|
|
28
28
|
name: string
|
|
@@ -33,7 +33,7 @@ export type TypeEventProperties = {
|
|
|
33
33
|
polygon: string
|
|
34
34
|
polygon_generated: boolean
|
|
35
35
|
}
|
|
36
|
-
parameters
|
|
36
|
+
parameters?: {
|
|
37
37
|
tags: string[]
|
|
38
38
|
instructions: string
|
|
39
39
|
source: string
|
|
@@ -66,10 +66,12 @@ export type TypeEventProperties = {
|
|
|
66
66
|
max_tops_x100feet: string
|
|
67
67
|
pds_watch: boolean
|
|
68
68
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
69
|
+
discussion_parameters?: {
|
|
70
|
+
discussion_number: string
|
|
71
|
+
discussion_concerning: string
|
|
72
|
+
discussion_max_tornado: string
|
|
73
|
+
discussion_max_hail: string
|
|
74
|
+
discussion_max_wind: string
|
|
75
|
+
discussion_watch_issuance: string
|
|
74
76
|
}
|
|
75
77
|
}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import {
|
|
20
|
+
import { TypeListener } from "./type.listener"
|
|
21
21
|
|
|
22
22
|
export type TypeSettings = {
|
|
23
23
|
Database: string
|
|
@@ -57,7 +57,7 @@ export type TypeSettings = {
|
|
|
57
57
|
ShapefileSkipPoints: number
|
|
58
58
|
NodeTTL: number
|
|
59
59
|
NodeMinDistance: number
|
|
60
|
-
|
|
60
|
+
ListenerSettings?: TypeListener[]
|
|
61
61
|
EventFiltering: {
|
|
62
62
|
ListeningEvents: string[]
|
|
63
63
|
ListeningICAO: string[]
|
|
@@ -68,9 +68,11 @@ export type TypeSettings = {
|
|
|
68
68
|
NodeLocationFiltering: boolean
|
|
69
69
|
IgnoreTestProducts: boolean
|
|
70
70
|
},
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
ArchiveSettings: {
|
|
72
|
+
TTL: number,
|
|
73
|
+
TextDirectory: string
|
|
74
|
+
EasDirectory: string
|
|
75
|
+
EasToneout: string
|
|
74
76
|
}
|
|
75
77
|
}
|
|
76
78
|
}
|
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.
|
|
24
|
+
version: `3.0.46`,
|
|
25
25
|
isReady: true,
|
|
26
26
|
ratelimits: {},
|
|
27
27
|
session_xmpp: null,
|
|
@@ -72,7 +72,7 @@ export const bootstrap = {
|
|
|
72
72
|
CallbackInterval: 15,
|
|
73
73
|
EventsEndpoint: `https://api.weather.gov/alerts/active`,
|
|
74
74
|
},
|
|
75
|
-
|
|
75
|
+
ListenerSettings: [],
|
|
76
76
|
GlobalSettings: {
|
|
77
77
|
EventManagement: true,
|
|
78
78
|
BetterEventNames: true,
|
|
@@ -92,9 +92,11 @@ export const bootstrap = {
|
|
|
92
92
|
NodeLocationFiltering: false,
|
|
93
93
|
IgnoreTestProducts: true,
|
|
94
94
|
},
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
ArchiveSettings: {
|
|
96
|
+
TTL: 60,
|
|
97
|
+
TextDirectory: null,
|
|
98
|
+
EasDirectory: null,
|
|
99
|
+
EasToneout: null
|
|
98
100
|
}
|
|
99
101
|
}
|
|
100
102
|
},
|
package/src/index.ts
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { TypeSettings } from './@types/
|
|
20
|
+
import { TypeSettings } from './@types/type.settings'
|
|
21
21
|
import { setSettings } from "./@modules/@utilities/utilities.setSettings"
|
|
22
22
|
import { getEventGeometry } from "./@building/building.geometry";
|
|
23
23
|
import { getCleanedEvent } from "./@building/building.clean"
|
|
@@ -30,6 +30,7 @@ import { setEasTone } from './@modules/@eas/eas.setEasTone';
|
|
|
30
30
|
import { setNode } from "./@core/core.setNode"
|
|
31
31
|
import { getEvents } from "./@core/core.getEvents"
|
|
32
32
|
import { getNodes } from "./@core/core.getNodes"
|
|
33
|
+
import { createEvent } from "./@core/core.createEvent"
|
|
33
34
|
import { getRandomEvent } from './@core/core.getRandomEvent';
|
|
34
35
|
import { query } from './@core/core.query';
|
|
35
36
|
import { clearEvents } from './@core/core.clearEvents';
|
|
@@ -64,7 +65,7 @@ export class Manager {
|
|
|
64
65
|
export default Manager;
|
|
65
66
|
export type { TypeEvent } from './@types/type.event';
|
|
66
67
|
export {
|
|
67
|
-
setSettings, getEventGeometry,
|
|
68
|
+
setSettings, getEventGeometry, createEvent,
|
|
68
69
|
getCleanedEvent, stopService, clearEvents,
|
|
69
70
|
startService, setNode, getRandomEvent,
|
|
70
71
|
getEvents, getNodes, setEasTone, query
|
package/test.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { Manager, setSettings, getSettings, getListener } = require(`../dist/cjs/index.cjs`)
|
|
2
2
|
|
|
3
3
|
const NOAAWeatherWireService = new Manager({
|
|
4
|
-
Database: `
|
|
4
|
+
Database: `shapefiles.db`,
|
|
5
5
|
EnableWireService: false,
|
|
6
6
|
EnableJournal: true,
|
|
7
7
|
NOAAWeatherWireServiceSettings: {
|
|
@@ -29,22 +29,20 @@ const NOAAWeatherWireService = new Manager({
|
|
|
29
29
|
CallbackInterval: 30,
|
|
30
30
|
EventsEndpoint: `https://api.weather.gov/alerts/active`,
|
|
31
31
|
},
|
|
32
|
-
|
|
32
|
+
ListenerSettings: [
|
|
33
33
|
{
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
events: [],
|
|
47
|
-
rate: 5,
|
|
34
|
+
events: [`*Thunderstorm Warning*`, `* Watch`],
|
|
35
|
+
webhook: {
|
|
36
|
+
enabled: true,
|
|
37
|
+
destination: "https://discord.com/api/XXXXXXXXXX/XXXXXXXXXXX",
|
|
38
|
+
title: "AtmosphericX - (Thunderstorm Warnings and Watches)",
|
|
39
|
+
message: "<@&XXXXXXXXXXXXXXXXXXXXX>",
|
|
40
|
+
ratelimit: 1
|
|
41
|
+
},
|
|
42
|
+
uploads: {
|
|
43
|
+
eas: true,
|
|
44
|
+
file: true
|
|
45
|
+
}
|
|
48
46
|
}
|
|
49
47
|
],
|
|
50
48
|
GlobalSettings: {
|
|
@@ -83,9 +81,11 @@ const NOAAWeatherWireService = new Manager({
|
|
|
83
81
|
NodeLocationFiltering: false,
|
|
84
82
|
IgnoreTestProducts: true,
|
|
85
83
|
},
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
84
|
+
ArchiveSettings: {
|
|
85
|
+
TTL: 600,
|
|
86
|
+
TextDirectory: `Storage/TextProducts`,
|
|
87
|
+
EasDirectory: `Storage/EasScenarios`,
|
|
88
|
+
EasToneout: `tone.wav`,
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
})
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
_ _ _ __ __
|
|
3
|
-
/\ | | | | (_) \ \ / /
|
|
4
|
-
/ \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
|
|
5
|
-
/ /\ \| __| '_ ` _ \ / _ \/ __| '_ \| '_ \ / _ \ '__| |/ __| > <
|
|
6
|
-
/ ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
|
|
7
|
-
/_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
|
|
8
|
-
| |
|
|
9
|
-
|_|
|
|
10
|
-
|
|
11
|
-
Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
|
|
12
|
-
Discord: https://atmosphericx-discord.scriptkitty.cafe
|
|
13
|
-
Ko-Fi: https://ko-fi.com/k3yomi
|
|
14
|
-
Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
|
|
15
|
-
|
|
16
|
-
Internal Package: @atmosx/event-product-parser
|
|
17
|
-
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
export const transcribedMessageReplacements: { regex: RegExp, replacement: string }[] = [
|
|
21
|
-
{ regex: /\*/g, replacement: "" },
|
|
22
|
-
{ regex: /\.{3,}/g, replacement: "" },
|
|
23
|
-
{ regex: /\bUTC\b/g, replacement: 'Coordinated Universal Time' },
|
|
24
|
-
{ regex: /\bGMT\b/g, replacement: 'Greenwich Mean Time' },
|
|
25
|
-
{ regex: /\bEST\b(?!\w)/g, replacement: 'Eastern Standard Time' },
|
|
26
|
-
{ regex: /\bEDT\b(?!\w)/g, replacement: 'Eastern Daylight Time' },
|
|
27
|
-
{ regex: /\bCST\b(?!\w)/g, replacement: 'Central Standard Time' },
|
|
28
|
-
{ regex: /\bCDT\b(?!\w)/g, replacement: 'Central Daylight Time' },
|
|
29
|
-
{ regex: /\bMST\b(?!\w)/g, replacement: 'Mountain Standard Time' },
|
|
30
|
-
{ regex: /\bMDT\b(?!\w)/g, replacement: 'Mountain Daylight Time' },
|
|
31
|
-
{ regex: /\bPST\b(?!\w)/g, replacement: 'Pacific Standard Time' },
|
|
32
|
-
{ regex: /\bPDT\b(?!\w)/g, replacement: 'Pacific Daylight Time' },
|
|
33
|
-
{ regex: /\bAKST\b(?!\w)/g, replacement: 'Alaska Standard Time' },
|
|
34
|
-
{ regex: /\bAKDT\b(?!\w)/g, replacement: 'Alaska Daylight Time' },
|
|
35
|
-
{ regex: /\bHST\b(?!\w)/g, replacement: 'Hawaii Standard Time' },
|
|
36
|
-
{ regex: /\bHDT\b(?!\w)/g, replacement: 'Hawaii Daylight Time' },
|
|
37
|
-
{ regex: /\bmph\b(?!\w)/g, replacement: 'miles per hour' },
|
|
38
|
-
{ regex: /\bkm\/h\b(?!\w)/g, replacement: 'kilometers per hour' },
|
|
39
|
-
{ regex: /\bkmh\b(?!\w)/g, replacement: 'kilometers per hour' },
|
|
40
|
-
{ regex: /\bkt\b(?!\w)/g, replacement: 'knots' },
|
|
41
|
-
{ regex: /\bNE\b(?!\w)/g, replacement: 'northeast' },
|
|
42
|
-
{ regex: /\bNW\b(?!\w)/g, replacement: 'northwest' },
|
|
43
|
-
{ regex: /\bSE\b(?!\w)/g, replacement: 'southeast' },
|
|
44
|
-
{ regex: /\bSW\b(?!\w)/g, replacement: 'southwest' },
|
|
45
|
-
{ regex: /\bNM\b(?!\w)/g, replacement: 'nautical miles' },
|
|
46
|
-
{ regex: /\bdeg\b(?!\w)/g, replacement: 'degrees' },
|
|
47
|
-
{ regex: /\btstm\b(?!\w)/g, replacement: 'thunderstorm' },
|
|
48
|
-
{ regex: /\bmm\b(?!\w)/g, replacement: 'millimeters' },
|
|
49
|
-
{ regex: /\bcm\b(?!\w)/g, replacement: 'centimeters' },
|
|
50
|
-
{ regex: /\bin.\b(?!\w)/g, replacement: 'inches' },
|
|
51
|
-
{ regex: /\bft\b(?!\w)/g, replacement: 'feet' },
|
|
52
|
-
{ regex: /\bmi\b(?!\w)/g, replacement: 'miles' },
|
|
53
|
-
{ regex: /\bhr\b(?!\w)/g, replacement: 'hour' },
|
|
54
|
-
{ regex: /\bhourly\b(?!\w)/g, replacement: 'per hour' },
|
|
55
|
-
{ regex: /\bkg\b(?!\w)/g, replacement: 'kilograms' },
|
|
56
|
-
{ regex: /\bg\/kg\b(?!\w)/g, replacement: 'grams per kilogram' },
|
|
57
|
-
{ regex: /\bmb\b(?!\w)/g, replacement: 'millibars' },
|
|
58
|
-
{ regex: /\bhPa\b(?!\w)/g, replacement: 'hectopascals' },
|
|
59
|
-
{ regex: /\bPa\b(?!\w)/g, replacement: 'pascals' },
|
|
60
|
-
{ regex: /\bKPa\b(?!\w)/g, replacement: 'kilopascals' },
|
|
61
|
-
{ regex: /\bC\/hr\b(?!\w)/g, replacement: 'degrees Celsius per hour' },
|
|
62
|
-
{ regex: /\bF\/hr\b(?!\w)/g, replacement: 'degrees Fahrenheit per hour' },
|
|
63
|
-
{ regex: /\bC\/min\b(?!\w)/g, replacement: 'degrees Celsius per minute' },
|
|
64
|
-
{ regex: /\bF\/min\b(?!\w)/g, replacement: 'degrees Fahrenheit per minute' },
|
|
65
|
-
{ regex: /\bC\b(?!\w)/g, replacement: 'degrees Celsius' },
|
|
66
|
-
{ regex: /\bF\b(?!\w)/g, replacement: 'degrees Fahrenheit' },
|
|
67
|
-
];
|
|
68
|
-
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
_ _ _ __ __
|
|
3
|
-
/\ | | | | (_) \ \ / /
|
|
4
|
-
/ \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
|
|
5
|
-
/ /\ \| __| '_ ` _ \ / _ \/ __| '_ \| '_ \ / _ \ '__| |/ __| > <
|
|
6
|
-
/ ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
|
|
7
|
-
/_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
|
|
8
|
-
| |
|
|
9
|
-
|_|
|
|
10
|
-
|
|
11
|
-
Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
|
|
12
|
-
Discord: https://atmosphericx-discord.scriptkitty.cafe
|
|
13
|
-
Ko-Fi: https://ko-fi.com/k3yomi
|
|
14
|
-
Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
|
|
15
|
-
|
|
16
|
-
Internal Package: @atmosx/event-product-parser
|
|
17
|
-
|
|
18
|
-
*/
|
|
19
|
-
|
|
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
|
-
import FormData from "form-data";
|
|
26
|
-
|
|
27
|
-
interface CreateWebhookOptions {
|
|
28
|
-
webhook: TypeWebhook
|
|
29
|
-
event: TypeEvent
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export const createWebhook = async (options: CreateWebhookOptions): Promise<void> => {
|
|
33
|
-
const event = options.event.properties;
|
|
34
|
-
const settings = options.webhook;
|
|
35
|
-
|
|
36
|
-
let body = [
|
|
37
|
-
event.locations ? `**Locations**: ${event.locations.slice(0,100)}` : null,
|
|
38
|
-
event.issued && event.status != `Expired` ? `**Issued**: <t:${Math.floor(new Date(event.issued).getTime()/1000)}:R>` : null,
|
|
39
|
-
event.expires && event.status != `Statement` ? `**Expires**: <t:${Math.floor(new Date(event.expires).getTime()/1000)}:R>` : null,
|
|
40
|
-
(() => {
|
|
41
|
-
const val = event.parameters.estimated_wind_gusts ?? null
|
|
42
|
-
const th = event.parameters.wind_threat ?? null
|
|
43
|
-
const combined = [val, th].filter(Boolean).join(' ');
|
|
44
|
-
return combined ? `**Wind Gusts**: ${val} ${th ? `(${th})` : ''}` : null;
|
|
45
|
-
})(),
|
|
46
|
-
(() => {
|
|
47
|
-
const val = event.parameters.estimated_hail_size ?? null
|
|
48
|
-
const th = event.parameters.hail_threat ?? null
|
|
49
|
-
return (val ?? th) ? `**Hail Threat**: ${val} ${th ? `(${th})` : ''}` : null;
|
|
50
|
-
})(),
|
|
51
|
-
event.parameters.damage_threat ? `**Damage Threat**: ${event.parameters.damage_threat}` : null,
|
|
52
|
-
event.parameters.flood_threat ? `**Flood Threat**: ${event.parameters.flood_threat}` : null,
|
|
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,
|
|
68
|
-
(event.parameters.tags?.length > 0) ? `**Tags**: ${event.parameters.tags.join(', ')}` : null,
|
|
69
|
-
(() => {
|
|
70
|
-
const val = event.geocode?.office?.name ?? `N/A`
|
|
71
|
-
const th = event.geocode?.office?.office ?? null
|
|
72
|
-
return (val ?? th) ? `**Sender**: ${val} ${th ? `(${th})` : ''}` : null;
|
|
73
|
-
})(),
|
|
74
|
-
event.metadata?.tracking ? `**Tracking**: ${event.metadata.tracking}` : null,
|
|
75
|
-
event.metadata.history?.length > 0 ? `**Logs**: ${event.metadata.history.length}` : null,
|
|
76
|
-
(() => {
|
|
77
|
-
if (event.status == `Expired`) { return null }
|
|
78
|
-
const desc = (event.description ?? '').split('\n').map(l => l.trim()).filter(Boolean).join('\n');
|
|
79
|
-
return desc ? '```' + '\n' + desc + '\n' + '```' : null;
|
|
80
|
-
})(),
|
|
81
|
-
].filter(Boolean).join('\n');
|
|
82
|
-
|
|
83
|
-
const isLimited = setTimeoutAction({ identifier: options.webhook.webhook, interval: options.webhook.rate, max: options.webhook.rate, addTime: true })
|
|
84
|
-
if (isLimited.limited) { return }
|
|
85
|
-
|
|
86
|
-
if (body.length > 1900) {
|
|
87
|
-
body = body.substring(0, 1900) + "\n\n[Message truncated due to length]";
|
|
88
|
-
const blocks = (body.match(/```/g) ?? []).length;
|
|
89
|
-
if (blocks % 2 !== 0) body += "```";
|
|
90
|
-
}
|
|
91
|
-
const form = new FormData();
|
|
92
|
-
const embed = {
|
|
93
|
-
title: `${event.event} (${event.status})`,
|
|
94
|
-
description: body,
|
|
95
|
-
color: 16711680,
|
|
96
|
-
timestamp: new Date().toISOString(),
|
|
97
|
-
footer: { text: settings.title }
|
|
98
|
-
};
|
|
99
|
-
form.append("payload_json", JSON.stringify({
|
|
100
|
-
username: settings.title ?? "AtmosphericX",
|
|
101
|
-
content: settings.message ?? "",
|
|
102
|
-
embeds: [embed]
|
|
103
|
-
}));
|
|
104
|
-
if (settings.upload) {
|
|
105
|
-
form.append("file", Buffer.from(JSON.stringify((getCleanedEvent(event)), null, 2)), {
|
|
106
|
-
filename: `${event.event}_${event.status}_${event.metadata.tracking}.json`,
|
|
107
|
-
contentType: "application/json"
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
await createHttp({
|
|
111
|
-
url: settings.webhook,
|
|
112
|
-
timeout: 2000,
|
|
113
|
-
method: `POST`,
|
|
114
|
-
headers: form.getHeaders(),
|
|
115
|
-
body: form
|
|
116
|
-
})
|
|
117
|
-
}
|