@oneuptime/common 12.0.5 → 12.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (528) hide show
  1. package/Models/DatabaseModels/AIRun.ts +33 -0
  2. package/Models/DatabaseModels/DataSource.ts +744 -0
  3. package/Models/DatabaseModels/Index.ts +3 -0
  4. package/Models/DatabaseModels/ProjectCallSMSConfig.ts +10 -2
  5. package/Models/DatabaseModels/User.ts +2 -0
  6. package/Models/DatabaseModels/UserOnCallLog.ts +2 -0
  7. package/Models/DatabaseModels/UserOnCallLogTimeline.ts +2 -0
  8. package/Models/DatabaseModels/UserSession.ts +2 -0
  9. package/Models/DatabaseModels/UserTotpAuth.ts +6 -4
  10. package/Models/DatabaseModels/UserWebAuthn.ts +5 -3
  11. package/Server/API/AIInsightAPI.ts +47 -4
  12. package/Server/API/AIInvestigationAPI.ts +25 -0
  13. package/Server/API/DashboardAPI.ts +176 -492
  14. package/Server/API/DataSourceAPI.ts +268 -0
  15. package/Server/API/StatusPageAPI.ts +11 -1
  16. package/Server/API/UserAPI.ts +119 -0
  17. package/Server/Infrastructure/ClickhouseConfig.ts +59 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.ts +39 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.ts +24 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.ts +76 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  22. package/Server/Infrastructure/Queue.ts +26 -0
  23. package/Server/Infrastructure/QueueWorker.ts +17 -0
  24. package/Server/Middleware/TelemetryIngest.ts +8 -3
  25. package/Server/Services/AIInsightService.ts +132 -12
  26. package/Server/Services/AIRunService.ts +34 -0
  27. package/Server/Services/AIService.ts +17 -2
  28. package/Server/Services/AlertService.ts +38 -32
  29. package/Server/Services/AnalyticsDatabaseService.ts +8 -4
  30. package/Server/Services/DataSourceService.ts +200 -0
  31. package/Server/Services/HostService.ts +92 -0
  32. package/Server/Services/IncidentService.ts +45 -0
  33. package/Server/Services/Index.ts +2 -0
  34. package/Server/Services/MonitorService.ts +49 -0
  35. package/Server/Services/MonitorStatusService.ts +166 -0
  36. package/Server/Services/OpenTelemetryIngestService.ts +255 -184
  37. package/Server/Services/RumSessionPinService.ts +7 -21
  38. package/Server/Services/StatusPageSubscriberService.ts +13 -0
  39. package/Server/Services/UserService.ts +280 -9
  40. package/Server/Static/Vendor/README.md +62 -0
  41. package/Server/Static/Vendor/fonts/InterVariable.woff2 +0 -0
  42. package/Server/Static/Vendor/highlight/highlight.min.js +1244 -0
  43. package/Server/Static/Vendor/highlight/languages/apache.min.js +15 -0
  44. package/Server/Static/Vendor/highlight/languages/bash.min.js +21 -0
  45. package/Server/Static/Vendor/highlight/languages/c.min.js +41 -0
  46. package/Server/Static/Vendor/highlight/languages/cpp.min.js +47 -0
  47. package/Server/Static/Vendor/highlight/languages/csharp.min.js +49 -0
  48. package/Server/Static/Vendor/highlight/languages/css.min.js +31 -0
  49. package/Server/Static/Vendor/highlight/languages/diff.min.js +9 -0
  50. package/Server/Static/Vendor/highlight/languages/dns.min.js +11 -0
  51. package/Server/Static/Vendor/highlight/languages/dockerfile.min.js +8 -0
  52. package/Server/Static/Vendor/highlight/languages/go.min.js +20 -0
  53. package/Server/Static/Vendor/highlight/languages/graphql.min.js +12 -0
  54. package/Server/Static/Vendor/highlight/languages/http.min.js +14 -0
  55. package/Server/Static/Vendor/highlight/languages/ini.min.js +15 -0
  56. package/Server/Static/Vendor/highlight/languages/java.min.js +38 -0
  57. package/Server/Static/Vendor/highlight/languages/javascript.min.js +81 -0
  58. package/Server/Static/Vendor/highlight/languages/json.min.js +8 -0
  59. package/Server/Static/Vendor/highlight/languages/kotlin.min.js +46 -0
  60. package/Server/Static/Vendor/highlight/languages/lua.min.js +15 -0
  61. package/Server/Static/Vendor/highlight/languages/makefile.min.js +14 -0
  62. package/Server/Static/Vendor/highlight/languages/nginx.min.js +21 -0
  63. package/Server/Static/Vendor/highlight/languages/perl.min.js +41 -0
  64. package/Server/Static/Vendor/highlight/languages/php.min.js +59 -0
  65. package/Server/Static/Vendor/highlight/languages/powershell.min.js +39 -0
  66. package/Server/Static/Vendor/highlight/languages/python.min.js +42 -0
  67. package/Server/Static/Vendor/highlight/languages/r.min.js +26 -0
  68. package/Server/Static/Vendor/highlight/languages/ruby.min.js +54 -0
  69. package/Server/Static/Vendor/highlight/languages/rust.min.js +27 -0
  70. package/Server/Static/Vendor/highlight/languages/scala.min.js +28 -0
  71. package/Server/Static/Vendor/highlight/languages/sql.min.js +21 -0
  72. package/Server/Static/Vendor/highlight/languages/swift.min.js +68 -0
  73. package/Server/Static/Vendor/highlight/languages/typescript.min.js +99 -0
  74. package/Server/Static/Vendor/highlight/languages/xml.min.js +29 -0
  75. package/Server/Static/Vendor/highlight/languages/yaml.min.js +28 -0
  76. package/Server/Static/Vendor/highlight/styles/github-dark.min.css +10 -0
  77. package/Server/Static/Vendor/highlight/styles/vs2015.min.css +1 -0
  78. package/Server/Static/Vendor/tailwind/tailwind-3.4.5.js +21028 -0
  79. package/Server/Types/Database/Permissions/BasePermission.ts +7 -0
  80. package/Server/Types/Database/Permissions/DeletePermission.ts +2 -0
  81. package/Server/Types/Database/Permissions/ReadPermission.ts +3 -0
  82. package/Server/Types/Database/Permissions/TenantPermission.ts +101 -16
  83. package/Server/Utils/AI/CodeFix/FixRunBudget.ts +2 -2
  84. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +90 -11
  85. package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +1 -0
  86. package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +1 -0
  87. package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.ts +125 -0
  88. package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts +25 -15
  89. package/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts +256 -57
  90. package/Server/Utils/AI/SRE/Insights/InsightStore.ts +76 -18
  91. package/Server/Utils/AI/SRE/InvestigationTldr.ts +352 -0
  92. package/Server/Utils/AnalyticsDatabase/InsertDedupContext.ts +7 -2
  93. package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +1793 -0
  94. package/Server/Utils/Dashboard/PublicDashboardViewConfig.ts +65 -0
  95. package/Server/Utils/DataSource/ConnectorRegistry.ts +53 -0
  96. package/Server/Utils/DataSource/Connectors/ClickHouseConnector.ts +338 -0
  97. package/Server/Utils/DataSource/Connectors/ElasticsearchConnector.ts +717 -0
  98. package/Server/Utils/DataSource/Connectors/LokiConnector.ts +606 -0
  99. package/Server/Utils/DataSource/Connectors/MySqlConnector.ts +307 -0
  100. package/Server/Utils/DataSource/Connectors/PostgresConnector.ts +260 -0
  101. package/Server/Utils/DataSource/Connectors/PrometheusConnector.ts +555 -0
  102. package/Server/Utils/DataSource/Connectors/RestApiConnector.ts +597 -0
  103. package/Server/Utils/DataSource/Connectors/SqlServerConnector.ts +318 -0
  104. package/Server/Utils/DataSource/EgressGuard.ts +446 -0
  105. package/Server/Utils/DataSource/HttpFetch.ts +221 -0
  106. package/Server/Utils/DataSource/SqlQueryGuard.ts +383 -0
  107. package/Server/Utils/DataSource/SqlResultShaper.ts +372 -0
  108. package/Server/Utils/DataSource/Types.ts +93 -0
  109. package/Server/Utils/Database/PostgresErrorTranslator.ts +172 -17
  110. package/Server/Utils/InProcessMemo.ts +141 -0
  111. package/Server/Utils/InstanceHealth/TelemetryIngestion.ts +628 -0
  112. package/Server/Utils/Monitor/MonitorMetricUtil.ts +58 -0
  113. package/Server/Utils/Monitor/MonitorResource.ts +14 -0
  114. package/Server/Utils/Response.ts +12 -1
  115. package/Server/Utils/SSRFProtection.ts +237 -0
  116. package/Server/Utils/StartServer.ts +8 -0
  117. package/Server/Utils/StatusPageSubscriberWebhook.ts +30 -0
  118. package/Server/Utils/Telemetry/CaptureSpan.ts +30 -18
  119. package/Server/Utils/Telemetry/IngestionTimestamp.ts +75 -0
  120. package/Server/Utils/Telemetry/ResourceHeartbeat.ts +99 -7
  121. package/Server/Utils/Telemetry/Telemetry.ts +112 -1
  122. package/Server/Utils/Telemetry.ts +104 -3
  123. package/Server/Utils/VendorAssets.ts +165 -0
  124. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +28 -5
  125. package/Server/Utils/Workspace/Slack/Slack.ts +5 -0
  126. package/Server/Views/Partials/Head.ejs +21 -7
  127. package/Tests/App/AdminDashboard/AdminProjectsIdFilter.test.tsx +207 -0
  128. package/Tests/App/AdminDashboard/AdminUsersIdFilter.test.tsx +216 -0
  129. package/Tests/App/Dashboard/AIInsightViewActions.test.tsx +422 -0
  130. package/Tests/App/Dashboard/AddWidgetModal.test.tsx +10 -3
  131. package/Tests/App/Dashboard/AlertsSideMenu.test.tsx +387 -0
  132. package/Tests/App/Dashboard/ChatActivityFeed.test.tsx +199 -0
  133. package/Tests/App/Dashboard/DataSourceChartSyntheticConfig.test.tsx +736 -0
  134. package/Tests/App/Dashboard/DataSourceQueryEditor.test.tsx +868 -0
  135. package/Tests/App/Dashboard/DataSourceWidgetCatalog.test.ts +440 -0
  136. package/Tests/App/Dashboard/DataSourceWidgetFetching.test.tsx +2109 -0
  137. package/Tests/App/Dashboard/DataSourceWidgetViews.test.tsx +726 -0
  138. package/Tests/App/Dashboard/IncidentsSideMenu.test.tsx +447 -0
  139. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +514 -3
  140. package/Tests/App/Dashboard/ProductMenuBreadcrumbs.test.tsx +391 -0
  141. package/Tests/App/Dashboard/ScheduledMaintenanceSideMenu.test.tsx +326 -0
  142. package/Tests/App/Dashboard/SideMenuHarness.tsx +187 -0
  143. package/Tests/App/Dashboard/WidgetCatalog.test.ts +6 -1
  144. package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +1858 -0
  145. package/Tests/Models/DatabaseModels/DataSourceModelSecrets.test.ts +70 -0
  146. package/Tests/Server/API/AIInvestigationAPI.test.ts +187 -0
  147. package/Tests/Server/API/DashboardPublicDataSourceStrip.test.ts +686 -0
  148. package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +585 -823
  149. package/Tests/Server/API/DataSourceAPIRoutes.test.ts +486 -0
  150. package/Tests/Server/API/StatusPageSubscriberOwnership.test.ts +291 -0
  151. package/Tests/Server/API/UserAuthenticationAPI.test.ts +641 -0
  152. package/Tests/Server/Infrastructure/ClickhouseKeepAliveOptions.test.ts +441 -0
  153. package/Tests/Server/Middleware/TelemetryIngestTokenLog.test.ts +140 -0
  154. package/Tests/Server/Services/AIInsightService.test.ts +266 -11
  155. package/Tests/Server/Services/AIRunAnalysisTldrPersistence.test.ts +160 -0
  156. package/Tests/Server/Services/AIServiceDailyBudget.test.ts +4 -0
  157. package/Tests/Server/Services/AlertMetricResourceAttributes.test.ts +352 -0
  158. package/Tests/Server/Services/DataSourceServiceSettings.test.ts +244 -0
  159. package/Tests/Server/Services/HostServiceFindOrCreateMemo.test.ts +397 -0
  160. package/Tests/Server/Services/HostServiceUpdateLastSeen.test.ts +41 -2
  161. package/Tests/Server/Services/IncidentMetricResourceAttributes.test.ts +408 -0
  162. package/Tests/Server/Services/MonitorStatusServiceDeleteReferenceCleanup.test.ts +351 -0
  163. package/Tests/Server/Services/MonitorStatusServiceValidation.test.ts +171 -0
  164. package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +398 -0
  165. package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +19 -0
  166. package/Tests/Server/Services/ProjectCallSMSConfigCredentialUniqueness.test.ts +305 -0
  167. package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +36 -1
  168. package/Tests/Server/Services/RumSessionPinUniqueViolationRecovery.test.ts +163 -0
  169. package/Tests/Server/Services/UserAuthenticationService.test.ts +973 -0
  170. package/Tests/Server/Types/Database/ObjectIdColumnQuery.test.ts +262 -0
  171. package/Tests/Server/Types/Database/Permissions/TenantPermission.test.ts +358 -0
  172. package/Tests/Server/Utils/AI/FixRunBudget.test.ts +2 -2
  173. package/Tests/Server/Utils/AI/Insights/ExceptionSpikeDetector.test.ts +6 -1
  174. package/Tests/Server/Utils/AI/Insights/InsightStore.test.ts +121 -4
  175. package/Tests/Server/Utils/AI/Insights/NewExceptionDetector.test.ts +361 -10
  176. package/Tests/Server/Utils/AI/InvestigationSettlement.test.ts +292 -0
  177. package/Tests/Server/Utils/AI/InvestigationTldr.test.ts +623 -0
  178. package/Tests/Server/Utils/AI/InvestigationTldrWiring.test.ts +98 -0
  179. package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +857 -0
  180. package/Tests/Server/Utils/Dashboard/PublicDashboardViewConfig.test.ts +480 -0
  181. package/Tests/Server/Utils/DataSource/ClickHouseConnector.test.ts +759 -0
  182. package/Tests/Server/Utils/DataSource/ConnectorRegistry.test.ts +37 -0
  183. package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +645 -0
  184. package/Tests/Server/Utils/DataSource/ElasticsearchConnector.test.ts +1206 -0
  185. package/Tests/Server/Utils/DataSource/HttpFetch.test.ts +616 -0
  186. package/Tests/Server/Utils/DataSource/LokiConnector.test.ts +970 -0
  187. package/Tests/Server/Utils/DataSource/MySqlConnector.test.ts +935 -0
  188. package/Tests/Server/Utils/DataSource/PostgresConnector.test.ts +854 -0
  189. package/Tests/Server/Utils/DataSource/PrometheusConnector.test.ts +881 -0
  190. package/Tests/Server/Utils/DataSource/RestApiConnector.test.ts +1020 -0
  191. package/Tests/Server/Utils/DataSource/SqlQueryGuard.test.ts +425 -0
  192. package/Tests/Server/Utils/DataSource/SqlResultShaper.test.ts +555 -0
  193. package/Tests/Server/Utils/DataSource/SqlServerConnector.test.ts +934 -0
  194. package/Tests/Server/Utils/Database/PostgresErrorTranslator.test.ts +228 -7
  195. package/Tests/Server/Utils/InProcessMemo.test.ts +292 -0
  196. package/Tests/Server/Utils/InstanceHealth/TelemetryIngestion.test.ts +960 -0
  197. package/Tests/Server/Utils/MicrosoftTeamsWebhookUrlValidation.test.ts +103 -0
  198. package/Tests/Server/Utils/Monitor/MonitorMetricResourceAttributes.test.ts +336 -0
  199. package/Tests/Server/Utils/OfflineAssetHygiene.test.ts +521 -0
  200. package/Tests/Server/Utils/ResponseRenderAnalytics.test.ts +143 -0
  201. package/Tests/Server/Utils/SSRFProtection.test.ts +193 -0
  202. package/Tests/Server/Utils/StatusPageSubscriberWebhook.test.ts +101 -0
  203. package/Tests/Server/Utils/TailwindBuildCopy.test.ts +225 -0
  204. package/Tests/Server/Utils/Telemetry/ResourceHeartbeatL1Memo.test.ts +355 -0
  205. package/Tests/Server/Utils/Telemetry/TelemetryFanInWriter.test.ts +128 -0
  206. package/Tests/Server/Utils/Telemetry/TelemetryUtilAttributeKeys.test.ts +381 -0
  207. package/Tests/Server/Utils/Telemetry.test.ts +87 -0
  208. package/Tests/Server/Utils/VendorAssetIntegrity.test.ts +343 -0
  209. package/Tests/Server/Utils/VendorAssets.test.ts +671 -0
  210. package/Tests/Server/Views/OfflineRender.test.ts +297 -0
  211. package/Tests/Types/Dashboard/DataSourceComponentTypes.test.ts +618 -0
  212. package/Tests/Types/DateClickhouseFormat.test.ts +192 -0
  213. package/Tests/Types/Password.test.ts +363 -0
  214. package/Tests/UI/Components/ConfirmModal.test.tsx +7 -0
  215. package/Tests/UI/Components/ErrorBoundary.test.tsx +53 -0
  216. package/Tests/UI/Components/Modal.test.tsx +281 -1
  217. package/Tests/UI/Components/ObjectIdFilterPipeline.test.tsx +396 -0
  218. package/Tests/UI/Components/StatusPage/ResourceGroupNavigator.test.tsx +1147 -0
  219. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +116 -1
  220. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +2 -0
  221. package/Tests/Utils/Analytics.test.ts +23 -0
  222. package/Tests/Utils/Dashboard/Components/DashboardDataSourceComponents.test.ts +640 -0
  223. package/Tests/Utils/DataSource/DataSourceQueryText.test.ts +138 -0
  224. package/Tests/Utils/DataSource/DataSourceValueReducer.test.ts +526 -0
  225. package/Tests/Utils/Metrics/MetricResourceAttributeUtil.test.ts +691 -0
  226. package/Tests/Utils/StatusPage/GroupHierarchyView.test.ts +1452 -0
  227. package/Tests/Utils/StatusPage/ResourceExplorer.test.ts +931 -0
  228. package/Tests/Utils/Telemetry/CaptureSpanExportGating.test.ts +288 -0
  229. package/Tests/Utils/Telemetry/IngestionTimestamp.test.ts +170 -0
  230. package/Types/AI/AIInsightEvidence.ts +6 -0
  231. package/Types/Analytics/RevenueEvent.ts +31 -0
  232. package/Types/Dashboard/DashboardComponentType.ts +31 -0
  233. package/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.ts +27 -0
  234. package/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.ts +32 -0
  235. package/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.ts +30 -0
  236. package/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.ts +55 -0
  237. package/Types/DataSource/DataSourceLimits.ts +62 -0
  238. package/Types/DataSource/DataSourceQueryConfig.ts +41 -0
  239. package/Types/DataSource/DataSourceTableResult.ts +38 -0
  240. package/Types/DataSource/DataSourceType.ts +213 -0
  241. package/Types/Date.ts +43 -3
  242. package/Types/Password.ts +64 -0
  243. package/Types/Permission.ts +46 -0
  244. package/Types/UserAuthenticationStatus.ts +34 -0
  245. package/UI/Components/Button/Button.tsx +1 -1
  246. package/UI/Components/ErrorBoundary.tsx +459 -108
  247. package/UI/Components/Icon/Icon.tsx +10 -9
  248. package/UI/Components/Modal/ConfirmModal.tsx +6 -1
  249. package/UI/Components/Modal/Modal.tsx +267 -35
  250. package/UI/Components/Modal/ModalFooter.tsx +6 -1
  251. package/UI/Components/MoreMenu/MoreMenu.tsx +19 -4
  252. package/UI/Components/MoreMenu/MoreMenuItem.tsx +6 -1
  253. package/UI/Components/StatusPage/ResourceGrid.tsx +314 -0
  254. package/UI/Components/StatusPage/ResourceGroupNavigator.tsx +808 -0
  255. package/UI/Components/StatusPage/ResourceList.tsx +570 -0
  256. package/UI/Styles/Theme.css +18 -0
  257. package/UI/Utils/API/RequestOptions.ts +7 -0
  258. package/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.ts +1 -0
  259. package/UI/Utils/ModelAPI/ModelAPI.ts +1 -0
  260. package/UI/Utils/TestDataSource.ts +61 -0
  261. package/UI/esbuild-config.js +45 -0
  262. package/Utils/Analytics.ts +15 -0
  263. package/Utils/Dashboard/Components/DashboardDataSourceChartComponent.ts +88 -0
  264. package/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.ts +123 -0
  265. package/Utils/Dashboard/Components/DashboardDataSourceShared.ts +16 -0
  266. package/Utils/Dashboard/Components/DashboardDataSourceTableComponent.ts +72 -0
  267. package/Utils/Dashboard/Components/DashboardDataSourceValueComponent.ts +126 -0
  268. package/Utils/Dashboard/Components/Index.ts +28 -0
  269. package/Utils/DataSource/DataSourceQueryText.ts +94 -0
  270. package/Utils/DataSource/DataSourceValueReducer.ts +156 -0
  271. package/Utils/Metrics/MetricResourceAttributeUtil.ts +380 -0
  272. package/Utils/NetworkDiscovery/ScanTargetUtil.ts +8 -6
  273. package/Utils/StatusPage/GroupHierarchyView.ts +931 -0
  274. package/Utils/StatusPage/ResourceExplorer.ts +853 -0
  275. package/build/dist/Models/DatabaseModels/AIRun.js +34 -0
  276. package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
  277. package/build/dist/Models/DatabaseModels/DataSource.js +774 -0
  278. package/build/dist/Models/DatabaseModels/DataSource.js.map +1 -0
  279. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  280. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  281. package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js +14 -4
  282. package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js.map +1 -1
  283. package/build/dist/Models/DatabaseModels/User.js +2 -0
  284. package/build/dist/Models/DatabaseModels/User.js.map +1 -1
  285. package/build/dist/Models/DatabaseModels/UserOnCallLog.js +2 -0
  286. package/build/dist/Models/DatabaseModels/UserOnCallLog.js.map +1 -1
  287. package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js +2 -0
  288. package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js.map +1 -1
  289. package/build/dist/Models/DatabaseModels/UserSession.js +2 -0
  290. package/build/dist/Models/DatabaseModels/UserSession.js.map +1 -1
  291. package/build/dist/Models/DatabaseModels/UserTotpAuth.js +6 -4
  292. package/build/dist/Models/DatabaseModels/UserTotpAuth.js.map +1 -1
  293. package/build/dist/Models/DatabaseModels/UserWebAuthn.js +5 -3
  294. package/build/dist/Models/DatabaseModels/UserWebAuthn.js.map +1 -1
  295. package/build/dist/Server/API/AIInsightAPI.js +34 -4
  296. package/build/dist/Server/API/AIInsightAPI.js.map +1 -1
  297. package/build/dist/Server/API/AIInvestigationAPI.js +23 -0
  298. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  299. package/build/dist/Server/API/DashboardAPI.js +119 -433
  300. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  301. package/build/dist/Server/API/DataSourceAPI.js +173 -0
  302. package/build/dist/Server/API/DataSourceAPI.js.map +1 -0
  303. package/build/dist/Server/API/StatusPageAPI.js +11 -1
  304. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  305. package/build/dist/Server/API/UserAPI.js +94 -2
  306. package/build/dist/Server/API/UserAPI.js.map +1 -1
  307. package/build/dist/Server/Infrastructure/ClickhouseConfig.js +49 -0
  308. package/build/dist/Server/Infrastructure/ClickhouseConfig.js.map +1 -1
  309. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.js +20 -0
  310. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.js.map +1 -0
  311. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.js +19 -0
  312. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.js.map +1 -0
  313. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.js +64 -0
  314. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.js.map +1 -0
  315. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  316. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  317. package/build/dist/Server/Infrastructure/Queue.js +27 -0
  318. package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
  319. package/build/dist/Server/Infrastructure/QueueWorker.js +13 -0
  320. package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
  321. package/build/dist/Server/Middleware/TelemetryIngest.js +8 -3
  322. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  323. package/build/dist/Server/Services/AIInsightService.js +110 -10
  324. package/build/dist/Server/Services/AIInsightService.js.map +1 -1
  325. package/build/dist/Server/Services/AIRunService.js +34 -0
  326. package/build/dist/Server/Services/AIRunService.js.map +1 -1
  327. package/build/dist/Server/Services/AIService.js +16 -2
  328. package/build/dist/Server/Services/AIService.js.map +1 -1
  329. package/build/dist/Server/Services/AlertService.js +28 -35
  330. package/build/dist/Server/Services/AlertService.js.map +1 -1
  331. package/build/dist/Server/Services/AnalyticsDatabaseService.js +8 -4
  332. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  333. package/build/dist/Server/Services/DataSourceService.js +159 -0
  334. package/build/dist/Server/Services/DataSourceService.js.map +1 -0
  335. package/build/dist/Server/Services/HostService.js +74 -0
  336. package/build/dist/Server/Services/HostService.js.map +1 -1
  337. package/build/dist/Server/Services/IncidentService.js +35 -24
  338. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  339. package/build/dist/Server/Services/Index.js +2 -0
  340. package/build/dist/Server/Services/Index.js.map +1 -1
  341. package/build/dist/Server/Services/MonitorService.js +45 -0
  342. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  343. package/build/dist/Server/Services/MonitorStatusService.js +129 -0
  344. package/build/dist/Server/Services/MonitorStatusService.js.map +1 -1
  345. package/build/dist/Server/Services/OpenTelemetryIngestService.js +222 -159
  346. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  347. package/build/dist/Server/Services/RumSessionPinService.js +7 -15
  348. package/build/dist/Server/Services/RumSessionPinService.js.map +1 -1
  349. package/build/dist/Server/Services/StatusPageSubscriberService.js +10 -0
  350. package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
  351. package/build/dist/Server/Services/UserService.js +241 -10
  352. package/build/dist/Server/Services/UserService.js.map +1 -1
  353. package/build/dist/Server/Types/Database/Permissions/BasePermission.js +6 -0
  354. package/build/dist/Server/Types/Database/Permissions/BasePermission.js.map +1 -1
  355. package/build/dist/Server/Types/Database/Permissions/DeletePermission.js +1 -0
  356. package/build/dist/Server/Types/Database/Permissions/DeletePermission.js.map +1 -1
  357. package/build/dist/Server/Types/Database/Permissions/ReadPermission.js +2 -0
  358. package/build/dist/Server/Types/Database/Permissions/ReadPermission.js.map +1 -1
  359. package/build/dist/Server/Types/Database/Permissions/TenantPermission.js +68 -12
  360. package/build/dist/Server/Types/Database/Permissions/TenantPermission.js.map +1 -1
  361. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +2 -2
  362. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
  363. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +68 -8
  364. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  365. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +1 -0
  366. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
  367. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +1 -0
  368. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
  369. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.js +97 -0
  370. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.js.map +1 -0
  371. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js +17 -15
  372. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js.map +1 -1
  373. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js +178 -54
  374. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js.map +1 -1
  375. package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js +65 -16
  376. package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js.map +1 -1
  377. package/build/dist/Server/Utils/AI/SRE/InvestigationTldr.js +303 -0
  378. package/build/dist/Server/Utils/AI/SRE/InvestigationTldr.js.map +1 -0
  379. package/build/dist/Server/Utils/AnalyticsDatabase/InsertDedupContext.js.map +1 -1
  380. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +1261 -0
  381. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -0
  382. package/build/dist/Server/Utils/Dashboard/PublicDashboardViewConfig.js +47 -0
  383. package/build/dist/Server/Utils/Dashboard/PublicDashboardViewConfig.js.map +1 -0
  384. package/build/dist/Server/Utils/DataSource/ConnectorRegistry.js +42 -0
  385. package/build/dist/Server/Utils/DataSource/ConnectorRegistry.js.map +1 -0
  386. package/build/dist/Server/Utils/DataSource/Connectors/ClickHouseConnector.js +187 -0
  387. package/build/dist/Server/Utils/DataSource/Connectors/ClickHouseConnector.js.map +1 -0
  388. package/build/dist/Server/Utils/DataSource/Connectors/ElasticsearchConnector.js +493 -0
  389. package/build/dist/Server/Utils/DataSource/Connectors/ElasticsearchConnector.js.map +1 -0
  390. package/build/dist/Server/Utils/DataSource/Connectors/LokiConnector.js +399 -0
  391. package/build/dist/Server/Utils/DataSource/Connectors/LokiConnector.js.map +1 -0
  392. package/build/dist/Server/Utils/DataSource/Connectors/MySqlConnector.js +195 -0
  393. package/build/dist/Server/Utils/DataSource/Connectors/MySqlConnector.js.map +1 -0
  394. package/build/dist/Server/Utils/DataSource/Connectors/PostgresConnector.js +149 -0
  395. package/build/dist/Server/Utils/DataSource/Connectors/PostgresConnector.js.map +1 -0
  396. package/build/dist/Server/Utils/DataSource/Connectors/PrometheusConnector.js +362 -0
  397. package/build/dist/Server/Utils/DataSource/Connectors/PrometheusConnector.js.map +1 -0
  398. package/build/dist/Server/Utils/DataSource/Connectors/RestApiConnector.js +342 -0
  399. package/build/dist/Server/Utils/DataSource/Connectors/RestApiConnector.js.map +1 -0
  400. package/build/dist/Server/Utils/DataSource/Connectors/SqlServerConnector.js +186 -0
  401. package/build/dist/Server/Utils/DataSource/Connectors/SqlServerConnector.js.map +1 -0
  402. package/build/dist/Server/Utils/DataSource/EgressGuard.js +305 -0
  403. package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -0
  404. package/build/dist/Server/Utils/DataSource/HttpFetch.js +134 -0
  405. package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -0
  406. package/build/dist/Server/Utils/DataSource/SqlQueryGuard.js +331 -0
  407. package/build/dist/Server/Utils/DataSource/SqlQueryGuard.js.map +1 -0
  408. package/build/dist/Server/Utils/DataSource/SqlResultShaper.js +280 -0
  409. package/build/dist/Server/Utils/DataSource/SqlResultShaper.js.map +1 -0
  410. package/build/dist/Server/Utils/DataSource/Types.js +2 -0
  411. package/build/dist/Server/Utils/DataSource/Types.js.map +1 -0
  412. package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js +103 -9
  413. package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js.map +1 -1
  414. package/build/dist/Server/Utils/InProcessMemo.js +113 -0
  415. package/build/dist/Server/Utils/InProcessMemo.js.map +1 -0
  416. package/build/dist/Server/Utils/InstanceHealth/TelemetryIngestion.js +406 -0
  417. package/build/dist/Server/Utils/InstanceHealth/TelemetryIngestion.js.map +1 -0
  418. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +34 -0
  419. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
  420. package/build/dist/Server/Utils/Monitor/MonitorResource.js +14 -0
  421. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  422. package/build/dist/Server/Utils/Response.js +9 -1
  423. package/build/dist/Server/Utils/Response.js.map +1 -1
  424. package/build/dist/Server/Utils/SSRFProtection.js +192 -0
  425. package/build/dist/Server/Utils/SSRFProtection.js.map +1 -0
  426. package/build/dist/Server/Utils/StartServer.js +7 -0
  427. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  428. package/build/dist/Server/Utils/StatusPageSubscriberWebhook.js +24 -0
  429. package/build/dist/Server/Utils/StatusPageSubscriberWebhook.js.map +1 -1
  430. package/build/dist/Server/Utils/Telemetry/CaptureSpan.js +25 -11
  431. package/build/dist/Server/Utils/Telemetry/CaptureSpan.js.map +1 -1
  432. package/build/dist/Server/Utils/Telemetry/IngestionTimestamp.js +32 -0
  433. package/build/dist/Server/Utils/Telemetry/IngestionTimestamp.js.map +1 -0
  434. package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js +92 -5
  435. package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js.map +1 -1
  436. package/build/dist/Server/Utils/Telemetry/Telemetry.js +92 -6
  437. package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
  438. package/build/dist/Server/Utils/Telemetry.js +93 -6
  439. package/build/dist/Server/Utils/Telemetry.js.map +1 -1
  440. package/build/dist/Server/Utils/VendorAssets.js +121 -0
  441. package/build/dist/Server/Utils/VendorAssets.js.map +1 -0
  442. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +25 -4
  443. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  444. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +5 -0
  445. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  446. package/build/dist/Types/Analytics/RevenueEvent.js +26 -0
  447. package/build/dist/Types/Analytics/RevenueEvent.js.map +1 -0
  448. package/build/dist/Types/Dashboard/DashboardComponentType.js +27 -0
  449. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  450. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.js +2 -0
  451. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.js.map +1 -0
  452. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.js +2 -0
  453. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.js.map +1 -0
  454. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.js +2 -0
  455. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.js.map +1 -0
  456. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.js +16 -0
  457. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.js.map +1 -0
  458. package/build/dist/Types/DataSource/DataSourceLimits.js +47 -0
  459. package/build/dist/Types/DataSource/DataSourceLimits.js.map +1 -0
  460. package/build/dist/Types/DataSource/DataSourceQueryConfig.js +10 -0
  461. package/build/dist/Types/DataSource/DataSourceQueryConfig.js.map +1 -0
  462. package/build/dist/Types/DataSource/DataSourceTableResult.js +14 -0
  463. package/build/dist/Types/DataSource/DataSourceTableResult.js.map +1 -0
  464. package/build/dist/Types/DataSource/DataSourceType.js +183 -0
  465. package/build/dist/Types/DataSource/DataSourceType.js.map +1 -0
  466. package/build/dist/Types/Date.js +38 -3
  467. package/build/dist/Types/Date.js.map +1 -1
  468. package/build/dist/Types/Password.js +56 -0
  469. package/build/dist/Types/Password.js.map +1 -0
  470. package/build/dist/Types/Permission.js +42 -0
  471. package/build/dist/Types/Permission.js.map +1 -1
  472. package/build/dist/Types/UserAuthenticationStatus.js +2 -0
  473. package/build/dist/Types/UserAuthenticationStatus.js.map +1 -0
  474. package/build/dist/UI/Components/ErrorBoundary.js +388 -72
  475. package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
  476. package/build/dist/UI/Components/Icon/Icon.js +10 -4
  477. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  478. package/build/dist/UI/Components/Modal/ConfirmModal.js +1 -1
  479. package/build/dist/UI/Components/Modal/ConfirmModal.js.map +1 -1
  480. package/build/dist/UI/Components/Modal/Modal.js +178 -19
  481. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  482. package/build/dist/UI/Components/Modal/ModalFooter.js +3 -1
  483. package/build/dist/UI/Components/Modal/ModalFooter.js.map +1 -1
  484. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +9 -6
  485. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  486. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +7 -1
  487. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
  488. package/build/dist/UI/Components/StatusPage/ResourceGrid.js +119 -0
  489. package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -0
  490. package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js +354 -0
  491. package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js.map +1 -0
  492. package/build/dist/UI/Components/StatusPage/ResourceList.js +203 -0
  493. package/build/dist/UI/Components/StatusPage/ResourceList.js.map +1 -0
  494. package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js +1 -6
  495. package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js.map +1 -1
  496. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +3 -8
  497. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  498. package/build/dist/UI/Utils/TestDataSource.js +39 -0
  499. package/build/dist/UI/Utils/TestDataSource.js.map +1 -0
  500. package/build/dist/Utils/Analytics.js +4 -0
  501. package/build/dist/Utils/Analytics.js.map +1 -1
  502. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceChartComponent.js +79 -0
  503. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceChartComponent.js.map +1 -0
  504. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.js +111 -0
  505. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.js.map +1 -0
  506. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceShared.js +15 -0
  507. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceShared.js.map +1 -0
  508. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceTableComponent.js +62 -0
  509. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceTableComponent.js.map +1 -0
  510. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceValueComponent.js +112 -0
  511. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceValueComponent.js.map +1 -0
  512. package/build/dist/Utils/Dashboard/Components/Index.js +16 -0
  513. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  514. package/build/dist/Utils/DataSource/DataSourceQueryText.js +64 -0
  515. package/build/dist/Utils/DataSource/DataSourceQueryText.js.map +1 -0
  516. package/build/dist/Utils/DataSource/DataSourceValueReducer.js +124 -0
  517. package/build/dist/Utils/DataSource/DataSourceValueReducer.js.map +1 -0
  518. package/build/dist/Utils/Metrics/MetricResourceAttributeUtil.js +281 -0
  519. package/build/dist/Utils/Metrics/MetricResourceAttributeUtil.js.map +1 -0
  520. package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js +8 -6
  521. package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js.map +1 -1
  522. package/build/dist/Utils/StatusPage/GroupHierarchyView.js +560 -0
  523. package/build/dist/Utils/StatusPage/GroupHierarchyView.js.map +1 -0
  524. package/build/dist/Utils/StatusPage/ResourceExplorer.js +519 -0
  525. package/build/dist/Utils/StatusPage/ResourceExplorer.js.map +1 -0
  526. package/jest.config.json +1 -0
  527. package/package.json +5 -1
  528. package/tsconfig.json +12 -10
