@oneuptime/common 11.5.9 → 11.5.10

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 (376) hide show
  1. package/Models/AnalyticsModels/Index.ts +13 -0
  2. package/Models/AnalyticsModels/MetricItemAggMV1mByContainer.ts +178 -0
  3. package/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.ts +179 -0
  4. package/Models/AnalyticsModels/MetricItemAggMV1mByService.ts +179 -0
  5. package/Models/AnalyticsModels/NetworkFlow.ts +397 -0
  6. package/Models/DatabaseModels/EnterpriseLicenseInstance.ts +18 -0
  7. package/Models/DatabaseModels/GlobalConfig.ts +36 -0
  8. package/Models/DatabaseModels/Index.ts +2 -0
  9. package/Models/DatabaseModels/MarketingConversion.ts +198 -0
  10. package/Models/DatabaseModels/MetricSavedView.ts +34 -0
  11. package/Models/DatabaseModels/MetricType.ts +74 -0
  12. package/Models/DatabaseModels/NetworkDevice.ts +332 -0
  13. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +113 -0
  14. package/Models/DatabaseModels/NetworkInterface.ts +58 -0
  15. package/Models/DatabaseModels/Project.ts +37 -0
  16. package/Models/DatabaseModels/User.ts +37 -0
  17. package/Server/API/BaseAnalyticsAPI.ts +23 -0
  18. package/Server/API/EnterpriseLicenseAPI.ts +14 -0
  19. package/Server/EnvironmentConfig.ts +84 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1784191414522-AddCounterSemanticsToMetricType.ts +38 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/1784191414600-AddViewTypeToMetricSavedView.ts +28 -0
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1784211212164-AddNetworkDeviceInventoryAndDiscoverySchedule.ts +108 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1784218257664-AddEnterpriseLicenseNotificationColumns.ts +31 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/1784293516000-AddAttributionColumnsToUserAndProject.ts +29 -0
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/1784298000000-AddMarketingConversionTable.ts +35 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +12 -0
  27. package/Server/Services/AnalyticsDatabaseService.ts +70 -1
  28. package/Server/Services/IncidentService.ts +13 -0
  29. package/Server/Services/Index.ts +10 -0
  30. package/Server/Services/MarketingConversionService.ts +10 -0
  31. package/Server/Services/MetricItemAggMV1mByContainerService.ts +31 -0
  32. package/Server/Services/MetricItemAggMV1mByK8sClusterService.ts +31 -0
  33. package/Server/Services/MetricItemAggMV1mByServiceService.ts +31 -0
  34. package/Server/Services/MetricService.ts +970 -122
  35. package/Server/Services/MonitorService.ts +14 -0
  36. package/Server/Services/NetworkDeviceOwnerTeamService.ts +42 -0
  37. package/Server/Services/NetworkDeviceOwnerUserService.ts +106 -0
  38. package/Server/Services/NetworkFlowService.ts +11 -0
  39. package/Server/Services/OnCallDutyPolicyService.ts +11 -1
  40. package/Server/Services/ProjectService.ts +136 -0
  41. package/Server/Services/SpanService.ts +13 -9
  42. package/Server/Services/StatusPageService.ts +10 -0
  43. package/Server/Services/TeamMemberService.ts +11 -0
  44. package/Server/Services/UserService.ts +59 -0
  45. package/Server/Types/AnalyticsDatabase/AggregateBy.ts +37 -7
  46. package/Server/Utils/Attribution.ts +99 -0
  47. package/Server/Utils/Marketing/ConversionUploadProvider.ts +103 -0
  48. package/Server/Utils/Marketing/ConversionUploadProviders.ts +22 -0
  49. package/Server/Utils/Marketing/Providers/GoogleAds.ts +270 -0
  50. package/Server/Utils/Marketing/Providers/LinkedIn.ts +147 -0
  51. package/Server/Utils/Marketing/Providers/Meta.ts +148 -0
  52. package/Server/Utils/Marketing/Providers/MicrosoftAds.ts +196 -0
  53. package/Server/Utils/Marketing/Providers/Reddit.ts +178 -0
  54. package/Server/Utils/Monitor/MonitorAlert.ts +71 -7
  55. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +31 -19
  56. package/Server/Utils/Monitor/MonitorIncident.ts +71 -7
  57. package/Server/Utils/Monitor/MonitorMetricUtil.ts +57 -0
  58. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +94 -0
  59. package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +15 -0
  60. package/Server/Utils/Monitor/NetworkInventoryUtil.ts +125 -14
  61. package/Server/Utils/ProductAnalytics.ts +133 -0
  62. package/Server/Utils/Telemetry/Telemetry.ts +39 -0
  63. package/Server/Utils/Telemetry/TelemetryEntity.ts +21 -0
  64. package/Tests/Server/API/BaseAnalyticsAPI.test.ts +72 -0
  65. package/Tests/Server/Infrastructure/SemaphorePermit.test.ts +9 -1
  66. package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +21 -2
  67. package/Tests/Server/Services/MetricEntityMVKeyParity.test.ts +173 -0
  68. package/Tests/Server/Services/MetricServiceAggregate.test.ts +1391 -0
  69. package/Tests/Server/Services/NetworkDeviceOwnerServices.test.ts +260 -0
  70. package/Tests/Server/Utils/Monitor/MonitorTemplateUtilNetworkDevice.test.ts +389 -0
  71. package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +764 -0
  72. package/Tests/Types/BaseDatabase/AggregationIntervalUtil.test.ts +111 -2
  73. package/Tests/Types/Database/EndsWith.test.ts +64 -0
  74. package/Tests/Types/Database/GreaterThan.test.ts +62 -0
  75. package/Tests/Types/Database/GreaterThanOrEqual.test.ts +65 -0
  76. package/Tests/Types/Database/GreaterThanOrNull.test.ts +63 -0
  77. package/Tests/Types/Database/Includes.test.ts +65 -0
  78. package/Tests/Types/Database/IncludesAll.test.ts +65 -0
  79. package/Tests/Types/Database/IncludesNone.test.ts +65 -0
  80. package/Tests/Types/Database/IsNull.test.ts +44 -0
  81. package/Tests/Types/Database/LessThan.test.ts +62 -0
  82. package/Tests/Types/Database/LessThanOrEqual.test.ts +62 -0
  83. package/Tests/Types/Database/LessThanOrNull.test.ts +62 -0
  84. package/Tests/Types/Database/MultiSearch.test.ts +81 -0
  85. package/Tests/Types/Database/NotContains.test.ts +64 -0
  86. package/Tests/Types/Database/NotNull.test.ts +44 -0
  87. package/Tests/Types/Database/StartsWith.test.ts +64 -0
  88. package/Tests/Types/Monitor/MonitorStepSqlMonitor.test.ts +83 -1
  89. package/Tests/Types/Monitor/SnmpV3EnumParsing.test.ts +247 -0
  90. package/Tests/Types/Monitor/SnmpVendorTemplate.test.ts +263 -0
  91. package/Tests/UI/Components/XAxis.test.ts +5 -3
  92. package/Tests/Utils/EnterpriseLicenseUsage.test.ts +76 -0
  93. package/Tests/Utils/Metrics/MetricExplorerUrl.test.ts +622 -0
  94. package/Tests/Utils/Metrics/MetricFormulaEvaluator.test.ts +474 -0
  95. package/Tests/Utils/Telemetry/HeartbeatAvailability.test.ts +52 -4
  96. package/Types/AnalyticsDatabase/AnalyticsTableName.ts +11 -0
  97. package/Types/BaseDatabase/AggregateBy.ts +31 -2
  98. package/Types/BaseDatabase/AggregatedResult.ts +22 -0
  99. package/Types/BaseDatabase/AggregationInterval.ts +11 -0
  100. package/Types/BaseDatabase/AggregationIntervalUtil.ts +30 -5
  101. package/Types/Dashboard/DashboardComponents/DashboardTraceChartComponent.ts +16 -0
  102. package/Types/Email/EmailTemplateType.ts +3 -0
  103. package/Types/Marketing/MarketingConversion.ts +11 -0
  104. package/Types/Metrics/MetricQueryConfigData.ts +21 -0
  105. package/Types/Metrics/MetricQueryData.ts +8 -0
  106. package/Types/Metrics/MetricViewData.ts +8 -0
  107. package/Types/Monitor/MonitorMetricType.ts +8 -0
  108. package/Types/Monitor/MonitorStep.ts +9 -0
  109. package/Types/Monitor/MonitorStepSqlMonitor.ts +12 -0
  110. package/Types/Monitor/MonitorType.ts +2 -1
  111. package/Types/Monitor/SSLMonitor/SslMonitorResponse.ts +17 -12
  112. package/Types/Monitor/SnmpMonitor/CdpNeighbor.ts +13 -0
  113. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +37 -3
  114. package/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.ts +46 -0
  115. package/Types/Monitor/SnmpMonitor/SnmpEntityInfo.ts +15 -0
  116. package/Types/Monitor/SnmpMonitor/SnmpInterface.ts +8 -0
  117. package/Types/Monitor/SnmpMonitor/SnmpMonitorResponse.ts +17 -8
  118. package/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.ts +53 -0
  119. package/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.ts +43 -0
  120. package/Types/Monitor/SnmpMonitor/SnmpSystemInfo.ts +16 -0
  121. package/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.ts +119 -3
  122. package/Types/NetFlow/NetworkFlowRecord.ts +25 -0
  123. package/Types/Syslog/SyslogMessage.ts +18 -0
  124. package/Types/Telemetry/TelemetrySavedViewState.ts +9 -0
  125. package/Types/Telemetry/TelemetrySavedViewType.ts +12 -0
  126. package/UI/Components/Charts/Area/AreaChart.tsx +51 -0
  127. package/UI/Components/Charts/Bar/BarChart.tsx +51 -1
  128. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +97 -26
  129. package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +328 -1
  130. package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +115 -0
  131. package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +328 -1
  132. package/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.ts +7 -0
  133. package/UI/Components/Charts/ChartLibrary/Types/FormattedReferenceRegion.ts +15 -0
  134. package/UI/Components/Charts/ChartLibrary/Types/FormattedTimeReferenceLine.ts +13 -0
  135. package/UI/Components/Charts/Line/LineChart.tsx +51 -0
  136. package/UI/Components/Charts/Types/ReferenceRegionProps.ts +12 -0
  137. package/UI/Components/Charts/Types/TimeReferenceLineProps.ts +12 -0
  138. package/UI/Components/Charts/Types/XAxis/XAxisPrecision.ts +1 -0
  139. package/UI/Components/Charts/Utils/DataPoint.ts +0 -0
  140. package/UI/Components/Charts/Utils/TimeAnnotation.ts +169 -0
  141. package/UI/Components/Charts/Utils/XAxis.ts +28 -4
  142. package/UI/Components/Icon/Icon.tsx +33 -13
  143. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +9 -0
  144. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +67 -0
  145. package/UI/Components/Page/ModelPage.tsx +6 -1
  146. package/UI/Components/TelemetryViewer/components/SavedViewsDropdown.tsx +33 -4
  147. package/UI/Styles/Theme.css +10 -0
  148. package/UI/Utils/User.ts +41 -2
  149. package/Utils/Analytics.ts +8 -6
  150. package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +74 -0
  151. package/Utils/Metrics/MetricExplorerUrl.ts +771 -0
  152. package/Utils/Metrics/MetricFormulaEvaluator.ts +410 -46
  153. package/Utils/Monitor/NetworkTopologyUtil.ts +261 -49
  154. package/Utils/ValueFormatter.ts +22 -1
  155. package/build/dist/Models/AnalyticsModels/Index.js +13 -0
  156. package/build/dist/Models/AnalyticsModels/Index.js.map +1 -1
  157. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByContainer.js +159 -0
  158. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByContainer.js.map +1 -0
  159. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.js +158 -0
  160. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.js.map +1 -0
  161. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByService.js +160 -0
  162. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByService.js.map +1 -0
  163. package/build/dist/Models/AnalyticsModels/NetworkFlow.js +351 -0
  164. package/build/dist/Models/AnalyticsModels/NetworkFlow.js.map +1 -0
  165. package/build/dist/Models/DatabaseModels/EnterpriseLicenseInstance.js +19 -0
  166. package/build/dist/Models/DatabaseModels/EnterpriseLicenseInstance.js.map +1 -1
  167. package/build/dist/Models/DatabaseModels/GlobalConfig.js +38 -0
  168. package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
  169. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  170. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  171. package/build/dist/Models/DatabaseModels/MarketingConversion.js +219 -0
  172. package/build/dist/Models/DatabaseModels/MarketingConversion.js.map +1 -0
  173. package/build/dist/Models/DatabaseModels/MetricSavedView.js +35 -0
  174. package/build/dist/Models/DatabaseModels/MetricSavedView.js.map +1 -1
  175. package/build/dist/Models/DatabaseModels/MetricType.js +76 -0
  176. package/build/dist/Models/DatabaseModels/MetricType.js.map +1 -1
  177. package/build/dist/Models/DatabaseModels/NetworkDevice.js +341 -0
  178. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  179. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +116 -0
  180. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  181. package/build/dist/Models/DatabaseModels/NetworkInterface.js +60 -0
  182. package/build/dist/Models/DatabaseModels/NetworkInterface.js.map +1 -1
  183. package/build/dist/Models/DatabaseModels/Project.js +38 -0
  184. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  185. package/build/dist/Models/DatabaseModels/User.js +38 -0
  186. package/build/dist/Models/DatabaseModels/User.js.map +1 -1
  187. package/build/dist/Server/API/BaseAnalyticsAPI.js +19 -0
  188. package/build/dist/Server/API/BaseAnalyticsAPI.js.map +1 -1
  189. package/build/dist/Server/API/EnterpriseLicenseAPI.js +8 -0
  190. package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +1 -1
  191. package/build/dist/Server/EnvironmentConfig.js +51 -0
  192. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  193. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784191414522-AddCounterSemanticsToMetricType.js +27 -0
  194. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784191414522-AddCounterSemanticsToMetricType.js.map +1 -0
  195. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784191414600-AddViewTypeToMetricSavedView.js +21 -0
  196. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784191414600-AddViewTypeToMetricSavedView.js.map +1 -0
  197. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784211212164-AddNetworkDeviceInventoryAndDiscoverySchedule.js +47 -0
  198. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784211212164-AddNetworkDeviceInventoryAndDiscoverySchedule.js.map +1 -0
  199. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784218257664-AddEnterpriseLicenseNotificationColumns.js +16 -0
  200. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784218257664-AddEnterpriseLicenseNotificationColumns.js.map +1 -0
  201. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784293516000-AddAttributionColumnsToUserAndProject.js +18 -0
  202. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784293516000-AddAttributionColumnsToUserAndProject.js.map +1 -0
  203. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784298000000-AddMarketingConversionTable.js +20 -0
  204. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784298000000-AddMarketingConversionTable.js.map +1 -0
  205. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +12 -0
  206. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  207. package/build/dist/Server/Services/AnalyticsDatabaseService.js +58 -4
  208. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  209. package/build/dist/Server/Services/IncidentService.js +12 -0
  210. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  211. package/build/dist/Server/Services/Index.js +10 -0
  212. package/build/dist/Server/Services/Index.js.map +1 -1
  213. package/build/dist/Server/Services/MarketingConversionService.js +9 -0
  214. package/build/dist/Server/Services/MarketingConversionService.js.map +1 -0
  215. package/build/dist/Server/Services/MetricItemAggMV1mByContainerService.js +29 -0
  216. package/build/dist/Server/Services/MetricItemAggMV1mByContainerService.js.map +1 -0
  217. package/build/dist/Server/Services/MetricItemAggMV1mByK8sClusterService.js +29 -0
  218. package/build/dist/Server/Services/MetricItemAggMV1mByK8sClusterService.js.map +1 -0
  219. package/build/dist/Server/Services/MetricItemAggMV1mByServiceService.js +29 -0
  220. package/build/dist/Server/Services/MetricItemAggMV1mByServiceService.js.map +1 -0
  221. package/build/dist/Server/Services/MetricService.js +761 -125
  222. package/build/dist/Server/Services/MetricService.js.map +1 -1
  223. package/build/dist/Server/Services/MonitorService.js +18 -5
  224. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  225. package/build/dist/Server/Services/NetworkDeviceOwnerTeamService.js +44 -0
  226. package/build/dist/Server/Services/NetworkDeviceOwnerTeamService.js.map +1 -1
  227. package/build/dist/Server/Services/NetworkDeviceOwnerUserService.js +88 -0
  228. package/build/dist/Server/Services/NetworkDeviceOwnerUserService.js.map +1 -1
  229. package/build/dist/Server/Services/NetworkFlowService.js +9 -0
  230. package/build/dist/Server/Services/NetworkFlowService.js.map +1 -0
  231. package/build/dist/Server/Services/OnCallDutyPolicyService.js +15 -6
  232. package/build/dist/Server/Services/OnCallDutyPolicyService.js.map +1 -1
  233. package/build/dist/Server/Services/ProjectService.js +107 -6
  234. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  235. package/build/dist/Server/Services/SpanService.js +8 -6
  236. package/build/dist/Server/Services/SpanService.js.map +1 -1
  237. package/build/dist/Server/Services/StatusPageService.js +10 -0
  238. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  239. package/build/dist/Server/Services/TeamMemberService.js +11 -0
  240. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  241. package/build/dist/Server/Services/UserService.js +52 -0
  242. package/build/dist/Server/Services/UserService.js.map +1 -1
  243. package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js +33 -7
  244. package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js.map +1 -1
  245. package/build/dist/Server/Utils/Attribution.js +74 -0
  246. package/build/dist/Server/Utils/Attribution.js.map +1 -0
  247. package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js +40 -0
  248. package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js.map +1 -0
  249. package/build/dist/Server/Utils/Marketing/ConversionUploadProviders.js +20 -0
  250. package/build/dist/Server/Utils/Marketing/ConversionUploadProviders.js.map +1 -0
  251. package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js +177 -0
  252. package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js.map +1 -0
  253. package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js +113 -0
  254. package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js.map +1 -0
  255. package/build/dist/Server/Utils/Marketing/Providers/Meta.js +109 -0
  256. package/build/dist/Server/Utils/Marketing/Providers/Meta.js.map +1 -0
  257. package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js +130 -0
  258. package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js.map +1 -0
  259. package/build/dist/Server/Utils/Marketing/Providers/Reddit.js +126 -0
  260. package/build/dist/Server/Utils/Marketing/Providers/Reddit.js.map +1 -0
  261. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +53 -9
  262. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  263. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +21 -10
  264. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  265. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +54 -11
  266. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  267. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +43 -3
  268. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
  269. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +68 -0
  270. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  271. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +15 -0
  272. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
  273. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +100 -15
  274. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
  275. package/build/dist/Server/Utils/ProductAnalytics.js +111 -0
  276. package/build/dist/Server/Utils/ProductAnalytics.js.map +1 -0
  277. package/build/dist/Server/Utils/Telemetry/Telemetry.js +32 -5
  278. package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
  279. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +17 -0
  280. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
  281. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +11 -0
  282. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -1
  283. package/build/dist/Types/BaseDatabase/AggregationInterval.js +11 -0
  284. package/build/dist/Types/BaseDatabase/AggregationInterval.js.map +1 -1
  285. package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js +33 -5
  286. package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js.map +1 -1
  287. package/build/dist/Types/Email/EmailTemplateType.js +2 -0
  288. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  289. package/build/dist/Types/Marketing/MarketingConversion.js +13 -0
  290. package/build/dist/Types/Marketing/MarketingConversion.js.map +1 -0
  291. package/build/dist/Types/Monitor/MonitorMetricType.js +7 -0
  292. package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
  293. package/build/dist/Types/Monitor/MonitorStep.js +6 -0
  294. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  295. package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js +3 -0
  296. package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js.map +1 -1
  297. package/build/dist/Types/Monitor/MonitorType.js +2 -1
  298. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  299. package/build/dist/Types/Monitor/SnmpMonitor/CdpNeighbor.js +2 -0
  300. package/build/dist/Types/Monitor/SnmpMonitor/CdpNeighbor.js.map +1 -0
  301. package/build/dist/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.js +41 -0
  302. package/build/dist/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.js.map +1 -1
  303. package/build/dist/Types/Monitor/SnmpMonitor/SnmpEntityInfo.js +2 -0
  304. package/build/dist/Types/Monitor/SnmpMonitor/SnmpEntityInfo.js.map +1 -0
  305. package/build/dist/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.js +48 -0
  306. package/build/dist/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.js.map +1 -1
  307. package/build/dist/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.js +38 -0
  308. package/build/dist/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.js.map +1 -1
  309. package/build/dist/Types/Monitor/SnmpMonitor/SnmpSystemInfo.js +2 -0
  310. package/build/dist/Types/Monitor/SnmpMonitor/SnmpSystemInfo.js.map +1 -0
  311. package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js +96 -3
  312. package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js.map +1 -1
  313. package/build/dist/Types/NetFlow/NetworkFlowRecord.js +2 -0
  314. package/build/dist/Types/NetFlow/NetworkFlowRecord.js.map +1 -0
  315. package/build/dist/Types/Syslog/SyslogMessage.js +2 -0
  316. package/build/dist/Types/Syslog/SyslogMessage.js.map +1 -0
  317. package/build/dist/Types/Telemetry/TelemetrySavedViewState.js +0 -7
  318. package/build/dist/Types/Telemetry/TelemetrySavedViewState.js.map +1 -1
  319. package/build/dist/Types/Telemetry/TelemetrySavedViewType.js +13 -0
  320. package/build/dist/Types/Telemetry/TelemetrySavedViewType.js.map +1 -0
  321. package/build/dist/UI/Components/Charts/Area/AreaChart.js +25 -1
  322. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  323. package/build/dist/UI/Components/Charts/Bar/BarChart.js +26 -2
  324. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  325. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +36 -12
  326. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  327. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +208 -6
  328. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
  329. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +52 -3
  330. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
  331. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +208 -6
  332. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
  333. package/build/dist/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.js +6 -1
  334. package/build/dist/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.js.map +1 -1
  335. package/build/dist/UI/Components/Charts/ChartLibrary/Types/FormattedReferenceRegion.js +2 -0
  336. package/build/dist/UI/Components/Charts/ChartLibrary/Types/FormattedReferenceRegion.js.map +1 -0
  337. package/build/dist/UI/Components/Charts/ChartLibrary/Types/FormattedTimeReferenceLine.js +2 -0
  338. package/build/dist/UI/Components/Charts/ChartLibrary/Types/FormattedTimeReferenceLine.js.map +1 -0
  339. package/build/dist/UI/Components/Charts/Line/LineChart.js +25 -1
  340. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  341. package/build/dist/UI/Components/Charts/Types/ReferenceRegionProps.js +2 -0
  342. package/build/dist/UI/Components/Charts/Types/ReferenceRegionProps.js.map +1 -0
  343. package/build/dist/UI/Components/Charts/Types/TimeReferenceLineProps.js +2 -0
  344. package/build/dist/UI/Components/Charts/Types/TimeReferenceLineProps.js.map +1 -0
  345. package/build/dist/UI/Components/Charts/Types/XAxis/XAxisPrecision.js +1 -0
  346. package/build/dist/UI/Components/Charts/Types/XAxis/XAxisPrecision.js.map +1 -1
  347. package/build/dist/UI/Components/Charts/Utils/DataPoint.js +0 -0
  348. package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
  349. package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js +121 -0
  350. package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js.map +1 -0
  351. package/build/dist/UI/Components/Charts/Utils/XAxis.js +27 -4
  352. package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
  353. package/build/dist/UI/Components/Icon/Icon.js +15 -8
  354. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  355. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  356. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +58 -0
  357. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
  358. package/build/dist/UI/Components/Page/ModelPage.js +7 -1
  359. package/build/dist/UI/Components/Page/ModelPage.js.map +1 -1
  360. package/build/dist/UI/Components/TelemetryViewer/components/SavedViewsDropdown.js +10 -4
  361. package/build/dist/UI/Components/TelemetryViewer/components/SavedViewsDropdown.js.map +1 -1
  362. package/build/dist/UI/Utils/User.js +35 -2
  363. package/build/dist/UI/Utils/User.js.map +1 -1
  364. package/build/dist/Utils/Analytics.js +8 -5
  365. package/build/dist/Utils/Analytics.js.map +1 -1
  366. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +57 -0
  367. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js.map +1 -1
  368. package/build/dist/Utils/Metrics/MetricExplorerUrl.js +418 -0
  369. package/build/dist/Utils/Metrics/MetricExplorerUrl.js.map +1 -0
  370. package/build/dist/Utils/Metrics/MetricFormulaEvaluator.js +296 -37
  371. package/build/dist/Utils/Metrics/MetricFormulaEvaluator.js.map +1 -1
  372. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +176 -40
  373. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  374. package/build/dist/Utils/ValueFormatter.js +20 -1
  375. package/build/dist/Utils/ValueFormatter.js.map +1 -1
  376. package/package.json +2 -2
