@libredb/studio 0.9.7 → 0.9.13
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/dist/chunk-34YQUUCM.mjs +319 -0
- package/dist/chunk-34YQUUCM.mjs.map +1 -0
- package/dist/chunk-4LVB3K53.mjs +37 -0
- package/dist/chunk-4LVB3K53.mjs.map +1 -0
- package/dist/chunk-6DRZXXNT.mjs +100 -0
- package/dist/chunk-6DRZXXNT.mjs.map +1 -0
- package/dist/chunk-CPF7XWV5.mjs +1289 -0
- package/dist/chunk-CPF7XWV5.mjs.map +1 -0
- package/dist/chunk-CZVV3JJB.mjs +160 -0
- package/dist/chunk-CZVV3JJB.mjs.map +1 -0
- package/dist/chunk-D4WVWWWF.js +332 -0
- package/dist/chunk-D4WVWWWF.js.map +1 -0
- package/dist/chunk-DY3KXE44.mjs +3 -0
- package/dist/chunk-DY3KXE44.mjs.map +1 -0
- package/dist/chunk-FYSE52VB.js +242 -0
- package/dist/chunk-FYSE52VB.js.map +1 -0
- package/dist/chunk-G3S66G64.mjs +6673 -0
- package/dist/chunk-G3S66G64.mjs.map +1 -0
- package/dist/chunk-G4WYE6TI.js +4 -0
- package/dist/chunk-G4WYE6TI.js.map +1 -0
- package/dist/chunk-HGPD6PWV.js +1310 -0
- package/dist/chunk-HGPD6PWV.js.map +1 -0
- package/dist/chunk-JZO5KRZN.js +165 -0
- package/dist/chunk-JZO5KRZN.js.map +1 -0
- package/dist/chunk-KV356UXJ.js +253 -0
- package/dist/chunk-KV356UXJ.js.map +1 -0
- package/dist/chunk-PPODO6HX.mjs +237 -0
- package/dist/chunk-PPODO6HX.mjs.map +1 -0
- package/dist/chunk-PTIRB2JO.js +258 -0
- package/dist/chunk-PTIRB2JO.js.map +1 -0
- package/dist/chunk-Q6LRDBK7.js +42 -0
- package/dist/chunk-Q6LRDBK7.js.map +1 -0
- package/dist/chunk-QJP5FZRY.mjs +255 -0
- package/dist/chunk-QJP5FZRY.mjs.map +1 -0
- package/dist/chunk-R3POCJK6.mjs +248 -0
- package/dist/chunk-R3POCJK6.mjs.map +1 -0
- package/dist/chunk-RCQB4FCE.js +186 -0
- package/dist/chunk-RCQB4FCE.js.map +1 -0
- package/dist/chunk-SR5DRGBX.mjs +174 -0
- package/dist/chunk-SR5DRGBX.mjs.map +1 -0
- package/dist/chunk-VLCRUZX7.js +102 -0
- package/dist/chunk-VLCRUZX7.js.map +1 -0
- package/dist/chunk-Y52UIFEX.js +6741 -0
- package/dist/chunk-Y52UIFEX.js.map +1 -0
- package/dist/components.d.mts +273 -0
- package/dist/components.d.ts +273 -0
- package/dist/components.js +59 -0
- package/dist/components.js.map +1 -0
- package/dist/components.mjs +6 -0
- package/dist/components.mjs.map +1 -0
- package/dist/custom-BNDOYC5P.js +134 -0
- package/dist/custom-BNDOYC5P.js.map +1 -0
- package/dist/custom-S2EKFMP3.mjs +132 -0
- package/dist/custom-S2EKFMP3.mjs.map +1 -0
- package/dist/gemini-4ASHNK4H.js +81 -0
- package/dist/gemini-4ASHNK4H.js.map +1 -0
- package/dist/gemini-C5RBLQEJ.mjs +79 -0
- package/dist/gemini-C5RBLQEJ.mjs.map +1 -0
- package/dist/index.d.mts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +95 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +10 -0
- package/dist/index.mjs.map +1 -0
- package/dist/mongodb-XMZEZA4A.mjs +748 -0
- package/dist/mongodb-XMZEZA4A.mjs.map +1 -0
- package/dist/mongodb-YQJJTLX3.js +750 -0
- package/dist/mongodb-YQJJTLX3.js.map +1 -0
- package/dist/mssql-PMOU4D36.js +916 -0
- package/dist/mssql-PMOU4D36.js.map +1 -0
- package/{src/lib/db/providers/sql/mssql.ts → dist/mssql-ZH5VP2C5.mjs} +268 -423
- package/dist/mssql-ZH5VP2C5.mjs.map +1 -0
- package/{src/lib/db/providers/sql/mysql.ts → dist/mysql-I3WJQXN2.mjs} +277 -428
- package/dist/mysql-I3WJQXN2.mjs.map +1 -0
- package/dist/mysql-Y3MSA5QY.js +833 -0
- package/dist/mysql-Y3MSA5QY.js.map +1 -0
- package/dist/ollama-26BYLVEV.mjs +115 -0
- package/dist/ollama-26BYLVEV.mjs.map +1 -0
- package/dist/ollama-HVWAGKQC.js +117 -0
- package/dist/ollama-HVWAGKQC.js.map +1 -0
- package/dist/openai-4U56KPG7.mjs +111 -0
- package/dist/openai-4U56KPG7.mjs.map +1 -0
- package/dist/openai-AK3R37BS.js +113 -0
- package/dist/openai-AK3R37BS.js.map +1 -0
- package/dist/oracle-L6VEAVXO.js +917 -0
- package/dist/oracle-L6VEAVXO.js.map +1 -0
- package/{src/lib/db/providers/sql/oracle.ts → dist/oracle-P2G7T4P4.mjs} +321 -454
- package/dist/oracle-P2G7T4P4.mjs.map +1 -0
- package/{src/lib/db/providers/sql/postgres.ts → dist/postgres-O5KOQUVP.mjs} +261 -471
- package/dist/postgres-O5KOQUVP.mjs.map +1 -0
- package/dist/postgres-RLCWNFFX.js +971 -0
- package/dist/postgres-RLCWNFFX.js.map +1 -0
- package/dist/providers.d.mts +149 -0
- package/dist/providers.d.ts +149 -0
- package/dist/providers.js +44 -0
- package/dist/providers.js.map +1 -0
- package/dist/providers.mjs +7 -0
- package/dist/providers.mjs.map +1 -0
- package/dist/redis-4WMQOVLX.mjs +435 -0
- package/dist/redis-4WMQOVLX.mjs.map +1 -0
- package/dist/redis-QVQ6YU62.js +441 -0
- package/dist/redis-QVQ6YU62.js.map +1 -0
- package/dist/sqlite-4I2P2OGQ.js +554 -0
- package/dist/sqlite-4I2P2OGQ.js.map +1 -0
- package/dist/sqlite-OA4YJX5S.mjs +531 -0
- package/dist/sqlite-OA4YJX5S.mjs.map +1 -0
- package/dist/types-BJvJfxSY.d.mts +141 -0
- package/dist/types-BJvJfxSY.d.ts +141 -0
- package/dist/types-ClAg_v5k.d.mts +343 -0
- package/dist/types-Der_X8E8.d.ts +343 -0
- package/dist/types.d.mts +2 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/types.mjs +3 -0
- package/dist/types.mjs.map +1 -0
- package/dist/workspace.d.mts +80 -0
- package/dist/workspace.d.ts +80 -0
- package/dist/workspace.js +4174 -0
- package/dist/workspace.js.map +1 -0
- package/dist/workspace.mjs +4147 -0
- package/dist/workspace.mjs.map +1 -0
- package/package.json +60 -5
- package/.claude/settings.local.json +0 -127
- package/.cursorrules +0 -426
- package/.devin/wiki.json +0 -143
- package/.dockerignore +0 -80
- package/.env.example +0 -159
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -49
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -29
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -57
- package/.github/workflows/ci.yml +0 -185
- package/.github/workflows/codeql.yml +0 -57
- package/.github/workflows/docker-build-push.yml +0 -118
- package/.github/workflows/helm-release.yml +0 -113
- package/CLAUDE.md +0 -265
- package/CODE_OF_CONDUCT.md +0 -124
- package/CONTRIBUTING.md +0 -154
- package/Dockerfile +0 -73
- package/SECURITY.md +0 -107
- package/artifacthub-repo.yml +0 -4
- package/bun.lock +0 -1714
- package/bunfig.toml +0 -3
- package/charts/libredb-studio/.helmignore +0 -11
- package/charts/libredb-studio/Chart.lock +0 -6
- package/charts/libredb-studio/Chart.yaml +0 -50
- package/charts/libredb-studio/README.md +0 -206
- package/charts/libredb-studio/templates/NOTES.txt +0 -59
- package/charts/libredb-studio/templates/_helpers.tpl +0 -135
- package/charts/libredb-studio/templates/configmap.yaml +0 -37
- package/charts/libredb-studio/templates/deployment.yaml +0 -184
- package/charts/libredb-studio/templates/hpa.yaml +0 -32
- package/charts/libredb-studio/templates/ingress.yaml +0 -41
- package/charts/libredb-studio/templates/networkpolicy.yaml +0 -50
- package/charts/libredb-studio/templates/pdb.yaml +0 -18
- package/charts/libredb-studio/templates/pvc.yaml +0 -23
- package/charts/libredb-studio/templates/secret.yaml +0 -30
- package/charts/libredb-studio/templates/seed-configmap.yaml +0 -11
- package/charts/libredb-studio/templates/service.yaml +0 -22
- package/charts/libredb-studio/templates/serviceaccount.yaml +0 -13
- package/charts/libredb-studio/values.schema.json +0 -246
- package/charts/libredb-studio/values.yaml +0 -286
- package/components.json +0 -22
- package/conductor/code_styleguides/typescript.md +0 -43
- package/conductor/product-guidelines.md +0 -43
- package/conductor/product.md +0 -3
- package/conductor/setup_state.json +0 -1
- package/conductor/tech-stack.md +0 -39
- package/conductor/tracks/enhance_postgres_monitoring_20251227/metadata.json +0 -8
- package/conductor/tracks/enhance_postgres_monitoring_20251227/plan.md +0 -44
- package/conductor/tracks/enhance_postgres_monitoring_20251227/spec.md +0 -31
- package/conductor/tracks.md +0 -8
- package/conductor/workflow.md +0 -333
- package/database-compose.yml +0 -55
- package/docker/postgres-init/01-extensions.sql +0 -10
- package/docker/postgres-init/02-sample-data.sql +0 -585
- package/docker/postgres.yml +0 -68
- package/docker-compose.yml +0 -38
- package/docs/AI_PLAN.md +0 -74
- package/docs/API_DOCS.md +0 -875
- package/docs/ARCHITECTURE.md +0 -218
- package/docs/DATABASE_PROVIDERS.md +0 -358
- package/docs/FEATURES.md +0 -116
- package/docs/HELM_CHART.md +0 -252
- package/docs/LOGIN_PAGE.md +0 -178
- package/docs/MONACO_EDITOR_PERFORMANCE.md +0 -315
- package/docs/OIDC_ARCH.md +0 -681
- package/docs/OIDC_SETUP.md +0 -322
- package/docs/POSTGRES_METRICS.md +0 -516
- package/docs/QUERY_OPTIMIZATION.md +0 -370
- package/docs/SEED_CONNECTIONS.md +0 -468
- package/docs/SQL_ALIAS_COMPLETION.md +0 -190
- package/docs/STORAGE_ARCHITECTURE.md +0 -565
- package/docs/STORAGE_QUICK_SETUP.md +0 -419
- package/docs/TECHNICAL_PLAN.md +0 -36
- package/docs/THEMING.md +0 -345
- package/docs/adding-a-new-database-provider.md +0 -642
- package/docs/backlogs/000-PLATFORM_DATA_SYNC_DATABASE.md +0 -360
- package/docs/backlogs/001-INLINE_DATA_EDITING.md +0 -118
- package/docs/backlogs/002-DATA_IMPORT.md +0 -215
- package/docs/backlogs/003-QUERY_TIME_MACHINE.md +0 -183
- package/docs/backlogs/004-AI_DATA_STORYTELLER.md +0 -292
- package/docs/backlogs/005-QUERY_PLAYGROUND.md +0 -352
- package/docs/backlogs/006-DATA_MASKING.md +0 -418
- package/docs/enterprise-features.md +0 -718
- package/docs/kubernetes-helm-chart-artifacthub-plan.md +0 -803
- package/docs/medium-koyeb-article-en.md +0 -215
- package/docs/plans/test-plans.md +0 -445
- package/docs/releases/RELEASE.V0.3.0.md +0 -22
- package/docs/releases/RELEASE.V0.4.0.md +0 -154
- package/docs/releases/RELEASE.V0.5.0.md +0 -252
- package/docs/releases/RELEASE_v0.5.6.md +0 -145
- package/docs/releases/RELEASE_v0.6.1.md +0 -303
- package/docs/releases/RELEASE_v0.6.7.md +0 -292
- package/docs/releases/RELEASE_v0.7.0.md +0 -332
- package/docs/releases/RELEASE_v0.8.0.md +0 -521
- package/docs/sampledb/titanic.sql +0 -1379
- package/docs/superpowers/plans/2026-03-25-seed-connections.md +0 -1362
- package/docs/superpowers/specs/2026-03-25-seed-connections-design.md +0 -590
- package/e2e/admin-dashboard.spec.ts +0 -64
- package/e2e/connection-management.spec.ts +0 -58
- package/e2e/export.spec.ts +0 -34
- package/e2e/login.spec.ts +0 -85
- package/e2e/query-execution.spec.ts +0 -35
- package/e2e/tab-management.spec.ts +0 -64
- package/eslint.config.mjs +0 -28
- package/fly.toml +0 -43
- package/next.config.ts +0 -32
- package/playwright.config.ts +0 -34
- package/postcss.config.mjs +0 -7
- package/public/favicon-32x32.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/file.svg +0 -1
- package/public/globe.svg +0 -1
- package/public/logo.svg +0 -32
- package/public/next.svg +0 -1
- package/public/screenshots/code-generator.png +0 -0
- package/public/screenshots/connection-modal.png +0 -0
- package/public/screenshots/data-profiler.png +0 -0
- package/public/screenshots/erd-diagram.png +0 -0
- package/public/screenshots/hero-editor.png +0 -0
- package/public/screenshots/nl2sql.png +0 -0
- package/public/vercel.svg +0 -1
- package/public/window.svg +0 -1
- package/render.yaml +0 -58
- package/scripts/merge-lcov.mjs +0 -239
- package/sonar-project.properties +0 -16
- package/src/app/admin/error.tsx +0 -46
- package/src/app/admin/page.tsx +0 -10
- package/src/app/api/admin/audit/route.ts +0 -52
- package/src/app/api/admin/fleet-health/route.ts +0 -81
- package/src/app/api/ai/autopilot/route.ts +0 -105
- package/src/app/api/ai/chat/route.ts +0 -132
- package/src/app/api/ai/describe-schema/route.ts +0 -52
- package/src/app/api/ai/explain/route.ts +0 -86
- package/src/app/api/ai/impact/route.ts +0 -97
- package/src/app/api/ai/index-advisor/route.ts +0 -98
- package/src/app/api/ai/nl2sql/route.ts +0 -87
- package/src/app/api/ai/query-safety/route.ts +0 -87
- package/src/app/api/auth/login/route.ts +0 -62
- package/src/app/api/auth/logout/route.ts +0 -25
- package/src/app/api/auth/me/route.ts +0 -10
- package/src/app/api/auth/oidc/callback/route.ts +0 -82
- package/src/app/api/auth/oidc/login/route.ts +0 -43
- package/src/app/api/connections/managed/route.ts +0 -35
- package/src/app/api/db/cancel/route.ts +0 -42
- package/src/app/api/db/disconnect/route.ts +0 -28
- package/src/app/api/db/health/route.ts +0 -49
- package/src/app/api/db/maintenance/route.ts +0 -72
- package/src/app/api/db/monitoring/route.ts +0 -62
- package/src/app/api/db/multi-query/route.ts +0 -116
- package/src/app/api/db/pool-stats/route.ts +0 -37
- package/src/app/api/db/profile/route.ts +0 -144
- package/src/app/api/db/provider-meta/route.ts +0 -49
- package/src/app/api/db/query/route.ts +0 -50
- package/src/app/api/db/schema/route.ts +0 -47
- package/src/app/api/db/schema-snapshot/route.ts +0 -42
- package/src/app/api/db/test-connection/route.ts +0 -55
- package/src/app/api/db/transaction/route.ts +0 -111
- package/src/app/api/storage/[collection]/route.ts +0 -67
- package/src/app/api/storage/config/route.ts +0 -17
- package/src/app/api/storage/migrate/route.ts +0 -45
- package/src/app/api/storage/route.ts +0 -32
- package/src/app/error.tsx +0 -49
- package/src/app/global-error.tsx +0 -55
- package/src/app/globals.css +0 -146
- package/src/app/icon.svg +0 -42
- package/src/app/layout.tsx +0 -34
- package/src/app/login/login-form.tsx +0 -301
- package/src/app/login/page.tsx +0 -11
- package/src/app/monitoring/page.tsx +0 -8
- package/src/app/not-found.tsx +0 -29
- package/src/app/page.tsx +0 -5
- package/src/components/AIAutopilotPanel.tsx +0 -238
- package/src/components/CodeGenerator.tsx +0 -271
- package/src/components/CommandPalette.tsx +0 -227
- package/src/components/ConnectionModal.tsx +0 -759
- package/src/components/CreateTableModal.tsx +0 -281
- package/src/components/DataCharts.tsx +0 -962
- package/src/components/DataImportModal.tsx +0 -582
- package/src/components/DataProfiler.tsx +0 -335
- package/src/components/DatabaseDocs.tsx +0 -251
- package/src/components/MaskingSettings.tsx +0 -414
- package/src/components/MobileNav.tsx +0 -50
- package/src/components/NL2SQLPanel.tsx +0 -281
- package/src/components/PivotTable.tsx +0 -257
- package/src/components/QueryEditor.tsx +0 -760
- package/src/components/QueryHistory.tsx +0 -344
- package/src/components/QuerySafetyDialog.tsx +0 -290
- package/src/components/ResultsGrid.tsx +0 -644
- package/src/components/SaveQueryModal.tsx +0 -104
- package/src/components/SavedQueries.tsx +0 -128
- package/src/components/SchemaDiagram.tsx +0 -473
- package/src/components/SchemaDiff.tsx +0 -473
- package/src/components/SnapshotTimeline.tsx +0 -116
- package/src/components/Studio.tsx +0 -639
- package/src/components/TestDataGenerator.tsx +0 -261
- package/src/components/VisualExplain.tsx +0 -820
- package/src/components/admin/AdminDashboard.tsx +0 -163
- package/src/components/admin/tabs/AuditTab.tsx +0 -531
- package/src/components/admin/tabs/MonitoringEmbed.tsx +0 -11
- package/src/components/admin/tabs/OperationsTab.tsx +0 -646
- package/src/components/admin/tabs/OverviewTab.tsx +0 -1328
- package/src/components/admin/tabs/SecurityTab.tsx +0 -284
- package/src/components/community-section.tsx +0 -92
- package/src/components/icons/db-icons.tsx +0 -84
- package/src/components/libredb-logo.tsx +0 -61
- package/src/components/monitoring/MonitoringDashboard.tsx +0 -345
- package/src/components/monitoring/tabs/MetricChart.tsx +0 -82
- package/src/components/monitoring/tabs/OverviewTab.tsx +0 -263
- package/src/components/monitoring/tabs/PerformanceTab.tsx +0 -254
- package/src/components/monitoring/tabs/PoolTab.tsx +0 -174
- package/src/components/monitoring/tabs/QueriesTab.tsx +0 -287
- package/src/components/monitoring/tabs/SessionsTab.tsx +0 -316
- package/src/components/monitoring/tabs/StorageTab.tsx +0 -335
- package/src/components/monitoring/tabs/TablesTab.tsx +0 -300
- package/src/components/results-grid/ResultCard.tsx +0 -111
- package/src/components/results-grid/RowDetailSheet.tsx +0 -178
- package/src/components/results-grid/StatsBar.tsx +0 -201
- package/src/components/results-grid/index.ts +0 -1
- package/src/components/results-grid/utils.ts +0 -23
- package/src/components/schema-explorer/ColumnList.tsx +0 -53
- package/src/components/schema-explorer/SchemaExplorer.tsx +0 -182
- package/src/components/schema-explorer/TableItem.tsx +0 -210
- package/src/components/schema-explorer/index.ts +0 -1
- package/src/components/sidebar/ConnectionItem.tsx +0 -105
- package/src/components/sidebar/ConnectionsList.tsx +0 -62
- package/src/components/sidebar/Sidebar.tsx +0 -130
- package/src/components/sidebar/index.ts +0 -2
- package/src/components/studio/BottomPanel.tsx +0 -286
- package/src/components/studio/QueryToolbar.tsx +0 -180
- package/src/components/studio/StudioDesktopHeader.tsx +0 -114
- package/src/components/studio/StudioMobileHeader.tsx +0 -340
- package/src/components/studio/StudioTabBar.tsx +0 -82
- package/src/components/studio/index.ts +0 -5
- package/src/components/ui/accordion.tsx +0 -66
- package/src/components/ui/alert-dialog.tsx +0 -157
- package/src/components/ui/alert.tsx +0 -66
- package/src/components/ui/aspect-ratio.tsx +0 -11
- package/src/components/ui/avatar.tsx +0 -53
- package/src/components/ui/badge.tsx +0 -46
- package/src/components/ui/breadcrumb.tsx +0 -109
- package/src/components/ui/button-group.tsx +0 -83
- package/src/components/ui/button.tsx +0 -60
- package/src/components/ui/calendar.tsx +0 -216
- package/src/components/ui/card.tsx +0 -92
- package/src/components/ui/carousel.tsx +0 -241
- package/src/components/ui/chart.tsx +0 -357
- package/src/components/ui/checkbox.tsx +0 -32
- package/src/components/ui/collapsible.tsx +0 -33
- package/src/components/ui/command.tsx +0 -184
- package/src/components/ui/context-menu.tsx +0 -252
- package/src/components/ui/dialog.tsx +0 -143
- package/src/components/ui/drawer.tsx +0 -135
- package/src/components/ui/dropdown-menu.tsx +0 -257
- package/src/components/ui/empty.tsx +0 -104
- package/src/components/ui/field.tsx +0 -248
- package/src/components/ui/form.tsx +0 -167
- package/src/components/ui/hover-card.tsx +0 -44
- package/src/components/ui/input-group.tsx +0 -170
- package/src/components/ui/input-otp.tsx +0 -77
- package/src/components/ui/input.tsx +0 -21
- package/src/components/ui/item.tsx +0 -193
- package/src/components/ui/kbd.tsx +0 -28
- package/src/components/ui/label.tsx +0 -24
- package/src/components/ui/menubar.tsx +0 -276
- package/src/components/ui/navigation-menu.tsx +0 -168
- package/src/components/ui/pagination.tsx +0 -127
- package/src/components/ui/popover.tsx +0 -48
- package/src/components/ui/progress.tsx +0 -31
- package/src/components/ui/radio-group.tsx +0 -45
- package/src/components/ui/resizable.tsx +0 -56
- package/src/components/ui/scroll-area.tsx +0 -58
- package/src/components/ui/select.tsx +0 -187
- package/src/components/ui/separator.tsx +0 -28
- package/src/components/ui/sheet.tsx +0 -139
- package/src/components/ui/sidebar.tsx +0 -726
- package/src/components/ui/skeleton.tsx +0 -13
- package/src/components/ui/slider.tsx +0 -63
- package/src/components/ui/sonner.tsx +0 -40
- package/src/components/ui/spinner.tsx +0 -16
- package/src/components/ui/switch.tsx +0 -31
- package/src/components/ui/table.tsx +0 -116
- package/src/components/ui/tabs.tsx +0 -66
- package/src/components/ui/textarea.tsx +0 -18
- package/src/components/ui/toggle-group.tsx +0 -83
- package/src/components/ui/toggle.tsx +0 -47
- package/src/components/ui/tooltip.tsx +0 -61
- package/src/exports/components.ts +0 -15
- package/src/exports/index.ts +0 -4
- package/src/exports/providers.ts +0 -4
- package/src/exports/types.ts +0 -26
- package/src/hooks/use-ai-chat.ts +0 -182
- package/src/hooks/use-all-connections.ts +0 -66
- package/src/hooks/use-api-call.ts +0 -71
- package/src/hooks/use-auth.ts +0 -51
- package/src/hooks/use-connection-form.ts +0 -349
- package/src/hooks/use-connection-manager.ts +0 -169
- package/src/hooks/use-connection-payload.ts +0 -15
- package/src/hooks/use-inline-editing.ts +0 -109
- package/src/hooks/use-mobile.ts +0 -20
- package/src/hooks/use-monitoring-data.ts +0 -270
- package/src/hooks/use-provider-metadata.ts +0 -62
- package/src/hooks/use-query-execution.ts +0 -478
- package/src/hooks/use-storage-sync.ts +0 -259
- package/src/hooks/use-tab-manager.ts +0 -231
- package/src/hooks/use-toast.ts +0 -20
- package/src/hooks/use-transaction-control.ts +0 -64
- package/src/lib/api/error-codes.ts +0 -30
- package/src/lib/api/errors.ts +0 -236
- package/src/lib/api/with-error-handler.ts +0 -41
- package/src/lib/audit.ts +0 -105
- package/src/lib/auth.ts +0 -87
- package/src/lib/connection-string-parser.ts +0 -172
- package/src/lib/data-masking.ts +0 -385
- package/src/lib/db/base-provider.ts +0 -325
- package/src/lib/db/errors.ts +0 -317
- package/src/lib/db/factory.ts +0 -324
- package/src/lib/db/index.ts +0 -123
- package/src/lib/db/providers/document/index.ts +0 -6
- package/src/lib/db/providers/document/mongodb.ts +0 -992
- package/src/lib/db/providers/keyvalue/redis.ts +0 -554
- package/src/lib/db/providers/sql/index.ts +0 -11
- package/src/lib/db/providers/sql/sql-base.ts +0 -174
- package/src/lib/db/providers/sql/sqlite.ts +0 -721
- package/src/lib/db/types.ts +0 -437
- package/src/lib/db/utils/pool-manager.ts +0 -287
- package/src/lib/db/utils/query-limiter.ts +0 -239
- package/src/lib/db-ui-config.ts +0 -86
- package/src/lib/editor/mongodb-completions.ts +0 -172
- package/src/lib/editor/sql-completions.ts +0 -280
- package/src/lib/llm/base-provider.ts +0 -117
- package/src/lib/llm/factory.ts +0 -102
- package/src/lib/llm/index.ts +0 -90
- package/src/lib/llm/providers/custom.ts +0 -181
- package/src/lib/llm/providers/gemini.ts +0 -126
- package/src/lib/llm/providers/ollama.ts +0 -154
- package/src/lib/llm/providers/openai.ts +0 -146
- package/src/lib/llm/types.ts +0 -173
- package/src/lib/llm/utils/config.ts +0 -187
- package/src/lib/llm/utils/retry.ts +0 -119
- package/src/lib/llm/utils/streaming.ts +0 -202
- package/src/lib/logger.ts +0 -127
- package/src/lib/monitoring-thresholds.ts +0 -44
- package/src/lib/oidc.ts +0 -262
- package/src/lib/query-generators.ts +0 -61
- package/src/lib/schema-diff/diff-engine.ts +0 -273
- package/src/lib/schema-diff/migration-generator.ts +0 -208
- package/src/lib/schema-diff/types.ts +0 -55
- package/src/lib/seed/config-loader.ts +0 -79
- package/src/lib/seed/connection-filter.ts +0 -49
- package/src/lib/seed/credential-resolver.ts +0 -62
- package/src/lib/seed/index.ts +0 -40
- package/src/lib/seed/resolve-connection.ts +0 -57
- package/src/lib/seed/types.ts +0 -69
- package/src/lib/sql/alias-extractor.ts +0 -267
- package/src/lib/sql/index.ts +0 -8
- package/src/lib/sql/statement-splitter.ts +0 -167
- package/src/lib/sql/types.ts +0 -40
- package/src/lib/ssh/tunnel.ts +0 -142
- package/src/lib/storage/factory.ts +0 -84
- package/src/lib/storage/index.ts +0 -14
- package/src/lib/storage/local-storage.ts +0 -99
- package/src/lib/storage/providers/postgres.ts +0 -225
- package/src/lib/storage/providers/sqlite.ts +0 -153
- package/src/lib/storage/storage-facade.ts +0 -272
- package/src/lib/storage/types.ts +0 -75
- package/src/lib/time-series-buffer.ts +0 -58
- package/src/lib/types.ts +0 -173
- package/src/lib/utils.ts +0 -6
- package/src/proxy.ts +0 -104
- package/src/types/db-drivers.d.ts +0 -23
- package/src/types/html2canvas.d.ts +0 -9
- package/tests/api/admin/audit.test.ts +0 -178
- package/tests/api/admin/fleet-health.test.ts +0 -183
- package/tests/api/ai/autopilot.test.ts +0 -174
- package/tests/api/ai/chat.test.ts +0 -250
- package/tests/api/ai/describe-schema.test.ts +0 -266
- package/tests/api/ai/explain.test.ts +0 -199
- package/tests/api/ai/impact.test.ts +0 -168
- package/tests/api/ai/index-advisor.test.ts +0 -171
- package/tests/api/ai/nl2sql.test.ts +0 -202
- package/tests/api/ai/query-safety.test.ts +0 -196
- package/tests/api/auth/login.test.ts +0 -170
- package/tests/api/auth/logout.test.ts +0 -140
- package/tests/api/auth/me.test.ts +0 -73
- package/tests/api/auth/oidc-callback.test.ts +0 -215
- package/tests/api/auth/oidc-login.test.ts +0 -127
- package/tests/api/db/cancel.test.ts +0 -198
- package/tests/api/db/disconnect.test.ts +0 -124
- package/tests/api/db/health.test.ts +0 -222
- package/tests/api/db/maintenance.test.ts +0 -263
- package/tests/api/db/monitoring.test.ts +0 -221
- package/tests/api/db/multi-query.test.ts +0 -316
- package/tests/api/db/pool-stats.test.ts +0 -135
- package/tests/api/db/profile.test.ts +0 -330
- package/tests/api/db/provider-meta.test.ts +0 -193
- package/tests/api/db/query.test.ts +0 -314
- package/tests/api/db/schema-snapshot.test.ts +0 -170
- package/tests/api/db/schema.test.ts +0 -191
- package/tests/api/db/test-connection.test.ts +0 -185
- package/tests/api/db/transaction.test.ts +0 -314
- package/tests/api/proxy.test.ts +0 -191
- package/tests/api/seed/managed-route.test.ts +0 -113
- package/tests/api/storage/config.test.ts +0 -42
- package/tests/api/storage/storage-routes.test.ts +0 -309
- package/tests/components/AIAutopilotPanel.test.tsx +0 -756
- package/tests/components/AdminPage.test.tsx +0 -33
- package/tests/components/CodeGenerator.test.tsx +0 -182
- package/tests/components/CommandPalette.test.tsx +0 -428
- package/tests/components/CommunitySection.test.tsx +0 -91
- package/tests/components/ConnectionModal.mobile.test.tsx +0 -284
- package/tests/components/ConnectionModal.test.tsx +0 -570
- package/tests/components/CreateTableModal.test.tsx +0 -383
- package/tests/components/DataCharts.test.tsx +0 -739
- package/tests/components/DataImportModal.test.tsx +0 -751
- package/tests/components/DataProfiler.test.tsx +0 -589
- package/tests/components/DatabaseDocs.test.tsx +0 -353
- package/tests/components/LoginPage.test.tsx +0 -163
- package/tests/components/LoginPageOIDC.test.tsx +0 -92
- package/tests/components/MaskingSettings.test.tsx +0 -498
- package/tests/components/MobileNav.test.tsx +0 -30
- package/tests/components/MonitoringPage.test.tsx +0 -32
- package/tests/components/NL2SQLPanel.test.tsx +0 -621
- package/tests/components/Page.test.tsx +0 -33
- package/tests/components/PivotTable.test.tsx +0 -350
- package/tests/components/QueryEditor.test.tsx +0 -1730
- package/tests/components/QueryHistory.test.tsx +0 -572
- package/tests/components/QuerySafetyDialog.test.tsx +0 -586
- package/tests/components/ResultsGrid.test.tsx +0 -804
- package/tests/components/RootLayout.test.tsx +0 -83
- package/tests/components/SaveQueryModal.test.tsx +0 -25
- package/tests/components/SavedQueries.test.tsx +0 -43
- package/tests/components/SchemaDiagram.test.tsx +0 -1034
- package/tests/components/SchemaDiff.test.tsx +0 -906
- package/tests/components/SnapshotTimeline.test.tsx +0 -174
- package/tests/components/Studio.test.tsx +0 -1030
- package/tests/components/TestDataGenerator.test.tsx +0 -291
- package/tests/components/VisualExplain.test.tsx +0 -704
- package/tests/components/admin/AdminDashboard.test.tsx +0 -205
- package/tests/components/admin/AuditTab.test.tsx +0 -220
- package/tests/components/admin/MonitoringEmbed.test.tsx +0 -58
- package/tests/components/admin/OperationsTab.test.tsx +0 -975
- package/tests/components/admin/OverviewTab.test.tsx +0 -254
- package/tests/components/admin/SecurityTab.test.tsx +0 -467
- package/tests/components/monitoring/MetricChart.test.tsx +0 -111
- package/tests/components/monitoring/MonitoringDashboard.test.tsx +0 -259
- package/tests/components/monitoring/OverviewTab.test.tsx +0 -78
- package/tests/components/monitoring/PerformanceTab.test.tsx +0 -87
- package/tests/components/monitoring/PoolTab.test.tsx +0 -42
- package/tests/components/monitoring/QueriesTab.test.tsx +0 -80
- package/tests/components/monitoring/SessionsTab.test.tsx +0 -154
- package/tests/components/monitoring/StorageTab.test.tsx +0 -127
- package/tests/components/monitoring/TablesTab.test.tsx +0 -153
- package/tests/components/results-grid/ResultCard.test.tsx +0 -105
- package/tests/components/results-grid/RowDetailSheet.test.tsx +0 -308
- package/tests/components/results-grid/StatsBar.test.tsx +0 -162
- package/tests/components/schema-explorer/ColumnList.test.tsx +0 -151
- package/tests/components/schema-explorer/SchemaExplorer.test.tsx +0 -461
- package/tests/components/schema-explorer/TableItem.test.tsx +0 -415
- package/tests/components/sidebar/ConnectionItem.test.tsx +0 -201
- package/tests/components/sidebar/ConnectionsList.test.tsx +0 -176
- package/tests/components/sidebar/Sidebar.test.tsx +0 -187
- package/tests/components/studio/BottomPanel.test.tsx +0 -383
- package/tests/components/studio/QueryToolbar.test.tsx +0 -321
- package/tests/components/studio/StudioDesktopHeader.test.tsx +0 -377
- package/tests/components/studio/StudioMobileHeader.test.tsx +0 -198
- package/tests/components/studio/StudioTabBar.test.tsx +0 -331
- package/tests/fixtures/connections.ts +0 -96
- package/tests/fixtures/masking-configs.ts +0 -86
- package/tests/fixtures/query-results.ts +0 -71
- package/tests/fixtures/schemas.ts +0 -64
- package/tests/fixtures/seed-connections/invalid-config.yaml +0 -7
- package/tests/fixtures/seed-connections/minimal-config.yaml +0 -8
- package/tests/fixtures/seed-connections/mixed-credentials.yaml +0 -23
- package/tests/fixtures/seed-connections/multi-role-config.yaml +0 -30
- package/tests/fixtures/seed-connections/valid-config.json +0 -15
- package/tests/fixtures/seed-connections/valid-config.yaml +0 -51
- package/tests/helpers/mock-fetch.ts +0 -59
- package/tests/helpers/mock-monaco.ts +0 -112
- package/tests/helpers/mock-navigation.ts +0 -28
- package/tests/helpers/mock-next.ts +0 -80
- package/tests/helpers/mock-provider.ts +0 -133
- package/tests/helpers/mock-sonner.ts +0 -29
- package/tests/helpers/render-with-providers.tsx +0 -19
- package/tests/hooks/use-ai-chat.test.ts +0 -600
- package/tests/hooks/use-auth.test.ts +0 -371
- package/tests/hooks/use-connection-form.test.ts +0 -743
- package/tests/hooks/use-connection-manager.test.ts +0 -466
- package/tests/hooks/use-inline-editing.test.ts +0 -321
- package/tests/hooks/use-mobile.test.ts +0 -177
- package/tests/hooks/use-monitoring-data.test.ts +0 -819
- package/tests/hooks/use-provider-metadata.test.ts +0 -228
- package/tests/hooks/use-query-execution.test.ts +0 -1212
- package/tests/hooks/use-tab-manager.test.ts +0 -756
- package/tests/hooks/use-toast.test.ts +0 -74
- package/tests/hooks/use-transaction-control.test.ts +0 -211
- package/tests/integration/db/mongodb-provider.test.ts +0 -698
- package/tests/integration/db/mssql-provider.test.ts +0 -840
- package/tests/integration/db/mysql-provider.test.ts +0 -872
- package/tests/integration/db/oracle-provider.test.ts +0 -843
- package/tests/integration/db/postgres-provider.test.ts +0 -1382
- package/tests/integration/db/redis-provider.test.ts +0 -526
- package/tests/integration/db/sqlite-provider.test.ts +0 -480
- package/tests/integration/seed/seed-pipeline.test.ts +0 -102
- package/tests/isolated/factory-singleton.test.ts +0 -150
- package/tests/isolated/use-storage-sync.test.ts +0 -389
- package/tests/run-components.sh +0 -196
- package/tests/setup-dom.ts +0 -58
- package/tests/setup.ts +0 -40
- package/tests/unit/api-errors.test.ts +0 -210
- package/tests/unit/code-generator-functions.test.ts +0 -271
- package/tests/unit/components/column-list.test.tsx +0 -190
- package/tests/unit/components/data-import-modal.test.tsx +0 -441
- package/tests/unit/components/studio-mobile-header.test.tsx +0 -327
- package/tests/unit/data-charts-functions.test.ts +0 -496
- package/tests/unit/data-import-functions.test.ts +0 -320
- package/tests/unit/data-import-utils.test.ts +0 -125
- package/tests/unit/db/base-provider.test.ts +0 -517
- package/tests/unit/db/errors.test.ts +0 -403
- package/tests/unit/db/factory.test.ts +0 -436
- package/tests/unit/db/pool-manager.test.ts +0 -440
- package/tests/unit/db/query-limiter.test.ts +0 -387
- package/tests/unit/db/sql-base.test.ts +0 -438
- package/tests/unit/lib/api/error-codes.test.ts +0 -39
- package/tests/unit/lib/audit.test.ts +0 -326
- package/tests/unit/lib/auth.test.ts +0 -146
- package/tests/unit/lib/connection-string-parser.test.ts +0 -424
- package/tests/unit/lib/data-masking.test.ts +0 -583
- package/tests/unit/lib/db-icons.test.tsx +0 -41
- package/tests/unit/lib/monitoring-thresholds.test.ts +0 -133
- package/tests/unit/lib/oidc.test.ts +0 -509
- package/tests/unit/lib/query-generators.test.ts +0 -127
- package/tests/unit/lib/storage/factory.test.ts +0 -71
- package/tests/unit/lib/storage/local-storage.test.ts +0 -114
- package/tests/unit/lib/storage/providers/postgres.test.ts +0 -312
- package/tests/unit/lib/storage/providers/sqlite.test.ts +0 -232
- package/tests/unit/lib/storage/storage-facade-extended.test.ts +0 -331
- package/tests/unit/lib/storage/storage-facade.test.ts +0 -184
- package/tests/unit/lib/storage.test.ts +0 -317
- package/tests/unit/lib/time-series-buffer.test.ts +0 -212
- package/tests/unit/lib/utils.test.ts +0 -24
- package/tests/unit/llm/base-provider.test.ts +0 -238
- package/tests/unit/llm/config.test.ts +0 -262
- package/tests/unit/llm/custom-provider.test.ts +0 -281
- package/tests/unit/llm/gemini-provider.test.ts +0 -248
- package/tests/unit/llm/llm-factory.test.ts +0 -155
- package/tests/unit/llm/ollama-provider.test.ts +0 -288
- package/tests/unit/llm/openai-provider.test.ts +0 -324
- package/tests/unit/llm/retry.test.ts +0 -180
- package/tests/unit/llm/streaming.test.ts +0 -355
- package/tests/unit/logger.test.ts +0 -198
- package/tests/unit/mongodb-completions.test.ts +0 -516
- package/tests/unit/pivot-table-functions.test.ts +0 -76
- package/tests/unit/query-cancelled-error.test.ts +0 -81
- package/tests/unit/schema-diff/diff-engine.test.ts +0 -367
- package/tests/unit/schema-diff/migration-generator.test.ts +0 -513
- package/tests/unit/seed/config-loader.test.ts +0 -73
- package/tests/unit/seed/connection-filter.test.ts +0 -91
- package/tests/unit/seed/credential-resolver.test.ts +0 -85
- package/tests/unit/seed/index.test.ts +0 -72
- package/tests/unit/seed/resolve-connection.test.ts +0 -74
- package/tests/unit/seed/types.test.ts +0 -129
- package/tests/unit/sql/alias-extractor.test.ts +0 -444
- package/tests/unit/sql/statement-splitter.test.ts +0 -348
- package/tests/unit/sql-completions.test.ts +0 -463
- package/tests/unit/ssh-tunnel.test.ts +0 -465
- package/tsconfig.json +0 -42
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkJZO5KRZN_js = require('./chunk-JZO5KRZN.js');
|
|
4
|
+
var chunkQ6LRDBK7_js = require('./chunk-Q6LRDBK7.js');
|
|
5
|
+
|
|
6
|
+
// src/lib/db/types.ts
|
|
7
|
+
var DEFAULT_POOL_CONFIG = {
|
|
8
|
+
min: 2,
|
|
9
|
+
max: 10,
|
|
10
|
+
idleTimeout: 3e4,
|
|
11
|
+
acquireTimeout: 6e4
|
|
12
|
+
};
|
|
13
|
+
var DEFAULT_QUERY_TIMEOUT = 6e4;
|
|
14
|
+
|
|
15
|
+
// src/lib/db/utils/pool-manager.ts
|
|
16
|
+
function mergePoolConfig(config) {
|
|
17
|
+
return chunkQ6LRDBK7_js.__spreadValues(chunkQ6LRDBK7_js.__spreadValues({}, DEFAULT_POOL_CONFIG), config);
|
|
18
|
+
}
|
|
19
|
+
function formatBytes(bytes) {
|
|
20
|
+
if (bytes === 0) return "0 B";
|
|
21
|
+
const k = 1024;
|
|
22
|
+
const sizes = ["B", "KB", "MB", "GB", "TB"];
|
|
23
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
24
|
+
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
|
|
25
|
+
}
|
|
26
|
+
function formatDuration(ms) {
|
|
27
|
+
if (ms < 1e3) return `${ms}ms`;
|
|
28
|
+
if (ms < 6e4) return `${(ms / 1e3).toFixed(2)}s`;
|
|
29
|
+
if (ms < 36e5) return `${(ms / 6e4).toFixed(2)}m`;
|
|
30
|
+
return `${(ms / 36e5).toFixed(2)}h`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// src/lib/db/base-provider.ts
|
|
34
|
+
var BaseDatabaseProvider = class {
|
|
35
|
+
constructor(config, options = {}) {
|
|
36
|
+
var _a;
|
|
37
|
+
this.type = config.type;
|
|
38
|
+
this.config = config;
|
|
39
|
+
this.options = options;
|
|
40
|
+
this.poolConfig = mergePoolConfig(options.pool);
|
|
41
|
+
this.queryTimeout = (_a = options.queryTimeout) != null ? _a : DEFAULT_QUERY_TIMEOUT;
|
|
42
|
+
this.state = {
|
|
43
|
+
connected: false,
|
|
44
|
+
activeQueries: 0
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
// ============================================================================
|
|
48
|
+
// Common Implementations
|
|
49
|
+
// ============================================================================
|
|
50
|
+
isConnected() {
|
|
51
|
+
return this.state.connected;
|
|
52
|
+
}
|
|
53
|
+
async getTables() {
|
|
54
|
+
const schema = await this.getSchema();
|
|
55
|
+
return schema.map((table) => table.name);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get comprehensive monitoring data
|
|
59
|
+
* This default implementation calls all monitoring methods in parallel
|
|
60
|
+
* Subclasses can override for optimized implementations
|
|
61
|
+
*/
|
|
62
|
+
async getMonitoringData(options = {}) {
|
|
63
|
+
const {
|
|
64
|
+
includeTables = true,
|
|
65
|
+
includeIndexes = true,
|
|
66
|
+
includeStorage = true,
|
|
67
|
+
slowQueryLimit = 10,
|
|
68
|
+
sessionLimit = 50,
|
|
69
|
+
schemaFilter
|
|
70
|
+
// undefined = all user schemas
|
|
71
|
+
} = options;
|
|
72
|
+
const [overview, performance2, slowQueries, activeSessions] = await Promise.all([
|
|
73
|
+
this.getOverview(),
|
|
74
|
+
this.getPerformanceMetrics(),
|
|
75
|
+
this.getSlowQueries({ limit: slowQueryLimit }),
|
|
76
|
+
this.getActiveSessions({ limit: sessionLimit })
|
|
77
|
+
]);
|
|
78
|
+
const result = {
|
|
79
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
80
|
+
overview,
|
|
81
|
+
performance: performance2,
|
|
82
|
+
slowQueries,
|
|
83
|
+
activeSessions
|
|
84
|
+
};
|
|
85
|
+
const optionalPromises = [];
|
|
86
|
+
if (includeTables) {
|
|
87
|
+
optionalPromises.push(
|
|
88
|
+
this.getTableStats({ schema: schemaFilter }).then((tables) => {
|
|
89
|
+
result.tables = tables;
|
|
90
|
+
})
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
if (includeIndexes) {
|
|
94
|
+
optionalPromises.push(
|
|
95
|
+
this.getIndexStats({ schema: schemaFilter }).then((indexes) => {
|
|
96
|
+
result.indexes = indexes;
|
|
97
|
+
})
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
if (includeStorage) {
|
|
101
|
+
optionalPromises.push(
|
|
102
|
+
this.getStorageStats().then((storage) => {
|
|
103
|
+
result.storage = storage;
|
|
104
|
+
})
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
await Promise.all(optionalPromises);
|
|
108
|
+
return result;
|
|
109
|
+
}
|
|
110
|
+
validate() {
|
|
111
|
+
if (!this.config.id) {
|
|
112
|
+
throw new chunkJZO5KRZN_js.DatabaseConfigError("Connection ID is required", this.type);
|
|
113
|
+
}
|
|
114
|
+
if (!this.config.type) {
|
|
115
|
+
throw new chunkJZO5KRZN_js.DatabaseConfigError("Database type is required", this.type);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// ============================================================================
|
|
119
|
+
// Provider Metadata (defaults — subclasses override)
|
|
120
|
+
// ============================================================================
|
|
121
|
+
getCapabilities() {
|
|
122
|
+
return {
|
|
123
|
+
queryLanguage: "sql",
|
|
124
|
+
supportsExplain: true,
|
|
125
|
+
supportsExternalQueryLimiting: true,
|
|
126
|
+
supportsCreateTable: true,
|
|
127
|
+
supportsMaintenance: true,
|
|
128
|
+
maintenanceOperations: ["vacuum", "analyze", "reindex", "kill", "optimize", "check"],
|
|
129
|
+
supportsConnectionString: false,
|
|
130
|
+
defaultPort: null,
|
|
131
|
+
schemaRefreshPattern: "(CREATE|DROP|ALTER|TRUNCATE)\\b"
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
getLabels() {
|
|
135
|
+
return {
|
|
136
|
+
entityName: "Table",
|
|
137
|
+
entityNamePlural: "Tables",
|
|
138
|
+
rowName: "row",
|
|
139
|
+
rowNamePlural: "rows",
|
|
140
|
+
selectAction: "Select Top 100",
|
|
141
|
+
generateAction: "Generate Query",
|
|
142
|
+
analyzeAction: "Analyze Table",
|
|
143
|
+
vacuumAction: "Vacuum Table",
|
|
144
|
+
searchPlaceholder: "Search tables or columns...",
|
|
145
|
+
analyzeGlobalLabel: "Run Analyze",
|
|
146
|
+
analyzeGlobalTitle: "Update Statistics",
|
|
147
|
+
analyzeGlobalDesc: "Updates the planner's statistics for all tables in the database to improve query optimization.",
|
|
148
|
+
vacuumGlobalLabel: "Run Vacuum",
|
|
149
|
+
vacuumGlobalTitle: "Reclaim Space",
|
|
150
|
+
vacuumGlobalDesc: "Removes dead rows from tables and returns space to the operating system."
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
prepareQuery(query, options = {}) {
|
|
154
|
+
return { query, wasLimited: false, limit: options.limit || 500, offset: options.offset || 0 };
|
|
155
|
+
}
|
|
156
|
+
// ============================================================================
|
|
157
|
+
// Protected Helpers
|
|
158
|
+
// ============================================================================
|
|
159
|
+
/**
|
|
160
|
+
* Ensure provider is connected before operation
|
|
161
|
+
*/
|
|
162
|
+
ensureConnected() {
|
|
163
|
+
if (!this.state.connected) {
|
|
164
|
+
throw new chunkJZO5KRZN_js.DatabaseConfigError(
|
|
165
|
+
"Provider is not connected. Call connect() first.",
|
|
166
|
+
this.type
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Track active query count
|
|
172
|
+
*/
|
|
173
|
+
async trackQuery(fn) {
|
|
174
|
+
this.state.activeQueries++;
|
|
175
|
+
try {
|
|
176
|
+
return await fn();
|
|
177
|
+
} finally {
|
|
178
|
+
this.state.activeQueries--;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Measure query execution time
|
|
183
|
+
*/
|
|
184
|
+
async measureExecution(fn) {
|
|
185
|
+
const startTime = performance.now();
|
|
186
|
+
const result = await fn();
|
|
187
|
+
const executionTime = Math.round(performance.now() - startTime);
|
|
188
|
+
return { result, executionTime };
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Map native errors to DatabaseError
|
|
192
|
+
*/
|
|
193
|
+
mapError(error, query) {
|
|
194
|
+
return chunkJZO5KRZN_js.mapDatabaseError(error, this.type, query);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Log error with safe config
|
|
198
|
+
*/
|
|
199
|
+
logError(operation, error) {
|
|
200
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
201
|
+
const sanitize = (v) => v.replace(/[\r\n]/g, " ").replace(/[\x00-\x08\x0b\x0c\x0e-\x1f]/g, "");
|
|
202
|
+
console.error(
|
|
203
|
+
`[DB:${sanitize(this.type)}] ${sanitize(operation)} failed: ${sanitize(errorMessage)}`
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Get config without sensitive data for logging
|
|
208
|
+
*/
|
|
209
|
+
getSafeConfig() {
|
|
210
|
+
return {
|
|
211
|
+
id: this.config.id,
|
|
212
|
+
name: this.config.name,
|
|
213
|
+
type: this.config.type,
|
|
214
|
+
host: this.config.host,
|
|
215
|
+
port: this.config.port,
|
|
216
|
+
database: this.config.database,
|
|
217
|
+
user: this.config.user
|
|
218
|
+
// Never log password or connection string
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Build connection info for health check
|
|
223
|
+
*/
|
|
224
|
+
getConnectionInfo() {
|
|
225
|
+
if (this.config.connectionString) {
|
|
226
|
+
return this.config.connectionString.replace(/:([^:@]+)@/, ":***@");
|
|
227
|
+
}
|
|
228
|
+
return `${this.config.host}:${this.config.port}/${this.config.database}`;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Format duration for display
|
|
232
|
+
*/
|
|
233
|
+
formatDuration(ms) {
|
|
234
|
+
return formatDuration(ms);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Update connection state
|
|
238
|
+
*/
|
|
239
|
+
setConnected(connected) {
|
|
240
|
+
this.state.connected = connected;
|
|
241
|
+
if (connected) {
|
|
242
|
+
this.state.lastConnected = /* @__PURE__ */ new Date();
|
|
243
|
+
this.state.lastError = void 0;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Record connection error
|
|
248
|
+
*/
|
|
249
|
+
setError(error) {
|
|
250
|
+
this.state.lastError = error;
|
|
251
|
+
this.state.connected = false;
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
exports.BaseDatabaseProvider = BaseDatabaseProvider;
|
|
256
|
+
exports.formatBytes = formatBytes;
|
|
257
|
+
//# sourceMappingURL=chunk-PTIRB2JO.js.map
|
|
258
|
+
//# sourceMappingURL=chunk-PTIRB2JO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/db/types.ts","../src/lib/db/utils/pool-manager.ts","../src/lib/db/base-provider.ts"],"names":["__spreadValues","performance","DatabaseConfigError","mapDatabaseError"],"mappings":"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","file":"chunk-PTIRB2JO.js","sourcesContent":["/**\n * Database Provider Types & Interfaces\n * Strategy Pattern implementation for multi-database support\n */\n\n// Re-export common types from main types file\nexport type {\n DatabaseType,\n DatabaseConnection,\n TableSchema,\n ColumnSchema,\n IndexSchema,\n ForeignKeySchema,\n QueryResult,\n} from '../types';\n\nimport type {\n DatabaseType,\n DatabaseConnection,\n TableSchema,\n QueryResult,\n} from '../types';\n\n// ============================================================================\n// Pool Configuration\n// ============================================================================\n\nexport interface PoolConfig {\n /** Minimum number of connections in pool (default: 2) */\n min: number;\n /** Maximum number of connections in pool (default: 10) */\n max: number;\n /** Close idle connections after this time in ms (default: 30000) */\n idleTimeout: number;\n /** Wait for connection timeout in ms (default: 60000) */\n acquireTimeout: number;\n}\n\nexport const DEFAULT_POOL_CONFIG: PoolConfig = {\n min: 2,\n max: 10,\n idleTimeout: 30000,\n acquireTimeout: 60000,\n};\n\n/** Query timeout in milliseconds (default: 60 seconds) */\nexport const DEFAULT_QUERY_TIMEOUT = 60000;\n\n// ============================================================================\n// Health Information\n// ============================================================================\n\nexport interface SlowQuery {\n query: string;\n calls: number;\n avgTime: string;\n}\n\nexport interface ActiveSession {\n pid: number | string;\n user: string;\n database: string;\n state: string;\n query: string;\n duration: string;\n}\n\nexport interface HealthInfo {\n activeConnections: number;\n databaseSize: string;\n cacheHitRatio: string;\n slowQueries: SlowQuery[];\n activeSessions: ActiveSession[];\n}\n\n// ============================================================================\n// Maintenance Operations\n// ============================================================================\n\nexport type MaintenanceType = 'vacuum' | 'analyze' | 'reindex' | 'kill' | 'optimize' | 'check';\n\nexport interface MaintenanceResult {\n success: boolean;\n executionTime: number;\n message: string;\n}\n\n// ============================================================================\n// Provider Capabilities & Labels\n// ============================================================================\n\nexport interface ProviderCapabilities {\n queryLanguage: 'sql' | 'json';\n supportsExplain: boolean;\n supportsExternalQueryLimiting: boolean;\n supportsCreateTable: boolean;\n supportsMaintenance: boolean;\n maintenanceOperations: MaintenanceType[];\n supportsConnectionString: boolean;\n defaultPort: number | null;\n schemaRefreshPattern: string;\n}\n\nexport interface ProviderLabels {\n entityName: string;\n entityNamePlural: string;\n rowName: string;\n rowNamePlural: string;\n selectAction: string;\n generateAction: string;\n analyzeAction: string;\n vacuumAction: string;\n searchPlaceholder: string;\n analyzeGlobalLabel: string;\n analyzeGlobalTitle: string;\n analyzeGlobalDesc: string;\n vacuumGlobalLabel: string;\n vacuumGlobalTitle: string;\n vacuumGlobalDesc: string;\n}\n\nexport interface PreparedQuery {\n query: string;\n wasLimited: boolean;\n limit: number;\n offset: number;\n}\n\nexport interface QueryPrepareOptions {\n limit?: number;\n offset?: number;\n unlimited?: boolean;\n}\n\n// ============================================================================\n// Provider Interface (Strategy Pattern)\n// ============================================================================\n\nexport interface DatabaseProvider {\n /** Database type identifier */\n readonly type: DatabaseType;\n\n /** Connection configuration */\n readonly config: DatabaseConnection;\n\n /**\n * Initialize connection pool or single connection\n */\n connect(): Promise<void>;\n\n /**\n * Close all connections and cleanup resources\n */\n disconnect(): Promise<void>;\n\n /**\n * Check if provider is currently connected\n */\n isConnected(): boolean;\n\n /**\n * Execute a SQL query\n * @param sql - SQL query string\n * @param params - Optional query parameters for prepared statements\n * @returns Query result with rows, fields, and execution time\n */\n query(sql: string, params?: unknown[]): Promise<QueryResult>;\n\n /**\n * Get full database schema\n * @returns Array of table schemas with columns, indexes, and foreign keys\n */\n getSchema(): Promise<TableSchema[]>;\n\n /**\n * Get list of table names\n */\n getTables(): Promise<string[]>;\n\n /**\n * Get health and performance metrics\n */\n getHealth(): Promise<HealthInfo>;\n\n /**\n * Get comprehensive monitoring data\n * @param options - What to include in the monitoring data\n */\n getMonitoringData(options?: MonitoringOptions): Promise<MonitoringData>;\n\n /**\n * Get database overview metrics\n */\n getOverview(): Promise<DatabaseOverview>;\n\n /**\n * Get performance metrics\n */\n getPerformanceMetrics(): Promise<PerformanceMetrics>;\n\n /**\n * Get slow query statistics\n * @param options - Query options (limit)\n */\n getSlowQueries(options?: { limit?: number }): Promise<SlowQueryStats[]>;\n\n /**\n * Get active sessions with details\n * @param options - Query options (limit)\n */\n getActiveSessions(options?: { limit?: number }): Promise<ActiveSessionDetails[]>;\n\n /**\n * Get table statistics\n * @param options - Query options (schema filter)\n */\n getTableStats(options?: { schema?: string }): Promise<TableStats[]>;\n\n /**\n * Get index statistics\n * @param options - Query options (schema filter)\n */\n getIndexStats(options?: { schema?: string }): Promise<IndexStats[]>;\n\n /**\n * Get storage/tablespace statistics\n */\n getStorageStats(): Promise<StorageStats[]>;\n\n /**\n * Run maintenance operations\n * @param type - Type of maintenance operation\n * @param target - Optional target (table name or process ID)\n */\n runMaintenance(type: MaintenanceType, target?: string): Promise<MaintenanceResult>;\n\n /**\n * Validate provider configuration\n * @throws DatabaseConfigError if configuration is invalid\n */\n validate(): void;\n\n /**\n * Get provider capabilities (query language, supported features, etc.)\n */\n getCapabilities(): ProviderCapabilities;\n\n /**\n * Get UI labels for this provider (entity names, action labels, etc.)\n */\n getLabels(): ProviderLabels;\n\n /**\n * Prepare a query for execution (apply limits, analyze query type, etc.)\n */\n prepareQuery(query: string, options?: QueryPrepareOptions): PreparedQuery;\n}\n\n// ============================================================================\n// Provider Configuration Options\n// ============================================================================\n\nexport interface ProviderOptions {\n /** Connection pool configuration */\n pool?: Partial<PoolConfig>;\n /** Query timeout in milliseconds */\n queryTimeout?: number;\n /** Enable SSL/TLS connection */\n ssl?: boolean | { rejectUnauthorized: boolean };\n /** Connection timezone */\n timezone?: string;\n}\n\n// ============================================================================\n// Internal Types\n// ============================================================================\n\nexport interface ConnectionState {\n connected: boolean;\n lastConnected?: Date;\n lastError?: Error;\n activeQueries: number;\n}\n\n// ============================================================================\n// Monitoring Types (Extended)\n// ============================================================================\n\n/**\n * Database overview metrics\n */\nexport interface DatabaseOverview {\n version: string;\n uptime: string;\n startTime?: Date;\n activeConnections: number;\n maxConnections: number;\n databaseSize: string;\n databaseSizeBytes: number;\n tableCount: number;\n indexCount: number;\n}\n\n/**\n * Performance metrics for the database\n */\nexport interface PerformanceMetrics {\n /** Cache hit ratio as percentage (0-100) */\n cacheHitRatio: number;\n /** Transactions per second */\n transactionsPerSecond?: number;\n /** Queries per second */\n queriesPerSecond?: number;\n /** Buffer pool usage as percentage (0-100) */\n bufferPoolUsage?: number;\n /** Number of deadlocks */\n deadlocks?: number;\n /** Checkpoint write time */\n checkpointWriteTime?: string;\n}\n\n/**\n * Slow query with detailed statistics\n */\nexport interface SlowQueryStats {\n queryId?: string;\n query: string;\n calls: number;\n totalTime: number;\n avgTime: number;\n minTime?: number;\n maxTime?: number;\n rows: number;\n sharedBlksHit?: number;\n sharedBlksRead?: number;\n}\n\n/**\n * Active session with detailed information\n */\nexport interface ActiveSessionDetails {\n pid: number | string;\n user: string;\n database: string;\n applicationName?: string;\n clientAddr?: string;\n state: string;\n query: string;\n queryStart?: Date;\n duration: string;\n durationMs: number;\n waitEventType?: string;\n waitEvent?: string;\n blocked?: boolean;\n}\n\n/**\n * Table statistics\n */\nexport interface TableStats {\n schemaName: string;\n tableName: string;\n rowCount: number;\n liveRowCount?: number;\n deadRowCount?: number;\n tableSize: string;\n tableSizeBytes: number;\n indexSize?: string;\n indexSizeBytes?: number;\n totalSize: string;\n totalSizeBytes: number;\n lastVacuum?: Date;\n lastAnalyze?: Date;\n bloatRatio?: number;\n}\n\n/**\n * Index statistics\n */\nexport interface IndexStats {\n schemaName: string;\n tableName: string;\n indexName: string;\n indexType?: string;\n columns: string[];\n isUnique: boolean;\n isPrimary: boolean;\n indexSize: string;\n indexSizeBytes: number;\n scans: number;\n usageRatio?: number;\n}\n\n/**\n * Storage statistics\n */\nexport interface StorageStats {\n name: string;\n location?: string;\n size: string;\n sizeBytes: number;\n usagePercent?: number;\n walSize?: string;\n walSizeBytes?: number;\n}\n\n/**\n * Comprehensive monitoring data combining all metrics\n */\nexport interface MonitoringData {\n timestamp: Date;\n overview: DatabaseOverview;\n performance: PerformanceMetrics;\n slowQueries: SlowQueryStats[];\n activeSessions: ActiveSessionDetails[];\n tables?: TableStats[];\n indexes?: IndexStats[];\n storage?: StorageStats[];\n}\n\n/**\n * Options for monitoring queries\n */\nexport interface MonitoringOptions {\n /** Include table statistics */\n includeTables?: boolean;\n /** Include index statistics */\n includeIndexes?: boolean;\n /** Include storage/tablespace info */\n includeStorage?: boolean;\n /** Limit for slow queries (default: 10) */\n slowQueryLimit?: number;\n /** Limit for active sessions (default: 50) */\n sessionLimit?: number;\n /** Schema filter (default: 'public' for PostgreSQL) */\n schemaFilter?: string;\n}\n","/**\n * Connection Pool Manager\n * Abstract pool management utilities for database providers\n */\n\nimport { type PoolConfig, DEFAULT_POOL_CONFIG, type DatabaseType } from '../types';\nimport { TimeoutError } from '../errors';\n\n// ============================================================================\n// Pool Statistics\n// ============================================================================\n\nexport interface PoolStats {\n /** Total connections in pool */\n total: number;\n /** Currently idle connections */\n idle: number;\n /** Currently active/busy connections */\n active: number;\n /** Connections waiting in queue */\n waiting: number;\n}\n\n// ============================================================================\n// Pool Manager Interface\n// ============================================================================\n\nexport interface PoolManager<T> {\n /** Acquire a connection from the pool */\n acquire(): Promise<T>;\n /** Release a connection back to the pool */\n release(connection: T): void;\n /** Get pool statistics */\n getStats(): PoolStats;\n /** Drain all connections and close pool */\n drain(): Promise<void>;\n /** Check if pool is healthy */\n isHealthy(): boolean;\n}\n\n// ============================================================================\n// Pool Configuration Utilities\n// ============================================================================\n\n/**\n * Merge user config with defaults\n */\nexport function mergePoolConfig(config?: Partial<PoolConfig>): PoolConfig {\n return {\n ...DEFAULT_POOL_CONFIG,\n ...config,\n };\n}\n\n/**\n * Validate pool configuration\n */\nexport function validatePoolConfig(config: PoolConfig): void {\n if (config.min < 0) {\n throw new Error('Pool min must be non-negative');\n }\n if (config.max < 1) {\n throw new Error('Pool max must be at least 1');\n }\n if (config.min > config.max) {\n throw new Error('Pool min cannot be greater than max');\n }\n if (config.idleTimeout < 0) {\n throw new Error('Pool idleTimeout must be non-negative');\n }\n if (config.acquireTimeout < 0) {\n throw new Error('Pool acquireTimeout must be non-negative');\n }\n}\n\n// ============================================================================\n// Timeout Utilities\n// ============================================================================\n\n/**\n * Execute a promise with timeout\n */\nexport async function withTimeout<T>(\n promise: Promise<T>,\n timeout: number,\n provider: DatabaseType,\n operation: string\n): Promise<T> {\n let timeoutId: NodeJS.Timeout;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(new TimeoutError(\n `${operation} timed out after ${timeout}ms`,\n provider,\n timeout\n ));\n }, timeout);\n });\n\n try {\n const result = await Promise.race([promise, timeoutPromise]);\n clearTimeout(timeoutId!);\n return result;\n } catch (error) {\n clearTimeout(timeoutId!);\n throw error;\n }\n}\n\n/**\n * Create a cancellable query wrapper\n */\nexport function createCancellableQuery<T>(\n queryFn: (signal?: AbortSignal) => Promise<T>,\n timeout: number,\n provider: DatabaseType\n): { promise: Promise<T>; cancel: () => void } {\n const controller = new AbortController();\n let timeoutId: NodeJS.Timeout;\n\n const promise = new Promise<T>((resolve, reject) => {\n timeoutId = setTimeout(() => {\n controller.abort();\n reject(new TimeoutError(\n `Query timed out after ${timeout}ms`,\n provider,\n timeout\n ));\n }, timeout);\n\n queryFn(controller.signal)\n .then(resolve)\n .catch(reject)\n .finally(() => clearTimeout(timeoutId));\n });\n\n return {\n promise,\n cancel: () => {\n clearTimeout(timeoutId);\n controller.abort();\n },\n };\n}\n\n// ============================================================================\n// Connection Health Check\n// ============================================================================\n\n/**\n * Simple ping-like health check\n */\nexport async function checkConnectionHealth<T>(\n acquireFn: () => Promise<T>,\n releaseFn: (conn: T) => void,\n pingFn: (conn: T) => Promise<void>,\n timeout: number,\n provider: DatabaseType\n): Promise<boolean> {\n try {\n const conn = await withTimeout(\n acquireFn(),\n timeout,\n provider,\n 'Connection acquire'\n );\n\n try {\n await withTimeout(\n pingFn(conn),\n timeout,\n provider,\n 'Connection ping'\n );\n return true;\n } finally {\n releaseFn(conn);\n }\n } catch {\n return false;\n }\n}\n\n// ============================================================================\n// Retry Logic\n// ============================================================================\n\nexport interface RetryOptions {\n maxAttempts?: number;\n initialDelay?: number;\n maxDelay?: number;\n backoffMultiplier?: number;\n}\n\nconst DEFAULT_RETRY_OPTIONS: Required<RetryOptions> = {\n maxAttempts: 3,\n initialDelay: 1000,\n maxDelay: 10000,\n backoffMultiplier: 2,\n};\n\n/**\n * Execute with retry logic and exponential backoff\n */\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n options: RetryOptions = {},\n isRetryable: (error: unknown) => boolean = () => true,\n provider?: DatabaseType\n): Promise<T> {\n const opts = { ...DEFAULT_RETRY_OPTIONS, ...options };\n let lastError: Error | undefined;\n let delay = opts.initialDelay;\n\n for (let attempt = 1; attempt <= opts.maxAttempts; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n if (!isRetryable(error) || attempt === opts.maxAttempts) {\n throw error;\n }\n\n console.error(\n `[DB${provider ? `:${provider}` : ''}] Operation failed (attempt ${attempt}/${opts.maxAttempts}): ${lastError.message}. Retrying in ${delay}ms...`\n );\n\n await sleep(delay);\n delay = Math.min(delay * opts.backoffMultiplier, opts.maxDelay);\n }\n }\n\n throw lastError;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// ============================================================================\n// SQL Utilities\n// ============================================================================\n\n/**\n * Escape SQL identifier (table name, column name)\n * Prevents SQL injection in dynamic queries\n */\nexport function escapeIdentifier(identifier: string, provider: DatabaseType): string {\n // Remove any existing quotes and escape internal quotes\n const cleaned = identifier.replace(/[\"'`]/g, '');\n\n switch (provider) {\n case 'postgres':\n return `\"${cleaned}\"`;\n case 'mysql':\n return `\\`${cleaned}\\``;\n case 'sqlite':\n return `\"${cleaned}\"`;\n default:\n return `\"${cleaned}\"`;\n }\n}\n\n/**\n * Format bytes to human readable size\n */\nexport function formatBytes(bytes: number): string {\n if (bytes === 0) return '0 B';\n\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;\n}\n\n/**\n * Format duration in milliseconds to human readable\n */\nexport function formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(2)}s`;\n if (ms < 3600000) return `${(ms / 60000).toFixed(2)}m`;\n return `${(ms / 3600000).toFixed(2)}h`;\n}\n","/**\n * Base Database Provider\n * Abstract class implementing common provider functionality\n */\n\nimport {\n type DatabaseProvider,\n type DatabaseType,\n type DatabaseConnection,\n type TableSchema,\n type QueryResult,\n type HealthInfo,\n type MaintenanceType,\n type MaintenanceResult,\n type ProviderOptions,\n type PoolConfig,\n type ConnectionState,\n type MonitoringData,\n type MonitoringOptions,\n type DatabaseOverview,\n type PerformanceMetrics,\n type SlowQueryStats,\n type ActiveSessionDetails,\n type TableStats,\n type IndexStats,\n type StorageStats,\n type ProviderCapabilities,\n type ProviderLabels,\n type PreparedQuery,\n type QueryPrepareOptions,\n DEFAULT_QUERY_TIMEOUT,\n} from './types';\nimport { DatabaseConfigError, mapDatabaseError } from './errors';\nimport { mergePoolConfig, formatDuration } from './utils/pool-manager';\n\n// ============================================================================\n// Base Provider Class\n// ============================================================================\n\nexport abstract class BaseDatabaseProvider implements DatabaseProvider {\n public readonly type: DatabaseType;\n public readonly config: DatabaseConnection;\n\n protected readonly poolConfig: PoolConfig;\n protected readonly queryTimeout: number;\n protected readonly options: ProviderOptions;\n protected state: ConnectionState;\n\n protected constructor(\n config: DatabaseConnection,\n options: ProviderOptions = {}\n ) {\n this.type = config.type;\n this.config = config;\n this.options = options;\n this.poolConfig = mergePoolConfig(options.pool);\n this.queryTimeout = options.queryTimeout ?? DEFAULT_QUERY_TIMEOUT;\n this.state = {\n connected: false,\n activeQueries: 0,\n };\n }\n\n // ============================================================================\n // Abstract Methods (must be implemented by subclasses)\n // ============================================================================\n\n public abstract connect(): Promise<void>;\n public abstract disconnect(): Promise<void>;\n public abstract query(sql: string, params?: unknown[]): Promise<QueryResult>;\n public abstract getSchema(): Promise<TableSchema[]>;\n public abstract getHealth(): Promise<HealthInfo>;\n public abstract runMaintenance(type: MaintenanceType, target?: string): Promise<MaintenanceResult>;\n\n // Monitoring methods (must be implemented by subclasses)\n public abstract getOverview(): Promise<DatabaseOverview>;\n public abstract getPerformanceMetrics(): Promise<PerformanceMetrics>;\n public abstract getSlowQueries(options?: { limit?: number }): Promise<SlowQueryStats[]>;\n public abstract getActiveSessions(options?: { limit?: number }): Promise<ActiveSessionDetails[]>;\n public abstract getTableStats(options?: { schema?: string }): Promise<TableStats[]>;\n public abstract getIndexStats(options?: { schema?: string }): Promise<IndexStats[]>;\n public abstract getStorageStats(): Promise<StorageStats[]>;\n\n // ============================================================================\n // Common Implementations\n // ============================================================================\n\n public isConnected(): boolean {\n return this.state.connected;\n }\n\n public async getTables(): Promise<string[]> {\n const schema = await this.getSchema();\n return schema.map((table) => table.name);\n }\n\n /**\n * Get comprehensive monitoring data\n * This default implementation calls all monitoring methods in parallel\n * Subclasses can override for optimized implementations\n */\n public async getMonitoringData(options: MonitoringOptions = {}): Promise<MonitoringData> {\n const {\n includeTables = true,\n includeIndexes = true,\n includeStorage = true,\n slowQueryLimit = 10,\n sessionLimit = 50,\n schemaFilter, // undefined = all user schemas\n } = options;\n\n // Fetch core data in parallel\n const [overview, performance, slowQueries, activeSessions] = await Promise.all([\n this.getOverview(),\n this.getPerformanceMetrics(),\n this.getSlowQueries({ limit: slowQueryLimit }),\n this.getActiveSessions({ limit: sessionLimit }),\n ]);\n\n const result: MonitoringData = {\n timestamp: new Date(),\n overview,\n performance,\n slowQueries,\n activeSessions,\n };\n\n // Fetch optional data in parallel\n const optionalPromises: Promise<void>[] = [];\n\n if (includeTables) {\n optionalPromises.push(\n this.getTableStats({ schema: schemaFilter }).then((tables) => {\n result.tables = tables;\n })\n );\n }\n\n if (includeIndexes) {\n optionalPromises.push(\n this.getIndexStats({ schema: schemaFilter }).then((indexes) => {\n result.indexes = indexes;\n })\n );\n }\n\n if (includeStorage) {\n optionalPromises.push(\n this.getStorageStats().then((storage) => {\n result.storage = storage;\n })\n );\n }\n\n await Promise.all(optionalPromises);\n\n return result;\n }\n\n public validate(): void {\n if (!this.config.id) {\n throw new DatabaseConfigError('Connection ID is required', this.type);\n }\n\n if (!this.config.type) {\n throw new DatabaseConfigError('Database type is required', this.type);\n }\n\n // Subclasses should override for provider-specific validation\n }\n\n // ============================================================================\n // Provider Metadata (defaults — subclasses override)\n // ============================================================================\n\n public getCapabilities(): ProviderCapabilities {\n return {\n queryLanguage: 'sql',\n supportsExplain: true,\n supportsExternalQueryLimiting: true,\n supportsCreateTable: true,\n supportsMaintenance: true,\n maintenanceOperations: ['vacuum', 'analyze', 'reindex', 'kill', 'optimize', 'check'],\n supportsConnectionString: false,\n defaultPort: null,\n schemaRefreshPattern: '(CREATE|DROP|ALTER|TRUNCATE)\\\\b',\n };\n }\n\n public getLabels(): ProviderLabels {\n return {\n entityName: 'Table',\n entityNamePlural: 'Tables',\n rowName: 'row',\n rowNamePlural: 'rows',\n selectAction: 'Select Top 100',\n generateAction: 'Generate Query',\n analyzeAction: 'Analyze Table',\n vacuumAction: 'Vacuum Table',\n searchPlaceholder: 'Search tables or columns...',\n analyzeGlobalLabel: 'Run Analyze',\n analyzeGlobalTitle: 'Update Statistics',\n analyzeGlobalDesc: \"Updates the planner's statistics for all tables in the database to improve query optimization.\",\n vacuumGlobalLabel: 'Run Vacuum',\n vacuumGlobalTitle: 'Reclaim Space',\n vacuumGlobalDesc: 'Removes dead rows from tables and returns space to the operating system.',\n };\n }\n\n public prepareQuery(query: string, options: QueryPrepareOptions = {}): PreparedQuery {\n return { query, wasLimited: false, limit: options.limit || 500, offset: options.offset || 0 };\n }\n\n // ============================================================================\n // Protected Helpers\n // ============================================================================\n\n /**\n * Ensure provider is connected before operation\n */\n protected ensureConnected(): void {\n if (!this.state.connected) {\n throw new DatabaseConfigError(\n 'Provider is not connected. Call connect() first.',\n this.type\n );\n }\n }\n\n /**\n * Track active query count\n */\n protected async trackQuery<T>(fn: () => Promise<T>): Promise<T> {\n this.state.activeQueries++;\n try {\n return await fn();\n } finally {\n this.state.activeQueries--;\n }\n }\n\n /**\n * Measure query execution time\n */\n protected async measureExecution<T>(\n fn: () => Promise<T>\n ): Promise<{ result: T; executionTime: number }> {\n const startTime = performance.now();\n const result = await fn();\n const executionTime = Math.round(performance.now() - startTime);\n return { result, executionTime };\n }\n\n /**\n * Map native errors to DatabaseError\n */\n protected mapError(error: unknown, query?: string): Error {\n return mapDatabaseError(error, this.type, query);\n }\n\n /**\n * Log error with safe config\n */\n protected logError(operation: string, error: unknown): void {\n const errorMessage = error instanceof Error ? error.message : String(error);\n // Sanitize to prevent log injection via newlines/control chars\n const sanitize = (v: string) => v.replace(/[\\r\\n]/g, ' ').replace(/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f]/g, '');\n console.error(\n `[DB:${sanitize(this.type)}] ${sanitize(operation)} failed: ${sanitize(errorMessage)}`\n );\n }\n\n /**\n * Get config without sensitive data for logging\n */\n protected getSafeConfig(): Record<string, unknown> {\n return {\n id: this.config.id,\n name: this.config.name,\n type: this.config.type,\n host: this.config.host,\n port: this.config.port,\n database: this.config.database,\n user: this.config.user,\n // Never log password or connection string\n };\n }\n\n /**\n * Build connection info for health check\n */\n protected getConnectionInfo(): string {\n if (this.config.connectionString) {\n // Mask password in connection string\n return this.config.connectionString.replace(/:([^:@]+)@/, ':***@');\n }\n return `${this.config.host}:${this.config.port}/${this.config.database}`;\n }\n\n /**\n * Format duration for display\n */\n protected formatDuration(ms: number): string {\n return formatDuration(ms);\n }\n\n /**\n * Update connection state\n */\n protected setConnected(connected: boolean): void {\n this.state.connected = connected;\n if (connected) {\n this.state.lastConnected = new Date();\n this.state.lastError = undefined;\n }\n }\n\n /**\n * Record connection error\n */\n protected setError(error: Error): void {\n this.state.lastError = error;\n this.state.connected = false;\n }\n}\n"]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __defProps = Object.defineProperties;
|
|
5
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
6
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
9
|
+
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : /* @__PURE__ */ Symbol.for("Symbol." + name);
|
|
10
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
11
|
+
var __spreadValues = (a, b) => {
|
|
12
|
+
for (var prop in b || (b = {}))
|
|
13
|
+
if (__hasOwnProp.call(b, prop))
|
|
14
|
+
__defNormalProp(a, prop, b[prop]);
|
|
15
|
+
if (__getOwnPropSymbols)
|
|
16
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
17
|
+
if (__propIsEnum.call(b, prop))
|
|
18
|
+
__defNormalProp(a, prop, b[prop]);
|
|
19
|
+
}
|
|
20
|
+
return a;
|
|
21
|
+
};
|
|
22
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
23
|
+
var __objRest = (source, exclude) => {
|
|
24
|
+
var target = {};
|
|
25
|
+
for (var prop in source)
|
|
26
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
27
|
+
target[prop] = source[prop];
|
|
28
|
+
if (source != null && __getOwnPropSymbols)
|
|
29
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
30
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
31
|
+
target[prop] = source[prop];
|
|
32
|
+
}
|
|
33
|
+
return target;
|
|
34
|
+
};
|
|
35
|
+
var __forAwait = (obj, it, method) => (it = obj[__knownSymbol("asyncIterator")]) ? it.call(obj) : (obj = obj[__knownSymbol("iterator")](), it = {}, method = (key, fn) => (fn = obj[key]) && (it[key] = (arg) => new Promise((yes, no, done) => (arg = fn.call(obj, arg), done = arg.done, Promise.resolve(arg.value).then((value) => yes({ value, done }), no)))), method("next"), method("return"), it);
|
|
36
|
+
|
|
37
|
+
exports.__forAwait = __forAwait;
|
|
38
|
+
exports.__objRest = __objRest;
|
|
39
|
+
exports.__spreadProps = __spreadProps;
|
|
40
|
+
exports.__spreadValues = __spreadValues;
|
|
41
|
+
//# sourceMappingURL=chunk-Q6LRDBK7.js.map
|
|
42
|
+
//# sourceMappingURL=chunk-Q6LRDBK7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-Q6LRDBK7.js"}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { DatabaseConfigError, mapDatabaseError } from './chunk-CZVV3JJB.mjs';
|
|
2
|
+
import { __spreadValues } from './chunk-4LVB3K53.mjs';
|
|
3
|
+
|
|
4
|
+
// src/lib/db/types.ts
|
|
5
|
+
var DEFAULT_POOL_CONFIG = {
|
|
6
|
+
min: 2,
|
|
7
|
+
max: 10,
|
|
8
|
+
idleTimeout: 3e4,
|
|
9
|
+
acquireTimeout: 6e4
|
|
10
|
+
};
|
|
11
|
+
var DEFAULT_QUERY_TIMEOUT = 6e4;
|
|
12
|
+
|
|
13
|
+
// src/lib/db/utils/pool-manager.ts
|
|
14
|
+
function mergePoolConfig(config) {
|
|
15
|
+
return __spreadValues(__spreadValues({}, DEFAULT_POOL_CONFIG), config);
|
|
16
|
+
}
|
|
17
|
+
function formatBytes(bytes) {
|
|
18
|
+
if (bytes === 0) return "0 B";
|
|
19
|
+
const k = 1024;
|
|
20
|
+
const sizes = ["B", "KB", "MB", "GB", "TB"];
|
|
21
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
22
|
+
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
|
|
23
|
+
}
|
|
24
|
+
function formatDuration(ms) {
|
|
25
|
+
if (ms < 1e3) return `${ms}ms`;
|
|
26
|
+
if (ms < 6e4) return `${(ms / 1e3).toFixed(2)}s`;
|
|
27
|
+
if (ms < 36e5) return `${(ms / 6e4).toFixed(2)}m`;
|
|
28
|
+
return `${(ms / 36e5).toFixed(2)}h`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// src/lib/db/base-provider.ts
|
|
32
|
+
var BaseDatabaseProvider = class {
|
|
33
|
+
constructor(config, options = {}) {
|
|
34
|
+
var _a;
|
|
35
|
+
this.type = config.type;
|
|
36
|
+
this.config = config;
|
|
37
|
+
this.options = options;
|
|
38
|
+
this.poolConfig = mergePoolConfig(options.pool);
|
|
39
|
+
this.queryTimeout = (_a = options.queryTimeout) != null ? _a : DEFAULT_QUERY_TIMEOUT;
|
|
40
|
+
this.state = {
|
|
41
|
+
connected: false,
|
|
42
|
+
activeQueries: 0
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
// ============================================================================
|
|
46
|
+
// Common Implementations
|
|
47
|
+
// ============================================================================
|
|
48
|
+
isConnected() {
|
|
49
|
+
return this.state.connected;
|
|
50
|
+
}
|
|
51
|
+
async getTables() {
|
|
52
|
+
const schema = await this.getSchema();
|
|
53
|
+
return schema.map((table) => table.name);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Get comprehensive monitoring data
|
|
57
|
+
* This default implementation calls all monitoring methods in parallel
|
|
58
|
+
* Subclasses can override for optimized implementations
|
|
59
|
+
*/
|
|
60
|
+
async getMonitoringData(options = {}) {
|
|
61
|
+
const {
|
|
62
|
+
includeTables = true,
|
|
63
|
+
includeIndexes = true,
|
|
64
|
+
includeStorage = true,
|
|
65
|
+
slowQueryLimit = 10,
|
|
66
|
+
sessionLimit = 50,
|
|
67
|
+
schemaFilter
|
|
68
|
+
// undefined = all user schemas
|
|
69
|
+
} = options;
|
|
70
|
+
const [overview, performance2, slowQueries, activeSessions] = await Promise.all([
|
|
71
|
+
this.getOverview(),
|
|
72
|
+
this.getPerformanceMetrics(),
|
|
73
|
+
this.getSlowQueries({ limit: slowQueryLimit }),
|
|
74
|
+
this.getActiveSessions({ limit: sessionLimit })
|
|
75
|
+
]);
|
|
76
|
+
const result = {
|
|
77
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
78
|
+
overview,
|
|
79
|
+
performance: performance2,
|
|
80
|
+
slowQueries,
|
|
81
|
+
activeSessions
|
|
82
|
+
};
|
|
83
|
+
const optionalPromises = [];
|
|
84
|
+
if (includeTables) {
|
|
85
|
+
optionalPromises.push(
|
|
86
|
+
this.getTableStats({ schema: schemaFilter }).then((tables) => {
|
|
87
|
+
result.tables = tables;
|
|
88
|
+
})
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
if (includeIndexes) {
|
|
92
|
+
optionalPromises.push(
|
|
93
|
+
this.getIndexStats({ schema: schemaFilter }).then((indexes) => {
|
|
94
|
+
result.indexes = indexes;
|
|
95
|
+
})
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
if (includeStorage) {
|
|
99
|
+
optionalPromises.push(
|
|
100
|
+
this.getStorageStats().then((storage) => {
|
|
101
|
+
result.storage = storage;
|
|
102
|
+
})
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
await Promise.all(optionalPromises);
|
|
106
|
+
return result;
|
|
107
|
+
}
|
|
108
|
+
validate() {
|
|
109
|
+
if (!this.config.id) {
|
|
110
|
+
throw new DatabaseConfigError("Connection ID is required", this.type);
|
|
111
|
+
}
|
|
112
|
+
if (!this.config.type) {
|
|
113
|
+
throw new DatabaseConfigError("Database type is required", this.type);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// ============================================================================
|
|
117
|
+
// Provider Metadata (defaults — subclasses override)
|
|
118
|
+
// ============================================================================
|
|
119
|
+
getCapabilities() {
|
|
120
|
+
return {
|
|
121
|
+
queryLanguage: "sql",
|
|
122
|
+
supportsExplain: true,
|
|
123
|
+
supportsExternalQueryLimiting: true,
|
|
124
|
+
supportsCreateTable: true,
|
|
125
|
+
supportsMaintenance: true,
|
|
126
|
+
maintenanceOperations: ["vacuum", "analyze", "reindex", "kill", "optimize", "check"],
|
|
127
|
+
supportsConnectionString: false,
|
|
128
|
+
defaultPort: null,
|
|
129
|
+
schemaRefreshPattern: "(CREATE|DROP|ALTER|TRUNCATE)\\b"
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
getLabels() {
|
|
133
|
+
return {
|
|
134
|
+
entityName: "Table",
|
|
135
|
+
entityNamePlural: "Tables",
|
|
136
|
+
rowName: "row",
|
|
137
|
+
rowNamePlural: "rows",
|
|
138
|
+
selectAction: "Select Top 100",
|
|
139
|
+
generateAction: "Generate Query",
|
|
140
|
+
analyzeAction: "Analyze Table",
|
|
141
|
+
vacuumAction: "Vacuum Table",
|
|
142
|
+
searchPlaceholder: "Search tables or columns...",
|
|
143
|
+
analyzeGlobalLabel: "Run Analyze",
|
|
144
|
+
analyzeGlobalTitle: "Update Statistics",
|
|
145
|
+
analyzeGlobalDesc: "Updates the planner's statistics for all tables in the database to improve query optimization.",
|
|
146
|
+
vacuumGlobalLabel: "Run Vacuum",
|
|
147
|
+
vacuumGlobalTitle: "Reclaim Space",
|
|
148
|
+
vacuumGlobalDesc: "Removes dead rows from tables and returns space to the operating system."
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
prepareQuery(query, options = {}) {
|
|
152
|
+
return { query, wasLimited: false, limit: options.limit || 500, offset: options.offset || 0 };
|
|
153
|
+
}
|
|
154
|
+
// ============================================================================
|
|
155
|
+
// Protected Helpers
|
|
156
|
+
// ============================================================================
|
|
157
|
+
/**
|
|
158
|
+
* Ensure provider is connected before operation
|
|
159
|
+
*/
|
|
160
|
+
ensureConnected() {
|
|
161
|
+
if (!this.state.connected) {
|
|
162
|
+
throw new DatabaseConfigError(
|
|
163
|
+
"Provider is not connected. Call connect() first.",
|
|
164
|
+
this.type
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Track active query count
|
|
170
|
+
*/
|
|
171
|
+
async trackQuery(fn) {
|
|
172
|
+
this.state.activeQueries++;
|
|
173
|
+
try {
|
|
174
|
+
return await fn();
|
|
175
|
+
} finally {
|
|
176
|
+
this.state.activeQueries--;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Measure query execution time
|
|
181
|
+
*/
|
|
182
|
+
async measureExecution(fn) {
|
|
183
|
+
const startTime = performance.now();
|
|
184
|
+
const result = await fn();
|
|
185
|
+
const executionTime = Math.round(performance.now() - startTime);
|
|
186
|
+
return { result, executionTime };
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Map native errors to DatabaseError
|
|
190
|
+
*/
|
|
191
|
+
mapError(error, query) {
|
|
192
|
+
return mapDatabaseError(error, this.type, query);
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Log error with safe config
|
|
196
|
+
*/
|
|
197
|
+
logError(operation, error) {
|
|
198
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
199
|
+
const sanitize = (v) => v.replace(/[\r\n]/g, " ").replace(/[\x00-\x08\x0b\x0c\x0e-\x1f]/g, "");
|
|
200
|
+
console.error(
|
|
201
|
+
`[DB:${sanitize(this.type)}] ${sanitize(operation)} failed: ${sanitize(errorMessage)}`
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Get config without sensitive data for logging
|
|
206
|
+
*/
|
|
207
|
+
getSafeConfig() {
|
|
208
|
+
return {
|
|
209
|
+
id: this.config.id,
|
|
210
|
+
name: this.config.name,
|
|
211
|
+
type: this.config.type,
|
|
212
|
+
host: this.config.host,
|
|
213
|
+
port: this.config.port,
|
|
214
|
+
database: this.config.database,
|
|
215
|
+
user: this.config.user
|
|
216
|
+
// Never log password or connection string
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Build connection info for health check
|
|
221
|
+
*/
|
|
222
|
+
getConnectionInfo() {
|
|
223
|
+
if (this.config.connectionString) {
|
|
224
|
+
return this.config.connectionString.replace(/:([^:@]+)@/, ":***@");
|
|
225
|
+
}
|
|
226
|
+
return `${this.config.host}:${this.config.port}/${this.config.database}`;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Format duration for display
|
|
230
|
+
*/
|
|
231
|
+
formatDuration(ms) {
|
|
232
|
+
return formatDuration(ms);
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Update connection state
|
|
236
|
+
*/
|
|
237
|
+
setConnected(connected) {
|
|
238
|
+
this.state.connected = connected;
|
|
239
|
+
if (connected) {
|
|
240
|
+
this.state.lastConnected = /* @__PURE__ */ new Date();
|
|
241
|
+
this.state.lastError = void 0;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Record connection error
|
|
246
|
+
*/
|
|
247
|
+
setError(error) {
|
|
248
|
+
this.state.lastError = error;
|
|
249
|
+
this.state.connected = false;
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
export { BaseDatabaseProvider, formatBytes };
|
|
254
|
+
//# sourceMappingURL=chunk-QJP5FZRY.mjs.map
|
|
255
|
+
//# sourceMappingURL=chunk-QJP5FZRY.mjs.map
|