@atmosx/event-product-parser 2.0.16 → 3.0.0
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 +4 -237
- package/dist/cjs/index.cjs +2233 -3105
- package/dist/esm/index.mjs +2233 -3108
- package/package.json +3 -2
- package/src/@building/building.clean.ts +30 -0
- package/src/@building/building.create.ts +42 -0
- package/src/@building/building.enhance.ts +56 -0
- package/src/@building/building.geometry.ts +42 -0
- package/src/@building/building.headers.ts +37 -0
- package/src/@building/building.office.ts +43 -0
- package/src/@building/building.polygon.ts +71 -0
- package/src/@building/building.properties.ts +89 -0
- package/src/@building/building.signature.ts +78 -0
- package/src/@building/building.tags.ts +24 -0
- package/src/@building/building.tracking.ts +68 -0
- package/src/@building/building.validate.ts +132 -0
- package/src/@core/core.callback.ts +39 -0
- package/src/@core/core.getEvents.ts +25 -0
- package/src/@core/core.getNodes.ts +25 -0
- package/src/@core/core.listener.ts +24 -0
- package/src/@core/core.setNode.ts +81 -0
- package/src/@core/core.start.ts +54 -0
- package/src/@core/core.stop.ts +32 -0
- package/src/@dictionaries/dictionaries.betterEventNames.ts +85 -0
- package/src/@dictionaries/dictionaries.eventActions.ts +28 -0
- package/src/@dictionaries/{awips.ts → dictionaries.eventAwipAbreviations.ts} +12 -6
- package/src/@dictionaries/dictionaries.eventCancelMessages.ts +29 -0
- package/src/@dictionaries/dictionaries.eventCauses.ts +36 -0
- package/src/@dictionaries/dictionaries.eventProducts.ts +25 -0
- package/src/@dictionaries/dictionaries.eventRecords.ts +25 -0
- package/src/@dictionaries/dictionaries.eventSeverity.ts +27 -0
- package/src/@dictionaries/dictionaries.eventStatus.ts +31 -0
- package/src/@dictionaries/{signatures.ts → dictionaries.eventTags.ts} +13 -68
- package/src/@dictionaries/dictionaries.eventTypes.ts +82 -0
- package/src/@dictionaries/dictionaries.eventsOffshore.ts +31 -0
- package/src/@dictionaries/dictionaries.hailStrings.ts +31 -0
- package/src/@dictionaries/{icao.ts → dictionaries.officeICAOs.ts} +13 -6
- package/src/@dictionaries/dictionaries.regExp.ts +28 -0
- package/src/@dictionaries/dictionaries.shapefileLinks.ts +36 -0
- package/src/@dictionaries/dictionaries.statusCorrelationText.ts +40 -0
- package/src/@dictionaries/dictionaries.test_signatures.ts +23 -0
- package/src/@dictionaries/dictionaries.transcribedMessageReplacements.ts +68 -0
- package/src/@events/events.api.ts +113 -0
- package/src/@events/events.text.ts +79 -0
- package/src/@events/events.ugc.ts +83 -0
- package/src/@events/events.vtec.ts +87 -0
- package/src/@manager/manager.mkEvent.ts +79 -0
- package/src/@manager/manager.rmEvent.ts +44 -0
- package/src/@manager/manager.setHash.ts +37 -0
- package/src/@manager/manager.updateNodes.ts +51 -0
- package/src/@modules/@database/database.cache.ts +48 -0
- package/src/@modules/@database/database.init.ts +45 -0
- package/src/@modules/@database/database.shapefiles.ts +97 -0
- package/src/@modules/@database/database.stanza.ts +47 -0
- package/src/@modules/@stanza/stanza.getAwipsType.ts +46 -0
- package/src/@modules/@stanza/stanza.validate.ts +50 -0
- package/src/@modules/@utilities/utilities.createHttp.ts +75 -0
- package/src/@modules/@utilities/utilities.getFormattedTime.ts +43 -0
- package/src/@modules/@utilities/utilities.getSettings.ts +25 -0
- package/src/@modules/@utilities/utilities.getShapeNearestPoint.ts +114 -0
- package/src/@modules/@utilities/utilities.setCronSchedule.ts +38 -0
- package/src/@modules/@utilities/utilities.setEventEmit.ts +41 -0
- package/src/@modules/@utilities/utilities.setListener.ts +30 -0
- package/src/@modules/@utilities/utilities.setSettings.ts +42 -0
- package/src/@modules/@utilities/utilities.setSleep.ts +33 -0
- package/src/@modules/@utilities/utilities.setTimeoutAction.ts +59 -0
- package/src/@modules/@utilities/utilities.setWarning.ts +34 -0
- package/src/@modules/@xmpp/xmpp.xDeploy.ts +58 -0
- package/src/@modules/@xmpp/xmpp.xError.ts +38 -0
- package/src/@modules/@xmpp/xmpp.xOffline.ts +38 -0
- package/src/@modules/@xmpp/xmpp.xOnline.ts +61 -0
- package/src/@modules/@xmpp/xmpp.xReconnect.ts +59 -0
- package/src/@modules/@xmpp/xmpp.xStanza.ts +63 -0
- package/src/@parsers/@hvtec/hvtec.extract.ts +40 -0
- package/src/@parsers/@pvtec/pvtec.expires.ts +26 -0
- package/src/@parsers/@pvtec/pvtec.extract.ts +50 -0
- package/src/@parsers/@text/text.getDescriptionFromProduct.ts +53 -0
- package/src/@parsers/@text/text.getPolygonFromProduct.ts +32 -0
- package/src/@parsers/@text/text.getTextFromProduct.ts +43 -0
- package/src/@parsers/@text/text.getXML.ts +61 -0
- package/src/@parsers/@ugc/ugc.coordinates.ts +110 -0
- package/src/@parsers/@ugc/ugc.expiry.ts +32 -0
- package/src/@parsers/@ugc/ugc.extract.ts +37 -0
- package/src/@parsers/@ugc/ugc.header.ts +30 -0
- package/src/@parsers/@ugc/ugc.locations.ts +29 -0
- package/src/@parsers/@ugc/ugc.zones.ts +52 -0
- package/src/@types/type.event.ts +67 -0
- package/src/@types/type.properties.ts +75 -0
- package/src/@types/types.attributes.ts +28 -0
- package/src/@types/types.compiled.ts +35 -0
- package/src/@types/types.hash.ts +24 -0
- package/src/@types/types.hvtec.ts +25 -0
- package/src/@types/types.pvtec.ts +29 -0
- package/src/@types/types.settings.ts +71 -0
- package/src/@types/types.stanza.ts +37 -0
- package/src/@types/types.ugc.ts +24 -0
- package/src/bootstrap.ts +82 -163
- package/src/index.ts +48 -216
- package/test.js +65 -49
- package/src/@dictionaries/events.ts +0 -168
- package/src/@parsers/@events/api.ts +0 -146
- package/src/@parsers/@events/cap.ts +0 -123
- package/src/@parsers/@events/text.ts +0 -104
- package/src/@parsers/@events/ugc.ts +0 -107
- package/src/@parsers/@events/vtec.ts +0 -76
- package/src/@parsers/events.ts +0 -392
- package/src/@parsers/hvtec.ts +0 -46
- package/src/@parsers/pvtec.ts +0 -72
- package/src/@parsers/stanza.ts +0 -97
- package/src/@parsers/text.ts +0 -165
- package/src/@parsers/ugc.ts +0 -247
- package/src/@submodules/database.ts +0 -201
- package/src/@submodules/eas.ts +0 -490
- package/src/@submodules/utils.ts +0 -191
- package/src/@submodules/xmpp.ts +0 -142
- package/src/types.ts +0 -259
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
_ _ __ __
|
|
3
|
-
/\ | | | | (_) \ \ / /
|
|
4
|
-
/ \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
|
|
5
|
-
/ /\ \| __| "_ ` _ \ / _ \/ __| "_ \| "_ \ / _ \ "__| |/ __| > <
|
|
6
|
-
/ ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
|
|
7
|
-
/_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
|
|
8
|
-
| |
|
|
9
|
-
|_|
|
|
10
|
-
|
|
11
|
-
Written by: KiyoWx (k3yomi)
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import * as types from '../../types';
|
|
15
|
-
import * as loader from '../../bootstrap';
|
|
16
|
-
import EventParser from '../events';
|
|
17
|
-
import TextParser from '../text';
|
|
18
|
-
|
|
19
|
-
export class APIAlerts {
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* @function getTracking
|
|
23
|
-
* @description
|
|
24
|
-
* Generates a unique tracking identifier for a CAP alert based on extracted XML values.
|
|
25
|
-
* If VTEC information is available, it constructs the tracking ID from the VTEC components.
|
|
26
|
-
* Otherwise, it uses the WMO identifier along with TTAI and CCCC attributes.
|
|
27
|
-
*
|
|
28
|
-
* @private
|
|
29
|
-
* @static
|
|
30
|
-
* @param {Record<string, string>} extracted
|
|
31
|
-
* @returns {string}
|
|
32
|
-
*/
|
|
33
|
-
private static getTracking(extracted: Record<string, string>): string {
|
|
34
|
-
if (extracted.pVtec) {
|
|
35
|
-
const vtecValue = Array.isArray(extracted.pVtec)
|
|
36
|
-
? extracted.pVtec[0] : extracted.pVtec;
|
|
37
|
-
const splitPVTEC = vtecValue.split('.');
|
|
38
|
-
return `${splitPVTEC[2]}-${splitPVTEC[3]}-${splitPVTEC[4]}-${splitPVTEC[5]}`;
|
|
39
|
-
}
|
|
40
|
-
const wmoMatch = extracted.wmoidentifier?.match(/([A-Z]{4}\d{2})\s+([A-Z]{4})/);
|
|
41
|
-
const station = wmoMatch?.[2] ?? 'N/A';
|
|
42
|
-
if (extracted.featureId) {
|
|
43
|
-
const idMatch = extracted.featureId.match(/([a-f0-9]+)\.(\d+)\.(\d+)$/);
|
|
44
|
-
return `${station}-${idMatch?.[1] ?? 'N/A'}`;
|
|
45
|
-
}
|
|
46
|
-
const id = wmoMatch?.[1] ?? 'N/A';
|
|
47
|
-
return `${station}-${id}`;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* @function getICAO
|
|
52
|
-
* @description
|
|
53
|
-
* Extracts the sender's ICAO code and corresponding name from a VTEC string.
|
|
54
|
-
*
|
|
55
|
-
* @private
|
|
56
|
-
* @static
|
|
57
|
-
* @param {string} pVtec
|
|
58
|
-
* @returns {{ icao: any; name: any; }}
|
|
59
|
-
*/
|
|
60
|
-
private static getICAO(pVtec: string): { icao: any; name: any; } {
|
|
61
|
-
const icao = pVtec ? pVtec.split(`.`)[2] : null;
|
|
62
|
-
const name = loader.definitions.ICAO?.[icao] ?? null;
|
|
63
|
-
return { icao, name };
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* @function event
|
|
68
|
-
* @description
|
|
69
|
-
* Processes validated API alert messages, extracting relevant information and compiling it into structured event objects.
|
|
70
|
-
*
|
|
71
|
-
* @public
|
|
72
|
-
* @static
|
|
73
|
-
* @async
|
|
74
|
-
* @param {types.StanzaCompiled} validated
|
|
75
|
-
* @returns {*}
|
|
76
|
-
*/
|
|
77
|
-
public static async event(validated: types.StanzaCompiled): Promise<void> {
|
|
78
|
-
let processed = [] as unknown[];
|
|
79
|
-
const messages = Object.values(JSON.parse(validated.message).features) as types.EventCompiled[];
|
|
80
|
-
for (let feature of messages) {
|
|
81
|
-
const tick = performance.now();
|
|
82
|
-
const getPVTEC = feature?.properties?.parameters?.VTEC?.[0] ?? null;
|
|
83
|
-
const getWmo = feature?.properties?.parameters?.WMOidentifier?.[0] ?? null;
|
|
84
|
-
const getUgc = feature?.properties?.geocode?.UGC ?? null;
|
|
85
|
-
const getHeadline = feature?.properties?.parameters?.NWSheadline?.[0] ?? "";
|
|
86
|
-
const getDescription = `${getHeadline} ${feature?.properties?.description ?? ``}`
|
|
87
|
-
const getAWIP = feature?.properties?.parameters?.AWIPSidentifier?.[0] ?? null;
|
|
88
|
-
const getHeader = EventParser.getHeader({ ...{ getAwip: {prefix: getAWIP?.slice(0, -3) }},} as types.StanzaAttributes);
|
|
89
|
-
const getSource = TextParser.textProductToString(getDescription, `SOURCE...`, [`.`]) ?? null;
|
|
90
|
-
const getOffice = this.getICAO(getPVTEC ?? ``);
|
|
91
|
-
processed.push({
|
|
92
|
-
type: "Feature",
|
|
93
|
-
properties: {
|
|
94
|
-
locations: feature?.properties?.areaDesc ?? null,
|
|
95
|
-
event: feature?.properties?.event ?? null,
|
|
96
|
-
issued: feature?.properties?.sent ? new Date(feature?.properties?.sent).toISOString() : null,
|
|
97
|
-
expires: feature?.properties?.expires ? new Date(feature?.properties?.expires).toISOString() : null,
|
|
98
|
-
parent: feature?.properties?.event ?? null,
|
|
99
|
-
action_type: feature?.properties?.messageType ?? null,
|
|
100
|
-
description: feature?.properties?.description ?? null,
|
|
101
|
-
instruction: feature?.properties?.instruction ?? null,
|
|
102
|
-
sender_name: getOffice.name ?? null,
|
|
103
|
-
sender_icao: getOffice.icao ?? null,
|
|
104
|
-
attributes: validated.attributes,
|
|
105
|
-
geocode: {
|
|
106
|
-
UGC: feature?.properties?.geocode?.UGC ?? [],
|
|
107
|
-
generated: feature?.geometry?.coordinates.length > 0 ? Buffer.from(JSON.stringify([feature?.geometry?.coordinates[0]])).toString('base64') : null,
|
|
108
|
-
},
|
|
109
|
-
raw: {},
|
|
110
|
-
parameters: {
|
|
111
|
-
wmo: feature?.properties?.parameters?.WMOidentifier?.[0] ?? getWmo ?? null,
|
|
112
|
-
source: getSource,
|
|
113
|
-
max_hail_size: feature?.properties?.parameters?.maxHailSize ?? null,
|
|
114
|
-
max_wind_gust: feature?.properties?.parameters?.maxWindGust ?? null,
|
|
115
|
-
damage_threat: feature?.properties?.parameters?.thunderstormDamageThreat?.[0] ?? null,
|
|
116
|
-
tornado_detection: feature?.properties?.parameters?.tornadoDetection?.[0] ?? null,
|
|
117
|
-
flood_detection: feature?.properties?.parameters?.floodDetection?.[0] ?? null,
|
|
118
|
-
discussion_tornado_intensity: null,
|
|
119
|
-
discussion_wind_intensity: null,
|
|
120
|
-
discussion_hail_intensity: null,
|
|
121
|
-
},
|
|
122
|
-
details: {
|
|
123
|
-
performance: performance.now() - tick,
|
|
124
|
-
source: `api-parser`,
|
|
125
|
-
tracking: this.getTracking({
|
|
126
|
-
pVtec: getPVTEC,
|
|
127
|
-
wmoidentifier: getWmo,
|
|
128
|
-
featureId: feature?.id,
|
|
129
|
-
ugc: getUgc ? getUgc.join(`,`) : null
|
|
130
|
-
}),
|
|
131
|
-
header: getHeader,
|
|
132
|
-
pvtec: getPVTEC ?? null,
|
|
133
|
-
history: [{
|
|
134
|
-
description: feature?.properties?.description ?? null,
|
|
135
|
-
action: feature?.properties?.messageType ?? null,
|
|
136
|
-
issued: feature?.properties?.sent ? new Date(feature?.properties?.sent).toISOString() : null
|
|
137
|
-
}],
|
|
138
|
-
},
|
|
139
|
-
},
|
|
140
|
-
})
|
|
141
|
-
}
|
|
142
|
-
EventParser.validateEvents(processed);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
export default APIAlerts;
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
_ _ __ __
|
|
3
|
-
/\ | | | | (_) \ \ / /
|
|
4
|
-
/ \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
|
|
5
|
-
/ /\ \| __| "_ ` _ \ / _ \/ __| "_ \| "_ \ / _ \ "__| |/ __| > <
|
|
6
|
-
/ ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
|
|
7
|
-
/_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
|
|
8
|
-
| |
|
|
9
|
-
|_|
|
|
10
|
-
|
|
11
|
-
Written by: KiyoWx (k3yomi)
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import * as types from '../../types';
|
|
15
|
-
import * as loader from '../../bootstrap';
|
|
16
|
-
import EventParser from '../events';
|
|
17
|
-
import TextParser from '../text';
|
|
18
|
-
|
|
19
|
-
export class CapAlerts {
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* @function getTracking
|
|
23
|
-
* @description
|
|
24
|
-
* Generates a unique tracking identifier for a CAP alert based on extracted XML values.
|
|
25
|
-
* If VTEC information is available, it constructs the tracking ID from the VTEC components.
|
|
26
|
-
* Otherwise, it uses the WMO identifier along with TTAI and CCCC attributes.
|
|
27
|
-
*
|
|
28
|
-
* @private
|
|
29
|
-
* @static
|
|
30
|
-
* @param {Record<string, string>} extracted
|
|
31
|
-
* @returns {string}
|
|
32
|
-
*/
|
|
33
|
-
private static getTracking(extracted: Record<string, string>, metadata: types.StanzaAttributes): string {
|
|
34
|
-
return extracted.vtec ? (() => {
|
|
35
|
-
const vtecValue = Array.isArray(extracted.vtec) ? extracted.vtec[0] : extracted.vtec;
|
|
36
|
-
const splitPVTEC = vtecValue.split('.');
|
|
37
|
-
return `${splitPVTEC[2]}-${splitPVTEC[3]}-${splitPVTEC[4]}-${splitPVTEC[5]}`;
|
|
38
|
-
})() : `${extracted.wmoidentifier.substring(extracted.wmoidentifier.length - 4)}-${metadata.attributes.ttaaii}-${metadata.attributes.id.slice(-4)}`;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* @function event
|
|
43
|
-
* @description
|
|
44
|
-
* Processes validated CAP alert messages, extracting relevant information and compiling it into structured event objects.
|
|
45
|
-
*
|
|
46
|
-
* @public
|
|
47
|
-
* @static
|
|
48
|
-
* @async
|
|
49
|
-
* @param {types.StanzaCompiled} validated
|
|
50
|
-
* @returns {*}
|
|
51
|
-
*/
|
|
52
|
-
public static async event(validated: types.StanzaCompiled): Promise<void> {
|
|
53
|
-
let processed = [] as unknown[];
|
|
54
|
-
const messages = validated?.message?.split(/(?=\$\$)/g)?.map(msg => msg.trim())?.filter(msg => msg && msg !== "$$");
|
|
55
|
-
if (!messages || messages.length == 0) { return }
|
|
56
|
-
for (let i = 0; i < messages.length; i++) {
|
|
57
|
-
const tick = performance.now();
|
|
58
|
-
let message = messages[i]
|
|
59
|
-
const attributes = validated as types.StanzaAttributes;
|
|
60
|
-
message = message.substring(message.indexOf(`<?xml version="1.0"`), message.lastIndexOf(`>`) + 1);
|
|
61
|
-
const parser = new loader.packages.xml2js.Parser({ explicitArray: false, mergeAttrs: true, trim: true })
|
|
62
|
-
const parsed = await parser.parseStringPromise(message);
|
|
63
|
-
if (parsed == null || parsed.alert == null) continue;
|
|
64
|
-
const extracted = TextParser.getXmlValues(parsed, [
|
|
65
|
-
`vtec`, `wmoidentifier`, `ugc`, `areadesc`,
|
|
66
|
-
`expires`, `sent`, `msgtype`, `description`,
|
|
67
|
-
`event`, `sendername`, `tornadodetection`, `polygon`,
|
|
68
|
-
`maxHailSize`, `maxWindGust`, `thunderstormdamagethreat`,
|
|
69
|
-
`tornadodamagethreat`, `waterspoutdetection`, `flooddetection`,
|
|
70
|
-
]);
|
|
71
|
-
const getHeader = EventParser.getHeader({ ...validated.attributes,} as types.StanzaAttributes);
|
|
72
|
-
const getSource = TextParser.textProductToString(extracted.description, `SOURCE...`, [`.`]) ?? null;
|
|
73
|
-
processed.push({
|
|
74
|
-
type: "Feature",
|
|
75
|
-
properties: {
|
|
76
|
-
locations: extracted.areadesc ?? null,
|
|
77
|
-
event: extracted.event ?? null,
|
|
78
|
-
issued: extracted.sent ? new Date(extracted.sent).toISOString() : null,
|
|
79
|
-
expires: extracted.expires ? new Date(extracted.expires).toISOString() : null,
|
|
80
|
-
parent: extracted.event ?? null,
|
|
81
|
-
action_type: extracted.msgtype ?? null,
|
|
82
|
-
description: extracted.description ?? null,
|
|
83
|
-
instruction: null,
|
|
84
|
-
sender_name: extracted.sendername ?? null,
|
|
85
|
-
sender_icao: extracted.wmoidentifier ? extracted.wmoidentifier.substring(extracted.wmoidentifier.length - 4) : null,
|
|
86
|
-
attributes: attributes,
|
|
87
|
-
geocode: {
|
|
88
|
-
UGC: extracted.ugc ? (Array.isArray(extracted.ugc) ? extracted.ugc : [extracted.ugc]) : [],
|
|
89
|
-
generated: extracted?.polygon?.length > 0 ? Buffer.from(JSON.stringify([extracted.polygon.split(' ').map((coord: string) => {
|
|
90
|
-
const [lat, lon] = coord.split(',').map(Number);
|
|
91
|
-
return [lon, lat];
|
|
92
|
-
})])).toString('base64') : null,
|
|
93
|
-
},
|
|
94
|
-
raw: {attributes},
|
|
95
|
-
parameters: {
|
|
96
|
-
wmo: extracted.wmoidentifier ?? null,
|
|
97
|
-
source: getSource,
|
|
98
|
-
max_hail_size: extracted.maxHailSize ?? null,
|
|
99
|
-
max_wind_gust: extracted.maxWindGust ?? null,
|
|
100
|
-
damage_threat: extracted.thunderstormdamagethreat ?? null,
|
|
101
|
-
tornado_detection: extracted.tornadodetection ?? extracted.waterspoutdetection ?? null,
|
|
102
|
-
flood_detection: extracted.flooddetection ?? null,
|
|
103
|
-
discussion_tornado_intensity: null,
|
|
104
|
-
discussion_wind_intensity: null,
|
|
105
|
-
discussion_hail_intensity: null,
|
|
106
|
-
},
|
|
107
|
-
details: {
|
|
108
|
-
performance: performance.now() - tick,
|
|
109
|
-
source: `cap-parser`,
|
|
110
|
-
tracking: this.getTracking(extracted, attributes),
|
|
111
|
-
header: getHeader,
|
|
112
|
-
pvtec: extracted.vtec ?? null,
|
|
113
|
-
hvtec: null,
|
|
114
|
-
history: [{ description: extracted.description ?? null, issued: extracted.sent ? new Date(extracted.sent).toISOString() : null, type: extracted.msgtype ?? null }],
|
|
115
|
-
},
|
|
116
|
-
},
|
|
117
|
-
})
|
|
118
|
-
}
|
|
119
|
-
EventParser.validateEvents(processed);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export default CapAlerts;
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
_ _ __ __
|
|
3
|
-
/\ | | | | (_) \ \ / /
|
|
4
|
-
/ \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
|
|
5
|
-
/ /\ \| __| "_ ` _ \ / _ \/ __| "_ \| "_ \ / _ \ "__| |/ __| > <
|
|
6
|
-
/ ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
|
|
7
|
-
/_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
|
|
8
|
-
| |
|
|
9
|
-
|_|
|
|
10
|
-
|
|
11
|
-
Written by: KiyoWx (k3yomi)
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import * as types from '../../types';
|
|
15
|
-
import * as loader from '../../bootstrap';
|
|
16
|
-
import EventParser from '../events';
|
|
17
|
-
|
|
18
|
-
export class TextAlerts {
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* @function getTracking
|
|
22
|
-
* @description
|
|
23
|
-
* Generates a unique tracking identifier for an event using the sender's ICAO
|
|
24
|
-
* and some attributes.
|
|
25
|
-
*
|
|
26
|
-
* @private
|
|
27
|
-
* @static
|
|
28
|
-
* @param {types.EventProperties} properties
|
|
29
|
-
* @returns {string}
|
|
30
|
-
*/
|
|
31
|
-
private static getTracking(properties: types.EventProperties): string {
|
|
32
|
-
return `${properties.sender_icao}-${properties.raw.attributes.ttaaii}-${properties?.raw?.attributes?.id.slice(-4) ?? 'N/A'}`;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* @function getEvent
|
|
37
|
-
* @description
|
|
38
|
-
* Determines the event name from a text message and its AWIPS attributes.
|
|
39
|
-
* If the message contains a known offshore event keyword, that offshore
|
|
40
|
-
* event is returned. Otherwise, the event type from the AWIPS attributes
|
|
41
|
-
* is formatted into a human-readable string with each word capitalized.
|
|
42
|
-
*
|
|
43
|
-
* @private
|
|
44
|
-
* @static
|
|
45
|
-
* @param {string} message
|
|
46
|
-
* @param {types.StanzaAttributes} metadata
|
|
47
|
-
* @returns {string}
|
|
48
|
-
*/
|
|
49
|
-
private static getEvent(message: string, metadata: types.StanzaAttributes): string {
|
|
50
|
-
const offshoreEvent = Object.keys(loader.definitions.offshore).find(event => message.toLowerCase().includes(event.toLowerCase()));
|
|
51
|
-
if (offshoreEvent != undefined ) return Object.keys(loader.definitions.offshore).find(event => message.toLowerCase().includes(event.toLowerCase()));
|
|
52
|
-
return metadata.awipsType.type.split(`-`).map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* @function event
|
|
57
|
-
* @description
|
|
58
|
-
* Processes a compiled text-based NOAA Stanza message and extracts relevant
|
|
59
|
-
* event information. Splits the message into multiple segments based on
|
|
60
|
-
* markers such as "$$", "ISSUED TIME...", or separator lines, generates
|
|
61
|
-
* base properties, headers, event names, and tracking information for
|
|
62
|
-
* each segment, then validates and emits the processed events.
|
|
63
|
-
*
|
|
64
|
-
* @public
|
|
65
|
-
* @static
|
|
66
|
-
* @async
|
|
67
|
-
* @param {types.StanzaCompiled} validated
|
|
68
|
-
* @returns {Promise<void>}
|
|
69
|
-
*/
|
|
70
|
-
public static async event(validated: types.StanzaCompiled): Promise<void> {
|
|
71
|
-
let processed = [] as unknown[];
|
|
72
|
-
const messages = validated?.message?.split(/(?=\$\$)/g)?.map(msg => msg.trim())?.filter(msg => msg && msg !== "$$");
|
|
73
|
-
if (!messages || messages.length == 0) { return }
|
|
74
|
-
for (let i = 0; i < messages.length; i++) {
|
|
75
|
-
const tick = performance.now();
|
|
76
|
-
const message = messages[i]
|
|
77
|
-
const attributes = validated as types.StanzaAttributes;
|
|
78
|
-
const baseProperties = await EventParser.getBaseProperties(message, attributes) as types.EventProperties;
|
|
79
|
-
const getHeader = EventParser.getHeader({ ...validated.attributes, ...baseProperties.raw } as types.StanzaAttributes, baseProperties)
|
|
80
|
-
const getEvent = this.getEvent(message, attributes);
|
|
81
|
-
processed.push({
|
|
82
|
-
properties: {
|
|
83
|
-
event: getEvent,
|
|
84
|
-
parent: getEvent,
|
|
85
|
-
action_type: `Issued`,
|
|
86
|
-
...baseProperties,
|
|
87
|
-
details: {
|
|
88
|
-
type: "Feature",
|
|
89
|
-
performance: performance.now() - tick,
|
|
90
|
-
source: `text-parser`,
|
|
91
|
-
tracking: this.getTracking(baseProperties),
|
|
92
|
-
header: getHeader,
|
|
93
|
-
pvtec: null,
|
|
94
|
-
hvtec: null,
|
|
95
|
-
history: [{ description: baseProperties.description, issued: baseProperties.issued, type: `Issued` }],
|
|
96
|
-
},
|
|
97
|
-
},
|
|
98
|
-
})
|
|
99
|
-
}
|
|
100
|
-
EventParser.validateEvents(processed);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
export default TextAlerts;
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
_ _ __ __
|
|
3
|
-
/\ | | | | (_) \ \ / /
|
|
4
|
-
/ \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
|
|
5
|
-
/ /\ \| __| "_ ` _ \ / _ \/ __| "_ \| "_ \ / _ \ "__| |/ __| > <
|
|
6
|
-
/ ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
|
|
7
|
-
/_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
|
|
8
|
-
| |
|
|
9
|
-
|_|
|
|
10
|
-
|
|
11
|
-
Written by: KiyoWx (k3yomi)
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import * as types from '../../types';
|
|
15
|
-
import * as loader from '../../bootstrap';
|
|
16
|
-
import UgcParser from '../ugc';
|
|
17
|
-
import EventParser from '../events';
|
|
18
|
-
|
|
19
|
-
export class UGCAlerts {
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* @function getTracking
|
|
23
|
-
* @description
|
|
24
|
-
* Generates a unique tracking identifier for an event using the sender's ICAO
|
|
25
|
-
* and some attributes.
|
|
26
|
-
*
|
|
27
|
-
* @private
|
|
28
|
-
* @static
|
|
29
|
-
* @param {types.EventProperties} properties
|
|
30
|
-
* @returns {string}
|
|
31
|
-
*/
|
|
32
|
-
private static getTracking(properties: types.EventProperties): string {
|
|
33
|
-
return `${properties.sender_icao}-${properties.raw.attributes.ttaaii}-${properties?.raw?.attributes?.id.slice(-4) ?? 'N/A'}`;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* @function getEvent
|
|
38
|
-
* @description
|
|
39
|
-
* Determines the human-readable event name from a message and AWIPS attributes.
|
|
40
|
-
* - Checks if the message contains any predefined offshore event keywords
|
|
41
|
-
* and returns the matching offshore event if found.
|
|
42
|
-
* - Otherwise, returns a formatted event type string from the provided attributes,
|
|
43
|
-
* capitalizing the first letter of each word.
|
|
44
|
-
*
|
|
45
|
-
* @private
|
|
46
|
-
* @static
|
|
47
|
-
* @param {string} message
|
|
48
|
-
* @param {Record<string, any>} metadata
|
|
49
|
-
* @returns {string}
|
|
50
|
-
*/
|
|
51
|
-
private static getEvent(message: string, metadata: types.StanzaAttributes): string {
|
|
52
|
-
const offshoreEvent = Object.keys(loader.definitions.offshore).find(event => message.toLowerCase().includes(event.toLowerCase()));
|
|
53
|
-
if (offshoreEvent != undefined ) return Object.keys(loader.definitions.offshore).find(event => message.toLowerCase().includes(event.toLowerCase()));
|
|
54
|
-
return metadata.awipsType.type.split(`-`).map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* @function event
|
|
59
|
-
* @description
|
|
60
|
-
* Processes a validated stanza message, extracting UGC entries and
|
|
61
|
-
* computing base properties for non-VTEC events. Each extracted event
|
|
62
|
-
* is enriched with metadata, performance timing, and history information,
|
|
63
|
-
* then filtered and emitted via `EventParser.validateEvents`.
|
|
64
|
-
*
|
|
65
|
-
* @static
|
|
66
|
-
* @async
|
|
67
|
-
* @param {types.StanzaCompiled} validated
|
|
68
|
-
* @returns {Promise<void>}
|
|
69
|
-
*/
|
|
70
|
-
public static async event(validated: types.StanzaCompiled): Promise<void> {
|
|
71
|
-
let processed = [] as unknown[];
|
|
72
|
-
const messages = validated?.message?.split(/(?=\$\$)/g)?.map(msg => msg.trim())?.filter(msg => msg && msg !== "$$");
|
|
73
|
-
if (!messages || messages.length == 0) { return }
|
|
74
|
-
for (let i = 0; i < messages.length; i++) {
|
|
75
|
-
const tick = performance.now();
|
|
76
|
-
const message = messages[i]
|
|
77
|
-
const getUGC = await UgcParser.ugcExtractor(message) as types.UGCEntry
|
|
78
|
-
if (getUGC != null) {
|
|
79
|
-
const attributes = validated as types.StanzaAttributes;
|
|
80
|
-
const baseProperties = await EventParser.getBaseProperties(message, attributes, getUGC) as types.EventProperties;
|
|
81
|
-
const getHeader = EventParser.getHeader({ ...attributes, ...baseProperties.raw } as types.StanzaAttributes, baseProperties);
|
|
82
|
-
const getEvent = this.getEvent(message, attributes);
|
|
83
|
-
processed.push({
|
|
84
|
-
type: "Feature",
|
|
85
|
-
properties: {
|
|
86
|
-
event: getEvent,
|
|
87
|
-
parent: getEvent,
|
|
88
|
-
action_type: `Issued`,
|
|
89
|
-
...baseProperties,
|
|
90
|
-
details: {
|
|
91
|
-
performance: performance.now() - tick,
|
|
92
|
-
source: `ugc-parser`,
|
|
93
|
-
tracking: this.getTracking(baseProperties),
|
|
94
|
-
header: getHeader,
|
|
95
|
-
pvtec: null,
|
|
96
|
-
hvtec: null,
|
|
97
|
-
history: [{ description: baseProperties.description, issued: baseProperties.issued, type: `Issued` }],
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
})
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
EventParser.validateEvents(processed);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export default UGCAlerts;
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
_ _ __ __
|
|
3
|
-
/\ | | | | (_) \ \ / /
|
|
4
|
-
/ \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
|
|
5
|
-
/ /\ \| __| "_ ` _ \ / _ \/ __| "_ \| "_ \ / _ \ "__| |/ __| > <
|
|
6
|
-
/ ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
|
|
7
|
-
/_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
|
|
8
|
-
| |
|
|
9
|
-
|_|
|
|
10
|
-
|
|
11
|
-
Written by: KiyoWx (k3yomi)
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import * as types from '../../types';
|
|
15
|
-
import pVtecParser from '../pvtec';
|
|
16
|
-
import hVtecParser from '../hvtec';
|
|
17
|
-
import UgcParser from '../ugc';
|
|
18
|
-
import EventParser from '../events';
|
|
19
|
-
|
|
20
|
-
export class VTECAlerts {
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* @function event
|
|
24
|
-
* @description
|
|
25
|
-
* Processes a validated stanza message, extracting VTEC and UGC entries,
|
|
26
|
-
* computing base properties, generating headers, and preparing structured
|
|
27
|
-
* event objects for downstream handling. Each extracted event is enriched
|
|
28
|
-
* with metadata, performance timing, and history information.
|
|
29
|
-
*
|
|
30
|
-
* @static
|
|
31
|
-
* @async
|
|
32
|
-
* @param {types.StanzaCompiled} validated
|
|
33
|
-
* @returns {Promise<void>}
|
|
34
|
-
*/
|
|
35
|
-
public static async event(validated: types.StanzaCompiled): Promise<void> {
|
|
36
|
-
let processed = [] as unknown[];
|
|
37
|
-
const messages = validated?.message?.split(/(?=\$\$)/g)?.map(msg => msg.trim())?.filter(msg => msg && msg !== "$$");
|
|
38
|
-
if (!messages || messages.length == 0) { return }
|
|
39
|
-
for (let i = 0; i < messages.length; i++) {
|
|
40
|
-
const tick = performance.now();
|
|
41
|
-
const message = messages[i]
|
|
42
|
-
const attributes = validated as types.StanzaAttributes;
|
|
43
|
-
const getPVTEC = await pVtecParser.pVtecExtractor(message) as types.PVtecEntry[]
|
|
44
|
-
const getHVTEC = await hVtecParser.HVtecExtractor(message) as types.HVtecEntry
|
|
45
|
-
const getUGC = await UgcParser.ugcExtractor(message) as types.UGCEntry
|
|
46
|
-
if (getPVTEC != null && getUGC != null) {
|
|
47
|
-
for (let j = 0; j < getPVTEC.length; j++) {
|
|
48
|
-
const pVtec = getPVTEC[j];
|
|
49
|
-
const baseProperties = await EventParser.getBaseProperties(message, attributes, getUGC, pVtec, getHVTEC) as types.EventProperties;
|
|
50
|
-
const getHeader = EventParser.getHeader({ ...validated.attributes, ...baseProperties.raw } as types.StanzaAttributes, baseProperties, pVtec);
|
|
51
|
-
processed.push({
|
|
52
|
-
type: "Feature",
|
|
53
|
-
properties: {
|
|
54
|
-
event: pVtec.event,
|
|
55
|
-
parent: pVtec.event,
|
|
56
|
-
action_type: pVtec.status,
|
|
57
|
-
...baseProperties,
|
|
58
|
-
details: {
|
|
59
|
-
performance: performance.now() - tick,
|
|
60
|
-
source: `pvtec-parser`,
|
|
61
|
-
tracking: pVtec.tracking,
|
|
62
|
-
header: getHeader,
|
|
63
|
-
pvtec: pVtec.raw,
|
|
64
|
-
hvtec: getHVTEC != null ? getHVTEC.raw : null,
|
|
65
|
-
history: [{ description: baseProperties.description, issued: baseProperties.issued, type: pVtec.status }],
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
})
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
EventParser.validateEvents(processed);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export default VTECAlerts;
|