@oneuptime/common 12.0.32 → 12.0.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1191) hide show
  1. package/Models/AnalyticsModels/RumSession.ts +117 -1
  2. package/Models/AnalyticsModels/RumSessionChunk.ts +13 -0
  3. package/Models/AnalyticsModels/Span.ts +14 -0
  4. package/Models/DatabaseModels/AlertCustomField.ts +77 -3
  5. package/Models/DatabaseModels/ApiKeyPermission.ts +3 -27
  6. package/Models/DatabaseModels/EnterpriseLicense.ts +56 -0
  7. package/Models/DatabaseModels/IncidentCustomField.ts +77 -3
  8. package/Models/DatabaseModels/Index.ts +10 -0
  9. package/Models/DatabaseModels/InventoryItemCustomField.ts +77 -3
  10. package/Models/DatabaseModels/Monitor.ts +76 -0
  11. package/Models/DatabaseModels/MonitorCustomField.ts +77 -3
  12. package/Models/DatabaseModels/NetworkAlertPolicy.ts +690 -0
  13. package/Models/DatabaseModels/NetworkDevice.ts +176 -1
  14. package/Models/DatabaseModels/NetworkSite.ts +201 -2
  15. package/Models/DatabaseModels/NetworkSiteType.ts +102 -3
  16. package/Models/DatabaseModels/NetworkSnmpCredentialProfile.ts +841 -0
  17. package/Models/DatabaseModels/OnCallDutyPolicyCustomField.ts +77 -3
  18. package/Models/DatabaseModels/RumApplication.ts +6 -6
  19. package/Models/DatabaseModels/ScheduledMaintenanceCustomField.ts +77 -3
  20. package/Models/DatabaseModels/StatusPageCustomField.ts +77 -3
  21. package/Models/DatabaseModels/TeamCustomField.ts +77 -3
  22. package/Models/DatabaseModels/TeamMember.ts +0 -9
  23. package/Models/DatabaseModels/TeamMemberCustomField.ts +77 -3
  24. package/Models/DatabaseModels/TeamPermission.ts +3 -24
  25. package/Models/DatabaseModels/TelemetryException.ts +119 -0
  26. package/Models/DatabaseModels/TelemetryIngestionKey.ts +260 -0
  27. package/Models/DatabaseModels/UserNotificationEmailRollupBatch.ts +334 -0
  28. package/Models/DatabaseModels/UserNotificationEmailRollupItem.ts +370 -0
  29. package/Models/DatabaseModels/UserNotificationEmailRollupSetting.ts +282 -0
  30. package/Models/DatabaseModels/UserTelegram.ts +0 -4
  31. package/Scripts/benchmark-fanin-capacity.js +181 -0
  32. package/Server/API/EnterpriseLicenseAPI.ts +391 -64
  33. package/Server/API/LlmProviderAPI.ts +137 -22
  34. package/Server/API/TelemetryAPI.ts +1284 -164
  35. package/Server/API/UserNotificationSettingAPI.ts +55 -0
  36. package/Server/API/UserTelegramAPI.ts +48 -4
  37. package/Server/EnvironmentConfig.ts +49 -2
  38. package/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.ts +55 -0
  39. package/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.ts +31 -0
  40. package/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.ts +124 -0
  41. package/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.ts +132 -0
  42. package/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.ts +79 -0
  43. package/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.ts +191 -0
  44. package/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.ts +91 -0
  45. package/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.ts +67 -0
  46. package/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.ts +139 -0
  47. package/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.ts +121 -0
  48. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +20 -0
  49. package/Server/Infrastructure/QueueWorker.ts +59 -23
  50. package/Server/Infrastructure/Semaphore.ts +2 -0
  51. package/Server/Middleware/BearerTokenAuthorization.ts +12 -0
  52. package/Server/Middleware/ProjectAuthorization.ts +11 -0
  53. package/Server/Middleware/SCIMAuthorization.ts +12 -0
  54. package/Server/Middleware/TelemetryIngest.ts +464 -7
  55. package/Server/Services/AIBillingService.ts +101 -27
  56. package/Server/Services/AccessTokenService.ts +1 -0
  57. package/Server/Services/AlertCustomFieldService.ts +98 -0
  58. package/Server/Services/AlertService.ts +37 -0
  59. package/Server/Services/ApiKeyPermissionService.ts +461 -29
  60. package/Server/Services/CustomFieldMappingService.ts +879 -0
  61. package/Server/Services/EnterpriseLicenseInstanceService.ts +197 -0
  62. package/Server/Services/EnterpriseLicenseService.ts +55 -0
  63. package/Server/Services/GlobalConfigService.ts +194 -0
  64. package/Server/Services/IncidentCustomFieldService.ts +98 -0
  65. package/Server/Services/IncidentService.ts +35 -0
  66. package/Server/Services/Index.ts +10 -0
  67. package/Server/Services/MetricService.ts +194 -0
  68. package/Server/Services/MonitorService.ts +175 -21
  69. package/Server/Services/MonitorStatusTimelineService.ts +150 -8
  70. package/Server/Services/MonitorTemplateService.ts +217 -1
  71. package/Server/Services/NetworkAlertPolicyEngineService.ts +2159 -0
  72. package/Server/Services/NetworkAlertPolicyService.ts +944 -0
  73. package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +87 -35
  74. package/Server/Services/NetworkDeviceAutoImportRuleService.ts +60 -15
  75. package/Server/Services/NetworkDeviceService.ts +1032 -73
  76. package/Server/Services/NetworkSiteService.ts +1502 -129
  77. package/Server/Services/NetworkSiteTypeService.ts +1216 -0
  78. package/Server/Services/NetworkSnmpCredentialProfileService.ts +238 -0
  79. package/Server/Services/NotificationService.ts +118 -28
  80. package/Server/Services/ProjectService.ts +127 -48
  81. package/Server/Services/RoutineEmailSettingsService.ts +73 -0
  82. package/Server/Services/RumSessionReplayViewService.ts +104 -24
  83. package/Server/Services/ScheduledMaintenanceCustomFieldService.ts +98 -0
  84. package/Server/Services/ScheduledMaintenanceService.ts +32 -0
  85. package/Server/Services/StatusPagePrivateUserService.ts +103 -3
  86. package/Server/Services/TeamMemberService.ts +78 -0
  87. package/Server/Services/TeamPermissionService.ts +235 -3
  88. package/Server/Services/TelemetryIngestionKeyService.ts +722 -19
  89. package/Server/Services/UserNotificationEmailRollupBatchService.ts +78 -0
  90. package/Server/Services/UserNotificationEmailRollupItemService.ts +79 -0
  91. package/Server/Services/UserNotificationEmailRollupSettingService.ts +113 -0
  92. package/Server/Services/UserNotificationSettingService.ts +90 -25
  93. package/Server/Services/UserService.ts +95 -0
  94. package/Server/Services/UserTelegramService.ts +326 -5
  95. package/Server/Types/Database/QueryHelper.ts +4 -2
  96. package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +14 -3
  97. package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts +10 -0
  98. package/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts +10 -0
  99. package/Server/Utils/AI/SRE/Insights/InsightTriageRunner.ts +62 -1
  100. package/Server/Utils/AI/Toolbox/AlertTools.ts +15 -1
  101. package/Server/Utils/APIKey/AccessPermission.ts +5 -2
  102. package/Server/Utils/Billing/BillingFailureNoticeThrottle.ts +80 -0
  103. package/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.ts +54 -0
  104. package/Server/Utils/CustomField/CustomFieldMappingRegistry.ts +415 -0
  105. package/Server/Utils/CustomField/CustomFieldMappingValidator.ts +335 -0
  106. package/Server/Utils/DataSource/EgressGuard.ts +177 -8
  107. package/Server/Utils/DataSource/HttpFetch.ts +9 -2
  108. package/Server/Utils/EmailRollup/EmailRollupConstants.ts +131 -0
  109. package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +925 -0
  110. package/Server/Utils/EmailRollup/EmailRollupRenderer.ts +781 -0
  111. package/Server/Utils/EmailRollup/EmailRollupWriter.ts +368 -0
  112. package/Server/Utils/FrontendEnvironment.ts +40 -0
  113. package/Server/Utils/LLM/LLMService.ts +78 -0
  114. package/Server/Utils/LogRedaction.ts +28 -0
  115. package/Server/Utils/Logger.ts +90 -1
  116. package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +338 -77
  117. package/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.ts +190 -0
  118. package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +9 -2
  119. package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +30 -4
  120. package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +61 -1
  121. package/Server/Utils/Monitor/MonitorAlert.ts +29 -6
  122. package/Server/Utils/Monitor/MonitorCriteriaDataExtractor.ts +14 -0
  123. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +159 -15
  124. package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +255 -4
  125. package/Server/Utils/Monitor/MonitorIncident.ts +22 -6
  126. package/Server/Utils/Monitor/MonitorMetricUtil.ts +41 -0
  127. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +72 -0
  128. package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +499 -19
  129. package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +66 -10
  130. package/Server/Utils/Monitor/NetworkDeviceWalkUtil.ts +238 -44
  131. package/Server/Utils/Monitor/NetworkInventoryUtil.ts +146 -39
  132. package/Server/Utils/Monitor/SeriesContextEnricher.ts +304 -0
  133. package/Server/Utils/NetworkDevice/DeviceHealthAggregation.ts +31 -18
  134. package/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.ts +213 -0
  135. package/Server/Utils/OutboundUserAgent.ts +152 -0
  136. package/Server/Utils/SSRFProtection.ts +217 -10
  137. package/Server/Utils/SessionReplay/SessionReplayGateCache.ts +239 -138
  138. package/Server/Utils/SessionReplay/SessionReplayHealthCounters.ts +305 -0
  139. package/Server/Utils/SessionReplay/SessionReplayReadService.ts +1430 -289
  140. package/Server/Utils/StartServer.ts +53 -36
  141. package/Server/Utils/TelegramVerificationToken.ts +185 -0
  142. package/Server/Utils/Telemetry/CaptureSpan.ts +32 -8
  143. package/Server/Utils/Telemetry/ErrorClassResolver.ts +120 -0
  144. package/Server/Utils/Telemetry/PinServiceName.ts +197 -0
  145. package/Server/Utils/Telemetry/SpanUtil.ts +33 -0
  146. package/Server/Utils/Telemetry/TelemetryFanInWriter.ts +38 -16
  147. package/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.ts +92 -0
  148. package/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.ts +217 -0
  149. package/Server/Utils/Telemetry.ts +198 -51
  150. package/Server/Utils/VM/VMAPI.ts +1 -0
  151. package/Server/Utils/VM/VMRunner.ts +975 -95
  152. package/Server/Views/Partials/SensitiveUrlToken.ejs +140 -0
  153. package/Tests/App/AdminDashboard/AdminHeaderSmallScreens.test.tsx +202 -0
  154. package/Tests/App/Dashboard/AddNeighborToMonitoringModal.test.tsx +134 -33
  155. package/Tests/App/Dashboard/AskAiSuggestedPrompts.test.ts +279 -0
  156. package/Tests/App/Dashboard/DashboardEditPermissions.test.tsx +517 -0
  157. package/Tests/App/Dashboard/DashboardHeaderSmallScreens.test.tsx +404 -0
  158. package/Tests/App/Dashboard/DashboardVariablesDiscard.test.tsx +26 -0
  159. package/Tests/App/Dashboard/DeviceStatusHero.test.tsx +588 -0
  160. package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +486 -9
  161. package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +632 -0
  162. package/Tests/App/Dashboard/MonitorRecommendationCreateProgress.test.tsx +682 -0
  163. package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +4 -2
  164. package/Tests/App/Dashboard/NetworkDeviceCreateFormMonitorBinding.test.tsx +676 -0
  165. package/Tests/App/Dashboard/NetworkDeviceCreateFormPingMonitor.test.tsx +791 -0
  166. package/Tests/App/Dashboard/NetworkDeviceCreateFormProbeAndSnmp.test.tsx +833 -0
  167. package/Tests/App/Dashboard/NetworkDeviceCriteriaFilter.test.ts +161 -0
  168. package/Tests/App/Dashboard/NetworkDeviceSettingsMonitoringSection.test.tsx +458 -0
  169. package/Tests/App/Dashboard/NetworkSideMenu.test.tsx +41 -5
  170. package/Tests/App/Dashboard/NotificationEmailPreferences.test.tsx +399 -0
  171. package/Tests/App/Dashboard/PingMonitorProvisioning.test.ts +368 -0
  172. package/Tests/App/Dashboard/RecommendationCard.test.tsx +796 -0
  173. package/Tests/App/Dashboard/RecommendationToolbar.test.tsx +519 -0
  174. package/Tests/App/Dashboard/RecommendationsList.test.tsx +661 -0
  175. package/Tests/App/Dashboard/UseBulkCreatePingMonitors.test.tsx +899 -0
  176. package/Tests/App/Dashboard/UseBulkSnmpCredentialProfileActions.test.tsx +732 -0
  177. package/Tests/App/SensitiveUrlTokenBootstrap.test.ts +256 -0
  178. package/Tests/App/StatusPage/StatusPageIndexPageRobotsMeta.test.ts +11 -1
  179. package/Tests/App/StatusPage/StatusPageLastUpdated.test.tsx +263 -0
  180. package/Tests/App/StatusPage/StatusPageLoginCodeBootstrap.test.ts +9 -4
  181. package/Tests/App/StatusPage/StatusPageOverviewLiveAndSearch.test.tsx +753 -0
  182. package/Tests/App/StatusPage/StatusPageResourceSearchBox.test.tsx +224 -0
  183. package/Tests/Models/AnalyticsModels/RumSessionReplayColumns.test.ts +262 -0
  184. package/Tests/Models/CustomFieldMappingColumns.test.ts +166 -0
  185. package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +20 -6
  186. package/Tests/Models/NetworkSiteHierarchy.test.ts +41 -4
  187. package/Tests/ResponsiveVisibility.test.ts +115 -0
  188. package/Tests/ResponsiveVisibility.ts +183 -0
  189. package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +951 -7
  190. package/Tests/Server/API/LlmProviderConnectionTest.test.ts +522 -0
  191. package/Tests/Server/API/SessionReplayAPI.test.ts +1940 -216
  192. package/Tests/Server/API/UserNotificationSettingAPI.test.ts +186 -0
  193. package/Tests/Server/API/UserTelegramAPISecurity.test.ts +231 -0
  194. package/Tests/Server/EnvironmentConfigFrontendSecurity.test.ts +234 -0
  195. package/Tests/Server/Infrastructure/Postgres/CustomFieldValueMappingMigration.test.ts +202 -0
  196. package/Tests/Server/Infrastructure/Postgres/InventoryItemArchiveMigration.test.ts +41 -0
  197. package/Tests/Server/Infrastructure/Postgres/NetworkSnmpCredentialProfilesAndAlertPoliciesMigration.test.ts +854 -0
  198. package/Tests/Server/Infrastructure/Postgres/SchemaMigrationsOrdering.test.ts +18 -0
  199. package/Tests/Server/Infrastructure/Postgres/SessionReplayRecordEverySessionByDefaultMigration.test.ts +169 -0
  200. package/Tests/Server/Infrastructure/Postgres/UserNotificationEmailRollupTableMigration.test.ts +535 -0
  201. package/Tests/Server/Infrastructure/QueueWorkerTimeout.test.ts +210 -0
  202. package/Tests/Server/Infrastructure/TelemetryExporterDeploymentConfig.test.ts +130 -0
  203. package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +4 -1
  204. package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +1163 -0
  205. package/Tests/Server/Middleware/TelemetryIngestTokenLog.test.ts +5 -3
  206. package/Tests/Server/Services/AIChatPrivacyPin.test.ts +560 -0
  207. package/Tests/Server/Services/AddTelemetryIngestionKeyTypeMigration.test.ts +555 -0
  208. package/Tests/Server/Services/ApiKeyPermissionSecurity.test.ts +678 -0
  209. package/Tests/Server/Services/ApiKeyPermissionService.test.ts +276 -28
  210. package/Tests/Server/Services/BillingRechargeOwnerEmailGuards.test.ts +783 -0
  211. package/Tests/Server/Services/CustomFieldDropdownOptionsColumnWidth.test.ts +431 -0
  212. package/Tests/Server/Services/CustomFieldMappingService.test.ts +850 -0
  213. package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +32 -0
  214. package/Tests/Server/Services/EnterpriseLicenseInstanceServiceDeletionUsage.test.ts +707 -0
  215. package/Tests/Server/Services/EnterpriseLicenseServiceUsageAggregationLock.test.ts +329 -0
  216. package/Tests/Server/Services/GlobalConfigService.test.ts +414 -1
  217. package/Tests/Server/Services/MetricRawEntityKeyPrune.test.ts +592 -0
  218. package/Tests/Server/Services/MonitorServiceDeleteNetworkDeviceCleanup.test.ts +294 -0
  219. package/Tests/Server/Services/MonitorStatusBridgeProbePath.test.ts +802 -0
  220. package/Tests/Server/Services/MonitorStatusTimelineService.test.ts +72 -2
  221. package/Tests/Server/Services/NetworkAlertPolicyEngineHooks.test.ts +752 -0
  222. package/Tests/Server/Services/NetworkAlertPolicyEngineService.test.ts +1849 -0
  223. package/Tests/Server/Services/NetworkAlertPolicyModel.test.ts +1793 -0
  224. package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +273 -5
  225. package/Tests/Server/Services/NetworkDeviceAutoImportRuleService.test.ts +97 -12
  226. package/Tests/Server/Services/NetworkDeviceAutoMonitorLifecycle.test.ts +148 -3
  227. package/Tests/Server/Services/NetworkDeviceMonitorBindingUpdateGuard.test.ts +514 -0
  228. package/Tests/Server/Services/NetworkDeviceMonitorStatusStamp.test.ts +447 -58
  229. package/Tests/Server/Services/NetworkDeviceMonitoringMethodTransition.test.ts +739 -0
  230. package/Tests/Server/Services/NetworkDevicePollingTenancy.test.ts +501 -0
  231. package/Tests/Server/Services/NetworkDeviceSiteDefaultProbe.test.ts +432 -0
  232. package/Tests/Server/Services/NetworkSiteMonitoringDefaults.test.ts +498 -0
  233. package/Tests/Server/Services/NetworkSiteRollupPolicyAndMaintenance.test.ts +337 -55
  234. package/Tests/Server/Services/NetworkSiteService.test.ts +1868 -131
  235. package/Tests/Server/Services/NetworkSiteTypeService.test.ts +1109 -0
  236. package/Tests/Server/Services/NetworkSnmpCredentialProfileModel.test.ts +926 -0
  237. package/Tests/Server/Services/NetworkSnmpCredentialProfileService.test.ts +796 -0
  238. package/Tests/Server/Services/ProjectServiceNetworkSiteTypeDefaults.test.ts +214 -0
  239. package/Tests/Server/Services/RoutineEmailSettingsPostgres.test.ts +329 -0
  240. package/Tests/Server/Services/RumSessionReplayViewService.test.ts +267 -0
  241. package/Tests/Server/Services/StatusPagePrivateUserEmailChangePasswordResetExpiry.test.ts +269 -0
  242. package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +9 -0
  243. package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +9 -0
  244. package/Tests/Server/Services/TeamPrivilegeEscalation.test.ts +834 -0
  245. package/Tests/Server/Services/TelemetryIngestionKeyPolicyResolution.test.ts +814 -0
  246. package/Tests/Server/Services/TelemetryIngestionKeyValidation.test.ts +998 -0
  247. package/Tests/Server/Services/UserEmailChangePasswordResetExpiry.test.ts +472 -0
  248. package/Tests/Server/Services/UserNotificationEmailRollupModels.test.ts +569 -0
  249. package/Tests/Server/Services/UserNotificationEmailRollupSettingModel.test.ts +314 -0
  250. package/Tests/Server/Services/UserNotificationEmailRollupSettingService.test.ts +409 -0
  251. package/Tests/Server/Services/UserNotificationSettingRollupRouting.test.ts +997 -0
  252. package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +110 -1
  253. package/Tests/Server/Services/UserTelegramVerificationSecurity.test.ts +688 -0
  254. package/Tests/Server/Types/Database/Permissions/DashboardAccessPermission.test.ts +321 -0
  255. package/Tests/Server/Types/Database/QueryHelperOperators.test.ts +17 -0
  256. package/Tests/Server/Utils/AI/AlertMonitorFilters.test.ts +124 -0
  257. package/Tests/Server/Utils/AI/Insights/InsightTriageRunner.test.ts +208 -0
  258. package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +235 -0
  259. package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +253 -0
  260. package/Tests/Server/Utils/AI/SRE/Insights/FixRouting.test.ts +497 -0
  261. package/Tests/Server/Utils/AI/Toolbox/Serializer.test.ts +383 -0
  262. package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +7 -3
  263. package/Tests/Server/Utils/AnalyticsDatabase/ClusterConfig.test.ts +315 -0
  264. package/Tests/Server/Utils/Captcha.test.ts +422 -0
  265. package/Tests/Server/Utils/CustomField/CustomFieldMappingValidator.test.ts +437 -0
  266. package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +300 -11
  267. package/Tests/Server/Utils/DataSource/HttpFetch.test.ts +96 -2
  268. package/Tests/Server/Utils/Database/MigrationFailureLog.test.ts +466 -0
  269. package/Tests/Server/Utils/EmailRollup/EmailRollupBurstWindow.test.ts +83 -0
  270. package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerBehaviour.test.ts +1096 -0
  271. package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerClaim.test.ts +466 -0
  272. package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerPreferences.test.ts +362 -0
  273. package/Tests/Server/Utils/EmailRollup/EmailRollupRenderer.test.ts +1428 -0
  274. package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +828 -0
  275. package/Tests/Server/Utils/EmailRollup/EmailRollupWriter.test.ts +864 -0
  276. package/Tests/Server/Utils/FrontendEnvironment.test.ts +190 -0
  277. package/Tests/Server/Utils/LogRedaction.test.ts +26 -0
  278. package/Tests/Server/Utils/LoggerCredentialLeak.test.ts +23 -9
  279. package/Tests/Server/Utils/LoggerFaultDemotion.test.ts +346 -0
  280. package/Tests/Server/Utils/Monitor/Criteria/CompareCriteriaAggregation.test.ts +584 -0
  281. package/Tests/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.test.ts +633 -0
  282. package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestHeaderCriteria.test.ts +236 -0
  283. package/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.ts +196 -0
  284. package/Tests/Server/Utils/Monitor/DatabaseMetricWrite.test.ts +367 -0
  285. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +437 -0
  286. package/Tests/Server/Utils/Monitor/MonitorCriteriaObservationBuilderUnits.test.ts +100 -0
  287. package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +5 -0
  288. package/Tests/Server/Utils/Monitor/MonitorTemplateUtilSeriesContext.test.ts +176 -0
  289. package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +512 -31
  290. package/Tests/Server/Utils/Monitor/NetworkDeviceMetricUtil.test.ts +252 -0
  291. package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +479 -42
  292. package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +351 -5
  293. package/Tests/Server/Utils/Monitor/SeriesContextEnricher.test.ts +356 -0
  294. package/Tests/Server/Utils/NetworkDevice/DeviceHealthAggregation.test.ts +136 -12
  295. package/Tests/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.test.ts +306 -0
  296. package/Tests/Server/Utils/OutboundUserAgent.test.ts +266 -0
  297. package/Tests/Server/Utils/SSRFProtectionCloudServiceAddresses.test.ts +595 -0
  298. package/Tests/Server/Utils/SecurityEvent/ThreatIntel/TaxiiClientUserAgent.test.ts +141 -0
  299. package/Tests/Server/Utils/SessionReplay/SessionReplayGateCachePolicy.test.ts +198 -1
  300. package/Tests/Server/Utils/SessionReplay/SessionReplayHealthCounters.test.ts +453 -0
  301. package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +1378 -0
  302. package/Tests/Server/Utils/SessionReplayOriginAllowListRefactor.test.ts +420 -0
  303. package/Tests/Server/Utils/TelegramVerificationToken.test.ts +253 -0
  304. package/Tests/Server/Utils/Telemetry/ErrorClassResolver.test.ts +298 -0
  305. package/Tests/Server/Utils/Telemetry/PinServiceName.test.ts +666 -0
  306. package/Tests/Server/Utils/Telemetry/TelemetryFanInWriterCapacity.test.ts +458 -0
  307. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +424 -0
  308. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.test.ts +528 -0
  309. package/Tests/Server/Utils/Telemetry.test.ts +456 -66
  310. package/Tests/Server/Utils/TelemetryExporterEnvironment.test.ts +56 -0
  311. package/Tests/Server/Utils/VM/VMRunnerHostBridgeLatency.test.ts +74 -0
  312. package/Tests/Server/Utils/VM/VMRunnerPrivateNetworkWiring.test.ts +100 -7
  313. package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +1176 -6
  314. package/Tests/Types/CustomField/CustomFieldMappingCatalog.test.ts +220 -0
  315. package/Tests/Types/CustomField/CustomFieldValueMapping.test.ts +348 -0
  316. package/Tests/Types/JSONFunctions.test.ts +260 -0
  317. package/Tests/Types/Monitor/CephAlertTemplates.test.ts +422 -53
  318. package/Tests/Types/Monitor/DatabaseMetricCatalog.test.ts +388 -0
  319. package/Tests/Types/Monitor/DockerAlertTemplates.test.ts +495 -15
  320. package/Tests/Types/Monitor/DockerSwarmAlertTemplates.test.ts +191 -45
  321. package/Tests/Types/Monitor/HostAlertTemplates.test.ts +370 -42
  322. package/Tests/Types/Monitor/IotAlertTemplates.test.ts +375 -20
  323. package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +636 -42
  324. package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +189 -0
  325. package/Tests/Types/Monitor/KubernetesTemplateGroupByKeys.test.ts +95 -14
  326. package/Tests/Types/Monitor/MonitorStepDatabaseMonitor.test.ts +243 -0
  327. package/Tests/Types/Monitor/MonitorStepDefaultTelemetryConfig.test.ts +1 -0
  328. package/Tests/Types/Monitor/MonitorType.test.ts +1 -0
  329. package/Tests/Types/Monitor/MonitorTypeKeywords.test.ts +16 -7
  330. package/Tests/Types/Monitor/NetworkDeviceAlertPack.test.ts +60 -0
  331. package/Tests/Types/Monitor/PodmanAlertTemplates.test.ts +190 -21
  332. package/Tests/Types/Monitor/ProxmoxAlertTemplates.test.ts +352 -22
  333. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationAlertDebuggability.test.ts +363 -0
  334. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +93 -18
  335. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +259 -0
  336. package/Tests/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.test.ts +476 -0
  337. package/Tests/Types/Monitor/RumAlertTemplates.test.ts +136 -0
  338. package/Tests/Types/Monitor/SeriesContext/SeriesDebugHints.test.ts +661 -0
  339. package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +507 -0
  340. package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +270 -0
  341. package/Tests/Types/Monitor/TemplateGroupByKeys.test.ts +38 -10
  342. package/Tests/Types/Monitor/Utils/RecommendationCriteriaAssertions.ts +102 -0
  343. package/Tests/Types/NetworkDevice/NetworkAlertPolicyScope.test.ts +655 -0
  344. package/Tests/Types/NetworkDevice/NetworkDeviceMonitoringMethod.test.ts +115 -26
  345. package/Tests/Types/NetworkSite/DefaultNetworkSiteType.test.ts +39 -0
  346. package/Tests/Types/NotificationSetting/NotificationEmailRollupPolicy.test.ts +299 -0
  347. package/Tests/Types/NotificationSetting/RoutineEmailEvents.test.ts +47 -0
  348. package/Tests/Types/Rum/SessionReplayApiContracts.test.ts +608 -0
  349. package/Tests/Types/Rum/SessionReplayCustomEvents.test.ts +434 -0
  350. package/Tests/Types/Telemetry/ErrorClass.test.ts +483 -0
  351. package/Tests/Types/WebsiteRequest.test.ts +285 -3
  352. package/Tests/UI/Components/BasicRadioButtons.test.tsx +336 -0
  353. package/Tests/UI/Components/Charts/ChartBucketIdentity.test.ts +16 -3
  354. package/Tests/UI/Components/Charts/ChartTrailingBucketGap.test.ts +691 -0
  355. package/Tests/UI/Components/ComponentsModal.test.tsx +12 -4
  356. package/Tests/UI/Components/ComponentsModalUsability.test.tsx +518 -0
  357. package/Tests/UI/Components/CustomFields/CustomFieldsDetailMapping.test.tsx +324 -0
  358. package/Tests/UI/Components/CustomFields/MapFromCustomFieldInput.test.tsx +176 -0
  359. package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +484 -0
  360. package/Tests/UI/Components/HeaderRightRail.test.tsx +157 -0
  361. package/Tests/UI/Components/IconDropdownItem.test.tsx +102 -0
  362. package/Tests/UI/Components/JSONTablePrototypePollution.test.tsx +117 -0
  363. package/Tests/UI/Components/KeyboardShortcutsModal.test.tsx +214 -0
  364. package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +561 -0
  365. package/Tests/UI/Components/MonitorGraphs/UptimeBarDayModal.test.tsx +302 -0
  366. package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +43 -12
  367. package/Tests/UI/Components/ProgressBar.test.tsx +38 -2
  368. package/Tests/UI/Components/ShortcutDialogGuard.test.tsx +74 -0
  369. package/Tests/UI/Components/SideMenuItem.test.tsx +226 -4
  370. package/Tests/UI/Components/SideMenuSection.test.tsx +310 -0
  371. package/Tests/UI/Components/SideOverSubmitState.test.tsx +335 -0
  372. package/Tests/UI/Components/StatusPage/ResourceGroupSectionAutoExpand.test.tsx +248 -0
  373. package/Tests/UI/Components/TableCellWrapping.test.tsx +625 -0
  374. package/Tests/UI/Components/TableLoadingStates.test.tsx +205 -0
  375. package/Tests/UI/Components/Workflow/NodePlacement.test.ts +148 -0
  376. package/Tests/UI/Components/Workflow/Workflow.test.tsx +981 -0
  377. package/Tests/UI/ConfigBrowserTelemetry.test.ts +70 -0
  378. package/Tests/UI/Rum/ChunkLoader.test.ts +1036 -2
  379. package/Tests/UI/Rum/FidelityNotices.test.ts +187 -0
  380. package/Tests/UI/Rum/InactivityMap.test.ts +341 -0
  381. package/Tests/UI/Rum/PrivacySummaryCard.test.tsx +259 -0
  382. package/Tests/UI/Rum/RecordingHealthCard.test.tsx +855 -0
  383. package/Tests/UI/Rum/RecordingHealthStrip.test.tsx +594 -0
  384. package/Tests/UI/Rum/ReplayCard.test.tsx +451 -0
  385. package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +536 -0
  386. package/Tests/UI/Rum/ReplayEngine.test.ts +2503 -0
  387. package/Tests/UI/Rum/ReplayEngineTypes.test.ts +171 -0
  388. package/Tests/UI/Rum/ReplayHeader.test.tsx +711 -0
  389. package/Tests/UI/Rum/ReplayLink.test.tsx +119 -0
  390. package/Tests/UI/Rum/ReplayPinControl.test.tsx +408 -0
  391. package/Tests/UI/Rum/ReplayPlaybackIntent.test.ts +152 -0
  392. package/Tests/UI/Rum/ReplayRail.test.tsx +1296 -0
  393. package/Tests/UI/Rum/ReplayRailDetail.test.tsx +900 -0
  394. package/Tests/UI/Rum/ReplayScrubber.test.tsx +763 -147
  395. package/Tests/UI/Rum/ReplaySignalTypes.test.ts +189 -0
  396. package/Tests/UI/Rum/ReplaySignals.test.ts +1579 -0
  397. package/Tests/UI/Rum/ReplayStage.test.tsx +396 -473
  398. package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +918 -0
  399. package/Tests/UI/Rum/ReplayTimeline.test.tsx +696 -0
  400. package/Tests/UI/Rum/SessionReplayEmptyState.test.tsx +499 -0
  401. package/Tests/UI/Rum/SessionReplaySearchBar.test.tsx +346 -0
  402. package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +545 -0
  403. package/Tests/UI/Rum/SessionReplayTable.test.tsx +991 -0
  404. package/Tests/UI/Rum/TargetedCapturePanel.test.tsx +254 -0
  405. package/Tests/UI/Telemetry/BrowserExporterIsolation.test.ts +71 -0
  406. package/Tests/UI/Utils/GlobalKeyboardShortcut.test.ts +344 -0
  407. package/Tests/UI/Utils/PageScrollLock.test.tsx +377 -0
  408. package/Tests/UI/Utils/PermissionGate.test.ts +78 -0
  409. package/Tests/UI/Utils/SensitiveUrlToken.test.ts +140 -0
  410. package/Tests/Utils/API.test.ts +308 -0
  411. package/Tests/Utils/EnterpriseLicenseSeats.test.ts +69 -0
  412. package/Tests/Utils/EnterpriseLicenseSync.test.ts +7 -1
  413. package/Tests/Utils/EnterpriseLicenseUsage.test.ts +433 -2
  414. package/Tests/Utils/HTTPResponseBodyReader.test.ts +323 -0
  415. package/Tests/Utils/Monitor/MonitorMetricType.test.ts +280 -1
  416. package/Tests/Utils/Monitor/MonitorSummarySnapshotUtil.test.ts +1 -0
  417. package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +38 -0
  418. package/Tests/Utils/NetworkDevice/DeviceHealthStateUtil.test.ts +284 -23
  419. package/Tests/Utils/NetworkDevice/DeviceReachabilityUtil.test.ts +177 -0
  420. package/Tests/Utils/NetworkDevice/MonitoringMethodThreadedClassifiers.test.ts +992 -0
  421. package/Tests/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.test.ts +427 -0
  422. package/Tests/Utils/NetworkDevice/ReachabilityStampConsistency.test.ts +185 -0
  423. package/Tests/Utils/NetworkDevice/SnmpCredentialUtil.test.ts +268 -0
  424. package/Tests/Utils/NetworkDiscovery/AutoImportRuleMatcher.test.ts +55 -5
  425. package/Tests/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.test.ts +98 -21
  426. package/Tests/Utils/NetworkDiscovery/DiscoveryImportEligibility.test.ts +98 -20
  427. package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +8 -7
  428. package/Tests/Utils/NetworkDiscovery/DiscoveryScanStatus.test.ts +117 -0
  429. package/Tests/Utils/NetworkDiscovery/PingMonitorBuilderForAddress.test.ts +274 -0
  430. package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +230 -51
  431. package/Tests/Utils/NetworkSite/TypeHierarchyUtil.test.ts +209 -0
  432. package/Tests/Utils/Rum/ChunkMath.test.ts +83 -0
  433. package/Tests/Utils/Rum/SessionReplayHealthDiagnosis.test.ts +993 -0
  434. package/Tests/Utils/Rum/SessionReplayStringMap.test.ts +245 -0
  435. package/Tests/Utils/StatusPage/ResourceSearch.test.ts +631 -0
  436. package/Tests/Utils/Telemetry/CaptureSpanExportGating.test.ts +145 -0
  437. package/Tests/Utils/Telemetry/OriginAllowList.test.ts +633 -0
  438. package/Tests/Utils/Uptime/DayUptimeGraphUtil.test.ts +461 -0
  439. package/Tests/Utils/ValueFormatter.test.ts +148 -0
  440. package/Types/AI/ExceptionAIClassification.ts +10 -24
  441. package/Types/CustomField/CustomFieldMappingCatalog.ts +161 -0
  442. package/Types/CustomField/CustomFieldMappingSourceResource.ts +19 -0
  443. package/Types/CustomField/CustomFieldValueMapping.ts +288 -0
  444. package/Types/Email/EmailTemplateType.ts +2 -0
  445. package/Types/EnterpriseLicense/EnterpriseLicenseInstanceSummary.ts +5 -0
  446. package/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.ts +13 -0
  447. package/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.ts +6 -0
  448. package/Types/Exception/ApiException.ts +10 -0
  449. package/Types/Exception/BadDataException.ts +11 -0
  450. package/Types/Exception/BadRequestException.ts +11 -0
  451. package/Types/Exception/Exception.ts +65 -0
  452. package/Types/Exception/ForbiddenException.ts +10 -0
  453. package/Types/Exception/NotAuthenticatedException.ts +10 -0
  454. package/Types/Exception/NotAuthorizedException.ts +10 -0
  455. package/Types/Exception/NotFoundException.ts +11 -0
  456. package/Types/Exception/PayloadTooLargeException.ts +11 -0
  457. package/Types/Exception/PaymentRequiredException.ts +10 -0
  458. package/Types/Exception/ServiceUnavailableException.ts +10 -0
  459. package/Types/Exception/SsoAuthorizationException.ts +10 -0
  460. package/Types/Exception/TenantNotFoundException.ts +11 -0
  461. package/Types/Exception/TimeoutException.ts +10 -0
  462. package/Types/Exception/TooManyRequestsException.ts +10 -0
  463. package/Types/Exception/UnableToReachServer.ts +10 -0
  464. package/Types/Exception/WebsiteRequestException.ts +10 -0
  465. package/Types/Icon/IconProp.ts +1 -0
  466. package/Types/JSONFunctions.ts +189 -43
  467. package/Types/Monitor/CephAlertTemplates.ts +157 -195
  468. package/Types/Monitor/CriteriaFilter.ts +60 -2
  469. package/Types/Monitor/DatabaseMetricCatalog.ts +693 -0
  470. package/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.ts +83 -0
  471. package/Types/Monitor/DockerAlertTemplates.ts +338 -128
  472. package/Types/Monitor/DockerSwarmAlertTemplates.ts +95 -112
  473. package/Types/Monitor/HostAlertTemplates.ts +302 -130
  474. package/Types/Monitor/IotAlertTemplates.ts +112 -104
  475. package/Types/Monitor/KubernetesAlertTemplates.ts +415 -224
  476. package/Types/Monitor/KubernetesMetricCatalog.ts +23 -19
  477. package/Types/Monitor/MonitorCriteriaInstance.ts +76 -0
  478. package/Types/Monitor/MonitorMetricType.ts +71 -0
  479. package/Types/Monitor/MonitorStep.ts +76 -0
  480. package/Types/Monitor/MonitorStepDatabaseMonitor.ts +171 -0
  481. package/Types/Monitor/MonitorStepSqlMonitor.ts +2 -20
  482. package/Types/Monitor/MonitorType.ts +47 -1
  483. package/Types/Monitor/PodmanAlertTemplates.ts +116 -163
  484. package/Types/Monitor/ProxmoxAlertTemplates.ts +217 -99
  485. package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +98 -6
  486. package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +44 -7
  487. package/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.ts +383 -0
  488. package/Types/Monitor/RumAlertTemplates.ts +46 -7
  489. package/Types/Monitor/SeriesContext/SeriesDebugHints.ts +596 -0
  490. package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +554 -0
  491. package/Types/Monitor/ServiceAlertTemplates.ts +98 -11
  492. package/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.ts +22 -1
  493. package/Types/Monitor/SqlConnectionConfig.ts +31 -0
  494. package/Types/Monitor/UptimeHistoryLabels.ts +56 -0
  495. package/Types/NetworkDevice/NetworkAlertPolicyScope.ts +343 -0
  496. package/Types/NetworkDevice/NetworkDeviceMonitoringMethod.ts +42 -22
  497. package/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.ts +30 -0
  498. package/Types/NotificationSetting/NotificationEmailRollupCategory.ts +255 -0
  499. package/Types/NotificationSetting/NotificationEmailRollupPolicy.ts +104 -0
  500. package/Types/NotificationSetting/RoutineEmailEvents.ts +30 -0
  501. package/Types/Permission.ts +90 -0
  502. package/Types/Probe/ProbeMonitorResponse.ts +16 -0
  503. package/Types/Rum/SessionReplay.ts +209 -0
  504. package/Types/Rum/SessionReplayApi.ts +722 -0
  505. package/Types/Rum/SessionReplayCaptureTrigger.ts +21 -12
  506. package/Types/Rum/SessionReplayConsentMode.ts +11 -7
  507. package/Types/Rum/SessionReplayCustomEvents.ts +549 -0
  508. package/Types/Rum/SessionReplayHealth.ts +238 -0
  509. package/Types/Telemetry/ErrorClass.ts +274 -0
  510. package/Types/Telemetry/TelemetryIngestSurface.ts +95 -0
  511. package/Types/Telemetry/TelemetryIngestionKeyPolicy.ts +75 -0
  512. package/Types/Telemetry/TelemetryIngestionKeyType.ts +29 -0
  513. package/Types/Telemetry/UnitOfWork.ts +59 -0
  514. package/Types/WebsiteRequest.ts +85 -3
  515. package/UI/Components/Charts/Area/AreaChart.tsx +13 -2
  516. package/UI/Components/Charts/Bar/BarChart.tsx +6 -2
  517. package/UI/Components/Charts/Line/LineChart.tsx +13 -2
  518. package/UI/Components/Charts/Types/XAxis/XAxis.ts +29 -0
  519. package/UI/Components/Charts/Utils/DataPoint.ts +22 -3
  520. package/UI/Components/Charts/Utils/TimeAnnotation.ts +76 -9
  521. package/UI/Components/Charts/Utils/XAxis.ts +217 -0
  522. package/UI/Components/CommandPalette/CommandPalette.tsx +2 -8
  523. package/UI/Components/CustomFields/CustomFieldsDetail.tsx +143 -25
  524. package/UI/Components/CustomFields/MapFromCustomFieldInput.tsx +216 -0
  525. package/UI/Components/EditionLabel/EditionLabel.tsx +4 -0
  526. package/UI/Components/Graphs/DayUptimeGraph.tsx +173 -8
  527. package/UI/Components/Graphs/UptimeBarTooltip.tsx +22 -278
  528. package/UI/Components/Graphs/UptimeDaySummary.tsx +327 -0
  529. package/UI/Components/Header/Header.tsx +25 -9
  530. package/UI/Components/Header/IconDropdown/IconDropdownItem.tsx +10 -1
  531. package/UI/Components/Header/IconDropdown/IconDropdownMenu.tsx +6 -1
  532. package/UI/Components/Header/ProjectPicker/ProjectPicker.tsx +6 -1
  533. package/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.tsx +6 -1
  534. package/UI/Components/Icon/Icon.tsx +11 -0
  535. package/UI/Components/JSONTable/JSONTable.tsx +2 -2
  536. package/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.tsx +125 -0
  537. package/UI/Components/KeyboardShortcut/Screenshots/README.md +19 -0
  538. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-command-palette.png +0 -0
  539. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog-dark.png +0 -0
  540. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog.png +0 -0
  541. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-help-menu.png +0 -0
  542. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-narrow.png +0 -0
  543. package/UI/Components/Modal/Modal.tsx +2 -8
  544. package/UI/Components/ModelTable/Column.ts +15 -0
  545. package/UI/Components/Monitor/SeriesDebugCommandsViewer.tsx +64 -0
  546. package/UI/Components/Monitor/SeriesLabelsViewer.tsx +93 -0
  547. package/UI/Components/MonitorGraphs/Uptime.tsx +14 -2
  548. package/UI/Components/MonitorGraphs/UptimeBarDayModal.tsx +63 -10
  549. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +88 -0
  550. package/UI/Components/ProgressBar/ProgressBar.tsx +12 -1
  551. package/UI/Components/RadioButtons/BasicRadioButtons.tsx +37 -7
  552. package/UI/Components/SideMenu/SideMenu.tsx +123 -5
  553. package/UI/Components/SideMenu/SideMenuItem.tsx +76 -84
  554. package/UI/Components/SideMenu/SideMenuSection.tsx +55 -23
  555. package/UI/Components/SideOver/SideOver.tsx +21 -20
  556. package/UI/Components/StatusPage/ResourceGroupSection.tsx +40 -0
  557. package/UI/Components/Table/CellClassName.ts +81 -0
  558. package/UI/Components/Table/TableRow.tsx +20 -14
  559. package/UI/Components/Table/TableSkeletonRows.tsx +9 -9
  560. package/UI/Components/Table/Types/Column.ts +36 -0
  561. package/UI/Components/Tooltip/Tooltip.tsx +11 -1
  562. package/UI/Components/Workflow/ComponentsModal.tsx +60 -39
  563. package/UI/Components/Workflow/NodePlacement.ts +57 -0
  564. package/UI/Components/Workflow/Workflow.tsx +47 -18
  565. package/UI/Config.ts +15 -33
  566. package/UI/Utils/GlobalKeyboardShortcut.ts +208 -0
  567. package/UI/Utils/PageScrollLock.ts +79 -3
  568. package/UI/Utils/PermissionGate.ts +61 -0
  569. package/UI/Utils/SensitiveUrlToken.ts +112 -0
  570. package/UI/Utils/Telemetry/BrowserTelemetryConfig.ts +28 -0
  571. package/UI/Utils/Telemetry/Telemetry.ts +10 -8
  572. package/UI/Utils/TestLLMProvider.ts +11 -0
  573. package/Utils/API.ts +129 -3
  574. package/Utils/EnterpriseLicense/EnterpriseLicenseSeats.ts +16 -0
  575. package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +191 -11
  576. package/Utils/HTTPResponseBodyReader.ts +221 -0
  577. package/Utils/Monitor/MonitorMetricType.ts +153 -1
  578. package/Utils/Monitor/NetworkTopologyUtil.ts +23 -3
  579. package/Utils/NetworkDevice/DeviceHealthStateUtil.ts +65 -14
  580. package/Utils/NetworkDevice/DeviceReachabilityUtil.ts +43 -14
  581. package/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.ts +247 -0
  582. package/Utils/NetworkDevice/SnmpCredentialUtil.ts +68 -0
  583. package/Utils/NetworkDiscovery/AutoImportRuleMatcher.ts +15 -7
  584. package/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.ts +52 -17
  585. package/Utils/NetworkDiscovery/DiscoveryImportEligibility.ts +55 -23
  586. package/Utils/NetworkDiscovery/DiscoveryScanStatus.ts +77 -0
  587. package/Utils/NetworkDiscovery/PingMonitorBuilder.ts +115 -13
  588. package/Utils/NetworkSite/SiteStatusRollupUtil.ts +66 -20
  589. package/Utils/NetworkSite/TypeHierarchyUtil.ts +313 -0
  590. package/Utils/Rum/ChunkMath.ts +106 -0
  591. package/Utils/Rum/SessionReplayHealth.ts +732 -0
  592. package/Utils/Rum/SessionReplayStringMap.ts +226 -0
  593. package/Utils/Schema/ModelSchema.ts +1 -0
  594. package/Utils/StatusPage/ResourceSearch.ts +290 -0
  595. package/Utils/Telemetry/OriginAllowList.ts +355 -0
  596. package/Utils/Uptime/DayUptimeGraphUtil.ts +205 -0
  597. package/Utils/ValueFormatter.ts +35 -1
  598. package/build/dist/Models/AnalyticsModels/RumSession.js +102 -19
  599. package/build/dist/Models/AnalyticsModels/RumSession.js.map +1 -1
  600. package/build/dist/Models/AnalyticsModels/RumSessionChunk.js +11 -9
  601. package/build/dist/Models/AnalyticsModels/RumSessionChunk.js.map +1 -1
  602. package/build/dist/Models/AnalyticsModels/Span.js +14 -0
  603. package/build/dist/Models/AnalyticsModels/Span.js.map +1 -1
  604. package/build/dist/Models/DatabaseModels/AlertCustomField.js +79 -3
  605. package/build/dist/Models/DatabaseModels/AlertCustomField.js.map +1 -1
  606. package/build/dist/Models/DatabaseModels/ApiKeyPermission.js +3 -27
  607. package/build/dist/Models/DatabaseModels/ApiKeyPermission.js.map +1 -1
  608. package/build/dist/Models/DatabaseModels/EnterpriseLicense.js +59 -0
  609. package/build/dist/Models/DatabaseModels/EnterpriseLicense.js.map +1 -1
  610. package/build/dist/Models/DatabaseModels/IncidentCustomField.js +79 -3
  611. package/build/dist/Models/DatabaseModels/IncidentCustomField.js.map +1 -1
  612. package/build/dist/Models/DatabaseModels/Index.js +10 -0
  613. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  614. package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js +79 -3
  615. package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js.map +1 -1
  616. package/build/dist/Models/DatabaseModels/Monitor.js +75 -0
  617. package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
  618. package/build/dist/Models/DatabaseModels/MonitorCustomField.js +79 -3
  619. package/build/dist/Models/DatabaseModels/MonitorCustomField.js.map +1 -1
  620. package/build/dist/Models/DatabaseModels/NetworkAlertPolicy.js +713 -0
  621. package/build/dist/Models/DatabaseModels/NetworkAlertPolicy.js.map +1 -0
  622. package/build/dist/Models/DatabaseModels/NetworkDevice.js +180 -1
  623. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  624. package/build/dist/Models/DatabaseModels/NetworkSite.js +200 -2
  625. package/build/dist/Models/DatabaseModels/NetworkSite.js.map +1 -1
  626. package/build/dist/Models/DatabaseModels/NetworkSiteType.js +102 -3
  627. package/build/dist/Models/DatabaseModels/NetworkSiteType.js.map +1 -1
  628. package/build/dist/Models/DatabaseModels/NetworkSnmpCredentialProfile.js +878 -0
  629. package/build/dist/Models/DatabaseModels/NetworkSnmpCredentialProfile.js.map +1 -0
  630. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js +79 -3
  631. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js.map +1 -1
  632. package/build/dist/Models/DatabaseModels/RumApplication.js +6 -6
  633. package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
  634. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js +79 -3
  635. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js.map +1 -1
  636. package/build/dist/Models/DatabaseModels/StatusPageCustomField.js +79 -3
  637. package/build/dist/Models/DatabaseModels/StatusPageCustomField.js.map +1 -1
  638. package/build/dist/Models/DatabaseModels/TeamCustomField.js +79 -3
  639. package/build/dist/Models/DatabaseModels/TeamCustomField.js.map +1 -1
  640. package/build/dist/Models/DatabaseModels/TeamMember.js +0 -9
  641. package/build/dist/Models/DatabaseModels/TeamMember.js.map +1 -1
  642. package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js +79 -3
  643. package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js.map +1 -1
  644. package/build/dist/Models/DatabaseModels/TeamPermission.js +3 -24
  645. package/build/dist/Models/DatabaseModels/TeamPermission.js.map +1 -1
  646. package/build/dist/Models/DatabaseModels/TelemetryException.js +123 -0
  647. package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -1
  648. package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js +267 -0
  649. package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js.map +1 -1
  650. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupBatch.js +363 -0
  651. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupBatch.js.map +1 -0
  652. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js +402 -0
  653. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js.map +1 -0
  654. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupSetting.js +296 -0
  655. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupSetting.js.map +1 -0
  656. package/build/dist/Models/DatabaseModels/UserTelegram.js +0 -4
  657. package/build/dist/Models/DatabaseModels/UserTelegram.js.map +1 -1
  658. package/build/dist/Server/API/EnterpriseLicenseAPI.js +273 -60
  659. package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +1 -1
  660. package/build/dist/Server/API/LlmProviderAPI.js +108 -13
  661. package/build/dist/Server/API/LlmProviderAPI.js.map +1 -1
  662. package/build/dist/Server/API/TelemetryAPI.js +769 -109
  663. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  664. package/build/dist/Server/API/UserNotificationSettingAPI.js +35 -0
  665. package/build/dist/Server/API/UserNotificationSettingAPI.js.map +1 -0
  666. package/build/dist/Server/API/UserTelegramAPI.js +28 -6
  667. package/build/dist/Server/API/UserTelegramAPI.js.map +1 -1
  668. package/build/dist/Server/EnvironmentConfig.js +41 -2
  669. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  670. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.js +24 -0
  671. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.js.map +1 -0
  672. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.js +16 -0
  673. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.js.map +1 -0
  674. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.js +111 -0
  675. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.js.map +1 -0
  676. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.js +77 -0
  677. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.js.map +1 -0
  678. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.js +50 -0
  679. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.js.map +1 -0
  680. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.js +83 -0
  681. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.js.map +1 -0
  682. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js +60 -0
  683. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js.map +1 -0
  684. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js +53 -0
  685. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js.map +1 -0
  686. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js +82 -0
  687. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js.map +1 -0
  688. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js +46 -0
  689. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js.map +1 -0
  690. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +20 -0
  691. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  692. package/build/dist/Server/Infrastructure/QueueWorker.js +52 -12
  693. package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
  694. package/build/dist/Server/Infrastructure/Semaphore.js +1 -0
  695. package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
  696. package/build/dist/Server/Middleware/BearerTokenAuthorization.js +12 -0
  697. package/build/dist/Server/Middleware/BearerTokenAuthorization.js.map +1 -1
  698. package/build/dist/Server/Middleware/ProjectAuthorization.js +11 -0
  699. package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
  700. package/build/dist/Server/Middleware/SCIMAuthorization.js +12 -0
  701. package/build/dist/Server/Middleware/SCIMAuthorization.js.map +1 -1
  702. package/build/dist/Server/Middleware/TelemetryIngest.js +326 -8
  703. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  704. package/build/dist/Server/Services/AIBillingService.js +70 -16
  705. package/build/dist/Server/Services/AIBillingService.js.map +1 -1
  706. package/build/dist/Server/Services/AccessTokenService.js +1 -0
  707. package/build/dist/Server/Services/AccessTokenService.js.map +1 -1
  708. package/build/dist/Server/Services/AlertCustomFieldService.js +93 -0
  709. package/build/dist/Server/Services/AlertCustomFieldService.js.map +1 -1
  710. package/build/dist/Server/Services/AlertService.js +34 -0
  711. package/build/dist/Server/Services/AlertService.js.map +1 -1
  712. package/build/dist/Server/Services/ApiKeyPermissionService.js +331 -28
  713. package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
  714. package/build/dist/Server/Services/CustomFieldMappingService.js +614 -0
  715. package/build/dist/Server/Services/CustomFieldMappingService.js.map +1 -0
  716. package/build/dist/Server/Services/EnterpriseLicenseInstanceService.js +167 -0
  717. package/build/dist/Server/Services/EnterpriseLicenseInstanceService.js.map +1 -1
  718. package/build/dist/Server/Services/EnterpriseLicenseService.js +39 -0
  719. package/build/dist/Server/Services/EnterpriseLicenseService.js.map +1 -1
  720. package/build/dist/Server/Services/GlobalConfigService.js +133 -0
  721. package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
  722. package/build/dist/Server/Services/IncidentCustomFieldService.js +93 -0
  723. package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
  724. package/build/dist/Server/Services/IncidentService.js +32 -0
  725. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  726. package/build/dist/Server/Services/Index.js +10 -0
  727. package/build/dist/Server/Services/Index.js.map +1 -1
  728. package/build/dist/Server/Services/MetricService.js +163 -0
  729. package/build/dist/Server/Services/MetricService.js.map +1 -1
  730. package/build/dist/Server/Services/MonitorService.js +148 -21
  731. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  732. package/build/dist/Server/Services/MonitorStatusTimelineService.js +127 -8
  733. package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
  734. package/build/dist/Server/Services/MonitorTemplateService.js +162 -0
  735. package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
  736. package/build/dist/Server/Services/NetworkAlertPolicyEngineService.js +1683 -0
  737. package/build/dist/Server/Services/NetworkAlertPolicyEngineService.js.map +1 -0
  738. package/build/dist/Server/Services/NetworkAlertPolicyService.js +732 -0
  739. package/build/dist/Server/Services/NetworkAlertPolicyService.js.map +1 -0
  740. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +89 -36
  741. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
  742. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js +54 -11
  743. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js.map +1 -1
  744. package/build/dist/Server/Services/NetworkDeviceService.js +841 -70
  745. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  746. package/build/dist/Server/Services/NetworkSiteService.js +1145 -107
  747. package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
  748. package/build/dist/Server/Services/NetworkSiteTypeService.js +863 -0
  749. package/build/dist/Server/Services/NetworkSiteTypeService.js.map +1 -1
  750. package/build/dist/Server/Services/NetworkSnmpCredentialProfileService.js +217 -0
  751. package/build/dist/Server/Services/NetworkSnmpCredentialProfileService.js.map +1 -0
  752. package/build/dist/Server/Services/NotificationService.js +80 -17
  753. package/build/dist/Server/Services/NotificationService.js.map +1 -1
  754. package/build/dist/Server/Services/ProjectService.js +88 -30
  755. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  756. package/build/dist/Server/Services/RoutineEmailSettingsService.js +69 -0
  757. package/build/dist/Server/Services/RoutineEmailSettingsService.js.map +1 -0
  758. package/build/dist/Server/Services/RumSessionReplayViewService.js +86 -24
  759. package/build/dist/Server/Services/RumSessionReplayViewService.js.map +1 -1
  760. package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js +93 -0
  761. package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js.map +1 -1
  762. package/build/dist/Server/Services/ScheduledMaintenanceService.js +29 -0
  763. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  764. package/build/dist/Server/Services/StatusPagePrivateUserService.js +92 -2
  765. package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
  766. package/build/dist/Server/Services/TeamMemberService.js +62 -2
  767. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  768. package/build/dist/Server/Services/TeamPermissionService.js +166 -3
  769. package/build/dist/Server/Services/TeamPermissionService.js.map +1 -1
  770. package/build/dist/Server/Services/TelemetryIngestionKeyService.js +562 -18
  771. package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
  772. package/build/dist/Server/Services/UserNotificationEmailRollupBatchService.js +76 -0
  773. package/build/dist/Server/Services/UserNotificationEmailRollupBatchService.js.map +1 -0
  774. package/build/dist/Server/Services/UserNotificationEmailRollupItemService.js +77 -0
  775. package/build/dist/Server/Services/UserNotificationEmailRollupItemService.js.map +1 -0
  776. package/build/dist/Server/Services/UserNotificationEmailRollupSettingService.js +111 -0
  777. package/build/dist/Server/Services/UserNotificationEmailRollupSettingService.js.map +1 -0
  778. package/build/dist/Server/Services/UserNotificationSettingService.js +66 -20
  779. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  780. package/build/dist/Server/Services/UserService.js +90 -0
  781. package/build/dist/Server/Services/UserService.js.map +1 -1
  782. package/build/dist/Server/Services/UserTelegramService.js +257 -4
  783. package/build/dist/Server/Services/UserTelegramService.js.map +1 -1
  784. package/build/dist/Server/Types/Database/QueryHelper.js +1 -1
  785. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  786. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +14 -3
  787. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js.map +1 -1
  788. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js +10 -0
  789. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js.map +1 -1
  790. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js +10 -0
  791. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js.map +1 -1
  792. package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js +54 -1
  793. package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js.map +1 -1
  794. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js +18 -4
  795. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js.map +1 -1
  796. package/build/dist/Server/Utils/APIKey/AccessPermission.js +2 -2
  797. package/build/dist/Server/Utils/APIKey/AccessPermission.js.map +1 -1
  798. package/build/dist/Server/Utils/Billing/BillingFailureNoticeThrottle.js +59 -0
  799. package/build/dist/Server/Utils/Billing/BillingFailureNoticeThrottle.js.map +1 -0
  800. package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js +27 -0
  801. package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js.map +1 -0
  802. package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js +226 -0
  803. package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js.map +1 -0
  804. package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js +189 -0
  805. package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js.map +1 -0
  806. package/build/dist/Server/Utils/DataSource/EgressGuard.js +121 -7
  807. package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
  808. package/build/dist/Server/Utils/DataSource/HttpFetch.js +2 -1
  809. package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -1
  810. package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js +124 -0
  811. package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js.map +1 -0
  812. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +733 -0
  813. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -0
  814. package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js +497 -0
  815. package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js.map +1 -0
  816. package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js +257 -0
  817. package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js.map +1 -0
  818. package/build/dist/Server/Utils/FrontendEnvironment.js +33 -0
  819. package/build/dist/Server/Utils/FrontendEnvironment.js.map +1 -0
  820. package/build/dist/Server/Utils/LLM/LLMService.js +64 -1
  821. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  822. package/build/dist/Server/Utils/LogRedaction.js +28 -0
  823. package/build/dist/Server/Utils/LogRedaction.js.map +1 -1
  824. package/build/dist/Server/Utils/Logger.js +73 -1
  825. package/build/dist/Server/Utils/Logger.js.map +1 -1
  826. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +287 -68
  827. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
  828. package/build/dist/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.js +141 -0
  829. package/build/dist/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.js.map +1 -0
  830. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +8 -1
  831. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
  832. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +20 -4
  833. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
  834. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +51 -1
  835. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
  836. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +29 -6
  837. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  838. package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js +7 -0
  839. package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js.map +1 -1
  840. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +125 -13
  841. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  842. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +158 -6
  843. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
  844. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +22 -6
  845. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  846. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +33 -0
  847. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
  848. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +54 -0
  849. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  850. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +330 -21
  851. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
  852. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +55 -10
  853. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -1
  854. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js +178 -49
  855. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js.map +1 -1
  856. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +119 -29
  857. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
  858. package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js +237 -0
  859. package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js.map +1 -0
  860. package/build/dist/Server/Utils/NetworkDevice/DeviceHealthAggregation.js +30 -17
  861. package/build/dist/Server/Utils/NetworkDevice/DeviceHealthAggregation.js.map +1 -1
  862. package/build/dist/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.js +158 -0
  863. package/build/dist/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.js.map +1 -0
  864. package/build/dist/Server/Utils/OutboundUserAgent.js +123 -0
  865. package/build/dist/Server/Utils/OutboundUserAgent.js.map +1 -0
  866. package/build/dist/Server/Utils/SSRFProtection.js +136 -9
  867. package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
  868. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js +174 -89
  869. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js.map +1 -1
  870. package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js +223 -0
  871. package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js.map +1 -0
  872. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +945 -164
  873. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
  874. package/build/dist/Server/Utils/StartServer.js +41 -28
  875. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  876. package/build/dist/Server/Utils/TelegramVerificationToken.js +129 -0
  877. package/build/dist/Server/Utils/TelegramVerificationToken.js.map +1 -0
  878. package/build/dist/Server/Utils/Telemetry/CaptureSpan.js +28 -8
  879. package/build/dist/Server/Utils/Telemetry/CaptureSpan.js.map +1 -1
  880. package/build/dist/Server/Utils/Telemetry/ErrorClassResolver.js +95 -0
  881. package/build/dist/Server/Utils/Telemetry/ErrorClassResolver.js.map +1 -0
  882. package/build/dist/Server/Utils/Telemetry/PinServiceName.js +163 -0
  883. package/build/dist/Server/Utils/Telemetry/PinServiceName.js.map +1 -0
  884. package/build/dist/Server/Utils/Telemetry/SpanUtil.js +29 -0
  885. package/build/dist/Server/Utils/Telemetry/SpanUtil.js.map +1 -1
  886. package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js +28 -15
  887. package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js.map +1 -1
  888. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js +64 -0
  889. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js.map +1 -0
  890. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js +171 -0
  891. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js.map +1 -0
  892. package/build/dist/Server/Utils/Telemetry.js +162 -46
  893. package/build/dist/Server/Utils/Telemetry.js.map +1 -1
  894. package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
  895. package/build/dist/Server/Utils/VM/VMRunner.js +780 -69
  896. package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
  897. package/build/dist/Types/AI/ExceptionAIClassification.js +10 -24
  898. package/build/dist/Types/AI/ExceptionAIClassification.js.map +1 -1
  899. package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js +60 -0
  900. package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js.map +1 -0
  901. package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js +20 -0
  902. package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js.map +1 -0
  903. package/build/dist/Types/CustomField/CustomFieldValueMapping.js +141 -0
  904. package/build/dist/Types/CustomField/CustomFieldValueMapping.js.map +1 -0
  905. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  906. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  907. package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.js +2 -0
  908. package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.js.map +1 -0
  909. package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.js +7 -0
  910. package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.js.map +1 -0
  911. package/build/dist/Types/Exception/ApiException.js +9 -0
  912. package/build/dist/Types/Exception/ApiException.js.map +1 -1
  913. package/build/dist/Types/Exception/BadDataException.js +10 -0
  914. package/build/dist/Types/Exception/BadDataException.js.map +1 -1
  915. package/build/dist/Types/Exception/BadRequestException.js +10 -0
  916. package/build/dist/Types/Exception/BadRequestException.js.map +1 -1
  917. package/build/dist/Types/Exception/Exception.js +56 -0
  918. package/build/dist/Types/Exception/Exception.js.map +1 -1
  919. package/build/dist/Types/Exception/ForbiddenException.js +9 -0
  920. package/build/dist/Types/Exception/ForbiddenException.js.map +1 -1
  921. package/build/dist/Types/Exception/NotAuthenticatedException.js +9 -0
  922. package/build/dist/Types/Exception/NotAuthenticatedException.js.map +1 -1
  923. package/build/dist/Types/Exception/NotAuthorizedException.js +9 -0
  924. package/build/dist/Types/Exception/NotAuthorizedException.js.map +1 -1
  925. package/build/dist/Types/Exception/NotFoundException.js +10 -0
  926. package/build/dist/Types/Exception/NotFoundException.js.map +1 -1
  927. package/build/dist/Types/Exception/PayloadTooLargeException.js +10 -0
  928. package/build/dist/Types/Exception/PayloadTooLargeException.js.map +1 -1
  929. package/build/dist/Types/Exception/PaymentRequiredException.js +9 -0
  930. package/build/dist/Types/Exception/PaymentRequiredException.js.map +1 -1
  931. package/build/dist/Types/Exception/ServiceUnavailableException.js +9 -0
  932. package/build/dist/Types/Exception/ServiceUnavailableException.js.map +1 -1
  933. package/build/dist/Types/Exception/SsoAuthorizationException.js +9 -0
  934. package/build/dist/Types/Exception/SsoAuthorizationException.js.map +1 -1
  935. package/build/dist/Types/Exception/TenantNotFoundException.js +10 -0
  936. package/build/dist/Types/Exception/TenantNotFoundException.js.map +1 -1
  937. package/build/dist/Types/Exception/TimeoutException.js +9 -0
  938. package/build/dist/Types/Exception/TimeoutException.js.map +1 -1
  939. package/build/dist/Types/Exception/TooManyRequestsException.js +9 -0
  940. package/build/dist/Types/Exception/TooManyRequestsException.js.map +1 -1
  941. package/build/dist/Types/Exception/UnableToReachServer.js +9 -0
  942. package/build/dist/Types/Exception/UnableToReachServer.js.map +1 -1
  943. package/build/dist/Types/Exception/WebsiteRequestException.js +9 -0
  944. package/build/dist/Types/Exception/WebsiteRequestException.js.map +1 -1
  945. package/build/dist/Types/Icon/IconProp.js +1 -0
  946. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  947. package/build/dist/Types/JSONFunctions.js +118 -37
  948. package/build/dist/Types/JSONFunctions.js.map +1 -1
  949. package/build/dist/Types/Monitor/CephAlertTemplates.js +130 -171
  950. package/build/dist/Types/Monitor/CephAlertTemplates.js.map +1 -1
  951. package/build/dist/Types/Monitor/CriteriaFilter.js +45 -2
  952. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  953. package/build/dist/Types/Monitor/DatabaseMetricCatalog.js +594 -0
  954. package/build/dist/Types/Monitor/DatabaseMetricCatalog.js.map +1 -0
  955. package/build/dist/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.js +21 -0
  956. package/build/dist/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.js.map +1 -0
  957. package/build/dist/Types/Monitor/DockerAlertTemplates.js +286 -121
  958. package/build/dist/Types/Monitor/DockerAlertTemplates.js.map +1 -1
  959. package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js +84 -105
  960. package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js.map +1 -1
  961. package/build/dist/Types/Monitor/HostAlertTemplates.js +250 -122
  962. package/build/dist/Types/Monitor/HostAlertTemplates.js.map +1 -1
  963. package/build/dist/Types/Monitor/IotAlertTemplates.js +81 -81
  964. package/build/dist/Types/Monitor/IotAlertTemplates.js.map +1 -1
  965. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +375 -215
  966. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
  967. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js +19 -19
  968. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js.map +1 -1
  969. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +70 -0
  970. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  971. package/build/dist/Types/Monitor/MonitorMetricType.js +61 -0
  972. package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
  973. package/build/dist/Types/Monitor/MonitorStep.js +54 -0
  974. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  975. package/build/dist/Types/Monitor/MonitorStepDatabaseMonitor.js +122 -0
  976. package/build/dist/Types/Monitor/MonitorStepDatabaseMonitor.js.map +1 -0
  977. package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js.map +1 -1
  978. package/build/dist/Types/Monitor/MonitorType.js +45 -1
  979. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  980. package/build/dist/Types/Monitor/PodmanAlertTemplates.js +104 -153
  981. package/build/dist/Types/Monitor/PodmanAlertTemplates.js.map +1 -1
  982. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +156 -91
  983. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
  984. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +67 -6
  985. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -1
  986. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +38 -7
  987. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
  988. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js +261 -0
  989. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js.map +1 -0
  990. package/build/dist/Types/Monitor/RumAlertTemplates.js +46 -7
  991. package/build/dist/Types/Monitor/RumAlertTemplates.js.map +1 -1
  992. package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js +422 -0
  993. package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js.map +1 -0
  994. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +441 -0
  995. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -0
  996. package/build/dist/Types/Monitor/ServiceAlertTemplates.js +79 -15
  997. package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -1
  998. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js +21 -1
  999. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js.map +1 -1
  1000. package/build/dist/Types/Monitor/SqlConnectionConfig.js +2 -0
  1001. package/build/dist/Types/Monitor/SqlConnectionConfig.js.map +1 -0
  1002. package/build/dist/Types/Monitor/UptimeHistoryLabels.js +17 -0
  1003. package/build/dist/Types/Monitor/UptimeHistoryLabels.js.map +1 -0
  1004. package/build/dist/Types/NetworkDevice/NetworkAlertPolicyScope.js +172 -0
  1005. package/build/dist/Types/NetworkDevice/NetworkAlertPolicyScope.js.map +1 -0
  1006. package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js +40 -22
  1007. package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js.map +1 -1
  1008. package/build/dist/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.js +26 -0
  1009. package/build/dist/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.js.map +1 -0
  1010. package/build/dist/Types/NotificationSetting/NotificationEmailRollupCategory.js +186 -0
  1011. package/build/dist/Types/NotificationSetting/NotificationEmailRollupCategory.js.map +1 -0
  1012. package/build/dist/Types/NotificationSetting/NotificationEmailRollupPolicy.js +87 -0
  1013. package/build/dist/Types/NotificationSetting/NotificationEmailRollupPolicy.js.map +1 -0
  1014. package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js +29 -0
  1015. package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js.map +1 -0
  1016. package/build/dist/Types/Permission.js +80 -0
  1017. package/build/dist/Types/Permission.js.map +1 -1
  1018. package/build/dist/Types/Rum/SessionReplay.js +117 -0
  1019. package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
  1020. package/build/dist/Types/Rum/SessionReplayApi.js +181 -0
  1021. package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -0
  1022. package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js +21 -12
  1023. package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js.map +1 -1
  1024. package/build/dist/Types/Rum/SessionReplayConsentMode.js +11 -7
  1025. package/build/dist/Types/Rum/SessionReplayConsentMode.js.map +1 -1
  1026. package/build/dist/Types/Rum/SessionReplayCustomEvents.js +172 -0
  1027. package/build/dist/Types/Rum/SessionReplayCustomEvents.js.map +1 -0
  1028. package/build/dist/Types/Rum/SessionReplayHealth.js +37 -0
  1029. package/build/dist/Types/Rum/SessionReplayHealth.js.map +1 -0
  1030. package/build/dist/Types/Telemetry/ErrorClass.js +216 -0
  1031. package/build/dist/Types/Telemetry/ErrorClass.js.map +1 -0
  1032. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +85 -0
  1033. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -0
  1034. package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js +15 -0
  1035. package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js.map +1 -0
  1036. package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js +30 -0
  1037. package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js.map +1 -0
  1038. package/build/dist/Types/Telemetry/UnitOfWork.js +59 -0
  1039. package/build/dist/Types/Telemetry/UnitOfWork.js.map +1 -0
  1040. package/build/dist/Types/WebsiteRequest.js +55 -3
  1041. package/build/dist/Types/WebsiteRequest.js.map +1 -1
  1042. package/build/dist/UI/Components/Charts/Area/AreaChart.js +13 -2
  1043. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  1044. package/build/dist/UI/Components/Charts/Bar/BarChart.js +6 -2
  1045. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  1046. package/build/dist/UI/Components/Charts/Line/LineChart.js +13 -2
  1047. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  1048. package/build/dist/UI/Components/Charts/Types/XAxis/XAxis.js.map +1 -1
  1049. package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -3
  1050. package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
  1051. package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js +40 -9
  1052. package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js.map +1 -1
  1053. package/build/dist/UI/Components/Charts/Utils/XAxis.js +186 -0
  1054. package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
  1055. package/build/dist/UI/Components/CommandPalette/CommandPalette.js +2 -7
  1056. package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -1
  1057. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +80 -6
  1058. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
  1059. package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js +118 -0
  1060. package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js.map +1 -0
  1061. package/build/dist/UI/Components/EditionLabel/EditionLabel.js +3 -0
  1062. package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
  1063. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +112 -7
  1064. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
  1065. package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js +5 -162
  1066. package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js.map +1 -1
  1067. package/build/dist/UI/Components/Graphs/UptimeDaySummary.js +181 -0
  1068. package/build/dist/UI/Components/Graphs/UptimeDaySummary.js.map +1 -0
  1069. package/build/dist/UI/Components/Header/Header.js +2 -3
  1070. package/build/dist/UI/Components/Header/Header.js.map +1 -1
  1071. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js +2 -1
  1072. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js.map +1 -1
  1073. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js +7 -1
  1074. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js.map +1 -1
  1075. package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js +7 -1
  1076. package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js.map +1 -1
  1077. package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js +7 -1
  1078. package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js.map +1 -1
  1079. package/build/dist/UI/Components/Icon/Icon.js +5 -0
  1080. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  1081. package/build/dist/UI/Components/JSONTable/JSONTable.js +2 -2
  1082. package/build/dist/UI/Components/JSONTable/JSONTable.js.map +1 -1
  1083. package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js +35 -0
  1084. package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js.map +1 -0
  1085. package/build/dist/UI/Components/Modal/Modal.js +2 -7
  1086. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  1087. package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js +34 -0
  1088. package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js.map +1 -0
  1089. package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js +49 -0
  1090. package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js.map +1 -0
  1091. package/build/dist/UI/Components/MonitorGraphs/Uptime.js +1 -1
  1092. package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
  1093. package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js +32 -6
  1094. package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js.map +1 -1
  1095. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +77 -0
  1096. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
  1097. package/build/dist/UI/Components/ProgressBar/ProgressBar.js +12 -1
  1098. package/build/dist/UI/Components/ProgressBar/ProgressBar.js.map +1 -1
  1099. package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js +6 -6
  1100. package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js.map +1 -1
  1101. package/build/dist/UI/Components/SideMenu/SideMenu.js +67 -5
  1102. package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
  1103. package/build/dist/UI/Components/SideMenu/SideMenuItem.js +49 -53
  1104. package/build/dist/UI/Components/SideMenu/SideMenuItem.js.map +1 -1
  1105. package/build/dist/UI/Components/SideMenu/SideMenuSection.js +25 -7
  1106. package/build/dist/UI/Components/SideMenu/SideMenuSection.js.map +1 -1
  1107. package/build/dist/UI/Components/SideOver/SideOver.js +5 -20
  1108. package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
  1109. package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js +22 -1
  1110. package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js.map +1 -1
  1111. package/build/dist/UI/Components/Table/CellClassName.js +55 -0
  1112. package/build/dist/UI/Components/Table/CellClassName.js.map +1 -0
  1113. package/build/dist/UI/Components/Table/TableRow.js +16 -13
  1114. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  1115. package/build/dist/UI/Components/Table/TableSkeletonRows.js +9 -8
  1116. package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -1
  1117. package/build/dist/UI/Components/Tooltip/Tooltip.js +25 -1
  1118. package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
  1119. package/build/dist/UI/Components/Workflow/ComponentsModal.js +47 -30
  1120. package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
  1121. package/build/dist/UI/Components/Workflow/NodePlacement.js +37 -0
  1122. package/build/dist/UI/Components/Workflow/NodePlacement.js.map +1 -0
  1123. package/build/dist/UI/Components/Workflow/Workflow.js +35 -18
  1124. package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
  1125. package/build/dist/UI/Config.js +10 -20
  1126. package/build/dist/UI/Config.js.map +1 -1
  1127. package/build/dist/UI/Utils/GlobalKeyboardShortcut.js +138 -0
  1128. package/build/dist/UI/Utils/GlobalKeyboardShortcut.js.map +1 -0
  1129. package/build/dist/UI/Utils/PageScrollLock.js +31 -3
  1130. package/build/dist/UI/Utils/PageScrollLock.js.map +1 -1
  1131. package/build/dist/UI/Utils/PermissionGate.js +42 -1
  1132. package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
  1133. package/build/dist/UI/Utils/SensitiveUrlToken.js +97 -0
  1134. package/build/dist/UI/Utils/SensitiveUrlToken.js.map +1 -0
  1135. package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js +14 -0
  1136. package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js.map +1 -0
  1137. package/build/dist/UI/Utils/Telemetry/Telemetry.js +7 -5
  1138. package/build/dist/UI/Utils/Telemetry/Telemetry.js.map +1 -1
  1139. package/build/dist/UI/Utils/TestLLMProvider.js +4 -5
  1140. package/build/dist/UI/Utils/TestLLMProvider.js.map +1 -1
  1141. package/build/dist/Utils/API.js +67 -5
  1142. package/build/dist/Utils/API.js.map +1 -1
  1143. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js +15 -0
  1144. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js.map +1 -1
  1145. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +111 -9
  1146. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js.map +1 -1
  1147. package/build/dist/Utils/HTTPResponseBodyReader.js +157 -0
  1148. package/build/dist/Utils/HTTPResponseBodyReader.js.map +1 -0
  1149. package/build/dist/Utils/Monitor/MonitorMetricType.js +109 -1
  1150. package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
  1151. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +8 -3
  1152. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  1153. package/build/dist/Utils/NetworkDevice/DeviceHealthStateUtil.js +27 -7
  1154. package/build/dist/Utils/NetworkDevice/DeviceHealthStateUtil.js.map +1 -1
  1155. package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js +7 -5
  1156. package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js.map +1 -1
  1157. package/build/dist/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.js +180 -0
  1158. package/build/dist/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.js.map +1 -0
  1159. package/build/dist/Utils/NetworkDevice/SnmpCredentialUtil.js +12 -0
  1160. package/build/dist/Utils/NetworkDevice/SnmpCredentialUtil.js.map +1 -0
  1161. package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js +15 -5
  1162. package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js.map +1 -1
  1163. package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js +44 -15
  1164. package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js.map +1 -1
  1165. package/build/dist/Utils/NetworkDiscovery/DiscoveryImportEligibility.js +52 -23
  1166. package/build/dist/Utils/NetworkDiscovery/DiscoveryImportEligibility.js.map +1 -1
  1167. package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js +69 -0
  1168. package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js.map +1 -0
  1169. package/build/dist/Utils/NetworkDiscovery/PingMonitorBuilder.js +85 -13
  1170. package/build/dist/Utils/NetworkDiscovery/PingMonitorBuilder.js.map +1 -1
  1171. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +30 -15
  1172. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -1
  1173. package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js +191 -0
  1174. package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js.map +1 -0
  1175. package/build/dist/Utils/Rum/ChunkMath.js +76 -0
  1176. package/build/dist/Utils/Rum/ChunkMath.js.map +1 -1
  1177. package/build/dist/Utils/Rum/SessionReplayHealth.js +534 -0
  1178. package/build/dist/Utils/Rum/SessionReplayHealth.js.map +1 -0
  1179. package/build/dist/Utils/Rum/SessionReplayStringMap.js +165 -0
  1180. package/build/dist/Utils/Rum/SessionReplayStringMap.js.map +1 -0
  1181. package/build/dist/Utils/Schema/ModelSchema.js +1 -0
  1182. package/build/dist/Utils/Schema/ModelSchema.js.map +1 -1
  1183. package/build/dist/Utils/StatusPage/ResourceSearch.js +200 -0
  1184. package/build/dist/Utils/StatusPage/ResourceSearch.js.map +1 -0
  1185. package/build/dist/Utils/Telemetry/OriginAllowList.js +299 -0
  1186. package/build/dist/Utils/Telemetry/OriginAllowList.js.map +1 -0
  1187. package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js +147 -0
  1188. package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js.map +1 -0
  1189. package/build/dist/Utils/ValueFormatter.js +32 -1
  1190. package/build/dist/Utils/ValueFormatter.js.map +1 -1
  1191. package/package.json +2 -2