@@ -0,0 +1,771 @@
1
+ import Dictionary from "../../Types/Dictionary";
2
+ import JSONFunctions from "../../Types/JSONFunctions";
3
+ import OneUptimeDate from "../../Types/Date";
4
+ import MetricFormulaConfigData from "../../Types/Metrics/MetricFormulaConfigData";
5
+ import MetricQueryConfigData, {
6
+ MetricChartType,
7
+ } from "../../Types/Metrics/MetricQueryConfigData";
8
+ import MetricViewData from "../../Types/Metrics/MetricViewData";
9
+ import MetricsAggregationType from "../../Types/Metrics/MetricsAggregationType";
10
+ import TimeRange from "../../Types/Time/TimeRange";
11
+
12
+ /*
13
+ * Single source of truth for the metric explorer's URL schema — the
14
+ * JSON-encoded `metricQueries` / `metricFormulas` params plus the
15
+ * `startTime` / `endTime` window. Shared between the browser bundle
16
+ * (MetricExplorer's URL round-trip) and the server (incident root-cause
17
+ * deep links built by MonitorCriteriaEvaluator), so it must never import
18
+ * anything that touches window/DOM/UI.
19
+ */
20
+
21
+ export enum MetricExplorerUrlParam {
22
+ MetricQueries = "metricQueries",
23
+ MetricFormulas = "metricFormulas",
24
+ StartTime = "startTime",
25
+ EndTime = "endTime",
26
+ /*
27
+ * Relative-time token (a TimeRange enum value, e.g. "Past 1 Day").
28
+ * Emitted for every relative range — including the default Past 1 Hour,
29
+ * so reloaded/shared links keep rolling instead of pinning — and
30
+ * omitted only for Custom/pinned absolute windows. startTime/endTime
31
+ * always carry the absolute window for back-compat, so older links
32
+ * (which never had a range param) keep working as pinned windows.
33
+ */
34
+ Range = "range",
35
+ }
36
+
37
+ export interface SerializedMetricQueryAlias {
38
+ title?: string | undefined;
39
+ description?: string | undefined;
40
+ legend?: string | undefined;
41
+ legendUnit?: string | undefined;
42
+ }
43
+
44
+ /*
45
+ * Plain-data shape of one query inside the `metricQueries` param. Every
46
+ * field except metricName is optional so links serialized by older
47
+ * versions (which carried only metricName/attributes/aggregationType/
48
+ * alias) keep parsing. Runtime-injected function fields on
49
+ * MetricQueryConfigData (getSeries, yAxisValueFormatter, transformValue)
50
+ * are intentionally absent — they must never serialize.
51
+ */
52
+ export interface SerializedMetricQuery {
53
+ metricName: string;
54
+ /*
55
+ * The query's variable letter (metricAliasData.metricVariable), so
56
+ * formulas referencing it keep resolving after a round-trip even when
57
+ * the live view's variables are not positional (e.g. a lone query
58
+ * named "b" after "a" was deleted). Absent on links serialized by
59
+ * older versions — reconstruction then falls back to positional
60
+ * lettering (a, b, ...).
61
+ */
62
+ variable?: string | undefined;
63
+ attributes?: Dictionary<string | number | boolean> | undefined;
64
+ aggregationType?: MetricsAggregationType | undefined;
65
+ alias?: SerializedMetricQueryAlias | undefined;
66
+ groupByAttributeKeys?: Array<string> | undefined;
67
+ chartType?: MetricChartType | undefined;
68
+ color?: string | undefined;
69
+ colorsByGroup?: Dictionary<string> | undefined;
70
+ warningThreshold?: number | undefined;
71
+ criticalThreshold?: number | undefined;
72
+ transformAsRate?: boolean | undefined;
73
+ overlayWithPreviousQuery?: boolean | undefined;
74
+ topN?: number | undefined;
75
+ }
76
+
77
+ /*
78
+ * Plain-data shape of one formula inside the `metricFormulas` param.
79
+ * Display customization (chart type, color, thresholds) round-trips just
80
+ * like it does for queries — dropping it on share/save would silently
81
+ * lose user work. All of it is optional so older links keep parsing.
82
+ */
83
+ export interface SerializedMetricFormula {
84
+ formula: string;
85
+ variable?: string | undefined;
86
+ alias?: SerializedMetricQueryAlias | undefined;
87
+ chartType?: MetricChartType | undefined;
88
+ color?: string | undefined;
89
+ warningThreshold?: number | undefined;
90
+ criticalThreshold?: number | undefined;
91
+ }
92
+
93
+ export default class MetricExplorerUrl {
94
+ /*
95
+ * Builds the full URL param dictionary for a metric-view state. Keys
96
+ * are only present when they carry a value (empty/meaningless queries
97
+ * and formulas are skipped; the time params are only emitted when both
98
+ * ends of the window exist), so callers can set present keys and
99
+ * delete absent ones. Keyed by MetricExplorerUrlParam values so a
100
+ * future param (e.g. a relative-range token) only needs a new enum
101
+ * member and builder branch.
102
+ */
103
+ public static buildQueryParamsFromMetricViewData(
104
+ data: MetricViewData,
105
+ ): Dictionary<string> {
106
+ const params: Dictionary<string> = {};
107
+
108
+ const queries: Array<SerializedMetricQuery> = data.queryConfigs
109
+ .map((queryConfig: MetricQueryConfigData): SerializedMetricQuery => {
110
+ return MetricExplorerUrl.buildSerializedMetricQuery(queryConfig);
111
+ })
112
+ .filter(MetricExplorerUrl.isMeaningfulMetricQuery);
113
+
114
+ const formulas: Array<SerializedMetricFormula> = data.formulaConfigs
115
+ .map(
116
+ (formulaConfig: MetricFormulaConfigData): SerializedMetricFormula => {
117
+ return MetricExplorerUrl.buildSerializedMetricFormula(formulaConfig);
118
+ },
119
+ )
120
+ .filter(MetricExplorerUrl.isMeaningfulMetricFormula);
121
+
122
+ if (queries.length > 0) {
123
+ params[MetricExplorerUrlParam.MetricQueries] = JSON.stringify(queries);
124
+ }
125
+
126
+ if (formulas.length > 0) {
127
+ params[MetricExplorerUrlParam.MetricFormulas] = JSON.stringify(formulas);
128
+ }
129
+
130
+ const startTimeValue: Date | undefined = data.startAndEndDate?.startValue;
131
+ const endTimeValue: Date | undefined = data.startAndEndDate?.endValue;
132
+
133
+ if (startTimeValue && endTimeValue) {
134
+ params[MetricExplorerUrlParam.StartTime] =
135
+ OneUptimeDate.toString(startTimeValue);
136
+ params[MetricExplorerUrlParam.EndTime] =
137
+ OneUptimeDate.toString(endTimeValue);
138
+ }
139
+
140
+ /*
141
+ * Relative token. Emitted for every relative range — including the
142
+ * default Past 1 Hour, because parsing treats absolute-only params
143
+ * as a pinned Custom window, so leaving the default implicit would
144
+ * silently turn the rolling hour into a frozen window on reload or
145
+ * Copy Link. Custom windows are represented by the absolute params
146
+ * alone (getValidRangeToken filters Custom and garbage).
147
+ */
148
+ const rangeToken: string | undefined = MetricExplorerUrl.getValidRangeToken(
149
+ data.rangeToken,
150
+ );
151
+
152
+ if (rangeToken) {
153
+ params[MetricExplorerUrlParam.Range] = rangeToken;
154
+ }
155
+
156
+ return params;
157
+ }
158
+
159
+ /*
160
+ * Returns the value as a relative TimeRange token when it is a known
161
+ * enum member other than Custom (Custom windows are carried by the
162
+ * absolute startTime/endTime params instead); undefined otherwise.
163
+ */
164
+ public static getValidRangeToken(value: unknown): string | undefined {
165
+ if (typeof value !== "string") {
166
+ return undefined;
167
+ }
168
+
169
+ const knownRanges: Array<string> = Object.values(
170
+ TimeRange,
171
+ ) as Array<string>;
172
+
173
+ if (!knownRanges.includes(value) || value === TimeRange.CUSTOM) {
174
+ return undefined;
175
+ }
176
+
177
+ return value;
178
+ }
179
+
180
+ public static buildSerializedMetricQuery(
181
+ queryConfig: MetricQueryConfigData,
182
+ ): SerializedMetricQuery {
183
+ const filterDataRecord: Record<string, unknown> = queryConfig
184
+ .metricQueryData.filterData as Record<string, unknown>;
185
+
186
+ const metricNameValue: unknown = filterDataRecord["metricName"];
187
+
188
+ const metricName: string =
189
+ typeof metricNameValue === "string" ? metricNameValue : "";
190
+
191
+ const attributes: Dictionary<string | number | boolean> =
192
+ MetricExplorerUrl.sanitizeAttributes(filterDataRecord["attributes"]);
193
+
194
+ const aggregationType: MetricsAggregationType | undefined =
195
+ MetricExplorerUrl.getAggregationTypeFromValue(
196
+ filterDataRecord["aggegationType"],
197
+ );
198
+
199
+ const alias: SerializedMetricQueryAlias | undefined =
200
+ MetricExplorerUrl.buildAliasFromMetricAliasData(
201
+ queryConfig.metricAliasData,
202
+ );
203
+
204
+ const groupByAttributeKeys: Array<string> =
205
+ MetricExplorerUrl.sanitizeGroupByAttributeKeys(
206
+ queryConfig.metricQueryData.groupByAttributeKeys,
207
+ );
208
+
209
+ const chartType: MetricChartType | undefined =
210
+ MetricExplorerUrl.getChartTypeFromValue(queryConfig.chartType);
211
+
212
+ const color: string | undefined =
213
+ typeof queryConfig.color === "string" && queryConfig.color.trim() !== ""
214
+ ? queryConfig.color
215
+ : undefined;
216
+
217
+ const colorsByGroup: Dictionary<string> =
218
+ MetricExplorerUrl.sanitizeColorsByGroup(queryConfig.colorsByGroup);
219
+
220
+ const warningThreshold: number | undefined =
221
+ MetricExplorerUrl.getFiniteNumberFromValue(queryConfig.warningThreshold);
222
+
223
+ const criticalThreshold: number | undefined =
224
+ MetricExplorerUrl.getFiniteNumberFromValue(queryConfig.criticalThreshold);
225
+
226
+ const topN: number | undefined =
227
+ MetricExplorerUrl.getPositiveIntegerFromValue(
228
+ queryConfig.metricQueryData.topN,
229
+ );
230
+
231
+ return {
232
+ metricName,
233
+ ...(queryConfig.metricAliasData?.metricVariable
234
+ ? { variable: queryConfig.metricAliasData.metricVariable }
235
+ : {}),
236
+ attributes,
237
+ ...(aggregationType ? { aggregationType } : {}),
238
+ ...(alias ? { alias } : {}),
239
+ ...(groupByAttributeKeys.length > 0 ? { groupByAttributeKeys } : {}),
240
+ ...(chartType ? { chartType } : {}),
241
+ ...(color ? { color } : {}),
242
+ ...(Object.keys(colorsByGroup).length > 0 ? { colorsByGroup } : {}),
243
+ ...(warningThreshold !== undefined ? { warningThreshold } : {}),
244
+ ...(criticalThreshold !== undefined ? { criticalThreshold } : {}),
245
+ ...(queryConfig.transformAsRate === true
246
+ ? { transformAsRate: true }
247
+ : {}),
248
+ ...(queryConfig.overlayWithPreviousQuery === true
249
+ ? { overlayWithPreviousQuery: true }
250
+ : {}),
251
+ ...(topN !== undefined ? { topN } : {}),
252
+ };
253
+ }
254
+
255
+ public static buildSerializedMetricFormula(
256
+ formulaConfig: MetricFormulaConfigData,
257
+ ): SerializedMetricFormula {
258
+ const alias: SerializedMetricQueryAlias | undefined =
259
+ MetricExplorerUrl.buildAliasFromMetricAliasData(
260
+ formulaConfig.metricAliasData,
261
+ );
262
+
263
+ const chartType: MetricChartType | undefined =
264
+ MetricExplorerUrl.getChartTypeFromValue(formulaConfig.chartType);
265
+
266
+ const color: string | undefined =
267
+ typeof formulaConfig.color === "string" &&
268
+ formulaConfig.color.trim() !== ""
269
+ ? formulaConfig.color
270
+ : undefined;
271
+
272
+ const warningThreshold: number | undefined =
273
+ MetricExplorerUrl.getFiniteNumberFromValue(
274
+ formulaConfig.warningThreshold,
275
+ );
276
+
277
+ const criticalThreshold: number | undefined =
278
+ MetricExplorerUrl.getFiniteNumberFromValue(
279
+ formulaConfig.criticalThreshold,
280
+ );
281
+
282
+ return {
283
+ formula: formulaConfig.metricFormulaData?.metricFormula || "",
284
+ ...(formulaConfig.metricAliasData?.metricVariable
285
+ ? { variable: formulaConfig.metricAliasData.metricVariable }
286
+ : {}),
287
+ ...(alias ? { alias } : {}),
288
+ ...(chartType ? { chartType } : {}),
289
+ ...(color ? { color } : {}),
290
+ ...(warningThreshold !== undefined ? { warningThreshold } : {}),
291
+ ...(criticalThreshold !== undefined ? { criticalThreshold } : {}),
292
+ };
293
+ }
294
+
295
+ /*
296
+ * Parses the JSON-encoded `metricQueries` param. Defensive by design:
297
+ * malformed JSON or a non-array yields [], garbage entries are skipped,
298
+ * wrong-typed fields are dropped, unknown fields are ignored — the
299
+ * result is always safe plain data. Older links carrying only a subset
300
+ * of fields parse fine because everything except metricName defaults.
301
+ */
302
+ public static parseMetricQueriesParam(
303
+ raw: string,
304
+ ): Array<SerializedMetricQuery> {
305
+ let parsedValue: unknown = null;
306
+
307
+ try {
308
+ parsedValue = JSONFunctions.parse(raw);
309
+ } catch {
310
+ return [];
311
+ }
312
+
313
+ if (!Array.isArray(parsedValue)) {
314
+ return [];
315
+ }
316
+
317
+ const sanitizedQueries: Array<SerializedMetricQuery> = [];
318
+
319
+ for (const entry of parsedValue) {
320
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
321
+ continue;
322
+ }
323
+
324
+ const entryRecord: Record<string, unknown> = entry as Record<
325
+ string,
326
+ unknown
327
+ >;
328
+
329
+ const metricName: string =
330
+ typeof entryRecord["metricName"] === "string"
331
+ ? (entryRecord["metricName"] as string)
332
+ : "";
333
+
334
+ const variable: string | undefined =
335
+ typeof entryRecord["variable"] === "string"
336
+ ? (entryRecord["variable"] as string)
337
+ : undefined;
338
+
339
+ const attributes: Dictionary<string | number | boolean> =
340
+ MetricExplorerUrl.sanitizeAttributes(entryRecord["attributes"]);
341
+
342
+ const aggregationType: MetricsAggregationType | undefined =
343
+ MetricExplorerUrl.getAggregationTypeFromValue(
344
+ entryRecord["aggregationType"],
345
+ );
346
+
347
+ const alias: SerializedMetricQueryAlias | undefined =
348
+ MetricExplorerUrl.sanitizeAlias(entryRecord["alias"], entryRecord);
349
+
350
+ const groupByAttributeKeys: Array<string> =
351
+ MetricExplorerUrl.sanitizeGroupByAttributeKeys(
352
+ entryRecord["groupByAttributeKeys"],
353
+ );
354
+
355
+ const chartType: MetricChartType | undefined =
356
+ MetricExplorerUrl.getChartTypeFromValue(entryRecord["chartType"]);
357
+
358
+ const color: string | undefined =
359
+ typeof entryRecord["color"] === "string" &&
360
+ (entryRecord["color"] as string).trim() !== ""
361
+ ? (entryRecord["color"] as string)
362
+ : undefined;
363
+
364
+ const colorsByGroup: Dictionary<string> =
365
+ MetricExplorerUrl.sanitizeColorsByGroup(entryRecord["colorsByGroup"]);
366
+
367
+ const warningThreshold: number | undefined =
368
+ MetricExplorerUrl.getFiniteNumberFromValue(
369
+ entryRecord["warningThreshold"],
370
+ );
371
+
372
+ const criticalThreshold: number | undefined =
373
+ MetricExplorerUrl.getFiniteNumberFromValue(
374
+ entryRecord["criticalThreshold"],
375
+ );
376
+
377
+ const topN: number | undefined =
378
+ MetricExplorerUrl.getPositiveIntegerFromValue(entryRecord["topN"]);
379
+
380
+ sanitizedQueries.push({
381
+ metricName,
382
+ ...(variable ? { variable } : {}),
383
+ attributes,
384
+ ...(aggregationType ? { aggregationType } : {}),
385
+ ...(alias ? { alias } : {}),
386
+ ...(groupByAttributeKeys.length > 0 ? { groupByAttributeKeys } : {}),
387
+ ...(chartType ? { chartType } : {}),
388
+ ...(color ? { color } : {}),
389
+ ...(Object.keys(colorsByGroup).length > 0 ? { colorsByGroup } : {}),
390
+ ...(warningThreshold !== undefined ? { warningThreshold } : {}),
391
+ ...(criticalThreshold !== undefined ? { criticalThreshold } : {}),
392
+ ...(entryRecord["transformAsRate"] === true
393
+ ? { transformAsRate: true }
394
+ : {}),
395
+ ...(entryRecord["overlayWithPreviousQuery"] === true
396
+ ? { overlayWithPreviousQuery: true }
397
+ : {}),
398
+ ...(topN !== undefined ? { topN } : {}),
399
+ });
400
+ }
401
+
402
+ return sanitizedQueries;
403
+ }
404
+
405
+ public static parseMetricFormulasParam(
406
+ raw: string,
407
+ ): Array<SerializedMetricFormula> {
408
+ let parsedValue: unknown = null;
409
+
410
+ try {
411
+ parsedValue = JSONFunctions.parse(raw);
412
+ } catch {
413
+ return [];
414
+ }
415
+
416
+ if (!Array.isArray(parsedValue)) {
417
+ return [];
418
+ }
419
+
420
+ const formulas: Array<SerializedMetricFormula> = [];
421
+
422
+ for (const entry of parsedValue) {
423
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
424
+ continue;
425
+ }
426
+
427
+ const entryRecord: Record<string, unknown> = entry as Record<
428
+ string,
429
+ unknown
430
+ >;
431
+
432
+ const formula: string =
433
+ typeof entryRecord["formula"] === "string"
434
+ ? (entryRecord["formula"] as string)
435
+ : "";
436
+
437
+ if (!formula) {
438
+ continue;
439
+ }
440
+
441
+ const variable: string | undefined =
442
+ typeof entryRecord["variable"] === "string"
443
+ ? (entryRecord["variable"] as string)
444
+ : undefined;
445
+
446
+ const alias: SerializedMetricQueryAlias | undefined =
447
+ MetricExplorerUrl.sanitizeAlias(entryRecord["alias"], entryRecord);
448
+
449
+ const chartType: MetricChartType | undefined =
450
+ MetricExplorerUrl.getChartTypeFromValue(entryRecord["chartType"]);
451
+
452
+ const color: string | undefined =
453
+ typeof entryRecord["color"] === "string" &&
454
+ (entryRecord["color"] as string).trim() !== ""
455
+ ? (entryRecord["color"] as string)
456
+ : undefined;
457
+
458
+ const warningThreshold: number | undefined =
459
+ MetricExplorerUrl.getFiniteNumberFromValue(
460
+ entryRecord["warningThreshold"],
461
+ );
462
+
463
+ const criticalThreshold: number | undefined =
464
+ MetricExplorerUrl.getFiniteNumberFromValue(
465
+ entryRecord["criticalThreshold"],
466
+ );
467
+
468
+ formulas.push({
469
+ formula,
470
+ ...(variable ? { variable } : {}),
471
+ ...(alias ? { alias } : {}),
472
+ ...(chartType ? { chartType } : {}),
473
+ ...(color ? { color } : {}),
474
+ ...(warningThreshold !== undefined ? { warningThreshold } : {}),
475
+ ...(criticalThreshold !== undefined ? { criticalThreshold } : {}),
476
+ });
477
+ }
478
+
479
+ return formulas;
480
+ }
481
+
482
+ /*
483
+ * A query earns a spot in the URL if it selects any data (name,
484
+ * attribute filters, non-default aggregation, group-by) OR carries any
485
+ * display-only customization (alias text, chart type, colors,
486
+ * thresholds, rate/overlay transforms) — dropping those on share would
487
+ * silently lose user work.
488
+ */
489
+ public static isMeaningfulMetricQuery(query: SerializedMetricQuery): boolean {
490
+ if (query.metricName) {
491
+ return true;
492
+ }
493
+
494
+ if (query.attributes && Object.keys(query.attributes).length > 0) {
495
+ return true;
496
+ }
497
+
498
+ if (
499
+ query.aggregationType &&
500
+ query.aggregationType !== MetricsAggregationType.Avg
501
+ ) {
502
+ return true;
503
+ }
504
+
505
+ if (query.alias && Object.keys(query.alias).length > 0) {
506
+ return true;
507
+ }
508
+
509
+ if (query.groupByAttributeKeys && query.groupByAttributeKeys.length > 0) {
510
+ return true;
511
+ }
512
+
513
+ if (query.chartType) {
514
+ return true;
515
+ }
516
+
517
+ if (query.color) {
518
+ return true;
519
+ }
520
+
521
+ if (query.colorsByGroup && Object.keys(query.colorsByGroup).length > 0) {
522
+ return true;
523
+ }
524
+
525
+ if (
526
+ query.warningThreshold !== undefined ||
527
+ query.criticalThreshold !== undefined
528
+ ) {
529
+ return true;
530
+ }
531
+
532
+ if (query.transformAsRate === true) {
533
+ return true;
534
+ }
535
+
536
+ if (query.overlayWithPreviousQuery === true) {
537
+ return true;
538
+ }
539
+
540
+ if (query.topN !== undefined) {
541
+ return true;
542
+ }
543
+
544
+ return false;
545
+ }
546
+
547
+ public static isMeaningfulMetricFormula(
548
+ formula: SerializedMetricFormula,
549
+ ): boolean {
550
+ return Boolean(formula.formula && formula.formula.trim());
551
+ }
552
+
553
+ public static sanitizeAttributes(
554
+ value: unknown,
555
+ ): Dictionary<string | number | boolean> {
556
+ if (value === null || value === undefined) {
557
+ return {};
558
+ }
559
+
560
+ let candidate: unknown = value;
561
+
562
+ if (typeof value === "string") {
563
+ try {
564
+ candidate = JSONFunctions.parse(value);
565
+ } catch {
566
+ return {};
567
+ }
568
+ }
569
+
570
+ if (
571
+ !candidate ||
572
+ typeof candidate !== "object" ||
573
+ Array.isArray(candidate)
574
+ ) {
575
+ return {};
576
+ }
577
+
578
+ const attributes: Dictionary<string | number | boolean> = {};
579
+
580
+ for (const key in candidate as Record<string, unknown>) {
581
+ const attributeValue: unknown = (candidate as Record<string, unknown>)[
582
+ key
583
+ ];
584
+
585
+ if (
586
+ typeof attributeValue === "string" ||
587
+ typeof attributeValue === "number" ||
588
+ typeof attributeValue === "boolean"
589
+ ) {
590
+ attributes[key] = attributeValue;
591
+ }
592
+ }
593
+
594
+ return attributes;
595
+ }
596
+
597
+ private static buildAliasFromMetricAliasData(
598
+ data: MetricQueryConfigData["metricAliasData"],
599
+ ): SerializedMetricQueryAlias | undefined {
600
+ if (!data) {
601
+ return undefined;
602
+ }
603
+
604
+ const alias: SerializedMetricQueryAlias = {};
605
+
606
+ if (typeof data.title === "string" && data.title.trim() !== "") {
607
+ alias.title = data.title;
608
+ }
609
+
610
+ if (
611
+ typeof data.description === "string" &&
612
+ data.description.trim() !== ""
613
+ ) {
614
+ alias.description = data.description;
615
+ }
616
+
617
+ if (typeof data.legend === "string" && data.legend.trim() !== "") {
618
+ alias.legend = data.legend;
619
+ }
620
+
621
+ if (typeof data.legendUnit === "string" && data.legendUnit.trim() !== "") {
622
+ alias.legendUnit = data.legendUnit;
623
+ }
624
+
625
+ return Object.keys(alias).length > 0 ? alias : undefined;
626
+ }
627
+
628
+ private static sanitizeAlias(
629
+ value: unknown,
630
+ fallback?: Record<string, unknown>,
631
+ ): SerializedMetricQueryAlias | undefined {
632
+ const alias: SerializedMetricQueryAlias = {};
633
+
634
+ if (value && typeof value === "object" && !Array.isArray(value)) {
635
+ const aliasRecord: Record<string, unknown> = value as Record<
636
+ string,
637
+ unknown
638
+ >;
639
+
640
+ if (typeof aliasRecord["title"] === "string") {
641
+ alias.title = aliasRecord["title"] as string;
642
+ }
643
+
644
+ if (typeof aliasRecord["description"] === "string") {
645
+ alias.description = aliasRecord["description"] as string;
646
+ }
647
+
648
+ if (typeof aliasRecord["legend"] === "string") {
649
+ alias.legend = aliasRecord["legend"] as string;
650
+ }
651
+
652
+ if (typeof aliasRecord["legendUnit"] === "string") {
653
+ alias.legendUnit = aliasRecord["legendUnit"] as string;
654
+ }
655
+ }
656
+
657
+ // Backward compatibility: allow flat keys on the main query record.
658
+ if (fallback) {
659
+ if (alias.title === undefined && typeof fallback["title"] === "string") {
660
+ alias.title = fallback["title"] as string;
661
+ }
662
+
663
+ if (
664
+ alias.description === undefined &&
665
+ typeof fallback["description"] === "string"
666
+ ) {
667
+ alias.description = fallback["description"] as string;
668
+ }
669
+
670
+ if (
671
+ alias.legend === undefined &&
672
+ typeof fallback["legend"] === "string"
673
+ ) {
674
+ alias.legend = fallback["legend"] as string;
675
+ }
676
+
677
+ if (
678
+ alias.legendUnit === undefined &&
679
+ typeof fallback["legendUnit"] === "string"
680
+ ) {
681
+ alias.legendUnit = fallback["legendUnit"] as string;
682
+ }
683
+ }
684
+
685
+ return Object.keys(alias).length > 0 ? alias : undefined;
686
+ }
687
+
688
+ private static getAggregationTypeFromValue(
689
+ value: unknown,
690
+ ): MetricsAggregationType | undefined {
691
+ if (typeof value === "string") {
692
+ const aggregationTypeValues: Array<string> = Object.values(
693
+ MetricsAggregationType,
694
+ ) as Array<string>;
695
+
696
+ if (aggregationTypeValues.includes(value)) {
697
+ return value as MetricsAggregationType;
698
+ }
699
+ }
700
+
701
+ return undefined;
702
+ }
703
+
704
+ private static getChartTypeFromValue(
705
+ value: unknown,
706
+ ): MetricChartType | undefined {
707
+ if (typeof value === "string") {
708
+ const chartTypeValues: Array<string> = Object.values(
709
+ MetricChartType,
710
+ ) as Array<string>;
711
+
712
+ if (chartTypeValues.includes(value)) {
713
+ return value as MetricChartType;
714
+ }
715
+ }
716
+
717
+ return undefined;
718
+ }
719
+
720
+ private static getFiniteNumberFromValue(value: unknown): number | undefined {
721
+ if (typeof value === "number" && Number.isFinite(value)) {
722
+ return value;
723
+ }
724
+
725
+ return undefined;
726
+ }
727
+
728
+ private static getPositiveIntegerFromValue(
729
+ value: unknown,
730
+ ): number | undefined {
731
+ if (typeof value === "number" && Number.isInteger(value) && value > 0) {
732
+ return value;
733
+ }
734
+
735
+ return undefined;
736
+ }
737
+
738
+ private static sanitizeGroupByAttributeKeys(value: unknown): Array<string> {
739
+ if (!Array.isArray(value)) {
740
+ return [];
741
+ }
742
+
743
+ const keys: Array<string> = [];
744
+
745
+ for (const entry of value) {
746
+ if (typeof entry === "string" && entry.trim() !== "") {
747
+ keys.push(entry);
748
+ }
749
+ }
750
+
751
+ return keys;
752
+ }
753
+
754
+ private static sanitizeColorsByGroup(value: unknown): Dictionary<string> {
755
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
756
+ return {};
757
+ }
758
+
759
+ const colorsByGroup: Dictionary<string> = {};
760
+
761
+ for (const key in value as Record<string, unknown>) {
762
+ const colorValue: unknown = (value as Record<string, unknown>)[key];
763
+
764
+ if (typeof colorValue === "string" && colorValue.trim() !== "") {
765
+ colorsByGroup[key] = colorValue;
766
+ }
767
+ }
768
+
769
+ return colorsByGroup;
770
+ }
771
+ }