@oneuptime/common 12.0.33 → 12.0.34
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/AnalyticsModels/RumSession.ts +117 -1
- package/Models/AnalyticsModels/RumSessionChunk.ts +13 -0
- package/Models/DatabaseModels/AlertCustomField.ts +77 -3
- package/Models/DatabaseModels/ApiKeyPermission.ts +3 -27
- package/Models/DatabaseModels/IncidentCustomField.ts +77 -3
- package/Models/DatabaseModels/InventoryItemCustomField.ts +77 -3
- package/Models/DatabaseModels/MonitorCustomField.ts +77 -3
- package/Models/DatabaseModels/OnCallDutyPolicyCustomField.ts +77 -3
- package/Models/DatabaseModels/RumApplication.ts +6 -6
- package/Models/DatabaseModels/ScheduledMaintenanceCustomField.ts +77 -3
- package/Models/DatabaseModels/StatusPageCustomField.ts +77 -3
- package/Models/DatabaseModels/TeamCustomField.ts +77 -3
- package/Models/DatabaseModels/TeamMember.ts +0 -9
- package/Models/DatabaseModels/TeamMemberCustomField.ts +77 -3
- package/Models/DatabaseModels/TeamPermission.ts +3 -24
- package/Models/DatabaseModels/TelemetryIngestionKey.ts +260 -0
- package/Models/DatabaseModels/UserTelegram.ts +0 -4
- package/Scripts/benchmark-fanin-capacity.js +181 -0
- package/Server/API/TelemetryAPI.ts +1284 -164
- package/Server/API/UserNotificationSettingAPI.ts +55 -0
- package/Server/API/UserTelegramAPI.ts +48 -4
- package/Server/EnvironmentConfig.ts +35 -2
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.ts +91 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.ts +67 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.ts +139 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.ts +121 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
- package/Server/Infrastructure/QueueWorker.ts +20 -14
- package/Server/Infrastructure/Semaphore.ts +2 -0
- package/Server/Middleware/TelemetryIngest.ts +453 -7
- package/Server/Services/AccessTokenService.ts +1 -0
- package/Server/Services/AlertCustomFieldService.ts +98 -0
- package/Server/Services/AlertService.ts +37 -0
- package/Server/Services/ApiKeyPermissionService.ts +461 -29
- package/Server/Services/CustomFieldMappingService.ts +879 -0
- package/Server/Services/GlobalConfigService.ts +194 -0
- package/Server/Services/IncidentCustomFieldService.ts +98 -0
- package/Server/Services/IncidentService.ts +35 -0
- package/Server/Services/MetricService.ts +194 -0
- package/Server/Services/MonitorService.ts +32 -0
- package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +78 -25
- package/Server/Services/ProjectService.ts +22 -0
- package/Server/Services/RoutineEmailSettingsService.ts +73 -0
- package/Server/Services/RumSessionReplayViewService.ts +104 -24
- package/Server/Services/ScheduledMaintenanceCustomFieldService.ts +98 -0
- package/Server/Services/ScheduledMaintenanceService.ts +32 -0
- package/Server/Services/TeamMemberService.ts +78 -0
- package/Server/Services/TeamPermissionService.ts +235 -3
- package/Server/Services/TelemetryIngestionKeyService.ts +722 -19
- package/Server/Services/UserNotificationSettingService.ts +34 -6
- package/Server/Services/UserTelegramService.ts +326 -5
- package/Server/Types/Database/QueryHelper.ts +2 -0
- package/Server/Utils/APIKey/AccessPermission.ts +5 -2
- package/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.ts +54 -0
- package/Server/Utils/CustomField/CustomFieldMappingRegistry.ts +415 -0
- package/Server/Utils/CustomField/CustomFieldMappingValidator.ts +335 -0
- package/Server/Utils/DataSource/EgressGuard.ts +177 -8
- package/Server/Utils/EmailRollup/EmailRollupConstants.ts +38 -5
- package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +57 -4
- package/Server/Utils/FrontendEnvironment.ts +40 -0
- package/Server/Utils/LogRedaction.ts +20 -0
- package/Server/Utils/Logger.ts +11 -0
- package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +338 -77
- package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +30 -4
- package/Server/Utils/Monitor/MonitorAlert.ts +29 -6
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +110 -15
- package/Server/Utils/Monitor/MonitorIncident.ts +22 -6
- package/Server/Utils/Monitor/MonitorTemplateUtil.ts +29 -0
- package/Server/Utils/Monitor/SeriesContextEnricher.ts +304 -0
- package/Server/Utils/SSRFProtection.ts +217 -10
- package/Server/Utils/SessionReplay/SessionReplayGateCache.ts +239 -138
- package/Server/Utils/SessionReplay/SessionReplayHealthCounters.ts +305 -0
- package/Server/Utils/SessionReplay/SessionReplayReadService.ts +1430 -289
- package/Server/Utils/StartServer.ts +2 -17
- package/Server/Utils/TelegramVerificationToken.ts +185 -0
- package/Server/Utils/Telemetry/PinServiceName.ts +197 -0
- package/Server/Utils/Telemetry/TelemetryFanInWriter.ts +38 -16
- package/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.ts +92 -0
- package/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.ts +217 -0
- package/Server/Utils/VM/VMAPI.ts +1 -0
- package/Server/Utils/VM/VMRunner.ts +975 -95
- package/Tests/App/AdminDashboard/AdminHeaderSmallScreens.test.tsx +202 -0
- package/Tests/App/Dashboard/DashboardHeaderSmallScreens.test.tsx +404 -0
- package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +468 -0
- package/Tests/App/Dashboard/NotificationEmailPreferences.test.tsx +399 -0
- package/Tests/App/StatusPage/StatusPageLastUpdated.test.tsx +263 -0
- package/Tests/App/StatusPage/StatusPageOverviewLiveAndSearch.test.tsx +753 -0
- package/Tests/App/StatusPage/StatusPageResourceSearchBox.test.tsx +224 -0
- package/Tests/Models/AnalyticsModels/RumSessionReplayColumns.test.ts +262 -0
- package/Tests/Models/CustomFieldMappingColumns.test.ts +166 -0
- package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +20 -6
- package/Tests/ResponsiveVisibility.test.ts +115 -0
- package/Tests/ResponsiveVisibility.ts +183 -0
- package/Tests/Server/API/SessionReplayAPI.test.ts +1940 -216
- package/Tests/Server/API/UserNotificationSettingAPI.test.ts +186 -0
- package/Tests/Server/API/UserTelegramAPISecurity.test.ts +231 -0
- package/Tests/Server/EnvironmentConfigFrontendSecurity.test.ts +234 -0
- package/Tests/Server/Infrastructure/Postgres/CustomFieldValueMappingMigration.test.ts +202 -0
- package/Tests/Server/Infrastructure/Postgres/InventoryItemArchiveMigration.test.ts +41 -0
- package/Tests/Server/Infrastructure/Postgres/SessionReplayRecordEverySessionByDefaultMigration.test.ts +169 -0
- package/Tests/Server/Infrastructure/QueueWorkerTimeout.test.ts +210 -0
- package/Tests/Server/Infrastructure/TelemetryExporterDeploymentConfig.test.ts +130 -0
- package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +4 -1
- package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +1163 -0
- package/Tests/Server/Middleware/TelemetryIngestTokenLog.test.ts +5 -3
- package/Tests/Server/Services/AddTelemetryIngestionKeyTypeMigration.test.ts +555 -0
- package/Tests/Server/Services/ApiKeyPermissionSecurity.test.ts +678 -0
- package/Tests/Server/Services/ApiKeyPermissionService.test.ts +276 -28
- package/Tests/Server/Services/CustomFieldDropdownOptionsColumnWidth.test.ts +431 -0
- package/Tests/Server/Services/CustomFieldMappingService.test.ts +850 -0
- package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +32 -0
- package/Tests/Server/Services/GlobalConfigService.test.ts +414 -1
- package/Tests/Server/Services/MetricRawEntityKeyPrune.test.ts +592 -0
- package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +226 -1
- package/Tests/Server/Services/RoutineEmailSettingsPostgres.test.ts +329 -0
- package/Tests/Server/Services/RumSessionReplayViewService.test.ts +267 -0
- package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +9 -0
- package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +9 -0
- package/Tests/Server/Services/TeamPrivilegeEscalation.test.ts +834 -0
- package/Tests/Server/Services/TelemetryIngestionKeyPolicyResolution.test.ts +814 -0
- package/Tests/Server/Services/TelemetryIngestionKeyValidation.test.ts +998 -0
- package/Tests/Server/Services/UserNotificationSettingRollupRouting.test.ts +141 -0
- package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +18 -10
- package/Tests/Server/Services/UserTelegramVerificationSecurity.test.ts +688 -0
- package/Tests/Server/Utils/AI/SRE/Insights/FixRouting.test.ts +497 -0
- package/Tests/Server/Utils/AI/Toolbox/Serializer.test.ts +383 -0
- package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +7 -3
- package/Tests/Server/Utils/AnalyticsDatabase/ClusterConfig.test.ts +315 -0
- package/Tests/Server/Utils/CustomField/CustomFieldMappingValidator.test.ts +437 -0
- package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +300 -11
- package/Tests/Server/Utils/EmailRollup/EmailRollupBurstWindow.test.ts +83 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerBehaviour.test.ts +1 -1
- package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerPreferences.test.ts +362 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +77 -1
- package/Tests/Server/Utils/FrontendEnvironment.test.ts +190 -0
- package/Tests/Server/Utils/LogRedaction.test.ts +26 -0
- package/Tests/Server/Utils/LoggerCredentialLeak.test.ts +23 -9
- package/Tests/Server/Utils/Monitor/Criteria/CompareCriteriaAggregation.test.ts +584 -0
- package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestHeaderCriteria.test.ts +236 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +437 -0
- package/Tests/Server/Utils/Monitor/MonitorTemplateUtilSeriesContext.test.ts +176 -0
- package/Tests/Server/Utils/Monitor/SeriesContextEnricher.test.ts +356 -0
- package/Tests/Server/Utils/SSRFProtectionCloudServiceAddresses.test.ts +595 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayGateCachePolicy.test.ts +198 -1
- package/Tests/Server/Utils/SessionReplay/SessionReplayHealthCounters.test.ts +453 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +1378 -0
- package/Tests/Server/Utils/SessionReplayOriginAllowListRefactor.test.ts +420 -0
- package/Tests/Server/Utils/TelegramVerificationToken.test.ts +253 -0
- package/Tests/Server/Utils/Telemetry/PinServiceName.test.ts +666 -0
- package/Tests/Server/Utils/Telemetry/TelemetryFanInWriterCapacity.test.ts +458 -0
- package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +424 -0
- package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.test.ts +528 -0
- package/Tests/Server/Utils/TelemetryExporterEnvironment.test.ts +56 -0
- package/Tests/Server/Utils/VM/VMRunnerHostBridgeLatency.test.ts +74 -0
- package/Tests/Server/Utils/VM/VMRunnerPrivateNetworkWiring.test.ts +100 -7
- package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +1176 -6
- package/Tests/Types/CustomField/CustomFieldMappingCatalog.test.ts +220 -0
- package/Tests/Types/CustomField/CustomFieldValueMapping.test.ts +348 -0
- package/Tests/Types/JSONFunctions.test.ts +260 -0
- package/Tests/Types/Monitor/CephAlertTemplates.test.ts +422 -53
- package/Tests/Types/Monitor/DockerAlertTemplates.test.ts +495 -15
- package/Tests/Types/Monitor/DockerSwarmAlertTemplates.test.ts +191 -45
- package/Tests/Types/Monitor/HostAlertTemplates.test.ts +370 -42
- package/Tests/Types/Monitor/IotAlertTemplates.test.ts +375 -20
- package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +636 -42
- package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +189 -0
- package/Tests/Types/Monitor/KubernetesTemplateGroupByKeys.test.ts +95 -14
- package/Tests/Types/Monitor/PodmanAlertTemplates.test.ts +190 -21
- package/Tests/Types/Monitor/ProxmoxAlertTemplates.test.ts +352 -22
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationAlertDebuggability.test.ts +363 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +93 -18
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +259 -0
- package/Tests/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.test.ts +476 -0
- package/Tests/Types/Monitor/RumAlertTemplates.test.ts +136 -0
- package/Tests/Types/Monitor/SeriesContext/SeriesDebugHints.test.ts +661 -0
- package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +507 -0
- package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +270 -0
- package/Tests/Types/Monitor/TemplateGroupByKeys.test.ts +38 -10
- package/Tests/Types/Monitor/Utils/RecommendationCriteriaAssertions.ts +102 -0
- package/Tests/Types/NotificationSetting/RoutineEmailEvents.test.ts +47 -0
- package/Tests/Types/Rum/SessionReplayApiContracts.test.ts +608 -0
- package/Tests/Types/Rum/SessionReplayCustomEvents.test.ts +434 -0
- package/Tests/Types/WebsiteRequest.test.ts +285 -3
- package/Tests/UI/Components/Charts/ChartBucketIdentity.test.ts +16 -3
- package/Tests/UI/Components/Charts/ChartTrailingBucketGap.test.ts +691 -0
- package/Tests/UI/Components/ComponentsModal.test.tsx +12 -4
- package/Tests/UI/Components/ComponentsModalUsability.test.tsx +518 -0
- package/Tests/UI/Components/CustomFields/CustomFieldsDetailMapping.test.tsx +324 -0
- package/Tests/UI/Components/CustomFields/MapFromCustomFieldInput.test.tsx +176 -0
- package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +484 -0
- package/Tests/UI/Components/HeaderRightRail.test.tsx +157 -0
- package/Tests/UI/Components/IconDropdownItem.test.tsx +102 -0
- package/Tests/UI/Components/JSONTablePrototypePollution.test.tsx +117 -0
- package/Tests/UI/Components/KeyboardShortcutsModal.test.tsx +214 -0
- package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +561 -0
- package/Tests/UI/Components/MonitorGraphs/UptimeBarDayModal.test.tsx +302 -0
- package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +28 -12
- package/Tests/UI/Components/ShortcutDialogGuard.test.tsx +74 -0
- package/Tests/UI/Components/StatusPage/ResourceGroupSectionAutoExpand.test.tsx +248 -0
- package/Tests/UI/Components/TableCellWrapping.test.tsx +625 -0
- package/Tests/UI/Components/TableLoadingStates.test.tsx +205 -0
- package/Tests/UI/Components/Workflow/NodePlacement.test.ts +148 -0
- package/Tests/UI/Components/Workflow/Workflow.test.tsx +981 -0
- package/Tests/UI/ConfigBrowserTelemetry.test.ts +70 -0
- package/Tests/UI/Rum/ChunkLoader.test.ts +1036 -2
- package/Tests/UI/Rum/FidelityNotices.test.ts +187 -0
- package/Tests/UI/Rum/InactivityMap.test.ts +341 -0
- package/Tests/UI/Rum/PrivacySummaryCard.test.tsx +259 -0
- package/Tests/UI/Rum/RecordingHealthCard.test.tsx +855 -0
- package/Tests/UI/Rum/RecordingHealthStrip.test.tsx +594 -0
- package/Tests/UI/Rum/ReplayCard.test.tsx +451 -0
- package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +536 -0
- package/Tests/UI/Rum/ReplayEngine.test.ts +2503 -0
- package/Tests/UI/Rum/ReplayEngineTypes.test.ts +171 -0
- package/Tests/UI/Rum/ReplayHeader.test.tsx +711 -0
- package/Tests/UI/Rum/ReplayLink.test.tsx +119 -0
- package/Tests/UI/Rum/ReplayPinControl.test.tsx +408 -0
- package/Tests/UI/Rum/ReplayPlaybackIntent.test.ts +152 -0
- package/Tests/UI/Rum/ReplayRail.test.tsx +1296 -0
- package/Tests/UI/Rum/ReplayRailDetail.test.tsx +900 -0
- package/Tests/UI/Rum/ReplayScrubber.test.tsx +763 -147
- package/Tests/UI/Rum/ReplaySignalTypes.test.ts +189 -0
- package/Tests/UI/Rum/ReplaySignals.test.ts +1579 -0
- package/Tests/UI/Rum/ReplayStage.test.tsx +396 -473
- package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +918 -0
- package/Tests/UI/Rum/ReplayTimeline.test.tsx +696 -0
- package/Tests/UI/Rum/SessionReplayEmptyState.test.tsx +499 -0
- package/Tests/UI/Rum/SessionReplaySearchBar.test.tsx +346 -0
- package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +545 -0
- package/Tests/UI/Rum/SessionReplayTable.test.tsx +991 -0
- package/Tests/UI/Rum/TargetedCapturePanel.test.tsx +254 -0
- package/Tests/UI/Telemetry/BrowserExporterIsolation.test.ts +71 -0
- package/Tests/UI/Utils/GlobalKeyboardShortcut.test.ts +344 -0
- package/Tests/Utils/API.test.ts +308 -0
- package/Tests/Utils/HTTPResponseBodyReader.test.ts +323 -0
- package/Tests/Utils/NetworkDiscovery/DiscoveryScanStatus.test.ts +117 -0
- package/Tests/Utils/Rum/ChunkMath.test.ts +83 -0
- package/Tests/Utils/Rum/SessionReplayHealthDiagnosis.test.ts +993 -0
- package/Tests/Utils/Rum/SessionReplayStringMap.test.ts +245 -0
- package/Tests/Utils/StatusPage/ResourceSearch.test.ts +631 -0
- package/Tests/Utils/Telemetry/OriginAllowList.test.ts +633 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtil.test.ts +461 -0
- package/Tests/Utils/ValueFormatter.test.ts +148 -0
- package/Types/CustomField/CustomFieldMappingCatalog.ts +161 -0
- package/Types/CustomField/CustomFieldMappingSourceResource.ts +19 -0
- package/Types/CustomField/CustomFieldValueMapping.ts +288 -0
- package/Types/Icon/IconProp.ts +1 -0
- package/Types/JSONFunctions.ts +189 -43
- package/Types/Monitor/CephAlertTemplates.ts +157 -195
- package/Types/Monitor/DockerAlertTemplates.ts +338 -128
- package/Types/Monitor/DockerSwarmAlertTemplates.ts +95 -112
- package/Types/Monitor/HostAlertTemplates.ts +302 -130
- package/Types/Monitor/IotAlertTemplates.ts +112 -104
- package/Types/Monitor/KubernetesAlertTemplates.ts +415 -224
- package/Types/Monitor/KubernetesMetricCatalog.ts +23 -19
- package/Types/Monitor/PodmanAlertTemplates.ts +116 -163
- package/Types/Monitor/ProxmoxAlertTemplates.ts +217 -99
- package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +98 -6
- package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +44 -7
- package/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.ts +383 -0
- package/Types/Monitor/RumAlertTemplates.ts +46 -7
- package/Types/Monitor/SeriesContext/SeriesDebugHints.ts +596 -0
- package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +554 -0
- package/Types/Monitor/ServiceAlertTemplates.ts +98 -11
- package/Types/Monitor/UptimeHistoryLabels.ts +56 -0
- package/Types/NotificationSetting/RoutineEmailEvents.ts +30 -0
- package/Types/Rum/SessionReplay.ts +209 -0
- package/Types/Rum/SessionReplayApi.ts +722 -0
- package/Types/Rum/SessionReplayCaptureTrigger.ts +21 -12
- package/Types/Rum/SessionReplayConsentMode.ts +11 -7
- package/Types/Rum/SessionReplayCustomEvents.ts +549 -0
- package/Types/Rum/SessionReplayHealth.ts +238 -0
- package/Types/Telemetry/TelemetryIngestSurface.ts +95 -0
- package/Types/Telemetry/TelemetryIngestionKeyPolicy.ts +75 -0
- package/Types/Telemetry/TelemetryIngestionKeyType.ts +29 -0
- package/Types/WebsiteRequest.ts +85 -3
- package/UI/Components/Charts/Area/AreaChart.tsx +13 -2
- package/UI/Components/Charts/Bar/BarChart.tsx +6 -2
- package/UI/Components/Charts/Line/LineChart.tsx +13 -2
- package/UI/Components/Charts/Types/XAxis/XAxis.ts +29 -0
- package/UI/Components/Charts/Utils/DataPoint.ts +22 -3
- package/UI/Components/Charts/Utils/TimeAnnotation.ts +76 -9
- package/UI/Components/Charts/Utils/XAxis.ts +217 -0
- package/UI/Components/CustomFields/CustomFieldsDetail.tsx +143 -25
- package/UI/Components/CustomFields/MapFromCustomFieldInput.tsx +216 -0
- package/UI/Components/Graphs/DayUptimeGraph.tsx +173 -8
- package/UI/Components/Graphs/UptimeBarTooltip.tsx +22 -278
- package/UI/Components/Graphs/UptimeDaySummary.tsx +327 -0
- package/UI/Components/Header/Header.tsx +25 -9
- package/UI/Components/Header/IconDropdown/IconDropdownItem.tsx +10 -1
- package/UI/Components/Header/IconDropdown/IconDropdownMenu.tsx +6 -1
- package/UI/Components/Header/ProjectPicker/ProjectPicker.tsx +6 -1
- package/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.tsx +6 -1
- package/UI/Components/Icon/Icon.tsx +11 -0
- package/UI/Components/JSONTable/JSONTable.tsx +2 -2
- package/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.tsx +125 -0
- package/UI/Components/KeyboardShortcut/Screenshots/README.md +19 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-command-palette.png +0 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog-dark.png +0 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog.png +0 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-help-menu.png +0 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-narrow.png +0 -0
- package/UI/Components/ModelTable/Column.ts +15 -0
- package/UI/Components/Monitor/SeriesDebugCommandsViewer.tsx +64 -0
- package/UI/Components/Monitor/SeriesLabelsViewer.tsx +93 -0
- package/UI/Components/MonitorGraphs/Uptime.tsx +14 -2
- package/UI/Components/MonitorGraphs/UptimeBarDayModal.tsx +63 -10
- package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +44 -0
- package/UI/Components/StatusPage/ResourceGroupSection.tsx +40 -0
- package/UI/Components/Table/CellClassName.ts +81 -0
- package/UI/Components/Table/TableRow.tsx +20 -14
- package/UI/Components/Table/TableSkeletonRows.tsx +9 -9
- package/UI/Components/Table/Types/Column.ts +36 -0
- package/UI/Components/Tooltip/Tooltip.tsx +11 -1
- package/UI/Components/Workflow/ComponentsModal.tsx +60 -39
- package/UI/Components/Workflow/NodePlacement.ts +57 -0
- package/UI/Components/Workflow/Workflow.tsx +47 -18
- package/UI/Config.ts +15 -33
- package/UI/Utils/GlobalKeyboardShortcut.ts +208 -0
- package/UI/Utils/Telemetry/BrowserTelemetryConfig.ts +28 -0
- package/UI/Utils/Telemetry/Telemetry.ts +10 -8
- package/Utils/API.ts +129 -3
- package/Utils/HTTPResponseBodyReader.ts +221 -0
- package/Utils/NetworkDiscovery/DiscoveryScanStatus.ts +77 -0
- package/Utils/Rum/ChunkMath.ts +106 -0
- package/Utils/Rum/SessionReplayHealth.ts +732 -0
- package/Utils/Rum/SessionReplayStringMap.ts +226 -0
- package/Utils/Schema/ModelSchema.ts +1 -0
- package/Utils/StatusPage/ResourceSearch.ts +290 -0
- package/Utils/Telemetry/OriginAllowList.ts +355 -0
- package/Utils/Uptime/DayUptimeGraphUtil.ts +205 -0
- package/Utils/ValueFormatter.ts +35 -1
- package/build/dist/Models/AnalyticsModels/RumSession.js +102 -19
- package/build/dist/Models/AnalyticsModels/RumSession.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/RumSessionChunk.js +11 -9
- package/build/dist/Models/AnalyticsModels/RumSessionChunk.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/AlertCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ApiKeyPermission.js +3 -27
- package/build/dist/Models/DatabaseModels/ApiKeyPermission.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/IncidentCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/MonitorCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js +6 -6
- package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/StatusPageCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/TeamCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamMember.js +0 -9
- package/build/dist/Models/DatabaseModels/TeamMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamPermission.js +3 -24
- package/build/dist/Models/DatabaseModels/TeamPermission.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js +267 -0
- package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserTelegram.js +0 -4
- package/build/dist/Models/DatabaseModels/UserTelegram.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +769 -109
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/API/UserNotificationSettingAPI.js +35 -0
- package/build/dist/Server/API/UserNotificationSettingAPI.js.map +1 -0
- package/build/dist/Server/API/UserTelegramAPI.js +28 -6
- package/build/dist/Server/API/UserTelegramAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +29 -2
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js +60 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js +53 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js +82 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js +46 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/QueueWorker.js +19 -7
- package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
- package/build/dist/Server/Infrastructure/Semaphore.js +1 -0
- package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +315 -8
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/AccessTokenService.js +1 -0
- package/build/dist/Server/Services/AccessTokenService.js.map +1 -1
- package/build/dist/Server/Services/AlertCustomFieldService.js +93 -0
- package/build/dist/Server/Services/AlertCustomFieldService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +34 -0
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/ApiKeyPermissionService.js +331 -28
- package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
- package/build/dist/Server/Services/CustomFieldMappingService.js +614 -0
- package/build/dist/Server/Services/CustomFieldMappingService.js.map +1 -0
- package/build/dist/Server/Services/GlobalConfigService.js +133 -0
- package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
- package/build/dist/Server/Services/IncidentCustomFieldService.js +93 -0
- package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +32 -0
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/MetricService.js +163 -0
- package/build/dist/Server/Services/MetricService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +29 -0
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +79 -27
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +22 -0
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/RoutineEmailSettingsService.js +69 -0
- package/build/dist/Server/Services/RoutineEmailSettingsService.js.map +1 -0
- package/build/dist/Server/Services/RumSessionReplayViewService.js +86 -24
- package/build/dist/Server/Services/RumSessionReplayViewService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js +93 -0
- package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +29 -0
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +62 -2
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TeamPermissionService.js +166 -3
- package/build/dist/Server/Services/TeamPermissionService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryIngestionKeyService.js +562 -18
- package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationSettingService.js +26 -6
- package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
- package/build/dist/Server/Services/UserTelegramService.js +257 -4
- package/build/dist/Server/Services/UserTelegramService.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Utils/APIKey/AccessPermission.js +2 -2
- package/build/dist/Server/Utils/APIKey/AccessPermission.js.map +1 -1
- package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js +27 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js.map +1 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js +226 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js.map +1 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js +189 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/EgressGuard.js +121 -7
- package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js +38 -5
- package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +44 -2
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -1
- package/build/dist/Server/Utils/FrontendEnvironment.js +33 -0
- package/build/dist/Server/Utils/FrontendEnvironment.js.map +1 -0
- package/build/dist/Server/Utils/LogRedaction.js +20 -0
- package/build/dist/Server/Utils/LogRedaction.js.map +1 -1
- package/build/dist/Server/Utils/Logger.js +10 -0
- package/build/dist/Server/Utils/Logger.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +287 -68
- package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +20 -4
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +29 -6
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +88 -13
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +22 -6
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +22 -0
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js +237 -0
- package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js.map +1 -0
- package/build/dist/Server/Utils/SSRFProtection.js +136 -9
- package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js +174 -89
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js +223 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js.map +1 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +945 -164
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +3 -14
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/TelegramVerificationToken.js +129 -0
- package/build/dist/Server/Utils/TelegramVerificationToken.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/PinServiceName.js +163 -0
- package/build/dist/Server/Utils/Telemetry/PinServiceName.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js +28 -15
- package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js +64 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js +171 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js.map +1 -0
- package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
- package/build/dist/Server/Utils/VM/VMRunner.js +780 -69
- package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
- package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js +60 -0
- package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js +20 -0
- package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldValueMapping.js +141 -0
- package/build/dist/Types/CustomField/CustomFieldValueMapping.js.map +1 -0
- package/build/dist/Types/Icon/IconProp.js +1 -0
- package/build/dist/Types/Icon/IconProp.js.map +1 -1
- package/build/dist/Types/JSONFunctions.js +118 -37
- package/build/dist/Types/JSONFunctions.js.map +1 -1
- package/build/dist/Types/Monitor/CephAlertTemplates.js +130 -171
- package/build/dist/Types/Monitor/CephAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/DockerAlertTemplates.js +286 -121
- package/build/dist/Types/Monitor/DockerAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js +84 -105
- package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/HostAlertTemplates.js +250 -122
- package/build/dist/Types/Monitor/HostAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/IotAlertTemplates.js +81 -81
- package/build/dist/Types/Monitor/IotAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +375 -215
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/KubernetesMetricCatalog.js +19 -19
- package/build/dist/Types/Monitor/KubernetesMetricCatalog.js.map +1 -1
- package/build/dist/Types/Monitor/PodmanAlertTemplates.js +104 -153
- package/build/dist/Types/Monitor/PodmanAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +156 -91
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +67 -6
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +38 -7
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js +261 -0
- package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js.map +1 -0
- package/build/dist/Types/Monitor/RumAlertTemplates.js +46 -7
- package/build/dist/Types/Monitor/RumAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js +422 -0
- package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js.map +1 -0
- package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +441 -0
- package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -0
- package/build/dist/Types/Monitor/ServiceAlertTemplates.js +79 -15
- package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/UptimeHistoryLabels.js +17 -0
- package/build/dist/Types/Monitor/UptimeHistoryLabels.js.map +1 -0
- package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js +29 -0
- package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js.map +1 -0
- package/build/dist/Types/Rum/SessionReplay.js +117 -0
- package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayApi.js +181 -0
- package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -0
- package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js +21 -12
- package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayConsentMode.js +11 -7
- package/build/dist/Types/Rum/SessionReplayConsentMode.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayCustomEvents.js +172 -0
- package/build/dist/Types/Rum/SessionReplayCustomEvents.js.map +1 -0
- package/build/dist/Types/Rum/SessionReplayHealth.js +37 -0
- package/build/dist/Types/Rum/SessionReplayHealth.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +85 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js +15 -0
- package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js +30 -0
- package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js.map +1 -0
- package/build/dist/Types/WebsiteRequest.js +55 -3
- package/build/dist/Types/WebsiteRequest.js.map +1 -1
- package/build/dist/UI/Components/Charts/Area/AreaChart.js +13 -2
- package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js +6 -2
- package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Line/LineChart.js +13 -2
- package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Types/XAxis/XAxis.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -3
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js +40 -9
- package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/XAxis.js +186 -0
- package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +80 -6
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
- package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js +118 -0
- package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js.map +1 -0
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +112 -7
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
- package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js +5 -162
- package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js.map +1 -1
- package/build/dist/UI/Components/Graphs/UptimeDaySummary.js +181 -0
- package/build/dist/UI/Components/Graphs/UptimeDaySummary.js.map +1 -0
- package/build/dist/UI/Components/Header/Header.js +2 -3
- package/build/dist/UI/Components/Header/Header.js.map +1 -1
- package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js +2 -1
- package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js.map +1 -1
- package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js +7 -1
- package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js.map +1 -1
- package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js +7 -1
- package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js.map +1 -1
- package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js +7 -1
- package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +5 -0
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/JSONTable/JSONTable.js +2 -2
- package/build/dist/UI/Components/JSONTable/JSONTable.js.map +1 -1
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js +35 -0
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js.map +1 -0
- package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js +34 -0
- package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js.map +1 -0
- package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js +49 -0
- package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js.map +1 -0
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js +1 -1
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
- package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js +32 -6
- package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js.map +1 -1
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +38 -0
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js +22 -1
- package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js.map +1 -1
- package/build/dist/UI/Components/Table/CellClassName.js +55 -0
- package/build/dist/UI/Components/Table/CellClassName.js.map +1 -0
- package/build/dist/UI/Components/Table/TableRow.js +16 -13
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/Table/TableSkeletonRows.js +9 -8
- package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js +25 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentsModal.js +47 -30
- package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/NodePlacement.js +37 -0
- package/build/dist/UI/Components/Workflow/NodePlacement.js.map +1 -0
- package/build/dist/UI/Components/Workflow/Workflow.js +35 -18
- package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
- package/build/dist/UI/Config.js +10 -20
- package/build/dist/UI/Config.js.map +1 -1
- package/build/dist/UI/Utils/GlobalKeyboardShortcut.js +138 -0
- package/build/dist/UI/Utils/GlobalKeyboardShortcut.js.map +1 -0
- package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js +14 -0
- package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js.map +1 -0
- package/build/dist/UI/Utils/Telemetry/Telemetry.js +7 -5
- package/build/dist/UI/Utils/Telemetry/Telemetry.js.map +1 -1
- package/build/dist/Utils/API.js +67 -5
- package/build/dist/Utils/API.js.map +1 -1
- package/build/dist/Utils/HTTPResponseBodyReader.js +157 -0
- package/build/dist/Utils/HTTPResponseBodyReader.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js +69 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js.map +1 -0
- package/build/dist/Utils/Rum/ChunkMath.js +76 -0
- package/build/dist/Utils/Rum/ChunkMath.js.map +1 -1
- package/build/dist/Utils/Rum/SessionReplayHealth.js +534 -0
- package/build/dist/Utils/Rum/SessionReplayHealth.js.map +1 -0
- package/build/dist/Utils/Rum/SessionReplayStringMap.js +165 -0
- package/build/dist/Utils/Rum/SessionReplayStringMap.js.map +1 -0
- package/build/dist/Utils/Schema/ModelSchema.js +1 -0
- package/build/dist/Utils/Schema/ModelSchema.js.map +1 -1
- package/build/dist/Utils/StatusPage/ResourceSearch.js +200 -0
- package/build/dist/Utils/StatusPage/ResourceSearch.js.map +1 -0
- package/build/dist/Utils/Telemetry/OriginAllowList.js +299 -0
- package/build/dist/Utils/Telemetry/OriginAllowList.js.map +1 -0
- package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js +147 -0
- package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js.map +1 -0
- package/build/dist/Utils/ValueFormatter.js +32 -1
- package/build/dist/Utils/ValueFormatter.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { describe, expect, test } from "@jest/globals";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { getMetadataArgsStorage } from "typeorm";
|
|
5
|
+
import { ColumnMetadataArgs } from "typeorm/metadata-args/ColumnMetadataArgs";
|
|
6
|
+
import AlertCustomField from "../../../../Models/DatabaseModels/AlertCustomField";
|
|
7
|
+
import IncidentCustomField from "../../../../Models/DatabaseModels/IncidentCustomField";
|
|
8
|
+
import InventoryItemCustomField from "../../../../Models/DatabaseModels/InventoryItemCustomField";
|
|
9
|
+
import MonitorCustomField from "../../../../Models/DatabaseModels/MonitorCustomField";
|
|
10
|
+
import OnCallDutyPolicyCustomField from "../../../../Models/DatabaseModels/OnCallDutyPolicyCustomField";
|
|
11
|
+
import ScheduledMaintenanceCustomField from "../../../../Models/DatabaseModels/ScheduledMaintenanceCustomField";
|
|
12
|
+
import StatusPageCustomField from "../../../../Models/DatabaseModels/StatusPageCustomField";
|
|
13
|
+
import TeamCustomField from "../../../../Models/DatabaseModels/TeamCustomField";
|
|
14
|
+
import TeamMemberCustomField from "../../../../Models/DatabaseModels/TeamMemberCustomField";
|
|
15
|
+
import { AddCustomFieldValueMapping1791600000000 } from "../../../../Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping";
|
|
16
|
+
import SchemaMigrations from "../../../../Server/Infrastructure/Postgres/SchemaMigrations/Index";
|
|
17
|
+
|
|
18
|
+
/*
|
|
19
|
+
* The value-mapping columns, and the two ways a migration silently fails to
|
|
20
|
+
* ship them.
|
|
21
|
+
*
|
|
22
|
+
* The first is the one AGENTS.md calls out: a migration file that exists but
|
|
23
|
+
* is never added to SchemaMigrations/Index.ts does not run, so the column is
|
|
24
|
+
* simply missing in production while every local database that was migrated by
|
|
25
|
+
* hand looks fine. The second is a column added to a model but not to the
|
|
26
|
+
* migration (or vice versa) — that is a green deploy followed by a red Schema
|
|
27
|
+
* Drift job.
|
|
28
|
+
*
|
|
29
|
+
* Both are checked against the models' own decorator metadata and the
|
|
30
|
+
* filesystem rather than a list written out twice.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
const MIGRATIONS_DIRECTORY: string = path.join(
|
|
34
|
+
__dirname,
|
|
35
|
+
"..",
|
|
36
|
+
"..",
|
|
37
|
+
"..",
|
|
38
|
+
"..",
|
|
39
|
+
"Server",
|
|
40
|
+
"Infrastructure",
|
|
41
|
+
"Postgres",
|
|
42
|
+
"SchemaMigrations",
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
const MIGRATION_PATH: string = path.join(
|
|
46
|
+
MIGRATIONS_DIRECTORY,
|
|
47
|
+
"1791600000000-AddCustomFieldValueMapping.ts",
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const SOURCE: string = fs.readFileSync(MIGRATION_PATH, "utf8");
|
|
51
|
+
|
|
52
|
+
const MODELS_DIRECTORY: string = path.join(
|
|
53
|
+
__dirname,
|
|
54
|
+
"..",
|
|
55
|
+
"..",
|
|
56
|
+
"..",
|
|
57
|
+
"..",
|
|
58
|
+
"Models",
|
|
59
|
+
"DatabaseModels",
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
const MAPPING_COLUMNS: ReadonlyArray<string> = [
|
|
63
|
+
"mapFromResourceType",
|
|
64
|
+
"mapFromCustomFieldName",
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
/** The `<timestamp>-<Name>.ts` prefix TypeORM orders migrations by. */
|
|
68
|
+
const MIGRATION_TIMESTAMP_PREFIX: RegExp = /^(\d+)-/;
|
|
69
|
+
|
|
70
|
+
/*
|
|
71
|
+
* What TypeORM's metadata storage keys entities by: the class itself. Only
|
|
72
|
+
* ever compared by identity against `column.target`, so `unknown` states the
|
|
73
|
+
* requirement exactly — and avoids `Function`/`object`, both of which this
|
|
74
|
+
* repo's eslint config bans.
|
|
75
|
+
*/
|
|
76
|
+
type ModelClass = unknown;
|
|
77
|
+
|
|
78
|
+
const DEFINITION_MODELS: Record<string, ModelClass> = {
|
|
79
|
+
AlertCustomField: AlertCustomField,
|
|
80
|
+
IncidentCustomField: IncidentCustomField,
|
|
81
|
+
InventoryItemCustomField: InventoryItemCustomField,
|
|
82
|
+
MonitorCustomField: MonitorCustomField,
|
|
83
|
+
OnCallDutyPolicyCustomField: OnCallDutyPolicyCustomField,
|
|
84
|
+
ScheduledMaintenanceCustomField: ScheduledMaintenanceCustomField,
|
|
85
|
+
StatusPageCustomField: StatusPageCustomField,
|
|
86
|
+
TeamCustomField: TeamCustomField,
|
|
87
|
+
TeamMemberCustomField: TeamMemberCustomField,
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/*
|
|
91
|
+
* The definition tables as they exist on disk, so a tenth one added later
|
|
92
|
+
* fails this suite rather than quietly shipping without the columns.
|
|
93
|
+
*/
|
|
94
|
+
const DEFINITION_TABLES: Array<string> = fs
|
|
95
|
+
.readdirSync(MODELS_DIRECTORY)
|
|
96
|
+
.filter((fileName: string) => {
|
|
97
|
+
return fileName.endsWith("CustomField.ts");
|
|
98
|
+
})
|
|
99
|
+
.map((fileName: string) => {
|
|
100
|
+
return fileName.replace(/\.ts$/, "");
|
|
101
|
+
})
|
|
102
|
+
.sort();
|
|
103
|
+
|
|
104
|
+
type DeclaredColumnsFunction = (modelType: ModelClass) => Array<string>;
|
|
105
|
+
|
|
106
|
+
const getDeclaredColumns: DeclaredColumnsFunction = (
|
|
107
|
+
modelType: ModelClass,
|
|
108
|
+
): Array<string> => {
|
|
109
|
+
return getMetadataArgsStorage()
|
|
110
|
+
.columns.filter((column: ColumnMetadataArgs): boolean => {
|
|
111
|
+
return column.target === modelType;
|
|
112
|
+
})
|
|
113
|
+
.map((column: ColumnMetadataArgs): string => {
|
|
114
|
+
return column.propertyName;
|
|
115
|
+
});
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
describe("the value-mapping migration", () => {
|
|
119
|
+
test("the file the rest of this suite reads exists, and every definition table is covered", () => {
|
|
120
|
+
expect(fs.existsSync(MIGRATION_PATH)).toBe(true);
|
|
121
|
+
expect(SOURCE.length).toBeGreaterThan(0);
|
|
122
|
+
expect(DEFINITION_TABLES.length).toBeGreaterThanOrEqual(9);
|
|
123
|
+
expect(Object.keys(DEFINITION_MODELS).sort()).toEqual(DEFINITION_TABLES);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
/*
|
|
127
|
+
* Registration is the step with no feedback: an unregistered migration
|
|
128
|
+
* throws no error, logs nothing and simply never runs.
|
|
129
|
+
*/
|
|
130
|
+
test("is registered in SchemaMigrations/Index.ts so it actually runs", () => {
|
|
131
|
+
expect(SchemaMigrations).toContain(AddCustomFieldValueMapping1791600000000);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test("its class name matches the `name` TypeORM records in the migrations table", () => {
|
|
135
|
+
expect(new AddCustomFieldValueMapping1791600000000().name).toBe(
|
|
136
|
+
"AddCustomFieldValueMapping1791600000000",
|
|
137
|
+
);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
test.each(DEFINITION_TABLES)(
|
|
141
|
+
"adds both mapping columns to %s",
|
|
142
|
+
(tableName: string) => {
|
|
143
|
+
for (const column of MAPPING_COLUMNS) {
|
|
144
|
+
expect(SOURCE).toContain(
|
|
145
|
+
`ALTER TABLE "${tableName}" ADD "${column}" character varying(100)`,
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
test.each(DEFINITION_TABLES)(
|
|
152
|
+
"drops both mapping columns from %s on the way down",
|
|
153
|
+
(tableName: string) => {
|
|
154
|
+
for (const column of MAPPING_COLUMNS) {
|
|
155
|
+
expect(SOURCE).toContain(
|
|
156
|
+
`ALTER TABLE "${tableName}" DROP COLUMN "${column}"`,
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
test.each(DEFINITION_TABLES)(
|
|
163
|
+
"%s declares both mapping columns on the model, so the schema and the entities agree",
|
|
164
|
+
(tableName: string) => {
|
|
165
|
+
const declared: Array<string> = getDeclaredColumns(
|
|
166
|
+
DEFINITION_MODELS[tableName],
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
for (const column of MAPPING_COLUMNS) {
|
|
170
|
+
expect(declared).toContain(column);
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
/*
|
|
176
|
+
* TypeORM orders migrations by the timestamp in the class name, not by the
|
|
177
|
+
* order of the array. A timestamp below one already registered would run
|
|
178
|
+
* this migration before migrations that shipped earlier — harmless here, but
|
|
179
|
+
* the convention in this directory is a monotonic timestamp and breaking it
|
|
180
|
+
* makes the ordering unreadable.
|
|
181
|
+
*/
|
|
182
|
+
test("its timestamp is the newest in the directory", () => {
|
|
183
|
+
const timestamps: Array<number> = fs
|
|
184
|
+
.readdirSync(MIGRATIONS_DIRECTORY)
|
|
185
|
+
.map((fileName: string) => {
|
|
186
|
+
return MIGRATION_TIMESTAMP_PREFIX.exec(fileName);
|
|
187
|
+
})
|
|
188
|
+
.filter((match: RegExpExecArray | null): match is RegExpExecArray => {
|
|
189
|
+
return Boolean(match);
|
|
190
|
+
})
|
|
191
|
+
.map((match: RegExpExecArray) => {
|
|
192
|
+
return parseInt(match[1]!, 10);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
const ownTimestamp: number = parseInt(
|
|
196
|
+
MIGRATION_TIMESTAMP_PREFIX.exec(path.basename(MIGRATION_PATH))![1]!,
|
|
197
|
+
10,
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
expect(Math.max(...timestamps)).toBe(ownTimestamp);
|
|
201
|
+
});
|
|
202
|
+
});
|
|
@@ -137,12 +137,53 @@ describe("the custom field table", () => {
|
|
|
137
137
|
/*
|
|
138
138
|
* Read off the model rather than listed here, so a column added to the
|
|
139
139
|
* model without a migration fails rather than throwing at runtime.
|
|
140
|
+
*
|
|
141
|
+
* A column may legitimately arrive in a LATER migration instead of this
|
|
142
|
+
* CREATE TABLE — this migration has already shipped, and editing it would
|
|
143
|
+
* do nothing for the databases that have run it while putting them out of
|
|
144
|
+
* step with fresh ones. So the invariant is "every model column is created
|
|
145
|
+
* here or added later", which still fails a column that no migration
|
|
146
|
+
* mentions at all. The end-state schema itself is owned by the Schema
|
|
147
|
+
* Drift job, which migrates an empty database and diffs it against the
|
|
148
|
+
* models.
|
|
140
149
|
*/
|
|
141
150
|
const createStatement: string = SOURCE.slice(
|
|
142
151
|
SOURCE.indexOf('CREATE TABLE "InventoryItemCustomField"'),
|
|
143
152
|
).split("`")[0]!;
|
|
144
153
|
|
|
154
|
+
const migrationsDirectory: string = path.dirname(MIGRATION_PATH);
|
|
155
|
+
|
|
156
|
+
const addedByLaterMigration: Set<string> = new Set<string>();
|
|
157
|
+
|
|
158
|
+
for (const fileName of fs.readdirSync(migrationsDirectory)) {
|
|
159
|
+
if (
|
|
160
|
+
!fileName.endsWith(".ts") ||
|
|
161
|
+
fileName === path.basename(MIGRATION_PATH)
|
|
162
|
+
) {
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const migrationSource: string = fs.readFileSync(
|
|
167
|
+
path.join(migrationsDirectory, fileName),
|
|
168
|
+
"utf8",
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
const addPattern: RegExp =
|
|
172
|
+
/ALTER TABLE "InventoryItemCustomField" ADD "([^"]+)"/g;
|
|
173
|
+
|
|
174
|
+
let match: RegExpExecArray | null = addPattern.exec(migrationSource);
|
|
175
|
+
|
|
176
|
+
while (match) {
|
|
177
|
+
addedByLaterMigration.add(match[1]!);
|
|
178
|
+
match = addPattern.exec(migrationSource);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
145
182
|
for (const column of getDeclaredColumns(InventoryItemCustomField)) {
|
|
183
|
+
if (addedByLaterMigration.has(column)) {
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
|
|
146
187
|
expect(createStatement).toContain(`"${column}"`);
|
|
147
188
|
}
|
|
148
189
|
});
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { describe, expect, test } from "@jest/globals";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import SchemaMigrations from "../../../../Server/Infrastructure/Postgres/SchemaMigrations/Index";
|
|
5
|
+
import { SessionReplayRecordEverySessionByDefault1791400000000 } from "../../../../Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault";
|
|
6
|
+
import RumApplication from "../../../../Models/DatabaseModels/RumApplication";
|
|
7
|
+
import SessionReplayCaptureTrigger from "../../../../Types/Rum/SessionReplayCaptureTrigger";
|
|
8
|
+
import { TableColumnMetadata } from "../../../../Types/Database/TableColumn";
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
* The migration that makes session replay record every session rather than
|
|
12
|
+
* only the ones that broke.
|
|
13
|
+
*
|
|
14
|
+
* The reported bug was not that playback was broken for unfailed sessions —
|
|
15
|
+
* it was that they were never uploaded at all. `OnErrorOrFrustration` with
|
|
16
|
+
* `sessionReplaySamplePercentage: 0` means the recorder buffers in memory and
|
|
17
|
+
* posts nothing until an error, a 5xx or a frustration signal fires, so the
|
|
18
|
+
* only rows that ever reached the session list carried one of those signals.
|
|
19
|
+
* Everything else read as "Metadata only" or as no row at all, which is
|
|
20
|
+
* indistinguishable from a feature that does not work.
|
|
21
|
+
*
|
|
22
|
+
* Three things are pinned here, and each of them is a silent regression if it
|
|
23
|
+
* moves on its own:
|
|
24
|
+
*
|
|
25
|
+
* 1. THE ENTITY AND THE MIGRATION AGREE. A default lives in two places —
|
|
26
|
+
* the @Column decorator TypeORM generates DDL from, and the ALTER this
|
|
27
|
+
* migration runs on databases that already exist. If only one moves, a
|
|
28
|
+
* fresh install and an upgraded install disagree about what recording
|
|
29
|
+
* means, and the schema-drift job does not catch a DEFAULT that matches
|
|
30
|
+
* the entity it was generated from.
|
|
31
|
+
*
|
|
32
|
+
* 2. THE BACKFILL IS SCOPED TO ROWS STILL ON BOTH OLD DEFAULTS. An
|
|
33
|
+
* unscoped UPDATE would overwrite a deliberate configuration; scoping on
|
|
34
|
+
* only one of the two columns would catch an application whose operator
|
|
35
|
+
* had set the other on purpose. Requiring both is the closest a
|
|
36
|
+
* migration can get to "was never configured", and widening it later
|
|
37
|
+
* would quietly increase how much end-user data an install records.
|
|
38
|
+
*
|
|
39
|
+
* 3. down() REVERSES THE DEFAULTS AND NOT THE BACKFILL. Rows moved by the
|
|
40
|
+
* backfill are indistinguishable from ones an operator chose afterwards,
|
|
41
|
+
* so moving them back would silently stop recording sessions somebody is
|
|
42
|
+
* relying on being able to watch.
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
const MIGRATION_PATH: string = path.join(
|
|
46
|
+
__dirname,
|
|
47
|
+
"../../../../Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.ts",
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const SOURCE: string = fs.readFileSync(MIGRATION_PATH, "utf8");
|
|
51
|
+
|
|
52
|
+
function bodyOf(method: "up" | "down"): string {
|
|
53
|
+
const start: number = SOURCE.indexOf(`public async ${method}(`);
|
|
54
|
+
|
|
55
|
+
expect(start).toBeGreaterThan(-1);
|
|
56
|
+
|
|
57
|
+
const end: number =
|
|
58
|
+
method === "up" ? SOURCE.indexOf("public async down(") : SOURCE.length;
|
|
59
|
+
|
|
60
|
+
return SOURCE.slice(start, end);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function statementsIn(body: string): Array<string> {
|
|
64
|
+
return [...body.matchAll(/`([^`]+)`/g)].map(
|
|
65
|
+
(match: RegExpMatchArray): string => {
|
|
66
|
+
return match[1] as string;
|
|
67
|
+
},
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const UP_STATEMENTS: Array<string> = statementsIn(bodyOf("up"));
|
|
72
|
+
const DOWN_STATEMENTS: Array<string> = statementsIn(bodyOf("down"));
|
|
73
|
+
|
|
74
|
+
describe("SessionReplayRecordEverySessionByDefault migration", () => {
|
|
75
|
+
test("it is registered in the schema migration list", () => {
|
|
76
|
+
expect(SchemaMigrations).toContain(
|
|
77
|
+
SessionReplayRecordEverySessionByDefault1791400000000,
|
|
78
|
+
);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test("its class name matches its file name, so typeorm can find it", () => {
|
|
82
|
+
expect(
|
|
83
|
+
new SessionReplayRecordEverySessionByDefault1791400000000().name,
|
|
84
|
+
).toBe("SessionReplayRecordEverySessionByDefault1791400000000");
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test("it moves both column defaults to always-on recording", () => {
|
|
88
|
+
expect(UP_STATEMENTS).toContain(
|
|
89
|
+
`ALTER TABLE "RumApplication" ALTER COLUMN "sessionReplayCaptureTrigger" SET DEFAULT 'Always'`,
|
|
90
|
+
);
|
|
91
|
+
expect(UP_STATEMENTS).toContain(
|
|
92
|
+
`ALTER TABLE "RumApplication" ALTER COLUMN "sessionReplaySamplePercentage" SET DEFAULT 100`,
|
|
93
|
+
);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test("it backfills only rows still sitting on BOTH previous defaults", () => {
|
|
97
|
+
const updates: Array<string> = UP_STATEMENTS.filter(
|
|
98
|
+
(statement: string): boolean => {
|
|
99
|
+
return statement.startsWith("UPDATE ");
|
|
100
|
+
},
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
expect(updates).toHaveLength(1);
|
|
104
|
+
|
|
105
|
+
const update: string = updates[0] as string;
|
|
106
|
+
|
|
107
|
+
expect(update).toContain(`"sessionReplayCaptureTrigger" = 'Always'`);
|
|
108
|
+
expect(update).toContain(`"sessionReplaySamplePercentage" = 100`);
|
|
109
|
+
|
|
110
|
+
/*
|
|
111
|
+
* The WHERE is the entire safety property. Both conditions, joined by
|
|
112
|
+
* AND: an application whose operator chose Always, or dialled the
|
|
113
|
+
* sample percentage anywhere off zero, is left exactly as configured.
|
|
114
|
+
*/
|
|
115
|
+
const where: string = update.slice(update.indexOf(" WHERE "));
|
|
116
|
+
|
|
117
|
+
expect(where).toContain(
|
|
118
|
+
`"sessionReplayCaptureTrigger" = 'OnErrorOrFrustration'`,
|
|
119
|
+
);
|
|
120
|
+
expect(where).toContain(`"sessionReplaySamplePercentage" = 0`);
|
|
121
|
+
expect(where).toContain(" AND ");
|
|
122
|
+
expect(where).not.toContain(" OR ");
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test("down() restores the defaults and leaves the backfilled rows alone", () => {
|
|
126
|
+
expect(DOWN_STATEMENTS).toContain(
|
|
127
|
+
`ALTER TABLE "RumApplication" ALTER COLUMN "sessionReplayCaptureTrigger" SET DEFAULT 'OnErrorOrFrustration'`,
|
|
128
|
+
);
|
|
129
|
+
expect(DOWN_STATEMENTS).toContain(
|
|
130
|
+
`ALTER TABLE "RumApplication" ALTER COLUMN "sessionReplaySamplePercentage" SET DEFAULT 0`,
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
expect(
|
|
134
|
+
DOWN_STATEMENTS.some((statement: string): boolean => {
|
|
135
|
+
return statement.startsWith("UPDATE ");
|
|
136
|
+
}),
|
|
137
|
+
).toBe(false);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
describe("RumApplication session replay capture defaults", () => {
|
|
142
|
+
test("a new application records every session from its first event", () => {
|
|
143
|
+
const application: RumApplication = new RumApplication();
|
|
144
|
+
|
|
145
|
+
const trigger: TableColumnMetadata = application.getTableColumnMetadata(
|
|
146
|
+
"sessionReplayCaptureTrigger",
|
|
147
|
+
);
|
|
148
|
+
const sample: TableColumnMetadata = application.getTableColumnMetadata(
|
|
149
|
+
"sessionReplaySamplePercentage",
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
expect(trigger.defaultValue).toBe(SessionReplayCaptureTrigger.Always);
|
|
153
|
+
expect(sample.defaultValue).toBe(100);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
/*
|
|
157
|
+
* The dashboard form renders this enum straight into a dropdown, in
|
|
158
|
+
* declaration order, so the first member is what a person reads as the
|
|
159
|
+
* recommended answer. Keeping Always first is the difference between the
|
|
160
|
+
* default being discoverable and being buried under the option that
|
|
161
|
+
* records nothing for a healthy visit.
|
|
162
|
+
*/
|
|
163
|
+
test("Always is the first capture trigger a person is offered", () => {
|
|
164
|
+
expect(Object.values(SessionReplayCaptureTrigger)).toEqual([
|
|
165
|
+
SessionReplayCaptureTrigger.Always,
|
|
166
|
+
SessionReplayCaptureTrigger.OnErrorOrFrustration,
|
|
167
|
+
]);
|
|
168
|
+
});
|
|
169
|
+
});
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import QueueWorker from "../../../Server/Infrastructure/QueueWorker";
|
|
2
|
+
import TimeoutException from "../../../Types/Exception/TimeoutException";
|
|
3
|
+
|
|
4
|
+
jest.mock("../../../Server/Utils/Telemetry/CaptureSpan", () => {
|
|
5
|
+
return {
|
|
6
|
+
__esModule: true,
|
|
7
|
+
default: () => {
|
|
8
|
+
return (
|
|
9
|
+
_target: unknown,
|
|
10
|
+
_name: string,
|
|
11
|
+
descriptor: PropertyDescriptor,
|
|
12
|
+
): PropertyDescriptor => {
|
|
13
|
+
return descriptor;
|
|
14
|
+
};
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
jest.mock("../../../Server/Utils/Telemetry", () => {
|
|
20
|
+
return { __esModule: true, default: {} };
|
|
21
|
+
});
|
|
22
|
+
jest.mock("../../../Server/Utils/Telemetry/AppMetrics", () => {
|
|
23
|
+
return { __esModule: true, default: {} };
|
|
24
|
+
});
|
|
25
|
+
jest.mock("../../../Server/Infrastructure/Redis", () => {
|
|
26
|
+
return { __esModule: true, default: {} };
|
|
27
|
+
});
|
|
28
|
+
jest.mock("../../../Server/Utils/GracefulShutdown", () => {
|
|
29
|
+
return { __esModule: true, default: {} };
|
|
30
|
+
});
|
|
31
|
+
jest.mock("../../../Server/Utils/Logger", () => {
|
|
32
|
+
return { __esModule: true, default: {} };
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
interface DeferredJob {
|
|
36
|
+
promise: Promise<void>;
|
|
37
|
+
resolve: () => void;
|
|
38
|
+
reject: (reason: unknown) => void;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function deferredJob(): DeferredJob {
|
|
42
|
+
let resolve!: () => void;
|
|
43
|
+
let reject!: (reason: unknown) => void;
|
|
44
|
+
const promise: Promise<void> = new Promise<void>(
|
|
45
|
+
(res: () => void, rej: (reason: unknown) => void) => {
|
|
46
|
+
resolve = res;
|
|
47
|
+
reject = rej;
|
|
48
|
+
},
|
|
49
|
+
);
|
|
50
|
+
return { promise, resolve, reject };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
describe("QueueWorker.runJobWithTimeout timer lifecycle", () => {
|
|
54
|
+
beforeEach(() => {
|
|
55
|
+
jest.useFakeTimers();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
afterEach(() => {
|
|
59
|
+
jest.clearAllTimers();
|
|
60
|
+
jest.useRealTimers();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it.each([0, 1, 300_000, 3_600_000])(
|
|
64
|
+
"releases a %i ms deadline immediately when the job succeeds",
|
|
65
|
+
async (deadline: number) => {
|
|
66
|
+
const callback: jest.Mock = jest.fn().mockResolvedValue(undefined);
|
|
67
|
+
await expect(
|
|
68
|
+
QueueWorker.runJobWithTimeout(deadline, callback),
|
|
69
|
+
).resolves.toBeUndefined();
|
|
70
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
71
|
+
expect(jest.getTimerCount()).toBe(0);
|
|
72
|
+
},
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
it.each([new Error("failed"), "non-error rejection", null])(
|
|
76
|
+
"preserves rejection identity and clears the deadline (%p)",
|
|
77
|
+
async (error: unknown) => {
|
|
78
|
+
await expect(
|
|
79
|
+
QueueWorker.runJobWithTimeout(300_000, () => {
|
|
80
|
+
return Promise.reject(error);
|
|
81
|
+
}),
|
|
82
|
+
).rejects.toBe(error);
|
|
83
|
+
expect(jest.getTimerCount()).toBe(0);
|
|
84
|
+
},
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
it("clears the timer when the callback throws before returning a promise", async () => {
|
|
88
|
+
const error: Error = new Error("synchronous failure");
|
|
89
|
+
await expect(
|
|
90
|
+
QueueWorker.runJobWithTimeout(300_000, () => {
|
|
91
|
+
throw error;
|
|
92
|
+
}),
|
|
93
|
+
).rejects.toBe(error);
|
|
94
|
+
expect(jest.getTimerCount()).toBe(0);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it("holds a deadline only while a job is pending", async () => {
|
|
98
|
+
const job: DeferredJob = deferredJob();
|
|
99
|
+
const result: Promise<void> = QueueWorker.runJobWithTimeout(100, () => {
|
|
100
|
+
return job.promise;
|
|
101
|
+
});
|
|
102
|
+
expect(jest.getTimerCount()).toBe(1);
|
|
103
|
+
jest.advanceTimersByTime(99);
|
|
104
|
+
job.resolve();
|
|
105
|
+
await result;
|
|
106
|
+
expect(jest.getTimerCount()).toBe(0);
|
|
107
|
+
jest.advanceTimersByTime(1);
|
|
108
|
+
await expect(result).resolves.toBeUndefined();
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("rejects at the deadline with the existing timeout error", async () => {
|
|
112
|
+
const job: DeferredJob = deferredJob();
|
|
113
|
+
const result: Promise<void> = QueueWorker.runJobWithTimeout(100, () => {
|
|
114
|
+
return job.promise;
|
|
115
|
+
});
|
|
116
|
+
const rejection: Promise<void> = expect(result).rejects.toEqual(
|
|
117
|
+
new TimeoutException("Job Timeout"),
|
|
118
|
+
);
|
|
119
|
+
jest.advanceTimersByTime(100);
|
|
120
|
+
await rejection;
|
|
121
|
+
expect(jest.getTimerCount()).toBe(0);
|
|
122
|
+
// The timeout is a deadline, not cancellation of the underlying work.
|
|
123
|
+
job.resolve();
|
|
124
|
+
await job.promise;
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it("observes a job rejection after its deadline without an unhandled rejection", async () => {
|
|
128
|
+
const job: DeferredJob = deferredJob();
|
|
129
|
+
const result: Promise<void> = QueueWorker.runJobWithTimeout(10, () => {
|
|
130
|
+
return job.promise;
|
|
131
|
+
});
|
|
132
|
+
const rejection: Promise<void> =
|
|
133
|
+
expect(result).rejects.toBeInstanceOf(TimeoutException);
|
|
134
|
+
jest.advanceTimersByTime(10);
|
|
135
|
+
await rejection;
|
|
136
|
+
job.reject(new Error("late failure"));
|
|
137
|
+
await Promise.resolve();
|
|
138
|
+
await Promise.resolve();
|
|
139
|
+
expect(jest.getTimerCount()).toBe(0);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it("keeps another concurrent job's deadline active", async () => {
|
|
143
|
+
const first: DeferredJob = deferredJob();
|
|
144
|
+
const second: DeferredJob = deferredJob();
|
|
145
|
+
const firstResult: Promise<void> = QueueWorker.runJobWithTimeout(
|
|
146
|
+
100,
|
|
147
|
+
() => {
|
|
148
|
+
return first.promise;
|
|
149
|
+
},
|
|
150
|
+
);
|
|
151
|
+
const secondResult: Promise<void> = QueueWorker.runJobWithTimeout(
|
|
152
|
+
200,
|
|
153
|
+
() => {
|
|
154
|
+
return second.promise;
|
|
155
|
+
},
|
|
156
|
+
);
|
|
157
|
+
const secondRejection: Promise<void> =
|
|
158
|
+
expect(secondResult).rejects.toBeInstanceOf(TimeoutException);
|
|
159
|
+
|
|
160
|
+
first.resolve();
|
|
161
|
+
await firstResult;
|
|
162
|
+
expect(jest.getTimerCount()).toBe(1);
|
|
163
|
+
jest.advanceTimersByTime(200);
|
|
164
|
+
await secondRejection;
|
|
165
|
+
expect(jest.getTimerCount()).toBe(0);
|
|
166
|
+
second.resolve();
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it("does not clear timers created by the job itself", async () => {
|
|
170
|
+
const jobTimer: jest.Mock = jest.fn();
|
|
171
|
+
await QueueWorker.runJobWithTimeout(100, async () => {
|
|
172
|
+
setTimeout(jobTimer, 200);
|
|
173
|
+
});
|
|
174
|
+
expect(jest.getTimerCount()).toBe(1);
|
|
175
|
+
jest.advanceTimersByTime(200);
|
|
176
|
+
expect(jobTimer).toHaveBeenCalledTimes(1);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it("keeps the original deadline-first ordering for equal-time completion", async () => {
|
|
180
|
+
const result: Promise<void> = QueueWorker.runJobWithTimeout(100, () => {
|
|
181
|
+
return new Promise<void>((resolve: () => void) => {
|
|
182
|
+
setTimeout(resolve, 100);
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
const rejection: Promise<void> =
|
|
186
|
+
expect(result).rejects.toBeInstanceOf(TimeoutException);
|
|
187
|
+
jest.advanceTimersByTime(100);
|
|
188
|
+
await rejection;
|
|
189
|
+
expect(jest.getTimerCount()).toBe(0);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it("does not accumulate timeout handles across 10,000 completed jobs", async () => {
|
|
193
|
+
for (let batch: number = 0; batch < 100; batch++) {
|
|
194
|
+
const jobs: Array<Promise<void>> = Array.from(
|
|
195
|
+
{ length: 100 },
|
|
196
|
+
(_value: unknown, index: number): Promise<void> => {
|
|
197
|
+
return QueueWorker.runJobWithTimeout(300_000, async () => {
|
|
198
|
+
if (index % 2 === 0) {
|
|
199
|
+
throw new Error("expected job failure");
|
|
200
|
+
}
|
|
201
|
+
}).catch(() => {
|
|
202
|
+
// Failed jobs must release their timers too.
|
|
203
|
+
});
|
|
204
|
+
},
|
|
205
|
+
);
|
|
206
|
+
await Promise.all(jobs);
|
|
207
|
+
expect(jest.getTimerCount()).toBe(0);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
});
|