@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.
Files changed (652) hide show
  1. package/Models/AnalyticsModels/RumSession.ts +117 -1
  2. package/Models/AnalyticsModels/RumSessionChunk.ts +13 -0
  3. package/Models/DatabaseModels/AlertCustomField.ts +77 -3
  4. package/Models/DatabaseModels/ApiKeyPermission.ts +3 -27
  5. package/Models/DatabaseModels/IncidentCustomField.ts +77 -3
  6. package/Models/DatabaseModels/InventoryItemCustomField.ts +77 -3
  7. package/Models/DatabaseModels/MonitorCustomField.ts +77 -3
  8. package/Models/DatabaseModels/OnCallDutyPolicyCustomField.ts +77 -3
  9. package/Models/DatabaseModels/RumApplication.ts +6 -6
  10. package/Models/DatabaseModels/ScheduledMaintenanceCustomField.ts +77 -3
  11. package/Models/DatabaseModels/StatusPageCustomField.ts +77 -3
  12. package/Models/DatabaseModels/TeamCustomField.ts +77 -3
  13. package/Models/DatabaseModels/TeamMember.ts +0 -9
  14. package/Models/DatabaseModels/TeamMemberCustomField.ts +77 -3
  15. package/Models/DatabaseModels/TeamPermission.ts +3 -24
  16. package/Models/DatabaseModels/TelemetryIngestionKey.ts +260 -0
  17. package/Models/DatabaseModels/UserTelegram.ts +0 -4
  18. package/Scripts/benchmark-fanin-capacity.js +181 -0
  19. package/Server/API/TelemetryAPI.ts +1284 -164
  20. package/Server/API/UserNotificationSettingAPI.ts +55 -0
  21. package/Server/API/UserTelegramAPI.ts +48 -4
  22. package/Server/EnvironmentConfig.ts +35 -2
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.ts +91 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.ts +67 -0
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.ts +139 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.ts +121 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  28. package/Server/Infrastructure/QueueWorker.ts +20 -14
  29. package/Server/Infrastructure/Semaphore.ts +2 -0
  30. package/Server/Middleware/TelemetryIngest.ts +453 -7
  31. package/Server/Services/AccessTokenService.ts +1 -0
  32. package/Server/Services/AlertCustomFieldService.ts +98 -0
  33. package/Server/Services/AlertService.ts +37 -0
  34. package/Server/Services/ApiKeyPermissionService.ts +461 -29
  35. package/Server/Services/CustomFieldMappingService.ts +879 -0
  36. package/Server/Services/GlobalConfigService.ts +194 -0
  37. package/Server/Services/IncidentCustomFieldService.ts +98 -0
  38. package/Server/Services/IncidentService.ts +35 -0
  39. package/Server/Services/MetricService.ts +194 -0
  40. package/Server/Services/MonitorService.ts +32 -0
  41. package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +78 -25
  42. package/Server/Services/ProjectService.ts +22 -0
  43. package/Server/Services/RoutineEmailSettingsService.ts +73 -0
  44. package/Server/Services/RumSessionReplayViewService.ts +104 -24
  45. package/Server/Services/ScheduledMaintenanceCustomFieldService.ts +98 -0
  46. package/Server/Services/ScheduledMaintenanceService.ts +32 -0
  47. package/Server/Services/TeamMemberService.ts +78 -0
  48. package/Server/Services/TeamPermissionService.ts +235 -3
  49. package/Server/Services/TelemetryIngestionKeyService.ts +722 -19
  50. package/Server/Services/UserNotificationSettingService.ts +34 -6
  51. package/Server/Services/UserTelegramService.ts +326 -5
  52. package/Server/Types/Database/QueryHelper.ts +2 -0
  53. package/Server/Utils/APIKey/AccessPermission.ts +5 -2
  54. package/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.ts +54 -0
  55. package/Server/Utils/CustomField/CustomFieldMappingRegistry.ts +415 -0
  56. package/Server/Utils/CustomField/CustomFieldMappingValidator.ts +335 -0
  57. package/Server/Utils/DataSource/EgressGuard.ts +177 -8
  58. package/Server/Utils/EmailRollup/EmailRollupConstants.ts +38 -5
  59. package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +57 -4
  60. package/Server/Utils/FrontendEnvironment.ts +40 -0
  61. package/Server/Utils/LogRedaction.ts +20 -0
  62. package/Server/Utils/Logger.ts +11 -0
  63. package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +338 -77
  64. package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +30 -4
  65. package/Server/Utils/Monitor/MonitorAlert.ts +29 -6
  66. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +110 -15
  67. package/Server/Utils/Monitor/MonitorIncident.ts +22 -6
  68. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +29 -0
  69. package/Server/Utils/Monitor/SeriesContextEnricher.ts +304 -0
  70. package/Server/Utils/SSRFProtection.ts +217 -10
  71. package/Server/Utils/SessionReplay/SessionReplayGateCache.ts +239 -138
  72. package/Server/Utils/SessionReplay/SessionReplayHealthCounters.ts +305 -0
  73. package/Server/Utils/SessionReplay/SessionReplayReadService.ts +1430 -289
  74. package/Server/Utils/StartServer.ts +2 -17
  75. package/Server/Utils/TelegramVerificationToken.ts +185 -0
  76. package/Server/Utils/Telemetry/PinServiceName.ts +197 -0
  77. package/Server/Utils/Telemetry/TelemetryFanInWriter.ts +38 -16
  78. package/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.ts +92 -0
  79. package/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.ts +217 -0
  80. package/Server/Utils/VM/VMAPI.ts +1 -0
  81. package/Server/Utils/VM/VMRunner.ts +975 -95
  82. package/Tests/App/AdminDashboard/AdminHeaderSmallScreens.test.tsx +202 -0
  83. package/Tests/App/Dashboard/DashboardHeaderSmallScreens.test.tsx +404 -0
  84. package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +468 -0
  85. package/Tests/App/Dashboard/NotificationEmailPreferences.test.tsx +399 -0
  86. package/Tests/App/StatusPage/StatusPageLastUpdated.test.tsx +263 -0
  87. package/Tests/App/StatusPage/StatusPageOverviewLiveAndSearch.test.tsx +753 -0
  88. package/Tests/App/StatusPage/StatusPageResourceSearchBox.test.tsx +224 -0
  89. package/Tests/Models/AnalyticsModels/RumSessionReplayColumns.test.ts +262 -0
  90. package/Tests/Models/CustomFieldMappingColumns.test.ts +166 -0
  91. package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +20 -6
  92. package/Tests/ResponsiveVisibility.test.ts +115 -0
  93. package/Tests/ResponsiveVisibility.ts +183 -0
  94. package/Tests/Server/API/SessionReplayAPI.test.ts +1940 -216
  95. package/Tests/Server/API/UserNotificationSettingAPI.test.ts +186 -0
  96. package/Tests/Server/API/UserTelegramAPISecurity.test.ts +231 -0
  97. package/Tests/Server/EnvironmentConfigFrontendSecurity.test.ts +234 -0
  98. package/Tests/Server/Infrastructure/Postgres/CustomFieldValueMappingMigration.test.ts +202 -0
  99. package/Tests/Server/Infrastructure/Postgres/InventoryItemArchiveMigration.test.ts +41 -0
  100. package/Tests/Server/Infrastructure/Postgres/SessionReplayRecordEverySessionByDefaultMigration.test.ts +169 -0
  101. package/Tests/Server/Infrastructure/QueueWorkerTimeout.test.ts +210 -0
  102. package/Tests/Server/Infrastructure/TelemetryExporterDeploymentConfig.test.ts +130 -0
  103. package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +4 -1
  104. package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +1163 -0
  105. package/Tests/Server/Middleware/TelemetryIngestTokenLog.test.ts +5 -3
  106. package/Tests/Server/Services/AddTelemetryIngestionKeyTypeMigration.test.ts +555 -0
  107. package/Tests/Server/Services/ApiKeyPermissionSecurity.test.ts +678 -0
  108. package/Tests/Server/Services/ApiKeyPermissionService.test.ts +276 -28
  109. package/Tests/Server/Services/CustomFieldDropdownOptionsColumnWidth.test.ts +431 -0
  110. package/Tests/Server/Services/CustomFieldMappingService.test.ts +850 -0
  111. package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +32 -0
  112. package/Tests/Server/Services/GlobalConfigService.test.ts +414 -1
  113. package/Tests/Server/Services/MetricRawEntityKeyPrune.test.ts +592 -0
  114. package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +226 -1
  115. package/Tests/Server/Services/RoutineEmailSettingsPostgres.test.ts +329 -0
  116. package/Tests/Server/Services/RumSessionReplayViewService.test.ts +267 -0
  117. package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +9 -0
  118. package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +9 -0
  119. package/Tests/Server/Services/TeamPrivilegeEscalation.test.ts +834 -0
  120. package/Tests/Server/Services/TelemetryIngestionKeyPolicyResolution.test.ts +814 -0
  121. package/Tests/Server/Services/TelemetryIngestionKeyValidation.test.ts +998 -0
  122. package/Tests/Server/Services/UserNotificationSettingRollupRouting.test.ts +141 -0
  123. package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +18 -10
  124. package/Tests/Server/Services/UserTelegramVerificationSecurity.test.ts +688 -0
  125. package/Tests/Server/Utils/AI/SRE/Insights/FixRouting.test.ts +497 -0
  126. package/Tests/Server/Utils/AI/Toolbox/Serializer.test.ts +383 -0
  127. package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +7 -3
  128. package/Tests/Server/Utils/AnalyticsDatabase/ClusterConfig.test.ts +315 -0
  129. package/Tests/Server/Utils/CustomField/CustomFieldMappingValidator.test.ts +437 -0
  130. package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +300 -11
  131. package/Tests/Server/Utils/EmailRollup/EmailRollupBurstWindow.test.ts +83 -0
  132. package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerBehaviour.test.ts +1 -1
  133. package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerPreferences.test.ts +362 -0
  134. package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +77 -1
  135. package/Tests/Server/Utils/FrontendEnvironment.test.ts +190 -0
  136. package/Tests/Server/Utils/LogRedaction.test.ts +26 -0
  137. package/Tests/Server/Utils/LoggerCredentialLeak.test.ts +23 -9
  138. package/Tests/Server/Utils/Monitor/Criteria/CompareCriteriaAggregation.test.ts +584 -0
  139. package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestHeaderCriteria.test.ts +236 -0
  140. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +437 -0
  141. package/Tests/Server/Utils/Monitor/MonitorTemplateUtilSeriesContext.test.ts +176 -0
  142. package/Tests/Server/Utils/Monitor/SeriesContextEnricher.test.ts +356 -0
  143. package/Tests/Server/Utils/SSRFProtectionCloudServiceAddresses.test.ts +595 -0
  144. package/Tests/Server/Utils/SessionReplay/SessionReplayGateCachePolicy.test.ts +198 -1
  145. package/Tests/Server/Utils/SessionReplay/SessionReplayHealthCounters.test.ts +453 -0
  146. package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +1378 -0
  147. package/Tests/Server/Utils/SessionReplayOriginAllowListRefactor.test.ts +420 -0
  148. package/Tests/Server/Utils/TelegramVerificationToken.test.ts +253 -0
  149. package/Tests/Server/Utils/Telemetry/PinServiceName.test.ts +666 -0
  150. package/Tests/Server/Utils/Telemetry/TelemetryFanInWriterCapacity.test.ts +458 -0
  151. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +424 -0
  152. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.test.ts +528 -0
  153. package/Tests/Server/Utils/TelemetryExporterEnvironment.test.ts +56 -0
  154. package/Tests/Server/Utils/VM/VMRunnerHostBridgeLatency.test.ts +74 -0
  155. package/Tests/Server/Utils/VM/VMRunnerPrivateNetworkWiring.test.ts +100 -7
  156. package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +1176 -6
  157. package/Tests/Types/CustomField/CustomFieldMappingCatalog.test.ts +220 -0
  158. package/Tests/Types/CustomField/CustomFieldValueMapping.test.ts +348 -0
  159. package/Tests/Types/JSONFunctions.test.ts +260 -0
  160. package/Tests/Types/Monitor/CephAlertTemplates.test.ts +422 -53
  161. package/Tests/Types/Monitor/DockerAlertTemplates.test.ts +495 -15
  162. package/Tests/Types/Monitor/DockerSwarmAlertTemplates.test.ts +191 -45
  163. package/Tests/Types/Monitor/HostAlertTemplates.test.ts +370 -42
  164. package/Tests/Types/Monitor/IotAlertTemplates.test.ts +375 -20
  165. package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +636 -42
  166. package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +189 -0
  167. package/Tests/Types/Monitor/KubernetesTemplateGroupByKeys.test.ts +95 -14
  168. package/Tests/Types/Monitor/PodmanAlertTemplates.test.ts +190 -21
  169. package/Tests/Types/Monitor/ProxmoxAlertTemplates.test.ts +352 -22
  170. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationAlertDebuggability.test.ts +363 -0
  171. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +93 -18
  172. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +259 -0
  173. package/Tests/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.test.ts +476 -0
  174. package/Tests/Types/Monitor/RumAlertTemplates.test.ts +136 -0
  175. package/Tests/Types/Monitor/SeriesContext/SeriesDebugHints.test.ts +661 -0
  176. package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +507 -0
  177. package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +270 -0
  178. package/Tests/Types/Monitor/TemplateGroupByKeys.test.ts +38 -10
  179. package/Tests/Types/Monitor/Utils/RecommendationCriteriaAssertions.ts +102 -0
  180. package/Tests/Types/NotificationSetting/RoutineEmailEvents.test.ts +47 -0
  181. package/Tests/Types/Rum/SessionReplayApiContracts.test.ts +608 -0
  182. package/Tests/Types/Rum/SessionReplayCustomEvents.test.ts +434 -0
  183. package/Tests/Types/WebsiteRequest.test.ts +285 -3
  184. package/Tests/UI/Components/Charts/ChartBucketIdentity.test.ts +16 -3
  185. package/Tests/UI/Components/Charts/ChartTrailingBucketGap.test.ts +691 -0
  186. package/Tests/UI/Components/ComponentsModal.test.tsx +12 -4
  187. package/Tests/UI/Components/ComponentsModalUsability.test.tsx +518 -0
  188. package/Tests/UI/Components/CustomFields/CustomFieldsDetailMapping.test.tsx +324 -0
  189. package/Tests/UI/Components/CustomFields/MapFromCustomFieldInput.test.tsx +176 -0
  190. package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +484 -0
  191. package/Tests/UI/Components/HeaderRightRail.test.tsx +157 -0
  192. package/Tests/UI/Components/IconDropdownItem.test.tsx +102 -0
  193. package/Tests/UI/Components/JSONTablePrototypePollution.test.tsx +117 -0
  194. package/Tests/UI/Components/KeyboardShortcutsModal.test.tsx +214 -0
  195. package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +561 -0
  196. package/Tests/UI/Components/MonitorGraphs/UptimeBarDayModal.test.tsx +302 -0
  197. package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +28 -12
  198. package/Tests/UI/Components/ShortcutDialogGuard.test.tsx +74 -0
  199. package/Tests/UI/Components/StatusPage/ResourceGroupSectionAutoExpand.test.tsx +248 -0
  200. package/Tests/UI/Components/TableCellWrapping.test.tsx +625 -0
  201. package/Tests/UI/Components/TableLoadingStates.test.tsx +205 -0
  202. package/Tests/UI/Components/Workflow/NodePlacement.test.ts +148 -0
  203. package/Tests/UI/Components/Workflow/Workflow.test.tsx +981 -0
  204. package/Tests/UI/ConfigBrowserTelemetry.test.ts +70 -0
  205. package/Tests/UI/Rum/ChunkLoader.test.ts +1036 -2
  206. package/Tests/UI/Rum/FidelityNotices.test.ts +187 -0
  207. package/Tests/UI/Rum/InactivityMap.test.ts +341 -0
  208. package/Tests/UI/Rum/PrivacySummaryCard.test.tsx +259 -0
  209. package/Tests/UI/Rum/RecordingHealthCard.test.tsx +855 -0
  210. package/Tests/UI/Rum/RecordingHealthStrip.test.tsx +594 -0
  211. package/Tests/UI/Rum/ReplayCard.test.tsx +451 -0
  212. package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +536 -0
  213. package/Tests/UI/Rum/ReplayEngine.test.ts +2503 -0
  214. package/Tests/UI/Rum/ReplayEngineTypes.test.ts +171 -0
  215. package/Tests/UI/Rum/ReplayHeader.test.tsx +711 -0
  216. package/Tests/UI/Rum/ReplayLink.test.tsx +119 -0
  217. package/Tests/UI/Rum/ReplayPinControl.test.tsx +408 -0
  218. package/Tests/UI/Rum/ReplayPlaybackIntent.test.ts +152 -0
  219. package/Tests/UI/Rum/ReplayRail.test.tsx +1296 -0
  220. package/Tests/UI/Rum/ReplayRailDetail.test.tsx +900 -0
  221. package/Tests/UI/Rum/ReplayScrubber.test.tsx +763 -147
  222. package/Tests/UI/Rum/ReplaySignalTypes.test.ts +189 -0
  223. package/Tests/UI/Rum/ReplaySignals.test.ts +1579 -0
  224. package/Tests/UI/Rum/ReplayStage.test.tsx +396 -473
  225. package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +918 -0
  226. package/Tests/UI/Rum/ReplayTimeline.test.tsx +696 -0
  227. package/Tests/UI/Rum/SessionReplayEmptyState.test.tsx +499 -0
  228. package/Tests/UI/Rum/SessionReplaySearchBar.test.tsx +346 -0
  229. package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +545 -0
  230. package/Tests/UI/Rum/SessionReplayTable.test.tsx +991 -0
  231. package/Tests/UI/Rum/TargetedCapturePanel.test.tsx +254 -0
  232. package/Tests/UI/Telemetry/BrowserExporterIsolation.test.ts +71 -0
  233. package/Tests/UI/Utils/GlobalKeyboardShortcut.test.ts +344 -0
  234. package/Tests/Utils/API.test.ts +308 -0
  235. package/Tests/Utils/HTTPResponseBodyReader.test.ts +323 -0
  236. package/Tests/Utils/NetworkDiscovery/DiscoveryScanStatus.test.ts +117 -0
  237. package/Tests/Utils/Rum/ChunkMath.test.ts +83 -0
  238. package/Tests/Utils/Rum/SessionReplayHealthDiagnosis.test.ts +993 -0
  239. package/Tests/Utils/Rum/SessionReplayStringMap.test.ts +245 -0
  240. package/Tests/Utils/StatusPage/ResourceSearch.test.ts +631 -0
  241. package/Tests/Utils/Telemetry/OriginAllowList.test.ts +633 -0
  242. package/Tests/Utils/Uptime/DayUptimeGraphUtil.test.ts +461 -0
  243. package/Tests/Utils/ValueFormatter.test.ts +148 -0
  244. package/Types/CustomField/CustomFieldMappingCatalog.ts +161 -0
  245. package/Types/CustomField/CustomFieldMappingSourceResource.ts +19 -0
  246. package/Types/CustomField/CustomFieldValueMapping.ts +288 -0
  247. package/Types/Icon/IconProp.ts +1 -0
  248. package/Types/JSONFunctions.ts +189 -43
  249. package/Types/Monitor/CephAlertTemplates.ts +157 -195
  250. package/Types/Monitor/DockerAlertTemplates.ts +338 -128
  251. package/Types/Monitor/DockerSwarmAlertTemplates.ts +95 -112
  252. package/Types/Monitor/HostAlertTemplates.ts +302 -130
  253. package/Types/Monitor/IotAlertTemplates.ts +112 -104
  254. package/Types/Monitor/KubernetesAlertTemplates.ts +415 -224
  255. package/Types/Monitor/KubernetesMetricCatalog.ts +23 -19
  256. package/Types/Monitor/PodmanAlertTemplates.ts +116 -163
  257. package/Types/Monitor/ProxmoxAlertTemplates.ts +217 -99
  258. package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +98 -6
  259. package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +44 -7
  260. package/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.ts +383 -0
  261. package/Types/Monitor/RumAlertTemplates.ts +46 -7
  262. package/Types/Monitor/SeriesContext/SeriesDebugHints.ts +596 -0
  263. package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +554 -0
  264. package/Types/Monitor/ServiceAlertTemplates.ts +98 -11
  265. package/Types/Monitor/UptimeHistoryLabels.ts +56 -0
  266. package/Types/NotificationSetting/RoutineEmailEvents.ts +30 -0
  267. package/Types/Rum/SessionReplay.ts +209 -0
  268. package/Types/Rum/SessionReplayApi.ts +722 -0
  269. package/Types/Rum/SessionReplayCaptureTrigger.ts +21 -12
  270. package/Types/Rum/SessionReplayConsentMode.ts +11 -7
  271. package/Types/Rum/SessionReplayCustomEvents.ts +549 -0
  272. package/Types/Rum/SessionReplayHealth.ts +238 -0
  273. package/Types/Telemetry/TelemetryIngestSurface.ts +95 -0
  274. package/Types/Telemetry/TelemetryIngestionKeyPolicy.ts +75 -0
  275. package/Types/Telemetry/TelemetryIngestionKeyType.ts +29 -0
  276. package/Types/WebsiteRequest.ts +85 -3
  277. package/UI/Components/Charts/Area/AreaChart.tsx +13 -2
  278. package/UI/Components/Charts/Bar/BarChart.tsx +6 -2
  279. package/UI/Components/Charts/Line/LineChart.tsx +13 -2
  280. package/UI/Components/Charts/Types/XAxis/XAxis.ts +29 -0
  281. package/UI/Components/Charts/Utils/DataPoint.ts +22 -3
  282. package/UI/Components/Charts/Utils/TimeAnnotation.ts +76 -9
  283. package/UI/Components/Charts/Utils/XAxis.ts +217 -0
  284. package/UI/Components/CustomFields/CustomFieldsDetail.tsx +143 -25
  285. package/UI/Components/CustomFields/MapFromCustomFieldInput.tsx +216 -0
  286. package/UI/Components/Graphs/DayUptimeGraph.tsx +173 -8
  287. package/UI/Components/Graphs/UptimeBarTooltip.tsx +22 -278
  288. package/UI/Components/Graphs/UptimeDaySummary.tsx +327 -0
  289. package/UI/Components/Header/Header.tsx +25 -9
  290. package/UI/Components/Header/IconDropdown/IconDropdownItem.tsx +10 -1
  291. package/UI/Components/Header/IconDropdown/IconDropdownMenu.tsx +6 -1
  292. package/UI/Components/Header/ProjectPicker/ProjectPicker.tsx +6 -1
  293. package/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.tsx +6 -1
  294. package/UI/Components/Icon/Icon.tsx +11 -0
  295. package/UI/Components/JSONTable/JSONTable.tsx +2 -2
  296. package/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.tsx +125 -0
  297. package/UI/Components/KeyboardShortcut/Screenshots/README.md +19 -0
  298. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-command-palette.png +0 -0
  299. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog-dark.png +0 -0
  300. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog.png +0 -0
  301. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-help-menu.png +0 -0
  302. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-narrow.png +0 -0
  303. package/UI/Components/ModelTable/Column.ts +15 -0
  304. package/UI/Components/Monitor/SeriesDebugCommandsViewer.tsx +64 -0
  305. package/UI/Components/Monitor/SeriesLabelsViewer.tsx +93 -0
  306. package/UI/Components/MonitorGraphs/Uptime.tsx +14 -2
  307. package/UI/Components/MonitorGraphs/UptimeBarDayModal.tsx +63 -10
  308. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +44 -0
  309. package/UI/Components/StatusPage/ResourceGroupSection.tsx +40 -0
  310. package/UI/Components/Table/CellClassName.ts +81 -0
  311. package/UI/Components/Table/TableRow.tsx +20 -14
  312. package/UI/Components/Table/TableSkeletonRows.tsx +9 -9
  313. package/UI/Components/Table/Types/Column.ts +36 -0
  314. package/UI/Components/Tooltip/Tooltip.tsx +11 -1
  315. package/UI/Components/Workflow/ComponentsModal.tsx +60 -39
  316. package/UI/Components/Workflow/NodePlacement.ts +57 -0
  317. package/UI/Components/Workflow/Workflow.tsx +47 -18
  318. package/UI/Config.ts +15 -33
  319. package/UI/Utils/GlobalKeyboardShortcut.ts +208 -0
  320. package/UI/Utils/Telemetry/BrowserTelemetryConfig.ts +28 -0
  321. package/UI/Utils/Telemetry/Telemetry.ts +10 -8
  322. package/Utils/API.ts +129 -3
  323. package/Utils/HTTPResponseBodyReader.ts +221 -0
  324. package/Utils/NetworkDiscovery/DiscoveryScanStatus.ts +77 -0
  325. package/Utils/Rum/ChunkMath.ts +106 -0
  326. package/Utils/Rum/SessionReplayHealth.ts +732 -0
  327. package/Utils/Rum/SessionReplayStringMap.ts +226 -0
  328. package/Utils/Schema/ModelSchema.ts +1 -0
  329. package/Utils/StatusPage/ResourceSearch.ts +290 -0
  330. package/Utils/Telemetry/OriginAllowList.ts +355 -0
  331. package/Utils/Uptime/DayUptimeGraphUtil.ts +205 -0
  332. package/Utils/ValueFormatter.ts +35 -1
  333. package/build/dist/Models/AnalyticsModels/RumSession.js +102 -19
  334. package/build/dist/Models/AnalyticsModels/RumSession.js.map +1 -1
  335. package/build/dist/Models/AnalyticsModels/RumSessionChunk.js +11 -9
  336. package/build/dist/Models/AnalyticsModels/RumSessionChunk.js.map +1 -1
  337. package/build/dist/Models/DatabaseModels/AlertCustomField.js +79 -3
  338. package/build/dist/Models/DatabaseModels/AlertCustomField.js.map +1 -1
  339. package/build/dist/Models/DatabaseModels/ApiKeyPermission.js +3 -27
  340. package/build/dist/Models/DatabaseModels/ApiKeyPermission.js.map +1 -1
  341. package/build/dist/Models/DatabaseModels/IncidentCustomField.js +79 -3
  342. package/build/dist/Models/DatabaseModels/IncidentCustomField.js.map +1 -1
  343. package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js +79 -3
  344. package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js.map +1 -1
  345. package/build/dist/Models/DatabaseModels/MonitorCustomField.js +79 -3
  346. package/build/dist/Models/DatabaseModels/MonitorCustomField.js.map +1 -1
  347. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js +79 -3
  348. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js.map +1 -1
  349. package/build/dist/Models/DatabaseModels/RumApplication.js +6 -6
  350. package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
  351. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js +79 -3
  352. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js.map +1 -1
  353. package/build/dist/Models/DatabaseModels/StatusPageCustomField.js +79 -3
  354. package/build/dist/Models/DatabaseModels/StatusPageCustomField.js.map +1 -1
  355. package/build/dist/Models/DatabaseModels/TeamCustomField.js +79 -3
  356. package/build/dist/Models/DatabaseModels/TeamCustomField.js.map +1 -1
  357. package/build/dist/Models/DatabaseModels/TeamMember.js +0 -9
  358. package/build/dist/Models/DatabaseModels/TeamMember.js.map +1 -1
  359. package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js +79 -3
  360. package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js.map +1 -1
  361. package/build/dist/Models/DatabaseModels/TeamPermission.js +3 -24
  362. package/build/dist/Models/DatabaseModels/TeamPermission.js.map +1 -1
  363. package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js +267 -0
  364. package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js.map +1 -1
  365. package/build/dist/Models/DatabaseModels/UserTelegram.js +0 -4
  366. package/build/dist/Models/DatabaseModels/UserTelegram.js.map +1 -1
  367. package/build/dist/Server/API/TelemetryAPI.js +769 -109
  368. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  369. package/build/dist/Server/API/UserNotificationSettingAPI.js +35 -0
  370. package/build/dist/Server/API/UserNotificationSettingAPI.js.map +1 -0
  371. package/build/dist/Server/API/UserTelegramAPI.js +28 -6
  372. package/build/dist/Server/API/UserTelegramAPI.js.map +1 -1
  373. package/build/dist/Server/EnvironmentConfig.js +29 -2
  374. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  375. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js +60 -0
  376. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js.map +1 -0
  377. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js +53 -0
  378. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js.map +1 -0
  379. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js +82 -0
  380. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js.map +1 -0
  381. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js +46 -0
  382. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js.map +1 -0
  383. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  384. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  385. package/build/dist/Server/Infrastructure/QueueWorker.js +19 -7
  386. package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
  387. package/build/dist/Server/Infrastructure/Semaphore.js +1 -0
  388. package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
  389. package/build/dist/Server/Middleware/TelemetryIngest.js +315 -8
  390. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  391. package/build/dist/Server/Services/AccessTokenService.js +1 -0
  392. package/build/dist/Server/Services/AccessTokenService.js.map +1 -1
  393. package/build/dist/Server/Services/AlertCustomFieldService.js +93 -0
  394. package/build/dist/Server/Services/AlertCustomFieldService.js.map +1 -1
  395. package/build/dist/Server/Services/AlertService.js +34 -0
  396. package/build/dist/Server/Services/AlertService.js.map +1 -1
  397. package/build/dist/Server/Services/ApiKeyPermissionService.js +331 -28
  398. package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
  399. package/build/dist/Server/Services/CustomFieldMappingService.js +614 -0
  400. package/build/dist/Server/Services/CustomFieldMappingService.js.map +1 -0
  401. package/build/dist/Server/Services/GlobalConfigService.js +133 -0
  402. package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
  403. package/build/dist/Server/Services/IncidentCustomFieldService.js +93 -0
  404. package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
  405. package/build/dist/Server/Services/IncidentService.js +32 -0
  406. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  407. package/build/dist/Server/Services/MetricService.js +163 -0
  408. package/build/dist/Server/Services/MetricService.js.map +1 -1
  409. package/build/dist/Server/Services/MonitorService.js +29 -0
  410. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  411. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +79 -27
  412. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
  413. package/build/dist/Server/Services/ProjectService.js +22 -0
  414. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  415. package/build/dist/Server/Services/RoutineEmailSettingsService.js +69 -0
  416. package/build/dist/Server/Services/RoutineEmailSettingsService.js.map +1 -0
  417. package/build/dist/Server/Services/RumSessionReplayViewService.js +86 -24
  418. package/build/dist/Server/Services/RumSessionReplayViewService.js.map +1 -1
  419. package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js +93 -0
  420. package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js.map +1 -1
  421. package/build/dist/Server/Services/ScheduledMaintenanceService.js +29 -0
  422. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  423. package/build/dist/Server/Services/TeamMemberService.js +62 -2
  424. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  425. package/build/dist/Server/Services/TeamPermissionService.js +166 -3
  426. package/build/dist/Server/Services/TeamPermissionService.js.map +1 -1
  427. package/build/dist/Server/Services/TelemetryIngestionKeyService.js +562 -18
  428. package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
  429. package/build/dist/Server/Services/UserNotificationSettingService.js +26 -6
  430. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  431. package/build/dist/Server/Services/UserTelegramService.js +257 -4
  432. package/build/dist/Server/Services/UserTelegramService.js.map +1 -1
  433. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  434. package/build/dist/Server/Utils/APIKey/AccessPermission.js +2 -2
  435. package/build/dist/Server/Utils/APIKey/AccessPermission.js.map +1 -1
  436. package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js +27 -0
  437. package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js.map +1 -0
  438. package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js +226 -0
  439. package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js.map +1 -0
  440. package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js +189 -0
  441. package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js.map +1 -0
  442. package/build/dist/Server/Utils/DataSource/EgressGuard.js +121 -7
  443. package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
  444. package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js +38 -5
  445. package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js.map +1 -1
  446. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +44 -2
  447. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -1
  448. package/build/dist/Server/Utils/FrontendEnvironment.js +33 -0
  449. package/build/dist/Server/Utils/FrontendEnvironment.js.map +1 -0
  450. package/build/dist/Server/Utils/LogRedaction.js +20 -0
  451. package/build/dist/Server/Utils/LogRedaction.js.map +1 -1
  452. package/build/dist/Server/Utils/Logger.js +10 -0
  453. package/build/dist/Server/Utils/Logger.js.map +1 -1
  454. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +287 -68
  455. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
  456. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +20 -4
  457. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
  458. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +29 -6
  459. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  460. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +88 -13
  461. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  462. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +22 -6
  463. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  464. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +22 -0
  465. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  466. package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js +237 -0
  467. package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js.map +1 -0
  468. package/build/dist/Server/Utils/SSRFProtection.js +136 -9
  469. package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
  470. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js +174 -89
  471. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js.map +1 -1
  472. package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js +223 -0
  473. package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js.map +1 -0
  474. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +945 -164
  475. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
  476. package/build/dist/Server/Utils/StartServer.js +3 -14
  477. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  478. package/build/dist/Server/Utils/TelegramVerificationToken.js +129 -0
  479. package/build/dist/Server/Utils/TelegramVerificationToken.js.map +1 -0
  480. package/build/dist/Server/Utils/Telemetry/PinServiceName.js +163 -0
  481. package/build/dist/Server/Utils/Telemetry/PinServiceName.js.map +1 -0
  482. package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js +28 -15
  483. package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js.map +1 -1
  484. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js +64 -0
  485. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js.map +1 -0
  486. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js +171 -0
  487. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js.map +1 -0
  488. package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
  489. package/build/dist/Server/Utils/VM/VMRunner.js +780 -69
  490. package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
  491. package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js +60 -0
  492. package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js.map +1 -0
  493. package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js +20 -0
  494. package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js.map +1 -0
  495. package/build/dist/Types/CustomField/CustomFieldValueMapping.js +141 -0
  496. package/build/dist/Types/CustomField/CustomFieldValueMapping.js.map +1 -0
  497. package/build/dist/Types/Icon/IconProp.js +1 -0
  498. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  499. package/build/dist/Types/JSONFunctions.js +118 -37
  500. package/build/dist/Types/JSONFunctions.js.map +1 -1
  501. package/build/dist/Types/Monitor/CephAlertTemplates.js +130 -171
  502. package/build/dist/Types/Monitor/CephAlertTemplates.js.map +1 -1
  503. package/build/dist/Types/Monitor/DockerAlertTemplates.js +286 -121
  504. package/build/dist/Types/Monitor/DockerAlertTemplates.js.map +1 -1
  505. package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js +84 -105
  506. package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js.map +1 -1
  507. package/build/dist/Types/Monitor/HostAlertTemplates.js +250 -122
  508. package/build/dist/Types/Monitor/HostAlertTemplates.js.map +1 -1
  509. package/build/dist/Types/Monitor/IotAlertTemplates.js +81 -81
  510. package/build/dist/Types/Monitor/IotAlertTemplates.js.map +1 -1
  511. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +375 -215
  512. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
  513. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js +19 -19
  514. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js.map +1 -1
  515. package/build/dist/Types/Monitor/PodmanAlertTemplates.js +104 -153
  516. package/build/dist/Types/Monitor/PodmanAlertTemplates.js.map +1 -1
  517. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +156 -91
  518. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
  519. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +67 -6
  520. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -1
  521. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +38 -7
  522. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
  523. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js +261 -0
  524. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js.map +1 -0
  525. package/build/dist/Types/Monitor/RumAlertTemplates.js +46 -7
  526. package/build/dist/Types/Monitor/RumAlertTemplates.js.map +1 -1
  527. package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js +422 -0
  528. package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js.map +1 -0
  529. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +441 -0
  530. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -0
  531. package/build/dist/Types/Monitor/ServiceAlertTemplates.js +79 -15
  532. package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -1
  533. package/build/dist/Types/Monitor/UptimeHistoryLabels.js +17 -0
  534. package/build/dist/Types/Monitor/UptimeHistoryLabels.js.map +1 -0
  535. package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js +29 -0
  536. package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js.map +1 -0
  537. package/build/dist/Types/Rum/SessionReplay.js +117 -0
  538. package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
  539. package/build/dist/Types/Rum/SessionReplayApi.js +181 -0
  540. package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -0
  541. package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js +21 -12
  542. package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js.map +1 -1
  543. package/build/dist/Types/Rum/SessionReplayConsentMode.js +11 -7
  544. package/build/dist/Types/Rum/SessionReplayConsentMode.js.map +1 -1
  545. package/build/dist/Types/Rum/SessionReplayCustomEvents.js +172 -0
  546. package/build/dist/Types/Rum/SessionReplayCustomEvents.js.map +1 -0
  547. package/build/dist/Types/Rum/SessionReplayHealth.js +37 -0
  548. package/build/dist/Types/Rum/SessionReplayHealth.js.map +1 -0
  549. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +85 -0
  550. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -0
  551. package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js +15 -0
  552. package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js.map +1 -0
  553. package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js +30 -0
  554. package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js.map +1 -0
  555. package/build/dist/Types/WebsiteRequest.js +55 -3
  556. package/build/dist/Types/WebsiteRequest.js.map +1 -1
  557. package/build/dist/UI/Components/Charts/Area/AreaChart.js +13 -2
  558. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  559. package/build/dist/UI/Components/Charts/Bar/BarChart.js +6 -2
  560. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  561. package/build/dist/UI/Components/Charts/Line/LineChart.js +13 -2
  562. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  563. package/build/dist/UI/Components/Charts/Types/XAxis/XAxis.js.map +1 -1
  564. package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -3
  565. package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
  566. package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js +40 -9
  567. package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js.map +1 -1
  568. package/build/dist/UI/Components/Charts/Utils/XAxis.js +186 -0
  569. package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
  570. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +80 -6
  571. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
  572. package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js +118 -0
  573. package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js.map +1 -0
  574. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +112 -7
  575. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
  576. package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js +5 -162
  577. package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js.map +1 -1
  578. package/build/dist/UI/Components/Graphs/UptimeDaySummary.js +181 -0
  579. package/build/dist/UI/Components/Graphs/UptimeDaySummary.js.map +1 -0
  580. package/build/dist/UI/Components/Header/Header.js +2 -3
  581. package/build/dist/UI/Components/Header/Header.js.map +1 -1
  582. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js +2 -1
  583. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js.map +1 -1
  584. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js +7 -1
  585. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js.map +1 -1
  586. package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js +7 -1
  587. package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js.map +1 -1
  588. package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js +7 -1
  589. package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js.map +1 -1
  590. package/build/dist/UI/Components/Icon/Icon.js +5 -0
  591. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  592. package/build/dist/UI/Components/JSONTable/JSONTable.js +2 -2
  593. package/build/dist/UI/Components/JSONTable/JSONTable.js.map +1 -1
  594. package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js +35 -0
  595. package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js.map +1 -0
  596. package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js +34 -0
  597. package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js.map +1 -0
  598. package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js +49 -0
  599. package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js.map +1 -0
  600. package/build/dist/UI/Components/MonitorGraphs/Uptime.js +1 -1
  601. package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
  602. package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js +32 -6
  603. package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js.map +1 -1
  604. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +38 -0
  605. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
  606. package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js +22 -1
  607. package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js.map +1 -1
  608. package/build/dist/UI/Components/Table/CellClassName.js +55 -0
  609. package/build/dist/UI/Components/Table/CellClassName.js.map +1 -0
  610. package/build/dist/UI/Components/Table/TableRow.js +16 -13
  611. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  612. package/build/dist/UI/Components/Table/TableSkeletonRows.js +9 -8
  613. package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -1
  614. package/build/dist/UI/Components/Tooltip/Tooltip.js +25 -1
  615. package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
  616. package/build/dist/UI/Components/Workflow/ComponentsModal.js +47 -30
  617. package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
  618. package/build/dist/UI/Components/Workflow/NodePlacement.js +37 -0
  619. package/build/dist/UI/Components/Workflow/NodePlacement.js.map +1 -0
  620. package/build/dist/UI/Components/Workflow/Workflow.js +35 -18
  621. package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
  622. package/build/dist/UI/Config.js +10 -20
  623. package/build/dist/UI/Config.js.map +1 -1
  624. package/build/dist/UI/Utils/GlobalKeyboardShortcut.js +138 -0
  625. package/build/dist/UI/Utils/GlobalKeyboardShortcut.js.map +1 -0
  626. package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js +14 -0
  627. package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js.map +1 -0
  628. package/build/dist/UI/Utils/Telemetry/Telemetry.js +7 -5
  629. package/build/dist/UI/Utils/Telemetry/Telemetry.js.map +1 -1
  630. package/build/dist/Utils/API.js +67 -5
  631. package/build/dist/Utils/API.js.map +1 -1
  632. package/build/dist/Utils/HTTPResponseBodyReader.js +157 -0
  633. package/build/dist/Utils/HTTPResponseBodyReader.js.map +1 -0
  634. package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js +69 -0
  635. package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js.map +1 -0
  636. package/build/dist/Utils/Rum/ChunkMath.js +76 -0
  637. package/build/dist/Utils/Rum/ChunkMath.js.map +1 -1
  638. package/build/dist/Utils/Rum/SessionReplayHealth.js +534 -0
  639. package/build/dist/Utils/Rum/SessionReplayHealth.js.map +1 -0
  640. package/build/dist/Utils/Rum/SessionReplayStringMap.js +165 -0
  641. package/build/dist/Utils/Rum/SessionReplayStringMap.js.map +1 -0
  642. package/build/dist/Utils/Schema/ModelSchema.js +1 -0
  643. package/build/dist/Utils/Schema/ModelSchema.js.map +1 -1
  644. package/build/dist/Utils/StatusPage/ResourceSearch.js +200 -0
  645. package/build/dist/Utils/StatusPage/ResourceSearch.js.map +1 -0
  646. package/build/dist/Utils/Telemetry/OriginAllowList.js +299 -0
  647. package/build/dist/Utils/Telemetry/OriginAllowList.js.map +1 -0
  648. package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js +147 -0
  649. package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js.map +1 -0
  650. package/build/dist/Utils/ValueFormatter.js +32 -1
  651. package/build/dist/Utils/ValueFormatter.js.map +1 -1
  652. package/package.json +1 -1
