@aeroswarm/core 0.2.11 → 0.2.12

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
@@ -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-OLU4NICO.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"]),
@@ -36,6 +40,7 @@ var currentTrackSchema = z.object({
36
40
  targetType: z.enum(["aircraft", "vehicle", "unknown"]).optional(),
37
41
  vehicleFleet: z.number().optional(),
38
42
  airportId: z.string().optional(),
43
+ dataSource: dataSourceSchema.optional(),
39
44
  lat: z.number().min(-90).max(90).nullable(),
40
45
  lon: z.number().min(-180).max(180).nullable(),
41
46
  altitudeFt: z.number().nullable(),
@@ -119,13 +124,26 @@ var wsUpdateFilterSchema = z.object({
119
124
  maxUpdateHz: z.number().min(1).max(60).optional(),
120
125
  maxTracks: z.number().int().min(1).max(1e4).nullable().optional()
121
126
  });
122
- var apiSuccessSchema = (dataSchema) => z.object({ ok: z.literal(true), data: dataSchema });
127
+ var apiMetaSchema = z.object({
128
+ /** The server's clock when it answered (ms). */
129
+ serverTime: z.number(),
130
+ /** Number of items, for list responses. */
131
+ count: z.number().int().nonnegative().optional(),
132
+ /** Pass back to get the next page. */
133
+ nextCursor: z.string().optional(),
134
+ /** The server returned fewer items than matched (a `limit`, or thinning). */
135
+ truncated: z.boolean().optional()
136
+ });
137
+ var apiSuccessSchema = (dataSchema) => z.object({ ok: z.literal(true), data: dataSchema, meta: apiMetaSchema.optional() });
123
138
  var apiErrorSchema = z.object({
124
139
  ok: z.literal(false),
125
140
  error: z.object({
141
+ /** Stable machine-readable code, e.g. "NOT_FOUND". A client must tolerate codes it does not know. */
126
142
  code: z.string(),
127
143
  message: z.string(),
128
- recoverable: z.boolean()
144
+ /** Retrying the same request later may succeed. Same field as the WS `stream.error` payload. */
145
+ recoverable: z.boolean(),
146
+ details: z.unknown().optional()
129
147
  })
130
148
  });
131
149
  var apiResponseSchema = (dataSchema) => z.union([apiSuccessSchema(dataSchema), apiErrorSchema]);
@@ -134,11 +152,13 @@ export {
134
152
  positionSchema,
135
153
  velocitySchema,
136
154
  flightPlanSummarySchema,
155
+ dataSourceSchema,
137
156
  currentTrackSchema,
138
157
  streamEnvelopeSchema,
139
158
  sourceHeartbeatSchema,
140
159
  wsSubscribeSchema,
141
160
  wsUpdateFilterSchema,
161
+ apiMetaSchema,
142
162
  apiSuccessSchema,
143
163
  apiErrorSchema,
144
164
  apiResponseSchema
@@ -84,6 +84,7 @@ function toCurrentTrack(fused, staleAfterMs = 15e3, lostAfterMs = 9e4) {
84
84
  ...fused.identity.targetType !== void 0 && { targetType: fused.identity.targetType },
85
85
  ...fused.identity.vehicleFleet !== void 0 && { vehicleFleet: fused.identity.vehicleFleet },
86
86
  ...fused.airportId !== void 0 && { airportId: fused.airportId },
87
+ ...fused.dataSource !== void 0 && { dataSource: fused.dataSource },
87
88
  lat: fused.position?.lat ?? null,
88
89
  lon: fused.position?.lon ?? null,
89
90
  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, 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-J2UTSYKD.js";
27
+ } from "./chunk-YDUPWSVU.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-ZYX6U3ZK.js";
42
+ } from "./chunk-OLU4NICO.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,
@@ -22,6 +22,12 @@ 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
+ }
25
31
  interface FusedTrackEvent {
26
32
  trackId: string;
27
33
  sources: [string, ...string[]];
@@ -35,6 +41,8 @@ interface FusedTrackEvent {
35
41
  vehicleFleet?: number;
36
42
  };
37
43
  protocol: Protocol;
44
+ /** Sensor that reported this track (ASTERIX feeds only). For a merged track: the sensor whose position is shown. */
45
+ dataSource?: DataSource;
38
46
  position?: Position;
39
47
  velocity?: Velocity;
40
48
  confidence: ConfidenceBudget;
@@ -184,6 +192,8 @@ interface CurrentTrack {
184
192
  vehicleFleet?: number;
185
193
  /** ICAO airport code this track is attributed to; undefined = unscoped */
186
194
  airportId?: string;
195
+ /** Sensor (SAC/SIC) that reported the position shown; ASTERIX feeds only */
196
+ dataSource?: DataSource;
187
197
  lat: number | null;
188
198
  lon: number | null;
189
199
  altitudeFt: number | null;
@@ -257,4 +267,4 @@ interface AeroRecoverableError {
257
267
  }
258
268
  type SourceStatus = SourceHealthEvent["status"];
259
269
 
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 };
270
+ export type { AeroConnectionStatus, AeroRecoverableError, AftnMessagePayload, AssignedRoute, Bbox, ConfidenceBudget, CurrentTrack, DataSource, FlightPhase, FlightPlan, FlightPlanEvent, FlightPlanStatus, FlightPlanSummary, FusedTrackEvent, Position, Protocol, RouteAssignment, SourceHealthEvent, SourceStatus, StreamEnvelope, TargetType, TrackSource, TrackStatus, Velocity };
@@ -15,7 +15,7 @@ import {
15
15
  isInsideBbox,
16
16
  isRenderableTrack,
17
17
  toCurrentTrack
18
- } from "../chunk-J2UTSYKD.js";
18
+ } from "../chunk-YDUPWSVU.js";
19
19
  export {
20
20
  EMERGENCY_SQUAWKS,
21
21
  LOST_AFTER_MS,
@@ -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<{
@@ -64,6 +68,10 @@ declare const currentTrackSchema: z.ZodObject<{
64
68
  }>>;
65
69
  vehicleFleet: z.ZodOptional<z.ZodNumber>;
66
70
  airportId: z.ZodOptional<z.ZodString>;
71
+ dataSource: z.ZodOptional<z.ZodObject<{
72
+ sac: z.ZodNumber;
73
+ sic: z.ZodNumber;
74
+ }, z.core.$strip>>;
67
75
  lat: z.ZodNullable<z.ZodNumber>;
68
76
  lon: z.ZodNullable<z.ZodNumber>;
69
77
  altitudeFt: z.ZodNullable<z.ZodNumber>;
@@ -131,6 +139,10 @@ declare const streamEnvelopeSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
131
139
  }>>;
132
140
  vehicleFleet: z.ZodOptional<z.ZodNumber>;
133
141
  airportId: z.ZodOptional<z.ZodString>;
142
+ dataSource: z.ZodOptional<z.ZodObject<{
143
+ sac: z.ZodNumber;
144
+ sic: z.ZodNumber;
145
+ }, z.core.$strip>>;
134
146
  lat: z.ZodNullable<z.ZodNumber>;
135
147
  lon: z.ZodNullable<z.ZodNumber>;
136
148
  altitudeFt: z.ZodNullable<z.ZodNumber>;
@@ -199,6 +211,10 @@ declare const streamEnvelopeSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
199
211
  }>>;
200
212
  vehicleFleet: z.ZodOptional<z.ZodNumber>;
201
213
  airportId: z.ZodOptional<z.ZodString>;
214
+ dataSource: z.ZodOptional<z.ZodObject<{
215
+ sac: z.ZodNumber;
216
+ sic: z.ZodNumber;
217
+ }, z.core.$strip>>;
202
218
  lat: z.ZodNullable<z.ZodNumber>;
203
219
  lon: z.ZodNullable<z.ZodNumber>;
204
220
  altitudeFt: z.ZodNullable<z.ZodNumber>;
@@ -325,9 +341,22 @@ declare const wsUpdateFilterSchema: z.ZodObject<{
325
341
  maxUpdateHz: z.ZodOptional<z.ZodNumber>;
326
342
  maxTracks: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
327
343
  }, z.core.$strip>;
344
+ /** Rides along with a successful REST response. */
345
+ declare const apiMetaSchema: z.ZodObject<{
346
+ serverTime: z.ZodNumber;
347
+ count: z.ZodOptional<z.ZodNumber>;
348
+ nextCursor: z.ZodOptional<z.ZodString>;
349
+ truncated: z.ZodOptional<z.ZodBoolean>;
350
+ }, z.core.$strip>;
328
351
  declare const apiSuccessSchema: <T extends z.ZodTypeAny>(dataSchema: T) => z.ZodObject<{
329
352
  ok: z.ZodLiteral<true>;
330
353
  data: T;
354
+ meta: z.ZodOptional<z.ZodObject<{
355
+ serverTime: z.ZodNumber;
356
+ count: z.ZodOptional<z.ZodNumber>;
357
+ nextCursor: z.ZodOptional<z.ZodString>;
358
+ truncated: z.ZodOptional<z.ZodBoolean>;
359
+ }, z.core.$strip>>;
331
360
  }, z.core.$strip>;
332
361
  declare const apiErrorSchema: z.ZodObject<{
333
362
  ok: z.ZodLiteral<false>;
@@ -335,21 +364,29 @@ declare const apiErrorSchema: z.ZodObject<{
335
364
  code: z.ZodString;
336
365
  message: z.ZodString;
337
366
  recoverable: z.ZodBoolean;
367
+ details: z.ZodOptional<z.ZodUnknown>;
338
368
  }, z.core.$strip>;
339
369
  }, z.core.$strip>;
340
370
  declare const apiResponseSchema: <T extends z.ZodTypeAny>(dataSchema: T) => z.ZodUnion<readonly [z.ZodObject<{
341
371
  ok: z.ZodLiteral<true>;
342
372
  data: T;
373
+ meta: z.ZodOptional<z.ZodObject<{
374
+ serverTime: z.ZodNumber;
375
+ count: z.ZodOptional<z.ZodNumber>;
376
+ nextCursor: z.ZodOptional<z.ZodString>;
377
+ truncated: z.ZodOptional<z.ZodBoolean>;
378
+ }, z.core.$strip>>;
343
379
  }, z.core.$strip>, z.ZodObject<{
344
380
  ok: z.ZodLiteral<false>;
345
381
  error: z.ZodObject<{
346
382
  code: z.ZodString;
347
383
  message: z.ZodString;
348
384
  recoverable: z.ZodBoolean;
385
+ details: z.ZodOptional<z.ZodUnknown>;
349
386
  }, z.core.$strip>;
350
387
  }, z.core.$strip>]>;
351
388
  type CurrentTrackInput = z.infer<typeof currentTrackSchema>;
352
389
  type WsSubscribeInput = z.infer<typeof wsSubscribeSchema>;
353
390
  type StreamEnvelopeInput = z.infer<typeof streamEnvelopeSchema>;
354
391
 
355
- export { type CurrentTrackInput, type StreamEnvelopeInput, type WsSubscribeInput, apiErrorSchema, apiResponseSchema, apiSuccessSchema, currentTrackSchema, flightPlanSummarySchema, positionSchema, sourceHeartbeatSchema, streamEnvelopeSchema, velocitySchema, wsSubscribeSchema, wsUpdateFilterSchema };
392
+ export { type CurrentTrackInput, type StreamEnvelopeInput, type WsSubscribeInput, apiErrorSchema, apiMetaSchema, apiResponseSchema, apiSuccessSchema, currentTrackSchema, dataSourceSchema, flightPlanSummarySchema, positionSchema, sourceHeartbeatSchema, streamEnvelopeSchema, velocitySchema, wsSubscribeSchema, wsUpdateFilterSchema };
@@ -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-ZYX6U3ZK.js";
15
+ } from "../chunk-OLU4NICO.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.11",
3
+ "version": "0.2.12",
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",