@squawk/flightplan 0.7.0 → 0.8.1

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 CHANGED
@@ -120,8 +120,8 @@ Each element has a `type` discriminant and a `raw` field with the original token
120
120
  | Type | Description | Key fields |
121
121
  | --------------- | ----------------------------------------- | ----------------------------------------------------------- |
122
122
  | `airport` | Resolved airport (ICAO or FAA ID) | `airport` |
123
- | `sid` | Standard Instrument Departure | `procedure`, `legs` |
124
- | `star` | Standard Terminal Arrival Route | `procedure`, `legs` |
123
+ | `sid` | Standard Instrument Departure | `procedure`, `legs`, `transition` |
124
+ | `star` | Standard Terminal Arrival Route | `procedure`, `legs`, `transition` |
125
125
  | `airway` | Airway segment between entry and exit fix | `airway`, `entryFix`, `exitFix`, `waypoints`, `gaps` |
126
126
  | `direct` | DCT (direct) indicator | - |
127
127
  | `waypoint` | Resolved fix or navaid | `fix` and/or `navaid`, `lat`, `lon` |
@@ -152,8 +152,24 @@ is not defined and is not valid as filed.
152
152
  When a token matches an airway designation and both a previous waypoint
153
153
  and a next token (exit fix) are available, the resolver expands the airway
154
154
  between those fixes. The exit fix token is consumed as part of the airway
155
- element. If expansion fails, the airway token falls through to other
156
- resolution strategies.
155
+ element. If expansion fails, the airway token is marked `unresolved` and the
156
+ exit fix token is parsed on its own.
157
+
158
+ ### Procedure handling
159
+
160
+ A token that names a SID or STAR is expanded through the procedure provider.
161
+ The dotted `PROCEDURE.TRANSITION` form (`DEEZZ6.CANDR`) merges the named
162
+ transition into the expansion. Without a dotted transition, the resolver looks
163
+ at the adjacent fix - the token after a SID, or the waypoint before a STAR -
164
+ and merges that transition when the procedure publishes one by that name,
165
+ which is how routes are usually filed (`KJFK DEEZZ6 CANDR`). Otherwise the
166
+ common route alone is expanded. The `sid` or `star` element records the merged
167
+ transition in `transition`.
168
+
169
+ A procedure that cannot be expanded is marked `unresolved`: either the dotted
170
+ transition is not one of its transitions, or the procedure has no common route
171
+ (some SIDs and STARs are published as transitions only) and no adjacent fix
172
+ names one of its transitions.
157
173
 
158
174
  ### Identifier ambiguity
159
175
 
@@ -92,6 +92,8 @@ export interface SidRouteElement {
92
92
  raw: string;
93
93
  /** Resolved procedure record. */
94
94
  procedure: Procedure;
95
+ /** Name of the transition merged into `legs`: the one named in a dotted token (`DEEZZ6.CANDR`), or the fix following the SID when it names one of the procedure's transitions. Absent when only the common route was expanded. */
96
+ transition?: string;
95
97
  /** Ordered legs for the procedure expansion. */
96
98
  legs: ProcedureLeg[];
97
99
  }
@@ -105,6 +107,8 @@ export interface StarRouteElement {
105
107
  raw: string;
106
108
  /** Resolved procedure record. */
107
109
  procedure: Procedure;
110
+ /** Name of the transition merged into `legs`: the one named in a dotted token (`AALLE4.BBOTL`), or the waypoint preceding the STAR when it names one of the procedure's transitions. Absent when only the common route was expanded. */
111
+ transition?: string;
108
112
  /** Ordered legs for the procedure expansion. */
109
113
  legs: ProcedureLeg[];
110
114
  }
@@ -1 +1 @@
1
- {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"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"}
package/dist/resolver.js CHANGED
@@ -105,17 +105,26 @@ function tryAirport(token, airports) {
105
105
  * the most recent airport is the best available hint).
