@oneuptime/common 12.0.3 → 12.0.5

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 (516) hide show
  1. package/Models/DatabaseModels/AIRun.ts +38 -1
  2. package/Models/DatabaseModels/AlertFeed.ts +30 -0
  3. package/Models/DatabaseModels/CephCluster.ts +14 -0
  4. package/Models/DatabaseModels/CodeRepository.ts +14 -6
  5. package/Models/DatabaseModels/Dashboard.ts +28 -0
  6. package/Models/DatabaseModels/DockerHost.ts +14 -0
  7. package/Models/DatabaseModels/GlobalOidcProject.ts +18 -0
  8. package/Models/DatabaseModels/GlobalSsoProject.ts +18 -0
  9. package/Models/DatabaseModels/Incident.ts +2 -0
  10. package/Models/DatabaseModels/IncidentEpisode.ts +1 -0
  11. package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +1 -0
  12. package/Models/DatabaseModels/IncidentEpisodeStateTimeline.ts +1 -0
  13. package/Models/DatabaseModels/IncidentFeed.ts +30 -0
  14. package/Models/DatabaseModels/IncidentPublicNote.ts +1 -0
  15. package/Models/DatabaseModels/IncidentStateTimeline.ts +1 -0
  16. package/Models/DatabaseModels/IoTFleet.ts +14 -0
  17. package/Models/DatabaseModels/KubernetesCluster.ts +14 -0
  18. package/Models/DatabaseModels/LogSavedView.ts +33 -0
  19. package/Models/DatabaseModels/NetworkDevice.ts +14 -0
  20. package/Models/DatabaseModels/NetworkInterface.ts +18 -0
  21. package/Models/DatabaseModels/Project.ts +247 -11
  22. package/Models/DatabaseModels/ProxmoxCluster.ts +14 -0
  23. package/Models/DatabaseModels/ScheduledMaintenance.ts +1 -0
  24. package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +1 -0
  25. package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +1 -0
  26. package/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerUser.ts +4 -4
  27. package/Models/DatabaseModels/Service.ts +30 -0
  28. package/Models/DatabaseModels/StatusPage.ts +28 -0
  29. package/Models/DatabaseModels/StatusPageAnnouncement.ts +1 -0
  30. package/Models/DatabaseModels/StatusPagePrivateUser.ts +30 -0
  31. package/Models/DatabaseModels/User.ts +30 -0
  32. package/Server/API/AIAgentDataAPI.ts +75 -55
  33. package/Server/API/AIInvestigationAPI.ts +175 -17
  34. package/Server/API/DashboardAPI.ts +429 -22
  35. package/Server/API/GitHubAPI.ts +119 -283
  36. package/Server/API/StatusPageAPI.ts +38 -19
  37. package/Server/API/UserAPI.ts +263 -1
  38. package/Server/EnvironmentConfig.ts +23 -3
  39. package/Server/Infrastructure/ClickhouseConfig.ts +15 -1
  40. package/Server/Infrastructure/ClickhouseDatabase.ts +1 -1
  41. package/Server/Infrastructure/GlobalCache.ts +37 -0
  42. package/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.ts +21 -0
  43. package/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.ts +68 -0
  44. package/Server/Infrastructure/Postgres/SchemaMigrations/1786096660558-AddTimeRangeToLogSavedView.ts +27 -0
  45. package/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.ts +100 -0
  46. package/Server/Infrastructure/Postgres/SchemaMigrations/1786101798351-MigrationName.ts +89 -0
  47. package/Server/Infrastructure/Postgres/SchemaMigrations/1786105470826-MigrationName.ts +27 -0
  48. package/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.ts +214 -0
  49. package/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.ts +69 -0
  50. package/Server/Infrastructure/Postgres/SchemaMigrations/1786400000000-AddMasterPasswordSalt.ts +40 -0
  51. package/Server/Infrastructure/Postgres/SchemaMigrations/1786500000000-AddInvestigationCodeFixRecommendation.ts +26 -0
  52. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +20 -0
  53. package/Server/Services/AIRunService.ts +78 -10
  54. package/Server/Services/AIService.ts +94 -22
  55. package/Server/Services/AlertFeedService.ts +5 -0
  56. package/Server/Services/AnalyticsDatabaseService.ts +101 -1
  57. package/Server/Services/CodeRepositoryService.ts +105 -2
  58. package/Server/Services/DatabaseService.ts +227 -3
  59. package/Server/Services/IncidentFeedService.ts +5 -0
  60. package/Server/Services/LlmLogService.ts +46 -2
  61. package/Server/Services/OpenTelemetryIngestService.ts +230 -26
  62. package/Server/Services/UserService.ts +184 -0
  63. package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +6 -0
  64. package/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.ts +4 -0
  65. package/Server/Utils/AI/CodeFix/CodeFixReadiness.ts +8 -5
  66. package/Server/Utils/AI/CodeFix/FixRunBudget.ts +90 -16
  67. package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +2 -0
  68. package/Server/Utils/AI/Remediation/RemediationPlanRunner.ts +2 -0
  69. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +223 -22
  70. package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +25 -24
  71. package/Server/Utils/AI/SRE/ConfidenceSignal.ts +182 -71
  72. package/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.ts +252 -43
  73. package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +25 -24
  74. package/Server/Utils/AI/SRE/InstrumentationTaskTrigger.ts +47 -13
  75. package/Server/Utils/AI/SRE/InvestigationGrader.ts +9 -5
  76. package/Server/Utils/AI/SRE/InvestigationQueue.ts +141 -24
  77. package/Server/Utils/AI/SRE/InvestigationSubjectLock.ts +66 -0
  78. package/Server/Utils/AI/SRE/PostedRootCause.ts +94 -3
  79. package/Server/Utils/AI/SRE/README.md +1 -1
  80. package/Server/Utils/AI/SRE/SubjectCodeFixRun.ts +132 -10
  81. package/Server/Utils/AI/Toolbox/CodeTools.ts +45 -4
  82. package/Server/Utils/AnalyticsDatabase/ClusterConfig.ts +24 -0
  83. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +13 -0
  84. package/Server/Utils/CodeRepository/GitHub/GitHub.ts +157 -4
  85. package/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.ts +130 -0
  86. package/Server/Utils/Monitor/Criteria/APIRequestCriteria.ts +29 -0
  87. package/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.ts +56 -0
  88. package/Server/Utils/Monitor/MonitorMetricUtil.ts +46 -0
  89. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +1 -0
  90. package/Server/Utils/PasswordHash.ts +330 -0
  91. package/Tests/App/Dashboard/AIInvestigationHeaderStatus.test.tsx +251 -0
  92. package/Tests/App/Dashboard/EventStatusPanel.test.tsx +747 -0
  93. package/Tests/App/Dashboard/InvestigationFeedRefresh.test.tsx +480 -0
  94. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1184 -0
  95. package/Tests/App/Dashboard/InvestigationPanelStatus.test.tsx +500 -0
  96. package/Tests/App/Dashboard/OverviewCustomFields.test.tsx +333 -0
  97. package/Tests/App/Dashboard/PortMonitorCriteriaFilter.test.ts +93 -0
  98. package/Tests/App/Dashboard/UserCustomFields.test.tsx +392 -0
  99. package/Tests/App/StatusPage/PublicStatusPageAPIErrorHandling.test.ts +117 -0
  100. package/Tests/App/StatusPage/StatusPageModelAPIPolymorphism.test.ts +223 -0
  101. package/Tests/Models/DatabaseModels/PermissionCatalogueCoverage.test.ts +243 -0
  102. package/Tests/Server/API/AIAgentDataFixFromIncidentContext.test.ts +266 -0
  103. package/Tests/Server/API/AIAgentDataRepositoryToken.test.ts +381 -0
  104. package/Tests/Server/API/AIInvestigationAPI.test.ts +594 -0
  105. package/Tests/Server/API/AIInvestigationCreateFixTask.test.ts +80 -0
  106. package/Tests/Server/API/DashboardMasterPasswordAPI.test.ts +172 -1
  107. package/Tests/Server/API/DashboardPublicAttributeValuesAPI.test.ts +943 -0
  108. package/Tests/Server/API/DashboardPublicMetricsAggregateAPI.test.ts +1296 -0
  109. package/Tests/Server/API/DashboardPublicTemplatePayloads.test.ts +598 -0
  110. package/Tests/Server/API/GitHubAppInstallationBindingAPI.test.ts +539 -0
  111. package/Tests/Server/API/Helpers.ts +6 -1
  112. package/Tests/Server/API/StatusPageMasterPasswordAPI.test.ts +335 -0
  113. package/Tests/Server/API/UserProjectsAPI.test.ts +852 -0
  114. package/Tests/Server/Infrastructure/GlobalCache.test.ts +128 -0
  115. package/Tests/Server/Infrastructure/SemaphoreMutex.test.ts +215 -0
  116. package/Tests/Server/Services/AIRunCodeFixClaim.test.ts +59 -5
  117. package/Tests/Server/Services/AIRunHumanVerdict.test.ts +127 -58
  118. package/Tests/Server/Services/AIServiceDailyBudget.test.ts +396 -20
  119. package/Tests/Server/Services/AddMasterPasswordSaltMigration.test.ts +283 -0
  120. package/Tests/Server/Services/AddPerUserPasswordSaltMigration.test.ts +178 -0
  121. package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +582 -0
  122. package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +30 -1
  123. package/Tests/Server/Services/CodeRepositoryInstallationBinding.test.ts +305 -0
  124. package/Tests/Server/Services/CodeRepositoryResolutionBinding.test.ts +147 -0
  125. package/Tests/Server/Services/DatabaseServicePerUserPasswordSalt.test.ts +880 -0
  126. package/Tests/Server/Services/DatabaseServiceUpdateColumnsWithoutHooks.test.ts +54 -0
  127. package/Tests/Server/Services/FeedAIRunAssociation.test.ts +125 -0
  128. package/Tests/Server/Services/FixFromIncidentTaskTrigger.test.ts +418 -57
  129. package/Tests/Server/Services/InstrumentationTaskTrigger.test.ts +173 -14
  130. package/Tests/Server/Services/MasterPasswordScrypt.test.ts +567 -0
  131. package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +568 -0
  132. package/Tests/Server/Services/RestoreDroppedUniqueIndexesMigration.test.ts +386 -0
  133. package/Tests/Server/Services/RestoreServiceLowerNameIndexMigration.test.ts +240 -0
  134. package/Tests/Server/Services/SeparateIncidentAlertAiSettingsMigration.test.ts +194 -0
  135. package/Tests/Server/Services/UserServiceFirstMasterAdminElection.test.ts +885 -0
  136. package/Tests/Server/Services/WidenHashedStringColumnsForScryptMigration.test.ts +220 -0
  137. package/Tests/Server/Utils/AI/AIAlertGating.test.ts +37 -4
  138. package/Tests/Server/Utils/AI/AIConfidenceSignal.test.ts +330 -29
  139. package/Tests/Server/Utils/AI/AIIncidentGating.test.ts +25 -0
  140. package/Tests/Server/Utils/AI/AIInvestigationQueue.test.ts +293 -5
  141. package/Tests/Server/Utils/AI/CodeFixAgentCompletion.test.ts +59 -1
  142. package/Tests/Server/Utils/AI/CodeTools.test.ts +47 -1
  143. package/Tests/Server/Utils/AI/CodeWriteTools.test.ts +10 -0
  144. package/Tests/Server/Utils/AI/FixFromIncidentAutoTrigger.test.ts +342 -19
  145. package/Tests/Server/Utils/AI/FixRunBudget.test.ts +214 -30
  146. package/Tests/Server/Utils/AI/Insights/InvestigationQueueInsightSubject.test.ts +2 -0
  147. package/Tests/Server/Utils/AI/InvestigationGrader.test.ts +65 -17
  148. package/Tests/Server/Utils/AI/InvestigationQueueRemediationExecution.test.ts +3 -0
  149. package/Tests/Server/Utils/AI/InvestigationSettlement.test.ts +313 -20
  150. package/Tests/Server/Utils/AI/PostedRootCause.test.ts +254 -0
  151. package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +4 -0
  152. package/Tests/Server/Utils/AI/RemediationPlanRunner.test.ts +2 -0
  153. package/Tests/Server/Utils/AI/SubjectCodeFixRunDedupe.test.ts +44 -0
  154. package/Tests/Server/Utils/AnalyticsDatabase/ClusterAwareSchema.test.ts +30 -0
  155. package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +120 -0
  156. package/Tests/Server/Utils/CodeRepository/GitHubInstallationBinding.test.ts +292 -0
  157. package/Tests/Server/Utils/GitHubInstallationOwnershipVerification.test.ts +340 -0
  158. package/Tests/Server/Utils/GitHubWebhookAndTreeCacheIsolation.test.ts +250 -0
  159. package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaPortTimings.test.ts +212 -0
  160. package/Tests/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.test.ts +401 -0
  161. package/Tests/Server/Utils/Monitor/MonitorMetricUtilPortTimings.test.ts +243 -0
  162. package/Tests/Server/Utils/PasswordHash.test.ts +585 -0
  163. package/Tests/Types/Dashboard/DashboardTemplates.test.ts +111 -0
  164. package/Tests/Types/Database/ColumnLength.test.ts +7 -1
  165. package/Tests/Types/HashedStringPerUserSalt.test.ts +476 -0
  166. package/Tests/Types/Monitor/CephMetricCatalog.test.ts +104 -0
  167. package/Tests/Types/Monitor/CriteriaFilter.test.ts +4 -0
  168. package/Tests/Types/Monitor/DockerAlertTemplates.test.ts +293 -0
  169. package/Tests/Types/Monitor/DockerMetricCatalog.test.ts +109 -0
  170. package/Tests/Types/Monitor/DockerSwarmMetricCatalog.test.ts +118 -0
  171. package/Tests/Types/Monitor/HostAlertTemplates.test.ts +249 -0
  172. package/Tests/Types/Monitor/HostMetricCatalog.test.ts +104 -0
  173. package/Tests/Types/Monitor/IotAlertTemplates.test.ts +320 -0
  174. package/Tests/Types/Monitor/IotMetricCatalog.test.ts +104 -0
  175. package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +118 -0
  176. package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +42 -0
  177. package/Tests/Types/Monitor/MonitorStep.test.ts +38 -0
  178. package/Tests/Types/Monitor/MonitorStepDomainMonitor.test.ts +75 -0
  179. package/Tests/Types/Monitor/PodmanAlertTemplates.test.ts +271 -0
  180. package/Tests/Types/Monitor/PodmanMetricCatalog.test.ts +109 -0
  181. package/Tests/Types/Monitor/ProxmoxMetricCatalog.test.ts +107 -0
  182. package/Tests/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.test.ts +151 -0
  183. package/Tests/Types/Permission.test.ts +137 -0
  184. package/Tests/Types/Rum/SessionReplayMaskingMode.test.ts +101 -0
  185. package/Tests/UI/Components/AiInvestigationSettingsCard.test.tsx +5 -5
  186. package/Tests/UI/Components/CardModelDetailEdit.test.tsx +3 -5
  187. package/Tests/UI/Components/CustomFields/CustomFieldsDetail.test.tsx +696 -0
  188. package/Tests/UI/Components/ErrorBoundary.test.tsx +158 -0
  189. package/Tests/UI/Components/FeedItemSafeMode.test.tsx +74 -0
  190. package/Tests/UI/Components/MoreMenu.test.tsx +756 -0
  191. package/Tests/UI/Components/StatusPage/ResourceGroupSection.test.tsx +62 -0
  192. package/Tests/UI/Monitor/PortMonitorView.test.tsx +237 -0
  193. package/Tests/UI/Telemetry/TelemetrySnapshotWindowAlert.test.tsx +91 -0
  194. package/Tests/UI/Utils/DownloadFile.test.ts +103 -0
  195. package/Tests/UI/Utils/ErrorSupportBundle.test.ts +582 -0
  196. package/Tests/UI/Utils/Project.test.ts +31 -0
  197. package/Tests/UI/Utils/StatusPageModelAPIInjection.test.ts +245 -0
  198. package/Tests/UI/Utils/UseDashboardGridDnd.test.tsx +820 -0
  199. package/Tests/UI/Utils/UserProjectsModelAPI.test.ts +714 -0
  200. package/Tests/Utils/Dashboard/DashboardViewConfig.test.ts +329 -0
  201. package/Tests/Utils/Dashboard/GridLayout.test.ts +951 -0
  202. package/Tests/Utils/Monitor/MonitorMetricType.test.ts +117 -0
  203. package/Tests/Utils/RecordingRuleExpression.test.ts +327 -0
  204. package/Tests/Utils/StatusPage/GroupNestingLayout.test.ts +186 -0
  205. package/Tests/Utils/StatusPage/GroupTree.test.ts +456 -0
  206. package/Tests/Utils/StatusPage/OverviewGroupHierarchyVisibility.test.ts +588 -0
  207. package/Tests/Utils/TeamMembersByProject.test.ts +655 -0
  208. package/Tests/Utils/Telemetry/SavedViewTimeRange.test.ts +244 -0
  209. package/Tests/Utils/Telemetry/TelemetryQueryTimeRange.test.ts +825 -0
  210. package/Types/AI/AIRunCodeFixRecommendation.ts +17 -0
  211. package/Types/AI/CodeFixTaskContext.ts +63 -3
  212. package/Types/AI/CodeFixTaskType.ts +3 -3
  213. package/Types/Database/ColumnLength.ts +9 -1
  214. package/Types/Database/TableColumn.ts +11 -0
  215. package/Types/Database/UnsynchronizedIndex.ts +48 -0
  216. package/Types/HashedString.ts +140 -4
  217. package/Types/Monitor/CriteriaFilter.ts +4 -0
  218. package/Types/Monitor/DomainMonitor/DomainLookupMethod.ts +23 -0
  219. package/Types/Monitor/DomainMonitor/DomainMonitorResponse.ts +7 -0
  220. package/Types/Monitor/MonitorCriteriaInstance.ts +24 -7
  221. package/Types/Monitor/MonitorMetricType.ts +8 -0
  222. package/Types/Monitor/MonitorStep.ts +10 -1
  223. package/Types/Monitor/MonitorStepDomainMonitor.ts +21 -0
  224. package/Types/Monitor/PortMonitor/PortMonitorTimings.ts +10 -0
  225. package/Types/Permission.ts +23 -175
  226. package/Types/Probe/ProbeMonitorResponse.ts +6 -0
  227. package/UI/Components/BulkUpdate/BulkUpdateForm.tsx +2 -3
  228. package/UI/Components/CustomFields/CustomFieldsDetail.tsx +85 -11
  229. package/UI/Components/ErrorBoundary.tsx +138 -11
  230. package/UI/Components/Feed/FeedItem.tsx +9 -2
  231. package/UI/Components/ModelDetail/CardModelDetail.tsx +0 -12
  232. package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
  233. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +12 -2
  234. package/UI/Components/MoreMenu/MoreMenu.tsx +285 -97
  235. package/UI/Components/MoreMenu/MoreMenuItem.tsx +8 -5
  236. package/UI/Components/Navbar/NavBar.tsx +12 -2
  237. package/UI/Components/Navbar/NavBarMenuModal.tsx +19 -7
  238. package/UI/Utils/DownloadFile.ts +16 -8
  239. package/UI/Utils/ErrorSupportBundle.ts +805 -0
  240. package/UI/Utils/ModelAPI/ModelAPI.ts +19 -8
  241. package/UI/Utils/ModelAPI/UserProjectsModelAPI.ts +257 -0
  242. package/UI/Utils/Project.ts +4 -0
  243. package/UI/Utils/StatusPage.ts +8 -2
  244. package/UI/Utils/UseDashboardGridDnd.ts +917 -0
  245. package/Utils/Dashboard/DashboardViewConfig.ts +80 -36
  246. package/Utils/Dashboard/GridLayout.ts +523 -0
  247. package/Utils/Metrics/RecordingRuleExpression.ts +19 -17
  248. package/Utils/Monitor/MonitorMetricType.ts +44 -2
  249. package/Utils/StatusPage/GroupNestingLayout.ts +69 -0
  250. package/Utils/StatusPage/GroupTree.ts +157 -66
  251. package/Utils/StatusPage/ResourceUptime.ts +37 -2
  252. package/Utils/TeamMembersByProject.ts +237 -0
  253. package/Utils/Telemetry/SavedViewTimeRange.ts +114 -0
  254. package/Utils/Telemetry/TelemetryQueryTimeRange.ts +334 -0
  255. package/build/dist/Models/DatabaseModels/AIRun.js +39 -1
  256. package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
  257. package/build/dist/Models/DatabaseModels/AlertFeed.js +32 -0
  258. package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -1
  259. package/build/dist/Models/DatabaseModels/CephCluster.js +16 -1
  260. package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -1
  261. package/build/dist/Models/DatabaseModels/CodeRepository.js +14 -6
  262. package/build/dist/Models/DatabaseModels/CodeRepository.js.map +1 -1
  263. package/build/dist/Models/DatabaseModels/Dashboard.js +29 -0
  264. package/build/dist/Models/DatabaseModels/Dashboard.js.map +1 -1
  265. package/build/dist/Models/DatabaseModels/DockerHost.js +16 -1
  266. package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
  267. package/build/dist/Models/DatabaseModels/GlobalOidcProject.js +16 -1
  268. package/build/dist/Models/DatabaseModels/GlobalOidcProject.js.map +1 -1
  269. package/build/dist/Models/DatabaseModels/GlobalSsoProject.js +16 -1
  270. package/build/dist/Models/DatabaseModels/GlobalSsoProject.js.map +1 -1
  271. package/build/dist/Models/DatabaseModels/Incident.js +2 -0
  272. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  273. package/build/dist/Models/DatabaseModels/IncidentEpisode.js +1 -0
  274. package/build/dist/Models/DatabaseModels/IncidentEpisode.js.map +1 -1
  275. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +1 -0
  276. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -1
  277. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js +1 -0
  278. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js.map +1 -1
  279. package/build/dist/Models/DatabaseModels/IncidentFeed.js +32 -0
  280. package/build/dist/Models/DatabaseModels/IncidentFeed.js.map +1 -1
  281. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +1 -0
  282. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
  283. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +1 -0
  284. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
  285. package/build/dist/Models/DatabaseModels/IoTFleet.js +16 -1
  286. package/build/dist/Models/DatabaseModels/IoTFleet.js.map +1 -1
  287. package/build/dist/Models/DatabaseModels/KubernetesCluster.js +16 -1
  288. package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
  289. package/build/dist/Models/DatabaseModels/LogSavedView.js +33 -0
  290. package/build/dist/Models/DatabaseModels/LogSavedView.js.map +1 -1
  291. package/build/dist/Models/DatabaseModels/NetworkDevice.js +16 -1
  292. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  293. package/build/dist/Models/DatabaseModels/NetworkInterface.js +16 -1
  294. package/build/dist/Models/DatabaseModels/NetworkInterface.js.map +1 -1
  295. package/build/dist/Models/DatabaseModels/Project.js +257 -13
  296. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  297. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +16 -1
  298. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js.map +1 -1
  299. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +1 -0
  300. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  301. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +1 -0
  302. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
  303. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +1 -0
  304. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
  305. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerUser.js +4 -4
  306. package/build/dist/Models/DatabaseModels/Service.js +28 -1
  307. package/build/dist/Models/DatabaseModels/Service.js.map +1 -1
  308. package/build/dist/Models/DatabaseModels/StatusPage.js +29 -0
  309. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  310. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +1 -0
  311. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
  312. package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js +32 -0
  313. package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js.map +1 -1
  314. package/build/dist/Models/DatabaseModels/User.js +32 -0
  315. package/build/dist/Models/DatabaseModels/User.js.map +1 -1
  316. package/build/dist/Server/API/AIAgentDataAPI.js +49 -48
  317. package/build/dist/Server/API/AIAgentDataAPI.js.map +1 -1
  318. package/build/dist/Server/API/AIInvestigationAPI.js +111 -11
  319. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  320. package/build/dist/Server/API/DashboardAPI.js +312 -15
  321. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  322. package/build/dist/Server/API/GitHubAPI.js +94 -167
  323. package/build/dist/Server/API/GitHubAPI.js.map +1 -1
  324. package/build/dist/Server/API/StatusPageAPI.js +29 -11
  325. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  326. package/build/dist/Server/API/UserAPI.js +187 -2
  327. package/build/dist/Server/API/UserAPI.js.map +1 -1
  328. package/build/dist/Server/EnvironmentConfig.js +21 -3
  329. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  330. package/build/dist/Server/Infrastructure/ClickhouseConfig.js +12 -1
  331. package/build/dist/Server/Infrastructure/ClickhouseConfig.js.map +1 -1
  332. package/build/dist/Server/Infrastructure/ClickhouseDatabase.js +1 -1
  333. package/build/dist/Server/Infrastructure/ClickhouseDatabase.js.map +1 -1
  334. package/build/dist/Server/Infrastructure/GlobalCache.js +29 -0
  335. package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
  336. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.js +14 -0
  337. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.js.map +1 -0
  338. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.js +59 -0
  339. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.js.map +1 -0
  340. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786096660558-AddTimeRangeToLogSavedView.js +22 -0
  341. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786096660558-AddTimeRangeToLogSavedView.js.map +1 -0
  342. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js +93 -0
  343. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js.map +1 -0
  344. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786101798351-MigrationName.js +36 -0
  345. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786101798351-MigrationName.js.map +1 -0
  346. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786105470826-MigrationName.js +18 -0
  347. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786105470826-MigrationName.js.map +1 -0
  348. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.js +101 -0
  349. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.js.map +1 -0
  350. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.js +66 -0
  351. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.js.map +1 -0
  352. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786400000000-AddMasterPasswordSalt.js +19 -0
  353. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786400000000-AddMasterPasswordSalt.js.map +1 -0
  354. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786500000000-AddInvestigationCodeFixRecommendation.js +19 -0
  355. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786500000000-AddInvestigationCodeFixRecommendation.js.map +1 -0
  356. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +20 -0
  357. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  358. package/build/dist/Server/Services/AIRunService.js +58 -12
  359. package/build/dist/Server/Services/AIRunService.js.map +1 -1
  360. package/build/dist/Server/Services/AIService.js +74 -21
  361. package/build/dist/Server/Services/AIService.js.map +1 -1
  362. package/build/dist/Server/Services/AlertFeedService.js +3 -0
  363. package/build/dist/Server/Services/AlertFeedService.js.map +1 -1
  364. package/build/dist/Server/Services/AnalyticsDatabaseService.js +86 -2
  365. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  366. package/build/dist/Server/Services/CodeRepositoryService.js +90 -2
  367. package/build/dist/Server/Services/CodeRepositoryService.js.map +1 -1
  368. package/build/dist/Server/Services/DatabaseService.js +180 -3
  369. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  370. package/build/dist/Server/Services/IncidentFeedService.js +3 -0
  371. package/build/dist/Server/Services/IncidentFeedService.js.map +1 -1
  372. package/build/dist/Server/Services/LlmLogService.js +22 -1
  373. package/build/dist/Server/Services/LlmLogService.js.map +1 -1
  374. package/build/dist/Server/Services/OpenTelemetryIngestService.js +155 -25
  375. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  376. package/build/dist/Server/Services/UserService.js +165 -0
  377. package/build/dist/Server/Services/UserService.js.map +1 -1
  378. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +3 -0
  379. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
  380. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js +4 -0
  381. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js.map +1 -1
  382. package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js +8 -5
  383. package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js.map +1 -1
  384. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +63 -24
  385. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
  386. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +2 -0
  387. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
  388. package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js +2 -0
  389. package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js.map +1 -1
  390. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +156 -28
  391. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  392. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +21 -19
  393. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
  394. package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js +128 -49
  395. package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js.map +1 -1
  396. package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js +170 -31
  397. package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js.map +1 -1
  398. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +21 -19
  399. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
  400. package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js +33 -9
  401. package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js.map +1 -1
  402. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +9 -5
  403. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js.map +1 -1
  404. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js +121 -41
  405. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js.map +1 -1
  406. package/build/dist/Server/Utils/AI/SRE/InvestigationSubjectLock.js +46 -0
  407. package/build/dist/Server/Utils/AI/SRE/InvestigationSubjectLock.js.map +1 -0
  408. package/build/dist/Server/Utils/AI/SRE/PostedRootCause.js +61 -14
  409. package/build/dist/Server/Utils/AI/SRE/PostedRootCause.js.map +1 -1
  410. package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js +79 -1
  411. package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js.map +1 -1
  412. package/build/dist/Server/Utils/AI/Toolbox/CodeTools.js +31 -1
  413. package/build/dist/Server/Utils/AI/Toolbox/CodeTools.js.map +1 -1
  414. package/build/dist/Server/Utils/AnalyticsDatabase/ClusterConfig.js +21 -0
  415. package/build/dist/Server/Utils/AnalyticsDatabase/ClusterConfig.js.map +1 -1
  416. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +13 -0
  417. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  418. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +126 -4
  419. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
  420. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.js +136 -0
  421. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.js.map +1 -0
  422. package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js +20 -3
  423. package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js.map +1 -1
  424. package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js +43 -0
  425. package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js.map +1 -1
  426. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +33 -0
  427. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
  428. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +1 -0
  429. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  430. package/build/dist/Server/Utils/PasswordHash.js +258 -0
  431. package/build/dist/Server/Utils/PasswordHash.js.map +1 -0
  432. package/build/dist/Types/AI/AIRunCodeFixRecommendation.js +18 -0
  433. package/build/dist/Types/AI/AIRunCodeFixRecommendation.js.map +1 -0
  434. package/build/dist/Types/AI/CodeFixTaskContext.js +23 -3
  435. package/build/dist/Types/AI/CodeFixTaskContext.js.map +1 -1
  436. package/build/dist/Types/AI/CodeFixTaskType.js +3 -3
  437. package/build/dist/Types/Database/ColumnLength.js +9 -1
  438. package/build/dist/Types/Database/ColumnLength.js.map +1 -1
  439. package/build/dist/Types/Database/TableColumn.js.map +1 -1
  440. package/build/dist/Types/Database/UnsynchronizedIndex.js +46 -0
  441. package/build/dist/Types/Database/UnsynchronizedIndex.js.map +1 -0
  442. package/build/dist/Types/HashedString.js +96 -5
  443. package/build/dist/Types/HashedString.js.map +1 -1
  444. package/build/dist/Types/Monitor/CriteriaFilter.js +4 -0
  445. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  446. package/build/dist/Types/Monitor/DomainMonitor/DomainLookupMethod.js +24 -0
  447. package/build/dist/Types/Monitor/DomainMonitor/DomainLookupMethod.js.map +1 -0
  448. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +24 -7
  449. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  450. package/build/dist/Types/Monitor/MonitorMetricType.js +7 -0
  451. package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
  452. package/build/dist/Types/Monitor/MonitorStep.js +6 -1
  453. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  454. package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js +15 -0
  455. package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js.map +1 -1
  456. package/build/dist/Types/Monitor/PortMonitor/PortMonitorTimings.js +2 -0
  457. package/build/dist/Types/Monitor/PortMonitor/PortMonitorTimings.js.map +1 -0
  458. package/build/dist/Types/Permission.js +23 -155
  459. package/build/dist/Types/Permission.js.map +1 -1
  460. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js +2 -5
  461. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js.map +1 -1
  462. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +51 -10
  463. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
  464. package/build/dist/UI/Components/ErrorBoundary.js +67 -8
  465. package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
  466. package/build/dist/UI/Components/Feed/FeedItem.js +2 -2
  467. package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
  468. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +0 -12
  469. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  470. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
  471. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  472. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +12 -2
  473. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
  474. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +193 -65
  475. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  476. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +1 -1
  477. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
  478. package/build/dist/UI/Components/Navbar/NavBar.js +3 -1
  479. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  480. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +19 -7
  481. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  482. package/build/dist/UI/Utils/DownloadFile.js +15 -8
  483. package/build/dist/UI/Utils/DownloadFile.js.map +1 -1
  484. package/build/dist/UI/Utils/ErrorSupportBundle.js +476 -0
  485. package/build/dist/UI/Utils/ErrorSupportBundle.js.map +1 -0
  486. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +18 -8
  487. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  488. package/build/dist/UI/Utils/ModelAPI/UserProjectsModelAPI.js +156 -0
  489. package/build/dist/UI/Utils/ModelAPI/UserProjectsModelAPI.js.map +1 -0
  490. package/build/dist/UI/Utils/Project.js +3 -0
  491. package/build/dist/UI/Utils/Project.js.map +1 -1
  492. package/build/dist/UI/Utils/StatusPage.js +4 -4
  493. package/build/dist/UI/Utils/StatusPage.js.map +1 -1
  494. package/build/dist/UI/Utils/UseDashboardGridDnd.js +551 -0
  495. package/build/dist/UI/Utils/UseDashboardGridDnd.js.map +1 -0
  496. package/build/dist/Utils/Dashboard/DashboardViewConfig.js +42 -26
  497. package/build/dist/Utils/Dashboard/DashboardViewConfig.js.map +1 -1
  498. package/build/dist/Utils/Dashboard/GridLayout.js +338 -0
  499. package/build/dist/Utils/Dashboard/GridLayout.js.map +1 -0
  500. package/build/dist/Utils/Metrics/RecordingRuleExpression.js +19 -17
  501. package/build/dist/Utils/Metrics/RecordingRuleExpression.js.map +1 -1
  502. package/build/dist/Utils/Monitor/MonitorMetricType.js +38 -6
  503. package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
  504. package/build/dist/Utils/StatusPage/GroupNestingLayout.js +46 -0
  505. package/build/dist/Utils/StatusPage/GroupNestingLayout.js.map +1 -1
  506. package/build/dist/Utils/StatusPage/GroupTree.js +79 -34
  507. package/build/dist/Utils/StatusPage/GroupTree.js.map +1 -1
  508. package/build/dist/Utils/StatusPage/ResourceUptime.js +22 -1
  509. package/build/dist/Utils/StatusPage/ResourceUptime.js.map +1 -1
  510. package/build/dist/Utils/TeamMembersByProject.js +145 -0
  511. package/build/dist/Utils/TeamMembersByProject.js.map +1 -0
  512. package/build/dist/Utils/Telemetry/SavedViewTimeRange.js +79 -0
  513. package/build/dist/Utils/Telemetry/SavedViewTimeRange.js.map +1 -0
  514. package/build/dist/Utils/Telemetry/TelemetryQueryTimeRange.js +236 -0
  515. package/build/dist/Utils/Telemetry/TelemetryQueryTimeRange.js.map +1 -0
  516. package/package.json +1 -1
