@atmosx/event-product-parser 3.0.62 → 3.0.75

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 (179) hide show
  1. package/.github/docs/docs-functions.md +1 -1
  2. package/.github/docs/docs-general-configurations.md +1 -11
  3. package/.github/docs/docs-integrations.md +3 -2
  4. package/README.md +10 -8
  5. package/dist/cjs/index.cjs +24482 -7207
  6. package/dist/esm/index.mjs +24275 -7003
  7. package/package.json +56 -47
  8. package/pnpm-workspace.yaml +4 -0
  9. package/src/bootstrap.ts +65 -48
  10. package/src/{@building → building}/CreateEvent.ts +22 -24
  11. package/src/{@building → building}/GetCleanedEvent.ts +2 -2
  12. package/src/{@building → building}/GetEventAttachments.ts +14 -12
  13. package/src/building/GetEventDirection.ts +28 -0
  14. package/src/{@building → building}/GetEventEnhancedName.ts +5 -8
  15. package/src/{@building → building}/GetEventGeometry.ts +19 -13
  16. package/src/{@building → building}/GetEventHeader.ts +13 -13
  17. package/src/{@building → building}/GetEventNodes.ts +22 -20
  18. package/src/{@building → building}/GetEventOffice.ts +13 -13
  19. package/src/building/GetEventPopulation.ts +58 -0
  20. package/src/building/GetEventProperties.ts +106 -0
  21. package/src/{@building → building}/GetEventSignature.ts +9 -9
  22. package/src/{@building → building}/GetEventTags.ts +3 -3
  23. package/src/building/GetEventTheme.ts +26 -0
  24. package/src/building/GetEventTracking.ts +64 -0
  25. package/src/components/audio/GenerateAudioMessage.ts +149 -0
  26. package/src/{@modules/@eas → components/audio/components}/GetCleanDescription.ts +2 -2
  27. package/src/{@modules/@eas → components/audio/components}/GetFloatPCM16.ts +2 -2
  28. package/src/{@modules/@eas → components/audio/components}/GetMergedPCM16.ts +2 -2
  29. package/src/{@modules/@eas → components/audio/components}/GetPCM16.ts +13 -8
  30. package/src/{@modules/@eas → components/audio/components}/GetPCMToFloat.ts +2 -2
  31. package/src/{@modules/@eas → components/audio/components}/GetSampledPCM16.ts +14 -8
  32. package/src/{@modules/@eas → components/audio/components}/GetTTS.ts +17 -10
  33. package/src/{@modules/@eas → components/audio/components}/GetWavPCM16.ts +7 -7
  34. package/src/{@modules/@eas → components/audio/components}/SetAFSK.ts +13 -8
  35. package/src/{@modules/@eas → components/audio/components}/SetAsciiToBits.ts +2 -2
  36. package/src/{@modules/@eas → components/audio/components}/SetAttentionTone.ts +11 -6
  37. package/src/{@modules/@eas → components/audio/components}/SetNoise.ts +12 -7
  38. package/src/{@modules/@eas → components/audio/components}/SetRadioEffect.ts +12 -7
  39. package/src/{@modules/@eas → components/audio/components}/SetSameHeader.ts +22 -14
  40. package/src/{@modules/@utilities/SetWarning.ts → components/database/CreateQuery.ts} +18 -13
  41. package/src/{@modules/@database → components/database}/GetCachedEvents.ts +18 -15
  42. package/src/components/database/ImportBoundaries.ts +168 -0
  43. package/src/{@modules/@database → components/database}/ImportBroadcastify.ts +14 -24
  44. package/src/components/database/ImportCities.ts +87 -0
  45. package/src/{@modules/@database → components/database}/ImportShapefiles.ts +23 -26
  46. package/src/{@modules/@database → components/database}/ImportStanza.ts +15 -19
  47. package/src/components/database/InitializeDatabase.ts +71 -0
  48. package/src/components/images/GenerateGraphic.ts +242 -0
  49. package/src/components/images/components/CreateRectangle.ts +22 -0
  50. package/src/components/images/components/CreateText.ts +22 -0
  51. package/src/components/images/modules/CreateSVG.ts +37 -0
  52. package/src/components/images/modules/GetGeographicalBoundaries.ts +72 -0
  53. package/src/components/images/modules/GetGeographicalCities.ts +58 -0
  54. package/src/components/images/modules/GetGeographicalEvents.ts +48 -0
  55. package/src/components/images/modules/GetGeometryBounds.ts +82 -0
  56. package/src/components/images/modules/GetParsedBoundary.ts +58 -0
  57. package/src/components/images/modules/GetSVGPath.ts +53 -0
  58. package/src/components/images/modules/NormalizePolygon.ts +57 -0
  59. package/src/{@modules/@stanza → components/stanza}/GetAwipsType.ts +16 -17
  60. package/src/{@modules/@stanza → components/stanza}/ValidateStanza.ts +27 -15
  61. package/src/{@modules/@utilities → components/utilities}/CreateHttp.ts +26 -26
  62. package/src/{@parsers/@text → components/utilities}/GetEmbededText.ts +8 -6
  63. package/src/{@modules/@utilities → components/utilities}/GetFormattedTime.ts +2 -2
  64. package/src/{@modules/@utilities → components/utilities}/GetLatestIssuance.ts +2 -2
  65. package/src/{@modules/@utilities → components/utilities}/GetMatched.ts +10 -5
  66. package/src/{@modules/@utilities → components/utilities}/GetShapeNearestPoint.ts +24 -19
  67. package/src/{@parsers/@text → components/utilities}/GetStringText.ts +9 -9
  68. package/src/components/utilities/GetUnionPolygon.ts +36 -0
  69. package/src/components/utilities/QueueManager.ts +70 -0
  70. package/src/components/utilities/SetCronSchedule.ts +106 -0
  71. package/src/{@modules/@utilities → components/utilities}/SetDebug.ts +12 -12
  72. package/src/components/utilities/SetEventEmit.ts +42 -0
  73. package/src/{@modules/@utilities → components/utilities}/SetSettings.ts +7 -7
  74. package/src/{@modules/@utilities → components/utilities}/SetSleep.ts +5 -5
  75. package/src/components/utilities/SetTimeoutAction.ts +64 -0
  76. package/src/components/utilities/SetWarning.ts +47 -0
  77. package/src/{@modules/@xmpp → components/xmpp}/DeployXMPP.ts +20 -20
  78. package/src/{@core/CreateListener.ts → components/xmpp/ErrorXMPP.ts} +8 -5
  79. package/src/{@modules/@xmpp → components/xmpp}/OfflineXMPP.ts +13 -13
  80. package/src/{@modules/@xmpp → components/xmpp}/OnlineXMPP.ts +18 -18
  81. package/src/components/xmpp/ReconnectXMPP.ts +64 -0
  82. package/src/{@modules/@xmpp → components/xmpp}/StanzaXMPP.ts +25 -25
  83. package/src/{@core → core}/ClearEvents.ts +9 -9
  84. package/src/{@core → core}/GetEvents.ts +4 -4
  85. package/src/{@core → core}/GetNodes.ts +4 -4
  86. package/src/{@core → core}/GetRandomEvent.ts +4 -4
  87. package/src/{@core → core}/GetVersion.ts +4 -4
  88. package/src/{@core → core}/ManualEvent.ts +23 -24
  89. package/src/{@core → core}/QueryStanza.ts +12 -11
  90. package/src/core/SetNode.ts +87 -0
  91. package/src/{@core → core}/StartService.ts +21 -20
  92. package/src/{@core → core}/StopService.ts +10 -10
  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 +38 -37
  119. package/src/index.ts +57 -37
  120. package/src/{@manager → manager}/MakeEvents.ts +38 -47
  121. package/src/manager/RemoveEvent.ts +74 -0
  122. package/src/{@manager → manager}/SetHash.ts +18 -13
  123. package/src/{@manager → manager}/UpdateEvents.ts +12 -12
  124. package/src/{@manager → manager}/UpdateNode.ts +14 -14
  125. package/src/{@manager → manager}/ValidateEvents.ts +55 -45
  126. package/src/{@parsers/@hvtec → parsers/hvtec}/HVExtract.ts +11 -11
  127. package/src/{@parsers/@text → parsers/text}/GetDescriptionFromProduct.ts +20 -21
  128. package/src/parsers/text/GetPolygonFromProduct.ts +71 -0
  129. package/src/{@parsers/@text → parsers/text}/GetTextFromProduct.ts +12 -12
  130. package/src/parsers/ugc/GetCache.ts +24 -0
  131. package/src/{@parsers/@ugc → parsers/ugc}/GetExpiry.ts +2 -2
  132. package/src/{@parsers/@ugc/GetUGCHeader.ts → parsers/ugc/GetHeader.ts} +4 -4
  133. package/src/{@parsers/@ugc → parsers/ugc}/GetLocations.ts +10 -10
  134. package/src/parsers/ugc/GetZonePolygon.ts +73 -0
  135. package/src/{@parsers/@ugc → parsers/ugc}/GetZones.ts +3 -3
  136. package/src/{@parsers/@ugc → parsers/ugc}/SetCache.ts +13 -8
  137. package/src/{@parsers/@ugc → parsers/ugc}/UGCExtract.ts +14 -14
  138. package/src/{@parsers/@pvtec → parsers/vtec}/GetExpiry.ts +2 -2
  139. package/src/parsers/vtec/VTECExtract.ts +49 -0
  140. package/src/{@types → static}/Attributes.ts +2 -3
  141. package/src/{@types → static}/Event.ts +8 -7
  142. package/src/{@types → static}/Properties.ts +17 -3
  143. package/src/{@types → static}/Stanza.ts +2 -2
  144. package/src/tasks/CreateTasks.ts +116 -0
  145. package/src/tasks/TaskGenerateJSON.ts +34 -0
  146. package/src/tasks/TaskGenerateText.ts +34 -0
  147. package/src/tasks/TaskSendNTFY.ts +95 -0
  148. package/src/tasks/TaskSendWebhook.ts +107 -0
  149. package/src/{@types → types}/Actions.ts +3 -3
  150. package/src/{@types → types}/HVTEC.ts +6 -6
  151. package/src/{@types → types}/Hash.ts +5 -5
  152. package/src/types/Nodes.ts +29 -0
  153. package/src/{@types → types}/Settings.ts +17 -8
  154. package/src/{@types → types}/StanzaCompiled.ts +15 -15
  155. package/src/{@types → types}/UGC.ts +5 -5
  156. package/src/{@modules/@utilities/GetSettings.ts → types/VTEC.ts} +12 -7
  157. package/tools/build.js +47 -0
  158. package/tsconfig.json +28 -1
  159. package/src/@building/GetEventProperties.ts +0 -96
  160. package/src/@building/GetEventTracking.ts +0 -68
  161. package/src/@core/SetNode.ts +0 -81
  162. package/src/@events/ParseAPI.ts +0 -117
  163. package/src/@manager/RemoveEvent.ts +0 -70
  164. package/src/@manager/Tasks.ts +0 -246
  165. package/src/@modules/@database/InitializeDatabase.ts +0 -59
  166. package/src/@modules/@eas/GenerateEASMessage.ts +0 -144
  167. package/src/@modules/@utilities/SetCronSchedule.ts +0 -94
  168. package/src/@modules/@utilities/SetEventEmit.ts +0 -41
  169. package/src/@modules/@utilities/SetListener.ts +0 -30
  170. package/src/@modules/@utilities/SetTimeoutAction.ts +0 -64
  171. package/src/@modules/@xmpp/ErrorXMPP.ts +0 -27
  172. package/src/@modules/@xmpp/ReconnectXMPP.ts +0 -64
  173. package/src/@parsers/@pvtec/VTECExtract.ts +0 -49
  174. package/src/@parsers/@text/GetPolygonFromProduct.ts +0 -53
  175. package/src/@parsers/@text/GetXML.ts +0 -61
  176. package/src/@parsers/@ugc/GetCache.ts +0 -24
  177. package/src/@parsers/@ugc/GetZonePolygon.ts +0 -111
  178. package/src/@types/VTEC.ts +0 -30
  179. package/tsup.config.ts +0 -16