106
106
  *
107
107
  * Accepts both the bare CIFP identifier (e.g. `DEEZZ6`) and the dotted
108
- * identifier-with-transition form (e.g. `DEEZZ6.CANDR`). When a
109
- * transition is supplied it is forwarded to the procedure resolver so
110
- * that the transition's legs are merged into the expansion.
108
+ * identifier-with-transition form (e.g. `DEEZZ6.CANDR`). A dotted
109
+ * transition is forwarded to the procedure resolver so that the
110
+ * transition's legs are merged into the expansion. Without one, the
111
+ * adjacent fix is tried as the transition name: the token after a SID
112
+ * or the waypoint before a STAR, which is how routes are usually filed
113
+ * (`KJFK DEEZZ6 CANDR`). When neither names a transition the common
114
+ * route alone is expanded.
115
+ *
116
+ * Returns `undefined` when the token is not a known SID or STAR. Returns
117
+ * an `unresolved` element when the procedure is known but cannot be
118
+ * expanded: the dotted transition is not one of its transitions, or it
119
+ * has no common route and no adjacent fix names a transition.
111
120
  */
112
- function tryProcedure(token, procedures, airportContext) {
121
+ function tryProcedure(token, procedures, airportContext, previousWaypoint, nextToken) {
113
122
  if (!procedures) {
114
123
  return undefined;
115
124
  }
116
125
  const dotIndex = token.indexOf('.');
117
126
  const identifier = dotIndex >= 0 ? token.slice(0, dotIndex) : token;
118
- const transitionName = dotIndex >= 0 ? token.slice(dotIndex + 1) : undefined;
127
+ const dottedTransition = dotIndex >= 0 ? token.slice(dotIndex + 1) : undefined;
119
128
  if (identifier.length === 0) {
120
129
  return undefined;
121
130
  }
@@ -135,13 +144,34 @@ function tryProcedure(token, procedures, airportContext) {
135
144
  return undefined;
136
145
  }
137
146
  const airportForExpansion = proc.airports[0];
138
- const legs = airportForExpansion === undefined
139
- ? []
140
- : (procedures.expand(airportForExpansion, identifier, transitionName)?.legs ?? []);
141
- if (proc.type === 'SID') {
142
- return { type: 'sid', raw: token, procedure: proc, legs };
147
+ if (airportForExpansion === undefined) {
148
+ return { type: 'unresolved', raw: token };
149
+ }
150
+ const adjacentFix = proc.type === 'SID' ? nextToken : previousWaypoint;
151
+ const transitionName = dottedTransition ?? inferTransitionName(proc, adjacentFix);
152
+ const expansion = procedures.expand(airportForExpansion, identifier, transitionName);
153
+ if (expansion === undefined) {
154
+ return { type: 'unresolved', raw: token };
155
+ }
156
+ const element = proc.type === 'SID'
157
+ ? { type: 'sid', raw: token, procedure: proc, legs: expansion.legs }
158
+ : { type: 'star', raw: token, procedure: proc, legs: expansion.legs };
159
+ if (transitionName !== undefined) {
160
+ element.transition = transitionName;
161
+ }
162
+ return element;
163
+ }
164
+ /**
165
+ * Returns the procedure's transition whose name matches the adjacent fix
166
+ * token, in the procedure's own spelling, or `undefined` when there is
167
+ * no adjacent fix or no transition by that name.
168
+ */
169
+ function inferTransitionName(procedure, adjacentFix) {
170
+ if (adjacentFix === undefined) {
171
+ return undefined;
143
172
  }
144
- return { type: 'star', raw: token, procedure: proc, legs };
173
+ const upper = adjacentFix.toUpperCase();
174
+ return procedure.transitions.find((t) => t.name.toUpperCase() === upper)?.name;
145
175
  }
146
176
  /**
147
177
  * Attempts to resolve a token as a fix waypoint. When an anchor is supplied and
@@ -312,20 +342,26 @@ export function createFlightplanResolver(options) {
312
342
  i++;
313
343
  continue;
314
344
  }
315
- // Try procedure (SID/STAR)
316
- const procElement = tryProcedure(token, procedures, lastAirportIdent);
345
+ // Try procedure (SID/STAR). The fix after a SID or before a STAR may
346
+ // name the transition when the token itself does not.
347
+ const procElement = tryProcedure(token, procedures, lastAirportIdent, lastWaypointIdent, tokens[i + 1]?.toUpperCase());
317
348
  if (procElement) {
318
349
  elements.push(procElement);
319
- // Update last waypoint to the last fix in the procedure expansion
320
- // that actually terminates at a fix (some leg types have no fix).
321
- for (let j = procElement.legs.length - 1; j >= 0; j--) {
322
- const leg = procElement.legs[j];
323
- if (leg?.fixIdentifier !== undefined) {
324
- lastWaypointIdent = leg.fixIdentifier;
325
- if (leg.lat !== undefined && leg.lon !== undefined) {
326
- lastPosition = { lat: leg.lat, lon: leg.lon };
350
+ if (procElement.type === 'unresolved') {
351
+ lastWaypointIdent = undefined;
352
+ }
353
+ else {
354
+ // Update last waypoint to the last fix in the procedure expansion
355
+ // that actually terminates at a fix (some leg types have no fix).
356
+ for (let j = procElement.legs.length - 1; j >= 0; j--) {
357
+ const leg = procElement.legs[j];
358
+ if (leg?.fixIdentifier !== undefined) {
359
+ lastWaypointIdent = leg.fixIdentifier;
360
+ if (leg.lat !== undefined && leg.lon !== undefined) {
361
+ lastPosition = { lat: leg.lat, lon: leg.lon };
362
+ }
363
+ break;
327
364
  }
328
- break;
329
365
  }
330
366
  }
331
367
  i++;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@squawk/flightplan",
3
- "version": "0.7.0",
3
+ "version": "0.8.1",
4
4
  "type": "module",
5
5
  "description": "Flight plan route string parsing and resolution using composed navigation resolvers",
6
6
  "author": "Neil Cochran",
@@ -43,21 +43,21 @@
43
43
  },
44
44
  "dependencies": {
45
45
  "@squawk/flight-math": "^0.5.9",
46
- "@squawk/geo": "^0.5.1",
47
- "@squawk/types": "^0.11.0",
46
+ "@squawk/geo": "^0.5.3",
47
+ "@squawk/types": "^0.13.0",
48
48
  "@types/geojson": "^7946.0.16"
49
49
  },
50
50
  "devDependencies": {
51
- "@squawk/airport-data": "^0.8.3",
52
- "@squawk/airports": "^0.7.4",
53
- "@squawk/airway-data": "^0.6.4",
54
- "@squawk/airways": "^0.6.0",
55
- "@squawk/fix-data": "^0.7.3",
56
- "@squawk/fixes": "^0.5.4",
57
- "@squawk/navaid-data": "^0.7.3",
58
- "@squawk/navaids": "^0.6.4",
59
- "@squawk/procedure-data": "^0.8.3",
60
- "@squawk/procedures": "^0.7.3",
51
+ "@squawk/airport-data": "^0.8.5",
52
+ "@squawk/airports": "^0.7.6",
53
+ "@squawk/airway-data": "^0.6.6",
54
+ "@squawk/airways": "^0.6.2",
55
+ "@squawk/fix-data": "^0.7.5",
56
+ "@squawk/fixes": "^0.5.6",
57
+ "@squawk/navaid-data": "^0.7.5",
58
+ "@squawk/navaids": "^0.6.6",
59
+ "@squawk/procedure-data": "^0.9.1",
60
+ "@squawk/procedures": "^0.8.1",
61
61
  "@types/node": "^26.6.4"
62
62
  },
63
63
  "keywords": [