@@ -0,0 +1,1428 @@
1
+ import {
2
+ MAX_ROWS_IN_ROLLUP,
3
+ ROLLUP_PROJECT_NAME_MAX,
4
+ ROLLUP_SUBJECT_LEAD_TITLE_MAX,
5
+ ROLLUP_SUBJECT_MAX_CATEGORIES,
6
+ } from "../../../../Server/Utils/EmailRollup/EmailRollupConstants";
7
+ import {
8
+ RollupEmail,
9
+ RollupRow,
10
+ buildRollupEmail,
11
+ foldItems,
12
+ } from "../../../../Server/Utils/EmailRollup/EmailRollupRenderer";
13
+ import UserNotificationEmailRollupItem from "../../../../Models/DatabaseModels/UserNotificationEmailRollupItem";
14
+ import { JSONObject, JSONValue } from "../../../../Types/JSON";
15
+ import RollupCategory, {
16
+ ROLLUP_CATEGORY_LABEL,
17
+ ROLLUP_CATEGORY_ORDER,
18
+ } from "../../../../Types/NotificationSetting/NotificationEmailRollupCategory";
19
+ import NotificationSettingEventType from "../../../../Types/NotificationSetting/NotificationSettingEventType";
20
+ import { describe, expect, test } from "@jest/globals";
21
+
22
+ /*
23
+ * The rollup email is the ONLY thing a flooded recipient sees instead of the
24
+ * forty individual emails it replaces, so everything that can quietly ruin it
25
+ * is pinned here.
26
+ *
27
+ * What breaks in production if this regresses:
28
+ *
29
+ * - Fold on the wrong key and one incident's created / acknowledged /
30
+ * resolved emails stay three rows carrying three contradictory states,
31
+ * which is worse than the three separate emails were.
32
+ * - Count categories over the rendered slice instead of over every item and
33
+ * the email claims a 300-notification storm was 100 notifications, which
34
+ * breaks the one promise this feature makes: nothing was suppressed.
35
+ * - Get the escaping contract backwards and a resource title containing
36
+ * markup is either an XSS hole in a mail client or a wall of visible
37
+ * `<`. Both have already shipped in this repo's templates.
38
+ * - Leave the Handlebars braces in the subject and MailService, which
39
+ * compiles the subject as a template, substitutes an incident title away
40
+ * to an empty string on its way to the inbox.
41
+ * - Drop the opt-out from the footer copy and rollup becomes a thing that
42
+ * happens TO people: it is on by default with no preference, so this email
43
+ * is the only place a recipient who wants one email per event finds out
44
+ * they can have that back.
45
+ * - Stop alternating rowBackground and a hundred-row table is one flat wall
46
+ * of white, which is how it actually shipped: the template asked for
47
+ * {{#if @odd}}, a data variable Handlebars does not define.
48
+ *
49
+ * Pure and synchronous: no database, no clock, no mocks.
50
+ */
51
+
52
+ const BASE_TIME_MS: number = Date.UTC(2026, 8, 3, 12, 0, 0);
53
+
54
+ type AtFunction = (offsetSeconds: number) => Date;
55
+
56
+ const at: AtFunction = (offsetSeconds: number): Date => {
57
+ return new Date(BASE_TIME_MS + offsetSeconds * 1000);
58
+ };
59
+
60
+ interface ItemInput {
61
+ createdAt: Date;
62
+ subject: string;
63
+ eventType?: NotificationSettingEventType | undefined;
64
+ viewLink?: string | undefined;
65
+ rollupCategory?: RollupCategory | undefined;
66
+ }
67
+
68
+ type MakeItemFunction = (input: ItemInput) => UserNotificationEmailRollupItem;
69
+
70
+ /*
71
+ * exactOptionalPropertyTypes is on, so an optional property is assigned only
72
+ * when there is something to assign - `item.viewLink = undefined` does not
73
+ * compile, and a linkless item is exactly the case the fold has to handle.
74
+ */
75
+ const makeItem: MakeItemFunction = (
76
+ input: ItemInput,
77
+ ): UserNotificationEmailRollupItem => {
78
+ const item: UserNotificationEmailRollupItem =
79
+ new UserNotificationEmailRollupItem();
80
+
81
+ item.createdAt = input.createdAt;
82
+ item.subject = input.subject;
83
+ item.eventType =
84
+ input.eventType ??
85
+ NotificationSettingEventType.SEND_INCIDENT_CREATED_OWNER_NOTIFICATION;
86
+ item.rollupCategory = input.rollupCategory ?? RollupCategory.Incidents;
87
+
88
+ if (input.viewLink !== undefined) {
89
+ item.viewLink = input.viewLink;
90
+ }
91
+
92
+ return item;
93
+ };
94
+
95
+ type SortAscendingFunction = (
96
+ items: Array<UserNotificationEmailRollupItem>,
97
+ ) => Array<UserNotificationEmailRollupItem>;
98
+
99
+ const sortAscending: SortAscendingFunction = (
100
+ items: Array<UserNotificationEmailRollupItem>,
101
+ ): Array<UserNotificationEmailRollupItem> => {
102
+ return items
103
+ .slice()
104
+ .sort(
105
+ (
106
+ a: UserNotificationEmailRollupItem,
107
+ b: UserNotificationEmailRollupItem,
108
+ ): number => {
109
+ return (a.createdAt?.getTime() ?? 0) - (b.createdAt?.getTime() ?? 0);
110
+ },
111
+ );
112
+ };
113
+
114
+ type BuildFunction = (
115
+ items: Array<UserNotificationEmailRollupItem>,
116
+ projectName?: string,
117
+ ) => RollupEmail;
118
+
119
+ const build: BuildFunction = (
120
+ items: Array<UserNotificationEmailRollupItem>,
121
+ projectName: string = "Acme",
122
+ ): RollupEmail => {
123
+ return buildRollupEmail({
124
+ projectName: projectName,
125
+ projectHomeLink: "https://oneuptime.example.com/dashboard/p1/home",
126
+ preferencesLink:
127
+ "https://oneuptime.example.com/dashboard/p1/user-settings/notification-settings",
128
+ items: sortAscending(items),
129
+ });
130
+ };
131
+
132
+ type VarStringFunction = (email: RollupEmail, name: string) => string;
133
+
134
+ /*
135
+ * Throws rather than stringifying, so a renamed variable fails the assertion
136
+ * that reads it instead of quietly comparing against "undefined".
137
+ */
138
+ const varString: VarStringFunction = (
139
+ email: RollupEmail,
140
+ name: string,
141
+ ): string => {
142
+ const value: string | JSONObject | undefined = email.vars[name];
143
+
144
+ if (typeof value !== "string") {
145
+ throw new Error(`Template var "${name}" is not a string`);
146
+ }
147
+
148
+ return value;
149
+ };
150
+
151
+ type VarRowsFunction = (email: RollupEmail) => Array<JSONObject>;
152
+
153
+ const varRows: VarRowsFunction = (email: RollupEmail): Array<JSONObject> => {
154
+ return email.vars["rows"] as unknown as Array<JSONObject>;
155
+ };
156
+
157
+ type RowFieldFunction = (row: JSONObject, name: string) => string;
158
+
159
+ const rowField: RowFieldFunction = (row: JSONObject, name: string): string => {
160
+ const value: JSONValue | undefined = row[name];
161
+
162
+ if (typeof value !== "string") {
163
+ throw new Error(`Row field "${name}" is not a string`);
164
+ }
165
+
166
+ return value;
167
+ };
168
+
169
+ /*
170
+ * The vars the template hands to a TRIPLE stache. These carry plain text that
171
+ * this builder has already escaped.
172
+ */
173
+ const HTML_VAR_NAMES: Array<string> = [
174
+ "rollupIntroHtml",
175
+ "moreTextHtml",
176
+ "preferencesHtml",
177
+ ];
178
+
179
+ /*
180
+ * The vars the template renders through a DOUBLE stache, where Handlebars
181
+ * escapes them. These must arrive RAW - pre-escaping one would show the
182
+ * recipient a literal "&amp;amp;".
183
+ *
184
+ * categoryCounts is the one that moved between the two lists when the summary
185
+ * card replaced the TitleBlock the counts used to be rendered through, which
186
+ * is exactly the kind of change that ships a wall of "&amp;quot;" to
187
+ * everybody, so both lists are pinned rather than only the escaped one.
188
+ */
189
+ const RAW_VAR_NAMES: Array<string> = [
190
+ "rollupTitle",
191
+ "summaryCount",
192
+ "summaryWindow",
193
+ "categoryCounts",
194
+ ];
195
+
196
+ describe("foldItems", () => {
197
+ test("four items sharing one view link fold to one row carrying the latest subject", () => {
198
+ const link: string =
199
+ "https://oneuptime.example.com/dashboard/p1/incidents/i1";
200
+
201
+ const rows: Array<RollupRow> = foldItems(
202
+ sortAscending([
203
+ makeItem({
204
+ createdAt: at(0),
205
+ subject: "Checkout is down",
206
+ viewLink: link,
207
+ }),
208
+ makeItem({
209
+ createdAt: at(60),
210
+ subject: "Checkout is down - acknowledged",
211
+ viewLink: link,
212
+ }),
213
+ makeItem({
214
+ createdAt: at(120),
215
+ subject: "Checkout is down - investigating",
216
+ viewLink: link,
217
+ }),
218
+ makeItem({
219
+ createdAt: at(180),
220
+ subject: "Checkout is down - resolved",
221
+ viewLink: link,
222
+ }),
223
+ ]),
224
+ );
225
+
226
+ expect(rows).toHaveLength(1);
227
+ expect(rows[0]!.title).toBe("Checkout is down - resolved");
228
+ expect(rows[0]!.itemCount).toBe(4);
229
+ expect(rows[0]!.itemCount).toBe(4);
230
+ expect(rows[0]!.link).toBe(link);
231
+ expect(rows[0]!.hasLink).toBe("true");
232
+ });
233
+
234
+ test("the fold key is the link ALONE, so a different event type on the same resource still folds", () => {
235
+ const link: string =
236
+ "https://oneuptime.example.com/dashboard/p1/incidents/i1";
237
+
238
+ const rows: Array<RollupRow> = foldItems(
239
+ sortAscending([
240
+ makeItem({
241
+ createdAt: at(0),
242
+ subject: "Incident created",
243
+ viewLink: link,
244
+ eventType:
245
+ NotificationSettingEventType.SEND_INCIDENT_CREATED_OWNER_NOTIFICATION,
246
+ }),
247
+ makeItem({
248
+ createdAt: at(60),
249
+ subject: "Incident state changed",
250
+ viewLink: link,
251
+ eventType:
252
+ NotificationSettingEventType.SEND_INCIDENT_STATE_CHANGED_OWNER_NOTIFICATION,
253
+ }),
254
+ ]),
255
+ );
256
+
257
+ expect(rows).toHaveLength(1);
258
+ expect(rows[0]!.title).toBe("Incident state changed");
259
+ expect(rows[0]!.itemCount).toBe(2);
260
+ });
261
+
262
+ test("two different links produce two rows, newest group first", () => {
263
+ const older: string =
264
+ "https://oneuptime.example.com/dashboard/p1/alerts/a1";
265
+ const newer: string =
266
+ "https://oneuptime.example.com/dashboard/p1/incidents/i9";
267
+
268
+ const rows: Array<RollupRow> = foldItems(
269
+ sortAscending([
270
+ makeItem({ createdAt: at(0), subject: "Old alert", viewLink: older }),
271
+ makeItem({
272
+ createdAt: at(30),
273
+ subject: "Old alert again",
274
+ viewLink: older,
275
+ }),
276
+ makeItem({
277
+ createdAt: at(600),
278
+ subject: "Fresh incident",
279
+ viewLink: newer,
280
+ }),
281
+ ]),
282
+ );
283
+
284
+ expect(rows).toHaveLength(2);
285
+ expect(rows[0]!.title).toBe("Fresh incident");
286
+ expect(rows[0]!.itemCount).toBe(1);
287
+ expect(rows[1]!.title).toBe("Old alert again");
288
+ expect(rows[1]!.itemCount).toBe(2);
289
+ });
290
+
291
+ test("items with no view link fold on event type plus subject", () => {
292
+ const rows: Array<RollupRow> = foldItems(
293
+ sortAscending([
294
+ makeItem({
295
+ createdAt: at(0),
296
+ subject: "Probe eu-west is disconnected",
297
+ eventType:
298
+ NotificationSettingEventType.SEND_PROBE_STATUS_CHANGED_OWNER_NOTIFICATION,
299
+ rollupCategory: RollupCategory.Probes,
300
+ }),
301
+ makeItem({
302
+ createdAt: at(60),
303
+ subject: "Probe eu-west is disconnected",
304
+ eventType:
305
+ NotificationSettingEventType.SEND_PROBE_STATUS_CHANGED_OWNER_NOTIFICATION,
306
+ rollupCategory: RollupCategory.Probes,
307
+ }),
308
+ makeItem({
309
+ createdAt: at(120),
310
+ subject: "Probe us-east is disconnected",
311
+ eventType:
312
+ NotificationSettingEventType.SEND_PROBE_STATUS_CHANGED_OWNER_NOTIFICATION,
313
+ rollupCategory: RollupCategory.Probes,
314
+ }),
315
+ /*
316
+ * Same words, different event: these are two genuinely different
317
+ * notices and must not be collapsed into one line.
318
+ */
319
+ makeItem({
320
+ createdAt: at(180),
321
+ subject: "Probe us-east is disconnected",
322
+ eventType:
323
+ NotificationSettingEventType.SEND_PROBE_OWNER_ADDED_NOTIFICATION,
324
+ rollupCategory: RollupCategory.Probes,
325
+ }),
326
+ ]),
327
+ );
328
+
329
+ const counts: Array<number> = rows.map((row: RollupRow): number => {
330
+ return row.itemCount;
331
+ });
332
+
333
+ expect(rows).toHaveLength(3);
334
+ expect(counts).toEqual([1, 1, 2]);
335
+ expect(
336
+ rows.every((row: RollupRow): boolean => {
337
+ return row.hasLink === "false" && row.link === "";
338
+ }),
339
+ ).toBe(true);
340
+ });
341
+
342
+ test("an empty list folds to no rows", () => {
343
+ expect(foldItems([])).toEqual([]);
344
+ });
345
+ });
346
+
347
+ describe("buildRollupEmail category counts", () => {
348
+ test("counts every item, not the rendered slice: 300 items, 100 rows, 300 counted", () => {
349
+ const items: Array<UserNotificationEmailRollupItem> = [];
350
+
351
+ for (let index: number = 0; index < 300; index++) {
352
+ items.push(
353
+ makeItem({
354
+ createdAt: at(index),
355
+ subject: `Event ${index}`,
356
+ viewLink: `https://oneuptime.example.com/dashboard/p1/r/${index}`,
357
+ rollupCategory:
358
+ index < 200 ? RollupCategory.Monitors : RollupCategory.Incidents,
359
+ }),
360
+ );
361
+ }
362
+
363
+ const email: RollupEmail = build(items);
364
+
365
+ expect(varRows(email)).toHaveLength(MAX_ROWS_IN_ROLLUP);
366
+
367
+ const counts: string = varString(email, "categoryCounts");
368
+
369
+ expect(counts).toBe("200 Monitors · 100 Incidents");
370
+
371
+ let total: number = 0;
372
+
373
+ for (const part of counts.split(" · ")) {
374
+ total = total + Number(part.split(" ")[0]!);
375
+ }
376
+
377
+ expect(total).toBe(300);
378
+ });
379
+
380
+ test("counts are ordered by size descending, then by label ascending", () => {
381
+ const items: Array<UserNotificationEmailRollupItem> = [
382
+ makeItem({
383
+ createdAt: at(1),
384
+ subject: "s",
385
+ rollupCategory: RollupCategory.StatusPages,
386
+ }),
387
+ makeItem({
388
+ createdAt: at(2),
389
+ subject: "a",
390
+ rollupCategory: RollupCategory.Alerts,
391
+ }),
392
+ makeItem({
393
+ createdAt: at(3),
394
+ subject: "m1",
395
+ rollupCategory: RollupCategory.Monitors,
396
+ }),
397
+ makeItem({
398
+ createdAt: at(4),
399
+ subject: "m2",
400
+ rollupCategory: RollupCategory.Monitors,
401
+ }),
402
+ ];
403
+
404
+ expect(varString(build(items), "categoryCounts")).toBe(
405
+ "2 Monitors · 1 Alerts · 1 Status Pages",
406
+ );
407
+ });
408
+
409
+ test("a category code the build has never heard of counts as Other rather than crashing", () => {
410
+ const item: UserNotificationEmailRollupItem = makeItem({
411
+ createdAt: at(0),
412
+ subject: "From a newer build",
413
+ });
414
+
415
+ item.rollupCategory = "quantum-widgets" as RollupCategory;
416
+
417
+ expect(varString(build([item]), "categoryCounts")).toBe("1 Other");
418
+ });
419
+ });
420
+
421
+ describe("buildRollupEmail row cap", () => {
422
+ /*
423
+ * 150 groups, of which the oldest 50 carry two items each. The hidden ROW
424
+ * count and the hidden ITEM count are deliberately different numbers so a
425
+ * copy bug that reports one where it means the other cannot pass.
426
+ */
427
+ type BuildOversizedFunction = () => Array<UserNotificationEmailRollupItem>;
428
+
429
+ const buildOversized: BuildOversizedFunction =
430
+ (): Array<UserNotificationEmailRollupItem> => {
431
+ const items: Array<UserNotificationEmailRollupItem> = [];
432
+
433
+ for (let group: number = 0; group < 150; group++) {
434
+ const link: string = `https://oneuptime.example.com/dashboard/p1/r/${group}`;
435
+
436
+ items.push(
437
+ makeItem({
438
+ createdAt: at(group * 60),
439
+ subject: `Group ${group}`,
440
+ viewLink: link,
441
+ }),
442
+ );
443
+
444
+ if (group < 50) {
445
+ items.push(
446
+ makeItem({
447
+ createdAt: at(group * 60 + 1),
448
+ subject: `Group ${group} update`,
449
+ viewLink: link,
450
+ }),
451
+ );
452
+ }
453
+ }
454
+
455
+ return items;
456
+ };
457
+
458
+ test("renders at most MAX_ROWS_IN_ROLLUP rows and flags the rest", () => {
459
+ const email: RollupEmail = build(buildOversized());
460
+
461
+ expect(varRows(email)).toHaveLength(100);
462
+ expect(varString(email, "hasMore")).toBe("true");
463
+ });
464
+
465
+ test("the tail names the true hidden row count and hidden item count", () => {
466
+ const email: RollupEmail = build(buildOversized());
467
+ const moreText: string = varString(email, "moreTextHtml");
468
+
469
+ expect(moreText).toContain("50 more updates");
470
+ expect(moreText).toContain("covering 100 notifications");
471
+ expect(moreText).toContain("are not listed here");
472
+ });
473
+
474
+ test("nothing hidden means no tail at all", () => {
475
+ const email: RollupEmail = build([
476
+ makeItem({ createdAt: at(0), subject: "One thing" }),
477
+ makeItem({ createdAt: at(1), subject: "Another thing" }),
478
+ ]);
479
+
480
+ expect(varString(email, "hasMore")).toBe("false");
481
+ expect(varString(email, "moreTextHtml")).toBe("");
482
+ });
483
+ });
484
+
485
+ describe("buildRollupEmail subject grammar", () => {
486
+ test("more than one notification reads [project] N notifications", () => {
487
+ const items: Array<UserNotificationEmailRollupItem> = [];
488
+
489
+ for (let index: number = 0; index < 12; index++) {
490
+ items.push(makeItem({ createdAt: at(index), subject: `Event ${index}` }));
491
+ }
492
+
493
+ expect(build(items).subject).toBe("[Acme] 12 notifications: 12 Incidents");
494
+ });
495
+
496
+ test("exactly one notification leads with its title", () => {
497
+ expect(
498
+ build([makeItem({ createdAt: at(0), subject: "Checkout is down" })])
499
+ .subject,
500
+ ).toBe("[Acme] 1 notification: Checkout is down");
501
+ });
502
+
503
+ test("the lead title is truncated to ROLLUP_SUBJECT_LEAD_TITLE_MAX", () => {
504
+ const longTitle: string = "T".repeat(200);
505
+ const subject: string = build([
506
+ makeItem({ createdAt: at(0), subject: longTitle }),
507
+ ]).subject;
508
+
509
+ const lead: string = subject.replace("[Acme] 1 notification: ", "");
510
+
511
+ expect(lead).toHaveLength(ROLLUP_SUBJECT_LEAD_TITLE_MAX);
512
+ expect(lead).toBe(`${"T".repeat(79)}…`);
513
+ });
514
+
515
+ test("the project name is truncated to ROLLUP_PROJECT_NAME_MAX", () => {
516
+ const subject: string = build(
517
+ [
518
+ makeItem({ createdAt: at(0), subject: "a" }),
519
+ makeItem({ createdAt: at(1), subject: "b" }),
520
+ ],
521
+ "P".repeat(200),
522
+ ).subject;
523
+
524
+ expect(subject).toBe(`[${"P".repeat(59)}…] 2 notifications: 2 Incidents`);
525
+ expect(subject.indexOf("]") - 1).toBe(ROLLUP_PROJECT_NAME_MAX);
526
+ });
527
+
528
+ test("handlebars braces are stripped, because MailService compiles the subject", () => {
529
+ const subject: string = build(
530
+ [
531
+ makeItem({ createdAt: at(0), subject: "a" }),
532
+ makeItem({ createdAt: at(1), subject: "b" }),
533
+ ],
534
+ "{{constructor}}",
535
+ ).subject;
536
+
537
+ expect(subject).toBe("[constructor] 2 notifications: 2 Incidents");
538
+ expect(subject).not.toContain("{{");
539
+ });
540
+
541
+ test("braces are stripped from the lead title too", () => {
542
+ expect(
543
+ build([
544
+ makeItem({ createdAt: at(0), subject: "{{projectName}} is down" }),
545
+ ]).subject,
546
+ ).toBe("[Acme] 1 notification: projectName is down");
547
+ });
548
+
549
+ test("an unnamed project falls back to prose rather than an empty bracket", () => {
550
+ expect(
551
+ build(
552
+ [
553
+ makeItem({ createdAt: at(0), subject: "a" }),
554
+ makeItem({ createdAt: at(1), subject: "b" }),
555
+ ],
556
+ "",
557
+ ).subject,
558
+ ).toBe("[your project] 2 notifications: 2 Incidents");
559
+ });
560
+ });
561
+
562
+ describe("buildRollupEmail escaping contract", () => {
563
+ /*
564
+ * The fixture carries EVERY character escapeHtml touches - & < > " and ' -
565
+ * on purpose. A fixture built only from <script>alert(1)</script> exercises
566
+ * two of the five, and, worse, a fixture with no escapable character at all
567
+ * makes the whole contract untestable: raw and pre-escaped are then the
568
+ * same bytes, so a test written against it passes whichever way round the
569
+ * two are wired. Both halves of the contract are asserted here, because
570
+ * both halves fail silently in production:
571
+ *
572
+ * raw value in a triple stache -> live markup in a mail client
573
+ * pre-escaped value in a double -> the recipient reads "&amp;lt;"
574
+ *
575
+ * `&` in a project name is the common case (Marks & Spencer), and `"` in a
576
+ * title is the common case for a monitor named after a quoted hostname.
577
+ */
578
+ const hostileProject: string = "A&B <\"Corp\"> 'Ltd'";
579
+ const hostileSubject: string =
580
+ "Disk \"sda1\" > 90% & <b>hot</b> at 'eu-west'";
581
+
582
+ /* What escapeHtml makes of hostileProject. Escaped once, never twice. */
583
+ const projectEscapedOnce: string =
584
+ "A&amp;B &lt;&quot;Corp&quot;&gt; &#39;Ltd&#39;";
585
+
586
+ /*
587
+ * An `&` that does not open one of the five entities escapeHtml produces.
588
+ * A pre-escaped var containing one was escaped too few times - which is
589
+ * exactly what dropping the `&` replace from escapeHtml would do, while
590
+ * leaving every angle bracket looking correct.
591
+ */
592
+ const unescapedAmpersand: RegExp = /&(?!(?:amp|lt|gt|quot|#39);)/;
593
+
594
+ type HostileEmailFunction = () => RollupEmail;
595
+
596
+ const hostileEmail: HostileEmailFunction = (): RollupEmail => {
597
+ return build(
598
+ [
599
+ makeItem({
600
+ createdAt: at(0),
601
+ subject: hostileSubject,
602
+ viewLink: "https://oneuptime.example.com/dashboard/p1/incidents/i1",
603
+ }),
604
+ makeItem({ createdAt: at(1), subject: "Something ordinary" }),
605
+ ],
606
+ hostileProject,
607
+ );
608
+ };
609
+
610
+ test("a var the template feeds to a DOUBLE stache arrives RAW, byte for byte", () => {
611
+ const email: RollupEmail = hostileEmail();
612
+ const rows: Array<JSONObject> = varRows(email);
613
+
614
+ /* rollupTitle -> {{> EmailTitle title=... }} -> {{title}} */
615
+ expect(varString(email, "rollupTitle")).toBe(
616
+ `2 notifications from ${hostileProject}`,
617
+ );
618
+
619
+ /* rows[].title -> {{this.title}} in this template's own table. */
620
+ expect(rowField(rows[1]!, "title")).toBe(hostileSubject);
621
+
622
+ /*
623
+ * Not one of the five has become an entity yet: Handlebars has not run,
624
+ * and when it does it must be the FIRST and only pass over these bytes.
625
+ */
626
+ expect(varString(email, "rollupTitle")).not.toContain("&amp;");
627
+ expect(varString(email, "rollupTitle")).not.toContain("&lt;");
628
+ expect(rowField(rows[1]!, "title")).not.toContain("&quot;");
629
+ expect(rowField(rows[1]!, "title")).not.toContain("&#39;");
630
+ });
631
+
632
+ test("a var the template feeds to a TRIPLE stache arrives PRE-ESCAPED, exactly once", () => {
633
+ const email: RollupEmail = hostileEmail();
634
+
635
+ /* rollupIntroHtml -> {{> InfoBlock info=... }} -> {{{info}}} */
636
+ expect(varString(email, "rollupIntroHtml")).toContain(projectEscapedOnce);
637
+
638
+ for (const name of HTML_VAR_NAMES) {
639
+ const value: string = varString(email, name);
640
+
641
+ /* Escaped at least once: nothing a triple stache would render live. */
642
+ expect(value).not.toContain("<");
643
+ expect(value).not.toContain(">");
644
+ expect(value).not.toContain('"');
645
+ expect(value).not.toContain("'");
646
+ expect(value).not.toMatch(unescapedAmpersand);
647
+
648
+ /* And at most once: escaped twice reads as literal "&amp;lt;". */
649
+ expect(value).not.toContain("&amp;amp;");
650
+ expect(value).not.toContain("&amp;lt;");
651
+ expect(value).not.toContain("&amp;gt;");
652
+ expect(value).not.toContain("&amp;quot;");
653
+ expect(value).not.toContain("&amp;#39;");
654
+ }
655
+ });
656
+
657
+ test("the raw links are passed through untouched for their href attributes", () => {
658
+ const email: RollupEmail = hostileEmail();
659
+
660
+ expect(varString(email, "projectHomeLink")).toBe(
661
+ "https://oneuptime.example.com/dashboard/p1/home",
662
+ );
663
+ expect(varString(email, "preferencesLink")).toBe(
664
+ "https://oneuptime.example.com/dashboard/p1/user-settings/notification-settings",
665
+ );
666
+ });
667
+ });
668
+
669
+ describe("buildRollupEmail zebra striping", () => {
670
+ /*
671
+ * The template used to decide the stripe itself, with {{#if @odd}}.
672
+ * Handlebars defines @index, @first, @last, @key, @root and @level - and
673
+ * NOT @odd - and an unknown @-variable resolves to undefined instead of
674
+ * erroring, so that condition was false on every single row and the table
675
+ * rendered flat white. Nothing failed, nothing logged, and no test noticed.
676
+ *
677
+ * The colour is a builder field now, and these are the assertions that
678
+ * would have caught it: the sequence itself, pinned per index.
679
+ */
680
+ type StripedEmailFunction = (rowCount: number) => RollupEmail;
681
+
682
+ const stripedEmail: StripedEmailFunction = (
683
+ rowCount: number,
684
+ ): RollupEmail => {
685
+ const items: Array<UserNotificationEmailRollupItem> = [];
686
+
687
+ for (let index: number = 0; index < rowCount; index++) {
688
+ items.push(
689
+ makeItem({
690
+ createdAt: at(index * 60),
691
+ subject: `Event ${index}`,
692
+ viewLink: `https://oneuptime.example.com/dashboard/p1/r/${index}`,
693
+ }),
694
+ );
695
+ }
696
+
697
+ return build(items);
698
+ };
699
+
700
+ type BackgroundsFunction = (email: RollupEmail) => Array<string>;
701
+
702
+ const backgrounds: BackgroundsFunction = (
703
+ email: RollupEmail,
704
+ ): Array<string> => {
705
+ return varRows(email).map((row: JSONObject): string => {
706
+ return rowField(row, "rowBackground");
707
+ });
708
+ };
709
+
710
+ test("row backgrounds alternate, starting white on the first row", () => {
711
+ expect(backgrounds(stripedEmail(5))).toEqual([
712
+ "#ffffff",
713
+ "#f7f9fc",
714
+ "#ffffff",
715
+ "#f7f9fc",
716
+ "#ffffff",
717
+ ]);
718
+ });
719
+
720
+ test("a one-row rollup is white, never the stripe colour", () => {
721
+ expect(backgrounds(stripedEmail(1))).toEqual(["#ffffff"]);
722
+ });
723
+
724
+ test("every rendered row carries a colour and no two neighbours share one", () => {
725
+ const colours: Array<string> = backgrounds(
726
+ stripedEmail(MAX_ROWS_IN_ROLLUP + 20),
727
+ );
728
+
729
+ expect(colours).toHaveLength(MAX_ROWS_IN_ROLLUP);
730
+
731
+ for (let index: number = 1; index < colours.length; index++) {
732
+ expect(colours[index]!).not.toBe(colours[index - 1]!);
733
+ }
734
+ });
735
+ });
736
+
737
+ describe("buildRollupEmail singular and plural copy", () => {
738
+ test("one item reads in the singular throughout", () => {
739
+ const email: RollupEmail = build([
740
+ makeItem({ createdAt: at(0), subject: "Checkout is down" }),
741
+ ]);
742
+
743
+ expect(varString(email, "rollupTitle")).toBe("1 notification from Acme");
744
+ expect(varString(email, "summaryCount")).toBe("1 notification");
745
+ expect(varString(email, "rollupIntroHtml")).toBe(
746
+ "OneUptime grouped this notification from Acme into a single email. Nothing was suppressed.",
747
+ );
748
+ expect(varRows(email)).toHaveLength(1);
749
+
750
+ /*
751
+ * A single-update row says WHEN and nothing else. "1 update" would be
752
+ * noise on every row of the common case - most rows in a real rollup are
753
+ * one event about one resource.
754
+ */
755
+ expect(rowField(varRows(email)[0]!, "metaLabel")).toBe("12:00 UTC");
756
+ expect(rowField(varRows(email)[0]!, "sectionCount")).toBe("1 update");
757
+ });
758
+
759
+ test("many items read in the plural throughout", () => {
760
+ const email: RollupEmail = build([
761
+ makeItem({ createdAt: at(0), subject: "a" }),
762
+ makeItem({ createdAt: at(1), subject: "b" }),
763
+ ]);
764
+
765
+ expect(varString(email, "rollupTitle")).toBe("2 notifications from Acme");
766
+ expect(varString(email, "summaryCount")).toBe("2 notifications");
767
+ expect(varString(email, "rollupIntroHtml")).toBe(
768
+ "OneUptime grouped these 2 notifications from Acme into a single email " +
769
+ "instead of sending 2 separate messages. Nothing was suppressed.",
770
+ );
771
+ });
772
+
773
+ test("exactly one hidden row and one hidden item read in the singular", () => {
774
+ const items: Array<UserNotificationEmailRollupItem> = [];
775
+
776
+ for (let index: number = 0; index < MAX_ROWS_IN_ROLLUP + 1; index++) {
777
+ items.push(
778
+ makeItem({
779
+ createdAt: at(index * 60),
780
+ subject: `Event ${index}`,
781
+ viewLink: `https://oneuptime.example.com/dashboard/p1/r/${index}`,
782
+ }),
783
+ );
784
+ }
785
+
786
+ const moreText: string = varString(build(items), "moreTextHtml");
787
+
788
+ expect(moreText).toContain("1 more update ");
789
+ expect(moreText).toContain("covering 1 notification)");
790
+ expect(moreText).toContain("is not listed here");
791
+ });
792
+ });
793
+
794
+ describe("buildRollupEmail variable set", () => {
795
+ test("every variable the template needs is present, and rows carry exactly eight fields", () => {
796
+ const email: RollupEmail = build([
797
+ makeItem({
798
+ createdAt: at(0),
799
+ subject: "Checkout is down",
800
+ viewLink: "https://oneuptime.example.com/dashboard/p1/incidents/i1",
801
+ }),
802
+ ]);
803
+
804
+ expect(Object.keys(email.vars).sort()).toEqual(
805
+ [
806
+ "categoryCounts",
807
+ "hasMore",
808
+ "moreTextHtml",
809
+ "preferencesHtml",
810
+ "preferencesLink",
811
+ "projectHomeLink",
812
+ "rollupIntroHtml",
813
+ "rollupTitle",
814
+ "rows",
815
+ "summaryCount",
816
+ "summaryWindow",
817
+ ].sort(),
818
+ );
819
+
820
+ /*
821
+ * Exactly these, no more: a row field the template reads and the builder
822
+ * does not set renders as the empty string, and rowBackground lives
823
+ * inside a style attribute, where empty means `background-color: ;` and a
824
+ * mail client throws the whole declaration away.
825
+ */
826
+ expect(Object.keys(varRows(email)[0]!).sort()).toEqual(
827
+ [
828
+ "hasLink",
829
+ "isSectionStart",
830
+ "link",
831
+ "metaLabel",
832
+ "rowBackground",
833
+ "sectionCount",
834
+ "sectionLabel",
835
+ "title",
836
+ ].sort(),
837
+ );
838
+ });
839
+
840
+ test("the preferences copy explains the batching AND names the way out of it", () => {
841
+ const email: RollupEmail = build([
842
+ makeItem({ createdAt: at(0), subject: "a" }),
843
+ ]);
844
+
845
+ const preferences: string = varString(email, "preferencesHtml");
846
+
847
+ /* Why an email the recipient did not recognise arrived at all. */
848
+ expect(preferences).toContain(
849
+ "groups owner notifications into a single email",
850
+ );
851
+
852
+ /*
853
+ * And the escape hatch, which is the half that regresses silently.
854
+ * Rollup is on for everyone with no preference and no announcement, so
855
+ * this paragraph is the only place a recipient learns the opt-out exists
856
+ * - copy that merely says "choose which notifications you receive" sends
857
+ * them to a page whose most useful switch it never mentioned, and they
858
+ * conclude batching is mandatory.
859
+ */
860
+ expect(preferences).toContain("turn off email rollup for this project");
861
+ expect(preferences).toContain("notification settings");
862
+
863
+ /*
864
+ * The template renders preferencesLink as a bare URL on the line below
865
+ * this text, so the text has to hand off to it. End on a full stop and
866
+ * the reader gets a naked link with nothing claiming it.
867
+ */
868
+ expect(preferences.endsWith(":")).toBe(true);
869
+ });
870
+ });
871
+
872
+ /*
873
+ * The rest of this file pins the SHAPE of the rollup email: which section a
874
+ * row lands in, what order the sections come in, what each row says about
875
+ * when it happened, and whether the numbers in the three places this email
876
+ * counts things agree with each other.
877
+ *
878
+ * All of it is behaviour a reader notices immediately and no type checks:
879
+ * every field below is a string in a Dictionary, and every one of them
880
+ * renders as the empty string when it is wrong.
881
+ */
882
+
883
+ type SectionSummary = {
884
+ label: string;
885
+ count: string;
886
+ titles: Array<string>;
887
+ };
888
+
889
+ type SectionsOfFunction = (email: RollupEmail) => Array<SectionSummary>;
890
+
891
+ /*
892
+ * Rebuild the sections from the flat rows the way the TEMPLATE does - by
893
+ * starting a new one every time isSectionStart is "true" - rather than by
894
+ * reading the builder's internals. A section boundary that the builder knows
895
+ * about and the flag does not express is invisible in the email, so it has to
896
+ * be invisible here too.
897
+ */
898
+ const sectionsOf: SectionsOfFunction = (
899
+ email: RollupEmail,
900
+ ): Array<SectionSummary> => {
901
+ const sections: Array<SectionSummary> = [];
902
+
903
+ for (const row of varRows(email)) {
904
+ const title: string = rowField(row, "title");
905
+
906
+ if (rowField(row, "isSectionStart") === "true") {
907
+ sections.push({
908
+ label: rowField(row, "sectionLabel"),
909
+ count: rowField(row, "sectionCount"),
910
+ titles: [title],
911
+ });
912
+ continue;
913
+ }
914
+
915
+ const current: SectionSummary | undefined = sections[sections.length - 1];
916
+
917
+ if (!current) {
918
+ throw new Error("A row appeared before any section started");
919
+ }
920
+
921
+ current.titles.push(title);
922
+ }
923
+
924
+ return sections;
925
+ };
926
+
927
+ describe("buildRollupEmail sections", () => {
928
+ type MixedItemsFunction = () => Array<UserNotificationEmailRollupItem>;
929
+
930
+ /*
931
+ * Deliberately seeded OUT of the order the sections must come out in, and
932
+ * with the biggest category last: a builder that grouped by first
933
+ * appearance, or that sorted sections by size the way the summary card
934
+ * sorts its counts, passes neither of the next two tests.
935
+ */
936
+ const mixedItems: MixedItemsFunction =
937
+ (): Array<UserNotificationEmailRollupItem> => {
938
+ return [
939
+ makeItem({
940
+ createdAt: at(0),
941
+ subject: "Probe eu-west is disconnected",
942
+ viewLink: "https://oneuptime.example.com/dashboard/p1/probes/p1",
943
+ rollupCategory: RollupCategory.Probes,
944
+ }),
945
+ makeItem({
946
+ createdAt: at(60),
947
+ subject: "api.acme.com is offline",
948
+ viewLink: "https://oneuptime.example.com/dashboard/p1/monitors/m1",
949
+ rollupCategory: RollupCategory.Monitors,
950
+ }),
951
+ makeItem({
952
+ createdAt: at(120),
953
+ subject: "Checkout is down",
954
+ viewLink: "https://oneuptime.example.com/dashboard/p1/incidents/i1",
955
+ rollupCategory: RollupCategory.Incidents,
956
+ }),
957
+ makeItem({
958
+ createdAt: at(180),
959
+ subject: "Checkout is down - acknowledged",
960
+ viewLink: "https://oneuptime.example.com/dashboard/p1/incidents/i1",
961
+ rollupCategory: RollupCategory.Incidents,
962
+ }),
963
+ makeItem({
964
+ createdAt: at(240),
965
+ subject: "Error rate above 5%",
966
+ viewLink: "https://oneuptime.example.com/dashboard/p1/alerts/a1",
967
+ rollupCategory: RollupCategory.Alerts,
968
+ }),
969
+ ];
970
+ };
971
+
972
+ test("rows are grouped into one section per category", () => {
973
+ const sections: Array<SectionSummary> = sectionsOf(build(mixedItems()));
974
+
975
+ expect(
976
+ sections.map((section: SectionSummary): string => {
977
+ return section.label;
978
+ }),
979
+ ).toEqual(["Incidents", "Alerts", "Monitors", "Probes"]);
980
+ });
981
+
982
+ test("sections follow ROLLUP_CATEGORY_ORDER, not size and not arrival order", () => {
983
+ const sections: Array<SectionSummary> = sectionsOf(build(mixedItems()));
984
+
985
+ const orderedLabels: Array<string> = ROLLUP_CATEGORY_ORDER.filter(
986
+ (category: RollupCategory): boolean => {
987
+ return [
988
+ RollupCategory.Incidents,
989
+ RollupCategory.Alerts,
990
+ RollupCategory.Monitors,
991
+ RollupCategory.Probes,
992
+ ].includes(category);
993
+ },
994
+ ).map((category: RollupCategory): string => {
995
+ return ROLLUP_CATEGORY_LABEL[category];
996
+ });
997
+
998
+ expect(
999
+ sections.map((section: SectionSummary): string => {
1000
+ return section.label;
1001
+ }),
1002
+ ).toEqual(orderedLabels);
1003
+ });
1004
+
1005
+ test("exactly one row per section is flagged as its start", () => {
1006
+ const email: RollupEmail = build(mixedItems());
1007
+
1008
+ const starts: number = varRows(email).filter((row: JSONObject): boolean => {
1009
+ return rowField(row, "isSectionStart") === "true";
1010
+ }).length;
1011
+
1012
+ expect(starts).toBe(4);
1013
+ expect(rowField(varRows(email)[0]!, "isSectionStart")).toBe("true");
1014
+ });
1015
+
1016
+ test("every row carries its own section's label and count, not only the first", () => {
1017
+ const email: RollupEmail = build(mixedItems());
1018
+
1019
+ for (const row of varRows(email)) {
1020
+ expect(rowField(row, "sectionLabel").length).toBeGreaterThan(0);
1021
+ expect(rowField(row, "sectionCount")).toMatch(/^\d+ updates?$/);
1022
+ }
1023
+ });
1024
+
1025
+ test("rows inside a section stay newest first", () => {
1026
+ const link: string = "https://oneuptime.example.com/dashboard/p1/i";
1027
+
1028
+ const email: RollupEmail = build([
1029
+ makeItem({
1030
+ createdAt: at(0),
1031
+ subject: "Oldest",
1032
+ viewLink: `${link}/1`,
1033
+ }),
1034
+ makeItem({
1035
+ createdAt: at(60),
1036
+ subject: "Middle",
1037
+ viewLink: `${link}/2`,
1038
+ }),
1039
+ makeItem({
1040
+ createdAt: at(120),
1041
+ subject: "Newest",
1042
+ viewLink: `${link}/3`,
1043
+ }),
1044
+ ]);
1045
+
1046
+ expect(sectionsOf(email)[0]!.titles).toEqual([
1047
+ "Newest",
1048
+ "Middle",
1049
+ "Oldest",
1050
+ ]);
1051
+ });
1052
+
1053
+ test("the section count is UPDATES, so it equals the summary card's count for that category", () => {
1054
+ const sections: Array<SectionSummary> = sectionsOf(build(mixedItems()));
1055
+
1056
+ /* Two notifications about ONE incident: one row, and a heading saying 2. */
1057
+ expect(sections[0]!.label).toBe("Incidents");
1058
+ expect(sections[0]!.titles).toHaveLength(1);
1059
+ expect(sections[0]!.count).toBe("2 updates");
1060
+
1061
+ const counts: string = varString(build(mixedItems()), "categoryCounts");
1062
+
1063
+ expect(counts).toContain("2 Incidents");
1064
+ });
1065
+
1066
+ test("the section counts add up to the summary count, every category", () => {
1067
+ const email: RollupEmail = build(mixedItems());
1068
+
1069
+ let total: number = 0;
1070
+
1071
+ for (const section of sectionsOf(email)) {
1072
+ total = total + Number(section.count.split(" ")[0]!);
1073
+ }
1074
+
1075
+ expect(varString(email, "summaryCount")).toBe(`${total} notifications`);
1076
+ expect(total).toBe(5);
1077
+ });
1078
+
1079
+ test("one update reads in the singular in a section heading", () => {
1080
+ const sections: Array<SectionSummary> = sectionsOf(build(mixedItems()));
1081
+
1082
+ expect(sections[1]!.label).toBe("Alerts");
1083
+ expect(sections[1]!.count).toBe("1 update");
1084
+ });
1085
+
1086
+ test("a category the build has never heard of renders under Other rather than vanishing", () => {
1087
+ const item: UserNotificationEmailRollupItem = makeItem({
1088
+ createdAt: at(0),
1089
+ subject: "From a newer build",
1090
+ });
1091
+
1092
+ item.rollupCategory = "quantum-widgets" as RollupCategory;
1093
+
1094
+ const sections: Array<SectionSummary> = sectionsOf(build([item]));
1095
+
1096
+ expect(sections).toHaveLength(1);
1097
+ expect(sections[0]!.label).toBe("Other");
1098
+ expect(sections[0]!.titles).toEqual(["From a newer build"]);
1099
+ });
1100
+
1101
+ test("EVERY row survives grouping - a section is a heading, never a filter", () => {
1102
+ const items: Array<UserNotificationEmailRollupItem> = [];
1103
+
1104
+ for (const category of ROLLUP_CATEGORY_ORDER) {
1105
+ items.push(
1106
+ makeItem({
1107
+ createdAt: at(items.length * 60),
1108
+ subject: `Something in ${category}`,
1109
+ viewLink: `https://oneuptime.example.com/dashboard/p1/r/${category}`,
1110
+ rollupCategory: category,
1111
+ }),
1112
+ );
1113
+ }
1114
+
1115
+ const email: RollupEmail = build(items);
1116
+
1117
+ expect(varRows(email)).toHaveLength(ROLLUP_CATEGORY_ORDER.length);
1118
+ expect(sectionsOf(email)).toHaveLength(ROLLUP_CATEGORY_ORDER.length);
1119
+ expect(
1120
+ sectionsOf(email).map((section: SectionSummary): string => {
1121
+ return section.label;
1122
+ }),
1123
+ ).toEqual(
1124
+ ROLLUP_CATEGORY_ORDER.map((category: RollupCategory): string => {
1125
+ return ROLLUP_CATEGORY_LABEL[category];
1126
+ }),
1127
+ );
1128
+ });
1129
+
1130
+ test("the zebra stripe restarts at white in every section", () => {
1131
+ const items: Array<UserNotificationEmailRollupItem> = [];
1132
+
1133
+ /* Two incidents, then two monitors: without a restart the third row is striped. */
1134
+ for (let index: number = 0; index < 2; index++) {
1135
+ items.push(
1136
+ makeItem({
1137
+ createdAt: at(index * 60),
1138
+ subject: `Incident ${index}`,
1139
+ viewLink: `https://oneuptime.example.com/dashboard/p1/incidents/${index}`,
1140
+ rollupCategory: RollupCategory.Incidents,
1141
+ }),
1142
+ );
1143
+ items.push(
1144
+ makeItem({
1145
+ createdAt: at(index * 60 + 1),
1146
+ subject: `Monitor ${index}`,
1147
+ viewLink: `https://oneuptime.example.com/dashboard/p1/monitors/${index}`,
1148
+ rollupCategory: RollupCategory.Monitors,
1149
+ }),
1150
+ );
1151
+ }
1152
+
1153
+ const colours: Array<string> = varRows(build(items)).map(
1154
+ (row: JSONObject): string => {
1155
+ return rowField(row, "rowBackground");
1156
+ },
1157
+ );
1158
+
1159
+ expect(colours).toEqual(["#ffffff", "#f7f9fc", "#ffffff", "#f7f9fc"]);
1160
+ });
1161
+ });
1162
+
1163
+ describe("buildRollupEmail times", () => {
1164
+ test("a single-update row carries only its timestamp", () => {
1165
+ const email: RollupEmail = build([
1166
+ makeItem({ createdAt: at(0), subject: "Checkout is down" }),
1167
+ ]);
1168
+
1169
+ expect(rowField(varRows(email)[0]!, "metaLabel")).toBe("12:00 UTC");
1170
+ });
1171
+
1172
+ test("a folded row carries its update count and the time of the LATEST of them", () => {
1173
+ const link: string = "https://oneuptime.example.com/dashboard/p1/i1";
1174
+
1175
+ const email: RollupEmail = build([
1176
+ makeItem({ createdAt: at(0), subject: "Down", viewLink: link }),
1177
+ makeItem({ createdAt: at(9 * 60), subject: "Acked", viewLink: link }),
1178
+ makeItem({ createdAt: at(21 * 60), subject: "Resolved", viewLink: link }),
1179
+ ]);
1180
+
1181
+ expect(rowField(varRows(email)[0]!, "metaLabel")).toBe(
1182
+ "3 updates · latest 12:21 UTC",
1183
+ );
1184
+ });
1185
+
1186
+ test("times are UTC and zero padded, whatever the process timezone is", () => {
1187
+ const email: RollupEmail = build([
1188
+ makeItem({
1189
+ createdAt: new Date(Date.UTC(2026, 8, 3, 4, 5, 0)),
1190
+ subject: "Early",
1191
+ }),
1192
+ ]);
1193
+
1194
+ expect(rowField(varRows(email)[0]!, "metaLabel")).toBe("04:05 UTC");
1195
+ });
1196
+
1197
+ test("the summary window spans the earliest and latest notification", () => {
1198
+ const email: RollupEmail = build([
1199
+ makeItem({ createdAt: at(0), subject: "First" }),
1200
+ makeItem({ createdAt: at(26 * 60), subject: "Last" }),
1201
+ ]);
1202
+
1203
+ expect(varString(email, "summaryWindow")).toBe("12:00 UTC to 12:26 UTC");
1204
+ });
1205
+
1206
+ test("a window that starts and ends in the same minute is printed once, not as a range", () => {
1207
+ const email: RollupEmail = build([
1208
+ makeItem({ createdAt: at(0), subject: "a" }),
1209
+ makeItem({ createdAt: at(30), subject: "b" }),
1210
+ ]);
1211
+
1212
+ expect(varString(email, "summaryWindow")).toBe("12:00 UTC");
1213
+ });
1214
+
1215
+ test("a rollup that spans two UTC days prints the date on EVERY time", () => {
1216
+ const email: RollupEmail = build([
1217
+ makeItem({
1218
+ createdAt: new Date(Date.UTC(2026, 8, 3, 23, 50, 0)),
1219
+ subject: "Late on the third",
1220
+ viewLink: "https://oneuptime.example.com/dashboard/p1/r/1",
1221
+ }),
1222
+ makeItem({
1223
+ createdAt: new Date(Date.UTC(2026, 8, 4, 0, 10, 0)),
1224
+ subject: "Early on the fourth",
1225
+ viewLink: "https://oneuptime.example.com/dashboard/p1/r/2",
1226
+ }),
1227
+ ]);
1228
+
1229
+ expect(varString(email, "summaryWindow")).toBe(
1230
+ "Sep 3, 23:50 UTC to Sep 4, 00:10 UTC",
1231
+ );
1232
+
1233
+ /*
1234
+ * BOTH rows, not only the one on the later day: a table where some times
1235
+ * carry a date and others do not is read as though they are all on the
1236
+ * same day, which is the misreading the date exists to prevent.
1237
+ */
1238
+ expect(rowField(varRows(email)[0]!, "metaLabel")).toBe("Sep 4, 00:10 UTC");
1239
+ expect(rowField(varRows(email)[1]!, "metaLabel")).toBe("Sep 3, 23:50 UTC");
1240
+ });
1241
+
1242
+ test("a rollup inside one UTC day prints no date at all", () => {
1243
+ const email: RollupEmail = build([
1244
+ makeItem({
1245
+ createdAt: new Date(Date.UTC(2026, 8, 3, 0, 1, 0)),
1246
+ subject: "Just after midnight",
1247
+ viewLink: "https://oneuptime.example.com/dashboard/p1/r/1",
1248
+ }),
1249
+ makeItem({
1250
+ createdAt: new Date(Date.UTC(2026, 8, 3, 23, 59, 0)),
1251
+ subject: "Just before the next one",
1252
+ viewLink: "https://oneuptime.example.com/dashboard/p1/r/2",
1253
+ }),
1254
+ ]);
1255
+
1256
+ expect(varString(email, "summaryWindow")).toBe("00:01 UTC to 23:59 UTC");
1257
+ expect(rowField(varRows(email)[0]!, "metaLabel")).toBe("23:59 UTC");
1258
+ });
1259
+
1260
+ test("the window covers items the row cap hid, because the card counts them too", () => {
1261
+ const items: Array<UserNotificationEmailRollupItem> = [];
1262
+
1263
+ for (let index: number = 0; index < MAX_ROWS_IN_ROLLUP + 10; index++) {
1264
+ items.push(
1265
+ makeItem({
1266
+ createdAt: at(index * 60),
1267
+ subject: `Event ${index}`,
1268
+ viewLink: `https://oneuptime.example.com/dashboard/p1/r/${index}`,
1269
+ }),
1270
+ );
1271
+ }
1272
+
1273
+ /* The oldest ten rows are not rendered; the window still starts at 12:00. */
1274
+ expect(varString(build(items), "summaryWindow")).toBe(
1275
+ "12:00 UTC to 13:49 UTC",
1276
+ );
1277
+ });
1278
+
1279
+ test("an item with no createdAt at all leaves the window empty rather than printing 1970", () => {
1280
+ const item: UserNotificationEmailRollupItem = makeItem({
1281
+ createdAt: at(0),
1282
+ subject: "No timestamp",
1283
+ });
1284
+
1285
+ delete (item as unknown as { createdAt?: Date }).createdAt;
1286
+
1287
+ const email: RollupEmail = build([item]);
1288
+
1289
+ expect(varString(email, "summaryWindow")).toBe("");
1290
+ expect(rowField(varRows(email)[0]!, "metaLabel")).not.toContain("1970");
1291
+ });
1292
+ });
1293
+
1294
+ describe("buildRollupEmail subject category summary", () => {
1295
+ type SpreadFunction = (
1296
+ counts: Array<[RollupCategory, number]>,
1297
+ ) => Array<UserNotificationEmailRollupItem>;
1298
+
1299
+ const spread: SpreadFunction = (
1300
+ counts: Array<[RollupCategory, number]>,
1301
+ ): Array<UserNotificationEmailRollupItem> => {
1302
+ const items: Array<UserNotificationEmailRollupItem> = [];
1303
+
1304
+ for (const [category, count] of counts) {
1305
+ for (let index: number = 0; index < count; index++) {
1306
+ items.push(
1307
+ makeItem({
1308
+ createdAt: at(items.length * 60),
1309
+ subject: `${category} ${index}`,
1310
+ viewLink: `https://oneuptime.example.com/dashboard/p1/r/${category}/${index}`,
1311
+ rollupCategory: category,
1312
+ }),
1313
+ );
1314
+ }
1315
+ }
1316
+
1317
+ return items;
1318
+ };
1319
+
1320
+ test("the subject names what kind of storm this is, biggest category first", () => {
1321
+ const subject: string = build(
1322
+ spread([
1323
+ [RollupCategory.Monitors, 2],
1324
+ [RollupCategory.Incidents, 5],
1325
+ ]),
1326
+ ).subject;
1327
+
1328
+ expect(subject).toBe("[Acme] 7 notifications: 5 Incidents, 2 Monitors");
1329
+ });
1330
+
1331
+ test("at most ROLLUP_SUBJECT_MAX_CATEGORIES are named, and the rest are counted", () => {
1332
+ const subject: string = build(
1333
+ spread([
1334
+ [RollupCategory.Incidents, 5],
1335
+ [RollupCategory.Monitors, 4],
1336
+ [RollupCategory.Alerts, 3],
1337
+ [RollupCategory.Probes, 2],
1338
+ [RollupCategory.StatusPages, 1],
1339
+ ]),
1340
+ ).subject;
1341
+
1342
+ expect(subject).toBe(
1343
+ "[Acme] 15 notifications: 5 Incidents, 4 Monitors, 3 Alerts +2 more",
1344
+ );
1345
+ expect(subject.split(", ")).toHaveLength(ROLLUP_SUBJECT_MAX_CATEGORIES);
1346
+ });
1347
+
1348
+ test("exactly ROLLUP_SUBJECT_MAX_CATEGORIES categories claims nothing is left over", () => {
1349
+ const subject: string = build(
1350
+ spread([
1351
+ [RollupCategory.Incidents, 3],
1352
+ [RollupCategory.Monitors, 2],
1353
+ [RollupCategory.Alerts, 1],
1354
+ ]),
1355
+ ).subject;
1356
+
1357
+ expect(subject).toBe(
1358
+ "[Acme] 6 notifications: 3 Incidents, 2 Monitors, 1 Alerts",
1359
+ );
1360
+ expect(subject).not.toContain("+");
1361
+ });
1362
+
1363
+ test("the subject's counts are the summary card's counts", () => {
1364
+ const items: Array<UserNotificationEmailRollupItem> = spread([
1365
+ [RollupCategory.Incidents, 5],
1366
+ [RollupCategory.Monitors, 2],
1367
+ ]);
1368
+
1369
+ const email: RollupEmail = build(items);
1370
+
1371
+ expect(email.subject).toContain("5 Incidents, 2 Monitors");
1372
+ expect(varString(email, "categoryCounts")).toBe("5 Incidents · 2 Monitors");
1373
+ });
1374
+
1375
+ test("a one-notification rollup still leads with the title, not with a category", () => {
1376
+ expect(
1377
+ build([makeItem({ createdAt: at(0), subject: "Checkout is down" })])
1378
+ .subject,
1379
+ ).toBe("[Acme] 1 notification: Checkout is down");
1380
+ });
1381
+ });
1382
+
1383
+ describe("buildRollupEmail raw and pre-escaped vars stay on their own side", () => {
1384
+ test("every RAW var is free of the entities a double stache would escape twice", () => {
1385
+ const email: RollupEmail = build(
1386
+ [
1387
+ makeItem({ createdAt: at(0), subject: "a" }),
1388
+ makeItem({ createdAt: at(60), subject: "b" }),
1389
+ ],
1390
+ 'A&B <"Corp">',
1391
+ );
1392
+
1393
+ for (const name of RAW_VAR_NAMES) {
1394
+ const value: string = varString(email, name);
1395
+
1396
+ expect(value).not.toContain("&amp;");
1397
+ expect(value).not.toContain("&lt;");
1398
+ expect(value).not.toContain("&quot;");
1399
+ expect(value).not.toContain("&#39;");
1400
+ }
1401
+ });
1402
+
1403
+ test("the raw and pre-escaped lists together cover every string var the builder sets", () => {
1404
+ const email: RollupEmail = build([
1405
+ makeItem({ createdAt: at(0), subject: "a" }),
1406
+ ]);
1407
+
1408
+ const stringVars: Array<string> = Object.keys(email.vars).filter(
1409
+ (name: string): boolean => {
1410
+ return typeof email.vars[name] === "string";
1411
+ },
1412
+ );
1413
+
1414
+ const classified: Array<string> = [
1415
+ ...RAW_VAR_NAMES,
1416
+ ...HTML_VAR_NAMES,
1417
+ /* Links, which are neither: they go in an href and are never prose. */
1418
+ "projectHomeLink",
1419
+ "preferencesLink",
1420
+ /* A flag the template compares against a literal. */
1421
+ "hasMore",
1422
+ ];
1423
+
1424
+ for (const name of stringVars) {
1425
+ expect(classified).toContain(name);
1426
+ }
1427
+ });
1428
+ });