@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.
- package/Models/DatabaseModels/AIRun.ts +33 -0
- package/Models/DatabaseModels/DataSource.ts +744 -0
- package/Models/DatabaseModels/Index.ts +3 -0
- package/Models/DatabaseModels/ProjectCallSMSConfig.ts +10 -2
- package/Models/DatabaseModels/User.ts +2 -0
- package/Models/DatabaseModels/UserOnCallLog.ts +2 -0
- package/Models/DatabaseModels/UserOnCallLogTimeline.ts +2 -0
- package/Models/DatabaseModels/UserSession.ts +2 -0
- package/Models/DatabaseModels/UserTotpAuth.ts +6 -4
- package/Models/DatabaseModels/UserWebAuthn.ts +5 -3
- package/Server/API/AIInsightAPI.ts +47 -4
- package/Server/API/AIInvestigationAPI.ts +25 -0
- package/Server/API/DashboardAPI.ts +176 -492
- package/Server/API/DataSourceAPI.ts +268 -0
- package/Server/API/StatusPageAPI.ts +11 -1
- package/Server/API/UserAPI.ts +119 -0
- package/Server/Infrastructure/ClickhouseConfig.ts +59 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.ts +39 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.ts +24 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.ts +76 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Infrastructure/Queue.ts +26 -0
- package/Server/Infrastructure/QueueWorker.ts +17 -0
- package/Server/Middleware/TelemetryIngest.ts +8 -3
- package/Server/Services/AIInsightService.ts +132 -12
- package/Server/Services/AIRunService.ts +34 -0
- package/Server/Services/AIService.ts +17 -2
- package/Server/Services/AlertService.ts +38 -32
- package/Server/Services/AnalyticsDatabaseService.ts +8 -4
- package/Server/Services/DataSourceService.ts +200 -0
- package/Server/Services/HostService.ts +92 -0
- package/Server/Services/IncidentService.ts +45 -0
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/MonitorService.ts +49 -0
- package/Server/Services/MonitorStatusService.ts +166 -0
- package/Server/Services/OpenTelemetryIngestService.ts +255 -184
- package/Server/Services/RumSessionPinService.ts +7 -21
- package/Server/Services/StatusPageSubscriberService.ts +13 -0
- package/Server/Services/UserService.ts +280 -9
- package/Server/Static/Vendor/README.md +62 -0
- package/Server/Static/Vendor/fonts/InterVariable.woff2 +0 -0
- package/Server/Static/Vendor/highlight/highlight.min.js +1244 -0
- package/Server/Static/Vendor/highlight/languages/apache.min.js +15 -0
- package/Server/Static/Vendor/highlight/languages/bash.min.js +21 -0
- package/Server/Static/Vendor/highlight/languages/c.min.js +41 -0
- package/Server/Static/Vendor/highlight/languages/cpp.min.js +47 -0
- package/Server/Static/Vendor/highlight/languages/csharp.min.js +49 -0
- package/Server/Static/Vendor/highlight/languages/css.min.js +31 -0
- package/Server/Static/Vendor/highlight/languages/diff.min.js +9 -0
- package/Server/Static/Vendor/highlight/languages/dns.min.js +11 -0
- package/Server/Static/Vendor/highlight/languages/dockerfile.min.js +8 -0
- package/Server/Static/Vendor/highlight/languages/go.min.js +20 -0
- package/Server/Static/Vendor/highlight/languages/graphql.min.js +12 -0
- package/Server/Static/Vendor/highlight/languages/http.min.js +14 -0
- package/Server/Static/Vendor/highlight/languages/ini.min.js +15 -0
- package/Server/Static/Vendor/highlight/languages/java.min.js +38 -0
- package/Server/Static/Vendor/highlight/languages/javascript.min.js +81 -0
- package/Server/Static/Vendor/highlight/languages/json.min.js +8 -0
- package/Server/Static/Vendor/highlight/languages/kotlin.min.js +46 -0
- package/Server/Static/Vendor/highlight/languages/lua.min.js +15 -0
- package/Server/Static/Vendor/highlight/languages/makefile.min.js +14 -0
- package/Server/Static/Vendor/highlight/languages/nginx.min.js +21 -0
- package/Server/Static/Vendor/highlight/languages/perl.min.js +41 -0
- package/Server/Static/Vendor/highlight/languages/php.min.js +59 -0
- package/Server/Static/Vendor/highlight/languages/powershell.min.js +39 -0
- package/Server/Static/Vendor/highlight/languages/python.min.js +42 -0
- package/Server/Static/Vendor/highlight/languages/r.min.js +26 -0
- package/Server/Static/Vendor/highlight/languages/ruby.min.js +54 -0
- package/Server/Static/Vendor/highlight/languages/rust.min.js +27 -0
- package/Server/Static/Vendor/highlight/languages/scala.min.js +28 -0
- package/Server/Static/Vendor/highlight/languages/sql.min.js +21 -0
- package/Server/Static/Vendor/highlight/languages/swift.min.js +68 -0
- package/Server/Static/Vendor/highlight/languages/typescript.min.js +99 -0
- package/Server/Static/Vendor/highlight/languages/xml.min.js +29 -0
- package/Server/Static/Vendor/highlight/languages/yaml.min.js +28 -0
- package/Server/Static/Vendor/highlight/styles/github-dark.min.css +10 -0
- package/Server/Static/Vendor/highlight/styles/vs2015.min.css +1 -0
- package/Server/Static/Vendor/tailwind/tailwind-3.4.5.js +21028 -0
- package/Server/Types/Database/Permissions/BasePermission.ts +7 -0
- package/Server/Types/Database/Permissions/DeletePermission.ts +2 -0
- package/Server/Types/Database/Permissions/ReadPermission.ts +3 -0
- package/Server/Types/Database/Permissions/TenantPermission.ts +101 -16
- package/Server/Utils/AI/CodeFix/FixRunBudget.ts +2 -2
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +90 -11
- package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +1 -0
- package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +1 -0
- package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.ts +125 -0
- package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts +25 -15
- package/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts +256 -57
- package/Server/Utils/AI/SRE/Insights/InsightStore.ts +76 -18
- package/Server/Utils/AI/SRE/InvestigationTldr.ts +352 -0
- package/Server/Utils/AnalyticsDatabase/InsertDedupContext.ts +7 -2
- package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +1793 -0
- package/Server/Utils/Dashboard/PublicDashboardViewConfig.ts +65 -0
- package/Server/Utils/DataSource/ConnectorRegistry.ts +53 -0
- package/Server/Utils/DataSource/Connectors/ClickHouseConnector.ts +338 -0
- package/Server/Utils/DataSource/Connectors/ElasticsearchConnector.ts +717 -0
- package/Server/Utils/DataSource/Connectors/LokiConnector.ts +606 -0
- package/Server/Utils/DataSource/Connectors/MySqlConnector.ts +307 -0
- package/Server/Utils/DataSource/Connectors/PostgresConnector.ts +260 -0
- package/Server/Utils/DataSource/Connectors/PrometheusConnector.ts +555 -0
- package/Server/Utils/DataSource/Connectors/RestApiConnector.ts +597 -0
- package/Server/Utils/DataSource/Connectors/SqlServerConnector.ts +318 -0
- package/Server/Utils/DataSource/EgressGuard.ts +446 -0
- package/Server/Utils/DataSource/HttpFetch.ts +221 -0
- package/Server/Utils/DataSource/SqlQueryGuard.ts +383 -0
- package/Server/Utils/DataSource/SqlResultShaper.ts +372 -0
- package/Server/Utils/DataSource/Types.ts +93 -0
- package/Server/Utils/Database/PostgresErrorTranslator.ts +172 -17
- package/Server/Utils/InProcessMemo.ts +141 -0
- package/Server/Utils/InstanceHealth/TelemetryIngestion.ts +628 -0
- package/Server/Utils/Monitor/MonitorMetricUtil.ts +58 -0
- package/Server/Utils/Monitor/MonitorResource.ts +14 -0
- package/Server/Utils/Response.ts +12 -1
- package/Server/Utils/SSRFProtection.ts +237 -0
- package/Server/Utils/StartServer.ts +8 -0
- package/Server/Utils/StatusPageSubscriberWebhook.ts +30 -0
- package/Server/Utils/Telemetry/CaptureSpan.ts +30 -18
- package/Server/Utils/Telemetry/IngestionTimestamp.ts +75 -0
- package/Server/Utils/Telemetry/ResourceHeartbeat.ts +99 -7
- package/Server/Utils/Telemetry/Telemetry.ts +112 -1
- package/Server/Utils/Telemetry.ts +104 -3
- package/Server/Utils/VendorAssets.ts +165 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +28 -5
- package/Server/Utils/Workspace/Slack/Slack.ts +5 -0
- package/Server/Views/Partials/Head.ejs +21 -7
- package/Tests/App/AdminDashboard/AdminProjectsIdFilter.test.tsx +207 -0
- package/Tests/App/AdminDashboard/AdminUsersIdFilter.test.tsx +216 -0
- package/Tests/App/Dashboard/AIInsightViewActions.test.tsx +422 -0
- package/Tests/App/Dashboard/AddWidgetModal.test.tsx +10 -3
- package/Tests/App/Dashboard/AlertsSideMenu.test.tsx +387 -0
- package/Tests/App/Dashboard/ChatActivityFeed.test.tsx +199 -0
- package/Tests/App/Dashboard/DataSourceChartSyntheticConfig.test.tsx +736 -0
- package/Tests/App/Dashboard/DataSourceQueryEditor.test.tsx +868 -0
- package/Tests/App/Dashboard/DataSourceWidgetCatalog.test.ts +440 -0
- package/Tests/App/Dashboard/DataSourceWidgetFetching.test.tsx +2109 -0
- package/Tests/App/Dashboard/DataSourceWidgetViews.test.tsx +726 -0
- package/Tests/App/Dashboard/IncidentsSideMenu.test.tsx +447 -0
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +514 -3
- package/Tests/App/Dashboard/ProductMenuBreadcrumbs.test.tsx +391 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceSideMenu.test.tsx +326 -0
- package/Tests/App/Dashboard/SideMenuHarness.tsx +187 -0
- package/Tests/App/Dashboard/WidgetCatalog.test.ts +6 -1
- package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +1858 -0
- package/Tests/Models/DatabaseModels/DataSourceModelSecrets.test.ts +70 -0
- package/Tests/Server/API/AIInvestigationAPI.test.ts +187 -0
- package/Tests/Server/API/DashboardPublicDataSourceStrip.test.ts +686 -0
- package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +585 -823
- package/Tests/Server/API/DataSourceAPIRoutes.test.ts +486 -0
- package/Tests/Server/API/StatusPageSubscriberOwnership.test.ts +291 -0
- package/Tests/Server/API/UserAuthenticationAPI.test.ts +641 -0
- package/Tests/Server/Infrastructure/ClickhouseKeepAliveOptions.test.ts +441 -0
- package/Tests/Server/Middleware/TelemetryIngestTokenLog.test.ts +140 -0
- package/Tests/Server/Services/AIInsightService.test.ts +266 -11
- package/Tests/Server/Services/AIRunAnalysisTldrPersistence.test.ts +160 -0
- package/Tests/Server/Services/AIServiceDailyBudget.test.ts +4 -0
- package/Tests/Server/Services/AlertMetricResourceAttributes.test.ts +352 -0
- package/Tests/Server/Services/DataSourceServiceSettings.test.ts +244 -0
- package/Tests/Server/Services/HostServiceFindOrCreateMemo.test.ts +397 -0
- package/Tests/Server/Services/HostServiceUpdateLastSeen.test.ts +41 -2
- package/Tests/Server/Services/IncidentMetricResourceAttributes.test.ts +408 -0
- package/Tests/Server/Services/MonitorStatusServiceDeleteReferenceCleanup.test.ts +351 -0
- package/Tests/Server/Services/MonitorStatusServiceValidation.test.ts +171 -0
- package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +398 -0
- package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +19 -0
- package/Tests/Server/Services/ProjectCallSMSConfigCredentialUniqueness.test.ts +305 -0
- package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +36 -1
- package/Tests/Server/Services/RumSessionPinUniqueViolationRecovery.test.ts +163 -0
- package/Tests/Server/Services/UserAuthenticationService.test.ts +973 -0
- package/Tests/Server/Types/Database/ObjectIdColumnQuery.test.ts +262 -0
- package/Tests/Server/Types/Database/Permissions/TenantPermission.test.ts +358 -0
- package/Tests/Server/Utils/AI/FixRunBudget.test.ts +2 -2
- package/Tests/Server/Utils/AI/Insights/ExceptionSpikeDetector.test.ts +6 -1
- package/Tests/Server/Utils/AI/Insights/InsightStore.test.ts +121 -4
- package/Tests/Server/Utils/AI/Insights/NewExceptionDetector.test.ts +361 -10
- package/Tests/Server/Utils/AI/InvestigationSettlement.test.ts +292 -0
- package/Tests/Server/Utils/AI/InvestigationTldr.test.ts +623 -0
- package/Tests/Server/Utils/AI/InvestigationTldrWiring.test.ts +98 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +857 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardViewConfig.test.ts +480 -0
- package/Tests/Server/Utils/DataSource/ClickHouseConnector.test.ts +759 -0
- package/Tests/Server/Utils/DataSource/ConnectorRegistry.test.ts +37 -0
- package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +645 -0
- package/Tests/Server/Utils/DataSource/ElasticsearchConnector.test.ts +1206 -0
- package/Tests/Server/Utils/DataSource/HttpFetch.test.ts +616 -0
- package/Tests/Server/Utils/DataSource/LokiConnector.test.ts +970 -0
- package/Tests/Server/Utils/DataSource/MySqlConnector.test.ts +935 -0
- package/Tests/Server/Utils/DataSource/PostgresConnector.test.ts +854 -0
- package/Tests/Server/Utils/DataSource/PrometheusConnector.test.ts +881 -0
- package/Tests/Server/Utils/DataSource/RestApiConnector.test.ts +1020 -0
- package/Tests/Server/Utils/DataSource/SqlQueryGuard.test.ts +425 -0
- package/Tests/Server/Utils/DataSource/SqlResultShaper.test.ts +555 -0
- package/Tests/Server/Utils/DataSource/SqlServerConnector.test.ts +934 -0
- package/Tests/Server/Utils/Database/PostgresErrorTranslator.test.ts +228 -7
- package/Tests/Server/Utils/InProcessMemo.test.ts +292 -0
- package/Tests/Server/Utils/InstanceHealth/TelemetryIngestion.test.ts +960 -0
- package/Tests/Server/Utils/MicrosoftTeamsWebhookUrlValidation.test.ts +103 -0
- package/Tests/Server/Utils/Monitor/MonitorMetricResourceAttributes.test.ts +336 -0
- package/Tests/Server/Utils/OfflineAssetHygiene.test.ts +521 -0
- package/Tests/Server/Utils/ResponseRenderAnalytics.test.ts +143 -0
- package/Tests/Server/Utils/SSRFProtection.test.ts +193 -0
- package/Tests/Server/Utils/StatusPageSubscriberWebhook.test.ts +101 -0
- package/Tests/Server/Utils/TailwindBuildCopy.test.ts +225 -0
- package/Tests/Server/Utils/Telemetry/ResourceHeartbeatL1Memo.test.ts +355 -0
- package/Tests/Server/Utils/Telemetry/TelemetryFanInWriter.test.ts +128 -0
- package/Tests/Server/Utils/Telemetry/TelemetryUtilAttributeKeys.test.ts +381 -0
- package/Tests/Server/Utils/Telemetry.test.ts +87 -0
- package/Tests/Server/Utils/VendorAssetIntegrity.test.ts +343 -0
- package/Tests/Server/Utils/VendorAssets.test.ts +671 -0
- package/Tests/Server/Views/OfflineRender.test.ts +297 -0
- package/Tests/Types/Dashboard/DataSourceComponentTypes.test.ts +618 -0
- package/Tests/Types/DateClickhouseFormat.test.ts +192 -0
- package/Tests/Types/Password.test.ts +363 -0
- package/Tests/UI/Components/ConfirmModal.test.tsx +7 -0
- package/Tests/UI/Components/ErrorBoundary.test.tsx +53 -0
- package/Tests/UI/Components/Modal.test.tsx +281 -1
- package/Tests/UI/Components/ObjectIdFilterPipeline.test.tsx +396 -0
- package/Tests/UI/Components/StatusPage/ResourceGroupNavigator.test.tsx +1147 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +116 -1
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +2 -0
- package/Tests/Utils/Analytics.test.ts +23 -0
- package/Tests/Utils/Dashboard/Components/DashboardDataSourceComponents.test.ts +640 -0
- package/Tests/Utils/DataSource/DataSourceQueryText.test.ts +138 -0
- package/Tests/Utils/DataSource/DataSourceValueReducer.test.ts +526 -0
- package/Tests/Utils/Metrics/MetricResourceAttributeUtil.test.ts +691 -0
- package/Tests/Utils/StatusPage/GroupHierarchyView.test.ts +1452 -0
- package/Tests/Utils/StatusPage/ResourceExplorer.test.ts +931 -0
- package/Tests/Utils/Telemetry/CaptureSpanExportGating.test.ts +288 -0
- package/Tests/Utils/Telemetry/IngestionTimestamp.test.ts +170 -0
- package/Types/AI/AIInsightEvidence.ts +6 -0
- package/Types/Analytics/RevenueEvent.ts +31 -0
- package/Types/Dashboard/DashboardComponentType.ts +31 -0
- package/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.ts +27 -0
- package/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.ts +32 -0
- package/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.ts +30 -0
- package/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.ts +55 -0
- package/Types/DataSource/DataSourceLimits.ts +62 -0
- package/Types/DataSource/DataSourceQueryConfig.ts +41 -0
- package/Types/DataSource/DataSourceTableResult.ts +38 -0
- package/Types/DataSource/DataSourceType.ts +213 -0
- package/Types/Date.ts +43 -3
- package/Types/Password.ts +64 -0
- package/Types/Permission.ts +46 -0
- package/Types/UserAuthenticationStatus.ts +34 -0
- package/UI/Components/Button/Button.tsx +1 -1
- package/UI/Components/ErrorBoundary.tsx +459 -108
- package/UI/Components/Icon/Icon.tsx +10 -9
- package/UI/Components/Modal/ConfirmModal.tsx +6 -1
- package/UI/Components/Modal/Modal.tsx +267 -35
- package/UI/Components/Modal/ModalFooter.tsx +6 -1
- package/UI/Components/MoreMenu/MoreMenu.tsx +19 -4
- package/UI/Components/MoreMenu/MoreMenuItem.tsx +6 -1
- package/UI/Components/StatusPage/ResourceGrid.tsx +314 -0
- package/UI/Components/StatusPage/ResourceGroupNavigator.tsx +808 -0
- package/UI/Components/StatusPage/ResourceList.tsx +570 -0
- package/UI/Styles/Theme.css +18 -0
- package/UI/Utils/API/RequestOptions.ts +7 -0
- package/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.ts +1 -0
- package/UI/Utils/ModelAPI/ModelAPI.ts +1 -0
- package/UI/Utils/TestDataSource.ts +61 -0
- package/UI/esbuild-config.js +45 -0
- package/Utils/Analytics.ts +15 -0
- package/Utils/Dashboard/Components/DashboardDataSourceChartComponent.ts +88 -0
- package/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.ts +123 -0
- package/Utils/Dashboard/Components/DashboardDataSourceShared.ts +16 -0
- package/Utils/Dashboard/Components/DashboardDataSourceTableComponent.ts +72 -0
- package/Utils/Dashboard/Components/DashboardDataSourceValueComponent.ts +126 -0
- package/Utils/Dashboard/Components/Index.ts +28 -0
- package/Utils/DataSource/DataSourceQueryText.ts +94 -0
- package/Utils/DataSource/DataSourceValueReducer.ts +156 -0
- package/Utils/Metrics/MetricResourceAttributeUtil.ts +380 -0
- package/Utils/NetworkDiscovery/ScanTargetUtil.ts +8 -6
- package/Utils/StatusPage/GroupHierarchyView.ts +931 -0
- package/Utils/StatusPage/ResourceExplorer.ts +853 -0
- package/build/dist/Models/DatabaseModels/AIRun.js +34 -0
- package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DataSource.js +774 -0
- package/build/dist/Models/DatabaseModels/DataSource.js.map +1 -0
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js +14 -4
- package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/User.js +2 -0
- package/build/dist/Models/DatabaseModels/User.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserOnCallLog.js +2 -0
- package/build/dist/Models/DatabaseModels/UserOnCallLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js +2 -0
- package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserSession.js +2 -0
- package/build/dist/Models/DatabaseModels/UserSession.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserTotpAuth.js +6 -4
- package/build/dist/Models/DatabaseModels/UserTotpAuth.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserWebAuthn.js +5 -3
- package/build/dist/Models/DatabaseModels/UserWebAuthn.js.map +1 -1
- package/build/dist/Server/API/AIInsightAPI.js +34 -4
- package/build/dist/Server/API/AIInsightAPI.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +23 -0
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/DashboardAPI.js +119 -433
- package/build/dist/Server/API/DashboardAPI.js.map +1 -1
- package/build/dist/Server/API/DataSourceAPI.js +173 -0
- package/build/dist/Server/API/DataSourceAPI.js.map +1 -0
- package/build/dist/Server/API/StatusPageAPI.js +11 -1
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/UserAPI.js +94 -2
- package/build/dist/Server/API/UserAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/ClickhouseConfig.js +49 -0
- package/build/dist/Server/Infrastructure/ClickhouseConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.js +19 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.js +64 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/Queue.js +27 -0
- package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
- package/build/dist/Server/Infrastructure/QueueWorker.js +13 -0
- package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +8 -3
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/AIInsightService.js +110 -10
- package/build/dist/Server/Services/AIInsightService.js.map +1 -1
- package/build/dist/Server/Services/AIRunService.js +34 -0
- package/build/dist/Server/Services/AIRunService.js.map +1 -1
- package/build/dist/Server/Services/AIService.js +16 -2
- package/build/dist/Server/Services/AIService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +28 -35
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +8 -4
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DataSourceService.js +159 -0
- package/build/dist/Server/Services/DataSourceService.js.map +1 -0
- package/build/dist/Server/Services/HostService.js +74 -0
- package/build/dist/Server/Services/HostService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +35 -24
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +45 -0
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorStatusService.js +129 -0
- package/build/dist/Server/Services/MonitorStatusService.js.map +1 -1
- package/build/dist/Server/Services/OpenTelemetryIngestService.js +222 -159
- package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
- package/build/dist/Server/Services/RumSessionPinService.js +7 -15
- package/build/dist/Server/Services/RumSessionPinService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberService.js +10 -0
- package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +241 -10
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/BasePermission.js +6 -0
- package/build/dist/Server/Types/Database/Permissions/BasePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/DeletePermission.js +1 -0
- package/build/dist/Server/Types/Database/Permissions/DeletePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/ReadPermission.js +2 -0
- package/build/dist/Server/Types/Database/Permissions/ReadPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/TenantPermission.js +68 -12
- package/build/dist/Server/Types/Database/Permissions/TenantPermission.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +2 -2
- package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +68 -8
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +1 -0
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +1 -0
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.js +97 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js +17 -15
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js +178 -54
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js +65 -16
- package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationTldr.js +303 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationTldr.js.map +1 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/InsertDedupContext.js.map +1 -1
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +1261 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardViewConfig.js +47 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardViewConfig.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/ConnectorRegistry.js +42 -0
- package/build/dist/Server/Utils/DataSource/ConnectorRegistry.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/ClickHouseConnector.js +187 -0
- package/build/dist/Server/Utils/DataSource/Connectors/ClickHouseConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/ElasticsearchConnector.js +493 -0
- package/build/dist/Server/Utils/DataSource/Connectors/ElasticsearchConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/LokiConnector.js +399 -0
- package/build/dist/Server/Utils/DataSource/Connectors/LokiConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/MySqlConnector.js +195 -0
- package/build/dist/Server/Utils/DataSource/Connectors/MySqlConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/PostgresConnector.js +149 -0
- package/build/dist/Server/Utils/DataSource/Connectors/PostgresConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/PrometheusConnector.js +362 -0
- package/build/dist/Server/Utils/DataSource/Connectors/PrometheusConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/RestApiConnector.js +342 -0
- package/build/dist/Server/Utils/DataSource/Connectors/RestApiConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/SqlServerConnector.js +186 -0
- package/build/dist/Server/Utils/DataSource/Connectors/SqlServerConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/EgressGuard.js +305 -0
- package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/HttpFetch.js +134 -0
- package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/SqlQueryGuard.js +331 -0
- package/build/dist/Server/Utils/DataSource/SqlQueryGuard.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/SqlResultShaper.js +280 -0
- package/build/dist/Server/Utils/DataSource/SqlResultShaper.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Types.js +2 -0
- package/build/dist/Server/Utils/DataSource/Types.js.map +1 -0
- package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js +103 -9
- package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js.map +1 -1
- package/build/dist/Server/Utils/InProcessMemo.js +113 -0
- package/build/dist/Server/Utils/InProcessMemo.js.map +1 -0
- package/build/dist/Server/Utils/InstanceHealth/TelemetryIngestion.js +406 -0
- package/build/dist/Server/Utils/InstanceHealth/TelemetryIngestion.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +34 -0
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +14 -0
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Response.js +9 -1
- package/build/dist/Server/Utils/Response.js.map +1 -1
- package/build/dist/Server/Utils/SSRFProtection.js +192 -0
- package/build/dist/Server/Utils/SSRFProtection.js.map +1 -0
- package/build/dist/Server/Utils/StartServer.js +7 -0
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/StatusPageSubscriberWebhook.js +24 -0
- package/build/dist/Server/Utils/StatusPageSubscriberWebhook.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/CaptureSpan.js +25 -11
- package/build/dist/Server/Utils/Telemetry/CaptureSpan.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/IngestionTimestamp.js +32 -0
- package/build/dist/Server/Utils/Telemetry/IngestionTimestamp.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js +92 -5
- package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/Telemetry.js +92 -6
- package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry.js +93 -6
- package/build/dist/Server/Utils/Telemetry.js.map +1 -1
- package/build/dist/Server/Utils/VendorAssets.js +121 -0
- package/build/dist/Server/Utils/VendorAssets.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +25 -4
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js +5 -0
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
- package/build/dist/Types/Analytics/RevenueEvent.js +26 -0
- package/build/dist/Types/Analytics/RevenueEvent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js +27 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.js +16 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.js.map +1 -0
- package/build/dist/Types/DataSource/DataSourceLimits.js +47 -0
- package/build/dist/Types/DataSource/DataSourceLimits.js.map +1 -0
- package/build/dist/Types/DataSource/DataSourceQueryConfig.js +10 -0
- package/build/dist/Types/DataSource/DataSourceQueryConfig.js.map +1 -0
- package/build/dist/Types/DataSource/DataSourceTableResult.js +14 -0
- package/build/dist/Types/DataSource/DataSourceTableResult.js.map +1 -0
- package/build/dist/Types/DataSource/DataSourceType.js +183 -0
- package/build/dist/Types/DataSource/DataSourceType.js.map +1 -0
- package/build/dist/Types/Date.js +38 -3
- package/build/dist/Types/Date.js.map +1 -1
- package/build/dist/Types/Password.js +56 -0
- package/build/dist/Types/Password.js.map +1 -0
- package/build/dist/Types/Permission.js +42 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/UserAuthenticationStatus.js +2 -0
- package/build/dist/Types/UserAuthenticationStatus.js.map +1 -0
- package/build/dist/UI/Components/ErrorBoundary.js +388 -72
- package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +10 -4
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/Modal/ConfirmModal.js +1 -1
- package/build/dist/UI/Components/Modal/ConfirmModal.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +178 -19
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/Modal/ModalFooter.js +3 -1
- package/build/dist/UI/Components/Modal/ModalFooter.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js +9 -6
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +7 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceGrid.js +119 -0
- package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -0
- package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js +354 -0
- package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js.map +1 -0
- package/build/dist/UI/Components/StatusPage/ResourceList.js +203 -0
- package/build/dist/UI/Components/StatusPage/ResourceList.js.map +1 -0
- package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js +1 -6
- package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +3 -8
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/TestDataSource.js +39 -0
- package/build/dist/UI/Utils/TestDataSource.js.map +1 -0
- package/build/dist/Utils/Analytics.js +4 -0
- package/build/dist/Utils/Analytics.js.map +1 -1
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceChartComponent.js +79 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceChartComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.js +111 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceShared.js +15 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceShared.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceTableComponent.js +62 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceTableComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceValueComponent.js +112 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceValueComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/Index.js +16 -0
- package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
- package/build/dist/Utils/DataSource/DataSourceQueryText.js +64 -0
- package/build/dist/Utils/DataSource/DataSourceQueryText.js.map +1 -0
- package/build/dist/Utils/DataSource/DataSourceValueReducer.js +124 -0
- package/build/dist/Utils/DataSource/DataSourceValueReducer.js.map +1 -0
- package/build/dist/Utils/Metrics/MetricResourceAttributeUtil.js +281 -0
- package/build/dist/Utils/Metrics/MetricResourceAttributeUtil.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js +8 -6
- package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js.map +1 -1
- package/build/dist/Utils/StatusPage/GroupHierarchyView.js +560 -0
- package/build/dist/Utils/StatusPage/GroupHierarchyView.js.map +1 -0
- package/build/dist/Utils/StatusPage/ResourceExplorer.js +519 -0
- package/build/dist/Utils/StatusPage/ResourceExplorer.js.map +1 -0
- package/jest.config.json +1 -0
- package/package.json +5 -1
- 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
|
+
});
|