@oneuptime/common 12.0.33 → 12.0.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (652) hide show
  1. package/Models/AnalyticsModels/RumSession.ts +117 -1
  2. package/Models/AnalyticsModels/RumSessionChunk.ts +13 -0
  3. package/Models/DatabaseModels/AlertCustomField.ts +77 -3
  4. package/Models/DatabaseModels/ApiKeyPermission.ts +3 -27
  5. package/Models/DatabaseModels/IncidentCustomField.ts +77 -3
  6. package/Models/DatabaseModels/InventoryItemCustomField.ts +77 -3
  7. package/Models/DatabaseModels/MonitorCustomField.ts +77 -3
  8. package/Models/DatabaseModels/OnCallDutyPolicyCustomField.ts +77 -3
  9. package/Models/DatabaseModels/RumApplication.ts +6 -6
  10. package/Models/DatabaseModels/ScheduledMaintenanceCustomField.ts +77 -3
  11. package/Models/DatabaseModels/StatusPageCustomField.ts +77 -3
  12. package/Models/DatabaseModels/TeamCustomField.ts +77 -3
  13. package/Models/DatabaseModels/TeamMember.ts +0 -9
  14. package/Models/DatabaseModels/TeamMemberCustomField.ts +77 -3
  15. package/Models/DatabaseModels/TeamPermission.ts +3 -24
  16. package/Models/DatabaseModels/TelemetryIngestionKey.ts +260 -0
  17. package/Models/DatabaseModels/UserTelegram.ts +0 -4
  18. package/Scripts/benchmark-fanin-capacity.js +181 -0
  19. package/Server/API/TelemetryAPI.ts +1284 -164
  20. package/Server/API/UserNotificationSettingAPI.ts +55 -0
  21. package/Server/API/UserTelegramAPI.ts +48 -4
  22. package/Server/EnvironmentConfig.ts +35 -2
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.ts +91 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.ts +67 -0
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.ts +139 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.ts +121 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  28. package/Server/Infrastructure/QueueWorker.ts +20 -14
  29. package/Server/Infrastructure/Semaphore.ts +2 -0
  30. package/Server/Middleware/TelemetryIngest.ts +453 -7
  31. package/Server/Services/AccessTokenService.ts +1 -0
  32. package/Server/Services/AlertCustomFieldService.ts +98 -0
  33. package/Server/Services/AlertService.ts +37 -0
  34. package/Server/Services/ApiKeyPermissionService.ts +461 -29
  35. package/Server/Services/CustomFieldMappingService.ts +879 -0
  36. package/Server/Services/GlobalConfigService.ts +194 -0
  37. package/Server/Services/IncidentCustomFieldService.ts +98 -0
  38. package/Server/Services/IncidentService.ts +35 -0
  39. package/Server/Services/MetricService.ts +194 -0
  40. package/Server/Services/MonitorService.ts +32 -0
  41. package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +78 -25
  42. package/Server/Services/ProjectService.ts +22 -0
  43. package/Server/Services/RoutineEmailSettingsService.ts +73 -0
  44. package/Server/Services/RumSessionReplayViewService.ts +104 -24
  45. package/Server/Services/ScheduledMaintenanceCustomFieldService.ts +98 -0
  46. package/Server/Services/ScheduledMaintenanceService.ts +32 -0
  47. package/Server/Services/TeamMemberService.ts +78 -0
  48. package/Server/Services/TeamPermissionService.ts +235 -3
  49. package/Server/Services/TelemetryIngestionKeyService.ts +722 -19
  50. package/Server/Services/UserNotificationSettingService.ts +34 -6
  51. package/Server/Services/UserTelegramService.ts +326 -5
  52. package/Server/Types/Database/QueryHelper.ts +2 -0
  53. package/Server/Utils/APIKey/AccessPermission.ts +5 -2
  54. package/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.ts +54 -0
  55. package/Server/Utils/CustomField/CustomFieldMappingRegistry.ts +415 -0
  56. package/Server/Utils/CustomField/CustomFieldMappingValidator.ts +335 -0
  57. package/Server/Utils/DataSource/EgressGuard.ts +177 -8
  58. package/Server/Utils/EmailRollup/EmailRollupConstants.ts +38 -5
  59. package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +57 -4
  60. package/Server/Utils/FrontendEnvironment.ts +40 -0
  61. package/Server/Utils/LogRedaction.ts +20 -0
  62. package/Server/Utils/Logger.ts +11 -0
  63. package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +338 -77
  64. package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +30 -4
  65. package/Server/Utils/Monitor/MonitorAlert.ts +29 -6
  66. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +110 -15
  67. package/Server/Utils/Monitor/MonitorIncident.ts +22 -6
  68. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +29 -0
  69. package/Server/Utils/Monitor/SeriesContextEnricher.ts +304 -0
  70. package/Server/Utils/SSRFProtection.ts +217 -10
  71. package/Server/Utils/SessionReplay/SessionReplayGateCache.ts +239 -138
  72. package/Server/Utils/SessionReplay/SessionReplayHealthCounters.ts +305 -0
  73. package/Server/Utils/SessionReplay/SessionReplayReadService.ts +1430 -289
  74. package/Server/Utils/StartServer.ts +2 -17
  75. package/Server/Utils/TelegramVerificationToken.ts +185 -0
  76. package/Server/Utils/Telemetry/PinServiceName.ts +197 -0
  77. package/Server/Utils/Telemetry/TelemetryFanInWriter.ts +38 -16
  78. package/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.ts +92 -0
  79. package/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.ts +217 -0
  80. package/Server/Utils/VM/VMAPI.ts +1 -0
  81. package/Server/Utils/VM/VMRunner.ts +975 -95
  82. package/Tests/App/AdminDashboard/AdminHeaderSmallScreens.test.tsx +202 -0
  83. package/Tests/App/Dashboard/DashboardHeaderSmallScreens.test.tsx +404 -0
  84. package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +468 -0
  85. package/Tests/App/Dashboard/NotificationEmailPreferences.test.tsx +399 -0
  86. package/Tests/App/StatusPage/StatusPageLastUpdated.test.tsx +263 -0
  87. package/Tests/App/StatusPage/StatusPageOverviewLiveAndSearch.test.tsx +753 -0
  88. package/Tests/App/StatusPage/StatusPageResourceSearchBox.test.tsx +224 -0
  89. package/Tests/Models/AnalyticsModels/RumSessionReplayColumns.test.ts +262 -0
  90. package/Tests/Models/CustomFieldMappingColumns.test.ts +166 -0
  91. package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +20 -6
  92. package/Tests/ResponsiveVisibility.test.ts +115 -0
  93. package/Tests/ResponsiveVisibility.ts +183 -0
  94. package/Tests/Server/API/SessionReplayAPI.test.ts +1940 -216
  95. package/Tests/Server/API/UserNotificationSettingAPI.test.ts +186 -0
  96. package/Tests/Server/API/UserTelegramAPISecurity.test.ts +231 -0
  97. package/Tests/Server/EnvironmentConfigFrontendSecurity.test.ts +234 -0
  98. package/Tests/Server/Infrastructure/Postgres/CustomFieldValueMappingMigration.test.ts +202 -0
  99. package/Tests/Server/Infrastructure/Postgres/InventoryItemArchiveMigration.test.ts +41 -0
  100. package/Tests/Server/Infrastructure/Postgres/SessionReplayRecordEverySessionByDefaultMigration.test.ts +169 -0
  101. package/Tests/Server/Infrastructure/QueueWorkerTimeout.test.ts +210 -0
  102. package/Tests/Server/Infrastructure/TelemetryExporterDeploymentConfig.test.ts +130 -0
  103. package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +4 -1
  104. package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +1163 -0
  105. package/Tests/Server/Middleware/TelemetryIngestTokenLog.test.ts +5 -3
  106. package/Tests/Server/Services/AddTelemetryIngestionKeyTypeMigration.test.ts +555 -0
  107. package/Tests/Server/Services/ApiKeyPermissionSecurity.test.ts +678 -0
  108. package/Tests/Server/Services/ApiKeyPermissionService.test.ts +276 -28
  109. package/Tests/Server/Services/CustomFieldDropdownOptionsColumnWidth.test.ts +431 -0
  110. package/Tests/Server/Services/CustomFieldMappingService.test.ts +850 -0
  111. package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +32 -0
  112. package/Tests/Server/Services/GlobalConfigService.test.ts +414 -1
  113. package/Tests/Server/Services/MetricRawEntityKeyPrune.test.ts +592 -0
  114. package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +226 -1
  115. package/Tests/Server/Services/RoutineEmailSettingsPostgres.test.ts +329 -0
  116. package/Tests/Server/Services/RumSessionReplayViewService.test.ts +267 -0
  117. package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +9 -0
  118. package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +9 -0
  119. package/Tests/Server/Services/TeamPrivilegeEscalation.test.ts +834 -0
  120. package/Tests/Server/Services/TelemetryIngestionKeyPolicyResolution.test.ts +814 -0
  121. package/Tests/Server/Services/TelemetryIngestionKeyValidation.test.ts +998 -0
  122. package/Tests/Server/Services/UserNotificationSettingRollupRouting.test.ts +141 -0
  123. package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +18 -10
  124. package/Tests/Server/Services/UserTelegramVerificationSecurity.test.ts +688 -0
  125. package/Tests/Server/Utils/AI/SRE/Insights/FixRouting.test.ts +497 -0
  126. package/Tests/Server/Utils/AI/Toolbox/Serializer.test.ts +383 -0
  127. package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +7 -3
  128. package/Tests/Server/Utils/AnalyticsDatabase/ClusterConfig.test.ts +315 -0
  129. package/Tests/Server/Utils/CustomField/CustomFieldMappingValidator.test.ts +437 -0
  130. package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +300 -11
  131. package/Tests/Server/Utils/EmailRollup/EmailRollupBurstWindow.test.ts +83 -0
  132. package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerBehaviour.test.ts +1 -1
  133. package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerPreferences.test.ts +362 -0
  134. package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +77 -1
  135. package/Tests/Server/Utils/FrontendEnvironment.test.ts +190 -0
  136. package/Tests/Server/Utils/LogRedaction.test.ts +26 -0
  137. package/Tests/Server/Utils/LoggerCredentialLeak.test.ts +23 -9
  138. package/Tests/Server/Utils/Monitor/Criteria/CompareCriteriaAggregation.test.ts +584 -0
  139. package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestHeaderCriteria.test.ts +236 -0
  140. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +437 -0
  141. package/Tests/Server/Utils/Monitor/MonitorTemplateUtilSeriesContext.test.ts +176 -0
  142. package/Tests/Server/Utils/Monitor/SeriesContextEnricher.test.ts +356 -0
  143. package/Tests/Server/Utils/SSRFProtectionCloudServiceAddresses.test.ts +595 -0
  144. package/Tests/Server/Utils/SessionReplay/SessionReplayGateCachePolicy.test.ts +198 -1
  145. package/Tests/Server/Utils/SessionReplay/SessionReplayHealthCounters.test.ts +453 -0
  146. package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +1378 -0
  147. package/Tests/Server/Utils/SessionReplayOriginAllowListRefactor.test.ts +420 -0
  148. package/Tests/Server/Utils/TelegramVerificationToken.test.ts +253 -0
  149. package/Tests/Server/Utils/Telemetry/PinServiceName.test.ts +666 -0
  150. package/Tests/Server/Utils/Telemetry/TelemetryFanInWriterCapacity.test.ts +458 -0
  151. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +424 -0
  152. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.test.ts +528 -0
  153. package/Tests/Server/Utils/TelemetryExporterEnvironment.test.ts +56 -0
  154. package/Tests/Server/Utils/VM/VMRunnerHostBridgeLatency.test.ts +74 -0
  155. package/Tests/Server/Utils/VM/VMRunnerPrivateNetworkWiring.test.ts +100 -7
  156. package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +1176 -6
  157. package/Tests/Types/CustomField/CustomFieldMappingCatalog.test.ts +220 -0
  158. package/Tests/Types/CustomField/CustomFieldValueMapping.test.ts +348 -0
  159. package/Tests/Types/JSONFunctions.test.ts +260 -0
  160. package/Tests/Types/Monitor/CephAlertTemplates.test.ts +422 -53
  161. package/Tests/Types/Monitor/DockerAlertTemplates.test.ts +495 -15
  162. package/Tests/Types/Monitor/DockerSwarmAlertTemplates.test.ts +191 -45
  163. package/Tests/Types/Monitor/HostAlertTemplates.test.ts +370 -42
  164. package/Tests/Types/Monitor/IotAlertTemplates.test.ts +375 -20
  165. package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +636 -42
  166. package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +189 -0
  167. package/Tests/Types/Monitor/KubernetesTemplateGroupByKeys.test.ts +95 -14
  168. package/Tests/Types/Monitor/PodmanAlertTemplates.test.ts +190 -21
  169. package/Tests/Types/Monitor/ProxmoxAlertTemplates.test.ts +352 -22
  170. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationAlertDebuggability.test.ts +363 -0
  171. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +93 -18
  172. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +259 -0
  173. package/Tests/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.test.ts +476 -0
  174. package/Tests/Types/Monitor/RumAlertTemplates.test.ts +136 -0
  175. package/Tests/Types/Monitor/SeriesContext/SeriesDebugHints.test.ts +661 -0
  176. package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +507 -0
  177. package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +270 -0
  178. package/Tests/Types/Monitor/TemplateGroupByKeys.test.ts +38 -10
  179. package/Tests/Types/Monitor/Utils/RecommendationCriteriaAssertions.ts +102 -0
  180. package/Tests/Types/NotificationSetting/RoutineEmailEvents.test.ts +47 -0
  181. package/Tests/Types/Rum/SessionReplayApiContracts.test.ts +608 -0
  182. package/Tests/Types/Rum/SessionReplayCustomEvents.test.ts +434 -0
  183. package/Tests/Types/WebsiteRequest.test.ts +285 -3
  184. package/Tests/UI/Components/Charts/ChartBucketIdentity.test.ts +16 -3
  185. package/Tests/UI/Components/Charts/ChartTrailingBucketGap.test.ts +691 -0
  186. package/Tests/UI/Components/ComponentsModal.test.tsx +12 -4
  187. package/Tests/UI/Components/ComponentsModalUsability.test.tsx +518 -0
  188. package/Tests/UI/Components/CustomFields/CustomFieldsDetailMapping.test.tsx +324 -0
  189. package/Tests/UI/Components/CustomFields/MapFromCustomFieldInput.test.tsx +176 -0
  190. package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +484 -0
  191. package/Tests/UI/Components/HeaderRightRail.test.tsx +157 -0
  192. package/Tests/UI/Components/IconDropdownItem.test.tsx +102 -0
  193. package/Tests/UI/Components/JSONTablePrototypePollution.test.tsx +117 -0
  194. package/Tests/UI/Components/KeyboardShortcutsModal.test.tsx +214 -0
  195. package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +561 -0
  196. package/Tests/UI/Components/MonitorGraphs/UptimeBarDayModal.test.tsx +302 -0
  197. package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +28 -12
  198. package/Tests/UI/Components/ShortcutDialogGuard.test.tsx +74 -0
  199. package/Tests/UI/Components/StatusPage/ResourceGroupSectionAutoExpand.test.tsx +248 -0
  200. package/Tests/UI/Components/TableCellWrapping.test.tsx +625 -0
  201. package/Tests/UI/Components/TableLoadingStates.test.tsx +205 -0
  202. package/Tests/UI/Components/Workflow/NodePlacement.test.ts +148 -0
  203. package/Tests/UI/Components/Workflow/Workflow.test.tsx +981 -0
  204. package/Tests/UI/ConfigBrowserTelemetry.test.ts +70 -0
  205. package/Tests/UI/Rum/ChunkLoader.test.ts +1036 -2
  206. package/Tests/UI/Rum/FidelityNotices.test.ts +187 -0
  207. package/Tests/UI/Rum/InactivityMap.test.ts +341 -0
  208. package/Tests/UI/Rum/PrivacySummaryCard.test.tsx +259 -0
  209. package/Tests/UI/Rum/RecordingHealthCard.test.tsx +855 -0
  210. package/Tests/UI/Rum/RecordingHealthStrip.test.tsx +594 -0
  211. package/Tests/UI/Rum/ReplayCard.test.tsx +451 -0
  212. package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +536 -0
  213. package/Tests/UI/Rum/ReplayEngine.test.ts +2503 -0
  214. package/Tests/UI/Rum/ReplayEngineTypes.test.ts +171 -0
  215. package/Tests/UI/Rum/ReplayHeader.test.tsx +711 -0
  216. package/Tests/UI/Rum/ReplayLink.test.tsx +119 -0
  217. package/Tests/UI/Rum/ReplayPinControl.test.tsx +408 -0
  218. package/Tests/UI/Rum/ReplayPlaybackIntent.test.ts +152 -0
  219. package/Tests/UI/Rum/ReplayRail.test.tsx +1296 -0
  220. package/Tests/UI/Rum/ReplayRailDetail.test.tsx +900 -0
  221. package/Tests/UI/Rum/ReplayScrubber.test.tsx +763 -147
  222. package/Tests/UI/Rum/ReplaySignalTypes.test.ts +189 -0
  223. package/Tests/UI/Rum/ReplaySignals.test.ts +1579 -0
  224. package/Tests/UI/Rum/ReplayStage.test.tsx +396 -473
  225. package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +918 -0
  226. package/Tests/UI/Rum/ReplayTimeline.test.tsx +696 -0
  227. package/Tests/UI/Rum/SessionReplayEmptyState.test.tsx +499 -0
  228. package/Tests/UI/Rum/SessionReplaySearchBar.test.tsx +346 -0
  229. package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +545 -0
  230. package/Tests/UI/Rum/SessionReplayTable.test.tsx +991 -0
  231. package/Tests/UI/Rum/TargetedCapturePanel.test.tsx +254 -0
  232. package/Tests/UI/Telemetry/BrowserExporterIsolation.test.ts +71 -0
  233. package/Tests/UI/Utils/GlobalKeyboardShortcut.test.ts +344 -0
  234. package/Tests/Utils/API.test.ts +308 -0
  235. package/Tests/Utils/HTTPResponseBodyReader.test.ts +323 -0
  236. package/Tests/Utils/NetworkDiscovery/DiscoveryScanStatus.test.ts +117 -0
  237. package/Tests/Utils/Rum/ChunkMath.test.ts +83 -0
  238. package/Tests/Utils/Rum/SessionReplayHealthDiagnosis.test.ts +993 -0
  239. package/Tests/Utils/Rum/SessionReplayStringMap.test.ts +245 -0
  240. package/Tests/Utils/StatusPage/ResourceSearch.test.ts +631 -0
  241. package/Tests/Utils/Telemetry/OriginAllowList.test.ts +633 -0
  242. package/Tests/Utils/Uptime/DayUptimeGraphUtil.test.ts +461 -0
  243. package/Tests/Utils/ValueFormatter.test.ts +148 -0
  244. package/Types/CustomField/CustomFieldMappingCatalog.ts +161 -0
  245. package/Types/CustomField/CustomFieldMappingSourceResource.ts +19 -0
  246. package/Types/CustomField/CustomFieldValueMapping.ts +288 -0
  247. package/Types/Icon/IconProp.ts +1 -0
  248. package/Types/JSONFunctions.ts +189 -43
  249. package/Types/Monitor/CephAlertTemplates.ts +157 -195
  250. package/Types/Monitor/DockerAlertTemplates.ts +338 -128
  251. package/Types/Monitor/DockerSwarmAlertTemplates.ts +95 -112
  252. package/Types/Monitor/HostAlertTemplates.ts +302 -130
  253. package/Types/Monitor/IotAlertTemplates.ts +112 -104
  254. package/Types/Monitor/KubernetesAlertTemplates.ts +415 -224
  255. package/Types/Monitor/KubernetesMetricCatalog.ts +23 -19
  256. package/Types/Monitor/PodmanAlertTemplates.ts +116 -163
  257. package/Types/Monitor/ProxmoxAlertTemplates.ts +217 -99
  258. package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +98 -6
  259. package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +44 -7
  260. package/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.ts +383 -0
  261. package/Types/Monitor/RumAlertTemplates.ts +46 -7
  262. package/Types/Monitor/SeriesContext/SeriesDebugHints.ts +596 -0
  263. package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +554 -0
  264. package/Types/Monitor/ServiceAlertTemplates.ts +98 -11
  265. package/Types/Monitor/UptimeHistoryLabels.ts +56 -0
  266. package/Types/NotificationSetting/RoutineEmailEvents.ts +30 -0
  267. package/Types/Rum/SessionReplay.ts +209 -0
  268. package/Types/Rum/SessionReplayApi.ts +722 -0
  269. package/Types/Rum/SessionReplayCaptureTrigger.ts +21 -12
  270. package/Types/Rum/SessionReplayConsentMode.ts +11 -7
  271. package/Types/Rum/SessionReplayCustomEvents.ts +549 -0
  272. package/Types/Rum/SessionReplayHealth.ts +238 -0
  273. package/Types/Telemetry/TelemetryIngestSurface.ts +95 -0
  274. package/Types/Telemetry/TelemetryIngestionKeyPolicy.ts +75 -0
  275. package/Types/Telemetry/TelemetryIngestionKeyType.ts +29 -0
  276. package/Types/WebsiteRequest.ts +85 -3
  277. package/UI/Components/Charts/Area/AreaChart.tsx +13 -2
  278. package/UI/Components/Charts/Bar/BarChart.tsx +6 -2
  279. package/UI/Components/Charts/Line/LineChart.tsx +13 -2
  280. package/UI/Components/Charts/Types/XAxis/XAxis.ts +29 -0
  281. package/UI/Components/Charts/Utils/DataPoint.ts +22 -3
  282. package/UI/Components/Charts/Utils/TimeAnnotation.ts +76 -9
  283. package/UI/Components/Charts/Utils/XAxis.ts +217 -0
  284. package/UI/Components/CustomFields/CustomFieldsDetail.tsx +143 -25
  285. package/UI/Components/CustomFields/MapFromCustomFieldInput.tsx +216 -0
  286. package/UI/Components/Graphs/DayUptimeGraph.tsx +173 -8
  287. package/UI/Components/Graphs/UptimeBarTooltip.tsx +22 -278
  288. package/UI/Components/Graphs/UptimeDaySummary.tsx +327 -0
  289. package/UI/Components/Header/Header.tsx +25 -9
  290. package/UI/Components/Header/IconDropdown/IconDropdownItem.tsx +10 -1
  291. package/UI/Components/Header/IconDropdown/IconDropdownMenu.tsx +6 -1
  292. package/UI/Components/Header/ProjectPicker/ProjectPicker.tsx +6 -1
  293. package/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.tsx +6 -1
  294. package/UI/Components/Icon/Icon.tsx +11 -0
  295. package/UI/Components/JSONTable/JSONTable.tsx +2 -2
  296. package/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.tsx +125 -0
  297. package/UI/Components/KeyboardShortcut/Screenshots/README.md +19 -0
  298. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-command-palette.png +0 -0
  299. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog-dark.png +0 -0
  300. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog.png +0 -0
  301. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-help-menu.png +0 -0
  302. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-narrow.png +0 -0
  303. package/UI/Components/ModelTable/Column.ts +15 -0
  304. package/UI/Components/Monitor/SeriesDebugCommandsViewer.tsx +64 -0
  305. package/UI/Components/Monitor/SeriesLabelsViewer.tsx +93 -0
  306. package/UI/Components/MonitorGraphs/Uptime.tsx +14 -2
  307. package/UI/Components/MonitorGraphs/UptimeBarDayModal.tsx +63 -10
  308. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +44 -0
  309. package/UI/Components/StatusPage/ResourceGroupSection.tsx +40 -0
  310. package/UI/Components/Table/CellClassName.ts +81 -0
  311. package/UI/Components/Table/TableRow.tsx +20 -14
  312. package/UI/Components/Table/TableSkeletonRows.tsx +9 -9
  313. package/UI/Components/Table/Types/Column.ts +36 -0
  314. package/UI/Components/Tooltip/Tooltip.tsx +11 -1
  315. package/UI/Components/Workflow/ComponentsModal.tsx +60 -39
  316. package/UI/Components/Workflow/NodePlacement.ts +57 -0
  317. package/UI/Components/Workflow/Workflow.tsx +47 -18
  318. package/UI/Config.ts +15 -33
  319. package/UI/Utils/GlobalKeyboardShortcut.ts +208 -0
  320. package/UI/Utils/Telemetry/BrowserTelemetryConfig.ts +28 -0
  321. package/UI/Utils/Telemetry/Telemetry.ts +10 -8
  322. package/Utils/API.ts +129 -3
  323. package/Utils/HTTPResponseBodyReader.ts +221 -0
  324. package/Utils/NetworkDiscovery/DiscoveryScanStatus.ts +77 -0
  325. package/Utils/Rum/ChunkMath.ts +106 -0
  326. package/Utils/Rum/SessionReplayHealth.ts +732 -0
  327. package/Utils/Rum/SessionReplayStringMap.ts +226 -0
  328. package/Utils/Schema/ModelSchema.ts +1 -0
  329. package/Utils/StatusPage/ResourceSearch.ts +290 -0
  330. package/Utils/Telemetry/OriginAllowList.ts +355 -0
  331. package/Utils/Uptime/DayUptimeGraphUtil.ts +205 -0
  332. package/Utils/ValueFormatter.ts +35 -1
  333. package/build/dist/Models/AnalyticsModels/RumSession.js +102 -19
  334. package/build/dist/Models/AnalyticsModels/RumSession.js.map +1 -1
  335. package/build/dist/Models/AnalyticsModels/RumSessionChunk.js +11 -9
  336. package/build/dist/Models/AnalyticsModels/RumSessionChunk.js.map +1 -1
  337. package/build/dist/Models/DatabaseModels/AlertCustomField.js +79 -3
  338. package/build/dist/Models/DatabaseModels/AlertCustomField.js.map +1 -1
  339. package/build/dist/Models/DatabaseModels/ApiKeyPermission.js +3 -27
  340. package/build/dist/Models/DatabaseModels/ApiKeyPermission.js.map +1 -1
  341. package/build/dist/Models/DatabaseModels/IncidentCustomField.js +79 -3
  342. package/build/dist/Models/DatabaseModels/IncidentCustomField.js.map +1 -1
  343. package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js +79 -3
  344. package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js.map +1 -1
  345. package/build/dist/Models/DatabaseModels/MonitorCustomField.js +79 -3
  346. package/build/dist/Models/DatabaseModels/MonitorCustomField.js.map +1 -1
  347. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js +79 -3
  348. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js.map +1 -1
  349. package/build/dist/Models/DatabaseModels/RumApplication.js +6 -6
  350. package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
  351. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js +79 -3
  352. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js.map +1 -1
  353. package/build/dist/Models/DatabaseModels/StatusPageCustomField.js +79 -3
  354. package/build/dist/Models/DatabaseModels/StatusPageCustomField.js.map +1 -1
  355. package/build/dist/Models/DatabaseModels/TeamCustomField.js +79 -3
  356. package/build/dist/Models/DatabaseModels/TeamCustomField.js.map +1 -1
  357. package/build/dist/Models/DatabaseModels/TeamMember.js +0 -9
  358. package/build/dist/Models/DatabaseModels/TeamMember.js.map +1 -1
  359. package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js +79 -3
  360. package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js.map +1 -1
  361. package/build/dist/Models/DatabaseModels/TeamPermission.js +3 -24
  362. package/build/dist/Models/DatabaseModels/TeamPermission.js.map +1 -1
  363. package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js +267 -0
  364. package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js.map +1 -1
  365. package/build/dist/Models/DatabaseModels/UserTelegram.js +0 -4
  366. package/build/dist/Models/DatabaseModels/UserTelegram.js.map +1 -1
  367. package/build/dist/Server/API/TelemetryAPI.js +769 -109
  368. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  369. package/build/dist/Server/API/UserNotificationSettingAPI.js +35 -0
  370. package/build/dist/Server/API/UserNotificationSettingAPI.js.map +1 -0
  371. package/build/dist/Server/API/UserTelegramAPI.js +28 -6
  372. package/build/dist/Server/API/UserTelegramAPI.js.map +1 -1
  373. package/build/dist/Server/EnvironmentConfig.js +29 -2
  374. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  375. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js +60 -0
  376. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js.map +1 -0
  377. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js +53 -0
  378. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js.map +1 -0
  379. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js +82 -0
  380. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js.map +1 -0
  381. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js +46 -0
  382. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js.map +1 -0
  383. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  384. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  385. package/build/dist/Server/Infrastructure/QueueWorker.js +19 -7
  386. package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
  387. package/build/dist/Server/Infrastructure/Semaphore.js +1 -0
  388. package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
  389. package/build/dist/Server/Middleware/TelemetryIngest.js +315 -8
  390. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  391. package/build/dist/Server/Services/AccessTokenService.js +1 -0
  392. package/build/dist/Server/Services/AccessTokenService.js.map +1 -1
  393. package/build/dist/Server/Services/AlertCustomFieldService.js +93 -0
  394. package/build/dist/Server/Services/AlertCustomFieldService.js.map +1 -1
  395. package/build/dist/Server/Services/AlertService.js +34 -0
  396. package/build/dist/Server/Services/AlertService.js.map +1 -1
  397. package/build/dist/Server/Services/ApiKeyPermissionService.js +331 -28
  398. package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
  399. package/build/dist/Server/Services/CustomFieldMappingService.js +614 -0
  400. package/build/dist/Server/Services/CustomFieldMappingService.js.map +1 -0
  401. package/build/dist/Server/Services/GlobalConfigService.js +133 -0
  402. package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
  403. package/build/dist/Server/Services/IncidentCustomFieldService.js +93 -0
  404. package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
  405. package/build/dist/Server/Services/IncidentService.js +32 -0
  406. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  407. package/build/dist/Server/Services/MetricService.js +163 -0
  408. package/build/dist/Server/Services/MetricService.js.map +1 -1
  409. package/build/dist/Server/Services/MonitorService.js +29 -0
  410. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  411. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +79 -27
  412. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
  413. package/build/dist/Server/Services/ProjectService.js +22 -0
  414. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  415. package/build/dist/Server/Services/RoutineEmailSettingsService.js +69 -0
  416. package/build/dist/Server/Services/RoutineEmailSettingsService.js.map +1 -0
  417. package/build/dist/Server/Services/RumSessionReplayViewService.js +86 -24
  418. package/build/dist/Server/Services/RumSessionReplayViewService.js.map +1 -1
  419. package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js +93 -0
  420. package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js.map +1 -1
  421. package/build/dist/Server/Services/ScheduledMaintenanceService.js +29 -0
  422. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  423. package/build/dist/Server/Services/TeamMemberService.js +62 -2
  424. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  425. package/build/dist/Server/Services/TeamPermissionService.js +166 -3
  426. package/build/dist/Server/Services/TeamPermissionService.js.map +1 -1
  427. package/build/dist/Server/Services/TelemetryIngestionKeyService.js +562 -18
  428. package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
  429. package/build/dist/Server/Services/UserNotificationSettingService.js +26 -6
  430. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  431. package/build/dist/Server/Services/UserTelegramService.js +257 -4
  432. package/build/dist/Server/Services/UserTelegramService.js.map +1 -1
  433. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  434. package/build/dist/Server/Utils/APIKey/AccessPermission.js +2 -2
  435. package/build/dist/Server/Utils/APIKey/AccessPermission.js.map +1 -1
  436. package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js +27 -0
  437. package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js.map +1 -0
  438. package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js +226 -0
  439. package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js.map +1 -0
  440. package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js +189 -0
  441. package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js.map +1 -0
  442. package/build/dist/Server/Utils/DataSource/EgressGuard.js +121 -7
  443. package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
  444. package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js +38 -5
  445. package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js.map +1 -1
  446. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +44 -2
  447. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -1
  448. package/build/dist/Server/Utils/FrontendEnvironment.js +33 -0
  449. package/build/dist/Server/Utils/FrontendEnvironment.js.map +1 -0
  450. package/build/dist/Server/Utils/LogRedaction.js +20 -0
  451. package/build/dist/Server/Utils/LogRedaction.js.map +1 -1
  452. package/build/dist/Server/Utils/Logger.js +10 -0
  453. package/build/dist/Server/Utils/Logger.js.map +1 -1
  454. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +287 -68
  455. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
  456. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +20 -4
  457. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
  458. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +29 -6
  459. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  460. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +88 -13
  461. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  462. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +22 -6
  463. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  464. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +22 -0
  465. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  466. package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js +237 -0
  467. package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js.map +1 -0
  468. package/build/dist/Server/Utils/SSRFProtection.js +136 -9
  469. package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
  470. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js +174 -89
  471. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js.map +1 -1
  472. package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js +223 -0
  473. package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js.map +1 -0
  474. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +945 -164
  475. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
  476. package/build/dist/Server/Utils/StartServer.js +3 -14
  477. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  478. package/build/dist/Server/Utils/TelegramVerificationToken.js +129 -0
  479. package/build/dist/Server/Utils/TelegramVerificationToken.js.map +1 -0
  480. package/build/dist/Server/Utils/Telemetry/PinServiceName.js +163 -0
  481. package/build/dist/Server/Utils/Telemetry/PinServiceName.js.map +1 -0
  482. package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js +28 -15
  483. package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js.map +1 -1
  484. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js +64 -0
  485. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js.map +1 -0
  486. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js +171 -0
  487. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js.map +1 -0
  488. package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
  489. package/build/dist/Server/Utils/VM/VMRunner.js +780 -69
  490. package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
  491. package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js +60 -0
  492. package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js.map +1 -0
  493. package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js +20 -0
  494. package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js.map +1 -0
  495. package/build/dist/Types/CustomField/CustomFieldValueMapping.js +141 -0
  496. package/build/dist/Types/CustomField/CustomFieldValueMapping.js.map +1 -0
  497. package/build/dist/Types/Icon/IconProp.js +1 -0
  498. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  499. package/build/dist/Types/JSONFunctions.js +118 -37
  500. package/build/dist/Types/JSONFunctions.js.map +1 -1
  501. package/build/dist/Types/Monitor/CephAlertTemplates.js +130 -171
  502. package/build/dist/Types/Monitor/CephAlertTemplates.js.map +1 -1
  503. package/build/dist/Types/Monitor/DockerAlertTemplates.js +286 -121
  504. package/build/dist/Types/Monitor/DockerAlertTemplates.js.map +1 -1
  505. package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js +84 -105
  506. package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js.map +1 -1
  507. package/build/dist/Types/Monitor/HostAlertTemplates.js +250 -122
  508. package/build/dist/Types/Monitor/HostAlertTemplates.js.map +1 -1
  509. package/build/dist/Types/Monitor/IotAlertTemplates.js +81 -81
  510. package/build/dist/Types/Monitor/IotAlertTemplates.js.map +1 -1
  511. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +375 -215
  512. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
  513. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js +19 -19
  514. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js.map +1 -1
  515. package/build/dist/Types/Monitor/PodmanAlertTemplates.js +104 -153
  516. package/build/dist/Types/Monitor/PodmanAlertTemplates.js.map +1 -1
  517. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +156 -91
  518. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
  519. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +67 -6
  520. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -1
  521. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +38 -7
  522. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
  523. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js +261 -0
  524. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js.map +1 -0
  525. package/build/dist/Types/Monitor/RumAlertTemplates.js +46 -7
  526. package/build/dist/Types/Monitor/RumAlertTemplates.js.map +1 -1
  527. package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js +422 -0
  528. package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js.map +1 -0
  529. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +441 -0
  530. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -0
  531. package/build/dist/Types/Monitor/ServiceAlertTemplates.js +79 -15
  532. package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -1
  533. package/build/dist/Types/Monitor/UptimeHistoryLabels.js +17 -0
  534. package/build/dist/Types/Monitor/UptimeHistoryLabels.js.map +1 -0
  535. package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js +29 -0
  536. package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js.map +1 -0
  537. package/build/dist/Types/Rum/SessionReplay.js +117 -0
  538. package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
  539. package/build/dist/Types/Rum/SessionReplayApi.js +181 -0
  540. package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -0
  541. package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js +21 -12
  542. package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js.map +1 -1
  543. package/build/dist/Types/Rum/SessionReplayConsentMode.js +11 -7
  544. package/build/dist/Types/Rum/SessionReplayConsentMode.js.map +1 -1
  545. package/build/dist/Types/Rum/SessionReplayCustomEvents.js +172 -0
  546. package/build/dist/Types/Rum/SessionReplayCustomEvents.js.map +1 -0
  547. package/build/dist/Types/Rum/SessionReplayHealth.js +37 -0
  548. package/build/dist/Types/Rum/SessionReplayHealth.js.map +1 -0
  549. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +85 -0
  550. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -0
  551. package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js +15 -0
  552. package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js.map +1 -0
  553. package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js +30 -0
  554. package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js.map +1 -0
  555. package/build/dist/Types/WebsiteRequest.js +55 -3
  556. package/build/dist/Types/WebsiteRequest.js.map +1 -1
  557. package/build/dist/UI/Components/Charts/Area/AreaChart.js +13 -2
  558. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  559. package/build/dist/UI/Components/Charts/Bar/BarChart.js +6 -2
  560. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  561. package/build/dist/UI/Components/Charts/Line/LineChart.js +13 -2
  562. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  563. package/build/dist/UI/Components/Charts/Types/XAxis/XAxis.js.map +1 -1
  564. package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -3
  565. package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
  566. package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js +40 -9
  567. package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js.map +1 -1
  568. package/build/dist/UI/Components/Charts/Utils/XAxis.js +186 -0
  569. package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
  570. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +80 -6
  571. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
  572. package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js +118 -0
  573. package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js.map +1 -0
  574. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +112 -7
  575. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
  576. package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js +5 -162
  577. package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js.map +1 -1
  578. package/build/dist/UI/Components/Graphs/UptimeDaySummary.js +181 -0
  579. package/build/dist/UI/Components/Graphs/UptimeDaySummary.js.map +1 -0
  580. package/build/dist/UI/Components/Header/Header.js +2 -3
  581. package/build/dist/UI/Components/Header/Header.js.map +1 -1
  582. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js +2 -1
  583. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js.map +1 -1
  584. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js +7 -1
  585. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js.map +1 -1
  586. package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js +7 -1
  587. package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js.map +1 -1
  588. package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js +7 -1
  589. package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js.map +1 -1
  590. package/build/dist/UI/Components/Icon/Icon.js +5 -0
  591. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  592. package/build/dist/UI/Components/JSONTable/JSONTable.js +2 -2
  593. package/build/dist/UI/Components/JSONTable/JSONTable.js.map +1 -1
  594. package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js +35 -0
  595. package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js.map +1 -0
  596. package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js +34 -0
  597. package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js.map +1 -0
  598. package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js +49 -0
  599. package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js.map +1 -0
  600. package/build/dist/UI/Components/MonitorGraphs/Uptime.js +1 -1
  601. package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
  602. package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js +32 -6
  603. package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js.map +1 -1
  604. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +38 -0
  605. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
  606. package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js +22 -1
  607. package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js.map +1 -1
  608. package/build/dist/UI/Components/Table/CellClassName.js +55 -0
  609. package/build/dist/UI/Components/Table/CellClassName.js.map +1 -0
  610. package/build/dist/UI/Components/Table/TableRow.js +16 -13
  611. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  612. package/build/dist/UI/Components/Table/TableSkeletonRows.js +9 -8
  613. package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -1
  614. package/build/dist/UI/Components/Tooltip/Tooltip.js +25 -1
  615. package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
  616. package/build/dist/UI/Components/Workflow/ComponentsModal.js +47 -30
  617. package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
  618. package/build/dist/UI/Components/Workflow/NodePlacement.js +37 -0
  619. package/build/dist/UI/Components/Workflow/NodePlacement.js.map +1 -0
  620. package/build/dist/UI/Components/Workflow/Workflow.js +35 -18
  621. package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
  622. package/build/dist/UI/Config.js +10 -20
  623. package/build/dist/UI/Config.js.map +1 -1
  624. package/build/dist/UI/Utils/GlobalKeyboardShortcut.js +138 -0
  625. package/build/dist/UI/Utils/GlobalKeyboardShortcut.js.map +1 -0
  626. package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js +14 -0
  627. package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js.map +1 -0
  628. package/build/dist/UI/Utils/Telemetry/Telemetry.js +7 -5
  629. package/build/dist/UI/Utils/Telemetry/Telemetry.js.map +1 -1
  630. package/build/dist/Utils/API.js +67 -5
  631. package/build/dist/Utils/API.js.map +1 -1
  632. package/build/dist/Utils/HTTPResponseBodyReader.js +157 -0
  633. package/build/dist/Utils/HTTPResponseBodyReader.js.map +1 -0
  634. package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js +69 -0
  635. package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js.map +1 -0
  636. package/build/dist/Utils/Rum/ChunkMath.js +76 -0
  637. package/build/dist/Utils/Rum/ChunkMath.js.map +1 -1
  638. package/build/dist/Utils/Rum/SessionReplayHealth.js +534 -0
  639. package/build/dist/Utils/Rum/SessionReplayHealth.js.map +1 -0
  640. package/build/dist/Utils/Rum/SessionReplayStringMap.js +165 -0
  641. package/build/dist/Utils/Rum/SessionReplayStringMap.js.map +1 -0
  642. package/build/dist/Utils/Schema/ModelSchema.js +1 -0
  643. package/build/dist/Utils/Schema/ModelSchema.js.map +1 -1
  644. package/build/dist/Utils/StatusPage/ResourceSearch.js +200 -0
  645. package/build/dist/Utils/StatusPage/ResourceSearch.js.map +1 -0
  646. package/build/dist/Utils/Telemetry/OriginAllowList.js +299 -0
  647. package/build/dist/Utils/Telemetry/OriginAllowList.js.map +1 -0
  648. package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js +147 -0
  649. package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js.map +1 -0
  650. package/build/dist/Utils/ValueFormatter.js +32 -1
  651. package/build/dist/Utils/ValueFormatter.js.map +1 -1
  652. package/package.json +1 -1
