diff --git a/docs/openapi/monitoring-api.json b/docs/openapi/monitoring-api.json index 3dea12c..d3dfb3f 100644 --- a/docs/openapi/monitoring-api.json +++ b/docs/openapi/monitoring-api.json @@ -4215,6 +4215,48 @@ } } }, + "/api/v1/services/{slugOrId}/days/{date}": { + "get": { + "tags": [ + "Status Data" + ], + "summary": "One-day rollup for a service: aggregated uptime, per-component impacts, and overlapping incidents", + "description": "Powers the click/hover-to-expand panel under each uptime bar on the public status page. Single round-trip — components, sums, and overlapping incidents (with affected component names) are returned in one response.", + "operationId": "getServiceDayDetail", + "parameters": [ + { + "name": "slugOrId", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "date", + "in": "path", + "description": "UTC calendar day in ISO format (YYYY-MM-DD)", + "required": true, + "schema": { + "type": "string", + "format": "date" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseServiceDayDetailDto" + } + } + } + } + } + } + }, "/api/v1/services/{slugOrId}/incidents": { "get": { "tags": [ @@ -6512,11 +6554,13 @@ "properties": { "body": { "type": "string", - "description": "Update message or post-mortem notes" + "description": "Update message or post-mortem notes", + "nullable": true }, "newStatus": { "type": "string", "description": "Updated incident status; null to keep current status", + "nullable": true, "enum": [ "WATCHING", "TRIGGERED", @@ -6530,8 +6574,6 @@ } }, "required": [ - "body", - "newStatus", "notifySubscribers" ] }, @@ -6730,6 +6772,16 @@ "description": "Alert channel with non-sensitive configuration metadata" }, "AlertDeliveryDto": { + "required": [ + "channel", + "channelId", + "channelType", + "createdAt", + "eventType", + "id", + "incidentId", + "status" + ], "type": "object", "properties": { "id": { @@ -6823,20 +6875,7 @@ "format": "date-time" } }, - "description": "Delivery record for a single channel within a notification dispatch", - "required": [ - "id", - "incidentId", - "channelId", - "channel", - "channelType", - "status", - "eventType", - "stepNumber", - "fireCount", - "attemptCount", - "createdAt" - ] + "description": "Delivery record for a single channel within a notification dispatch" }, "ApiKeyAuthConfig": { "required": [ @@ -6870,6 +6909,11 @@ ] }, "ApiKeyCreateResponse": { + "required": [ + "createdAt", + "key", + "name" + ], "type": "object", "properties": { "id": { @@ -6878,10 +6922,12 @@ "format": "int32" }, "name": { + "minLength": 1, "type": "string", "description": "Human-readable name for this API key" }, "key": { + "minLength": 1, "type": "string", "description": "Full API key value in dh_live_* format; store this now" }, @@ -6897,15 +6943,15 @@ "nullable": true } }, - "description": "Created API key with the full key value — store it now, it won't be shown again", - "required": [ - "id", - "name", - "key", - "createdAt" - ] + "description": "Created API key with the full key value — store it now, it won't be shown again" }, "ApiKeyDto": { + "required": [ + "createdAt", + "key", + "name", + "updatedAt" + ], "type": "object", "properties": { "id": { @@ -6914,10 +6960,12 @@ "format": "int32" }, "name": { + "minLength": 1, "type": "string", "description": "Human-readable name for this API key" }, "key": { + "minLength": 1, "type": "string", "description": "Full API key value in dh_live_* format" }, @@ -6950,14 +6998,7 @@ "nullable": true } }, - "description": "API key for programmatic access to the DevHelm API", - "required": [ - "id", - "name", - "key", - "createdAt", - "updatedAt" - ] + "description": "API key for programmatic access to the DevHelm API" }, "AssertionConfig": { "required": [ @@ -7019,6 +7060,10 @@ } }, "AssertionResultDto": { + "required": [ + "severity", + "type" + ], "type": "object", "properties": { "type": { @@ -7056,14 +7101,14 @@ "example": "503" } }, - "description": "Result of evaluating a single assertion against a check result", - "required": [ - "type", - "passed", - "severity" - ] + "description": "Result of evaluating a single assertion against a check result" }, "AssertionTestResultDto": { + "required": [ + "assertionType", + "message", + "severity" + ], "type": "object", "properties": { "assertionType": { @@ -7140,15 +7185,13 @@ "description": "Actual value observed during the test", "nullable": true } - }, - "required": [ - "assertionType", - "passed", - "severity", - "message" - ] + } }, "AuditEventDto": { + "required": [ + "action", + "createdAt" + ], "type": "object", "properties": { "id": { @@ -7201,14 +7244,15 @@ "description": "Timestamp when the action was performed", "format": "date-time" } - }, - "required": [ - "id", - "action", - "createdAt" - ] + } }, "AuthMeResponse": { + "required": [ + "key", + "organization", + "plan", + "rateLimits" + ], "type": "object", "properties": { "key": { @@ -7224,13 +7268,7 @@ "$ref": "#/components/schemas/RateLimitInfo" } }, - "description": "Identity, organization, plan, and rate-limit info for the authenticated API key", - "required": [ - "key", - "organization", - "plan", - "rateLimits" - ] + "description": "Identity, organization, plan, and rate-limit info for the authenticated API key" }, "BasicAuthConfig": { "type": "object", @@ -7345,6 +7383,10 @@ "description": "Request body for performing a bulk action on multiple monitors" }, "BulkMonitorActionResult": { + "required": [ + "failed", + "succeeded" + ], "type": "object", "properties": { "succeeded": { @@ -7364,13 +7406,12 @@ } } }, - "description": "Result of a bulk monitor action, including partial-success details", - "required": [ - "succeeded", - "failed" - ] + "description": "Result of a bulk monitor action, including partial-success details" }, "CategoryDto": { + "required": [ + "category" + ], "type": "object", "properties": { "category": { @@ -7383,11 +7424,7 @@ "format": "int64" } }, - "description": "Service category with its count of catalog entries", - "required": [ - "category", - "serviceCount" - ] + "description": "Service category with its count of catalog entries" }, "ChangeRoleRequest": { "required": [ @@ -7453,6 +7490,9 @@ } }, "ChartBucketDto": { + "required": [ + "bucket" + ], "type": "object", "properties": { "bucket": { @@ -7490,10 +7530,7 @@ "example": 480 } }, - "description": "Aggregated metrics for a time bucket", - "required": [ - "bucket" - ] + "description": "Aggregated metrics for a time bucket" }, "CheckResultDetailsDto": { "type": "object", @@ -7572,6 +7609,11 @@ "description": "Type-specific details captured during a check execution" }, "CheckResultDto": { + "required": [ + "id", + "region", + "timestamp" + ], "type": "object", "properties": { "id": { @@ -7626,13 +7668,7 @@ "nullable": true } }, - "description": "A single check result from a monitor run", - "required": [ - "id", - "timestamp", - "region", - "passed" - ] + "description": "A single check result from a monitor run" }, "CheckTypeDetailsDto": { "required": [ @@ -7649,6 +7685,45 @@ "propertyName": "check_type" } }, + "ComponentImpact": { + "required": [ + "componentId", + "componentName" + ], + "type": "object", + "properties": { + "componentId": { + "type": "string", + "description": "Status page component UUID", + "format": "uuid" + }, + "componentName": { + "type": "string", + "description": "Component display name" + }, + "groupName": { + "type": "string", + "description": "Parent group display name when the component belongs to a group", + "nullable": true + }, + "uptimePercentage": { + "type": "number", + "description": "Computed uptime % for this component on this day", + "format": "double" + }, + "partialOutageSeconds": { + "type": "integer", + "description": "Seconds of partial outage observed on this day", + "format": "int32" + }, + "majorOutageSeconds": { + "type": "integer", + "description": "Seconds of major outage observed on this day", + "format": "int32" + } + }, + "description": "One component's uptime contribution for the day" + }, "ComponentPosition": { "required": [ "componentId" @@ -7668,12 +7743,18 @@ "groupId": { "type": "string", "description": "Target group ID, null for ungrouped", - "format": "uuid" + "format": "uuid", + "nullable": true } }, "description": "A single component position" }, "ComponentStatusDto": { + "required": [ + "id", + "name", + "status" + ], "type": "object", "properties": { "id": { @@ -7689,14 +7770,12 @@ "description": "Current component status, e.g. operational, degraded_performance" } }, - "description": "Current status of each active component", - "required": [ - "id", - "name", - "status" - ] + "description": "Current status of each active component" }, "ComponentUptimeDayDto": { + "required": [ + "date" + ], "type": "object", "properties": { "date": { @@ -7728,15 +7807,12 @@ } } }, - "description": "Daily uptime data for a status page component", - "required": [ - "date", - "partialOutageSeconds", - "majorOutageSeconds", - "uptimePercentage" - ] + "description": "Daily uptime data for a status page component" }, "ComponentUptimeSummaryDto": { + "required": [ + "source" + ], "type": "object", "properties": { "day": { @@ -7766,10 +7842,7 @@ "example": "vendor_reported" } }, - "description": "Inline uptime percentages for 24h, 7d, 30d", - "required": [ - "source" - ] + "description": "Inline uptime percentages for 24h, 7d, 30d" }, "ConfirmationPolicy": { "required": [ @@ -7859,7 +7932,8 @@ }, "CreateAssertionRequest": { "required": [ - "config" + "config", + "severity" ], "type": "object", "properties": { @@ -8075,7 +8149,8 @@ "monitorId": { "type": "string", "description": "Monitor to attach this maintenance window to; null for org-wide", - "format": "uuid" + "format": "uuid", + "nullable": true }, "startsAt": { "type": "string", @@ -8091,15 +8166,18 @@ "maxLength": 100, "minLength": 0, "type": "string", - "description": "iCal RRULE for recurring windows (max 100 chars); null for one-time" + "description": "iCal RRULE for recurring windows (max 100 chars); null for one-time", + "nullable": true }, "reason": { "type": "string", - "description": "Human-readable reason for the maintenance" + "description": "Human-readable reason for the maintenance", + "nullable": true }, "suppressAlerts": { "type": "boolean", - "description": "Whether to suppress alerts during this window (default: true)" + "description": "Whether to suppress alerts during this window (default: true)", + "nullable": true } } }, @@ -8188,8 +8266,9 @@ }, "frequencySeconds": { "type": "integer", - "description": "Check frequency in seconds (30–86400, default: 60)", - "format": "int32" + "description": "Check frequency in seconds (30–86400); null defaults to plan minimum (60s on most paid plans)", + "format": "int32", + "nullable": true }, "enabled": { "type": "boolean", @@ -8266,8 +8345,11 @@ }, "CreateNotificationPolicyRequest": { "required": [ + "enabled", "escalation", - "name" + "matchRules", + "name", + "priority" ], "type": "object", "properties": { @@ -8745,7 +8827,8 @@ "maxLength": 255, "minLength": 0, "type": "string", - "description": "Optional human-readable description" + "description": "Optional human-readable description", + "nullable": true }, "subscribedEvents": { "minItems": 1, @@ -8774,6 +8857,9 @@ "description": "Create a new workspace within the organization" }, "CursorPage": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -8794,13 +8880,12 @@ "description": "Whether more results exist beyond this page" } }, - "description": "Cursor-paginated response for time-series and append-only data", - "required": [ - "data", - "hasMore" - ] + "description": "Cursor-paginated response for time-series and append-only data" }, "CursorPageCheckResultDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -8820,13 +8905,12 @@ "description": "Whether more results exist beyond this page" } }, - "description": "Cursor-paginated response for time-series and append-only data", - "required": [ - "data", - "hasMore" - ] + "description": "Cursor-paginated response for time-series and append-only data" }, "CursorPageServiceCatalogDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -8846,13 +8930,12 @@ "description": "Whether more results exist beyond this page" } }, - "description": "Cursor-paginated response for time-series and append-only data", - "required": [ - "data", - "hasMore" - ] + "description": "Cursor-paginated response for time-series and append-only data" }, "CursorPageServicePollResultDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -8872,13 +8955,13 @@ "description": "Whether more results exist beyond this page" } }, - "description": "Cursor-paginated response for time-series and append-only data", - "required": [ - "data", - "hasMore" - ] + "description": "Cursor-paginated response for time-series and append-only data" }, "DashboardOverviewDto": { + "required": [ + "incidents", + "monitors" + ], "type": "object", "properties": { "monitors": { @@ -8888,17 +8971,82 @@ "$ref": "#/components/schemas/IncidentsSummaryDto" } }, - "description": "Combined dashboard overview for monitors and incidents", - "required": [ - "monitors", - "incidents" - ] + "description": "Combined dashboard overview for monitors and incidents" }, - "DekRotationResultDto": { - "type": "object", - "properties": { - "previousDekVersion": { - "type": "integer", + "DayIncident": { + "required": [ + "affectedComponentNames", + "id", + "impact", + "status", + "title" + ], + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Status page incident UUID", + "format": "uuid" + }, + "title": { + "type": "string", + "description": "Incident title" + }, + "status": { + "type": "string", + "description": "Lifecycle status (investigating, identified, monitoring, resolved, …)", + "enum": [ + "INVESTIGATING", + "IDENTIFIED", + "MONITORING", + "RESOLVED" + ] + }, + "impact": { + "type": "string", + "description": "Severity bucket (none, minor, major, critical)", + "enum": [ + "NONE", + "MINOR", + "MAJOR", + "CRITICAL" + ] + }, + "scheduled": { + "type": "boolean", + "description": "True for scheduled maintenances; false for unplanned incidents" + }, + "startedAt": { + "type": "string", + "description": "Incident start timestamp", + "format": "date-time", + "nullable": true + }, + "resolvedAt": { + "type": "string", + "description": "Incident resolved timestamp; null while still active", + "format": "date-time", + "nullable": true + }, + "affectedComponentNames": { + "type": "array", + "description": "Display names of components affected by this incident (deduplicated)", + "items": { + "type": "string", + "description": "Display names of components affected by this incident (deduplicated)" + } + } + }, + "description": "Incident that overlapped the day" + }, + "DekRotationResultDto": { + "required": [ + "rotatedAt" + ], + "type": "object", + "properties": { + "previousDekVersion": { + "type": "integer", "description": "DEK version before rotation", "format": "int32" }, @@ -8923,14 +9071,7 @@ "format": "date-time" } }, - "description": "Result of a data encryption key rotation operation", - "required": [ - "previousDekVersion", - "newDekVersion", - "secretsReEncrypted", - "channelsReEncrypted", - "rotatedAt" - ] + "description": "Result of a data encryption key rotation operation" }, "DeleteChannelResult": { "type": "object", @@ -8953,6 +9094,12 @@ ] }, "DeliveryAttemptDto": { + "required": [ + "attemptedAt", + "deliveryId", + "id", + "status" + ], "type": "object", "properties": { "id": { @@ -9019,16 +9166,15 @@ "format": "date-time" } }, - "description": "Single delivery attempt with request/response audit data", - "required": [ - "id", - "deliveryId", - "attemptNumber", - "status", - "attemptedAt" - ] + "description": "Single delivery attempt with request/response audit data" }, "DeployLockDto": { + "required": [ + "expiresAt", + "id", + "lockedAt", + "lockedBy" + ], "type": "object", "properties": { "id": { @@ -9037,6 +9183,7 @@ "format": "uuid" }, "lockedBy": { + "minLength": 1, "type": "string", "description": "Identity of the lock holder (e.g. CLI session ID, username)" }, @@ -9051,13 +9198,7 @@ "format": "date-time" } }, - "description": "Represents an active deploy lock for a workspace", - "required": [ - "id", - "lockedBy", - "lockedAt", - "expiresAt" - ] + "description": "Represents an active deploy lock for a workspace" }, "DiscordChannelConfig": { "required": [ @@ -9164,7 +9305,8 @@ } }, "required": [ - "recordType" + "recordType", + "max" ] } ] @@ -9193,7 +9335,8 @@ } }, "required": [ - "recordType" + "recordType", + "min" ] } ] @@ -9350,7 +9493,10 @@ "description": "Maximum allowed DNS resolution time in milliseconds", "format": "int32" } - } + }, + "required": [ + "maxMs" + ] } ] }, @@ -9368,7 +9514,10 @@ "description": "DNS resolution time in milliseconds that triggers a warning only", "format": "int32" } - } + }, + "required": [ + "warnMs" + ] } ] }, @@ -9386,7 +9535,10 @@ "description": "Maximum TTL in seconds before a high-TTL warning is raised", "format": "int32" } - } + }, + "required": [ + "maxTtl" + ] } ] }, @@ -9404,7 +9556,10 @@ "description": "Minimum acceptable TTL in seconds before a warning is raised", "format": "int32" } - } + }, + "required": [ + "minTtl" + ] } ] }, @@ -9462,6 +9617,9 @@ ] }, "EntitlementDto": { + "required": [ + "key" + ], "type": "object", "properties": { "key": { @@ -9483,15 +9641,17 @@ "description": "Whether this entitlement has an org-level override" } }, - "description": "A single resolved entitlement for the organization", - "required": [ - "key", - "value", - "defaultValue", - "overridden" - ] + "description": "A single resolved entitlement for the organization" }, "EnvironmentDto": { + "required": [ + "createdAt", + "id", + "name", + "slug", + "updatedAt", + "variables" + ], "type": "object", "properties": { "id": { @@ -9505,10 +9665,12 @@ "format": "int32" }, "name": { + "minLength": 1, "type": "string", "description": "Human-readable environment name" }, "slug": { + "minLength": 1, "type": "string", "description": "URL-safe identifier" }, @@ -9540,18 +9702,7 @@ "description": "Whether this is the default environment for new monitors" } }, - "description": "Environment with variable substitutions for monitor configs", - "required": [ - "id", - "orgId", - "name", - "slug", - "variables", - "createdAt", - "updatedAt", - "monitorCount", - "isDefault" - ] + "description": "Environment with variable substitutions for monitor configs" }, "EscalationChain": { "required": [ @@ -9618,6 +9769,10 @@ "description": "Ordered escalation steps, evaluated in sequence" }, "FailureDetail": { + "required": [ + "monitorId", + "reason" + ], "type": "object", "properties": { "monitorId": { @@ -9630,13 +9785,12 @@ "description": "Human-readable reason for the failure" } }, - "description": "Details about a single monitor that failed the bulk action", - "required": [ - "monitorId", - "reason" - ] + "description": "Details about a single monitor that failed the bulk action" }, "GlobalStatusSummaryDto": { + "required": [ + "servicesWithIssues" + ], "type": "object", "properties": { "totalServices": { @@ -9687,21 +9841,11 @@ } } }, - "description": "Global status summary across all subscribed vendor services", - "required": [ - "totalServices", - "operationalCount", - "degradedCount", - "partialOutageCount", - "majorOutageCount", - "maintenanceCount", - "unknownCount", - "activeIncidentCount", - "servicesWithIssues" - ] + "description": "Global status summary across all subscribed vendor services" }, "GroupComponentOrder": { "required": [ + "groupId", "positions" ], "type": "object", @@ -9791,8 +9935,8 @@ } }, "required": [ - "expected", "headerName", + "expected", "operator" ] } @@ -9978,8 +10122,8 @@ } }, "required": [ - "method", - "url" + "url", + "method" ] } ] @@ -10040,7 +10184,10 @@ "description": "Maximum allowed packet loss percentage before the check fails (0–100)", "format": "double" } - } + }, + "required": [ + "maxPercent" + ] } ] }, @@ -10066,7 +10213,10 @@ "description": "Maximum average ICMP round-trip time in milliseconds", "format": "int32" } - } + }, + "required": [ + "maxMs" + ] } ] }, @@ -10084,11 +10234,18 @@ "description": "ICMP round-trip time in milliseconds that triggers a warning only", "format": "int32" } - } + }, + "required": [ + "warnMs" + ] } ] }, "IncidentDetailDto": { + "required": [ + "incident", + "updates" + ], "type": "object", "properties": { "incident": { @@ -10107,13 +10264,18 @@ "$ref": "#/components/schemas/LinkedStatusPageIncidentDto" } } - }, - "required": [ - "incident", - "updates" - ] + } }, "IncidentDto": { + "required": [ + "affectedRegions", + "createdAt", + "id", + "severity", + "source", + "status", + "updatedAt" + ], "type": "object", "properties": { "id": { @@ -10302,25 +10464,14 @@ "nullable": true } }, - "description": "Incident triggered by a monitor check failure or manual creation", - "required": [ - "id", - "organizationId", - "source", - "status", - "severity", - "affectedRegions", - "reopenCount", - "statusPageVisible", - "createdAt", - "updatedAt" - ] + "description": "Incident triggered by a monitor check failure or manual creation" }, "IncidentFilterParams": { "type": "object", "properties": { "status": { "type": "string", + "nullable": true, "enum": [ "WATCHING", "TRIGGERED", @@ -10330,6 +10481,7 @@ }, "severity": { "type": "string", + "nullable": true, "enum": [ "DOWN", "DEGRADED", @@ -10338,6 +10490,7 @@ }, "source": { "type": "string", + "nullable": true, "enum": [ "AUTOMATIC", "MANUAL", @@ -10348,15 +10501,18 @@ }, "monitorId": { "type": "string", - "format": "uuid" + "format": "uuid", + "nullable": true }, "serviceId": { "type": "string", - "format": "uuid" + "format": "uuid", + "nullable": true }, "resourceGroupId": { "type": "string", - "format": "uuid" + "format": "uuid", + "nullable": true }, "tagId": { "type": "string", @@ -10391,17 +10547,20 @@ } }, "required": [ - "status", - "severity", - "source", - "monitorId", - "serviceId", - "resourceGroupId", "page", "size" ] }, "IncidentPolicyDto": { + "required": [ + "confirmation", + "createdAt", + "id", + "monitorId", + "recovery", + "triggerRules", + "updatedAt" + ], "type": "object", "properties": { "id": { @@ -10450,18 +10609,14 @@ "nullable": true } }, - "description": "Incident detection, confirmation, and recovery policy for a monitor", - "required": [ - "id", - "monitorId", - "triggerRules", - "confirmation", - "recovery", - "createdAt", - "updatedAt" - ] + "description": "Incident detection, confirmation, and recovery policy for a monitor" }, "IncidentRef": { + "required": [ + "id", + "impact", + "title" + ], "type": "object", "properties": { "id": { @@ -10478,12 +10633,7 @@ "description": "Incident impact level" } }, - "description": "Lightweight reference to an incident overlapping this day", - "required": [ - "id", - "title", - "impact" - ] + "description": "Lightweight reference to an incident overlapping this day" }, "IncidentsSummaryDto": { "type": "object", @@ -10509,6 +10659,11 @@ ] }, "IncidentUpdateDto": { + "required": [ + "createdAt", + "id", + "incidentId" + ], "type": "object", "properties": { "id": { @@ -10545,6 +10700,7 @@ }, "createdBy": { "type": "string", + "nullable": true, "enum": [ "SYSTEM", "USER" @@ -10557,16 +10713,13 @@ "type": "string", "format": "date-time" } - }, - "required": [ - "id", - "incidentId", - "createdBy", - "notifySubscribers", - "createdAt" - ] + } }, "IntegrationConfigSchemaDto": { + "required": [ + "channelFields", + "connectionFields" + ], "type": "object", "properties": { "connectionFields": { @@ -10581,13 +10734,20 @@ "$ref": "#/components/schemas/IntegrationFieldDto" } } - }, - "required": [ - "connectionFields", - "channelFields" - ] + } }, "IntegrationDto": { + "required": [ + "authType", + "configSchema", + "description", + "lifecycle", + "logoUrl", + "name", + "setupGuideUrl", + "tierAvailability", + "type" + ], "type": "object", "properties": { "type": { @@ -10625,18 +10785,7 @@ "configSchema": { "$ref": "#/components/schemas/IntegrationConfigSchemaDto" } - }, - "required": [ - "type", - "name", - "description", - "logoUrl", - "authType", - "tierAvailability", - "lifecycle", - "setupGuideUrl", - "configSchema" - ] + } }, "IntegrationFieldDto": { "required": [ @@ -10685,6 +10834,11 @@ } }, "InviteDto": { + "required": [ + "email", + "expiresAt", + "roleOffered" + ], "type": "object", "properties": { "inviteId": { @@ -10723,13 +10877,7 @@ "nullable": true } }, - "description": "Organization invite sent to an email address", - "required": [ - "inviteId", - "email", - "roleOffered", - "expiresAt" - ] + "description": "Organization invite sent to an email address" }, "JsonPathAssertion": { "required": [ @@ -10769,14 +10917,18 @@ } }, "required": [ + "path", "expected", - "operator", - "path" + "operator" ] } ] }, "KeyInfo": { + "required": [ + "createdAt", + "name" + ], "type": "object", "properties": { "id": { @@ -10806,14 +10958,18 @@ "nullable": true } }, - "description": "API key metadata", - "required": [ - "id", - "name", - "createdAt" - ] + "description": "API key metadata" }, "LinkedStatusPageIncidentDto": { + "required": [ + "id", + "impact", + "status", + "statusPageId", + "statusPageName", + "statusPageSlug", + "title" + ], "type": "object", "properties": { "id": { @@ -10859,19 +11015,14 @@ "format": "date-time", "nullable": true } - }, - "required": [ - "id", - "statusPageId", - "statusPageName", - "statusPageSlug", - "title", - "status", - "impact", - "scheduled" - ] + } }, "MaintenanceComponentRef": { + "required": [ + "id", + "name", + "status" + ], "type": "object", "properties": { "id": { @@ -10888,14 +11039,13 @@ "description": "Component status at the time of the maintenance update" } }, - "description": "A component affected by a scheduled maintenance window", + "description": "A component affected by a scheduled maintenance window" + }, + "MaintenanceUpdateDto": { "required": [ "id", - "name", "status" - ] - }, - "MaintenanceUpdateDto": { + ], "type": "object", "properties": { "id": { @@ -10919,13 +11069,15 @@ "nullable": true } }, - "description": "A status update within a scheduled maintenance lifecycle", - "required": [ - "id", - "status" - ] + "description": "A status update within a scheduled maintenance lifecycle" }, "MaintenanceWindowDto": { + "required": [ + "createdAt", + "endsAt", + "id", + "startsAt" + ], "type": "object", "properties": { "id": { @@ -10974,15 +11126,7 @@ "format": "date-time" } }, - "description": "Scheduled maintenance window for a monitor", - "required": [ - "id", - "organizationId", - "startsAt", - "endsAt", - "suppressAlerts", - "createdAt" - ] + "description": "Scheduled maintenance window for a monitor" }, "MatchRule": { "required": [ @@ -11076,7 +11220,10 @@ "description": "Minimum number of tools the server must expose", "format": "int32" } - } + }, + "required": [ + "min" + ] } ] }, @@ -11118,7 +11265,10 @@ "description": "Maximum allowed MCP check duration in milliseconds", "format": "int32" } - } + }, + "required": [ + "maxMs" + ] } ] }, @@ -11136,7 +11286,10 @@ "description": "MCP check duration in milliseconds that triggers a warning only", "format": "int32" } - } + }, + "required": [ + "warnMs" + ] } ] }, @@ -11222,11 +11375,20 @@ "description": "Expected tool count; warns when the live count differs", "format": "int32" } - } + }, + "required": [ + "expectedCount" + ] } ] }, "MemberDto": { + "required": [ + "createdAt", + "email", + "orgRole", + "status" + ], "type": "object", "properties": { "userId": { @@ -11270,16 +11432,16 @@ "format": "date-time" } }, - "description": "Organization member with role and status", - "required": [ - "userId", - "email", - "orgRole", - "status", - "createdAt" - ] + "description": "Organization member with role and status" }, "MonitorAssertionDto": { + "required": [ + "assertionType", + "config", + "id", + "monitorId", + "severity" + ], "type": "object", "properties": { "id": { @@ -11474,14 +11636,7 @@ "warn" ] } - }, - "required": [ - "id", - "monitorId", - "assertionType", - "config", - "severity" - ] + } }, "MonitorAuthConfig": { "required": [ @@ -11505,6 +11660,12 @@ } }, "MonitorAuthDto": { + "required": [ + "authType", + "config", + "id", + "monitorId" + ], "type": "object", "properties": { "id": { @@ -11540,19 +11701,23 @@ } ] } - }, - "required": [ - "id", - "monitorId", - "authType", - "config" - ] + } }, "MonitorConfig": { "type": "object", "description": "Protocol-specific monitor configuration" }, "MonitorDto": { + "required": [ + "config", + "createdAt", + "id", + "managedBy", + "name", + "regions", + "type", + "updatedAt" + ], "type": "object", "properties": { "id": { @@ -11566,6 +11731,7 @@ "format": "int32" }, "name": { + "minLength": 1, "type": "string", "description": "Human-readable name for this monitor" }, @@ -11694,22 +11860,13 @@ } } }, - "description": "Full monitor representation", - "required": [ - "id", - "organizationId", - "name", - "type", - "config", - "frequencySeconds", - "enabled", - "regions", - "managedBy", - "createdAt", - "updatedAt" - ] + "description": "Full monitor representation" }, "MonitorReference": { + "required": [ + "id", + "name" + ], "type": "object", "properties": { "id": { @@ -11722,11 +11879,7 @@ "description": "Monitor name" } }, - "description": "Monitors that reference this secret; null on create/update responses", - "required": [ - "id", - "name" - ] + "description": "Monitors that reference this secret; null on create/update responses" }, "MonitorsSummaryDto": { "type": "object", @@ -11830,6 +11983,9 @@ } }, "MonitorTestResultDto": { + "required": [ + "assertionResults" + ], "type": "object", "properties": { "passed": { @@ -11892,13 +12048,16 @@ "type": "string" } } - }, - "required": [ - "passed", - "assertionResults" - ] + } }, "MonitorVersionDto": { + "required": [ + "changedVia", + "createdAt", + "id", + "monitorId", + "snapshot" + ], "type": "object", "properties": { "id": { @@ -11946,15 +12105,7 @@ "format": "date-time" } }, - "description": "A point-in-time version snapshot of a monitor configuration", - "required": [ - "id", - "monitorId", - "version", - "snapshot", - "changedVia", - "createdAt" - ] + "description": "A point-in-time version snapshot of a monitor configuration" }, "NewTagRequest": { "required": [ @@ -11978,6 +12129,15 @@ "description": "Inline tag creation — creates the tag if it does not already exist" }, "NotificationDispatchDto": { + "required": [ + "createdAt", + "deliveries", + "id", + "incidentId", + "policyId", + "status", + "updatedAt" + ], "type": "object", "properties": { "id": { @@ -12069,19 +12229,14 @@ "format": "date-time" } }, - "description": "Dispatch state for a single (incident, notification policy) pair, with delivery history", - "required": [ - "id", - "incidentId", - "policyId", - "status", - "currentStep", - "deliveries", - "createdAt", - "updatedAt" - ] + "description": "Dispatch state for a single (incident, notification policy) pair, with delivery history" }, "NotificationDto": { + "required": [ + "createdAt", + "title", + "type" + ], "type": "object", "properties": { "id": { @@ -12122,16 +12277,17 @@ "format": "date-time" } }, - "description": "In-app notification for the current user", - "required": [ - "id", - "type", - "title", - "read", - "createdAt" - ] + "description": "In-app notification for the current user" }, "NotificationPolicyDto": { + "required": [ + "createdAt", + "escalation", + "id", + "matchRules", + "name", + "updatedAt" + ], "type": "object", "properties": { "id": { @@ -12145,6 +12301,7 @@ "format": "int32" }, "name": { + "minLength": 1, "type": "string", "description": "Human-readable name for this policy" }, @@ -12178,18 +12335,7 @@ "format": "date-time" } }, - "description": "Org-level notification policy with match rules and escalation chain", - "required": [ - "id", - "organizationId", - "name", - "matchRules", - "escalation", - "enabled", - "priority", - "createdAt", - "updatedAt" - ] + "description": "Org-level notification policy with match rules and escalation chain" }, "OpsGenieChannelConfig": { "required": [ @@ -12221,6 +12367,10 @@ ] }, "OrganizationDto": { + "required": [ + "email", + "name" + ], "type": "object", "properties": { "id": { @@ -12253,13 +12403,12 @@ "nullable": true } }, - "description": "Organization account details", - "required": [ - "id", - "name" - ] + "description": "Organization account details" }, "OrgInfo": { + "required": [ + "name" + ], "type": "object", "properties": { "id": { @@ -12272,11 +12421,7 @@ "description": "Organization name" } }, - "description": "Organization the key belongs to", - "required": [ - "id", - "name" - ] + "description": "Organization the key belongs to" }, "Pageable": { "type": "object", @@ -12360,6 +12505,11 @@ ] }, "PlanInfo": { + "required": [ + "entitlements", + "tier", + "usage" + ], "type": "object", "properties": { "tier": { @@ -12406,17 +12556,14 @@ "description": "Current usage counters keyed by entitlement name" } }, - "description": "Billing plan and entitlement state", - "required": [ - "tier", - "trialActive", - "entitlements", - "usage" - ] + "description": "Billing plan and entitlement state" }, "PollChartBucketDto": { - "type": "object", - "properties": { + "required": [ + "bucket" + ], + "type": "object", + "properties": { "bucket": { "type": "string", "description": "Start of the time bucket (ISO 8601)", @@ -12443,11 +12590,7 @@ "example": 60 } }, - "description": "Aggregated poll metrics for a time bucket", - "required": [ - "bucket", - "totalPolls" - ] + "description": "Aggregated poll metrics for a time bucket" }, "PublishStatusPageIncidentRequest": { "type": "object", @@ -12567,7 +12710,10 @@ "description": "Maximum number of HTTP redirects allowed before the check fails", "format": "int32" } - } + }, + "required": [ + "maxCount" + ] } ] }, @@ -12634,6 +12780,10 @@ ] }, "RegionStatusDto": { + "required": [ + "region", + "timestamp" + ], "type": "object", "properties": { "region": { @@ -12664,12 +12814,7 @@ "nullable": true } }, - "description": "Latest check result for a single region", - "required": [ - "region", - "passed", - "timestamp" - ] + "description": "Latest check result for a single region" }, "RemoveMonitorTagsRequest": { "required": [ @@ -12733,18 +12878,26 @@ "description": "Reorder page-level layout: groups and ungrouped components share one ordering" }, "ResolveIncidentRequest": { + "required": [ + "body" + ], "type": "object", "properties": { "body": { "type": "string", "description": "Optional resolution message or post-mortem notes" } - }, - "required": [ - "body" - ] + } }, "ResourceGroupDto": { + "required": [ + "createdAt", + "health", + "id", + "name", + "slug", + "updatedAt" + ], "type": "object", "properties": { "id": { @@ -12758,10 +12911,12 @@ "format": "int32" }, "name": { + "minLength": 1, "type": "string", "description": "Human-readable group name" }, "slug": { + "minLength": 1, "type": "string", "description": "URL-safe group identifier" }, @@ -12867,19 +13022,12 @@ "format": "date-time" } }, - "description": "Resource group with health summary and optional member details", - "required": [ - "id", - "organizationId", - "name", - "slug", - "suppressMemberAlerts", - "health", - "createdAt", - "updatedAt" - ] + "description": "Resource group with health summary and optional member details" }, "ResourceGroupHealthDto": { + "required": [ + "status" + ], "type": "object", "properties": { "status": { @@ -12924,15 +13072,16 @@ "nullable": true } }, - "description": "Aggregated health summary for a resource group", - "required": [ - "status", - "totalMembers", - "operationalCount", - "activeIncidents" - ] + "description": "Aggregated health summary for a resource group" }, "ResourceGroupMemberDto": { + "required": [ + "createdAt", + "groupId", + "id", + "memberType", + "status" + ], "type": "object", "properties": { "id": { @@ -13042,14 +13191,7 @@ "nullable": true } }, - "description": "A single member of a resource group with its computed health status", - "required": [ - "id", - "groupId", - "memberType", - "status", - "createdAt" - ] + "description": "A single member of a resource group with its computed health status" }, "ResponseSizeAssertion": { "type": "object", @@ -13065,7 +13207,10 @@ "description": "Maximum response body size in bytes before the check fails", "format": "int32" } - } + }, + "required": [ + "maxBytes" + ] } ] }, @@ -13083,7 +13228,10 @@ "description": "Maximum allowed response time in milliseconds before the check fails", "format": "int32" } - } + }, + "required": [ + "thresholdMs" + ] } ] }, @@ -13101,11 +13249,19 @@ "description": "HTTP response time in milliseconds that triggers a warning only", "format": "int32" } - } + }, + "required": [ + "warnMs" + ] } ] }, "ResultSummaryDto": { + "required": [ + "chartData", + "currentStatus", + "latestPerRegion" + ], "type": "object", "properties": { "currentStatus": { @@ -13147,12 +13303,7 @@ "example": 99.8 } }, - "description": "Dashboard summary: current status, per-region latest results, and chart data", - "required": [ - "currentStatus", - "latestPerRegion", - "chartData" - ] + "description": "Dashboard summary: current status, per-region latest results, and chart data" }, "RetryStrategy": { "required": [ @@ -13178,6 +13329,14 @@ "description": "Default retry strategy for member monitors; null clears" }, "ScheduledMaintenanceDto": { + "required": [ + "affectedComponents", + "externalId", + "id", + "status", + "title", + "updates" + ], "type": "object", "properties": { "id": { @@ -13246,17 +13405,16 @@ } } }, - "description": "A scheduled maintenance window from a vendor status page", - "required": [ - "id", - "externalId", - "title", - "status", - "affectedComponents", - "updates" - ] + "description": "A scheduled maintenance window from a vendor status page" }, "SecretDto": { + "required": [ + "createdAt", + "id", + "key", + "updatedAt", + "valueHash" + ], "type": "object", "properties": { "id": { @@ -13296,15 +13454,7 @@ } } }, - "description": "Secret with change-detection hash; plaintext value is never returned", - "required": [ - "id", - "key", - "dekVersion", - "valueHash", - "createdAt", - "updatedAt" - ] + "description": "Secret with change-detection hash; plaintext value is never returned" }, "SeoMetadataDto": { "type": "object", @@ -13328,6 +13478,15 @@ "description": "Admin-editable SEO metadata for pSEO pages" }, "ServiceCatalogDto": { + "required": [ + "adapterType", + "createdAt", + "dataCompleteness", + "id", + "name", + "slug", + "updatedAt" + ], "type": "object", "properties": { "id": { @@ -13399,23 +13558,19 @@ "nullable": true } }, - "description": "Related services", + "description": "Related services" + }, + "ServiceComponentDto": { "required": [ + "dataType", + "externalId", + "firstSeenAt", "id", - "slug", + "lastSeenAt", + "lifecycleStatus", "name", - "adapterType", - "pollingIntervalSeconds", - "enabled", - "published", - "createdAt", - "updatedAt", - "componentCount", - "activeIncidentCount", - "dataCompleteness" - ] - }, - "ServiceComponentDto": { + "status" + ], "type": "object", "properties": { "id": { @@ -13483,6 +13638,16 @@ "description": "Display name of the parent group", "nullable": true }, + "displayAggregatedUptime": { + "type": "boolean", + "description": "Group-only: render an aggregated uptime bar above this group's children" + }, + "childCount": { + "type": "integer", + "description": "Group-only count of visible leaf children; null for leaves", + "format": "int32", + "nullable": true + }, "uptime": { "nullable": true, "allOf": [ @@ -13504,27 +13669,71 @@ "type": "string", "format": "date-time" }, - "group": { + "isGroup": { "type": "boolean" } }, - "description": "A first-class service component with lifecycle and uptime data", + "description": "A first-class service component with lifecycle and uptime data" + }, + "ServiceDayDetailDto": { "required": [ - "id", - "externalId", - "name", - "status", - "showcase", - "onlyShowIfDegraded", - "lifecycleStatus", - "dataType", - "hasUptime", - "firstSeenAt", - "lastSeenAt", - "group" - ] + "components", + "date", + "incidents" + ], + "type": "object", + "properties": { + "date": { + "type": "string", + "description": "UTC calendar day this rollup covers", + "format": "date" + }, + "overallUptimePercentage": { + "type": "number", + "description": "Average uptime % across leaf components with uptime data; null if no data", + "format": "double", + "nullable": true + }, + "totalPartialOutageSeconds": { + "type": "integer", + "description": "Sum of partial outage seconds across all leaf components", + "format": "int64" + }, + "totalMajorOutageSeconds": { + "type": "integer", + "description": "Sum of major outage seconds across all leaf components", + "format": "int64" + }, + "components": { + "type": "array", + "description": "Per-component impact rows for the day (only components with uptime data)", + "items": { + "$ref": "#/components/schemas/ComponentImpact" + } + }, + "incidents": { + "type": "array", + "description": "Incidents that were active at any point during this day (started before day end, resolved after day start)", + "items": { + "$ref": "#/components/schemas/DayIncident" + } + } + }, + "description": "One-day rollup for a public service status page: aggregated uptime, per-component impact, and incidents that overlapped the day. Powers the click/hover-to-expand panel under each uptime bar." }, "ServiceDetailDto": { + "required": [ + "activeMaintenances", + "adapterType", + "components", + "createdAt", + "dataCompleteness", + "id", + "name", + "recentIncidents", + "slug", + "updatedAt" + ], "type": "object", "properties": { "id": { @@ -13623,23 +13832,15 @@ "$ref": "#/components/schemas/ServiceCatalogDto" } } - }, - "required": [ - "id", - "slug", - "name", - "adapterType", - "pollingIntervalSeconds", - "enabled", - "createdAt", - "updatedAt", - "recentIncidents", - "components", - "activeMaintenances", - "dataCompleteness" - ] + } }, "ServiceIncidentDetailDto": { + "required": [ + "id", + "status", + "title", + "updates" + ], "type": "object", "properties": { "id": { @@ -13688,15 +13889,15 @@ "$ref": "#/components/schemas/ServiceIncidentUpdateDto" } } - }, + } + }, + "ServiceIncidentDto": { "required": [ "id", - "title", + "serviceId", "status", - "updates" - ] - }, - "ServiceIncidentDto": { + "title" + ], "type": "object", "properties": { "id": { @@ -13758,15 +13959,12 @@ "format": "date-time", "nullable": true } - }, - "required": [ - "id", - "serviceId", - "title", - "status" - ] + } }, "ServiceIncidentUpdateDto": { + "required": [ + "status" + ], "type": "object", "properties": { "status": { @@ -13781,12 +13979,12 @@ "format": "date-time", "nullable": true } - }, - "required": [ - "status" - ] + } }, "ServiceLiveStatusDto": { + "required": [ + "componentStatuses" + ], "type": "object", "properties": { "overallStatus": { @@ -13811,13 +14009,13 @@ "description": "ISO 8601 timestamp of the last status poll", "nullable": true } - }, - "required": [ - "componentStatuses", - "activeIncidentCount" - ] + } }, "ServicePollResultDto": { + "required": [ + "serviceId", + "timestamp" + ], "type": "object", "properties": { "serviceId": { @@ -13873,16 +14071,13 @@ "example": 1 } }, - "description": "A single poll result from the status poller", - "required": [ - "serviceId", - "timestamp", - "passed", - "componentCount", - "degradedCount" - ] + "description": "A single poll result from the status poller" }, "ServicePollSummaryDto": { + "required": [ + "chartData", + "window" + ], "type": "object", "properties": { "uptimePercentage": { @@ -13931,15 +14126,12 @@ } } }, - "description": "Aggregated poll metrics and chart data for a service", - "required": [ - "totalPolls", - "passedPolls", - "window", - "chartData" - ] + "description": "Aggregated poll metrics and chart data for a service" }, "ServiceStatusDto": { + "required": [ + "overallStatus" + ], "type": "object", "properties": { "overallStatus": { @@ -13950,10 +14142,7 @@ "format": "date-time", "nullable": true } - }, - "required": [ - "overallStatus" - ] + } }, "ServiceSubscribeRequest": { "type": "object", @@ -13973,6 +14162,15 @@ "description": "Optional body for subscribing to a specific component of a service" }, "ServiceSubscriptionDto": { + "required": [ + "adapterType", + "alertSensitivity", + "name", + "serviceId", + "slug", + "subscribedAt", + "subscriptionId" + ], "type": "object", "properties": { "subscriptionId": { @@ -13986,9 +14184,11 @@ "format": "uuid" }, "slug": { + "minLength": 1, "type": "string" }, "name": { + "minLength": 1, "type": "string" }, "category": { @@ -14000,6 +14200,7 @@ "nullable": true }, "adapterType": { + "minLength": 1, "type": "string" }, "pollingIntervalSeconds": { @@ -14034,6 +14235,7 @@ ] }, "alertSensitivity": { + "minLength": 1, "type": "string", "description": "Alert sensitivity: ALL (synthetic + real incidents), INCIDENTS_ONLY (real vendor incidents, default), MAJOR_ONLY (real + DOWN severity)", "enum": [ @@ -14048,20 +14250,14 @@ "format": "date-time" } }, - "description": "An org-level service subscription with current status information", - "required": [ - "subscriptionId", - "serviceId", - "slug", - "name", - "adapterType", - "pollingIntervalSeconds", - "enabled", - "alertSensitivity", - "subscribedAt" - ] + "description": "An org-level service subscription with current status information" }, "ServiceUptimeResponse": { + "required": [ + "buckets", + "granularity", + "period" + ], "type": "object", "properties": { "overallUptimePct": { @@ -14095,12 +14291,7 @@ "example": "vendor_reported" } }, - "description": "Uptime response with per-bucket breakdown and overall percentage for the period", - "required": [ - "period", - "granularity", - "buckets" - ] + "description": "Uptime response with per-bucket breakdown and overall percentage for the period" }, "SetAlertChannelsRequest": { "required": [ @@ -14145,160 +14336,163 @@ } }, "SingleValueResponseAlertChannelDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/AlertChannelDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseAlertDeliveryDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/AlertDeliveryDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseApiKeyCreateResponse": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/ApiKeyCreateResponse" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseApiKeyDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/ApiKeyDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseAuthMeResponse": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/AuthMeResponse" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseBulkMonitorActionResult": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/BulkMonitorActionResult" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseDashboardOverviewDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/DashboardOverviewDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseDekRotationResultDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/DekRotationResultDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseDeployLockDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/DeployLockDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseEnvironmentDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/EnvironmentDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseGlobalStatusSummaryDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/GlobalStatusSummaryDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseIncidentDetailDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/IncidentDetailDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseIncidentPolicyDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/IncidentPolicyDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseInviteDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/InviteDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseListUUID": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -14308,35 +14502,35 @@ "format": "uuid" } } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseLong": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "type": "integer", "format": "int64" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseMaintenanceWindowDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/MaintenanceWindowDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseMapStringListComponentUptimeDayDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -14348,384 +14542,392 @@ } } } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseMonitorAssertionDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/MonitorAssertionDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseMonitorAuthDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/MonitorAuthDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseMonitorDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/MonitorDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseMonitorTestResultDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/MonitorTestResultDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseMonitorVersionDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/MonitorVersionDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseNotificationDispatchDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/NotificationDispatchDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseNotificationPolicyDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/NotificationPolicyDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseOrganizationDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/OrganizationDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseResourceGroupDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/ResourceGroupDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseResourceGroupHealthDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/ResourceGroupHealthDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseResourceGroupMemberDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/ResourceGroupMemberDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseResultSummaryDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/ResultSummaryDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseSecretDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/SecretDto" } - }, + } + }, + "SingleValueResponseServiceDayDetailDto": { "required": [ "data" - ] + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/ServiceDayDetailDto" + } + } }, "SingleValueResponseServiceDetailDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/ServiceDetailDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseServiceIncidentDetailDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/ServiceIncidentDetailDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseServiceLiveStatusDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/ServiceLiveStatusDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseServicePollSummaryDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/ServicePollSummaryDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseServiceSubscriptionDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/ServiceSubscriptionDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseServiceUptimeResponse": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/ServiceUptimeResponse" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseStatusPageComponentDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/StatusPageComponentDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseStatusPageComponentGroupDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/StatusPageComponentGroupDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseStatusPageCustomDomainDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/StatusPageCustomDomainDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseStatusPageDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/StatusPageDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseStatusPageIncidentDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/StatusPageIncidentDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseStatusPageSubscriberDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/StatusPageSubscriberDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseString": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "type": "string" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseTagDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/TagDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseTestChannelResult": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/TestChannelResult" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseTestMatchResult": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/TestMatchResult" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseUptimeDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/UptimeDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseWebhookEndpointDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/WebhookEndpointDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseWebhookSigningSecretDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/WebhookSigningSecretDto" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseWebhookTestResult": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/WebhookTestResult" } - }, - "required": [ - "data" - ] + } }, "SingleValueResponseWorkspaceDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { "$ref": "#/components/schemas/WorkspaceDto" } - }, - "required": [ - "data" - ] + } }, "SlackChannelConfig": { "required": [ @@ -14770,7 +14972,10 @@ "description": "Minimum days before TLS certificate expiry; fails or warns below this threshold", "format": "int32" } - } + }, + "required": [ + "minDaysRemaining" + ] } ] }, @@ -14895,7 +15100,8 @@ }, "hidePoweredBy": { "type": "boolean", - "description": "Whether to hide the 'Powered by DevHelm' footer badge" + "description": "Whether to hide the 'Powered by DevHelm' footer badge (default: false)", + "default": false }, "customCss": { "maxLength": 50000, @@ -14912,12 +15118,18 @@ "nullable": true } }, - "description": "Updated branding configuration; null preserves current", - "required": [ - "hidePoweredBy" - ] + "description": "Updated branding configuration; null preserves current" }, "StatusPageComponentDto": { + "required": [ + "createdAt", + "currentStatus", + "id", + "name", + "statusPageId", + "type", + "updatedAt" + ], "type": "object", "properties": { "id": { @@ -14934,6 +15146,7 @@ "nullable": true }, "name": { + "minLength": 1, "type": "string" }, "description": { @@ -14995,22 +15208,16 @@ "type": "string", "format": "date-time" } - }, - "required": [ - "id", - "statusPageId", - "name", - "type", - "currentStatus", - "showUptime", - "displayOrder", - "pageOrder", - "excludeFromOverall", - "createdAt", - "updatedAt" - ] + } }, "StatusPageComponentGroupDto": { + "required": [ + "createdAt", + "id", + "name", + "statusPageId", + "updatedAt" + ], "type": "object", "properties": { "id": { @@ -15054,19 +15261,19 @@ "type": "string", "format": "date-time" } - }, - "required": [ - "id", - "statusPageId", - "name", - "displayOrder", - "pageOrder", - "collapsed", - "createdAt", - "updatedAt" - ] + } }, "StatusPageCustomDomainDto": { + "required": [ + "createdAt", + "hostname", + "id", + "status", + "updatedAt", + "verificationCnameTarget", + "verificationMethod", + "verificationToken" + ], "type": "object", "properties": { "id": { @@ -15121,20 +15328,19 @@ "primary": { "type": "boolean" } - }, + } + }, + "StatusPageDto": { "required": [ - "id", - "hostname", - "status", - "verificationMethod", - "verificationToken", - "verificationCnameTarget", + "branding", "createdAt", + "id", + "incidentMode", + "name", + "slug", "updatedAt", - "primary" - ] - }, - "StatusPageDto": { + "visibility" + ], "type": "object", "properties": { "id": { @@ -15150,9 +15356,11 @@ "format": "int32" }, "name": { + "minLength": 1, "type": "string" }, "slug": { + "minLength": 1, "type": "string" }, "description": { @@ -15210,22 +15418,14 @@ "type": "string", "format": "date-time" } - }, - "required": [ - "id", - "organizationId", - "workspaceId", - "name", - "slug", - "branding", - "visibility", - "enabled", - "incidentMode", - "createdAt", - "updatedAt" - ] + } }, "StatusPageIncidentComponentDto": { + "required": [ + "componentName", + "componentStatus", + "statusPageComponentId" + ], "type": "object", "properties": { "statusPageComponentId": { @@ -15245,14 +15445,19 @@ "componentName": { "type": "string" } - }, - "required": [ - "statusPageComponentId", - "componentStatus", - "componentName" - ] + } }, "StatusPageIncidentDto": { + "required": [ + "createdAt", + "id", + "impact", + "startedAt", + "status", + "statusPageId", + "title", + "updatedAt" + ], "type": "object", "properties": { "id": { @@ -15264,6 +15469,7 @@ "format": "uuid" }, "title": { + "minLength": 1, "type": "string" }, "status": { @@ -15354,21 +15560,15 @@ "type": "string", "format": "date-time" } - }, - "required": [ - "id", - "statusPageId", - "title", - "status", - "impact", - "scheduled", - "autoResolve", - "startedAt", - "createdAt", - "updatedAt" - ] + } }, "StatusPageIncidentUpdateDto": { + "required": [ + "body", + "createdAt", + "id", + "status" + ], "type": "object", "properties": { "id": { @@ -15389,6 +15589,7 @@ }, "createdBy": { "type": "string", + "nullable": true, "enum": [ "USER", "SYSTEM" @@ -15406,17 +15607,14 @@ "type": "string", "format": "date-time" } - }, - "required": [ - "id", - "status", - "body", - "createdBy", - "notifySubscribers", - "createdAt" - ] + } }, "StatusPageSubscriberDto": { + "required": [ + "createdAt", + "email", + "id" + ], "type": "object", "properties": { "id": { @@ -15433,15 +15631,14 @@ "type": "string", "format": "date-time" } - }, - "required": [ - "id", - "email", - "confirmed", - "createdAt" - ] + } }, "Summary": { + "required": [ + "id", + "name", + "slug" + ], "type": "object", "properties": { "id": { @@ -15449,20 +15646,20 @@ "format": "uuid" }, "name": { + "minLength": 1, "type": "string" }, "slug": { + "minLength": 1, "type": "string" } }, - "description": "Environment associated with this monitor; null when unassigned", - "required": [ - "id", - "name", - "slug" - ] + "description": "Environment associated with this monitor; null when unassigned" }, "TableValueResultAlertChannelDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -15487,14 +15684,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultAlertDeliveryDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -15519,14 +15714,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultApiKeyDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -15551,14 +15744,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultAuditEventDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -15583,14 +15774,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultCategoryDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -15615,14 +15804,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultComponentUptimeDayDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -15647,14 +15834,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultDeliveryAttemptDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -15679,14 +15864,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultEnvironmentDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -15711,14 +15894,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultIncidentDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -15743,14 +15924,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultIntegrationDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -15775,14 +15954,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultInviteDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -15807,14 +15984,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultMaintenanceWindowDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -15839,14 +16014,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultMemberDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -15871,14 +16044,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultMonitorDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -15903,14 +16074,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultMonitorVersionDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -15935,14 +16104,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultNotificationDispatchDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -15967,14 +16134,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultNotificationDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -15999,14 +16164,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultNotificationPolicyDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -16031,14 +16194,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultResourceGroupDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -16063,14 +16224,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultScheduledMaintenanceDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -16095,14 +16254,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultSecretDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -16127,14 +16284,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultServiceComponentDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -16159,14 +16314,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultServiceIncidentDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -16191,14 +16344,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultServiceSubscriptionDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -16223,14 +16374,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultStatusPageComponentDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -16255,14 +16404,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultStatusPageComponentGroupDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -16287,14 +16434,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultStatusPageCustomDomainDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -16319,14 +16464,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultStatusPageDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -16351,14 +16494,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultStatusPageIncidentDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -16383,14 +16524,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultStatusPageSubscriberDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -16415,14 +16554,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultTagDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -16447,14 +16584,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultWebhookDeliveryDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -16479,14 +16614,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultWebhookEndpointDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -16511,14 +16644,12 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TableValueResultWorkspaceDto": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -16543,14 +16674,16 @@ "format": "int32", "nullable": true } - }, - "required": [ - "data", - "hasNext", - "hasPrev" - ] + } }, "TagDto": { + "required": [ + "color", + "createdAt", + "id", + "name", + "updatedAt" + ], "type": "object", "properties": { "id": { @@ -16564,10 +16697,12 @@ "format": "int32" }, "name": { + "minLength": 1, "type": "string", "description": "Tag name, unique within the org" }, "color": { + "minLength": 1, "type": "string", "description": "Hex color code for display (e.g. #6B7280)" }, @@ -16582,15 +16717,7 @@ "format": "date-time" } }, - "description": "Tag for organizing and filtering monitors", - "required": [ - "id", - "organizationId", - "name", - "color", - "createdAt", - "updatedAt" - ] + "description": "Tag for organizing and filtering monitors" }, "TcpConnectsAssertion": { "type": "object", @@ -16632,7 +16759,8 @@ } }, "required": [ - "host" + "host", + "port" ] } ] @@ -16651,7 +16779,10 @@ "description": "Maximum TCP connect time in milliseconds before the check fails", "format": "int32" } - } + }, + "required": [ + "maxMs" + ] } ] }, @@ -16669,7 +16800,10 @@ "description": "TCP connect time in milliseconds that triggers a warning only", "format": "int32" } - } + }, + "required": [ + "warnMs" + ] } ] }, @@ -16732,6 +16866,9 @@ "description": "Alert channel configuration to test without saving" }, "TestChannelResult": { + "required": [ + "message" + ], "type": "object", "properties": { "success": { @@ -16740,13 +16877,13 @@ "message": { "type": "string" } - }, - "required": [ - "success", - "message" - ] + } }, "TestMatchResult": { + "required": [ + "matchedRules", + "unmatchedRules" + ], "type": "object", "properties": { "matched": { @@ -16770,12 +16907,7 @@ } } }, - "description": "Result of a dry-run match evaluation against a notification policy", - "required": [ - "matched", - "matchedRules", - "unmatchedRules" - ] + "description": "Result of a dry-run match evaluation against a notification policy" }, "TestNotificationPolicyRequest": { "type": "object", @@ -17183,6 +17315,7 @@ "severity": { "type": "string", "description": "New outcome severity: FAIL or WARN", + "nullable": true, "enum": [ "fail", "warn" @@ -17252,7 +17385,8 @@ "monitorId": { "type": "string", "description": "Monitor to attach this maintenance window to; null preserves current", - "format": "uuid" + "format": "uuid", + "nullable": true }, "startsAt": { "type": "string", @@ -17268,15 +17402,18 @@ "maxLength": 100, "minLength": 0, "type": "string", - "description": "Updated iCal RRULE; null clears the repeat rule" + "description": "Updated iCal RRULE; null clears the repeat rule", + "nullable": true }, "reason": { "type": "string", - "description": "Updated reason; null clears the existing reason" + "description": "Updated reason; null clears the existing reason", + "nullable": true }, "suppressAlerts": { "type": "boolean", - "description": "Whether to suppress alerts; null preserves current" + "description": "Whether to suppress alerts; null preserves current", + "nullable": true } } }, @@ -17419,36 +17556,38 @@ "maxLength": 255, "minLength": 0, "type": "string", - "description": "Human-readable name for this policy; null preserves current" + "description": "Human-readable name for this policy; null preserves current", + "nullable": true }, "matchRules": { "type": "array", "description": "Match rules to evaluate (all must pass; omit or empty for catch-all)", + "nullable": true, "items": { "$ref": "#/components/schemas/MatchRule" } }, "escalation": { - "$ref": "#/components/schemas/EscalationChain" + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/EscalationChain" + } + ] }, "enabled": { "type": "boolean", - "description": "Whether this policy is enabled; null preserves current" + "description": "Whether this policy is enabled; null preserves current", + "nullable": true }, "priority": { "type": "integer", "description": "Evaluation priority; higher value = evaluated first; null preserves current", - "format": "int32" + "format": "int32", + "nullable": true } }, - "description": "Request body for updating a notification policy (null fields are preserved)", - "required": [ - "name", - "matchRules", - "escalation", - "enabled", - "priority" - ] + "description": "Request body for updating a notification policy (null fields are preserved)" }, "UpdateOrgDetailsRequest": { "required": [ @@ -17473,19 +17612,22 @@ "maxLength": 50, "minLength": 0, "type": "string", - "description": "Team size range (e.g. 1-10, 11-50)" + "description": "Team size range (e.g. 1-10, 11-50)", + "nullable": true }, "industry": { "maxLength": 100, "minLength": 0, "type": "string", - "description": "Industry vertical (e.g. SaaS, Fintech)" + "description": "Industry vertical (e.g. SaaS, Fintech)", + "nullable": true }, "websiteUrl": { "maxLength": 255, "minLength": 0, "type": "string", - "description": "Organization website URL (max 255 chars)" + "description": "Organization website URL (max 255 chars)", + "nullable": true } } }, @@ -17866,6 +18008,9 @@ "description": "Update workspace details" }, "UptimeBucketDto": { + "required": [ + "timestamp" + ], "type": "object", "properties": { "timestamp": { @@ -17888,11 +18033,7 @@ "example": 12 } }, - "description": "Uptime statistics for a single time bucket", - "required": [ - "timestamp", - "totalPolls" - ] + "description": "Uptime statistics for a single time bucket" }, "UptimeDto": { "type": "object", @@ -17977,6 +18118,14 @@ ] }, "WebhookDeliveryDto": { + "required": [ + "createdAt", + "endpointId", + "eventId", + "eventType", + "id", + "status" + ], "type": "object", "properties": { "id": { @@ -18037,19 +18186,16 @@ "type": "string", "format": "date-time" } - }, - "required": [ - "id", - "endpointId", - "eventId", - "eventType", - "status", - "attemptCount", - "maxAttempts", - "createdAt" - ] + } }, "WebhookEndpointDto": { + "required": [ + "createdAt", + "id", + "subscribedEvents", + "updatedAt", + "url" + ], "type": "object", "properties": { "id": { @@ -18105,18 +18251,14 @@ "format": "date-time" } }, - "description": "Webhook endpoint that receives event delivery payloads", - "required": [ - "id", - "url", - "subscribedEvents", - "enabled", - "consecutiveFailures", - "createdAt", - "updatedAt" - ] + "description": "Webhook endpoint that receives event delivery payloads" }, "WebhookEventCatalogEntry": { + "required": [ + "description", + "surface", + "type" + ], "type": "object", "properties": { "type": { @@ -18132,14 +18274,12 @@ "description": "Human-readable description of when this event fires" } }, - "description": "List of all available webhook event types", - "required": [ - "type", - "surface", - "description" - ] + "description": "List of all available webhook event types" }, "WebhookEventCatalogResponse": { + "required": [ + "data" + ], "type": "object", "properties": { "data": { @@ -18149,10 +18289,7 @@ "$ref": "#/components/schemas/WebhookEventCatalogEntry" } } - }, - "required": [ - "data" - ] + } }, "WebhookSigningSecretDto": { "type": "object", @@ -18170,6 +18307,9 @@ ] }, "WebhookTestResult": { + "required": [ + "message" + ], "type": "object", "properties": { "success": { @@ -18188,13 +18328,14 @@ "format": "int64", "nullable": true } - }, - "required": [ - "success", - "message" - ] + } }, "WorkspaceDto": { + "required": [ + "createdAt", + "name", + "updatedAt" + ], "type": "object", "properties": { "id": { @@ -18213,6 +18354,7 @@ "format": "date-time" }, "name": { + "minLength": 1, "type": "string", "description": "Workspace name" }, @@ -18222,14 +18364,7 @@ "format": "int32" } }, - "description": "Workspace within an organization", - "required": [ - "id", - "createdAt", - "updatedAt", - "name", - "orgId" - ] + "description": "Workspace within an organization" } }, "securitySchemes": { diff --git a/eslint.config.js b/eslint.config.js index ba90718..b7d6c8c 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -22,6 +22,6 @@ export default [ }, }, { - ignores: ['dist/', 'node_modules/'], + ignores: ['dist/', 'node_modules/', 'src/lib/api-zod.generated.ts'], }, ] diff --git a/package-lock.json b/package-lock.json index 5514d34..46215e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,6 +30,7 @@ "eslint": "^10.2.0", "oclif": "^4.23.0", "openapi-typescript": "^7.13.0", + "openapi-zod-client": "^1.18.3", "typescript": "^6.0.2", "vitest": "^4.1.4" }, @@ -37,6 +38,84 @@ "node": ">=18.0.0" } }, + "node_modules/@apidevtools/json-schema-ref-parser": { + "version": "11.7.2", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.7.2.tgz", + "integrity": "sha512-4gY54eEGEstClvEkGnwVkTkrx0sqwemEFG5OSRRn3tD91XH0+Q8XIkYIfo7IwEWPpJZwILb9GUXeShtplRc/eA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.15", + "js-yaml": "^4.1.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/philsturgeon" + } + }, + "node_modules/@apidevtools/openapi-schemas": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz", + "integrity": "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/@apidevtools/swagger-methods": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz", + "integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@apidevtools/swagger-parser": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-10.1.1.tgz", + "integrity": "sha512-u/kozRnsPO/x8QtKYJOqoGtC4kH6yg1lfYkB9Au0WhYB0FNLpyFusttQtvhlwjtG3rOwiRz4D8DnnXa8iEpIKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@apidevtools/json-schema-ref-parser": "11.7.2", + "@apidevtools/openapi-schemas": "^2.1.0", + "@apidevtools/swagger-methods": "^3.0.2", + "@jsdevtools/ono": "^7.1.3", + "ajv": "^8.17.1", + "ajv-draft-04": "^1.0.0", + "call-me-maybe": "^1.0.2" + }, + "peerDependencies": { + "openapi-types": ">=7" + } + }, + "node_modules/@apidevtools/swagger-parser/node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@apidevtools/swagger-parser/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, "node_modules/@aws-crypto/crc32": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", @@ -1005,6 +1084,163 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/compat-data": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-validator-identifier": { "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", @@ -1015,6 +1251,94 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -1553,6 +1877,38 @@ } } }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", @@ -1560,6 +1916,73 @@ "dev": true, "license": "MIT" }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsdevtools/ono": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@liuli-util/fs-extra": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@liuli-util/fs-extra/-/fs-extra-0.1.0.tgz", + "integrity": "sha512-eaAyDyMGT23QuRGbITVY3SOJff3G9ekAAyGqB9joAnTBmqvFN+9a1FazOdO70G6IUqgpKV451eBHYSRcOJ/FNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/fs-extra": "^9.0.13", + "fs-extra": "^10.1.0" + } + }, + "node_modules/@liuli-util/fs-extra/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@liuli-util/fs-extra/node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@liuli-util/fs-extra/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/@napi-rs/wasm-runtime": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.3.tgz", @@ -2900,6 +3323,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/fs-extra": { + "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/http-cache-semantics": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", @@ -3304,6 +3737,17 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/@zodios/core": { + "version": "10.9.6", + "resolved": "https://registry.npmjs.org/@zodios/core/-/core-10.9.6.tgz", + "integrity": "sha512-aH4rOdb3AcezN7ws8vDgBfGboZMk2JGGzEq/DtW65MhnRxyTGRuLJRWVQ/2KxDgWvV2F5oTkAS+5pnjKbl0n+A==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "axios": "^0.x || ^1.0.0", + "zod": "^3.x" + } + }, "node_modules/acorn": { "version": "8.16.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", @@ -3354,6 +3798,21 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-draft-04": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", + "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^8.5.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -3445,15 +3904,47 @@ "retry": "0.13.1" } }, - "node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.0.tgz", + "integrity": "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", + "proxy-from-env": "^2.1.0" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "license": "MIT", "engines": { "node": "18 || 20 || >=22" } }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.20", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.20.tgz", + "integrity": "sha512-1AaXxEPfXT+GvTBJFuy4yXVHWJBXa4OdbIebGN/wX5DlsIkU0+wzGnd2lOzokSk51d5LUmqjgBLRLlypLUqInQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/bowser": { "version": "2.14.1", "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz", @@ -3486,6 +3977,50 @@ "node": ">=8" } }, + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/cacheable-lookup": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", @@ -3515,6 +4050,27 @@ "node": ">=14.16" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", + "dev": true, + "license": "MIT" + }, "node_modules/camel-case": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", @@ -3526,6 +4082,27 @@ "tslib": "^2.0.3" } }, + "node_modules/caniuse-lite": { + "version": "1.0.30001788", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001788.tgz", + "integrity": "sha512-6q8HFp+lOQtcf7wBK+uEenxymVWkGKkjFpCvw5W25cmMwEDU45p1xQFBQv8JDlMMry7eNxyBaR+qxgmTUZkIRQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, "node_modules/capital-case": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", @@ -3663,6 +4240,19 @@ "dev": true, "license": "MIT" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/config-chain": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", @@ -3781,6 +4371,16 @@ "node": ">=10" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/detect-indent": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-7.0.2.tgz", @@ -3828,6 +4428,21 @@ "tslib": "^2.0.3" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/ejs": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", @@ -3843,6 +4458,13 @@ "node": ">=0.10.0" } }, + "node_modules/electron-to-chromium": { + "version": "1.5.340", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.340.tgz", + "integrity": "sha512-908qahOGocRMinT2nM3ajCEM99H4iPdv84eagPP3FfZy/1ZGeOy2CZYzjhms81ckOPCXPlW7LkY4XpxD8r1DrA==", + "dev": true, + "license": "ISC" + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -3859,6 +4481,26 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-module-lexer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", @@ -3866,6 +4508,45 @@ "dev": true, "license": "MIT" }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -4076,6 +4757,13 @@ "node": ">=0.10.0" } }, + "node_modules/eval-estree-expression": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eval-estree-expression/-/eval-estree-expression-3.0.1.tgz", + "integrity": "sha512-zTLKGbiVdQYp4rQkSoXPibrFf5ZoPn6jzExegRLEQ13F+FSxu5iLgaRH6hlDs2kWSUa6vp8yD20cdJi0me6pEw==", + "dev": true, + "license": "MIT" + }, "node_modules/expect-type": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", @@ -4109,6 +4797,23 @@ "fastest-levenshtein": "^1.0.7" } }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/fast-xml-builder": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz", @@ -4282,6 +4987,44 @@ "dev": true, "license": "ISC" }, + "node_modules/follow-redirects": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/form-data-encoder": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", @@ -4322,6 +5065,51 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -4331,6 +5119,20 @@ "node": ">=8.0.0" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-stdin": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", @@ -4387,6 +5189,19 @@ "node": ">=10.13.0" } }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/got": { "version": "13.0.0", "resolved": "https://registry.npmjs.org/got/-/got-13.0.0.tgz", @@ -4420,6 +5235,28 @@ "dev": true, "license": "ISC" }, + "node_modules/handlebars": { + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", + "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -4429,6 +5266,48 @@ "node": ">=8" } }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", + "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/header-case": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", @@ -4737,6 +5616,19 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -4765,6 +5657,19 @@ "dev": true, "license": "MIT" }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", @@ -5141,6 +6046,16 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -5168,6 +6083,29 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/mimic-response": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", @@ -5196,6 +6134,16 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -5237,6 +6185,13 @@ "dev": true, "license": "MIT" }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -5248,6 +6203,13 @@ "tslib": "^2.0.3" } }, + "node_modules/node-releases": { + "version": "2.0.37", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.37.tgz", + "integrity": "sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==", + "dev": true, + "license": "MIT" + }, "node_modules/normalize-package-data": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", @@ -5502,6 +6464,13 @@ "openapi-typescript-helpers": "^0.1.0" } }, + "node_modules/openapi-types": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz", + "integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==", + "dev": true, + "license": "MIT" + }, "node_modules/openapi-typescript": { "version": "7.13.0", "resolved": "https://registry.npmjs.org/openapi-typescript/-/openapi-typescript-7.13.0.tgz", @@ -5580,6 +6549,42 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/openapi-zod-client": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/openapi-zod-client/-/openapi-zod-client-1.18.3.tgz", + "integrity": "sha512-10vYK7xo1yyZfcoRvYNGIsDeej1CG9k63u8dkjbGBlr+NHZMy2Iy2h9s11UWNKdj6XMDWbNOPp5gIy8YdpgPtQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@apidevtools/swagger-parser": "^10.1.0", + "@liuli-util/fs-extra": "^0.1.0", + "@zodios/core": "^10.3.1", + "axios": "^1.6.0", + "cac": "^6.7.14", + "handlebars": "^4.7.7", + "openapi-types": "^12.0.2", + "openapi3-ts": "3.1.0", + "pastable": "^2.2.1", + "prettier": "^2.7.1", + "tanu": "^0.1.13", + "ts-pattern": "^5.0.1", + "whence": "^2.0.0", + "zod": "^3.19.1" + }, + "bin": { + "openapi-zod-client": "bin.js" + } + }, + "node_modules/openapi3-ts": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/openapi3-ts/-/openapi3-ts-3.1.0.tgz", + "integrity": "sha512-1qKTvCCVoV0rkwUh1zq5o8QyghmwYPuhdvtjv1rFjuOnJToXhQyF8eGjNETQ8QmGjr9Jz/tkAKLITIl2s7dw3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "yaml": "^2.1.3" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -5683,6 +6688,45 @@ "tslib": "^2.0.3" } }, + "node_modules/pastable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/pastable/-/pastable-2.2.1.tgz", + "integrity": "sha512-K4ClMxRKpgN4sXj6VIPPrvor/TMp2yPNCGtfhvV106C73SwefQ3FuegURsH7AQHpqu0WwbvKXRl1HQxF6qax9w==", + "dev": true, + "dependencies": { + "@babel/core": "^7.20.12", + "ts-toolbelt": "^9.6.0", + "type-fest": "^3.5.3" + }, + "engines": { + "node": ">=14.x" + }, + "peerDependencies": { + "react": ">=17", + "xstate": ">=4.32.1" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "xstate": { + "optional": true + } + } + }, + "node_modules/pastable/node_modules/type-fest": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/path-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", @@ -5804,6 +6848,22 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/proto-list": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", @@ -5811,6 +6871,16 @@ "dev": true, "license": "ISC" }, + "node_modules/proxy-from-env": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -6055,6 +7125,16 @@ "sort-package-json": "cli.js" } }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -6169,6 +7249,31 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/tanu": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/tanu/-/tanu-0.1.13.tgz", + "integrity": "sha512-UbRmX7ccZ4wMVOY/Uw+7ji4VOkEYSYJG1+I4qzbnn4qh/jtvVbrm6BFnF12NQQ4+jGv21wKmjb1iFyUSVnBWcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0", + "typescript": "^4.7.4" + } + }, + "node_modules/tanu/node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/tiny-jsonc": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/tiny-jsonc/-/tiny-jsonc-1.0.2.tgz", @@ -6245,6 +7350,20 @@ "typescript": ">=4.8.4" } }, + "node_modules/ts-pattern": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/ts-pattern/-/ts-pattern-5.9.0.tgz", + "integrity": "sha512-6s5V71mX8qBUmlgbrfL33xDUwO0fq48rxAu2LBE11WBeGdpCPOsXksQbZJHvHwhrd3QjUusd3mAOM5Gg0mFBLg==", + "dev": true, + "license": "MIT" + }, + "node_modules/ts-toolbelt": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz", + "integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -6304,6 +7423,20 @@ "node": ">=14.17" } }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/undici-types": { "version": "7.18.2", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", @@ -6321,6 +7454,37 @@ "node": ">= 4.0.0" } }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, "node_modules/upper-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", @@ -6547,6 +7711,20 @@ } } }, + "node_modules/whence": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/whence/-/whence-2.1.0.tgz", + "integrity": "sha512-4UBPMg5mng5KLzdliVQdQ4fJwCdIMXkE8CkoDmGKRy5r8pV9xq+nVgf/sKXpmNEIOtFp7m7v2bFdb7JoLvh+Hg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.0", + "eval-estree-expression": "^3.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -6625,6 +7803,13 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, "node_modules/yaml": { "version": "2.8.3", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", diff --git a/package.json b/package.json index c84d402..5e3cd5c 100644 --- a/package.json +++ b/package.json @@ -23,8 +23,9 @@ "types": "dist/index.d.ts", "scripts": { "typegen": "openapi-typescript docs/openapi/monitoring-api.json -o src/lib/api.generated.ts", + "zodgen": "node scripts/generate-zod.mjs", "descgen": "node scripts/extract-descriptions.mjs", - "build": "npm run typegen && npm run descgen && tsc -b && oclif manifest", + "build": "npm run typegen && npm run zodgen && npm run descgen && tsc -b && oclif manifest", "lint": "eslint src/ test/", "lint:fix": "eslint src/ test/ --fix", "test": "vitest run", @@ -76,6 +77,7 @@ "eslint": "^10.2.0", "oclif": "^4.23.0", "openapi-typescript": "^7.13.0", + "openapi-zod-client": "^1.18.3", "typescript": "^6.0.2", "vitest": "^4.1.4" } diff --git a/scripts/generate-zod.mjs b/scripts/generate-zod.mjs new file mode 100644 index 0000000..fef05f0 --- /dev/null +++ b/scripts/generate-zod.mjs @@ -0,0 +1,134 @@ +#!/usr/bin/env node +/** + * Generate Zod schemas from the OpenAPI spec for CLI validation. + * + * Applies the same Springdoc preprocessing as the dashboard's sync-schema, + * then runs openapi-zod-client to produce typed Zod schemas that the YAML + * validation layer imports. + * + * Usage: node scripts/generate-zod.mjs + * + * Preprocessing logic is kept in sync with packages/openapi-tools in the + * monorepo. If you change preprocessing there, update it here too. + */ + +import { readFileSync, writeFileSync, mkdirSync } from 'node:fs'; +import { dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { generateZodClientFromOpenAPI } from 'openapi-zod-client'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const ROOT = join(__dirname, '..'); +const SPEC_PATH = join(ROOT, 'docs/openapi/monitoring-api.json'); +const OUTPUT_PATH = join(ROOT, 'src/lib/api-zod.generated.ts'); + +// ── Springdoc preprocessing (synced from packages/openapi-tools) ────── + +function setRequiredFields(spec) { + const schemas = spec.components?.schemas ?? {}; + for (const schema of Object.values(schemas)) { + if (schema.type !== 'object' || !schema.properties) continue; + if (Array.isArray(schema.required)) { + for (const [prop, propSchema] of Object.entries(schema.properties)) { + if (propSchema.nullable) continue; + if (propSchema.oneOf && !schema.required.includes(prop)) { + schema.required.push(prop); + } + } + continue; + } + const required = []; + for (const [prop, propSchema] of Object.entries(schema.properties)) { + if (propSchema.nullable) continue; + if (propSchema.allOf) continue; + required.push(prop); + } + if (required.length > 0) schema.required = required; + } +} + +function setRequiredOnAllOfMembers(spec) { + const schemas = spec.components?.schemas ?? {}; + for (const schema of Object.values(schemas)) { + if (!Array.isArray(schema.allOf)) continue; + for (const member of schema.allOf) { + if (!member.properties) continue; + if (Array.isArray(member.required)) continue; + const required = []; + for (const [prop, propSchema] of Object.entries(member.properties)) { + if (propSchema.nullable) continue; + if (propSchema.allOf) continue; + required.push(prop); + } + if (required.length > 0) member.required = required; + } + } +} + +function pushRequiredIntoAllOf(spec) { + const schemas = spec.components?.schemas ?? {}; + for (const schema of Object.values(schemas)) { + if (!Array.isArray(schema.required) || !Array.isArray(schema.allOf)) continue; + for (const member of schema.allOf) { + if (!member.properties) continue; + const memberRequired = []; + for (const field of schema.required) { + if (field in member.properties) memberRequired.push(field); + } + if (memberRequired.length > 0) { + member.required = member.required + ? [...new Set([...member.required, ...memberRequired])] + : memberRequired; + } + } + } +} + +// ── Post-processing (strip Zodios client, keep only Zod schemas) ───── +// Same approach as sdk-js/scripts/generate-schemas.js + +function extractSchemas(raw) { + const lines = raw.split('\n'); + const kept = []; + for (const line of lines) { + if (line.startsWith('const endpoints = makeApi') || line.startsWith('export const api')) break; + if (line.includes('@zodios/core')) continue; + kept.push(line); + } + return '// @ts-nocheck\n// Auto-generated Zod schemas from OpenAPI spec. DO NOT EDIT.\n' + + kept.join('\n') + '\n'; +} + +// ── Main ────────────────────────────────────────────────────────────── + +async function main() { + console.log('Reading spec from', SPEC_PATH); + const spec = JSON.parse(readFileSync(SPEC_PATH, 'utf8')); + + setRequiredFields(spec); + setRequiredOnAllOfMembers(spec); + pushRequiredIntoAllOf(spec); + console.log(`Preprocessed spec (${Object.keys(spec.components?.schemas ?? {}).length} schemas)`); + + mkdirSync(dirname(OUTPUT_PATH), { recursive: true }); + + await generateZodClientFromOpenAPI({ + openApiDoc: spec, + distPath: OUTPUT_PATH, + options: { + exportSchemas: true, + }, + }); + + const raw = readFileSync(OUTPUT_PATH, 'utf8'); + const clean = extractSchemas(raw); + writeFileSync(OUTPUT_PATH, clean, 'utf8'); + + const schemaCount = (clean.match(/^const /gm) || []).length; + console.log(`Generated Zod schemas (${schemaCount} schemas) → ${OUTPUT_PATH}`); +} + +main().catch((err) => { + console.error(err.message); + process.exit(1); +}); diff --git a/src/commands/init.ts b/src/commands/init.ts index 2cbf94f..98a60f4 100644 --- a/src/commands/init.ts +++ b/src/commands/init.ts @@ -8,7 +8,7 @@ version: "1" # defaults: # monitors: -# frequency: 60 +# frequencySeconds: 60 # regions: [us-east, eu-west] # enabled: true @@ -27,8 +27,8 @@ tags: alertChannels: - name: ops-slack - type: slack config: + channelType: slack webhookUrl: \${SLACK_WEBHOOK_URL:-https://hooks.slack.com/services/REPLACE_ME} # notificationPolicies: @@ -42,7 +42,7 @@ alertChannels: # webhooks: # - url: https://hooks.example.com/devhelm -# events: [monitor.down, monitor.recovered] +# subscribedEvents: [monitor.down, monitor.recovered] # resourceGroups: # - name: API Services @@ -55,22 +55,22 @@ monitors: url: https://example.com method: GET verifyTls: true - frequency: 60 + frequencySeconds: 60 regions: [us-east, eu-west] tags: [production] alertChannels: [ops-slack] assertions: - - type: StatusCodeAssertion - config: + - config: + type: status_code expected: "200" operator: equals severity: fail - - type: ResponseTimeAssertion - config: + - config: + type: response_time thresholdMs: 2000 severity: warn - - type: SslExpiryAssertion - config: + - config: + type: ssl_expiry minDaysRemaining: 30 severity: warn @@ -79,16 +79,17 @@ monitors: # config: # url: https://api.example.com/health # method: GET - # frequency: 30 + # frequencySeconds: 30 # - name: DNS Check # type: DNS # config: # hostname: example.com # recordTypes: [A, AAAA, MX] - # frequency: 300 + # frequencySeconds: 300 # assertions: - # - type: DnsResolvesAssertion + # - config: + # type: dns_resolves # severity: fail # - name: Heartbeat Worker @@ -102,7 +103,7 @@ monitors: # config: # command: npx # args: ["-y", "@company/mcp-server"] - # frequency: 300 + # frequencySeconds: 300 # dependencies: # - service: github diff --git a/src/lib/api-zod.generated.ts b/src/lib/api-zod.generated.ts new file mode 100644 index 0000000..97ff5f9 --- /dev/null +++ b/src/lib/api-zod.generated.ts @@ -0,0 +1,1309 @@ +// @ts-nocheck +// Auto-generated Zod schemas from OpenAPI spec. DO NOT EDIT. +import { z } from "zod"; + +const pageable = z + .object({ + page: z.number().int().gte(0), + size: z.number().int().gte(1), + sort: z.array(z.string()), + }) + .passthrough(); +const ChannelConfig = z.object({ channelType: z.string() }).passthrough(); +const DiscordChannelConfig = ChannelConfig.and( + z + .object({ + webhookUrl: z.string().min(1), + mentionRoleId: z.string().nullish(), + }) + .passthrough() +); +const EmailChannelConfig = ChannelConfig.and( + z.object({ recipients: z.array(z.string().email()).min(1) }).passthrough() +); +const OpsGenieChannelConfig = ChannelConfig.and( + z + .object({ apiKey: z.string().min(1), region: z.string().nullish() }) + .passthrough() +); +const PagerDutyChannelConfig = ChannelConfig.and( + z + .object({ + routingKey: z.string().min(1), + severityOverride: z.string().nullish(), + }) + .passthrough() +); +const SlackChannelConfig = ChannelConfig.and( + z + .object({ + webhookUrl: z.string().min(1), + mentionText: z.string().nullish(), + }) + .passthrough() +); +const TeamsChannelConfig = ChannelConfig.and( + z.object({ webhookUrl: z.string().min(1) }).passthrough() +); +const WebhookChannelConfig = ChannelConfig.and( + z + .object({ + url: z.string().min(1), + signingSecret: z.string().nullish(), + customHeaders: z.record(z.string().nullable()).nullish(), + }) + .passthrough() +); +const CreateAlertChannelRequest = z + .object({ + name: z.string().min(0).max(255), + config: z.union([ + DiscordChannelConfig, + EmailChannelConfig, + OpsGenieChannelConfig, + PagerDutyChannelConfig, + SlackChannelConfig, + TeamsChannelConfig, + WebhookChannelConfig, + ]), + }) + .passthrough(); +const UpdateAlertChannelRequest = z + .object({ + name: z.string().min(0).max(255), + config: z.union([ + DiscordChannelConfig, + EmailChannelConfig, + OpsGenieChannelConfig, + PagerDutyChannelConfig, + SlackChannelConfig, + TeamsChannelConfig, + WebhookChannelConfig, + ]), + }) + .passthrough(); +const TestAlertChannelRequest = z + .object({ + config: z.union([ + DiscordChannelConfig, + EmailChannelConfig, + OpsGenieChannelConfig, + PagerDutyChannelConfig, + SlackChannelConfig, + TeamsChannelConfig, + WebhookChannelConfig, + ]), + }) + .passthrough(); +const CreateApiKeyRequest = z + .object({ + name: z.string().min(0).max(200), + expiresAt: z.string().datetime({ offset: true }).nullish(), + }) + .passthrough(); +const UpdateApiKeyRequest = z + .object({ name: z.string().min(0).max(200) }) + .passthrough(); +const AcquireDeployLockRequest = z + .object({ + lockedBy: z.string().min(1), + ttlMinutes: z.number().int().nullish(), + }) + .passthrough(); +const CreateEnvironmentRequest = z + .object({ + name: z.string().min(0).max(100), + slug: z + .string() + .min(0) + .max(100) + .regex(/^[a-z0-9][a-z0-9_-]*$/), + variables: z.record(z.string().nullable()).nullish(), + isDefault: z.boolean().optional(), + }) + .passthrough(); +const UpdateEnvironmentRequest = z + .object({ + name: z.string().min(0).max(100).nullable(), + variables: z.record(z.string().nullable()).nullable(), + isDefault: z.boolean().nullable(), + }) + .partial() + .passthrough(); +const params = z + .object({ + status: z + .enum(["WATCHING", "TRIGGERED", "CONFIRMED", "RESOLVED"]) + .nullish(), + severity: z.enum(["DOWN", "DEGRADED", "MAINTENANCE"]).nullish(), + source: z + .enum([ + "AUTOMATIC", + "MANUAL", + "MONITORS", + "STATUS_DATA", + "RESOURCE_GROUP", + ]) + .nullish(), + monitorId: z.string().uuid().nullish(), + serviceId: z.string().uuid().nullish(), + resourceGroupId: z.string().uuid().nullish(), + tagId: z.string().uuid().nullish(), + environmentId: z.string().uuid().nullish(), + startedFrom: z.string().datetime({ offset: true }).nullish(), + startedTo: z.string().datetime({ offset: true }).nullish(), + page: z.number().int().gte(0), + size: z.number().int().gte(1).lte(200), + }) + .passthrough(); +const CreateManualIncidentRequest = z + .object({ + title: z.string().min(1), + severity: z.enum(["DOWN", "DEGRADED", "MAINTENANCE"]), + monitorId: z.string().uuid().nullish(), + body: z.string().nullish(), + }) + .passthrough(); +const ResolveIncidentRequest = z.object({ body: z.string() }).passthrough(); +const AddIncidentUpdateRequest = z + .object({ + body: z.string().nullish(), + newStatus: z + .enum(["WATCHING", "TRIGGERED", "CONFIRMED", "RESOLVED"]) + .nullish(), + notifySubscribers: z.boolean(), + }) + .passthrough(); +const CreateInviteRequest = z + .object({ + email: z.string().min(1).email(), + roleOffered: z.enum(["OWNER", "ADMIN", "MEMBER"]), + }) + .passthrough(); +const CreateMaintenanceWindowRequest = z + .object({ + monitorId: z.string().uuid().nullish(), + startsAt: z.string().datetime({ offset: true }), + endsAt: z.string().datetime({ offset: true }), + repeatRule: z.string().min(0).max(100).nullish(), + reason: z.string().nullish(), + suppressAlerts: z.boolean().nullish(), + }) + .passthrough(); +const UpdateMaintenanceWindowRequest = z + .object({ + monitorId: z.string().uuid().nullish(), + startsAt: z.string().datetime({ offset: true }), + endsAt: z.string().datetime({ offset: true }), + repeatRule: z.string().min(0).max(100).nullish(), + reason: z.string().nullish(), + suppressAlerts: z.boolean().nullish(), + }) + .passthrough(); +const ChangeRoleRequest = z + .object({ orgRole: z.enum(["OWNER", "ADMIN", "MEMBER"]) }) + .passthrough(); +const ChangeStatusRequest = z + .object({ + status: z.enum([ + "INVITED", + "ACTIVE", + "SUSPENDED", + "LEFT", + "REMOVED", + "DECLINED", + ]), + }) + .passthrough(); +const MonitorConfig = z.object({}).partial().passthrough(); +const DnsMonitorConfig = MonitorConfig.and( + z + .object({ + hostname: z.string().min(1), + recordTypes: z + .array( + z + .enum([ + "A", + "AAAA", + "CNAME", + "MX", + "NS", + "TXT", + "SRV", + "SOA", + "CAA", + "PTR", + ]) + .nullable() + ) + .nullish(), + nameservers: z.array(z.string().nullable()).nullish(), + timeoutMs: z.number().int().nullish(), + totalTimeoutMs: z.number().int().nullish(), + }) + .passthrough() +); +const HeartbeatMonitorConfig = MonitorConfig.and( + z + .object({ + expectedInterval: z.number().int().gte(1).lte(86400), + gracePeriod: z.number().int().gte(1), + }) + .passthrough() +); +const HttpMonitorConfig = MonitorConfig.and( + z + .object({ + url: z.string().min(1), + method: z.enum(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"]), + customHeaders: z.record(z.string().nullable()).nullish(), + requestBody: z.string().nullish(), + contentType: z.string().nullish(), + verifyTls: z.boolean().nullish(), + }) + .passthrough() +); +const IcmpMonitorConfig = MonitorConfig.and( + z + .object({ + host: z.string().min(1), + packetCount: z.number().int().gte(1).lte(20).nullish(), + timeoutMs: z.number().int().nullish(), + }) + .passthrough() +); +const McpServerMonitorConfig = MonitorConfig.and( + z + .object({ + command: z.string().min(1), + args: z.array(z.string().nullable()).nullish(), + env: z.record(z.string().nullable()).nullish(), + }) + .passthrough() +); +const TcpMonitorConfig = MonitorConfig.and( + z + .object({ + host: z.string().min(1), + port: z.number().int().gte(1).lte(65535), + timeoutMs: z.number().int().nullish(), + }) + .passthrough() +); +const AssertionConfig = z.object({ type: z.string() }).passthrough(); +const BodyContainsAssertion = AssertionConfig.and( + z.object({ substring: z.string().min(1) }).passthrough() +); +const DnsExpectedCnameAssertion = AssertionConfig.and( + z.object({ value: z.string().min(1) }).passthrough() +); +const DnsExpectedIpsAssertion = AssertionConfig.and( + z.object({ ips: z.array(z.string()).min(1) }).passthrough() +); +const DnsMaxAnswersAssertion = AssertionConfig.and( + z + .object({ recordType: z.string().min(1), max: z.number().int() }) + .passthrough() +); +const DnsMinAnswersAssertion = AssertionConfig.and( + z + .object({ recordType: z.string().min(1), min: z.number().int() }) + .passthrough() +); +const DnsRecordContainsAssertion = AssertionConfig.and( + z + .object({ recordType: z.string().min(1), substring: z.string().min(1) }) + .passthrough() +); +const DnsRecordEqualsAssertion = AssertionConfig.and( + z + .object({ recordType: z.string().min(1), value: z.string().min(1) }) + .passthrough() +); +const DnsResolvesAssertion = AssertionConfig; +const DnsResponseTimeAssertion = AssertionConfig.and( + z.object({ maxMs: z.number().int() }).passthrough() +); +const DnsResponseTimeWarnAssertion = AssertionConfig.and( + z.object({ warnMs: z.number().int() }).passthrough() +); +const DnsTtlHighAssertion = AssertionConfig.and( + z.object({ maxTtl: z.number().int() }).passthrough() +); +const DnsTtlLowAssertion = AssertionConfig.and( + z.object({ minTtl: z.number().int() }).passthrough() +); +const DnsTxtContainsAssertion = AssertionConfig.and( + z.object({ substring: z.string().min(1) }).passthrough() +); +const HeaderValueAssertion = AssertionConfig.and( + z + .object({ + headerName: z.string().min(1), + expected: z.string().min(1), + operator: z.enum([ + "equals", + "contains", + "less_than", + "greater_than", + "matches", + "range", + ]), + }) + .passthrough() +); +const HeartbeatIntervalDriftAssertion = AssertionConfig.and( + z + .object({ maxDeviationPercent: z.number().int().gte(1).lte(100) }) + .passthrough() +); +const HeartbeatMaxIntervalAssertion = AssertionConfig.and( + z.object({ maxSeconds: z.number().int().gte(1) }).passthrough() +); +const HeartbeatPayloadContainsAssertion = AssertionConfig.and( + z.object({ path: z.string().min(1), value: z.string() }).passthrough() +); +const HeartbeatReceivedAssertion = AssertionConfig; +const IcmpPacketLossAssertion = AssertionConfig.and( + z.object({ maxPercent: z.number().gte(0).lte(100) }).passthrough() +); +const IcmpReachableAssertion = AssertionConfig; +const IcmpResponseTimeAssertion = AssertionConfig.and( + z.object({ maxMs: z.number().int() }).passthrough() +); +const IcmpResponseTimeWarnAssertion = AssertionConfig.and( + z.object({ warnMs: z.number().int() }).passthrough() +); +const JsonPathAssertion = AssertionConfig.and( + z + .object({ + path: z.string().min(1), + expected: z.string().min(1), + operator: z.enum([ + "equals", + "contains", + "less_than", + "greater_than", + "matches", + "range", + ]), + }) + .passthrough() +); +const McpConnectsAssertion = AssertionConfig; +const McpHasCapabilityAssertion = AssertionConfig.and( + z.object({ capability: z.string().min(1) }).passthrough() +); +const McpMinToolsAssertion = AssertionConfig.and( + z.object({ min: z.number().int() }).passthrough() +); +const McpProtocolVersionAssertion = AssertionConfig.and( + z.object({ version: z.string().min(1) }).passthrough() +); +const McpResponseTimeAssertion = AssertionConfig.and( + z.object({ maxMs: z.number().int() }).passthrough() +); +const McpResponseTimeWarnAssertion = AssertionConfig.and( + z.object({ warnMs: z.number().int() }).passthrough() +); +const McpToolAvailableAssertion = AssertionConfig.and( + z.object({ toolName: z.string().min(1) }).passthrough() +); +const McpToolCountChangedAssertion = AssertionConfig.and( + z.object({ expectedCount: z.number().int() }).passthrough() +); +const RedirectCountAssertion = AssertionConfig.and( + z.object({ maxCount: z.number().int() }).passthrough() +); +const RedirectTargetAssertion = AssertionConfig.and( + z + .object({ + expected: z.string().min(1), + operator: z.enum([ + "equals", + "contains", + "less_than", + "greater_than", + "matches", + "range", + ]), + }) + .passthrough() +); +const RegexBodyAssertion = AssertionConfig.and( + z.object({ pattern: z.string().min(1) }).passthrough() +); +const ResponseSizeAssertion = AssertionConfig.and( + z.object({ maxBytes: z.number().int() }).passthrough() +); +const ResponseTimeAssertion = AssertionConfig.and( + z.object({ thresholdMs: z.number().int() }).passthrough() +); +const ResponseTimeWarnAssertion = AssertionConfig.and( + z.object({ warnMs: z.number().int() }).passthrough() +); +const SslExpiryAssertion = AssertionConfig.and( + z.object({ minDaysRemaining: z.number().int() }).passthrough() +); +const StatusCodeAssertion = AssertionConfig.and( + z + .object({ + expected: z.string().min(1), + operator: z.enum([ + "equals", + "contains", + "less_than", + "greater_than", + "matches", + "range", + ]), + }) + .passthrough() +); +const TcpConnectsAssertion = AssertionConfig; +const TcpResponseTimeAssertion = AssertionConfig.and( + z.object({ maxMs: z.number().int() }).passthrough() +); +const TcpResponseTimeWarnAssertion = AssertionConfig.and( + z.object({ warnMs: z.number().int() }).passthrough() +); +const CreateAssertionRequest = z + .object({ + config: z.union([ + BodyContainsAssertion, + DnsExpectedCnameAssertion, + DnsExpectedIpsAssertion, + DnsMaxAnswersAssertion, + DnsMinAnswersAssertion, + DnsRecordContainsAssertion, + DnsRecordEqualsAssertion, + DnsResolvesAssertion, + DnsResponseTimeAssertion, + DnsResponseTimeWarnAssertion, + DnsTtlHighAssertion, + DnsTtlLowAssertion, + DnsTxtContainsAssertion, + HeaderValueAssertion, + HeartbeatIntervalDriftAssertion, + HeartbeatMaxIntervalAssertion, + HeartbeatPayloadContainsAssertion, + HeartbeatReceivedAssertion, + IcmpPacketLossAssertion, + IcmpReachableAssertion, + IcmpResponseTimeAssertion, + IcmpResponseTimeWarnAssertion, + JsonPathAssertion, + McpConnectsAssertion, + McpHasCapabilityAssertion, + McpMinToolsAssertion, + McpProtocolVersionAssertion, + McpResponseTimeAssertion, + McpResponseTimeWarnAssertion, + McpToolAvailableAssertion, + McpToolCountChangedAssertion, + RedirectCountAssertion, + RedirectTargetAssertion, + RegexBodyAssertion, + ResponseSizeAssertion, + ResponseTimeAssertion, + ResponseTimeWarnAssertion, + SslExpiryAssertion, + StatusCodeAssertion, + TcpConnectsAssertion, + TcpResponseTimeAssertion, + TcpResponseTimeWarnAssertion, + ]), + severity: z.enum(["fail", "warn"]), + }) + .passthrough(); +const MonitorAuthConfig = z.object({ type: z.string() }).passthrough(); +const TriggerRule = z + .object({ + type: z.enum([ + "consecutive_failures", + "failures_in_window", + "response_time", + ]), + count: z.number().int().nullish(), + windowMinutes: z.number().int().nullish(), + scope: z.enum(["per_region", "any_region"]).nullable(), + thresholdMs: z.number().int().nullish(), + severity: z.enum(["down", "degraded"]), + aggregationType: z.enum(["all_exceed", "average", "p95", "max"]).nullish(), + }) + .passthrough(); +const ConfirmationPolicy = z + .object({ + type: z.literal("multi_region"), + minRegionsFailing: z.number().int().optional(), + maxWaitSeconds: z.number().int().optional(), + }) + .passthrough(); +const RecoveryPolicy = z + .object({ + consecutiveSuccesses: z.number().int(), + minRegionsPassing: z.number().int(), + cooldownMinutes: z.number().int(), + }) + .passthrough(); +const UpdateIncidentPolicyRequest = z + .object({ + triggerRules: z.array(TriggerRule).min(1), + confirmation: ConfirmationPolicy, + recovery: RecoveryPolicy, + }) + .passthrough(); +const NewTagRequest = z + .object({ + name: z.string().min(0).max(100), + color: z + .string() + .regex(/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/) + .nullish(), + }) + .passthrough(); +const AddMonitorTagsRequest = z + .object({ + tagIds: z.array(z.string().uuid()).nullable(), + newTags: z.array(NewTagRequest).nullable(), + }) + .partial() + .passthrough(); +const CreateMonitorRequest = z + .object({ + name: z.string().min(0).max(255), + type: z.enum(["HTTP", "DNS", "MCP_SERVER", "TCP", "ICMP", "HEARTBEAT"]), + config: z.union([ + DnsMonitorConfig, + HeartbeatMonitorConfig, + HttpMonitorConfig, + IcmpMonitorConfig, + McpServerMonitorConfig, + TcpMonitorConfig, + ]), + frequencySeconds: z.number().int().nullish(), + enabled: z.boolean().nullish(), + regions: z.array(z.string()).nullish(), + managedBy: z.enum(["DASHBOARD", "CLI", "TERRAFORM"]), + environmentId: z.string().uuid().nullish(), + assertions: z.array(CreateAssertionRequest).nullish(), + auth: MonitorAuthConfig.nullish(), + incidentPolicy: UpdateIncidentPolicyRequest.nullish(), + alertChannelIds: z.array(z.string().uuid()).nullish(), + tags: AddMonitorTagsRequest.nullish(), + }) + .passthrough(); +const UpdateMonitorRequest = z + .object({ + name: z.string().min(0).max(255).nullable(), + config: MonitorConfig.nullable(), + frequencySeconds: z.number().int().nullable(), + enabled: z.boolean().nullable(), + regions: z.array(z.string()).nullable(), + managedBy: z.enum(["DASHBOARD", "CLI", "TERRAFORM"]).nullable(), + environmentId: z.string().uuid().nullable(), + clearEnvironmentId: z.boolean().nullable(), + assertions: z.array(CreateAssertionRequest).nullable(), + auth: MonitorAuthConfig.nullable(), + clearAuth: z.boolean().nullable(), + incidentPolicy: UpdateIncidentPolicyRequest.nullable(), + alertChannelIds: z.array(z.string().uuid()).nullable(), + tags: AddMonitorTagsRequest.nullable(), + }) + .partial() + .passthrough(); +const RemoveMonitorTagsRequest = z + .object({ tagIds: z.array(z.string().uuid()).min(1) }) + .passthrough(); +const SetAlertChannelsRequest = z + .object({ channelIds: z.array(z.string().uuid()) }) + .passthrough(); +const UpdateAssertionRequest = z + .object({ + config: z.union([ + BodyContainsAssertion, + DnsExpectedCnameAssertion, + DnsExpectedIpsAssertion, + DnsMaxAnswersAssertion, + DnsMinAnswersAssertion, + DnsRecordContainsAssertion, + DnsRecordEqualsAssertion, + DnsResolvesAssertion, + DnsResponseTimeAssertion, + DnsResponseTimeWarnAssertion, + DnsTtlHighAssertion, + DnsTtlLowAssertion, + DnsTxtContainsAssertion, + HeaderValueAssertion, + HeartbeatIntervalDriftAssertion, + HeartbeatMaxIntervalAssertion, + HeartbeatPayloadContainsAssertion, + HeartbeatReceivedAssertion, + IcmpPacketLossAssertion, + IcmpReachableAssertion, + IcmpResponseTimeAssertion, + IcmpResponseTimeWarnAssertion, + JsonPathAssertion, + McpConnectsAssertion, + McpHasCapabilityAssertion, + McpMinToolsAssertion, + McpProtocolVersionAssertion, + McpResponseTimeAssertion, + McpResponseTimeWarnAssertion, + McpToolAvailableAssertion, + McpToolCountChangedAssertion, + RedirectCountAssertion, + RedirectTargetAssertion, + RegexBodyAssertion, + ResponseSizeAssertion, + ResponseTimeAssertion, + ResponseTimeWarnAssertion, + SslExpiryAssertion, + StatusCodeAssertion, + TcpConnectsAssertion, + TcpResponseTimeAssertion, + TcpResponseTimeWarnAssertion, + ]), + severity: z.enum(["fail", "warn"]).nullish(), + }) + .passthrough(); +const ApiKeyAuthConfig = MonitorAuthConfig.and( + z + .object({ + headerName: z + .string() + .min(1) + .regex(/^[A-Za-z0-9\-_]+$/), + vaultSecretId: z.string().uuid().nullish(), + }) + .passthrough() +); +const BasicAuthConfig = MonitorAuthConfig.and( + z + .object({ vaultSecretId: z.string().uuid().nullable() }) + .partial() + .passthrough() +); +const BearerAuthConfig = MonitorAuthConfig.and( + z + .object({ vaultSecretId: z.string().uuid().nullable() }) + .partial() + .passthrough() +); +const HeaderAuthConfig = MonitorAuthConfig.and( + z + .object({ + headerName: z + .string() + .min(1) + .regex(/^[A-Za-z0-9\-_]+$/), + vaultSecretId: z.string().uuid().nullish(), + }) + .passthrough() +); +const UpdateMonitorAuthRequest = z + .object({ + config: z.union([ + ApiKeyAuthConfig, + BasicAuthConfig, + BearerAuthConfig, + HeaderAuthConfig, + ]), + }) + .passthrough(); +const SetMonitorAuthRequest = z + .object({ + config: z.union([ + ApiKeyAuthConfig, + BasicAuthConfig, + BearerAuthConfig, + HeaderAuthConfig, + ]), + }) + .passthrough(); +const BulkMonitorActionRequest = z + .object({ + monitorIds: z.array(z.string().uuid()).max(200), + action: z.enum(["PAUSE", "RESUME", "DELETE", "ADD_TAG", "REMOVE_TAG"]), + tagIds: z.array(z.string().uuid()).nullish(), + newTags: z.array(NewTagRequest).nullish(), + }) + .passthrough(); +const MonitorTestRequest = z + .object({ + type: z.enum(["HTTP", "DNS", "MCP_SERVER", "TCP", "ICMP", "HEARTBEAT"]), + config: z.union([ + DnsMonitorConfig, + HeartbeatMonitorConfig, + HttpMonitorConfig, + IcmpMonitorConfig, + McpServerMonitorConfig, + TcpMonitorConfig, + ]), + assertions: z.array(CreateAssertionRequest).nullish(), + }) + .passthrough(); +const MatchRule = z + .object({ + type: z.string(), + value: z.string().nullish(), + monitorIds: z.array(z.string().uuid()).nullish(), + regions: z.array(z.string()).nullish(), + values: z.array(z.string()).nullish(), + }) + .passthrough(); +const EscalationStep = z + .object({ + delayMinutes: z.number().int().gte(0).optional(), + channelIds: z.array(z.string().uuid()).min(1), + requireAck: z.boolean().nullish(), + repeatIntervalSeconds: z.number().int().gte(1).nullish(), + }) + .passthrough(); +const EscalationChain = z + .object({ + steps: z.array(EscalationStep).min(1), + onResolve: z.string().nullish(), + onReopen: z.string().nullish(), + }) + .passthrough(); +const CreateNotificationPolicyRequest = z + .object({ + name: z.string().min(0).max(255), + matchRules: z.array(MatchRule), + escalation: EscalationChain, + enabled: z.boolean().default(true), + priority: z.number().int().default(0), + }) + .passthrough(); +const UpdateNotificationPolicyRequest = z + .object({ + name: z.string().min(0).max(255).nullable(), + matchRules: z.array(MatchRule).nullable(), + escalation: EscalationChain.nullable(), + enabled: z.boolean().nullable(), + priority: z.number().int().nullable(), + }) + .partial() + .passthrough(); +const TestNotificationPolicyRequest = z + .object({ + severity: z.string().nullable(), + monitorId: z.string().uuid().nullable(), + regions: z.array(z.string()).nullable(), + eventType: z.string().nullable(), + monitorType: z.string().nullable(), + serviceId: z.string().uuid().nullable(), + componentName: z.string().nullable(), + resourceGroupIds: z.array(z.string().uuid()).nullable(), + }) + .partial() + .passthrough(); +const UpdateOrgDetailsRequest = z + .object({ + name: z.string().min(0).max(200), + email: z.string().min(1).email(), + size: z.string().min(0).max(50).nullish(), + industry: z.string().min(0).max(100).nullish(), + websiteUrl: z.string().min(0).max(255).nullish(), + }) + .passthrough(); +const RetryStrategy = z + .object({ + type: z.string(), + maxRetries: z.number().int().optional(), + interval: z.number().int().optional(), + }) + .passthrough(); +const CreateResourceGroupRequest = z + .object({ + name: z.string().min(0).max(255), + description: z.string().nullish(), + alertPolicyId: z.string().uuid().nullish(), + defaultFrequency: z.number().int().gte(30).lte(86400).nullish(), + defaultRegions: z.array(z.string()).nullish(), + defaultRetryStrategy: RetryStrategy.nullish(), + defaultAlertChannels: z.array(z.string().uuid()).nullish(), + defaultEnvironmentId: z.string().uuid().nullish(), + healthThresholdType: z.enum(["COUNT", "PERCENTAGE"]).nullish(), + healthThresholdValue: z.number().gte(0).lte(100).nullish(), + suppressMemberAlerts: z.boolean().nullish(), + confirmationDelaySeconds: z.number().int().gte(0).lte(600).nullish(), + recoveryCooldownMinutes: z.number().int().gte(0).lte(60).nullish(), + }) + .passthrough(); +const UpdateResourceGroupRequest = z + .object({ + name: z.string().min(0).max(255), + description: z.string().nullish(), + alertPolicyId: z.string().uuid().nullish(), + defaultFrequency: z.number().int().gte(30).lte(86400).nullish(), + defaultRegions: z.array(z.string()).nullish(), + defaultRetryStrategy: RetryStrategy.nullish(), + defaultAlertChannels: z.array(z.string().uuid()).nullish(), + defaultEnvironmentId: z.string().uuid().nullish(), + healthThresholdType: z.enum(["COUNT", "PERCENTAGE"]).nullish(), + healthThresholdValue: z.number().gte(0).lte(100).nullish(), + suppressMemberAlerts: z.boolean().nullish(), + confirmationDelaySeconds: z.number().int().gte(0).lte(600).nullish(), + recoveryCooldownMinutes: z.number().int().gte(0).lte(60).nullish(), + }) + .passthrough(); +const AddResourceGroupMemberRequest = z + .object({ + memberType: z + .string() + .min(1) + .regex(/monitor|service/), + memberId: z.string().uuid(), + }) + .passthrough(); +const CreateSecretRequest = z + .object({ + key: z.string().min(0).max(255), + value: z.string().min(0).max(32768), + }) + .passthrough(); +const UpdateSecretRequest = z + .object({ value: z.string().min(0).max(32768) }) + .passthrough(); +const UpdateAlertSensitivityRequest = z + .object({ + alertSensitivity: z + .string() + .min(1) + .regex(/ALL|INCIDENTS_ONLY|MAJOR_ONLY/), + }) + .passthrough(); +const ServiceSubscribeRequest = z + .object({ + componentId: z.string().uuid().nullable(), + alertSensitivity: z.string().nullable(), + }) + .partial() + .passthrough(); +const StatusPageBranding = z + .object({ + logoUrl: z + .string() + .min(0) + .max(2048) + .regex(/^https?:\/\/.*/) + .nullish(), + faviconUrl: z + .string() + .min(0) + .max(2048) + .regex(/^https?:\/\/.*/) + .nullish(), + brandColor: z + .string() + .min(0) + .max(30) + .regex(/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/) + .nullish(), + pageBackground: z + .string() + .min(0) + .max(30) + .regex(/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/) + .nullish(), + cardBackground: z + .string() + .min(0) + .max(30) + .regex(/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/) + .nullish(), + textColor: z + .string() + .min(0) + .max(30) + .regex(/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/) + .nullish(), + borderColor: z + .string() + .min(0) + .max(30) + .regex(/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/) + .nullish(), + headerStyle: z.string().min(0).max(50).nullish(), + theme: z.string().min(0).max(50).nullish(), + reportUrl: z + .string() + .min(0) + .max(2048) + .regex(/^https?:\/\/.*/) + .nullish(), + hidePoweredBy: z.boolean().default(false), + customCss: z.string().min(0).max(50000).nullish(), + customHeadHtml: z.string().min(0).max(50000).nullish(), + }) + .passthrough(); +const CreateStatusPageRequest = z + .object({ + name: z.string().min(0).max(255), + slug: z + .string() + .min(3) + .max(63) + .regex(/^[a-z0-9][a-z0-9-]*[a-z0-9]$/), + description: z.string().min(0).max(500).nullish(), + branding: StatusPageBranding.nullish(), + visibility: z.enum(["PUBLIC", "PASSWORD", "IP_RESTRICTED"]).nullish(), + enabled: z.boolean().nullish(), + incidentMode: z.enum(["MANUAL", "REVIEW", "AUTOMATIC"]).nullish(), + }) + .passthrough(); +const UpdateStatusPageRequest = z + .object({ + name: z.string().min(0).max(255).nullable(), + description: z.string().min(0).max(500).nullable(), + branding: StatusPageBranding.nullable(), + visibility: z.enum(["PUBLIC", "PASSWORD", "IP_RESTRICTED"]).nullable(), + enabled: z.boolean().nullable(), + incidentMode: z.enum(["MANUAL", "REVIEW", "AUTOMATIC"]).nullable(), + }) + .partial() + .passthrough(); +const CreateStatusPageComponentRequest = z + .object({ + name: z.string().min(0).max(255), + description: z.string().min(0).max(500).nullish(), + type: z.enum(["MONITOR", "GROUP", "STATIC"]), + monitorId: z.string().uuid().nullish(), + resourceGroupId: z.string().uuid().nullish(), + groupId: z.string().uuid().nullish(), + showUptime: z.boolean().nullish(), + displayOrder: z.number().int().nullish(), + excludeFromOverall: z.boolean().nullish(), + startDate: z.string().nullish(), + }) + .passthrough(); +const UpdateStatusPageComponentRequest = z + .object({ + name: z.string().min(0).max(255).nullable(), + description: z.string().min(0).max(500).nullable(), + groupId: z.string().uuid().nullable(), + removeFromGroup: z.boolean().nullable(), + showUptime: z.boolean().nullable(), + displayOrder: z.number().int().nullable(), + excludeFromOverall: z.boolean().nullable(), + startDate: z.string().nullable(), + }) + .partial() + .passthrough(); +const ComponentPosition = z + .object({ + componentId: z.string().uuid(), + displayOrder: z.number().int().optional(), + groupId: z.string().uuid().nullish(), + }) + .passthrough(); +const ReorderComponentsRequest = z + .object({ positions: z.array(ComponentPosition).min(1) }) + .passthrough(); +const AddCustomDomainRequest = z + .object({ + hostname: z + .string() + .min(0) + .max(255) + .regex( + /^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$/ + ), + }) + .passthrough(); +const CreateStatusPageComponentGroupRequest = z + .object({ + name: z.string().min(0).max(255), + description: z.string().min(0).max(500).nullish(), + displayOrder: z.number().int().nullish(), + collapsed: z.boolean().nullish(), + }) + .passthrough(); +const UpdateStatusPageComponentGroupRequest = z + .object({ + name: z.string().min(0).max(255).nullable(), + description: z.string().min(0).max(500).nullable(), + displayOrder: z.number().int().nullable(), + collapsed: z.boolean().nullable(), + }) + .partial() + .passthrough(); +const AffectedComponent = z + .object({ + componentId: z.string().uuid(), + status: z.enum([ + "OPERATIONAL", + "DEGRADED_PERFORMANCE", + "PARTIAL_OUTAGE", + "MAJOR_OUTAGE", + "UNDER_MAINTENANCE", + ]), + }) + .passthrough(); +const CreateStatusPageIncidentRequest = z + .object({ + title: z.string().min(0).max(500), + status: z + .enum(["INVESTIGATING", "IDENTIFIED", "MONITORING", "RESOLVED"]) + .nullish(), + impact: z.enum(["NONE", "MINOR", "MAJOR", "CRITICAL"]), + body: z.string().min(1), + affectedComponents: z.array(AffectedComponent).nullish(), + scheduled: z.boolean().nullish(), + scheduledFor: z.string().datetime({ offset: true }).nullish(), + scheduledUntil: z.string().datetime({ offset: true }).nullish(), + autoResolve: z.boolean().nullish(), + notifySubscribers: z.boolean().nullish(), + }) + .passthrough(); +const UpdateStatusPageIncidentRequest = z + .object({ + title: z.string().min(0).max(500).nullable(), + status: z + .enum(["INVESTIGATING", "IDENTIFIED", "MONITORING", "RESOLVED"]) + .nullable(), + impact: z.enum(["NONE", "MINOR", "MAJOR", "CRITICAL"]).nullable(), + affectedComponents: z.array(AffectedComponent).nullable(), + postmortemBody: z.string().nullable(), + postmortemUrl: z + .string() + .min(0) + .max(2048) + .regex(/^https?:\/\/.*/) + .nullable(), + }) + .partial() + .passthrough(); +const PublishStatusPageIncidentRequest = z + .object({ + title: z.string().min(0).max(500).nullable(), + impact: z.enum(["NONE", "MINOR", "MAJOR", "CRITICAL"]).nullable(), + status: z + .enum(["INVESTIGATING", "IDENTIFIED", "MONITORING", "RESOLVED"]) + .nullable(), + body: z.string().nullable(), + affectedComponents: z.array(AffectedComponent).nullable(), + notifySubscribers: z.boolean().nullable(), + }) + .partial() + .passthrough(); +const CreateStatusPageIncidentUpdateRequest = z + .object({ + status: z.enum(["INVESTIGATING", "IDENTIFIED", "MONITORING", "RESOLVED"]), + body: z.string().min(1), + notifySubscribers: z.boolean().nullish(), + affectedComponents: z.array(AffectedComponent).nullish(), + }) + .passthrough(); +const PageSection = z + .object({ + groupId: z.string().uuid().nullish(), + componentId: z.string().uuid().nullish(), + pageOrder: z.number().int(), + }) + .passthrough(); +const GroupComponentOrder = z + .object({ + groupId: z.string().uuid(), + positions: z.array(ComponentPosition).min(1), + }) + .passthrough(); +const ReorderPageLayoutRequest = z + .object({ + sections: z.array(PageSection).min(1), + groupOrders: z.array(GroupComponentOrder).nullish(), + }) + .passthrough(); +const AdminAddSubscriberRequest = z + .object({ email: z.string().min(1).email() }) + .passthrough(); +const CreateTagRequest = z + .object({ + name: z.string().min(0).max(100), + color: z + .string() + .regex(/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/) + .nullish(), + }) + .passthrough(); +const UpdateTagRequest = z + .object({ + name: z.string().min(0).max(100).nullable(), + color: z + .string() + .regex(/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/) + .nullable(), + }) + .partial() + .passthrough(); +const CreateWebhookEndpointRequest = z + .object({ + url: z.string().min(0).max(2048), + description: z.string().min(0).max(255).nullish(), + subscribedEvents: z.array(z.string().min(1)).min(1), + }) + .passthrough(); +const UpdateWebhookEndpointRequest = z + .object({ + url: z.string().min(0).max(2048).nullable(), + description: z.string().min(0).max(255).nullable(), + subscribedEvents: z.array(z.string()).nullable(), + enabled: z.boolean().nullable(), + }) + .partial() + .passthrough(); +const TestWebhookEndpointRequest = z + .object({ eventType: z.string().nullable() }) + .partial() + .passthrough(); +const CreateWorkspaceRequest = z + .object({ name: z.string().min(1) }) + .passthrough(); +const UpdateWorkspaceRequest = z + .object({ name: z.string().min(0).max(200) }) + .passthrough(); + +export const schemas = { + pageable, + ChannelConfig, + DiscordChannelConfig, + EmailChannelConfig, + OpsGenieChannelConfig, + PagerDutyChannelConfig, + SlackChannelConfig, + TeamsChannelConfig, + WebhookChannelConfig, + CreateAlertChannelRequest, + UpdateAlertChannelRequest, + TestAlertChannelRequest, + CreateApiKeyRequest, + UpdateApiKeyRequest, + AcquireDeployLockRequest, + CreateEnvironmentRequest, + UpdateEnvironmentRequest, + params, + CreateManualIncidentRequest, + ResolveIncidentRequest, + AddIncidentUpdateRequest, + CreateInviteRequest, + CreateMaintenanceWindowRequest, + UpdateMaintenanceWindowRequest, + ChangeRoleRequest, + ChangeStatusRequest, + MonitorConfig, + DnsMonitorConfig, + HeartbeatMonitorConfig, + HttpMonitorConfig, + IcmpMonitorConfig, + McpServerMonitorConfig, + TcpMonitorConfig, + AssertionConfig, + BodyContainsAssertion, + DnsExpectedCnameAssertion, + DnsExpectedIpsAssertion, + DnsMaxAnswersAssertion, + DnsMinAnswersAssertion, + DnsRecordContainsAssertion, + DnsRecordEqualsAssertion, + DnsResolvesAssertion, + DnsResponseTimeAssertion, + DnsResponseTimeWarnAssertion, + DnsTtlHighAssertion, + DnsTtlLowAssertion, + DnsTxtContainsAssertion, + HeaderValueAssertion, + HeartbeatIntervalDriftAssertion, + HeartbeatMaxIntervalAssertion, + HeartbeatPayloadContainsAssertion, + HeartbeatReceivedAssertion, + IcmpPacketLossAssertion, + IcmpReachableAssertion, + IcmpResponseTimeAssertion, + IcmpResponseTimeWarnAssertion, + JsonPathAssertion, + McpConnectsAssertion, + McpHasCapabilityAssertion, + McpMinToolsAssertion, + McpProtocolVersionAssertion, + McpResponseTimeAssertion, + McpResponseTimeWarnAssertion, + McpToolAvailableAssertion, + McpToolCountChangedAssertion, + RedirectCountAssertion, + RedirectTargetAssertion, + RegexBodyAssertion, + ResponseSizeAssertion, + ResponseTimeAssertion, + ResponseTimeWarnAssertion, + SslExpiryAssertion, + StatusCodeAssertion, + TcpConnectsAssertion, + TcpResponseTimeAssertion, + TcpResponseTimeWarnAssertion, + CreateAssertionRequest, + MonitorAuthConfig, + TriggerRule, + ConfirmationPolicy, + RecoveryPolicy, + UpdateIncidentPolicyRequest, + NewTagRequest, + AddMonitorTagsRequest, + CreateMonitorRequest, + UpdateMonitorRequest, + RemoveMonitorTagsRequest, + SetAlertChannelsRequest, + UpdateAssertionRequest, + ApiKeyAuthConfig, + BasicAuthConfig, + BearerAuthConfig, + HeaderAuthConfig, + UpdateMonitorAuthRequest, + SetMonitorAuthRequest, + BulkMonitorActionRequest, + MonitorTestRequest, + MatchRule, + EscalationStep, + EscalationChain, + CreateNotificationPolicyRequest, + UpdateNotificationPolicyRequest, + TestNotificationPolicyRequest, + UpdateOrgDetailsRequest, + RetryStrategy, + CreateResourceGroupRequest, + UpdateResourceGroupRequest, + AddResourceGroupMemberRequest, + CreateSecretRequest, + UpdateSecretRequest, + UpdateAlertSensitivityRequest, + ServiceSubscribeRequest, + StatusPageBranding, + CreateStatusPageRequest, + UpdateStatusPageRequest, + CreateStatusPageComponentRequest, + UpdateStatusPageComponentRequest, + ComponentPosition, + ReorderComponentsRequest, + AddCustomDomainRequest, + CreateStatusPageComponentGroupRequest, + UpdateStatusPageComponentGroupRequest, + AffectedComponent, + CreateStatusPageIncidentRequest, + UpdateStatusPageIncidentRequest, + PublishStatusPageIncidentRequest, + CreateStatusPageIncidentUpdateRequest, + PageSection, + GroupComponentOrder, + ReorderPageLayoutRequest, + AdminAddSubscriberRequest, + CreateTagRequest, + UpdateTagRequest, + CreateWebhookEndpointRequest, + UpdateWebhookEndpointRequest, + TestWebhookEndpointRequest, + CreateWorkspaceRequest, + UpdateWorkspaceRequest, +}; + diff --git a/src/lib/api.generated.ts b/src/lib/api.generated.ts index 72e5bc9..d4888b6 100644 --- a/src/lib/api.generated.ts +++ b/src/lib/api.generated.ts @@ -1530,6 +1530,26 @@ export interface paths { patch?: never; trace?: never; }; + "/api/v1/services/{slugOrId}/days/{date}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * One-day rollup for a service: aggregated uptime, per-component impacts, and overlapping incidents + * @description Powers the click/hover-to-expand panel under each uptime bar on the public status page. Single round-trip — components, sums, and overlapping incidents (with affected component names) are returned in one response. + */ + get: operations["getServiceDayDetail"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/api/v1/services/{slugOrId}/incidents": { parameters: { query?: never; @@ -2270,12 +2290,12 @@ export interface components { }; AddIncidentUpdateRequest: { /** @description Update message or post-mortem notes */ - body: string; + body?: string | null; /** * @description Updated incident status; null to keep current status - * @enum {string} + * @enum {string|null} */ - newStatus: "WATCHING" | "TRIGGERED" | "CONFIRMED" | "RESOLVED"; + newStatus?: "WATCHING" | "TRIGGERED" | "CONFIRMED" | "RESOLVED" | null; /** @description Whether to notify subscribers of this update */ notifySubscribers: boolean; }; @@ -2403,17 +2423,17 @@ export interface components { * Format: int32 * @description 1-based escalation step this delivery belongs to */ - stepNumber: number; + stepNumber?: number; /** * Format: int32 * @description Fire sequence within the step: 1 = initial, 2+ = repeat re-fires */ - fireCount: number; + fireCount?: number; /** * Format: int32 * @description Number of delivery attempts made */ - attemptCount: number; + attemptCount?: number; /** * Format: date-time * @description When the last attempt was made @@ -2455,7 +2475,7 @@ export interface components { * Format: int32 * @description Unique API key identifier */ - id: number; + id?: number; /** @description Human-readable name for this API key */ name: string; /** @description Full API key value in dh_live_* format; store this now */ @@ -2477,7 +2497,7 @@ export interface components { * Format: int32 * @description Unique API key identifier */ - id: number; + id?: number; /** @description Human-readable name for this API key */ name: string; /** @description Full API key value in dh_live_* format */ @@ -2520,7 +2540,7 @@ export interface components { */ type: string; /** @description Whether the assertion passed */ - passed: boolean; + passed?: boolean; /** * @description Assertion severity * @enum {string} @@ -2546,7 +2566,7 @@ export interface components { */ assertionType: "status_code" | "response_time" | "body_contains" | "json_path" | "header_value" | "regex_body" | "dns_resolves" | "dns_response_time" | "dns_expected_ips" | "dns_expected_cname" | "dns_record_contains" | "dns_record_equals" | "dns_txt_contains" | "dns_min_answers" | "dns_max_answers" | "dns_response_time_warn" | "dns_ttl_low" | "dns_ttl_high" | "mcp_connects" | "mcp_response_time" | "mcp_has_capability" | "mcp_tool_available" | "mcp_min_tools" | "mcp_protocol_version" | "mcp_response_time_warn" | "mcp_tool_count_changed" | "ssl_expiry" | "response_size" | "redirect_count" | "redirect_target" | "response_time_warn" | "tcp_connects" | "tcp_response_time" | "tcp_response_time_warn" | "icmp_reachable" | "icmp_response_time" | "icmp_response_time_warn" | "icmp_packet_loss" | "heartbeat_received" | "heartbeat_max_interval" | "heartbeat_interval_drift" | "heartbeat_payload_contains"; /** @description Whether the assertion passed */ - passed: boolean; + passed?: boolean; /** * @description Assertion severity: FAIL or WARN * @enum {string} @@ -2564,7 +2584,7 @@ export interface components { * Format: int64 * @description Unique audit event identifier */ - id: number; + id?: number; /** * Format: int32 * @description User ID who performed the action; null for system actions @@ -2662,7 +2682,7 @@ export interface components { * Format: int64 * @description Number of services in this category */ - serviceCount: number; + serviceCount?: number; }; /** @description Update an organization member's role */ ChangeRoleRequest: { @@ -2777,7 +2797,7 @@ export interface components { * @description Whether the check passed * @example true */ - passed: boolean; + passed?: boolean; /** @description Reason for failure when passed=false */ failureReason?: string | null; /** @description Severity hint: 'down' for hard failures, 'degraded' for warn-only failures, null when passing */ @@ -2793,6 +2813,33 @@ export interface components { CheckTypeDetailsDto: { check_type: string; }; + /** @description One component's uptime contribution for the day */ + ComponentImpact: { + /** + * Format: uuid + * @description Status page component UUID + */ + componentId: string; + /** @description Component display name */ + componentName: string; + /** @description Parent group display name when the component belongs to a group */ + groupName?: string | null; + /** + * Format: double + * @description Computed uptime % for this component on this day + */ + uptimePercentage?: number; + /** + * Format: int32 + * @description Seconds of partial outage observed on this day + */ + partialOutageSeconds?: number; + /** + * Format: int32 + * @description Seconds of major outage observed on this day + */ + majorOutageSeconds?: number; + }; /** @description A single component position */ ComponentPosition: { /** @@ -2809,7 +2856,7 @@ export interface components { * Format: uuid * @description Target group ID, null for ungrouped */ - groupId?: string; + groupId?: string | null; }; /** @description Current status of each active component */ ComponentStatusDto: { @@ -2831,17 +2878,17 @@ export interface components { * Format: int32 * @description Seconds of partial outage on this day */ - partialOutageSeconds: number; + partialOutageSeconds?: number; /** * Format: int32 * @description Seconds of major outage on this day */ - majorOutageSeconds: number; + majorOutageSeconds?: number; /** * Format: double * @description Computed uptime percentage using weighted formula */ - uptimePercentage: number; + uptimePercentage?: number; /** @description Incidents that overlapped this day */ incidents?: components["schemas"]["IncidentRef"][] | null; }; @@ -2910,7 +2957,7 @@ export interface components { * @description Outcome severity: FAIL (fails the check) or WARN (warns without failing) * @enum {string} */ - severity?: "fail" | "warn"; + severity: "fail" | "warn"; }; CreateEnvironmentRequest: { /** @description Human-readable environment name */ @@ -2942,7 +2989,7 @@ export interface components { * Format: uuid * @description Monitor to attach this maintenance window to; null for org-wide */ - monitorId?: string; + monitorId?: string | null; /** * Format: date-time * @description Scheduled start of the maintenance window (ISO 8601) @@ -2954,11 +3001,11 @@ export interface components { */ endsAt: string; /** @description iCal RRULE for recurring windows (max 100 chars); null for one-time */ - repeatRule?: string; + repeatRule?: string | null; /** @description Human-readable reason for the maintenance */ - reason?: string; + reason?: string | null; /** @description Whether to suppress alerts during this window (default: true) */ - suppressAlerts?: boolean; + suppressAlerts?: boolean | null; }; CreateManualIncidentRequest: { /** @description Short summary of the incident */ @@ -2987,9 +3034,9 @@ export interface components { config: components["schemas"]["DnsMonitorConfig"] | components["schemas"]["HeartbeatMonitorConfig"] | components["schemas"]["HttpMonitorConfig"] | components["schemas"]["IcmpMonitorConfig"] | components["schemas"]["McpServerMonitorConfig"] | components["schemas"]["TcpMonitorConfig"]; /** * Format: int32 - * @description Check frequency in seconds (30–86400, default: 60) + * @description Check frequency in seconds (30–86400); null defaults to plan minimum (60s on most paid plans) */ - frequencySeconds?: number; + frequencySeconds?: number | null; /** @description Whether the monitor is active (default: true) */ enabled?: boolean | null; /** @description Probe regions to run checks from, e.g. us-east, eu-west */ @@ -3017,7 +3064,7 @@ export interface components { /** @description Human-readable name for this policy */ name: string; /** @description Match rules to evaluate (all must pass; omit or empty for catch-all) */ - matchRules?: components["schemas"]["MatchRule"][]; + matchRules: components["schemas"]["MatchRule"][]; escalation: components["schemas"]["EscalationChain"]; /** * @description Whether this policy is enabled (default true) @@ -3215,7 +3262,7 @@ export interface components { /** @description HTTPS endpoint that receives webhook event payloads */ url: string; /** @description Optional human-readable description */ - description?: string; + description?: string | null; /** @description Event types to deliver, e.g. monitor.created, incident.resolved */ subscribedEvents: string[]; }; @@ -3231,7 +3278,7 @@ export interface components { /** @description Opaque cursor for the next page; null when there are no more results */ nextCursor?: string | null; /** @description Whether more results exist beyond this page */ - hasMore: boolean; + hasMore?: boolean; }; /** @description Cursor-paginated response for time-series and append-only data */ CursorPageCheckResultDto: { @@ -3240,7 +3287,7 @@ export interface components { /** @description Opaque cursor for the next page; null when there are no more results */ nextCursor?: string | null; /** @description Whether more results exist beyond this page */ - hasMore: boolean; + hasMore?: boolean; }; /** @description Cursor-paginated response for time-series and append-only data */ CursorPageServiceCatalogDto: { @@ -3249,7 +3296,7 @@ export interface components { /** @description Opaque cursor for the next page; null when there are no more results */ nextCursor?: string | null; /** @description Whether more results exist beyond this page */ - hasMore: boolean; + hasMore?: boolean; }; /** @description Cursor-paginated response for time-series and append-only data */ CursorPageServicePollResultDto: { @@ -3258,35 +3305,69 @@ export interface components { /** @description Opaque cursor for the next page; null when there are no more results */ nextCursor?: string | null; /** @description Whether more results exist beyond this page */ - hasMore: boolean; + hasMore?: boolean; }; /** @description Combined dashboard overview for monitors and incidents */ DashboardOverviewDto: { monitors: components["schemas"]["MonitorsSummaryDto"]; incidents: components["schemas"]["IncidentsSummaryDto"]; }; + /** @description Incident that overlapped the day */ + DayIncident: { + /** + * Format: uuid + * @description Status page incident UUID + */ + id: string; + /** @description Incident title */ + title: string; + /** + * @description Lifecycle status (investigating, identified, monitoring, resolved, …) + * @enum {string} + */ + status: "INVESTIGATING" | "IDENTIFIED" | "MONITORING" | "RESOLVED"; + /** + * @description Severity bucket (none, minor, major, critical) + * @enum {string} + */ + impact: "NONE" | "MINOR" | "MAJOR" | "CRITICAL"; + /** @description True for scheduled maintenances; false for unplanned incidents */ + scheduled?: boolean; + /** + * Format: date-time + * @description Incident start timestamp + */ + startedAt?: string | null; + /** + * Format: date-time + * @description Incident resolved timestamp; null while still active + */ + resolvedAt?: string | null; + /** @description Display names of components affected by this incident (deduplicated) */ + affectedComponentNames: string[]; + }; /** @description Result of a data encryption key rotation operation */ DekRotationResultDto: { /** * Format: int32 * @description DEK version before rotation */ - previousDekVersion: number; + previousDekVersion?: number; /** * Format: int32 * @description DEK version after rotation */ - newDekVersion: number; + newDekVersion?: number; /** * Format: int32 * @description Number of secrets re-encrypted with the new DEK */ - secretsReEncrypted: number; + secretsReEncrypted?: number; /** * Format: int32 * @description Number of alert channels re-encrypted with the new DEK */ - channelsReEncrypted: number; + channelsReEncrypted?: number; /** * Format: date-time * @description Timestamp when the rotation was performed @@ -3316,7 +3397,7 @@ export interface components { * Format: int32 * @description 1-based attempt number */ - attemptNumber: number; + attemptNumber?: number; /** @description Outcome: SUCCESS, FAILED, TIMEOUT, ERROR */ status: string; /** @@ -3403,7 +3484,7 @@ export interface components { * Format: int32 * @description Maximum number of answers allowed for that record type */ - max?: number; + max: number; } & { /** * @description discriminator enum property added by openapi-typescript @@ -3418,7 +3499,7 @@ export interface components { * Format: int32 * @description Minimum number of answers required for that record type */ - min?: number; + min: number; } & { /** * @description discriminator enum property added by openapi-typescript @@ -3480,7 +3561,7 @@ export interface components { * Format: int32 * @description Maximum allowed DNS resolution time in milliseconds */ - maxMs?: number; + maxMs: number; } & { /** * @description discriminator enum property added by openapi-typescript @@ -3493,7 +3574,7 @@ export interface components { * Format: int32 * @description DNS resolution time in milliseconds that triggers a warning only */ - warnMs?: number; + warnMs: number; } & { /** * @description discriminator enum property added by openapi-typescript @@ -3506,7 +3587,7 @@ export interface components { * Format: int32 * @description Maximum TTL in seconds before a high-TTL warning is raised */ - maxTtl?: number; + maxTtl: number; } & { /** * @description discriminator enum property added by openapi-typescript @@ -3519,7 +3600,7 @@ export interface components { * Format: int32 * @description Minimum acceptable TTL in seconds before a warning is raised */ - minTtl?: number; + minTtl: number; } & { /** * @description discriminator enum property added by openapi-typescript @@ -3555,14 +3636,14 @@ export interface components { * Format: int64 * @description Effective limit value (overrides applied) */ - value: number; + value?: number; /** * Format: int64 * @description Plan-tier default value before overrides */ - defaultValue: number; + defaultValue?: number; /** @description Whether this entitlement has an org-level override */ - overridden: boolean; + overridden?: boolean; }; /** @description Environment with variable substitutions for monitor configs */ EnvironmentDto: { @@ -3575,7 +3656,7 @@ export interface components { * Format: int32 * @description Organization this environment belongs to */ - orgId: number; + orgId?: number; /** @description Human-readable environment name */ name: string; /** @description URL-safe identifier */ @@ -3598,9 +3679,9 @@ export interface components { * Format: int32 * @description Number of monitors using this environment */ - monitorCount: number; + monitorCount?: number; /** @description Whether this is the default environment for new monitors */ - isDefault: boolean; + isDefault?: boolean; }; /** @description Escalation chain defining which channels to notify; null preserves current */ EscalationChain: { @@ -3644,42 +3725,42 @@ export interface components { * Format: int32 * @description Total number of services in the catalog */ - totalServices: number; + totalServices?: number; /** * Format: int32 * @description Number of services currently fully operational */ - operationalCount: number; + operationalCount?: number; /** * Format: int32 * @description Number of services with degraded status */ - degradedCount: number; + degradedCount?: number; /** * Format: int32 * @description Number of services with partial outage */ - partialOutageCount: number; + partialOutageCount?: number; /** * Format: int32 * @description Number of services with major outage */ - majorOutageCount: number; + majorOutageCount?: number; /** * Format: int32 * @description Number of services currently under maintenance */ - maintenanceCount: number; + maintenanceCount?: number; /** * Format: int32 * @description Number of services with unknown or null status */ - unknownCount: number; + unknownCount?: number; /** * Format: int64 * @description Total number of active incidents across all services */ - activeIncidentCount: number; + activeIncidentCount?: number; /** @description Services that are not fully operational */ servicesWithIssues: components["schemas"]["ServiceCatalogDto"][]; }; @@ -3689,7 +3770,7 @@ export interface components { * Format: uuid * @description Group these components belong to */ - groupId?: string; + groupId: string; /** @description Ordered component IDs with their within-group display order */ positions: components["schemas"]["ComponentPosition"][]; }; @@ -3820,7 +3901,7 @@ export interface components { * Format: double * @description Maximum allowed packet loss percentage before the check fails (0–100) */ - maxPercent?: number; + maxPercent: number; } & { /** * @description discriminator enum property added by openapi-typescript @@ -3840,7 +3921,7 @@ export interface components { * Format: int32 * @description Maximum average ICMP round-trip time in milliseconds */ - maxMs?: number; + maxMs: number; } & { /** * @description discriminator enum property added by openapi-typescript @@ -3853,7 +3934,7 @@ export interface components { * Format: int32 * @description ICMP round-trip time in milliseconds that triggers a warning only */ - warnMs?: number; + warnMs: number; } & { /** * @description discriminator enum property added by openapi-typescript @@ -3882,7 +3963,7 @@ export interface components { * Format: int32 * @description Organization this incident belongs to */ - organizationId: number; + organizationId?: number; /** * @description Incident origin: MONITOR, SERVICE, or MANUAL * @enum {string} @@ -3908,14 +3989,14 @@ export interface components { * Format: int32 * @description Number of times this incident has been reopened */ - reopenCount: number; + reopenCount?: number; /** * Format: int32 * @description User who created the incident (manual incidents only) */ createdByUserId?: number | null; /** @description Whether this incident is visible on the status page */ - statusPageVisible: boolean; + statusPageVisible?: boolean; /** * Format: uuid * @description Linked vendor service incident ID; null for monitor incidents @@ -3984,18 +4065,18 @@ export interface components { resourceGroupName?: string | null; }; IncidentFilterParams: { - /** @enum {string} */ - status: "WATCHING" | "TRIGGERED" | "CONFIRMED" | "RESOLVED"; - /** @enum {string} */ - severity: "DOWN" | "DEGRADED" | "MAINTENANCE"; - /** @enum {string} */ - source: "AUTOMATIC" | "MANUAL" | "MONITORS" | "STATUS_DATA" | "RESOURCE_GROUP"; + /** @enum {string|null} */ + status?: "WATCHING" | "TRIGGERED" | "CONFIRMED" | "RESOLVED" | null; + /** @enum {string|null} */ + severity?: "DOWN" | "DEGRADED" | "MAINTENANCE" | null; + /** @enum {string|null} */ + source?: "AUTOMATIC" | "MANUAL" | "MONITORS" | "STATUS_DATA" | "RESOURCE_GROUP" | null; /** Format: uuid */ - monitorId: string; + monitorId?: string | null; /** Format: uuid */ - serviceId: string; + serviceId?: string | null; /** Format: uuid */ - resourceGroupId: string; + resourceGroupId?: string | null; /** Format: uuid */ tagId?: string | null; /** Format: uuid */ @@ -4077,9 +4158,9 @@ export interface components { /** @enum {string|null} */ newStatus?: "WATCHING" | "TRIGGERED" | "CONFIRMED" | "RESOLVED" | null; body?: string | null; - /** @enum {string} */ - createdBy: "SYSTEM" | "USER"; - notifySubscribers: boolean; + /** @enum {string|null} */ + createdBy?: "SYSTEM" | "USER" | null; + notifySubscribers?: boolean; /** Format: date-time */ createdAt: string; }; @@ -4116,7 +4197,7 @@ export interface components { * Format: int32 * @description Unique invite identifier */ - inviteId: number; + inviteId?: number; /** @description Email address the invite was sent to */ email: string; /** @@ -4163,7 +4244,7 @@ export interface components { * Format: int32 * @description Key ID */ - id: number; + id?: number; /** @description Human-readable key name */ name: string; /** @@ -4194,7 +4275,7 @@ export interface components { status: "INVESTIGATING" | "IDENTIFIED" | "MONITORING" | "RESOLVED"; /** @enum {string} */ impact: "NONE" | "MINOR" | "MAJOR" | "CRITICAL"; - scheduled: boolean; + scheduled?: boolean; /** Format: date-time */ publishedAt?: string | null; }; @@ -4243,7 +4324,7 @@ export interface components { * Format: int32 * @description Organization this maintenance window belongs to */ - organizationId: number; + organizationId?: number; /** * Format: date-time * @description Scheduled start of the maintenance window @@ -4259,7 +4340,7 @@ export interface components { /** @description Human-readable reason for the maintenance */ reason?: string | null; /** @description Whether alerts are suppressed during this window */ - suppressAlerts: boolean; + suppressAlerts?: boolean; /** * Format: date-time * @description Timestamp when the window was created @@ -4301,7 +4382,7 @@ export interface components { * Format: int32 * @description Minimum number of tools the server must expose */ - min?: number; + min: number; } & { /** * @description discriminator enum property added by openapi-typescript @@ -4324,7 +4405,7 @@ export interface components { * Format: int32 * @description Maximum allowed MCP check duration in milliseconds */ - maxMs?: number; + maxMs: number; } & { /** * @description discriminator enum property added by openapi-typescript @@ -4337,7 +4418,7 @@ export interface components { * Format: int32 * @description MCP check duration in milliseconds that triggers a warning only */ - warnMs?: number; + warnMs: number; } & { /** * @description discriminator enum property added by openapi-typescript @@ -4370,7 +4451,7 @@ export interface components { * Format: int32 * @description Expected tool count; warns when the live count differs */ - expectedCount?: number; + expectedCount: number; } & { /** * @description discriminator enum property added by openapi-typescript @@ -4384,7 +4465,7 @@ export interface components { * Format: int32 * @description User identifier of the member */ - userId: number; + userId?: number; /** @description Member email address */ email: string; /** @description Member display name; null if not set */ @@ -4442,7 +4523,7 @@ export interface components { * Format: int32 * @description Organization this monitor belongs to */ - organizationId: number; + organizationId?: number; /** @description Human-readable name for this monitor */ name: string; /** @enum {string} */ @@ -4452,9 +4533,9 @@ export interface components { * Format: int32 * @description Check frequency in seconds (30–86400) */ - frequencySeconds: number; + frequencySeconds?: number; /** @description Whether the monitor is active */ - enabled: boolean; + enabled?: boolean; /** @description Probe regions where checks are executed */ regions: string[]; /** @@ -4543,7 +4624,7 @@ export interface components { assertions?: components["schemas"]["CreateAssertionRequest"][] | null; }; MonitorTestResultDto: { - passed: boolean; + passed?: boolean; error?: string | null; /** Format: int32 */ statusCode?: number | null; @@ -4577,7 +4658,7 @@ export interface components { * Format: int32 * @description Monotonically increasing version number */ - version: number; + version?: number; snapshot: components["schemas"]["MonitorDto"]; /** * Format: int32 @@ -4637,7 +4718,7 @@ export interface components { * Format: int32 * @description 1-based index of the currently active escalation step */ - currentStep: number; + currentStep?: number; /** * Format: int32 * @description Total number of escalation steps in the policy (null if policy has been deleted) @@ -4677,7 +4758,7 @@ export interface components { * Format: int64 * @description Unique notification identifier */ - id: number; + id?: number; /** @description Notification category (e.g. incident, monitor, team) */ type: string; /** @description Short notification title */ @@ -4689,7 +4770,7 @@ export interface components { /** @description ID of the resource this notification is about */ resourceId?: string | null; /** @description Whether the notification has been read */ - read: boolean; + read?: boolean; /** * Format: date-time * @description Timestamp when the notification was created @@ -4707,19 +4788,19 @@ export interface components { * Format: int32 * @description Organization this policy belongs to */ - organizationId: number; + organizationId?: number; /** @description Human-readable name for this policy */ name: string; /** @description Match rules (all must pass; empty = catch-all) */ matchRules: components["schemas"]["MatchRule"][]; escalation: components["schemas"]["EscalationChain"]; /** @description Whether this policy is active */ - enabled: boolean; + enabled?: boolean; /** * Format: int32 * @description Evaluation order; higher value = evaluated first */ - priority: number; + priority?: number; /** * Format: date-time * @description Timestamp when the policy was created @@ -4749,11 +4830,11 @@ export interface components { * Format: int32 * @description Unique organization identifier */ - id: number; + id?: number; /** @description Organization name */ name: string; /** @description Billing and contact email */ - email?: string | null; + email: string | null; /** @description Team size range (e.g. 1-10, 11-50) */ size?: string | null; /** @description Industry vertical (e.g. SaaS, Fintech) */ @@ -4767,7 +4848,7 @@ export interface components { * Format: int32 * @description Organization ID */ - id: number; + id?: number; /** @description Organization name */ name: string; }; @@ -4818,7 +4899,7 @@ export interface components { /** @description Subscription status (null if no subscription) */ subscriptionStatus?: string | null; /** @description Whether the org is on a trial */ - trialActive: boolean; + trialActive?: boolean; /** * Format: date-time * @description Trial expiry (null if not trialing) @@ -4857,7 +4938,7 @@ export interface components { * @description Total polls in this bucket * @example 60 */ - totalPolls: number; + totalPolls?: number; }; PublishStatusPageIncidentRequest: { /** @description Customer-facing title; null keeps draft value */ @@ -4920,7 +5001,7 @@ export interface components { * Format: int32 * @description Maximum number of HTTP redirects allowed before the check fails */ - maxCount?: number; + maxCount: number; } & { /** * @description discriminator enum property added by openapi-typescript @@ -4964,7 +5045,7 @@ export interface components { * @description Whether the last check in this region passed * @example true */ - passed: boolean; + passed?: boolean; /** * Format: int32 * @description Response time in milliseconds for the last check @@ -5011,7 +5092,7 @@ export interface components { * Format: int32 * @description Organization this group belongs to */ - organizationId: number; + organizationId?: number; /** @description Human-readable group name */ name: string; /** @description URL-safe group identifier */ @@ -5046,7 +5127,7 @@ export interface components { /** @description Health threshold value */ healthThresholdValue?: number | null; /** @description When true, member-level incidents skip notification dispatch; only group alerts fire */ - suppressMemberAlerts: boolean; + suppressMemberAlerts?: boolean; /** * Format: int32 * @description Seconds to wait after health threshold breach before creating group incident @@ -5082,17 +5163,17 @@ export interface components { * Format: int32 * @description Total number of members in the group */ - totalMembers: number; + totalMembers?: number; /** * Format: int32 * @description Number of members currently in operational status */ - operationalCount: number; + operationalCount?: number; /** * Format: int32 * @description Number of members with an active incident or non-operational status */ - activeIncidents: number; + activeIncidents?: number; /** * @description Computed group health status based on threshold: 'healthy', 'degraded', or 'down'. Null when no health threshold is configured. * @enum {string|null} @@ -5181,7 +5262,7 @@ export interface components { * Format: int32 * @description Maximum response body size in bytes before the check fails */ - maxBytes?: number; + maxBytes: number; } & { /** * @description discriminator enum property added by openapi-typescript @@ -5194,7 +5275,7 @@ export interface components { * Format: int32 * @description Maximum allowed response time in milliseconds before the check fails */ - thresholdMs?: number; + thresholdMs: number; } & { /** * @description discriminator enum property added by openapi-typescript @@ -5207,7 +5288,7 @@ export interface components { * Format: int32 * @description HTTP response time in milliseconds that triggers a warning only */ - warnMs?: number; + warnMs: number; } & { /** * @description discriminator enum property added by openapi-typescript @@ -5309,7 +5390,7 @@ export interface components { * Format: int32 * @description DEK version at the time of last encryption */ - dekVersion: number; + dekVersion?: number; /** @description SHA-256 hex digest of the current plaintext; use for change detection */ valueHash: string; /** @@ -5346,18 +5427,18 @@ export interface components { logoUrl?: string | null; adapterType: string; /** Format: int32 */ - pollingIntervalSeconds: number; - enabled: boolean; - published: boolean; + pollingIntervalSeconds?: number; + enabled?: boolean; + published?: boolean; overallStatus?: string | null; /** Format: date-time */ createdAt: string; /** Format: date-time */ updatedAt: string; /** Format: int64 */ - componentCount: number; + componentCount?: number; /** Format: int64 */ - activeIncidentCount: number; + activeIncidentCount?: number; dataCompleteness: string; /** * Format: double @@ -5377,8 +5458,8 @@ export interface components { groupId?: string | null; /** Format: int32 */ position?: number | null; - showcase: boolean; - onlyShowIfDegraded: boolean; + showcase?: boolean; + onlyShowIfDegraded?: boolean; /** Format: date-time */ startDate?: string | null; /** Format: date-time */ @@ -5390,11 +5471,18 @@ export interface components { */ dataType: string; /** @description Whether uptime data is available for this component */ - hasUptime: boolean; + hasUptime?: boolean; /** @description Geographic region for regional components (AWS, GCP, Azure) */ region?: string | null; /** @description Display name of the parent group */ groupName?: string | null; + /** @description Group-only: render an aggregated uptime bar above this group's children */ + displayAggregatedUptime?: boolean; + /** + * Format: int32 + * @description Group-only count of visible leaf children; null for leaves + */ + childCount?: number | null; uptime?: components["schemas"]["ComponentUptimeSummaryDto"] | null; /** Format: date-time */ statusChangedAt?: string | null; @@ -5402,7 +5490,34 @@ export interface components { firstSeenAt: string; /** Format: date-time */ lastSeenAt: string; - group: boolean; + isGroup?: boolean; + }; + /** @description One-day rollup for a public service status page: aggregated uptime, per-component impact, and incidents that overlapped the day. Powers the click/hover-to-expand panel under each uptime bar. */ + ServiceDayDetailDto: { + /** + * Format: date + * @description UTC calendar day this rollup covers + */ + date: string; + /** + * Format: double + * @description Average uptime % across leaf components with uptime data; null if no data + */ + overallUptimePercentage?: number | null; + /** + * Format: int64 + * @description Sum of partial outage seconds across all leaf components + */ + totalPartialOutageSeconds?: number; + /** + * Format: int64 + * @description Sum of major outage seconds across all leaf components + */ + totalMajorOutageSeconds?: number; + /** @description Per-component impact rows for the day (only components with uptime data) */ + components: components["schemas"]["ComponentImpact"][]; + /** @description Incidents that were active at any point during this day (started before day end, resolved after day start) */ + incidents: components["schemas"]["DayIncident"][]; }; ServiceDetailDto: { /** Format: uuid */ @@ -5415,8 +5530,8 @@ export interface components { logoUrl?: string | null; adapterType: string; /** Format: int32 */ - pollingIntervalSeconds: number; - enabled: boolean; + pollingIntervalSeconds?: number; + enabled?: boolean; /** Format: date-time */ createdAt: string; /** Format: date-time */ @@ -5484,7 +5599,7 @@ export interface components { * Format: int32 * @description Number of currently unresolved incidents */ - activeIncidentCount: number; + activeIncidentCount?: number; /** @description ISO 8601 timestamp of the last status poll */ lastPolledAt?: string | null; }; @@ -5521,7 +5636,7 @@ export interface components { * @description Whether the poll succeeded * @example true */ - passed: boolean; + passed?: boolean; /** @description Reason for failure when passed=false */ failureReason?: string | null; /** @@ -5529,13 +5644,13 @@ export interface components { * @description Number of components reported by the service * @example 12 */ - componentCount: number; + componentCount?: number; /** * Format: int32 * @description Number of degraded or non-operational components * @example 1 */ - degradedCount: number; + degradedCount?: number; }; /** @description Aggregated poll metrics and chart data for a service */ ServicePollSummaryDto: { @@ -5550,13 +5665,13 @@ export interface components { * @description Total number of polls executed * @example 4320 */ - totalPolls: number; + totalPolls?: number; /** * Format: int64 * @description Number of polls that succeeded * @example 4318 */ - passedPolls: number; + passedPolls?: number; /** * Format: double * @description Average response time in milliseconds; null when no data @@ -5610,8 +5725,8 @@ export interface components { officialStatusUrl?: string | null; adapterType: string; /** Format: int32 */ - pollingIntervalSeconds: number; - enabled: boolean; + pollingIntervalSeconds?: number; + enabled?: boolean; /** @description Logo URL from the service catalog */ logoUrl?: string | null; /** @description Current overall status; null when the service has never been polled */ @@ -5763,6 +5878,9 @@ export interface components { SingleValueResponseSecretDto: { data: components["schemas"]["SecretDto"]; }; + SingleValueResponseServiceDayDetailDto: { + data: components["schemas"]["ServiceDayDetailDto"]; + }; SingleValueResponseServiceDetailDto: { data: components["schemas"]["ServiceDetailDto"]; }; @@ -5843,7 +5961,7 @@ export interface components { * Format: int32 * @description Minimum days before TLS certificate expiry; fails or warns below this threshold */ - minDaysRemaining?: number; + minDaysRemaining: number; } & { /** * @description discriminator enum property added by openapi-typescript @@ -5888,7 +6006,10 @@ export interface components { theme?: string | null; /** @description URL where visitors can report a problem */ reportUrl?: string | null; - /** @description Whether to hide the 'Powered by DevHelm' footer badge */ + /** + * @description Whether to hide the 'Powered by DevHelm' footer badge (default: false) + * @default false + */ hidePoweredBy: boolean; /** @description Custom CSS injected via