@aeroswarm/core 0.2.10 → 0.2.11
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/dist/chunk-3T3CHHEM.js +145 -0
- package/dist/flightplan/index.d.ts +21 -0
- package/dist/flightplan/index.js +16 -0
- package/dist/index.d.ts +4 -21
- package/dist/index.js +21 -150
- package/package.json +63 -59
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// src/flightplan/index.ts
|
|
2
|
+
var FLIGHT_PLAN_MATCH_WINDOW_MS = 36 * 36e5;
|
|
3
|
+
function normalizeCallsign(cs) {
|
|
4
|
+
const v = cs?.trim().toUpperCase().replace(/\s+/g, "");
|
|
5
|
+
return v || void 0;
|
|
6
|
+
}
|
|
7
|
+
function dayKey(msg, receivedAt) {
|
|
8
|
+
if (msg.dof && /^\d{6}$/.test(msg.dof)) return `20${msg.dof}`;
|
|
9
|
+
const t = msg.eobtAt ?? msg.atdAt ?? msg.ataAt ?? receivedAt;
|
|
10
|
+
return new Date(t).toISOString().slice(0, 10).replace(/-/g, "");
|
|
11
|
+
}
|
|
12
|
+
function flightPlanId(msg, receivedAt) {
|
|
13
|
+
const callsign = normalizeCallsign(msg.callsign);
|
|
14
|
+
if (!callsign) return null;
|
|
15
|
+
return `${callsign}|${msg.adep ?? "-"}|${msg.ades ?? "-"}|${dayKey(msg, receivedAt)}`;
|
|
16
|
+
}
|
|
17
|
+
function pickMatchingPlan(candidates, msg, receivedAt) {
|
|
18
|
+
const ref = msg.eobtAt ?? msg.atdAt ?? msg.ataAt ?? receivedAt;
|
|
19
|
+
let best;
|
|
20
|
+
let bestDiff = Infinity;
|
|
21
|
+
for (const c of candidates) {
|
|
22
|
+
if (msg.adep && c.adep && msg.adep !== c.adep) continue;
|
|
23
|
+
if (msg.ades && c.ades && msg.ades !== c.ades) continue;
|
|
24
|
+
const planTime = c.atdAt ?? c.eobtAt ?? c.firstSeenAt;
|
|
25
|
+
const diff = Math.abs(planTime - ref);
|
|
26
|
+
if (diff <= FLIGHT_PLAN_MATCH_WINDOW_MS && diff < bestDiff) {
|
|
27
|
+
best = c;
|
|
28
|
+
bestDiff = diff;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return best;
|
|
32
|
+
}
|
|
33
|
+
function assignDefined(target, patch) {
|
|
34
|
+
for (const [k, v] of Object.entries(patch)) {
|
|
35
|
+
if (v !== void 0 && v !== null && v !== "") target[k] = v;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function eetMs(eet) {
|
|
39
|
+
if (!eet || !/^\d{4}$/.test(eet)) return void 0;
|
|
40
|
+
return (Number(eet.slice(0, 2)) * 60 + Number(eet.slice(2, 4))) * 6e4;
|
|
41
|
+
}
|
|
42
|
+
function applyFlightPlanEvent(prev, ev) {
|
|
43
|
+
const m = ev.message;
|
|
44
|
+
const callsign = normalizeCallsign(m.callsign);
|
|
45
|
+
if (!callsign) return null;
|
|
46
|
+
const id = prev?.id ?? flightPlanId(m, ev.receivedAt);
|
|
47
|
+
if (!id) return null;
|
|
48
|
+
const next = {
|
|
49
|
+
status: "filed",
|
|
50
|
+
airportId: ev.airportId,
|
|
51
|
+
firstSeenAt: ev.receivedAt,
|
|
52
|
+
...prev,
|
|
53
|
+
id,
|
|
54
|
+
callsign,
|
|
55
|
+
other: { ...prev?.other ?? {} },
|
|
56
|
+
lastMessageType: m.type,
|
|
57
|
+
messageCount: (prev?.messageCount ?? 0) + 1,
|
|
58
|
+
updatedAt: ev.receivedAt
|
|
59
|
+
};
|
|
60
|
+
assignDefined(next, { icao24: m.icao24, registration: m.registration, dof: m.dof });
|
|
61
|
+
Object.assign(next.other, m.other);
|
|
62
|
+
if (!next.adep && m.adep) next.adep = m.adep;
|
|
63
|
+
if (!next.ades && m.ades) next.ades = m.ades;
|
|
64
|
+
switch (m.type) {
|
|
65
|
+
case "FPL":
|
|
66
|
+
assignDefined(next, {
|
|
67
|
+
aircraftType: m.aircraftType,
|
|
68
|
+
wake: m.wake,
|
|
69
|
+
flightRules: m.flightRules,
|
|
70
|
+
flightType: m.flightType,
|
|
71
|
+
adep: m.adep,
|
|
72
|
+
ades: m.ades,
|
|
73
|
+
alternates: m.alternates,
|
|
74
|
+
eobtAt: m.eobtAt,
|
|
75
|
+
eet: m.eet,
|
|
76
|
+
cruiseSpeed: m.cruiseSpeed,
|
|
77
|
+
cruiseLevel: m.cruiseLevel,
|
|
78
|
+
route: m.route,
|
|
79
|
+
equipment: m.equipment
|
|
80
|
+
});
|
|
81
|
+
if (prev?.status !== "departed" && prev?.status !== "arrived") next.status = "filed";
|
|
82
|
+
break;
|
|
83
|
+
case "CHG":
|
|
84
|
+
assignDefined(next, {
|
|
85
|
+
aircraftType: m.aircraftType,
|
|
86
|
+
wake: m.wake,
|
|
87
|
+
cruiseSpeed: m.cruiseSpeed,
|
|
88
|
+
cruiseLevel: m.cruiseLevel,
|
|
89
|
+
route: m.route
|
|
90
|
+
});
|
|
91
|
+
if (m.changes?.["13"]) assignDefined(next, { adep: m.adep, eobtAt: m.eobtAt });
|
|
92
|
+
if (m.changes?.["16"]) assignDefined(next, { ades: m.ades, eet: m.eet });
|
|
93
|
+
break;
|
|
94
|
+
case "DLA":
|
|
95
|
+
assignDefined(next, { eobtAt: m.eobtAt });
|
|
96
|
+
if (next.status === "filed" || next.status === "delayed") next.status = "delayed";
|
|
97
|
+
break;
|
|
98
|
+
case "DEP":
|
|
99
|
+
next.atdAt = m.atdAt ?? ev.receivedAt;
|
|
100
|
+
next.status = "departed";
|
|
101
|
+
break;
|
|
102
|
+
case "ARR":
|
|
103
|
+
next.ataAt = m.ataAt ?? ev.receivedAt;
|
|
104
|
+
next.status = "arrived";
|
|
105
|
+
break;
|
|
106
|
+
case "CNL":
|
|
107
|
+
next.status = "cancelled";
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
const departure = next.atdAt ?? next.eobtAt;
|
|
111
|
+
const flightTime = eetMs(next.eet);
|
|
112
|
+
next.etaAt = next.ataAt ?? (departure !== void 0 && flightTime !== void 0 ? departure + flightTime : void 0);
|
|
113
|
+
return next;
|
|
114
|
+
}
|
|
115
|
+
function flightPhase(plan, airportId) {
|
|
116
|
+
const icao = airportId?.trim().toUpperCase();
|
|
117
|
+
if (icao && plan.ades === icao) return "ARRIVAL";
|
|
118
|
+
if (icao && plan.adep === icao) return "DEPARTURE";
|
|
119
|
+
return plan.adep || plan.ades ? "OVERFLIGHT" : "UNKNOWN";
|
|
120
|
+
}
|
|
121
|
+
function summarizeFlightPlan(plan, airportId) {
|
|
122
|
+
const summary = { id: plan.id, status: plan.status, phase: flightPhase(plan, airportId) };
|
|
123
|
+
assignDefined(summary, {
|
|
124
|
+
adep: plan.adep,
|
|
125
|
+
ades: plan.ades,
|
|
126
|
+
aircraftType: plan.aircraftType,
|
|
127
|
+
registration: plan.registration,
|
|
128
|
+
eobtAt: plan.eobtAt,
|
|
129
|
+
atdAt: plan.atdAt,
|
|
130
|
+
ataAt: plan.ataAt,
|
|
131
|
+
etaAt: plan.etaAt,
|
|
132
|
+
cruiseLevel: plan.cruiseLevel,
|
|
133
|
+
route: plan.route
|
|
134
|
+
});
|
|
135
|
+
return summary;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export {
|
|
139
|
+
normalizeCallsign,
|
|
140
|
+
flightPlanId,
|
|
141
|
+
pickMatchingPlan,
|
|
142
|
+
applyFlightPlanEvent,
|
|
143
|
+
flightPhase,
|
|
144
|
+
summarizeFlightPlan
|
|
145
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { FlightPlan, FlightPlanEvent, FlightPhase, AftnMessagePayload, FlightPlanSummary } from '../types/index.js';
|
|
2
|
+
|
|
3
|
+
declare function normalizeCallsign(cs?: string | null): string | undefined;
|
|
4
|
+
/** Stable identity of one flight: callsign + route + day of flight. */
|
|
5
|
+
declare function flightPlanId(msg: AftnMessagePayload, receivedAt: number): string | null;
|
|
6
|
+
/** Pick the existing plan (candidates share the callsign) that a CHG/DLA/DEP/ARR/CNL
|
|
7
|
+
* refers to: same departure/destination when given, closest in time, within the window. */
|
|
8
|
+
declare function pickMatchingPlan(candidates: Iterable<FlightPlan>, msg: AftnMessagePayload, receivedAt: number): FlightPlan | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Fold one AFTN message into the flight's current state. Returns `null` when
|
|
11
|
+
* the message carries no aircraft identification.
|
|
12
|
+
*
|
|
13
|
+
* FPL (re)files the plan; CHG amends the changed items; DLA moves the EOBT;
|
|
14
|
+
* DEP/ARR record actual times; CNL cancels. Other types only bump counters.
|
|
15
|
+
*/
|
|
16
|
+
declare function applyFlightPlanEvent(prev: FlightPlan | undefined, ev: FlightPlanEvent): FlightPlan | null;
|
|
17
|
+
/** Arrival/departure relative to an airport (ICAO). */
|
|
18
|
+
declare function flightPhase(plan: Pick<FlightPlan, "adep" | "ades">, airportId?: string): FlightPhase;
|
|
19
|
+
declare function summarizeFlightPlan(plan: FlightPlan, airportId?: string): FlightPlanSummary;
|
|
20
|
+
|
|
21
|
+
export { applyFlightPlanEvent, flightPhase, flightPlanId, normalizeCallsign, pickMatchingPlan, summarizeFlightPlan };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
applyFlightPlanEvent,
|
|
3
|
+
flightPhase,
|
|
4
|
+
flightPlanId,
|
|
5
|
+
normalizeCallsign,
|
|
6
|
+
pickMatchingPlan,
|
|
7
|
+
summarizeFlightPlan
|
|
8
|
+
} from "../chunk-3T3CHHEM.js";
|
|
9
|
+
export {
|
|
10
|
+
applyFlightPlanEvent,
|
|
11
|
+
flightPhase,
|
|
12
|
+
flightPlanId,
|
|
13
|
+
normalizeCallsign,
|
|
14
|
+
pickMatchingPlan,
|
|
15
|
+
summarizeFlightPlan
|
|
16
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { AeroConnectionStatus, AeroRecoverableError, AssignedRoute, Bbox, ConfidenceBudget, CurrentTrack, FlightPlanStatus, Position, Protocol, RouteAssignment, SourceStatus, StreamEnvelope, TargetType, TrackSource, TrackStatus, Velocity } from './types/index.js';
|
|
1
|
+
import { SourceHealthEvent, FusedTrackEvent } from './types/index.js';
|
|
2
|
+
export { AeroConnectionStatus, AeroRecoverableError, AftnMessagePayload, AssignedRoute, Bbox, ConfidenceBudget, CurrentTrack, FlightPhase, FlightPlan, FlightPlanEvent, FlightPlanStatus, FlightPlanSummary, Position, Protocol, RouteAssignment, SourceStatus, StreamEnvelope, TargetType, TrackSource, TrackStatus, Velocity } from './types/index.js';
|
|
3
3
|
import { TopicName } from './utils/index.js';
|
|
4
4
|
export { EMERGENCY_SQUAWKS, LOST_AFTER_MS, MACH1_KT, PolylineDistance, STALE_AFTER_MS, TOPICS, clamp, createEventId, createEventUid, createNanoid, createSessionId, createTrackId, distanceToPolylineM, haversineKm, isInsideBbox, isRenderableTrack, toCurrentTrack } from './utils/index.js';
|
|
5
|
+
export { applyFlightPlanEvent, flightPhase, flightPlanId, normalizeCallsign, pickMatchingPlan, summarizeFlightPlan } from './flightplan/index.js';
|
|
5
6
|
export { CurrentTrackInput, StreamEnvelopeInput, WsSubscribeInput, apiErrorSchema, apiResponseSchema, apiSuccessSchema, currentTrackSchema, flightPlanSummarySchema, positionSchema, sourceHeartbeatSchema, streamEnvelopeSchema, velocitySchema, wsSubscribeSchema, wsUpdateFilterSchema } from './validation/index.js';
|
|
6
7
|
import pino, { Logger } from 'pino';
|
|
7
8
|
import { Registry, Counter, Gauge } from 'prom-client';
|
|
@@ -9,24 +10,6 @@ import { Redis } from 'ioredis';
|
|
|
9
10
|
import { Kafka, Producer, EachMessagePayload, GroupDescription } from 'kafkajs';
|
|
10
11
|
import 'zod';
|
|
11
12
|
|
|
12
|
-
declare function normalizeCallsign(cs?: string | null): string | undefined;
|
|
13
|
-
/** Stable identity of one flight: callsign + route + day of flight. */
|
|
14
|
-
declare function flightPlanId(msg: AftnMessagePayload, receivedAt: number): string | null;
|
|
15
|
-
/** Pick the existing plan (candidates share the callsign) that a CHG/DLA/DEP/ARR/CNL
|
|
16
|
-
* refers to: same departure/destination when given, closest in time, within the window. */
|
|
17
|
-
declare function pickMatchingPlan(candidates: Iterable<FlightPlan>, msg: AftnMessagePayload, receivedAt: number): FlightPlan | undefined;
|
|
18
|
-
/**
|
|
19
|
-
* Fold one AFTN message into the flight's current state. Returns `null` when
|
|
20
|
-
* the message carries no aircraft identification.
|
|
21
|
-
*
|
|
22
|
-
* FPL (re)files the plan; CHG amends the changed items; DLA moves the EOBT;
|
|
23
|
-
* DEP/ARR record actual times; CNL cancels. Other types only bump counters.
|
|
24
|
-
*/
|
|
25
|
-
declare function applyFlightPlanEvent(prev: FlightPlan | undefined, ev: FlightPlanEvent): FlightPlan | null;
|
|
26
|
-
/** Arrival/departure relative to an airport (ICAO). */
|
|
27
|
-
declare function flightPhase(plan: Pick<FlightPlan, "adep" | "ades">, airportId?: string): FlightPhase;
|
|
28
|
-
declare function summarizeFlightPlan(plan: FlightPlan, airportId?: string): FlightPlanSummary;
|
|
29
|
-
|
|
30
13
|
declare const ENV_VARS: {
|
|
31
14
|
readonly KAFKA_BROKERS: "KAFKA_BROKERS";
|
|
32
15
|
readonly KAFKA_CLIENT_ID: "KAFKA_CLIENT_ID";
|
|
@@ -274,4 +257,4 @@ declare function validateTopics(topics: string[]): {
|
|
|
274
257
|
invalidTopics: string[];
|
|
275
258
|
};
|
|
276
259
|
|
|
277
|
-
export {
|
|
260
|
+
export { type ConsumerConfig, type ConsumerControl, ENV_DEFAULTS, ENV_VARS, type EnvVarName, FusedTrackEvent, type HealthStatus, KAFKA_GROUPS, type KafkaGroupId, LIFECYCLE_STATES, type LifecycleState, PROTOCOL_TYPES, type ProtocolType, SERVICE_PORTS, type ServicePort, SourceHealthEvent, type SourceTokenInfo, TOPIC_REGISTRY, type TopicInfo, TopicName, buildHealthResponse, cacheSourceToken, checkKafkaHealth, checkRateLimit, createConsumer, createLogger, deleteTrack, disconnectProducer, disconnectRedis, ensureTopics, getConsumerGroupHealth, getDbSchema, getDbSearchPath, getEnv, getEnvNumber, getKafka, getProducer, getRedis, getSnapshot, getSourceHealth, getSystemConfig, getTopicInfo, getTrack, getWsClientCount, isConsumerGroupHealthy, isValidTopic, logger, partitionKeys, publishEvent, registerWsClient, registry, revokeSourceToken, runHealthCheck, setSnapshot, setSourceHealth, setSystemConfig, setTrack, trackUpdateRate, unregisterWsClient, validateSourceToken, validateTopics, wsClients };
|
package/dist/index.js
CHANGED
|
@@ -1,17 +1,12 @@
|
|
|
1
|
-
import "./chunk-FXPGR372.js";
|
|
2
1
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
velocitySchema,
|
|
12
|
-
wsSubscribeSchema,
|
|
13
|
-
wsUpdateFilterSchema
|
|
14
|
-
} from "./chunk-ZYX6U3ZK.js";
|
|
2
|
+
applyFlightPlanEvent,
|
|
3
|
+
flightPhase,
|
|
4
|
+
flightPlanId,
|
|
5
|
+
normalizeCallsign,
|
|
6
|
+
pickMatchingPlan,
|
|
7
|
+
summarizeFlightPlan
|
|
8
|
+
} from "./chunk-3T3CHHEM.js";
|
|
9
|
+
import "./chunk-FXPGR372.js";
|
|
15
10
|
import {
|
|
16
11
|
EMERGENCY_SQUAWKS,
|
|
17
12
|
LOST_AFTER_MS,
|
|
@@ -30,143 +25,19 @@ import {
|
|
|
30
25
|
isRenderableTrack,
|
|
31
26
|
toCurrentTrack
|
|
32
27
|
} from "./chunk-J2UTSYKD.js";
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const callsign = normalizeCallsign(msg.callsign);
|
|
47
|
-
if (!callsign) return null;
|
|
48
|
-
return `${callsign}|${msg.adep ?? "-"}|${msg.ades ?? "-"}|${dayKey(msg, receivedAt)}`;
|
|
49
|
-
}
|
|
50
|
-
function pickMatchingPlan(candidates, msg, receivedAt) {
|
|
51
|
-
const ref = msg.eobtAt ?? msg.atdAt ?? msg.ataAt ?? receivedAt;
|
|
52
|
-
let best;
|
|
53
|
-
let bestDiff = Infinity;
|
|
54
|
-
for (const c of candidates) {
|
|
55
|
-
if (msg.adep && c.adep && msg.adep !== c.adep) continue;
|
|
56
|
-
if (msg.ades && c.ades && msg.ades !== c.ades) continue;
|
|
57
|
-
const planTime = c.atdAt ?? c.eobtAt ?? c.firstSeenAt;
|
|
58
|
-
const diff = Math.abs(planTime - ref);
|
|
59
|
-
if (diff <= FLIGHT_PLAN_MATCH_WINDOW_MS && diff < bestDiff) {
|
|
60
|
-
best = c;
|
|
61
|
-
bestDiff = diff;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
return best;
|
|
65
|
-
}
|
|
66
|
-
function assignDefined(target, patch) {
|
|
67
|
-
for (const [k, v] of Object.entries(patch)) {
|
|
68
|
-
if (v !== void 0 && v !== null && v !== "") target[k] = v;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
function eetMs(eet) {
|
|
72
|
-
if (!eet || !/^\d{4}$/.test(eet)) return void 0;
|
|
73
|
-
return (Number(eet.slice(0, 2)) * 60 + Number(eet.slice(2, 4))) * 6e4;
|
|
74
|
-
}
|
|
75
|
-
function applyFlightPlanEvent(prev, ev) {
|
|
76
|
-
const m = ev.message;
|
|
77
|
-
const callsign = normalizeCallsign(m.callsign);
|
|
78
|
-
if (!callsign) return null;
|
|
79
|
-
const id = prev?.id ?? flightPlanId(m, ev.receivedAt);
|
|
80
|
-
if (!id) return null;
|
|
81
|
-
const next = {
|
|
82
|
-
status: "filed",
|
|
83
|
-
airportId: ev.airportId,
|
|
84
|
-
firstSeenAt: ev.receivedAt,
|
|
85
|
-
...prev,
|
|
86
|
-
id,
|
|
87
|
-
callsign,
|
|
88
|
-
other: { ...prev?.other ?? {} },
|
|
89
|
-
lastMessageType: m.type,
|
|
90
|
-
messageCount: (prev?.messageCount ?? 0) + 1,
|
|
91
|
-
updatedAt: ev.receivedAt
|
|
92
|
-
};
|
|
93
|
-
assignDefined(next, { icao24: m.icao24, registration: m.registration, dof: m.dof });
|
|
94
|
-
Object.assign(next.other, m.other);
|
|
95
|
-
if (!next.adep && m.adep) next.adep = m.adep;
|
|
96
|
-
if (!next.ades && m.ades) next.ades = m.ades;
|
|
97
|
-
switch (m.type) {
|
|
98
|
-
case "FPL":
|
|
99
|
-
assignDefined(next, {
|
|
100
|
-
aircraftType: m.aircraftType,
|
|
101
|
-
wake: m.wake,
|
|
102
|
-
flightRules: m.flightRules,
|
|
103
|
-
flightType: m.flightType,
|
|
104
|
-
adep: m.adep,
|
|
105
|
-
ades: m.ades,
|
|
106
|
-
alternates: m.alternates,
|
|
107
|
-
eobtAt: m.eobtAt,
|
|
108
|
-
eet: m.eet,
|
|
109
|
-
cruiseSpeed: m.cruiseSpeed,
|
|
110
|
-
cruiseLevel: m.cruiseLevel,
|
|
111
|
-
route: m.route,
|
|
112
|
-
equipment: m.equipment
|
|
113
|
-
});
|
|
114
|
-
if (prev?.status !== "departed" && prev?.status !== "arrived") next.status = "filed";
|
|
115
|
-
break;
|
|
116
|
-
case "CHG":
|
|
117
|
-
assignDefined(next, {
|
|
118
|
-
aircraftType: m.aircraftType,
|
|
119
|
-
wake: m.wake,
|
|
120
|
-
cruiseSpeed: m.cruiseSpeed,
|
|
121
|
-
cruiseLevel: m.cruiseLevel,
|
|
122
|
-
route: m.route
|
|
123
|
-
});
|
|
124
|
-
if (m.changes?.["13"]) assignDefined(next, { adep: m.adep, eobtAt: m.eobtAt });
|
|
125
|
-
if (m.changes?.["16"]) assignDefined(next, { ades: m.ades, eet: m.eet });
|
|
126
|
-
break;
|
|
127
|
-
case "DLA":
|
|
128
|
-
assignDefined(next, { eobtAt: m.eobtAt });
|
|
129
|
-
if (next.status === "filed" || next.status === "delayed") next.status = "delayed";
|
|
130
|
-
break;
|
|
131
|
-
case "DEP":
|
|
132
|
-
next.atdAt = m.atdAt ?? ev.receivedAt;
|
|
133
|
-
next.status = "departed";
|
|
134
|
-
break;
|
|
135
|
-
case "ARR":
|
|
136
|
-
next.ataAt = m.ataAt ?? ev.receivedAt;
|
|
137
|
-
next.status = "arrived";
|
|
138
|
-
break;
|
|
139
|
-
case "CNL":
|
|
140
|
-
next.status = "cancelled";
|
|
141
|
-
break;
|
|
142
|
-
}
|
|
143
|
-
const departure = next.atdAt ?? next.eobtAt;
|
|
144
|
-
const flightTime = eetMs(next.eet);
|
|
145
|
-
next.etaAt = next.ataAt ?? (departure !== void 0 && flightTime !== void 0 ? departure + flightTime : void 0);
|
|
146
|
-
return next;
|
|
147
|
-
}
|
|
148
|
-
function flightPhase(plan, airportId) {
|
|
149
|
-
const icao = airportId?.trim().toUpperCase();
|
|
150
|
-
if (icao && plan.ades === icao) return "ARRIVAL";
|
|
151
|
-
if (icao && plan.adep === icao) return "DEPARTURE";
|
|
152
|
-
return plan.adep || plan.ades ? "OVERFLIGHT" : "UNKNOWN";
|
|
153
|
-
}
|
|
154
|
-
function summarizeFlightPlan(plan, airportId) {
|
|
155
|
-
const summary = { id: plan.id, status: plan.status, phase: flightPhase(plan, airportId) };
|
|
156
|
-
assignDefined(summary, {
|
|
157
|
-
adep: plan.adep,
|
|
158
|
-
ades: plan.ades,
|
|
159
|
-
aircraftType: plan.aircraftType,
|
|
160
|
-
registration: plan.registration,
|
|
161
|
-
eobtAt: plan.eobtAt,
|
|
162
|
-
atdAt: plan.atdAt,
|
|
163
|
-
ataAt: plan.ataAt,
|
|
164
|
-
etaAt: plan.etaAt,
|
|
165
|
-
cruiseLevel: plan.cruiseLevel,
|
|
166
|
-
route: plan.route
|
|
167
|
-
});
|
|
168
|
-
return summary;
|
|
169
|
-
}
|
|
28
|
+
import {
|
|
29
|
+
apiErrorSchema,
|
|
30
|
+
apiResponseSchema,
|
|
31
|
+
apiSuccessSchema,
|
|
32
|
+
currentTrackSchema,
|
|
33
|
+
flightPlanSummarySchema,
|
|
34
|
+
positionSchema,
|
|
35
|
+
sourceHeartbeatSchema,
|
|
36
|
+
streamEnvelopeSchema,
|
|
37
|
+
velocitySchema,
|
|
38
|
+
wsSubscribeSchema,
|
|
39
|
+
wsUpdateFilterSchema
|
|
40
|
+
} from "./chunk-ZYX6U3ZK.js";
|
|
170
41
|
|
|
171
42
|
// src/config/index.ts
|
|
172
43
|
import { config } from "dotenv";
|
package/package.json
CHANGED
|
@@ -1,59 +1,63 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@aeroswarm/core",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"type": "module",
|
|
5
|
-
"main": "./dist/index.js",
|
|
6
|
-
"types": "./dist/index.d.ts",
|
|
7
|
-
"exports": {
|
|
8
|
-
".": {
|
|
9
|
-
"import": "./dist/index.js",
|
|
10
|
-
"types": "./dist/index.d.ts"
|
|
11
|
-
},
|
|
12
|
-
"./utils": {
|
|
13
|
-
"import": "./dist/utils/index.js",
|
|
14
|
-
"types": "./dist/utils/index.d.ts"
|
|
15
|
-
},
|
|
16
|
-
"./validation": {
|
|
17
|
-
"import": "./dist/validation/index.js",
|
|
18
|
-
"types": "./dist/validation/index.d.ts"
|
|
19
|
-
},
|
|
20
|
-
"./
|
|
21
|
-
"import": "./dist/
|
|
22
|
-
"types": "./dist/
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"release
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@aeroswarm/core",
|
|
3
|
+
"version": "0.2.11",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"./utils": {
|
|
13
|
+
"import": "./dist/utils/index.js",
|
|
14
|
+
"types": "./dist/utils/index.d.ts"
|
|
15
|
+
},
|
|
16
|
+
"./validation": {
|
|
17
|
+
"import": "./dist/validation/index.js",
|
|
18
|
+
"types": "./dist/validation/index.d.ts"
|
|
19
|
+
},
|
|
20
|
+
"./flightplan": {
|
|
21
|
+
"import": "./dist/flightplan/index.js",
|
|
22
|
+
"types": "./dist/flightplan/index.d.ts"
|
|
23
|
+
},
|
|
24
|
+
"./types": {
|
|
25
|
+
"import": "./dist/types/index.js",
|
|
26
|
+
"types": "./dist/types/index.d.ts"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"dist"
|
|
31
|
+
],
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public",
|
|
34
|
+
"registry": "https://registry.npmjs.org/"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsup src/index.ts src/utils/index.ts src/validation/index.ts src/types/index.ts src/flightplan/index.ts --format esm --clean --dts",
|
|
38
|
+
"dev": "tsup src/index.ts src/utils/index.ts src/validation/index.ts src/types/index.ts src/flightplan/index.ts --format esm --dts --watch",
|
|
39
|
+
"test": "vitest run --passWithNoTests",
|
|
40
|
+
"typecheck": "tsc --noEmit",
|
|
41
|
+
"clean": "rm -rf dist",
|
|
42
|
+
"prepublishOnly": "pnpm run typecheck && pnpm run test && pnpm run build",
|
|
43
|
+
"release": "release-it",
|
|
44
|
+
"release:dry": "release-it --dry-run",
|
|
45
|
+
"release:patch": "release-it patch --no-git.requireCleanWorkingDir",
|
|
46
|
+
"release:minor": "release-it minor --no-git.requireCleanWorkingDir",
|
|
47
|
+
"release:major": "release-it major --no-git.requireCleanWorkingDir"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"dotenv": "^16.6.1",
|
|
51
|
+
"ioredis": "^5.6.1",
|
|
52
|
+
"kafkajs": "^2.2.4",
|
|
53
|
+
"pino": "^9.7.0",
|
|
54
|
+
"pino-pretty": "^13.0.0",
|
|
55
|
+
"prom-client": "^15.1.3",
|
|
56
|
+
"zod": "^4.4.3"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"release-it": "^18.1.2",
|
|
60
|
+
"tsup": "^8.5.1",
|
|
61
|
+
"vitest": "^4.1.6"
|
|
62
|
+
}
|
|
63
|
+
}
|