@kquika-inc/s-system 1.0.7

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 ADDED
@@ -0,0 +1,222 @@
1
+ # @kquika-inc/s-system
2
+
3
+ The TypeScript client for S-System, the airline operations platform from
4
+ Kquika.
5
+
6
+ Flight operations and airport operations: live status, on-time performance,
7
+ route analytics, stand utilization and terminal congestion, from the platform
8
+ that forecasts disruption up to four days out.
9
+
10
+ ```bash
11
+ npm install @kquika-inc/s-system
12
+ ```
13
+
14
+ Browser and Node 18+. Fully typed, no fetch polyfill. MIT licensed.
15
+
16
+ Also available for Python as
17
+ [`kquika-ssystem`](https://pypi.org/project/kquika-ssystem/).
18
+
19
+ ## Data provenance
20
+
21
+ Every flight carries `data_confidence`, so your code can read the origin of a
22
+ record before acting on it.
23
+
24
+ | Value | Meaning |
25
+ |---|---|
26
+ | `live_feed` | Observed from the live provider feed. |
27
+ | `database` | Observed on an earlier read and persisted. |
28
+
29
+ Fields are left null where the source carries no value. A null
30
+ `delay_minutes` means no time was reported.
31
+
32
+ ## Denominators
33
+
34
+ `on_time_percentage` is calculated over `measured_flights`, and both counts
35
+ are in the response. Flights that reported no time are excluded from that
36
+ denominator, so other ratios can be derived from the same payload.
37
+
38
+ `gate_conflicts` is keyed on airport and gate together, so gate labels are
39
+ only compared within a single station.
40
+
41
+ ## What you can call
42
+
43
+ | | Plan |
44
+ |---|---|
45
+ | **List flights** with origin, destination and date filters | Standard |
46
+ | **One flight** by number | Standard |
47
+ | **Metrics**: on-time performance, average delay, gate conflicts | Standard |
48
+ | **Search** by number, route or date | Standard |
49
+ | **Route analytics**: performance grouped by route | Professional |
50
+ | **Refresh** the live feed on demand | Professional |
51
+ | **Airport overview**: movements, delay, stand utilization | Standard |
52
+ | **LiDAR heatmap**: passenger density by zone | Professional |
53
+ | **Congestion**: current level plus 1h and 3h forecast | Professional |
54
+
55
+ Passenger intelligence is delivered through the application and through
56
+ scheduled data delivery. Contact your account manager about direct access for
57
+ your integration.
58
+
59
+ ## Plans
60
+
61
+ Your rate limit follows your plan. Read it from the response headers instead
62
+ of hardcoding it.
63
+
64
+ | Plan | Rate limit | Burst |
65
+ |---|---|---|
66
+ | Standard | 100 requests/minute | 200/minute |
67
+ | Professional | 500 requests/minute | 1,000/minute |
68
+ | Enterprise | 2,000 requests/minute | 5,000/minute |
69
+
70
+ API access starts at Standard. Starter covers the dashboard and basic
71
+ passenger insights without programmatic access.
72
+
73
+ Capabilities follow the plan too. `GET /subscription` returns the feature
74
+ codes your account carries, so an integration can hide what it cannot reach
75
+ instead of surfacing a 403 to a user who cannot act on it.
76
+
77
+ ---
78
+
79
+ # Using the client
80
+
81
+ ## Getting started
82
+
83
+ ```ts
84
+ import { client, listFlights } from '@kquika-inc/s-system';
85
+
86
+ client.setConfig({
87
+ baseUrl: 'https://www.s-system.cloud',
88
+ headers: { 'X-API-Key': process.env.S_SYSTEM_API_KEY! },
89
+ });
90
+
91
+ const { data, error } = await listFlights({ query: { origin: 'SDQ', limit: 25 } });
92
+
93
+ if (error || !data?.success) {
94
+ console.error(data?.message ?? error);
95
+ } else {
96
+ for (const f of data.data!.flights!) {
97
+ console.log(f.flight_number, f.origin, f.destination, f.data_confidence);
98
+ }
99
+ }
100
+ ```
101
+
102
+ **Check `success` before reading `data`.** Every response carries
103
+ `{success, data, message}`, and `data` is null when `success` is false.
104
+
105
+ ## `data_confidence`
106
+
107
+ ```ts
108
+ for (const flight of data.data) {
109
+ if (flight.data_confidence === 'live_feed') schedule(flight);
110
+ }
111
+ ```
112
+
113
+ `live_feed` is the current reading from the provider. `database` is the same
114
+ reading persisted from an earlier call, so it may lag the feed.
115
+
116
+ TypeScript narrows that union, so a typo fails to compile instead of
117
+ silently never matching.
118
+
119
+ ## Nulls
120
+
121
+ `null` carries meaning in each of these fields.
122
+
123
+ | Field | `null` means |
124
+ |---|---|
125
+ | `delay_minutes` | No time was reported. |
126
+ | `scheduled_departure` | No schedule source covers this flight. |
127
+ | `departure_gate` | Unassigned, or the source carries no gate. |
128
+ | `on_time_percentage` | Nothing was measured. |
129
+
130
+ ```ts
131
+ // Wrong: counts an unreported flight as on time.
132
+ const avg = flights.reduce((s, f) => s + (f.delay_minutes ?? 0), 0) / flights.length;
133
+
134
+ // Right: denominated on what was actually measured.
135
+ const measured = flights.filter(f => f.delay_minutes !== null);
136
+ const avg = measured.reduce((s, f) => s + f.delay_minutes!, 0) / measured.length;
137
+ ```
138
+
139
+ ## Airport operations
140
+
141
+ ```ts
142
+ import {
143
+ getAirportOverview, getAirportHeatmap, getAirportCongestion,
144
+ } from '@kquika-inc/s-system';
145
+
146
+ const heat = await getAirportHeatmap({ path: { airport_code: 'SDQ' } });
147
+
148
+ if (!heat.data?.data?.lidar_available) {
149
+ // This station has no LiDAR coverage, so points is empty.
150
+ console.log('No LiDAR here.');
151
+ } else {
152
+ for (const p of heat.data.data.points!) {
153
+ console.log(p.zone, p.intensity, p.wait_time_minutes);
154
+ }
155
+ }
156
+ ```
157
+
158
+ `avg_wait_minutes` covers queueing zones only: security, check-in,
159
+ immigration and customs. Gates and lounges are out of scope.
160
+
161
+ Heatmap and congestion require Professional. Overview is Standard.
162
+
163
+ ## Flight metrics and route analytics
164
+
165
+ ```ts
166
+ import { getFlightMetrics, getRouteAnalytics } from '@kquika-inc/s-system';
167
+
168
+ const m = await getFlightMetrics();
169
+ const d = m.data!.data!;
170
+ console.log(d.on_time, 'of', d.measured_flights, 'measured');
171
+ console.log('of', d.total_flights, 'scheduled');
172
+ ```
173
+
174
+ Two denominators are returned. `on_time_percentage` divides by
175
+ `measured_flights`. Dividing by `total_flights` yourself treats an unreported
176
+ flight as on time.
177
+
178
+ `gate_conflicts` is null when no flight carried both a gate and a scheduled
179
+ time, which means the check could not run. Null and 0 carry different
180
+ meanings here.
181
+
182
+ ## Errors
183
+
184
+ | Code | Meaning |
185
+ |---|---|
186
+ | `unauthorized` | No valid key. Check `X-API-Key`. |
187
+ | `forbidden` | The key lacks the permission for this endpoint. |
188
+ | `plan_required` | Your plan does not cover this endpoint. |
189
+ | `rate_limited` | Back off for `retry_after_seconds`. |
190
+
191
+ `error` is a stable code and safe to branch on. `message` is for a human and
192
+ its wording may change.
193
+
194
+ `plan_required` is a billing matter: route analytics and refresh need
195
+ Professional, as do heatmap and congestion.
196
+
197
+ On 429, wait for `retry_after_seconds` before the next call. Rejected
198
+ requests count toward the limit.
199
+
200
+ ## Types
201
+
202
+ Every schema is exported.
203
+
204
+ ```ts
205
+ import type {
206
+ Flight,
207
+ DisruptionPrediction,
208
+ Exposure,
209
+ Meta,
210
+ } from '@kquika-inc/s-system';
211
+
212
+ function isActionable(p: DisruptionPrediction): boolean {
213
+ return p.risk_level === 'critical' || p.risk_level === 'elevated';
214
+ }
215
+ ```
216
+
217
+ ## Support
218
+
219
+ An API key, a plan change, or a capability you need that your plan does not
220
+ carry: [www.s-system.cloud](https://www.s-system.cloud)
221
+
222
+ S-System is built by Kquika, Inc.
@@ -0,0 +1,12 @@
1
+ import type { ClientOptions } from './types.gen';
2
+ import { type Config, type ClientOptions as DefaultClientOptions } from '@hey-api/client-fetch';
3
+ /**
4
+ * The `createClientConfig()` function will be called on client initialization
5
+ * and the returned object will become the client's initial configuration.
6
+ *
7
+ * You may want to initialize your client this way instead of calling
8
+ * `setConfig()`. This is useful for example if you're using Next.js
9
+ * to ensure your client always has the correct values.
10
+ */
11
+ export type CreateClientConfig<T extends DefaultClientOptions = ClientOptions> = (override?: Config<DefaultClientOptions & T>) => Config<Required<DefaultClientOptions> & T>;
12
+ export declare const client: import("@hey-api/client-fetch").Client;
@@ -0,0 +1,5 @@
1
+ // This file is auto-generated by @hey-api/openapi-ts
2
+ import { createClient, createConfig } from '@hey-api/client-fetch';
3
+ export const client = createClient(createConfig({
4
+ baseUrl: 'https://www.s-system.cloud'
5
+ }));
@@ -0,0 +1,2 @@
1
+ export * from './types.gen';
2
+ export * from './sdk.gen';
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ // This file is auto-generated by @hey-api/openapi-ts
2
+ export * from './types.gen';
3
+ export * from './sdk.gen';
@@ -0,0 +1,98 @@
1
+ import type { Options as ClientOptions, TDataShape, Client } from '@hey-api/client-fetch';
2
+ import type { ListFlightsData, GetFlightData, GetFlightMetricsData, GetRouteAnalyticsData, SearchFlightsData, RefreshFlightsData, GetAirportOverviewData, GetAirportHeatmapData, GetAirportCongestionData } from './types.gen';
3
+ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = ClientOptions<TData, ThrowOnError> & {
4
+ /**
5
+ * You can provide a client instance returned by `createClient()` instead of
6
+ * individual options. This might be also useful if you want to implement a
7
+ * custom client.
8
+ */
9
+ client?: Client;
10
+ /**
11
+ * You can pass arbitrary values through the `meta` object. This can be
12
+ * used to access values that aren't defined as part of the SDK function.
13
+ */
14
+ meta?: Record<string, unknown>;
15
+ };
16
+ /**
17
+ * List flights
18
+ * Flights for the authenticated company, with optional filters.
19
+ *
20
+ * **Requires Standard.**
21
+ *
22
+ * Each flight carries a `data_confidence` value. Confirm it before using the
23
+ * flight for operational planning.
24
+ */
25
+ export declare const listFlights: <ThrowOnError extends boolean = false>(options?: Options<ListFlightsData, ThrowOnError>) => import("@hey-api/client-fetch").RequestResult<import("./types.gen").FlightListResponse, import("./types.gen").ErrorResponse, ThrowOnError>;
26
+ /**
27
+ * One flight
28
+ * Details for a specific flight.
29
+ *
30
+ * **Requires Standard.**
31
+ */
32
+ export declare const getFlight: <ThrowOnError extends boolean = false>(options: Options<GetFlightData, ThrowOnError>) => import("@hey-api/client-fetch").RequestResult<import("./types.gen").FlightResponse, import("./types.gen").ErrorResponse, ThrowOnError>;
33
+ /**
34
+ * On-time performance, average delay and gate conflicts
35
+ * Aggregate performance for the operating day.
36
+ *
37
+ * **Requires Standard.**
38
+ *
39
+ * `on_time_percentage` is denominated on `measured_flights`. Flights that
40
+ * reported no time are excluded from that denominator. Both counts are returned
41
+ * so other ratios can be derived from the same response.
42
+ *
43
+ * `gate_conflicts` is keyed on airport and gate together, so gate labels are
44
+ * only compared within a single station.
45
+ */
46
+ export declare const getFlightMetrics: <ThrowOnError extends boolean = false>(options?: Options<GetFlightMetricsData, ThrowOnError>) => import("@hey-api/client-fetch").RequestResult<import("./types.gen").MetricsResponse, import("./types.gen").ErrorResponse, ThrowOnError>;
47
+ /**
48
+ * On-time performance grouped by route
49
+ * Performance per route over a window.
50
+ *
51
+ * **Requires Professional.**
52
+ */
53
+ export declare const getRouteAnalytics: <ThrowOnError extends boolean = false>(options?: Options<GetRouteAnalyticsData, ThrowOnError>) => import("@hey-api/client-fetch").RequestResult<import("./types.gen").RouteAnalyticsResponse, import("./types.gen").ErrorResponse, ThrowOnError>;
54
+ /**
55
+ * Search flights by number, route or date
56
+ * Free-text search across flight number, route and date.
57
+ *
58
+ * **Requires Standard.**
59
+ */
60
+ export declare const searchFlights: <ThrowOnError extends boolean = false>(options: Options<SearchFlightsData, ThrowOnError>) => import("@hey-api/client-fetch").RequestResult<import("./types.gen").FlightListResponse, import("./types.gen").ErrorResponse, ThrowOnError>;
61
+ /**
62
+ * Force a refresh of the live flight feed
63
+ * Pulls the live feed on demand, outside the scheduled refresh cycle.
64
+ *
65
+ * **Requires Professional.**
66
+ *
67
+ * This endpoint calls an upstream provider and is rate limited. Use it in
68
+ * response to a known change. Scheduled refreshes continue to run
69
+ * independently.
70
+ */
71
+ export declare const refreshFlights: <ThrowOnError extends boolean = false>(options?: Options<RefreshFlightsData, ThrowOnError>) => import("@hey-api/client-fetch").RequestResult<import("./types.gen").RefreshResponse, import("./types.gen").ErrorResponse, ThrowOnError>;
72
+ /**
73
+ * Airport overview
74
+ * Movements, delay and stand utilization for a station.
75
+ *
76
+ * **Requires Standard.**
77
+ */
78
+ export declare const getAirportOverview: <ThrowOnError extends boolean = false>(options: Options<GetAirportOverviewData, ThrowOnError>) => import("@hey-api/client-fetch").RequestResult<import("./types.gen").AirportOverviewResponse, import("./types.gen").ErrorResponse, ThrowOnError>;
79
+ /**
80
+ * LiDAR heatmap
81
+ * Passenger density by zone, from LiDAR.
82
+ *
83
+ * **Requires Professional.**
84
+ *
85
+ * Points are returned for stations with LiDAR coverage. Check
86
+ * `lidar_available` on the response before reading `points`.
87
+ */
88
+ export declare const getAirportHeatmap: <ThrowOnError extends boolean = false>(options: Options<GetAirportHeatmapData, ThrowOnError>) => import("@hey-api/client-fetch").RequestResult<import("./types.gen").HeatmapResponse, import("./types.gen").ErrorResponse, ThrowOnError>;
89
+ /**
90
+ * Congestion prediction
91
+ * Current congestion and the one and three hour forecast.
92
+ *
93
+ * **Requires Professional.**
94
+ *
95
+ * `avg_wait_minutes` covers queueing zones only: security, check-in,
96
+ * immigration and customs.
97
+ */
98
+ export declare const getAirportCongestion: <ThrowOnError extends boolean = false>(options: Options<GetAirportCongestionData, ThrowOnError>) => import("@hey-api/client-fetch").RequestResult<import("./types.gen").CongestionResponse, import("./types.gen").ErrorResponse, ThrowOnError>;
@@ -0,0 +1,184 @@
1
+ // This file is auto-generated by @hey-api/openapi-ts
2
+ import { client as _heyApiClient } from './client.gen';
3
+ /**
4
+ * List flights
5
+ * Flights for the authenticated company, with optional filters.
6
+ *
7
+ * **Requires Standard.**
8
+ *
9
+ * Each flight carries a `data_confidence` value. Confirm it before using the
10
+ * flight for operational planning.
11
+ */
12
+ export const listFlights = (options) => {
13
+ return (options?.client ?? _heyApiClient).get({
14
+ security: [
15
+ {
16
+ name: 'X-API-Key',
17
+ type: 'apiKey'
18
+ }
19
+ ],
20
+ url: '/api/v1/flights',
21
+ ...options
22
+ });
23
+ };
24
+ /**
25
+ * One flight
26
+ * Details for a specific flight.
27
+ *
28
+ * **Requires Standard.**
29
+ */
30
+ export const getFlight = (options) => {
31
+ return (options.client ?? _heyApiClient).get({
32
+ security: [
33
+ {
34
+ name: 'X-API-Key',
35
+ type: 'apiKey'
36
+ }
37
+ ],
38
+ url: '/api/v1/flights/{flight_id}',
39
+ ...options
40
+ });
41
+ };
42
+ /**
43
+ * On-time performance, average delay and gate conflicts
44
+ * Aggregate performance for the operating day.
45
+ *
46
+ * **Requires Standard.**
47
+ *
48
+ * `on_time_percentage` is denominated on `measured_flights`. Flights that
49
+ * reported no time are excluded from that denominator. Both counts are returned
50
+ * so other ratios can be derived from the same response.
51
+ *
52
+ * `gate_conflicts` is keyed on airport and gate together, so gate labels are
53
+ * only compared within a single station.
54
+ */
55
+ export const getFlightMetrics = (options) => {
56
+ return (options?.client ?? _heyApiClient).get({
57
+ security: [
58
+ {
59
+ name: 'X-API-Key',
60
+ type: 'apiKey'
61
+ }
62
+ ],
63
+ url: '/api/v1/flights/metrics',
64
+ ...options
65
+ });
66
+ };
67
+ /**
68
+ * On-time performance grouped by route
69
+ * Performance per route over a window.
70
+ *
71
+ * **Requires Professional.**
72
+ */
73
+ export const getRouteAnalytics = (options) => {
74
+ return (options?.client ?? _heyApiClient).get({
75
+ security: [
76
+ {
77
+ name: 'X-API-Key',
78
+ type: 'apiKey'
79
+ }
80
+ ],
81
+ url: '/api/v1/flights/route-analytics',
82
+ ...options
83
+ });
84
+ };
85
+ /**
86
+ * Search flights by number, route or date
87
+ * Free-text search across flight number, route and date.
88
+ *
89
+ * **Requires Standard.**
90
+ */
91
+ export const searchFlights = (options) => {
92
+ return (options.client ?? _heyApiClient).get({
93
+ security: [
94
+ {
95
+ name: 'X-API-Key',
96
+ type: 'apiKey'
97
+ }
98
+ ],
99
+ url: '/api/v1/flights/search',
100
+ ...options
101
+ });
102
+ };
103
+ /**
104
+ * Force a refresh of the live flight feed
105
+ * Pulls the live feed on demand, outside the scheduled refresh cycle.
106
+ *
107
+ * **Requires Professional.**
108
+ *
109
+ * This endpoint calls an upstream provider and is rate limited. Use it in
110
+ * response to a known change. Scheduled refreshes continue to run
111
+ * independently.
112
+ */
113
+ export const refreshFlights = (options) => {
114
+ return (options?.client ?? _heyApiClient).post({
115
+ security: [
116
+ {
117
+ name: 'X-API-Key',
118
+ type: 'apiKey'
119
+ }
120
+ ],
121
+ url: '/api/v1/flights/refresh',
122
+ ...options
123
+ });
124
+ };
125
+ /**
126
+ * Airport overview
127
+ * Movements, delay and stand utilization for a station.
128
+ *
129
+ * **Requires Standard.**
130
+ */
131
+ export const getAirportOverview = (options) => {
132
+ return (options.client ?? _heyApiClient).get({
133
+ security: [
134
+ {
135
+ name: 'X-API-Key',
136
+ type: 'apiKey'
137
+ }
138
+ ],
139
+ url: '/api/airport/{airport_code}/overview',
140
+ ...options
141
+ });
142
+ };
143
+ /**
144
+ * LiDAR heatmap
145
+ * Passenger density by zone, from LiDAR.
146
+ *
147
+ * **Requires Professional.**
148
+ *
149
+ * Points are returned for stations with LiDAR coverage. Check
150
+ * `lidar_available` on the response before reading `points`.
151
+ */
152
+ export const getAirportHeatmap = (options) => {
153
+ return (options.client ?? _heyApiClient).get({
154
+ security: [
155
+ {
156
+ name: 'X-API-Key',
157
+ type: 'apiKey'
158
+ }
159
+ ],
160
+ url: '/api/airport/{airport_code}/heatmap',
161
+ ...options
162
+ });
163
+ };
164
+ /**
165
+ * Congestion prediction
166
+ * Current congestion and the one and three hour forecast.
167
+ *
168
+ * **Requires Professional.**
169
+ *
170
+ * `avg_wait_minutes` covers queueing zones only: security, check-in,
171
+ * immigration and customs.
172
+ */
173
+ export const getAirportCongestion = (options) => {
174
+ return (options.client ?? _heyApiClient).get({
175
+ security: [
176
+ {
177
+ name: 'X-API-Key',
178
+ type: 'apiKey'
179
+ }
180
+ ],
181
+ url: '/api/airport/{airport_code}/congestion',
182
+ ...options
183
+ });
184
+ };
@@ -0,0 +1,451 @@
1
+ /**
2
+ * Standard response envelope. Check `success` before reading `data`.
3
+ */
4
+ export type Envelope = {
5
+ /**
6
+ * True when the request succeeded. `data` is null on any error. Branch on this
7
+ * field; do not test for the presence of `data`.
8
+ */
9
+ success: boolean;
10
+ /**
11
+ * Response payload. Null on error.
12
+ */
13
+ data?: unknown;
14
+ /**
15
+ * Human readable status text, safe to display. Wording is not part of the
16
+ * contract; branch on the HTTP status or on `error`.
17
+ */
18
+ message: string;
19
+ };
20
+ export type Flight = {
21
+ flight_number: string;
22
+ airline_code?: string;
23
+ origin: string;
24
+ destination: string;
25
+ /**
26
+ * Published departure time, UTC. Null when no schedule source covers this
27
+ * flight.
28
+ */
29
+ scheduled_departure?: string | null;
30
+ actual_departure?: string | null;
31
+ /**
32
+ * Actual departure minus scheduled departure, in minutes. Null when either time
33
+ * is unavailable. Null and 0 carry different meanings.
34
+ */
35
+ delay_minutes?: number | null;
36
+ /**
37
+ * Null when unassigned or not supplied by the source.
38
+ */
39
+ departure_gate?: string | null;
40
+ departure_terminal?: string | null;
41
+ aircraft_type?: string | null;
42
+ /**
43
+ * Normalized flight status. Defaults to `scheduled` when the source supplies no
44
+ * value.
45
+ */
46
+ status?: 'scheduled' | 'active' | 'landed' | 'delayed' | 'cancelled' | 'diverted' | 'unknown';
47
+ /**
48
+ * Provenance of this record. `live_feed` and `database` are observed records.
49
+ * `generated` is synthetic sample data and is not suitable for operational
50
+ * planning.
51
+ */
52
+ data_confidence: 'live_feed' | 'database' | 'generated';
53
+ };
54
+ export type FlightListResponse = Envelope & {
55
+ data?: {
56
+ flights?: Array<Flight>;
57
+ count?: number;
58
+ /**
59
+ * Provenance of the returned records. `generated` indicates synthetic sample
60
+ * data.
61
+ */
62
+ source?: 'live_feed' | 'database' | 'generated' | 'mixed';
63
+ };
64
+ };
65
+ export type FlightResponse = Envelope & {
66
+ data?: Flight;
67
+ };
68
+ export type MetricsResponse = Envelope & {
69
+ data?: {
70
+ /**
71
+ * All flights for the operating day, including those with no reported times.
72
+ */
73
+ total_flights?: number;
74
+ /**
75
+ * Flights that reported a departure time. Denominator for `on_time_percentage`.
76
+ */
77
+ measured_flights?: number;
78
+ /**
79
+ * Departures within 15 minutes of schedule.
80
+ */
81
+ on_time?: number;
82
+ /**
83
+ * `on_time` divided by `measured_flights`. Null when `measured_flights` is 0.
84
+ */
85
+ on_time_percentage?: number | null;
86
+ /**
87
+ * Mean delay across delayed departures only. The denominator excludes on time
88
+ * departures.
89
+ */
90
+ average_delay_minutes?: number | null;
91
+ /**
92
+ * Departures sharing a stand within the turnaround minimum. Null when no flight
93
+ * carried both a gate and a scheduled time, which is distinct from 0.
94
+ */
95
+ gate_conflicts?: number | null;
96
+ };
97
+ };
98
+ export type RouteAnalyticsResponse = Envelope & {
99
+ data?: Array<{
100
+ route?: string;
101
+ origin?: string;
102
+ destination?: string;
103
+ flights?: number;
104
+ /**
105
+ * Flights that reported a time. Denominator for the rates in this record.
106
+ */
107
+ measured_flights?: number;
108
+ on_time_percentage?: number | null;
109
+ average_delay_minutes?: number | null;
110
+ worst_delay_minutes?: number | null;
111
+ }>;
112
+ };
113
+ export type RefreshResponse = Envelope & {
114
+ data?: {
115
+ flights_fetched?: number;
116
+ /**
117
+ * Records persisted. May be lower than `flights_fetched`, since records without
118
+ * a usable schedule are skipped.
119
+ */
120
+ flights_stored?: number;
121
+ source?: string;
122
+ };
123
+ };
124
+ export type AirportOverviewResponse = Envelope & {
125
+ data?: {
126
+ airport_code?: string;
127
+ departures_today?: number;
128
+ arrivals_today?: number;
129
+ on_time_percentage?: number | null;
130
+ average_delay_minutes?: number | null;
131
+ gates_in_use?: number | null;
132
+ gate_conflicts?: number | null;
133
+ };
134
+ };
135
+ export type HeatmapResponse = Envelope & {
136
+ data?: {
137
+ airport_code?: string;
138
+ /**
139
+ * Whether LiDAR coverage exists at this station. `points` is empty when false,
140
+ * which carries no information about occupancy.
141
+ */
142
+ lidar_available?: boolean;
143
+ points?: Array<{
144
+ zone?: string;
145
+ zone_type?: string;
146
+ intensity?: number;
147
+ passenger_count?: number | null;
148
+ wait_time_minutes?: number | null;
149
+ }>;
150
+ };
151
+ };
152
+ export type CongestionResponse = Envelope & {
153
+ data?: Array<{
154
+ timestamp?: string;
155
+ congestion_level?: 'low' | 'moderate' | 'high' | 'critical';
156
+ estimated_passengers?: number | null;
157
+ /**
158
+ * Mean wait across queueing zones only: security, check-in, immigration and
159
+ * customs. Gates and lounges are out of scope.
160
+ */
161
+ avg_wait_minutes?: number | null;
162
+ /**
163
+ * Forecast level one hour ahead. Null when unavailable.
164
+ */
165
+ predicted_1h?: string | null;
166
+ /**
167
+ * Forecast level three hours ahead. Null when unavailable.
168
+ */
169
+ predicted_3h?: string | null;
170
+ }>;
171
+ };
172
+ export type ErrorResponse = Envelope & {
173
+ /**
174
+ * Stable machine-readable code. Safe to branch on.
175
+ */
176
+ error?: string;
177
+ /**
178
+ * Present on 429. Wait this long before retrying.
179
+ */
180
+ retry_after_seconds?: number | null;
181
+ };
182
+ /**
183
+ * IATA code, three letters. Case insensitive.
184
+ */
185
+ export type AirportCode = string;
186
+ export type ListFlightsData = {
187
+ body?: never;
188
+ path?: never;
189
+ query?: {
190
+ /**
191
+ * IATA code, three letters. Case insensitive.
192
+ */
193
+ origin?: string;
194
+ destination?: string;
195
+ /**
196
+ * Operating day, ISO 8601. Defaults to today in UTC.
197
+ */
198
+ date?: string;
199
+ limit?: number;
200
+ };
201
+ url: '/api/v1/flights';
202
+ };
203
+ export type ListFlightsErrors = {
204
+ /**
205
+ * Missing or invalid API key.
206
+ */
207
+ 401: ErrorResponse;
208
+ /**
209
+ * The key lacks the required scope, or the plan does not cover this endpoint.
210
+ * Use `error` to distinguish: `forbidden` indicates key scope, `plan_required`
211
+ * indicates billing.
212
+ */
213
+ 403: ErrorResponse;
214
+ /**
215
+ * Too many requests.
216
+ */
217
+ 429: ErrorResponse;
218
+ };
219
+ export type ListFlightsError = ListFlightsErrors[keyof ListFlightsErrors];
220
+ export type ListFlightsResponses = {
221
+ /**
222
+ * Flights matching the filters.
223
+ */
224
+ 200: FlightListResponse;
225
+ };
226
+ export type ListFlightsResponse = ListFlightsResponses[keyof ListFlightsResponses];
227
+ export type GetFlightData = {
228
+ body?: never;
229
+ path: {
230
+ flight_id: string;
231
+ };
232
+ query?: never;
233
+ url: '/api/v1/flights/{flight_id}';
234
+ };
235
+ export type GetFlightErrors = {
236
+ /**
237
+ * Missing or invalid API key.
238
+ */
239
+ 401: ErrorResponse;
240
+ /**
241
+ * No such flight.
242
+ */
243
+ 404: ErrorResponse;
244
+ };
245
+ export type GetFlightError = GetFlightErrors[keyof GetFlightErrors];
246
+ export type GetFlightResponses = {
247
+ /**
248
+ * The flight.
249
+ */
250
+ 200: FlightResponse;
251
+ };
252
+ export type GetFlightResponse = GetFlightResponses[keyof GetFlightResponses];
253
+ export type GetFlightMetricsData = {
254
+ body?: never;
255
+ path?: never;
256
+ query?: never;
257
+ url: '/api/v1/flights/metrics';
258
+ };
259
+ export type GetFlightMetricsErrors = {
260
+ /**
261
+ * Missing or invalid API key.
262
+ */
263
+ 401: ErrorResponse;
264
+ };
265
+ export type GetFlightMetricsError = GetFlightMetricsErrors[keyof GetFlightMetricsErrors];
266
+ export type GetFlightMetricsResponses = {
267
+ /**
268
+ * Metrics for the day.
269
+ */
270
+ 200: MetricsResponse;
271
+ };
272
+ export type GetFlightMetricsResponse = GetFlightMetricsResponses[keyof GetFlightMetricsResponses];
273
+ export type GetRouteAnalyticsData = {
274
+ body?: never;
275
+ path?: never;
276
+ query?: {
277
+ /**
278
+ * Lookback window in days.
279
+ */
280
+ days?: number;
281
+ };
282
+ url: '/api/v1/flights/route-analytics';
283
+ };
284
+ export type GetRouteAnalyticsErrors = {
285
+ /**
286
+ * Missing or invalid API key.
287
+ */
288
+ 401: ErrorResponse;
289
+ /**
290
+ * The key lacks the required scope, or the plan does not cover this endpoint.
291
+ * Use `error` to distinguish: `forbidden` indicates key scope, `plan_required`
292
+ * indicates billing.
293
+ */
294
+ 403: ErrorResponse;
295
+ };
296
+ export type GetRouteAnalyticsError = GetRouteAnalyticsErrors[keyof GetRouteAnalyticsErrors];
297
+ export type GetRouteAnalyticsResponses = {
298
+ /**
299
+ * Route performance.
300
+ */
301
+ 200: RouteAnalyticsResponse;
302
+ };
303
+ export type GetRouteAnalyticsResponse = GetRouteAnalyticsResponses[keyof GetRouteAnalyticsResponses];
304
+ export type SearchFlightsData = {
305
+ body?: never;
306
+ path?: never;
307
+ query: {
308
+ /**
309
+ * Flight number, route as ORIGIN-DESTINATION, or a date.
310
+ */
311
+ q: string;
312
+ limit?: number;
313
+ };
314
+ url: '/api/v1/flights/search';
315
+ };
316
+ export type SearchFlightsErrors = {
317
+ /**
318
+ * Missing or invalid API key.
319
+ */
320
+ 401: ErrorResponse;
321
+ };
322
+ export type SearchFlightsError = SearchFlightsErrors[keyof SearchFlightsErrors];
323
+ export type SearchFlightsResponses = {
324
+ /**
325
+ * Matching flights.
326
+ */
327
+ 200: FlightListResponse;
328
+ };
329
+ export type SearchFlightsResponse = SearchFlightsResponses[keyof SearchFlightsResponses];
330
+ export type RefreshFlightsData = {
331
+ body?: never;
332
+ path?: never;
333
+ query?: never;
334
+ url: '/api/v1/flights/refresh';
335
+ };
336
+ export type RefreshFlightsErrors = {
337
+ /**
338
+ * Missing or invalid API key.
339
+ */
340
+ 401: ErrorResponse;
341
+ /**
342
+ * The key lacks the required scope, or the plan does not cover this endpoint.
343
+ * Use `error` to distinguish: `forbidden` indicates key scope, `plan_required`
344
+ * indicates billing.
345
+ */
346
+ 403: ErrorResponse;
347
+ /**
348
+ * Too many requests.
349
+ */
350
+ 429: ErrorResponse;
351
+ };
352
+ export type RefreshFlightsError = RefreshFlightsErrors[keyof RefreshFlightsErrors];
353
+ export type RefreshFlightsResponses = {
354
+ /**
355
+ * Refresh completed.
356
+ */
357
+ 200: RefreshResponse;
358
+ };
359
+ export type RefreshFlightsResponse = RefreshFlightsResponses[keyof RefreshFlightsResponses];
360
+ export type GetAirportOverviewData = {
361
+ body?: never;
362
+ path: {
363
+ /**
364
+ * IATA code, three letters. Case insensitive.
365
+ */
366
+ airport_code: string;
367
+ };
368
+ query?: never;
369
+ url: '/api/airport/{airport_code}/overview';
370
+ };
371
+ export type GetAirportOverviewErrors = {
372
+ /**
373
+ * Missing or invalid API key.
374
+ */
375
+ 401: ErrorResponse;
376
+ };
377
+ export type GetAirportOverviewError = GetAirportOverviewErrors[keyof GetAirportOverviewErrors];
378
+ export type GetAirportOverviewResponses = {
379
+ /**
380
+ * Overview for the station.
381
+ */
382
+ 200: AirportOverviewResponse;
383
+ };
384
+ export type GetAirportOverviewResponse = GetAirportOverviewResponses[keyof GetAirportOverviewResponses];
385
+ export type GetAirportHeatmapData = {
386
+ body?: never;
387
+ path: {
388
+ /**
389
+ * IATA code, three letters. Case insensitive.
390
+ */
391
+ airport_code: string;
392
+ };
393
+ query?: never;
394
+ url: '/api/airport/{airport_code}/heatmap';
395
+ };
396
+ export type GetAirportHeatmapErrors = {
397
+ /**
398
+ * Missing or invalid API key.
399
+ */
400
+ 401: ErrorResponse;
401
+ /**
402
+ * The key lacks the required scope, or the plan does not cover this endpoint.
403
+ * Use `error` to distinguish: `forbidden` indicates key scope, `plan_required`
404
+ * indicates billing.
405
+ */
406
+ 403: ErrorResponse;
407
+ };
408
+ export type GetAirportHeatmapError = GetAirportHeatmapErrors[keyof GetAirportHeatmapErrors];
409
+ export type GetAirportHeatmapResponses = {
410
+ /**
411
+ * Heatmap points.
412
+ */
413
+ 200: HeatmapResponse;
414
+ };
415
+ export type GetAirportHeatmapResponse = GetAirportHeatmapResponses[keyof GetAirportHeatmapResponses];
416
+ export type GetAirportCongestionData = {
417
+ body?: never;
418
+ path: {
419
+ /**
420
+ * IATA code, three letters. Case insensitive.
421
+ */
422
+ airport_code: string;
423
+ };
424
+ query?: {
425
+ hours?: number;
426
+ };
427
+ url: '/api/airport/{airport_code}/congestion';
428
+ };
429
+ export type GetAirportCongestionErrors = {
430
+ /**
431
+ * Missing or invalid API key.
432
+ */
433
+ 401: ErrorResponse;
434
+ /**
435
+ * The key lacks the required scope, or the plan does not cover this endpoint.
436
+ * Use `error` to distinguish: `forbidden` indicates key scope, `plan_required`
437
+ * indicates billing.
438
+ */
439
+ 403: ErrorResponse;
440
+ };
441
+ export type GetAirportCongestionError = GetAirportCongestionErrors[keyof GetAirportCongestionErrors];
442
+ export type GetAirportCongestionResponses = {
443
+ /**
444
+ * Congestion readings and forecast.
445
+ */
446
+ 200: CongestionResponse;
447
+ };
448
+ export type GetAirportCongestionResponse = GetAirportCongestionResponses[keyof GetAirportCongestionResponses];
449
+ export type ClientOptions = {
450
+ baseUrl: 'https://www.s-system.cloud' | (string & {});
451
+ };
@@ -0,0 +1,2 @@
1
+ // This file is auto-generated by @hey-api/openapi-ts
2
+ export {};
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@kquika-inc/s-system",
3
+ "version": "1.0.7",
4
+ "description": "Predict flight disruption, price the passenger-rights exposure it carries, and rebook before it costs you.",
5
+ "author": { "name": "Kquika, Inc.", "email": "support@kquika.com" },
6
+ "homepage": "https://www.s-system.cloud/document",
7
+ "keywords": ["s-system", "airline-operations", "aviation", "passenger-management", "disruption-prediction", "api-client", "passenger-rights", "rebooking", "ancillary-pricing", "airport-operations"],
8
+ "type": "module",
9
+ "main": "dist/index.js",
10
+ "types": "dist/index.d.ts",
11
+ "files": ["dist"],
12
+ "scripts": {
13
+ "build": "tsc",
14
+ "prepublishOnly": "npm run build"
15
+ },
16
+ "dependencies": {
17
+ "@hey-api/client-fetch": "^0.10.0"
18
+ },
19
+ "devDependencies": {
20
+ "typescript": "^5.7.0"
21
+ },
22
+ "license": "MIT",
23
+ "publishConfig": { "access": "public" }
24
+ }