@oneuptime/common 13.0.5 → 13.0.6

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 (1091) hide show
  1. package/Models/AnalyticsModels/AuditLog.ts +81 -1
  2. package/Models/AnalyticsModels/SecurityEvent.ts +4 -4
  3. package/Models/DatabaseModels/Alert.ts +62 -0
  4. package/Models/DatabaseModels/GlobalConfig.ts +1 -1
  5. package/Models/DatabaseModels/Incident.ts +66 -0
  6. package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +74 -0
  7. package/Models/DatabaseModels/IncidentPublicNote.ts +74 -0
  8. package/Models/DatabaseModels/Index.ts +6 -4
  9. package/Models/DatabaseModels/NetworkDevice.ts +67 -0
  10. package/Models/DatabaseModels/NetworkDeviceDiagnostic.ts +746 -0
  11. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +151 -0
  12. package/Models/DatabaseModels/NetworkSiteAssignmentRule.ts +1 -1
  13. package/Models/DatabaseModels/Project.ts +41 -0
  14. package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +74 -0
  15. package/Models/DatabaseModels/SecurityEventConnection.ts +11 -11
  16. package/Models/DatabaseModels/ServiceLevelObjective.ts +185 -8
  17. package/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.ts +746 -43
  18. package/Models/DatabaseModels/ServiceLevelObjectiveFeed.ts +575 -0
  19. package/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.ts +582 -0
  20. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.ts +16 -0
  21. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.ts +16 -0
  22. package/Models/DatabaseModels/StatusPageAnnouncement.ts +75 -0
  23. package/Models/DatabaseModels/ThreatIntelFeed.ts +1 -1
  24. package/Server/API/BaseAPI.ts +17 -0
  25. package/Server/API/BillingInvoiceAPI.ts +343 -30
  26. package/Server/API/BillingPaymentMethodAPI.ts +126 -5
  27. package/Server/API/DashboardAPI.ts +96 -2
  28. package/Server/API/SecurityEventConnectionAPI.ts +141 -11
  29. package/Server/API/StatusPageAPI.ts +308 -199
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1792800000000-AddNetworkDeviceDiagnostic.ts +83 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/1792900000000-AddNetworkDeviceDnsNameAndShortDeviceNames.ts +36 -0
  32. package/Server/Infrastructure/Postgres/SchemaMigrations/1793000000000-AddNetbiosLookupToNetworkDeviceDiscoveryScan.ts +29 -0
  33. package/Server/Infrastructure/Postgres/SchemaMigrations/1793100000000-SloProductOverhaul.ts +516 -0
  34. package/Server/Infrastructure/Postgres/SchemaMigrations/1793200000000-BackfillSloMonitorRulesAndAffectedResources.ts +98 -0
  35. package/Server/Infrastructure/Postgres/SchemaMigrations/1793300000000-AddDataResidencyToProject.ts +27 -0
  36. package/Server/Infrastructure/Postgres/SchemaMigrations/1793400000000-AddSubscriberUpdateNotificationStatus.ts +97 -0
  37. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +14 -0
  38. package/Server/Services/AlertEpisodeLabelRuleEngineService.ts +138 -67
  39. package/Server/Services/AlertEpisodeOwnerRuleEngineService.ts +213 -84
  40. package/Server/Services/AlertEpisodePrivacyRuleEngineService.ts +112 -35
  41. package/Server/Services/AlertLabelRuleEngineService.ts +299 -217
  42. package/Server/Services/AlertOwnerRuleEngineService.ts +572 -396
  43. package/Server/Services/AlertPrivacyRuleEngineService.ts +116 -40
  44. package/Server/Services/AlertService.ts +111 -4
  45. package/Server/Services/AuditLogService.ts +612 -59
  46. package/Server/Services/BillingInvoiceService.ts +112 -102
  47. package/Server/Services/BillingService.ts +539 -11
  48. package/Server/Services/CephClusterLabelRuleEngineService.ts +170 -109
  49. package/Server/Services/CephClusterOwnerRuleEngineService.ts +233 -115
  50. package/Server/Services/CloudResourceLabelRuleEngineService.ts +163 -100
  51. package/Server/Services/CloudResourceOwnerRuleEngineService.ts +236 -115
  52. package/Server/Services/DashboardLabelRuleEngineService.ts +145 -84
  53. package/Server/Services/DashboardOwnerRuleEngineService.ts +213 -95
  54. package/Server/Services/DatabaseService.ts +171 -21
  55. package/Server/Services/DockerHostLabelRuleEngineService.ts +171 -110
  56. package/Server/Services/DockerHostOwnerRuleEngineService.ts +233 -115
  57. package/Server/Services/DockerSwarmClusterLabelRuleEngineService.ts +181 -112
  58. package/Server/Services/DockerSwarmClusterOwnerRuleEngineService.ts +243 -118
  59. package/Server/Services/HostLabelRuleEngineService.ts +167 -106
  60. package/Server/Services/HostOwnerRuleEngineService.ts +229 -111
  61. package/Server/Services/IncidentEpisodeLabelRuleEngineService.ts +141 -67
  62. package/Server/Services/IncidentEpisodeOwnerRuleEngineService.ts +272 -72
  63. package/Server/Services/IncidentEpisodePrivacyRuleEngineService.ts +112 -35
  64. package/Server/Services/IncidentEpisodePublicNoteService.ts +24 -0
  65. package/Server/Services/IncidentLabelRuleEngineService.ts +279 -204
  66. package/Server/Services/IncidentOwnerRuleEngineService.ts +595 -425
  67. package/Server/Services/IncidentPrivacyRuleEngineService.ts +117 -44
  68. package/Server/Services/IncidentPublicNoteService.ts +24 -0
  69. package/Server/Services/IncidentService.ts +114 -3
  70. package/Server/Services/IncomingCallPolicyLabelRuleEngineService.ts +147 -83
  71. package/Server/Services/IncomingCallPolicyOwnerRuleEngineService.ts +221 -100
  72. package/Server/Services/Index.ts +6 -4
  73. package/Server/Services/IoTFleetLabelRuleEngineService.ts +145 -84
  74. package/Server/Services/IoTFleetOwnerRuleEngineService.ts +213 -95
  75. package/Server/Services/KubernetesClusterLabelRuleEngineService.ts +181 -112
  76. package/Server/Services/KubernetesClusterOwnerRuleEngineService.ts +243 -118
  77. package/Server/Services/LabelService.ts +23 -28
  78. package/Server/Services/MonitorLabelRuleEngineService.ts +152 -92
  79. package/Server/Services/MonitorOwnerRuleEngineService.ts +220 -104
  80. package/Server/Services/MonitorProbeService.ts +20 -2
  81. package/Server/Services/MonitorService.ts +11 -9
  82. package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +376 -5
  83. package/Server/Services/NetworkDeviceDiagnosticService.ts +417 -0
  84. package/Server/Services/NetworkDeviceLabelRuleEngineService.ts +147 -83
  85. package/Server/Services/NetworkDeviceOwnerRuleEngineService.ts +218 -97
  86. package/Server/Services/NetworkDeviceService.ts +39 -2
  87. package/Server/Services/OnCallDutyPolicyLabelRuleEngineService.ts +151 -80
  88. package/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.ts +222 -97
  89. package/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.ts +154 -83
  90. package/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.ts +225 -100
  91. package/Server/Services/PodmanHostLabelRuleEngineService.ts +171 -110
  92. package/Server/Services/PodmanHostOwnerRuleEngineService.ts +235 -115
  93. package/Server/Services/ProjectService.ts +111 -10
  94. package/Server/Services/ProxmoxClusterLabelRuleEngineService.ts +174 -110
  95. package/Server/Services/ProxmoxClusterOwnerRuleEngineService.ts +239 -116
  96. package/Server/Services/RumApplicationLabelRuleEngineService.ts +137 -73
  97. package/Server/Services/RumApplicationOwnerRuleEngineService.ts +200 -83
  98. package/Server/Services/RunbookLabelRuleEngineService.ts +146 -84
  99. package/Server/Services/RunbookOwnerRuleEngineService.ts +216 -95
  100. package/Server/Services/ScheduledMaintenanceLabelRuleEngineService.ts +324 -230
  101. package/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.ts +613 -428
  102. package/Server/Services/ScheduledMaintenancePublicNoteService.ts +24 -0
  103. package/Server/Services/ScheduledMaintenanceService.ts +43 -14
  104. package/Server/Services/SecurityEventConnectionService.ts +56 -4
  105. package/Server/Services/ServerlessFunctionLabelRuleEngineService.ts +143 -74
  106. package/Server/Services/ServerlessFunctionOwnerRuleEngineService.ts +206 -85
  107. package/Server/Services/ServiceLabelRuleEngineService.ts +172 -110
  108. package/Server/Services/ServiceLevelObjectiveBurnRateRuleService.ts +1057 -18
  109. package/Server/Services/ServiceLevelObjectiveFeedService.ts +108 -0
  110. package/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.ts +793 -97
  111. package/Server/Services/ServiceLevelObjectiveMonitorRuleService.ts +1069 -0
  112. package/Server/Services/ServiceLevelObjectiveOwnerTeamService.ts +240 -1
  113. package/Server/Services/ServiceLevelObjectiveOwnerUserService.ts +257 -1
  114. package/Server/Services/ServiceLevelObjectiveService.ts +1356 -56
  115. package/Server/Services/ServiceOwnerRuleEngineService.ts +238 -116
  116. package/Server/Services/StatusPageAnnouncementService.ts +13 -0
  117. package/Server/Services/StatusPageLabelRuleEngineService.ts +146 -85
  118. package/Server/Services/StatusPageOwnerRuleEngineService.ts +210 -99
  119. package/Server/Services/StatusPageSubscriberNotificationTemplateService.ts +28 -232
  120. package/Server/Services/StatusPageSubscriberService.ts +6 -0
  121. package/Server/Services/TelemetryUsageBillingService.ts +38 -7
  122. package/Server/Services/ThreatIntelFeedService.ts +1 -1
  123. package/Server/Services/VMwareVCenterLabelRuleEngineService.ts +173 -110
  124. package/Server/Services/VMwareVCenterOwnerRuleEngineService.ts +238 -116
  125. package/Server/Services/WorkflowLabelRuleEngineService.ts +145 -84
  126. package/Server/Services/WorkflowOwnerRuleEngineService.ts +215 -95
  127. package/Server/Types/Database/UpdateByID.ts +3 -0
  128. package/Server/Types/Database/UpdateOneBy.ts +7 -0
  129. package/Server/Utils/AI/AlertAIContextBuilder.ts +19 -0
  130. package/Server/Utils/AI/IncidentAIContextBuilder.ts +39 -0
  131. package/Server/Utils/AI/Toolbox/AlertTools.ts +37 -1
  132. package/Server/Utils/AI/Toolbox/IncidentTools.ts +22 -1
  133. package/Server/Utils/AI/Toolbox/SloTools.ts +416 -51
  134. package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +151 -13
  135. package/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.ts +17 -4
  136. package/Server/Utils/Dashboard/PublicDashboardSloWidget.ts +155 -8
  137. package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +16 -0
  138. package/Server/Utils/Database/RelationValueUtil.ts +106 -0
  139. package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +6 -1
  140. package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +22 -27
  141. package/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.ts +3 -1
  142. package/Server/Utils/Monitor/MonitorStepsProjectValidator.ts +50 -20
  143. package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +13 -1
  144. package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +6 -11
  145. package/Server/Utils/Rules/MonitorRulePatternValidator.ts +51 -0
  146. package/Server/Utils/Rules/OwnerRuleAssignment.ts +110 -0
  147. package/Server/Utils/Rules/RuleRun/RuleApplication.ts +81 -0
  148. package/Server/Utils/Rules/RuleRun/RuleRunPermission.ts +188 -0
  149. package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +803 -0
  150. package/Server/Utils/Rules/RuleRun/RuleRunner.ts +341 -0
  151. package/Server/Utils/SecurityEvent/ConnectorErrorMessage.ts +3 -2
  152. package/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.ts +6 -4
  153. package/Server/Utils/SecurityEvent/{GoogleSecOps → Connectors/GoogleSecOps}/GoogleSecOpsClient.ts +263 -16
  154. package/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnector.ts +2101 -0
  155. package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.ts +194 -14
  156. package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.ts +1 -2
  157. package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.ts +38 -7
  158. package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry.ts +2 -0
  159. package/Server/Utils/SecurityEvent/Connectors/Types.ts +242 -2
  160. package/Server/Utils/SecurityEvent/DetectionRuleEvaluator.ts +1 -1
  161. package/Server/Utils/SecurityEvent/SecurityEventDedupe.ts +3 -3
  162. package/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.ts +2 -2
  163. package/Server/Utils/SessionReplay/SessionReplayReadService.ts +217 -56
  164. package/Server/Utils/Slo/SloFeedUtil.ts +200 -0
  165. package/Server/Utils/Slo/SloLegacyMonitorLabelAdoption.ts +173 -0
  166. package/Server/Utils/Slo/SloMetricUtil.ts +327 -0
  167. package/Server/Utils/Slo/SloOwnerReferenceValidator.ts +208 -0
  168. package/Server/Utils/Slo/SloRecordReferenceValidator.ts +169 -0
  169. package/Server/Utils/StatusPage/MonitorRulePatternValidator.ts +6 -43
  170. package/Server/Utils/StatusPageResource.ts +50 -5
  171. package/Tests/App/Dashboard/AIInvestigationHeaderStatus.test.tsx +664 -15
  172. package/Tests/App/Dashboard/AddWidgetModal.test.tsx +4 -1
  173. package/Tests/App/Dashboard/AffectedResourcesSlo.test.tsx +307 -0
  174. package/Tests/App/Dashboard/ArchiveResourceCard.test.tsx +289 -0
  175. package/Tests/App/Dashboard/AuditLogsTable.test.tsx +598 -0
  176. package/Tests/App/Dashboard/BillingDefaultPaymentMethod.test.tsx +1046 -0
  177. package/Tests/App/Dashboard/BillingPaidUsageFlow.test.tsx +3 -0
  178. package/Tests/App/Dashboard/BillingPaymentMethodForm.test.tsx +201 -7
  179. package/Tests/App/Dashboard/BooleanSeriesCriteriaFilterText.test.ts +82 -0
  180. package/Tests/App/Dashboard/BreadcrumbCoverage.test.tsx +16 -1
  181. package/Tests/App/Dashboard/ChangeAlertStateAIHeader.test.tsx +116 -8
  182. package/Tests/App/Dashboard/ChatActivityFeed.test.tsx +168 -1
  183. package/Tests/App/Dashboard/ConnectionTestModal.test.tsx +1 -1
  184. package/Tests/App/Dashboard/ConnectorTestReportView.test.tsx +20 -3
  185. package/Tests/App/Dashboard/CorrelateFilterBuilder.test.tsx +1095 -1
  186. package/Tests/App/Dashboard/CorrelateFilterChips.test.tsx +910 -0
  187. package/Tests/App/Dashboard/CorrelateGraph.test.tsx +3747 -25
  188. package/Tests/App/Dashboard/CorrelateGraphHelpers.test.ts +1085 -0
  189. package/Tests/App/Dashboard/CorrelateInspector.test.tsx +1534 -0
  190. package/Tests/App/Dashboard/CorrelateNodeCard.test.tsx +965 -0
  191. package/Tests/App/Dashboard/CorrelateResultSummary.test.tsx +1525 -0
  192. package/Tests/App/Dashboard/CorrelationGraph.test.ts +1030 -0
  193. package/Tests/App/Dashboard/CorrelationGraphLayout.test.ts +526 -0
  194. package/Tests/App/Dashboard/DeviceDiagnostics.test.tsx +787 -0
  195. package/Tests/App/Dashboard/DeviceLatencyTrend.test.tsx +278 -0
  196. package/Tests/App/Dashboard/DiscoveryReviewInventoryRefresh.test.tsx +279 -0
  197. package/Tests/App/Dashboard/DiscoveryScanEditForm.test.tsx +87 -0
  198. package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +443 -8
  199. package/Tests/App/Dashboard/EntityFilterDropdownArchivedSlos.test.tsx +340 -0
  200. package/Tests/App/Dashboard/EventOverviewPages.test.tsx +98 -2
  201. package/Tests/App/Dashboard/ExceptionSegmentedControl.test.tsx +1020 -0
  202. package/Tests/App/Dashboard/InvestigationEvidenceList.test.tsx +268 -47
  203. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1114 -76
  204. package/Tests/App/Dashboard/InvestigationPanelStatus.test.tsx +124 -2
  205. package/Tests/App/Dashboard/InvestigationReportView.test.tsx +279 -176
  206. package/Tests/App/Dashboard/InvestigationRunDetails.test.tsx +1166 -0
  207. package/Tests/App/Dashboard/InvoicesPayInvoice.test.tsx +437 -0
  208. package/Tests/App/Dashboard/NetworkDeviceBulkDelete.test.tsx +65 -0
  209. package/Tests/App/Dashboard/NetworkTopologyLiveView.test.tsx +5 -0
  210. package/Tests/App/Dashboard/ResourceAuditLogsSideMenus.test.tsx +74 -0
  211. package/Tests/App/Dashboard/ResourceFeed.test.tsx +125 -5
  212. package/Tests/App/Dashboard/ResourceFeedPageWiring.test.ts +8 -1
  213. package/Tests/App/Dashboard/SecurityEventConnectionDiagnostics.test.tsx +1764 -0
  214. package/Tests/App/Dashboard/SecurityEventConnectionFormModal.test.tsx +1000 -64
  215. package/Tests/App/Dashboard/SecurityEventConnectionsEmptyState.test.tsx +448 -0
  216. package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +739 -189
  217. package/Tests/App/Dashboard/SecurityEventSeverityPill.test.tsx +233 -0
  218. package/Tests/App/Dashboard/SecurityEventsEmptyState.test.tsx +282 -0
  219. package/Tests/App/Dashboard/SloActiveBurnEventsCard.test.tsx +538 -0
  220. package/Tests/App/Dashboard/SloBulkActionsArchive.test.tsx +252 -0
  221. package/Tests/App/Dashboard/SloDashboardTemplateWidgets.test.tsx +322 -518
  222. package/Tests/App/Dashboard/SloElement.test.tsx +194 -0
  223. package/Tests/App/Dashboard/SloFeed.test.tsx +289 -0
  224. package/Tests/App/Dashboard/SloHistoryCharts.test.tsx +471 -0
  225. package/Tests/App/Dashboard/SloHistorySeries.test.tsx +607 -0
  226. package/Tests/App/Dashboard/SloListWidget.test.tsx +783 -0
  227. package/Tests/App/Dashboard/SloMetricsPage.test.tsx +346 -0
  228. package/Tests/App/Dashboard/SloMonitorsPage.test.tsx +661 -0
  229. package/Tests/App/Dashboard/SloMonitorsSummaryCard.test.tsx +489 -0
  230. package/Tests/App/Dashboard/SloNavigationWiring.test.tsx +437 -0
  231. package/Tests/App/Dashboard/SloNoticeBanner.test.tsx +305 -0
  232. package/Tests/App/Dashboard/SloOverviewData.test.tsx +563 -0
  233. package/Tests/App/Dashboard/SloOverviewHero.test.tsx +311 -0
  234. package/Tests/App/Dashboard/SloOverviewKpiStrip.test.tsx +426 -0
  235. package/Tests/App/Dashboard/SloOverviewSidebarCards.test.tsx +493 -0
  236. package/Tests/App/Dashboard/SloSettings.test.tsx +633 -0
  237. package/Tests/App/Dashboard/SloStatusSummaryCards.test.tsx +403 -0
  238. package/Tests/App/Dashboard/SloViewSideMenuCounts.test.tsx +373 -0
  239. package/Tests/App/Dashboard/SloWidgetVariableBinding.test.tsx +689 -0
  240. package/Tests/App/Dashboard/TopologyConnectivitySection.test.tsx +206 -0
  241. package/Tests/App/Dashboard/TracesEntityNames.test.tsx +47 -15
  242. package/Tests/App/Dashboard/UseBulkShortenDeviceNames.test.tsx +1312 -0
  243. package/Tests/App/Dashboard/WidgetCatalog.test.ts +9 -1
  244. package/Tests/Models/AnalyticsModels/RumSessionReplayColumns.test.ts +14 -16
  245. package/Tests/Models/DatabaseModels/AuditLogModelConfiguration.test.ts +442 -0
  246. package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +9 -10
  247. package/Tests/Models/DatabaseModels/ResourceFeedModels.test.ts +48 -1
  248. package/Tests/Models/DatabaseModels/SloOverhaulModels.test.ts +835 -0
  249. package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +3 -2
  250. package/Tests/Models/DiscoveryScanNetbiosLookupColumn.test.ts +328 -0
  251. package/Tests/Models/DiscoveryScanShortDeviceNamesColumn.test.ts +335 -0
  252. package/Tests/Models/NetworkDeviceDiagnosticContract.test.ts +194 -0
  253. package/Tests/Models/NetworkDeviceDnsNameColumn.test.ts +321 -0
  254. package/Tests/Models/ProjectDataResidencyColumn.test.ts +154 -0
  255. package/Tests/Models/SecurityDomainAccessControl.test.ts +181 -50
  256. package/Tests/Server/API/BaseAPI.test.ts +6 -0
  257. package/Tests/Server/API/BaseAPIUpdateMiscDataProps.test.ts +217 -0
  258. package/Tests/Server/API/BillingInvoiceAPI.test.ts +7 -0
  259. package/Tests/Server/API/BillingInvoiceAPIPaymentStates.test.ts +990 -0
  260. package/Tests/Server/API/BillingPaymentMethodAPI.test.ts +498 -0
  261. package/Tests/Server/API/DashboardPublicSloAPI.test.ts +405 -0
  262. package/Tests/Server/API/SecurityEventConnectionAPI.test.ts +901 -7
  263. package/Tests/Server/API/SessionReplayAPI.test.ts +116 -0
  264. package/Tests/Server/API/StatusPageManageSubscriptionRecipient.test.ts +857 -0
  265. package/Tests/Server/API/StatusPageManageSubscriptionTemplateVariables.test.ts +1084 -0
  266. package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +33 -3
  267. package/Tests/Server/Infrastructure/Postgres/AddDataResidencyToProjectMigration.test.ts +202 -0
  268. package/Tests/Server/Infrastructure/Postgres/AddNetbiosLookupToNetworkDeviceDiscoveryScanMigration.test.ts +330 -0
  269. package/Tests/Server/Infrastructure/Postgres/AddNetworkDeviceDnsNameAndShortDeviceNamesMigration.test.ts +340 -0
  270. package/Tests/Server/Infrastructure/Postgres/BackfillSloMonitorRulesAndAffectedResourcesMigration.test.ts +343 -0
  271. package/Tests/Server/Infrastructure/Postgres/SloProductOverhaulMigration.test.ts +801 -0
  272. package/Tests/Server/Services/AddSubscriberUpdateNotificationStatusMigration.test.ts +307 -0
  273. package/Tests/Server/Services/AuditLogService.test.ts +1124 -0
  274. package/Tests/Server/Services/AutoImportScanCredentialSelect.test.ts +200 -1
  275. package/Tests/Server/Services/BillingInvoiceServiceMutexRelease.test.ts +254 -0
  276. package/Tests/Server/Services/BillingService.test.ts +70 -0
  277. package/Tests/Server/Services/BillingServicePayInvoiceStates.test.ts +723 -0
  278. package/Tests/Server/Services/BillingServicePaymentMethodReads.test.ts +14 -2
  279. package/Tests/Server/Services/BillingServiceSubscriptionPaymentMethodSync.test.ts +1634 -0
  280. package/Tests/Server/Services/DatabaseServiceAuditRelationDiff.test.ts +492 -0
  281. package/Tests/Server/Services/DatabaseServicePasswordFieldSecrets.test.ts +629 -0
  282. package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +431 -0
  283. package/Tests/Server/Services/IncidentAlertSloReferenceGuard.test.ts +358 -0
  284. package/Tests/Server/Services/MonitorProbeServicePastDueMonitoring.test.ts +362 -0
  285. package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +1460 -1
  286. package/Tests/Server/Services/NetworkDeviceDiagnosticService.test.ts +962 -0
  287. package/Tests/Server/Services/NetworkDeviceDiscoveryScanService.test.ts +106 -0
  288. package/Tests/Server/Services/NetworkDeviceRuleEngines.test.ts +10 -1
  289. package/Tests/Server/Services/NetworkDeviceServicePastDueMonitoring.test.ts +335 -0
  290. package/Tests/Server/Services/NetworkDeviceSiteRuleDnsName.test.ts +568 -0
  291. package/Tests/Server/Services/ProjectDataResidencyPostgres.test.ts +344 -0
  292. package/Tests/Server/Services/ProjectServiceAuditLogSettingsCache.test.ts +187 -0
  293. package/Tests/Server/Services/ProjectServiceDataResidency.test.ts +369 -0
  294. package/Tests/Server/Services/ProjectServiceDataResidencySelfHosted.test.ts +176 -0
  295. package/Tests/Server/Services/ProjectServicePastDueMonitoring.test.ts +289 -0
  296. package/Tests/Server/Services/ResourceFeedServices.test.ts +24 -8
  297. package/Tests/Server/Services/RuleRun/IncidentAlertMaintenanceRuleEnginesRun.test.ts +1396 -0
  298. package/Tests/Server/Services/RuleRun/LabelRuleEnginesGroupARun.test.ts +917 -0
  299. package/Tests/Server/Services/RuleRun/LabelRuleEnginesGroupBRun.test.ts +1262 -0
  300. package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupARun.test.ts +902 -0
  301. package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupBRun.test.ts +1163 -0
  302. package/Tests/Server/Services/RuleRun/PrivacyRuleEnginesRun.test.ts +843 -0
  303. package/Tests/Server/Services/ScheduledMaintenanceSubscriberTemplateFormats.test.ts +465 -0
  304. package/Tests/Server/Services/SecurityEventConnectionService.test.ts +525 -4
  305. package/Tests/Server/Services/SecurityEventLastErrorColumnWidth.test.ts +77 -23
  306. package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleFeedWrites.test.ts +777 -0
  307. package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleOptions.test.ts +1399 -0
  308. package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleService.test.ts +67 -74
  309. package/Tests/Server/Services/ServiceLevelObjectiveChildRowTenancy.test.ts +906 -0
  310. package/Tests/Server/Services/ServiceLevelObjectiveDeleteTenancy.test.ts +1029 -0
  311. package/Tests/Server/Services/ServiceLevelObjectiveFeedService.test.ts +313 -0
  312. package/Tests/Server/Services/ServiceLevelObjectiveFeedWrites.test.ts +1214 -0
  313. package/Tests/Server/Services/ServiceLevelObjectiveMarkdownLink.test.ts +289 -0
  314. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.test.ts +1455 -430
  315. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleLegacyLabelAdoption.test.ts +634 -0
  316. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleService.test.ts +1193 -0
  317. package/Tests/Server/Services/{SloMonitorLabelRuleHooks.test.ts → ServiceLevelObjectiveMonitorRuleTriggers.test.ts} +135 -41
  318. package/Tests/Server/Services/ServiceLevelObjectiveOwnerFeedWrites.test.ts +671 -0
  319. package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +180 -85
  320. package/Tests/Server/Services/ServiceLevelObjectiveServiceArchive.test.ts +537 -0
  321. package/Tests/Server/Services/ServiceLevelObjectiveServiceLegacyMonitorLabelWrite.test.ts +870 -0
  322. package/Tests/Server/Services/ServiceLevelObjectiveServiceMonitorRuleGuard.test.ts +343 -0
  323. package/Tests/Server/Services/ServiceLevelObjectiveServiceReEvaluation.test.ts +246 -0
  324. package/Tests/Server/Services/SloAffectedResourceCreatedFeed.test.ts +501 -0
  325. package/Tests/Server/Services/SloAffectedResourceLinkContract.test.ts +86 -0
  326. package/Tests/Server/Services/SloAffectedResourceMetricAttributes.test.ts +547 -0
  327. package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +10 -4
  328. package/Tests/Server/Services/StatusPageMonitorRuleHooks.test.ts +7 -2
  329. package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateCompile.test.ts +174 -0
  330. package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateServiceVariables.test.ts +40 -0
  331. package/Tests/Server/Services/SubscriberUpdateNotificationHooks.test.ts +541 -0
  332. package/Tests/Server/Services/TelemetryUsageBillingSloExclusion.test.ts +288 -0
  333. package/Tests/Server/TestingUtils/PastDueMonitoringClaimSql.ts +177 -0
  334. package/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts +51 -10
  335. package/Tests/Server/TestingUtils/__mocks__/Stripe.mock.ts +16 -1
  336. package/Tests/Server/Types/Database/Permissions/ProjectDataResidencyColumn.test.ts +386 -0
  337. package/Tests/Server/Types/Database/Permissions/SecurityRoleAccess.test.ts +26 -36
  338. package/Tests/Server/Utils/AI/SloAffectedResourceAIContext.test.ts +445 -0
  339. package/Tests/Server/Utils/AI/SloTools.test.ts +423 -1
  340. package/Tests/Server/Utils/AI/SloToolsArchive.test.ts +294 -0
  341. package/Tests/Server/Utils/AI/SloToolsRuleReadPermissions.test.ts +297 -0
  342. package/Tests/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.test.ts +255 -10
  343. package/Tests/Server/Utils/Dashboard/SloTemplatePublicDashboard.test.ts +404 -750
  344. package/Tests/Server/Utils/Database/ProjectScopedReferenceValidator.test.ts +45 -0
  345. package/Tests/Server/Utils/Database/RelationValueUtil.test.ts +157 -0
  346. package/Tests/Server/Utils/Monitor/Criteria/BooleanSeriesEvaluateOverTime.test.ts +260 -0
  347. package/Tests/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.test.ts +181 -0
  348. package/Tests/Server/Utils/Monitor/Criteria/EvaluateOverTime.test.ts +147 -30
  349. package/Tests/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.test.ts +17 -0
  350. package/Tests/Server/Utils/Monitor/MonitorStepsProjectValidator.test.ts +136 -0
  351. package/Tests/Server/Utils/Monitor/MonitorStepsProjectValidatorLoadOrder.test.ts +472 -0
  352. package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +48 -2
  353. package/Tests/Server/Utils/Monitor/SloTemplateMetricEmitterContract.test.ts +435 -475
  354. package/Tests/Server/Utils/Rules/MonitorRulePatternValidator.test.ts +77 -0
  355. package/Tests/Server/Utils/Rules/OwnerRuleAssignment.test.ts +177 -0
  356. package/Tests/Server/Utils/Rules/RuleRun/RuleRunPermission.test.ts +365 -0
  357. package/Tests/Server/Utils/Rules/RuleRun/RuleRunRegistry.test.ts +173 -0
  358. package/Tests/Server/Utils/Rules/RuleRun/RuleRunner.test.ts +675 -0
  359. package/Tests/Server/Utils/SecurityEvent/ConnectorErrorMessage.test.ts +8 -8
  360. package/Tests/Server/Utils/SecurityEvent/Connectors/ConnectorFetchSummary.test.ts +261 -0
  361. package/Tests/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.test.ts +68 -13
  362. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsAuth.test.ts → Connectors/GoogleSecOps/GoogleSecOpsAuth.test.ts} +5 -5
  363. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsClient.test.ts → Connectors/GoogleSecOps/GoogleSecOpsClient.test.ts} +4 -4
  364. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnector.test.ts +483 -0
  365. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorCuratedAndLateAlerts.test.ts +676 -0
  366. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorFetchEvents.test.ts +1994 -0
  367. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorFixtures.ts +332 -0
  368. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorHttpIntegration.test.ts +680 -0
  369. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorRequestContract.test.ts +1206 -0
  370. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorTestConnection.test.ts +1136 -0
  371. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsCuratedRuleCounts.test.ts +407 -0
  372. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsErrorHandling.test.ts → Connectors/GoogleSecOps/GoogleSecOpsErrorHandling.test.ts} +5 -5
  373. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingAdaptiveCatchUp.test.ts +730 -0
  374. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsClickhouseIntegration.test.ts → Connectors/GoogleSecOps/GoogleSecOpsPollingClickhouseIntegration.test.ts} +130 -35
  375. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingFailureTaxonomy.test.ts +772 -0
  376. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingFixtures.ts +648 -0
  377. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsHttpIntegration.test.ts → Connectors/GoogleSecOps/GoogleSecOpsPollingHttpIntegration.test.ts} +230 -225
  378. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingIntegration.test.ts +1390 -0
  379. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingLoop.test.ts +981 -0
  380. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingNothingImportedRegression.test.ts +290 -0
  381. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsRequestContract.test.ts → Connectors/GoogleSecOps/GoogleSecOpsRequestContract.test.ts} +2 -2
  382. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsResponseParsing.test.ts → Connectors/GoogleSecOps/GoogleSecOpsResponseParsing.test.ts} +5 -5
  383. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsSearchDetections.test.ts → Connectors/GoogleSecOps/GoogleSecOpsSearchDetections.test.ts} +38 -5
  384. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsTesterIntegration.test.ts +421 -0
  385. package/Tests/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.test.ts +1445 -3
  386. package/Tests/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.test.ts +14 -4
  387. package/Tests/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.test.ts +313 -4
  388. package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +352 -0
  389. package/Tests/Server/Utils/Slo/SloFeedUtil.test.ts +326 -0
  390. package/Tests/Server/Utils/Slo/SloLegacyMonitorLabelAdoption.test.ts +260 -0
  391. package/Tests/Server/Utils/Slo/SloMetricUtil.test.ts +592 -0
  392. package/Tests/Server/Utils/Slo/SloRecordReferenceValidator.test.ts +311 -0
  393. package/Tests/Server/Utils/StatusPageResource.test.ts +91 -3
  394. package/Tests/Types/Billing/SubscriptionStatus.test.ts +176 -0
  395. package/Tests/Types/Billing/SubscriptionStatusPastDueMonitoring.test.ts +187 -0
  396. package/Tests/Types/Dashboard/DashboardTemplateInvariants.test.ts +53 -7
  397. package/Tests/Types/Dashboard/SloDashboardTemplate.test.ts +816 -792
  398. package/Tests/Types/Monitor/CriteriaFilter.test.ts +216 -24
  399. package/Tests/Types/Monitor/MonitorStepDnssecMonitor.test.ts +14 -1
  400. package/Tests/Types/Monitor/MonitorStepDomainMonitor.test.ts +14 -1
  401. package/Tests/Types/Monitor/MonitorStepExternalStatusPageMonitor.test.ts +14 -1
  402. package/Tests/Types/Monitor/MonitorStepRetriesParsing.test.ts +201 -0
  403. package/Tests/Types/Rules/RuleRun.test.ts +315 -0
  404. package/Tests/Types/Rum/SessionReplayApiContracts.test.ts +60 -0
  405. package/Tests/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.test.ts +29 -4
  406. package/Tests/Types/StatusPage/SubscriberNotificationTemplateVariables.test.ts +217 -0
  407. package/Tests/Types/StatusPage/SubscriberUpdateNotification.test.ts +200 -0
  408. package/Tests/UI/Components/ActiveFilterChipsLockedFilters.test.tsx +141 -87
  409. package/Tests/UI/Components/AlertBanner.test.tsx +319 -0
  410. package/Tests/UI/Components/BulkArchiveActionsCopy.test.tsx +310 -0
  411. package/Tests/UI/Components/Detail/DetailIdIsUnique.test.tsx +87 -0
  412. package/Tests/UI/Components/Dropdown/DropdownClearable.test.tsx +393 -0
  413. package/Tests/UI/Components/Dropdown/DropdownMultiSelectChipAccessibleName.test.tsx +64 -0
  414. package/Tests/UI/Components/EmptyState/EmptyState.test.tsx +335 -4
  415. package/Tests/UI/Components/EmptyState/EmptyStateGuideLinks.test.tsx +337 -0
  416. package/Tests/UI/Components/Forms/ModelFormJsonColumns.test.tsx +21 -20
  417. package/Tests/UI/Components/LabelRuleImportExport.test.tsx +15 -2
  418. package/Tests/UI/Components/LockedFilterChip.test.tsx +281 -144
  419. package/Tests/UI/Components/MoreMenu.test.tsx +133 -0
  420. package/Tests/UI/Components/MoreMenuMotion.test.tsx +84 -3
  421. package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
  422. package/Tests/UI/Components/RuleRun/RuleDetailFields.test.tsx +336 -0
  423. package/Tests/UI/Components/RuleRun/RuleTable.test.tsx +304 -0
  424. package/Tests/UI/Components/RuleRun/RunRuleNowModal.test.tsx +231 -0
  425. package/Tests/UI/Components/RuleRun/RunRulesBulkAction.test.ts +213 -0
  426. package/Tests/UI/Components/TelemetryActiveFilterChipsLockedFilters.test.tsx +124 -61
  427. package/Tests/UI/Rum/ReplayEngine.test.ts +154 -0
  428. package/Tests/UI/Rum/ReplayHeader.test.tsx +234 -123
  429. package/Tests/UI/Rum/ReplayPinControl.test.tsx +122 -0
  430. package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +245 -0
  431. package/Tests/UI/Rum/ReplayRail.test.tsx +294 -0
  432. package/Tests/UI/Rum/ReplayScrubber.test.tsx +213 -1
  433. package/Tests/UI/Rum/ReplayStage.test.tsx +565 -172
  434. package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +260 -3
  435. package/Tests/UI/Rum/ReplayTabSwitcher.test.tsx +1391 -0
  436. package/Tests/UI/Rum/ReplayTimeline.test.tsx +222 -0
  437. package/Tests/UI/Utils/DashboardStackingLayers.test.ts +8 -1
  438. package/Tests/UI/Utils/RuleRunClient.test.ts +303 -0
  439. package/Tests/UI/Utils/Telemetry/TelemetryEntityNames.test.ts +1 -0
  440. package/Tests/Utils/Dashboard/Components/DashboardComponentDefaults.test.ts +2 -0
  441. package/Tests/Utils/Dashboard/Components/DashboardSloListComponent.test.ts +206 -0
  442. package/Tests/Utils/Dashboard/DashboardSloComponent.test.ts +36 -2
  443. package/Tests/Utils/Dashboard/SloTemplateVariableScoping.test.ts +409 -588
  444. package/Tests/Utils/Dashboard/SloWidgetSource.test.ts +351 -0
  445. package/Tests/Utils/Markdown/MarkdownEscape.test.ts +361 -0
  446. package/Tests/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.test.ts +1425 -118
  447. package/Tests/Utils/NetworkDiscovery/DiscoveredHostUtil.test.ts +188 -3
  448. package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +661 -13
  449. package/Tests/Utils/NetworkDiscovery/NetbiosNameUtil.test.ts +349 -0
  450. package/Tests/Utils/NetworkDiscovery/RunImportedDeviceNaming.test.ts +656 -0
  451. package/Tests/Utils/NetworkDiscovery/ShortDeviceNamePlanner.test.ts +1020 -0
  452. package/Tests/Utils/NetworkDiscovery/ShortHostnameUtil.test.ts +619 -0
  453. package/Tests/Utils/NetworkSite/CidrMatchUtil.test.ts +317 -0
  454. package/Tests/Utils/Project/DataResidency.test.ts +198 -0
  455. package/Tests/Utils/Rules/RuleRunSummary.test.ts +394 -0
  456. package/Tests/Utils/Slo/SloAffectedResourceMarkdown.test.ts +302 -0
  457. package/Tests/Utils/Slo/SloBurnRateTemplate.test.ts +468 -0
  458. package/Tests/Utils/Slo/SloEvaluation.test.ts +20 -4
  459. package/Tests/Utils/Slo/SloFeedMarkdown.test.ts +1185 -0
  460. package/Tests/Utils/Slo/SloHealth.test.ts +262 -0
  461. package/Tests/Utils/Slo/SloHistoryMetricName.test.ts +102 -0
  462. package/Tests/Utils/Slo/SloListWidgetFormat.test.ts +522 -0
  463. package/Tests/Utils/Slo/SloMetricType.test.ts +355 -0
  464. package/Tests/Utils/Slo/SloMonitorRuleCriteria.test.ts +387 -0
  465. package/Tests/Utils/Slo/SloMonitorStatusSummary.test.ts +210 -0
  466. package/Tests/Utils/Slo/SloOverviewText.test.ts +226 -0
  467. package/Tests/Utils/Slo/SloProjection.test.ts +1039 -0
  468. package/Tests/Utils/Slo/SloWidgetFormat.test.ts +47 -0
  469. package/Tests/Utils/Telemetry/LockedFilterSearch.test.ts +1 -80
  470. package/Types/BaseDatabase/EnableAuditLogOn.ts +41 -0
  471. package/Types/Billing/SubscriptionStatus.ts +39 -4
  472. package/Types/Dashboard/DashboardComponentType.ts +1 -0
  473. package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +5 -0
  474. package/Types/Dashboard/DashboardComponents/DashboardSloComponent.ts +10 -0
  475. package/Types/Dashboard/DashboardComponents/DashboardSloListComponent.ts +29 -0
  476. package/Types/Dashboard/DashboardTemplates.ts +290 -297
  477. package/Types/Database/EnableAuditLog.ts +23 -1
  478. package/Types/Email/EmailTemplateType.ts +4 -0
  479. package/Types/Monitor/CriteriaFilter.ts +55 -8
  480. package/Types/Monitor/MonitorStep.ts +5 -2
  481. package/Types/Monitor/MonitorStepDnsMonitor.ts +3 -1
  482. package/Types/Monitor/MonitorStepDnssecMonitor.ts +3 -1
  483. package/Types/Monitor/MonitorStepDomainMonitor.ts +3 -1
  484. package/Types/Monitor/MonitorStepExternalStatusPageMonitor.ts +3 -1
  485. package/Types/Monitor/MonitorStepRetries.ts +59 -0
  486. package/Types/Monitor/MonitorStepSnmpMonitor.ts +9 -2
  487. package/Types/NetworkDevice/NetworkDeviceDiagnosticResult.ts +104 -0
  488. package/Types/NetworkDevice/NetworkDeviceDiagnosticStatus.ts +47 -0
  489. package/Types/NetworkDevice/NetworkDeviceDiagnosticType.ts +47 -0
  490. package/Types/NetworkDevice/NetworkDevicePingMetricNames.ts +20 -0
  491. package/Types/Permission.ts +127 -0
  492. package/Types/Rules/RuleCriteriaFieldRegistry.ts +5 -0
  493. package/Types/Rules/RuleRun.ts +518 -0
  494. package/Types/Rum/SessionReplayApi.ts +18 -0
  495. package/Types/SecurityEvent/Connectors/ConnectorDiagnostics.ts +6 -0
  496. package/Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics.ts +30 -4
  497. package/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.ts +108 -1
  498. package/Types/SecurityEvent/Connectors/SecurityEventConnectorProvider.ts +6 -2
  499. package/Types/ServiceLevelObjective/SloHistoryMetricName.ts +25 -0
  500. package/Types/ServiceLevelObjective/SloMetricType.ts +49 -0
  501. package/Types/StatusPage/StatusPageSubscriberNotificationEventType.ts +4 -0
  502. package/Types/StatusPage/SubscriberNotificationTemplateVariables.ts +331 -0
  503. package/Types/StatusPage/SubscriberNotificationTrigger.ts +12 -0
  504. package/Types/StatusPage/SubscriberUpdateNotification.ts +89 -0
  505. package/Types/Telemetry/LockedFilterDetail.ts +7 -28
  506. package/Types/Telemetry/ServiceType.ts +7 -0
  507. package/Typings/Index.d.ts +53 -3
  508. package/UI/Components/AlertBanner/AlertBanner.tsx +85 -27
  509. package/UI/Components/BulkUpdate/BulkArchiveActions.tsx +21 -2
  510. package/UI/Components/Detail/Detail.tsx +9 -2
  511. package/UI/Components/Dropdown/Dropdown.tsx +64 -1
  512. package/UI/Components/EmptyState/EmptyState.tsx +27 -3
  513. package/UI/Components/EmptyState/EmptyStateGuideLinks.tsx +124 -0
  514. package/UI/Components/Forms/ModelForm.tsx +6 -5
  515. package/UI/Components/LabelRule/LabelRuleTable.tsx +8 -2
  516. package/UI/Components/LogsViewer/LogsViewer.tsx +2 -6
  517. package/UI/Components/LogsViewer/components/ActiveFilterChips.tsx +2 -13
  518. package/UI/Components/LogsViewer/types.ts +2 -2
  519. package/UI/Components/MoreMenu/MoreMenu.tsx +14 -3
  520. package/UI/Components/RuleRun/RuleDetailFields.tsx +359 -0
  521. package/UI/Components/RuleRun/RuleTable.tsx +183 -0
  522. package/UI/Components/RuleRun/RuleView.tsx +170 -0
  523. package/UI/Components/RuleRun/RunRuleNowModal.tsx +147 -0
  524. package/UI/Components/RuleRun/RunRulesBulkAction.ts +103 -0
  525. package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +2 -6
  526. package/UI/Components/TelemetryViewer/components/LockedFilterChip.tsx +38 -104
  527. package/UI/Components/TelemetryViewer/components/TelemetryActiveFilterChips.tsx +2 -18
  528. package/UI/Components/TelemetryViewer/types.ts +2 -2
  529. package/UI/Utils/Rules/RuleRunClient.ts +178 -0
  530. package/UI/Utils/Telemetry/TelemetryEntityNames.ts +8 -0
  531. package/Utils/Dashboard/Components/DashboardSloComponent.ts +19 -2
  532. package/Utils/Dashboard/Components/DashboardSloListComponent.ts +126 -0
  533. package/Utils/Dashboard/Components/Index.ts +7 -0
  534. package/Utils/Dashboard/SloWidgetSource.ts +188 -0
  535. package/Utils/Markdown/MarkdownEscape.ts +63 -0
  536. package/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.ts +161 -36
  537. package/Utils/NetworkDiscovery/DiscoveredHostUtil.ts +25 -0
  538. package/Utils/NetworkDiscovery/NetbiosNameUtil.ts +146 -0
  539. package/Utils/NetworkDiscovery/RunImportedDeviceNaming.ts +390 -0
  540. package/Utils/NetworkDiscovery/ShortDeviceNamePlanner.ts +291 -0
  541. package/Utils/NetworkDiscovery/ShortHostnameUtil.ts +91 -0
  542. package/Utils/NetworkSite/CidrMatchUtil.ts +37 -12
  543. package/Utils/Project/DataResidency.ts +63 -0
  544. package/Utils/Rules/RuleRunSummary.ts +323 -0
  545. package/Utils/Slo/SloAffectedResourceMarkdown.ts +123 -0
  546. package/Utils/Slo/SloBurnRateTemplate.ts +373 -0
  547. package/Utils/Slo/SloFeedMarkdown.ts +1507 -0
  548. package/Utils/Slo/SloHealth.ts +96 -9
  549. package/Utils/Slo/SloListWidgetFormat.ts +370 -0
  550. package/Utils/Slo/SloMetricType.ts +237 -0
  551. package/Utils/Slo/SloMonitorRuleCriteria.ts +364 -0
  552. package/Utils/Slo/SloMonitorStatusSummary.ts +210 -0
  553. package/Utils/Slo/SloOverviewText.ts +265 -0
  554. package/Utils/Slo/SloProjection.ts +967 -0
  555. package/Utils/Slo/SloWidgetFormat.ts +12 -2
  556. package/Utils/Telemetry/LockedFilterSearch.ts +3 -49
  557. package/build/dist/Models/AnalyticsModels/AuditLog.js +70 -1
  558. package/build/dist/Models/AnalyticsModels/AuditLog.js.map +1 -1
  559. package/build/dist/Models/AnalyticsModels/SecurityEvent.js +4 -4
  560. package/build/dist/Models/DatabaseModels/Alert.js +60 -0
  561. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  562. package/build/dist/Models/DatabaseModels/GlobalConfig.js +1 -1
  563. package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
  564. package/build/dist/Models/DatabaseModels/Incident.js +64 -0
  565. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  566. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +75 -0
  567. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -1
  568. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +75 -0
  569. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
  570. package/build/dist/Models/DatabaseModels/Index.js +6 -4
  571. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  572. package/build/dist/Models/DatabaseModels/NetworkDevice.js +68 -0
  573. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  574. package/build/dist/Models/DatabaseModels/NetworkDeviceDiagnostic.js +772 -0
  575. package/build/dist/Models/DatabaseModels/NetworkDeviceDiagnostic.js.map +1 -0
  576. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +140 -0
  577. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  578. package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js +1 -1
  579. package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js.map +1 -1
  580. package/build/dist/Models/DatabaseModels/Project.js +42 -0
  581. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  582. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +75 -0
  583. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
  584. package/build/dist/Models/DatabaseModels/SecurityEventConnection.js +11 -11
  585. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js +192 -10
  586. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js.map +1 -1
  587. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js +798 -96
  588. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js.map +1 -1
  589. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveFeed.js +596 -0
  590. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveFeed.js.map +1 -0
  591. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.js +590 -0
  592. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.js.map +1 -0
  593. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js +16 -0
  594. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js.map +1 -1
  595. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js +16 -0
  596. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js.map +1 -1
  597. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +75 -0
  598. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
  599. package/build/dist/Models/DatabaseModels/ThreatIntelFeed.js +1 -1
  600. package/build/dist/Server/API/BaseAPI.js +14 -0
  601. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  602. package/build/dist/Server/API/BillingInvoiceAPI.js +233 -19
  603. package/build/dist/Server/API/BillingInvoiceAPI.js.map +1 -1
  604. package/build/dist/Server/API/BillingPaymentMethodAPI.js +86 -5
  605. package/build/dist/Server/API/BillingPaymentMethodAPI.js.map +1 -1
  606. package/build/dist/Server/API/DashboardAPI.js +72 -2
  607. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  608. package/build/dist/Server/API/SecurityEventConnectionAPI.js +102 -10
  609. package/build/dist/Server/API/SecurityEventConnectionAPI.js.map +1 -1
  610. package/build/dist/Server/API/StatusPageAPI.js +236 -154
  611. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  612. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792800000000-AddNetworkDeviceDiagnostic.js +34 -0
  613. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792800000000-AddNetworkDeviceDiagnostic.js.map +1 -0
  614. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792900000000-AddNetworkDeviceDnsNameAndShortDeviceNames.js +24 -0
  615. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792900000000-AddNetworkDeviceDnsNameAndShortDeviceNames.js.map +1 -0
  616. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793000000000-AddNetbiosLookupToNetworkDeviceDiscoveryScan.js +21 -0
  617. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793000000000-AddNetbiosLookupToNetworkDeviceDiscoveryScan.js.map +1 -0
  618. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793100000000-SloProductOverhaul.js +207 -0
  619. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793100000000-SloProductOverhaul.js.map +1 -0
  620. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793200000000-BackfillSloMonitorRulesAndAffectedResources.js +72 -0
  621. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793200000000-BackfillSloMonitorRulesAndAffectedResources.js.map +1 -0
  622. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793300000000-AddDataResidencyToProject.js +20 -0
  623. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793300000000-AddDataResidencyToProject.js.map +1 -0
  624. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793400000000-AddSubscriberUpdateNotificationStatus.js +46 -0
  625. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793400000000-AddSubscriberUpdateNotificationStatus.js.map +1 -0
  626. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +14 -0
  627. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  628. package/build/dist/Server/Services/AlertEpisodeLabelRuleEngineService.js +112 -56
  629. package/build/dist/Server/Services/AlertEpisodeLabelRuleEngineService.js.map +1 -1
  630. package/build/dist/Server/Services/AlertEpisodeOwnerRuleEngineService.js +167 -68
  631. package/build/dist/Server/Services/AlertEpisodeOwnerRuleEngineService.js.map +1 -1
  632. package/build/dist/Server/Services/AlertEpisodePrivacyRuleEngineService.js +87 -26
  633. package/build/dist/Server/Services/AlertEpisodePrivacyRuleEngineService.js.map +1 -1
  634. package/build/dist/Server/Services/AlertLabelRuleEngineService.js +270 -203
  635. package/build/dist/Server/Services/AlertLabelRuleEngineService.js.map +1 -1
  636. package/build/dist/Server/Services/AlertOwnerRuleEngineService.js +498 -354
  637. package/build/dist/Server/Services/AlertOwnerRuleEngineService.js.map +1 -1
  638. package/build/dist/Server/Services/AlertPrivacyRuleEngineService.js +97 -34
  639. package/build/dist/Server/Services/AlertPrivacyRuleEngineService.js.map +1 -1
  640. package/build/dist/Server/Services/AlertService.js +91 -8
  641. package/build/dist/Server/Services/AlertService.js.map +1 -1
  642. package/build/dist/Server/Services/AuditLogService.js +408 -44
  643. package/build/dist/Server/Services/AuditLogService.js.map +1 -1
  644. package/build/dist/Server/Services/BillingInvoiceService.js +94 -85
  645. package/build/dist/Server/Services/BillingInvoiceService.js.map +1 -1
  646. package/build/dist/Server/Services/BillingService.js +406 -14
  647. package/build/dist/Server/Services/BillingService.js.map +1 -1
  648. package/build/dist/Server/Services/CephClusterLabelRuleEngineService.js +141 -92
  649. package/build/dist/Server/Services/CephClusterLabelRuleEngineService.js.map +1 -1
  650. package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js +189 -101
  651. package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js.map +1 -1
  652. package/build/dist/Server/Services/CloudResourceLabelRuleEngineService.js +135 -86
  653. package/build/dist/Server/Services/CloudResourceLabelRuleEngineService.js.map +1 -1
  654. package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js +189 -100
  655. package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js.map +1 -1
  656. package/build/dist/Server/Services/DashboardLabelRuleEngineService.js +117 -69
  657. package/build/dist/Server/Services/DashboardLabelRuleEngineService.js.map +1 -1
  658. package/build/dist/Server/Services/DashboardOwnerRuleEngineService.js +171 -83
  659. package/build/dist/Server/Services/DashboardOwnerRuleEngineService.js.map +1 -1
  660. package/build/dist/Server/Services/DatabaseService.js +125 -18
  661. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  662. package/build/dist/Server/Services/DockerHostLabelRuleEngineService.js +141 -92
  663. package/build/dist/Server/Services/DockerHostLabelRuleEngineService.js.map +1 -1
  664. package/build/dist/Server/Services/DockerHostOwnerRuleEngineService.js +189 -101
  665. package/build/dist/Server/Services/DockerHostOwnerRuleEngineService.js.map +1 -1
  666. package/build/dist/Server/Services/DockerSwarmClusterLabelRuleEngineService.js +145 -91
  667. package/build/dist/Server/Services/DockerSwarmClusterLabelRuleEngineService.js.map +1 -1
  668. package/build/dist/Server/Services/DockerSwarmClusterOwnerRuleEngineService.js +191 -101
  669. package/build/dist/Server/Services/DockerSwarmClusterOwnerRuleEngineService.js.map +1 -1
  670. package/build/dist/Server/Services/HostLabelRuleEngineService.js +141 -92
  671. package/build/dist/Server/Services/HostLabelRuleEngineService.js.map +1 -1
  672. package/build/dist/Server/Services/HostOwnerRuleEngineService.js +190 -102
  673. package/build/dist/Server/Services/HostOwnerRuleEngineService.js.map +1 -1
  674. package/build/dist/Server/Services/IncidentEpisodeLabelRuleEngineService.js +112 -56
  675. package/build/dist/Server/Services/IncidentEpisodeLabelRuleEngineService.js.map +1 -1
  676. package/build/dist/Server/Services/IncidentEpisodeOwnerRuleEngineService.js +220 -63
  677. package/build/dist/Server/Services/IncidentEpisodeOwnerRuleEngineService.js.map +1 -1
  678. package/build/dist/Server/Services/IncidentEpisodePrivacyRuleEngineService.js +87 -26
  679. package/build/dist/Server/Services/IncidentEpisodePrivacyRuleEngineService.js.map +1 -1
  680. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +24 -0
  681. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
  682. package/build/dist/Server/Services/IncidentLabelRuleEngineService.js +258 -192
  683. package/build/dist/Server/Services/IncidentLabelRuleEngineService.js.map +1 -1
  684. package/build/dist/Server/Services/IncidentOwnerRuleEngineService.js +519 -376
  685. package/build/dist/Server/Services/IncidentOwnerRuleEngineService.js.map +1 -1
  686. package/build/dist/Server/Services/IncidentPrivacyRuleEngineService.js +95 -32
  687. package/build/dist/Server/Services/IncidentPrivacyRuleEngineService.js.map +1 -1
  688. package/build/dist/Server/Services/IncidentPublicNoteService.js +24 -0
  689. package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
  690. package/build/dist/Server/Services/IncidentService.js +90 -5
  691. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  692. package/build/dist/Server/Services/IncomingCallPolicyLabelRuleEngineService.js +113 -65
  693. package/build/dist/Server/Services/IncomingCallPolicyLabelRuleEngineService.js.map +1 -1
  694. package/build/dist/Server/Services/IncomingCallPolicyOwnerRuleEngineService.js +171 -83
  695. package/build/dist/Server/Services/IncomingCallPolicyOwnerRuleEngineService.js.map +1 -1
  696. package/build/dist/Server/Services/Index.js +6 -4
  697. package/build/dist/Server/Services/Index.js.map +1 -1
  698. package/build/dist/Server/Services/IoTFleetLabelRuleEngineService.js +117 -69
  699. package/build/dist/Server/Services/IoTFleetLabelRuleEngineService.js.map +1 -1
  700. package/build/dist/Server/Services/IoTFleetOwnerRuleEngineService.js +171 -83
  701. package/build/dist/Server/Services/IoTFleetOwnerRuleEngineService.js.map +1 -1
  702. package/build/dist/Server/Services/KubernetesClusterLabelRuleEngineService.js +145 -91
  703. package/build/dist/Server/Services/KubernetesClusterLabelRuleEngineService.js.map +1 -1
  704. package/build/dist/Server/Services/KubernetesClusterOwnerRuleEngineService.js +191 -101
  705. package/build/dist/Server/Services/KubernetesClusterOwnerRuleEngineService.js.map +1 -1
  706. package/build/dist/Server/Services/LabelService.js +20 -25
  707. package/build/dist/Server/Services/LabelService.js.map +1 -1
  708. package/build/dist/Server/Services/MonitorLabelRuleEngineService.js +123 -77
  709. package/build/dist/Server/Services/MonitorLabelRuleEngineService.js.map +1 -1
  710. package/build/dist/Server/Services/MonitorOwnerRuleEngineService.js +167 -82
  711. package/build/dist/Server/Services/MonitorOwnerRuleEngineService.js.map +1 -1
  712. package/build/dist/Server/Services/MonitorProbeService.js +18 -2
  713. package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
  714. package/build/dist/Server/Services/MonitorService.js +11 -9
  715. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  716. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +287 -5
  717. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
  718. package/build/dist/Server/Services/NetworkDeviceDiagnosticService.js +333 -0
  719. package/build/dist/Server/Services/NetworkDeviceDiagnosticService.js.map +1 -0
  720. package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js +117 -69
  721. package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js.map +1 -1
  722. package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js +171 -83
  723. package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js.map +1 -1
  724. package/build/dist/Server/Services/NetworkDeviceService.js +36 -2
  725. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  726. package/build/dist/Server/Services/OnCallDutyPolicyLabelRuleEngineService.js +117 -64
  727. package/build/dist/Server/Services/OnCallDutyPolicyLabelRuleEngineService.js.map +1 -1
  728. package/build/dist/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.js +173 -83
  729. package/build/dist/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.js.map +1 -1
  730. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.js +116 -65
  731. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.js.map +1 -1
  732. package/build/dist/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.js +171 -83
  733. package/build/dist/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.js.map +1 -1
  734. package/build/dist/Server/Services/PodmanHostLabelRuleEngineService.js +141 -92
  735. package/build/dist/Server/Services/PodmanHostLabelRuleEngineService.js.map +1 -1
  736. package/build/dist/Server/Services/PodmanHostOwnerRuleEngineService.js +189 -101
  737. package/build/dist/Server/Services/PodmanHostOwnerRuleEngineService.js.map +1 -1
  738. package/build/dist/Server/Services/ProjectService.js +82 -10
  739. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  740. package/build/dist/Server/Services/ProxmoxClusterLabelRuleEngineService.js +141 -92
  741. package/build/dist/Server/Services/ProxmoxClusterLabelRuleEngineService.js.map +1 -1
  742. package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js +189 -101
  743. package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js.map +1 -1
  744. package/build/dist/Server/Services/RumApplicationLabelRuleEngineService.js +111 -63
  745. package/build/dist/Server/Services/RumApplicationLabelRuleEngineService.js.map +1 -1
  746. package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js +161 -77
  747. package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js.map +1 -1
  748. package/build/dist/Server/Services/RunbookLabelRuleEngineService.js +117 -69
  749. package/build/dist/Server/Services/RunbookLabelRuleEngineService.js.map +1 -1
  750. package/build/dist/Server/Services/RunbookOwnerRuleEngineService.js +171 -83
  751. package/build/dist/Server/Services/RunbookOwnerRuleEngineService.js.map +1 -1
  752. package/build/dist/Server/Services/ScheduledMaintenanceLabelRuleEngineService.js +280 -209
  753. package/build/dist/Server/Services/ScheduledMaintenanceLabelRuleEngineService.js.map +1 -1
  754. package/build/dist/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.js +521 -376
  755. package/build/dist/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.js.map +1 -1
  756. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +24 -0
  757. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
  758. package/build/dist/Server/Services/ScheduledMaintenanceService.js +24 -8
  759. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  760. package/build/dist/Server/Services/SecurityEventConnectionService.js +43 -3
  761. package/build/dist/Server/Services/SecurityEventConnectionService.js.map +1 -1
  762. package/build/dist/Server/Services/ServerlessFunctionLabelRuleEngineService.js +115 -62
  763. package/build/dist/Server/Services/ServerlessFunctionLabelRuleEngineService.js.map +1 -1
  764. package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js +163 -77
  765. package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js.map +1 -1
  766. package/build/dist/Server/Services/ServiceLabelRuleEngineService.js +141 -92
  767. package/build/dist/Server/Services/ServiceLabelRuleEngineService.js.map +1 -1
  768. package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js +769 -18
  769. package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js.map +1 -1
  770. package/build/dist/Server/Services/ServiceLevelObjectiveFeedService.js +96 -0
  771. package/build/dist/Server/Services/ServiceLevelObjectiveFeedService.js.map +1 -0
  772. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js +614 -87
  773. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js.map +1 -1
  774. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleService.js +844 -0
  775. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleService.js.map +1 -0
  776. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js +207 -1
  777. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js.map +1 -1
  778. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js +221 -1
  779. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js.map +1 -1
  780. package/build/dist/Server/Services/ServiceLevelObjectiveService.js +997 -50
  781. package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
  782. package/build/dist/Server/Services/ServiceOwnerRuleEngineService.js +191 -102
  783. package/build/dist/Server/Services/ServiceOwnerRuleEngineService.js.map +1 -1
  784. package/build/dist/Server/Services/StatusPageAnnouncementService.js +12 -0
  785. package/build/dist/Server/Services/StatusPageAnnouncementService.js.map +1 -1
  786. package/build/dist/Server/Services/StatusPageLabelRuleEngineService.js +118 -70
  787. package/build/dist/Server/Services/StatusPageLabelRuleEngineService.js.map +1 -1
  788. package/build/dist/Server/Services/StatusPageOwnerRuleEngineService.js +158 -76
  789. package/build/dist/Server/Services/StatusPageOwnerRuleEngineService.js.map +1 -1
  790. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js +19 -215
  791. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js.map +1 -1
  792. package/build/dist/Server/Services/StatusPageSubscriberService.js +6 -0
  793. package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
  794. package/build/dist/Server/Services/TelemetryUsageBillingService.js +27 -5
  795. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  796. package/build/dist/Server/Services/ThreatIntelFeedService.js +1 -1
  797. package/build/dist/Server/Services/VMwareVCenterLabelRuleEngineService.js +141 -92
  798. package/build/dist/Server/Services/VMwareVCenterLabelRuleEngineService.js.map +1 -1
  799. package/build/dist/Server/Services/VMwareVCenterOwnerRuleEngineService.js +189 -101
  800. package/build/dist/Server/Services/VMwareVCenterOwnerRuleEngineService.js.map +1 -1
  801. package/build/dist/Server/Services/WorkflowLabelRuleEngineService.js +117 -69
  802. package/build/dist/Server/Services/WorkflowLabelRuleEngineService.js.map +1 -1
  803. package/build/dist/Server/Services/WorkflowOwnerRuleEngineService.js +171 -83
  804. package/build/dist/Server/Services/WorkflowOwnerRuleEngineService.js.map +1 -1
  805. package/build/dist/Server/Utils/AI/AlertAIContextBuilder.js +17 -0
  806. package/build/dist/Server/Utils/AI/AlertAIContextBuilder.js.map +1 -1
  807. package/build/dist/Server/Utils/AI/IncidentAIContextBuilder.js +31 -0
  808. package/build/dist/Server/Utils/AI/IncidentAIContextBuilder.js.map +1 -1
  809. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js +24 -1
  810. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js.map +1 -1
  811. package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js +21 -1
  812. package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js.map +1 -1
  813. package/build/dist/Server/Utils/AI/Toolbox/SloTools.js +337 -53
  814. package/build/dist/Server/Utils/AI/Toolbox/SloTools.js.map +1 -1
  815. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +108 -15
  816. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -1
  817. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.js +2 -2
  818. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.js.map +1 -1
  819. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloWidget.js +115 -6
  820. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloWidget.js.map +1 -1
  821. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +13 -0
  822. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
  823. package/build/dist/Server/Utils/Database/RelationValueUtil.js +82 -0
  824. package/build/dist/Server/Utils/Database/RelationValueUtil.js.map +1 -0
  825. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +10 -6
  826. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
  827. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +17 -21
  828. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
  829. package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js +5 -4
  830. package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js.map +1 -1
  831. package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js +50 -10
  832. package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js.map +1 -1
  833. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +13 -1
  834. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
  835. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +6 -10
  836. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -1
  837. package/build/dist/Server/Utils/Rules/MonitorRulePatternValidator.js +34 -0
  838. package/build/dist/Server/Utils/Rules/MonitorRulePatternValidator.js.map +1 -0
  839. package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js +69 -0
  840. package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js.map +1 -0
  841. package/build/dist/Server/Utils/Rules/RuleRun/RuleApplication.js +25 -0
  842. package/build/dist/Server/Utils/Rules/RuleRun/RuleApplication.js.map +1 -0
  843. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunPermission.js +128 -0
  844. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunPermission.js.map +1 -0
  845. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +746 -0
  846. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -0
  847. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunner.js +221 -0
  848. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunner.js.map +1 -0
  849. package/build/dist/Server/Utils/SecurityEvent/ConnectorErrorMessage.js +3 -2
  850. package/build/dist/Server/Utils/SecurityEvent/ConnectorErrorMessage.js.map +1 -1
  851. package/build/dist/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.js +6 -4
  852. package/build/dist/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.js.map +1 -1
  853. package/build/dist/Server/Utils/SecurityEvent/{GoogleSecOps → Connectors/GoogleSecOps}/GoogleSecOpsClient.js +174 -14
  854. package/build/dist/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsClient.js.map +1 -0
  855. package/build/dist/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnector.js +1417 -0
  856. package/build/dist/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnector.js.map +1 -0
  857. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.js +138 -18
  858. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.js.map +1 -1
  859. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.js +1 -2
  860. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.js.map +1 -1
  861. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.js +23 -18
  862. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.js.map +1 -1
  863. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry.js +2 -0
  864. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry.js.map +1 -1
  865. package/build/dist/Server/Utils/SecurityEvent/Connectors/Types.js +95 -0
  866. package/build/dist/Server/Utils/SecurityEvent/Connectors/Types.js.map +1 -1
  867. package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js +1 -1
  868. package/build/dist/Server/Utils/SecurityEvent/SecurityEventDedupe.js +3 -3
  869. package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.js +2 -2
  870. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +118 -40
  871. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
  872. package/build/dist/Server/Utils/Slo/SloFeedUtil.js +150 -0
  873. package/build/dist/Server/Utils/Slo/SloFeedUtil.js.map +1 -0
  874. package/build/dist/Server/Utils/Slo/SloLegacyMonitorLabelAdoption.js +136 -0
  875. package/build/dist/Server/Utils/Slo/SloLegacyMonitorLabelAdoption.js.map +1 -0
  876. package/build/dist/Server/Utils/Slo/SloMetricUtil.js +269 -0
  877. package/build/dist/Server/Utils/Slo/SloMetricUtil.js.map +1 -0
  878. package/build/dist/Server/Utils/Slo/SloOwnerReferenceValidator.js +134 -0
  879. package/build/dist/Server/Utils/Slo/SloOwnerReferenceValidator.js.map +1 -0
  880. package/build/dist/Server/Utils/Slo/SloRecordReferenceValidator.js +137 -0
  881. package/build/dist/Server/Utils/Slo/SloRecordReferenceValidator.js.map +1 -0
  882. package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js +6 -26
  883. package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js.map +1 -1
  884. package/build/dist/Server/Utils/StatusPageResource.js +31 -5
  885. package/build/dist/Server/Utils/StatusPageResource.js.map +1 -1
  886. package/build/dist/Types/Billing/SubscriptionStatus.js +37 -3
  887. package/build/dist/Types/Billing/SubscriptionStatus.js.map +1 -1
  888. package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
  889. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  890. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +5 -0
  891. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
  892. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloListComponent.js +2 -0
  893. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloListComponent.js.map +1 -0
  894. package/build/dist/Types/Dashboard/DashboardTemplates.js +275 -286
  895. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  896. package/build/dist/Types/Database/EnableAuditLog.js +19 -1
  897. package/build/dist/Types/Database/EnableAuditLog.js.map +1 -1
  898. package/build/dist/Types/Email/EmailTemplateType.js +4 -0
  899. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  900. package/build/dist/Types/Monitor/CriteriaFilter.js +45 -6
  901. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  902. package/build/dist/Types/Monitor/MonitorStep.js +2 -0
  903. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  904. package/build/dist/Types/Monitor/MonitorStepDnsMonitor.js +3 -1
  905. package/build/dist/Types/Monitor/MonitorStepDnsMonitor.js.map +1 -1
  906. package/build/dist/Types/Monitor/MonitorStepDnssecMonitor.js +3 -1
  907. package/build/dist/Types/Monitor/MonitorStepDnssecMonitor.js.map +1 -1
  908. package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js +3 -1
  909. package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js.map +1 -1
  910. package/build/dist/Types/Monitor/MonitorStepExternalStatusPageMonitor.js +3 -1
  911. package/build/dist/Types/Monitor/MonitorStepExternalStatusPageMonitor.js.map +1 -1
  912. package/build/dist/Types/Monitor/MonitorStepRetries.js +47 -0
  913. package/build/dist/Types/Monitor/MonitorStepRetries.js.map +1 -0
  914. package/build/dist/Types/Monitor/MonitorStepSnmpMonitor.js +3 -1
  915. package/build/dist/Types/Monitor/MonitorStepSnmpMonitor.js.map +1 -1
  916. package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticResult.js +29 -0
  917. package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticResult.js.map +1 -0
  918. package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticStatus.js +37 -0
  919. package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticStatus.js.map +1 -0
  920. package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticType.js +42 -0
  921. package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticType.js.map +1 -0
  922. package/build/dist/Types/NetworkDevice/NetworkDevicePingMetricNames.js +20 -0
  923. package/build/dist/Types/NetworkDevice/NetworkDevicePingMetricNames.js.map +1 -0
  924. package/build/dist/Types/Permission.js +114 -0
  925. package/build/dist/Types/Permission.js.map +1 -1
  926. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +5 -0
  927. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
  928. package/build/dist/Types/Rules/RuleRun.js +267 -0
  929. package/build/dist/Types/Rules/RuleRun.js.map +1 -0
  930. package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -1
  931. package/build/dist/Types/SecurityEvent/Connectors/ConnectorDiagnostics.js.map +1 -1
  932. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics.js +16 -1
  933. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics.js.map +1 -1
  934. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js +65 -0
  935. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js.map +1 -1
  936. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorProvider.js +6 -2
  937. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorProvider.js.map +1 -1
  938. package/build/dist/Types/ServiceLevelObjective/SloHistoryMetricName.js +26 -0
  939. package/build/dist/Types/ServiceLevelObjective/SloHistoryMetricName.js.map +1 -0
  940. package/build/dist/Types/ServiceLevelObjective/SloMetricType.js +45 -0
  941. package/build/dist/Types/ServiceLevelObjective/SloMetricType.js.map +1 -0
  942. package/build/dist/Types/StatusPage/StatusPageSubscriberNotificationEventType.js +4 -0
  943. package/build/dist/Types/StatusPage/StatusPageSubscriberNotificationEventType.js.map +1 -1
  944. package/build/dist/Types/StatusPage/SubscriberNotificationTemplateVariables.js +295 -0
  945. package/build/dist/Types/StatusPage/SubscriberNotificationTemplateVariables.js.map +1 -0
  946. package/build/dist/Types/StatusPage/SubscriberNotificationTrigger.js +13 -0
  947. package/build/dist/Types/StatusPage/SubscriberNotificationTrigger.js.map +1 -0
  948. package/build/dist/Types/StatusPage/SubscriberUpdateNotification.js +67 -0
  949. package/build/dist/Types/StatusPage/SubscriberUpdateNotification.js.map +1 -0
  950. package/build/dist/Types/Telemetry/LockedFilterDetail.js +7 -7
  951. package/build/dist/Types/Telemetry/ServiceType.js +7 -0
  952. package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
  953. package/build/dist/UI/Components/AlertBanner/AlertBanner.js +48 -19
  954. package/build/dist/UI/Components/AlertBanner/AlertBanner.js.map +1 -1
  955. package/build/dist/UI/Components/BulkUpdate/BulkArchiveActions.js +10 -2
  956. package/build/dist/UI/Components/BulkUpdate/BulkArchiveActions.js.map +1 -1
  957. package/build/dist/UI/Components/Detail/Detail.js +12 -3
  958. package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
  959. package/build/dist/UI/Components/Dropdown/Dropdown.js +33 -5
  960. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  961. package/build/dist/UI/Components/EmptyState/EmptyState.js +3 -3
  962. package/build/dist/UI/Components/EmptyState/EmptyState.js.map +1 -1
  963. package/build/dist/UI/Components/EmptyState/EmptyStateGuideLinks.js +47 -0
  964. package/build/dist/UI/Components/EmptyState/EmptyStateGuideLinks.js.map +1 -0
  965. package/build/dist/UI/Components/Forms/ModelForm.js +6 -5
  966. package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
  967. package/build/dist/UI/Components/LabelRule/LabelRuleTable.js +6 -2
  968. package/build/dist/UI/Components/LabelRule/LabelRuleTable.js.map +1 -1
  969. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +1 -1
  970. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  971. package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js +0 -2
  972. package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js.map +1 -1
  973. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +3 -1
  974. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  975. package/build/dist/UI/Components/RuleRun/RuleDetailFields.js +226 -0
  976. package/build/dist/UI/Components/RuleRun/RuleDetailFields.js.map +1 -0
  977. package/build/dist/UI/Components/RuleRun/RuleTable.js +97 -0
  978. package/build/dist/UI/Components/RuleRun/RuleTable.js.map +1 -0
  979. package/build/dist/UI/Components/RuleRun/RuleView.js +83 -0
  980. package/build/dist/UI/Components/RuleRun/RuleView.js.map +1 -0
  981. package/build/dist/UI/Components/RuleRun/RunRuleNowModal.js +74 -0
  982. package/build/dist/UI/Components/RuleRun/RunRuleNowModal.js.map +1 -0
  983. package/build/dist/UI/Components/RuleRun/RunRulesBulkAction.js +78 -0
  984. package/build/dist/UI/Components/RuleRun/RunRulesBulkAction.js.map +1 -0
  985. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +1 -1
  986. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
  987. package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js +24 -50
  988. package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js.map +1 -1
  989. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryActiveFilterChips.js +0 -4
  990. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryActiveFilterChips.js.map +1 -1
  991. package/build/dist/UI/Utils/Rules/RuleRunClient.js +98 -0
  992. package/build/dist/UI/Utils/Rules/RuleRunClient.js.map +1 -0
  993. package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js +8 -0
  994. package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js.map +1 -1
  995. package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js +16 -2
  996. package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js.map +1 -1
  997. package/build/dist/Utils/Dashboard/Components/DashboardSloListComponent.js +94 -0
  998. package/build/dist/Utils/Dashboard/Components/DashboardSloListComponent.js.map +1 -0
  999. package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
  1000. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  1001. package/build/dist/Utils/Dashboard/SloWidgetSource.js +125 -0
  1002. package/build/dist/Utils/Dashboard/SloWidgetSource.js.map +1 -0
  1003. package/build/dist/Utils/Markdown/MarkdownEscape.js +49 -0
  1004. package/build/dist/Utils/Markdown/MarkdownEscape.js.map +1 -0
  1005. package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js +112 -34
  1006. package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js.map +1 -1
  1007. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js +22 -0
  1008. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js.map +1 -1
  1009. package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js +129 -0
  1010. package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js.map +1 -0
  1011. package/build/dist/Utils/NetworkDiscovery/RunImportedDeviceNaming.js +255 -0
  1012. package/build/dist/Utils/NetworkDiscovery/RunImportedDeviceNaming.js.map +1 -0
  1013. package/build/dist/Utils/NetworkDiscovery/ShortDeviceNamePlanner.js +184 -0
  1014. package/build/dist/Utils/NetworkDiscovery/ShortDeviceNamePlanner.js.map +1 -0
  1015. package/build/dist/Utils/NetworkDiscovery/ShortHostnameUtil.js +79 -0
  1016. package/build/dist/Utils/NetworkDiscovery/ShortHostnameUtil.js.map +1 -0
  1017. package/build/dist/Utils/NetworkSite/CidrMatchUtil.js +21 -12
  1018. package/build/dist/Utils/NetworkSite/CidrMatchUtil.js.map +1 -1
  1019. package/build/dist/Utils/Project/DataResidency.js +51 -0
  1020. package/build/dist/Utils/Project/DataResidency.js.map +1 -0
  1021. package/build/dist/Utils/Rules/RuleRunSummary.js +197 -0
  1022. package/build/dist/Utils/Rules/RuleRunSummary.js.map +1 -0
  1023. package/build/dist/Utils/Slo/SloAffectedResourceMarkdown.js +51 -0
  1024. package/build/dist/Utils/Slo/SloAffectedResourceMarkdown.js.map +1 -0
  1025. package/build/dist/Utils/Slo/SloBurnRateTemplate.js +228 -0
  1026. package/build/dist/Utils/Slo/SloBurnRateTemplate.js.map +1 -0
  1027. package/build/dist/Utils/Slo/SloFeedMarkdown.js +934 -0
  1028. package/build/dist/Utils/Slo/SloFeedMarkdown.js.map +1 -0
  1029. package/build/dist/Utils/Slo/SloHealth.js +75 -9
  1030. package/build/dist/Utils/Slo/SloHealth.js.map +1 -1
  1031. package/build/dist/Utils/Slo/SloListWidgetFormat.js +217 -0
  1032. package/build/dist/Utils/Slo/SloListWidgetFormat.js.map +1 -0
  1033. package/build/dist/Utils/Slo/SloMetricType.js +212 -0
  1034. package/build/dist/Utils/Slo/SloMetricType.js.map +1 -0
  1035. package/build/dist/Utils/Slo/SloMonitorRuleCriteria.js +216 -0
  1036. package/build/dist/Utils/Slo/SloMonitorRuleCriteria.js.map +1 -0
  1037. package/build/dist/Utils/Slo/SloMonitorStatusSummary.js +129 -0
  1038. package/build/dist/Utils/Slo/SloMonitorStatusSummary.js.map +1 -0
  1039. package/build/dist/Utils/Slo/SloOverviewText.js +110 -0
  1040. package/build/dist/Utils/Slo/SloOverviewText.js.map +1 -0
  1041. package/build/dist/Utils/Slo/SloProjection.js +448 -0
  1042. package/build/dist/Utils/Slo/SloProjection.js.map +1 -0
  1043. package/build/dist/Utils/Slo/SloWidgetFormat.js +4 -2
  1044. package/build/dist/Utils/Slo/SloWidgetFormat.js.map +1 -1
  1045. package/build/dist/Utils/Telemetry/LockedFilterSearch.js +1 -26
  1046. package/build/dist/Utils/Telemetry/LockedFilterSearch.js.map +1 -1
  1047. package/package.json +1 -1
  1048. package/Models/DatabaseModels/GoogleSecOpsConnection.ts +0 -447
  1049. package/Models/DatabaseModels/GoogleSecOpsConnectionRun.ts +0 -263
  1050. package/Server/API/GoogleSecOpsConnectionAPI.ts +0 -320
  1051. package/Server/Services/GoogleSecOpsConnectionRunService.ts +0 -10
  1052. package/Server/Services/GoogleSecOpsConnectionService.ts +0 -116
  1053. package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsConnectionTester.ts +0 -777
  1054. package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.ts +0 -1373
  1055. package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.ts +0 -512
  1056. package/Tests/App/Dashboard/GoogleSecOpsConnectionForm.test.tsx +0 -838
  1057. package/Tests/App/Dashboard/GoogleSecOpsConnectionsErrors.test.tsx +0 -441
  1058. package/Tests/App/Dashboard/GoogleSecOpsDiagnostics.test.tsx +0 -1001
  1059. package/Tests/Server/API/GoogleSecOpsConnectionAPI.test.ts +0 -657
  1060. package/Tests/Server/Services/GoogleSecOpsDiagnosticsModel.test.ts +0 -153
  1061. package/Tests/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsConnectionTester.test.ts +0 -784
  1062. package/Tests/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.test.ts +0 -823
  1063. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsDiagnostics.test.ts +0 -918
  1064. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPoller.test.ts +0 -738
  1065. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerFailureTaxonomy.test.ts +0 -874
  1066. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerHardening.test.ts +0 -1297
  1067. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsThreePassPoller.test.ts +0 -1577
  1068. package/Tests/UI/Components/LockedFilterActions.test.tsx +0 -396
  1069. package/Types/SecurityEvent/GoogleSecOpsDiagnostics.ts +0 -111
  1070. package/UI/Components/TelemetryViewer/components/LockedFilterActions.tsx +0 -205
  1071. package/build/dist/Models/DatabaseModels/GoogleSecOpsConnection.js +0 -478
  1072. package/build/dist/Models/DatabaseModels/GoogleSecOpsConnection.js.map +0 -1
  1073. package/build/dist/Models/DatabaseModels/GoogleSecOpsConnectionRun.js +0 -287
  1074. package/build/dist/Models/DatabaseModels/GoogleSecOpsConnectionRun.js.map +0 -1
  1075. package/build/dist/Server/API/GoogleSecOpsConnectionAPI.js +0 -231
  1076. package/build/dist/Server/API/GoogleSecOpsConnectionAPI.js.map +0 -1
  1077. package/build/dist/Server/Services/GoogleSecOpsConnectionRunService.js +0 -9
  1078. package/build/dist/Server/Services/GoogleSecOpsConnectionRunService.js.map +0 -1
  1079. package/build/dist/Server/Services/GoogleSecOpsConnectionService.js +0 -70
  1080. package/build/dist/Server/Services/GoogleSecOpsConnectionService.js.map +0 -1
  1081. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js.map +0 -1
  1082. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsConnectionTester.js +0 -537
  1083. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsConnectionTester.js.map +0 -1
  1084. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js +0 -1034
  1085. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js.map +0 -1
  1086. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.js +0 -410
  1087. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.js.map +0 -1
  1088. package/build/dist/Types/SecurityEvent/GoogleSecOpsDiagnostics.js +0 -2
  1089. package/build/dist/Types/SecurityEvent/GoogleSecOpsDiagnostics.js.map +0 -1
  1090. package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterActions.js +0 -88
  1091. package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterActions.js.map +0 -1
