@atmosx/event-product-parser 3.0.621 → 3.1.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.
Files changed (200) hide show
  1. package/.github/CHANGELOGS.md +52 -0
  2. package/.github/CODE_OF_CONDUCT.md +24 -1
  3. package/.github/CONTRIBUTING.md +22 -3
  4. package/.github/FUNDING.yaml +3 -0
  5. package/.github/LICENSE +24 -1
  6. package/.github/SECURITY.md +25 -6
  7. package/.github/docs/chapters/general-configurations.md +109 -0
  8. package/.github/docs/chapters/sources-and-attributes.md +219 -0
  9. package/README.md +56 -146
  10. package/dist/index.cjs +25333 -0
  11. package/package.json +17 -11
  12. package/pnpm-workspace.yaml +4 -0
  13. package/src/bootstrap.ts +67 -52
  14. package/src/components/audio/GenerateAudioMessage.ts +149 -0
  15. package/src/{@modules/@eas → components/audio/components}/GetCleanDescription.ts +2 -2
  16. package/src/{@modules/@eas → components/audio/components}/GetFloatPCM16.ts +2 -2
  17. package/src/{@modules/@eas → components/audio/components}/GetMergedPCM16.ts +2 -2
  18. package/src/{@modules/@eas → components/audio/components}/GetPCM16.ts +13 -8
  19. package/src/{@modules/@eas → components/audio/components}/GetPCMToFloat.ts +2 -2
  20. package/src/{@modules/@eas → components/audio/components}/GetSampledPCM16.ts +14 -8
  21. package/src/{@modules/@eas → components/audio/components}/GetTTS.ts +17 -10
  22. package/src/{@modules/@eas → components/audio/components}/GetWavPCM16.ts +7 -7
  23. package/src/{@modules/@eas → components/audio/components}/SetAFSK.ts +13 -8
  24. package/src/{@modules/@eas → components/audio/components}/SetAsciiToBits.ts +2 -2
  25. package/src/{@modules/@eas → components/audio/components}/SetAttentionTone.ts +11 -6
  26. package/src/{@modules/@eas → components/audio/components}/SetNoise.ts +12 -7
  27. package/src/{@modules/@eas → components/audio/components}/SetRadioEffect.ts +12 -7
  28. package/src/{@modules/@eas → components/audio/components}/SetSameHeader.ts +22 -14
  29. package/src/components/database/CreateQuery.ts +39 -0
  30. package/src/components/database/InitializeDatabase.ts +71 -0
  31. package/src/components/database/imports/Boundaires.ts +168 -0
  32. package/src/{@modules/@database/ImportBroadcastify.ts → components/database/imports/Broadcastify.ts} +15 -25
  33. package/src/components/database/imports/Census.ts +87 -0
  34. package/src/{@modules/@database/ImportShapefiles.ts → components/database/imports/Shapefiles.ts} +24 -27
  35. package/src/{@modules/@database/ImportStanza.ts → components/database/imports/Stanza.ts} +15 -19
  36. package/src/components/events/CreateEvents.ts +88 -0
  37. package/src/components/events/FilterEvents.ts +149 -0
  38. package/src/{@building/CreateEvent.ts → components/events/ProcessStanza.ts} +22 -24
  39. package/src/components/events/RemoveEvents.ts +74 -0
  40. package/src/{@building → components/events/components}/GetCleanedEvent.ts +2 -2
  41. package/src/{@building → components/events/components}/GetEventAttachments.ts +14 -12
  42. package/src/components/events/components/GetEventDirection.ts +28 -0
  43. package/src/{@building → components/events/components}/GetEventEnhancedName.ts +5 -8
  44. package/src/{@building → components/events/components}/GetEventGeometry.ts +19 -13
  45. package/src/{@building → components/events/components}/GetEventHeader.ts +13 -13
  46. package/src/components/events/components/GetEventMerged.ts +51 -0
  47. package/src/{@building → components/events/components}/GetEventNodes.ts +22 -20
  48. package/src/{@building → components/events/components}/GetEventOffice.ts +13 -13
  49. package/src/components/events/components/GetEventPopulation.ts +58 -0
  50. package/src/components/events/components/GetEventProperties.ts +106 -0
  51. package/src/{@building → components/events/components}/GetEventSignature.ts +9 -9
  52. package/src/{@building → components/events/components}/GetEventTags.ts +3 -3
  53. package/src/components/events/components/GetEventTheme.ts +26 -0
  54. package/src/components/events/components/GetEventTracking.ts +64 -0
  55. package/src/{@modules/@database → components/events/utilities}/GetCachedEvents.ts +18 -15
  56. package/src/{@manager → components/events/utilities}/SetHash.ts +18 -13
  57. package/src/{@manager → components/events/utilities}/UpdateEvents.ts +12 -12
  58. package/src/{@manager → components/events/utilities}/UpdateNode.ts +14 -14
  59. package/src/{@parsers/@text → components/formatting}/GetEmbededText.ts +14 -8
  60. package/src/{@parsers/@text → components/formatting}/GetStringText.ts +15 -11
  61. package/src/{@modules/@utilities → components/geometry}/GetShapeNearestPoint.ts +24 -19
  62. package/src/components/geometry/GetUnionPolygon.ts +36 -0
  63. package/src/components/images/GenerateGraphic.ts +242 -0
  64. package/src/components/images/components/CreateRectangle.ts +22 -0
  65. package/src/components/images/components/CreateText.ts +22 -0
  66. package/src/components/images/modules/CreateSVG.ts +37 -0
  67. package/src/components/images/modules/GetGeographicalBoundaries.ts +72 -0
  68. package/src/components/images/modules/GetGeographicalCities.ts +58 -0
  69. package/src/components/images/modules/GetGeographicalEvents.ts +48 -0
  70. package/src/components/images/modules/GetGeometryBounds.ts +82 -0
  71. package/src/components/images/modules/GetParsedBoundary.ts +58 -0
  72. package/src/components/images/modules/GetSVGPath.ts +53 -0
  73. package/src/components/images/modules/NormalizePolygon.ts +57 -0
  74. package/src/{@modules/@stanza → components/stanza}/GetAwipsType.ts +16 -17
  75. package/src/{@modules/@stanza → components/stanza}/ValidateStanza.ts +27 -15
  76. package/src/{@modules/@utilities → components/utilities}/CreateHttp.ts +26 -26
  77. package/src/components/utilities/EmitThread.ts +97 -0
  78. package/src/{@modules/@utilities → components/utilities}/GetLatestIssuance.ts +2 -2
  79. package/src/{@modules/@utilities → components/utilities}/GetMatched.ts +10 -5
  80. package/src/components/utilities/QueueManager.ts +70 -0
  81. package/src/{@modules/@utilities → components/utilities}/SetDebug.ts +13 -13
  82. package/src/components/utilities/SetEventEmit.ts +42 -0
  83. package/src/{@modules/@utilities → components/utilities}/SetSettings.ts +7 -7
  84. package/src/{@modules/@utilities → components/utilities}/SetSleep.ts +5 -5
  85. package/src/components/utilities/SetTimeoutAction.ts +64 -0
  86. package/src/components/utilities/SetWarning.ts +47 -0
  87. package/src/{@modules/@xmpp → components/xmpp}/DeployXMPP.ts +20 -20
  88. package/src/{@core/CreateListener.ts → components/xmpp/ErrorXMPP.ts} +8 -5
  89. package/src/{@modules/@xmpp → components/xmpp}/OfflineXMPP.ts +13 -13
  90. package/src/{@modules/@xmpp → components/xmpp}/OnlineXMPP.ts +18 -18
  91. package/src/components/xmpp/ReconnectXMPP.ts +64 -0
  92. package/src/{@modules/@xmpp → components/xmpp}/StanzaXMPP.ts +26 -26
  93. package/src/{@enums → enums}/AWIPS.ts +2 -2
  94. package/src/{@enums → enums}/Actions.ts +2 -2
  95. package/src/{@enums → enums}/Cancellation.ts +2 -2
  96. package/src/{@enums → enums}/Causes.ts +2 -2
  97. package/src/{@enums → enums}/Correlations.ts +2 -2
  98. package/src/{@enums → enums}/Enhanced.ts +4 -3
  99. package/src/{@enums → enums}/Events.ts +2 -2
  100. package/src/{@enums → enums}/Expressions.ts +3 -3
  101. package/src/{@enums → enums}/GlobalFilter.ts +2 -2
  102. package/src/{@enums → enums}/Hail.ts +2 -2
  103. package/src/{@enums → enums}/ICAO.ts +2 -2
  104. package/src/{@enums → enums}/Matches.ts +8 -3
  105. package/src/{@enums → enums}/Products.ts +2 -2
  106. package/src/{@enums → enums}/Records.ts +2 -2
  107. package/src/{@enums → enums}/Severity.ts +2 -2
  108. package/src/{@enums → enums}/Shapefiles.ts +2 -2
  109. package/src/{@enums → enums}/States.ts +68 -4
  110. package/src/{@enums → enums}/Status.ts +2 -2
  111. package/src/{@enums → enums}/Strings.ts +2 -2
  112. package/src/{@enums → enums}/Tags.ts +9 -4
  113. package/src/{@enums → enums}/Testing.ts +2 -2
  114. package/src/enums/Themes.ts +70 -0
  115. package/src/events/ParseAPI.ts +133 -0
  116. package/src/{@events → events}/ParseText.ts +24 -22
  117. package/src/{@events → events}/ParseUGC.ts +27 -26
  118. package/src/{@events → events}/ParseVTEC.ts +37 -36
  119. package/src/{@core → exports}/ClearEvents.ts +9 -9
  120. package/src/{@core → exports}/GetEvents.ts +4 -4
  121. package/src/exports/GetNearestCity.ts +45 -0
  122. package/src/{@core → exports}/GetNodes.ts +4 -4
  123. package/src/{@core → exports}/GetRandomEvent.ts +4 -4
  124. package/src/{@core → exports}/GetVersion.ts +4 -4
  125. package/src/exports/ManualEvent.ts +55 -0
  126. package/src/{@core → exports}/QueryStanza.ts +12 -11
  127. package/src/exports/SetNode.ts +100 -0
  128. package/src/{@core → exports}/StartService.ts +23 -22
  129. package/src/{@core → exports}/StopService.ts +10 -10
  130. package/src/index.ts +57 -37
  131. package/src/{@parsers/@hvtec → parsers/hvtec}/HVExtract.ts +7 -7
  132. package/src/{@parsers/@text → parsers/text}/GetDescriptionFromProduct.ts +20 -21
  133. package/src/parsers/text/GetPolygonFromProduct.ts +71 -0
  134. package/src/{@parsers/@text → parsers/text}/GetTextFromProduct.ts +12 -12
  135. package/src/parsers/ugc/GetCache.ts +24 -0
  136. package/src/{@parsers/@ugc → parsers/ugc}/GetExpiry.ts +2 -2
  137. package/src/{@parsers/@ugc/GetUGCHeader.ts → parsers/ugc/GetHeader.ts} +4 -4
  138. package/src/{@parsers/@ugc → parsers/ugc}/GetLocations.ts +10 -10
  139. package/src/parsers/ugc/GetZonePolygon.ts +73 -0
  140. package/src/{@parsers/@ugc → parsers/ugc}/GetZones.ts +3 -3
  141. package/src/{@parsers/@ugc → parsers/ugc}/SetCache.ts +13 -8
  142. package/src/{@parsers/@ugc → parsers/ugc}/UGCExtract.ts +14 -14
  143. package/src/{@parsers/@pvtec → parsers/vtec}/GetExpiry.ts +2 -2
  144. package/src/{@parsers/@pvtec → parsers/vtec}/VTECExtract.ts +17 -17
  145. package/src/tasks/CreateTasks.ts +116 -0
  146. package/src/tasks/TaskGenerateJSON.ts +34 -0
  147. package/src/tasks/TaskGenerateText.ts +34 -0
  148. package/src/tasks/TaskSendNTFY.ts +96 -0
  149. package/src/tasks/TaskSendWebhook.ts +107 -0
  150. package/src/{@types → types/event}/Attributes.ts +2 -3
  151. package/src/{@types → types/event}/Event.ts +8 -7
  152. package/src/{@types → types/event}/HVTEC.ts +2 -2
  153. package/src/{@types → types/event}/Properties.ts +17 -3
  154. package/src/{@types → types/event}/Stanza.ts +2 -2
  155. package/src/{@types → types/event}/VTEC.ts +8 -8
  156. package/src/{@types → types/standard}/Actions.ts +3 -3
  157. package/src/{@types → types/standard}/Hash.ts +5 -5
  158. package/src/{@modules/@utilities/GetSettings.ts → types/standard/Nodes.ts} +15 -7
  159. package/src/{@types → types/standard}/Settings.ts +19 -12
  160. package/src/{@types → types/standard}/StanzaCompiled.ts +15 -15
  161. package/src/{@types → types/standard}/UGC.ts +5 -5
  162. package/tools/build.js +32 -0
  163. package/tsconfig.json +32 -1
  164. package/.github/SUPPORTED_EVENTS.md +0 -370
  165. package/.github/docs/docs-functions.md +0 -30
  166. package/.github/docs/docs-general-configurations.md +0 -209
  167. package/.github/docs/docs-integrations.md +0 -37
  168. package/.github/docs/docs-listeners.md +0 -28
  169. package/.github/docs/docs-source-configuration.md +0 -218
  170. package/.github/docs/docs-technical.md +0 -50
  171. package/.github/logo.png +0 -0
  172. package/.github/samples/SAMPLE_EAS_GENERATION.wav +0 -0
  173. package/.github/samples/SAMPLE_GEOJSON.json +0 -204
  174. package/.github/samples/SAMPLE_TEXT_PRODUCT.txt +0 -119
  175. package/dist/cjs/index.cjs +0 -8005
  176. package/dist/esm/index.mjs +0 -7985
  177. package/src/@building/GetEventProperties.ts +0 -96
  178. package/src/@building/GetEventTracking.ts +0 -68
  179. package/src/@core/ManualEvent.ts +0 -56
  180. package/src/@core/SetNode.ts +0 -81
  181. package/src/@events/ParseAPI.ts +0 -117
  182. package/src/@manager/MakeEvents.ts +0 -106
  183. package/src/@manager/RemoveEvent.ts +0 -70
  184. package/src/@manager/Tasks.ts +0 -246
  185. package/src/@manager/ValidateEvents.ts +0 -142
  186. package/src/@modules/@database/InitializeDatabase.ts +0 -59
  187. package/src/@modules/@eas/GenerateEASMessage.ts +0 -144
  188. package/src/@modules/@utilities/GetFormattedTime.ts +0 -43
  189. package/src/@modules/@utilities/SetCronSchedule.ts +0 -94
  190. package/src/@modules/@utilities/SetEventEmit.ts +0 -41
  191. package/src/@modules/@utilities/SetListener.ts +0 -30
  192. package/src/@modules/@utilities/SetTimeoutAction.ts +0 -64
  193. package/src/@modules/@utilities/SetWarning.ts +0 -34
  194. package/src/@modules/@xmpp/ErrorXMPP.ts +0 -27
  195. package/src/@modules/@xmpp/ReconnectXMPP.ts +0 -64
  196. package/src/@parsers/@text/GetPolygonFromProduct.ts +0 -53
  197. package/src/@parsers/@text/GetXML.ts +0 -61
  198. package/src/@parsers/@ugc/GetCache.ts +0 -24
  199. package/src/@parsers/@ugc/GetZonePolygon.ts +0 -111
  200. package/tsup.config.ts +0 -16
