@atmosx/event-product-parser 3.0.47 → 3.0.48
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/dist/cjs/index.cjs +42 -9483
- package/dist/esm/index.mjs +42 -9483
- package/package.json +4 -5
- package/src/@building/building.attachments.ts +2 -2
- package/src/@manager/manager.updateListener.ts +9 -12
- package/src/@modules/@utilities/utilities.createHttp.ts +40 -64
- package/src/@modules/@utilities/utilities.setCronSchedule.ts +1 -1
- package/src/bootstrap.ts +1 -1
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atmosx/event-product-parser",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.48",
|
|
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",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "git+https://github.com/AtmosphericX/event-product-parser",
|
|
10
|
-
"branch": "beta"
|
|
10
|
+
"branch": "v3-beta-branch"
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
13
|
"start": "cd ./test && node ./index.js",
|
|
@@ -33,14 +33,13 @@
|
|
|
33
33
|
},
|
|
34
34
|
"homepage": "https://github.com/AtmosphericX/event-product-parser#readme",
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"express-ws": "5.0.2",
|
|
37
|
-
"express": "5.2.1",
|
|
38
36
|
"@xmpp/client": "0.14.0",
|
|
39
37
|
"better-sqlite3": "12.9.0",
|
|
40
38
|
"croner": "10.0.1",
|
|
39
|
+
"express": "5.2.1",
|
|
40
|
+
"express-ws": "5.0.2",
|
|
41
41
|
"jszip": "3.10.1",
|
|
42
42
|
"polygon-clipping": "0.15.7",
|
|
43
|
-
"request": "2.88.2",
|
|
44
43
|
"say": "0.16.0",
|
|
45
44
|
"shapefile": "0.6.6",
|
|
46
45
|
"typescript": "5.9.3",
|
|
@@ -38,12 +38,12 @@ type BroadcastifyResponse = {
|
|
|
38
38
|
|
|
39
39
|
export const getEventAttachments = (event: TypeEvent): GetEventAttachmentsResponse[] | null => {
|
|
40
40
|
let attachments = [];
|
|
41
|
-
const
|
|
41
|
+
const issuanceTime = getLatestIssuance();
|
|
42
42
|
const spcNumber = event?.properties?.discussion_parameters?.discussion_number;
|
|
43
43
|
const watchNumber = event?.properties?.watch_parameters?.watch_number;
|
|
44
44
|
const locations = event?.properties?.locations_array;
|
|
45
45
|
const events = [
|
|
46
|
-
{ target: "Day 1", attachment: `https://www.spc.noaa.gov/products/outlook/day1otlk_${
|
|
46
|
+
{ target: "Day 1", attachment: `https://www.spc.noaa.gov/products/outlook/day1otlk_${issuanceTime}.png` },
|
|
47
47
|
{ target: "Day 2", attachment: `https://www.spc.noaa.gov/products/outlook/day2otlk.png` },
|
|
48
48
|
{ target: "Day 3", attachment: `https://www.spc.noaa.gov/products/outlook/day3otlk.png` },
|
|
49
49
|
{ target: "Mesoscale Discussion", attachment: `https://www.spc.noaa.gov/products/md/mcd${spcNumber}.png` },
|
|
@@ -27,7 +27,8 @@ import { getEmebed } from "../@parsers/@text/text.getEmbed";
|
|
|
27
27
|
import { getCleanedEvent } from "../@building/building.clean"
|
|
28
28
|
import { createHttp } from "../@modules/@utilities/utilities.createHttp";
|
|
29
29
|
import { existsSync, mkdirSync, writeFileSync, readFileSync, appendFileSync } from "fs";
|
|
30
|
-
import
|
|
30
|
+
import { setWarning } from "../@modules/@utilities/utilities.setWarning";
|
|
31
|
+
|
|
31
32
|
|
|
32
33
|
|
|
33
34
|
|
|
@@ -94,7 +95,7 @@ export const updateListener = async (event: TypeEvent): Promise<void> => {
|
|
|
94
95
|
}
|
|
95
96
|
|
|
96
97
|
if (webhook.enabled && webhook.destination) {
|
|
97
|
-
const ratelimit = setTimeoutAction({ identifier: webhook.destination, interval: webhook.ratelimit, max: webhook.ratelimit, addTime: true })
|
|
98
|
+
const ratelimit = setTimeoutAction({ identifier: webhook.destination, interval: webhook.ratelimit * 2, max: webhook.ratelimit, addTime: true })
|
|
98
99
|
const form = new FormData();
|
|
99
100
|
const embed = {
|
|
100
101
|
title: `${metadata.name} (${metadata.status})`,
|
|
@@ -128,19 +129,13 @@ export const updateListener = async (event: TypeEvent): Promise<void> => {
|
|
|
128
129
|
}
|
|
129
130
|
|
|
130
131
|
if (uploads?.file) {
|
|
131
|
-
form.append("fUpload", Buffer.from(metadata.file), {
|
|
132
|
-
filename: `${properties.event}_${properties.status}_${properties.metadata.tracking}.txt`,
|
|
133
|
-
contentType: "application/text"
|
|
134
|
-
});
|
|
132
|
+
form.append("fUpload", new Blob([Buffer.from(metadata.file)], {type: "application/text"}), `${properties.event}_${properties.status}_${properties.metadata.tracking}.txt`)
|
|
135
133
|
}
|
|
136
134
|
|
|
137
135
|
if (uploads?.eas) {
|
|
138
136
|
if (metadata.eas) {
|
|
139
137
|
const file = readFileSync(metadata.eas)
|
|
140
|
-
form.append("fEas", Buffer.from(file), {
|
|
141
|
-
filename: `${properties.event}_${properties.status}_${properties.metadata.tracking}_eas.mp3`,
|
|
142
|
-
contentType: "audio/mpeg"
|
|
143
|
-
});
|
|
138
|
+
form.append("fEas", new Blob([Buffer.from(file)], { type: "audio/mpeg" }), `${properties.event}_${properties.status}_${properties.metadata.tracking}_eas.mp3`)
|
|
144
139
|
}
|
|
145
140
|
}
|
|
146
141
|
|
|
@@ -150,13 +145,15 @@ export const updateListener = async (event: TypeEvent): Promise<void> => {
|
|
|
150
145
|
embeds: [embed]
|
|
151
146
|
}));
|
|
152
147
|
|
|
153
|
-
await createHttp({
|
|
148
|
+
const a = await createHttp({
|
|
154
149
|
url: webhook.destination,
|
|
155
150
|
timeout: 5000,
|
|
156
151
|
method: `POST`,
|
|
157
|
-
headers: form.getHeaders(),
|
|
158
152
|
body: form
|
|
159
153
|
})
|
|
154
|
+
if (a.error) {
|
|
155
|
+
setWarning({ message: `Failed to send webhook: ${a.error.message}` })
|
|
156
|
+
}
|
|
160
157
|
}
|
|
161
158
|
}
|
|
162
159
|
}
|
|
@@ -17,10 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import request from 'request'
|
|
21
|
-
|
|
22
20
|
interface CreateHttpOptions {
|
|
23
|
-
proxy?: string
|
|
24
21
|
url: string
|
|
25
22
|
headers?: any
|
|
26
23
|
timeout?: number
|
|
@@ -30,65 +27,44 @@ interface CreateHttpOptions {
|
|
|
30
27
|
}
|
|
31
28
|
|
|
32
29
|
export const createHttp = async (options: CreateHttpOptions): Promise<any> => {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
options: requestOptions,
|
|
74
|
-
status: response.statusCode ?? -1,
|
|
75
|
-
message: `Empty Response Body`
|
|
76
|
-
})
|
|
77
|
-
}
|
|
78
|
-
resolve({
|
|
79
|
-
error: false,
|
|
80
|
-
options: requestOptions,
|
|
81
|
-
status: response.statusCode ?? -1,
|
|
82
|
-
message: body
|
|
83
|
-
})
|
|
84
|
-
})
|
|
85
|
-
} catch (error) {
|
|
86
|
-
return resolve({
|
|
87
|
-
error: true,
|
|
88
|
-
options: {},
|
|
89
|
-
status: -1,
|
|
90
|
-
message: error.message ?? `Unknown Error`
|
|
91
|
-
})
|
|
92
|
-
}
|
|
93
|
-
})
|
|
30
|
+
const requestOptions: RequestInit = {
|
|
31
|
+
method: options.method ?? "GET",
|
|
32
|
+
headers: options.headers ?? {
|
|
33
|
+
"User-Agent": "AtmosphericX",
|
|
34
|
+
"Accept": "application/geo+json, text/plain, */*; q=0.9",
|
|
35
|
+
"Accept-Language": "en-US,en;q=0.9",
|
|
36
|
+
},
|
|
37
|
+
signal: AbortSignal.timeout(options.timeout ?? 10_000),
|
|
38
|
+
redirect: "follow"
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
const returnHttp = function(error: boolean,status: number, message: string) {
|
|
43
|
+
return { error: error, options: requestOptions, status, message };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (options?.formData) {
|
|
47
|
+
requestOptions.body = options.formData;
|
|
48
|
+
} else if (options?.body != undefined) {
|
|
49
|
+
requestOptions.body =
|
|
50
|
+
options.body instanceof FormData
|
|
51
|
+
? options.body
|
|
52
|
+
: typeof options.body === "string"
|
|
53
|
+
? options.body
|
|
54
|
+
: JSON.stringify(options.body);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
const response = await fetch(
|
|
59
|
+
options?.url ?? `https://api.weather.gov/alerts/active`,
|
|
60
|
+
requestOptions
|
|
61
|
+
)
|
|
62
|
+
const body = await response.text();
|
|
63
|
+
if (!response.ok) {
|
|
64
|
+
return returnHttp(true, response.status, `HTTP Status Code ${response.status} (${response.statusText})`)
|
|
65
|
+
}
|
|
66
|
+
return returnHttp(false, response.status, body)
|
|
67
|
+
} catch (error) {
|
|
68
|
+
return returnHttp(true, 500, `Internal Server Error: ${error}`)
|
|
69
|
+
}
|
|
94
70
|
}
|