@oneuptime/common 12.0.1 → 12.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.ts +14 -0
- package/Models/DatabaseModels/Host.ts +12 -4
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/KubernetesContainer.ts +5 -4
- package/Models/DatabaseModels/KubernetesResource.ts +8 -7
- package/Models/DatabaseModels/LogDropFilter.ts +9 -20
- package/Models/DatabaseModels/PodmanResource.ts +6 -6
- package/Models/DatabaseModels/ServiceLevelObjective.ts +91 -0
- package/Models/DatabaseModels/StatusPage.ts +95 -0
- package/Models/DatabaseModels/StatusPageMonitorRule.ts +911 -0
- package/Models/DatabaseModels/StatusPageResource.ts +73 -0
- package/Models/DatabaseModels/TraceDropFilter.ts +9 -20
- package/Server/API/BaseAPI.ts +13 -2
- package/Server/API/DashboardAPI.ts +39 -0
- package/Server/API/TeamMemberAPI.ts +85 -0
- package/Server/EnvironmentConfig.ts +31 -1
- package/Server/Infrastructure/GlobalCache.ts +115 -0
- package/Server/Infrastructure/Postgres/DataSourceOptions.ts +16 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785900000000-AddSloMonitorLabelRule.ts +84 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785915638551-IncreaseHostIpAddressesLength.ts +40 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785930000000-WidenInventoryResourceNameColumns.ts +131 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785930709405-AddStatusPageReportPeriod.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786005052769-AddStatusPageMonitorRule.ts +123 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
- package/Server/Middleware/ProjectAuthorization.ts +66 -4
- package/Server/Services/AlertStateTimelineService.ts +20 -0
- package/Server/Services/BillingService.ts +600 -51
- package/Server/Services/CephClusterService.ts +27 -45
- package/Server/Services/CephResourceService.ts +43 -4
- package/Server/Services/CloudResourceService.ts +24 -42
- package/Server/Services/DatabaseService.ts +198 -6
- package/Server/Services/DockerHostService.ts +20 -38
- package/Server/Services/DockerResourceService.ts +62 -8
- package/Server/Services/DockerSwarmClusterService.ts +28 -46
- package/Server/Services/DockerSwarmResourceService.ts +53 -4
- package/Server/Services/HostService.ts +47 -57
- package/Server/Services/IncidentStateTimelineService.ts +20 -0
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/IoTDeviceService.ts +1 -17
- package/Server/Services/IoTFleetService.ts +20 -38
- package/Server/Services/KubernetesClusterService.ts +18 -36
- package/Server/Services/KubernetesContainerService.ts +50 -9
- package/Server/Services/KubernetesResourceService.ts +53 -7
- package/Server/Services/LabelService.ts +153 -1
- package/Server/Services/MetricTypeService.ts +84 -0
- package/Server/Services/MonitorService.ts +146 -14
- package/Server/Services/MonitorStatusTimelineService.ts +29 -0
- package/Server/Services/MonitorTemplateService.ts +65 -0
- package/Server/Services/PodmanHostService.ts +20 -38
- package/Server/Services/PodmanResourceService.ts +62 -8
- package/Server/Services/ProjectService.ts +165 -35
- package/Server/Services/ProxmoxClusterService.ts +24 -42
- package/Server/Services/ProxmoxResourceService.ts +43 -4
- package/Server/Services/RumApplicationService.ts +20 -38
- package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +21 -0
- package/Server/Services/ServerlessFunctionService.ts +25 -43
- package/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.ts +426 -0
- package/Server/Services/ServiceLevelObjectiveService.ts +39 -0
- package/Server/Services/ServiceService.ts +299 -73
- package/Server/Services/StatusPageMonitorRuleEngineService.ts +752 -0
- package/Server/Services/StatusPageMonitorRuleService.ts +471 -0
- package/Server/Services/StatusPageService.ts +95 -36
- package/Server/Services/StatusPageSubscriberNotificationTemplateService.ts +18 -1
- package/Server/Services/StatusPageSubscriberService.ts +3 -0
- package/Server/Services/TelemetryEntityRelationshipService.ts +1 -0
- package/Server/Services/TelemetryEntityService.ts +1 -0
- package/Server/Types/Database/JSONColumnQuery.ts +621 -0
- package/Server/Types/Database/Permissions/PublicPermission.ts +9 -2
- package/Server/Types/Database/QueryHelper.ts +17 -32
- package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +170 -39
- package/Server/Utils/Database/TruncateColumnValue.ts +84 -0
- package/Server/Utils/Monitor/MonitorResource.ts +63 -36
- package/Server/Utils/Monitor/MonitorStatusTimeline.ts +36 -0
- package/Server/Utils/Monitor/MonitorStepsProjectValidator.ts +148 -127
- package/Server/Utils/Monitor/MonitorStepsReferenceExtractor.ts +434 -0
- package/Server/Utils/SingleFlight.ts +83 -0
- package/Server/Utils/StatusPage/MonitorRulePatternValidator.ts +46 -0
- package/Server/Utils/Telemetry/EntityRegistry.ts +107 -26
- package/Server/Utils/Telemetry/ResourceHeartbeat.ts +314 -0
- package/Server/Utils/Telemetry/Telemetry.ts +351 -122
- package/Tests/App/Dashboard/UsersTableGroupsByPerson.test.tsx +448 -0
- package/Tests/App/Dashboard/WidgetCatalog.test.ts +2 -0
- package/Tests/Models/DatabaseModels/ColumnTransformerInvariants.test.ts +306 -0
- package/Tests/Models/DatabaseModels/NumberColumnDeserialization.test.ts +333 -0
- package/Tests/Models/DatabaseModels/StatusPageMonitorRuleModel.test.ts +190 -0
- package/Tests/Server/API/BaseAPIApiKeyAuth.test.ts +704 -0
- package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +26 -0
- package/Tests/Server/API/TeamMemberRemoveUserFromProjectAPI.test.ts +303 -0
- package/Tests/Server/Infrastructure/GlobalCache.test.ts +226 -0
- package/Tests/Server/Infrastructure/PostgresLockTimeoutOptions.test.ts +181 -0
- package/Tests/Server/Middleware/MasterAdminAuthorization.test.ts +350 -0
- package/Tests/Server/Middleware/ProjectAuthorizationApiKeyHeader.test.ts +362 -0
- package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +687 -0
- package/Tests/Server/Services/BillingService.test.ts +78 -3
- package/Tests/Server/Services/BillingServiceChangePlanCancel.test.ts +645 -0
- package/Tests/Server/Services/BillingServiceTrialPlanChange.test.ts +1005 -0
- package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlocked.test.ts +342 -0
- package/Tests/Server/Services/DropFilterSaveValidation.test.ts +245 -0
- package/Tests/Server/Services/HookFreeWriteLengthClamp.test.ts +503 -0
- package/Tests/Server/Services/HostIpAddressesColumnWidth.test.ts +198 -0
- package/Tests/Server/Services/HostServiceUpdateLastSeen.test.ts +658 -0
- package/Tests/Server/Services/InventoryResourceNameColumnWidth.test.ts +500 -0
- package/Tests/Server/Services/InventoryUpsertSchemaParity.test.ts +586 -0
- package/Tests/Server/Services/InventoryUpsertTruncationGuard.test.ts +1242 -0
- package/Tests/Server/Services/MetricTypeAttachServices.test.ts +222 -0
- package/Tests/Server/Services/MissingReferenceWriteGuard.test.ts +614 -0
- package/Tests/Server/Services/MonitorStatusTimelineFastPath.test.ts +23 -0
- package/Tests/Server/Services/ProjectServiceChangePlan.test.ts +650 -0
- package/Tests/Server/Services/ProjectServiceExtendTrial.test.ts +1 -0
- package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +636 -0
- package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.test.ts +770 -0
- package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +130 -0
- package/Tests/Server/Services/ServiceUpdateLastSeenSplitGates.test.ts +705 -0
- package/Tests/Server/Services/SloMonitorLabelRuleHooks.test.ts +352 -0
- package/Tests/Server/Services/StatusPageMonitorRuleEngineService.test.ts +1719 -0
- package/Tests/Server/Services/StatusPageMonitorRuleHooks.test.ts +1212 -0
- package/Tests/Server/Services/StatusPageMonitorRuleMonitorCreateHook.test.ts +228 -0
- package/Tests/Server/Services/StatusPageSubscriberReport.test.ts +29 -13
- package/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts +69 -8
- package/Tests/Server/Types/Database/JSONColumnQuery.test.ts +593 -0
- package/Tests/Server/Types/Database/Permissions/PublicPermission.test.ts +495 -0
- package/Tests/Server/Types/Database/QueryUtil.test.ts +113 -0
- package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +267 -0
- package/Tests/Server/Utils/Database/ProjectScopedReferenceValidator.test.ts +260 -13
- package/Tests/Server/Utils/Database/TruncateColumnValue.test.ts +179 -0
- package/Tests/Server/Utils/EntityRegistryRowFence.test.ts +302 -0
- package/Tests/Server/Utils/MetricTypeIndexConvergence.test.ts +598 -0
- package/Tests/Server/Utils/Monitor/MonitorStatusTimelineUnusableStatus.test.ts +154 -0
- package/Tests/Server/Utils/Monitor/MonitorStepsProjectValidator.test.ts +638 -92
- package/Tests/Server/Utils/Monitor/MonitorStepsReferenceExtractor.test.ts +724 -0
- package/Tests/Server/Utils/SingleFlight.test.ts +221 -0
- package/Tests/Types/Dashboard/NetworkDashboardTemplate.test.ts +793 -0
- package/Tests/Types/Database/BigIntColumnTransformer.test.ts +147 -0
- package/Tests/Types/Database/DatabasePropertyTransformer.test.ts +140 -0
- package/Tests/Types/Database/NumericColumnValue.test.ts +127 -0
- package/Tests/Types/Decimal.test.ts +37 -0
- package/Tests/Types/Events/Recurring.test.ts +157 -0
- package/Tests/Types/Monitor/SnmpVersionParsing.test.ts +152 -0
- package/Tests/Types/Port.test.ts +38 -0
- package/Tests/UI/Components/LogsHistogram.test.tsx +276 -0
- package/Tests/UI/Components/ModelTable/ModelTableGroupsProjectUsers.test.tsx +375 -0
- package/Tests/UI/Components/ModelTable/useCustomFieldColumns.test.tsx +196 -0
- package/Tests/UI/Components/UseLiveLogsRefresh.test.tsx +489 -0
- package/Tests/UI/Components/UseLogsHistogram.test.tsx +500 -0
- package/Tests/UI/Utils/ProjectUsersModelAPI.test.ts +739 -0
- package/Tests/UI/Utils/TeamMembersByUser.test.ts +633 -0
- package/Tests/Utils/Dashboard/Components/DashboardComponentsUtil.test.ts +120 -0
- package/Tests/Utils/Dashboard/DashboardNetworkMapComponent.test.ts +327 -0
- package/Tests/Utils/StatusPage/ReportPeriod.test.ts +218 -0
- package/Tests/Utils/Telemetry/HostIpAddresses.test.ts +291 -0
- package/Types/CustomField/CustomFieldDefinition.ts +24 -0
- package/Types/Dashboard/DashboardComponentType.ts +1 -0
- package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +1 -0
- package/Types/Dashboard/DashboardComponents/DashboardNetworkMapComponent.ts +40 -0
- package/Types/Dashboard/DashboardTemplates.ts +397 -0
- package/Types/Database/BigIntColumnTransformer.ts +74 -0
- package/Types/Database/DatabaseProperty.ts +26 -0
- package/Types/Database/NumericColumnValue.ts +128 -0
- package/Types/Date.ts +112 -0
- package/Types/Decimal.ts +16 -4
- package/Types/Events/Recurring.ts +99 -1
- package/Types/Permission.ts +48 -0
- package/Types/Port.ts +16 -4
- package/Types/StatusPage/StatusPageReport.ts +11 -0
- package/Types/StatusPage/StatusPageReportPeriodType.ts +21 -0
- package/UI/Components/LogsViewer/useLiveLogsRefresh.ts +86 -0
- package/UI/Components/LogsViewer/useLogsHistogram.ts +113 -0
- package/UI/Components/ModelTable/CustomFieldColumns.tsx +2 -6
- package/UI/Components/ModelTable/useCustomFieldColumns.ts +21 -2
- package/UI/Utils/ModelAPI/ProjectUsersModelAPI.ts +305 -0
- package/UI/Utils/TeamMembersByUser.ts +302 -0
- package/Utils/Dashboard/Components/DashboardNetworkMapComponent.ts +136 -0
- package/Utils/Dashboard/Components/Index.ts +7 -0
- package/Utils/StatusPage/ReportPeriod.ts +236 -0
- package/Utils/Telemetry/HostIpAddresses.ts +98 -0
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js +12 -0
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Host.js +12 -4
- package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesContainer.js +4 -4
- package/build/dist/Models/DatabaseModels/KubernetesContainer.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesResource.js +7 -7
- package/build/dist/Models/DatabaseModels/KubernetesResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/LogDropFilter.js +9 -20
- package/build/dist/Models/DatabaseModels/LogDropFilter.js.map +1 -1
- package/build/dist/Models/DatabaseModels/PodmanResource.js +6 -6
- package/build/dist/Models/DatabaseModels/PodmanResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js +87 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +98 -0
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageMonitorRule.js +925 -0
- package/build/dist/Models/DatabaseModels/StatusPageMonitorRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/StatusPageResource.js +72 -0
- package/build/dist/Models/DatabaseModels/StatusPageResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TraceDropFilter.js +9 -20
- package/build/dist/Models/DatabaseModels/TraceDropFilter.js.map +1 -1
- package/build/dist/Server/API/BaseAPI.js +11 -1
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/DashboardAPI.js +39 -0
- package/build/dist/Server/API/DashboardAPI.js.map +1 -1
- package/build/dist/Server/API/TeamMemberAPI.js +57 -2
- package/build/dist/Server/API/TeamMemberAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +27 -1
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/GlobalCache.js +91 -0
- package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js +5 -3
- package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785900000000-AddSloMonitorLabelRule.js +45 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785900000000-AddSloMonitorLabelRule.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785915638551-IncreaseHostIpAddressesLength.js +31 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785915638551-IncreaseHostIpAddressesLength.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930000000-WidenInventoryResourceNameColumns.js +90 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930000000-WidenInventoryResourceNameColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930709405-AddStatusPageReportPeriod.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930709405-AddStatusPageReportPeriod.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786005052769-AddStatusPageMonitorRule.js +48 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786005052769-AddStatusPageMonitorRule.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/ProjectAuthorization.js +59 -4
- package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
- package/build/dist/Server/Services/AlertStateTimelineService.js +19 -0
- package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/BillingService.js +466 -36
- package/build/dist/Server/Services/BillingService.js.map +1 -1
- package/build/dist/Server/Services/CephClusterService.js +26 -39
- package/build/dist/Server/Services/CephClusterService.js.map +1 -1
- package/build/dist/Server/Services/CephResourceService.js +28 -3
- package/build/dist/Server/Services/CephResourceService.js.map +1 -1
- package/build/dist/Server/Services/CloudResourceService.js +23 -36
- package/build/dist/Server/Services/CloudResourceService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +155 -2
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DockerHostService.js +19 -32
- package/build/dist/Server/Services/DockerHostService.js.map +1 -1
- package/build/dist/Server/Services/DockerResourceService.js +34 -4
- package/build/dist/Server/Services/DockerResourceService.js.map +1 -1
- package/build/dist/Server/Services/DockerSwarmClusterService.js +27 -40
- package/build/dist/Server/Services/DockerSwarmClusterService.js.map +1 -1
- package/build/dist/Server/Services/DockerSwarmResourceService.js +28 -3
- package/build/dist/Server/Services/DockerSwarmResourceService.js.map +1 -1
- package/build/dist/Server/Services/HostService.js +58 -64
- package/build/dist/Server/Services/HostService.js.map +1 -1
- package/build/dist/Server/Services/IncidentStateTimelineService.js +19 -0
- package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/IoTDeviceService.js +1 -8
- package/build/dist/Server/Services/IoTDeviceService.js.map +1 -1
- package/build/dist/Server/Services/IoTFleetService.js +19 -32
- package/build/dist/Server/Services/IoTFleetService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesClusterService.js +17 -30
- package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesContainerService.js +29 -3
- package/build/dist/Server/Services/KubernetesContainerService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesResourceService.js +32 -4
- package/build/dist/Server/Services/KubernetesResourceService.js.map +1 -1
- package/build/dist/Server/Services/LabelService.js +127 -0
- package/build/dist/Server/Services/LabelService.js.map +1 -1
- package/build/dist/Server/Services/MetricTypeService.js +74 -0
- package/build/dist/Server/Services/MetricTypeService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +128 -9
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorStatusTimelineService.js +28 -0
- package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
- package/build/dist/Server/Services/MonitorTemplateService.js +60 -0
- package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
- package/build/dist/Server/Services/PodmanHostService.js +19 -32
- package/build/dist/Server/Services/PodmanHostService.js.map +1 -1
- package/build/dist/Server/Services/PodmanResourceService.js +34 -4
- package/build/dist/Server/Services/PodmanResourceService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +135 -21
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxClusterService.js +23 -36
- package/build/dist/Server/Services/ProxmoxClusterService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxResourceService.js +28 -3
- package/build/dist/Server/Services/ProxmoxResourceService.js.map +1 -1
- package/build/dist/Server/Services/RumApplicationService.js +19 -32
- package/build/dist/Server/Services/RumApplicationService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +20 -0
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/ServerlessFunctionService.js +24 -37
- package/build/dist/Server/Services/ServerlessFunctionService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js +347 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js +33 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
- package/build/dist/Server/Services/ServiceService.js +236 -61
- package/build/dist/Server/Services/ServiceService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js +603 -0
- package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/StatusPageMonitorRuleService.js +401 -0
- package/build/dist/Server/Services/StatusPageMonitorRuleService.js.map +1 -0
- package/build/dist/Server/Services/StatusPageService.js +69 -46
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js +17 -1
- package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberService.js +3 -0
- package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryEntityRelationshipService.js +1 -0
- package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryEntityService.js +1 -0
- package/build/dist/Server/Services/TelemetryEntityService.js.map +1 -1
- package/build/dist/Server/Types/Database/JSONColumnQuery.js +402 -0
- package/build/dist/Server/Types/Database/JSONColumnQuery.js.map +1 -0
- package/build/dist/Server/Types/Database/Permissions/PublicPermission.js +9 -2
- package/build/dist/Server/Types/Database/Permissions/PublicPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js +17 -27
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +105 -29
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
- package/build/dist/Server/Utils/Database/TruncateColumnValue.js +32 -0
- package/build/dist/Server/Utils/Database/TruncateColumnValue.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +56 -32
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js +30 -3
- package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js +110 -98
- package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorStepsReferenceExtractor.js +312 -0
- package/build/dist/Server/Utils/Monitor/MonitorStepsReferenceExtractor.js.map +1 -0
- package/build/dist/Server/Utils/SingleFlight.js +76 -0
- package/build/dist/Server/Utils/SingleFlight.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js +29 -0
- package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +78 -19
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js +160 -0
- package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/Telemetry.js +279 -104
- package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
- package/build/dist/Types/CustomField/CustomFieldDefinition.js +2 -0
- package/build/dist/Types/CustomField/CustomFieldDefinition.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardNetworkMapComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardNetworkMapComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.js +368 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
- package/build/dist/Types/Database/BigIntColumnTransformer.js +66 -0
- package/build/dist/Types/Database/BigIntColumnTransformer.js.map +1 -0
- package/build/dist/Types/Database/DatabaseProperty.js +25 -0
- package/build/dist/Types/Database/DatabaseProperty.js.map +1 -1
- package/build/dist/Types/Database/NumericColumnValue.js +97 -0
- package/build/dist/Types/Database/NumericColumnValue.js.map +1 -0
- package/build/dist/Types/Date.js +68 -0
- package/build/dist/Types/Date.js.map +1 -1
- package/build/dist/Types/Decimal.js +14 -3
- package/build/dist/Types/Decimal.js.map +1 -1
- package/build/dist/Types/Events/Recurring.js +63 -0
- package/build/dist/Types/Events/Recurring.js.map +1 -1
- package/build/dist/Types/Permission.js +42 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Port.js +15 -5
- package/build/dist/Types/Port.js.map +1 -1
- package/build/dist/Types/StatusPage/StatusPageReportPeriodType.js +22 -0
- package/build/dist/Types/StatusPage/StatusPageReportPeriodType.js.map +1 -0
- package/build/dist/UI/Components/LogsViewer/useLiveLogsRefresh.js +44 -0
- package/build/dist/UI/Components/LogsViewer/useLiveLogsRefresh.js.map +1 -0
- package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js +75 -0
- package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +18 -2
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js +213 -0
- package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js.map +1 -0
- package/build/dist/UI/Utils/TeamMembersByUser.js +195 -0
- package/build/dist/UI/Utils/TeamMembersByUser.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardNetworkMapComponent.js +114 -0
- package/build/dist/Utils/Dashboard/Components/DashboardNetworkMapComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
- package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
- package/build/dist/Utils/StatusPage/ReportPeriod.js +131 -0
- package/build/dist/Utils/StatusPage/ReportPeriod.js.map +1 -0
- package/build/dist/Utils/Telemetry/HostIpAddresses.js +82 -0
- package/build/dist/Utils/Telemetry/HostIpAddresses.js.map +1 -0
- package/jest.config.json +2 -0
- package/package.json +1 -1
- package/tsconfig.json +12 -1
package/Types/Date.ts
CHANGED
|
@@ -9,6 +9,12 @@ import Zod, { ZodSchema } from "../Utils/Schema/Zod";
|
|
|
9
9
|
|
|
10
10
|
export const Moment: typeof moment = moment;
|
|
11
11
|
|
|
12
|
+
/*
|
|
13
|
+
* The units a calendar (rather than a fixed-length) interval can be measured in.
|
|
14
|
+
* See getStartOfCalendarUnit / addRemoveCalendarUnits below.
|
|
15
|
+
*/
|
|
16
|
+
export type CalendarUnit = "hour" | "day" | "week" | "month" | "year";
|
|
17
|
+
|
|
12
18
|
export default class OneUptimeDate {
|
|
13
19
|
// get date time from unix timestamp
|
|
14
20
|
|
|
@@ -363,6 +369,27 @@ export default class OneUptimeDate {
|
|
|
363
369
|
).trim();
|
|
364
370
|
}
|
|
365
371
|
|
|
372
|
+
/*
|
|
373
|
+
* Format an instant with an explicit moment format string, resolved in an
|
|
374
|
+
* IANA timezone. The formatted-string helpers above each bake in a layout;
|
|
375
|
+
* this one is for callers that need a specific shape ("MMMM YYYY" for the
|
|
376
|
+
* month a status page report covers) and know exactly which zone it must be
|
|
377
|
+
* read in. Falls back to the viewer's / process's zone without one.
|
|
378
|
+
*/
|
|
379
|
+
public static getDateAsCustomFormattedStringInTimezone(data: {
|
|
380
|
+
date: Date | string;
|
|
381
|
+
format: string;
|
|
382
|
+
timezone?: string | undefined;
|
|
383
|
+
}): string {
|
|
384
|
+
const date: Date = this.fromString(data.date);
|
|
385
|
+
|
|
386
|
+
if (!data.timezone) {
|
|
387
|
+
return this.inCurrentTimezone(date).format(data.format);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
return moment(date).tz(data.timezone).format(data.format);
|
|
391
|
+
}
|
|
392
|
+
|
|
366
393
|
/**
|
|
367
394
|
* Reinterpret the wall-clock components of `date` — read in the CURRENT
|
|
368
395
|
* timezone, i.e. the one the pickers render in — as the SAME wall-clock in
|
|
@@ -1213,6 +1240,91 @@ export default class OneUptimeDate {
|
|
|
1213
1240
|
return moment(date).endOf("day").toDate();
|
|
1214
1241
|
}
|
|
1215
1242
|
|
|
1243
|
+
/*
|
|
1244
|
+
* Calendar arithmetic - "the previous calendar month", "add 3 calendar
|
|
1245
|
+
* months" - as opposed to the fixed-length arithmetic the rest of this class
|
|
1246
|
+
* does. A calendar month is 28-31 days long and a calendar day is 23-25 hours
|
|
1247
|
+
* long across a DST transition, so anything that has to line up with a wall
|
|
1248
|
+
* clock (a status page report that must read "Jul 1 - Jul 31", a schedule that
|
|
1249
|
+
* must keep firing at 09:00 local) cannot be expressed by adding milliseconds.
|
|
1250
|
+
*
|
|
1251
|
+
* Every helper below takes an optional IANA timezone. Without one the
|
|
1252
|
+
* boundaries land in the process's local zone, which on a server is UTC.
|
|
1253
|
+
*/
|
|
1254
|
+
private static toMomentCalendarUnit(
|
|
1255
|
+
unit: CalendarUnit,
|
|
1256
|
+
forStartOf: boolean,
|
|
1257
|
+
): moment.unitOfTime.StartOf & moment.unitOfTime.DurationConstructor {
|
|
1258
|
+
/*
|
|
1259
|
+
* moment's "week" starts on the locale's first day, which differs between
|
|
1260
|
+
* environments and would make a weekly report cover Sun-Sat on one host and
|
|
1261
|
+
* Mon-Sun on another. ISO weeks are always Monday-Sunday, so the boundary is
|
|
1262
|
+
* the same everywhere. Durations have no such ambiguity - a week is 7 days -
|
|
1263
|
+
* and moment has no "isoWeek" duration, so only startOf is remapped.
|
|
1264
|
+
*/
|
|
1265
|
+
if (unit === "week" && forStartOf) {
|
|
1266
|
+
return "isoWeek" as moment.unitOfTime.StartOf &
|
|
1267
|
+
moment.unitOfTime.DurationConstructor;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
return unit as moment.unitOfTime.StartOf &
|
|
1271
|
+
moment.unitOfTime.DurationConstructor;
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
private static inTimezone(
|
|
1275
|
+
date: Date,
|
|
1276
|
+
timezone?: string | undefined,
|
|
1277
|
+
): moment.Moment {
|
|
1278
|
+
return timezone ? moment.tz(date, timezone) : moment(date);
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
/*
|
|
1282
|
+
* The instant the calendar unit containing `date` began - e.g. the first
|
|
1283
|
+
* millisecond of that month, in `timezone`.
|
|
1284
|
+
*/
|
|
1285
|
+
public static getStartOfCalendarUnit(
|
|
1286
|
+
date: Date,
|
|
1287
|
+
unit: CalendarUnit,
|
|
1288
|
+
timezone?: string | undefined,
|
|
1289
|
+
): Date {
|
|
1290
|
+
return this.inTimezone(this.fromString(date), timezone)
|
|
1291
|
+
.startOf(this.toMomentCalendarUnit(unit, true))
|
|
1292
|
+
.toDate();
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
/*
|
|
1296
|
+
* Move `date` by whole calendar units, keeping the wall clock in `timezone`.
|
|
1297
|
+
* Adding one month to Jan 31 lands on Feb 28/29 (moment clamps), and adding a
|
|
1298
|
+
* day across a DST boundary still lands at the same local time.
|
|
1299
|
+
*/
|
|
1300
|
+
public static addRemoveCalendarUnits(
|
|
1301
|
+
date: Date,
|
|
1302
|
+
unit: CalendarUnit,
|
|
1303
|
+
count: number,
|
|
1304
|
+
timezone?: string | undefined,
|
|
1305
|
+
): Date {
|
|
1306
|
+
return this.inTimezone(this.fromString(date), timezone)
|
|
1307
|
+
.add(count, this.toMomentCalendarUnit(unit, false))
|
|
1308
|
+
.toDate();
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
/*
|
|
1312
|
+
* How many whole calendar units fit between the two instants, measured in
|
|
1313
|
+
* `timezone`. Used to jump a recurrence forward to "now" in one step instead
|
|
1314
|
+
* of looping one interval at a time.
|
|
1315
|
+
*/
|
|
1316
|
+
public static getCalendarUnitsBetween(
|
|
1317
|
+
startDate: Date,
|
|
1318
|
+
endDate: Date,
|
|
1319
|
+
unit: CalendarUnit,
|
|
1320
|
+
timezone?: string | undefined,
|
|
1321
|
+
): number {
|
|
1322
|
+
return this.inTimezone(this.fromString(endDate), timezone).diff(
|
|
1323
|
+
this.inTimezone(this.fromString(startDate), timezone),
|
|
1324
|
+
this.toMomentCalendarUnit(unit, false),
|
|
1325
|
+
);
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1216
1328
|
public static isBetween(date: Date, startDate: Date, endDate: Date): boolean {
|
|
1217
1329
|
date = this.fromString(date);
|
|
1218
1330
|
startDate = this.fromString(startDate);
|
package/Types/Decimal.ts
CHANGED
|
@@ -35,14 +35,26 @@ export default class Decimal extends DatabaseProperty {
|
|
|
35
35
|
return this.value.toString();
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
/*
|
|
39
|
+
* A decimal column is declared `TableColumnType.Number`, so what reaches
|
|
40
|
+
* the transformer may be a Decimal, a string, or a plain number depending
|
|
41
|
+
* on how far the request body got through deserialization.
|
|
42
|
+
*
|
|
43
|
+
* Both raw forms are handled before the truthiness check, because `0` is a
|
|
44
|
+
* perfectly good decimal and the old `if (value)` sent it to `null` — on a
|
|
45
|
+
* NOT NULL column that is a constraint violation for a value the caller
|
|
46
|
+
* supplied.
|
|
47
|
+
*/
|
|
38
48
|
protected static override toDatabase(
|
|
39
49
|
value: Decimal | FindOperator<Decimal>,
|
|
40
50
|
): string | null {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
51
|
+
const rawValue: unknown = value;
|
|
52
|
+
|
|
53
|
+
if (typeof rawValue === "string" || typeof rawValue === "number") {
|
|
54
|
+
return new Decimal(rawValue).toString();
|
|
55
|
+
}
|
|
45
56
|
|
|
57
|
+
if (value) {
|
|
46
58
|
return value.toString();
|
|
47
59
|
}
|
|
48
60
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import DatabaseProperty from "../Database/DatabaseProperty";
|
|
2
|
-
import OneUptimeDate from "../Date";
|
|
2
|
+
import OneUptimeDate, { CalendarUnit } from "../Date";
|
|
3
3
|
import BadDataException from "../Exception/BadDataException";
|
|
4
4
|
import { JSONArray, JSONObject, ObjectType } from "../JSON";
|
|
5
5
|
import JSONFunctions from "../JSONFunctions";
|
|
@@ -109,6 +109,104 @@ export default class Recurring extends DatabaseProperty {
|
|
|
109
109
|
return nextDate;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
+
/*
|
|
113
|
+
* The calendar unit this interval is expressed in, for the date helpers that
|
|
114
|
+
* do calendar (rather than fixed-millisecond) arithmetic.
|
|
115
|
+
*/
|
|
116
|
+
public static toCalendarUnit(intervalType: EventInterval): CalendarUnit {
|
|
117
|
+
switch (intervalType) {
|
|
118
|
+
case EventInterval.Hour:
|
|
119
|
+
return "hour";
|
|
120
|
+
case EventInterval.Day:
|
|
121
|
+
return "day";
|
|
122
|
+
case EventInterval.Week:
|
|
123
|
+
return "week";
|
|
124
|
+
case EventInterval.Month:
|
|
125
|
+
return "month";
|
|
126
|
+
case EventInterval.Year:
|
|
127
|
+
return "year";
|
|
128
|
+
default:
|
|
129
|
+
throw new BadDataException("Invalid Interval Type: " + intervalType);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* The first occurrence of `recurring` (anchored at `startDate`) strictly after
|
|
135
|
+
* `afterDate`, stepping in whole CALENDAR units in `timezone`.
|
|
136
|
+
*
|
|
137
|
+
* getNextDate() approximates a month as 30.4375 days and a year as 365.25
|
|
138
|
+
* days, which is fine for hours/days/weeks but makes a monthly recurrence
|
|
139
|
+
* walk backwards through the calendar: anchored on 1 Jul it fires on 31 Jul,
|
|
140
|
+
* then 30 Aug, and eventually skips a month entirely. This steps 1 Jul ->
|
|
141
|
+
* 1 Aug -> 1 Sep instead, and holds the local time of day across DST.
|
|
142
|
+
*
|
|
143
|
+
* A start date already after `afterDate` is returned unchanged - the first
|
|
144
|
+
* occurrence has not happened yet.
|
|
145
|
+
*/
|
|
146
|
+
public static getNextDateAfter(data: {
|
|
147
|
+
startDate: Date;
|
|
148
|
+
recurring: Recurring;
|
|
149
|
+
afterDate: Date;
|
|
150
|
+
timezone?: string | undefined;
|
|
151
|
+
}): Date {
|
|
152
|
+
const startDate: Date = OneUptimeDate.fromString(data.startDate);
|
|
153
|
+
const recurring: Recurring = Recurring.fromJSON(data.recurring);
|
|
154
|
+
const unit: CalendarUnit = Recurring.toCalendarUnit(recurring.intervalType);
|
|
155
|
+
|
|
156
|
+
const intervalCount: number = Math.max(
|
|
157
|
+
1,
|
|
158
|
+
Math.floor(recurring.intervalCount.toNumber()),
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
if (startDate.getTime() > data.afterDate.getTime()) {
|
|
162
|
+
return startDate;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/*
|
|
166
|
+
* Jump most of the way in one step so a status page left disabled for a year
|
|
167
|
+
* does not loop 365 times, then walk the remainder. The estimate can only be
|
|
168
|
+
* off by a single interval either way (calendar units are not uniform), so
|
|
169
|
+
* the two loops below run a handful of times at most.
|
|
170
|
+
*/
|
|
171
|
+
const elapsedUnits: number = OneUptimeDate.getCalendarUnitsBetween(
|
|
172
|
+
startDate,
|
|
173
|
+
data.afterDate,
|
|
174
|
+
unit,
|
|
175
|
+
data.timezone,
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
let intervals: number = Math.max(
|
|
179
|
+
0,
|
|
180
|
+
Math.floor(elapsedUnits / intervalCount),
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
type OccurrenceFunction = (intervalsToAdd: number) => Date;
|
|
184
|
+
|
|
185
|
+
const occurrence: OccurrenceFunction = (intervalsToAdd: number): Date => {
|
|
186
|
+
return OneUptimeDate.addRemoveCalendarUnits(
|
|
187
|
+
startDate,
|
|
188
|
+
unit,
|
|
189
|
+
intervalsToAdd * intervalCount,
|
|
190
|
+
data.timezone,
|
|
191
|
+
);
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
// Overshot - come back until we are at or before the cutoff.
|
|
195
|
+
while (
|
|
196
|
+
intervals > 0 &&
|
|
197
|
+
occurrence(intervals - 1).getTime() > data.afterDate.getTime()
|
|
198
|
+
) {
|
|
199
|
+
intervals--;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Undershot - advance until we are strictly after it.
|
|
203
|
+
while (occurrence(intervals).getTime() <= data.afterDate.getTime()) {
|
|
204
|
+
intervals++;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return occurrence(intervals);
|
|
208
|
+
}
|
|
209
|
+
|
|
112
210
|
private data: RecurringData = Recurring.getDefaultRotationData();
|
|
113
211
|
|
|
114
212
|
public get intervalType(): EventInterval {
|
package/Types/Permission.ts
CHANGED
|
@@ -484,6 +484,12 @@ enum Permission {
|
|
|
484
484
|
EditStatusPageLabelRule = "EditStatusPageLabelRule",
|
|
485
485
|
ReadStatusPageLabelRule = "ReadStatusPageLabelRule",
|
|
486
486
|
|
|
487
|
+
// Status Page Monitor Rule Permissions
|
|
488
|
+
CreateStatusPageMonitorRule = "CreateStatusPageMonitorRule",
|
|
489
|
+
DeleteStatusPageMonitorRule = "DeleteStatusPageMonitorRule",
|
|
490
|
+
EditStatusPageMonitorRule = "EditStatusPageMonitorRule",
|
|
491
|
+
ReadStatusPageMonitorRule = "ReadStatusPageMonitorRule",
|
|
492
|
+
|
|
487
493
|
// Host Owner Rule Permissions
|
|
488
494
|
CreateHostOwnerRule = "CreateHostOwnerRule",
|
|
489
495
|
DeleteHostOwnerRule = "DeleteHostOwnerRule",
|
|
@@ -11104,6 +11110,48 @@ export class PermissionHelper {
|
|
|
11104
11110
|
group: PermissionGroup.StatusPage,
|
|
11105
11111
|
},
|
|
11106
11112
|
|
|
11113
|
+
// Status Page Monitor Rule Permissions
|
|
11114
|
+
{
|
|
11115
|
+
permission: Permission.CreateStatusPageMonitorRule,
|
|
11116
|
+
title: "Create Status Page Monitor Rule",
|
|
11117
|
+
description:
|
|
11118
|
+
"This permission can create Status Page Monitor Rules in this project.",
|
|
11119
|
+
isAssignableToTenant: true,
|
|
11120
|
+
isAccessControlPermission: false,
|
|
11121
|
+
isRolePermission: false,
|
|
11122
|
+
group: PermissionGroup.StatusPage,
|
|
11123
|
+
},
|
|
11124
|
+
{
|
|
11125
|
+
permission: Permission.DeleteStatusPageMonitorRule,
|
|
11126
|
+
title: "Delete Status Page Monitor Rule",
|
|
11127
|
+
description:
|
|
11128
|
+
"This permission can delete Status Page Monitor Rules of this project.",
|
|
11129
|
+
isAssignableToTenant: true,
|
|
11130
|
+
isAccessControlPermission: false,
|
|
11131
|
+
isRolePermission: false,
|
|
11132
|
+
group: PermissionGroup.StatusPage,
|
|
11133
|
+
},
|
|
11134
|
+
{
|
|
11135
|
+
permission: Permission.EditStatusPageMonitorRule,
|
|
11136
|
+
title: "Edit Status Page Monitor Rule",
|
|
11137
|
+
description:
|
|
11138
|
+
"This permission can edit Status Page Monitor Rules of this project.",
|
|
11139
|
+
isAssignableToTenant: true,
|
|
11140
|
+
isAccessControlPermission: false,
|
|
11141
|
+
isRolePermission: false,
|
|
11142
|
+
group: PermissionGroup.StatusPage,
|
|
11143
|
+
},
|
|
11144
|
+
{
|
|
11145
|
+
permission: Permission.ReadStatusPageMonitorRule,
|
|
11146
|
+
title: "Read Status Page Monitor Rule",
|
|
11147
|
+
description:
|
|
11148
|
+
"This permission can read Status Page Monitor Rules of this project.",
|
|
11149
|
+
isAssignableToTenant: true,
|
|
11150
|
+
isAccessControlPermission: false,
|
|
11151
|
+
isRolePermission: false,
|
|
11152
|
+
group: PermissionGroup.StatusPage,
|
|
11153
|
+
},
|
|
11154
|
+
|
|
11107
11155
|
// Host Owner Rule Permissions
|
|
11108
11156
|
{
|
|
11109
11157
|
permission: Permission.CreateHostOwnerRule,
|
package/Types/Port.ts
CHANGED
|
@@ -59,17 +59,29 @@ export default class Port extends DatabaseProperty {
|
|
|
59
59
|
this.port = new PositiveNumber(port);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
/*
|
|
63
|
+
* A port column is declared `TableColumnType.Number`, so a raw number is
|
|
64
|
+
* as legitimate an incoming value as a raw string — the SMTP forms send
|
|
65
|
+
* one or the other depending on how far the value got through
|
|
66
|
+
* deserialization. Dropping a number on the floor here wrote NULL over a
|
|
67
|
+
* port the user had just typed, with no error anywhere.
|
|
68
|
+
*/
|
|
62
69
|
public static override toDatabase(
|
|
63
70
|
value: Port | FindOperator<Port>,
|
|
64
71
|
): number | null {
|
|
65
|
-
|
|
66
|
-
|
|
72
|
+
/*
|
|
73
|
+
* The declared parameter type stays Port-shaped so this still overrides
|
|
74
|
+
* DatabaseProperty.toDatabase, but a raw string or number genuinely
|
|
75
|
+
* arrives here — see the note above — so widen at the check instead.
|
|
76
|
+
*/
|
|
77
|
+
const rawValue: unknown = value;
|
|
78
|
+
|
|
79
|
+
if (typeof rawValue === "string" || typeof rawValue === "number") {
|
|
80
|
+
value = new Port(rawValue);
|
|
67
81
|
}
|
|
68
82
|
|
|
69
83
|
if (value instanceof Port) {
|
|
70
84
|
return value.toNumber();
|
|
71
|
-
} else if (typeof value === "string") {
|
|
72
|
-
return parseInt(value);
|
|
73
85
|
}
|
|
74
86
|
|
|
75
87
|
return null;
|
|
@@ -85,6 +85,17 @@ export interface StatusPageReportRow {
|
|
|
85
85
|
|
|
86
86
|
export interface StatusPageReport {
|
|
87
87
|
reportDates: string; // start date and end date in string. e.g. "01 July 2021 - 14 July 2021"
|
|
88
|
+
/*
|
|
89
|
+
* How a sentence refers to the period this report covers - "the last 30
|
|
90
|
+
* days", "July 2026", "the week of Jul 27, 2026". `reportDates` is the raw
|
|
91
|
+
* range; this is the phrase that goes after "your status summary for ...".
|
|
92
|
+
*/
|
|
93
|
+
reportPeriodName: string;
|
|
94
|
+
// The two ends of the window on their own, for templates that lay them out.
|
|
95
|
+
reportStartDate: string;
|
|
96
|
+
reportEndDate: string;
|
|
97
|
+
// The IANA zone every date above was resolved in, e.g. "America/New_York".
|
|
98
|
+
reportTimezone: string;
|
|
88
99
|
totalResources: number;
|
|
89
100
|
totalIncidents: number;
|
|
90
101
|
averageUptimePercent: string;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* What stretch of time a scheduled status page report covers.
|
|
3
|
+
*
|
|
4
|
+
* The report used to only ever cover "the last N days counted back from the
|
|
5
|
+
* moment the email went out", which can never line up with a calendar month -
|
|
6
|
+
* a monthly report sent on 1 Aug covered 2 Jul - 1 Aug rather than the July
|
|
7
|
+
* everyone reading it expects, and consecutive reports silently overlapped or
|
|
8
|
+
* left gaps whenever the day count did not match the send frequency.
|
|
9
|
+
*/
|
|
10
|
+
enum StatusPageReportPeriodType {
|
|
11
|
+
// The window ends when the email is sent and runs back `reportDataInDays`.
|
|
12
|
+
Rolling = "Rolling",
|
|
13
|
+
/*
|
|
14
|
+
* The last whole calendar period before the email is sent, sized by the send
|
|
15
|
+
* frequency: a report sent monthly covers 1 Jul 00:00 - 31 Jul 23:59:59.999
|
|
16
|
+
* in the status page's report timezone.
|
|
17
|
+
*/
|
|
18
|
+
PreviousCalendarPeriod = "Previous Calendar Period",
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default StatusPageReportPeriodType;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import React, { useEffect, useRef } from "react";
|
|
2
|
+
|
|
3
|
+
export interface LiveLogsRefreshOptions {
|
|
4
|
+
/** Whether the user has switched live mode on. */
|
|
5
|
+
isLive: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Whether the current view can be refreshed in place. Live tailing only
|
|
8
|
+
* makes sense on the first page sorted newest-first — on page 3, or sorted
|
|
9
|
+
* by severity, "the newest logs" is not what the viewer is showing.
|
|
10
|
+
*/
|
|
11
|
+
isEligible: boolean;
|
|
12
|
+
/** How often to poll while live mode is on. */
|
|
13
|
+
intervalInMs: number;
|
|
14
|
+
/** Pull the newest page of logs. */
|
|
15
|
+
refreshLogs: () => void;
|
|
16
|
+
/**
|
|
17
|
+
* Re-run the histogram query. The chart is driven by its own aggregation
|
|
18
|
+
* request rather than by the rows in the table, so it goes stale unless it
|
|
19
|
+
* is refreshed on the same beat as the list.
|
|
20
|
+
*/
|
|
21
|
+
refreshHistogram: () => void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type UseLiveLogsRefreshFunction = (
|
|
25
|
+
options: LiveLogsRefreshOptions,
|
|
26
|
+
) => void;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Drives the polling loop behind the log viewer's live mode.
|
|
30
|
+
*
|
|
31
|
+
* Every tick refreshes the log list *and* the histogram together. That
|
|
32
|
+
* pairing is the point of this hook: the two come from different endpoints,
|
|
33
|
+
* and refreshing only the list leaves a chart that stops moving while rows
|
|
34
|
+
* keep arriving underneath it.
|
|
35
|
+
*
|
|
36
|
+
* The callbacks are read through refs, so a parent that re-renders (which it
|
|
37
|
+
* does on every poll, as results land) does not tear down and re-arm the
|
|
38
|
+
* timer — that would reset the cadence and fire an extra immediate poll each
|
|
39
|
+
* time. Only the gating flags and the interval restart the loop.
|
|
40
|
+
*/
|
|
41
|
+
const useLiveLogsRefresh: UseLiveLogsRefreshFunction = (
|
|
42
|
+
options: LiveLogsRefreshOptions,
|
|
43
|
+
): void => {
|
|
44
|
+
const { isLive, isEligible, intervalInMs } = options;
|
|
45
|
+
|
|
46
|
+
const refreshLogsRef: React.MutableRefObject<() => void> = useRef<() => void>(
|
|
47
|
+
options.refreshLogs,
|
|
48
|
+
);
|
|
49
|
+
const refreshHistogramRef: React.MutableRefObject<() => void> = useRef<
|
|
50
|
+
() => void
|
|
51
|
+
>(options.refreshHistogram);
|
|
52
|
+
|
|
53
|
+
/*
|
|
54
|
+
* Declared before the polling effect so the refs are already current by the
|
|
55
|
+
* time that effect (re-)runs — effects fire in declaration order.
|
|
56
|
+
*/
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
refreshLogsRef.current = options.refreshLogs;
|
|
59
|
+
refreshHistogramRef.current = options.refreshHistogram;
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (!isLive || !isEligible) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const poll: () => void = (): void => {
|
|
68
|
+
refreshLogsRef.current();
|
|
69
|
+
refreshHistogramRef.current();
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// Switching live mode on should show fresh data immediately, not one tick later.
|
|
73
|
+
poll();
|
|
74
|
+
|
|
75
|
+
const intervalId: ReturnType<typeof setInterval> = setInterval(
|
|
76
|
+
poll,
|
|
77
|
+
intervalInMs,
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
return () => {
|
|
81
|
+
clearInterval(intervalId);
|
|
82
|
+
};
|
|
83
|
+
}, [isLive, isEligible, intervalInMs]);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export default useLiveLogsRefresh;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
2
|
+
import { HistogramBucket } from "./types";
|
|
3
|
+
|
|
4
|
+
export interface LogsHistogramRefreshOptions {
|
|
5
|
+
/**
|
|
6
|
+
* A background refresh: no loader, no blanking on failure, and no stacking
|
|
7
|
+
* if the previous one has not come back yet. This is what live mode uses.
|
|
8
|
+
*/
|
|
9
|
+
silent?: boolean | undefined;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface LogsHistogramState {
|
|
13
|
+
buckets: Array<HistogramBucket>;
|
|
14
|
+
isLoading: boolean;
|
|
15
|
+
refresh: (options?: LogsHistogramRefreshOptions) => Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type FetchHistogramBucketsFunction = () => Promise<
|
|
19
|
+
Array<HistogramBucket>
|
|
20
|
+
>;
|
|
21
|
+
|
|
22
|
+
export type UseLogsHistogramFunction = (
|
|
23
|
+
fetchBuckets: FetchHistogramBucketsFunction,
|
|
24
|
+
) => LogsHistogramState;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Owns the log histogram's data, loading flag and refresh loop.
|
|
28
|
+
*
|
|
29
|
+
* The chart is fed by its own aggregation query rather than by the rows in
|
|
30
|
+
* the table, so it needs refreshing in its own right — including on every
|
|
31
|
+
* live-mode tick. A poll is a *silent* refresh, which is what keeps live mode
|
|
32
|
+
* from looking broken:
|
|
33
|
+
*
|
|
34
|
+
* - it does not raise the loading flag, so the chart does not flash a loader
|
|
35
|
+
* every few seconds;
|
|
36
|
+
* - it keeps the buckets already on screen if the request fails, so one bad
|
|
37
|
+
* response does not blank the chart;
|
|
38
|
+
* - it is dropped while an earlier poll is still running, so a slow
|
|
39
|
+
* aggregation cannot pile requests up behind it.
|
|
40
|
+
*
|
|
41
|
+
* `fetchBuckets` doubles as the query identity: hand over a new callback (a
|
|
42
|
+
* new time range, filter or scope) and the histogram reloads.
|
|
43
|
+
*/
|
|
44
|
+
const useLogsHistogram: UseLogsHistogramFunction = (
|
|
45
|
+
fetchBuckets: FetchHistogramBucketsFunction,
|
|
46
|
+
): LogsHistogramState => {
|
|
47
|
+
const [buckets, setBuckets] = useState<Array<HistogramBucket>>([]);
|
|
48
|
+
const [isLoading, setIsLoading] = useState<boolean>(false);
|
|
49
|
+
|
|
50
|
+
const silentRequestInFlight: React.MutableRefObject<boolean> =
|
|
51
|
+
useRef<boolean>(false);
|
|
52
|
+
|
|
53
|
+
/*
|
|
54
|
+
* The query the viewer is on right now. A request that comes back after the
|
|
55
|
+
* reader has moved to another time range or filter is dropped rather than
|
|
56
|
+
* painted over the window they are actually looking at.
|
|
57
|
+
*/
|
|
58
|
+
const currentQuery: React.MutableRefObject<FetchHistogramBucketsFunction> =
|
|
59
|
+
useRef<FetchHistogramBucketsFunction>(fetchBuckets);
|
|
60
|
+
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
currentQuery.current = fetchBuckets;
|
|
63
|
+
}, [fetchBuckets]);
|
|
64
|
+
|
|
65
|
+
const refresh: (options?: LogsHistogramRefreshOptions) => Promise<void> =
|
|
66
|
+
useCallback(
|
|
67
|
+
async (options: LogsHistogramRefreshOptions = {}): Promise<void> => {
|
|
68
|
+
const isSilent: boolean = options.silent === true;
|
|
69
|
+
|
|
70
|
+
if (isSilent) {
|
|
71
|
+
if (silentRequestInFlight.current) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
silentRequestInFlight.current = true;
|
|
76
|
+
} else {
|
|
77
|
+
setIsLoading(true);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
const nextBuckets: Array<HistogramBucket> = await fetchBuckets();
|
|
82
|
+
|
|
83
|
+
if (currentQuery.current === fetchBuckets) {
|
|
84
|
+
setBuckets(nextBuckets);
|
|
85
|
+
}
|
|
86
|
+
} catch {
|
|
87
|
+
// The histogram is non-critical; degrade rather than fail the page.
|
|
88
|
+
if (!isSilent && currentQuery.current === fetchBuckets) {
|
|
89
|
+
setBuckets([]);
|
|
90
|
+
}
|
|
91
|
+
} finally {
|
|
92
|
+
if (isSilent) {
|
|
93
|
+
silentRequestInFlight.current = false;
|
|
94
|
+
} else if (currentQuery.current === fetchBuckets) {
|
|
95
|
+
setIsLoading(false);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
[fetchBuckets],
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
useEffect(() => {
|
|
103
|
+
void refresh();
|
|
104
|
+
}, [refresh]);
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
buckets: buckets,
|
|
108
|
+
isLoading: isLoading,
|
|
109
|
+
refresh: refresh,
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export default useLogsHistogram;
|
|
@@ -5,6 +5,7 @@ import DropdownValueBadge from "../Dropdown/DropdownValueBadge";
|
|
|
5
5
|
import AnalyticsBaseModel from "../../../Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel";
|
|
6
6
|
import BaseModel from "../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
|
|
7
7
|
import CustomFieldType from "../../../Types/CustomField/CustomFieldType";
|
|
8
|
+
import { CustomFieldDefinition } from "../../../Types/CustomField/CustomFieldDefinition";
|
|
8
9
|
import {
|
|
9
10
|
CustomFieldDropdownOption,
|
|
10
11
|
parseCustomFieldDropdownOptions,
|
|
@@ -45,12 +46,7 @@ import React, { ReactElement } from "react";
|
|
|
45
46
|
* fall-through text branch understands a dotted key.
|
|
46
47
|
*/
|
|
47
48
|
|
|
48
|
-
export
|
|
49
|
-
name: string;
|
|
50
|
-
description?: string | undefined;
|
|
51
|
-
customFieldType?: CustomFieldType | undefined;
|
|
52
|
-
dropdownOptions?: string | undefined;
|
|
53
|
-
}
|
|
49
|
+
export type { CustomFieldDefinition } from "../../../Types/CustomField/CustomFieldDefinition";
|
|
54
50
|
|
|
55
51
|
export const CustomFieldsColumnKey: string = "customFields";
|
|
56
52
|
|
|
@@ -55,18 +55,37 @@ const useCustomFieldColumns: UseCustomFieldColumnsFunction = <
|
|
|
55
55
|
const [definitions, setDefinitions] = useState<Array<CustomFieldDefinition>>(
|
|
56
56
|
[],
|
|
57
57
|
);
|
|
58
|
-
const [isLoading, setIsLoading] = useState<boolean>(false);
|
|
59
|
-
const [error, setError] = useState<string>("");
|
|
60
58
|
|
|
61
59
|
const projectId: ObjectID | null =
|
|
62
60
|
data.projectId ?? ProjectUtil.getCurrentProjectId();
|
|
63
61
|
|
|
62
|
+
/*
|
|
63
|
+
* Starts true whenever a request is actually going to happen, rather than
|
|
64
|
+
* false-until-the-effect-runs.
|
|
65
|
+
*
|
|
66
|
+
* Columns did not care — they only ever appear — but a caller that has to
|
|
67
|
+
* distinguish "no custom fields" from "not yet" does. The facet bar is one:
|
|
68
|
+
* on the first render it must know that a chip restored from a shared link
|
|
69
|
+
* may still be on its way, or it drops the link's filter before the request
|
|
70
|
+
* has even been sent.
|
|
71
|
+
*/
|
|
72
|
+
const [isLoading, setIsLoading] = useState<boolean>(
|
|
73
|
+
Boolean(data.customFieldsModelType && projectId),
|
|
74
|
+
);
|
|
75
|
+
const [error, setError] = useState<string>("");
|
|
76
|
+
|
|
64
77
|
const projectIdString: string = projectId?.toString() || "";
|
|
65
78
|
const modelName: string = customFieldsModelType?.name || "";
|
|
66
79
|
|
|
67
80
|
useEffect(() => {
|
|
68
81
|
if (!customFieldsModelType || !projectId) {
|
|
69
82
|
setDefinitions([]);
|
|
83
|
+
/*
|
|
84
|
+
* Nothing to wait for. Said explicitly because the initial state is now
|
|
85
|
+
* "loading" whenever a request is expected, and a model type that goes
|
|
86
|
+
* away between renders would otherwise leave it stuck there.
|
|
87
|
+
*/
|
|
88
|
+
setIsLoading(false);
|
|
70
89
|
return;
|
|
71
90
|
}
|
|
72
91
|
|