metar-taf-parser 1.2.0 → 2.0.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 (121) hide show
  1. package/README.md +85 -12
  2. package/dist/command/common.js +13 -10
  3. package/dist/command/metar/AltimeterCommand.d.ts +7 -0
  4. package/dist/command/metar/AltimeterCommand.js +26 -0
  5. package/dist/command/metar/AltimeterMercuryCommand.d.ts +7 -0
  6. package/dist/command/metar/AltimeterMercuryCommand.js +51 -0
  7. package/dist/command/metar/RunwayCommand.d.ts +7 -0
  8. package/dist/command/metar/RunwayCommand.js +60 -0
  9. package/dist/command/metar/TemperatureCommand.d.ts +7 -0
  10. package/dist/command/metar/TemperatureCommand.js +51 -0
  11. package/dist/command/metar.d.ts +1 -22
  12. package/dist/command/metar.js +10 -113
  13. package/dist/command/remark/CeilingHeightCommand.d.ts +18 -0
  14. package/dist/command/remark/CeilingHeightCommand.js +40 -0
  15. package/dist/command/remark/CeilingSecondLocationCommand.d.ts +12 -0
  16. package/dist/command/remark/CeilingSecondLocationCommand.js +40 -0
  17. package/dist/command/remark/Command.d.ts +8 -0
  18. package/dist/command/remark/Command.js +9 -0
  19. package/dist/command/remark/DefaultCommand.d.ts +11 -0
  20. package/dist/command/remark/DefaultCommand.js +38 -0
  21. package/dist/command/remark/HailSizeCommand.d.ts +11 -0
  22. package/dist/command/remark/HailSizeCommand.js +37 -0
  23. package/dist/command/remark/HourlyMaximumMinimumTemperatureCommand.d.ts +18 -0
  24. package/dist/command/remark/HourlyMaximumMinimumTemperatureCommand.js +39 -0
  25. package/dist/command/remark/HourlyMaximumTemperatureCommand.d.ts +14 -0
  26. package/dist/command/remark/HourlyMaximumTemperatureCommand.js +38 -0
  27. package/dist/command/remark/HourlyMinimumTemperatureCommand.d.ts +14 -0
  28. package/dist/command/remark/HourlyMinimumTemperatureCommand.js +38 -0
  29. package/dist/command/remark/HourlyPrecipitationAmountCommand.d.ts +14 -0
  30. package/dist/command/remark/HourlyPrecipitationAmountCommand.js +38 -0
  31. package/dist/command/remark/HourlyPressureCommand.d.ts +32 -0
  32. package/dist/command/remark/HourlyPressureCommand.js +40 -0
  33. package/dist/command/remark/HourlyTemperatureDewPointCommand.d.ts +18 -0
  34. package/dist/command/remark/HourlyTemperatureDewPointCommand.js +52 -0
  35. package/dist/command/remark/IceAccretionCommand.d.ts +15 -0
  36. package/dist/command/remark/IceAccretionCommand.js +38 -0
  37. package/dist/command/remark/ObscurationCommand.d.ts +14 -0
  38. package/dist/command/remark/ObscurationCommand.js +44 -0
  39. package/dist/command/remark/PrecipitationAmount24HourCommand.d.ts +14 -0
  40. package/dist/command/remark/PrecipitationAmount24HourCommand.js +39 -0
  41. package/dist/command/remark/PrecipitationAmount36HourCommand.d.ts +15 -0
  42. package/dist/command/remark/PrecipitationAmount36HourCommand.js +41 -0
  43. package/dist/command/remark/PrecipitationBegCommand.d.ts +15 -0
  44. package/dist/command/remark/PrecipitationBegCommand.js +45 -0
  45. package/dist/command/remark/PrecipitationBegEndCommand.d.ts +17 -0
  46. package/dist/command/remark/PrecipitationBegEndCommand.js +46 -0
  47. package/dist/command/remark/PrecipitationEndCommand.d.ts +15 -0
  48. package/dist/command/remark/PrecipitationEndCommand.js +45 -0
  49. package/dist/command/remark/PrevailingVisibilityCommand.d.ts +12 -0
  50. package/dist/command/remark/PrevailingVisibilityCommand.js +40 -0
  51. package/dist/command/remark/SeaLevelPressureCommand.d.ts +11 -0
  52. package/dist/command/remark/SeaLevelPressureCommand.js +39 -0
  53. package/dist/command/remark/SecondLocationVisibilityCommand.d.ts +12 -0
  54. package/dist/command/remark/SecondLocationVisibilityCommand.js +40 -0
  55. package/dist/command/remark/SectorVisibilityCommand.d.ts +13 -0
  56. package/dist/command/remark/SectorVisibilityCommand.js +41 -0
  57. package/dist/command/remark/SmallHailSizeCommand.d.ts +11 -0
  58. package/dist/command/remark/SmallHailSizeCommand.js +37 -0
  59. package/dist/command/remark/SnowDepthCommand.d.ts +11 -0
  60. package/dist/command/remark/SnowDepthCommand.js +38 -0
  61. package/dist/command/remark/SnowIncreaseCommand.d.ts +12 -0
  62. package/dist/command/remark/SnowIncreaseCommand.js +40 -0
  63. package/dist/command/remark/SnowPelletsCommand.d.ts +11 -0
  64. package/dist/command/remark/SnowPelletsCommand.js +37 -0
  65. package/dist/command/remark/SunshineDurationCommand.d.ts +11 -0
  66. package/dist/command/remark/SunshineDurationCommand.js +38 -0
  67. package/dist/command/remark/SurfaceVisibilityCommand.d.ts +11 -0
  68. package/dist/command/remark/SurfaceVisibilityCommand.js +38 -0
  69. package/dist/command/remark/ThunderStormLocationCommand.d.ts +12 -0
  70. package/dist/command/remark/ThunderStormLocationCommand.js +40 -0
  71. package/dist/command/remark/ThunderStormLocationMovingCommand.d.ts +19 -0
  72. package/dist/command/remark/ThunderStormLocationMovingCommand.js +42 -0
  73. package/dist/command/remark/TornadicActivityBegCommand.d.ts +16 -0
  74. package/dist/command/remark/TornadicActivityBegCommand.js +44 -0
  75. package/dist/command/remark/TornadicActivityBegEndCommand.d.ts +18 -0
  76. package/dist/command/remark/TornadicActivityBegEndCommand.js +46 -0
  77. package/dist/command/remark/TornadicActivityEndCommand.d.ts +16 -0
  78. package/dist/command/remark/TornadicActivityEndCommand.js +44 -0
  79. package/dist/command/remark/TowerVisibilityCommand.d.ts +11 -0
  80. package/dist/command/remark/TowerVisibilityCommand.js +38 -0
  81. package/dist/command/remark/VariableSkyCommand.d.ts +12 -0
  82. package/dist/command/remark/VariableSkyCommand.js +41 -0
  83. package/dist/command/remark/VariableSkyHeightCommand.d.ts +13 -0
  84. package/dist/command/remark/VariableSkyHeightCommand.js +43 -0
  85. package/dist/command/remark/VirgaDirectionCommand.d.ts +12 -0
  86. package/dist/command/remark/VirgaDirectionCommand.js +40 -0
  87. package/dist/command/remark/WaterEquivalentSnowCommand.d.ts +11 -0
  88. package/dist/command/remark/WaterEquivalentSnowCommand.js +38 -0
  89. package/dist/command/remark/WindPeakCommandCommand.d.ts +17 -0
  90. package/dist/command/remark/WindPeakCommandCommand.js +42 -0
  91. package/dist/command/remark/WindShiftCommand.d.ts +12 -0
  92. package/dist/command/remark/WindShiftCommand.js +38 -0
  93. package/dist/command/remark/WindShiftFropaCommand.d.ts +12 -0
  94. package/dist/command/remark/WindShiftFropaCommand.js +38 -0
  95. package/dist/command/remark.d.ts +100 -194
  96. package/dist/command/remark.js +135 -753
  97. package/dist/commons/converter.d.ts +14 -2
  98. package/dist/commons/converter.js +53 -5
  99. package/dist/commons/errors.d.ts +6 -2
  100. package/dist/commons/errors.js +15 -8
  101. package/dist/commons/i18n.d.ts +2 -2
  102. package/dist/commons/i18n.js +9 -3
  103. package/dist/dates/metar.d.ts +5 -0
  104. package/dist/dates/metar.js +8 -0
  105. package/dist/dates/taf.d.ts +28 -0
  106. package/dist/dates/taf.js +17 -0
  107. package/dist/forecast/forecast.d.ts +36 -0
  108. package/dist/forecast/forecast.js +73 -0
  109. package/dist/helpers/date.d.ts +11 -0
  110. package/dist/helpers/date.js +56 -0
  111. package/dist/helpers/helpers.d.ts +7 -0
  112. package/dist/helpers/helpers.js +14 -1
  113. package/dist/index.d.ts +23 -2
  114. package/dist/index.js +24 -7
  115. package/dist/model/enum.d.ts +44 -0
  116. package/dist/model/enum.js +50 -1
  117. package/dist/model/model.d.ts +84 -19
  118. package/dist/model/model.js +3 -1
  119. package/dist/parser/parser.d.ts +13 -6
  120. package/dist/parser/parser.js +63 -29
  121. package/package.json +3 -3
