@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,879 @@
1
+ import CustomFieldMappingSourceResource from "../../Types/CustomField/CustomFieldMappingSourceResource";
2
+ import CustomFieldType from "../../Types/CustomField/CustomFieldType";
3
+ import {
4
+ isCustomFieldValueEmpty,
5
+ mergeMappedCustomFieldValues,
6
+ MergedCustomFields,
7
+ ResolvedCustomFieldValue,
8
+ resolveMappedCustomFieldValue,
9
+ } from "../../Types/CustomField/CustomFieldValueMapping";
10
+ import SortOrder from "../../Types/BaseDatabase/SortOrder";
11
+ import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
12
+ import { JSONObject } from "../../Types/JSON";
13
+ import ObjectID from "../../Types/ObjectID";
14
+ import BaseModel from "../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
15
+ import { MAX_RULES_EVALUATED_PER_PROJECT } from "../../Utils/Rules/RuleEngineLimits";
16
+ import CreateBy from "../Types/Database/CreateBy";
17
+ import UpdateBy from "../Types/Database/UpdateBy";
18
+ import QueryHelper from "../Types/Database/QueryHelper";
19
+ import {
20
+ CustomFieldMappingSourceEntry,
21
+ CustomFieldMappingTargetEntry,
22
+ getCustomFieldMappingTarget,
23
+ getCustomFieldMappingTargetsForSource,
24
+ } from "../Utils/CustomField/CustomFieldMappingRegistry";
25
+ import logIfRuleReadWasTruncated from "../Utils/Rules/RuleEngineRuleRead";
26
+ import logger, { LogAttributes } from "../Utils/Logger";
27
+ import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
28
+
29
+ /*
30
+ * CUSTOM FIELD VALUE MAPPING (OneUptime/oneuptime#3549).
31
+ *
32
+ * A custom field defined on Alert can be configured to take its value from
33
+ * the same-shaped custom field on the Monitor the alert belongs to, instead of
34
+ * being typed in again by hand. The configuration lives on the definition row
35
+ * (`mapFromResourceType` + `mapFromCustomFieldName`); this service is
36
+ * everything that happens as a result.
37
+ *
38
+ * THE INVARIANT. Mapping only ever writes a value that exists on a source. It
39
+ * has no code path that clears a key:
40
+ *
41
+ * - target has no source record -> write nothing
42
+ * - source definition does not exist -> write nothing
43
+ * - source value is empty -> write nothing
44
+ * - sources disagree (and the field holds one value) -> write nothing
45
+ *
46
+ * That is not timidity, it is the difference between a safe feature and a
47
+ * destructive one. The natural first action after this ships is "turn the
48
+ * mapping on for Vendor" on a project that has been filling Vendor in by hand
49
+ * for a year and whose monitors have no Vendor at all. Any rule that treated
50
+ * "source is empty" as "clear the target" would erase every one of those
51
+ * values, through a hook-free write that leaves no audit row. The cost of the
52
+ * invariant is stated plainly in the settings help text: clearing the source
53
+ * does not clear the copies.
54
+ *
55
+ * WHERE IT RUNS, and why each is the only place that works:
56
+ *
57
+ * 1. `applyMappingsToCreate` from the target's `onBeforeCreate`. Every
58
+ * creation path in the product — monitor criteria, the REST API, Slack,
59
+ * Teams, the AI toolbox, workflows — funnels through DatabaseService
60
+ * .create, so one hook covers all of them. It cannot be onCreateSuccess:
61
+ * that chain is un-awaited and runs after the response, and customFields
62
+ * is a column on the row the caller is handed back.
63
+ *
64
+ * 2. `applyMappingsToUpdate` from the target's `onBeforeUpdate`. Covers two
65
+ * cases at once: the Custom Fields modal saving the WHOLE bag back (which
66
+ * would otherwise clobber a mapped value), and the record being re-pointed
67
+ * at a different monitor. Doing it in the before-hook makes it one atomic
68
+ * write with a correct audit row, workflow payload and realtime event —
69
+ * repairing it afterwards would publish the wrong value first.
70
+ *
71
+ * 3. `propagateFromSourceRecord` from `MonitorService.onUpdateSuccess`. The
72
+ * "stays in sync" half of the issue.
73
+ *
74
+ * 4. `backfillProject` from the definition service's create/update hooks, so
75
+ * turning a mapping on fills in records that already exist.
76
+ *
77
+ * KNOWN LIMITS, deliberately not solved here. There is no reconcile cron: a
78
+ * fan-out lost to a pod restart, or truncated at LIMIT_PER_PROJECT, leaves
79
+ * some records holding an older value until the source is edited again.
80
+ * Because of the invariant that is always a stale copy and never a lost value.
81
+ * Deleting the source monitor freezes the value rather than clearing it, for
82
+ * the same reason. And the ClickHouse metric attributes derived from
83
+ * `customFields` are refreshed on their existing triggers only — the same gap
84
+ * a manual custom field edit has today.
85
+ */
86
+
87
+ /** One configured mapping, resolved against the registry. */
88
+ export interface CustomFieldMapping {
89
+ targetFieldName: string;
90
+ sourceFieldName: string;
91
+ targetFieldType?: CustomFieldType | undefined;
92
+ source: CustomFieldMappingSourceEntry;
93
+ }
94
+
95
+ /*
96
+ * How many target records one fan-out reads at a time. Small enough that a
97
+ * page of rows and their sources sits comfortably in memory, large enough
98
+ * that a monitor with a few thousand alerts is a handful of round trips.
99
+ */
100
+ const FAN_OUT_PAGE_SIZE: number = 500;
101
+
102
+ /*
103
+ * Ceiling on how many target records one source change or one backfill
104
+ * rewrites. Same bound and the same reasoning as the rule engines: it is a
105
+ * ceiling rather than a page size, and crossing it is logged rather than
106
+ * silently swallowed.
107
+ */
108
+ const MAX_RECORDS_RESTAMPED: number = LIMIT_PER_PROJECT;
109
+
110
+ export class CustomFieldMappingServiceClass {
111
+ /**
112
+ * The mappings configured on one target's definition table for one project.
113
+ * Empty — the overwhelmingly common answer — costs a single indexed read.
114
+ */
115
+ @CaptureSpan()
116
+ public async getMappings(data: {
117
+ target: CustomFieldMappingTargetEntry;
118
+ projectId: ObjectID;
119
+ }): Promise<Array<CustomFieldMapping>> {
120
+ const definitions: Array<BaseModel> = await data.target
121
+ .getDefinitionService()
122
+ .findBy({
123
+ query: {
124
+ projectId: data.projectId,
125
+ },
126
+ select: {
127
+ name: true,
128
+ customFieldType: true,
129
+ mapFromResourceType: true,
130
+ mapFromCustomFieldName: true,
131
+ },
132
+ limit: MAX_RULES_EVALUATED_PER_PROJECT,
133
+ skip: 0,
134
+ props: {
135
+ isRoot: true,
136
+ },
137
+ });
138
+
139
+ logIfRuleReadWasTruncated({
140
+ ruleKind: data.target.definitionTableName,
141
+ projectId: data.projectId,
142
+ rulesRead: definitions.length,
143
+ });
144
+
145
+ const mappings: Array<CustomFieldMapping> = [];
146
+
147
+ for (const definition of definitions) {
148
+ const targetFieldName: string | undefined = (definition as any)["name"];
149
+ const resource: string | undefined = (definition as any)[
150
+ "mapFromResourceType"
151
+ ];
152
+ const sourceFieldName: string | undefined = (definition as any)[
153
+ "mapFromCustomFieldName"
154
+ ];
155
+
156
+ if (!targetFieldName || !resource || !sourceFieldName) {
157
+ continue;
158
+ }
159
+
160
+ const source: CustomFieldMappingSourceEntry | undefined =
161
+ data.target.sources.find((entry: CustomFieldMappingSourceEntry) => {
162
+ return entry.info.resource === resource;
163
+ });
164
+
165
+ /*
166
+ * A row can name a resource this target cannot reach if the catalog
167
+ * shrinks after the mapping was saved. Skipping is the same behaviour as
168
+ * a dangling source field: the field simply goes back to being manual.
169
+ */
170
+ if (!source) {
171
+ continue;
172
+ }
173
+
174
+ mappings.push({
175
+ targetFieldName: targetFieldName,
176
+ sourceFieldName: sourceFieldName,
177
+ targetFieldType: (definition as any)["customFieldType"],
178
+ source: source,
179
+ });
180
+ }
181
+
182
+ /* Stable order so log lines and tests do not depend on row order. */
183
+ return mappings.sort((a: CustomFieldMapping, b: CustomFieldMapping) => {
184
+ return a.targetFieldName.localeCompare(b.targetFieldName);
185
+ });
186
+ }
187
+
188
+ /**
189
+ * Resolve every mapping for ONE target record.
190
+ *
191
+ * `sourceBagsById` is a cache shared across a fan-out page so a monitor
192
+ * attached to fifty incidents is read once.
193
+ */
194
+ private async resolveValuesForRecord(data: {
195
+ mappings: Array<CustomFieldMapping>;
196
+ sourceIdsBySource: Map<CustomFieldMappingSourceEntry, Array<ObjectID>>;
197
+ sourceBagsById: Map<string, JSONObject>;
198
+ }): Promise<JSONObject> {
199
+ await this.loadMissingSourceBags({
200
+ sourceIdsBySource: data.sourceIdsBySource,
201
+ sourceBagsById: data.sourceBagsById,
202
+ });
203
+
204
+ const resolved: JSONObject = {};
205
+
206
+ for (const mapping of data.mappings) {
207
+ const sourceIds: Array<ObjectID> =
208
+ data.sourceIdsBySource.get(mapping.source) || [];
209
+
210
+ const sourceValues: Array<unknown> = sourceIds.map((id: ObjectID) => {
211
+ const bag: JSONObject | undefined = data.sourceBagsById.get(
212
+ id.toString(),
213
+ );
214
+
215
+ return bag ? bag[mapping.sourceFieldName] : undefined;
216
+ });
217
+
218
+ const resolution: ResolvedCustomFieldValue =
219
+ resolveMappedCustomFieldValue({
220
+ sourceValues: sourceValues,
221
+ targetFieldType: mapping.targetFieldType,
222
+ });
223
+
224
+ if (!resolution.hasValue) {
225
+ continue;
226
+ }
227
+
228
+ resolved[mapping.targetFieldName] =
229
+ resolution.value as JSONObject[string];
230
+ }
231
+
232
+ return resolved;
233
+ }
234
+
235
+ private async loadMissingSourceBags(data: {
236
+ sourceIdsBySource: Map<CustomFieldMappingSourceEntry, Array<ObjectID>>;
237
+ sourceBagsById: Map<string, JSONObject>;
238
+ }): Promise<void> {
239
+ for (const [source, ids] of data.sourceIdsBySource.entries()) {
240
+ const missing: Array<ObjectID> = ids.filter((id: ObjectID) => {
241
+ return !data.sourceBagsById.has(id.toString());
242
+ });
243
+
244
+ if (missing.length === 0) {
245
+ continue;
246
+ }
247
+
248
+ const records: Array<BaseModel> = await source.getSourceService().findBy({
249
+ query: {
250
+ _id: QueryHelper.any(
251
+ missing.map((id: ObjectID) => {
252
+ return id.toString();
253
+ }),
254
+ ),
255
+ },
256
+ select: {
257
+ _id: true,
258
+ customFields: true,
259
+ },
260
+ limit: missing.length,
261
+ skip: 0,
262
+ props: {
263
+ isRoot: true,
264
+ },
265
+ });
266
+
267
+ for (const record of records) {
268
+ data.sourceBagsById.set(
269
+ record.id!.toString(),
270
+ ((record as any)["customFields"] || {}) as JSONObject,
271
+ );
272
+ }
273
+
274
+ /*
275
+ * A source that could not be read — deleted between the two queries, or
276
+ * simply gone — is cached as an empty bag rather than retried on every
277
+ * record in the page. An empty bag resolves to "write nothing", which is
278
+ * the intended behaviour for a missing source.
279
+ */
280
+ for (const id of missing) {
281
+ if (!data.sourceBagsById.has(id.toString())) {
282
+ data.sourceBagsById.set(id.toString(), {});
283
+ }
284
+ }
285
+ }
286
+ }
287
+
288
+ /**
289
+ * Stamp mapped values onto a record being created.
290
+ *
291
+ * Never throws: this runs on the alert/incident ingest path, where a failure
292
+ * to inherit a custom field must not stop the alert from being opened.
293
+ */
294
+ @CaptureSpan()
295
+ public async applyMappingsToCreate(data: {
296
+ definitionModelType: { new (): BaseModel };
297
+ createBy: CreateBy<any>;
298
+ }): Promise<void> {
299
+ try {
300
+ const target: CustomFieldMappingTargetEntry | undefined =
301
+ getCustomFieldMappingTarget(new data.definitionModelType().tableName!);
302
+
303
+ if (!target) {
304
+ return;
305
+ }
306
+
307
+ const projectId: ObjectID | undefined =
308
+ (data.createBy.props.tenantId as ObjectID | undefined) ||
309
+ (data.createBy.data as any)["projectId"];
310
+
311
+ if (!projectId) {
312
+ return;
313
+ }
314
+
315
+ const mappings: Array<CustomFieldMapping> = await this.getMappings({
316
+ target: target,
317
+ projectId: projectId,
318
+ });
319
+
320
+ if (mappings.length === 0) {
321
+ return;
322
+ }
323
+
324
+ const sourceIdsBySource: Map<
325
+ CustomFieldMappingSourceEntry,
326
+ Array<ObjectID>
327
+ > = new Map<CustomFieldMappingSourceEntry, Array<ObjectID>>();
328
+ const sourceBagsById: Map<string, JSONObject> = new Map<
329
+ string,
330
+ JSONObject
331
+ >();
332
+
333
+ for (const source of target.sources) {
334
+ sourceIdsBySource.set(
335
+ source,
336
+ source.readSourceIdsFromPayload(data.createBy.data) || [],
337
+ );
338
+
339
+ /*
340
+ * Monitor criteria hand us the whole Monitor, already read with its
341
+ * customFields (MonitorResource selects them for metric attributes).
342
+ * Taking the bag from the payload keeps the hottest creation path in
343
+ * the product free of an extra query.
344
+ */
345
+ for (const [id, bag] of Object.entries(
346
+ source.readHydratedSourcesFromPayload(data.createBy.data),
347
+ )) {
348
+ sourceBagsById.set(id, bag);
349
+ }
350
+ }
351
+
352
+ const resolved: JSONObject = await this.resolveValuesForRecord({
353
+ mappings: mappings,
354
+ sourceIdsBySource: sourceIdsBySource,
355
+ sourceBagsById: sourceBagsById,
356
+ });
357
+
358
+ if (Object.keys(resolved).length === 0) {
359
+ return;
360
+ }
361
+
362
+ const merged: MergedCustomFields = mergeMappedCustomFieldValues({
363
+ existingCustomFields: (data.createBy.data as any)["customFields"],
364
+ resolvedValues: resolved,
365
+ });
366
+
367
+ if (!merged.hasChanged) {
368
+ return;
369
+ }
370
+
371
+ (data.createBy.data as any)["customFields"] = merged.customFields;
372
+ } catch (error) {
373
+ logger.error("Custom field value mapping failed on create.");
374
+ logger.error(error as Error);
375
+ }
376
+ }
377
+
378
+ /**
379
+ * Re-stamp mapped values into an update payload.
380
+ *
381
+ * Only the single-row case is folded into the payload, because `updateBy`
382
+ * carries ONE payload for every row its query matches and two records can
383
+ * have different monitors. Multi-row updates are handled after the fact by
384
+ * `restampRecordsByIds`, which resolves per row.
385
+ */
386
+ @CaptureSpan()
387
+ public async applyMappingsToUpdate(data: {
388
+ definitionModelType: { new (): BaseModel };
389
+ updateBy: UpdateBy<any>;
390
+ }): Promise<void> {
391
+ try {
392
+ const target: CustomFieldMappingTargetEntry | undefined =
393
+ getCustomFieldMappingTarget(new data.definitionModelType().tableName!);
394
+
395
+ if (!target) {
396
+ return;
397
+ }
398
+
399
+ if (
400
+ !this.doesUpdateAffectMappedValues({ target, updateBy: data.updateBy })
401
+ ) {
402
+ return;
403
+ }
404
+
405
+ /*
406
+ * Limit 2 rather than 1: the answer needed is "exactly one row or more
407
+ * than one", and asking for two is how you tell those apart without
408
+ * counting the whole match.
409
+ */
410
+ const affected: Array<BaseModel> = await this.findTargetRecords({
411
+ target: target,
412
+ query: data.updateBy.query as JSONObject,
413
+ limit: 2,
414
+ skip: 0,
415
+ });
416
+
417
+ if (affected.length !== 1) {
418
+ return;
419
+ }
420
+
421
+ const record: BaseModel = affected[0]!;
422
+ const projectId: ObjectID | undefined = (record as any)["projectId"];
423
+
424
+ if (!projectId) {
425
+ return;
426
+ }
427
+
428
+ const mappings: Array<CustomFieldMapping> = await this.getMappings({
429
+ target: target,
430
+ projectId: projectId,
431
+ });
432
+
433
+ if (mappings.length === 0) {
434
+ return;
435
+ }
436
+
437
+ const sourceIdsBySource: Map<
438
+ CustomFieldMappingSourceEntry,
439
+ Array<ObjectID>
440
+ > = new Map<CustomFieldMappingSourceEntry, Array<ObjectID>>();
441
+
442
+ for (const source of target.sources) {
443
+ /*
444
+ * The payload wins when it writes the relation — that is the
445
+ * re-pointing case, and the record still holds the OLD monitor.
446
+ */
447
+ const fromPayload: Array<ObjectID> | null =
448
+ source.readSourceIdsFromPayload(data.updateBy.data);
449
+
450
+ sourceIdsBySource.set(
451
+ source,
452
+ fromPayload === null
453
+ ? source.readSourceIdsFromRecord(record)
454
+ : fromPayload,
455
+ );
456
+ }
457
+
458
+ const resolved: JSONObject = await this.resolveValuesForRecord({
459
+ mappings: mappings,
460
+ sourceIdsBySource: sourceIdsBySource,
461
+ sourceBagsById: new Map<string, JSONObject>(),
462
+ });
463
+
464
+ if (Object.keys(resolved).length === 0) {
465
+ return;
466
+ }
467
+
468
+ /*
469
+ * When the payload replaces the whole bag, that replacement is the base
470
+ * to merge into. When it does not (a pure re-point), the stored bag is.
471
+ */
472
+ const base: JSONObject =
473
+ (data.updateBy.data as any)["customFields"] !== undefined
474
+ ? ((data.updateBy.data as any)["customFields"] as JSONObject)
475
+ : (((record as any)["customFields"] || {}) as JSONObject);
476
+
477
+ const merged: MergedCustomFields = mergeMappedCustomFieldValues({
478
+ existingCustomFields: base,
479
+ resolvedValues: resolved,
480
+ });
481
+
482
+ if (!merged.hasChanged) {
483
+ return;
484
+ }
485
+
486
+ (data.updateBy.data as any)["customFields"] = merged.customFields;
487
+ } catch (error) {
488
+ logger.error("Custom field value mapping failed on update.");
489
+ logger.error(error as Error);
490
+ }
491
+ }
492
+
493
+ /**
494
+ * The multi-row half of `applyMappingsToUpdate`.
495
+ *
496
+ * `updateBy` carries ONE payload for every row its query matched, so a
497
+ * query-based update touching several records cannot have per-record values
498
+ * folded into it. Those rows are re-resolved individually here instead —
499
+ * after the fact, but a query-based write of `customFields` across many rows
500
+ * is not something any UI in the product does, so this is a backstop for the
501
+ * raw API rather than the path anyone takes.
502
+ *
503
+ * Fire-and-forget: the single-row case has already been handled atomically,
504
+ * and this must not add its cost to the caller's request.
505
+ */
506
+ @CaptureSpan()
507
+ public restampAfterMultiRowUpdate(data: {
508
+ definitionModelType: { new (): BaseModel };
509
+ updateBy: UpdateBy<any>;
510
+ updatedItemIds: Array<ObjectID>;
511
+ }): void {
512
+ if (data.updatedItemIds.length < 2) {
513
+ return;
514
+ }
515
+
516
+ const target: CustomFieldMappingTargetEntry | undefined =
517
+ getCustomFieldMappingTarget(new data.definitionModelType().tableName!);
518
+
519
+ if (!target) {
520
+ return;
521
+ }
522
+
523
+ if (
524
+ !this.doesUpdateAffectMappedValues({
525
+ target: target,
526
+ updateBy: data.updateBy,
527
+ })
528
+ ) {
529
+ return;
530
+ }
531
+
532
+ const projectId: ObjectID | undefined = data.updateBy.props.tenantId as
533
+ | ObjectID
534
+ | undefined;
535
+
536
+ if (!projectId) {
537
+ return;
538
+ }
539
+
540
+ this.restampRecordsByIds({
541
+ target: target,
542
+ projectId: projectId,
543
+ recordIds: data.updatedItemIds,
544
+ }).catch((error: Error) => {
545
+ logger.error(
546
+ `Custom field value mapping: could not re-apply mappings after a multi-row ${target.targetName} update.`,
547
+ );
548
+ logger.error(error);
549
+ });
550
+ }
551
+
552
+ /**
553
+ * True when this update could change what a mapped field should hold: it
554
+ * either rewrites the bag, or it moves the record to another source.
555
+ */
556
+ public doesUpdateAffectMappedValues(data: {
557
+ target: CustomFieldMappingTargetEntry;
558
+ updateBy: UpdateBy<any>;
559
+ }): boolean {
560
+ if ((data.updateBy.data as any)["customFields"] !== undefined) {
561
+ return true;
562
+ }
563
+
564
+ const dataKeys: Array<string> = Object.keys(data.updateBy.data || {});
565
+
566
+ return data.target.sources.some((source: CustomFieldMappingSourceEntry) => {
567
+ return source.relationDataKeys.some((key: string) => {
568
+ return dataKeys.includes(key);
569
+ });
570
+ });
571
+ }
572
+
573
+ /**
574
+ * Re-resolve and re-write mapped values for specific target records.
575
+ *
576
+ * Writes go through `updateColumnsByIdWithoutHooks` because this is derived
577
+ * data: the full update pipeline would fire a workflow POST, a realtime
578
+ * emit and an audit-log insert per row, none of which a value the system
579
+ * computed for itself should produce. `expectedData` makes each write a
580
+ * compare-and-set on the bag it was resolved from, so a concurrent save
581
+ * through the Custom Fields modal is left alone rather than half-overwritten,
582
+ * and `skipUpdateDateColumn` keeps one monitor edit from restamping
583
+ * `updatedAt` across years of resolved alerts.
584
+ */
585
+ @CaptureSpan()
586
+ public async restampRecordsByIds(data: {
587
+ target: CustomFieldMappingTargetEntry;
588
+ projectId: ObjectID;
589
+ recordIds: Array<ObjectID>;
590
+ }): Promise<number> {
591
+ if (data.recordIds.length === 0) {
592
+ return 0;
593
+ }
594
+
595
+ const mappings: Array<CustomFieldMapping> = await this.getMappings({
596
+ target: data.target,
597
+ projectId: data.projectId,
598
+ });
599
+
600
+ if (mappings.length === 0) {
601
+ return 0;
602
+ }
603
+
604
+ const records: Array<BaseModel> = await this.findTargetRecords({
605
+ target: data.target,
606
+ query: {
607
+ _id: QueryHelper.any(
608
+ data.recordIds.map((id: ObjectID) => {
609
+ return id.toString();
610
+ }),
611
+ ),
612
+ } as JSONObject,
613
+ limit: data.recordIds.length,
614
+ skip: 0,
615
+ });
616
+
617
+ return this.restampRecords({
618
+ target: data.target,
619
+ mappings: mappings,
620
+ records: records,
621
+ sourceBagsById: new Map<string, JSONObject>(),
622
+ });
623
+ }
624
+
625
+ private async restampRecords(data: {
626
+ target: CustomFieldMappingTargetEntry;
627
+ mappings: Array<CustomFieldMapping>;
628
+ records: Array<BaseModel>;
629
+ sourceBagsById: Map<string, JSONObject>;
630
+ }): Promise<number> {
631
+ let updatedCount: number = 0;
632
+
633
+ for (const record of data.records) {
634
+ const sourceIdsBySource: Map<
635
+ CustomFieldMappingSourceEntry,
636
+ Array<ObjectID>
637
+ > = new Map<CustomFieldMappingSourceEntry, Array<ObjectID>>();
638
+
639
+ for (const source of data.target.sources) {
640
+ sourceIdsBySource.set(source, source.readSourceIdsFromRecord(record));
641
+ }
642
+
643
+ const resolved: JSONObject = await this.resolveValuesForRecord({
644
+ mappings: data.mappings,
645
+ sourceIdsBySource: sourceIdsBySource,
646
+ sourceBagsById: data.sourceBagsById,
647
+ });
648
+
649
+ if (Object.keys(resolved).length === 0) {
650
+ continue;
651
+ }
652
+
653
+ const existing: JSONObject | null =
654
+ ((record as any)["customFields"] as JSONObject) ?? null;
655
+
656
+ const merged: MergedCustomFields = mergeMappedCustomFieldValues({
657
+ existingCustomFields: existing,
658
+ resolvedValues: resolved,
659
+ });
660
+
661
+ if (!merged.hasChanged) {
662
+ continue;
663
+ }
664
+
665
+ await data.target.getTargetService().updateColumnsByIdWithoutHooks({
666
+ id: record.id!,
667
+ data: {
668
+ customFields: merged.customFields,
669
+ },
670
+ expectedData: {
671
+ customFields: existing,
672
+ },
673
+ skipUpdateDateColumn: true,
674
+ });
675
+
676
+ updatedCount++;
677
+ }
678
+
679
+ return updatedCount;
680
+ }
681
+
682
+ /**
683
+ * A source record's custom fields changed — bring every target attached to
684
+ * it back in line.
685
+ *
686
+ * Note that for a many-source target the changed source is not enough to
687
+ * recompute with: an incident spanning three monitors resolves from all
688
+ * three, so each record is re-read with its full relation.
689
+ */
690
+ @CaptureSpan()
691
+ public async propagateFromSourceRecord(data: {
692
+ resource: CustomFieldMappingSourceResource;
693
+ sourceId: ObjectID;
694
+ projectId: ObjectID;
695
+ }): Promise<void> {
696
+ const pairs: Array<{
697
+ target: CustomFieldMappingTargetEntry;
698
+ source: CustomFieldMappingSourceEntry;
699
+ }> = getCustomFieldMappingTargetsForSource(data.resource);
700
+
701
+ for (const pair of pairs) {
702
+ try {
703
+ const mappings: Array<CustomFieldMapping> = await this.getMappings({
704
+ target: pair.target,
705
+ projectId: data.projectId,
706
+ });
707
+
708
+ const mappingsForSource: Array<CustomFieldMapping> = mappings.filter(
709
+ (mapping: CustomFieldMapping) => {
710
+ return mapping.source === pair.source;
711
+ },
712
+ );
713
+
714
+ if (mappingsForSource.length === 0) {
715
+ continue;
716
+ }
717
+
718
+ await this.restampMatchingRecords({
719
+ target: pair.target,
720
+ mappings: mappings,
721
+ query: {
722
+ projectId: data.projectId,
723
+ ...pair.source.buildTargetQueryForSourceId(data.sourceId),
724
+ } as JSONObject,
725
+ reason: `${pair.source.info.title} ${data.sourceId.toString()} custom fields changed`,
726
+ });
727
+ } catch (error) {
728
+ logger.error(
729
+ `Custom field value mapping: could not propagate ${pair.source.info.title} changes to ${pair.target.targetName}.`,
730
+ {
731
+ projectId: data.projectId.toString(),
732
+ } as LogAttributes,
733
+ );
734
+ logger.error(error as Error);
735
+ }
736
+ }
737
+ }
738
+
739
+ /**
740
+ * A mapping was created or changed — fill in the records that already exist.
741
+ */
742
+ @CaptureSpan()
743
+ public async backfillProject(data: {
744
+ definitionModelType: { new (): BaseModel };
745
+ projectId: ObjectID;
746
+ }): Promise<void> {
747
+ const target: CustomFieldMappingTargetEntry | undefined =
748
+ getCustomFieldMappingTarget(new data.definitionModelType().tableName!);
749
+
750
+ if (!target) {
751
+ return;
752
+ }
753
+
754
+ try {
755
+ const mappings: Array<CustomFieldMapping> = await this.getMappings({
756
+ target: target,
757
+ projectId: data.projectId,
758
+ });
759
+
760
+ if (mappings.length === 0) {
761
+ return;
762
+ }
763
+
764
+ await this.restampMatchingRecords({
765
+ target: target,
766
+ mappings: mappings,
767
+ query: { projectId: data.projectId } as JSONObject,
768
+ reason: `${target.definitionTableName} mapping configuration changed`,
769
+ });
770
+ } catch (error) {
771
+ logger.error(
772
+ `Custom field value mapping: backfill of ${target.targetName} records failed.`,
773
+ {
774
+ projectId: data.projectId.toString(),
775
+ } as LogAttributes,
776
+ );
777
+ logger.error(error as Error);
778
+ }
779
+ }
780
+
781
+ private async restampMatchingRecords(data: {
782
+ target: CustomFieldMappingTargetEntry;
783
+ mappings: Array<CustomFieldMapping>;
784
+ query: JSONObject;
785
+ reason: string;
786
+ }): Promise<void> {
787
+ /*
788
+ * Sources are cached for the whole sweep, not per page: a project-wide
789
+ * backfill of ten thousand alerts across two hundred monitors reads each
790
+ * monitor once.
791
+ */
792
+ const sourceBagsById: Map<string, JSONObject> = new Map<
793
+ string,
794
+ JSONObject
795
+ >();
796
+
797
+ let skip: number = 0;
798
+ let updatedCount: number = 0;
799
+ let readCount: number = 0;
800
+
801
+ /*
802
+ * Newest first. If a project is large enough to reach the ceiling, the
803
+ * records people are actually looking at are the ones that get the value.
804
+ */
805
+ while (skip < MAX_RECORDS_RESTAMPED) {
806
+ const page: Array<BaseModel> = await this.findTargetRecords({
807
+ target: data.target,
808
+ query: data.query,
809
+ limit: Math.min(FAN_OUT_PAGE_SIZE, MAX_RECORDS_RESTAMPED - skip),
810
+ skip: skip,
811
+ sortNewestFirst: true,
812
+ });
813
+
814
+ if (page.length === 0) {
815
+ break;
816
+ }
817
+
818
+ readCount += page.length;
819
+
820
+ updatedCount += await this.restampRecords({
821
+ target: data.target,
822
+ mappings: data.mappings,
823
+ records: page,
824
+ sourceBagsById: sourceBagsById,
825
+ });
826
+
827
+ if (page.length < FAN_OUT_PAGE_SIZE) {
828
+ break;
829
+ }
830
+
831
+ skip += page.length;
832
+ }
833
+
834
+ if (readCount >= MAX_RECORDS_RESTAMPED) {
835
+ logger.error(
836
+ `Custom field value mapping: stopped after ${MAX_RECORDS_RESTAMPED} ${data.target.targetName} records (${data.reason}). Older records keep their previous values until their source changes again.`,
837
+ );
838
+ }
839
+
840
+ if (updatedCount > 0) {
841
+ logger.debug(
842
+ `Custom field value mapping: updated ${updatedCount} ${data.target.targetName} records (${data.reason}).`,
843
+ );
844
+ }
845
+ }
846
+
847
+ private async findTargetRecords(data: {
848
+ target: CustomFieldMappingTargetEntry;
849
+ query: JSONObject;
850
+ limit: number;
851
+ skip: number;
852
+ sortNewestFirst?: boolean | undefined;
853
+ }): Promise<Array<BaseModel>> {
854
+ const select: JSONObject = {
855
+ _id: true,
856
+ projectId: true,
857
+ customFields: true,
858
+ };
859
+
860
+ for (const source of data.target.sources) {
861
+ Object.assign(select, source.targetRelationSelect);
862
+ }
863
+
864
+ return data.target.getTargetService().findBy({
865
+ query: data.query,
866
+ select: select,
867
+ limit: data.limit,
868
+ skip: data.skip,
869
+ sort: data.sortNewestFirst ? { createdAt: SortOrder.Descending } : {},
870
+ props: {
871
+ isRoot: true,
872
+ },
873
+ });
874
+ }
875
+ }
876
+
877
+ export { isCustomFieldValueEmpty };
878
+
879
+ export default new CustomFieldMappingServiceClass();