@atmosx/event-product-parser 3.0.48 → 3.0.52

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 (141) hide show
  1. package/.vscode/settings.json +3 -3
  2. package/CODE_OF_CONDUCT.md +9 -9
  3. package/CONTRIBUTING.md +29 -29
  4. package/LICENSE +17 -17
  5. package/README.md +443 -417
  6. package/SECURITY.md +20 -20
  7. package/SUPPORTED_EVENTS.md +369 -368
  8. package/dist/cjs/index.cjs +1925 -1885
  9. package/dist/esm/index.mjs +1927 -1887
  10. package/package.json +52 -52
  11. package/src/@building/building.attachments.ts +82 -82
  12. package/src/@building/building.clean.ts +29 -29
  13. package/src/@building/building.create.ts +55 -41
  14. package/src/@building/building.enhance.ts +59 -59
  15. package/src/@building/building.geometry.ts +47 -47
  16. package/src/@building/building.headers.ts +36 -36
  17. package/src/@building/building.office.ts +42 -42
  18. package/src/@building/building.polygon.ts +69 -70
  19. package/src/@building/building.properties.ts +95 -95
  20. package/src/@building/building.signature.ts +60 -61
  21. package/src/@building/building.tags.ts +23 -23
  22. package/src/@building/building.tracking.ts +67 -67
  23. package/src/@building/building.validate.ts +152 -146
  24. package/src/@core/core.clearEvents.ts +30 -31
  25. package/src/@core/core.createListener.ts +23 -23
  26. package/src/@core/core.getEvents.ts +23 -24
  27. package/src/@core/core.getNodes.ts +23 -24
  28. package/src/@core/core.getRandomEvent.ts +23 -24
  29. package/src/@core/core.getVersion.ts +23 -24
  30. package/src/@core/core.manualEvent.ts +38 -0
  31. package/src/@core/core.query.ts +38 -38
  32. package/src/@core/core.setNode.ts +80 -80
  33. package/src/@core/core.start.ts +60 -60
  34. package/src/@core/core.stop.ts +31 -31
  35. package/src/@dictionaries/dictionaries.actions.ts +27 -27
  36. package/src/@dictionaries/dictionaries.awips.ts +363 -363
  37. package/src/@dictionaries/dictionaries.cancellation.ts +30 -30
  38. package/src/@dictionaries/dictionaries.causes.ts +35 -35
  39. package/src/@dictionaries/dictionaries.correlations.ts +42 -42
  40. package/src/@dictionaries/dictionaries.enhanced.ts +66 -109
  41. package/src/@dictionaries/dictionaries.events.ts +82 -82
  42. package/src/@dictionaries/dictionaries.expressions.ts +28 -28
  43. package/src/@dictionaries/dictionaries.global.ts +24 -0
  44. package/src/@dictionaries/dictionaries.hail.ts +35 -35
  45. package/src/@dictionaries/dictionaries.icao.ts +258 -258
  46. package/src/@dictionaries/dictionaries.matches.ts +54 -35
  47. package/src/@dictionaries/dictionaries.products.ts +24 -24
  48. package/src/@dictionaries/dictionaries.records.ts +25 -25
  49. package/src/@dictionaries/dictionaries.severity.ts +27 -27
  50. package/src/@dictionaries/dictionaries.shapefiles.ts +35 -35
  51. package/src/@dictionaries/dictionaries.states.ts +71 -71
  52. package/src/@dictionaries/dictionaries.status.ts +30 -30
  53. package/src/@dictionaries/dictionaries.tags.ts +92 -92
  54. package/src/@dictionaries/dictionaries.testing.ts +24 -24
  55. package/src/@events/events.api.ts +116 -118
  56. package/src/@events/events.text.ts +84 -81
  57. package/src/@events/events.ugc.ts +89 -85
  58. package/src/@events/events.vtec.ts +86 -87
  59. package/src/@manager/manager.mkEvent.ts +97 -88
  60. package/src/@manager/manager.rmEvent.ts +56 -49
  61. package/src/@manager/manager.setHash.ts +35 -36
  62. package/src/@manager/manager.updateEvents.ts +32 -34
  63. package/src/@manager/manager.updateListener.ts +154 -159
  64. package/src/@manager/manager.updateNodes.ts +53 -54
  65. package/src/@modules/@database/database.broadcastify.ts +66 -66
  66. package/src/@modules/@database/database.cache.ts +49 -47
  67. package/src/@modules/@database/database.init.ts +58 -57
  68. package/src/@modules/@database/database.shapefiles.ts +92 -92
  69. package/src/@modules/@database/database.stanza.ts +46 -47
  70. package/src/@modules/@eas/eas.getCleanDescription.ts +91 -91
  71. package/src/@modules/@eas/eas.getFloatPCM16.ts +29 -29
  72. package/src/@modules/@eas/eas.getMergedPCM16.ts +32 -32
  73. package/src/@modules/@eas/eas.getPCM16.ts +52 -52
  74. package/src/@modules/@eas/eas.getPCMToFloat.ts +26 -26
  75. package/src/@modules/@eas/eas.getSampledPCM16.ts +36 -36
  76. package/src/@modules/@eas/eas.getTTS.ts +54 -54
  77. package/src/@modules/@eas/eas.getWavPCM16.ts +52 -52
  78. package/src/@modules/@eas/eas.setAFSK.ts +51 -52
  79. package/src/@modules/@eas/eas.setAsciiToBits.ts +31 -32
  80. package/src/@modules/@eas/eas.setAttentionTone.ts +40 -40
  81. package/src/@modules/@eas/eas.setEasTone.ts +151 -147
  82. package/src/@modules/@eas/eas.setNoise.ts +32 -31
  83. package/src/@modules/@eas/eas.setRadioEffect.ts +50 -49
  84. package/src/@modules/@eas/eas.setSameHeader.ts +44 -45
  85. package/src/@modules/@stanza/stanza.getAwipsType.ts +45 -45
  86. package/src/@modules/@stanza/stanza.validate.ts +49 -49
  87. package/src/@modules/@utilities/utilities.createHttp.ts +70 -70
  88. package/src/@modules/@utilities/utilities.getFormattedTime.ts +43 -43
  89. package/src/@modules/@utilities/utilities.getLatestIssuance.ts +32 -32
  90. package/src/@modules/@utilities/utilities.getMatched.ts +33 -0
  91. package/src/@modules/@utilities/utilities.getSettings.ts +25 -25
  92. package/src/@modules/@utilities/utilities.getShapeNearestPoint.ts +114 -114
  93. package/src/@modules/@utilities/utilities.setCronSchedule.ts +94 -94
  94. package/src/@modules/@utilities/utilities.setDebug.ts +38 -0
  95. package/src/@modules/@utilities/utilities.setEventEmit.ts +41 -41
  96. package/src/@modules/@utilities/utilities.setListener.ts +30 -30
  97. package/src/@modules/@utilities/utilities.setSettings.ts +42 -42
  98. package/src/@modules/@utilities/utilities.setSleep.ts +33 -33
  99. package/src/@modules/@utilities/utilities.setTimeoutAction.ts +62 -58
  100. package/src/@modules/@utilities/utilities.setWarning.ts +34 -34
  101. package/src/@modules/@xmpp/xmpp.xDeploy.ts +57 -58
  102. package/src/@modules/@xmpp/xmpp.xError.ts +26 -28
  103. package/src/@modules/@xmpp/xmpp.xOffline.ts +36 -37
  104. package/src/@modules/@xmpp/xmpp.xOnline.ts +45 -44
  105. package/src/@modules/@xmpp/xmpp.xReconnect.ts +64 -64
  106. package/src/@modules/@xmpp/xmpp.xStanza.ts +62 -62
  107. package/src/@parsers/@hvtec/hvtec.extract.ts +39 -39
  108. package/src/@parsers/@pvtec/pvtec.expires.ts +25 -25
  109. package/src/@parsers/@pvtec/pvtec.extract.ts +48 -48
  110. package/src/@parsers/@text/text.getDescriptionFromProduct.ts +52 -52
  111. package/src/@parsers/@text/text.getEmbed.ts +55 -57
  112. package/src/@parsers/@text/text.getPolygonFromProduct.ts +53 -32
  113. package/src/@parsers/@text/text.getTextFromProduct.ts +42 -42
  114. package/src/@parsers/@text/text.getXML.ts +60 -60
  115. package/src/@parsers/@ugc/ugc.coordinates.ts +110 -109
  116. package/src/@parsers/@ugc/ugc.expiry.ts +31 -31
  117. package/src/@parsers/@ugc/ugc.extract.ts +36 -36
  118. package/src/@parsers/@ugc/ugc.getCache.ts +24 -0
  119. package/src/@parsers/@ugc/ugc.header.ts +29 -29
  120. package/src/@parsers/@ugc/ugc.locations.ts +57 -29
  121. package/src/@parsers/@ugc/ugc.setCache.ts +28 -0
  122. package/src/@parsers/@ugc/ugc.zones.ts +51 -51
  123. package/src/@types/type.attributes.ts +28 -28
  124. package/src/@types/type.compiled.ts +34 -34
  125. package/src/@types/type.event.ts +69 -69
  126. package/src/@types/type.hash.ts +24 -24
  127. package/src/@types/type.hvtec.ts +25 -25
  128. package/src/@types/type.listener.ts +32 -32
  129. package/src/@types/type.properties.ts +77 -77
  130. package/src/@types/type.pvtec.ts +30 -30
  131. package/src/@types/type.settings.ts +84 -83
  132. package/src/@types/type.stanza.ts +37 -37
  133. package/src/@types/type.ugc.ts +24 -24
  134. package/src/bootstrap.ts +115 -112
  135. package/src/index.ts +74 -74
  136. package/test.js +92 -98
  137. package/tsconfig.json +13 -13
  138. package/tsup.config.ts +15 -15
  139. package/dist/index.d.mts +0 -299
  140. package/dist/index.d.ts +0 -299
  141. package/src/@core/core.createEvent.ts +0 -83