@@ -11,18 +11,23 @@
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 { bootstrap } from "../../bootstrap";
20
+ import { Bootstrap } from "@Bootstrap"
21
21
 
22
- export const setCache = (key: string, value: string[]) => {
23
- if (bootstrap.cache.ugc.size >= 5000) {
24
- const firstKey = bootstrap.cache.ugc.keys().next().value;
25
- bootstrap.cache.ugc.delete(firstKey);
22
+ interface SetCacheOptions {
23
+ Key: string
24
+ Value: string[]
25
+ }
26
+
27
+ export const SetCache = ({ Key, Value }: SetCacheOptions) => {
28
+ if (Bootstrap.Cache.UGC.size >= 5000) {
29
+ const firstKey = Bootstrap.Cache.UGC.keys().next().value;
30
+ Bootstrap.Cache.UGC.delete(firstKey);
26
31
  }
27
- bootstrap.cache.ugc.set(key, value);
32
+ Bootstrap.Cache.UGC.set(Key, Value);
28
33
  };
@@ -11,27 +11,27 @@
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 { TypeUGC } from "../../@types/UGC";
21
- import { getUGCHeader } from "./GetUGCHeader"
22
- import { getZones } from "./GetZones";
23
- import { GetExpiry } from './GetExpiry';
24
- import { getLocations } from "./GetLocations";
20
+ import { TypeUGC } from "Types/UGC"
21
+ import { GetHeader } from "@ParsingUGC/GetHeader"
22
+ import { GetZones } from "@ParsingUGC/GetZones"
23
+ import { GetExpiry } from "@ParsingUGC/GetExpiry"
24
+ import { GetLocations } from "@ParsingUGC/GetLocations"
25
25
 
26
- export const ugcExtract = async (message: string): Promise<TypeUGC> => {
27
- const head = getUGCHeader(message);
28
- const ugcs = getZones(head)
26
+ export const UGCExtract = async (message: string): Promise<TypeUGC> => {
29
27
  const expires = GetExpiry(message)
30
- const areas = await getLocations(ugcs)
28
+ const head = GetHeader(message);
29
+ const ugcs = GetZones(head);
30
+ const areas = await GetLocations(ugcs)
31
31
  if (!head || ugcs?.length == 0) return;
32
32
  return {
33
- zones: ugcs,
34
- locations: areas,
35
- expires: expires
33
+ Zones: ugcs,
34
+ Locations: areas,
35
+ Expires: expires
36
36
  }
37
37
  }
@@ -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
 
@@ -0,0 +1,49 @@
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 { TypeVTEC } 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 "@ParsingVTEC/GetExpiry"
27
+
28
+ export const VTECExtract = (message: string): TypeVTEC[] | null => {
29
+ if (!message) return null;
30
+ const getVTECs = message.match(EnumExpressions.vtec) ?? [];
31
+ const vtecs: TypeVTEC[] = [];
32
+ for (const vtec of getVTECs) {
33
+ const sub = vtec.split(`.`);
34
+ if (sub?.length < 7) continue;
35
+ const dates = sub[6]?.split(`-`);
36
+ vtecs.push({
37
+ Raw: vtec,
38
+ ProductType: EnumProducts[sub[0]],
39
+ Tracking: `${sub[2]}.${sub[3]}.${sub[4]}.${sub[5]}`,
40
+ Event: `${EnumEvents[sub[3]]} ${EnumActions[sub[4]]}`,
41
+ Status: EnumStatus[sub[1]],
42
+ WMO: message.match(EnumExpressions.wmo)?.[0] ?? null,
43
+ Expires: GetExpiry(dates),
44
+ Watch: (sub[4] == `A` || sub[4] == `Y`) && (sub[3] == `TO` || sub[3] == `SV`),
45
+ PredictionCenter: sub[2] == `KWNS` ? true : false
46
+ })
47
+ }
48
+ return vtecs.length > 0 ? vtecs : null;
49
+ }
@@ -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 "StaticTypes/Properties"
21
+ import { TypeHVTEC } from "Types/HVTEC"
22
+ import { TypeVTEC } from "Types/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,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 "StaticTypes/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
 
@@ -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 "Types/Settings"
20
+ import { TypeEvent } from "StaticTypes/Event"
21
+ import { TypeActions } from "Types/Actions"
22
+ import { Bootstrap } from "@Bootstrap"
23
+ import { SetDebug } from "@Utilities/SetDebug"
24
+ import { GetMatched } from "@Utilities/GetMatched"
25
+ import { GetStringText } from "@Utilities/GetStringText"
26
+ import { GetCleanedEvent } from "@Building/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,95 @@
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 "StaticTypes/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`,
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`,
54
+ }] : []),
55
+ ...(SPCGraphic ? [{
56
+ "action": "view",
57
+ "label": "View Graphic",
58
+ "url": SPCGraphic.link,
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 }),
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
+ Topic,
91
+ ...(properties.metadata.filtered_proximity ? [`${Topic}-LOCAL`] : []),
92
+ ];
93
+
94
+ await Promise.all([...new Set(topics)].map(post));
95
+ }
@@ -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 "StaticTypes/Event"
21
+ import { CreateHttp } from "@Utilities/CreateHttp";
22
+ import { SetTimeoutAction } from "@Utilities/SetTimeoutAction";
23
+ import { GetEmbededText } from "@Utilities/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
+ }