@aeroswarm/core 0.2.11 → 0.2.13
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 +21 -0
- package/dist/api/index.d.ts +45 -0
- package/dist/api/index.js +75 -0
- package/dist/{chunk-ZYX6U3ZK.js → chunk-7SUMR3X2.js} +26 -2
- package/dist/{chunk-J2UTSYKD.js → chunk-UROKN5FM.js} +5 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +6 -2
- package/dist/types/index.d.ts +45 -1
- package/dist/utils/index.js +1 -1
- package/dist/validation/index.d.ts +59 -1
- package/dist/validation/index.js +5 -1
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -54,6 +54,27 @@ Both `FusedTrackEvent` and `AlertEvent` carry an optional `airportId` (ICAO code
|
|
|
54
54
|
|
|
55
55
|
`positionSchema`, `velocitySchema`, `currentTrackSchema`, `streamEnvelopeSchema`, `sourceHeartbeatSchema`, `wsSubscribeSchema`, `apiSuccessSchema`, `apiErrorSchema`, `apiResponseSchema` + inferred input types (`CurrentTrackInput`, `WsSubscribeInput`, `StreamEnvelopeInput`).
|
|
56
56
|
|
|
57
|
+
### `api` — one response format for every REST endpoint (`@aeroswarm/core/api`)
|
|
58
|
+
|
|
59
|
+
So that a developer who adds an endpoint does not invent a new shape. The WebSocket has its own strict envelope (`streamEnvelopeSchema`); this is the REST counterpart, and its error has the same fields as the WS `stream.error` payload.
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import { ok, fail, toResponse } from "@aeroswarm/core/api";
|
|
63
|
+
|
|
64
|
+
return toResponse(ok(rows, { count: rows.length })); // { ok: true, data: rows, meta: { serverTime, count } }
|
|
65
|
+
return toResponse(fail("NOT_FOUND", "no such track")); // 404 { ok: false, error: { code, message, recoverable } }
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
| | |
|
|
69
|
+
|---|---|
|
|
70
|
+
| Success | `{ "ok": true, "data": <T>, "meta": { "serverTime": 1730000000000, "count"?, "nextCursor"?, "truncated"? } }` |
|
|
71
|
+
| Failure | `{ "ok": false, "error": { "code", "message", "recoverable", "details"? } }` |
|
|
72
|
+
| Codes | `UNAUTHORIZED` 401, `FORBIDDEN` 403, `NOT_FOUND` 404, `BAD_REQUEST` 400, `CONFLICT` 409, `RATE_LIMITED` 429, `UNAVAILABLE` 503, `INTERNAL` 500. `recoverable` is true for the last three and for rate limits. A client must tolerate codes it does not know. |
|
|
73
|
+
| Conventions | times are epoch milliseconds (as in the WS); positions are `{ lat, lon }` (arrays `[lon, lat]` only inside GeoJSON); ids are strings; lists page with `nextCursor` |
|
|
74
|
+
| Older servers | an endpoint that existed before this format keeps its old shape unless the request asks for the envelope: `wantsEnvelope(url, headers)` is true for the header `x-aero-envelope: 1` (`ENVELOPE_HEADER`) or `?envelope=1`. `@aeroswarm/replay-server` does this. |
|
|
75
|
+
|
|
76
|
+
Also exported: `statusFor(code)`, `codeForStatus(status)`, `API_ERROR_CODES`, and the schemas `apiResponseSchema(dataSchema)`, `apiSuccessSchema`, `apiErrorSchema`, `apiMetaSchema`. Checklist for a new endpoint: answer with `ok()` / `fail()`; for a new WS message type, add it to `streamEnvelopeSchema` (turn on `validateOutgoing` in `@aeroswarm/live-server` in your tests to catch a type that was not added).
|
|
77
|
+
|
|
57
78
|
### `config` — environment access
|
|
58
79
|
|
|
59
80
|
| Export | Purpose |
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export { apiErrorSchema, apiMetaSchema, apiResponseSchema, apiSuccessSchema } from '../validation/index.js';
|
|
2
|
+
import 'zod';
|
|
3
|
+
|
|
4
|
+
declare const API_ERROR_CODES: readonly ["UNAUTHORIZED", "FORBIDDEN", "NOT_FOUND", "BAD_REQUEST", "CONFLICT", "RATE_LIMITED", "UNAVAILABLE", "INTERNAL"];
|
|
5
|
+
type ApiErrorCode = (typeof API_ERROR_CODES)[number];
|
|
6
|
+
interface ApiMeta {
|
|
7
|
+
serverTime: number;
|
|
8
|
+
count?: number;
|
|
9
|
+
nextCursor?: string;
|
|
10
|
+
truncated?: boolean;
|
|
11
|
+
}
|
|
12
|
+
interface ApiOk<T> {
|
|
13
|
+
ok: true;
|
|
14
|
+
data: T;
|
|
15
|
+
meta?: ApiMeta;
|
|
16
|
+
}
|
|
17
|
+
interface ApiErr {
|
|
18
|
+
ok: false;
|
|
19
|
+
error: {
|
|
20
|
+
code: string;
|
|
21
|
+
message: string;
|
|
22
|
+
recoverable: boolean;
|
|
23
|
+
details?: unknown;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
type ApiResponse<T> = ApiOk<T> | ApiErr;
|
|
27
|
+
declare const statusFor: (code: ApiErrorCode) => number;
|
|
28
|
+
/** The code for an HTTP status from a server that does not send one. */
|
|
29
|
+
declare function codeForStatus(status: number): ApiErrorCode;
|
|
30
|
+
/** `meta.serverTime` is always set; pass `count`, `nextCursor` or `truncated` for lists. */
|
|
31
|
+
declare function ok<T>(data: T, meta?: Partial<ApiMeta>): ApiOk<T>;
|
|
32
|
+
declare function fail(code: ApiErrorCode, message: string, details?: unknown): ApiErr;
|
|
33
|
+
/** A standard `Response`: JSON, status 200 for success, `statusFor(code)` for a failure. */
|
|
34
|
+
declare function toResponse(body: ApiOk<unknown> | ApiErr, status?: number): Response;
|
|
35
|
+
/**
|
|
36
|
+
* Servers that existed before this format keep answering in their old shape unless the
|
|
37
|
+
* request asks for the envelope, so clients that were written against the old shape do
|
|
38
|
+
* not break. Ask with the header (or `?envelope=1`, for a plain browser request).
|
|
39
|
+
*/
|
|
40
|
+
declare const ENVELOPE_HEADER = "x-aero-envelope";
|
|
41
|
+
declare function wantsEnvelope(url: URL, headers?: {
|
|
42
|
+
get(name: string): string | null;
|
|
43
|
+
}): boolean;
|
|
44
|
+
|
|
45
|
+
export { API_ERROR_CODES, type ApiErr, type ApiErrorCode, type ApiMeta, type ApiOk, type ApiResponse, ENVELOPE_HEADER, codeForStatus, fail, ok, statusFor, toResponse, wantsEnvelope };
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import {
|
|
2
|
+
apiErrorSchema,
|
|
3
|
+
apiMetaSchema,
|
|
4
|
+
apiResponseSchema,
|
|
5
|
+
apiSuccessSchema
|
|
6
|
+
} from "../chunk-7SUMR3X2.js";
|
|
7
|
+
|
|
8
|
+
// src/api/index.ts
|
|
9
|
+
var API_ERROR_CODES = [
|
|
10
|
+
"UNAUTHORIZED",
|
|
11
|
+
"FORBIDDEN",
|
|
12
|
+
"NOT_FOUND",
|
|
13
|
+
"BAD_REQUEST",
|
|
14
|
+
"CONFLICT",
|
|
15
|
+
"RATE_LIMITED",
|
|
16
|
+
"UNAVAILABLE",
|
|
17
|
+
"INTERNAL"
|
|
18
|
+
];
|
|
19
|
+
var STATUS = {
|
|
20
|
+
UNAUTHORIZED: 401,
|
|
21
|
+
FORBIDDEN: 403,
|
|
22
|
+
NOT_FOUND: 404,
|
|
23
|
+
BAD_REQUEST: 400,
|
|
24
|
+
CONFLICT: 409,
|
|
25
|
+
RATE_LIMITED: 429,
|
|
26
|
+
UNAVAILABLE: 503,
|
|
27
|
+
INTERNAL: 500
|
|
28
|
+
};
|
|
29
|
+
var RECOVERABLE = /* @__PURE__ */ new Set(["RATE_LIMITED", "UNAVAILABLE", "INTERNAL"]);
|
|
30
|
+
var statusFor = (code) => STATUS[code];
|
|
31
|
+
function codeForStatus(status) {
|
|
32
|
+
for (const code of API_ERROR_CODES) if (STATUS[code] === status) return code;
|
|
33
|
+
if (status >= 500) return "INTERNAL";
|
|
34
|
+
return "BAD_REQUEST";
|
|
35
|
+
}
|
|
36
|
+
function ok(data, meta = {}) {
|
|
37
|
+
return { ok: true, data, meta: { serverTime: Date.now(), ...meta } };
|
|
38
|
+
}
|
|
39
|
+
function fail(code, message, details) {
|
|
40
|
+
return {
|
|
41
|
+
ok: false,
|
|
42
|
+
error: {
|
|
43
|
+
code,
|
|
44
|
+
message,
|
|
45
|
+
recoverable: RECOVERABLE.has(code),
|
|
46
|
+
...details !== void 0 && { details }
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function toResponse(body, status) {
|
|
51
|
+
const code = body.ok ? void 0 : body.error.code;
|
|
52
|
+
const resolved = status ?? (body.ok ? 200 : (code && STATUS[code]) ?? 500);
|
|
53
|
+
return new Response(JSON.stringify(body), {
|
|
54
|
+
status: resolved,
|
|
55
|
+
headers: { "content-type": "application/json" }
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
var ENVELOPE_HEADER = "x-aero-envelope";
|
|
59
|
+
function wantsEnvelope(url, headers) {
|
|
60
|
+
return url.searchParams.get("envelope") === "1" || headers?.get(ENVELOPE_HEADER) === "1";
|
|
61
|
+
}
|
|
62
|
+
export {
|
|
63
|
+
API_ERROR_CODES,
|
|
64
|
+
ENVELOPE_HEADER,
|
|
65
|
+
apiErrorSchema,
|
|
66
|
+
apiMetaSchema,
|
|
67
|
+
apiResponseSchema,
|
|
68
|
+
apiSuccessSchema,
|
|
69
|
+
codeForStatus,
|
|
70
|
+
fail,
|
|
71
|
+
ok,
|
|
72
|
+
statusFor,
|
|
73
|
+
toResponse,
|
|
74
|
+
wantsEnvelope
|
|
75
|
+
};
|
|
@@ -27,6 +27,10 @@ var flightPlanSummarySchema = z.object({
|
|
|
27
27
|
status: z.enum(["filed", "delayed", "departed", "arrived", "cancelled"]),
|
|
28
28
|
phase: z.enum(["ARRIVAL", "DEPARTURE", "OVERFLIGHT", "UNKNOWN"])
|
|
29
29
|
});
|
|
30
|
+
var dataSourceSchema = z.object({
|
|
31
|
+
sac: z.number().int().min(0).max(255),
|
|
32
|
+
sic: z.number().int().min(0).max(255)
|
|
33
|
+
});
|
|
30
34
|
var currentTrackSchema = z.object({
|
|
31
35
|
trackId: z.string(),
|
|
32
36
|
source: z.enum(["ADSB", "ASTERIX_CAT010", "ASTERIX_CAT011", "ASTERIX_CAT020", "ASTERIX_CAT021", "ASTERIX_CAT048", "ASTERIX_CAT062", "FUSED"]),
|
|
@@ -35,7 +39,12 @@ var currentTrackSchema = z.object({
|
|
|
35
39
|
squawk: z.string().nullable(),
|
|
36
40
|
targetType: z.enum(["aircraft", "vehicle", "unknown"]).optional(),
|
|
37
41
|
vehicleFleet: z.number().optional(),
|
|
42
|
+
aircraftType: z.string().optional(),
|
|
43
|
+
wake: z.string().optional(),
|
|
44
|
+
route: z.object({ adep: z.string().optional(), ades: z.string().optional() }).optional(),
|
|
45
|
+
onGround: z.boolean().optional(),
|
|
38
46
|
airportId: z.string().optional(),
|
|
47
|
+
dataSource: dataSourceSchema.optional(),
|
|
39
48
|
lat: z.number().min(-90).max(90).nullable(),
|
|
40
49
|
lon: z.number().min(-180).max(180).nullable(),
|
|
41
50
|
altitudeFt: z.number().nullable(),
|
|
@@ -119,13 +128,26 @@ var wsUpdateFilterSchema = z.object({
|
|
|
119
128
|
maxUpdateHz: z.number().min(1).max(60).optional(),
|
|
120
129
|
maxTracks: z.number().int().min(1).max(1e4).nullable().optional()
|
|
121
130
|
});
|
|
122
|
-
var
|
|
131
|
+
var apiMetaSchema = z.object({
|
|
132
|
+
/** The server's clock when it answered (ms). */
|
|
133
|
+
serverTime: z.number(),
|
|
134
|
+
/** Number of items, for list responses. */
|
|
135
|
+
count: z.number().int().nonnegative().optional(),
|
|
136
|
+
/** Pass back to get the next page. */
|
|
137
|
+
nextCursor: z.string().optional(),
|
|
138
|
+
/** The server returned fewer items than matched (a `limit`, or thinning). */
|
|
139
|
+
truncated: z.boolean().optional()
|
|
140
|
+
});
|
|
141
|
+
var apiSuccessSchema = (dataSchema) => z.object({ ok: z.literal(true), data: dataSchema, meta: apiMetaSchema.optional() });
|
|
123
142
|
var apiErrorSchema = z.object({
|
|
124
143
|
ok: z.literal(false),
|
|
125
144
|
error: z.object({
|
|
145
|
+
/** Stable machine-readable code, e.g. "NOT_FOUND". A client must tolerate codes it does not know. */
|
|
126
146
|
code: z.string(),
|
|
127
147
|
message: z.string(),
|
|
128
|
-
|
|
148
|
+
/** Retrying the same request later may succeed. Same field as the WS `stream.error` payload. */
|
|
149
|
+
recoverable: z.boolean(),
|
|
150
|
+
details: z.unknown().optional()
|
|
129
151
|
})
|
|
130
152
|
});
|
|
131
153
|
var apiResponseSchema = (dataSchema) => z.union([apiSuccessSchema(dataSchema), apiErrorSchema]);
|
|
@@ -134,11 +156,13 @@ export {
|
|
|
134
156
|
positionSchema,
|
|
135
157
|
velocitySchema,
|
|
136
158
|
flightPlanSummarySchema,
|
|
159
|
+
dataSourceSchema,
|
|
137
160
|
currentTrackSchema,
|
|
138
161
|
streamEnvelopeSchema,
|
|
139
162
|
sourceHeartbeatSchema,
|
|
140
163
|
wsSubscribeSchema,
|
|
141
164
|
wsUpdateFilterSchema,
|
|
165
|
+
apiMetaSchema,
|
|
142
166
|
apiSuccessSchema,
|
|
143
167
|
apiErrorSchema,
|
|
144
168
|
apiResponseSchema
|
|
@@ -83,7 +83,12 @@ function toCurrentTrack(fused, staleAfterMs = 15e3, lostAfterMs = 9e4) {
|
|
|
83
83
|
squawk: fused.identity.squawk ?? null,
|
|
84
84
|
...fused.identity.targetType !== void 0 && { targetType: fused.identity.targetType },
|
|
85
85
|
...fused.identity.vehicleFleet !== void 0 && { vehicleFleet: fused.identity.vehicleFleet },
|
|
86
|
+
...fused.identity.aircraftType !== void 0 && { aircraftType: fused.identity.aircraftType },
|
|
87
|
+
...fused.identity.wake !== void 0 && { wake: fused.identity.wake },
|
|
88
|
+
...fused.route !== void 0 && { route: fused.route },
|
|
89
|
+
...fused.position?.onGround !== void 0 && { onGround: fused.position.onGround },
|
|
86
90
|
...fused.airportId !== void 0 && { airportId: fused.airportId },
|
|
91
|
+
...fused.dataSource !== void 0 && { dataSource: fused.dataSource },
|
|
87
92
|
lat: fused.position?.lat ?? null,
|
|
88
93
|
lon: fused.position?.lon ?? null,
|
|
89
94
|
altitudeFt: fused.position?.alt ?? null,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
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';
|
|
2
|
+
export { AeroConnectionStatus, AeroRecoverableError, AftnMessagePayload, AssignedRoute, Bbox, ConfidenceBudget, CurrentTrack, DataSource, FlightPhase, FlightPlan, FlightPlanEvent, FlightPlanStatus, FlightPlanSummary, Position, Protocol, RouteAssignment, SourceStatus, StreamEnvelope, TargetDetails, 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
5
|
export { applyFlightPlanEvent, flightPhase, flightPlanId, normalizeCallsign, pickMatchingPlan, summarizeFlightPlan } from './flightplan/index.js';
|
|
6
|
-
export { CurrentTrackInput, StreamEnvelopeInput, WsSubscribeInput, apiErrorSchema, apiResponseSchema, apiSuccessSchema, currentTrackSchema, flightPlanSummarySchema, positionSchema, sourceHeartbeatSchema, streamEnvelopeSchema, velocitySchema, wsSubscribeSchema, wsUpdateFilterSchema } from './validation/index.js';
|
|
6
|
+
export { CurrentTrackInput, StreamEnvelopeInput, WsSubscribeInput, apiErrorSchema, apiMetaSchema, apiResponseSchema, apiSuccessSchema, currentTrackSchema, dataSourceSchema, flightPlanSummarySchema, positionSchema, sourceHeartbeatSchema, streamEnvelopeSchema, velocitySchema, wsSubscribeSchema, wsUpdateFilterSchema } from './validation/index.js';
|
|
7
7
|
import pino, { Logger } from 'pino';
|
|
8
8
|
import { Registry, Counter, Gauge } from 'prom-client';
|
|
9
9
|
import { Redis } from 'ioredis';
|
package/dist/index.js
CHANGED
|
@@ -24,12 +24,14 @@ import {
|
|
|
24
24
|
isInsideBbox,
|
|
25
25
|
isRenderableTrack,
|
|
26
26
|
toCurrentTrack
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-UROKN5FM.js";
|
|
28
28
|
import {
|
|
29
29
|
apiErrorSchema,
|
|
30
|
+
apiMetaSchema,
|
|
30
31
|
apiResponseSchema,
|
|
31
32
|
apiSuccessSchema,
|
|
32
33
|
currentTrackSchema,
|
|
34
|
+
dataSourceSchema,
|
|
33
35
|
flightPlanSummarySchema,
|
|
34
36
|
positionSchema,
|
|
35
37
|
sourceHeartbeatSchema,
|
|
@@ -37,7 +39,7 @@ import {
|
|
|
37
39
|
velocitySchema,
|
|
38
40
|
wsSubscribeSchema,
|
|
39
41
|
wsUpdateFilterSchema
|
|
40
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-7SUMR3X2.js";
|
|
41
43
|
|
|
42
44
|
// src/config/index.ts
|
|
43
45
|
import { config } from "dotenv";
|
|
@@ -535,6 +537,7 @@ export {
|
|
|
535
537
|
TOPICS,
|
|
536
538
|
TOPIC_REGISTRY,
|
|
537
539
|
apiErrorSchema,
|
|
540
|
+
apiMetaSchema,
|
|
538
541
|
apiResponseSchema,
|
|
539
542
|
apiSuccessSchema,
|
|
540
543
|
applyFlightPlanEvent,
|
|
@@ -551,6 +554,7 @@ export {
|
|
|
551
554
|
createSessionId,
|
|
552
555
|
createTrackId,
|
|
553
556
|
currentTrackSchema,
|
|
557
|
+
dataSourceSchema,
|
|
554
558
|
deleteTrack,
|
|
555
559
|
disconnectProducer,
|
|
556
560
|
disconnectRedis,
|
package/dist/types/index.d.ts
CHANGED
|
@@ -22,6 +22,25 @@ type Protocol = "adsb" | "asterix-cat010" | "asterix-cat011" | "asterix-cat020"
|
|
|
22
22
|
type Bbox = [minLon: number, minLat: number, maxLon: number, maxLat: number];
|
|
23
23
|
/** Surface target classification (A-SMGCS CAT010/011). Absent for en-route tracks. */
|
|
24
24
|
type TargetType = "aircraft" | "vehicle" | "unknown";
|
|
25
|
+
/** ASTERIX Data Source Identifier (I010 / I020 / I021 / I048 ...): which sensor or ground
|
|
26
|
+
* station reported a track, as System Area Code / System Identification Code (0-255 each). */
|
|
27
|
+
interface DataSource {
|
|
28
|
+
sac: number;
|
|
29
|
+
sic: number;
|
|
30
|
+
}
|
|
31
|
+
/** Facts a sensor reports about a target besides its position and identity. All optional: a sensor sends what it has. */
|
|
32
|
+
interface TargetDetails {
|
|
33
|
+
/** Track number the sensor assigned */
|
|
34
|
+
trackNumber?: number;
|
|
35
|
+
/** Time of the report as the sensor stamped it, seconds since midnight UTC */
|
|
36
|
+
timeOfDay?: number;
|
|
37
|
+
/** ADS-B emitter category (CAT021 ECAT) */
|
|
38
|
+
emitterCategory?: number;
|
|
39
|
+
/** Footprint of a surface target, metres, and the way it points, degrees */
|
|
40
|
+
lengthM?: number;
|
|
41
|
+
widthM?: number;
|
|
42
|
+
orientationDeg?: number;
|
|
43
|
+
}
|
|
25
44
|
interface FusedTrackEvent {
|
|
26
45
|
trackId: string;
|
|
27
46
|
sources: [string, ...string[]];
|
|
@@ -33,8 +52,21 @@ interface FusedTrackEvent {
|
|
|
33
52
|
squawk?: string;
|
|
34
53
|
targetType?: TargetType;
|
|
35
54
|
vehicleFleet?: number;
|
|
55
|
+
/** ICAO aircraft type designator the surveillance system reports, e.g. "A320" (ASTERIX CAT062) */
|
|
56
|
+
aircraftType?: string;
|
|
57
|
+
/** Wake turbulence category L / M / H / J, as in `FlightPlan.wake` */
|
|
58
|
+
wake?: string;
|
|
36
59
|
};
|
|
60
|
+
/** Departure and destination aerodromes the surveillance system reports for the flight (ICAO), named as in `FlightPlan`. */
|
|
61
|
+
route?: {
|
|
62
|
+
adep?: string;
|
|
63
|
+
ades?: string;
|
|
64
|
+
};
|
|
65
|
+
/** What the sensor reported about the target besides where it is (ASTERIX feeds). */
|
|
66
|
+
details?: TargetDetails;
|
|
37
67
|
protocol: Protocol;
|
|
68
|
+
/** Sensor that reported this track (ASTERIX feeds only). For a merged track: the sensor whose position is shown. */
|
|
69
|
+
dataSource?: DataSource;
|
|
38
70
|
position?: Position;
|
|
39
71
|
velocity?: Velocity;
|
|
40
72
|
confidence: ConfidenceBudget;
|
|
@@ -182,8 +214,20 @@ interface CurrentTrack {
|
|
|
182
214
|
targetType?: TargetType;
|
|
183
215
|
/** I010/300 Vehicle Fleet Identification code; only present when targetType is "vehicle" */
|
|
184
216
|
vehicleFleet?: number;
|
|
217
|
+
/** Aircraft type and wake category the surveillance system reports (not the flight plan's: see `flightPlan`) */
|
|
218
|
+
aircraftType?: string;
|
|
219
|
+
wake?: string;
|
|
220
|
+
/** Departure and destination the surveillance system reports for the flight */
|
|
221
|
+
route?: {
|
|
222
|
+
adep?: string;
|
|
223
|
+
ades?: string;
|
|
224
|
+
};
|
|
225
|
+
/** On the ground as the sensor reports it; the airport backend may replace it with its own derived state */
|
|
226
|
+
onGround?: boolean;
|
|
185
227
|
/** ICAO airport code this track is attributed to; undefined = unscoped */
|
|
186
228
|
airportId?: string;
|
|
229
|
+
/** Sensor (SAC/SIC) that reported the position shown; ASTERIX feeds only */
|
|
230
|
+
dataSource?: DataSource;
|
|
187
231
|
lat: number | null;
|
|
188
232
|
lon: number | null;
|
|
189
233
|
altitudeFt: number | null;
|
|
@@ -257,4 +301,4 @@ interface AeroRecoverableError {
|
|
|
257
301
|
}
|
|
258
302
|
type SourceStatus = SourceHealthEvent["status"];
|
|
259
303
|
|
|
260
|
-
export type { AeroConnectionStatus, AeroRecoverableError, AftnMessagePayload, AssignedRoute, Bbox, ConfidenceBudget, CurrentTrack, FlightPhase, FlightPlan, FlightPlanEvent, FlightPlanStatus, FlightPlanSummary, FusedTrackEvent, Position, Protocol, RouteAssignment, SourceHealthEvent, SourceStatus, StreamEnvelope, TargetType, TrackSource, TrackStatus, Velocity };
|
|
304
|
+
export type { AeroConnectionStatus, AeroRecoverableError, AftnMessagePayload, AssignedRoute, Bbox, ConfidenceBudget, CurrentTrack, DataSource, FlightPhase, FlightPlan, FlightPlanEvent, FlightPlanStatus, FlightPlanSummary, FusedTrackEvent, Position, Protocol, RouteAssignment, SourceHealthEvent, SourceStatus, StreamEnvelope, TargetDetails, TargetType, TrackSource, TrackStatus, Velocity };
|
package/dist/utils/index.js
CHANGED
|
@@ -42,6 +42,10 @@ declare const flightPlanSummarySchema: z.ZodObject<{
|
|
|
42
42
|
UNKNOWN: "UNKNOWN";
|
|
43
43
|
}>;
|
|
44
44
|
}, z.core.$strip>;
|
|
45
|
+
declare const dataSourceSchema: z.ZodObject<{
|
|
46
|
+
sac: z.ZodNumber;
|
|
47
|
+
sic: z.ZodNumber;
|
|
48
|
+
}, z.core.$strip>;
|
|
45
49
|
declare const currentTrackSchema: z.ZodObject<{
|
|
46
50
|
trackId: z.ZodString;
|
|
47
51
|
source: z.ZodEnum<{
|
|
@@ -63,7 +67,18 @@ declare const currentTrackSchema: z.ZodObject<{
|
|
|
63
67
|
unknown: "unknown";
|
|
64
68
|
}>>;
|
|
65
69
|
vehicleFleet: z.ZodOptional<z.ZodNumber>;
|
|
70
|
+
aircraftType: z.ZodOptional<z.ZodString>;
|
|
71
|
+
wake: z.ZodOptional<z.ZodString>;
|
|
72
|
+
route: z.ZodOptional<z.ZodObject<{
|
|
73
|
+
adep: z.ZodOptional<z.ZodString>;
|
|
74
|
+
ades: z.ZodOptional<z.ZodString>;
|
|
75
|
+
}, z.core.$strip>>;
|
|
76
|
+
onGround: z.ZodOptional<z.ZodBoolean>;
|
|
66
77
|
airportId: z.ZodOptional<z.ZodString>;
|
|
78
|
+
dataSource: z.ZodOptional<z.ZodObject<{
|
|
79
|
+
sac: z.ZodNumber;
|
|
80
|
+
sic: z.ZodNumber;
|
|
81
|
+
}, z.core.$strip>>;
|
|
67
82
|
lat: z.ZodNullable<z.ZodNumber>;
|
|
68
83
|
lon: z.ZodNullable<z.ZodNumber>;
|
|
69
84
|
altitudeFt: z.ZodNullable<z.ZodNumber>;
|
|
@@ -130,7 +145,18 @@ declare const streamEnvelopeSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
130
145
|
unknown: "unknown";
|
|
131
146
|
}>>;
|
|
132
147
|
vehicleFleet: z.ZodOptional<z.ZodNumber>;
|
|
148
|
+
aircraftType: z.ZodOptional<z.ZodString>;
|
|
149
|
+
wake: z.ZodOptional<z.ZodString>;
|
|
150
|
+
route: z.ZodOptional<z.ZodObject<{
|
|
151
|
+
adep: z.ZodOptional<z.ZodString>;
|
|
152
|
+
ades: z.ZodOptional<z.ZodString>;
|
|
153
|
+
}, z.core.$strip>>;
|
|
154
|
+
onGround: z.ZodOptional<z.ZodBoolean>;
|
|
133
155
|
airportId: z.ZodOptional<z.ZodString>;
|
|
156
|
+
dataSource: z.ZodOptional<z.ZodObject<{
|
|
157
|
+
sac: z.ZodNumber;
|
|
158
|
+
sic: z.ZodNumber;
|
|
159
|
+
}, z.core.$strip>>;
|
|
134
160
|
lat: z.ZodNullable<z.ZodNumber>;
|
|
135
161
|
lon: z.ZodNullable<z.ZodNumber>;
|
|
136
162
|
altitudeFt: z.ZodNullable<z.ZodNumber>;
|
|
@@ -198,7 +224,18 @@ declare const streamEnvelopeSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
198
224
|
unknown: "unknown";
|
|
199
225
|
}>>;
|
|
200
226
|
vehicleFleet: z.ZodOptional<z.ZodNumber>;
|
|
227
|
+
aircraftType: z.ZodOptional<z.ZodString>;
|
|
228
|
+
wake: z.ZodOptional<z.ZodString>;
|
|
229
|
+
route: z.ZodOptional<z.ZodObject<{
|
|
230
|
+
adep: z.ZodOptional<z.ZodString>;
|
|
231
|
+
ades: z.ZodOptional<z.ZodString>;
|
|
232
|
+
}, z.core.$strip>>;
|
|
233
|
+
onGround: z.ZodOptional<z.ZodBoolean>;
|
|
201
234
|
airportId: z.ZodOptional<z.ZodString>;
|
|
235
|
+
dataSource: z.ZodOptional<z.ZodObject<{
|
|
236
|
+
sac: z.ZodNumber;
|
|
237
|
+
sic: z.ZodNumber;
|
|
238
|
+
}, z.core.$strip>>;
|
|
202
239
|
lat: z.ZodNullable<z.ZodNumber>;
|
|
203
240
|
lon: z.ZodNullable<z.ZodNumber>;
|
|
204
241
|
altitudeFt: z.ZodNullable<z.ZodNumber>;
|
|
@@ -325,9 +362,22 @@ declare const wsUpdateFilterSchema: z.ZodObject<{
|
|
|
325
362
|
maxUpdateHz: z.ZodOptional<z.ZodNumber>;
|
|
326
363
|
maxTracks: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
327
364
|
}, z.core.$strip>;
|
|
365
|
+
/** Rides along with a successful REST response. */
|
|
366
|
+
declare const apiMetaSchema: z.ZodObject<{
|
|
367
|
+
serverTime: z.ZodNumber;
|
|
368
|
+
count: z.ZodOptional<z.ZodNumber>;
|
|
369
|
+
nextCursor: z.ZodOptional<z.ZodString>;
|
|
370
|
+
truncated: z.ZodOptional<z.ZodBoolean>;
|
|
371
|
+
}, z.core.$strip>;
|
|
328
372
|
declare const apiSuccessSchema: <T extends z.ZodTypeAny>(dataSchema: T) => z.ZodObject<{
|
|
329
373
|
ok: z.ZodLiteral<true>;
|
|
330
374
|
data: T;
|
|
375
|
+
meta: z.ZodOptional<z.ZodObject<{
|
|
376
|
+
serverTime: z.ZodNumber;
|
|
377
|
+
count: z.ZodOptional<z.ZodNumber>;
|
|
378
|
+
nextCursor: z.ZodOptional<z.ZodString>;
|
|
379
|
+
truncated: z.ZodOptional<z.ZodBoolean>;
|
|
380
|
+
}, z.core.$strip>>;
|
|
331
381
|
}, z.core.$strip>;
|
|
332
382
|
declare const apiErrorSchema: z.ZodObject<{
|
|
333
383
|
ok: z.ZodLiteral<false>;
|
|
@@ -335,21 +385,29 @@ declare const apiErrorSchema: z.ZodObject<{
|
|
|
335
385
|
code: z.ZodString;
|
|
336
386
|
message: z.ZodString;
|
|
337
387
|
recoverable: z.ZodBoolean;
|
|
388
|
+
details: z.ZodOptional<z.ZodUnknown>;
|
|
338
389
|
}, z.core.$strip>;
|
|
339
390
|
}, z.core.$strip>;
|
|
340
391
|
declare const apiResponseSchema: <T extends z.ZodTypeAny>(dataSchema: T) => z.ZodUnion<readonly [z.ZodObject<{
|
|
341
392
|
ok: z.ZodLiteral<true>;
|
|
342
393
|
data: T;
|
|
394
|
+
meta: z.ZodOptional<z.ZodObject<{
|
|
395
|
+
serverTime: z.ZodNumber;
|
|
396
|
+
count: z.ZodOptional<z.ZodNumber>;
|
|
397
|
+
nextCursor: z.ZodOptional<z.ZodString>;
|
|
398
|
+
truncated: z.ZodOptional<z.ZodBoolean>;
|
|
399
|
+
}, z.core.$strip>>;
|
|
343
400
|
}, z.core.$strip>, z.ZodObject<{
|
|
344
401
|
ok: z.ZodLiteral<false>;
|
|
345
402
|
error: z.ZodObject<{
|
|
346
403
|
code: z.ZodString;
|
|
347
404
|
message: z.ZodString;
|
|
348
405
|
recoverable: z.ZodBoolean;
|
|
406
|
+
details: z.ZodOptional<z.ZodUnknown>;
|
|
349
407
|
}, z.core.$strip>;
|
|
350
408
|
}, z.core.$strip>]>;
|
|
351
409
|
type CurrentTrackInput = z.infer<typeof currentTrackSchema>;
|
|
352
410
|
type WsSubscribeInput = z.infer<typeof wsSubscribeSchema>;
|
|
353
411
|
type StreamEnvelopeInput = z.infer<typeof streamEnvelopeSchema>;
|
|
354
412
|
|
|
355
|
-
export { type CurrentTrackInput, type StreamEnvelopeInput, type WsSubscribeInput, apiErrorSchema, apiResponseSchema, apiSuccessSchema, currentTrackSchema, flightPlanSummarySchema, positionSchema, sourceHeartbeatSchema, streamEnvelopeSchema, velocitySchema, wsSubscribeSchema, wsUpdateFilterSchema };
|
|
413
|
+
export { type CurrentTrackInput, type StreamEnvelopeInput, type WsSubscribeInput, apiErrorSchema, apiMetaSchema, apiResponseSchema, apiSuccessSchema, currentTrackSchema, dataSourceSchema, flightPlanSummarySchema, positionSchema, sourceHeartbeatSchema, streamEnvelopeSchema, velocitySchema, wsSubscribeSchema, wsUpdateFilterSchema };
|
package/dist/validation/index.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
apiErrorSchema,
|
|
3
|
+
apiMetaSchema,
|
|
3
4
|
apiResponseSchema,
|
|
4
5
|
apiSuccessSchema,
|
|
5
6
|
currentTrackSchema,
|
|
7
|
+
dataSourceSchema,
|
|
6
8
|
flightPlanSummarySchema,
|
|
7
9
|
positionSchema,
|
|
8
10
|
sourceHeartbeatSchema,
|
|
@@ -10,12 +12,14 @@ import {
|
|
|
10
12
|
velocitySchema,
|
|
11
13
|
wsSubscribeSchema,
|
|
12
14
|
wsUpdateFilterSchema
|
|
13
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-7SUMR3X2.js";
|
|
14
16
|
export {
|
|
15
17
|
apiErrorSchema,
|
|
18
|
+
apiMetaSchema,
|
|
16
19
|
apiResponseSchema,
|
|
17
20
|
apiSuccessSchema,
|
|
18
21
|
currentTrackSchema,
|
|
22
|
+
dataSourceSchema,
|
|
19
23
|
flightPlanSummarySchema,
|
|
20
24
|
positionSchema,
|
|
21
25
|
sourceHeartbeatSchema,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aeroswarm/core",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.13",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -21,6 +21,10 @@
|
|
|
21
21
|
"import": "./dist/flightplan/index.js",
|
|
22
22
|
"types": "./dist/flightplan/index.d.ts"
|
|
23
23
|
},
|
|
24
|
+
"./api": {
|
|
25
|
+
"import": "./dist/api/index.js",
|
|
26
|
+
"types": "./dist/api/index.d.ts"
|
|
27
|
+
},
|
|
24
28
|
"./types": {
|
|
25
29
|
"import": "./dist/types/index.js",
|
|
26
30
|
"types": "./dist/types/index.d.ts"
|
|
@@ -34,8 +38,8 @@
|
|
|
34
38
|
"registry": "https://registry.npmjs.org/"
|
|
35
39
|
},
|
|
36
40
|
"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",
|
|
41
|
+
"build": "tsup src/index.ts src/utils/index.ts src/validation/index.ts src/types/index.ts src/flightplan/index.ts src/api/index.ts --format esm --clean --dts",
|
|
42
|
+
"dev": "tsup src/index.ts src/utils/index.ts src/validation/index.ts src/types/index.ts src/flightplan/index.ts src/api/index.ts --format esm --dts --watch",
|
|
39
43
|
"test": "vitest run --passWithNoTests",
|
|
40
44
|
"typecheck": "tsc --noEmit",
|
|
41
45
|
"clean": "rm -rf dist",
|