@@ -0,0 +1,1764 @@
1
+ import "@testing-library/jest-dom";
2
+ import {
3
+ afterEach,
4
+ beforeEach,
5
+ describe,
6
+ expect,
7
+ jest,
8
+ test,
9
+ } from "@jest/globals";
10
+ import {
11
+ act,
12
+ cleanup,
13
+ fireEvent,
14
+ render,
15
+ screen,
16
+ waitFor,
17
+ within,
18
+ } from "@testing-library/react";
19
+ import React from "react";
20
+ import { MemoryRouter } from "react-router-dom";
21
+ import SecurityEventConnectionDiagnostics from "../../../../App/FeatureSet/Dashboard/src/Components/SecurityEvents/SecurityEventConnectionDiagnostics";
22
+ import SecurityEventConnectionRunDetails from "../../../../App/FeatureSet/Dashboard/src/Components/SecurityEvents/SecurityEventConnectionRunDetails";
23
+ import {
24
+ ConnectorProviderDetailGroup,
25
+ connectionEventAttributeKey,
26
+ connectionEventsRoute,
27
+ connectorHealth,
28
+ connectorProviderDetailGroups,
29
+ connectorProviderTitle,
30
+ connectorSampleEventTime,
31
+ connectorSampleTitle,
32
+ connectorScopeImportNoun,
33
+ connectorScopeLabel,
34
+ connectorScopeSummary,
35
+ normalizeConnectorCheckStatus,
36
+ readConnectorProviderDetails,
37
+ validateConnectionRange,
38
+ } from "../../../../App/FeatureSet/Dashboard/src/Components/SecurityEvents/SecurityEventConnectionDiagnosticsUtil";
39
+ import { RouteUtil } from "../../../../App/FeatureSet/Dashboard/src/Utils/RouteMap";
40
+ import SecurityEventConnection from "../../../Models/DatabaseModels/SecurityEventConnection";
41
+ import SecurityEventConnectionRun from "../../../Models/DatabaseModels/SecurityEventConnectionRun";
42
+ import HTTPErrorResponse from "../../../Types/API/HTTPErrorResponse";
43
+ import HTTPResponse from "../../../Types/API/HTTPResponse";
44
+ import Route from "../../../Types/API/Route";
45
+ import InBetween from "../../../Types/BaseDatabase/InBetween";
46
+ import ListResult from "../../../Types/BaseDatabase/ListResult";
47
+ import { JSONObject } from "../../../Types/JSON";
48
+ import JSONFunctions from "../../../Types/JSONFunctions";
49
+ import ObjectID from "../../../Types/ObjectID";
50
+ import {
51
+ SecurityConnectorSample,
52
+ SecurityConnectorTestReport,
53
+ } from "../../../Types/SecurityEvent/Connectors/ConnectorDiagnostics";
54
+ import {
55
+ LEGACY_GOOGLE_SECOPS_CONNECTION_ID_ATTRIBUTE,
56
+ SECURITY_CONNECTION_ID_ATTRIBUTE,
57
+ SecurityEventConnectionRunResult,
58
+ SecurityEventConnectionRunStatus,
59
+ SecurityEventConnectionRunType,
60
+ } from "../../../Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics";
61
+ import {
62
+ SecurityEventConnectorDefinition,
63
+ getSecurityEventConnectorDefinition,
64
+ } from "../../../Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog";
65
+ import SecurityEventConnectorProvider from "../../../Types/SecurityEvent/Connectors/SecurityEventConnectorProvider";
66
+ import API from "../../../UI/Utils/API/API";
67
+ import ModelAPI from "../../../UI/Utils/ModelAPI/ModelAPI";
68
+
69
+ /*
70
+ * The diagnostics modal, run details and their util, driven by a Google
71
+ * SecOps connection. Most cases are ported from the retired
72
+ * GoogleSecOpsDiagnostics suite, which pinned the same behaviour on the
73
+ * Google-only copies of these components; the rest pin what the merge
74
+ * added: catalog-driven wording (Data to import, Preview detections), the
75
+ * provider diagnostics and alert flag a SecOps run reports, and run history
76
+ * carried over from the retired connector (no provider, legacy sample and
77
+ * check shapes, and events stamped with the legacy connection attribute).
78
+ */
79
+
80
+ const GOOGLE: string = SecurityEventConnectorProvider.GoogleSecOps;
81
+ const OKTA: string = SecurityEventConnectorProvider.OktaSystemLog;
82
+ const CONNECTION_ID: string = "11111111-1111-4111-8111-111111111111";
83
+ const PROJECT_ID: string = "22222222-2222-4222-8222-222222222222";
84
+ const RUN_ID: string = "33333333-3333-4333-8333-333333333333";
85
+ const NOW: number = new Date("2026-09-10T12:00:00Z").getTime();
86
+
87
+ type SecurityEventConnectionOverrides = {
88
+ [Key in keyof SecurityEventConnection]?:
89
+ | SecurityEventConnection[Key]
90
+ | undefined;
91
+ };
92
+
93
+ function connection(
94
+ overrides: SecurityEventConnectionOverrides = {},
95
+ ): SecurityEventConnection {
96
+ const value: SecurityEventConnection = new SecurityEventConnection();
97
+ value._id = CONNECTION_ID;
98
+ value.projectId = new ObjectID(PROJECT_ID);
99
+ value.name = "Customer SecOps";
100
+ value.provider = SecurityEventConnectorProvider.GoogleSecOps;
101
+ value.config = {
102
+ region: "europe",
103
+ instanceResourceName: "projects/acme/locations/europe/instances/i",
104
+ };
105
+ value.isEnabled = true;
106
+ value.pollIntervalInMinutes = 5;
107
+ value.alertingOnly = true;
108
+ value.createdAt = new Date(NOW - 60_000);
109
+ Object.assign(value, overrides);
110
+ return value;
111
+ }
112
+
113
+ function sample(
114
+ overrides: Partial<SecurityConnectorSample> = {},
115
+ ): SecurityConnectorSample {
116
+ return {
117
+ id: "detection-1",
118
+ title: "Successful brute force",
119
+ severity: "High",
120
+ eventTime: "2026-09-09T01:30:30Z",
121
+ createdTime: "2026-09-10T04:16:58.612Z",
122
+ isAlert: true,
123
+ ...overrides,
124
+ };
125
+ }
126
+
127
+ function result(
128
+ overrides: Partial<SecurityEventConnectionRunResult> = {},
129
+ ): SecurityEventConnectionRunResult {
130
+ return {
131
+ type: "poll",
132
+ provider: GOOGLE,
133
+ status: "success",
134
+ startedAt: "2026-09-10T11:59:00Z",
135
+ completedAt: "2026-09-10T12:00:00Z",
136
+ durationMs: 60000,
137
+ windowStart: "2026-09-10T04:00:00Z",
138
+ windowEnd: "2026-09-10T05:00:00Z",
139
+ fetchedCount: 1,
140
+ ingestedCount: 1,
141
+ duplicateCount: 0,
142
+ rejectedCount: 0,
143
+ failedCount: 0,
144
+ complete: true,
145
+ requestCount: 1,
146
+ warnings: [],
147
+ samples: [sample()],
148
+ checks: [
149
+ {
150
+ key: "read-rule-detections",
151
+ name: "Read rule detections by created time",
152
+ status: "pass",
153
+ durationMs: 500,
154
+ message: "Detection read access verified.",
155
+ },
156
+ ],
157
+ eventTimeStart: "2026-09-09T01:30:30Z",
158
+ eventTimeEnd: "2026-09-09T01:30:30Z",
159
+ ...overrides,
160
+ };
161
+ }
162
+
163
+ // What a synchronous Test connection stores as its run's result.
164
+ function testReport(
165
+ overrides: Partial<SecurityConnectorTestReport> = {},
166
+ ): SecurityConnectorTestReport {
167
+ return {
168
+ provider: GOOGLE,
169
+ status: "pass",
170
+ startedAt: "2026-09-10T11:59:58.000Z",
171
+ completedAt: "2026-09-10T12:00:00.000Z",
172
+ durationMs: 2000,
173
+ checks: [
174
+ {
175
+ key: "authentication",
176
+ name: "Authenticate with Google",
177
+ status: "pass",
178
+ durationMs: 300,
179
+ message: "Google accepted the service account credentials.",
180
+ },
181
+ {
182
+ key: "worker-consumers",
183
+ name: "Background workers",
184
+ status: "pass",
185
+ durationMs: 10,
186
+ message: "2 worker processes are consuming the queue.",
187
+ },
188
+ ],
189
+ summary: "Google SecOps is reachable, credentials are accepted.",
190
+ ...overrides,
191
+ };
192
+ }
193
+
194
+ function testRequestUrls(): Array<string> {
195
+ return jest
196
+ .mocked(API.post)
197
+ .mock.calls.map((call: Array<unknown>): string => {
198
+ return String((call[0] as { url: unknown }).url);
199
+ });
200
+ }
201
+
202
+ function run(
203
+ status: SecurityEventConnectionRunStatus = "success",
204
+ type: SecurityEventConnectionRunType = "poll",
205
+ value?: SecurityEventConnectionRunResult | JSONObject,
206
+ ): SecurityEventConnectionRun {
207
+ const model: SecurityEventConnectionRun = new SecurityEventConnectionRun();
208
+ model._id = RUN_ID;
209
+ model.securityEventConnectionId = new ObjectID(CONNECTION_ID);
210
+ model.type = type;
211
+ model.status = status;
212
+ model.createdAt = new Date(NOW - 60_000);
213
+ model.requestedByUserId = new ObjectID(PROJECT_ID);
214
+ if (status !== "queued" && status !== "running") {
215
+ model.startedAt = new Date(NOW - 60_000);
216
+ model.completedAt = new Date(NOW);
217
+ model.result = (value || result({ type, status })) as unknown as JSONObject;
218
+ }
219
+ return model;
220
+ }
221
+
222
+ function history(
223
+ data: Array<SecurityEventConnectionRun>,
224
+ ): ListResult<SecurityEventConnectionRun> {
225
+ return { data, count: data.length, skip: 0, limit: 20 };
226
+ }
227
+
228
+ function renderDiagnostics(
229
+ data: {
230
+ canRun?: boolean;
231
+ initialAction?: "test" | "poll";
232
+ item?: SecurityEventConnection;
233
+ } = {},
234
+ ): ReturnType<typeof render> {
235
+ return render(
236
+ <MemoryRouter>
237
+ <SecurityEventConnectionDiagnostics
238
+ connection={data.item || connection()}
239
+ canRun={data.canRun ?? true}
240
+ initialAction={data.initialAction}
241
+ onClose={(): void => {}}
242
+ onUpdated={(): void => {}}
243
+ />
244
+ </MemoryRouter>,
245
+ );
246
+ }
247
+
248
+ function renderRun(
249
+ value: SecurityEventConnectionRun,
250
+ provider?: string,
251
+ ): HTMLElement {
252
+ render(
253
+ <MemoryRouter>
254
+ <SecurityEventConnectionRunDetails run={value} provider={provider} />
255
+ </MemoryRouter>,
256
+ );
257
+ return screen.getByRole("region", { name: "Run details" });
258
+ }
259
+
260
+ function scheduledPolling(): HTMLElement {
261
+ return screen.getByRole("region", { name: "Scheduled polling" });
262
+ }
263
+
264
+ function eventsFilter(route: Route): JSONObject {
265
+ const text: string = route.toString();
266
+ const params: URLSearchParams = new URLSearchParams(
267
+ text.slice(text.indexOf("?")),
268
+ );
269
+ return JSONFunctions.deserialize(
270
+ JSON.parse(params.get("security-events-table-filter")!) as JSONObject,
271
+ );
272
+ }
273
+
274
+ function filterRange(filter: JSONObject): [string, string] {
275
+ const range: InBetween<Date> = filter["time"] as InBetween<Date>;
276
+ expect(range).toBeInstanceOf(InBetween);
277
+ return [
278
+ new Date(range.startValue).toISOString(),
279
+ new Date(range.endValue).toISOString(),
280
+ ];
281
+ }
282
+
283
+ describe("SecurityEventConnectionDiagnostics for a Google SecOps connection", () => {
284
+ beforeEach((): void => {
285
+ jest.useFakeTimers();
286
+ jest.setSystemTime(NOW);
287
+ jest.spyOn(ModelAPI, "getList").mockResolvedValue(history([]));
288
+ jest.spyOn(ModelAPI, "getItem").mockResolvedValue(connection());
289
+ jest
290
+ .spyOn(ModelAPI, "getCommonHeaders")
291
+ .mockReturnValue({ "project-id": PROJECT_ID });
292
+ jest
293
+ .spyOn(API, "post")
294
+ .mockResolvedValue(new HTTPResponse(200, { runId: RUN_ID }, {}));
295
+ jest
296
+ .spyOn(RouteUtil, "populateRouteParams")
297
+ .mockImplementation((): Route => {
298
+ /*
299
+ * A fresh Route per call: addQueryParams mutates the Route it is
300
+ * given, so a shared instance would carry one link's query into the
301
+ * next.
302
+ */
303
+ return new Route(`/dashboard/${PROJECT_ID}/security-events`);
304
+ });
305
+ });
306
+
307
+ afterEach((): void => {
308
+ cleanup();
309
+ jest.restoreAllMocks();
310
+ jest.useRealTimers();
311
+ });
312
+
313
+ test("loads tenant-scoped history and never requests credentials", async (): Promise<void> => {
314
+ renderDiagnostics();
315
+ expect(screen.getByText("Loading run history…")).toBeInTheDocument();
316
+ expect(await screen.findByText(/No runs recorded yet/)).toBeInTheDocument();
317
+ expect(ModelAPI.getList).toHaveBeenCalledWith(
318
+ expect.objectContaining({
319
+ modelType: SecurityEventConnectionRun,
320
+ query: {
321
+ projectId: new ObjectID(PROJECT_ID),
322
+ securityEventConnectionId: new ObjectID(CONNECTION_ID),
323
+ },
324
+ limit: 20,
325
+ skip: 0,
326
+ }),
327
+ );
328
+ expect(ModelAPI.getItem).toHaveBeenCalledWith(
329
+ expect.objectContaining({ id: new ObjectID(CONNECTION_ID) }),
330
+ );
331
+ expect(
332
+ jest.mocked(ModelAPI.getItem).mock.calls[0]?.[0].select,
333
+ ).not.toHaveProperty("secrets");
334
+ expect(
335
+ jest.mocked(ModelAPI.getItem).mock.calls[0]?.[0].select,
336
+ ).toHaveProperty("alertingOnly", true);
337
+ expect(API.post).not.toHaveBeenCalled();
338
+ });
339
+
340
+ /*
341
+ * google-diagnostics-test-still-queued: Test connection used to POST
342
+ * /:id/run and wait for a worker. It calls the synchronous endpoint and
343
+ * renders the checklist inline.
344
+ */
345
+ test("runs the synchronous connection test and renders its checklist inline", async (): Promise<void> => {
346
+ jest
347
+ .mocked(API.post)
348
+ .mockResolvedValue(
349
+ new HTTPResponse(200, testReport() as unknown as JSONObject, {}),
350
+ );
351
+ renderDiagnostics();
352
+ await screen.findByText(/No runs recorded yet/);
353
+ fireEvent.click(screen.getByRole("button", { name: "Test connection" }));
354
+ const report: HTMLElement = await screen.findByRole("region", {
355
+ name: "Connection test report",
356
+ });
357
+ expect(within(report).getByText("All checks passed")).toBeVisible();
358
+ expect(within(report).getByText("Background workers")).toBeVisible();
359
+ expect(report).toHaveTextContent("Access to Google SecOps");
360
+ expect(API.post).toHaveBeenCalledTimes(1);
361
+ expect(API.post).toHaveBeenCalledWith(
362
+ expect.objectContaining({
363
+ data: { connectionId: CONNECTION_ID },
364
+ headers: { "project-id": PROJECT_ID },
365
+ }),
366
+ );
367
+ expect(testRequestUrls()[0]).toContain("/security-event-connection/test");
368
+ expect(testRequestUrls()[0]).not.toContain("/run");
369
+ expect(testRequestUrls()[0]).not.toContain("google-secops-connection");
370
+ expect(
371
+ screen.getByText(/It runs immediately and imports nothing/),
372
+ ).toBeVisible();
373
+ });
374
+
375
+ test("Test connection stays available while a queued run waits for a worker", async (): Promise<void> => {
376
+ jest.mocked(ModelAPI.getList).mockResolvedValue(history([run("queued")]));
377
+ jest.mocked(API.post).mockResolvedValue(
378
+ new HTTPResponse(
379
+ 200,
380
+ testReport({
381
+ status: "fail",
382
+ summary: "1 check failed: Background workers.",
383
+ }) as unknown as JSONObject,
384
+ {},
385
+ ),
386
+ );
387
+ renderDiagnostics();
388
+ expect(
389
+ await screen.findByText(/Queued — waiting for a worker/),
390
+ ).toBeVisible();
391
+ expect(screen.getByRole("button", { name: "Run now" })).toBeDisabled();
392
+ const testButton: HTMLElement = screen.getByRole("button", {
393
+ name: "Test connection",
394
+ });
395
+ expect(testButton).toBeEnabled();
396
+ fireEvent.click(testButton);
397
+ expect(await screen.findByText("Some checks failed")).toBeVisible();
398
+ expect(testRequestUrls()).toEqual([
399
+ expect.stringContaining("/security-event-connection/test"),
400
+ ]);
401
+ });
402
+
403
+ test("a failed re-run clears the previous report instead of showing it beside the error", async (): Promise<void> => {
404
+ jest
405
+ .mocked(API.post)
406
+ .mockResolvedValueOnce(
407
+ new HTTPResponse(200, testReport() as unknown as JSONObject, {}),
408
+ )
409
+ .mockResolvedValueOnce(
410
+ new HTTPErrorResponse(
411
+ 500,
412
+ { message: "Test endpoint unavailable." },
413
+ {},
414
+ ),
415
+ );
416
+ renderDiagnostics();
417
+ await screen.findByText(/No runs recorded yet/);
418
+ fireEvent.click(screen.getByRole("button", { name: "Test connection" }));
419
+ expect(await screen.findByText("All checks passed")).toBeVisible();
420
+ fireEvent.click(screen.getByRole("button", { name: "Test connection" }));
421
+ expect(await screen.findByText(/Test endpoint unavailable/)).toBeVisible();
422
+ expect(screen.queryByText("All checks passed")).not.toBeInTheDocument();
423
+ });
424
+
425
+ test("an initial test action runs the synchronous test once", async (): Promise<void> => {
426
+ jest
427
+ .mocked(API.post)
428
+ .mockResolvedValue(
429
+ new HTTPResponse(200, testReport() as unknown as JSONObject, {}),
430
+ );
431
+ renderDiagnostics({ initialAction: "test" });
432
+ expect(await screen.findByText("All checks passed")).toBeVisible();
433
+ await act(async (): Promise<void> => {
434
+ jest.advanceTimersByTime(15000);
435
+ });
436
+ expect(testRequestUrls()).toEqual([
437
+ expect.stringContaining("/security-event-connection/test"),
438
+ ]);
439
+ });
440
+
441
+ test("the copy speaks in detections and the Data to import control", async (): Promise<void> => {
442
+ renderDiagnostics();
443
+ await screen.findByText(/No runs recorded yet/);
444
+
445
+ const scheduled: HTMLElement = scheduledPolling();
446
+ const scopeLabel: HTMLElement =
447
+ within(scheduled).getByText("Data to import");
448
+ expect(scopeLabel.tagName).toBe("DT");
449
+ expect(scopeLabel.parentElement).toHaveTextContent(
450
+ "Data to importAlerts only",
451
+ );
452
+ expect(within(scheduled).queryByText("Scope")).not.toBeInTheDocument();
453
+ expect(
454
+ screen.getByText(
455
+ /To import detections too, select Detections under Data to import using Edit connection\./,
456
+ ),
457
+ ).toBeVisible();
458
+ expect(
459
+ screen.queryByText(/Change settings using Edit connection/),
460
+ ).not.toBeInTheDocument();
461
+ expect(
462
+ screen.getByText(
463
+ /what it has available to import with and without Detections, and whether/,
464
+ ),
465
+ ).toBeVisible();
466
+ expect(
467
+ screen.getByRole("heading", { name: "Find historical detections" }),
468
+ ).toBeVisible();
469
+ expect(
470
+ screen.getByText(
471
+ /When Last Error says polling moved past a minute it could not read in full, import that minute here to recover what one run can read\./,
472
+ ),
473
+ ).toBeVisible();
474
+ expect(
475
+ screen.getByRole("button", { name: "Preview detections" }),
476
+ ).toBeVisible();
477
+ expect(
478
+ screen.queryByRole("button", { name: "Preview records" }),
479
+ ).not.toBeInTheDocument();
480
+ expect(screen.queryByText(/15 minutes/)).not.toBeInTheDocument();
481
+ });
482
+
483
+ test("a connection importing Detections too reads as Alerts and detections", async (): Promise<void> => {
484
+ const allDetections: SecurityEventConnection = connection({
485
+ alertingOnly: false,
486
+ });
487
+ jest.mocked(ModelAPI.getItem).mockResolvedValue(allDetections);
488
+ renderDiagnostics({ item: allDetections });
489
+ await screen.findByText(/No runs recorded yet/);
490
+
491
+ expect(
492
+ within(scheduledPolling()).getByText("Data to import").parentElement,
493
+ ).toHaveTextContent("Data to importAlerts and detections");
494
+ });
495
+
496
+ test("a provider without an alerting distinction keeps the generic wording in its own record name", async (): Promise<void> => {
497
+ const okta: SecurityEventConnection = connection({
498
+ name: "Acme Okta",
499
+ provider: SecurityEventConnectorProvider.OktaSystemLog,
500
+ config: { orgUrl: "https://acme.okta.com" },
501
+ });
502
+ jest.mocked(ModelAPI.getItem).mockResolvedValue(okta);
503
+ renderDiagnostics({ item: okta });
504
+ await screen.findByText(/No runs recorded yet/);
505
+
506
+ expect(
507
+ screen.getByText(/Change settings using Edit connection\./),
508
+ ).toBeVisible();
509
+ expect(
510
+ within(scheduledPolling()).queryByText("Data to import"),
511
+ ).not.toBeInTheDocument();
512
+ expect(
513
+ within(scheduledPolling()).queryByText("Scope"),
514
+ ).not.toBeInTheDocument();
515
+ expect(screen.queryByText(/with and without/)).not.toBeInTheDocument();
516
+ expect(
517
+ screen.getByRole("button", { name: "Preview log events" }),
518
+ ).toBeVisible();
519
+ // The forced-advance recovery path is not provider-specific.
520
+ expect(screen.getByText(/import that minute here/)).toBeVisible();
521
+
522
+ fireEvent.click(
523
+ screen.getByRole("button", { name: "Import this time range" }),
524
+ );
525
+ expect(
526
+ screen.getByRole("group", { name: "Confirm historical import" }),
527
+ ).toHaveTextContent("Import log events from");
528
+ });
529
+
530
+ test("Run now is available for paused schedules and sends a poll request", async (): Promise<void> => {
531
+ const paused: SecurityEventConnection = connection({ isEnabled: false });
532
+ jest.mocked(ModelAPI.getItem).mockResolvedValue(paused);
533
+ renderDiagnostics({ item: paused });
534
+ await screen.findByText(/No runs recorded yet/);
535
+ expect(screen.getByText(/Schedule paused/)).toBeVisible();
536
+ fireEvent.click(screen.getByRole("button", { name: "Run now" }));
537
+ await waitFor((): void => {
538
+ expect(API.post).toHaveBeenCalledWith(
539
+ expect.objectContaining({ data: { type: "poll" } }),
540
+ );
541
+ });
542
+ expect(testRequestUrls()[0]).toContain(
543
+ `/security-event-connection/${CONNECTION_ID}/run`,
544
+ );
545
+ });
546
+
547
+ test("a direct row action is submitted only once even with refreshes", async (): Promise<void> => {
548
+ jest
549
+ .mocked(ModelAPI.getList)
550
+ .mockResolvedValue(history([run("queued", "poll")]));
551
+ renderDiagnostics({ initialAction: "poll" });
552
+ expect(
553
+ await screen.findByText(/Queued — waiting for a worker/),
554
+ ).toBeVisible();
555
+ await act(async (): Promise<void> => {
556
+ jest.advanceTimersByTime(3000);
557
+ });
558
+ expect(API.post).toHaveBeenCalledTimes(1);
559
+ });
560
+
561
+ test("queued and running runs disable duplicate actions and update to completed results", async (): Promise<void> => {
562
+ jest.mocked(ModelAPI.getList).mockResolvedValue(history([run("queued")]));
563
+ renderDiagnostics();
564
+ expect(
565
+ await screen.findByText(/Queued — waiting for a worker/),
566
+ ).toBeVisible();
567
+ expect(screen.getByRole("button", { name: "Run now" })).toBeDisabled();
568
+ expect(
569
+ screen.getByRole("button", { name: "Preview detections" }),
570
+ ).toBeDisabled();
571
+ jest.mocked(ModelAPI.getList).mockResolvedValue(history([run("running")]));
572
+ await act(async (): Promise<void> => {
573
+ jest.advanceTimersByTime(3000);
574
+ });
575
+ // A running run has no result yet; the connection names the provider.
576
+ expect(
577
+ await screen.findByText(/Running — checking Google SecOps/),
578
+ ).toBeVisible();
579
+ jest.mocked(ModelAPI.getList).mockResolvedValue(history([run()]));
580
+ await act(async (): Promise<void> => {
581
+ jest.advanceTimersByTime(3000);
582
+ });
583
+ expect(await screen.findByText("Result: Success")).toBeVisible();
584
+ expect(screen.getByRole("button", { name: "Run now" })).toBeEnabled();
585
+ expect(screen.getByText("Successful brute force")).toBeVisible();
586
+ });
587
+
588
+ test("read-only users can inspect results but cannot start any operation", async (): Promise<void> => {
589
+ jest.mocked(ModelAPI.getList).mockResolvedValue(history([run()]));
590
+ renderDiagnostics({ canRun: false });
591
+ await screen.findByText("Result: Success");
592
+ for (const title of [
593
+ "Test connection",
594
+ "Run now",
595
+ "Preview detections",
596
+ "Import this time range",
597
+ ]) {
598
+ expect(screen.getByRole("button", { name: title })).toBeDisabled();
599
+ }
600
+ fireEvent.click(screen.getByRole("button", { name: "View run" }));
601
+ expect(screen.getByRole("region", { name: "Run details" })).toBeVisible();
602
+ expect(API.post).not.toHaveBeenCalled();
603
+ });
604
+
605
+ test("a selected run leaving the recent history does not disable actions", async (): Promise<void> => {
606
+ jest.mocked(ModelAPI.getList).mockResolvedValue(history([run()]));
607
+ renderDiagnostics();
608
+ await screen.findByText("Successful brute force");
609
+ const latest: SecurityEventConnectionRun = run(
610
+ "empty",
611
+ "preview",
612
+ result({
613
+ type: "preview",
614
+ status: "empty",
615
+ fetchedCount: 0,
616
+ ingestedCount: 0,
617
+ samples: [],
618
+ }),
619
+ );
620
+ latest._id = "44444444-4444-4444-8444-444444444444";
621
+ jest.mocked(ModelAPI.getList).mockResolvedValue(history([latest]));
622
+ fireEvent.click(screen.getByRole("button", { name: "Refresh history" }));
623
+ expect(
624
+ await screen.findByText("Result: No records returned"),
625
+ ).toBeVisible();
626
+ expect(screen.getByRole("button", { name: "Run now" })).toBeEnabled();
627
+ expect(
628
+ screen.queryByText(/Waiting for the run to appear/),
629
+ ).not.toBeInTheDocument();
630
+ });
631
+
632
+ test("previews a selected seven-day range without importing", async (): Promise<void> => {
633
+ renderDiagnostics();
634
+ await screen.findByText(/No runs recorded yet/);
635
+ fireEvent.change(screen.getByLabelText("Time range"), {
636
+ target: { value: "168" },
637
+ });
638
+ fireEvent.click(screen.getByRole("button", { name: "Preview detections" }));
639
+ await waitFor((): void => {
640
+ expect(API.post).toHaveBeenCalledWith(
641
+ expect.objectContaining({
642
+ data: {
643
+ type: "preview",
644
+ startTime: "2026-09-03T12:00:00.000Z",
645
+ endTime: "2026-09-10T12:00:00.000Z",
646
+ },
647
+ }),
648
+ );
649
+ });
650
+ expect(API.post).toHaveBeenCalledTimes(1);
651
+ });
652
+
653
+ test("historical import requires confirmation for the actual range and scope", async (): Promise<void> => {
654
+ const allDetections: SecurityEventConnection = connection({
655
+ alertingOnly: false,
656
+ });
657
+ jest.mocked(ModelAPI.getItem).mockResolvedValue(allDetections);
658
+ renderDiagnostics({ item: allDetections });
659
+ await screen.findByText(/No runs recorded yet/);
660
+ fireEvent.click(
661
+ screen.getByRole("button", { name: "Import this time range" }),
662
+ );
663
+ const confirmation: HTMLElement = screen.getByRole("group", {
664
+ name: "Confirm historical import",
665
+ });
666
+ expect(confirmation).toHaveTextContent("Import alerts and detections from");
667
+ expect(confirmation).toHaveTextContent("2026-09-09 12:00:00 UTC");
668
+ expect(confirmation).toHaveTextContent(
669
+ "Already imported detections are skipped",
670
+ );
671
+ expect(API.post).not.toHaveBeenCalled();
672
+ fireEvent.click(
673
+ within(confirmation).getByRole("button", { name: "Confirm import" }),
674
+ );
675
+ await waitFor((): void => {
676
+ expect(API.post).toHaveBeenCalledWith(
677
+ expect.objectContaining({
678
+ data: {
679
+ type: "backfill",
680
+ startTime: "2026-09-09T12:00:00.000Z",
681
+ endTime: "2026-09-10T12:00:00.000Z",
682
+ },
683
+ }),
684
+ );
685
+ });
686
+ });
687
+
688
+ test("an alerts-only connection confirms importing alerts", async (): Promise<void> => {
689
+ renderDiagnostics();
690
+ await screen.findByText(/No runs recorded yet/);
691
+ fireEvent.click(
692
+ screen.getByRole("button", { name: "Import this time range" }),
693
+ );
694
+ const confirmation: HTMLElement = screen.getByRole("group", {
695
+ name: "Confirm historical import",
696
+ });
697
+ expect(confirmation).toHaveTextContent("Import alerts from");
698
+ expect(confirmation).not.toHaveTextContent("alerts and detections");
699
+ });
700
+
701
+ test("changing the selected range cancels a pending import confirmation", async (): Promise<void> => {
702
+ renderDiagnostics();
703
+ await screen.findByText(/No runs recorded yet/);
704
+ fireEvent.click(
705
+ screen.getByRole("button", { name: "Import this time range" }),
706
+ );
707
+ fireEvent.change(screen.getByLabelText("Time range"), {
708
+ target: { value: "1" },
709
+ });
710
+ expect(
711
+ screen.queryByRole("group", { name: "Confirm historical import" }),
712
+ ).not.toBeInTheDocument();
713
+ expect(API.post).not.toHaveBeenCalled();
714
+ });
715
+
716
+ test("invalid dates disable preview and import with a specific explanation", async (): Promise<void> => {
717
+ renderDiagnostics();
718
+ await screen.findByText(/No runs recorded yet/);
719
+ fireEvent.change(screen.getByLabelText("Start (your local time)"), {
720
+ target: { value: "" },
721
+ });
722
+ expect(screen.getByRole("alert")).toHaveTextContent(
723
+ "Choose a valid start and end time",
724
+ );
725
+ expect(
726
+ screen.getByRole("button", { name: "Preview detections" }),
727
+ ).toBeDisabled();
728
+ expect(
729
+ screen.getByRole("button", { name: "Import this time range" }),
730
+ ).toBeDisabled();
731
+ expect(API.post).not.toHaveBeenCalled();
732
+ });
733
+
734
+ test("submission failures are visible and retry remains available", async (): Promise<void> => {
735
+ jest
736
+ .mocked(API.post)
737
+ .mockResolvedValue(
738
+ new HTTPErrorResponse(
739
+ 400,
740
+ { message: "Another run is already queued for this connection." },
741
+ {},
742
+ ),
743
+ );
744
+ renderDiagnostics();
745
+ await screen.findByText(/No runs recorded yet/);
746
+ fireEvent.click(screen.getByRole("button", { name: "Run now" }));
747
+ expect(
748
+ await screen.findByText(/Another run is already queued/),
749
+ ).toBeVisible();
750
+ expect(screen.getByRole("button", { name: "Run now" })).toBeEnabled();
751
+ });
752
+
753
+ test("history failures offer refresh and stop polling when the modal unmounts", async (): Promise<void> => {
754
+ jest
755
+ .mocked(ModelAPI.getList)
756
+ .mockRejectedValue(new Error("History unavailable"));
757
+ const view: ReturnType<typeof render> = renderDiagnostics();
758
+ expect(await screen.findByText(/History unavailable/)).toBeVisible();
759
+ jest.mocked(ModelAPI.getList).mockResolvedValue(history([]));
760
+ fireEvent.click(screen.getByRole("button", { name: "Refresh history" }));
761
+ expect(await screen.findByText(/No runs recorded yet/)).toBeVisible();
762
+ const calls: number = jest.mocked(ModelAPI.getList).mock.calls.length;
763
+ view.unmount();
764
+ await act(async (): Promise<void> => {
765
+ jest.advanceTimersByTime(30000);
766
+ });
767
+ expect(ModelAPI.getList).toHaveBeenCalledTimes(calls);
768
+ });
769
+
770
+ test("a run carried over without a provider still reads as Google SecOps in the modal", async (): Promise<void> => {
771
+ const migrated: JSONObject = {
772
+ ...(result() as unknown as JSONObject),
773
+ };
774
+ delete migrated["provider"];
775
+ jest
776
+ .mocked(ModelAPI.getList)
777
+ .mockResolvedValue(history([run("success", "poll", migrated)]));
778
+ renderDiagnostics();
779
+
780
+ expect(await screen.findByText("Result: Success")).toBeVisible();
781
+ const details: HTMLElement = screen.getByRole("region", {
782
+ name: "Run details",
783
+ });
784
+ expect(details).toHaveTextContent("Returned by Google SecOps");
785
+ });
786
+ });
787
+
788
+ describe("SecurityEventConnectionRunDetails for Google SecOps runs", () => {
789
+ beforeEach((): void => {
790
+ jest
791
+ .spyOn(RouteUtil, "populateRouteParams")
792
+ .mockImplementation((): Route => {
793
+ /*
794
+ * A fresh Route per call: addQueryParams mutates the Route it is
795
+ * given, so a shared instance would carry one link's query into the
796
+ * next.
797
+ */
798
+ return new Route(`/dashboard/${PROJECT_ID}/security-events`);
799
+ });
800
+ });
801
+
802
+ afterEach((): void => {
803
+ cleanup();
804
+ jest.restoreAllMocks();
805
+ });
806
+
807
+ test("partial and empty results have different guidance and preserve the source dates", (): void => {
808
+ const partial: SecurityEventConnectionRunResult = result({
809
+ status: "partial",
810
+ complete: false,
811
+ ingestedCount: 0,
812
+ rejectedCount: 1,
813
+ warnings: ["One payload could not be normalized."],
814
+ });
815
+ const view: ReturnType<typeof render> = render(
816
+ <MemoryRouter>
817
+ <SecurityEventConnectionRunDetails
818
+ run={run("partial", "poll", partial)}
819
+ />
820
+ </MemoryRouter>,
821
+ );
822
+ expect(screen.getByText("Result: Partial")).toBeVisible();
823
+ expect(
824
+ screen.getByText(/This run did not finish processing every record/),
825
+ ).toBeVisible();
826
+ expect(
827
+ screen.getByText("One payload could not be normalized."),
828
+ ).toBeVisible();
829
+ expect(screen.getByText("2026-09-09 01:30:30 UTC")).toBeVisible();
830
+ expect(screen.getByText("2026-09-10 04:16:58 UTC")).toBeVisible();
831
+ expect(screen.getByText("Returned by Google SecOps")).toBeVisible();
832
+ view.unmount();
833
+
834
+ render(
835
+ <MemoryRouter>
836
+ <SecurityEventConnectionRunDetails
837
+ run={run(
838
+ "empty",
839
+ "preview",
840
+ result({
841
+ type: "preview",
842
+ status: "empty",
843
+ fetchedCount: 0,
844
+ ingestedCount: 0,
845
+ samples: [],
846
+ providerDetails: { includeNonAlertingDetections: false },
847
+ }),
848
+ )}
849
+ />
850
+ </MemoryRouter>,
851
+ );
852
+ expect(screen.getByText("Result: No records returned")).toBeVisible();
853
+ expect(
854
+ screen.getByText(
855
+ "Google SecOps returned no matching records for this time range. Try a wider range, or use Test connection to see what is available to import. Only alerts are imported with this Data to import selection; select Detections to import the rest.",
856
+ ),
857
+ ).toBeVisible();
858
+ expect(screen.queryByRole("link")).not.toBeInTheDocument();
859
+ });
860
+
861
+ test("an empty run that already imported Detections gets no Detections advice", (): void => {
862
+ renderRun(
863
+ run(
864
+ "empty",
865
+ "poll",
866
+ result({
867
+ status: "empty",
868
+ fetchedCount: 0,
869
+ ingestedCount: 0,
870
+ samples: [],
871
+ providerDetails: { includeNonAlertingDetections: true },
872
+ }),
873
+ ),
874
+ );
875
+ expect(
876
+ screen.getByText(/returned no matching records for this time range/),
877
+ ).not.toHaveTextContent("select Detections");
878
+ });
879
+
880
+ test.each(["test", "preview"] as Array<SecurityEventConnectionRunType>)(
881
+ "%s reports duplicate detection as not checked",
882
+ (type: SecurityEventConnectionRunType): void => {
883
+ renderRun(run("success", type, result({ type, duplicateCount: 0 })));
884
+
885
+ const duplicateCount: HTMLElement | null =
886
+ screen.getByText("Already imported").parentElement;
887
+ expect(duplicateCount).toHaveTextContent("Not checked");
888
+ expect(duplicateCount).not.toHaveTextContent("0");
889
+ },
890
+ );
891
+
892
+ test.each(["poll", "backfill"] as Array<SecurityEventConnectionRunType>)(
893
+ "%s reports the actual duplicate detection count",
894
+ (type: SecurityEventConnectionRunType): void => {
895
+ renderRun(run("success", type, result({ type, duplicateCount: 7 })));
896
+
897
+ const duplicateCount: HTMLElement | null =
898
+ screen.getByText("Already imported").parentElement;
899
+ expect(duplicateCount).toHaveTextContent("7");
900
+ expect(duplicateCount).not.toHaveTextContent("Not checked");
901
+ },
902
+ );
903
+
904
+ test("an import failure preserves successful Google read diagnostics without blaming Google", (): void => {
905
+ const failed: SecurityEventConnectionRunResult = result({
906
+ status: "failed",
907
+ complete: false,
908
+ ingestedCount: 0,
909
+ failedCount: 1,
910
+ error: "OneUptime telemetry storage is unavailable.",
911
+ checks: [
912
+ {
913
+ key: "read",
914
+ name: "Read detections from the configured instance",
915
+ status: "pass",
916
+ durationMs: 500,
917
+ message: "Google SecOps detection read succeeded.",
918
+ },
919
+ {
920
+ key: "store",
921
+ name: "Import detections",
922
+ status: "fail",
923
+ durationMs: 500,
924
+ message: "The detection could not be stored in OneUptime.",
925
+ remediation: "Check that the telemetry database is reachable.",
926
+ },
927
+ ],
928
+ });
929
+ renderRun(run("failed", "poll", failed));
930
+
931
+ expect(screen.getByText("Result: Failed")).toBeVisible();
932
+ expect(
933
+ screen.getByText(/This run did not finish processing every record/),
934
+ ).toHaveTextContent("Review the checks and warnings before retrying.");
935
+ expect(
936
+ screen.getByText("Read detections from the configured instance: Passed"),
937
+ ).toHaveClass("text-green-700");
938
+ expect(screen.getByText("Import detections: Failed")).toHaveClass(
939
+ "text-red-700",
940
+ );
941
+ expect(
942
+ screen.getByText("Check that the telemetry database is reachable."),
943
+ ).toBeVisible();
944
+ expect(
945
+ screen.getByText("OneUptime telemetry storage is unavailable."),
946
+ ).toBeVisible();
947
+ expect(
948
+ screen.queryByText(/Google did not return a complete result/),
949
+ ).not.toBeInTheDocument();
950
+ });
951
+
952
+ /*
953
+ * A failed synchronous test stores its summary as the run error and the
954
+ * checklist as the result. The summary is shown once, in the report
955
+ * banner, never again as a red box above it.
956
+ */
957
+ test("a stored synchronous test report renders as its checklist with its error shown once", (): void => {
958
+ const stored: SecurityEventConnectionRun = run("failed", "test");
959
+ stored.result = testReport({
960
+ status: "fail",
961
+ summary: "1 check failed: Background workers.",
962
+ checks: [
963
+ {
964
+ key: "worker-consumers",
965
+ name: "Background workers",
966
+ status: "fail",
967
+ durationMs: 10,
968
+ message: "No process is consuming the Worker queue.",
969
+ remediation: "Start a worker.",
970
+ },
971
+ ],
972
+ }) as unknown as JSONObject;
973
+ stored.error = "1 check failed: Background workers.";
974
+ const details: HTMLElement = renderRun(stored);
975
+
976
+ const report: HTMLElement = screen.getByRole("region", {
977
+ name: "Connection test report",
978
+ });
979
+ expect(within(report).getByText("Some checks failed")).toBeVisible();
980
+ expect(
981
+ within(report).getByText("No process is consuming the Worker queue."),
982
+ ).toBeVisible();
983
+ expect(
984
+ screen.getAllByText("1 check failed: Background workers."),
985
+ ).toHaveLength(1);
986
+ expect(
987
+ within(details).queryByText("1 check failed: Background workers.", {
988
+ selector: 'p[role="alert"]',
989
+ }),
990
+ ).not.toBeInTheDocument();
991
+ expect(screen.queryByText(/Returned by/)).not.toBeInTheDocument();
992
+ });
993
+
994
+ test("a failed run without a report still shows its error, as literal text", (): void => {
995
+ const failed: SecurityEventConnectionRun = run("failed");
996
+ failed.error = "Google rejected access. <script>not markup</script>";
997
+ renderRun(failed);
998
+ expect(screen.getByRole("alert")).toHaveTextContent(failed.error);
999
+ expect(document.querySelector("script")).toBeNull();
1000
+ });
1001
+
1002
+ test("a legacy queued test result still renders as a run result", (): void => {
1003
+ renderRun(run("success", "test", result({ type: "test" })));
1004
+ expect(screen.getByText("Returned by Google SecOps")).toBeVisible();
1005
+ expect(
1006
+ screen.getByText(
1007
+ /does not import events or confirm that scheduled polling is working/,
1008
+ ),
1009
+ ).toBeVisible();
1010
+ expect(
1011
+ screen.queryByRole("region", { name: "Connection test report" }),
1012
+ ).not.toBeInTheDocument();
1013
+ });
1014
+
1015
+ test("a forced advance explains the skipped minute and how to recover it", (): void => {
1016
+ const details: HTMLElement = renderRun(
1017
+ run(
1018
+ "partial",
1019
+ "poll",
1020
+ result({
1021
+ status: "partial",
1022
+ complete: false,
1023
+ chunkMinutes: 1,
1024
+ nextChunkMinutes: 1,
1025
+ forcedAdvance: true,
1026
+ warnings: [
1027
+ "More records were created in the one minute from 2026-09-10T04:59:00.000Z to 2026-09-10T05:00:00.000Z than one poll can read. Polling moved past this minute so newer records keep arriving; use Import this time range in Diagnostics on this minute to recover what one run can read.",
1028
+ ],
1029
+ checks: [
1030
+ {
1031
+ key: "read-rule-detections",
1032
+ name: "Read rule detections by created time",
1033
+ status: "warn",
1034
+ durationMs: 500,
1035
+ message: "stopped by the request budget after 20 requests",
1036
+ },
1037
+ ],
1038
+ }),
1039
+ ),
1040
+ );
1041
+
1042
+ /*
1043
+ * Hoisted: eslint's wrap-regex and prettier disagree about an inline
1044
+ * literal followed by .test().
1045
+ */
1046
+ const pollingMovedPast: RegExp = /Polling moved past one minute/;
1047
+ const alert: HTMLElement = within(details)
1048
+ .getAllByRole("alert")
1049
+ .find((element: HTMLElement): boolean => {
1050
+ return pollingMovedPast.test(element.textContent || "");
1051
+ }) as HTMLElement;
1052
+ expect(alert).toHaveTextContent(
1053
+ "More detections were created in one minute than one poll can read.",
1054
+ );
1055
+ expect(alert).toHaveTextContent(
1056
+ "use Import this time range under Find historical detections for 2026-09-10 04:59:00 UTC → 2026-09-10 05:00:00 UTC",
1057
+ );
1058
+ expect(details).toHaveTextContent("Window read by this poll1 minute");
1059
+ expect(details).not.toHaveTextContent("did not finish processing");
1060
+ expect(
1061
+ screen.getByText("Read rule detections by created time: Warning"),
1062
+ ).toHaveClass("text-amber-700");
1063
+ });
1064
+
1065
+ test("a narrowed partial poll says the next poll re-reads a shorter window", (): void => {
1066
+ const details: HTMLElement = renderRun(
1067
+ run(
1068
+ "partial",
1069
+ "poll",
1070
+ result({
1071
+ status: "partial",
1072
+ complete: false,
1073
+ chunkMinutes: 1440,
1074
+ nextChunkMinutes: 720,
1075
+ warnings: [
1076
+ "This window holds more records than one poll can read; the next poll reads a 720 minute window from the same starting point.",
1077
+ ],
1078
+ }),
1079
+ ),
1080
+ );
1081
+ expect(details).toHaveTextContent(
1082
+ "This window held more detections than one poll can read, so the cursor stayed where it was. The next scheduled poll reads a window of 12 hours from the same starting point",
1083
+ );
1084
+ expect(details).toHaveTextContent("Window read by this poll24 hours");
1085
+ expect(details).not.toHaveTextContent("Polling moved past one minute");
1086
+ });
1087
+
1088
+ test("provider details show the basis, per-pass counts and creation lag, and the scope as Data to import", (): void => {
1089
+ const details: HTMLElement = renderRun(
1090
+ run(
1091
+ "success",
1092
+ "poll",
1093
+ result({
1094
+ providerDetails: {
1095
+ basis: "created-time",
1096
+ sourceCounts: {
1097
+ ruleDetections: 12,
1098
+ curatedDetections: 3,
1099
+ alertsView: 4,
1100
+ },
1101
+ creationLag: { measured: 18, lateCount: 2, maxLagMinutes: 95 },
1102
+ includeNonAlertingDetections: false,
1103
+ },
1104
+ }),
1105
+ ),
1106
+ );
1107
+
1108
+ const provider: HTMLElement = within(details).getByRole("region", {
1109
+ name: "Provider details",
1110
+ });
1111
+ const detail: (key: string) => Element | null = (
1112
+ key: string,
1113
+ ): Element | null => {
1114
+ return provider.querySelector(`[data-detail-key="${key}"]`);
1115
+ };
1116
+ expect(detail("basis")).toHaveTextContent("Time basis readCreated time");
1117
+ expect(within(provider).getByText("Returned by each pass")).toBeVisible();
1118
+ expect(detail("sourceCounts.ruleDetections")).toHaveTextContent(
1119
+ "Rule detections12",
1120
+ );
1121
+ expect(detail("sourceCounts.curatedDetections")).toHaveTextContent(
1122
+ "Curated rule detections3",
1123
+ );
1124
+ expect(detail("sourceCounts.alertsView")).toHaveTextContent("Alerts view4");
1125
+ expect(within(provider).getByText("Creation lag")).toBeVisible();
1126
+ expect(detail("creationLag.measured")).toHaveTextContent(
1127
+ "Records measured18",
1128
+ );
1129
+ expect(detail("creationLag.lateCount")).toHaveTextContent(
1130
+ "Created later than the poll interval2",
1131
+ );
1132
+ expect(detail("creationLag.maxLagMinutes")).toHaveTextContent(
1133
+ "Longest lag (minutes)95",
1134
+ );
1135
+ // The scope is its own line in the provider's words, not a raw detail.
1136
+ expect(provider).not.toHaveTextContent("Includes non-alerting records");
1137
+ expect(detail("includeNonAlertingDetections")).toBeNull();
1138
+ expect(
1139
+ within(details).getByText("Data to import").parentElement,
1140
+ ).toHaveTextContent("Data to importAlerts only");
1141
+ });
1142
+
1143
+ test("a preview read by detection time with Detections included says so", (): void => {
1144
+ const details: HTMLElement = renderRun(
1145
+ run(
1146
+ "success",
1147
+ "preview",
1148
+ result({
1149
+ type: "preview",
1150
+ providerDetails: {
1151
+ basis: "detection-time",
1152
+ includeNonAlertingDetections: true,
1153
+ },
1154
+ }),
1155
+ ),
1156
+ );
1157
+
1158
+ expect(
1159
+ within(details).getByRole("region", { name: "Provider details" }),
1160
+ ).toHaveTextContent(
1161
+ "Time basis readDetection time, with created time also read",
1162
+ );
1163
+ expect(
1164
+ within(details).getByText("Data to import").parentElement,
1165
+ ).toHaveTextContent("Data to importAlerts and detections");
1166
+ });
1167
+
1168
+ test("a run without provider details renders neither the section nor a scope line", (): void => {
1169
+ const details: HTMLElement = renderRun(run());
1170
+ expect(
1171
+ within(details).queryByRole("region", { name: "Provider details" }),
1172
+ ).not.toBeInTheDocument();
1173
+ expect(
1174
+ within(details).queryByText("Data to import"),
1175
+ ).not.toBeInTheDocument();
1176
+ });
1177
+
1178
+ test("a provider without the Data to import control lists every detail it reports", (): void => {
1179
+ const details: HTMLElement = renderRun(
1180
+ run(
1181
+ "success",
1182
+ "poll",
1183
+ result({
1184
+ provider: OKTA,
1185
+ providerDetails: {
1186
+ includeNonAlertingDetections: false,
1187
+ pagesRead: 3,
1188
+ },
1189
+ }),
1190
+ ),
1191
+ );
1192
+
1193
+ const provider: HTMLElement = within(details).getByRole("region", {
1194
+ name: "Provider details",
1195
+ });
1196
+ expect(
1197
+ provider.querySelector(
1198
+ '[data-detail-key="includeNonAlertingDetections"]',
1199
+ ),
1200
+ ).toHaveTextContent("Includes non-alerting recordsNo");
1201
+ expect(
1202
+ provider.querySelector('[data-detail-key="pagesRead"]'),
1203
+ ).toHaveTextContent("Pages read3");
1204
+ expect(
1205
+ within(details).queryByText("Data to import"),
1206
+ ).not.toBeInTheDocument();
1207
+ });
1208
+
1209
+ test("samples get an Alert column only when the source says which records are alerts", (): void => {
1210
+ const details: HTMLElement = renderRun(
1211
+ run(
1212
+ "success",
1213
+ "poll",
1214
+ result({
1215
+ fetchedCount: 3,
1216
+ samples: [
1217
+ sample({ id: "alert", title: "Alerting rule", isAlert: true }),
1218
+ sample({ id: "match", title: "Rule match", isAlert: false }),
1219
+ sample({ id: "unknown", title: "Unlabelled", isAlert: undefined }),
1220
+ ],
1221
+ }),
1222
+ ),
1223
+ );
1224
+
1225
+ expect(
1226
+ within(details).getByRole("columnheader", { name: "Alert" }),
1227
+ ).toBeVisible();
1228
+ const cells: (title: string) => Array<string> = (
1229
+ title: string,
1230
+ ): Array<string> => {
1231
+ const rowElement: HTMLElement = within(details)
1232
+ .getByText(title)
1233
+ .closest("tr") as HTMLElement;
1234
+ return Array.from(rowElement.querySelectorAll("td")).map(
1235
+ (cell: HTMLTableCellElement): string => {
1236
+ return cell.textContent || "";
1237
+ },
1238
+ );
1239
+ };
1240
+ expect(cells("Alerting rule")[4]).toBe("Yes");
1241
+ expect(cells("Rule match")[4]).toBe("No");
1242
+ expect(cells("Unlabelled")[4]).toBe("Unknown");
1243
+ cleanup();
1244
+
1245
+ const withoutFlag: HTMLElement = renderRun(
1246
+ run(
1247
+ "success",
1248
+ "poll",
1249
+ result({
1250
+ provider: OKTA,
1251
+ samples: [sample({ isAlert: undefined })],
1252
+ }),
1253
+ ),
1254
+ );
1255
+ expect(
1256
+ within(withoutFlag).queryByRole("columnheader", { name: "Alert" }),
1257
+ ).not.toBeInTheDocument();
1258
+ expect(
1259
+ within(withoutFlag)
1260
+ .getAllByRole("columnheader")
1261
+ .map((header: HTMLElement): string => {
1262
+ return header.textContent || "";
1263
+ }),
1264
+ ).toEqual([
1265
+ "Record",
1266
+ "Severity",
1267
+ "Event time (UTC)",
1268
+ "Created at source (UTC)",
1269
+ ]);
1270
+ });
1271
+
1272
+ /*
1273
+ * Poll history carried over from the retired Google SecOps connector: no
1274
+ * provider on the result, the diagnostics at the top level, samples that
1275
+ * name the rule and detection time, and success/failed check statuses.
1276
+ */
1277
+ test("a run carried over from the retired connector renders truthfully", (): void => {
1278
+ const legacy: JSONObject = {
1279
+ type: "poll",
1280
+ status: "success",
1281
+ startedAt: "2026-09-10T11:59:00Z",
1282
+ completedAt: "2026-09-10T12:00:00Z",
1283
+ durationMs: 60000,
1284
+ windowStart: "2026-09-10T04:00:00Z",
1285
+ windowEnd: "2026-09-10T05:00:00Z",
1286
+ includeNonAlertingDetections: true,
1287
+ basis: "created-time",
1288
+ sourceCounts: { ruleDetections: 2, curatedDetections: 0, alertsView: 1 },
1289
+ creationLag: { measured: 2, lateCount: 1, maxLagMinutes: 75 },
1290
+ fetchedCount: 2,
1291
+ ingestedCount: 2,
1292
+ duplicateCount: 0,
1293
+ rejectedCount: 0,
1294
+ failedCount: 0,
1295
+ complete: true,
1296
+ requestCount: 3,
1297
+ warnings: [],
1298
+ samples: [
1299
+ {
1300
+ id: "legacy-1",
1301
+ ruleName: "Legacy brute force rule",
1302
+ detectionTime: "2026-09-09T01:30:30Z",
1303
+ createdTime: "2026-09-10T04:16:58Z",
1304
+ isAlert: false,
1305
+ },
1306
+ ],
1307
+ checks: [
1308
+ {
1309
+ name: "Read detections",
1310
+ status: "success",
1311
+ durationMs: 5,
1312
+ message: "Read two detections.",
1313
+ },
1314
+ {
1315
+ name: "Import detections",
1316
+ status: "failed",
1317
+ durationMs: 5,
1318
+ message: "One detection was not stored.",
1319
+ },
1320
+ ],
1321
+ eventTimeStart: "2026-09-09T01:30:30Z",
1322
+ eventTimeEnd: "2026-09-09T01:30:30Z",
1323
+ };
1324
+ const details: HTMLElement = renderRun(
1325
+ run("success", "poll", legacy),
1326
+ GOOGLE,
1327
+ );
1328
+
1329
+ expect(details).toHaveTextContent("Returned by Google SecOps");
1330
+ expect(
1331
+ within(details).getByText("Data to import").parentElement,
1332
+ ).toHaveTextContent("Data to importAlerts and detections");
1333
+ const provider: HTMLElement = within(details).getByRole("region", {
1334
+ name: "Provider details",
1335
+ });
1336
+ expect(
1337
+ provider.querySelector('[data-detail-key="sourceCounts.ruleDetections"]'),
1338
+ ).toHaveTextContent("Rule detections2");
1339
+ expect(
1340
+ provider.querySelector('[data-detail-key="creationLag.maxLagMinutes"]'),
1341
+ ).toHaveTextContent("Longest lag (minutes)75");
1342
+
1343
+ const sampleRow: HTMLElement = within(details)
1344
+ .getByText("Legacy brute force rule")
1345
+ .closest("tr") as HTMLElement;
1346
+ expect(sampleRow).toHaveTextContent("2026-09-09 01:30:30 UTC");
1347
+ expect(sampleRow).not.toHaveTextContent("Untitled");
1348
+ expect(
1349
+ Array.from(sampleRow.querySelectorAll("td")).map(
1350
+ (cell: HTMLTableCellElement): string => {
1351
+ return cell.textContent || "";
1352
+ },
1353
+ )[4],
1354
+ ).toBe("No");
1355
+
1356
+ expect(screen.getByText("Read detections: Passed")).toHaveClass(
1357
+ "text-green-700",
1358
+ );
1359
+ expect(screen.getByText("Import detections: Failed")).toHaveClass(
1360
+ "text-red-700",
1361
+ );
1362
+ expect(
1363
+ screen.getByRole("link", { name: "View events in this time range" }),
1364
+ ).toBeVisible();
1365
+
1366
+ const filter: JSONObject = eventsFilter(
1367
+ connectionEventsRoute(
1368
+ legacy as unknown as SecurityEventConnectionRunResult,
1369
+ CONNECTION_ID,
1370
+ ),
1371
+ );
1372
+ expect(filter["attributes"]).toEqual({
1373
+ [LEGACY_GOOGLE_SECOPS_CONNECTION_ID_ATTRIBUTE]: CONNECTION_ID,
1374
+ });
1375
+ });
1376
+ });
1377
+
1378
+ describe("View events for a connection run", () => {
1379
+ beforeEach((): void => {
1380
+ jest
1381
+ .spyOn(RouteUtil, "populateRouteParams")
1382
+ .mockImplementation((): Route => {
1383
+ /*
1384
+ * A fresh Route per call: addQueryParams mutates the Route it is
1385
+ * given, so a shared instance would carry one link's query into the
1386
+ * next.
1387
+ */
1388
+ return new Route(`/dashboard/${PROJECT_ID}/security-events`);
1389
+ });
1390
+ });
1391
+
1392
+ afterEach((): void => {
1393
+ jest.restoreAllMocks();
1394
+ });
1395
+
1396
+ test("newly imported events are filtered on the shared connection attribute", (): void => {
1397
+ const filter: JSONObject = eventsFilter(
1398
+ connectionEventsRoute(result(), CONNECTION_ID),
1399
+ );
1400
+ expect(filter["attributes"]).toEqual({
1401
+ "oneuptime.security_connection.id": CONNECTION_ID,
1402
+ });
1403
+ expect(SECURITY_CONNECTION_ID_ATTRIBUTE).toBe(
1404
+ "oneuptime.security_connection.id",
1405
+ );
1406
+ });
1407
+
1408
+ /*
1409
+ * Events a migrated connection imported before the move carry the retired
1410
+ * connector's attribute; its carried-over runs name that key, and the
1411
+ * link has to filter on it or it opens an empty table.
1412
+ */
1413
+ test("a carried-over run filters on the attribute its events were stamped with", (): void => {
1414
+ const filter: JSONObject = eventsFilter(
1415
+ connectionEventsRoute(
1416
+ result({
1417
+ eventAttributeKey: LEGACY_GOOGLE_SECOPS_CONNECTION_ID_ATTRIBUTE,
1418
+ }),
1419
+ CONNECTION_ID,
1420
+ ),
1421
+ );
1422
+ expect(filter["attributes"]).toEqual({
1423
+ "oneuptime.google_secops.connection_id": CONNECTION_ID,
1424
+ });
1425
+ expect(filter["attributes"]).not.toHaveProperty(
1426
+ SECURITY_CONNECTION_ID_ATTRIBUTE,
1427
+ );
1428
+ });
1429
+
1430
+ test("the attribute key: named, recognisably legacy, or the shared default", (): void => {
1431
+ expect(connectionEventAttributeKey(result())).toBe(
1432
+ SECURITY_CONNECTION_ID_ATTRIBUTE,
1433
+ );
1434
+ expect(
1435
+ connectionEventAttributeKey(
1436
+ result({ eventAttributeKey: "custom.connection.id" }),
1437
+ ),
1438
+ ).toBe("custom.connection.id");
1439
+ expect(
1440
+ connectionEventAttributeKey({
1441
+ ...result(),
1442
+ includeNonAlertingDetections: false,
1443
+ } as unknown as SecurityEventConnectionRunResult),
1444
+ ).toBe(LEGACY_GOOGLE_SECOPS_CONNECTION_ID_ATTRIBUTE);
1445
+ // The shared poller files the flag under providerDetails, never on top.
1446
+ expect(
1447
+ connectionEventAttributeKey(
1448
+ result({ providerDetails: { includeNonAlertingDetections: false } }),
1449
+ ),
1450
+ ).toBe(SECURITY_CONNECTION_ID_ATTRIBUTE);
1451
+ // A named key wins even on a legacy-shaped result.
1452
+ expect(
1453
+ connectionEventAttributeKey({
1454
+ ...result({ eventAttributeKey: SECURITY_CONNECTION_ID_ATTRIBUTE }),
1455
+ includeNonAlertingDetections: true,
1456
+ } as unknown as SecurityEventConnectionRunResult),
1457
+ ).toBe(SECURITY_CONNECTION_ID_ATTRIBUTE);
1458
+ });
1459
+
1460
+ test("View events targets detection time rather than creation or import time", (): void => {
1461
+ const filter: JSONObject = eventsFilter(connectionEventsRoute(result()));
1462
+ expect(filterRange(filter)).toEqual([
1463
+ "2026-09-09T01:30:29.000Z",
1464
+ "2026-09-09T01:30:31.000Z",
1465
+ ]);
1466
+ // Without a connection id there is nothing to scope on.
1467
+ expect(filter["attributes"]).toBeUndefined();
1468
+ });
1469
+
1470
+ /*
1471
+ * A duplicate-only run imported nothing, so the link cannot scope to the
1472
+ * connection, and a run without a stored event-time range must still
1473
+ * open the range the detections are stored under: their detection time,
1474
+ * which for a late-created detection is a day before its creation time.
1475
+ */
1476
+ test("duplicate-only links recover the detection-time range from samples", (): void => {
1477
+ const filter: JSONObject = eventsFilter(
1478
+ connectionEventsRoute(
1479
+ result({
1480
+ ingestedCount: 0,
1481
+ duplicateCount: 1,
1482
+ eventTimeStart: undefined,
1483
+ eventTimeEnd: undefined,
1484
+ }),
1485
+ CONNECTION_ID,
1486
+ ),
1487
+ );
1488
+ expect(filterRange(filter)).toEqual([
1489
+ "2026-09-09T01:30:29.000Z",
1490
+ "2026-09-09T01:30:31.000Z",
1491
+ ]);
1492
+ expect(filter["attributes"]).toBeUndefined();
1493
+ });
1494
+
1495
+ test("a legacy sample's detection time is used the same way", (): void => {
1496
+ const legacySample: SecurityConnectorSample = {
1497
+ id: "legacy",
1498
+ detectionTime: "2026-09-08T22:00:00Z",
1499
+ createdTime: "2026-09-10T04:00:00Z",
1500
+ } as unknown as SecurityConnectorSample;
1501
+ const filter: JSONObject = eventsFilter(
1502
+ connectionEventsRoute(
1503
+ result({
1504
+ ingestedCount: 0,
1505
+ duplicateCount: 1,
1506
+ eventTimeStart: undefined,
1507
+ eventTimeEnd: undefined,
1508
+ samples: [legacySample],
1509
+ }),
1510
+ ),
1511
+ );
1512
+ expect(filterRange(filter)).toEqual([
1513
+ "2026-09-08T21:59:59.000Z",
1514
+ "2026-09-08T22:00:01.000Z",
1515
+ ]);
1516
+ });
1517
+
1518
+ test("creation time is the fallback for a sample without an event time, and the window for no samples", (): void => {
1519
+ expect(
1520
+ filterRange(
1521
+ eventsFilter(
1522
+ connectionEventsRoute(
1523
+ result({
1524
+ eventTimeStart: undefined,
1525
+ eventTimeEnd: undefined,
1526
+ samples: [
1527
+ sample({
1528
+ eventTime: undefined,
1529
+ createdTime: "2026-09-10T04:10:00Z",
1530
+ }),
1531
+ ],
1532
+ }),
1533
+ ),
1534
+ ),
1535
+ ),
1536
+ ).toEqual(["2026-09-10T04:09:59.000Z", "2026-09-10T04:10:01.000Z"]);
1537
+
1538
+ expect(
1539
+ filterRange(
1540
+ eventsFilter(
1541
+ connectionEventsRoute(
1542
+ result({
1543
+ eventTimeStart: undefined,
1544
+ eventTimeEnd: undefined,
1545
+ samples: [],
1546
+ }),
1547
+ ),
1548
+ ),
1549
+ ),
1550
+ ).toEqual(["2026-09-10T03:59:59.000Z", "2026-09-10T05:00:01.000Z"]);
1551
+ });
1552
+
1553
+ test("a stored event-time range wins over the samples", (): void => {
1554
+ expect(
1555
+ filterRange(
1556
+ eventsFilter(
1557
+ connectionEventsRoute(
1558
+ result({
1559
+ eventTimeStart: "2026-09-01T00:00:00Z",
1560
+ eventTimeEnd: "2026-09-02T00:00:00Z",
1561
+ }),
1562
+ ),
1563
+ ),
1564
+ ),
1565
+ ).toEqual(["2026-08-31T23:59:59.000Z", "2026-09-02T00:00:01.000Z"]);
1566
+ });
1567
+ });
1568
+
1569
+ describe("connection diagnostics util", () => {
1570
+ const google: SecurityEventConnectorDefinition =
1571
+ getSecurityEventConnectorDefinition(
1572
+ GOOGLE,
1573
+ ) as SecurityEventConnectorDefinition;
1574
+ const okta: SecurityEventConnectorDefinition =
1575
+ getSecurityEventConnectorDefinition(
1576
+ OKTA,
1577
+ ) as SecurityEventConnectorDefinition;
1578
+
1579
+ test("Google SecOps is titled from the catalog, and an unknown provider by its identifier", (): void => {
1580
+ expect(connectorProviderTitle(GOOGLE)).toBe("Google SecOps");
1581
+ expect(connectorProviderTitle("future-provider")).toBe("future-provider");
1582
+ expect(connectorProviderTitle("")).toBe("");
1583
+ });
1584
+
1585
+ test("the scope reads in the control's words, generically without one, and not at all without a distinction", (): void => {
1586
+ expect(connectorScopeLabel(google)).toBe("Data to import");
1587
+ expect(connectorScopeLabel(okta)).toBe("Scope");
1588
+ expect(connectorScopeLabel(undefined)).toBe("Scope");
1589
+
1590
+ expect(connectorScopeSummary(google, true)).toBe("Alerts only");
1591
+ expect(connectorScopeSummary(google, undefined)).toBe("Alerts only");
1592
+ expect(connectorScopeSummary(google, false)).toBe("Alerts and detections");
1593
+ expect(connectorScopeSummary(okta, false)).toBeUndefined();
1594
+ expect(connectorScopeSummary(undefined, false)).toBeUndefined();
1595
+
1596
+ const toggleOnly: Pick<
1597
+ SecurityEventConnectorDefinition,
1598
+ "supportsAlertingOnlyToggle" | "alertingOnlyControl"
1599
+ > = { supportsAlertingOnlyToggle: true };
1600
+ expect(connectorScopeLabel(toggleOnly)).toBe("Scope");
1601
+ expect(connectorScopeSummary(toggleOnly, true)).toBe("Alerts only");
1602
+ expect(connectorScopeSummary(toggleOnly, false)).toBe(
1603
+ "Alerts and detections",
1604
+ );
1605
+ });
1606
+
1607
+ test("an import names what it brings in only when the provider has a control", (): void => {
1608
+ expect(connectorScopeImportNoun(google, true)).toBe("alerts");
1609
+ expect(connectorScopeImportNoun(google, false)).toBe(
1610
+ "alerts and detections",
1611
+ );
1612
+ expect(connectorScopeImportNoun(okta, false)).toBeUndefined();
1613
+ expect(
1614
+ connectorScopeImportNoun({ supportsAlertingOnlyToggle: true }, false),
1615
+ ).toBeUndefined();
1616
+ // A control on a provider without the distinction is ignored.
1617
+ expect(
1618
+ connectorScopeImportNoun(
1619
+ {
1620
+ supportsAlertingOnlyToggle: false,
1621
+ alertingOnlyControl: google.alertingOnlyControl,
1622
+ },
1623
+ false,
1624
+ ),
1625
+ ).toBeUndefined();
1626
+ });
1627
+
1628
+ test("provider details come from providerDetails, or from the top of a carried-over result", (): void => {
1629
+ expect(
1630
+ readConnectorProviderDetails(
1631
+ result({ providerDetails: { basis: "created-time" } }),
1632
+ ),
1633
+ ).toEqual({ basis: "created-time" });
1634
+ expect(readConnectorProviderDetails(result())).toBeUndefined();
1635
+
1636
+ const legacy: SecurityEventConnectionRunResult = {
1637
+ ...result(),
1638
+ includeNonAlertingDetections: false,
1639
+ basis: "detection-time",
1640
+ sourceCounts: { ruleDetections: 1 },
1641
+ creationLag: { measured: 0, lateCount: 0, maxLagMinutes: 0 },
1642
+ unrelated: "ignored",
1643
+ } as unknown as SecurityEventConnectionRunResult;
1644
+ expect(readConnectorProviderDetails(legacy)).toEqual({
1645
+ includeNonAlertingDetections: false,
1646
+ basis: "detection-time",
1647
+ sourceCounts: { ruleDetections: 1 },
1648
+ creationLag: { measured: 0, lateCount: 0, maxLagMinutes: 0 },
1649
+ });
1650
+
1651
+ // providerDetails wins when both are present.
1652
+ expect(
1653
+ readConnectorProviderDetails({
1654
+ ...legacy,
1655
+ providerDetails: { basis: "created-time" },
1656
+ }),
1657
+ ).toEqual({ basis: "created-time" });
1658
+ });
1659
+
1660
+ test("detail groups: values first, one group per object, deeper values as JSON, blanks and omitted keys dropped", (): void => {
1661
+ expect(connectorProviderDetailGroups(undefined)).toEqual([]);
1662
+ expect(connectorProviderDetailGroups({})).toEqual([]);
1663
+
1664
+ const groups: Array<ConnectorProviderDetailGroup> =
1665
+ connectorProviderDetailGroups(
1666
+ {
1667
+ sourceCounts: { ruleDetections: 1200, nested: { deep: true } },
1668
+ basis: "created-time",
1669
+ truncated: true,
1670
+ skipped: null,
1671
+ emptyGroup: {},
1672
+ includeNonAlertingDetections: false,
1673
+ },
1674
+ ["includeNonAlertingDetections"],
1675
+ );
1676
+
1677
+ expect(groups).toEqual([
1678
+ {
1679
+ key: "",
1680
+ rows: [
1681
+ { key: "basis", label: "Time basis read", value: "Created time" },
1682
+ { key: "truncated", label: "Truncated", value: "Yes" },
1683
+ ],
1684
+ },
1685
+ {
1686
+ key: "sourceCounts",
1687
+ title: "Returned by each pass",
1688
+ rows: [
1689
+ {
1690
+ key: "sourceCounts.ruleDetections",
1691
+ label: "Rule detections",
1692
+ value: (1200).toLocaleString(),
1693
+ },
1694
+ {
1695
+ key: "sourceCounts.nested",
1696
+ label: "Nested",
1697
+ value: '{"deep":true}',
1698
+ },
1699
+ ],
1700
+ },
1701
+ ]);
1702
+ });
1703
+
1704
+ test("carried-over check statuses and samples are read in the shared vocabulary", (): void => {
1705
+ expect(normalizeConnectorCheckStatus("success")).toBe("pass");
1706
+ expect(normalizeConnectorCheckStatus("failed")).toBe("fail");
1707
+ for (const status of ["pass", "fail", "warn", "skip", "unexpected"]) {
1708
+ expect(normalizeConnectorCheckStatus(status)).toBe(status);
1709
+ }
1710
+
1711
+ expect(connectorSampleTitle(sample())).toBe("Successful brute force");
1712
+ const legacy: SecurityConnectorSample = {
1713
+ id: "legacy",
1714
+ ruleName: "Legacy rule",
1715
+ detectionTime: "2026-09-09T00:00:00Z",
1716
+ } as unknown as SecurityConnectorSample;
1717
+ expect(connectorSampleTitle(legacy)).toBe("Legacy rule");
1718
+ expect(connectorSampleEventTime(legacy)).toBe("2026-09-09T00:00:00Z");
1719
+ expect(connectorSampleEventTime(sample())).toBe("2026-09-09T01:30:30Z");
1720
+ expect(
1721
+ connectorSampleTitle({ id: "blank" } as SecurityConnectorSample),
1722
+ ).toBe("");
1723
+ expect(
1724
+ connectorSampleEventTime({ id: "blank" } as SecurityConnectorSample),
1725
+ ).toBeUndefined();
1726
+ });
1727
+
1728
+ test.each([
1729
+ ["", "2026-09-10T12:00:00Z", "valid start"],
1730
+ ["2026-09-10T12:00:00Z", "2026-09-10T12:00:00Z", "before the end"],
1731
+ ["2026-09-10T11:00:00Z", "2026-09-10T12:01:00Z", "future"],
1732
+ ["2026-09-02T12:00:00Z", "2026-09-10T12:00:00Z", "7 days or less"],
1733
+ ])(
1734
+ "rejects range %s to %s",
1735
+ (start: string, end: string, expected: string): void => {
1736
+ expect(validateConnectionRange(start, end, NOW)).toContain(expected);
1737
+ },
1738
+ );
1739
+
1740
+ test("allows a complete seven-day historical range", (): void => {
1741
+ expect(
1742
+ validateConnectionRange(
1743
+ "2026-09-03T12:00:00Z",
1744
+ "2026-09-10T12:00:00Z",
1745
+ NOW,
1746
+ ),
1747
+ ).toBeNull();
1748
+ });
1749
+
1750
+ test("a Google SecOps connection's partial imports and catch-up stay distinguishable from failures", (): void => {
1751
+ const item: SecurityEventConnection = connection({
1752
+ lastPolledAt: new Date(NOW),
1753
+ lastError: "Poll incomplete; retrying the same window.",
1754
+ lastPollResult: result({
1755
+ status: "partial",
1756
+ complete: false,
1757
+ }) as unknown as JSONObject,
1758
+ });
1759
+ expect(connectorHealth(item, NOW)).toBe("Partial import");
1760
+ delete item.lastError;
1761
+ item.lastPollResult = result() as unknown as JSONObject;
1762
+ expect(connectorHealth(item, NOW)).toBe("Catching up");
1763
+ });
1764
+ });