@@ -0,0 +1,94 @@
1
+ import DashboardVariable from "../../Types/Dashboard/DashboardVariable";
2
+ import DashboardVariableInterpolation, {
3
+ ResolvedVariableValue,
4
+ } from "../Dashboard/VariableInterpolation";
5
+
6
+ /*
7
+ * Pure text utilities for external Data Source queries: dashboard-variable
8
+ * interpolation into query text, and legend templates for series naming.
9
+ * Client-side only — the server never interpolates variables (it receives
10
+ * the final query text).
11
+ */
12
+ export default class DataSourceQueryText {
13
+ /*
14
+ * Replace {{variableName}} tokens with the variable's current value.
15
+ * Multi-select values join with "|" — regex alternation, which drops
16
+ * straight into PromQL/LogQL label matchers (the dominant use). SQL
17
+ * users needing IN-lists can bind single-select variables. Unresolved
18
+ * variables leave the token untouched so the connector's error names
19
+ * the real problem instead of silently querying "".
20
+ */
21
+ public static applyVariables(
22
+ queryText: string,
23
+ variables: Array<DashboardVariable> | undefined,
24
+ ): string {
25
+ if (!queryText || !variables || variables.length === 0) {
26
+ return queryText;
27
+ }
28
+
29
+ let result: string = queryText;
30
+
31
+ for (const variable of variables) {
32
+ if (!variable.name) {
33
+ continue;
34
+ }
35
+
36
+ const resolved: ResolvedVariableValue | undefined =
37
+ DashboardVariableInterpolation.resolveValue(variable);
38
+
39
+ if (!resolved) {
40
+ continue;
41
+ }
42
+
43
+ const replacement: string =
44
+ resolved.multi && resolved.multi.length > 0
45
+ ? resolved.multi.join("|")
46
+ : resolved.scalar || "";
47
+
48
+ if (!replacement) {
49
+ continue;
50
+ }
51
+
52
+ /*
53
+ * {{ name }} with optional inner whitespace. Variable names come
54
+ * from user config — escape regex metacharacters.
55
+ */
56
+ const escapedName: string = variable.name.replace(
57
+ /[.*+?^${}()|[\]\\]/g,
58
+ "\\$&",
59
+ );
60
+ const token: RegExp = new RegExp(
61
+ `\\{\\{\\s*${escapedName}\\s*\\}\\}`,
62
+ "g",
63
+ );
64
+ result = result.replace(token, replacement);
65
+ }
66
+
67
+ return result;
68
+ }
69
+
70
+ /*
71
+ * Render a legend template against one series' attribute set:
72
+ * "{{instance}} ({{job}})" + { instance: "a:9090", job: "api" } →
73
+ * "a:9090 (api)". Unknown keys render as "(unset)". Returns the
74
+ * template untouched when it has no placeholders.
75
+ */
76
+ public static applyLegendTemplate(
77
+ template: string,
78
+ attributes: Record<string, string> | undefined,
79
+ ): string {
80
+ if (!template) {
81
+ return template;
82
+ }
83
+
84
+ return template.replace(
85
+ /\{\{\s*([^}\s]+)\s*\}\}/g,
86
+ (_match: string, key: string): string => {
87
+ const value: string | undefined = attributes
88
+ ? attributes[key]
89
+ : undefined;
90
+ return value === undefined || value === "" ? "(unset)" : value;
91
+ },
92
+ );
93
+ }
94
+ }
@@ -0,0 +1,156 @@
1
+ import AggregatedModel from "../../Types/BaseDatabase/AggregatedModel";
2
+ import AggregatedResult from "../../Types/BaseDatabase/AggregatedResult";
3
+ import { DataSourceValueReduce } from "../../Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent";
4
+
5
+ /*
6
+ * Collapsing an external Data Source time series into the single number the
7
+ * Value and Gauge widgets show.
8
+ *
9
+ * The metric widgets get this for free — the OneUptime metrics API already
10
+ * reduces server-side according to the query's "Aggregate by" — but an
11
+ * external query returns whatever its source returns, so the reduction is a
12
+ * widget setting and happens here, on the client.
13
+ */
14
+ export default class DataSourceValueReducer {
15
+ /*
16
+ * Flatten the points into values in TIME order, discarding non-finite
17
+ * entries. Time order is what makes First/Last mean what they say; the
18
+ * finiteness filter matters because `value` is typed `number` but
19
+ * AggregatedModel carries a JSONValue index signature, and a SQL NULL /
20
+ * missing column arrives as null — left unchecked it poisons an average
21
+ * with NaN.
22
+ */
23
+ public static getNumericValues(
24
+ results: Array<AggregatedResult>,
25
+ ): Array<number> {
26
+ const values: Array<number> = [];
27
+
28
+ for (const point of DataSourceValueReducer.sortPointsByTime(results)) {
29
+ const value: number = point.value as number;
30
+ if (typeof value === "number" && Number.isFinite(value)) {
31
+ values.push(value);
32
+ }
33
+ }
34
+
35
+ return values;
36
+ }
37
+
38
+ /*
39
+ * Reduce to one number. Returns null for an empty input so callers can
40
+ * tell "the query returned nothing" apart from "the query returned 0" —
41
+ * seeding a reduction with 0 is what makes an empty widget render a
42
+ * confident, wrong zero.
43
+ *
44
+ * Undefined `reduce` means Last: for an external query, "what is this
45
+ * right now" is the overwhelmingly common intent, and it is the only
46
+ * reduction that leaves a raw gauge/instant query untouched.
47
+ */
48
+ public static reduce(
49
+ values: Array<number>,
50
+ reduce: DataSourceValueReduce | undefined,
51
+ ): number | null {
52
+ if (values.length === 0) {
53
+ return null;
54
+ }
55
+
56
+ switch (reduce) {
57
+ case DataSourceValueReduce.First:
58
+ return values[0]!;
59
+ case DataSourceValueReduce.Avg:
60
+ return (
61
+ values.reduce((sum: number, value: number) => {
62
+ return sum + value;
63
+ }, 0) / values.length
64
+ );
65
+ case DataSourceValueReduce.Sum:
66
+ return values.reduce((sum: number, value: number) => {
67
+ return sum + value;
68
+ }, 0);
69
+ /*
70
+ * Folded, not `Math.min(...values)`. The spread pushes one argument
71
+ * per point onto the call stack, and a fine-step query over a wide
72
+ * dashboard window really does return hundreds of thousands of points
73
+ * — enough to throw RangeError mid-render, and only for these two of
74
+ * the six reductions, which reads as a data problem rather than a bug.
75
+ */
76
+ case DataSourceValueReduce.Min:
77
+ return values.reduce((min: number, value: number) => {
78
+ return value < min ? value : min;
79
+ }, values[0]!);
80
+ case DataSourceValueReduce.Max:
81
+ return values.reduce((max: number, value: number) => {
82
+ return value > max ? value : max;
83
+ }, values[0]!);
84
+ case DataSourceValueReduce.Last:
85
+ default:
86
+ return values[values.length - 1]!;
87
+ }
88
+ }
89
+
90
+ /*
91
+ * Convenience for the widgets: numeric values + the reduced number in one
92
+ * pass. `value` is null when the query returned no usable points.
93
+ */
94
+ public static reduceResults(
95
+ results: Array<AggregatedResult>,
96
+ reduce: DataSourceValueReduce | undefined,
97
+ ): { values: Array<number>; value: number | null } {
98
+ const values: Array<number> =
99
+ DataSourceValueReducer.getNumericValues(results);
100
+
101
+ return {
102
+ values: values,
103
+ value: DataSourceValueReducer.reduce(values, reduce),
104
+ };
105
+ }
106
+
107
+ /*
108
+ * First error a connector attached to a result, so an empty widget can say
109
+ * WHY it is empty instead of just "no data".
110
+ */
111
+ public static getResultsErrorMessage(
112
+ results: Array<AggregatedResult>,
113
+ ): string | undefined {
114
+ return results.find((result: AggregatedResult) => {
115
+ return Boolean(result.errorMessage);
116
+ })?.errorMessage;
117
+ }
118
+
119
+ /*
120
+ * Points in timestamp order, for the sparkline. Connectors are expected to
121
+ * return sorted data, but "expected to" is not "guaranteed to" for a
122
+ * hand-written SQL query with no ORDER BY — an unsorted series draws a
123
+ * scribble, and Last would pick an arbitrary point.
124
+ */
125
+ public static sortPointsByTime(
126
+ results: Array<AggregatedResult>,
127
+ ): Array<AggregatedModel> {
128
+ const points: Array<AggregatedModel> = [];
129
+
130
+ for (const result of results) {
131
+ points.push(...result.data);
132
+ }
133
+
134
+ return points.sort((a: AggregatedModel, b: AggregatedModel): number => {
135
+ return (
136
+ DataSourceValueReducer.getTime(a) - DataSourceValueReducer.getTime(b)
137
+ );
138
+ });
139
+ }
140
+
141
+ private static getTime(point: AggregatedModel): number {
142
+ const timestamp: Date =
143
+ point.timestamp instanceof Date
144
+ ? point.timestamp
145
+ : new Date(point.timestamp as unknown as string);
146
+
147
+ const time: number = timestamp.getTime();
148
+
149
+ /*
150
+ * NaN sorts unpredictably. Park unparseable timestamps at the start —
151
+ * NEGATIVE_INFINITY, not 0, so they stay first even for a query that
152
+ * legitimately returns pre-1970 timestamps.
153
+ */
154
+ return Number.isNaN(time) ? Number.NEGATIVE_INFINITY : time;
155
+ }
156
+ }
@@ -0,0 +1,380 @@
1
+ import Label from "../../Models/DatabaseModels/Label";
2
+ import { JSONObject, JSONValue } from "../../Types/JSON";
3
+
4
+ /*
5
+ * ---------------------------------------------------------------------------
6
+ * Labels and custom fields as metric attributes
7
+ * ---------------------------------------------------------------------------
8
+ *
9
+ * Incident / alert / monitor metrics carry a fixed set of dimensions (severity,
10
+ * owners, monitor names). Everything a project uses to describe *its own*
11
+ * taxonomy — labels and custom fields — lived only in Postgres, so a dashboard
12
+ * could not answer "MTTR for the payments product" without leaving the metric
13
+ * store. These helpers turn both into ClickHouse metric attributes so they are
14
+ * groupable and filterable like any other dimension.
15
+ *
16
+ * Labels are a flat list of names, and projects already encode structure in
17
+ * that name. Two shapes are supported:
18
+ *
19
+ * "product" -> oneuptime.label.product = "true" (the label is present)
20
+ * "product:X" -> oneuptime.label.product = "X" (the label carries a value)
21
+ *
22
+ * Custom fields already are key/value, so they map straight across:
23
+ *
24
+ * { "Team": "Payments" } -> oneuptime.customField.team = "Payments"
25
+ *
26
+ * Three properties are load-bearing:
27
+ *
28
+ * 1. VALUES ARE ALWAYS STRINGS. The ClickHouse column is Map(String, String);
29
+ * numbers, booleans and multi-select arrays are stringified here rather
30
+ * than at each call site, so every writer records the same shape.
31
+ *
32
+ * 2. THE SAME RESOURCE ALWAYS PRODUCES THE SAME ATTRIBUTES. Incident and alert
33
+ * metrics are *mutable* metrics — a refresh replaces the previous point for
34
+ * the same identity. If attribute order or collision handling varied
35
+ * between refreshes the series would churn, so merged values are sorted and
36
+ * collisions resolve deterministically.
37
+ *
38
+ * 3. A KEY THAT CANNOT BE FORMED IS DROPPED, NEVER GUESSED. A label named
39
+ * ":::" or a custom field named " " yields no attribute at all instead of
40
+ * an empty-keyed one, which ClickHouse would happily store and no filter
41
+ * could ever select.
42
+ */
43
+
44
+ /** Namespace for attributes derived from a resource's labels. */
45
+ export const LabelMetricAttributeNamespace: string = "oneuptime.label";
46
+
47
+ /** Namespace for attributes derived from a resource's custom fields. */
48
+ export const CustomFieldMetricAttributeNamespace: string =
49
+ "oneuptime.customField";
50
+
51
+ /**
52
+ * Value recorded for a label that carries no `key:value` payload. The label's
53
+ * presence is itself the fact worth charting, so it records as a string
54
+ * "true" — Map(String, String) has no boolean.
55
+ */
56
+ export const LabelPresentAttributeValue: string = "true";
57
+
58
+ /** One label name, split into the attribute key and its optional value. */
59
+ export interface ParsedLabelName {
60
+ /** Normalized key segment, e.g. `product`. Never empty. */
61
+ key: string;
62
+ /** Text after the first `:`, or null for a bare label. Never empty. */
63
+ value: string | null;
64
+ }
65
+
66
+ export default class MetricResourceAttributeUtil {
67
+ /*
68
+ * Long text custom fields would otherwise put a whole paragraph in a metric
69
+ * attribute, which bloats every row of the series. Attributes are dimensions,
70
+ * not payloads, so values are cut at a length that still distinguishes them.
71
+ */
72
+ private static readonly MAX_ATTRIBUTE_VALUE_LENGTH: number = 512;
73
+
74
+ /*
75
+ * Guard for pathological nesting inside a custom field's jsonb value. Real
76
+ * values are scalars or a one-level array (multi-select); anything deeper is
77
+ * stringified rather than walked forever.
78
+ */
79
+ private static readonly MAX_VALUE_DEPTH: number = 2;
80
+
81
+ /**
82
+ * Normalize free text (a label key, a custom field name) into one attribute
83
+ * key segment: lowercased, with whitespace and ASCII punctuation collapsed to
84
+ * `_`. Non-ASCII letters survive, so "Produção" stays "produção" instead of
85
+ * degrading to "produ_o" and colliding with unrelated names.
86
+ *
87
+ * Returns null when nothing usable is left.
88
+ */
89
+ public static getAttributeKeySegment(
90
+ name: string | undefined | null,
91
+ ): string | null {
92
+ if (typeof name !== "string") {
93
+ return null;
94
+ }
95
+
96
+ /*
97
+ * Everything in the ASCII range that is not a letter or a digit — control
98
+ * characters, space, punctuation, symbols. Ranges rather than \p{...} so
99
+ * the regex is valid at this project's es2017 target.
100
+ *
101
+ * no-control-regex is disabled deliberately: a control character inside a
102
+ * user-typed name is exactly what has to be stripped before the text can
103
+ * become a ClickHouse map key.
104
+ */
105
+ const segment: string = name
106
+ .trim()
107
+ .toLowerCase()
108
+ // eslint-disable-next-line no-control-regex
109
+ .replace(/[\u0000-\u002F\u003A-\u0040\u005B-\u0060\u007B-\u007F]+/g, "_")
110
+ .replace(/^_+/, "")
111
+ .replace(/_+$/, "");
112
+
113
+ if (segment.length === 0) {
114
+ return null;
115
+ }
116
+
117
+ return segment;
118
+ }
119
+
120
+ /**
121
+ * Split one label name into its attribute key and value. Only the FIRST `:`
122
+ * separates the two, so "env:us-east:1a" reads as env = "us-east:1a" rather
123
+ * than silently losing the tail.
124
+ */
125
+ public static parseLabelName(
126
+ labelName: string | undefined | null,
127
+ ): ParsedLabelName | null {
128
+ if (typeof labelName !== "string") {
129
+ return null;
130
+ }
131
+
132
+ const trimmedName: string = labelName.trim();
133
+
134
+ if (trimmedName.length === 0) {
135
+ return null;
136
+ }
137
+
138
+ const separatorIndex: number = trimmedName.indexOf(":");
139
+
140
+ const rawKey: string =
141
+ separatorIndex === -1
142
+ ? trimmedName
143
+ : trimmedName.substring(0, separatorIndex);
144
+
145
+ const rawValue: string =
146
+ separatorIndex === -1
147
+ ? ""
148
+ : trimmedName.substring(separatorIndex + 1).trim();
149
+
150
+ const key: string | null = this.getAttributeKeySegment(rawKey);
151
+
152
+ if (!key) {
153
+ return null;
154
+ }
155
+
156
+ return {
157
+ key: key,
158
+ // "product:" is a bare label with a stray separator, not an empty value.
159
+ value: rawValue.length > 0 ? this.truncate(rawValue) : null,
160
+ };
161
+ }
162
+
163
+ /**
164
+ * Build `oneuptime.label.*` attributes from a resource's labels.
165
+ *
166
+ * Several labels can normalize onto one key ("product:web" and
167
+ * "Product: api"). Their values merge into a sorted, comma-separated list so
168
+ * the result does not depend on the order the database returned the rows in.
169
+ * An explicit value always beats the bare presence marker: "product" plus
170
+ * "product:web" records "web", not "true, web".
171
+ */
172
+ public static getLabelAttributes(
173
+ labels: Array<Label> | undefined | null,
174
+ ): JSONObject {
175
+ const attributes: JSONObject = {};
176
+
177
+ if (!labels || !Array.isArray(labels)) {
178
+ return attributes;
179
+ }
180
+
181
+ /*
182
+ * key -> the explicit values seen for it. A key present with an empty
183
+ * list was only ever seen bare, and records the presence marker.
184
+ */
185
+ const collected: Map<string, Array<string>> = new Map<
186
+ string,
187
+ Array<string>
188
+ >();
189
+
190
+ for (const label of labels) {
191
+ const parsed: ParsedLabelName | null = this.parseLabelName(label?.name);
192
+
193
+ if (!parsed) {
194
+ continue;
195
+ }
196
+
197
+ let values: Array<string> | undefined = collected.get(parsed.key);
198
+
199
+ if (!values) {
200
+ values = [];
201
+ collected.set(parsed.key, values);
202
+ }
203
+
204
+ if (parsed.value !== null && !values.includes(parsed.value)) {
205
+ values.push(parsed.value);
206
+ }
207
+ }
208
+
209
+ // Sorted so the emitted object's key order is stable too, not just its content.
210
+ for (const key of Array.from(collected.keys()).sort()) {
211
+ const values: Array<string> = collected.get(key) || [];
212
+
213
+ attributes[`${LabelMetricAttributeNamespace}.${key}`] =
214
+ values.length > 0
215
+ ? this.truncate(values.slice().sort().join(", "))
216
+ : LabelPresentAttributeValue;
217
+ }
218
+
219
+ return attributes;
220
+ }
221
+
222
+ /**
223
+ * Build `oneuptime.customField.*` attributes from a resource's `customFields`
224
+ * jsonb column, which stores a flat object keyed by each custom field
225
+ * definition's name.
226
+ *
227
+ * Two definitions whose names normalize onto the same key ("Team Name" and
228
+ * "team-name") are an accident, not a taxonomy, so they do not merge: the
229
+ * first by sorted field name wins, which keeps the result stable across
230
+ * refreshes instead of depending on object key order.
231
+ */
232
+ public static getCustomFieldAttributes(
233
+ customFields: JSONObject | undefined | null,
234
+ ): JSONObject {
235
+ const attributes: JSONObject = {};
236
+
237
+ if (
238
+ !customFields ||
239
+ typeof customFields !== "object" ||
240
+ Array.isArray(customFields)
241
+ ) {
242
+ return attributes;
243
+ }
244
+
245
+ for (const fieldName of Object.keys(customFields).sort()) {
246
+ const key: string | null = this.getAttributeKeySegment(fieldName);
247
+
248
+ if (!key) {
249
+ continue;
250
+ }
251
+
252
+ const attributeKey: string = `${CustomFieldMetricAttributeNamespace}.${key}`;
253
+
254
+ if (attributes[attributeKey] !== undefined) {
255
+ continue;
256
+ }
257
+
258
+ const value: string | null = this.toAttributeValue(
259
+ customFields[fieldName] as JSONValue,
260
+ 0,
261
+ );
262
+
263
+ if (value === null) {
264
+ continue;
265
+ }
266
+
267
+ attributes[attributeKey] = value;
268
+ }
269
+
270
+ return attributes;
271
+ }
272
+
273
+ /**
274
+ * Every label and custom field attribute for one resource. Callers merge this
275
+ * into their metric's attributes; the two namespaces cannot collide with the
276
+ * existing dimension names, which are unprefixed camelCase.
277
+ */
278
+ public static getResourceAttributes(data: {
279
+ labels?: Array<Label> | undefined | null;
280
+ customFields?: JSONObject | undefined | null;
281
+ }): JSONObject {
282
+ return {
283
+ ...this.getLabelAttributes(data.labels),
284
+ ...this.getCustomFieldAttributes(data.customFields),
285
+ };
286
+ }
287
+
288
+ /**
289
+ * Merge resource attributes into an existing attribute set. Resource
290
+ * attributes win on conflict, so a user-supplied attribute (custom monitor
291
+ * metrics let callers pass their own) cannot shadow the namespace.
292
+ */
293
+ public static mergeResourceAttributes(
294
+ attributes: JSONObject,
295
+ resourceAttributes: JSONObject,
296
+ ): JSONObject {
297
+ return { ...attributes, ...resourceAttributes };
298
+ }
299
+
300
+ /*
301
+ * One custom field value as attribute text. Returns null for anything that
302
+ * carries no information — absent, empty, or non-finite — so the caller drops
303
+ * the attribute instead of recording "undefined".
304
+ */
305
+ private static toAttributeValue(
306
+ value: JSONValue | undefined,
307
+ depth: number,
308
+ ): string | null {
309
+ if (value === null || value === undefined) {
310
+ return null;
311
+ }
312
+
313
+ if (typeof value === "string") {
314
+ const trimmedValue: string = value.trim();
315
+ return trimmedValue.length > 0 ? this.truncate(trimmedValue) : null;
316
+ }
317
+
318
+ if (typeof value === "boolean") {
319
+ return value ? "true" : "false";
320
+ }
321
+
322
+ if (typeof value === "number") {
323
+ // NaN / Infinity would record as text no chart could use.
324
+ return isFinite(value) ? String(value) : null;
325
+ }
326
+
327
+ if (value instanceof Date) {
328
+ return value.toISOString();
329
+ }
330
+
331
+ if (Array.isArray(value)) {
332
+ // Multi-select dropdowns: keep the order the user chose.
333
+ if (depth >= this.MAX_VALUE_DEPTH) {
334
+ return this.stringifyValue(value);
335
+ }
336
+
337
+ const parts: Array<string> = [];
338
+
339
+ for (const element of value) {
340
+ const part: string | null = this.toAttributeValue(
341
+ element as JSONValue,
342
+ depth + 1,
343
+ );
344
+
345
+ if (part !== null) {
346
+ parts.push(part);
347
+ }
348
+ }
349
+
350
+ return parts.length > 0 ? this.truncate(parts.join(", ")) : null;
351
+ }
352
+
353
+ if (typeof value === "object") {
354
+ return this.stringifyValue(value);
355
+ }
356
+
357
+ return null;
358
+ }
359
+
360
+ private static stringifyValue(value: unknown): string | null {
361
+ try {
362
+ const serialized: string | undefined = JSON.stringify(value);
363
+
364
+ if (!serialized || serialized === "{}" || serialized === "[]") {
365
+ return null;
366
+ }
367
+
368
+ return this.truncate(serialized);
369
+ } catch {
370
+ // Circular structures cannot become an attribute; drop rather than throw.
371
+ return null;
372
+ }
373
+ }
374
+
375
+ private static truncate(value: string): string {
376
+ return value.length > this.MAX_ATTRIBUTE_VALUE_LENGTH
377
+ ? value.substring(0, this.MAX_ATTRIBUTE_VALUE_LENGTH)
378
+ : value;
379
+ }
380
+ }
@@ -63,12 +63,14 @@ export class ScanTargetUtil {
63
63
  *
64
64
  * The number is a wall-clock budget, not a memory one. SubnetScanner runs 32
65
65
  * workers; a dead host costs ~1s (the ICMP pre-sweep timeout), or ~2s when
66
- * the pre-sweep is unavailable and every host is SNMP-probed directly. At
67
- * this ceiling that is ~17 minutes with the pre-sweep and ~34 minutes
68
- * without both comfortably inside the 2-hour window after which the server
69
- * declares an In Progress scan abandoned (Workers/Jobs/
70
- * NetworkDeviceDiscovery/RequeueRecurringScans.ts) and safely above the
71
- * 15-minute minimum rescan interval for recurring scans.
66
+ * every host is SNMP-probed directly. At this ceiling that is ~17 minutes
67
+ * for a sweep the ICMP gate resolves, ~34 minutes when the pre-sweep is
68
+ * unavailable, and ~51 minutes in the worst case an ICMP pass that finds
69
+ * no SNMP responder, so every address is re-probed over SNMP as well (see
70
+ * the ICMP-filtered fallback in SubnetScanner.scan). All three sit inside
71
+ * the 2-hour window after which the server declares an In Progress scan
72
+ * abandoned (Workers/Jobs/NetworkDeviceDiscovery/RequeueRecurringScans.ts)
73
+ * and above the 15-minute minimum rescan interval for recurring scans.
72
74
  *
73
75
  * It is also still a real abuse guard: a /17 in CIDR terms. Anything larger
74
76
  * (a /16 sweep, an unbounded 10.*.*.* octet range) is rejected at write time