@@ -0,0 +1,850 @@
1
+ import { afterEach, describe, expect, test } from "@jest/globals";
2
+ import CustomFieldMappingSourceResource from "../../../Types/CustomField/CustomFieldMappingSourceResource";
3
+ import CustomFieldType from "../../../Types/CustomField/CustomFieldType";
4
+ import { JSONObject } from "../../../Types/JSON";
5
+ import ObjectID from "../../../Types/ObjectID";
6
+ import Alert from "../../../Models/DatabaseModels/Alert";
7
+ import AlertCustomField from "../../../Models/DatabaseModels/AlertCustomField";
8
+ import Incident from "../../../Models/DatabaseModels/Incident";
9
+ import IncidentCustomField from "../../../Models/DatabaseModels/IncidentCustomField";
10
+ import Monitor from "../../../Models/DatabaseModels/Monitor";
11
+ import AlertService from "../../../Server/Services/AlertService";
12
+ import AlertCustomFieldService from "../../../Server/Services/AlertCustomFieldService";
13
+ import IncidentService from "../../../Server/Services/IncidentService";
14
+ import IncidentCustomFieldService from "../../../Server/Services/IncidentCustomFieldService";
15
+ import MonitorService from "../../../Server/Services/MonitorService";
16
+ import ScheduledMaintenanceService from "../../../Server/Services/ScheduledMaintenanceService";
17
+ import ScheduledMaintenanceCustomFieldService from "../../../Server/Services/ScheduledMaintenanceCustomFieldService";
18
+ import CustomFieldMappingService from "../../../Server/Services/CustomFieldMappingService";
19
+ import CreateBy from "../../../Server/Types/Database/CreateBy";
20
+ import UpdateBy from "../../../Server/Types/Database/UpdateBy";
21
+
22
+ /*
23
+ * The engine behind "copy this custom field's value from the monitor"
24
+ * (OneUptime/oneuptime#3549).
25
+ *
26
+ * Two properties matter more than any individual behaviour and are asserted
27
+ * from several directions below:
28
+ *
29
+ * 1. It never destroys a value. No source record, no source definition and
30
+ * an empty source value all mean "leave the target alone". The scenario
31
+ * this guards is the natural first action after the feature ships —
32
+ * turning a mapping on for a field a project has been typing in by hand,
33
+ * before any monitor has a value for it.
34
+ *
35
+ * 2. It writes derived data as derived data: hook-free, compare-and-set
36
+ * against the bag it resolved from, and without touching `updatedAt`.
37
+ * Otherwise one monitor edit fires a workflow POST, a realtime emit and
38
+ * an audit insert per alert, and restamps `updatedAt` across years of
39
+ * resolved alerts.
40
+ */
41
+
42
+ const PROJECT_ID: ObjectID = new ObjectID(
43
+ "11111111-1111-4111-8111-111111111111",
44
+ );
45
+ const MONITOR_ID: ObjectID = new ObjectID(
46
+ "22222222-2222-4222-8222-222222222222",
47
+ );
48
+ const OTHER_MONITOR_ID: ObjectID = new ObjectID(
49
+ "33333333-3333-4333-8333-333333333333",
50
+ );
51
+ const ALERT_ID: ObjectID = new ObjectID("44444444-4444-4444-8444-444444444444");
52
+ const INCIDENT_ID: ObjectID = new ObjectID(
53
+ "55555555-5555-4555-8555-555555555555",
54
+ );
55
+
56
+ interface DefinitionFixture {
57
+ name: string;
58
+ customFieldType?: CustomFieldType | undefined;
59
+ mapFromResourceType?: string | undefined;
60
+ mapFromCustomFieldName?: string | undefined;
61
+ }
62
+
63
+ type BuildDefinitionsFunction = (
64
+ fixtures: Array<DefinitionFixture>,
65
+ ) => Array<AlertCustomField>;
66
+
67
+ const buildDefinitions: BuildDefinitionsFunction = (
68
+ fixtures: Array<DefinitionFixture>,
69
+ ): Array<AlertCustomField> => {
70
+ return fixtures.map((fixture: DefinitionFixture): AlertCustomField => {
71
+ /*
72
+ * Assigned through Object.assign because `exactOptionalPropertyTypes`
73
+ * rejects writing an explicit `undefined` into an optional model property,
74
+ * and "this fixture leaves the field unset" is exactly what several cases
75
+ * below are testing.
76
+ */
77
+ return Object.assign(new AlertCustomField(), fixture);
78
+ });
79
+ };
80
+
81
+ type BuildMonitorFunction = (
82
+ id: ObjectID,
83
+ customFields?: JSONObject | undefined,
84
+ ) => Monitor;
85
+
86
+ const buildMonitor: BuildMonitorFunction = (
87
+ id: ObjectID,
88
+ customFields?: JSONObject | undefined,
89
+ ): Monitor => {
90
+ const monitor: Monitor = new Monitor();
91
+ monitor._id = id.toString();
92
+
93
+ /*
94
+ * Only set when the caller has one. A monitor read WITHOUT its customFields
95
+ * must not look like a monitor whose bag is empty — that distinction is what
96
+ * decides whether the resolver can use the payload or has to query.
97
+ */
98
+ if (customFields) {
99
+ monitor.customFields = customFields;
100
+ }
101
+
102
+ return monitor;
103
+ };
104
+
105
+ const VENDOR_MAPPING: Array<DefinitionFixture> = [
106
+ {
107
+ name: "Vendor",
108
+ customFieldType: CustomFieldType.Text,
109
+ mapFromResourceType: CustomFieldMappingSourceResource.Monitor,
110
+ mapFromCustomFieldName: "Vendor",
111
+ },
112
+ ];
113
+
114
+ type StubAlertDefinitionsFunction = (
115
+ fixtures: Array<DefinitionFixture>,
116
+ ) => jest.SpyInstance;
117
+
118
+ const stubAlertDefinitions: StubAlertDefinitionsFunction = (
119
+ fixtures: Array<DefinitionFixture>,
120
+ ): jest.SpyInstance => {
121
+ return jest
122
+ .spyOn(AlertCustomFieldService, "findBy")
123
+ .mockResolvedValue(buildDefinitions(fixtures) as never);
124
+ };
125
+
126
+ type BuildAlertCreateByFunction = (data: Partial<Alert>) => CreateBy<Alert>;
127
+
128
+ const buildAlertCreateBy: BuildAlertCreateByFunction = (
129
+ data: Partial<Alert>,
130
+ ): CreateBy<Alert> => {
131
+ const alert: Alert = new Alert();
132
+ Object.assign(alert, data);
133
+
134
+ return {
135
+ data: alert,
136
+ props: { isRoot: true, tenantId: PROJECT_ID },
137
+ } as CreateBy<Alert>;
138
+ };
139
+
140
+ afterEach(() => {
141
+ jest.restoreAllMocks();
142
+ });
143
+
144
+ describe("CustomFieldMappingService.applyMappingsToCreate", () => {
145
+ test("stamps the monitor's value onto a new alert", async () => {
146
+ stubAlertDefinitions(VENDOR_MAPPING);
147
+ jest
148
+ .spyOn(MonitorService, "findBy")
149
+ .mockResolvedValue([
150
+ buildMonitor(MONITOR_ID, { Vendor: "Acme" }),
151
+ ] as never);
152
+
153
+ const createBy: CreateBy<Alert> = buildAlertCreateBy({
154
+ monitorId: MONITOR_ID,
155
+ });
156
+
157
+ await CustomFieldMappingService.applyMappingsToCreate({
158
+ definitionModelType: AlertCustomField,
159
+ createBy: createBy,
160
+ });
161
+
162
+ expect(createBy.data.customFields).toEqual({ Vendor: "Acme" });
163
+ });
164
+
165
+ /*
166
+ * The hottest creation path in the product is a monitor criterion opening an
167
+ * alert, and it assigns the whole Monitor — already read with its
168
+ * customFields for metric attributes. Taking the bag from there is what
169
+ * keeps the ingest path free of an extra query per alert.
170
+ */
171
+ test("uses a monitor already hydrated on the payload instead of querying", async () => {
172
+ stubAlertDefinitions(VENDOR_MAPPING);
173
+ const findMonitors: jest.SpyInstance = jest
174
+ .spyOn(MonitorService, "findBy")
175
+ .mockResolvedValue([] as never);
176
+
177
+ const createBy: CreateBy<Alert> = buildAlertCreateBy({
178
+ monitor: buildMonitor(MONITOR_ID, { Vendor: "Acme" }),
179
+ });
180
+
181
+ await CustomFieldMappingService.applyMappingsToCreate({
182
+ definitionModelType: AlertCustomField,
183
+ createBy: createBy,
184
+ });
185
+
186
+ expect(createBy.data.customFields).toEqual({ Vendor: "Acme" });
187
+ expect(findMonitors).not.toHaveBeenCalled();
188
+ });
189
+
190
+ /*
191
+ * A monitor supplied as a bare id stub carries no bag. Treating its missing
192
+ * customFields as "empty" instead of "unknown" skips the lookup and silently
193
+ * inherits nothing — which is what an earlier `hasOwnProperty` check did,
194
+ * because every model class initialises its columns in the class body and so
195
+ * a bare `new Monitor()` already owns the property.
196
+ */
197
+ test("looks the monitor up when the payload carries only an id stub", async () => {
198
+ stubAlertDefinitions(VENDOR_MAPPING);
199
+ const findMonitors: jest.SpyInstance = jest
200
+ .spyOn(MonitorService, "findBy")
201
+ .mockResolvedValue([
202
+ buildMonitor(MONITOR_ID, { Vendor: "Acme" }),
203
+ ] as never);
204
+
205
+ const stub: Monitor = new Monitor();
206
+ stub._id = MONITOR_ID.toString();
207
+
208
+ const createBy: CreateBy<Alert> = buildAlertCreateBy({ monitor: stub });
209
+
210
+ await CustomFieldMappingService.applyMappingsToCreate({
211
+ definitionModelType: AlertCustomField,
212
+ createBy: createBy,
213
+ });
214
+
215
+ expect(findMonitors).toHaveBeenCalled();
216
+ expect(createBy.data.customFields).toEqual({ Vendor: "Acme" });
217
+ });
218
+
219
+ /*
220
+ * The other side of that distinction: a monitor read WITH its customFields
221
+ * whose column is NULL in Postgres arrives with the property set to null.
222
+ * That is a real answer — the monitor has no value — and must not trigger a
223
+ * second lookup that would return the same nothing.
224
+ */
225
+ test("treats a monitor read with an empty bag as answered, without querying", async () => {
226
+ stubAlertDefinitions(VENDOR_MAPPING);
227
+ const findMonitors: jest.SpyInstance = jest
228
+ .spyOn(MonitorService, "findBy")
229
+ .mockResolvedValue([] as never);
230
+
231
+ const readButEmpty: Monitor = new Monitor();
232
+ readButEmpty._id = MONITOR_ID.toString();
233
+ readButEmpty.customFields = null as unknown as JSONObject;
234
+
235
+ const createBy: CreateBy<Alert> = buildAlertCreateBy({
236
+ monitor: readButEmpty,
237
+ customFields: { Vendor: "Typed by hand" },
238
+ });
239
+
240
+ await CustomFieldMappingService.applyMappingsToCreate({
241
+ definitionModelType: AlertCustomField,
242
+ createBy: createBy,
243
+ });
244
+
245
+ expect(findMonitors).not.toHaveBeenCalled();
246
+ expect(createBy.data.customFields).toEqual({ Vendor: "Typed by hand" });
247
+ });
248
+
249
+ test("leaves the bag alone when the project has no mappings", async () => {
250
+ stubAlertDefinitions([
251
+ { name: "Vendor", customFieldType: CustomFieldType.Text },
252
+ ]);
253
+ const findMonitors: jest.SpyInstance = jest
254
+ .spyOn(MonitorService, "findBy")
255
+ .mockResolvedValue([] as never);
256
+
257
+ const createBy: CreateBy<Alert> = buildAlertCreateBy({
258
+ monitorId: MONITOR_ID,
259
+ customFields: { Vendor: "Typed by hand" },
260
+ });
261
+
262
+ await CustomFieldMappingService.applyMappingsToCreate({
263
+ definitionModelType: AlertCustomField,
264
+ createBy: createBy,
265
+ });
266
+
267
+ expect(createBy.data.customFields).toEqual({ Vendor: "Typed by hand" });
268
+ expect(findMonitors).not.toHaveBeenCalled();
269
+ });
270
+
271
+ /*
272
+ * SLO burn-rate alerts, security-event alerts and network-site rollup alerts
273
+ * are all created with no monitor at all.
274
+ */
275
+ test("leaves the bag alone when the alert has no monitor", async () => {
276
+ stubAlertDefinitions(VENDOR_MAPPING);
277
+
278
+ const createBy: CreateBy<Alert> = buildAlertCreateBy({
279
+ customFields: { Vendor: "Typed by hand" },
280
+ });
281
+
282
+ await CustomFieldMappingService.applyMappingsToCreate({
283
+ definitionModelType: AlertCustomField,
284
+ createBy: createBy,
285
+ });
286
+
287
+ expect(createBy.data.customFields).toEqual({ Vendor: "Typed by hand" });
288
+ });
289
+
290
+ test("leaves the bag alone when the monitor holds no value for the source field", async () => {
291
+ stubAlertDefinitions(VENDOR_MAPPING);
292
+ jest
293
+ .spyOn(MonitorService, "findBy")
294
+ .mockResolvedValue([buildMonitor(MONITOR_ID, { Other: "x" })] as never);
295
+
296
+ const createBy: CreateBy<Alert> = buildAlertCreateBy({
297
+ monitorId: MONITOR_ID,
298
+ customFields: { Vendor: "Typed by hand" },
299
+ });
300
+
301
+ await CustomFieldMappingService.applyMappingsToCreate({
302
+ definitionModelType: AlertCustomField,
303
+ createBy: createBy,
304
+ });
305
+
306
+ expect(createBy.data.customFields).toEqual({ Vendor: "Typed by hand" });
307
+ });
308
+
309
+ test("does not touch custom fields the mapping does not own", async () => {
310
+ stubAlertDefinitions(VENDOR_MAPPING);
311
+ jest
312
+ .spyOn(MonitorService, "findBy")
313
+ .mockResolvedValue([
314
+ buildMonitor(MONITOR_ID, { Vendor: "Acme" }),
315
+ ] as never);
316
+
317
+ const createBy: CreateBy<Alert> = buildAlertCreateBy({
318
+ monitorId: MONITOR_ID,
319
+ customFields: { Owner: "kate" },
320
+ });
321
+
322
+ await CustomFieldMappingService.applyMappingsToCreate({
323
+ definitionModelType: AlertCustomField,
324
+ createBy: createBy,
325
+ });
326
+
327
+ expect(createBy.data.customFields).toEqual({
328
+ Owner: "kate",
329
+ Vendor: "Acme",
330
+ });
331
+ });
332
+
333
+ test("a mapping pointing at a field the monitor never defined writes nothing", async () => {
334
+ stubAlertDefinitions([
335
+ {
336
+ name: "Vendor",
337
+ customFieldType: CustomFieldType.Text,
338
+ mapFromResourceType: CustomFieldMappingSourceResource.Monitor,
339
+ mapFromCustomFieldName: "Supplier",
340
+ },
341
+ ]);
342
+ jest
343
+ .spyOn(MonitorService, "findBy")
344
+ .mockResolvedValue([
345
+ buildMonitor(MONITOR_ID, { Vendor: "Acme" }),
346
+ ] as never);
347
+
348
+ const createBy: CreateBy<Alert> = buildAlertCreateBy({
349
+ monitorId: MONITOR_ID,
350
+ });
351
+
352
+ await CustomFieldMappingService.applyMappingsToCreate({
353
+ definitionModelType: AlertCustomField,
354
+ createBy: createBy,
355
+ });
356
+
357
+ expect(createBy.data.customFields).toBeUndefined();
358
+ });
359
+
360
+ /*
361
+ * A failure to inherit a custom field must never stop an alert being opened,
362
+ * so the whole path is written not to throw.
363
+ */
364
+ test("swallows a failure reading the definitions", async () => {
365
+ jest
366
+ .spyOn(AlertCustomFieldService, "findBy")
367
+ .mockRejectedValue(new Error("database is down") as never);
368
+
369
+ const createBy: CreateBy<Alert> = buildAlertCreateBy({
370
+ monitorId: MONITOR_ID,
371
+ });
372
+
373
+ await expect(
374
+ CustomFieldMappingService.applyMappingsToCreate({
375
+ definitionModelType: AlertCustomField,
376
+ createBy: createBy,
377
+ }),
378
+ ).resolves.toBeUndefined();
379
+ });
380
+ });
381
+
382
+ describe("CustomFieldMappingService.applyMappingsToCreate for many-source resources", () => {
383
+ type BuildIncidentCreateByFunction = (
384
+ monitors: Array<Monitor>,
385
+ ) => CreateBy<Incident>;
386
+
387
+ const buildIncidentCreateBy: BuildIncidentCreateByFunction = (
388
+ monitors: Array<Monitor>,
389
+ ): CreateBy<Incident> => {
390
+ const incident: Incident = new Incident();
391
+ incident.monitors = monitors;
392
+
393
+ return {
394
+ data: incident,
395
+ props: { isRoot: true, tenantId: PROJECT_ID },
396
+ } as CreateBy<Incident>;
397
+ };
398
+
399
+ const INCIDENT_VENDOR_MAPPING: Array<IncidentCustomField> = [
400
+ Object.assign(new IncidentCustomField(), {
401
+ name: "Vendor",
402
+ customFieldType: CustomFieldType.Text,
403
+ mapFromResourceType: CustomFieldMappingSourceResource.Monitor,
404
+ mapFromCustomFieldName: "Vendor",
405
+ }),
406
+ ];
407
+
408
+ test("uses the value every attached monitor agrees on", async () => {
409
+ jest
410
+ .spyOn(IncidentCustomFieldService, "findBy")
411
+ .mockResolvedValue(INCIDENT_VENDOR_MAPPING as never);
412
+ jest
413
+ .spyOn(MonitorService, "findBy")
414
+ .mockResolvedValue([
415
+ buildMonitor(MONITOR_ID, { Vendor: "Acme" }),
416
+ buildMonitor(OTHER_MONITOR_ID, { Vendor: "Acme" }),
417
+ ] as never);
418
+
419
+ const createBy: CreateBy<Incident> = buildIncidentCreateBy([
420
+ buildMonitor(MONITOR_ID),
421
+ buildMonitor(OTHER_MONITOR_ID),
422
+ ]);
423
+
424
+ await CustomFieldMappingService.applyMappingsToCreate({
425
+ definitionModelType: IncidentCustomField,
426
+ createBy: createBy,
427
+ });
428
+
429
+ expect(createBy.data.customFields).toEqual({ Vendor: "Acme" });
430
+ });
431
+
432
+ /*
433
+ * The monitors relation carries no ORDER BY, so "the first one" is not a
434
+ * stable answer — choosing a winner would make the value flip on its own.
435
+ */
436
+ test("writes nothing when the attached monitors disagree", async () => {
437
+ jest
438
+ .spyOn(IncidentCustomFieldService, "findBy")
439
+ .mockResolvedValue(INCIDENT_VENDOR_MAPPING as never);
440
+ jest
441
+ .spyOn(MonitorService, "findBy")
442
+ .mockResolvedValue([
443
+ buildMonitor(MONITOR_ID, { Vendor: "Acme" }),
444
+ buildMonitor(OTHER_MONITOR_ID, { Vendor: "Globex" }),
445
+ ] as never);
446
+
447
+ const createBy: CreateBy<Incident> = buildIncidentCreateBy([
448
+ buildMonitor(MONITOR_ID),
449
+ buildMonitor(OTHER_MONITOR_ID),
450
+ ]);
451
+
452
+ await CustomFieldMappingService.applyMappingsToCreate({
453
+ definitionModelType: IncidentCustomField,
454
+ createBy: createBy,
455
+ });
456
+
457
+ expect(createBy.data.customFields).toBeUndefined();
458
+ });
459
+
460
+ test("an incident with no monitors inherits nothing", async () => {
461
+ jest
462
+ .spyOn(IncidentCustomFieldService, "findBy")
463
+ .mockResolvedValue(INCIDENT_VENDOR_MAPPING as never);
464
+ const findMonitors: jest.SpyInstance = jest
465
+ .spyOn(MonitorService, "findBy")
466
+ .mockResolvedValue([] as never);
467
+
468
+ const createBy: CreateBy<Incident> = buildIncidentCreateBy([]);
469
+
470
+ await CustomFieldMappingService.applyMappingsToCreate({
471
+ definitionModelType: IncidentCustomField,
472
+ createBy: createBy,
473
+ });
474
+
475
+ expect(createBy.data.customFields).toBeUndefined();
476
+ expect(findMonitors).not.toHaveBeenCalled();
477
+ });
478
+ });
479
+
480
+ describe("CustomFieldMappingService.applyMappingsToUpdate", () => {
481
+ type BuildAlertUpdateByFunction = (data: JSONObject) => UpdateBy<Alert>;
482
+
483
+ const buildAlertUpdateBy: BuildAlertUpdateByFunction = (
484
+ data: JSONObject,
485
+ ): UpdateBy<Alert> => {
486
+ return {
487
+ query: { _id: ALERT_ID.toString() },
488
+ data: data,
489
+ props: { isRoot: true, tenantId: PROJECT_ID },
490
+ limit: 1,
491
+ skip: 0,
492
+ } as unknown as UpdateBy<Alert>;
493
+ };
494
+
495
+ type StubAffectedAlertFunction = (alert: Partial<Alert>) => jest.SpyInstance;
496
+
497
+ const stubAffectedAlert: StubAffectedAlertFunction = (
498
+ alert: Partial<Alert>,
499
+ ): jest.SpyInstance => {
500
+ const model: Alert = new Alert();
501
+ model._id = ALERT_ID.toString();
502
+ model.projectId = PROJECT_ID;
503
+ Object.assign(model, alert);
504
+
505
+ return jest
506
+ .spyOn(AlertService, "findBy")
507
+ .mockResolvedValue([model] as never);
508
+ };
509
+
510
+ /*
511
+ * The Custom Fields modal replaces the WHOLE bag — it has no server-side
512
+ * merge — so saving an unrelated field would otherwise drop the mapped one.
513
+ */
514
+ test("restores a mapped value the caller's payload dropped", async () => {
515
+ stubAlertDefinitions(VENDOR_MAPPING);
516
+ stubAffectedAlert({
517
+ monitorId: MONITOR_ID,
518
+ customFields: { Vendor: "Acme", Owner: "kate" },
519
+ });
520
+ jest
521
+ .spyOn(MonitorService, "findBy")
522
+ .mockResolvedValue([
523
+ buildMonitor(MONITOR_ID, { Vendor: "Acme" }),
524
+ ] as never);
525
+
526
+ const updateBy: UpdateBy<Alert> = buildAlertUpdateBy({
527
+ customFields: { Owner: "raj" },
528
+ });
529
+
530
+ await CustomFieldMappingService.applyMappingsToUpdate({
531
+ definitionModelType: AlertCustomField,
532
+ updateBy: updateBy,
533
+ });
534
+
535
+ expect((updateBy.data as JSONObject)["customFields"]).toEqual({
536
+ Owner: "raj",
537
+ Vendor: "Acme",
538
+ });
539
+ });
540
+
541
+ /*
542
+ * Re-pointing an alert at another monitor changes what the mapped field
543
+ * should hold, and the payload — not the stored row — is the new truth.
544
+ */
545
+ test("recomputes from the new monitor when the alert is repointed", async () => {
546
+ stubAlertDefinitions(VENDOR_MAPPING);
547
+ stubAffectedAlert({
548
+ monitorId: MONITOR_ID,
549
+ customFields: { Vendor: "Acme" },
550
+ });
551
+ jest
552
+ .spyOn(MonitorService, "findBy")
553
+ .mockResolvedValue([
554
+ buildMonitor(OTHER_MONITOR_ID, { Vendor: "Globex" }),
555
+ ] as never);
556
+
557
+ const updateBy: UpdateBy<Alert> = buildAlertUpdateBy({
558
+ monitorId: OTHER_MONITOR_ID,
559
+ });
560
+
561
+ await CustomFieldMappingService.applyMappingsToUpdate({
562
+ definitionModelType: AlertCustomField,
563
+ updateBy: updateBy,
564
+ });
565
+
566
+ expect((updateBy.data as JSONObject)["customFields"]).toEqual({
567
+ Vendor: "Globex",
568
+ });
569
+ });
570
+
571
+ test("recognises the relation-object spelling the dashboard posts", async () => {
572
+ stubAlertDefinitions(VENDOR_MAPPING);
573
+ stubAffectedAlert({ monitorId: MONITOR_ID, customFields: {} });
574
+ jest
575
+ .spyOn(MonitorService, "findBy")
576
+ .mockResolvedValue([
577
+ buildMonitor(OTHER_MONITOR_ID, { Vendor: "Globex" }),
578
+ ] as never);
579
+
580
+ const updateBy: UpdateBy<Alert> = buildAlertUpdateBy({
581
+ monitor: { _id: OTHER_MONITOR_ID.toString() },
582
+ });
583
+
584
+ await CustomFieldMappingService.applyMappingsToUpdate({
585
+ definitionModelType: AlertCustomField,
586
+ updateBy: updateBy,
587
+ });
588
+
589
+ expect((updateBy.data as JSONObject)["customFields"]).toEqual({
590
+ Vendor: "Globex",
591
+ });
592
+ });
593
+
594
+ test("ignores an update that touches neither the bag nor the relation", async () => {
595
+ const definitions: jest.SpyInstance = stubAlertDefinitions(VENDOR_MAPPING);
596
+ const findAlerts: jest.SpyInstance = jest
597
+ .spyOn(AlertService, "findBy")
598
+ .mockResolvedValue([] as never);
599
+
600
+ const updateBy: UpdateBy<Alert> = buildAlertUpdateBy({ title: "New" });
601
+
602
+ await CustomFieldMappingService.applyMappingsToUpdate({
603
+ definitionModelType: AlertCustomField,
604
+ updateBy: updateBy,
605
+ });
606
+
607
+ expect((updateBy.data as JSONObject)["customFields"]).toBeUndefined();
608
+ expect(findAlerts).not.toHaveBeenCalled();
609
+ expect(definitions).not.toHaveBeenCalled();
610
+ });
611
+
612
+ /*
613
+ * One payload is shared by every row a query-based update matches, and two
614
+ * alerts can have different monitors — so there is no single correct
615
+ * customFields to fold in. Those rows are re-resolved individually instead.
616
+ */
617
+ test("leaves the payload alone when the update matches more than one row", async () => {
618
+ stubAlertDefinitions(VENDOR_MAPPING);
619
+
620
+ const first: Alert = new Alert();
621
+ first._id = ALERT_ID.toString();
622
+ const second: Alert = new Alert();
623
+ second._id = OTHER_MONITOR_ID.toString();
624
+
625
+ jest
626
+ .spyOn(AlertService, "findBy")
627
+ .mockResolvedValue([first, second] as never);
628
+
629
+ const updateBy: UpdateBy<Alert> = buildAlertUpdateBy({
630
+ customFields: { Owner: "raj" },
631
+ });
632
+
633
+ await CustomFieldMappingService.applyMappingsToUpdate({
634
+ definitionModelType: AlertCustomField,
635
+ updateBy: updateBy,
636
+ });
637
+
638
+ expect((updateBy.data as JSONObject)["customFields"]).toEqual({
639
+ Owner: "raj",
640
+ });
641
+ });
642
+
643
+ test("does not restore a mapped value on an alert with no monitor", async () => {
644
+ stubAlertDefinitions(VENDOR_MAPPING);
645
+ stubAffectedAlert({ customFields: { Vendor: "Typed by hand" } });
646
+
647
+ const updateBy: UpdateBy<Alert> = buildAlertUpdateBy({
648
+ customFields: { Vendor: "Still typed by hand" },
649
+ });
650
+
651
+ await CustomFieldMappingService.applyMappingsToUpdate({
652
+ definitionModelType: AlertCustomField,
653
+ updateBy: updateBy,
654
+ });
655
+
656
+ expect((updateBy.data as JSONObject)["customFields"]).toEqual({
657
+ Vendor: "Still typed by hand",
658
+ });
659
+ });
660
+ });
661
+
662
+ describe("CustomFieldMappingService.propagateFromSourceRecord", () => {
663
+ type StubTargetsFunction = (alerts: Array<Alert>) => void;
664
+
665
+ const stubTargets: StubTargetsFunction = (alerts: Array<Alert>): void => {
666
+ jest.spyOn(AlertService, "findBy").mockResolvedValue(alerts as never);
667
+ jest.spyOn(IncidentService, "findBy").mockResolvedValue([] as never);
668
+ jest
669
+ .spyOn(ScheduledMaintenanceService, "findBy")
670
+ .mockResolvedValue([] as never);
671
+ };
672
+
673
+ /*
674
+ * A monitor change fans out to all three target resources; these tests are
675
+ * about the Alert leg, so the other two are configured with no mappings.
676
+ */
677
+ type StubOtherTargetsHaveNoMappingsFunction = () => void;
678
+
679
+ const stubOtherTargetsHaveNoMappings: StubOtherTargetsHaveNoMappingsFunction =
680
+ (): void => {
681
+ jest
682
+ .spyOn(IncidentCustomFieldService, "findBy")
683
+ .mockResolvedValue([] as never);
684
+ jest
685
+ .spyOn(ScheduledMaintenanceCustomFieldService, "findBy")
686
+ .mockResolvedValue([] as never);
687
+ };
688
+
689
+ type BuildAlertFunction = (id: ObjectID, customFields: JSONObject) => Alert;
690
+
691
+ const buildAlert: BuildAlertFunction = (
692
+ id: ObjectID,
693
+ customFields: JSONObject,
694
+ ): Alert => {
695
+ const alert: Alert = new Alert();
696
+ alert._id = id.toString();
697
+ alert.projectId = PROJECT_ID;
698
+ alert.monitorId = MONITOR_ID;
699
+ alert.customFields = customFields;
700
+ return alert;
701
+ };
702
+
703
+ /*
704
+ * The full update pipeline would fire a workflow POST, a realtime emit and
705
+ * an audit insert for every alert on the monitor. Derived data goes through
706
+ * the hook-free write instead, with a compare-and-set on the bag it was
707
+ * resolved from and without touching `updatedAt`.
708
+ */
709
+ test("writes through the hook-free path with a compare-and-set and no updatedAt bump", async () => {
710
+ stubAlertDefinitions(VENDOR_MAPPING);
711
+ stubOtherTargetsHaveNoMappings();
712
+
713
+ stubTargets([buildAlert(ALERT_ID, { Vendor: "Old", Owner: "kate" })]);
714
+ jest
715
+ .spyOn(MonitorService, "findBy")
716
+ .mockResolvedValue([
717
+ buildMonitor(MONITOR_ID, { Vendor: "Acme" }),
718
+ ] as never);
719
+
720
+ const write: jest.SpyInstance = jest
721
+ .spyOn(AlertService, "updateColumnsByIdWithoutHooks")
722
+ .mockResolvedValue(undefined as never);
723
+
724
+ await CustomFieldMappingService.propagateFromSourceRecord({
725
+ resource: CustomFieldMappingSourceResource.Monitor,
726
+ sourceId: MONITOR_ID,
727
+ projectId: PROJECT_ID,
728
+ });
729
+
730
+ expect(write).toHaveBeenCalledTimes(1);
731
+
732
+ const call: JSONObject = write.mock.calls[0]![0] as JSONObject;
733
+
734
+ expect((call["data"] as JSONObject)["customFields"]).toEqual({
735
+ Vendor: "Acme",
736
+ Owner: "kate",
737
+ });
738
+ expect((call["expectedData"] as JSONObject)["customFields"]).toEqual({
739
+ Vendor: "Old",
740
+ Owner: "kate",
741
+ });
742
+ expect(call["skipUpdateDateColumn"]).toBe(true);
743
+ });
744
+
745
+ test("does not write a row that already holds the right value", async () => {
746
+ stubAlertDefinitions(VENDOR_MAPPING);
747
+ stubOtherTargetsHaveNoMappings();
748
+
749
+ stubTargets([buildAlert(ALERT_ID, { Vendor: "Acme" })]);
750
+ jest
751
+ .spyOn(MonitorService, "findBy")
752
+ .mockResolvedValue([
753
+ buildMonitor(MONITOR_ID, { Vendor: "Acme" }),
754
+ ] as never);
755
+
756
+ const write: jest.SpyInstance = jest
757
+ .spyOn(AlertService, "updateColumnsByIdWithoutHooks")
758
+ .mockResolvedValue(undefined as never);
759
+
760
+ await CustomFieldMappingService.propagateFromSourceRecord({
761
+ resource: CustomFieldMappingSourceResource.Monitor,
762
+ sourceId: MONITOR_ID,
763
+ projectId: PROJECT_ID,
764
+ });
765
+
766
+ expect(write).not.toHaveBeenCalled();
767
+ });
768
+
769
+ /*
770
+ * The single most dangerous thing this feature could do. Clearing the
771
+ * monitor's Vendor must not clear it on every alert that ever inherited it.
772
+ */
773
+ test("clearing the source does not clear the copies", async () => {
774
+ stubAlertDefinitions(VENDOR_MAPPING);
775
+ stubOtherTargetsHaveNoMappings();
776
+
777
+ stubTargets([buildAlert(ALERT_ID, { Vendor: "Acme" })]);
778
+ jest
779
+ .spyOn(MonitorService, "findBy")
780
+ .mockResolvedValue([buildMonitor(MONITOR_ID, {})] as never);
781
+
782
+ const write: jest.SpyInstance = jest
783
+ .spyOn(AlertService, "updateColumnsByIdWithoutHooks")
784
+ .mockResolvedValue(undefined as never);
785
+
786
+ await CustomFieldMappingService.propagateFromSourceRecord({
787
+ resource: CustomFieldMappingSourceResource.Monitor,
788
+ sourceId: MONITOR_ID,
789
+ projectId: PROJECT_ID,
790
+ });
791
+
792
+ expect(write).not.toHaveBeenCalled();
793
+ });
794
+
795
+ test("a propagation failure for one resource does not stop the others", async () => {
796
+ jest
797
+ .spyOn(AlertCustomFieldService, "findBy")
798
+ .mockRejectedValue(new Error("boom") as never);
799
+ const incidentDefinitions: jest.SpyInstance = jest
800
+ .spyOn(IncidentCustomFieldService, "findBy")
801
+ .mockResolvedValue([] as never);
802
+ jest
803
+ .spyOn(ScheduledMaintenanceCustomFieldService, "findBy")
804
+ .mockResolvedValue([] as never);
805
+
806
+ await expect(
807
+ CustomFieldMappingService.propagateFromSourceRecord({
808
+ resource: CustomFieldMappingSourceResource.Monitor,
809
+ sourceId: MONITOR_ID,
810
+ projectId: PROJECT_ID,
811
+ }),
812
+ ).resolves.toBeUndefined();
813
+
814
+ expect(incidentDefinitions).toHaveBeenCalled();
815
+ });
816
+ });
817
+
818
+ describe("CustomFieldMappingService.restampAfterMultiRowUpdate", () => {
819
+ test("does nothing for a single-row update, which the before-hook already handled", () => {
820
+ const definitions: jest.SpyInstance = stubAlertDefinitions(VENDOR_MAPPING);
821
+
822
+ CustomFieldMappingService.restampAfterMultiRowUpdate({
823
+ definitionModelType: AlertCustomField,
824
+ updateBy: {
825
+ query: {},
826
+ data: { customFields: {} },
827
+ props: { isRoot: true, tenantId: PROJECT_ID },
828
+ } as unknown as UpdateBy<Alert>,
829
+ updatedItemIds: [ALERT_ID],
830
+ });
831
+
832
+ expect(definitions).not.toHaveBeenCalled();
833
+ });
834
+
835
+ test("does nothing when the update cannot have changed a mapped value", () => {
836
+ const definitions: jest.SpyInstance = stubAlertDefinitions(VENDOR_MAPPING);
837
+
838
+ CustomFieldMappingService.restampAfterMultiRowUpdate({
839
+ definitionModelType: AlertCustomField,
840
+ updateBy: {
841
+ query: {},
842
+ data: { title: "New" },
843
+ props: { isRoot: true, tenantId: PROJECT_ID },
844
+ } as unknown as UpdateBy<Alert>,
845
+ updatedItemIds: [ALERT_ID, INCIDENT_ID],
846
+ });
847
+
848
+ expect(definitions).not.toHaveBeenCalled();
849
+ });
850
+ });