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.
- package/README.md +85 -12
- package/dist/command/common.js +13 -10
- package/dist/command/metar/AltimeterCommand.d.ts +7 -0
- package/dist/command/metar/AltimeterCommand.js +26 -0
- package/dist/command/metar/AltimeterMercuryCommand.d.ts +7 -0
- package/dist/command/metar/AltimeterMercuryCommand.js +51 -0
- package/dist/command/metar/RunwayCommand.d.ts +7 -0
- package/dist/command/metar/RunwayCommand.js +60 -0
- package/dist/command/metar/TemperatureCommand.d.ts +7 -0
- package/dist/command/metar/TemperatureCommand.js +51 -0
- package/dist/command/metar.d.ts +1 -22
- package/dist/command/metar.js +10 -113
- package/dist/command/remark/CeilingHeightCommand.d.ts +18 -0
- package/dist/command/remark/CeilingHeightCommand.js +40 -0
- package/dist/command/remark/CeilingSecondLocationCommand.d.ts +12 -0
- package/dist/command/remark/CeilingSecondLocationCommand.js +40 -0
- package/dist/command/remark/Command.d.ts +8 -0
- package/dist/command/remark/Command.js +9 -0
- package/dist/command/remark/DefaultCommand.d.ts +11 -0
- package/dist/command/remark/DefaultCommand.js +38 -0
- package/dist/command/remark/HailSizeCommand.d.ts +11 -0
- package/dist/command/remark/HailSizeCommand.js +37 -0
- package/dist/command/remark/HourlyMaximumMinimumTemperatureCommand.d.ts +18 -0
- package/dist/command/remark/HourlyMaximumMinimumTemperatureCommand.js +39 -0
- package/dist/command/remark/HourlyMaximumTemperatureCommand.d.ts +14 -0
- package/dist/command/remark/HourlyMaximumTemperatureCommand.js +38 -0
- package/dist/command/remark/HourlyMinimumTemperatureCommand.d.ts +14 -0
- package/dist/command/remark/HourlyMinimumTemperatureCommand.js +38 -0
- package/dist/command/remark/HourlyPrecipitationAmountCommand.d.ts +14 -0
- package/dist/command/remark/HourlyPrecipitationAmountCommand.js +38 -0
- package/dist/command/remark/HourlyPressureCommand.d.ts +32 -0
- package/dist/command/remark/HourlyPressureCommand.js +40 -0
- package/dist/command/remark/HourlyTemperatureDewPointCommand.d.ts +18 -0
- package/dist/command/remark/HourlyTemperatureDewPointCommand.js +52 -0
- package/dist/command/remark/IceAccretionCommand.d.ts +15 -0
- package/dist/command/remark/IceAccretionCommand.js +38 -0
- package/dist/command/remark/ObscurationCommand.d.ts +14 -0
- package/dist/command/remark/ObscurationCommand.js +44 -0
- package/dist/command/remark/PrecipitationAmount24HourCommand.d.ts +14 -0
- package/dist/command/remark/PrecipitationAmount24HourCommand.js +39 -0
- package/dist/command/remark/PrecipitationAmount36HourCommand.d.ts +15 -0
- package/dist/command/remark/PrecipitationAmount36HourCommand.js +41 -0
- package/dist/command/remark/PrecipitationBegCommand.d.ts +15 -0
- package/dist/command/remark/PrecipitationBegCommand.js +45 -0
- package/dist/command/remark/PrecipitationBegEndCommand.d.ts +17 -0
- package/dist/command/remark/PrecipitationBegEndCommand.js +46 -0
- package/dist/command/remark/PrecipitationEndCommand.d.ts +15 -0
- package/dist/command/remark/PrecipitationEndCommand.js +45 -0
- package/dist/command/remark/PrevailingVisibilityCommand.d.ts +12 -0
- package/dist/command/remark/PrevailingVisibilityCommand.js +40 -0
- package/dist/command/remark/SeaLevelPressureCommand.d.ts +11 -0
- package/dist/command/remark/SeaLevelPressureCommand.js +39 -0
- package/dist/command/remark/SecondLocationVisibilityCommand.d.ts +12 -0
- package/dist/command/remark/SecondLocationVisibilityCommand.js +40 -0
- package/dist/command/remark/SectorVisibilityCommand.d.ts +13 -0
- package/dist/command/remark/SectorVisibilityCommand.js +41 -0
- package/dist/command/remark/SmallHailSizeCommand.d.ts +11 -0
- package/dist/command/remark/SmallHailSizeCommand.js +37 -0
- package/dist/command/remark/SnowDepthCommand.d.ts +11 -0
- package/dist/command/remark/SnowDepthCommand.js +38 -0
- package/dist/command/remark/SnowIncreaseCommand.d.ts +12 -0
- package/dist/command/remark/SnowIncreaseCommand.js +40 -0
- package/dist/command/remark/SnowPelletsCommand.d.ts +11 -0
- package/dist/command/remark/SnowPelletsCommand.js +37 -0
- package/dist/command/remark/SunshineDurationCommand.d.ts +11 -0
- package/dist/command/remark/SunshineDurationCommand.js +38 -0
- package/dist/command/remark/SurfaceVisibilityCommand.d.ts +11 -0
- package/dist/command/remark/SurfaceVisibilityCommand.js +38 -0
- package/dist/command/remark/ThunderStormLocationCommand.d.ts +12 -0
- package/dist/command/remark/ThunderStormLocationCommand.js +40 -0
- package/dist/command/remark/ThunderStormLocationMovingCommand.d.ts +19 -0
- package/dist/command/remark/ThunderStormLocationMovingCommand.js +42 -0
- package/dist/command/remark/TornadicActivityBegCommand.d.ts +16 -0
- package/dist/command/remark/TornadicActivityBegCommand.js +44 -0
- package/dist/command/remark/TornadicActivityBegEndCommand.d.ts +18 -0
- package/dist/command/remark/TornadicActivityBegEndCommand.js +46 -0
- package/dist/command/remark/TornadicActivityEndCommand.d.ts +16 -0
- package/dist/command/remark/TornadicActivityEndCommand.js +44 -0
- package/dist/command/remark/TowerVisibilityCommand.d.ts +11 -0
- package/dist/command/remark/TowerVisibilityCommand.js +38 -0
- package/dist/command/remark/VariableSkyCommand.d.ts +12 -0
- package/dist/command/remark/VariableSkyCommand.js +41 -0
- package/dist/command/remark/VariableSkyHeightCommand.d.ts +13 -0
- package/dist/command/remark/VariableSkyHeightCommand.js +43 -0
- package/dist/command/remark/VirgaDirectionCommand.d.ts +12 -0
- package/dist/command/remark/VirgaDirectionCommand.js +40 -0
- package/dist/command/remark/WaterEquivalentSnowCommand.d.ts +11 -0
- package/dist/command/remark/WaterEquivalentSnowCommand.js +38 -0
- package/dist/command/remark/WindPeakCommandCommand.d.ts +17 -0
- package/dist/command/remark/WindPeakCommandCommand.js +42 -0
- package/dist/command/remark/WindShiftCommand.d.ts +12 -0
- package/dist/command/remark/WindShiftCommand.js +38 -0
- package/dist/command/remark/WindShiftFropaCommand.d.ts +12 -0
- package/dist/command/remark/WindShiftFropaCommand.js +38 -0
- package/dist/command/remark.d.ts +100 -194
- package/dist/command/remark.js +135 -753
- package/dist/commons/converter.d.ts +14 -2
- package/dist/commons/converter.js +53 -5
- package/dist/commons/errors.d.ts +6 -2
- package/dist/commons/errors.js +15 -8
- package/dist/commons/i18n.d.ts +2 -2
- package/dist/commons/i18n.js +9 -3
- package/dist/dates/metar.d.ts +5 -0
- package/dist/dates/metar.js +8 -0
- package/dist/dates/taf.d.ts +28 -0
- package/dist/dates/taf.js +17 -0
- package/dist/forecast/forecast.d.ts +36 -0
- package/dist/forecast/forecast.js +73 -0
- package/dist/helpers/date.d.ts +11 -0
- package/dist/helpers/date.js +56 -0
- package/dist/helpers/helpers.d.ts +7 -0
- package/dist/helpers/helpers.js +14 -1
- package/dist/index.d.ts +23 -2
- package/dist/index.js +24 -7
- package/dist/model/enum.d.ts +44 -0
- package/dist/model/enum.js +50 -1
- package/dist/model/model.d.ts +84 -19
- package/dist/model/model.js +3 -1
- package/dist/parser/parser.d.ts +13 -6
- package/dist/parser/parser.js +63 -29
- package/package.json +3 -3
package/dist/model/enum.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.WeatherChangeType = exports.TimeIndicator = exports.Phenomenon = exports.Descriptive = exports.Intensity = exports.CloudType = exports.CloudQuantity = void 0;
|
|
3
|
+
exports.RunwayInfoUnit = exports.RunwayInfoTrend = exports.ValueIndicator = exports.DistanceUnit = exports.Direction = exports.WeatherChangeType = exports.TimeIndicator = exports.Phenomenon = exports.Descriptive = exports.Intensity = exports.CloudType = exports.CloudQuantity = void 0;
|
|
4
4
|
var CloudQuantity;
|
|
5
5
|
(function (CloudQuantity) {
|
|
6
6
|
/**
|
|
@@ -119,6 +119,7 @@ var Phenomenon;
|
|
|
119
119
|
Phenomenon["SPRAY"] = "PY";
|
|
120
120
|
Phenomenon["SQUALL"] = "SQ";
|
|
121
121
|
Phenomenon["SAND_WHIRLS"] = "PO";
|
|
122
|
+
Phenomenon["THUNDERSTORM"] = "TS";
|
|
122
123
|
Phenomenon["DUSTSTORM"] = "DS";
|
|
123
124
|
Phenomenon["SANDSTORM"] = "SS";
|
|
124
125
|
Phenomenon["FUNNEL_CLOUD"] = "FC";
|
|
@@ -229,3 +230,51 @@ var WeatherChangeType;
|
|
|
229
230
|
*/
|
|
230
231
|
WeatherChangeType["PROB"] = "PROB";
|
|
231
232
|
})(WeatherChangeType = exports.WeatherChangeType || (exports.WeatherChangeType = {}));
|
|
233
|
+
var Direction;
|
|
234
|
+
(function (Direction) {
|
|
235
|
+
Direction["E"] = "E";
|
|
236
|
+
Direction["ENE"] = "ENE";
|
|
237
|
+
Direction["ESE"] = "ESE";
|
|
238
|
+
Direction["N"] = "N";
|
|
239
|
+
Direction["NE"] = "NE";
|
|
240
|
+
Direction["NNE"] = "NNE";
|
|
241
|
+
Direction["NNW"] = "NNW";
|
|
242
|
+
Direction["NW"] = "NW";
|
|
243
|
+
Direction["S"] = "S";
|
|
244
|
+
Direction["SE"] = "SE";
|
|
245
|
+
Direction["SSE"] = "SSE";
|
|
246
|
+
Direction["SSW"] = "SSW";
|
|
247
|
+
Direction["SW"] = "SW";
|
|
248
|
+
Direction["W"] = "W";
|
|
249
|
+
Direction["WNW"] = "WNW";
|
|
250
|
+
Direction["WSW"] = "WSW";
|
|
251
|
+
})(Direction = exports.Direction || (exports.Direction = {}));
|
|
252
|
+
var DistanceUnit;
|
|
253
|
+
(function (DistanceUnit) {
|
|
254
|
+
DistanceUnit["Meters"] = "m";
|
|
255
|
+
DistanceUnit["StatuteMiles"] = "SM";
|
|
256
|
+
})(DistanceUnit = exports.DistanceUnit || (exports.DistanceUnit = {}));
|
|
257
|
+
/**
|
|
258
|
+
* Used to indicate the actual value is greater than or less than the value written
|
|
259
|
+
*
|
|
260
|
+
* For example,
|
|
261
|
+
*
|
|
262
|
+
* 1. `P6SM` = visibility greater than 6 statute miles
|
|
263
|
+
* 2. `M1/4SM` = visibility less than 1/4 statute mile
|
|
264
|
+
*/
|
|
265
|
+
var ValueIndicator;
|
|
266
|
+
(function (ValueIndicator) {
|
|
267
|
+
ValueIndicator["GreaterThan"] = "P";
|
|
268
|
+
ValueIndicator["LessThan"] = "M";
|
|
269
|
+
})(ValueIndicator = exports.ValueIndicator || (exports.ValueIndicator = {}));
|
|
270
|
+
var RunwayInfoTrend;
|
|
271
|
+
(function (RunwayInfoTrend) {
|
|
272
|
+
RunwayInfoTrend["Uprising"] = "U";
|
|
273
|
+
RunwayInfoTrend["Decreasing"] = "D";
|
|
274
|
+
RunwayInfoTrend["NoSignificantChange"] = "N";
|
|
275
|
+
})(RunwayInfoTrend = exports.RunwayInfoTrend || (exports.RunwayInfoTrend = {}));
|
|
276
|
+
var RunwayInfoUnit;
|
|
277
|
+
(function (RunwayInfoUnit) {
|
|
278
|
+
RunwayInfoUnit["Feet"] = "FT";
|
|
279
|
+
RunwayInfoUnit["Meters"] = "m";
|
|
280
|
+
})(RunwayInfoUnit = exports.RunwayInfoUnit || (exports.RunwayInfoUnit = {}));
|
package/dist/model/model.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { CloudQuantity, CloudType, Descriptive, Phenomenon, TimeIndicator, WeatherChangeType } from "../model/enum";
|
|
1
|
+
import { CloudQuantity, CloudType, Descriptive, ValueIndicator, Phenomenon, TimeIndicator, WeatherChangeType, DistanceUnit, RunwayInfoTrend, RunwayInfoUnit, Intensity } from "../model/enum";
|
|
2
|
+
import { Remark } from "../command/remark";
|
|
2
3
|
export interface ICountry {
|
|
3
4
|
name: string;
|
|
4
5
|
}
|
|
@@ -27,13 +28,25 @@ export interface IWind {
|
|
|
27
28
|
export interface IWindShear extends IWind {
|
|
28
29
|
height: number;
|
|
29
30
|
}
|
|
30
|
-
export interface
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
export interface Distance {
|
|
32
|
+
indicator?: ValueIndicator;
|
|
33
|
+
value: number;
|
|
34
|
+
unit: DistanceUnit;
|
|
35
|
+
/** No Directional Visibility */
|
|
36
|
+
ndv?: true;
|
|
37
|
+
}
|
|
38
|
+
export declare type Visibility = Distance & {
|
|
39
|
+
/**
|
|
40
|
+
* Never in North American METARs
|
|
41
|
+
*/
|
|
42
|
+
min?: {
|
|
43
|
+
/** Always in meters */
|
|
44
|
+
value: number;
|
|
45
|
+
direction: string;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
35
48
|
export interface IWeatherCondition {
|
|
36
|
-
intensity?:
|
|
49
|
+
intensity?: Intensity;
|
|
37
50
|
descriptive?: Descriptive;
|
|
38
51
|
phenomenons: Phenomenon[];
|
|
39
52
|
}
|
|
@@ -47,7 +60,15 @@ export interface IRunwayInfo {
|
|
|
47
60
|
name: string;
|
|
48
61
|
minRange: number;
|
|
49
62
|
maxRange?: number;
|
|
50
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Only used in North American runway ranges (feet unit of measurement)
|
|
65
|
+
*/
|
|
66
|
+
indicator?: ValueIndicator;
|
|
67
|
+
/**
|
|
68
|
+
* Only used in IACO runway ranges (meters unit of measurement)
|
|
69
|
+
*/
|
|
70
|
+
trend?: RunwayInfoTrend;
|
|
71
|
+
unit: RunwayInfoUnit;
|
|
51
72
|
}
|
|
52
73
|
export interface ICloud {
|
|
53
74
|
height?: number;
|
|
@@ -59,9 +80,9 @@ export interface IAbstractWeatherContainer {
|
|
|
59
80
|
visibility?: Visibility;
|
|
60
81
|
verticalVisibility?: number;
|
|
61
82
|
windShear?: IWindShear;
|
|
62
|
-
cavok?:
|
|
83
|
+
cavok?: true;
|
|
63
84
|
remark?: string;
|
|
64
|
-
remarks:
|
|
85
|
+
remarks: Remark[];
|
|
65
86
|
clouds: ICloud[];
|
|
66
87
|
weatherConditions: IWeatherCondition[];
|
|
67
88
|
}
|
|
@@ -83,21 +104,27 @@ export interface IAbstractWeatherCode extends IAbstractWeatherContainer, ITime {
|
|
|
83
104
|
station: string;
|
|
84
105
|
trends: IAbstractTrend[];
|
|
85
106
|
}
|
|
107
|
+
export interface IAbstractWeatherCodeDated extends IAbstractWeatherCode {
|
|
108
|
+
issued: Date;
|
|
109
|
+
}
|
|
86
110
|
export interface IMetar extends IAbstractWeatherCode {
|
|
87
111
|
temperature?: number;
|
|
88
112
|
dewPoint?: number;
|
|
89
113
|
altimeter?: number;
|
|
90
|
-
nosig?:
|
|
91
|
-
auto?:
|
|
114
|
+
nosig?: true;
|
|
115
|
+
auto?: true;
|
|
92
116
|
runwaysInfo: IRunwayInfo[];
|
|
117
|
+
/**
|
|
118
|
+
* Not used in North America
|
|
119
|
+
*/
|
|
93
120
|
trends: IMetarTrend[];
|
|
94
121
|
}
|
|
95
122
|
export interface ITAF extends IAbstractWeatherCode {
|
|
96
123
|
validity: IValidity;
|
|
97
124
|
maxTemperature?: ITemperatureDated;
|
|
98
125
|
minTemperature?: ITemperatureDated;
|
|
99
|
-
amendment?:
|
|
100
|
-
trends:
|
|
126
|
+
amendment?: true;
|
|
127
|
+
trends: TAFTrend[];
|
|
101
128
|
}
|
|
102
129
|
export interface IAbstractTrend extends IAbstractWeatherContainer {
|
|
103
130
|
type: WeatherChangeType;
|
|
@@ -108,16 +135,54 @@ export interface IMetarTrendTime extends ITime {
|
|
|
108
135
|
export interface IMetarTrend extends IAbstractTrend {
|
|
109
136
|
times: IMetarTrendTime[];
|
|
110
137
|
}
|
|
111
|
-
export interface
|
|
138
|
+
export interface IBaseTAFTrend extends IAbstractTrend {
|
|
139
|
+
/**
|
|
140
|
+
* Will not be found on FM trends. May exist on others.
|
|
141
|
+
*
|
|
142
|
+
* If does not exist, probability is > 40%
|
|
143
|
+
*/
|
|
112
144
|
probability?: number;
|
|
113
|
-
|
|
114
|
-
|
|
145
|
+
/**
|
|
146
|
+
* All trends have `startDay` and `startHour` defined. Additionally:
|
|
147
|
+
*
|
|
148
|
+
* - FM trends also have `startMinutes`. They **DO NOT** have an explicit end
|
|
149
|
+
* validity (it is implied by the following FM).
|
|
150
|
+
* - All others (PROB, TEMPO, BECMG) have `endDay` and `endHour`.
|
|
151
|
+
*
|
|
152
|
+
* All properties are allowed to be accessed (as optionals), but if you want
|
|
153
|
+
* type guarantees, you can check the trend type. For example:
|
|
154
|
+
*
|
|
155
|
+
* ```ts
|
|
156
|
+
* switch (trend.type) {
|
|
157
|
+
* case WeatherChangeType.FM:
|
|
158
|
+
* // trend.validity now has startMinutes defined
|
|
159
|
+
* break;
|
|
160
|
+
* case WeatherChangeType.PROB:
|
|
161
|
+
* case WeatherChangeType.BECMG:
|
|
162
|
+
* case WeatherChangeType.TEMPO:
|
|
163
|
+
* // trend.validity now has endHour, endDay defined
|
|
164
|
+
* }
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
validity: IAbstractValidity & Partial<IFMValidity> & Partial<IValidity>;
|
|
168
|
+
}
|
|
169
|
+
export declare type TAFTrend = IBaseTAFTrend & ({
|
|
170
|
+
type: WeatherChangeType.FM;
|
|
171
|
+
validity: IFMValidity;
|
|
172
|
+
} | {
|
|
173
|
+
type: WeatherChangeType;
|
|
174
|
+
validity: IValidity;
|
|
175
|
+
});
|
|
115
176
|
export interface IEndValidity {
|
|
116
177
|
endHour: number;
|
|
117
178
|
endDay: number;
|
|
118
179
|
}
|
|
119
180
|
export interface IValidity extends IAbstractValidity, IEndValidity {
|
|
120
181
|
}
|
|
121
|
-
export interface
|
|
122
|
-
|
|
182
|
+
export interface IValidityDated extends IAbstractValidity, IEndValidity {
|
|
183
|
+
start: Date;
|
|
184
|
+
end: Date;
|
|
185
|
+
}
|
|
186
|
+
export interface IFMValidity extends IAbstractValidity {
|
|
187
|
+
startMinutes: number;
|
|
123
188
|
}
|
package/dist/model/model.js
CHANGED
|
@@ -4,6 +4,8 @@ exports.isWeatherConditionValid = void 0;
|
|
|
4
4
|
const enum_1 = require("../model/enum");
|
|
5
5
|
function isWeatherConditionValid(weather) {
|
|
6
6
|
return (weather.phenomenons.length !== 0 ||
|
|
7
|
-
weather.descriptive == enum_1.Descriptive.THUNDERSTORM
|
|
7
|
+
weather.descriptive == enum_1.Descriptive.THUNDERSTORM ||
|
|
8
|
+
(weather.intensity === enum_1.Intensity.IN_VICINITY &&
|
|
9
|
+
weather.descriptive == enum_1.Descriptive.SHOWERS));
|
|
8
10
|
}
|
|
9
11
|
exports.isWeatherConditionValid = isWeatherConditionValid;
|
package/dist/parser/parser.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Remark } from "../command/remark";
|
|
2
|
+
import { IAbstractWeatherContainer, IMetar, IMetarTrend, ITAF, TAFTrend, ITemperatureDated, IValidity, IWeatherCondition, IValidityDated } from "../model/model";
|
|
3
3
|
import { Locale } from "../commons/i18n";
|
|
4
4
|
/**
|
|
5
5
|
* Parses the temperature in a TAF
|
|
@@ -12,7 +12,7 @@ export declare function parseTemperature(input: string): ITemperatureDated;
|
|
|
12
12
|
* @param input the string containing the validity
|
|
13
13
|
* @returns Validity object
|
|
14
14
|
*/
|
|
15
|
-
export declare function parseValidity(input: string): IValidity;
|
|
15
|
+
export declare function parseValidity(input: string, date?: Date): IValidityDated | IValidity;
|
|
16
16
|
/**
|
|
17
17
|
* Abstract class.
|
|
18
18
|
* Base parser.
|
|
@@ -87,18 +87,25 @@ export declare class TAFParser extends AbstractParser {
|
|
|
87
87
|
* @param lineTokens the array of tokens representing a line
|
|
88
88
|
*/
|
|
89
89
|
parseLine(taf: ITAF, lineTokens: string[]): void;
|
|
90
|
+
/**
|
|
91
|
+
* Finds a non-FM validity in a line
|
|
92
|
+
* @param index the index at which the array should be parsed
|
|
93
|
+
* @param line The array of string containing the line
|
|
94
|
+
* @param trend The trend object to update
|
|
95
|
+
*/
|
|
96
|
+
findLineValidity(index: number, line: string[]): IValidity | undefined;
|
|
90
97
|
/**
|
|
91
98
|
* Parses a trend of the TAF
|
|
92
99
|
* @param index the index at which the array should be parsed
|
|
93
100
|
* @param line The array of string containing the line
|
|
94
101
|
* @param trend The trend object to update
|
|
95
102
|
*/
|
|
96
|
-
parseTrend(index: number, line: string[], trend:
|
|
97
|
-
makeEmptyTAFTrend(
|
|
103
|
+
parseTrend(index: number, line: string[], trend: TAFTrend): void;
|
|
104
|
+
makeEmptyTAFTrend(): Omit<TAFTrend, "type" | "validity">;
|
|
98
105
|
}
|
|
99
106
|
export declare class RemarkParser {
|
|
100
107
|
#private;
|
|
101
108
|
private locale;
|
|
102
109
|
constructor(locale: Locale);
|
|
103
|
-
parse(code: string):
|
|
110
|
+
parse(code: string): Remark[];
|
|
104
111
|
}
|
package/dist/parser/parser.js
CHANGED
|
@@ -32,10 +32,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
32
32
|
exports.RemarkParser = exports.TAFParser = exports.MetarParser = exports.AbstractParser = exports.parseValidity = exports.parseTemperature = void 0;
|
|
33
33
|
const remark_1 = require("../command/remark");
|
|
34
34
|
const model_1 = require("../model/model");
|
|
35
|
+
const enum_1 = require("../model/enum");
|
|
35
36
|
const converter = __importStar(require("../commons/converter"));
|
|
36
37
|
const helpers_1 = require("../helpers/helpers");
|
|
37
38
|
const common_1 = require("../command/common");
|
|
38
|
-
const
|
|
39
|
+
const enum_2 = require("../model/enum");
|
|
39
40
|
const metar_1 = require("../command/metar");
|
|
40
41
|
const errors_1 = require("../commons/errors");
|
|
41
42
|
/**
|
|
@@ -44,10 +45,15 @@ const errors_1 = require("../commons/errors");
|
|
|
44
45
|
* @param timeString The string representing the delivery time
|
|
45
46
|
*/
|
|
46
47
|
function parseDeliveryTime(timeString) {
|
|
48
|
+
const day = +timeString.slice(0, 2);
|
|
49
|
+
const hour = +timeString.slice(2, 4);
|
|
50
|
+
const minute = +timeString.slice(4, 6);
|
|
51
|
+
if (isNaN(day) || isNaN(hour) || isNaN(minute))
|
|
52
|
+
throw new errors_1.InvalidWeatherStatementError("Report time is invalid");
|
|
47
53
|
return {
|
|
48
|
-
day
|
|
49
|
-
hour
|
|
50
|
-
minute
|
|
54
|
+
day,
|
|
55
|
+
hour,
|
|
56
|
+
minute,
|
|
51
57
|
};
|
|
52
58
|
}
|
|
53
59
|
/**
|
|
@@ -59,7 +65,9 @@ function parseDeliveryTime(timeString) {
|
|
|
59
65
|
function parseRemark(container, line, index, locale) {
|
|
60
66
|
const remarks = new RemarkParser(locale).parse(line.slice(index + 1).join(" "));
|
|
61
67
|
container.remarks = remarks;
|
|
62
|
-
container.remark = remarks
|
|
68
|
+
container.remark = remarks
|
|
69
|
+
.map(({ description, raw }) => description || raw)
|
|
70
|
+
.join(" ");
|
|
63
71
|
}
|
|
64
72
|
/**
|
|
65
73
|
* Parses the temperature in a TAF
|
|
@@ -80,7 +88,7 @@ exports.parseTemperature = parseTemperature;
|
|
|
80
88
|
* @param input the string containing the validity
|
|
81
89
|
* @returns Validity object
|
|
82
90
|
*/
|
|
83
|
-
function parseValidity(input) {
|
|
91
|
+
function parseValidity(input, date) {
|
|
84
92
|
const parts = (0, helpers_1.pySplit)(input, "/");
|
|
85
93
|
return {
|
|
86
94
|
startDay: +parts[0].slice(0, 2),
|
|
@@ -128,7 +136,7 @@ class AbstractParser {
|
|
|
128
136
|
intensity = match;
|
|
129
137
|
}
|
|
130
138
|
let descriptive;
|
|
131
|
-
for (const key of Object.values(
|
|
139
|
+
for (const key of Object.values(enum_2.Descriptive)) {
|
|
132
140
|
if (input.includes(key))
|
|
133
141
|
descriptive = key;
|
|
134
142
|
}
|
|
@@ -137,7 +145,10 @@ class AbstractParser {
|
|
|
137
145
|
descriptive,
|
|
138
146
|
phenomenons: [],
|
|
139
147
|
};
|
|
140
|
-
for (const key of Object.values(
|
|
148
|
+
for (const key of Object.values(enum_2.Phenomenon)) {
|
|
149
|
+
// Thunderstorm as descriptive should not be added as a phenomenon
|
|
150
|
+
if (descriptive === key)
|
|
151
|
+
continue;
|
|
141
152
|
if (input.includes(key))
|
|
142
153
|
weatherCondition.phenomenons.push(key);
|
|
143
154
|
}
|
|
@@ -154,7 +165,7 @@ class AbstractParser {
|
|
|
154
165
|
// Hack for safari below...
|
|
155
166
|
const splitRegex = /\s|=/;
|
|
156
167
|
const smRegex = /^\d\/\dSM$/;
|
|
157
|
-
const digitRegex =
|
|
168
|
+
const digitRegex = /^(P|M)?\d$/;
|
|
158
169
|
// return input.split(this.#TOKENIZE_REGEX).filter((v) => v);
|
|
159
170
|
const splitted = input.split(splitRegex);
|
|
160
171
|
for (let i = 0; i < splitted.length; i++) {
|
|
@@ -176,12 +187,11 @@ class AbstractParser {
|
|
|
176
187
|
generalParse(abstractWeatherContainer, input) {
|
|
177
188
|
if (input === __classPrivateFieldGet(this, _AbstractParser_CAVOK, "f")) {
|
|
178
189
|
abstractWeatherContainer.cavok = true;
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
abstractWeatherContainer.visibility.distance = distance;
|
|
190
|
+
abstractWeatherContainer.visibility = {
|
|
191
|
+
indicator: enum_1.ValueIndicator.GreaterThan,
|
|
192
|
+
value: 9999,
|
|
193
|
+
unit: enum_1.DistanceUnit.Meters,
|
|
194
|
+
};
|
|
185
195
|
return true;
|
|
186
196
|
}
|
|
187
197
|
const command = __classPrivateFieldGet(this, _AbstractParser_commonSupplier, "f").get(input);
|
|
@@ -221,7 +231,7 @@ class MetarParser extends AbstractParser {
|
|
|
221
231
|
trendParts[i].startsWith(this.TL) ||
|
|
222
232
|
trendParts[i].startsWith(this.AT)) {
|
|
223
233
|
const trendTime = {
|
|
224
|
-
type:
|
|
234
|
+
type: enum_2.TimeIndicator[trendParts[i].slice(0, 2)],
|
|
225
235
|
hour: +trendParts[i].slice(2, 4),
|
|
226
236
|
minute: +trendParts[i].slice(4, 6),
|
|
227
237
|
};
|
|
@@ -241,7 +251,7 @@ class MetarParser extends AbstractParser {
|
|
|
241
251
|
*/
|
|
242
252
|
parse(input) {
|
|
243
253
|
const metarTab = this.tokenize(input);
|
|
244
|
-
const metar = Object.assign(Object.assign({}, parseDeliveryTime(metarTab[1])), { station: metarTab[0], message: input,
|
|
254
|
+
const metar = Object.assign(Object.assign({}, parseDeliveryTime(metarTab[1])), { station: metarTab[0], message: input, remarks: [], clouds: [], weatherConditions: [], trends: [], runwaysInfo: [] });
|
|
245
255
|
let index = 2;
|
|
246
256
|
while (index < metarTab.length) {
|
|
247
257
|
if (!super.generalParse(metar, metarTab[index])) {
|
|
@@ -254,7 +264,7 @@ class MetarParser extends AbstractParser {
|
|
|
254
264
|
else if (metarTab[index] === this.TEMPO ||
|
|
255
265
|
metarTab[index] === this.BECMG) {
|
|
256
266
|
const trend = {
|
|
257
|
-
type:
|
|
267
|
+
type: enum_2.WeatherChangeType[metarTab[index]],
|
|
258
268
|
weatherConditions: [],
|
|
259
269
|
clouds: [],
|
|
260
270
|
times: [],
|
|
@@ -302,7 +312,7 @@ class TAFParser extends AbstractParser {
|
|
|
302
312
|
let amendment;
|
|
303
313
|
const lines = this.extractLinesTokens(input);
|
|
304
314
|
if (lines[0][0] !== this.TAF)
|
|
305
|
-
throw new errors_1.InvalidWeatherStatementError('TAF report must begin with
|
|
315
|
+
throw new errors_1.InvalidWeatherStatementError('TAF report must begin with "TAF"');
|
|
306
316
|
let index = 1;
|
|
307
317
|
if (lines[0][1] === this.TAF)
|
|
308
318
|
index = 2;
|
|
@@ -319,8 +329,10 @@ class TAFParser extends AbstractParser {
|
|
|
319
329
|
amendment }, time), { validity, message: input, trends: [], remarks: [], clouds: [], weatherConditions: [] });
|
|
320
330
|
for (let i = index + 1; i < lines[0].length; i++) {
|
|
321
331
|
const token = lines[0][i];
|
|
322
|
-
if (token == this.RMK)
|
|
332
|
+
if (token == this.RMK) {
|
|
323
333
|
parseRemark(taf, lines[0], i, this.locale);
|
|
334
|
+
break;
|
|
335
|
+
}
|
|
324
336
|
else if (token.startsWith(this.TX))
|
|
325
337
|
taf.maxTemperature = parseTemperature(token);
|
|
326
338
|
else if (token.startsWith(this.TN))
|
|
@@ -375,22 +387,42 @@ class TAFParser extends AbstractParser {
|
|
|
375
387
|
let index = 1;
|
|
376
388
|
let trend;
|
|
377
389
|
if (lineTokens[0].startsWith(this.FM)) {
|
|
378
|
-
trend = Object.assign(Object.assign({}, this.makeEmptyTAFTrend(
|
|
390
|
+
trend = Object.assign(Object.assign({}, this.makeEmptyTAFTrend()), { type: enum_2.WeatherChangeType.FM, validity: parseFromValidity(lineTokens[0]) });
|
|
379
391
|
}
|
|
380
392
|
else if (lineTokens[0].startsWith(this.PROB)) {
|
|
381
|
-
|
|
393
|
+
const validity = this.findLineValidity(index, lineTokens);
|
|
394
|
+
if (!validity)
|
|
395
|
+
return;
|
|
396
|
+
trend = Object.assign(Object.assign({}, this.makeEmptyTAFTrend()), { type: enum_2.WeatherChangeType.PROB, validity });
|
|
382
397
|
if (lineTokens.length > 1 && lineTokens[1] === this.TEMPO) {
|
|
383
|
-
trend = this.makeEmptyTAFTrend(
|
|
398
|
+
trend = Object.assign(Object.assign({}, this.makeEmptyTAFTrend()), { type: enum_2.WeatherChangeType[lineTokens[1]], validity });
|
|
384
399
|
index = 2;
|
|
385
400
|
}
|
|
386
401
|
trend.probability = +lineTokens[0].slice(4);
|
|
387
402
|
}
|
|
388
403
|
else {
|
|
389
|
-
|
|
404
|
+
const validity = this.findLineValidity(index, lineTokens);
|
|
405
|
+
if (!validity)
|
|
406
|
+
return;
|
|
407
|
+
trend = Object.assign(Object.assign({}, this.makeEmptyTAFTrend()), { type: enum_2.WeatherChangeType[lineTokens[0]], validity });
|
|
390
408
|
}
|
|
391
409
|
this.parseTrend(index, lineTokens, trend);
|
|
392
410
|
taf.trends.push(trend);
|
|
393
411
|
}
|
|
412
|
+
/**
|
|
413
|
+
* Finds a non-FM validity in a line
|
|
414
|
+
* @param index the index at which the array should be parsed
|
|
415
|
+
* @param line The array of string containing the line
|
|
416
|
+
* @param trend The trend object to update
|
|
417
|
+
*/
|
|
418
|
+
findLineValidity(index, line) {
|
|
419
|
+
let validity;
|
|
420
|
+
for (let i = index; i < line.length; i++) {
|
|
421
|
+
if (__classPrivateFieldGet(this, _TAFParser_validityPattern, "f").test(line[i]))
|
|
422
|
+
validity = parseValidity(line[i]);
|
|
423
|
+
}
|
|
424
|
+
return validity;
|
|
425
|
+
}
|
|
394
426
|
/**
|
|
395
427
|
* Parses a trend of the TAF
|
|
396
428
|
* @param index the index at which the array should be parsed
|
|
@@ -399,17 +431,19 @@ class TAFParser extends AbstractParser {
|
|
|
399
431
|
*/
|
|
400
432
|
parseTrend(index, line, trend) {
|
|
401
433
|
for (let i = index; i < line.length; i++) {
|
|
402
|
-
if (line[i] === this.RMK)
|
|
434
|
+
if (line[i] === this.RMK) {
|
|
403
435
|
parseRemark(trend, line, i, this.locale);
|
|
436
|
+
break;
|
|
437
|
+
}
|
|
438
|
+
// already parsed
|
|
404
439
|
else if (__classPrivateFieldGet(this, _TAFParser_validityPattern, "f").test(line[i]))
|
|
405
|
-
|
|
440
|
+
continue;
|
|
406
441
|
else
|
|
407
442
|
super.generalParse(trend, line[i]);
|
|
408
443
|
}
|
|
409
444
|
}
|
|
410
|
-
makeEmptyTAFTrend(
|
|
445
|
+
makeEmptyTAFTrend() {
|
|
411
446
|
return {
|
|
412
|
-
type,
|
|
413
447
|
remarks: [],
|
|
414
448
|
clouds: [],
|
|
415
449
|
weatherConditions: [],
|
|
@@ -431,7 +465,7 @@ class RemarkParser {
|
|
|
431
465
|
[rmkStr, rmkList] = __classPrivateFieldGet(this, _RemarkParser_supplier, "f").get(rmkStr).execute(rmkStr, rmkList);
|
|
432
466
|
}
|
|
433
467
|
catch (e) {
|
|
434
|
-
if (e instanceof errors_1.
|
|
468
|
+
if (e instanceof errors_1.CommandExecutionError) {
|
|
435
469
|
[rmkStr, rmkList] = __classPrivateFieldGet(this, _RemarkParser_supplier, "f").defaultCommand.execute(rmkStr, rmkList);
|
|
436
470
|
}
|
|
437
471
|
else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "metar-taf-parser",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Parse METAR and TAF reports",
|
|
5
5
|
"homepage": "https://aeharding.github.io/metar-taf-parser",
|
|
6
6
|
"keywords": [
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"url": "https://github.com/aeharding/metar-taf-parser.git"
|
|
22
22
|
},
|
|
23
23
|
"scripts": {
|
|
24
|
-
"build": "
|
|
24
|
+
"build": "tsc --project tsconfig.build.json && tsc-alias",
|
|
25
25
|
"clean": "rm -rf ./dist",
|
|
26
26
|
"start": "node --experimental-specifier-resolution=node --loader ts-node/esm lib",
|
|
27
27
|
"check-types": "tsc --noEmit",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"watch": "watch 'yarn build' src",
|
|
30
30
|
"test": "jest --coverage",
|
|
31
31
|
"test-watch": "jest --watch --coverage",
|
|
32
|
-
"prepublishOnly": "yarn build"
|
|
32
|
+
"prepublishOnly": "yarn clean && yarn build"
|
|
33
33
|
},
|
|
34
34
|
"files": [
|
|
35
35
|
"dist",
|