@@ -11,38 +11,38 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
20
- import { TypePVTEC } from "../../@types/VTEC";
21
- import { EnumExpressions } from "../../@enums/Expressions";
22
- import { EnumProducts } from "../../@enums/Products";
23
- import { EnumEvents } from "../../@enums/Events";
24
- import { EnumActions } from "../../@enums/Actions";
25
- import { EnumStatus } from "../../@enums/Status";
26
- import { GetExpiry } from "./GetExpiry";
20
+ import { TypeVTEC } from "TypesEvent/VTEC"
21
+ import { EnumExpressions } from "@Enums/Expressions"
22
+ import { EnumProducts } from "@Enums/Products"
23
+ import { EnumEvents } from "@Enums/Events"
24
+ import { EnumActions } from "@Enums/Actions"
25
+ import { EnumStatus } from "@Enums/Status"
26
+ import { GetExpiry } from "@ParsingVTEC/GetExpiry"
27
27
 
28
- export const VTECExtract = (message: string): TypePVTEC[] | null => {
28
+ export const VTECExtract = (message: string): TypeVTEC[] | null => {
29
29
  if (!message) return null;
30
- const getVTECs = message.match(EnumExpressions.pvtec) ?? [];
31
- const vtecs: TypePVTEC[] = [];
30
+ const getVTECs = message.match(EnumExpressions.vtec) ?? [];
31
+ const vtecs: TypeVTEC[] = [];
32
32
  for (const vtec of getVTECs) {
33
33
  const sub = vtec.split(`.`);
34
34
  if (sub?.length < 7) continue;
35
35
  const dates = sub[6]?.split(`-`);
36
36
  vtecs.push({
37
- vtec: vtec,
38
- product: EnumProducts[sub[0]],
37
+ raw: vtec,
38
+ type: EnumProducts[sub[0]],
39
39
  tracking: `${sub[2]}.${sub[3]}.${sub[4]}.${sub[5]}`,
40
40
  event: `${EnumEvents[sub[3]]} ${EnumActions[sub[4]]}`,
41
41
  status: EnumStatus[sub[1]],
42
- organization: message.match(EnumExpressions.wmo)?.[0] ?? null,
42
+ wmo: message.match(EnumExpressions.wmo)?.[0] ?? null,
43
43
  expires: GetExpiry(dates),
44
- is_watch: (sub[4] == `A` || sub[4] == `Y`) && (sub[3] == `TO` || sub[3] == `SV`),
45
- prediction_center: sub[2] == `KWNS` ? true : false
44
+ watch: (sub[4] == `A` || sub[4] == `Y`) && (sub[3] == `TO` || sub[3] == `SV`),
45
+ wou: sub[2] == `KWNS` ? true : false
46
46
  })
47
47
  }
48
48
  return vtecs.length > 0 ? vtecs : null;
@@ -0,0 +1,116 @@
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: https://atmosphericx.scriptkitty.cafe/documentation
15
+
16
+ Independent Package: @atmosx/event-product-parser
17
+ */
18
+
19
+ import { TypeSettings } from "TypesStandard/Settings"
20
+ import { TypeEvent } from "TypesEvent/Event"
21
+ import { TypeActions } from "TypesStandard/Actions"
22
+ import { Bootstrap } from "@Bootstrap"
23
+ import { SetDebug } from "@Utilities/SetDebug"
24
+ import { GetMatched } from "@Utilities/GetMatched"
25
+ import { GetStringText } from "@Formatting/GetStringText"
26
+ import { GetCleanedEvent } from "@BuilderComponents/GetCleanedEvent"
27
+ import { GenerateAudioMessage } from "@Audio/GenerateAudioMessage"
28
+ import { TaskGenerateText } from "@Tasks/TaskGenerateText"
29
+ import { TaskGenerateJSON } from "@Tasks/TaskGenerateJSON"
30
+ import { TaskSendNTFY } from "@Tasks/TaskSendNTFY"
31
+ import { TaskSendWebhook } from "@Tasks/TaskSendWebhook"
32
+ import { GenerateGraphic } from "@Image/GenerateGraphic"
33
+ import { QueueManager } from "@Utilities/QueueManager"
34
+
35
+ const Webhooks = new QueueManager({ Concurrency: 1 });
36
+ const NTFY = new QueueManager({ Concurrency: 5 });
37
+
38
+ export const CreateTasks = async (events: TypeEvent[]): Promise<void> => {
39
+
40
+ const settings = Bootstrap.Settings as TypeSettings;
41
+ const { ActionSettings, GlobalSettings, NotifyServer } = settings;
42
+ const actions = ActionSettings as TypeActions[];
43
+ for (const event of events) {
44
+ const tick = performance.now()
45
+ const { properties } = event;
46
+ const isActioning = Array.isArray(actions) && actions.length > 0;
47
+ if (!isActioning) { continue }
48
+ for (const action of actions) {
49
+ const { Events, Webhook, NotificationServer, Uploads } = action;
50
+ const isValidAction = GetMatched({ Strings: Events, String: properties.event });
51
+
52
+ if ((Events.length == 0 || isValidAction)) {
53
+ const a = performance.now();
54
+ const [audio, text, json, image] = await Promise.all([
55
+ Uploads?.AUDIO && GlobalSettings?.ArchiveSettings?.AudioDirectory ? GenerateAudioMessage({
56
+ Directory: GlobalSettings?.ArchiveSettings?.AudioDirectory + `/${properties?.regions_string ?? `MC`}`,
57
+ Title: (`${properties.event}_${properties.metadata.tracking}`).replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim(),
58
+ Message: properties.description,
59
+ Header: properties.metadata.header
60
+ }).then((result) => { return result; }) : Promise.resolve(null),
61
+
62
+ Uploads?.TEXT && GlobalSettings?.ArchiveSettings?.TextDirectory ? TaskGenerateText({
63
+ String: properties.metadata.raw,
64
+ Directory: GlobalSettings?.ArchiveSettings?.TextDirectory + `/${properties?.regions_string ?? `MC`}`,
65
+ Filename: (`${properties.event}_${properties.metadata.tracking}.txt`).replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim()
66
+ }).then((result) => { return result; }) : Promise.resolve(null),
67
+
68
+ Uploads?.JSON && GlobalSettings?.ArchiveSettings?.JSONDirectory ? TaskGenerateJSON({
69
+ String: JSON.stringify(GetCleanedEvent(event), null, 2),
70
+ Directory: GlobalSettings?.ArchiveSettings?.JSONDirectory + `/${properties?.regions_string ?? `MC`}`,
71
+ Filename: (`${properties.event}_${properties.metadata.tracking}.json`).replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim()
72
+ }).then((result) => { return result; }) : Promise.resolve(null),
73
+
74
+ Uploads?.IMAGE && GlobalSettings?.ArchiveSettings?.ImageDirectory ? GenerateGraphic({
75
+ Event: event,
76
+ File: {
77
+ Directory: GlobalSettings?.ArchiveSettings?.ImageDirectory + `/${properties?.regions_string ?? `MC`}`,
78
+ Name: (`${properties.event}_${properties.metadata.tracking}.png`).replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim()
79
+ }
80
+ }).then((result) => { return result; }) : Promise.resolve(null)
81
+ ]);
82
+
83
+
84
+ SetDebug({ Title: `Tasks/Generative`, Message: `${Math.round(performance.now() - a)}ms` })
85
+
86
+ const b = performance.now();
87
+ await Promise.all([
88
+ NotificationServer?.Enabled && NotifyServer?.Enabled && NotificationServer?.Topic ? NTFY.enqueue(() => TaskSendNTFY({
89
+ Event: event,
90
+ Priority: NotificationServer?.Priority ?? 5,
91
+ Body: GetStringText(event),
92
+ Topic: NotificationServer?.Topic
93
+ })) : Promise.resolve(null),
94
+ Webhook?.Enabled && Webhook?.Destination ? Webhooks.enqueue(() => TaskSendWebhook({
95
+ Event: event,
96
+ Webhook: {
97
+ Enabled: Webhook?.Enabled,
98
+ Destination: Webhook?.Destination,
99
+ Message: Webhook?.Message,
100
+ Title: Webhook?.Title,
101
+ Ratelimit: Webhook?.Ratelimit
102
+ },
103
+ Attachments: {
104
+ Image: image,
105
+ Text: text,
106
+ Audio: audio,
107
+ Json: json
108
+ }
109
+ })) : Promise.resolve(null)
110
+ ]);
111
+ SetDebug({ Title: `Tasks/Send`, Message: `${Math.round(performance.now() - b)}ms` })
112
+ }
113
+ }
114
+ SetDebug({ Title: `Tasks/CompletedEventTask`, Message: `${Math.round(performance.now() - tick)}ms` })
115
+ }
116
+ }
@@ -0,0 +1,34 @@
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: https://atmosphericx.scriptkitty.cafe/documentation
15
+
16
+ Independent Package: @atmosx/event-product-parser
17
+
18
+ */
19
+
20
+ import { mkdir, writeFile } from "fs/promises"
21
+
22
+ interface TaskGenerateJSONOptions {
23
+ String: string;
24
+ Directory: string;
25
+ Filename: string;
26
+ }
27
+
28
+ export const TaskGenerateJSON = async function({ String, Directory, Filename }: TaskGenerateJSONOptions): Promise<string> {
29
+ if (Directory) {
30
+ await mkdir(Directory, { recursive: true });
31
+ await writeFile(Directory + "/" + Filename, `${String}${"\n".repeat(5)}`);
32
+ }
33
+ return String;
34
+ }
@@ -0,0 +1,34 @@
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: https://atmosphericx.scriptkitty.cafe/documentation
15
+
16
+ Independent Package: @atmosx/event-product-parser
17
+
18
+ */
19
+
20
+ import { mkdir, appendFile } from "fs/promises"
21
+
22
+ interface TaskGenerateTextOptions {
23
+ String: string;
24
+ Directory: string;
25
+ Filename: string;
26
+ }
27
+
28
+ export const TaskGenerateText = async function({ String, Directory, Filename }: TaskGenerateTextOptions): Promise<string> {
29
+ if (Directory) {
30
+ await mkdir(Directory, { recursive: true });
31
+ await appendFile(Directory + "/" + Filename, `${String}${"\n".repeat(5)}`);
32
+ }
33
+ return String;
34
+ }
@@ -0,0 +1,96 @@
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: https://atmosphericx.scriptkitty.cafe/documentation
15
+
16
+ Independent Package: @atmosx/event-product-parser
17
+
18
+ */
19
+
20
+ import { TypeEvent } from "TypesEvent/Event"
21
+ import { Bootstrap } from "@Bootstrap"
22
+ import { CreateHttp } from "@Utilities/CreateHttp";
23
+ import { SetDebug } from "@Utilities/SetDebug";
24
+
25
+ interface TaskSendNTFYOptions {
26
+ Event: TypeEvent
27
+ Priority: string | number
28
+ Body: string
29
+ Topic: string
30
+ }
31
+
32
+ export const TaskSendNTFY = async function({ Event, Priority, Body, Topic }: TaskSendNTFYOptions): Promise<void> {
33
+ const { properties } = Event;
34
+
35
+ const configurations = Bootstrap.Settings.NotifyServer;
36
+ const authentication = configurations?.Credentials?.Username && configurations?.Credentials?.Password ? {
37
+ Username: configurations.Credentials.Username,
38
+ Password: configurations.Credentials.Password
39
+ } : undefined;
40
+
41
+ const image = configurations?.MediaStorage?.IMAGE ? { link: `${configurations?.MediaStorage?.IMAGE}/${properties.regions_string}//${properties?.event}_${properties?.metadata?.tracking}.png` } : undefined;
42
+ const SPCGraphic = properties?.metadata?.attachments?.find(a => a.name === "Image: SPC Graphic")
43
+
44
+ const buttons = [
45
+ ...(configurations?.MediaStorage?.AUDIO ? [{
46
+ "action": "view",
47
+ "label": "View Audio",
48
+ "url": `${configurations.MediaStorage.AUDIO}/${properties.regions_string}/${properties.event}_${properties.metadata.tracking}.wav?unix=${new Date().getTime()}`,
49
+ }] : []),
50
+ ...(configurations?.MediaStorage?.TEXT ? [{
51
+ "action": "view",
52
+ "label": "View Text",
53
+ "url": `${configurations.MediaStorage.TEXT}/${properties.regions_string}/${properties.event}_${properties.metadata.tracking}.txt?unix=${new Date().getTime()}`,
54
+ }] : []),
55
+ ...(SPCGraphic ? [{
56
+ "action": "view",
57
+ "label": "View Graphic",
58
+ "url": SPCGraphic.link + `?unix=${new Date().getTime()}`,
59
+ }] : []),
60
+ ... [{
61
+ "action": "copy",
62
+ "label": "Copy Card",
63
+ "value": `${properties.event} (${properties.status})\n${Body}\nTags: ${properties.parameters.tags?.join(",") ?? "N/A"}`
64
+ }]
65
+ ];
66
+
67
+ const headers = {
68
+ "Title": `${properties.event} (${properties.status})`,
69
+ "Tags": properties.parameters.tags?.join(",") ?? "N/A",
70
+ "Priority": Priority ?? "5",
71
+ ...(image && { "Attach": image.link + `?unix=${new Date().getTime()}` }),
72
+ ...(buttons.length > 0 && { "Actions": JSON.stringify(buttons) }),
73
+ };
74
+
75
+ const post = async (topic: string) => {
76
+ const response = await CreateHttp({
77
+ URL: `${configurations?.Server?.replace(/\/$/, "")}/${topic}`,
78
+ Timeout: 15_000,
79
+ Method: "PUT",
80
+ ...(authentication && { Auth: authentication }),
81
+ Headers: headers,
82
+ Body: Body
83
+ })
84
+ if (response.error) {
85
+ SetDebug({ Title: `Tasks/NTFY`, Message: `Failed to send notification to topic "${topic}": ${response.message}` })
86
+ }
87
+ }
88
+
89
+ const topics = [
90
+ `GLOBAL`,
91
+ Topic,
92
+ ...(properties.metadata.filtered_proximity ? [`${Topic}-LOCAL`] : []),
93
+ ];
94
+
95
+ await Promise.all([...new Set(topics)].map(post));
96
+ }
@@ -0,0 +1,107 @@
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: https://atmosphericx.scriptkitty.cafe/documentation
15
+
16
+ Independent Package: @atmosx/event-product-parser
17
+
18
+ */
19
+
20
+ import { TypeEvent } from "TypesEvent/Event"
21
+ import { CreateHttp } from "@Utilities/CreateHttp";
22
+ import { SetTimeoutAction } from "@Utilities/SetTimeoutAction";
23
+ import { GetEmbededText } from "@Formatting/GetEmbededText";
24
+ import { readFile } from "fs/promises"
25
+
26
+ interface TaskSendWebhookOptions {
27
+ Event: TypeEvent;
28
+ Webhook: {
29
+ Enabled: boolean;
30
+ Destination: string;
31
+ Message: string;
32
+ Title: string;
33
+ Ratelimit: number;
34
+ };
35
+ Attachments: {
36
+ Image?: string;
37
+ Text?: string;
38
+ Audio?: string;
39
+ Json?: string;
40
+ }
41
+ }
42
+
43
+ export const TaskSendWebhook = async function({ Event, Webhook, Attachments }: TaskSendWebhookOptions): Promise<void> {
44
+ const { properties } = Event;
45
+ const isRatelimited = SetTimeoutAction({
46
+ Identifier: Webhook.Destination,
47
+ Interval: (Webhook.Ratelimit ?? 2) * 2,
48
+ Max: (Webhook.Ratelimit ?? 2),
49
+ AddTime: true
50
+ })
51
+ if (isRatelimited.Limited) { return }
52
+ const newForm = new FormData();
53
+ const newEmbed = {
54
+ title: `${properties.event} (${properties.status})`,
55
+ description: GetEmbededText(Event),
56
+ fields: [] as { name: string, value: string }[],
57
+ color: 16711680,
58
+ thumbnail: Attachments?.Image ? { url: `attachment://${properties.event}_${properties.status}_${properties.metadata.tracking}.png` } : undefined,
59
+ timestamp: new Date().toISOString(),
60
+ footer: { text: Webhook.Title ?? `AtmosphericX` }
61
+ };
62
+ if (properties.description && !properties.status_metadata.is_expired) {
63
+ const description = properties.description.length > 900
64
+ ? properties.description.substring(0, 900) + "\n\n[Message truncated due to length]"
65
+ : properties.description;
66
+ newEmbed.fields.push({
67
+ name: "Description",
68
+ value: description ? '```' + '\n' + description.split('\n').map(l => l.trim()).filter(Boolean).join('\n') + '\n' + '```' : ""
69
+ });
70
+ }
71
+ if (properties.metadata.attachments?.length > 0) {
72
+ const attachments = properties.metadata.attachments.slice(0, 5);
73
+ newEmbed.fields.push({
74
+ name: "Attachments",
75
+ value: attachments.map(attachment => `- [${attachment.name.length > 45 ? attachment.name.substring(0, 45) + '...' : attachment.name}](${attachment.link})`).join('\n')
76
+ });
77
+ }
78
+
79
+ if (Attachments?.Image) {
80
+ const file = await readFile(Attachments.Image);
81
+ newForm.append("attachmentImage", new Blob([Buffer.from(file)], {type: "image/png"}), `${properties.event}_${properties.status}_${properties.metadata.tracking}.png`)
82
+ }
83
+
84
+ if (Attachments?.Text) {
85
+ newForm.append("attachmentText", new Blob([Buffer.from(Attachments.Text)], {type: "application/text"}), `${properties.event}_${properties.status}_${properties.metadata.tracking}.txt`)
86
+ }
87
+ if (Attachments?.Json) {
88
+ newForm.append("attachmentJson", new Blob([Buffer.from(Attachments.Json)], {type: "application/json"}), `${properties.event}_${properties.status}_${properties.metadata.tracking}.json`)
89
+ }
90
+ if (Attachments?.Audio) {
91
+ const file = await readFile(Attachments.Audio);
92
+ newForm.append("attachmentAudio", new Blob([Buffer.from(file)], {type: "application/wav"}), `${properties.event}_${properties.status}_${properties.metadata.tracking}.wav`)
93
+ }
94
+
95
+ newForm.append("payload_json", JSON.stringify({
96
+ username: Webhook.Title ?? `AtmosphericX`,
97
+ content: Webhook.Message ?? "",
98
+ embeds: [newEmbed]
99
+ }));
100
+
101
+ await CreateHttp({
102
+ URL: Webhook.Destination,
103
+ Timeout: 15e3,
104
+ Method: `POST`,
105
+ Body: newForm
106
+ })
107
+ }
@@ -11,13 +11,12 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
20
-
21
20
  export type TypeAttributes = {
22
21
  xmlns: string
23
22
  id: string
@@ -11,20 +11,20 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
20
- import { TypeEventProperties as BaseTypeEventProperties } from "./Properties";
21
- import { TypeHVTEC } from "./HVTEC";
22
- import { TypePVTEC } from "./VTEC";
20
+ import { TypeEventProperties as BaseTypeEventProperties } from "TypesEvent/Properties"
21
+ import { TypeHVTEC } from "TypesEvent/HVTEC"
22
+ import { TypeVTEC } from "TypesEvent/VTEC"
23
23
 
24
24
  export type TypeEvent = {
25
25
  type: string
26
26
  geometry: {
27
- type: string
27
+ type: "Polygon" | "MultiPolygon"
28
28
  coordinates: number[][]
29
29
  }
30
30
  properties: {
@@ -33,6 +33,7 @@ export type TypeEvent = {
33
33
  status: string
34
34
  issued: string
35
35
  expires: string
36
+ theme: string
36
37
  status_metadata?: {
37
38
  is_issued?: boolean
38
39
  is_updated?: boolean
@@ -46,7 +47,7 @@ export type TypeEvent = {
46
47
  tracking: string
47
48
  hash?: string
48
49
  header: string
49
- vtec?: TypePVTEC | null
50
+ vtec?: TypeVTEC | null
50
51
  hvtec?: TypeHVTEC[] | null
51
52
  nodes?: {
52
53
  id?: string | number
@@ -11,9 +11,9 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
@@ -11,17 +11,26 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
20
- import { TypeAttributes } from "./Attributes";
20
+ import { TypeAttributes } from "TypesEvent/Attributes"
21
+
22
+ export type TypeCities = {
23
+ name: string
24
+ state: string
25
+ county: string
26
+ population: number
27
+ }
21
28
 
22
29
  export type TypeEventProperties = {
23
30
  locations: string
24
31
  locations_array: string[]
32
+ regions: string[]
33
+ regions_string: string
25
34
  description: string
26
35
  attributes?: TypeAttributes
27
36
  geocode: {
@@ -31,6 +40,10 @@ export type TypeEventProperties = {
31
40
  }
32
41
  organization: string
33
42
  ugc: string[]
43
+ census?: {
44
+ population?: number
45
+ cities?: TypeCities[]
46
+ }
34
47
  polygon: string
35
48
  polygon_generated: boolean
36
49
  }
@@ -42,6 +55,7 @@ export type TypeEventProperties = {
42
55
  impacts: string
43
56
  estimated_hail_size: string
44
57
  estimated_wind_gusts: string
58
+ direction: string
45
59
  damage_threat: string
46
60
  tornado_threat: string
47
61
  flood_threat: string
@@ -11,9 +11,9 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
@@ -11,20 +11,20 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
20
- export type TypePVTEC = {
21
- vtec: string
22
- product: string
20
+ export type TypeVTEC = {
21
+ raw: string
22
+ type: string
23
23
  tracking: string
24
24
  event: string
25
25
  status: string
26
- organization: string
26
+ wmo: string
27
27
  expires: string
28
- is_watch: boolean
29
- prediction_center: boolean
28
+ watch: boolean
29
+ wou: boolean
30
30
  }
@@ -11,9 +11,9 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
@@ -32,6 +32,6 @@ export type TypeActions = {
32
32
  Priority?: string | number
33
33
  }
34
34
  Uploads?: {
35
- TEXT?: boolean, EAS?: boolean, JSON?: boolean
35
+ TEXT?: boolean, AUDIO?: boolean, JSON?: boolean, IMAGE?: boolean
36
36
  }
37
37
  }
@@ -11,14 +11,14 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
20
20
  export type TypeHash = {
21
- tracking: string
22
- hashes: string[]
23
- expires: string
21
+ Tracking: string
22
+ Hashes: string[]
23
+ Expires: string
24
24
  }