@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,307 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ConnectionOptions,
|
|
3
|
+
createConnection,
|
|
4
|
+
Connection,
|
|
5
|
+
} from "mysql2/promise";
|
|
6
|
+
import AggregatedResult from "../../../../Types/BaseDatabase/AggregatedResult";
|
|
7
|
+
import {
|
|
8
|
+
DATA_SOURCE_CONNECT_TIMEOUT_IN_MS,
|
|
9
|
+
DATA_SOURCE_MAX_TABLE_ROWS,
|
|
10
|
+
DATA_SOURCE_MAX_TIME_SERIES_ROWS,
|
|
11
|
+
DATA_SOURCE_QUERY_TIMEOUT_IN_MS,
|
|
12
|
+
} from "../../../../Types/DataSource/DataSourceLimits";
|
|
13
|
+
import DataSourceTableResult from "../../../../Types/DataSource/DataSourceTableResult";
|
|
14
|
+
import DataSourceType from "../../../../Types/DataSource/DataSourceType";
|
|
15
|
+
import BadDataException from "../../../../Types/Exception/BadDataException";
|
|
16
|
+
import DataSourceEgressGuard from "../EgressGuard";
|
|
17
|
+
import SqlQueryGuard from "../SqlQueryGuard";
|
|
18
|
+
import SqlResultShaper from "../SqlResultShaper";
|
|
19
|
+
import {
|
|
20
|
+
DataSourceConnectionSettings,
|
|
21
|
+
DataSourceConnector,
|
|
22
|
+
DataSourceQueryWindow,
|
|
23
|
+
} from "../Types";
|
|
24
|
+
|
|
25
|
+
/*
|
|
26
|
+
* MySQL / MariaDB connector for external Data Sources.
|
|
27
|
+
*
|
|
28
|
+
* Read-only enforcement is layered:
|
|
29
|
+
* 1. SqlQueryGuard.assertReadOnlyQuery rejects anything that is not a
|
|
30
|
+
* single read-only statement BEFORE a connection is opened;
|
|
31
|
+
* 2. the driver runs with multipleStatements: false so stacked statements
|
|
32
|
+
* can never execute even if the classifier were bypassed;
|
|
33
|
+
* 3. the user's query runs inside START TRANSACTION READ ONLY, so the
|
|
34
|
+
* server itself rejects writes regardless of the query text.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
/*
|
|
38
|
+
* Minimal surface of a mysql2 promise connection the connector uses —
|
|
39
|
+
* doubles as the DI seam so tests can substitute a scripted fake without
|
|
40
|
+
* touching a real server. Result rows are element [0] of the query tuple.
|
|
41
|
+
*/
|
|
42
|
+
export interface MySqlConnectionLike {
|
|
43
|
+
query(sql: string): Promise<[unknown, unknown]>;
|
|
44
|
+
end(): Promise<void>;
|
|
45
|
+
destroy(): void;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export type MySqlConnectionFactory = (
|
|
49
|
+
options: ConnectionOptions,
|
|
50
|
+
) => Promise<MySqlConnectionLike>;
|
|
51
|
+
|
|
52
|
+
const defaultConnectionFactory: MySqlConnectionFactory = async (
|
|
53
|
+
options: ConnectionOptions,
|
|
54
|
+
): Promise<MySqlConnectionLike> => {
|
|
55
|
+
const connection: Connection = await createConnection(options);
|
|
56
|
+
return {
|
|
57
|
+
query: async (sql: string): Promise<[unknown, unknown]> => {
|
|
58
|
+
const result: [unknown, unknown] = (await connection.query(sql)) as [
|
|
59
|
+
unknown,
|
|
60
|
+
unknown,
|
|
61
|
+
];
|
|
62
|
+
return result;
|
|
63
|
+
},
|
|
64
|
+
end: (): Promise<void> => {
|
|
65
|
+
return connection.end();
|
|
66
|
+
},
|
|
67
|
+
destroy: (): void => {
|
|
68
|
+
connection.destroy();
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export default class MySqlConnector implements DataSourceConnector {
|
|
74
|
+
public dataSourceType: DataSourceType = DataSourceType.MySQL;
|
|
75
|
+
|
|
76
|
+
private connectionFactory: MySqlConnectionFactory;
|
|
77
|
+
|
|
78
|
+
public constructor(connectionFactory?: MySqlConnectionFactory) {
|
|
79
|
+
this.connectionFactory = connectionFactory || defaultConnectionFactory;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public async testConnection(
|
|
83
|
+
settings: DataSourceConnectionSettings,
|
|
84
|
+
): Promise<void> {
|
|
85
|
+
const connection: MySqlConnectionLike = await this.connect(settings);
|
|
86
|
+
try {
|
|
87
|
+
await connection.query("SELECT 1");
|
|
88
|
+
} catch (error) {
|
|
89
|
+
throw new BadDataException(
|
|
90
|
+
SqlResultShaper.sanitizeError(error, this.getSecrets(settings)),
|
|
91
|
+
);
|
|
92
|
+
} finally {
|
|
93
|
+
await this.closeConnection(connection);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
public async queryTimeSeries(
|
|
98
|
+
settings: DataSourceConnectionSettings,
|
|
99
|
+
query: string,
|
|
100
|
+
window: DataSourceQueryWindow,
|
|
101
|
+
): Promise<AggregatedResult> {
|
|
102
|
+
const rows: Array<Record<string, unknown>> = await this.runReadOnlyQuery(
|
|
103
|
+
settings,
|
|
104
|
+
query,
|
|
105
|
+
window,
|
|
106
|
+
DATA_SOURCE_MAX_TIME_SERIES_ROWS,
|
|
107
|
+
);
|
|
108
|
+
return SqlResultShaper.rowsToTimeSeries(rows, {
|
|
109
|
+
maxRows: DATA_SOURCE_MAX_TIME_SERIES_ROWS,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
public async queryTable(
|
|
114
|
+
settings: DataSourceConnectionSettings,
|
|
115
|
+
query: string,
|
|
116
|
+
window: DataSourceQueryWindow,
|
|
117
|
+
): Promise<DataSourceTableResult> {
|
|
118
|
+
const rows: Array<Record<string, unknown>> = await this.runReadOnlyQuery(
|
|
119
|
+
settings,
|
|
120
|
+
query,
|
|
121
|
+
window,
|
|
122
|
+
DATA_SOURCE_MAX_TABLE_ROWS,
|
|
123
|
+
);
|
|
124
|
+
return SqlResultShaper.rowsToTable(rows, {
|
|
125
|
+
maxRows: DATA_SOURCE_MAX_TABLE_ROWS,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
private getSecrets(
|
|
130
|
+
settings: DataSourceConnectionSettings,
|
|
131
|
+
): Array<string | undefined> {
|
|
132
|
+
return [
|
|
133
|
+
settings.password,
|
|
134
|
+
settings.apiToken,
|
|
135
|
+
settings.databaseHost,
|
|
136
|
+
settings.username,
|
|
137
|
+
];
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
private buildConnectionOptions(
|
|
141
|
+
settings: DataSourceConnectionSettings,
|
|
142
|
+
): ConnectionOptions {
|
|
143
|
+
const options: ConnectionOptions = {
|
|
144
|
+
host: settings.databaseHost!,
|
|
145
|
+
port: settings.databasePort ?? 3306,
|
|
146
|
+
connectTimeout: DATA_SOURCE_CONNECT_TIMEOUT_IN_MS,
|
|
147
|
+
/*
|
|
148
|
+
* NEVER true: stacked statements ("SELECT 1; DROP TABLE x") must be
|
|
149
|
+
* impossible at the driver level, as defense in depth beneath the
|
|
150
|
+
* SqlQueryGuard classifier and the read-only transaction.
|
|
151
|
+
*/
|
|
152
|
+
multipleStatements: false,
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
if (settings.databaseName !== undefined) {
|
|
156
|
+
options.database = settings.databaseName;
|
|
157
|
+
}
|
|
158
|
+
if (settings.username !== undefined) {
|
|
159
|
+
options.user = settings.username;
|
|
160
|
+
}
|
|
161
|
+
if (settings.password !== undefined) {
|
|
162
|
+
options.password = settings.password;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (settings.additionalOptions?.["sslEnabled"] === true) {
|
|
166
|
+
/*
|
|
167
|
+
* Certificate verification stays ON by default; only an explicit
|
|
168
|
+
* sslRejectUnauthorized === false disables it.
|
|
169
|
+
*/
|
|
170
|
+
options.ssl = {
|
|
171
|
+
rejectUnauthorized:
|
|
172
|
+
settings.additionalOptions?.["sslRejectUnauthorized"] !== false,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return options;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/*
|
|
180
|
+
* Egress-validate the host, then open a driver connection. Called only
|
|
181
|
+
* after the query (when there is one) has already passed the read-only
|
|
182
|
+
* guard, so a rejected query never even dials the server.
|
|
183
|
+
*/
|
|
184
|
+
private async connect(
|
|
185
|
+
settings: DataSourceConnectionSettings,
|
|
186
|
+
): Promise<MySqlConnectionLike> {
|
|
187
|
+
if (!settings.databaseHost) {
|
|
188
|
+
throw new BadDataException(
|
|
189
|
+
"MySQL data source is missing a database host. Set the host in the data source settings.",
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/*
|
|
194
|
+
* SSRF guard — must pass BEFORE any socket is opened towards the
|
|
195
|
+
* configured host.
|
|
196
|
+
*/
|
|
197
|
+
await DataSourceEgressGuard.assertHostnameAllowed(settings.databaseHost);
|
|
198
|
+
|
|
199
|
+
const options: ConnectionOptions = this.buildConnectionOptions(settings);
|
|
200
|
+
|
|
201
|
+
try {
|
|
202
|
+
return await this.connectionFactory(options);
|
|
203
|
+
} catch (error) {
|
|
204
|
+
throw new BadDataException(
|
|
205
|
+
SqlResultShaper.sanitizeError(error, this.getSecrets(settings)),
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/*
|
|
211
|
+
* Teardown: roll the read-only transaction back (harmless when none is
|
|
212
|
+
* open), then close. Every step is guarded — a wedged server must not
|
|
213
|
+
* turn cleanup into an unhandled rejection — with destroy() as the
|
|
214
|
+
* hard fallback when a graceful end() fails.
|
|
215
|
+
*/
|
|
216
|
+
private async closeConnection(
|
|
217
|
+
connection: MySqlConnectionLike,
|
|
218
|
+
): Promise<void> {
|
|
219
|
+
try {
|
|
220
|
+
await connection.query("ROLLBACK");
|
|
221
|
+
} catch {
|
|
222
|
+
/* Best effort — the transaction may already be gone. */
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
try {
|
|
226
|
+
await connection.end();
|
|
227
|
+
} catch {
|
|
228
|
+
try {
|
|
229
|
+
connection.destroy();
|
|
230
|
+
} catch {
|
|
231
|
+
/* Best effort — the socket may already be gone. */
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
private async runReadOnlyQuery(
|
|
237
|
+
settings: DataSourceConnectionSettings,
|
|
238
|
+
query: string,
|
|
239
|
+
window: DataSourceQueryWindow,
|
|
240
|
+
maxRows: number,
|
|
241
|
+
): Promise<Array<Record<string, unknown>>> {
|
|
242
|
+
const withMacros: string = SqlQueryGuard.applyTimeMacros(
|
|
243
|
+
query,
|
|
244
|
+
window.startDate,
|
|
245
|
+
window.endDate,
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
/*
|
|
249
|
+
* The read-only classifier runs on the USER's query only. The session
|
|
250
|
+
* SET statements issued below are our own fixed strings and never pass
|
|
251
|
+
* through this guard — the guard's ban on the SET keyword applies to
|
|
252
|
+
* user queries, not to the connector's session setup.
|
|
253
|
+
*/
|
|
254
|
+
SqlQueryGuard.assertReadOnlyQuery(withMacros);
|
|
255
|
+
|
|
256
|
+
/* Drop a trailing semicolon; the statement runs bare. */
|
|
257
|
+
const finalSql: string = withMacros.replace(/;\s*$/, "");
|
|
258
|
+
|
|
259
|
+
const connection: MySqlConnectionLike = await this.connect(settings);
|
|
260
|
+
|
|
261
|
+
try {
|
|
262
|
+
/*
|
|
263
|
+
* Best-effort server-side statement timeout. MAX_EXECUTION_TIME
|
|
264
|
+
* (milliseconds, SELECT-only) exists on MySQL 5.7.8+; MariaDB uses
|
|
265
|
+
* max_statement_time in seconds instead, so this statement can fail
|
|
266
|
+
* there — swallow the error and rely on the engine defaults rather
|
|
267
|
+
* than failing the query.
|
|
268
|
+
*/
|
|
269
|
+
try {
|
|
270
|
+
await connection.query(
|
|
271
|
+
`SET SESSION MAX_EXECUTION_TIME = ${DATA_SOURCE_QUERY_TIMEOUT_IN_MS}`,
|
|
272
|
+
);
|
|
273
|
+
} catch {
|
|
274
|
+
/* Non-fatal — variable unknown on MariaDB and older MySQL. */
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/*
|
|
278
|
+
* Server-side row bound at cap+1 so the shaper can detect truncation.
|
|
279
|
+
* An explicit LIMIT in the user's query takes precedence over
|
|
280
|
+
* SQL_SELECT_LIMIT; the shaper's maxRows clamp is the authoritative
|
|
281
|
+
* cap either way.
|
|
282
|
+
*/
|
|
283
|
+
await connection.query(`SET SESSION SQL_SELECT_LIMIT = ${maxRows + 1}`);
|
|
284
|
+
|
|
285
|
+
/*
|
|
286
|
+
* Server-enforced read-only guarantee, independent of the query text
|
|
287
|
+
* classifier.
|
|
288
|
+
*/
|
|
289
|
+
await connection.query("START TRANSACTION READ ONLY");
|
|
290
|
+
|
|
291
|
+
const result: [unknown, unknown] = await connection.query(finalSql);
|
|
292
|
+
const rows: unknown = result[0];
|
|
293
|
+
return Array.isArray(rows)
|
|
294
|
+
? (rows as Array<Record<string, unknown>>)
|
|
295
|
+
: [];
|
|
296
|
+
} catch (error) {
|
|
297
|
+
if (error instanceof BadDataException) {
|
|
298
|
+
throw error;
|
|
299
|
+
}
|
|
300
|
+
throw new BadDataException(
|
|
301
|
+
SqlResultShaper.sanitizeError(error, this.getSecrets(settings)),
|
|
302
|
+
);
|
|
303
|
+
} finally {
|
|
304
|
+
await this.closeConnection(connection);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { Client, ClientConfig } from "pg";
|
|
2
|
+
import AggregatedResult from "../../../../Types/BaseDatabase/AggregatedResult";
|
|
3
|
+
import {
|
|
4
|
+
DATA_SOURCE_CONNECT_TIMEOUT_IN_MS,
|
|
5
|
+
DATA_SOURCE_MAX_TABLE_ROWS,
|
|
6
|
+
DATA_SOURCE_MAX_TIME_SERIES_ROWS,
|
|
7
|
+
DATA_SOURCE_QUERY_TIMEOUT_IN_MS,
|
|
8
|
+
} from "../../../../Types/DataSource/DataSourceLimits";
|
|
9
|
+
import DataSourceTableResult from "../../../../Types/DataSource/DataSourceTableResult";
|
|
10
|
+
import DataSourceType from "../../../../Types/DataSource/DataSourceType";
|
|
11
|
+
import BadDataException from "../../../../Types/Exception/BadDataException";
|
|
12
|
+
import DataSourceEgressGuard from "../EgressGuard";
|
|
13
|
+
import SqlQueryGuard from "../SqlQueryGuard";
|
|
14
|
+
import SqlResultShaper from "../SqlResultShaper";
|
|
15
|
+
import {
|
|
16
|
+
DataSourceConnector,
|
|
17
|
+
DataSourceConnectionSettings,
|
|
18
|
+
DataSourceQueryWindow,
|
|
19
|
+
} from "../Types";
|
|
20
|
+
|
|
21
|
+
/*
|
|
22
|
+
* PostgreSQL Data Source connector.
|
|
23
|
+
*
|
|
24
|
+
* Read-only enforcement is layered: the SqlQueryGuard classifier rejects
|
|
25
|
+
* anything that is not a single read-only statement BEFORE a connection is
|
|
26
|
+
* opened, and the query then runs inside a server-enforced READ ONLY
|
|
27
|
+
* transaction (which also blocks writable CTEs the classifier cannot see).
|
|
28
|
+
* Rows are capped server-side with a NO SCROLL cursor + bounded FETCH so an
|
|
29
|
+
* unbounded query never materializes on the OneUptime API server — the same
|
|
30
|
+
* technique the probe's SqlMonitor uses.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/*
|
|
34
|
+
* Structural subset of pg's Client used by this connector. The constructor
|
|
35
|
+
* accepts a factory producing this shape so tests can inject a fake client
|
|
36
|
+
* and record every statement without touching a real database.
|
|
37
|
+
*/
|
|
38
|
+
export interface PgClientLike {
|
|
39
|
+
connect(): Promise<void>;
|
|
40
|
+
query(text: string): Promise<{ rows: Array<Record<string, unknown>> }>;
|
|
41
|
+
end(): Promise<void>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type PgClientFactory = (config: ClientConfig) => PgClientLike;
|
|
45
|
+
|
|
46
|
+
const CURSOR_NAME: string = "oneuptime_data_source_cursor";
|
|
47
|
+
|
|
48
|
+
export default class PostgresConnector implements DataSourceConnector {
|
|
49
|
+
public dataSourceType: DataSourceType = DataSourceType.PostgreSQL;
|
|
50
|
+
|
|
51
|
+
private clientFactory: PgClientFactory;
|
|
52
|
+
|
|
53
|
+
public constructor(clientFactory?: PgClientFactory) {
|
|
54
|
+
this.clientFactory =
|
|
55
|
+
clientFactory ||
|
|
56
|
+
((config: ClientConfig): PgClientLike => {
|
|
57
|
+
/*
|
|
58
|
+
* Wrap the driver client: pg's Client.connect() resolves with the
|
|
59
|
+
* Client instance, but the seam promises void — adapt instead of
|
|
60
|
+
* widening the interface every fake must implement.
|
|
61
|
+
*/
|
|
62
|
+
const client: Client = new Client(config);
|
|
63
|
+
return {
|
|
64
|
+
connect: async (): Promise<void> => {
|
|
65
|
+
await client.connect();
|
|
66
|
+
},
|
|
67
|
+
query: (
|
|
68
|
+
text: string,
|
|
69
|
+
): Promise<{ rows: Array<Record<string, unknown>> }> => {
|
|
70
|
+
return client.query(text);
|
|
71
|
+
},
|
|
72
|
+
end: (): Promise<void> => {
|
|
73
|
+
return client.end();
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public async testConnection(
|
|
80
|
+
settings: DataSourceConnectionSettings,
|
|
81
|
+
): Promise<void> {
|
|
82
|
+
await this.assertEgressAllowed(settings);
|
|
83
|
+
|
|
84
|
+
const client: PgClientLike = this.clientFactory(
|
|
85
|
+
this.buildClientConfig(settings),
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
await client.connect();
|
|
90
|
+
await client.query("SELECT 1");
|
|
91
|
+
} catch (error) {
|
|
92
|
+
throw this.toBadDataException(error, settings);
|
|
93
|
+
} finally {
|
|
94
|
+
try {
|
|
95
|
+
await client.end();
|
|
96
|
+
} catch {
|
|
97
|
+
// Best effort — the socket may never have opened.
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public async queryTimeSeries(
|
|
103
|
+
settings: DataSourceConnectionSettings,
|
|
104
|
+
query: string,
|
|
105
|
+
window: DataSourceQueryWindow,
|
|
106
|
+
): Promise<AggregatedResult> {
|
|
107
|
+
const rows: Array<Record<string, unknown>> = await this.fetchRows(
|
|
108
|
+
settings,
|
|
109
|
+
query,
|
|
110
|
+
window,
|
|
111
|
+
DATA_SOURCE_MAX_TIME_SERIES_ROWS,
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
return SqlResultShaper.rowsToTimeSeries(rows, {
|
|
115
|
+
maxRows: DATA_SOURCE_MAX_TIME_SERIES_ROWS,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
public async queryTable(
|
|
120
|
+
settings: DataSourceConnectionSettings,
|
|
121
|
+
query: string,
|
|
122
|
+
window: DataSourceQueryWindow,
|
|
123
|
+
): Promise<DataSourceTableResult> {
|
|
124
|
+
const rows: Array<Record<string, unknown>> = await this.fetchRows(
|
|
125
|
+
settings,
|
|
126
|
+
query,
|
|
127
|
+
window,
|
|
128
|
+
DATA_SOURCE_MAX_TABLE_ROWS,
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
return SqlResultShaper.rowsToTable(rows, {
|
|
132
|
+
maxRows: DATA_SOURCE_MAX_TABLE_ROWS,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/*
|
|
137
|
+
* Validate the target host through the SSRF egress guard. MUST run before
|
|
138
|
+
* any connection is opened (test and query alike).
|
|
139
|
+
*/
|
|
140
|
+
private async assertEgressAllowed(
|
|
141
|
+
settings: DataSourceConnectionSettings,
|
|
142
|
+
): Promise<void> {
|
|
143
|
+
if (!settings.databaseHost) {
|
|
144
|
+
throw new BadDataException(
|
|
145
|
+
"Database host is required for a PostgreSQL data source.",
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
await DataSourceEgressGuard.assertHostnameAllowed(settings.databaseHost);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
private buildClientConfig(
|
|
153
|
+
settings: DataSourceConnectionSettings,
|
|
154
|
+
): ClientConfig {
|
|
155
|
+
const sslEnabled: boolean =
|
|
156
|
+
settings.additionalOptions?.["sslEnabled"] === true;
|
|
157
|
+
const sslRejectUnauthorized: boolean =
|
|
158
|
+
settings.additionalOptions?.["sslRejectUnauthorized"] !== false;
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
host: settings.databaseHost,
|
|
162
|
+
port: settings.databasePort ?? 5432,
|
|
163
|
+
database: settings.databaseName ?? "postgres",
|
|
164
|
+
user: settings.username,
|
|
165
|
+
password: settings.password,
|
|
166
|
+
connectionTimeoutMillis: DATA_SOURCE_CONNECT_TIMEOUT_IN_MS,
|
|
167
|
+
// Server-side per-statement cap (primary timeout control).
|
|
168
|
+
statement_timeout: DATA_SOURCE_QUERY_TIMEOUT_IN_MS,
|
|
169
|
+
// Client-side backstop in case the server ignores statement_timeout.
|
|
170
|
+
query_timeout: DATA_SOURCE_QUERY_TIMEOUT_IN_MS + 2000,
|
|
171
|
+
application_name: "OneUptime-DataSource",
|
|
172
|
+
ssl: sslEnabled ? { rejectUnauthorized: sslRejectUnauthorized } : false,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private toBadDataException(
|
|
177
|
+
error: unknown,
|
|
178
|
+
settings: DataSourceConnectionSettings,
|
|
179
|
+
): BadDataException {
|
|
180
|
+
if (error instanceof BadDataException) {
|
|
181
|
+
return error;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return new BadDataException(
|
|
185
|
+
SqlResultShaper.sanitizeError(error, [
|
|
186
|
+
settings.password,
|
|
187
|
+
settings.apiToken,
|
|
188
|
+
settings.databaseHost,
|
|
189
|
+
settings.username,
|
|
190
|
+
]),
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/*
|
|
195
|
+
* Open a connection, run the (macro-expanded, read-only-verified) query
|
|
196
|
+
* inside a READ ONLY transaction and read at most maxRows+1 rows through a
|
|
197
|
+
* server-side cursor — the +1 lets the shaper detect truncation. The
|
|
198
|
+
* transaction is always rolled back and the connection always closed.
|
|
199
|
+
*/
|
|
200
|
+
private async fetchRows(
|
|
201
|
+
settings: DataSourceConnectionSettings,
|
|
202
|
+
query: string,
|
|
203
|
+
window: DataSourceQueryWindow,
|
|
204
|
+
maxRows: number,
|
|
205
|
+
): Promise<Array<Record<string, unknown>>> {
|
|
206
|
+
await this.assertEgressAllowed(settings);
|
|
207
|
+
|
|
208
|
+
const finalSql: string = SqlQueryGuard.applyTimeMacros(
|
|
209
|
+
query,
|
|
210
|
+
window.startDate,
|
|
211
|
+
window.endDate,
|
|
212
|
+
);
|
|
213
|
+
SqlQueryGuard.assertReadOnlyQuery(finalSql);
|
|
214
|
+
|
|
215
|
+
// Strip trailing terminators so the SQL embeds in DECLARE ... CURSOR.
|
|
216
|
+
const cursorSql: string = finalSql.replace(/;+\s*$/g, "").trim();
|
|
217
|
+
|
|
218
|
+
const client: PgClientLike = this.clientFactory(
|
|
219
|
+
this.buildClientConfig(settings),
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
try {
|
|
223
|
+
await client.connect();
|
|
224
|
+
|
|
225
|
+
/*
|
|
226
|
+
* Server-enforced read-only guarantee: a READ ONLY transaction blocks
|
|
227
|
+
* all writes — including writable CTEs — regardless of the query text.
|
|
228
|
+
*/
|
|
229
|
+
await client.query("START TRANSACTION READ ONLY");
|
|
230
|
+
await client.query(
|
|
231
|
+
`SET LOCAL statement_timeout = ${Math.floor(
|
|
232
|
+
DATA_SOURCE_QUERY_TIMEOUT_IN_MS,
|
|
233
|
+
)}`,
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
await client.query(
|
|
237
|
+
`DECLARE ${CURSOR_NAME} NO SCROLL CURSOR FOR ${cursorSql}`,
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
const result: { rows: Array<Record<string, unknown>> } =
|
|
241
|
+
await client.query(`FETCH FORWARD ${maxRows + 1} FROM ${CURSOR_NAME}`);
|
|
242
|
+
|
|
243
|
+
return result.rows || [];
|
|
244
|
+
} catch (error) {
|
|
245
|
+
throw this.toBadDataException(error, settings);
|
|
246
|
+
} finally {
|
|
247
|
+
try {
|
|
248
|
+
await client.query("ROLLBACK");
|
|
249
|
+
} catch {
|
|
250
|
+
// Best effort — the transaction may never have started.
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
try {
|
|
254
|
+
await client.end();
|
|
255
|
+
} catch {
|
|
256
|
+
// Best effort — the socket may already be gone.
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|