metar-taf-parser 4.1.0 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -8
- package/metar-taf-parser.d.ts +11 -9
- package/metar-taf-parser.js +16 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -39,9 +39,8 @@ const metar = parseMetar(rawMetarString);
|
|
|
39
39
|
|
|
40
40
|
// -or-
|
|
41
41
|
|
|
42
|
-
// Optionally pass
|
|
43
|
-
|
|
44
|
-
const datedMetar = parseMetar(rawMetarString, { date: new Date() });
|
|
42
|
+
// Optionally pass the date issued to add it to the report
|
|
43
|
+
const datedMetar = parseMetar(rawMetarString, { issued });
|
|
45
44
|
```
|
|
46
45
|
|
|
47
46
|
#### `parseTAF`
|
|
@@ -55,9 +54,9 @@ const taf = parseTAF(rawTAFString);
|
|
|
55
54
|
|
|
56
55
|
// -or-
|
|
57
56
|
|
|
58
|
-
// Optionally pass
|
|
59
|
-
//
|
|
60
|
-
const datedTAF = parseTAF(rawTAFString, {
|
|
57
|
+
// Optionally pass the date issued to get the report issued and
|
|
58
|
+
// trend validity dates (start/end) on the report:
|
|
59
|
+
const datedTAF = parseTAF(rawTAFString, { issued });
|
|
61
60
|
```
|
|
62
61
|
|
|
63
62
|
### Higher level parsing: The Forecast abstraction
|
|
@@ -72,7 +71,7 @@ Returns a more normalized TAF report. Most notably: while the `parseTAF` functio
|
|
|
72
71
|
import { parseTAFAsForecast } from "metar-taf-parser";
|
|
73
72
|
|
|
74
73
|
// You must provide an issued date to use the Forecast abstraction
|
|
75
|
-
const report = parseTAFAsForecast(rawTAFString, {
|
|
74
|
+
const report = parseTAFAsForecast(rawTAFString, { issued: tafIssuedDate });
|
|
76
75
|
|
|
77
76
|
console.log(report.forecast);
|
|
78
77
|
```
|
|
@@ -98,7 +97,7 @@ import {
|
|
|
98
97
|
getCompositeForecastForDate,
|
|
99
98
|
} from "metar-taf-parser";
|
|
100
99
|
|
|
101
|
-
const report = parseTAFAsForecast(rawTAFString, {
|
|
100
|
+
const report = parseTAFAsForecast(rawTAFString, { issued: tafIssuedDate });
|
|
102
101
|
|
|
103
102
|
const forecastPerHour = eachHourOfInterval({
|
|
104
103
|
start: report.start,
|
package/metar-taf-parser.d.ts
CHANGED
|
@@ -1142,11 +1142,11 @@ interface IAbstractValidity {
|
|
|
1142
1142
|
* Exclusive for the TS port (because python has `time()` and js does not)
|
|
1143
1143
|
*/
|
|
1144
1144
|
interface ITime {
|
|
1145
|
-
hour
|
|
1146
|
-
minute
|
|
1145
|
+
hour?: number;
|
|
1146
|
+
minute?: number;
|
|
1147
1147
|
}
|
|
1148
1148
|
interface IAbstractWeatherCode extends IAbstractWeatherContainer, ITime {
|
|
1149
|
-
day
|
|
1149
|
+
day?: number;
|
|
1150
1150
|
airport?: IAirport;
|
|
1151
1151
|
message: string;
|
|
1152
1152
|
station: string;
|
|
@@ -1171,9 +1171,14 @@ interface ITAF extends IAbstractWeatherCode {
|
|
|
1171
1171
|
maxTemperature?: ITemperatureDated;
|
|
1172
1172
|
minTemperature?: ITemperatureDated;
|
|
1173
1173
|
trends: TAFTrend[];
|
|
1174
|
+
/**
|
|
1175
|
+
* Just the first part of the TAF message without trends (FM, BECMG, etc)
|
|
1176
|
+
*/
|
|
1177
|
+
initialRaw: string;
|
|
1174
1178
|
}
|
|
1175
1179
|
interface IAbstractTrend extends IAbstractWeatherContainer {
|
|
1176
1180
|
type: WeatherChangeType;
|
|
1181
|
+
raw: string;
|
|
1177
1182
|
}
|
|
1178
1183
|
interface IMetarTrendTime extends ITime {
|
|
1179
1184
|
type: TimeIndicator;
|
|
@@ -1326,15 +1331,12 @@ interface IMetarTAFParserOptions {
|
|
|
1326
1331
|
}
|
|
1327
1332
|
interface IMetarTAFParserOptionsDated extends IMetarTAFParserOptions {
|
|
1328
1333
|
/**
|
|
1329
|
-
* This date should
|
|
1330
|
-
* can be be +/- one week of the actual report date and work properly.
|
|
1331
|
-
*
|
|
1332
|
-
* So if you know the report was recently issued, you can pass `new Date()`
|
|
1334
|
+
* This date should be the date the report was issued.
|
|
1333
1335
|
*
|
|
1334
1336
|
* This date is needed to create actual timestamps since the report only has
|
|
1335
|
-
* day of month, hour, and minute.
|
|
1337
|
+
* day of month, hour, and minute (and sometimes not even that).
|
|
1336
1338
|
*/
|
|
1337
|
-
|
|
1339
|
+
issued: Date;
|
|
1338
1340
|
}
|
|
1339
1341
|
declare function parseMetar(rawMetar: string, options?: IMetarTAFParserOptions): IMetar;
|
|
1340
1342
|
declare function parseMetar(rawMetar: string, options?: IMetarTAFParserOptionsDated): IMetarDated;
|
package/metar-taf-parser.js
CHANGED
|
@@ -2064,7 +2064,7 @@ function parseDeliveryTime(timeString) {
|
|
|
2064
2064
|
const hour = +timeString.slice(2, 4);
|
|
2065
2065
|
const minute = +timeString.slice(4, 6);
|
|
2066
2066
|
if (isNaN(day) || isNaN(hour) || isNaN(minute))
|
|
2067
|
-
|
|
2067
|
+
return;
|
|
2068
2068
|
return {
|
|
2069
2069
|
day,
|
|
2070
2070
|
hour,
|
|
@@ -2120,7 +2120,7 @@ function parseTemperature(input) {
|
|
|
2120
2120
|
* @param input the string containing the validity
|
|
2121
2121
|
* @returns Validity object
|
|
2122
2122
|
*/
|
|
2123
|
-
function parseValidity(input
|
|
2123
|
+
function parseValidity(input) {
|
|
2124
2124
|
const parts = pySplit(input, "/");
|
|
2125
2125
|
return {
|
|
2126
2126
|
startDay: +parts[0].slice(0, 2),
|
|
@@ -2304,6 +2304,7 @@ class MetarParser extends AbstractParser {
|
|
|
2304
2304
|
clouds: [],
|
|
2305
2305
|
times: [],
|
|
2306
2306
|
remarks: [],
|
|
2307
|
+
raw: input,
|
|
2307
2308
|
};
|
|
2308
2309
|
index = this.parseTrend(index, trend, metarTab);
|
|
2309
2310
|
metar.trends.push(trend);
|
|
@@ -2356,7 +2357,8 @@ class TAFParser extends AbstractParser {
|
|
|
2356
2357
|
const station = lines[0][index];
|
|
2357
2358
|
index += 1;
|
|
2358
2359
|
const time = parseDeliveryTime(lines[0][index]);
|
|
2359
|
-
|
|
2360
|
+
if (time)
|
|
2361
|
+
index += 1;
|
|
2360
2362
|
const validity = parseValidity(lines[0][index]);
|
|
2361
2363
|
const taf = {
|
|
2362
2364
|
station,
|
|
@@ -2368,6 +2370,7 @@ class TAFParser extends AbstractParser {
|
|
|
2368
2370
|
remarks: [],
|
|
2369
2371
|
clouds: [],
|
|
2370
2372
|
weatherConditions: [],
|
|
2373
|
+
initialRaw: lines[0].join(" "),
|
|
2371
2374
|
};
|
|
2372
2375
|
for (let i = index + 1; i < lines[0].length; i++) {
|
|
2373
2376
|
const token = lines[0][i];
|
|
@@ -2434,6 +2437,7 @@ class TAFParser extends AbstractParser {
|
|
|
2434
2437
|
...this.makeEmptyTAFTrend(),
|
|
2435
2438
|
type: WeatherChangeType.FM,
|
|
2436
2439
|
validity: parseFromValidity(lineTokens[0]),
|
|
2440
|
+
raw: lineTokens.join(" "),
|
|
2437
2441
|
};
|
|
2438
2442
|
}
|
|
2439
2443
|
else if (lineTokens[0].startsWith(this.PROB)) {
|
|
@@ -2444,12 +2448,14 @@ class TAFParser extends AbstractParser {
|
|
|
2444
2448
|
...this.makeEmptyTAFTrend(),
|
|
2445
2449
|
type: WeatherChangeType.PROB,
|
|
2446
2450
|
validity,
|
|
2451
|
+
raw: lineTokens.join(" "),
|
|
2447
2452
|
};
|
|
2448
2453
|
if (lineTokens.length > 1 && lineTokens[1] === this.TEMPO) {
|
|
2449
2454
|
trend = {
|
|
2450
2455
|
...this.makeEmptyTAFTrend(),
|
|
2451
2456
|
type: WeatherChangeType[lineTokens[1]],
|
|
2452
2457
|
validity,
|
|
2458
|
+
raw: lineTokens.join(" "),
|
|
2453
2459
|
};
|
|
2454
2460
|
index = 2;
|
|
2455
2461
|
}
|
|
@@ -2463,6 +2469,7 @@ class TAFParser extends AbstractParser {
|
|
|
2463
2469
|
...this.makeEmptyTAFTrend(),
|
|
2464
2470
|
type: WeatherChangeType[lineTokens[0]],
|
|
2465
2471
|
validity,
|
|
2472
|
+
raw: lineTokens.join(" "),
|
|
2466
2473
|
};
|
|
2467
2474
|
}
|
|
2468
2475
|
this.parseTrend(index, lineTokens, trend);
|
|
@@ -2546,6 +2553,9 @@ _RemarkParser_supplier = new WeakMap();
|
|
|
2546
2553
|
* @returns
|
|
2547
2554
|
*/
|
|
2548
2555
|
function determineReportIssuedDate(date, day, hour, minute) {
|
|
2556
|
+
// Some TAF reports do not include a delivery time
|
|
2557
|
+
if (day == null || hour == null)
|
|
2558
|
+
return date;
|
|
2549
2559
|
const months = [
|
|
2550
2560
|
setDateComponents(addMonthsUTC(date, -1), day, hour, minute),
|
|
2551
2561
|
setDateComponents(new Date(date), day, hour, minute),
|
|
@@ -2650,6 +2660,7 @@ function makeInitialForecast(taf) {
|
|
|
2650
2660
|
remarks: taf.remarks,
|
|
2651
2661
|
clouds: taf.clouds,
|
|
2652
2662
|
weatherConditions: taf.weatherConditions,
|
|
2663
|
+
raw: taf.initialRaw,
|
|
2653
2664
|
validity: {
|
|
2654
2665
|
// End day/hour are for end of the entire TAF
|
|
2655
2666
|
startDay: taf.validity.startDay,
|
|
@@ -2705,8 +2716,8 @@ function parse(rawReport, options, parser, datesHydrator) {
|
|
|
2705
2716
|
const lang = options?.locale || en;
|
|
2706
2717
|
try {
|
|
2707
2718
|
const report = new parser(lang).parse(rawReport);
|
|
2708
|
-
if (options && "
|
|
2709
|
-
return datesHydrator(report, options.
|
|
2719
|
+
if (options && "issued" in options) {
|
|
2720
|
+
return datesHydrator(report, options.issued);
|
|
2710
2721
|
}
|
|
2711
2722
|
return report;
|
|
2712
2723
|
}
|