@@ -0,0 +1,825 @@
1
+ import ExceptionInstance from "../../../Models/AnalyticsModels/ExceptionInstance";
2
+ import Log from "../../../Models/AnalyticsModels/Log";
3
+ import Span from "../../../Models/AnalyticsModels/Span";
4
+ import InBetween from "../../../Types/BaseDatabase/InBetween";
5
+ import Includes from "../../../Types/BaseDatabase/Includes";
6
+ import Query from "../../../Types/BaseDatabase/Query";
7
+ import Search from "../../../Types/BaseDatabase/Search";
8
+ import { JSONObject } from "../../../Types/JSON";
9
+ import JSONFunctions from "../../../Types/JSONFunctions";
10
+ import LogSeverity from "../../../Types/Log/LogSeverity";
11
+ import MetricViewData from "../../../Types/Metrics/MetricViewData";
12
+ import { MonitorStepExceptionMonitorUtil } from "../../../Types/Monitor/MonitorStepExceptionMonitor";
13
+ import { MonitorStepLogMonitorUtil } from "../../../Types/Monitor/MonitorStepLogMonitor";
14
+ import { MonitorStepTraceMonitorUtil } from "../../../Types/Monitor/MonitorStepTraceMonitor";
15
+ import { TelemetryQuery } from "../../../Types/Telemetry/TelemetryQuery";
16
+ import TelemetryType from "../../../Types/Telemetry/TelemetryType";
17
+ import RangeStartAndEndDateTime, {
18
+ RangeStartAndEndDateTimeUtil,
19
+ } from "../../../Types/Time/RangeStartAndEndDateTime";
20
+ import TimeRange from "../../../Types/Time/TimeRange";
21
+ import TelemetryQueryTimeRange from "../../../Utils/Telemetry/TelemetryQueryTimeRange";
22
+ import { describe, expect, test } from "@jest/globals";
23
+
24
+ /*
25
+ * When a telemetry monitor opens an incident it stamps the window it just
26
+ * evaluated over onto the query it stores on the row. The incident page is
27
+ * supposed to render that exact window — "the logs at the moment this fired" —
28
+ * but the logs viewer was substituting a rolling "past 1 hour" over it, so an
29
+ * incident from last Tuesday showed the last hour of unrelated traffic under
30
+ * the heading "Logs for this incident".
31
+ *
32
+ * The root cause that let it go unnoticed for so long is in these tests'
33
+ * crosshairs: the window survives storage by VALUE but not by TYPE. It is
34
+ * persisted through JSON.stringify, which calls InBetween.toJSON() and then
35
+ * flattens each Date bound to an ISO string; InBetween.fromJSON hands those
36
+ * strings straight to the constructor. So a restored window is a real
37
+ * InBetween whose `startValue` is a `string`, even though the type says Date —
38
+ * and every consumer guarding on `instanceof Date` silently did nothing.
39
+ *
40
+ * These tests pin both halves: the coercion itself, and the full
41
+ * monitor -> store -> load round trip that produces the awkward shape.
42
+ */
43
+ describe("TelemetryQueryTimeRange", () => {
44
+ const START_ISO: string = "2026-08-04T10:00:00.000Z";
45
+ const END_ISO: string = "2026-08-04T10:01:00.000Z";
46
+ const START_DATE: Date = new Date(START_ISO);
47
+ const END_DATE: Date = new Date(END_ISO);
48
+
49
+ describe("toDateWindow", () => {
50
+ test("returns Date bounds unchanged when they are already Dates", () => {
51
+ const window: InBetween<Date> | null =
52
+ TelemetryQueryTimeRange.toDateWindow(
53
+ new InBetween<Date>(START_DATE, END_DATE),
54
+ );
55
+
56
+ expect(window).not.toBeNull();
57
+ expect(window!.startValue).toBeInstanceOf(Date);
58
+ expect(window!.startValue.getTime()).toBe(START_DATE.getTime());
59
+ expect(window!.endValue.getTime()).toBe(END_DATE.getTime());
60
+ });
61
+
62
+ test("hands back the same instance when nothing needs coercing", () => {
63
+ /*
64
+ * Identity is the signal callers use to decide whether anything changed;
65
+ * an equal-but-fresh object would churn React state on every load.
66
+ */
67
+ const already: InBetween<Date> = new InBetween<Date>(
68
+ START_DATE,
69
+ END_DATE,
70
+ );
71
+
72
+ expect(TelemetryQueryTimeRange.toDateWindow(already)).toBe(already);
73
+ });
74
+
75
+ test("coerces ISO string bounds back to Dates — the shape storage actually returns", () => {
76
+ /*
77
+ * This is the exact value InBetween.fromJSON produces for a stored
78
+ * window: the right class, the wrong bound type.
79
+ */
80
+ const restored: InBetween<Date> = new InBetween<Date>(
81
+ START_ISO as unknown as Date,
82
+ END_ISO as unknown as Date,
83
+ );
84
+
85
+ expect(restored.startValue).not.toBeInstanceOf(Date);
86
+
87
+ const window: InBetween<Date> | null =
88
+ TelemetryQueryTimeRange.toDateWindow(restored);
89
+
90
+ expect(window!.startValue).toBeInstanceOf(Date);
91
+ expect(window!.endValue).toBeInstanceOf(Date);
92
+ expect(window!.startValue.toISOString()).toBe(START_ISO);
93
+ expect(window!.endValue.toISOString()).toBe(END_ISO);
94
+ });
95
+
96
+ test("coerces epoch-number bounds", () => {
97
+ const window: InBetween<Date> | null =
98
+ TelemetryQueryTimeRange.toDateWindow(
99
+ new InBetween<Date>(
100
+ START_DATE.getTime() as unknown as Date,
101
+ END_DATE.getTime() as unknown as Date,
102
+ ),
103
+ );
104
+
105
+ expect(window!.startValue.getTime()).toBe(START_DATE.getTime());
106
+ expect(window!.endValue.getTime()).toBe(END_DATE.getTime());
107
+ });
108
+
109
+ test("accepts the plain tagged object, for callers that skipped deserialize", () => {
110
+ const window: InBetween<Date> | null =
111
+ TelemetryQueryTimeRange.toDateWindow({
112
+ _type: "InBetween",
113
+ startValue: START_ISO,
114
+ endValue: END_ISO,
115
+ });
116
+
117
+ expect(window!.startValue.getTime()).toBe(START_DATE.getTime());
118
+ expect(window!.endValue.getTime()).toBe(END_DATE.getTime());
119
+ });
120
+
121
+ test("returns null for absent, non-object and untagged values", () => {
122
+ expect(TelemetryQueryTimeRange.toDateWindow(null)).toBeNull();
123
+ expect(TelemetryQueryTimeRange.toDateWindow(undefined)).toBeNull();
124
+ expect(TelemetryQueryTimeRange.toDateWindow(START_ISO)).toBeNull();
125
+ expect(TelemetryQueryTimeRange.toDateWindow(12345)).toBeNull();
126
+ expect(
127
+ TelemetryQueryTimeRange.toDateWindow({
128
+ startValue: START_ISO,
129
+ endValue: END_ISO,
130
+ }),
131
+ ).toBeNull();
132
+ // A different operator must not be mistaken for a window.
133
+ expect(
134
+ TelemetryQueryTimeRange.toDateWindow(new Search("boom")),
135
+ ).toBeNull();
136
+ });
137
+
138
+ test("returns null when either bound is unparseable, rather than an Invalid Date", () => {
139
+ expect(
140
+ TelemetryQueryTimeRange.toDateWindow(
141
+ new InBetween<Date>("not-a-date" as unknown as Date, END_DATE),
142
+ ),
143
+ ).toBeNull();
144
+ expect(
145
+ TelemetryQueryTimeRange.toDateWindow(
146
+ new InBetween<Date>(START_DATE, "" as unknown as Date),
147
+ ),
148
+ ).toBeNull();
149
+ expect(
150
+ TelemetryQueryTimeRange.toDateWindow(
151
+ new InBetween<Date>(
152
+ START_DATE,
153
+ new Date("nonsense") as unknown as Date,
154
+ ),
155
+ ),
156
+ ).toBeNull();
157
+ expect(
158
+ TelemetryQueryTimeRange.toDateWindow({
159
+ _type: "InBetween",
160
+ startValue: null,
161
+ endValue: END_ISO,
162
+ }),
163
+ ).toBeNull();
164
+ });
165
+
166
+ test("preserves an inverted window instead of falling back", () => {
167
+ /*
168
+ * A start after the end is a server-side bug. Rendering it makes that
169
+ * visible; quietly reverting to a rolling default would reintroduce the
170
+ * exact failure this whole helper exists to stop — unrelated data shown
171
+ * under an incident's heading with nothing to indicate it.
172
+ */
173
+ const window: InBetween<Date> | null =
174
+ TelemetryQueryTimeRange.toDateWindow(
175
+ new InBetween<Date>(END_DATE, START_DATE),
176
+ );
177
+
178
+ expect(window!.startValue.getTime()).toBe(END_DATE.getTime());
179
+ expect(window!.endValue.getTime()).toBe(START_DATE.getTime());
180
+ });
181
+ });
182
+
183
+ describe("getWindowFieldName", () => {
184
+ test("maps each telemetry type to the field its monitor stamps", () => {
185
+ expect(
186
+ TelemetryQueryTimeRange.getWindowFieldName(TelemetryType.Log),
187
+ ).toBe("time");
188
+ expect(
189
+ TelemetryQueryTimeRange.getWindowFieldName(TelemetryType.Exception),
190
+ ).toBe("time");
191
+ expect(
192
+ TelemetryQueryTimeRange.getWindowFieldName(TelemetryType.Trace),
193
+ ).toBe("startTime");
194
+ });
195
+
196
+ test("returns null for types that carry no query window", () => {
197
+ expect(
198
+ TelemetryQueryTimeRange.getWindowFieldName(TelemetryType.Metric),
199
+ ).toBeNull();
200
+ expect(
201
+ TelemetryQueryTimeRange.getWindowFieldName(TelemetryType.Profile),
202
+ ).toBeNull();
203
+ expect(TelemetryQueryTimeRange.getWindowFieldName(undefined)).toBeNull();
204
+ });
205
+ });
206
+
207
+ describe("getQueryWindow", () => {
208
+ test("reads the field named by the telemetry type", () => {
209
+ const spanQuery: JSONObject = {
210
+ startTime: new InBetween<Date>(START_DATE, END_DATE),
211
+ };
212
+
213
+ expect(
214
+ TelemetryQueryTimeRange.getQueryWindow(
215
+ spanQuery,
216
+ TelemetryType.Trace,
217
+ )!.startValue.getTime(),
218
+ ).toBe(START_DATE.getTime());
219
+
220
+ // Spans keep theirs on startTime, so looking for `time` must find nothing.
221
+ expect(
222
+ TelemetryQueryTimeRange.getQueryWindow(spanQuery, TelemetryType.Log),
223
+ ).toBeNull();
224
+ });
225
+
226
+ test("tries both known fields when the type is unknown", () => {
227
+ expect(
228
+ TelemetryQueryTimeRange.getQueryWindow({
229
+ time: new InBetween<Date>(START_DATE, END_DATE),
230
+ }),
231
+ ).not.toBeNull();
232
+
233
+ expect(
234
+ TelemetryQueryTimeRange.getQueryWindow({
235
+ startTime: new InBetween<Date>(START_DATE, END_DATE),
236
+ }),
237
+ ).not.toBeNull();
238
+ });
239
+
240
+ test("returns null for an empty or absent query, and for a query with no window", () => {
241
+ expect(TelemetryQueryTimeRange.getQueryWindow(null)).toBeNull();
242
+ expect(TelemetryQueryTimeRange.getQueryWindow(undefined)).toBeNull();
243
+ expect(TelemetryQueryTimeRange.getQueryWindow({})).toBeNull();
244
+ expect(
245
+ TelemetryQueryTimeRange.getQueryWindow({
246
+ body: new Search("boom"),
247
+ severityText: new Includes([LogSeverity.Error]),
248
+ }),
249
+ ).toBeNull();
250
+ });
251
+ });
252
+
253
+ describe("round trip from a real monitor evaluation", () => {
254
+ /*
255
+ * The regression that matters. These walk the actual production path —
256
+ * build the query the way the worker does, persist it the way the worker
257
+ * does, restore it the way the page does — instead of hand-writing a
258
+ * fixture of what that is assumed to look like. A hand-written fixture is
259
+ * how the previous attempt at covering this drifted into asserting
260
+ * nothing.
261
+ */
262
+ type StoreAndRestoreFunction = (query: JSONObject) => JSONObject;
263
+
264
+ const storeAndRestore: StoreAndRestoreFunction = (
265
+ query: JSONObject,
266
+ ): JSONObject => {
267
+ // Exactly what the worker writes, then what the client reads back.
268
+ const stored: JSONObject = JSONFunctions.anyObjectToJSONObject(query);
269
+
270
+ return JSONFunctions.deserialize(stored);
271
+ };
272
+
273
+ test("log monitor: the stored window is flat ISO strings, and is recovered as Dates", () => {
274
+ const query: Query<Log> = MonitorStepLogMonitorUtil.toQuery({
275
+ ...MonitorStepLogMonitorUtil.getDefault(),
276
+ body: "boom",
277
+ lastXSecondsOfLogs: 60,
278
+ });
279
+
280
+ const evaluated: InBetween<Date> = (query as JSONObject)[
281
+ "time"
282
+ ] as InBetween<Date>;
283
+ expect(evaluated.startValue).toBeInstanceOf(Date);
284
+
285
+ const stored: JSONObject = JSONFunctions.anyObjectToJSONObject(query);
286
+
287
+ /*
288
+ * Pin the on-disk shape. It is FLAT — `{_type, startValue, endValue}`,
289
+ * with no `value` wrapper and no `{_type:"DateTime"}` tagging of the
290
+ * bounds. Any fixture that models it otherwise deserializes to an empty
291
+ * InBetween and silently asserts nothing.
292
+ */
293
+ expect(stored["time"]).toEqual({
294
+ _type: "InBetween",
295
+ startValue: evaluated.startValue.toISOString(),
296
+ endValue: evaluated.endValue.toISOString(),
297
+ });
298
+
299
+ const restored: JSONObject = JSONFunctions.deserialize(stored);
300
+ const restoredWindow: InBetween<Date> = restored[
301
+ "time"
302
+ ] as InBetween<Date>;
303
+
304
+ // The class survives; the bound type does not. This is the whole trap.
305
+ expect(restoredWindow).toBeInstanceOf(InBetween);
306
+ expect(typeof restoredWindow.startValue).toBe("string");
307
+
308
+ const recovered: InBetween<Date> | null =
309
+ TelemetryQueryTimeRange.getQueryWindow(restored, TelemetryType.Log);
310
+
311
+ expect(recovered!.startValue).toBeInstanceOf(Date);
312
+ expect(recovered!.startValue.getTime()).toBe(
313
+ evaluated.startValue.getTime(),
314
+ );
315
+ expect(recovered!.endValue.getTime()).toBe(evaluated.endValue.getTime());
316
+ });
317
+
318
+ test("log monitor: the window is exactly lastXSecondsOfLogs wide", () => {
319
+ const query: Query<Log> = MonitorStepLogMonitorUtil.toQuery({
320
+ ...MonitorStepLogMonitorUtil.getDefault(),
321
+ lastXSecondsOfLogs: 300,
322
+ });
323
+
324
+ const window: InBetween<Date> | null =
325
+ TelemetryQueryTimeRange.getQueryWindow(
326
+ storeAndRestore(query as JSONObject),
327
+ TelemetryType.Log,
328
+ );
329
+
330
+ expect(window!.endValue.getTime() - window!.startValue.getTime()).toBe(
331
+ 300 * 1000,
332
+ );
333
+ });
334
+
335
+ test("trace monitor: the window round-trips off startTime", () => {
336
+ const query: Query<Span> = MonitorStepTraceMonitorUtil.toQuery({
337
+ ...MonitorStepTraceMonitorUtil.getDefault(),
338
+ lastXSecondsOfSpans: 120,
339
+ });
340
+
341
+ const evaluated: InBetween<Date> = (query as JSONObject)[
342
+ "startTime"
343
+ ] as InBetween<Date>;
344
+
345
+ const window: InBetween<Date> | null =
346
+ TelemetryQueryTimeRange.getQueryWindow(
347
+ storeAndRestore(query as JSONObject),
348
+ TelemetryType.Trace,
349
+ );
350
+
351
+ expect(window!.startValue).toBeInstanceOf(Date);
352
+ expect(window!.startValue.getTime()).toBe(evaluated.startValue.getTime());
353
+ expect(window!.endValue.getTime() - window!.startValue.getTime()).toBe(
354
+ 120 * 1000,
355
+ );
356
+ });
357
+
358
+ test("exception monitor: the window round-trips off time", () => {
359
+ const query: Query<ExceptionInstance> =
360
+ MonitorStepExceptionMonitorUtil.toAnalyticsQuery({
361
+ ...MonitorStepExceptionMonitorUtil.getDefault(),
362
+ lastXSecondsOfExceptions: 90,
363
+ });
364
+
365
+ const window: InBetween<Date> | null =
366
+ TelemetryQueryTimeRange.getQueryWindow(
367
+ storeAndRestore(query as JSONObject),
368
+ TelemetryType.Exception,
369
+ );
370
+
371
+ expect(window!.startValue).toBeInstanceOf(Date);
372
+ expect(window!.endValue.getTime() - window!.startValue.getTime()).toBe(
373
+ 90 * 1000,
374
+ );
375
+ });
376
+
377
+ test("a monitor configured with no window stores none, and none is recovered", () => {
378
+ // Backwards compatibility: older incidents, and monitors with the window off.
379
+ const query: Query<Log> = MonitorStepLogMonitorUtil.toQuery({
380
+ ...MonitorStepLogMonitorUtil.getDefault(),
381
+ body: "boom",
382
+ lastXSecondsOfLogs: 0,
383
+ });
384
+
385
+ expect((query as JSONObject)["time"]).toBeUndefined();
386
+
387
+ expect(
388
+ TelemetryQueryTimeRange.getQueryWindow(
389
+ storeAndRestore(query as JSONObject),
390
+ TelemetryType.Log,
391
+ ),
392
+ ).toBeNull();
393
+ });
394
+ });
395
+
396
+ describe("getSnapshotWindow", () => {
397
+ test("finds the window for each telemetry type", () => {
398
+ const logWindow: InBetween<Date> | null =
399
+ TelemetryQueryTimeRange.getSnapshotWindow({
400
+ telemetryType: TelemetryType.Log,
401
+ telemetryQuery: {
402
+ time: new InBetween<Date>(
403
+ START_ISO as unknown as Date,
404
+ END_ISO as unknown as Date,
405
+ ),
406
+ } as Query<Log>,
407
+ metricViewData: null,
408
+ });
409
+ expect(logWindow!.startValue.getTime()).toBe(START_DATE.getTime());
410
+
411
+ const traceWindow: InBetween<Date> | null =
412
+ TelemetryQueryTimeRange.getSnapshotWindow({
413
+ telemetryType: TelemetryType.Trace,
414
+ telemetryQuery: {
415
+ startTime: new InBetween<Date>(
416
+ START_ISO as unknown as Date,
417
+ END_ISO as unknown as Date,
418
+ ),
419
+ } as Query<Span>,
420
+ metricViewData: null,
421
+ });
422
+ expect(traceWindow!.startValue.getTime()).toBe(START_DATE.getTime());
423
+
424
+ const exceptionWindow: InBetween<Date> | null =
425
+ TelemetryQueryTimeRange.getSnapshotWindow({
426
+ telemetryType: TelemetryType.Exception,
427
+ telemetryQuery: {
428
+ time: new InBetween<Date>(
429
+ START_ISO as unknown as Date,
430
+ END_ISO as unknown as Date,
431
+ ),
432
+ } as Query<ExceptionInstance>,
433
+ metricViewData: null,
434
+ });
435
+ expect(exceptionWindow!.startValue.getTime()).toBe(START_DATE.getTime());
436
+
437
+ const metricWindow: InBetween<Date> | null =
438
+ TelemetryQueryTimeRange.getSnapshotWindow({
439
+ telemetryType: TelemetryType.Metric,
440
+ telemetryQuery: null,
441
+ metricViewData: {
442
+ startAndEndDate: new InBetween<Date>(
443
+ START_ISO as unknown as Date,
444
+ END_ISO as unknown as Date,
445
+ ),
446
+ queryConfigs: [],
447
+ formulaConfigs: [],
448
+ } as MetricViewData,
449
+ });
450
+ expect(metricWindow!.startValue).toBeInstanceOf(Date);
451
+ expect(metricWindow!.startValue.getTime()).toBe(START_DATE.getTime());
452
+ });
453
+
454
+ test("returns null for no telemetry query and for one carrying no window", () => {
455
+ expect(TelemetryQueryTimeRange.getSnapshotWindow(null)).toBeNull();
456
+ expect(TelemetryQueryTimeRange.getSnapshotWindow(undefined)).toBeNull();
457
+ expect(
458
+ TelemetryQueryTimeRange.getSnapshotWindow({
459
+ telemetryType: TelemetryType.Log,
460
+ telemetryQuery: { body: new Search("boom") } as Query<Log>,
461
+ metricViewData: null,
462
+ }),
463
+ ).toBeNull();
464
+ expect(
465
+ TelemetryQueryTimeRange.getSnapshotWindow({
466
+ telemetryType: TelemetryType.Metric,
467
+ telemetryQuery: null,
468
+ metricViewData: {
469
+ startAndEndDate: null,
470
+ queryConfigs: [],
471
+ formulaConfigs: [],
472
+ } as MetricViewData,
473
+ }),
474
+ ).toBeNull();
475
+ });
476
+ });
477
+
478
+ describe("toRangeStartAndEndDateTime / getPinnedRangeForQuery", () => {
479
+ test("resolves to CUSTOM so the window cannot re-anchor to now", () => {
480
+ const range: RangeStartAndEndDateTime | null =
481
+ TelemetryQueryTimeRange.toRangeStartAndEndDateTime(
482
+ new InBetween<Date>(START_DATE, END_DATE),
483
+ );
484
+
485
+ expect(range!.range).toBe(TimeRange.CUSTOM);
486
+ expect(range!.startAndEndDate!.startValue.getTime()).toBe(
487
+ START_DATE.getTime(),
488
+ );
489
+ });
490
+
491
+ test("survives the picker's own resolution unchanged", () => {
492
+ /*
493
+ * The property the whole fix rests on: the logs viewer stores this value
494
+ * as picker state and every downstream request (list, histogram, facets)
495
+ * re-resolves it through RangeStartAndEndDateTimeUtil. A relative range
496
+ * would slide to "now" on each of those calls; CUSTOM must come back
497
+ * byte-identical every time.
498
+ */
499
+ const range: RangeStartAndEndDateTime | null =
500
+ TelemetryQueryTimeRange.toRangeStartAndEndDateTime(
501
+ new InBetween<Date>(START_DATE, END_DATE),
502
+ );
503
+
504
+ const resolved: InBetween<Date> =
505
+ RangeStartAndEndDateTimeUtil.getStartAndEndDate(range!);
506
+
507
+ expect(resolved.startValue.getTime()).toBe(START_DATE.getTime());
508
+ expect(resolved.endValue.getTime()).toBe(END_DATE.getTime());
509
+
510
+ // And again — resolving twice must not move it.
511
+ const resolvedAgain: InBetween<Date> =
512
+ RangeStartAndEndDateTimeUtil.getStartAndEndDate(range!);
513
+ expect(resolvedAgain.startValue.getTime()).toBe(START_DATE.getTime());
514
+ });
515
+
516
+ test("resolved bounds are real Dates, which downstream callers require", () => {
517
+ /*
518
+ * The facets request calls `.toISOString()` on these bounds directly. A
519
+ * string-valued bound would throw, so coercion is load-bearing, not
520
+ * cosmetic.
521
+ */
522
+ const range: RangeStartAndEndDateTime | null =
523
+ TelemetryQueryTimeRange.getPinnedRangeForQuery(
524
+ {
525
+ time: new InBetween<Date>(
526
+ START_ISO as unknown as Date,
527
+ END_ISO as unknown as Date,
528
+ ),
529
+ },
530
+ TelemetryType.Log,
531
+ );
532
+
533
+ const resolved: InBetween<Date> =
534
+ RangeStartAndEndDateTimeUtil.getStartAndEndDate(range!);
535
+
536
+ expect(() => {
537
+ return resolved.startValue.toISOString();
538
+ }).not.toThrow();
539
+ expect(resolved.startValue.toISOString()).toBe(START_ISO);
540
+ });
541
+
542
+ test("returns null when there is nothing to pin, so hosts keep their own default", () => {
543
+ expect(
544
+ TelemetryQueryTimeRange.toRangeStartAndEndDateTime(null),
545
+ ).toBeNull();
546
+ expect(
547
+ TelemetryQueryTimeRange.getPinnedRangeForQuery({}, TelemetryType.Log),
548
+ ).toBeNull();
549
+ expect(
550
+ TelemetryQueryTimeRange.getPinnedRangeForQuery(
551
+ undefined,
552
+ TelemetryType.Log,
553
+ ),
554
+ ).toBeNull();
555
+ });
556
+ });
557
+
558
+ describe("isSameRange", () => {
559
+ test("compares by value, not identity", () => {
560
+ const a: RangeStartAndEndDateTime = {
561
+ range: TimeRange.CUSTOM,
562
+ startAndEndDate: new InBetween<Date>(START_DATE, END_DATE),
563
+ };
564
+ const b: RangeStartAndEndDateTime = {
565
+ range: TimeRange.CUSTOM,
566
+ startAndEndDate: new InBetween<Date>(
567
+ new Date(START_ISO),
568
+ new Date(END_ISO),
569
+ ),
570
+ };
571
+
572
+ expect(a.startAndEndDate).not.toBe(b.startAndEndDate);
573
+ expect(TelemetryQueryTimeRange.isSameRange(a, b)).toBe(true);
574
+ });
575
+
576
+ test("treats string-valued and Date-valued bounds for the same instant as equal", () => {
577
+ // A host rebuilding its query from stored JSON must not look like a change.
578
+ expect(
579
+ TelemetryQueryTimeRange.isSameRange(
580
+ {
581
+ range: TimeRange.CUSTOM,
582
+ startAndEndDate: new InBetween<Date>(START_DATE, END_DATE),
583
+ },
584
+ {
585
+ range: TimeRange.CUSTOM,
586
+ startAndEndDate: new InBetween<Date>(
587
+ START_ISO as unknown as Date,
588
+ END_ISO as unknown as Date,
589
+ ),
590
+ },
591
+ ),
592
+ ).toBe(true);
593
+ });
594
+
595
+ test("detects a different window and a different range kind", () => {
596
+ const base: RangeStartAndEndDateTime = {
597
+ range: TimeRange.CUSTOM,
598
+ startAndEndDate: new InBetween<Date>(START_DATE, END_DATE),
599
+ };
600
+
601
+ expect(
602
+ TelemetryQueryTimeRange.isSameRange(base, {
603
+ range: TimeRange.CUSTOM,
604
+ startAndEndDate: new InBetween<Date>(
605
+ START_DATE,
606
+ new Date("2026-08-04T10:05:00.000Z"),
607
+ ),
608
+ }),
609
+ ).toBe(false);
610
+
611
+ expect(
612
+ TelemetryQueryTimeRange.isSameRange(base, {
613
+ range: TimeRange.PAST_ONE_HOUR,
614
+ }),
615
+ ).toBe(false);
616
+ });
617
+
618
+ test("handles absent values", () => {
619
+ expect(TelemetryQueryTimeRange.isSameRange(null, null)).toBe(true);
620
+ expect(TelemetryQueryTimeRange.isSameRange(undefined, null)).toBe(true);
621
+ expect(
622
+ TelemetryQueryTimeRange.isSameRange(null, {
623
+ range: TimeRange.PAST_ONE_HOUR,
624
+ }),
625
+ ).toBe(false);
626
+ expect(
627
+ TelemetryQueryTimeRange.isSameRange(
628
+ { range: TimeRange.PAST_ONE_HOUR },
629
+ { range: TimeRange.PAST_ONE_HOUR },
630
+ ),
631
+ ).toBe(true);
632
+ });
633
+ });
634
+
635
+ describe("hydrate", () => {
636
+ test("gives the metric view real Date bounds", () => {
637
+ /*
638
+ * The metric chart gates bucket-grid alignment and exemplar fetching on
639
+ * `instanceof Date`. Until this runs, both are switched off on every
640
+ * incident and alert page.
641
+ */
642
+ const telemetryQuery: TelemetryQuery = {
643
+ telemetryType: TelemetryType.Metric,
644
+ telemetryQuery: null,
645
+ metricViewData: {
646
+ startAndEndDate: new InBetween<Date>(
647
+ START_ISO as unknown as Date,
648
+ END_ISO as unknown as Date,
649
+ ),
650
+ queryConfigs: [],
651
+ formulaConfigs: [],
652
+ rangeToken: undefined,
653
+ } as MetricViewData,
654
+ };
655
+
656
+ const hydrated: TelemetryQuery | null =
657
+ TelemetryQueryTimeRange.hydrate(telemetryQuery);
658
+
659
+ expect(
660
+ hydrated!.metricViewData!.startAndEndDate!.startValue,
661
+ ).toBeInstanceOf(Date);
662
+ expect(
663
+ hydrated!.metricViewData!.startAndEndDate!.startValue.getTime(),
664
+ ).toBe(START_DATE.getTime());
665
+ expect(
666
+ hydrated!.metricViewData!.startAndEndDate!.endValue.getTime(),
667
+ ).toBe(END_DATE.getTime());
668
+ });
669
+
670
+ test("gives log, trace and exception queries real Date bounds on the right field", () => {
671
+ const log: TelemetryQuery | null = TelemetryQueryTimeRange.hydrate({
672
+ telemetryType: TelemetryType.Log,
673
+ telemetryQuery: {
674
+ time: new InBetween<Date>(
675
+ START_ISO as unknown as Date,
676
+ END_ISO as unknown as Date,
677
+ ),
678
+ } as Query<Log>,
679
+ metricViewData: null,
680
+ });
681
+ expect(
682
+ ((log!.telemetryQuery as JSONObject)["time"] as InBetween<Date>)
683
+ .startValue,
684
+ ).toBeInstanceOf(Date);
685
+
686
+ const trace: TelemetryQuery | null = TelemetryQueryTimeRange.hydrate({
687
+ telemetryType: TelemetryType.Trace,
688
+ telemetryQuery: {
689
+ startTime: new InBetween<Date>(
690
+ START_ISO as unknown as Date,
691
+ END_ISO as unknown as Date,
692
+ ),
693
+ } as Query<Span>,
694
+ metricViewData: null,
695
+ });
696
+ expect(
697
+ ((trace!.telemetryQuery as JSONObject)["startTime"] as InBetween<Date>)
698
+ .startValue,
699
+ ).toBeInstanceOf(Date);
700
+
701
+ const exception: TelemetryQuery | null = TelemetryQueryTimeRange.hydrate({
702
+ telemetryType: TelemetryType.Exception,
703
+ telemetryQuery: {
704
+ time: new InBetween<Date>(
705
+ START_ISO as unknown as Date,
706
+ END_ISO as unknown as Date,
707
+ ),
708
+ } as Query<ExceptionInstance>,
709
+ metricViewData: null,
710
+ });
711
+ expect(
712
+ ((exception!.telemetryQuery as JSONObject)["time"] as InBetween<Date>)
713
+ .startValue,
714
+ ).toBeInstanceOf(Date);
715
+ });
716
+
717
+ test("leaves every other filter on the query untouched", () => {
718
+ const body: Search<string> = new Search("boom");
719
+ const severity: Includes = new Includes([LogSeverity.Error]);
720
+
721
+ const hydrated: TelemetryQuery | null = TelemetryQueryTimeRange.hydrate({
722
+ telemetryType: TelemetryType.Log,
723
+ telemetryQuery: {
724
+ body: body,
725
+ severityText: severity,
726
+ time: new InBetween<Date>(
727
+ START_ISO as unknown as Date,
728
+ END_ISO as unknown as Date,
729
+ ),
730
+ } as unknown as Query<Log>,
731
+ metricViewData: null,
732
+ });
733
+
734
+ const query: JSONObject = hydrated!.telemetryQuery as JSONObject;
735
+ expect(query["body"]).toBe(body);
736
+ expect(query["severityText"]).toBe(severity);
737
+ });
738
+
739
+ test("leaves the rest of the metric view untouched, including rangeToken", () => {
740
+ const queryConfigs: MetricViewData["queryConfigs"] = [];
741
+ const metricViewData: MetricViewData = {
742
+ startAndEndDate: new InBetween<Date>(
743
+ START_ISO as unknown as Date,
744
+ END_ISO as unknown as Date,
745
+ ),
746
+ queryConfigs: queryConfigs,
747
+ formulaConfigs: [],
748
+ rangeToken: TimeRange.PAST_ONE_HOUR,
749
+ };
750
+
751
+ const hydrated: TelemetryQuery | null = TelemetryQueryTimeRange.hydrate({
752
+ telemetryType: TelemetryType.Metric,
753
+ telemetryQuery: null,
754
+ metricViewData: metricViewData,
755
+ });
756
+
757
+ expect(hydrated!.metricViewData!.queryConfigs).toBe(queryConfigs);
758
+ expect(hydrated!.metricViewData!.rangeToken).toBe(
759
+ TimeRange.PAST_ONE_HOUR,
760
+ );
761
+ });
762
+
763
+ test("returns the same reference when there is nothing to fix", () => {
764
+ /*
765
+ * React hosts call this on every load; handing back a fresh-but-equal
766
+ * object would churn state and refetch.
767
+ */
768
+ const alreadyDates: TelemetryQuery = {
769
+ telemetryType: TelemetryType.Log,
770
+ telemetryQuery: {
771
+ time: new InBetween<Date>(START_DATE, END_DATE),
772
+ } as Query<Log>,
773
+ metricViewData: null,
774
+ };
775
+ expect(TelemetryQueryTimeRange.hydrate(alreadyDates)).toBe(alreadyDates);
776
+
777
+ const noWindow: TelemetryQuery = {
778
+ telemetryType: TelemetryType.Log,
779
+ telemetryQuery: { body: new Search("boom") } as Query<Log>,
780
+ metricViewData: null,
781
+ };
782
+ expect(TelemetryQueryTimeRange.hydrate(noWindow)).toBe(noWindow);
783
+ });
784
+
785
+ test("returns null for no telemetry query", () => {
786
+ expect(TelemetryQueryTimeRange.hydrate(null)).toBeNull();
787
+ expect(TelemetryQueryTimeRange.hydrate(undefined)).toBeNull();
788
+ });
789
+
790
+ test("hydrating a stored blob end to end yields a chart-ready window", () => {
791
+ // The full production path for a metric incident, in one assertion chain.
792
+ const evaluated: InBetween<Date> = new InBetween<Date>(
793
+ START_DATE,
794
+ END_DATE,
795
+ );
796
+
797
+ const restored: TelemetryQuery = JSONFunctions.deserialize(
798
+ JSONFunctions.anyObjectToJSONObject({
799
+ telemetryType: TelemetryType.Metric,
800
+ telemetryQuery: null,
801
+ metricViewData: {
802
+ startAndEndDate: evaluated,
803
+ queryConfigs: [],
804
+ formulaConfigs: [],
805
+ },
806
+ }),
807
+ ) as unknown as TelemetryQuery;
808
+
809
+ // Before hydration the guard downstream would reject this.
810
+ expect(
811
+ restored.metricViewData!.startAndEndDate!.startValue,
812
+ ).not.toBeInstanceOf(Date);
813
+
814
+ const hydrated: TelemetryQuery | null =
815
+ TelemetryQueryTimeRange.hydrate(restored);
816
+
817
+ expect(
818
+ hydrated!.metricViewData!.startAndEndDate!.startValue,
819
+ ).toBeInstanceOf(Date);
820
+ expect(
821
+ hydrated!.metricViewData!.startAndEndDate!.startValue.getTime(),
822
+ ).toBe(START_DATE.getTime());
823
+ });
824
+ });
825
+ });