@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,671 @@
1
+ import {
2
+ afterAll,
3
+ beforeAll,
4
+ describe,
5
+ expect,
6
+ jest,
7
+ test,
8
+ } from "@jest/globals";
9
+ import childProcess from "child_process";
10
+ import fs from "fs";
11
+ import path from "path";
12
+ import http, { IncomingMessage, Server, createServer } from "http";
13
+ import { AddressInfo } from "net";
14
+ import { createExpressApp } from "../../../Server/Utils/Express";
15
+ import mountVendorAssets, {
16
+ MountVendorAssetsFunction,
17
+ VendorAssetsPath,
18
+ VendorAssetsRoute,
19
+ getMermaidDistPath,
20
+ } from "../../../Server/Utils/VendorAssets";
21
+
22
+ type GenericSendBody = (body: string) => void;
23
+
24
+ /*
25
+ * These run against a real Express app on a real socket rather than against a
26
+ * mocked app.use(). The bug this whole change exists to fix is a URL that
27
+ * resolves to nothing at runtime - a test that only checks which middleware
28
+ * got registered would pass with the files missing, the route mistyped, or a
29
+ * catch-all mounted ahead of it, which is every way this can actually break.
30
+ *
31
+ * Requests go through node:http rather than fetch because Common's Jest
32
+ * environment is jsdom, which supplies no fetch.
33
+ */
34
+
35
+ interface AssetResponse {
36
+ status: number;
37
+ contentType: string;
38
+ cacheControl: string;
39
+ body: Buffer;
40
+ text: string;
41
+ }
42
+
43
+ const INDEX_PAGE: string = "<html>index</html>";
44
+
45
+ const REPOSITORY_ROOT: string = path.resolve(__dirname, "..", "..", "..", "..");
46
+
47
+ describe("vendored browser assets", () => {
48
+ let server: Server;
49
+ let port: number;
50
+
51
+ beforeAll(async () => {
52
+ const app: ReturnType<typeof createExpressApp> = createExpressApp();
53
+
54
+ mountVendorAssets(app);
55
+
56
+ /*
57
+ * The catch-all every frontend service registers, so the tests below prove
58
+ * the asset mount answers first rather than falling through to an index
59
+ * page - a 200 full of HTML is the failure mode that looks like success.
60
+ */
61
+ app.get("/*", (_request: unknown, response: { send: GenericSendBody }) => {
62
+ return response.send(INDEX_PAGE);
63
+ });
64
+
65
+ server = createServer(app);
66
+
67
+ await new Promise<void>((resolve: () => void) => {
68
+ server.listen(0, "127.0.0.1", resolve);
69
+ });
70
+
71
+ port = (server.address() as AddressInfo).port;
72
+ });
73
+
74
+ afterAll(async () => {
75
+ await new Promise<void>((resolve: () => void) => {
76
+ server.close(() => {
77
+ resolve();
78
+ });
79
+ });
80
+ });
81
+
82
+ type GetAsset = (urlPath: string) => Promise<AssetResponse>;
83
+
84
+ const getAsset: GetAsset = (urlPath: string): Promise<AssetResponse> => {
85
+ return new Promise<AssetResponse>(
86
+ (
87
+ resolve: (value: AssetResponse) => void,
88
+ reject: (reason: Error) => void,
89
+ ) => {
90
+ const request: http.ClientRequest = http.get(
91
+ { host: "127.0.0.1", port, path: urlPath },
92
+ (message: IncomingMessage) => {
93
+ const chunks: Array<Buffer> = [];
94
+
95
+ message.on("data", (chunk: Buffer) => {
96
+ chunks.push(chunk);
97
+ });
98
+
99
+ message.on("end", () => {
100
+ const body: Buffer = Buffer.concat(chunks);
101
+
102
+ resolve({
103
+ status: message.statusCode || 0,
104
+ contentType: String(message.headers["content-type"] || ""),
105
+ cacheControl: String(message.headers["cache-control"] || ""),
106
+ body,
107
+ text: body.toString("utf8"),
108
+ });
109
+ });
110
+ },
111
+ );
112
+
113
+ request.on("error", reject);
114
+ },
115
+ );
116
+ };
117
+
118
+ describe("mount point", () => {
119
+ test("is the path the views hard-code", () => {
120
+ /*
121
+ * Changing this constant without changing every .ejs that references it
122
+ * breaks every server-rendered page at once, so it is pinned literally.
123
+ */
124
+ expect(VendorAssetsRoute).toBe("/oneuptime-assets");
125
+ });
126
+
127
+ test("resolves to a directory that ships with Common", () => {
128
+ expect(fs.existsSync(VendorAssetsPath)).toBe(true);
129
+ expect(fs.statSync(VendorAssetsPath).isDirectory()).toBe(true);
130
+ expect(
131
+ VendorAssetsPath.endsWith(path.join("Server", "Static", "Vendor")),
132
+ ).toBe(true);
133
+ });
134
+ });
135
+
136
+ describe("tailwind", () => {
137
+ test("serves the Play CDN build", async () => {
138
+ const asset: AssetResponse = await getAsset(
139
+ "/oneuptime-assets/tailwind/tailwind-3.4.5.js",
140
+ );
141
+
142
+ expect(asset.status).toBe(200);
143
+ expect(asset.contentType).toContain("javascript");
144
+ expect(asset.body.byteLength).toBeGreaterThan(100000);
145
+ });
146
+
147
+ test("is the only copy in the tree", () => {
148
+ /*
149
+ * Each of the five frontends used to commit its own byte-identical copy
150
+ * of this 684 KB file. They now get it copied in at build time from the
151
+ * one here, so a committed copy reappearing means someone has re-created
152
+ * the drift - two builds of Tailwind on one deployment, where a class
153
+ * renders in the dashboard and silently does nothing in the docs.
154
+ *
155
+ * Checked against git rather than the filesystem, because the build
156
+ * output is expected to be sitting there in a working tree that has run
157
+ * one; it is gitignored.
158
+ */
159
+ const tracked: string = childProcess
160
+ .execFileSync("git", ["ls-files", "--", "*tailwind-3.4.5.js"], {
161
+ cwd: REPOSITORY_ROOT,
162
+ encoding: "utf8",
163
+ })
164
+ .trim();
165
+
166
+ expect(tracked.split("\n").filter(Boolean)).toEqual([
167
+ "Common/Server/Static/Vendor/tailwind/tailwind-3.4.5.js",
168
+ ]);
169
+ });
170
+ });
171
+
172
+ describe("the frontend build's copy of tailwind", () => {
173
+ /*
174
+ * The SPAs keep loading it from their own origin - /dashboard/assets/js/...
175
+ * - rather than through the shared mount. Their index.ejs is unchanged and
176
+ * their URLs are unchanged; only where the bytes come from moved. Anything
177
+ * else would have meant editing five index.ejs files and betting the
178
+ * product's entire styling on getting all five right.
179
+ */
180
+ const esbuildConfig: string = fs.readFileSync(
181
+ path.resolve(__dirname, "..", "..", "..", "UI", "esbuild-config.js"),
182
+ "utf8",
183
+ );
184
+
185
+ test("runs for every service, on both build and watch", () => {
186
+ /* Once in build(), once in watch(), plus the definition. */
187
+ expect(esbuildConfig.match(/copyTailwindAsset\(/g)?.length).toBe(3);
188
+ });
189
+
190
+ test("reads it from the one vendored copy", () => {
191
+ expect(esbuildConfig).toContain('"Static"');
192
+ expect(esbuildConfig).toContain('"Vendor"');
193
+ expect(esbuildConfig).toContain(
194
+ 'TAILWIND_FILENAME = "tailwind-3.4.5.js"',
195
+ );
196
+ });
197
+
198
+ test("writes it to the path each index.ejs asks for", () => {
199
+ expect(esbuildConfig).toContain('"assets/js"');
200
+
201
+ const appRoot: string = path.join(REPOSITORY_ROOT, "App", "FeatureSet");
202
+
203
+ for (const [service, routePrefix] of [
204
+ ["Dashboard", "dashboard"],
205
+ ["Accounts", "accounts"],
206
+ ["AdminDashboard", "admin"],
207
+ ["StatusPage", "status-page"],
208
+ ["PublicDashboard", "public-dashboard"],
209
+ ]) {
210
+ const indexView: string = fs.readFileSync(
211
+ path.join(appRoot, service as string, "views", "index.ejs"),
212
+ "utf8",
213
+ );
214
+
215
+ expect([
216
+ service,
217
+ indexView.includes(`/${routePrefix}/assets/js/tailwind-3.4.5.js`),
218
+ ]).toEqual([service, true]);
219
+ }
220
+ });
221
+
222
+ test("is gitignored, so the build output cannot be committed back", () => {
223
+ const gitignore: string = fs.readFileSync(
224
+ path.join(REPOSITORY_ROOT, ".gitignore"),
225
+ "utf8",
226
+ );
227
+
228
+ expect(gitignore).toContain("**/public/assets/js/tailwind-3.4.5.js");
229
+ });
230
+ });
231
+
232
+ describe("highlight.js", () => {
233
+ test("serves the core bundle", async () => {
234
+ const asset: AssetResponse = await getAsset(
235
+ "/oneuptime-assets/highlight/highlight.min.js",
236
+ );
237
+
238
+ expect(asset.status).toBe(200);
239
+ expect(asset.contentType).toContain("javascript");
240
+ /* The global the view scripts call highlightAll() on. */
241
+ expect(asset.text).toContain("hljs");
242
+ });
243
+
244
+ for (const style of ["vs2015", "github-dark"]) {
245
+ test(`serves the ${style} theme`, async () => {
246
+ const asset: AssetResponse = await getAsset(
247
+ `/oneuptime-assets/highlight/styles/${style}.min.css`,
248
+ );
249
+
250
+ expect(asset.status).toBe(200);
251
+ expect(asset.contentType).toContain("text/css");
252
+ expect(asset.text).toContain(".hljs");
253
+ });
254
+ }
255
+
256
+ test("ships every grammar the API reference loads eagerly", async () => {
257
+ /*
258
+ * These are <script> tags in the API reference head, not a lazy map, so a
259
+ * missing file is a 404 on every page of the reference.
260
+ */
261
+ const eager: Array<string> = [
262
+ "python",
263
+ "go",
264
+ "java",
265
+ "csharp",
266
+ "php",
267
+ "ruby",
268
+ "rust",
269
+ "powershell",
270
+ "bash",
271
+ "json",
272
+ "javascript",
273
+ "typescript",
274
+ ];
275
+
276
+ for (const language of eager) {
277
+ const asset: AssetResponse = await getAsset(
278
+ `/oneuptime-assets/highlight/languages/${language}.min.js`,
279
+ );
280
+
281
+ expect([language, asset.status]).toEqual([language, 200]);
282
+ }
283
+ });
284
+
285
+ test("does not ship an hcl grammar, because highlight.js has none", () => {
286
+ /*
287
+ * Guards the langMap edit in the docs head: re-adding 'hcl' would put
288
+ * back a request that 404s. If highlight.js ever ships one, this test is
289
+ * the place that says so.
290
+ */
291
+ expect(
292
+ fs.existsSync(
293
+ path.join(VendorAssetsPath, "highlight", "languages", "hcl.min.js"),
294
+ ),
295
+ ).toBe(false);
296
+ });
297
+ });
298
+
299
+ describe("fonts", () => {
300
+ test("serves Inter as a woff2", async () => {
301
+ const asset: AssetResponse = await getAsset(
302
+ "/oneuptime-assets/fonts/InterVariable.woff2",
303
+ );
304
+
305
+ expect(asset.status).toBe(200);
306
+ expect(asset.contentType).toContain("font/woff2");
307
+ expect(asset.body.byteLength).toBeGreaterThan(1000);
308
+ });
309
+
310
+ test("is byte-identical to the copies the docs and reference already ship", () => {
311
+ const vendored: Buffer = fs.readFileSync(
312
+ path.join(VendorAssetsPath, "fonts", "InterVariable.woff2"),
313
+ );
314
+
315
+ const appRoot: string = path.resolve(
316
+ __dirname,
317
+ "..",
318
+ "..",
319
+ "..",
320
+ "..",
321
+ "App",
322
+ );
323
+
324
+ let compared: number = 0;
325
+
326
+ for (const service of ["Docs", "APIReference"]) {
327
+ const copy: string = path.join(
328
+ appRoot,
329
+ "FeatureSet",
330
+ service,
331
+ "Static",
332
+ "fonts",
333
+ "InterVariable.woff2",
334
+ );
335
+
336
+ if (!fs.existsSync(copy)) {
337
+ continue;
338
+ }
339
+
340
+ compared++;
341
+ expect([service, fs.readFileSync(copy).equals(vendored)]).toEqual([
342
+ service,
343
+ true,
344
+ ]);
345
+ }
346
+
347
+ expect(compared).toBe(2);
348
+ });
349
+ });
350
+
351
+ describe("mermaid", () => {
352
+ test("resolves out of node_modules rather than a committed copy", () => {
353
+ const mermaidDistPath: string | null = getMermaidDistPath();
354
+
355
+ expect(mermaidDistPath).not.toBeNull();
356
+ expect(fs.existsSync(mermaidDistPath as string)).toBe(true);
357
+ expect(
358
+ fs.existsSync(
359
+ path.join(VendorAssetsPath, "mermaid", "mermaid.esm.min.mjs"),
360
+ ),
361
+ ).toBe(false);
362
+ });
363
+
364
+ test("serves the ES module entrypoint the docs import", async () => {
365
+ const asset: AssetResponse = await getAsset(
366
+ "/oneuptime-assets/mermaid/mermaid.esm.min.mjs",
367
+ );
368
+
369
+ expect(asset.status).toBe(200);
370
+ expect(asset.text).toContain("import");
371
+ });
372
+
373
+ test("serves the lazily-imported diagram chunks the entrypoint pulls in", async () => {
374
+ /*
375
+ * The entrypoint is 26 KB; every diagram type it can draw is a separate
376
+ * import resolved relative to it. Serving only the entrypoint would have
377
+ * looked fine right up until a page contained an actual diagram.
378
+ */
379
+ const chunkDirectory: string = path.join(
380
+ getMermaidDistPath() as string,
381
+ "chunks",
382
+ "mermaid.esm.min",
383
+ );
384
+
385
+ expect(fs.existsSync(chunkDirectory)).toBe(true);
386
+
387
+ const chunk: string | undefined = fs
388
+ .readdirSync(chunkDirectory)
389
+ .find((file: string): boolean => {
390
+ return file.endsWith(".mjs");
391
+ });
392
+
393
+ expect(chunk).toBeDefined();
394
+
395
+ const asset: AssetResponse = await getAsset(
396
+ `/oneuptime-assets/mermaid/chunks/mermaid.esm.min/${chunk}`,
397
+ );
398
+
399
+ expect(asset.status).toBe(200);
400
+ });
401
+
402
+ test("serves the UMD bundle the blog loads", async () => {
403
+ const asset: AssetResponse = await getAsset(
404
+ "/oneuptime-assets/mermaid/mermaid.min.js",
405
+ );
406
+
407
+ expect(asset.status).toBe(200);
408
+ expect(asset.contentType).toContain("javascript");
409
+ });
410
+
411
+ test("does not serve the type definitions, sourcemaps or docs beside it", async () => {
412
+ /*
413
+ * dist/ is 65 MB of build outputs for every module format mermaid
414
+ * publishes. The browser asks for two of them; the rest is refused.
415
+ */
416
+ for (const notCode of [
417
+ "mermaid.d.ts",
418
+ "mermaid.min.js.map",
419
+ "config.type.d.ts",
420
+ ]) {
421
+ const asset: AssetResponse = await getAsset(
422
+ `/oneuptime-assets/mermaid/${notCode}`,
423
+ );
424
+
425
+ expect([notCode, asset.status]).toEqual([notCode, 404]);
426
+ }
427
+ });
428
+ });
429
+
430
+ describe("caching", () => {
431
+ test("marks the version-named assets immutable", async () => {
432
+ const asset: AssetResponse = await getAsset(
433
+ "/oneuptime-assets/tailwind/tailwind-3.4.5.js",
434
+ );
435
+
436
+ expect(asset.cacheControl).toContain("max-age=31536000");
437
+ });
438
+
439
+ test("keeps the year on mermaid's content-hashed chunks", async () => {
440
+ const chunkDirectory: string = path.join(
441
+ getMermaidDistPath() as string,
442
+ "chunks",
443
+ "mermaid.esm.min",
444
+ );
445
+
446
+ const chunk: string = fs
447
+ .readdirSync(chunkDirectory)
448
+ .find((file: string): boolean => {
449
+ return file.endsWith(".mjs");
450
+ }) as string;
451
+
452
+ const asset: AssetResponse = await getAsset(
453
+ `/oneuptime-assets/mermaid/chunks/mermaid.esm.min/${chunk}`,
454
+ );
455
+
456
+ expect(asset.status).toBe(200);
457
+ expect(asset.cacheControl).toContain("max-age=31536000");
458
+ });
459
+
460
+ test("does not give mermaid's stable entrypoints a year", async () => {
461
+ /*
462
+ * mermaid.esm.min.mjs keeps its name across releases while every chunk it
463
+ * imports is content-hashed. Cached for a year, a visitor who came back
464
+ * after a mermaid bump would keep replaying an entrypoint that asks for
465
+ * chunk filenames the upgrade deleted - and every docs diagram would stay
466
+ * broken for that one person until the entry aged out.
467
+ */
468
+ for (const entrypoint of ["mermaid.esm.min.mjs", "mermaid.min.js"]) {
469
+ const asset: AssetResponse = await getAsset(
470
+ `/oneuptime-assets/mermaid/${entrypoint}`,
471
+ );
472
+
473
+ expect([entrypoint, asset.status]).toEqual([entrypoint, 200]);
474
+ expect([
475
+ entrypoint,
476
+ asset.cacheControl.includes("max-age=31536000"),
477
+ ]).toEqual([entrypoint, false]);
478
+ expect([entrypoint, asset.cacheControl]).toEqual([
479
+ entrypoint,
480
+ "public, max-age=3600",
481
+ ]);
482
+ }
483
+ });
484
+ });
485
+
486
+ describe("anything the mount does not have", () => {
487
+ /*
488
+ * These three all used to fall through to whatever was registered next.
489
+ * In the App container that is the dashboard's SPA catch-all, which answers
490
+ * HTTP 200 with text/html - so a missing stylesheet came back as a page, a
491
+ * <script> handed HTML fired onload rather than onerror, and the docs' lazy
492
+ * grammar loader counted it as a success. A 404 is the whole point.
493
+ */
494
+ test("a grammar that was never vendored is a 404, not the index page", async () => {
495
+ const asset: AssetResponse = await getAsset(
496
+ "/oneuptime-assets/highlight/languages/no-such-grammar.min.js",
497
+ );
498
+
499
+ expect(asset.status).toBe(404);
500
+ expect(asset.text).not.toBe(INDEX_PAGE);
501
+ });
502
+
503
+ test("a directory is a 404 rather than a listing or the index page", async () => {
504
+ const asset: AssetResponse = await getAsset(
505
+ "/oneuptime-assets/highlight/languages/",
506
+ );
507
+
508
+ expect(asset.status).toBe(404);
509
+ expect(asset.text).not.toBe(INDEX_PAGE);
510
+ });
511
+
512
+ test("the bare mount point is a 404", async () => {
513
+ const asset: AssetResponse = await getAsset("/oneuptime-assets/");
514
+
515
+ expect(asset.status).toBe(404);
516
+ expect(asset.text).not.toBe(INDEX_PAGE);
517
+ });
518
+
519
+ test("a path that escapes the vendor directory is refused", async () => {
520
+ const asset: AssetResponse = await getAsset(
521
+ "/oneuptime-assets/../../package.json",
522
+ );
523
+
524
+ expect(asset.text).not.toContain("@oneuptime/common");
525
+ });
526
+ });
527
+ });
528
+
529
+ describe("when the vendored directory is missing from the image", () => {
530
+ /*
531
+ * The failure this guards is subtle: the early return that used to sit here
532
+ * skipped the terminating 404 along with the static mount, so a build that
533
+ * shipped without Common/Server/Static/Vendor answered every asset request
534
+ * with the dashboard's index page at HTTP 200 - and looked, from the outside,
535
+ * like it was working.
536
+ */
537
+ let server: Server;
538
+ let port: number;
539
+
540
+ beforeAll(async () => {
541
+ jest.resetModules();
542
+
543
+ jest.doMock("fs", () => {
544
+ const actual: typeof fs = jest.requireActual("fs") as typeof fs;
545
+
546
+ return {
547
+ ...actual,
548
+ existsSync: (candidate: string): boolean => {
549
+ if (candidate === VendorAssetsPath) {
550
+ return false;
551
+ }
552
+
553
+ return actual.existsSync(candidate);
554
+ },
555
+ };
556
+ });
557
+
558
+ /*
559
+ * Re-imported after doMock so the module evaluates against the stubbed fs.
560
+ * A dynamic import, not the static one at the top of the file - that
561
+ * instance was built before the mock existed and still sees the real
562
+ * directory.
563
+ */
564
+ const mountWithoutVendorDirectory: MountVendorAssetsFunction = (
565
+ (await import("../../../Server/Utils/VendorAssets")) as {
566
+ default: MountVendorAssetsFunction;
567
+ }
568
+ ).default;
569
+
570
+ const app: ReturnType<typeof createExpressApp> = createExpressApp();
571
+
572
+ mountWithoutVendorDirectory(app);
573
+
574
+ app.get("/*", (_request: unknown, response: { send: GenericSendBody }) => {
575
+ return response.send(INDEX_PAGE);
576
+ });
577
+
578
+ server = createServer(app);
579
+
580
+ await new Promise<void>((resolve: () => void) => {
581
+ server.listen(0, "127.0.0.1", resolve);
582
+ });
583
+
584
+ port = (server.address() as AddressInfo).port;
585
+ });
586
+
587
+ afterAll(async () => {
588
+ jest.dontMock("fs");
589
+ jest.resetModules();
590
+
591
+ await new Promise<void>((resolve: () => void) => {
592
+ server.close(() => {
593
+ resolve();
594
+ });
595
+ });
596
+ });
597
+
598
+ test("still refuses the request rather than handing back a page", async () => {
599
+ const status: number = await new Promise<number>(
600
+ (resolve: (value: number) => void, reject: (reason: Error) => void) => {
601
+ const request: http.ClientRequest = http.get(
602
+ {
603
+ host: "127.0.0.1",
604
+ port,
605
+ path: "/oneuptime-assets/tailwind/tailwind-3.4.5.js",
606
+ },
607
+ (message: IncomingMessage) => {
608
+ message.resume();
609
+ resolve(message.statusCode || 0);
610
+ },
611
+ );
612
+
613
+ request.on("error", reject);
614
+ },
615
+ );
616
+
617
+ expect(status).toBe(404);
618
+ });
619
+ });
620
+
621
+ describe("every service mounts the vendored assets", () => {
622
+ /*
623
+ * Read rather than executed: importing StartServer creates the app, wires
624
+ * the common API and registers a shutdown handler. What matters here is only
625
+ * that the mount happens, and that it happens early - a frontend service
626
+ * answers "/*" with its index page, so a mount registered after that would
627
+ * hand the browser HTML with a 200 for every stylesheet it asked for. That
628
+ * is worse than a 404, because nothing logs it.
629
+ */
630
+ const startServerSource: string = fs.readFileSync(
631
+ path.resolve(
632
+ __dirname,
633
+ "..",
634
+ "..",
635
+ "..",
636
+ "Server",
637
+ "Utils",
638
+ "StartServer.ts",
639
+ ),
640
+ "utf8",
641
+ );
642
+
643
+ test("imports the mount from VendorAssets", () => {
644
+ expect(startServerSource).toContain(
645
+ 'import mountVendorAssets from "./VendorAssets";',
646
+ );
647
+ });
648
+
649
+ test("calls it during init", () => {
650
+ expect(startServerSource).toContain("mountVendorAssets(app);");
651
+ });
652
+
653
+ test("calls it before the frontend static mount and the catch-all", () => {
654
+ const mountIndex: number = startServerSource.indexOf(
655
+ "mountVendorAssets(app);",
656
+ );
657
+ const frontendStaticIndex: number = startServerSource.indexOf(
658
+ 'ExpressStatic("/usr/src/app/public")',
659
+ );
660
+ const catchAllIndex: number = startServerSource.indexOf(
661
+ '["/*", `/${appName}/*`]',
662
+ );
663
+
664
+ expect(mountIndex).toBeGreaterThan(-1);
665
+ expect(frontendStaticIndex).toBeGreaterThan(-1);
666
+ expect(catchAllIndex).toBeGreaterThan(-1);
667
+
668
+ expect(mountIndex).toBeLessThan(frontendStaticIndex);
669
+ expect(mountIndex).toBeLessThan(catchAllIndex);
670
+ });
671
+ });