package/README.md CHANGED
@@ -14,31 +14,104 @@ npm i --save metar-taf-parser
14
14
 
15
15
  ## Usage
16
16
 
17
- ### Parse a METAR
17
+ ### Parsing
18
+
19
+ The `parseMetar` & `parseTAF` functions are designed to parse the raw report string into an object representation of a METAR/TAF.
20
+
21
+ #### `parseMetar`
22
+
23
+ ```ts
24
+ import { parseMetar } from "metar-taf-parser";
25
+
26
+ const metar = parseMetar(rawMetarString);
27
+
28
+ // -or-
29
+
30
+ // Optionally pass a date (approximately when the report was issued, +/- a week)
31
+ // to get the issued date on the report:
32
+ const datedMetar = parseMetar(rawMetarString, { date: new Date() });
33
+ ```
34
+
35
+ #### `parseTAF`
36
+
37
+ 👉 **Note:** One of the common use cases for TAF reports is to get relevant forecast data for a given date. Check out [the `Forecast` abstraction](#higher-level-parsing-the-forecast-abstraction) below which may provide TAF data in a more normalized format, depending on your use case.
18
38
 
19
39
  ```ts
20
- import { parseMetar } from 'metar-taf-parser'
40
+ import { parseTAF } from "metar-taf-parser";
41
+
42
+ const taf = parseTAF(rawTAFString);
21
43
 
22
- const metar = parseMetar(rawMetarString)
44
+ // -or-
45
+
46
+ // Optionally pass a date (approximately when the report was issued, +/- a week)
47
+ // to get the report issued and trend validity dates (start/end) on the report:
48
+ const datedTAF = parseTAF(rawTAFString, { date: new Date() });
23
49
  ```
24
50
 
25
- ### Parse a TAF
51
+ ### Higher level parsing: The Forecast abstraction
52
+
53
+ TAF reports are a little funky... FM, BECMG, PROB, etc. You may find the `Forecast` abstraction more helpful.
54
+
55
+ #### `parseTAFAsForecast`
56
+
57
+ Returns a more normalized TAF report. Most notably: while the `parseTAF` function returns initial weather conditions on the base of the returned result (and further conditions on `trends[]`), the `parseTAFAsForecast` function returns the initial weather conditions as the first element of the `forecast[]` property, followed by subsequent trends. This makes it much easier to iterate though.
26
58
 
27
59
  ```ts
28
- import { parseTAF } from 'metar-taf-parser'
60
+ import { parseTAFAsForecast } from "metar-taf-parser";
61
+
62
+ // You must provide an issued date to use the Forecast abstraction
63
+ const report = parseTAFAsForecast(rawTAFString, { date: tafIssuedDate });
64
+
65
+ console.log(report.forecast);
66
+ ```
67
+
68
+ #### `getCompositeForecastForDate`
69
+
70
+ > ⚠️ **Warning:** Experimental API
71
+
72
+ Provides all relevant weather conditions for a given timestamp. It returns a `ICompositeForecast` with a `base` and `additional` component. The `base` component is the base weather condition period (the FM part of the report) - and there will always be one.
29
73
 
30
- const taf = parseTAF(rawTAFString)
74
+ The `additional` property is an array of weather condition periods valid for the given timestamp (any `BECMG`, `PROB`, `TEMPO`, etc.)
75
+
76
+ You will still need to write some logic to use this API to determine what data to use - for example, if `additional[0].visibility` exists, use it over `base.visibility`.
77
+
78
+ #### Example
79
+
80
+ This example provides an array of hourly weather conditions over the duration of the TAF report.
81
+
82
+ ```ts
83
+ import { eachHourOfInterval } from "date-fns";
84
+ import {
85
+ parseTAFAsForecast,
86
+ getCompositeForecastForDate,
87
+ } from "metar-taf-parser";
88
+
89
+ const report = parseTAFAsForecast(rawTAFString, { date: tafIssuedDate });
90
+
91
+ const forecastPerHour = eachHourOfInterval({
92
+ start: report.start,
93
+ end: report.end,
94
+ }).map((hour) => ({
95
+ hour,
96
+ ...getCompositeForecastForDate(hour, report),
97
+ }));
31
98
  ```
32
99
 
33
100
  ## i18n
34
101
 
102
+ The `description` property in the `Remark` is translated, if available.
103
+
35
104
  ```ts
36
- import { parseMetar } from 'metar-taf-parser'
37
- import de from 'metar-taf-parser/dist/locale/de'
105
+ import { parseMetar } from "metar-taf-parser";
106
+ import de from "metar-taf-parser/dist/locale/de";
107
+
108
+ const rawMetarReport = "KTTN 051853Z 04011KT RMK SLP176";
38
109
 
39
- const { metar } = await myService.getAirportData('KMSN')
110
+ const metarResult = parseMetar(rawMetarReport, {
111
+ locale: de,
112
+ });
40
113
 
41
- const metarResult = parseMetar(metar, { locale: de })
114
+ console.log(metarReport.remarks[0].description);
42
115
  ```
43
116
 
44
117
  ## Development
@@ -49,8 +122,8 @@ Please see [the example site README.md](example/README.md).
49
122
 
50
123
  ## Contributing
51
124
 
52
- This project is intended to provide feature parity with [python-metar-taf-parser](https://github.com/mivek/python-metar-taf-parser) and will only accept PRs to maintain feature parity or to fix inconsistencies with that project.
125
+ This project is based on [python-metar-taf-parser](https://github.com/mivek/python-metar-taf-parser) and the parsing should be as similar to that project as possible. That being said, PRs are welcome.
53
126
 
54
127
  ## Acknowledgment
55
128
 
56
- This software port was made possible due to the fantastic work of [@mivek](https://github.com/mivek) in [python-metar-taf-parser](https://github.com/mivek/python-metar-taf-parser). If you like this project, please [consider buying @mivek a coffee](https://ko-fi.com/mivek).
129
+ This software port was made possible due to the fantastic work of [@mivek](https://github.com/mivek) in [python-metar-taf-parser](https://github.com/mivek/python-metar-taf-parser). If you like this project, please [consider buying @mivek a coffee](https://ko-fi.com/mivek).
@@ -92,8 +92,10 @@ class MainVisibilityCommand {
92
92
  return false;
93
93
  const distance = converter.convertVisibility(matches[1]);
94
94
  if (!container.visibility)
95
- container.visibility = { distance };
96
- container.visibility.distance = distance;
95
+ container.visibility = distance;
96
+ container.visibility = Object.assign(Object.assign({}, container.visibility), distance);
97
+ if (matches[2] === "NDV")
98
+ container.visibility.ndv = true;
97
99
  return true;
98
100
  }
99
101
  }
@@ -136,7 +138,7 @@ class WindVariationCommand {
136
138
  }
137
139
  execute(container, windString) {
138
140
  if (!container.wind)
139
- throw new errors_1.InvalidWeatherStatementError();
141
+ throw new errors_1.UnexpectedParseError();
140
142
  this.parseWindVariation(container.wind, windString);
141
143
  return true;
142
144
  }
@@ -182,7 +184,7 @@ exports.VerticalVisibilityCommand = VerticalVisibilityCommand;
182
184
  _VerticalVisibilityCommand_regex = new WeakMap();
183
185
  class MinimalVisibilityCommand {
184
186
  constructor() {
185
- _MinimalVisibilityCommand_regex.set(this, /^(\d{4}[a-z])$/);
187
+ _MinimalVisibilityCommand_regex.set(this, /^(\d{4}[a-zA-Z]{1,2})$/);
186
188
  }
187
189
  execute(container, visibilityString) {
188
190
  const matches = visibilityString.match(__classPrivateFieldGet(this, _MinimalVisibilityCommand_regex, "f"));
@@ -190,8 +192,10 @@ class MinimalVisibilityCommand {
190
192
  throw new errors_1.UnexpectedParseError("Vertical visibility should be defined");
191
193
  if (!container.visibility)
192
194
  throw new errors_1.UnexpectedParseError("container.visibility not instantiated");
193
- container.visibility.minDistance = +matches[1].slice(0, 4);
194
- container.visibility.minDirection = matches[1][4];
195
+ container.visibility.min = {
196
+ value: +matches[1].slice(0, 4),
197
+ direction: matches[1].slice(4),
198
+ };
195
199
  return true;
196
200
  }
197
201
  canParse(windString) {
@@ -202,12 +206,11 @@ exports.MinimalVisibilityCommand = MinimalVisibilityCommand;
202
206
  _MinimalVisibilityCommand_regex = new WeakMap();
203
207
  class MainVisibilityNauticalMilesCommand {
204
208
  constructor() {
205
- _MainVisibilityNauticalMilesCommand_regex.set(this, /^(\d)*(\s)?((\d\/\d)?SM)$/);
209
+ _MainVisibilityNauticalMilesCommand_regex.set(this, /^(P|M)?(\d)*(\s)?((\d\/\d)?SM)$/);
206
210
  }
207
211
  execute(container, visibilityString) {
208
- if (!container.visibility)
209
- container.visibility = { distance: visibilityString };
210
- container.visibility.distance = visibilityString;
212
+ const distance = converter.convertNauticalMilesVisibility(visibilityString);
213
+ container.visibility = distance;
211
214
  return true;
212
215
  }
213
216
  canParse(windString) {
@@ -0,0 +1,7 @@
1
+ import { IMetar } from "../../model/model";
2
+ import { ICommand } from "../metar";
3
+ export declare class AltimeterCommand implements ICommand {
4
+ #private;
5
+ canParse(input: string): boolean;
6
+ execute(metar: IMetar, input: string): void;
7
+ }
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
+ };
7
+ var _AltimeterCommand_regex;
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.AltimeterCommand = void 0;
10
+ const errors_1 = require("../../commons/errors");
11
+ class AltimeterCommand {
12
+ constructor() {
13
+ _AltimeterCommand_regex.set(this, /^Q(\d{4})$/);
14
+ }
15
+ canParse(input) {
16
+ return __classPrivateFieldGet(this, _AltimeterCommand_regex, "f").test(input);
17
+ }
18
+ execute(metar, input) {
19
+ const matches = input.match(__classPrivateFieldGet(this, _AltimeterCommand_regex, "f"));
20
+ if (!matches)
21
+ throw new errors_1.UnexpectedParseError("Match not found");
22
+ metar.altimeter = Math.trunc(+matches[1]);
23
+ }
24
+ }
25
+ exports.AltimeterCommand = AltimeterCommand;
26
+ _AltimeterCommand_regex = new WeakMap();
@@ -0,0 +1,7 @@
1
+ import { IMetar } from "../../model/model";
2
+ import { ICommand } from "../metar";
3
+ export declare class AltimeterMercuryCommand implements ICommand {
4
+ #private;
5
+ canParse(input: string): boolean;
6
+ execute(metar: IMetar, input: string): void;
7
+ }
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
26
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
27
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
28
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
29
+ };
30
+ var _AltimeterMercuryCommand_regex;
31
+ Object.defineProperty(exports, "__esModule", { value: true });
32
+ exports.AltimeterMercuryCommand = void 0;
33
+ const converter = __importStar(require("../../commons/converter"));
34
+ const errors_1 = require("../../commons/errors");
35
+ class AltimeterMercuryCommand {
36
+ constructor() {
37
+ _AltimeterMercuryCommand_regex.set(this, /^A(\d{4})$/);
38
+ }
39
+ canParse(input) {
40
+ return __classPrivateFieldGet(this, _AltimeterMercuryCommand_regex, "f").test(input);
41
+ }
42
+ execute(metar, input) {
43
+ const matches = input.match(__classPrivateFieldGet(this, _AltimeterMercuryCommand_regex, "f"));
44
+ if (!matches)
45
+ throw new errors_1.UnexpectedParseError("Match not found");
46
+ const mercury = +matches[1] / 100;
47
+ metar.altimeter = Math.trunc(converter.convertInchesMercuryToPascal(mercury));
48
+ }
49
+ }
50
+ exports.AltimeterMercuryCommand = AltimeterMercuryCommand;
51
+ _AltimeterMercuryCommand_regex = new WeakMap();
@@ -0,0 +1,7 @@
1
+ import { IMetar } from "../../model/model";
2
+ import { ICommand } from "../metar";
3
+ export declare class RunwayCommand implements ICommand {
4
+ #private;
5
+ canParse(input: string): boolean;
6
+ execute(metar: IMetar, input: string): void;
7
+ }
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
+ };
7
+ var _RunwayCommand_genericRegex, _RunwayCommand_runwayMaxRangeRegex, _RunwayCommand_runwayRegex;
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.RunwayCommand = void 0;
10
+ const errors_1 = require("../../commons/errors");
11
+ const helpers_1 = require("../../helpers/helpers");
12
+ const enum_1 = require("../../model/enum");
13
+ class RunwayCommand {
14
+ constructor() {
15
+ _RunwayCommand_genericRegex.set(this, /^(R\d{2}\w?\/)/);
16
+ _RunwayCommand_runwayMaxRangeRegex.set(this, /^R(\d{2}\w?)\/(\d{4})V(\d{3,4})([UDN])?(FT)?/);
17
+ _RunwayCommand_runwayRegex.set(this, /^R(\d{2}\w?)\/([MP])?(\d{4})([UDN])?(FT)?$/);
18
+ }
19
+ canParse(input) {
20
+ return __classPrivateFieldGet(this, _RunwayCommand_genericRegex, "f").test(input);
21
+ }
22
+ execute(metar, input) {
23
+ // TODO idk if this matches super well...
24
+ if (__classPrivateFieldGet(this, _RunwayCommand_runwayRegex, "f").test(input)) {
25
+ const matches = input.match(__classPrivateFieldGet(this, _RunwayCommand_runwayRegex, "f"));
26
+ if (!matches)
27
+ throw new errors_1.UnexpectedParseError("Should be able to parse");
28
+ const indicator = matches[2] ? (0, helpers_1.as)(matches[2], enum_1.ValueIndicator) : undefined;
29
+ const trend = matches[4] ? (0, helpers_1.as)(matches[4], enum_1.RunwayInfoTrend) : undefined;
30
+ const unit = matches[5]
31
+ ? (0, helpers_1.as)(matches[5], enum_1.RunwayInfoUnit)
32
+ : enum_1.RunwayInfoUnit.Meters;
33
+ metar.runwaysInfo.push({
34
+ name: matches[1],
35
+ indicator,
36
+ minRange: +matches[3],
37
+ trend,
38
+ unit,
39
+ });
40
+ }
41
+ else if (__classPrivateFieldGet(this, _RunwayCommand_runwayMaxRangeRegex, "f").test(input)) {
42
+ const matches = input.match(__classPrivateFieldGet(this, _RunwayCommand_runwayMaxRangeRegex, "f"));
43
+ if (!matches)
44
+ throw new errors_1.UnexpectedParseError("Should be able to parse");
45
+ const trend = matches[4] ? (0, helpers_1.as)(matches[4], enum_1.RunwayInfoTrend) : undefined;
46
+ const unit = matches[5]
47
+ ? (0, helpers_1.as)(matches[5], enum_1.RunwayInfoUnit)
48
+ : enum_1.RunwayInfoUnit.Meters;
49
+ metar.runwaysInfo.push({
50
+ name: matches[1],
51
+ minRange: +matches[2],
52
+ maxRange: +matches[3],
53
+ trend,
54
+ unit,
55
+ });
56
+ }
57
+ }
58
+ }
59
+ exports.RunwayCommand = RunwayCommand;
60
+ _RunwayCommand_genericRegex = new WeakMap(), _RunwayCommand_runwayMaxRangeRegex = new WeakMap(), _RunwayCommand_runwayRegex = new WeakMap();
@@ -0,0 +1,7 @@
1
+ import { IMetar } from "../../model/model";
2
+ import { ICommand } from "../metar";
3
+ export declare class TemperatureCommand implements ICommand {
4
+ #private;
5
+ canParse(input: string): boolean;
6
+ execute(metar: IMetar, input: string): void;
7
+ }
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
26
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
27
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
28
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
29
+ };
30
+ var _TemperatureCommand_regex;
31
+ Object.defineProperty(exports, "__esModule", { value: true });
32
+ exports.TemperatureCommand = void 0;
33
+ const converter = __importStar(require("../../commons/converter"));
34
+ const errors_1 = require("../../commons/errors");
35
+ class TemperatureCommand {
36
+ constructor() {
37
+ _TemperatureCommand_regex.set(this, /^(M?\d{2})\/(M?\d{2})$/);
38
+ }
39
+ canParse(input) {
40
+ return __classPrivateFieldGet(this, _TemperatureCommand_regex, "f").test(input);
41
+ }
42
+ execute(metar, input) {
43
+ const matches = input.match(__classPrivateFieldGet(this, _TemperatureCommand_regex, "f"));
44
+ if (!matches)
45
+ throw new errors_1.UnexpectedParseError("Match not found");
46
+ metar.temperature = converter.convertTemperature(matches[1]);
47
+ metar.dewPoint = converter.convertTemperature(matches[2]);
48
+ }
49
+ }
50
+ exports.TemperatureCommand = TemperatureCommand;
51
+ _TemperatureCommand_regex = new WeakMap();
@@ -1,30 +1,9 @@
1
1
  import { IMetar } from "../model/model";
2
- interface ICommand {
2
+ export interface ICommand {
3
3
  canParse(str: string): boolean;
4
4
  execute(metar: IMetar, str: string): void;
5
5
  }
6
- export declare class AltimeterCommand implements ICommand {
7
- #private;
8
- canParse(input: string): boolean;
9
- execute(metar: IMetar, input: string): void;
10
- }
11
- export declare class AltimeterMercuryCommand implements ICommand {
12
- #private;
13
- canParse(input: string): boolean;
14
- execute(metar: IMetar, input: string): void;
15
- }
16
- export declare class RunwayCommand implements ICommand {
17
- #private;
18
- canParse(input: string): boolean;
19
- execute(metar: IMetar, input: string): void;
20
- }
21
- export declare class TemperatureCommand implements ICommand {
22
- #private;
23
- canParse(input: string): boolean;
24
- execute(metar: IMetar, input: string): void;
25
- }
26
6
  export declare class CommandSupplier {
27
7
  #private;
28
8
  get(input: string): ICommand | undefined;
29
9
  }
30
- export {};
@@ -1,126 +1,23 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
2
  var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
26
3
  if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
27
4
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
28
5
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
29
6
  };
30
- var _AltimeterCommand_regex, _AltimeterMercuryCommand_regex, _RunwayCommand_genericRegex, _RunwayCommand_runwayMaxRangeRegex, _RunwayCommand_runwayRegex, _TemperatureCommand_regex, _CommandSupplier_commands;
7
+ var _CommandSupplier_commands;
31
8
  Object.defineProperty(exports, "__esModule", { value: true });
32
- exports.CommandSupplier = exports.TemperatureCommand = exports.RunwayCommand = exports.AltimeterMercuryCommand = exports.AltimeterCommand = void 0;
33
- const converter = __importStar(require("../commons/converter"));
34
- const errors_1 = require("../commons/errors");
35
- class AltimeterCommand {
36
- constructor() {
37
- _AltimeterCommand_regex.set(this, /^Q(\d{4})$/);
38
- }
39
- canParse(input) {
40
- return __classPrivateFieldGet(this, _AltimeterCommand_regex, "f").test(input);
41
- }
42
- execute(metar, input) {
43
- const matches = input.match(__classPrivateFieldGet(this, _AltimeterCommand_regex, "f"));
44
- if (!matches)
45
- throw new errors_1.UnexpectedParseError("Match not found");
46
- metar.altimeter = Math.trunc(+matches[1]);
47
- }
48
- }
49
- exports.AltimeterCommand = AltimeterCommand;
50
- _AltimeterCommand_regex = new WeakMap();
51
- class AltimeterMercuryCommand {
52
- constructor() {
53
- _AltimeterMercuryCommand_regex.set(this, /^A(\d{4})$/);
54
- }
55
- canParse(input) {
56
- return __classPrivateFieldGet(this, _AltimeterMercuryCommand_regex, "f").test(input);
57
- }
58
- execute(metar, input) {
59
- const matches = input.match(__classPrivateFieldGet(this, _AltimeterMercuryCommand_regex, "f"));
60
- if (!matches)
61
- throw new errors_1.UnexpectedParseError("Match not found");
62
- const mercury = +matches[1] / 100;
63
- metar.altimeter = Math.trunc(converter.convertInchesMercuryToPascal(mercury));
64
- }
65
- }
66
- exports.AltimeterMercuryCommand = AltimeterMercuryCommand;
67
- _AltimeterMercuryCommand_regex = new WeakMap();
68
- class RunwayCommand {
69
- constructor() {
70
- _RunwayCommand_genericRegex.set(this, /^(R\d{2}\w?\/)/);
71
- _RunwayCommand_runwayMaxRangeRegex.set(this, /^R(\d{2}\w?)\/(\d{4})V(\d{3})(\w{0,2})/);
72
- _RunwayCommand_runwayRegex.set(this, /^R(\d{2}\w?)\/(\w)?(\d{4})(\w{0,2})$/);
73
- }
74
- canParse(input) {
75
- return __classPrivateFieldGet(this, _RunwayCommand_genericRegex, "f").test(input);
76
- }
77
- execute(metar, input) {
78
- const matches = input.match(__classPrivateFieldGet(this, _RunwayCommand_runwayRegex, "f"));
79
- // TODO idk if this matches super well...
80
- if (matches) {
81
- metar.runwaysInfo.push({
82
- name: matches[1],
83
- minRange: +matches[3],
84
- trend: matches[4],
85
- });
86
- }
87
- const maxRangeMatches = input.match(__classPrivateFieldGet(this, _RunwayCommand_runwayMaxRangeRegex, "f"));
88
- if (maxRangeMatches) {
89
- metar.runwaysInfo.push({
90
- name: maxRangeMatches[1],
91
- minRange: +maxRangeMatches[2],
92
- maxRange: +maxRangeMatches[3],
93
- trend: maxRangeMatches[4],
94
- });
95
- }
96
- }
97
- }
98
- exports.RunwayCommand = RunwayCommand;
99
- _RunwayCommand_genericRegex = new WeakMap(), _RunwayCommand_runwayMaxRangeRegex = new WeakMap(), _RunwayCommand_runwayRegex = new WeakMap();
100
- class TemperatureCommand {
101
- constructor() {
102
- _TemperatureCommand_regex.set(this, /^(M?\d{2})\/(M?\d{2})$/);
103
- }
104
- canParse(input) {
105
- return __classPrivateFieldGet(this, _TemperatureCommand_regex, "f").test(input);
106
- }
107
- execute(metar, input) {
108
- const matches = input.match(__classPrivateFieldGet(this, _TemperatureCommand_regex, "f"));
109
- if (!matches)
110
- throw new errors_1.UnexpectedParseError("Match not found");
111
- metar.temperature = converter.convertTemperature(matches[1]);
112
- metar.dewPoint = converter.convertTemperature(matches[2]);
113
- }
114
- }
115
- exports.TemperatureCommand = TemperatureCommand;
116
- _TemperatureCommand_regex = new WeakMap();
9
+ exports.CommandSupplier = void 0;
10
+ const AltimeterCommand_1 = require("./metar/AltimeterCommand");
11
+ const AltimeterMercuryCommand_1 = require("./metar/AltimeterMercuryCommand");
12
+ const RunwayCommand_1 = require("./metar/RunwayCommand");
13
+ const TemperatureCommand_1 = require("./metar/TemperatureCommand");
117
14
  class CommandSupplier {
118
15
  constructor() {
119
16
  _CommandSupplier_commands.set(this, [
120
- new RunwayCommand(),
121
- new TemperatureCommand(),
122
- new AltimeterCommand(),
123
- new AltimeterMercuryCommand(),
17
+ new RunwayCommand_1.RunwayCommand(),
18
+ new TemperatureCommand_1.TemperatureCommand(),
19
+ new AltimeterCommand_1.AltimeterCommand(),
20
+ new AltimeterMercuryCommand_1.AltimeterMercuryCommand(),
124
21
  ]);
125
22
  }
126
23
  get(input) {
@@ -0,0 +1,18 @@
1
+ import { IBaseRemark, RemarkType, Remark } from "../remark";
2
+ import { Command } from "./Command";
3
+ export interface ICeilingHeightRemark extends IBaseRemark {
4
+ type: RemarkType.CeilingHeight;
5
+ /**
6
+ * Ceiling min height (varying between min and max) above ground level
7
+ */
8
+ min: number;
9
+ /**
10
+ * Ceiling max height (varying between min and max) above ground level
11
+ */
12
+ max: number;
13
+ }
14
+ export declare class CeilingHeightCommand extends Command {
15
+ #private;
16
+ canParse(code: string): boolean;
17
+ execute(code: string, remark: Remark[]): [string, Remark[]];
18
+ }
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
+ };
7
+ var _CeilingHeightCommand_regex;
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.CeilingHeightCommand = void 0;
10
+ const i18n_1 = require("../../commons/i18n");
11
+ const errors_1 = require("../../commons/errors");
12
+ const remark_1 = require("../remark");
13
+ const Command_1 = require("./Command");
14
+ class CeilingHeightCommand extends Command_1.Command {
15
+ constructor() {
16
+ super(...arguments);
17
+ _CeilingHeightCommand_regex.set(this, /^CIG (\d{3})V(\d{3})\b/);
18
+ }
19
+ canParse(code) {
20
+ return __classPrivateFieldGet(this, _CeilingHeightCommand_regex, "f").test(code);
21
+ }
22
+ execute(code, remark) {
23
+ const matches = code.match(__classPrivateFieldGet(this, _CeilingHeightCommand_regex, "f"));
24
+ if (!matches)
25
+ throw new errors_1.UnexpectedParseError("Match not found");
26
+ const min = +matches[1] * 100;
27
+ const max = +matches[2] * 100;
28
+ const description = (0, i18n_1.format)((0, i18n_1._)("Remark.Ceiling.Height", this.locale), min, max);
29
+ remark.push({
30
+ type: remark_1.RemarkType.CeilingHeight,
31
+ description,
32
+ raw: matches[0],
33
+ min,
34
+ max,
35
+ });
36
+ return [code.replace(__classPrivateFieldGet(this, _CeilingHeightCommand_regex, "f"), "").trim(), remark];
37
+ }
38
+ }
39
+ exports.CeilingHeightCommand = CeilingHeightCommand;
40
+ _CeilingHeightCommand_regex = new WeakMap();
@@ -0,0 +1,12 @@
1
+ import { IBaseRemark, RemarkType, Remark } from "../remark";
2
+ import { Command } from "./Command";
3
+ export interface ICeilingSecondLocationRemark extends IBaseRemark {
4
+ type: RemarkType.CeilingSecondLocation;
5
+ height: number;
6
+ location: string;
7
+ }
8
+ export declare class CeilingSecondLocationCommand extends Command {
9
+ #private;
10
+ canParse(code: string): boolean;
11
+ execute(code: string, remark: Remark[]): [string, Remark[]];
12
+ }