diff --git a/packages/importers/src/providers/statuspage/api-types.ts b/packages/importers/src/providers/statuspage/api-types.ts index 64de54bc..eb512034 100644 --- a/packages/importers/src/providers/statuspage/api-types.ts +++ b/packages/importers/src/providers/statuspage/api-types.ts @@ -5,10 +5,10 @@ import { lenientEnum } from "../../schemas"; export const StatuspageComponentSchema = z.object({ id: z.string(), page_id: z.string(), - group_id: z.string().nullable(), + group_id: z.string().nullish(), name: z.string(), - description: z.string().nullable(), - position: z.number(), + description: z.string().nullish(), + position: z.number().nullish(), status: lenientEnum([ "operational", "degraded_performance", @@ -18,10 +18,10 @@ export const StatuspageComponentSchema = z.object({ // the spec allows an empty status "", ]), - showcase: z.boolean(), - only_show_if_degraded: z.boolean(), - group: z.boolean(), - start_date: z.string().nullable(), + showcase: z.boolean().nullish(), + only_show_if_degraded: z.boolean().nullish(), + group: z.boolean().nullish(), + start_date: z.string().nullish(), created_at: z.string(), updated_at: z.string(), }); @@ -32,9 +32,9 @@ export const StatuspageGroupComponentSchema = z.object({ id: z.string(), page_id: z.string(), name: z.string(), - description: z.string().nullable(), - components: z.array(z.string()), - position: z.number(), + description: z.string().nullish(), + components: z.array(z.string()).nullish(), + position: z.number().nullish(), created_at: z.string(), updated_at: z.string(), }); @@ -60,9 +60,9 @@ export const StatuspageIncidentUpdateSchema = z.object({ id: z.string(), incident_id: z.string(), status: StatuspageIncidentStatusSchema, - body: z.string().nullable(), - display_at: z.string().nullable(), - deliver_notifications: z.boolean(), + body: z.string().nullish(), + display_at: z.string().nullish(), + deliver_notifications: z.boolean().nullish(), affected_components: z .array( z.object({ @@ -72,7 +72,7 @@ export const StatuspageIncidentUpdateSchema = z.object({ new_status: z.string(), }), ) - .nullable(), + .nullish(), created_at: z.string(), updated_at: z.string(), }); @@ -92,18 +92,18 @@ export const StatuspageIncidentSchema = z.object({ "minor", "major", "critical", - ]).nullable(), - shortlink: z.string().nullable(), - scheduled_for: z.string().nullable(), - scheduled_until: z.string().nullable(), - resolved_at: z.string().nullable(), - monitoring_at: z.string().nullable(), + ]).nullish(), + shortlink: z.string().nullish(), + scheduled_for: z.string().nullish(), + scheduled_until: z.string().nullish(), + resolved_at: z.string().nullish(), + monitoring_at: z.string().nullish(), created_at: z.string(), updated_at: z.string(), incident_updates: z.array(StatuspageIncidentUpdateSchema).optional(), components: z.array(StatuspageComponentSchema).optional(), - postmortem_body: z.string().nullable(), - metadata: z.unknown().nullable(), + postmortem_body: z.string().nullish(), + metadata: z.unknown().nullish(), }); export type StatuspageIncident = z.infer; @@ -119,15 +119,15 @@ export const StatuspageSubscriberSchema = z.object({ "teams", "integration_partner", ]), - email: z.string().nullable(), - endpoint: z.string().nullable(), - phone_number: z.string().nullable(), - phone_country: z.string().nullable(), - display_phone_number: z.string().nullable(), - obfuscated_channel_name: z.string().nullable(), - workspace_name: z.string().nullable(), - components: z.array(z.string()).nullable(), - quarantined_at: z.string().nullable(), + email: z.string().nullish(), + endpoint: z.string().nullish(), + phone_number: z.string().nullish(), + phone_country: z.string().nullish(), + display_phone_number: z.string().nullish(), + obfuscated_channel_name: z.string().nullish(), + workspace_name: z.string().nullish(), + components: z.array(z.string()).nullish(), + quarantined_at: z.string().nullish(), created_at: z.string(), }); @@ -136,16 +136,16 @@ export type StatuspageSubscriber = z.infer; export const StatuspagePageSchema = z.object({ id: z.string(), name: z.string(), - page_description: z.string().nullable(), + page_description: z.string().nullish(), subdomain: z.string(), - domain: z.string().nullable(), - url: z.string().nullable(), - support_url: z.string().nullable(), - time_zone: z.string().nullable(), - allow_page_subscribers: z.boolean(), - allow_email_subscribers: z.boolean(), - allow_sms_subscribers: z.boolean(), - allow_webhook_subscribers: z.boolean(), + domain: z.string().nullish(), + url: z.string().nullish(), + support_url: z.string().nullish(), + time_zone: z.string().nullish(), + allow_page_subscribers: z.boolean().nullish(), + allow_email_subscribers: z.boolean().nullish(), + allow_sms_subscribers: z.boolean().nullish(), + allow_webhook_subscribers: z.boolean().nullish(), created_at: z.string(), updated_at: z.string(), }); diff --git a/packages/importers/src/providers/statuspage/client.test.ts b/packages/importers/src/providers/statuspage/client.test.ts index 26f98e4a..b86af6dc 100644 --- a/packages/importers/src/providers/statuspage/client.test.ts +++ b/packages/importers/src/providers/statuspage/client.test.ts @@ -145,6 +145,35 @@ describe("StatuspageClient", () => { expect(subscribers[0].mode).toBe("teams"); }); + test("getSubscribers accepts subscribers with omitted optional fields", async () => { + const { + phone_number, + phone_country, + display_phone_number, + obfuscated_channel_name, + workspace_name, + components, + quarantined_at, + ...subscriber + } = MOCK_SUBSCRIBERS[0]; + mockFetchPaginated([subscriber]); + const subscribers = await client.getSubscribers("sp_page_001"); + expect(subscribers[0].email).toBe(MOCK_SUBSCRIBERS[0].email); + expect(subscribers[0].workspace_name).toBeUndefined(); + }); + + test("getIncidents accepts incidents with omitted optional fields", async () => { + const [incident] = MOCK_INCIDENTS; + const { metadata, postmortem_body, shortlink, ...rest } = incident; + const updates = (incident.incident_updates ?? []).map( + ({ affected_components, display_at, deliver_notifications, ...u }) => u, + ); + mockFetchPaginated([{ ...rest, incident_updates: updates }]); + const incidents = await client.getIncidents("sp_page_001"); + expect(incidents[0].postmortem_body).toBeUndefined(); + expect(incidents[0].incident_updates?.[0].affected_components).toBeUndefined(); + }); + test("getSubscribers returns parsed subscribers", async () => { mockFetchPaginated(MOCK_SUBSCRIBERS); const subscribers = await client.getSubscribers("sp_page_001"); diff --git a/packages/importers/src/providers/statuspage/provider.ts b/packages/importers/src/providers/statuspage/provider.ts index 7e337e54..e0be0ab3 100644 --- a/packages/importers/src/providers/statuspage/provider.ts +++ b/packages/importers/src/providers/statuspage/provider.ts @@ -94,7 +94,7 @@ export function createStatuspageProvider(): ImportProvider