@@ -0,0 +1,732 @@
1
+ import {
2
+ RecordingHealthAction,
3
+ RecordingHealthActionTarget,
4
+ RecordingHealthDiagnosis,
5
+ RecordingHealthPolicy,
6
+ RecordingHealthStatus,
7
+ SessionReplayRefusalCount,
8
+ SessionReplayRefusalReason,
9
+ isSessionReplayRefusalReason,
10
+ } from "../../Types/Rum/SessionReplayHealth";
11
+ import SessionReplayCaptureTrigger from "../../Types/Rum/SessionReplayCaptureTrigger";
12
+ import SessionReplayConsentMode from "../../Types/Rum/SessionReplayConsentMode";
13
+ import {
14
+ readDtoBoolean,
15
+ readDtoNumber,
16
+ readDtoOptionalNumber,
17
+ readDtoString,
18
+ readDtoStringArray,
19
+ } from "../../Types/Rum/SessionReplayApi";
20
+
21
+ /*
22
+ * diagnoseRecordingHealth: one pure function that turns the ingest-status
23
+ * response into the single sentence the list page, the settings page and
24
+ * the setup guide all show.
25
+ *
26
+ * Pure and isomorphic (no Date.now(), no I/O, no DOM) so every state in
27
+ * the priority table is a unit test with a fixed clock. The copy rules it
28
+ * enforces are the product's, not decoration: name the cause, quantify
29
+ * it, offer ONE action, never render a counter that was not read as 0,
30
+ * and never say "disconnected" without saying why.
31
+ */
32
+
33
+ /*
34
+ * A refusal reason has to recur before it is reported as THE problem: a
35
+ * handful of origin-not-allowed refusals in a day is a developer's local
36
+ * build, hundreds is a misconfigured allowlist.
37
+ */
38
+ export const SESSION_REPLAY_REFUSAL_ALERT_THRESHOLD: number = 5;
39
+
40
+ /*
41
+ * A recorder that keeps fetching its policy but has not delivered a chunk
42
+ * for this long is stuck, not quiet. 6h spans a working day's lull
43
+ * without flagging a site that simply has evening traffic.
44
+ */
45
+ export const SESSION_REPLAY_STALE_CHUNK_MS: number = 6 * 60 * 60 * 1000;
46
+
47
+ /*
48
+ * "The recorder is loading on the site" means a policy fetch inside this
49
+ * window. Past it no recorder is running right now, which is why a silent
50
+ * application splits in two: a recorder that keeps fetching but delivers
51
+ * nothing is STUCK (state "stale"), while one that is not fetching either
52
+ * is simply not on any page being served - and the health copy says so
53
+ * rather than calling the second one healthy.
54
+ */
55
+ export const SESSION_REPLAY_RECORDER_ACTIVE_WINDOW_MS: number =
56
+ 24 * 60 * 60 * 1000;
57
+
58
+ const SECOND_MS: number = 1000;
59
+ const MINUTE_MS: number = 60 * SECOND_MS;
60
+ const HOUR_MS: number = 60 * MINUTE_MS;
61
+ const DAY_MS: number = 24 * HOUR_MS;
62
+
63
+ /*
64
+ * "12s ago", "5m ago", "7h ago", "3d ago". A future or sub-second time is
65
+ * "just now" (clock skew between the browser and the server is normal); a
66
+ * non-finite input is "unknown" so a bad timestamp can never render as
67
+ * "0s ago", which would claim liveness that was never observed.
68
+ */
69
+ export function formatRelativeAge(
70
+ fromUnixMs: number,
71
+ nowUnixMs: number,
72
+ ): string {
73
+ if (!Number.isFinite(fromUnixMs) || !Number.isFinite(nowUnixMs)) {
74
+ return "unknown";
75
+ }
76
+
77
+ const ageMs: number = nowUnixMs - fromUnixMs;
78
+
79
+ if (ageMs < SECOND_MS) {
80
+ return "just now";
81
+ }
82
+
83
+ if (ageMs < MINUTE_MS) {
84
+ return `${Math.floor(ageMs / SECOND_MS)}s ago`;
85
+ }
86
+
87
+ if (ageMs < HOUR_MS) {
88
+ return `${Math.floor(ageMs / MINUTE_MS)}m ago`;
89
+ }
90
+
91
+ if (ageMs < DAY_MS) {
92
+ return `${Math.floor(ageMs / HOUR_MS)}h ago`;
93
+ }
94
+
95
+ return `${Math.floor(ageMs / DAY_MS)}d ago`;
96
+ }
97
+
98
+ /* "1h", "6h", "3d" - a duration rather than an age, for "no chunk for 7h". */
99
+ export function formatDurationForCopy(durationMs: number): string {
100
+ if (!Number.isFinite(durationMs) || durationMs < 0) {
101
+ return "unknown";
102
+ }
103
+
104
+ if (durationMs < MINUTE_MS) {
105
+ return `${Math.floor(durationMs / SECOND_MS)}s`;
106
+ }
107
+
108
+ if (durationMs < HOUR_MS) {
109
+ return `${Math.floor(durationMs / MINUTE_MS)}m`;
110
+ }
111
+
112
+ if (durationMs < DAY_MS) {
113
+ return `${Math.floor(durationMs / HOUR_MS)}h`;
114
+ }
115
+
116
+ return `${Math.floor(durationMs / DAY_MS)}d`;
117
+ }
118
+
119
+ /*
120
+ * A count for copy: "1,234", or "unknown" for null. Formatted by hand
121
+ * rather than toLocaleString so the sentence is identical in every
122
+ * browser locale and in tests.
123
+ */
124
+ export function formatCountForCopy(count: number | null): string {
125
+ if (count === null || !Number.isFinite(count)) {
126
+ return "unknown";
127
+ }
128
+
129
+ const rounded: number = Math.max(0, Math.floor(count));
130
+ const digits: string = String(rounded);
131
+ let formatted: string = "";
132
+
133
+ for (let index: number = 0; index < digits.length; index++) {
134
+ const fromEnd: number = digits.length - index;
135
+
136
+ if (index > 0 && fromEnd % 3 === 0) {
137
+ formatted += ",";
138
+ }
139
+
140
+ formatted += digits[index];
141
+ }
142
+
143
+ return formatted;
144
+ }
145
+
146
+ /* "1 GB", "512 MB", "2.5 GB". Byte budgets are set in whole GB or MB. */
147
+ export function formatBytesForCopy(bytes: number): string {
148
+ if (!Number.isFinite(bytes) || bytes < 0) {
149
+ return "unknown";
150
+ }
151
+
152
+ const gb: number = bytes / (1024 * 1024 * 1024);
153
+
154
+ if (gb >= 1) {
155
+ return `${Number.isInteger(gb) ? gb : gb.toFixed(1)} GB`;
156
+ }
157
+
158
+ const mb: number = bytes / (1024 * 1024);
159
+
160
+ return `${Math.round(mb)} MB`;
161
+ }
162
+
163
+ /* ISO string -> unix ms, or null when absent or unparseable. */
164
+ export function parseHealthTimestamp(value: string | null): number | null {
165
+ if (typeof value !== "string" || value.length === 0) {
166
+ return null;
167
+ }
168
+
169
+ const parsed: number = Date.parse(value);
170
+
171
+ return Number.isFinite(parsed) ? parsed : null;
172
+ }
173
+
174
+ /*
175
+ * Normalise the /ingest-status JSON. The legacy top-level policy fields
176
+ * are folded into `policy`; every additive field defaults to null (not
177
+ * measured) rather than 0 or "", and unknown refusal reasons are dropped
178
+ * so the diagnosis only ever names a reason it has copy for. Returns null
179
+ * for a body that is not an object at all, which the caller reports as
180
+ * "unknown" health.
181
+ */
182
+ export function parseRecordingHealthStatus(
183
+ raw: unknown,
184
+ ): RecordingHealthStatus | null {
185
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
186
+ return null;
187
+ }
188
+
189
+ const row: Record<string, unknown> = raw as Record<string, unknown>;
190
+
191
+ const readNullableString: (key: string) => string | null = (
192
+ key: string,
193
+ ): string | null => {
194
+ const value: unknown = row[key];
195
+
196
+ return typeof value === "string" && value.length > 0 ? value : null;
197
+ };
198
+
199
+ const readNullableNumber: (key: string) => number | null = (
200
+ key: string,
201
+ ): number | null => {
202
+ const value: number | undefined = readDtoOptionalNumber(row, key);
203
+
204
+ return value === undefined ? null : value;
205
+ };
206
+
207
+ const rawRefusals: unknown = row["refusalsLast24h"];
208
+ let refusals: Array<SessionReplayRefusalCount> | null = null;
209
+
210
+ if (Array.isArray(rawRefusals)) {
211
+ refusals = [];
212
+
213
+ for (const entry of rawRefusals) {
214
+ if (entry === null || typeof entry !== "object") {
215
+ continue;
216
+ }
217
+
218
+ const entryRow: Record<string, unknown> = entry as Record<
219
+ string,
220
+ unknown
221
+ >;
222
+ const reason: unknown = entryRow["reason"];
223
+ const count: number | undefined = readDtoOptionalNumber(
224
+ entryRow,
225
+ "count",
226
+ );
227
+
228
+ if (isSessionReplayRefusalReason(reason) && count !== undefined) {
229
+ refusals.push({ reason: reason, count: count });
230
+ }
231
+ }
232
+ }
233
+
234
+ /*
235
+ * Drops keep whatever reason string the worker used: they are shown
236
+ * verbatim ("12 chunks dropped after acceptance: scrub-incomplete") and
237
+ * never drive a diagnosis state, so an unknown reason is still worth
238
+ * showing rather than filtering.
239
+ */
240
+ const rawDrops: unknown = row["dropsLast24h"];
241
+ let drops: Array<{ reason: string; count: number }> | null = null;
242
+
243
+ if (Array.isArray(rawDrops)) {
244
+ drops = [];
245
+
246
+ for (const entry of rawDrops) {
247
+ if (entry === null || typeof entry !== "object") {
248
+ continue;
249
+ }
250
+
251
+ const entryRow: Record<string, unknown> = entry as Record<
252
+ string,
253
+ unknown
254
+ >;
255
+ const reason: unknown = entryRow["reason"];
256
+ const count: number | undefined = readDtoOptionalNumber(
257
+ entryRow,
258
+ "count",
259
+ );
260
+
261
+ if (typeof reason === "string" && reason && count !== undefined) {
262
+ drops.push({ reason: reason, count: count });
263
+ }
264
+ }
265
+ }
266
+
267
+ /*
268
+ * Absent or not an array means the server never reported capabilities
269
+ * (unknown); an empty array means a recorder uploaded and announced
270
+ * none. Entries are kept verbatim rather than filtered against a known
271
+ * list: the vocabulary belongs to the recorder, and a capability this
272
+ * build has not heard of is exactly what somebody debugging a mixed
273
+ * rollout needs to see.
274
+ */
275
+ const rawCapabilities: unknown = row["recorderCapabilities"];
276
+ const recorderCapabilities: Array<string> | null = Array.isArray(
277
+ rawCapabilities,
278
+ )
279
+ ? readDtoStringArray(row, "recorderCapabilities")
280
+ : null;
281
+
282
+ const retentionInDays: number | undefined = readDtoOptionalNumber(
283
+ row,
284
+ "retentionInDays",
285
+ );
286
+
287
+ const policy: RecordingHealthPolicy = {
288
+ isProjectEnabled: readDtoBoolean(row, "isProjectAllowed"),
289
+ isApplicationEnabled: readDtoBoolean(row, "isApplicationEnabled"),
290
+ captureTrigger: readDtoString(row, "captureTrigger"),
291
+ samplePercentage: readDtoNumber(row, "samplePercentage"),
292
+ consentMode: readDtoString(row, "consentMode"),
293
+ maskingMode: readDtoString(row, "maskingMode"),
294
+ retentionInDays: retentionInDays === undefined ? null : retentionInDays,
295
+ };
296
+
297
+ return {
298
+ appIdentifier: readDtoString(row, "appIdentifier"),
299
+ allowedOrigins: readDtoStringArray(row, "allowedOrigins"),
300
+ policy: policy,
301
+ publishedRecorderVersion: readNullableString("publishedRecorderVersion"),
302
+ lastConfigFetchAt: readNullableString("lastConfigFetchAt"),
303
+ lastChunkReceivedAt: readNullableString("lastChunkReceivedAt"),
304
+ lastSessionStartedAt: readNullableString("lastSessionStartedAt"),
305
+ budgetExceededAt: readNullableString("budgetExceededAt"),
306
+ sessionsLast24h: readNullableNumber("sessionsLast24h"),
307
+ playableSessionsLast24h: readNullableNumber("playableSessionsLast24h"),
308
+ refusalsLast24h: refusals,
309
+ dropsLast24h: drops,
310
+ recorderCapabilities: recorderCapabilities,
311
+ projectBytesUsedToday: readNullableNumber("projectBytesUsedToday"),
312
+ dailyByteLimit: readDtoNumber(row, "dailyByteLimit"),
313
+ applicationBytesUsedThisMonth: readNullableNumber(
314
+ "applicationBytesUsedThisMonth",
315
+ ),
316
+ monthlyBudgetInGB: readNullableNumber("monthlyBudgetInGB"),
317
+ };
318
+ }
319
+
320
+ /* The most frequent refusal reason, or null when nothing was refused. */
321
+ export function getTopRefusal(
322
+ refusals: Array<SessionReplayRefusalCount> | null,
323
+ ): SessionReplayRefusalCount | null {
324
+ if (refusals === null || refusals.length === 0) {
325
+ return null;
326
+ }
327
+
328
+ let top: SessionReplayRefusalCount | null = null;
329
+
330
+ for (const refusal of refusals) {
331
+ if (top === null || refusal.count > top.count) {
332
+ top = refusal;
333
+ }
334
+ }
335
+
336
+ return top;
337
+ }
338
+
339
+ interface RefusalCopy {
340
+ /* Short, human: replaces the kebab-case reason in the title. */
341
+ label: string;
342
+ /* Says what to do about it, or why nothing in the product can. */
343
+ detail: string;
344
+ action?: RecordingHealthAction;
345
+ }
346
+
347
+ /*
348
+ * One entry per gate reason, so the title never shows the bare reason
349
+ * code. Deployment-level causes (ingest switched off, no artifact, Redis
350
+ * down) have no action: nothing on a settings page fixes them, and
351
+ * offering a link that cannot help is worse than saying so.
352
+ */
353
+ const REFUSAL_COPY: Record<SessionReplayRefusalReason, RefusalCopy> = {
354
+ "ingest-disabled": {
355
+ label: "ingest is switched off on this deployment",
356
+ detail:
357
+ "SESSION_REPLAY_INGEST_ENABLED is false on the server, so every chunk is refused. Only the operator of this deployment can change that.",
358
+ },
359
+ "instance-not-offering-replay": {
360
+ label: "this deployment publishes no recorder",
361
+ detail:
362
+ "No recorder artifact is built on this deployment, so chunks from a cached recorder are refused. Only the operator of this deployment can change that.",
363
+ },
364
+ "policy-unavailable": {
365
+ label: "the policy lookup failed",
366
+ detail:
367
+ "The server could not load this application's replay policy and refused rather than guess. This clears on its own once the database is reachable.",
368
+ },
369
+ "not-enabled": {
370
+ label: "replay was switched off when they arrived",
371
+ detail:
372
+ "Chunks arrived while the application or project had session replay switched off.",
373
+ action: { label: "Check the switch", target: "app-settings" },
374
+ },
375
+ "origin-not-allowed": {
376
+ label: "origin not allowed",
377
+ detail: "Requests came from an origin that is not in your allowed origins.",
378
+ action: { label: "Edit allowed origins", target: "allowed-origins" },
379
+ },
380
+ "session-chunk-cap": {
381
+ label: "sessions hit the chunk cap",
382
+ detail:
383
+ "Some sessions reached the per-session chunk cap and stopped uploading; the recording up to that point is kept.",
384
+ },
385
+ "not-sampled": {
386
+ label: "not sampled",
387
+ detail:
388
+ "The server's sampling draw refused chunks the recorder sent, which happens when the sample percentage was lowered while sessions were live.",
389
+ action: { label: "Review sampling", target: "app-settings" },
390
+ },
391
+ "rate-limited": {
392
+ label: "rate limited",
393
+ detail:
394
+ "Uploads exceeded the per-application rate limit and were refused. A burst of page loads clears on its own.",
395
+ },
396
+ "rate-counter-unavailable": {
397
+ label: "the rate counter was unreachable",
398
+ detail:
399
+ "The server could not reach its rate counter and refused rather than guess. This clears on its own once the counter store is reachable.",
400
+ },
401
+ "budget-exhausted": {
402
+ label: "the project's daily budget is spent",
403
+ detail: "This project used its daily byte budget for session replay.",
404
+ action: { label: "Review the budget", target: "budget" },
405
+ },
406
+ "budget-counter-unavailable": {
407
+ label: "the budget counter was unreachable",
408
+ detail:
409
+ "The server could not reach its budget counter and refused rather than guess. This clears on its own once the counter store is reachable.",
410
+ },
411
+ "app-monthly-budget-exhausted": {
412
+ label: "the monthly budget is spent",
413
+ detail: "This application used its monthly byte budget for session replay.",
414
+ action: { label: "Raise the budget", target: "budget" },
415
+ },
416
+ "consent-required": {
417
+ label: "consent was not granted",
418
+ detail:
419
+ "Uploads arrived before your page called OneUptimeReplay.grantConsent(). The recorder keeps recording in memory; nothing is stored until consent is granted.",
420
+ action: { label: "How consent works", target: "docs-consent" },
421
+ },
422
+ };
423
+
424
+ function action(
425
+ label: string,
426
+ target: RecordingHealthActionTarget,
427
+ ): RecordingHealthAction {
428
+ return { label: label, target: target };
429
+ }
430
+
431
+ /* "for acme-web" when the identifier is known, "" otherwise. */
432
+ function appSuffix(status: RecordingHealthStatus): string {
433
+ return status.appIdentifier ? ` for ${status.appIdentifier}` : "";
434
+ }
435
+
436
+ /*
437
+ * What keeps a loaded recorder from ever uploading, read off the policy
438
+ * alone. Ordered by how absolute the block is: sampling at 0% records
439
+ * nothing at all; consent gates every upload until the page grants it;
440
+ * the error/frustration trigger uploads nothing on a quiet day. When
441
+ * none applies, the generic explanation points at the request path.
442
+ */
443
+ function explainLoadedNeverUploaded(status: RecordingHealthStatus): {
444
+ detail: string;
445
+ action: RecordingHealthAction;
446
+ } {
447
+ const policy: RecordingHealthPolicy = status.policy;
448
+
449
+ if (policy.samplePercentage <= 0) {
450
+ return {
451
+ detail:
452
+ "Your sample percentage is 0%, so no session is recorded. Raise it to record the next visitor.",
453
+ action: action("Set sampling to 100%", "app-settings"),
454
+ };
455
+ }
456
+
457
+ if (policy.consentMode === SessionReplayConsentMode.RequireExplicit) {
458
+ return {
459
+ detail:
460
+ "Waiting for consent: the page has not called OneUptimeReplay.grantConsent(), and nothing uploads until it does.",
461
+ action: action("How consent works", "docs-consent"),
462
+ };
463
+ }
464
+
465
+ if (
466
+ policy.captureTrigger === SessionReplayCaptureTrigger.OnErrorOrFrustration
467
+ ) {
468
+ return {
469
+ detail:
470
+ "Uploads only start when an error or frustration signal fires; a quiet day looks like nothing. Switch the trigger to Always to record every session.",
471
+ action: action("Record every session", "app-settings"),
472
+ };
473
+ }
474
+
475
+ return {
476
+ detail:
477
+ "The policy fetch succeeds but no chunk has arrived. Uploads flush every 15s, so a request is being blocked on the way: check the browser console for a CSP or ad-blocker refusal of the ingest URL.",
478
+ action: action("Allow the recorder through your CSP", "docs-csp"),
479
+ };
480
+ }
481
+
482
+ function isDailyBudgetSpent(status: RecordingHealthStatus): boolean {
483
+ return (
484
+ status.projectBytesUsedToday !== null &&
485
+ status.dailyByteLimit > 0 &&
486
+ status.projectBytesUsedToday >= status.dailyByteLimit
487
+ );
488
+ }
489
+
490
+ /*
491
+ * budgetExceededAt is a stamp, not a live flag. When the month's usage is
492
+ * known and sits under the budget, the stamp is from a previous month and
493
+ * uploads are flowing again; only then is it ignored.
494
+ */
495
+ function isMonthlyBudgetPaused(status: RecordingHealthStatus): boolean {
496
+ if (status.budgetExceededAt === null) {
497
+ return false;
498
+ }
499
+
500
+ if (
501
+ status.applicationBytesUsedThisMonth !== null &&
502
+ status.monthlyBudgetInGB !== null &&
503
+ status.monthlyBudgetInGB > 0 &&
504
+ status.applicationBytesUsedThisMonth <
505
+ status.monthlyBudgetInGB * 1024 * 1024 * 1024
506
+ ) {
507
+ return false;
508
+ }
509
+
510
+ return true;
511
+ }
512
+
513
+ /* "143 sessions in 24h (120 playable)", with unknown counters said so. */
514
+ function describeSessions(status: RecordingHealthStatus): string {
515
+ const sessions: string = formatCountForCopy(status.sessionsLast24h);
516
+
517
+ if (status.sessionsLast24h === null) {
518
+ return "sessions in 24h: unknown";
519
+ }
520
+
521
+ const playable: string =
522
+ status.playableSessionsLast24h === null
523
+ ? ""
524
+ : ` (${formatCountForCopy(status.playableSessionsLast24h)} playable)`;
525
+
526
+ return `${sessions} session${status.sessionsLast24h === 1 ? "" : "s"} in 24h${playable}`;
527
+ }
528
+
529
+ /*
530
+ * The diagnosis. Strict priority, first match wins:
531
+ *
532
+ * disabled-project > disabled-app > budget-paused > refusing >
533
+ * never-loaded > loaded-never-uploaded > stale > healthy-quiet > healthy
534
+ *
535
+ * The last two split the same silence by whether a recorder is still
536
+ * running: past SESSION_REPLAY_STALE_CHUNK_MS without a chunk, a policy
537
+ * fetch inside SESSION_REPLAY_RECORDER_ACTIVE_WINDOW_MS means "stale"
538
+ * (loading but not uploading - something is blocking the request), and no
539
+ * policy fetch in that window means "healthy-quiet" (no recorder is on a
540
+ * page right now: quiet traffic, or a snippet that was removed).
541
+ *
542
+ * and "unknown" when there is no status to read. The order is the order
543
+ * in which a fix has to happen: a switched-off project makes every later
544
+ * signal moot, a spent budget explains any refusal, a refusal explains a
545
+ * missing chunk, and only a recorder that is loading and uploading can be
546
+ * stale or healthy.
547
+ */
548
+ export function diagnoseRecordingHealth(
549
+ status: RecordingHealthStatus | null,
550
+ nowUnixMs: number,
551
+ ): RecordingHealthDiagnosis {
552
+ if (status === null) {
553
+ return {
554
+ state: "unknown",
555
+ severity: "info",
556
+ title: "Recording health is unknown",
557
+ detail:
558
+ "The health status could not be loaded, so nothing here says whether recording works. Reload to try again.",
559
+ };
560
+ }
561
+
562
+ const policy: RecordingHealthPolicy = status.policy;
563
+
564
+ if (!policy.isProjectEnabled) {
565
+ return {
566
+ state: "disabled-project",
567
+ severity: "error",
568
+ title: "Session replay is switched off for this project",
569
+ detail:
570
+ "Nothing is recorded for any application while the project switch is off, whatever the application settings say.",
571
+ action: action("Turn it on", "project-settings"),
572
+ };
573
+ }
574
+
575
+ if (!policy.isApplicationEnabled) {
576
+ return {
577
+ state: "disabled-app",
578
+ severity: "error",
579
+ title: `Session replay is switched off${appSuffix(status)}`,
580
+ detail:
581
+ "Recorders on this application's pages fetch a disabled policy and record nothing.",
582
+ action: action("Turn it on", "app-settings"),
583
+ };
584
+ }
585
+
586
+ if (isMonthlyBudgetPaused(status)) {
587
+ const since: number | null = parseHealthTimestamp(status.budgetExceededAt);
588
+ const sinceCopy: string =
589
+ since === null ? "" : ` ${formatRelativeAge(since, nowUnixMs)}`;
590
+ const budgetCopy: string =
591
+ status.monthlyBudgetInGB === null
592
+ ? "its monthly budget"
593
+ : `its ${status.monthlyBudgetInGB} GB monthly budget`;
594
+
595
+ return {
596
+ state: "budget-paused",
597
+ severity: "error",
598
+ title: `Uploads paused${sinceCopy}`,
599
+ detail: `This application used ${budgetCopy}. Uploads resume next month, or as soon as the budget is raised.`,
600
+ action: action("Raise the budget", "budget"),
601
+ };
602
+ }
603
+
604
+ if (isDailyBudgetSpent(status)) {
605
+ return {
606
+ state: "budget-paused",
607
+ severity: "error",
608
+ title: "Uploads paused for today",
609
+ detail: `This project used its ${formatBytesForCopy(status.dailyByteLimit)} daily budget for session replay (${formatBytesForCopy(status.projectBytesUsedToday as number)} used). Uploads resume tomorrow.`,
610
+ action: action("Review the budget", "budget"),
611
+ };
612
+ }
613
+
614
+ const topRefusal: SessionReplayRefusalCount | null = getTopRefusal(
615
+ status.refusalsLast24h,
616
+ );
617
+
618
+ if (
619
+ topRefusal !== null &&
620
+ topRefusal.count >= SESSION_REPLAY_REFUSAL_ALERT_THRESHOLD
621
+ ) {
622
+ const copy: RefusalCopy = REFUSAL_COPY[topRefusal.reason];
623
+
624
+ return {
625
+ state: "refusing",
626
+ severity: "warning",
627
+ title: `${formatCountForCopy(topRefusal.count)} uploads refused in 24h: ${copy.label}`,
628
+ detail: copy.detail,
629
+ ...(copy.action && { action: copy.action }),
630
+ };
631
+ }
632
+
633
+ const lastConfigFetchUnixMs: number | null = parseHealthTimestamp(
634
+ status.lastConfigFetchAt,
635
+ );
636
+ const lastChunkUnixMs: number | null = parseHealthTimestamp(
637
+ status.lastChunkReceivedAt,
638
+ );
639
+
640
+ /*
641
+ * Both null, not just the config stamp: an older server never sends
642
+ * lastConfigFetchAt, and a recorder that has delivered a chunk has
643
+ * self-evidently loaded.
644
+ */
645
+ if (lastConfigFetchUnixMs === null && lastChunkUnixMs === null) {
646
+ return {
647
+ state: "never-loaded",
648
+ severity: "warning",
649
+ title: `The recorder has never loaded${appSuffix(status)}`,
650
+ detail:
651
+ "No page has fetched this application's replay policy and no chunk has arrived. Add the script tag to your site, then reload a page that uses it.",
652
+ action: action("Open the setup guide", "setup-guide"),
653
+ };
654
+ }
655
+
656
+ if (lastChunkUnixMs === null) {
657
+ const explanation: { detail: string; action: RecordingHealthAction } =
658
+ explainLoadedNeverUploaded(status);
659
+
660
+ return {
661
+ state: "loaded-never-uploaded",
662
+ severity: "warning",
663
+ title: `The recorder loaded ${formatRelativeAge(lastConfigFetchUnixMs as number, nowUnixMs)} but nothing has been uploaded`,
664
+ detail: explanation.detail,
665
+ action: explanation.action,
666
+ };
667
+ }
668
+
669
+ const chunkAgeMs: number = nowUnixMs - lastChunkUnixMs;
670
+ const isRecorderStillLoading: boolean =
671
+ lastConfigFetchUnixMs !== null &&
672
+ nowUnixMs - lastConfigFetchUnixMs <=
673
+ SESSION_REPLAY_RECORDER_ACTIVE_WINDOW_MS;
674
+
675
+ if (chunkAgeMs > SESSION_REPLAY_STALE_CHUNK_MS && isRecorderStillLoading) {
676
+ const explanation: { detail: string; action: RecordingHealthAction } =
677
+ explainLoadedNeverUploaded(status);
678
+
679
+ return {
680
+ state: "stale",
681
+ severity: "warning",
682
+ title: `No chunk for ${formatDurationForCopy(chunkAgeMs)} while the recorder keeps loading`,
683
+ detail: `The recorder last fetched its policy ${formatRelativeAge(lastConfigFetchUnixMs as number, nowUnixMs)}, but the last chunk arrived ${formatRelativeAge(lastChunkUnixMs, nowUnixMs)}. ${explanation.detail}`,
684
+ action: explanation.action,
685
+ };
686
+ }
687
+
688
+ /*
689
+ * What is left of the >6h case: no chunk AND no policy fetch inside the
690
+ * active window either (or no policy-fetch stamp at all on an older
691
+ * server). Nothing is switched off, over budget or being refused, so
692
+ * this is not an error - but "no recorder has loaded for a day" is also
693
+ * exactly what a removed script tag looks like, and the previous copy
694
+ * ("quiet traffic rather than a broken install") handed out that
695
+ * reassurance for the one silent case it cannot actually vouch for. The
696
+ * copy now names what it knows, quantifies both silences, and offers
697
+ * the install check as the single next step.
698
+ */
699
+ if (chunkAgeMs > SESSION_REPLAY_STALE_CHUNK_MS) {
700
+ const quietTitle: string = `No session recorded in the past ${formatDurationForCopy(chunkAgeMs)}`;
701
+ const chunkAgeCopy: string = formatRelativeAge(lastChunkUnixMs, nowUnixMs);
702
+
703
+ /*
704
+ * No action in this branch: an older server sends no lastConfigFetchAt
705
+ * at all, so nothing here says the install is wrong, and pointing at
706
+ * the setup guide would be a guess dressed as advice.
707
+ */
708
+ if (lastConfigFetchUnixMs === null) {
709
+ return {
710
+ state: "healthy-quiet",
711
+ severity: "info",
712
+ title: quietTitle,
713
+ detail: `The last chunk arrived ${chunkAgeCopy} and this server does not report policy fetches, so whether a recorder is still loading on your pages cannot be told from here. The policy is healthy (sampling ${policy.samplePercentage}%).`,
714
+ };
715
+ }
716
+
717
+ return {
718
+ state: "healthy-quiet",
719
+ severity: "info",
720
+ title: quietTitle,
721
+ detail: `The last chunk arrived ${chunkAgeCopy} and no page has fetched the policy for ${formatDurationForCopy(nowUnixMs - lastConfigFetchUnixMs)} either, so no recorder is running on this application right now - quiet traffic on a low-traffic or staging app, or a snippet that is no longer on the page. The policy is healthy (sampling ${policy.samplePercentage}%).`,
722
+ action: action("Check the install", "setup-guide"),
723
+ };
724
+ }
725
+
726
+ return {
727
+ state: "healthy",
728
+ severity: "ok",
729
+ title: "Recording healthy",
730
+ detail: `Last chunk ${formatRelativeAge(lastChunkUnixMs, nowUnixMs)} - ${describeSessions(status)} - sampling ${policy.samplePercentage}%.`,
731
+ };
732
+ }