@@ -1,62 +1,61 @@
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: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
15
-
16
- Internal Package: @atmosx/event-product-parser
17
-
18
- */
19
-
20
- import { TypeEvent } from "../@types/type.event";
21
- import { dict_correlations } from "../@dictionaries/dictionaries.correlations";
22
- import { dict_cancellation } from "../@dictionaries/dictionaries.cancellation";
23
- import { dict_testing} from "../@dictionaries/dictionaries.testing"
24
- import { dict_products } from "../@dictionaries/dictionaries.products";
25
- import { dict_hail } from "../@dictionaries/dictionaries.hail"
26
-
27
-
28
- export const getEventSignature = (event: TypeEvent): TypeEvent => {
29
- const properties = event?.properties;
30
- const vtec = event?.properties?.metadata?.vtec
31
- const status = dict_correlations
32
- .find((c: { type: string }) => c.type === properties?.status);
33
- const csig = dict_cancellation.find(sig => properties.description.toLowerCase().includes(sig.toLowerCase()));
34
- properties.status_metadata = { ...properties.status_metadata, is_issued: true, is_test: false};
35
-
36
- if (properties?.parameters?.estimated_hail_size) {
37
- properties.parameters.estimated_hail_size += ` (${dict_hail[properties?.parameters?.estimated_hail_size] ?? '--'})`
38
- }
39
-
40
- if (status) {
41
- properties.status = status.name ?? properties.status;
42
- properties.status_metadata = { ...properties.status_metadata, is_updated: !!status.isUpdate, is_issued: !!status.isIssued, is_expired: !!status.isCancel, is_statement: !!status.isStatement };
43
- }
44
- if (csig) {
45
- properties.status_metadata = { ...properties.status_metadata, is_expired: true };
46
- }
47
-
48
- const getProduct = vtec?.vtec?.split(`.`)[0]?.replace(`/`, ``)
49
- const isTestProduct = dict_products[getProduct] == `Test Product`
50
- if (isTestProduct || dict_testing.some(sig => properties.description?.toLowerCase().includes(sig.toLowerCase()) ?? properties?.parameters?.instructions?.toLowerCase().includes(sig.toLowerCase()))) {
51
- properties.status_metadata = { ...properties.status_metadata, is_test: true }
52
- }
53
-
54
- if (new Date(properties.expires).getTime() < Date.now()) {
55
- properties.status_metadata = { ...properties.status_metadata, is_expired: true };
56
- }
57
- properties.status_metadata = {
58
- ...properties.status_metadata,
59
- }
60
-
61
- return event
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: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
15
+
16
+ Internal Package: @atmosx/event-product-parser
17
+
18
+ */
19
+
20
+ import { TypeEvent } from "../@types/type.event";
21
+ import { dict_correlations } from "../@dictionaries/dictionaries.correlations";
22
+ import { dict_cancellation } from "../@dictionaries/dictionaries.cancellation";
23
+ import { dict_testing} from "../@dictionaries/dictionaries.testing"
24
+ import { dict_products } from "../@dictionaries/dictionaries.products";
25
+ import { dict_hail } from "../@dictionaries/dictionaries.hail"
26
+
27
+ export const getEventSignature = (event: TypeEvent): TypeEvent => {
28
+ const properties = event?.properties;
29
+ const vtec = event?.properties?.metadata?.vtec
30
+ const status = dict_correlations
31
+ .find((c: { type: string }) => c.type === properties?.status);
32
+ const csig = dict_cancellation.find(sig => properties.description.toLowerCase().includes(sig.toLowerCase()));
33
+ properties.status_metadata = { ...properties.status_metadata, is_issued: true, is_test: false};
34
+
35
+ if (properties?.parameters?.estimated_hail_size) {
36
+ properties.parameters.estimated_hail_size += ` (${dict_hail[properties?.parameters?.estimated_hail_size] ?? '--'})`
37
+ }
38
+
39
+ if (status) {
40
+ properties.status = status.name ?? properties.status;
41
+ properties.status_metadata = { ...properties.status_metadata, is_updated: !!status.isUpdate, is_issued: !!status.isIssued, is_expired: !!status.isCancel, is_statement: !!status.isStatement };
42
+ }
43
+ if (csig) {
44
+ properties.status_metadata = { ...properties.status_metadata, is_expired: true };
45
+ }
46
+
47
+ const getProduct = vtec?.vtec?.split(`.`)[0]?.replace(`/`, ``)
48
+ const isTestProduct = dict_products[getProduct] == `Test Product`
49
+ if (isTestProduct || dict_testing.some(sig => properties.description?.toLowerCase().includes(sig.toLowerCase()) ?? properties?.parameters?.instructions?.toLowerCase().includes(sig.toLowerCase()))) {
50
+ properties.status_metadata = { ...properties.status_metadata, is_test: true }
51
+ }
52
+
53
+ if (new Date(properties.expires).getTime() < Date.now()) {
54
+ properties.status_metadata = { ...properties.status_metadata, is_expired: true };
55
+ }
56
+ properties.status_metadata = {
57
+ ...properties.status_metadata,
58
+ }
59
+
60
+ return event
62
61
  }
@@ -1,24 +1,24 @@
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: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
15
-
16
- Internal Package: @atmosx/event-product-parser
17
-
18
- */
19
-
20
- import { dict_tags } from "../@dictionaries/dictionaries.tags";
21
-
22
- export const getEventTags = (message: string): string[] => {
23
- return Object.entries(dict_tags).filter(([key]) => message?.toLowerCase().includes(key.toLowerCase())).map(([, value]) => value)
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: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
15
+
16
+ Internal Package: @atmosx/event-product-parser
17
+
18
+ */
19
+
20
+ import { dict_tags } from "../@dictionaries/dictionaries.tags";
21
+
22
+ export const getEventTags = (message: string): string[] => {
23
+ return Object.entries(dict_tags).filter(([key]) => message?.toLowerCase().includes(key.toLowerCase())).map(([, value]) => value)
24
24
  }
@@ -1,68 +1,68 @@
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: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
15
-
16
- Internal Package: @atmosx/event-product-parser
17
-
18
- */
19
-
20
- import { TypeAttributes } from "../@types/type.attributes";
21
- import { TypeEventProperties } from "../@types/type.properties";
22
- import { TypeStanzaCompiled } from "../@types/type.compiled";
23
- import { TypePVTEC } from "../@types/type.pvtec";
24
-
25
- interface GetTrackingOptions {
26
- type: `RAW` | `VTEC` | `API`
27
- stanza?: TypeStanzaCompiled
28
- attributes?: TypeAttributes
29
- properties?: TypeEventProperties
30
- organization?: {
31
- wmoidentifier: string
32
- featureId: string
33
- }
34
- vtec?: TypePVTEC
35
- }
36
-
37
- export const getEventTracking = (options: GetTrackingOptions): string => {
38
- const properties = options.properties
39
- const attributes = options.attributes
40
- const stanza = options.stanza
41
- const vtec = options.vtec
42
- if (options.type === `RAW`) {
43
- const getWatchNumber = properties.watch_parameters.watch_number ?? null
44
- if (getWatchNumber) {
45
- return `${properties.geocode.office.office}.${stanza.getType.prefix}.A.${getWatchNumber}`
46
- }
47
- return `${properties.geocode.office.office}.${attributes.ttaaii}.${attributes.id.slice(-4).replace(`.`, ``) ?? '0'}`
48
- }
49
- if (options.type === `VTEC`) {
50
- return vtec.tracking;
51
- }
52
- if (options.type === `API`) {
53
- if (options.vtec) {
54
- const vtecValue = Array.isArray(options.vtec)
55
- ? options.vtec[0].vtec : options.vtec?.vtec;
56
- const splitPVTEC = vtecValue.split('.');
57
- return `${splitPVTEC[2]}.${splitPVTEC[3]}.${splitPVTEC[4]}.${splitPVTEC[5]}`;
58
- }
59
- const wmoMatch = options.organization?.wmoidentifier?.match(/([A-Z]{4}\d{2})\s+([A-Z]{4})/);
60
- const station = wmoMatch?.[2] ?? 'N/A';
61
- if (options.organization.featureId) {
62
- const idMatch = options.organization.featureId.match(/([a-f0-9]+)\.(\d+)\.(\d+)$/);
63
- return `${station}.${idMatch?.[0]?.replace(/\./g, '') ?? 'N/A'}`;
64
- }
65
- const id = wmoMatch?.[1] ?? 'N/A';
66
- return `${station}.${id?.replace(/\./g, '') ?? 'N/A'}`;
67
- }
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: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
15
+
16
+ Internal Package: @atmosx/event-product-parser
17
+
18
+ */
19
+
20
+ import { TypeAttributes } from "../@types/type.attributes";
21
+ import { TypeEventProperties } from "../@types/type.properties";
22
+ import { TypeStanzaCompiled } from "../@types/type.compiled";
23
+ import { TypePVTEC } from "../@types/type.pvtec";
24
+
25
+ interface GetTrackingOptions {
26
+ type: `RAW` | `VTEC` | `API`
27
+ stanza?: TypeStanzaCompiled
28
+ attributes?: TypeAttributes
29
+ properties?: TypeEventProperties
30
+ organization?: {
31
+ wmoidentifier: string
32
+ featureId: string
33
+ }
34
+ vtec?: TypePVTEC
35
+ }
36
+
37
+ export const getEventTracking = (options: GetTrackingOptions): string => {
38
+ const properties = options.properties
39
+ const attributes = options.attributes
40
+ const stanza = options.stanza
41
+ const vtec = options.vtec
42
+ if (options.type === `RAW`) {
43
+ const getWatchNumber = properties.watch_parameters.watch_number ?? null
44
+ if (getWatchNumber) {
45
+ return `${properties.geocode.office.office}.${stanza.getType.prefix}.A.${getWatchNumber}`
46
+ }
47
+ return `${properties.geocode.office.office}.${attributes.ttaaii}.${attributes.id.slice(-4).replace(`.`, ``) ?? '0'}`
48
+ }
49
+ if (options.type === `VTEC`) {
50
+ return vtec.tracking;
51
+ }
52
+ if (options.type === `API`) {
53
+ if (options.vtec) {
54
+ const vtecValue = Array.isArray(options.vtec)
55
+ ? options.vtec[0].vtec : options.vtec?.vtec;
56
+ const splitPVTEC = vtecValue.split('.');
57
+ return `${splitPVTEC[2]}.${splitPVTEC[3]}.${splitPVTEC[4]}.${splitPVTEC[5]}`;
58
+ }
59
+ const wmoMatch = options.organization?.wmoidentifier?.match(/([A-Z]{4}\d{2})\s+([A-Z]{4})/);
60
+ const station = wmoMatch?.[2] ?? '---';
61
+ if (options.organization.featureId) {
62
+ const idMatch = options.organization.featureId.match(/([a-f0-9]+)\.(\d+)\.(\d+)$/);
63
+ return `${station}.${idMatch?.[0]?.replace(/\./g, '') ?? '---'}`;
64
+ }
65
+ const id = wmoMatch?.[1] ?? '---';
66
+ return `${station}.${id?.replace(/\./g, '') ?? '---'}`;
67
+ }
68
68
  }
@@ -1,147 +1,153 @@
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: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
15
-
16
- Internal Package: @atmosx/event-product-parser
17
-
18
- */
19
-
20
- import { createHash } from "crypto"
21
- import { TypeEvent } from "../@types/type.event";
22
- import { TypeSettings } from "../@types/type.settings";
23
- import { bootstrap } from "../bootstrap"
24
- import { getEventEnhancedName } from "./building.enhance";
25
- import { getEventSignature } from "./building.signature"
26
- import { mkEvent } from "../@manager/manager.mkEvent";
27
- import { rmEvent } from "../@manager/manager.rmEvent";
28
- import { getEventGeometry } from "./building.geometry";
29
- import { getEventAttachments } from "./building.attachments";
30
- import { updateNode } from "../@manager/manager.updateNodes";
31
- import { setEventEmit } from "../@modules/@utilities/utilities.setEventEmit";
32
-
33
- export const validateEvents = async (events: TypeEvent[]): Promise<void> => {
34
- if (events.length === 0) return;
35
- const configurations = bootstrap.settings as TypeSettings
36
- const sets = {} as Record<string, Set<string>>;
37
- const bools = {} as Record<string, boolean>;
38
- const megered = {...configurations.GlobalSettings, ...configurations.GlobalSettings.EventFiltering}
39
- for (const key in megered) {
40
- const setting = megered[key];
41
- if (Array.isArray(setting)) { sets[key] = new Set(setting.map(item => item.toLowerCase())); }
42
- if (typeof setting === 'boolean') { bools[key] = setting; }
43
- }
44
- const filterd = events.filter((event: TypeEvent) => {
45
- const define = getEventSignature(event) as TypeEvent;
46
- const properties = define.properties;
47
- const zones = properties.geocode.ugc;
48
- const icao = properties.geocode.office.office
49
- const enhancedEventName = properties.event = getEventEnhancedName(event)
50
- const filteredProperties = JSON.parse(JSON.stringify(properties)) as typeof properties;
51
- if (filteredProperties?.metadata && 'ms' in filteredProperties.metadata) {
52
- delete filteredProperties.metadata.ms;
53
- }
54
- filteredProperties.metadata = filteredProperties.metadata ?? {} as any;
55
- properties.metadata.hash = createHash("sha256").update(JSON.stringify(filteredProperties)).digest("hex")
56
- properties.metadata.attachments = getEventAttachments(event)
57
- setEventEmit({ event: `onProductType${enhancedEventName.replace(/\s+/g, '')}`, metadata: define });
58
-
59
- if (properties.status_metadata.is_test) {
60
- setEventEmit({ event: `onTestProduct`, metadata: define })
61
- if (bools?.IgnoreTestProducts) return false;
62
- }
63
-
64
- if (properties.status_metadata.is_expired) {
65
- setEventEmit({ event: `onExpiredProduct`, metadata: define })
66
- rmEvent(define)
67
- return false;
68
- }
69
-
70
- if (properties.metadata?.vtec?.is_watch && properties.metadata.source != `events.api`) {
71
- const isSPC = properties.metadata?.vtec?.prediction_center;
72
- setEventEmit({ event: isSPC ? `onStormPredictionWatch` : `onNonStormPredictionWatch`, metadata: define })
73
- if (bools?.SPCWatchesOnly && !isSPC) {
74
- return false;
75
- }
76
- if ((!bools?.SPCWatchesOnly) && isSPC) {
77
- return false
78
- }
79
- }
80
-
81
- for (const key in sets) {
82
- const setting = sets[key]
83
- if (key === 'ListeningEvents' && setting.size > 0 && !setting.has(define.properties.event.toLowerCase())) {
84
- setEventEmit({
85
- event: `onFilteredEvent`,
86
- metadata: define
87
- });
88
- return false
89
- }
90
- if (key === 'IgnoredEvents' && setting.size > 0 && setting.has(define.properties.event.toLowerCase())) {
91
- setEventEmit({
92
- event: `onIgnoredEvent`,
93
- metadata: define
94
- });
95
- return false
96
- }
97
- if (key === 'ListeningICAO' && setting.size > 0 && icao != null && !setting.has(icao.toLowerCase())) {
98
- setEventEmit({
99
- event: `onFilteredICAO`,
100
- metadata: define
101
- });
102
- return false
103
- }
104
- if (key === 'IgnoredICAO' && setting.size > 0 && icao != null && setting.has(icao.toLowerCase())) {
105
- setEventEmit({
106
- event: `onIgnoredICAO`,
107
- metadata: define
108
- });
109
- return false
110
- }
111
- if (key === 'ListeningUGC' && setting.size > 0 && zones.length > 0 && !zones.some((ugc: string) => setting.has(ugc.toLowerCase()))) {
112
- setEventEmit({
113
- event: `onFilteredUGC`,
114
- metadata: define
115
- });
116
- return false
117
- }
118
- if (key === 'ListeningStates' && setting.size > 0 && zones.length > 0 && !zones.some((ugc: string) => setting.has(ugc.substring(0, 2).toLowerCase()))) {
119
- setEventEmit({
120
- event: `onFilteredState`,
121
- metadata: define
122
- });
123
- return false
124
- }
125
- }
126
- return true;
127
- })
128
-
129
-
130
- if (!configurations?.GlobalSettings?.DisableGeometryParsing) {
131
- for (const event of filterd) {
132
- event.geometry = await getEventGeometry(event)
133
- }
134
- }
135
-
136
- if (filterd.length > 0) {
137
- for (const event of filterd) {
138
- await mkEvent(event)
139
- }
140
- }
141
- await updateNode()
142
- setEventEmit({
143
- event: `onEventCache`,
144
- metadata: bootstrap.cache.events,
145
- limited: true
146
- })
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: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
15
+
16
+ Internal Package: @atmosx/event-product-parser
17
+
18
+ */
19
+
20
+ import { TypeEvent } from "../@types/type.event";
21
+ import { TypeSettings } from "../@types/type.settings";
22
+ import { bootstrap } from "../bootstrap"
23
+ import { getEventEnhancedName } from "./building.enhance";
24
+ import { getEventSignature } from "./building.signature"
25
+ import { mkEvent } from "../@manager/manager.mkEvent";
26
+ import { rmEvent } from "../@manager/manager.rmEvent";
27
+ import { getEventAttachments } from "./building.attachments";
28
+ import { updateNode } from "../@manager/manager.updateNodes";
29
+ import { setEventEmit } from "../@modules/@utilities/utilities.setEventEmit";
30
+ import { setDebug } from "../@modules/@utilities/utilities.setDebug";
31
+ import { getMatched } from "../@modules/@utilities/utilities.getMatched";
32
+ import { getEventGeometry } from "../@building/building.geometry";
33
+ import { createHash } from "crypto"
34
+
35
+ export const validateEvents = async (events: TypeEvent[]): Promise<void> => {
36
+ const tick = performance.now();
37
+ if (events.length === 0) return
38
+ const configurations = bootstrap.settings as TypeSettings
39
+ const sets = {} as Record<string, Set<string>>;
40
+ const bools = {} as Record<string, boolean>;
41
+ const megered = {...configurations.GlobalSettings, ...configurations.GlobalSettings.EventFiltering}
42
+ for (const key in megered) {
43
+ const setting = megered[key];
44
+ if (Array.isArray(setting)) { sets[key] = new Set(setting.map(item => item.toLowerCase())); }
45
+ if (typeof setting === 'boolean') { bools[key] = setting; }
46
+ }
47
+
48
+ const isFiltered = (define: TypeEvent): boolean => {
49
+ const properties = define.properties;
50
+ const zones = properties.geocode.ugc;
51
+ const icao = properties.geocode.office.office
52
+
53
+ if (properties.status_metadata.is_test) {
54
+ setEventEmit({ event: `onTestProduct`, metadata: define })
55
+ if (bools?.IgnoreTestProducts) return true;
56
+ }
57
+
58
+ if (properties.status_metadata.is_expired) {
59
+ setEventEmit({ event: `onExpiredProduct`, metadata: define })
60
+ rmEvent(define)
61
+ return true;
62
+ }
63
+
64
+ if (properties.metadata?.vtec?.is_watch && properties.metadata.source != `events.api`) {
65
+ const isSPC = properties.metadata?.vtec?.prediction_center;
66
+ setEventEmit({ event: isSPC ? `onStormPredictionWatch` : `onNonStormPredictionWatch`, metadata: define })
67
+ if (bools?.SPCWatchesOnly && !isSPC) {
68
+ return true;
69
+ }
70
+ if ((!bools?.SPCWatchesOnly) && isSPC) {
71
+ return true
72
+ }
73
+ }
74
+
75
+ for (const key in sets) {
76
+ const setting = sets[key]
77
+ const values = [...setting];
78
+ if (key === 'ListeningEvents' && setting.size > 0 && !getMatched(values, define.properties.event)) {
79
+ setEventEmit({
80
+ event: `onFilteredEvent`,
81
+ metadata: define
82
+ });
83
+ return true
84
+ }
85
+ if (key === 'IgnoredEvents' && setting.size > 0 && getMatched(values, define.properties.event)) {
86
+ setEventEmit({
87
+ event: `onIgnoredEvent`,
88
+ metadata: define
89
+ });
90
+ return true
91
+ }
92
+ if (key === 'ListeningICAO' && setting.size > 0 && icao != null && !setting.has(icao.toLowerCase())) {
93
+ setEventEmit({
94
+ event: `onFilteredICAO`,
95
+ metadata: define
96
+ });
97
+ return true
98
+ }
99
+ if (key === 'IgnoredICAO' && setting.size > 0 && icao != null && setting.has(icao.toLowerCase())) {
100
+ setEventEmit({
101
+ event: `onIgnoredICAO`,
102
+ metadata: define
103
+ });
104
+ return true
105
+ }
106
+ if (key === 'ListeningUGC' && setting.size > 0 && zones.length > 0 && !zones.some((ugc: string) => setting.has(ugc.toLowerCase()))) {
107
+ setEventEmit({
108
+ event: `onFilteredUGC`,
109
+ metadata: define
110
+ });
111
+ return true
112
+ }
113
+ if (key === 'ListeningStates' && setting.size > 0 && zones.length > 0 && !zones.some((ugc: string) => setting.has(ugc.substring(0, 2).toLowerCase()))) {
114
+ setEventEmit({
115
+ event: `onFilteredState`,
116
+ metadata: define
117
+ });
118
+ return true
119
+ }
120
+ }
121
+ return false
122
+ }
123
+
124
+ const filtering = events.filter((event: TypeEvent) => {
125
+ bootstrap.cache.processed = bootstrap.cache.processed.filter((e) => e !== event);
126
+ const define = getEventSignature(event) as TypeEvent;
127
+ const properties = define.properties; delete properties?.metadata?.ms;
128
+ const enhanced = properties.event = getEventEnhancedName(event)
129
+ const filtered = isFiltered(define)
130
+ if (!filtered) {
131
+ event.geometry = !bools?.DisableGeometryParsing ? getEventGeometry(event) : null;
132
+ properties.metadata.attachments = getEventAttachments(event)
133
+ }
134
+ properties.metadata.hash = createHash("sha256").update(JSON.stringify(properties)).digest("hex")
135
+ setEventEmit({ event: `onProductType${enhanced.replace(/\s+/g, '')}`, metadata: define });
136
+ return !filtered
137
+ })
138
+
139
+
140
+ if (filtering.length > 0) {
141
+ for (const event of filtering) {
142
+ await mkEvent(event)
143
+ }
144
+ }
145
+
146
+ await updateNode()
147
+ setEventEmit({
148
+ event: `onEventCache`,
149
+ metadata: bootstrap.cache.events,
150
+ limited: true
151
+ })
152
+ setDebug({ title: `@building.validate`, message: `Filtered ${filtering.length} events which took ${performance.now() - tick} ms` })
147
153
  }