@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/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@atmosx/event-product-parser",
3
- "version": "3.0.47",
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 latestTime = getLatestIssuance();
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_${latestTime}.png` },
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 FormData from "form-data";
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
- return new Promise((resolve, reject) => {
34
- try {
35
- const requestOptions = {
36
- url: options.url ?? `https://api.weather.gov/alerts/active`,
37
- headers: options.headers ?? {
38
- "User-Agent": "AtmosphericX",
39
- "Accept": "application/geo+json, text/plain, */*; q=0.9",
40
- "Accept-Language": "en-US,en;q=0.9"
41
- },
42
- method: options.method ?? `GET`,
43
- timeout: options.timeout ?? 10e3,
44
- proxy: options.proxy ?? null,
45
- maxRedirects: 1,
46
- };
47
- if (options.formData) {
48
- requestOptions['formData'] = options.formData;
49
- } else if (options.body) {
50
- requestOptions['body'] = options.body;
51
- }
52
-
53
- request(requestOptions, (error, response, body) => {
54
- if (error) {
55
- return resolve({
56
- error: true,
57
- options: requestOptions,
58
- status: -1,
59
- message: error.message ?? `Unknown Error`
60
- })
61
- }
62
- if (response.statusCode < 200 || response.statusCode >= 300) {
63
- return resolve({
64
- error: true,
65
- options: requestOptions,
66
- status: response.statusCode ?? -1,
67
- message: `HTTP Status Code ${response.statusCode ?? `Unknown Status Code`} (${body})`
68
- })
69
- }
70
- if (body == undefined || body == null) {
71
- return resolve({
72
- error: true,
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
  }
@@ -68,7 +68,7 @@ export const setCronSchedule = async (): Promise<void> => {
68
68
  }
69
69
  })
70
70
  if (response.error) {
71
- return setEventEmit({
71
+ return setEventEmit({
72
72
  event: `onServiceStatus`,
73
73
  metadata: {
74
74
  type: "fetch-api",
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.47`,
24
+ version: `3.0.48`,
25
25
  isReady: true,
26
26
  ratelimits: {},
27
27
  session_xmpp: null,