@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,640 @@
1
+ import { describe, expect, test } from "@jest/globals";
2
+ import {
3
+ ComponentArgumentSection,
4
+ ComponentInputType,
5
+ } from "../../../../Types/Dashboard/DashboardComponents/ComponentArgument";
6
+ import DashboardBaseComponent from "../../../../Types/Dashboard/DashboardComponents/DashboardBaseComponent";
7
+ import { DataSourceValueReduce } from "../../../../Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent";
8
+ import DashboardComponentType, {
9
+ DataSourceComponentTypes,
10
+ } from "../../../../Types/Dashboard/DashboardComponentType";
11
+ import DataSourceQueryConfig from "../../../../Types/DataSource/DataSourceQueryConfig";
12
+ import BadDataException from "../../../../Types/Exception/BadDataException";
13
+ import { ObjectType } from "../../../../Types/JSON";
14
+ import DashboardDataSourceChartComponentUtil from "../../../../Utils/Dashboard/Components/DashboardDataSourceChartComponent";
15
+ import DashboardDataSourceGaugeComponentUtil from "../../../../Utils/Dashboard/Components/DashboardDataSourceGaugeComponent";
16
+ import { DATA_SOURCE_REDUCE_DROPDOWN_OPTIONS } from "../../../../Utils/Dashboard/Components/DashboardDataSourceShared";
17
+ import DashboardDataSourceTableComponentUtil from "../../../../Utils/Dashboard/Components/DashboardDataSourceTableComponent";
18
+ import DashboardDataSourceValueComponentUtil from "../../../../Utils/Dashboard/Components/DashboardDataSourceValueComponent";
19
+ import DashboardComponentsUtil from "../../../../Utils/Dashboard/Components/Index";
20
+
21
+ /*
22
+ * The four Data Source widgets (Chart / Value / Gauge / Table) were split out
23
+ * of the metric widgets, where external queries used to live as an alternative
24
+ * mode of the same component. Two things about that split are easy to get
25
+ * wrong and impossible to catch with the compiler:
26
+ *
27
+ * - A new widget type can be added to the DashboardComponentType enum and
28
+ * shipped with a util, but never wired into the if/else chain in
29
+ * Components/Index.ts. The settings panel then throws BadDataException the
30
+ * moment a user opens the widget's config.
31
+ * - The metric inputs (MetricsQueryConfig, TableColumns, ...) can be copied
32
+ * across when a Data Source widget is written by cloning its metric
33
+ * sibling. A Data Source widget that renders a metric-query editor is the
34
+ * exact confusion the split was meant to remove — and it would render an
35
+ * editor writing to an argument the renderer never reads.
36
+ *
37
+ * Defaults matter for the same reason: a widget is dropped on the canvas
38
+ * before it is configured, so the seeded query must be blank (the canvas keys
39
+ * "unconfigured" off an empty dataSourceId) and the whole component must
40
+ * survive JSON.stringify, because it is persisted inside the dashboard's
41
+ * JSONB view-config column rather than as its own table.
42
+ */
43
+
44
+ interface DropdownOptionView {
45
+ label: string;
46
+ value: unknown;
47
+ }
48
+
49
+ /*
50
+ * A structural view of ComponentArgument that drops the `keyof T["arguments"]`
51
+ * id typing, so all four widgets' argument lists can be walked by one loop.
52
+ */
53
+ interface ConfigArgumentView {
54
+ name: string;
55
+ description: string;
56
+ required: boolean;
57
+ type: ComponentInputType;
58
+ id: string;
59
+ isAdvanced?: boolean | undefined;
60
+ placeholder?: string | undefined;
61
+ section?: ComponentArgumentSection | undefined;
62
+ dropdownOptions?: Array<DropdownOptionView> | undefined;
63
+ }
64
+
65
+ type AsArgumentViewsFunction = (
66
+ componentArguments: unknown,
67
+ ) => Array<ConfigArgumentView>;
68
+
69
+ const asArgumentViews: AsArgumentViewsFunction = (
70
+ componentArguments: unknown,
71
+ ): Array<ConfigArgumentView> => {
72
+ return componentArguments as Array<ConfigArgumentView>;
73
+ };
74
+
75
+ type GetDefaultComponentFunction = () => DashboardBaseComponent;
76
+ type GetConfigArgumentsFunction = () => Array<ConfigArgumentView>;
77
+ type GetSeededQueriesFunction = (
78
+ component: DashboardBaseComponent,
79
+ ) => Array<DataSourceQueryConfig>;
80
+
81
+ interface DataSourceWidgetCase {
82
+ label: string;
83
+ componentType: DashboardComponentType;
84
+ getDefaultComponent: GetDefaultComponentFunction;
85
+ getConfigArguments: GetConfigArgumentsFunction;
86
+ getSeededQueries: GetSeededQueriesFunction;
87
+ }
88
+
89
+ type GetSingleQueryFunction = (
90
+ component: DashboardBaseComponent,
91
+ ) => Array<DataSourceQueryConfig>;
92
+
93
+ // Value / Gauge / Table hold one query; the chart holds a list of them.
94
+ const getSingleQuery: GetSingleQueryFunction = (
95
+ component: DashboardBaseComponent,
96
+ ): Array<DataSourceQueryConfig> => {
97
+ const componentArguments: { query?: DataSourceQueryConfig | undefined } =
98
+ component.arguments as { query?: DataSourceQueryConfig | undefined };
99
+
100
+ return componentArguments.query ? [componentArguments.query] : [];
101
+ };
102
+
103
+ const WIDGET_CASES: Array<DataSourceWidgetCase> = [
104
+ {
105
+ label: "DataSourceChart",
106
+ componentType: DashboardComponentType.DataSourceChart,
107
+ getDefaultComponent: (): DashboardBaseComponent => {
108
+ return DashboardDataSourceChartComponentUtil.getDefaultComponent();
109
+ },
110
+ getConfigArguments: (): Array<ConfigArgumentView> => {
111
+ return asArgumentViews(
112
+ DashboardDataSourceChartComponentUtil.getComponentConfigArguments(),
113
+ );
114
+ },
115
+ getSeededQueries: (
116
+ component: DashboardBaseComponent,
117
+ ): Array<DataSourceQueryConfig> => {
118
+ const componentArguments: {
119
+ queries?: Array<DataSourceQueryConfig> | undefined;
120
+ } = component.arguments as {
121
+ queries?: Array<DataSourceQueryConfig> | undefined;
122
+ };
123
+
124
+ return componentArguments.queries || [];
125
+ },
126
+ },
127
+ {
128
+ label: "DataSourceValue",
129
+ componentType: DashboardComponentType.DataSourceValue,
130
+ getDefaultComponent: (): DashboardBaseComponent => {
131
+ return DashboardDataSourceValueComponentUtil.getDefaultComponent();
132
+ },
133
+ getConfigArguments: (): Array<ConfigArgumentView> => {
134
+ return asArgumentViews(
135
+ DashboardDataSourceValueComponentUtil.getComponentConfigArguments(),
136
+ );
137
+ },
138
+ getSeededQueries: getSingleQuery,
139
+ },
140
+ {
141
+ label: "DataSourceGauge",
142
+ componentType: DashboardComponentType.DataSourceGauge,
143
+ getDefaultComponent: (): DashboardBaseComponent => {
144
+ return DashboardDataSourceGaugeComponentUtil.getDefaultComponent();
145
+ },
146
+ getConfigArguments: (): Array<ConfigArgumentView> => {
147
+ return asArgumentViews(
148
+ DashboardDataSourceGaugeComponentUtil.getComponentConfigArguments(),
149
+ );
150
+ },
151
+ getSeededQueries: getSingleQuery,
152
+ },
153
+ {
154
+ label: "DataSourceTable",
155
+ componentType: DashboardComponentType.DataSourceTable,
156
+ getDefaultComponent: (): DashboardBaseComponent => {
157
+ return DashboardDataSourceTableComponentUtil.getDefaultComponent();
158
+ },
159
+ getConfigArguments: (): Array<ConfigArgumentView> => {
160
+ return asArgumentViews(
161
+ DashboardDataSourceTableComponentUtil.getComponentConfigArguments(),
162
+ );
163
+ },
164
+ getSeededQueries: getSingleQuery,
165
+ },
166
+ ];
167
+
168
+ /*
169
+ * Input types that belong exclusively to the OneUptime-telemetry widgets. A
170
+ * Data Source widget must expose none of them.
171
+ */
172
+ const METRIC_ONLY_INPUT_TYPES: Array<ComponentInputType> = [
173
+ ComponentInputType.MetricsQueryConfig,
174
+ ComponentInputType.MetricsQueryConfigs,
175
+ ComponentInputType.MetricsFormulaConfigs,
176
+ ComponentInputType.TableColumns,
177
+ ComponentInputType.TableGroupBy,
178
+ ];
179
+
180
+ for (const widgetCase of WIDGET_CASES) {
181
+ describe(`${widgetCase.label} widget util`, () => {
182
+ test("declares its own component type and marks itself as a dashboard component", () => {
183
+ const component: DashboardBaseComponent =
184
+ widgetCase.getDefaultComponent();
185
+
186
+ expect(component.componentType).toBe(widgetCase.componentType);
187
+ expect(component._type).toBe(ObjectType.DashboardComponent);
188
+ });
189
+
190
+ test("drops onto the canvas origin at a positive size no smaller than its own minimum", () => {
191
+ const component: DashboardBaseComponent =
192
+ widgetCase.getDefaultComponent();
193
+
194
+ expect(component.topInDashboardUnits).toBe(0);
195
+ expect(component.leftInDashboardUnits).toBe(0);
196
+
197
+ expect(component.widthInDashboardUnits).toBeGreaterThan(0);
198
+ expect(component.heightInDashboardUnits).toBeGreaterThan(0);
199
+ expect(component.minWidthInDashboardUnits).toBeGreaterThan(0);
200
+ expect(component.minHeightInDashboardUnits).toBeGreaterThan(0);
201
+
202
+ /*
203
+ * A default smaller than its own minimum makes the grid snap the widget
204
+ * larger the instant it is dropped, moving whatever sat below it.
205
+ */
206
+ expect(component.minWidthInDashboardUnits).toBeLessThanOrEqual(
207
+ component.widthInDashboardUnits,
208
+ );
209
+ expect(component.minHeightInDashboardUnits).toBeLessThanOrEqual(
210
+ component.heightInDashboardUnits,
211
+ );
212
+ });
213
+
214
+ test("generates a fresh componentId and query id on every call", () => {
215
+ const first: DashboardBaseComponent = widgetCase.getDefaultComponent();
216
+ const second: DashboardBaseComponent = widgetCase.getDefaultComponent();
217
+
218
+ // Two widgets of the same type on one dashboard must not share an id.
219
+ expect(first.componentId.toString().length).toBeGreaterThan(0);
220
+ expect(first.componentId.toString()).not.toBe(
221
+ second.componentId.toString(),
222
+ );
223
+
224
+ const firstQueries: Array<DataSourceQueryConfig> =
225
+ widgetCase.getSeededQueries(first);
226
+ const secondQueries: Array<DataSourceQueryConfig> =
227
+ widgetCase.getSeededQueries(second);
228
+
229
+ expect(firstQueries[0]?.id).toBeTruthy();
230
+ expect(firstQueries[0]?.id).not.toBe(secondQueries[0]?.id);
231
+ });
232
+
233
+ test("seeds exactly one blank query so the widget starts unconfigured", () => {
234
+ const component: DashboardBaseComponent =
235
+ widgetCase.getDefaultComponent();
236
+ const queries: Array<DataSourceQueryConfig> =
237
+ widgetCase.getSeededQueries(component);
238
+
239
+ expect(queries).toHaveLength(1);
240
+
241
+ /*
242
+ * Blank on both fields: an empty dataSourceId is what the widget reads
243
+ * as "not configured yet", and a non-empty default query would be run
244
+ * against whichever source the user picks first.
245
+ */
246
+ expect(queries[0]?.dataSourceId).toBe("");
247
+ expect(queries[0]?.query).toBe("");
248
+ });
249
+
250
+ test("survives the JSON round trip it takes through the dashboard's JSONB config", () => {
251
+ const component: DashboardBaseComponent =
252
+ widgetCase.getDefaultComponent();
253
+
254
+ const roundTripped: DashboardBaseComponent = JSON.parse(
255
+ JSON.stringify(component),
256
+ ) as DashboardBaseComponent;
257
+
258
+ expect(roundTripped.arguments).toEqual(component.arguments);
259
+ expect(roundTripped.componentType).toBe(widgetCase.componentType);
260
+ expect(roundTripped.widthInDashboardUnits).toBe(
261
+ component.widthInDashboardUnits,
262
+ );
263
+
264
+ // The seeded query has to still be there and still be blank.
265
+ const queries: Array<DataSourceQueryConfig> =
266
+ widgetCase.getSeededQueries(roundTripped);
267
+
268
+ expect(queries).toHaveLength(1);
269
+ expect(queries[0]?.dataSourceId).toBe("");
270
+ expect(queries[0]?.query).toBe("");
271
+ expect(queries[0]?.id).toBe(
272
+ widgetCase.getSeededQueries(component)[0]?.id,
273
+ );
274
+ });
275
+
276
+ test("declares config arguments that are unique, labelled and sectioned", () => {
277
+ const configArguments: Array<ConfigArgumentView> =
278
+ widgetCase.getConfigArguments();
279
+
280
+ expect(configArguments.length).toBeGreaterThan(0);
281
+
282
+ const ids: Array<string> = configArguments.map(
283
+ (configArgument: ConfigArgumentView): string => {
284
+ return String(configArgument.id);
285
+ },
286
+ );
287
+
288
+ // A duplicate id means the second field silently overwrites the first.
289
+ expect(new Set<string>(ids).size).toBe(ids.length);
290
+
291
+ const sectionsByName: Map<string, ComponentArgumentSection> = new Map<
292
+ string,
293
+ ComponentArgumentSection
294
+ >();
295
+
296
+ for (const configArgument of configArguments) {
297
+ expect(String(configArgument.id).trim().length).toBeGreaterThan(0);
298
+ expect(configArgument.name.trim().length).toBeGreaterThan(0);
299
+ expect(configArgument.description.trim().length).toBeGreaterThan(0);
300
+ expect(typeof configArgument.required).toBe("boolean");
301
+ expect(Object.values(ComponentInputType)).toContain(
302
+ configArgument.type,
303
+ );
304
+
305
+ // Section-less arguments render outside every collapsible group.
306
+ expect(configArgument.section).toBeDefined();
307
+
308
+ const section: ComponentArgumentSection =
309
+ configArgument.section as ComponentArgumentSection;
310
+
311
+ expect(section.name.trim().length).toBeGreaterThan(0);
312
+ expect(typeof section.order).toBe("number");
313
+ expect(Number.isFinite(section.order)).toBe(true);
314
+
315
+ /*
316
+ * The settings panel groups by section object, so two arguments that
317
+ * name the same section must literally share it — otherwise the panel
318
+ * renders the same heading twice.
319
+ */
320
+ const alreadySeen: ComponentArgumentSection | undefined =
321
+ sectionsByName.get(section.name);
322
+
323
+ if (alreadySeen) {
324
+ expect(section).toBe(alreadySeen);
325
+ } else {
326
+ sectionsByName.set(section.name, section);
327
+ }
328
+ }
329
+ });
330
+
331
+ test("carries option lists on its dropdowns and nowhere else", () => {
332
+ /*
333
+ * Not every one of these widgets has a dropdown (the table has none), so
334
+ * this checks the correspondence rather than a count: a Dropdown must
335
+ * have usable options, and a non-Dropdown must not carry an option list
336
+ * the renderer will never show.
337
+ */
338
+ for (const configArgument of widgetCase.getConfigArguments()) {
339
+ if (configArgument.type !== ComponentInputType.Dropdown) {
340
+ expect(configArgument.dropdownOptions).toBeUndefined();
341
+ continue;
342
+ }
343
+
344
+ const options: Array<DropdownOptionView> =
345
+ configArgument.dropdownOptions || [];
346
+
347
+ // A dropdown with no options is a permanently empty, unusable field.
348
+ expect(options.length).toBeGreaterThan(0);
349
+
350
+ const values: Array<unknown> = options.map(
351
+ (option: DropdownOptionView): unknown => {
352
+ return option.value;
353
+ },
354
+ );
355
+
356
+ // A duplicate value makes two rows that store the same thing.
357
+ expect(new Set<unknown>(values).size).toBe(values.length);
358
+
359
+ for (const option of options) {
360
+ expect(option.label.trim().length).toBeGreaterThan(0);
361
+ expect(option.value).toBeTruthy();
362
+ }
363
+ }
364
+ });
365
+
366
+ /*
367
+ * The regression guard the whole split exists for. These widgets read an
368
+ * external source; a metric input here would render a metric-explorer
369
+ * editor writing to an argument nothing consumes.
370
+ */
371
+ test("exposes no metric or telemetry surface at all", () => {
372
+ const configArguments: Array<ConfigArgumentView> =
373
+ widgetCase.getConfigArguments();
374
+
375
+ const usedTypes: Array<ComponentInputType> = configArguments.map(
376
+ (configArgument: ConfigArgumentView): ComponentInputType => {
377
+ return configArgument.type;
378
+ },
379
+ );
380
+
381
+ for (const metricInputType of METRIC_ONLY_INPUT_TYPES) {
382
+ expect(usedTypes).not.toContain(metricInputType);
383
+ }
384
+
385
+ // Nor a metric-named argument key left behind by a copied widget.
386
+ for (const configArgument of configArguments) {
387
+ expect(String(configArgument.id).toLowerCase()).not.toContain("metric");
388
+ }
389
+ });
390
+ });
391
+ }
392
+
393
+ describe("Data Source widgets as a group", () => {
394
+ test("covers exactly the widget types declared as data-source types", () => {
395
+ /*
396
+ * If a fifth Data Source widget is added to DataSourceComponentTypes, this
397
+ * suite must grow with it rather than quietly skipping it.
398
+ */
399
+ const covered: Array<DashboardComponentType> = WIDGET_CASES.map(
400
+ (widgetCase: DataSourceWidgetCase): DashboardComponentType => {
401
+ return widgetCase.componentType;
402
+ },
403
+ );
404
+
405
+ expect(covered.slice().sort()).toEqual(
406
+ DataSourceComponentTypes.slice().sort(),
407
+ );
408
+ });
409
+
410
+ test("uses one order per section name across all four widgets", () => {
411
+ /*
412
+ * The four widgets sit side by side in the same settings panel styling;
413
+ * "Display Options" appearing above "Thresholds" in one widget and below
414
+ * it in another is a UI inconsistency no single widget's test can see.
415
+ */
416
+ const orderBySectionName: Map<string, number> = new Map<string, number>();
417
+
418
+ for (const widgetCase of WIDGET_CASES) {
419
+ for (const configArgument of widgetCase.getConfigArguments()) {
420
+ const section: ComponentArgumentSection | undefined =
421
+ configArgument.section;
422
+
423
+ if (!section) {
424
+ continue;
425
+ }
426
+
427
+ const knownOrder: number | undefined = orderBySectionName.get(
428
+ section.name,
429
+ );
430
+
431
+ if (knownOrder === undefined) {
432
+ orderBySectionName.set(section.name, section.order);
433
+ continue;
434
+ }
435
+
436
+ expect({ name: section.name, order: section.order }).toEqual({
437
+ name: section.name,
438
+ order: knownOrder,
439
+ });
440
+ }
441
+ }
442
+
443
+ expect(orderBySectionName.size).toBeGreaterThan(0);
444
+ });
445
+
446
+ test("keeps widget-specific defaults sane", () => {
447
+ const value: DashboardBaseComponent =
448
+ DashboardDataSourceValueComponentUtil.getDefaultComponent();
449
+ const valueArguments: { title: string; reduce?: unknown } =
450
+ value.arguments as { title: string; reduce?: unknown };
451
+
452
+ // Empty title, not a placeholder string that would ship as real content.
453
+ expect(valueArguments.title).toBe("");
454
+ expect(valueArguments.reduce).toBe(DataSourceValueReduce.Last);
455
+
456
+ const gauge: DashboardBaseComponent =
457
+ DashboardDataSourceGaugeComponentUtil.getDefaultComponent();
458
+ const gaugeArguments: {
459
+ minValue?: number | undefined;
460
+ maxValue?: number | undefined;
461
+ reduce?: unknown;
462
+ } = gauge.arguments as {
463
+ minValue?: number | undefined;
464
+ maxValue?: number | undefined;
465
+ reduce?: unknown;
466
+ };
467
+
468
+ // An inverted or zero-width scale gives the needle nowhere to point.
469
+ expect(gaugeArguments.minValue).toBe(0);
470
+ expect(gaugeArguments.maxValue).toBe(100);
471
+ expect(gaugeArguments.minValue as number).toBeLessThan(
472
+ gaugeArguments.maxValue as number,
473
+ );
474
+ expect(gaugeArguments.reduce).toBe(DataSourceValueReduce.Last);
475
+
476
+ const table: DashboardBaseComponent =
477
+ DashboardDataSourceTableComponentUtil.getDefaultComponent();
478
+ const tableArguments: { maxRows?: number | undefined } =
479
+ table.arguments as { maxRows?: number | undefined };
480
+
481
+ // Absent maxRows means "render every row the query returned".
482
+ expect(tableArguments.maxRows).toBeUndefined();
483
+ });
484
+ });
485
+
486
+ describe("registration in DashboardComponentsUtil", () => {
487
+ for (const widgetCase of WIDGET_CASES) {
488
+ test(`${widgetCase.label} resolves to its own non-empty argument list`, () => {
489
+ const fromRegistry: Array<ConfigArgumentView> = asArgumentViews(
490
+ DashboardComponentsUtil.getComponentSettingsArguments(
491
+ widgetCase.componentType,
492
+ ),
493
+ );
494
+
495
+ expect(fromRegistry.length).toBeGreaterThan(0);
496
+
497
+ expect(
498
+ fromRegistry.map((configArgument: ConfigArgumentView): string => {
499
+ return String(configArgument.id);
500
+ }),
501
+ ).toEqual(
502
+ widgetCase
503
+ .getConfigArguments()
504
+ .map((configArgument: ConfigArgumentView): string => {
505
+ return String(configArgument.id);
506
+ }),
507
+ );
508
+ });
509
+ }
510
+
511
+ test("still rejects a component type it does not know", () => {
512
+ expect(() => {
513
+ return DashboardComponentsUtil.getComponentSettingsArguments(
514
+ "NotARealDataSourceWidget" as DashboardComponentType,
515
+ );
516
+ }).toThrow(BadDataException);
517
+ });
518
+
519
+ test("rejects an empty component type rather than falling back to a widget", () => {
520
+ expect(() => {
521
+ return DashboardComponentsUtil.getComponentSettingsArguments(
522
+ "" as DashboardComponentType,
523
+ );
524
+ }).toThrow(BadDataException);
525
+ });
526
+ });
527
+
528
+ /*
529
+ * The other half of the split: the metric widgets must keep the metric inputs
530
+ * that were never supposed to move. If a metric input disappeared from one of
531
+ * these while the Data Source widgets stayed clean, the split gutted the
532
+ * telemetry widget instead of separating from it.
533
+ */
534
+ describe("metric widgets retain their metric inputs", () => {
535
+ type MetricExpectation = [DashboardComponentType, Array<ComponentInputType>];
536
+
537
+ const METRIC_EXPECTATIONS: Array<MetricExpectation> = [
538
+ [
539
+ DashboardComponentType.Chart,
540
+ [
541
+ ComponentInputType.MetricsQueryConfig,
542
+ ComponentInputType.MetricsQueryConfigs,
543
+ ComponentInputType.MetricsFormulaConfigs,
544
+ ],
545
+ ],
546
+ [DashboardComponentType.Value, [ComponentInputType.MetricsQueryConfig]],
547
+ [DashboardComponentType.Gauge, [ComponentInputType.MetricsQueryConfig]],
548
+ [
549
+ DashboardComponentType.Table,
550
+ [ComponentInputType.TableColumns, ComponentInputType.TableGroupBy],
551
+ ],
552
+ ];
553
+
554
+ for (const [componentType, expectedInputTypes] of METRIC_EXPECTATIONS) {
555
+ test(`${componentType} still offers its telemetry inputs`, () => {
556
+ const usedTypes: Array<ComponentInputType> = asArgumentViews(
557
+ DashboardComponentsUtil.getComponentSettingsArguments(componentType),
558
+ ).map((configArgument: ConfigArgumentView): ComponentInputType => {
559
+ return configArgument.type;
560
+ });
561
+
562
+ for (const expectedInputType of expectedInputTypes) {
563
+ expect(usedTypes).toContain(expectedInputType);
564
+ }
565
+ });
566
+ }
567
+ });
568
+
569
+ describe("DATA_SOURCE_REDUCE_DROPDOWN_OPTIONS", () => {
570
+ test("offers every DataSourceValueReduce member exactly once", () => {
571
+ /*
572
+ * A missing member is a reduction the renderer supports but no user can
573
+ * choose; a duplicated one renders the same choice twice.
574
+ */
575
+ const values: Array<unknown> = DATA_SOURCE_REDUCE_DROPDOWN_OPTIONS.map(
576
+ (option: DropdownOptionView): unknown => {
577
+ return option.value;
578
+ },
579
+ );
580
+
581
+ expect(values.slice().sort()).toEqual(
582
+ Object.values(DataSourceValueReduce).slice().sort(),
583
+ );
584
+ expect(new Set<unknown>(values).size).toBe(values.length);
585
+
586
+ // Including the reduction the Value and Gauge defaults fall back to.
587
+ expect(values).toContain(DataSourceValueReduce.Last);
588
+ });
589
+
590
+ test("labels every option distinctly and non-blank", () => {
591
+ const labels: Array<string> = DATA_SOURCE_REDUCE_DROPDOWN_OPTIONS.map(
592
+ (option: DropdownOptionView): string => {
593
+ return option.label;
594
+ },
595
+ );
596
+
597
+ for (const label of labels) {
598
+ expect(label.trim().length).toBeGreaterThan(0);
599
+ }
600
+
601
+ // Two identical labels are two indistinguishable rows in the picker.
602
+ expect(new Set<string>(labels).size).toBe(labels.length);
603
+ });
604
+
605
+ test("is the option list both the Value and Gauge reduce pickers use", () => {
606
+ type FindReduceOptionsFunction = (
607
+ configArguments: Array<ConfigArgumentView>,
608
+ ) => Array<DropdownOptionView>;
609
+
610
+ const findReduceOptions: FindReduceOptionsFunction = (
611
+ configArguments: Array<ConfigArgumentView>,
612
+ ): Array<DropdownOptionView> => {
613
+ const found: ConfigArgumentView | undefined = configArguments.find(
614
+ (configArgument: ConfigArgumentView): boolean => {
615
+ return String(configArgument.id) === "reduce";
616
+ },
617
+ );
618
+
619
+ if (!found) {
620
+ throw new Error("No 'reduce' argument declared on this widget");
621
+ }
622
+
623
+ return found.dropdownOptions || [];
624
+ };
625
+
626
+ const valueOptions: Array<DropdownOptionView> = findReduceOptions(
627
+ asArgumentViews(
628
+ DashboardDataSourceValueComponentUtil.getComponentConfigArguments(),
629
+ ),
630
+ );
631
+ const gaugeOptions: Array<DropdownOptionView> = findReduceOptions(
632
+ asArgumentViews(
633
+ DashboardDataSourceGaugeComponentUtil.getComponentConfigArguments(),
634
+ ),
635
+ );
636
+
637
+ expect(valueOptions).toEqual(DATA_SOURCE_REDUCE_DROPDOWN_OPTIONS);
638
+ expect(gaugeOptions).toEqual(DATA_SOURCE_REDUCE_DROPDOWN_OPTIONS);
639
+ });
640
+ });