@guinetik/primitives-ts 0.15.0 → 0.16.0
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/home-dashboard.types.d.ts +10 -2
- package/dist/home-dashboard.types.d.ts.map +1 -1
- package/dist/home-dashboard.types.js +14 -0
- package/dist/home-dashboard.types.spec.js +8 -0
- package/dist/widget-services.types.d.ts +69 -1
- package/dist/widget-services.types.d.ts.map +1 -1
- package/dist/widget-services.types.js +31 -0
- package/dist/widget-services.types.spec.js +20 -0
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { GeoLocation } from "./geo.types";
|
|
2
|
-
export type HomeWidgetType = "launchpad" | "clock" | "webpage" | "analytics" | "utility" | "news" | "weather" | "currency" | "crypto" | "apod";
|
|
2
|
+
export type HomeWidgetType = "launchpad" | "clock" | "webpage" | "analytics" | "utility" | "news" | "weather" | "currency" | "crypto" | "apod" | "flight";
|
|
3
3
|
export type HomeWidgetColSpan = 1 | 2 | 3;
|
|
4
4
|
export interface LaunchpadWidgetConfig {
|
|
5
5
|
/** Launchpad group ids to show. Omitted on legacy widgets means all groups. */
|
|
@@ -64,7 +64,15 @@ export interface ApodWidgetConfig {
|
|
|
64
64
|
/** Enabled NASA provider to use. Omitted means the NASA category default. */
|
|
65
65
|
providerId?: string;
|
|
66
66
|
}
|
|
67
|
-
|
|
67
|
+
/**
|
|
68
|
+
* Flight numbers are ephemeral, so the persisted config carries only the
|
|
69
|
+
* provider choice; the tracked number lives in the viewer's browser.
|
|
70
|
+
*/
|
|
71
|
+
export interface FlightWidgetConfig {
|
|
72
|
+
/** Enabled flight provider to use. Omitted means the category default. */
|
|
73
|
+
providerId?: string;
|
|
74
|
+
}
|
|
75
|
+
export type HomeWidgetConfig = LaunchpadWidgetConfig | ClockWidgetConfig | WebpageWidgetConfig | AnalyticsWidgetConfig | UtilityWidgetConfig | NewsWidgetConfig | WeatherWidgetConfig | CurrencyWidgetConfig | CryptoWidgetConfig | ApodWidgetConfig | FlightWidgetConfig;
|
|
68
76
|
export interface HomeDashboardWidget {
|
|
69
77
|
id: string;
|
|
70
78
|
/** Optional user-defined chrome title. The widget type is used when omitted. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"home-dashboard.types.d.ts","sourceRoot":"","sources":["../src/home-dashboard.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,MAAM,cAAc,GACtB,WAAW,GACX,OAAO,GACP,SAAS,GACT,WAAW,GACX,SAAS,GACT,MAAM,GACN,SAAS,GACT,UAAU,GACV,QAAQ,GACR,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"home-dashboard.types.d.ts","sourceRoot":"","sources":["../src/home-dashboard.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,6 +20,7 @@ exports.HOME_WIDGET_TYPES = [
|
|
|
20
20
|
"currency",
|
|
21
21
|
"crypto",
|
|
22
22
|
"apod",
|
|
23
|
+
"flight",
|
|
23
24
|
];
|
|
24
25
|
exports.MAX_HOME_WIDGETS = 30;
|
|
25
26
|
exports.CLOCK_DEFAULT_TIMEZONE = "America/Sao_Paulo";
|
|
@@ -220,6 +221,19 @@ const HOME_WIDGET_CONFIG_VALIDATORS = {
|
|
|
220
221
|
? "apod widget config contains an unsupported setting"
|
|
221
222
|
: null;
|
|
222
223
|
},
|
|
224
|
+
flight(config) {
|
|
225
|
+
const value = configRecord(config);
|
|
226
|
+
if (!value)
|
|
227
|
+
return "flight widget config must be an object";
|
|
228
|
+
const providerError = providerIdError(value);
|
|
229
|
+
if (providerError)
|
|
230
|
+
return providerError;
|
|
231
|
+
// Flight numbers are deliberately not persisted; reject them so a board
|
|
232
|
+
// written directly through the API cannot smuggle one in.
|
|
233
|
+
return Object.keys(value).some((key) => key !== "providerId")
|
|
234
|
+
? "flight widget config contains an unsupported setting"
|
|
235
|
+
: null;
|
|
236
|
+
},
|
|
223
237
|
};
|
|
224
238
|
function validateHomeWidgetConfig(type, config) {
|
|
225
239
|
return HOME_WIDGET_CONFIG_VALIDATORS[type](config);
|
|
@@ -18,6 +18,7 @@ describe("home dashboard types", () => {
|
|
|
18
18
|
"currency",
|
|
19
19
|
"crypto",
|
|
20
20
|
"apod",
|
|
21
|
+
"flight",
|
|
21
22
|
]);
|
|
22
23
|
expect((0, home_dashboard_types_1.isHomeWidgetType)("clock")).toBe(true);
|
|
23
24
|
expect((0, home_dashboard_types_1.isHomeWidgetType)("analytics")).toBe(true);
|
|
@@ -26,6 +27,13 @@ describe("home dashboard types", () => {
|
|
|
26
27
|
expect((0, home_dashboard_types_1.isHomeWidgetType)("apod")).toBe(true);
|
|
27
28
|
expect((0, home_dashboard_types_1.isHomeWidgetType)("stock-ticker")).toBe(false);
|
|
28
29
|
});
|
|
30
|
+
it("validates flight widget configs as provider-only", () => {
|
|
31
|
+
expect((0, home_dashboard_types_1.validateHomeWidgetConfig)("flight", {})).toBeNull();
|
|
32
|
+
expect((0, home_dashboard_types_1.validateHomeWidgetConfig)("flight", { providerId: "fa-1" })).toBeNull();
|
|
33
|
+
expect((0, home_dashboard_types_1.validateHomeWidgetConfig)("flight", { providerId: "" })).not.toBeNull();
|
|
34
|
+
expect((0, home_dashboard_types_1.validateHomeWidgetConfig)("flight", null)).not.toBeNull();
|
|
35
|
+
expect((0, home_dashboard_types_1.validateHomeWidgetConfig)("flight", { flightNumber: "LA8084" })).not.toBeNull();
|
|
36
|
+
});
|
|
29
37
|
it("validates the APOD provider selection", () => {
|
|
30
38
|
expect((0, home_dashboard_types_1.validateHomeWidgetConfig)("apod", {})).toBeNull();
|
|
31
39
|
expect((0, home_dashboard_types_1.validateHomeWidgetConfig)("apod", { providerId: "nasa-1" })).toBeNull();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Shared contracts for provider-backed dashboard widgets. */
|
|
2
|
-
export type WidgetServiceKind = "news" | "weather" | "currency" | "geo" | "crypto" | "nasa";
|
|
2
|
+
export type WidgetServiceKind = "news" | "weather" | "currency" | "geo" | "crypto" | "nasa" | "flight";
|
|
3
3
|
export type WidgetServiceSettingValue = string | number | boolean;
|
|
4
4
|
export type WidgetServiceSettings = Record<string, WidgetServiceSettingValue>;
|
|
5
5
|
export interface WidgetServiceProviderSettingsMap {
|
|
@@ -17,6 +17,10 @@ export interface WidgetServiceProviderSettingsMap {
|
|
|
17
17
|
nasa: {
|
|
18
18
|
apiKey?: string;
|
|
19
19
|
};
|
|
20
|
+
flightaware: {
|
|
21
|
+
apiKey: string;
|
|
22
|
+
};
|
|
23
|
+
adsb: Record<string, never>;
|
|
20
24
|
}
|
|
21
25
|
export type WidgetServiceProviderType = keyof WidgetServiceProviderSettingsMap;
|
|
22
26
|
export interface WidgetServiceSettingsField {
|
|
@@ -49,6 +53,9 @@ declare function normalizeCoingeckoSettings(settings: WidgetServiceSettings): {
|
|
|
49
53
|
declare function normalizeOptionalApiKey(settings: WidgetServiceSettings): {
|
|
50
54
|
apiKey?: string;
|
|
51
55
|
};
|
|
56
|
+
declare function normalizeFlightAwareSettings(settings: WidgetServiceSettings): {
|
|
57
|
+
apiKey: string;
|
|
58
|
+
};
|
|
52
59
|
/** Single registration point for provider metadata and per-type settings schemas. */
|
|
53
60
|
export declare const WIDGET_SERVICE_PROVIDER_DEFINITIONS: {
|
|
54
61
|
rss: {
|
|
@@ -124,6 +131,28 @@ export declare const WIDGET_SERVICE_PROVIDER_DEFINITIONS: {
|
|
|
124
131
|
secretSettingKeys: "apiKey"[];
|
|
125
132
|
normalizeSettings: typeof normalizeOptionalApiKey;
|
|
126
133
|
};
|
|
134
|
+
flightaware: {
|
|
135
|
+
type: "flightaware";
|
|
136
|
+
kind: "flight";
|
|
137
|
+
label: string;
|
|
138
|
+
settingsFields: {
|
|
139
|
+
key: string;
|
|
140
|
+
label: string;
|
|
141
|
+
input: "password";
|
|
142
|
+
required: true;
|
|
143
|
+
maxLength: number;
|
|
144
|
+
}[];
|
|
145
|
+
secretSettingKeys: "apiKey"[];
|
|
146
|
+
normalizeSettings: typeof normalizeFlightAwareSettings;
|
|
147
|
+
};
|
|
148
|
+
adsb: {
|
|
149
|
+
type: "adsb";
|
|
150
|
+
kind: "flight";
|
|
151
|
+
label: string;
|
|
152
|
+
settingsFields: never[];
|
|
153
|
+
secretSettingKeys: never[];
|
|
154
|
+
normalizeSettings: typeof noSettings;
|
|
155
|
+
};
|
|
127
156
|
};
|
|
128
157
|
export declare const WIDGET_SERVICE_PROVIDER_TYPES: readonly (keyof WidgetServiceProviderSettingsMap)[];
|
|
129
158
|
export declare function normalizeWidgetServiceProviderSettings<T extends WidgetServiceProviderType>(type: T, settings: WidgetServiceSettings): WidgetServiceProviderSettingsMap[T];
|
|
@@ -201,6 +230,45 @@ export interface CryptoBoard {
|
|
|
201
230
|
quotes: CryptoQuote[];
|
|
202
231
|
fetchedAt: string;
|
|
203
232
|
}
|
|
233
|
+
export type FlightPhase = "scheduled" | "active" | "landed" | "cancelled" | "diverted" | "unknown";
|
|
234
|
+
export interface FlightAirport {
|
|
235
|
+
/** IATA or ICAO code as the provider reports it, e.g. "GRU". */
|
|
236
|
+
code: string;
|
|
237
|
+
name?: string;
|
|
238
|
+
city?: string;
|
|
239
|
+
}
|
|
240
|
+
export interface FlightPosition {
|
|
241
|
+
lat: number;
|
|
242
|
+
lon: number;
|
|
243
|
+
altitudeM?: number;
|
|
244
|
+
groundSpeedKph?: number;
|
|
245
|
+
headingDegrees?: number;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Normalized flight lookup result. Providers fill what they know: a
|
|
249
|
+
* schedule-aware provider fills times and phase; a live ADS-B provider fills
|
|
250
|
+
* callsign and position only, with phase "active" while broadcasting.
|
|
251
|
+
*/
|
|
252
|
+
export interface FlightStatus {
|
|
253
|
+
/** Flight number or callsign as queried, e.g. "LA8084". */
|
|
254
|
+
ident: string;
|
|
255
|
+
callsign?: string;
|
|
256
|
+
phase: FlightPhase;
|
|
257
|
+
origin?: FlightAirport;
|
|
258
|
+
destination?: FlightAirport;
|
|
259
|
+
scheduledDeparture?: string;
|
|
260
|
+
actualDeparture?: string;
|
|
261
|
+
scheduledArrival?: string;
|
|
262
|
+
estimatedArrival?: string;
|
|
263
|
+
actualArrival?: string;
|
|
264
|
+
/** Positive means late, negative early, in minutes. */
|
|
265
|
+
arrivalDelayMinutes?: number;
|
|
266
|
+
/** 0-100 while en route, when the provider reports it. */
|
|
267
|
+
progressPercent?: number;
|
|
268
|
+
position?: FlightPosition;
|
|
269
|
+
aircraftType?: string;
|
|
270
|
+
fetchedAt: string;
|
|
271
|
+
}
|
|
204
272
|
export interface AstronomyPictureOfTheDay {
|
|
205
273
|
date: string;
|
|
206
274
|
title: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"widget-services.types.d.ts","sourceRoot":"","sources":["../src/widget-services.types.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,MAAM,MAAM,iBAAiB,GACzB,MAAM,GACN,SAAS,GACT,UAAU,GACV,KAAK,GACL,QAAQ,GACR,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"widget-services.types.d.ts","sourceRoot":"","sources":["../src/widget-services.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -47,6 +47,13 @@ function normalizeOptionalApiKey(settings) {
|
|
|
47
47
|
const apiKey = typeof settings.apiKey === "string" ? settings.apiKey.trim() : "";
|
|
48
48
|
return apiKey && apiKey !== exports.WIDGET_SERVICE_SECRET_MASK ? { apiKey } : {};
|
|
49
49
|
}
|
|
50
|
+
function normalizeFlightAwareSettings(settings) {
|
|
51
|
+
const apiKey = typeof settings.apiKey === "string" ? settings.apiKey.trim() : "";
|
|
52
|
+
if (!apiKey || apiKey === exports.WIDGET_SERVICE_SECRET_MASK) {
|
|
53
|
+
throw new Error("FlightAware API key is required");
|
|
54
|
+
}
|
|
55
|
+
return { apiKey };
|
|
56
|
+
}
|
|
50
57
|
/** Single registration point for provider metadata and per-type settings schemas. */
|
|
51
58
|
exports.WIDGET_SERVICE_PROVIDER_DEFINITIONS = {
|
|
52
59
|
rss: {
|
|
@@ -130,6 +137,30 @@ exports.WIDGET_SERVICE_PROVIDER_DEFINITIONS = {
|
|
|
130
137
|
secretSettingKeys: ["apiKey"],
|
|
131
138
|
normalizeSettings: normalizeOptionalApiKey,
|
|
132
139
|
},
|
|
140
|
+
flightaware: {
|
|
141
|
+
type: "flightaware",
|
|
142
|
+
kind: "flight",
|
|
143
|
+
label: "FlightAware AeroAPI",
|
|
144
|
+
settingsFields: [
|
|
145
|
+
{
|
|
146
|
+
key: "apiKey",
|
|
147
|
+
label: "API key",
|
|
148
|
+
input: "password",
|
|
149
|
+
required: true,
|
|
150
|
+
maxLength: 512,
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
secretSettingKeys: ["apiKey"],
|
|
154
|
+
normalizeSettings: normalizeFlightAwareSettings,
|
|
155
|
+
},
|
|
156
|
+
adsb: {
|
|
157
|
+
type: "adsb",
|
|
158
|
+
kind: "flight",
|
|
159
|
+
label: "ADS-B (adsb.lol)",
|
|
160
|
+
settingsFields: [],
|
|
161
|
+
secretSettingKeys: [],
|
|
162
|
+
normalizeSettings: noSettings,
|
|
163
|
+
},
|
|
133
164
|
};
|
|
134
165
|
exports.WIDGET_SERVICE_PROVIDER_TYPES = Object.freeze(Object.keys(exports.WIDGET_SERVICE_PROVIDER_DEFINITIONS));
|
|
135
166
|
function normalizeWidgetServiceProviderSettings(type, settings) {
|
|
@@ -31,6 +31,8 @@ describe("widget service provider definitions", () => {
|
|
|
31
31
|
"google-places",
|
|
32
32
|
"coingecko",
|
|
33
33
|
"nasa",
|
|
34
|
+
"flightaware",
|
|
35
|
+
"adsb",
|
|
34
36
|
]);
|
|
35
37
|
expect(widget_services_types_1.WIDGET_SERVICE_PROVIDER_DEFINITIONS["google-places"]).toMatchObject({
|
|
36
38
|
kind: "geo",
|
|
@@ -44,6 +46,24 @@ describe("widget service provider definitions", () => {
|
|
|
44
46
|
kind: "nasa",
|
|
45
47
|
secretSettingKeys: ["apiKey"],
|
|
46
48
|
});
|
|
49
|
+
expect(widget_services_types_1.WIDGET_SERVICE_PROVIDER_DEFINITIONS.flightaware).toMatchObject({
|
|
50
|
+
kind: "flight",
|
|
51
|
+
secretSettingKeys: ["apiKey"],
|
|
52
|
+
});
|
|
53
|
+
expect(widget_services_types_1.WIDGET_SERVICE_PROVIDER_DEFINITIONS.adsb).toMatchObject({
|
|
54
|
+
kind: "flight",
|
|
55
|
+
secretSettingKeys: [],
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
it("requires the FlightAware API key but keeps adsb keyless", () => {
|
|
59
|
+
expect((0, widget_services_types_1.normalizeWidgetServiceProviderSettings)("flightaware", {
|
|
60
|
+
apiKey: " fa-key ",
|
|
61
|
+
})).toEqual({ apiKey: "fa-key" });
|
|
62
|
+
expect(() => (0, widget_services_types_1.normalizeWidgetServiceProviderSettings)("flightaware", { apiKey: "" })).toThrow("FlightAware API key is required");
|
|
63
|
+
expect(() => (0, widget_services_types_1.normalizeWidgetServiceProviderSettings)("flightaware", {
|
|
64
|
+
apiKey: widget_services_types_1.WIDGET_SERVICE_SECRET_MASK,
|
|
65
|
+
})).toThrow("FlightAware API key is required");
|
|
66
|
+
expect((0, widget_services_types_1.normalizeWidgetServiceProviderSettings)("adsb", { ignored: true })).toEqual({});
|
|
47
67
|
});
|
|
48
68
|
it("keeps the CoinGecko API key optional", () => {
|
|
49
69
|
expect((0, widget_services_types_1.normalizeWidgetServiceProviderSettings)("coingecko", { apiKey: " k-1 " })).toEqual({ apiKey: "k-1" });
|