@airframes/acars-decoder 1.8.13 → 1.9.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/License.md +21 -0
- package/README.md +8 -11
- package/dist/index.d.mts +154 -2
- package/dist/index.d.ts +154 -2
- package/dist/index.js +634 -681
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +634 -681
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/License.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Airframes contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,17 +1,7 @@
|
|
|
1
|
-
# Node.js Support Policy
|
|
2
|
-
|
|
3
|
-
- Runtime support: Node.js >= 18
|
|
4
|
-
- Development and CI: validated on Node 18.x, 20.x, 22.x, and 24.x
|
|
5
|
-
- TypeScript development uses the latest stable Node types (currently v24) without forcing consumers to use a specific Node types version, since `@types/node` is a devDependency.
|
|
6
|
-
- The published builds are compiled targeting Node 18 runtime via `tsup` so they remain compatible across supported Node versions.
|
|
7
|
-
|
|
8
|
-
# @airframes/acars-decoder
|
|
9
|
-
|
|
10
|
-
This is a no-op documentation tweak to verify repository access, build/lint, tests, and PR workflow. No functional code changes are included.
|
|
11
|
-
|
|
12
1
|
# acars-decoder-typescript
|
|
13
2
|
|
|
14
3
|
[](https://badge.fury.io/js/@airframes%2Facars-decoder)
|
|
4
|
+
[](./License.md)
|
|
15
5
|
[
|
|
16
6
|
](https://github.com/airframesio/acars-decoder-typescript/actions/workflows/yarn-test.yml)
|
|
17
7
|

|
|
@@ -27,6 +17,13 @@ It has been written in TypeScript (which compiles to Javascript) and is publishe
|
|
|
27
17
|
|
|
28
18
|
You are welcome to contribute (please see https://github.com/airframesio/acars-message-documentation where we collaborate to research and document the various types of messages), and while it was primarily developed to power [Airframes](https://app.airframes.io) and [AcarsHub](https://sdr-e.com/docker-acarshub), you may use this library in your own applications freely.
|
|
29
19
|
|
|
20
|
+
# Node.js Support Policy
|
|
21
|
+
|
|
22
|
+
- Runtime support: Node.js >= 18
|
|
23
|
+
- Development and CI: validated on Node 18.x, 20.x, 22.x, and 24.x
|
|
24
|
+
- TypeScript development uses the latest stable Node types (currently v24) without forcing consumers to use a specific Node types version, since `@types/node` is a devDependency.
|
|
25
|
+
- The published builds are compiled targeting Node 18 runtime via `tsup` so they remain compatible across supported Node versions.
|
|
26
|
+
|
|
30
27
|
# Installation
|
|
31
28
|
|
|
32
29
|
Add the `@airframes/acars-decoder` library to your JavaScript or TypeScript project.
|
package/dist/index.d.mts
CHANGED
|
@@ -6,6 +6,70 @@ declare class IcaoDecoder {
|
|
|
6
6
|
isMilitary(): boolean;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Represenation of a waypoint.
|
|
11
|
+
*
|
|
12
|
+
* Usually used in Routes which is an array of waypoints.
|
|
13
|
+
* Airways/Jetways can also be represented as a waypoint, by just the name.
|
|
14
|
+
* There is no distinction between the two currently because there is no difference from the current messages
|
|
15
|
+
* Distinction must be determined from tne name.
|
|
16
|
+
* In the event that a waypoint is a GPS position, the name can be the raw position string (N12345W012345)
|
|
17
|
+
*/
|
|
18
|
+
interface Waypoint {
|
|
19
|
+
/** unique identifier of the waypoint*/
|
|
20
|
+
name: string;
|
|
21
|
+
/**
|
|
22
|
+
* latitude in decimal degrees
|
|
23
|
+
*
|
|
24
|
+
* if set, longitude must be provided
|
|
25
|
+
*/
|
|
26
|
+
latitude?: number;
|
|
27
|
+
/** longitude in decimal degrees
|
|
28
|
+
*
|
|
29
|
+
* if set, latitude must be provided
|
|
30
|
+
*/
|
|
31
|
+
longitude?: number;
|
|
32
|
+
/**
|
|
33
|
+
* time of arrival. If in future, it is an ETA.
|
|
34
|
+
*/
|
|
35
|
+
time?: number;
|
|
36
|
+
/**
|
|
37
|
+
* offset from the actual waypoint
|
|
38
|
+
*
|
|
39
|
+
* bearing: degrees from the waypoint
|
|
40
|
+
* distance: distance in nautical miles
|
|
41
|
+
*/
|
|
42
|
+
offset?: {
|
|
43
|
+
bearing: number;
|
|
44
|
+
distance: number;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Representation of a route
|
|
50
|
+
*
|
|
51
|
+
* Typically a list of waypoints, this can also be a named company route.
|
|
52
|
+
*/
|
|
53
|
+
interface Route {
|
|
54
|
+
/** optional name. If not set, `waypoints` is required */
|
|
55
|
+
name?: string;
|
|
56
|
+
/** optional runway */
|
|
57
|
+
runway?: string;
|
|
58
|
+
/** optional list of waypoints. If not set, `name` is required */
|
|
59
|
+
waypoints?: Waypoint[];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
interface Wind {
|
|
63
|
+
waypoint: Waypoint;
|
|
64
|
+
flightLevel: number;
|
|
65
|
+
windDirection: number;
|
|
66
|
+
windSpeed: number;
|
|
67
|
+
temperature?: {
|
|
68
|
+
flightLevel: number;
|
|
69
|
+
degreesC: number;
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
9
73
|
/**
|
|
10
74
|
* Representation of a Message
|
|
11
75
|
*/
|
|
@@ -20,6 +84,87 @@ interface Message {
|
|
|
20
84
|
interface Options {
|
|
21
85
|
debug?: boolean;
|
|
22
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Known fields that can appear on DecodeResult.raw.
|
|
89
|
+
* The index signature allows plugin-specific fields without losing type safety
|
|
90
|
+
* on the well-known ones.
|
|
91
|
+
*/
|
|
92
|
+
interface RawFields {
|
|
93
|
+
position?: {
|
|
94
|
+
latitude: number;
|
|
95
|
+
longitude: number;
|
|
96
|
+
};
|
|
97
|
+
altitude?: number;
|
|
98
|
+
heading?: number;
|
|
99
|
+
groundspeed?: number;
|
|
100
|
+
airspeed?: number;
|
|
101
|
+
mach?: number;
|
|
102
|
+
flight_number?: string;
|
|
103
|
+
callsign?: string;
|
|
104
|
+
tail?: string;
|
|
105
|
+
departure_icao?: string;
|
|
106
|
+
departure_iata?: string;
|
|
107
|
+
arrival_icao?: string;
|
|
108
|
+
arrival_iata?: string;
|
|
109
|
+
alternate_icao?: string;
|
|
110
|
+
departure_runway?: string;
|
|
111
|
+
arrival_runway?: string;
|
|
112
|
+
alternate_runway?: string;
|
|
113
|
+
message_timestamp?: number;
|
|
114
|
+
eta_time?: number;
|
|
115
|
+
out_time?: number;
|
|
116
|
+
off_time?: number;
|
|
117
|
+
on_time?: number;
|
|
118
|
+
in_time?: number;
|
|
119
|
+
engine_start_time?: number;
|
|
120
|
+
engine_stop_time?: number;
|
|
121
|
+
day?: number | string;
|
|
122
|
+
month?: number;
|
|
123
|
+
departure_day?: number;
|
|
124
|
+
arrival_day?: number;
|
|
125
|
+
fuel_on_board?: number;
|
|
126
|
+
fuel_burned?: number;
|
|
127
|
+
fuel_remaining?: number;
|
|
128
|
+
fuel_in_tons?: number;
|
|
129
|
+
out_fuel?: number;
|
|
130
|
+
off_fuel?: number;
|
|
131
|
+
on_fuel?: number;
|
|
132
|
+
in_fuel?: number;
|
|
133
|
+
start_fuel?: number;
|
|
134
|
+
outside_air_temperature?: number;
|
|
135
|
+
total_air_temperature?: number;
|
|
136
|
+
center_of_gravity?: number;
|
|
137
|
+
cg_lower_limit?: number;
|
|
138
|
+
cg_upper_limit?: number;
|
|
139
|
+
mac?: number;
|
|
140
|
+
trim?: number;
|
|
141
|
+
route?: Route;
|
|
142
|
+
wind_data?: Wind[];
|
|
143
|
+
requested_alts?: number[];
|
|
144
|
+
desired_alt?: number;
|
|
145
|
+
start_point?: string;
|
|
146
|
+
route_number?: string;
|
|
147
|
+
flight_plan?: string;
|
|
148
|
+
label?: string;
|
|
149
|
+
sublabel?: string;
|
|
150
|
+
preamble?: string;
|
|
151
|
+
version?: number;
|
|
152
|
+
checksum_algorithm?: string;
|
|
153
|
+
checksum?: number;
|
|
154
|
+
sequence_number?: number;
|
|
155
|
+
sequence_response?: number;
|
|
156
|
+
ground_address?: string;
|
|
157
|
+
text?: string;
|
|
158
|
+
state_change?: {
|
|
159
|
+
from: string;
|
|
160
|
+
to: string;
|
|
161
|
+
};
|
|
162
|
+
door_event?: {
|
|
163
|
+
door: string;
|
|
164
|
+
state: string;
|
|
165
|
+
};
|
|
166
|
+
[key: string]: unknown;
|
|
167
|
+
}
|
|
23
168
|
/**
|
|
24
169
|
* Results from decoding a message
|
|
25
170
|
*/
|
|
@@ -41,7 +186,7 @@ interface DecodeResult {
|
|
|
41
186
|
}[];
|
|
42
187
|
};
|
|
43
188
|
message?: Message;
|
|
44
|
-
raw:
|
|
189
|
+
raw: RawFields;
|
|
45
190
|
remaining: {
|
|
46
191
|
text?: string;
|
|
47
192
|
};
|
|
@@ -51,7 +196,7 @@ interface Qualifiers {
|
|
|
51
196
|
preambles?: string[];
|
|
52
197
|
}
|
|
53
198
|
interface DecoderPluginInterface {
|
|
54
|
-
decode(message: Message): DecodeResult;
|
|
199
|
+
decode(message: Message, options?: Options): DecodeResult;
|
|
55
200
|
meetsStateRequirements(): boolean;
|
|
56
201
|
qualifiers(): Qualifiers;
|
|
57
202
|
}
|
|
@@ -60,9 +205,16 @@ declare class MessageDecoder {
|
|
|
60
205
|
name: string;
|
|
61
206
|
plugins: Array<DecoderPluginInterface>;
|
|
62
207
|
debug: boolean;
|
|
208
|
+
/** Maps a label string to the candidate entries (wildcard + label-specific) in registration order. */
|
|
209
|
+
private candidatesByLabel;
|
|
210
|
+
/** Wildcard entries (plugins that register the '*' label). */
|
|
211
|
+
private wildcardEntries;
|
|
212
|
+
/** Membership set for wildcard entries to dedupe when a plugin also registers a specific label. */
|
|
213
|
+
private wildcardSet;
|
|
63
214
|
constructor();
|
|
64
215
|
registerPlugin(plugin: DecoderPluginInterface): boolean;
|
|
65
216
|
decode(message: Message, options?: Options): DecodeResult;
|
|
217
|
+
private matchesPreambles;
|
|
66
218
|
}
|
|
67
219
|
|
|
68
220
|
export { IcaoDecoder, MessageDecoder };
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,70 @@ declare class IcaoDecoder {
|
|
|
6
6
|
isMilitary(): boolean;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Represenation of a waypoint.
|
|
11
|
+
*
|
|
12
|
+
* Usually used in Routes which is an array of waypoints.
|
|
13
|
+
* Airways/Jetways can also be represented as a waypoint, by just the name.
|
|
14
|
+
* There is no distinction between the two currently because there is no difference from the current messages
|
|
15
|
+
* Distinction must be determined from tne name.
|
|
16
|
+
* In the event that a waypoint is a GPS position, the name can be the raw position string (N12345W012345)
|
|
17
|
+
*/
|
|
18
|
+
interface Waypoint {
|
|
19
|
+
/** unique identifier of the waypoint*/
|
|
20
|
+
name: string;
|
|
21
|
+
/**
|
|
22
|
+
* latitude in decimal degrees
|
|
23
|
+
*
|
|
24
|
+
* if set, longitude must be provided
|
|
25
|
+
*/
|
|
26
|
+
latitude?: number;
|
|
27
|
+
/** longitude in decimal degrees
|
|
28
|
+
*
|
|
29
|
+
* if set, latitude must be provided
|
|
30
|
+
*/
|
|
31
|
+
longitude?: number;
|
|
32
|
+
/**
|
|
33
|
+
* time of arrival. If in future, it is an ETA.
|
|
34
|
+
*/
|
|
35
|
+
time?: number;
|
|
36
|
+
/**
|
|
37
|
+
* offset from the actual waypoint
|
|
38
|
+
*
|
|
39
|
+
* bearing: degrees from the waypoint
|
|
40
|
+
* distance: distance in nautical miles
|
|
41
|
+
*/
|
|
42
|
+
offset?: {
|
|
43
|
+
bearing: number;
|
|
44
|
+
distance: number;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Representation of a route
|
|
50
|
+
*
|
|
51
|
+
* Typically a list of waypoints, this can also be a named company route.
|
|
52
|
+
*/
|
|
53
|
+
interface Route {
|
|
54
|
+
/** optional name. If not set, `waypoints` is required */
|
|
55
|
+
name?: string;
|
|
56
|
+
/** optional runway */
|
|
57
|
+
runway?: string;
|
|
58
|
+
/** optional list of waypoints. If not set, `name` is required */
|
|
59
|
+
waypoints?: Waypoint[];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
interface Wind {
|
|
63
|
+
waypoint: Waypoint;
|
|
64
|
+
flightLevel: number;
|
|
65
|
+
windDirection: number;
|
|
66
|
+
windSpeed: number;
|
|
67
|
+
temperature?: {
|
|
68
|
+
flightLevel: number;
|
|
69
|
+
degreesC: number;
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
9
73
|
/**
|
|
10
74
|
* Representation of a Message
|
|
11
75
|
*/
|
|
@@ -20,6 +84,87 @@ interface Message {
|
|
|
20
84
|
interface Options {
|
|
21
85
|
debug?: boolean;
|
|
22
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Known fields that can appear on DecodeResult.raw.
|
|
89
|
+
* The index signature allows plugin-specific fields without losing type safety
|
|
90
|
+
* on the well-known ones.
|
|
91
|
+
*/
|
|
92
|
+
interface RawFields {
|
|
93
|
+
position?: {
|
|
94
|
+
latitude: number;
|
|
95
|
+
longitude: number;
|
|
96
|
+
};
|
|
97
|
+
altitude?: number;
|
|
98
|
+
heading?: number;
|
|
99
|
+
groundspeed?: number;
|
|
100
|
+
airspeed?: number;
|
|
101
|
+
mach?: number;
|
|
102
|
+
flight_number?: string;
|
|
103
|
+
callsign?: string;
|
|
104
|
+
tail?: string;
|
|
105
|
+
departure_icao?: string;
|
|
106
|
+
departure_iata?: string;
|
|
107
|
+
arrival_icao?: string;
|
|
108
|
+
arrival_iata?: string;
|
|
109
|
+
alternate_icao?: string;
|
|
110
|
+
departure_runway?: string;
|
|
111
|
+
arrival_runway?: string;
|
|
112
|
+
alternate_runway?: string;
|
|
113
|
+
message_timestamp?: number;
|
|
114
|
+
eta_time?: number;
|
|
115
|
+
out_time?: number;
|
|
116
|
+
off_time?: number;
|
|
117
|
+
on_time?: number;
|
|
118
|
+
in_time?: number;
|
|
119
|
+
engine_start_time?: number;
|
|
120
|
+
engine_stop_time?: number;
|
|
121
|
+
day?: number | string;
|
|
122
|
+
month?: number;
|
|
123
|
+
departure_day?: number;
|
|
124
|
+
arrival_day?: number;
|
|
125
|
+
fuel_on_board?: number;
|
|
126
|
+
fuel_burned?: number;
|
|
127
|
+
fuel_remaining?: number;
|
|
128
|
+
fuel_in_tons?: number;
|
|
129
|
+
out_fuel?: number;
|
|
130
|
+
off_fuel?: number;
|
|
131
|
+
on_fuel?: number;
|
|
132
|
+
in_fuel?: number;
|
|
133
|
+
start_fuel?: number;
|
|
134
|
+
outside_air_temperature?: number;
|
|
135
|
+
total_air_temperature?: number;
|
|
136
|
+
center_of_gravity?: number;
|
|
137
|
+
cg_lower_limit?: number;
|
|
138
|
+
cg_upper_limit?: number;
|
|
139
|
+
mac?: number;
|
|
140
|
+
trim?: number;
|
|
141
|
+
route?: Route;
|
|
142
|
+
wind_data?: Wind[];
|
|
143
|
+
requested_alts?: number[];
|
|
144
|
+
desired_alt?: number;
|
|
145
|
+
start_point?: string;
|
|
146
|
+
route_number?: string;
|
|
147
|
+
flight_plan?: string;
|
|
148
|
+
label?: string;
|
|
149
|
+
sublabel?: string;
|
|
150
|
+
preamble?: string;
|
|
151
|
+
version?: number;
|
|
152
|
+
checksum_algorithm?: string;
|
|
153
|
+
checksum?: number;
|
|
154
|
+
sequence_number?: number;
|
|
155
|
+
sequence_response?: number;
|
|
156
|
+
ground_address?: string;
|
|
157
|
+
text?: string;
|
|
158
|
+
state_change?: {
|
|
159
|
+
from: string;
|
|
160
|
+
to: string;
|
|
161
|
+
};
|
|
162
|
+
door_event?: {
|
|
163
|
+
door: string;
|
|
164
|
+
state: string;
|
|
165
|
+
};
|
|
166
|
+
[key: string]: unknown;
|
|
167
|
+
}
|
|
23
168
|
/**
|
|
24
169
|
* Results from decoding a message
|
|
25
170
|
*/
|
|
@@ -41,7 +186,7 @@ interface DecodeResult {
|
|
|
41
186
|
}[];
|
|
42
187
|
};
|
|
43
188
|
message?: Message;
|
|
44
|
-
raw:
|
|
189
|
+
raw: RawFields;
|
|
45
190
|
remaining: {
|
|
46
191
|
text?: string;
|
|
47
192
|
};
|
|
@@ -51,7 +196,7 @@ interface Qualifiers {
|
|
|
51
196
|
preambles?: string[];
|
|
52
197
|
}
|
|
53
198
|
interface DecoderPluginInterface {
|
|
54
|
-
decode(message: Message): DecodeResult;
|
|
199
|
+
decode(message: Message, options?: Options): DecodeResult;
|
|
55
200
|
meetsStateRequirements(): boolean;
|
|
56
201
|
qualifiers(): Qualifiers;
|
|
57
202
|
}
|
|
@@ -60,9 +205,16 @@ declare class MessageDecoder {
|
|
|
60
205
|
name: string;
|
|
61
206
|
plugins: Array<DecoderPluginInterface>;
|
|
62
207
|
debug: boolean;
|
|
208
|
+
/** Maps a label string to the candidate entries (wildcard + label-specific) in registration order. */
|
|
209
|
+
private candidatesByLabel;
|
|
210
|
+
/** Wildcard entries (plugins that register the '*' label). */
|
|
211
|
+
private wildcardEntries;
|
|
212
|
+
/** Membership set for wildcard entries to dedupe when a plugin also registers a specific label. */
|
|
213
|
+
private wildcardSet;
|
|
63
214
|
constructor();
|
|
64
215
|
registerPlugin(plugin: DecoderPluginInterface): boolean;
|
|
65
216
|
decode(message: Message, options?: Options): DecodeResult;
|
|
217
|
+
private matchesPreambles;
|
|
66
218
|
}
|
|
67
219
|
|
|
68
220
|
export { IcaoDecoder, MessageDecoder };
|