@libredb/studio 0.9.7 → 0.9.12
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-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-DZ2UB3C6.mjs +6679 -0
- package/dist/chunk-DZ2UB3C6.mjs.map +1 -0
- package/dist/chunk-FYSE52VB.js +242 -0
- package/dist/chunk-FYSE52VB.js.map +1 -0
- package/dist/chunk-G4WYE6TI.js +4 -0
- package/dist/chunk-G4WYE6TI.js.map +1 -0
- package/dist/chunk-JOGLIOFO.js +1310 -0
- package/dist/chunk-JOGLIOFO.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-RBVDMLFV.js +6747 -0
- package/dist/chunk-RBVDMLFV.js.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-VWVRUCQO.mjs +1289 -0
- package/dist/chunk-VWVRUCQO.mjs.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 +4182 -0
- package/dist/workspace.js.map +1 -0
- package/dist/workspace.mjs +4155 -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,319 @@
|
|
|
1
|
+
import { resolveConfig, getSafeConfigForLogging, LLMConfigError } from './chunk-SR5DRGBX.mjs';
|
|
2
|
+
import { logger } from './chunk-6DRZXXNT.mjs';
|
|
3
|
+
import { DatabaseConfigError } from './chunk-CZVV3JJB.mjs';
|
|
4
|
+
import { __spreadProps, __spreadValues } from './chunk-4LVB3K53.mjs';
|
|
5
|
+
import { Client } from 'ssh2';
|
|
6
|
+
import net from 'net';
|
|
7
|
+
|
|
8
|
+
var activeTunnels = /* @__PURE__ */ new Map();
|
|
9
|
+
async function createSSHTunnel(connectionId, sshConfig, remoteHost, remotePort) {
|
|
10
|
+
const existing = activeTunnels.get(connectionId);
|
|
11
|
+
if (existing) {
|
|
12
|
+
return existing;
|
|
13
|
+
}
|
|
14
|
+
return new Promise((resolve, reject) => {
|
|
15
|
+
const sshClient = new Client();
|
|
16
|
+
let localServer = null;
|
|
17
|
+
const cleanup = async () => {
|
|
18
|
+
activeTunnels.delete(connectionId);
|
|
19
|
+
if (localServer) {
|
|
20
|
+
localServer.close();
|
|
21
|
+
localServer = null;
|
|
22
|
+
}
|
|
23
|
+
sshClient.end();
|
|
24
|
+
};
|
|
25
|
+
sshClient.on("ready", () => {
|
|
26
|
+
localServer = net.createServer((socket) => {
|
|
27
|
+
sshClient.forwardOut(
|
|
28
|
+
"127.0.0.1",
|
|
29
|
+
0,
|
|
30
|
+
remoteHost,
|
|
31
|
+
remotePort,
|
|
32
|
+
(err, stream) => {
|
|
33
|
+
if (err) {
|
|
34
|
+
socket.end();
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
stream.on("error", () => {
|
|
38
|
+
socket.destroy();
|
|
39
|
+
});
|
|
40
|
+
socket.on("error", () => {
|
|
41
|
+
stream.close();
|
|
42
|
+
});
|
|
43
|
+
socket.pipe(stream).pipe(socket);
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
localServer.on("error", (err) => {
|
|
48
|
+
cleanup();
|
|
49
|
+
reject(new Error(`SSH tunnel local server error: ${err.message}`));
|
|
50
|
+
});
|
|
51
|
+
localServer.listen(0, "127.0.0.1", () => {
|
|
52
|
+
const address = localServer.address();
|
|
53
|
+
const tunnelInfo = {
|
|
54
|
+
localHost: "127.0.0.1",
|
|
55
|
+
localPort: address.port,
|
|
56
|
+
close: cleanup
|
|
57
|
+
};
|
|
58
|
+
activeTunnels.set(connectionId, tunnelInfo);
|
|
59
|
+
logger.info(`Tunnel created for ${connectionId}: 127.0.0.1:${address.port} -> ${remoteHost}:${remotePort}`, { connectionId });
|
|
60
|
+
resolve(tunnelInfo);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
sshClient.on("error", (err) => {
|
|
64
|
+
sshClient.end();
|
|
65
|
+
cleanup();
|
|
66
|
+
reject(new Error(`SSH connection error: ${err.message}`));
|
|
67
|
+
});
|
|
68
|
+
const connectOptions = {
|
|
69
|
+
host: sshConfig.host,
|
|
70
|
+
port: sshConfig.port || 22,
|
|
71
|
+
username: sshConfig.username
|
|
72
|
+
};
|
|
73
|
+
if (sshConfig.authMethod === "password") {
|
|
74
|
+
connectOptions.password = sshConfig.password;
|
|
75
|
+
} else if (sshConfig.authMethod === "privateKey") {
|
|
76
|
+
connectOptions.privateKey = sshConfig.privateKey;
|
|
77
|
+
if (sshConfig.passphrase) {
|
|
78
|
+
connectOptions.passphrase = sshConfig.passphrase;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
sshClient.connect(connectOptions);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
async function closeSSHTunnel(connectionId) {
|
|
85
|
+
const tunnel = activeTunnels.get(connectionId);
|
|
86
|
+
if (tunnel) {
|
|
87
|
+
await tunnel.close();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/lib/db/factory.ts
|
|
92
|
+
async function createDatabaseProvider(connection, options = {}) {
|
|
93
|
+
const sanitize = (v) => v.replace(/[\r\n]/g, " ").replace(/[\x00-\x08\x0b\x0c\x0e-\x1f]/g, "");
|
|
94
|
+
console.log(`[DB] Creating ${sanitize(connection.type)} provider for "${sanitize(connection.name || "")}"`);
|
|
95
|
+
switch (connection.type) {
|
|
96
|
+
// SQL Databases - dynamically imported to reduce memory
|
|
97
|
+
case "postgres": {
|
|
98
|
+
const { PostgresProvider } = await import('./postgres-O5KOQUVP.mjs');
|
|
99
|
+
return new PostgresProvider(connection, options);
|
|
100
|
+
}
|
|
101
|
+
case "mysql": {
|
|
102
|
+
const { MySQLProvider } = await import('./mysql-I3WJQXN2.mjs');
|
|
103
|
+
return new MySQLProvider(connection, options);
|
|
104
|
+
}
|
|
105
|
+
case "sqlite": {
|
|
106
|
+
const { SQLiteProvider } = await import('./sqlite-OA4YJX5S.mjs');
|
|
107
|
+
return new SQLiteProvider(connection, options);
|
|
108
|
+
}
|
|
109
|
+
case "oracle": {
|
|
110
|
+
const { OracleProvider } = await import('./oracle-P2G7T4P4.mjs');
|
|
111
|
+
return new OracleProvider(connection, options);
|
|
112
|
+
}
|
|
113
|
+
case "mssql": {
|
|
114
|
+
const { MSSQLProvider } = await import('./mssql-ZH5VP2C5.mjs');
|
|
115
|
+
return new MSSQLProvider(connection, options);
|
|
116
|
+
}
|
|
117
|
+
// Document Databases - dynamically imported
|
|
118
|
+
case "mongodb": {
|
|
119
|
+
const { MongoDBProvider } = await import('./mongodb-XMZEZA4A.mjs');
|
|
120
|
+
return new MongoDBProvider(connection, options);
|
|
121
|
+
}
|
|
122
|
+
// Key-Value Stores - dynamically imported
|
|
123
|
+
case "redis": {
|
|
124
|
+
const { RedisProvider } = await import('./redis-4WMQOVLX.mjs');
|
|
125
|
+
return new RedisProvider(connection, options);
|
|
126
|
+
}
|
|
127
|
+
default:
|
|
128
|
+
throw new DatabaseConfigError(
|
|
129
|
+
`Unknown database type: ${connection.type}. Supported types: postgres, mysql, sqlite, oracle, mssql, mongodb, redis`,
|
|
130
|
+
connection.type
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
var providerCache = /* @__PURE__ */ new Map();
|
|
135
|
+
var IDLE_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
136
|
+
var SWEEP_INTERVAL_MS = 5 * 60 * 1e3;
|
|
137
|
+
var sweepTimer = null;
|
|
138
|
+
async function evictIdleProviders(maxIdleMs = IDLE_TIMEOUT_MS) {
|
|
139
|
+
const now = Date.now();
|
|
140
|
+
let evicted = 0;
|
|
141
|
+
for (const [id, entry] of providerCache) {
|
|
142
|
+
if (now - entry.lastUsed >= maxIdleMs) {
|
|
143
|
+
logger.info(`[DB] Evicting idle provider: ${id} (idle ${Math.round((now - entry.lastUsed) / 6e4)}min)`);
|
|
144
|
+
try {
|
|
145
|
+
await entry.provider.disconnect();
|
|
146
|
+
} catch (error) {
|
|
147
|
+
logger.warn(`[DB] Error disconnecting idle provider ${id}`, { connectionId: id, error: String(error) });
|
|
148
|
+
}
|
|
149
|
+
providerCache.delete(id);
|
|
150
|
+
try {
|
|
151
|
+
await closeSSHTunnel(id);
|
|
152
|
+
} catch (e) {
|
|
153
|
+
}
|
|
154
|
+
evicted++;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (providerCache.size === 0 && sweepTimer) {
|
|
158
|
+
clearInterval(sweepTimer);
|
|
159
|
+
sweepTimer = null;
|
|
160
|
+
}
|
|
161
|
+
return evicted;
|
|
162
|
+
}
|
|
163
|
+
function startIdleSweep() {
|
|
164
|
+
if (sweepTimer) return;
|
|
165
|
+
sweepTimer = setInterval(() => {
|
|
166
|
+
evictIdleProviders();
|
|
167
|
+
}, SWEEP_INTERVAL_MS);
|
|
168
|
+
if (sweepTimer && typeof sweepTimer === "object" && "unref" in sweepTimer) {
|
|
169
|
+
sweepTimer.unref();
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
async function getOrCreateProvider(connection, options = {}) {
|
|
173
|
+
var _a;
|
|
174
|
+
const cacheKey = connection.id;
|
|
175
|
+
const cached = providerCache.get(cacheKey);
|
|
176
|
+
if (cached == null ? void 0 : cached.provider.isConnected()) {
|
|
177
|
+
cached.lastUsed = Date.now();
|
|
178
|
+
return cached.provider;
|
|
179
|
+
}
|
|
180
|
+
let effectiveConnection = connection;
|
|
181
|
+
let tunnel = null;
|
|
182
|
+
if (((_a = connection.sshTunnel) == null ? void 0 : _a.enabled) && connection.host && connection.port) {
|
|
183
|
+
tunnel = await createSSHTunnel(
|
|
184
|
+
connection.id,
|
|
185
|
+
connection.sshTunnel,
|
|
186
|
+
connection.host,
|
|
187
|
+
connection.port
|
|
188
|
+
);
|
|
189
|
+
effectiveConnection = __spreadProps(__spreadValues({}, connection), {
|
|
190
|
+
host: tunnel.localHost,
|
|
191
|
+
port: tunnel.localPort
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
const provider = await createDatabaseProvider(effectiveConnection, options);
|
|
195
|
+
try {
|
|
196
|
+
await provider.connect();
|
|
197
|
+
} catch (error) {
|
|
198
|
+
if (tunnel) {
|
|
199
|
+
await tunnel.close().catch(() => {
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
throw error;
|
|
203
|
+
}
|
|
204
|
+
providerCache.set(cacheKey, { provider, lastUsed: Date.now() });
|
|
205
|
+
startIdleSweep();
|
|
206
|
+
return provider;
|
|
207
|
+
}
|
|
208
|
+
async function removeProvider(connectionId) {
|
|
209
|
+
const cached = providerCache.get(connectionId);
|
|
210
|
+
if (cached) {
|
|
211
|
+
try {
|
|
212
|
+
await cached.provider.disconnect();
|
|
213
|
+
} catch (error) {
|
|
214
|
+
logger.warn(`Error disconnecting provider ${connectionId}`, { connectionId, error: String(error) });
|
|
215
|
+
}
|
|
216
|
+
providerCache.delete(connectionId);
|
|
217
|
+
}
|
|
218
|
+
try {
|
|
219
|
+
await closeSSHTunnel(connectionId);
|
|
220
|
+
} catch (error) {
|
|
221
|
+
logger.warn(`Error closing SSH tunnel for ${connectionId}`, { connectionId, error: String(error) });
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
async function clearProviderCache() {
|
|
225
|
+
if (sweepTimer) {
|
|
226
|
+
clearInterval(sweepTimer);
|
|
227
|
+
sweepTimer = null;
|
|
228
|
+
}
|
|
229
|
+
const disconnectPromises = [];
|
|
230
|
+
for (const [id, entry] of providerCache) {
|
|
231
|
+
disconnectPromises.push(
|
|
232
|
+
entry.provider.disconnect().catch((error) => {
|
|
233
|
+
console.error(`[DB] Error disconnecting provider ${id}:`, error);
|
|
234
|
+
})
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
await Promise.all(disconnectPromises);
|
|
238
|
+
providerCache.clear();
|
|
239
|
+
}
|
|
240
|
+
function getProviderCacheStats() {
|
|
241
|
+
return {
|
|
242
|
+
size: providerCache.size,
|
|
243
|
+
connections: Array.from(providerCache.keys())
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
var shutdownRegistered = false;
|
|
247
|
+
function registerShutdownHandlers() {
|
|
248
|
+
if (shutdownRegistered) return;
|
|
249
|
+
shutdownRegistered = true;
|
|
250
|
+
const shutdown = async (signal) => {
|
|
251
|
+
logger.info(`[DB] Received ${signal}, closing all database connections...`);
|
|
252
|
+
try {
|
|
253
|
+
await clearProviderCache();
|
|
254
|
+
logger.info("[DB] All database connections closed gracefully");
|
|
255
|
+
} catch (error) {
|
|
256
|
+
logger.error("[DB] Error during graceful shutdown", { error: String(error) });
|
|
257
|
+
}
|
|
258
|
+
process.exit(0);
|
|
259
|
+
};
|
|
260
|
+
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
261
|
+
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
262
|
+
}
|
|
263
|
+
if (typeof process !== "undefined" && process.env.NODE_ENV !== "test") {
|
|
264
|
+
registerShutdownHandlers();
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// src/lib/llm/factory.ts
|
|
268
|
+
async function createLLMProvider(config) {
|
|
269
|
+
const resolvedConfig = resolveConfig(config);
|
|
270
|
+
const safeConfig = getSafeConfigForLogging(resolvedConfig);
|
|
271
|
+
console.log(`[LLM] Creating provider:`, safeConfig);
|
|
272
|
+
try {
|
|
273
|
+
switch (resolvedConfig.provider) {
|
|
274
|
+
case "gemini": {
|
|
275
|
+
const { GeminiProvider } = await import('./gemini-C5RBLQEJ.mjs');
|
|
276
|
+
return new GeminiProvider(resolvedConfig);
|
|
277
|
+
}
|
|
278
|
+
case "openai": {
|
|
279
|
+
const { OpenAIProvider } = await import('./openai-4U56KPG7.mjs');
|
|
280
|
+
return new OpenAIProvider(resolvedConfig);
|
|
281
|
+
}
|
|
282
|
+
case "ollama": {
|
|
283
|
+
const { OllamaProvider } = await import('./ollama-26BYLVEV.mjs');
|
|
284
|
+
return new OllamaProvider(resolvedConfig);
|
|
285
|
+
}
|
|
286
|
+
case "custom": {
|
|
287
|
+
const { CustomProvider } = await import('./custom-S2EKFMP3.mjs');
|
|
288
|
+
return new CustomProvider(resolvedConfig);
|
|
289
|
+
}
|
|
290
|
+
default:
|
|
291
|
+
throw new LLMConfigError(
|
|
292
|
+
`Unknown provider: ${resolvedConfig.provider}. Valid options: gemini, openai, ollama, custom`,
|
|
293
|
+
resolvedConfig.provider
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
} catch (error) {
|
|
297
|
+
if (error instanceof LLMConfigError) {
|
|
298
|
+
throw error;
|
|
299
|
+
}
|
|
300
|
+
throw new LLMConfigError(
|
|
301
|
+
`Failed to load ${resolvedConfig.provider} provider: ${error instanceof Error ? error.message : String(error)}`,
|
|
302
|
+
resolvedConfig.provider
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
var defaultProvider = null;
|
|
307
|
+
async function getDefaultProvider() {
|
|
308
|
+
if (!defaultProvider) {
|
|
309
|
+
defaultProvider = await createLLMProvider();
|
|
310
|
+
}
|
|
311
|
+
return defaultProvider;
|
|
312
|
+
}
|
|
313
|
+
function resetDefaultProvider() {
|
|
314
|
+
defaultProvider = null;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
export { clearProviderCache, createDatabaseProvider, createLLMProvider, getDefaultProvider, getOrCreateProvider, getProviderCacheStats, removeProvider, resetDefaultProvider };
|
|
318
|
+
//# sourceMappingURL=chunk-34YQUUCM.mjs.map
|
|
319
|
+
//# sourceMappingURL=chunk-34YQUUCM.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/ssh/tunnel.ts","../src/lib/db/factory.ts","../src/lib/llm/factory.ts"],"names":[],"mappings":"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","file":"chunk-34YQUUCM.mjs","sourcesContent":["/**\n * SSH Tunnel Manager\n * Creates SSH tunnels for database connections behind firewalls/bastion hosts.\n * Uses ssh2 library for tunnel creation.\n */\n\nimport { Client } from 'ssh2';\nimport net from 'net';\nimport type { SSHTunnelConfig } from '@/lib/types';\nimport { logger } from '@/lib/logger';\n\nexport interface TunnelInfo {\n localHost: string;\n localPort: number;\n close: () => Promise<void>;\n}\n\n// Cache active tunnels by connection ID\nconst activeTunnels = new Map<string, TunnelInfo>();\n\n/**\n * Create an SSH tunnel for a database connection.\n * Returns the local host/port to connect the database client to.\n */\nexport async function createSSHTunnel(\n connectionId: string,\n sshConfig: SSHTunnelConfig,\n remoteHost: string,\n remotePort: number\n): Promise<TunnelInfo> {\n // Return existing tunnel if already active\n // Note: cached tunnel may be stale if the SSH connection dropped silently.\n // Callers should handle connection errors and call closeSSHTunnel() to evict stale entries.\n const existing = activeTunnels.get(connectionId);\n if (existing) {\n return existing;\n }\n\n return new Promise((resolve, reject) => {\n const sshClient = new Client();\n let localServer: net.Server | null = null;\n\n const cleanup = async () => {\n activeTunnels.delete(connectionId);\n if (localServer) {\n localServer.close();\n localServer = null;\n }\n sshClient.end();\n };\n\n sshClient.on('ready', () => {\n // Create a local TCP server that forwards to the remote host through SSH\n localServer = net.createServer((socket) => {\n sshClient.forwardOut(\n '127.0.0.1',\n 0,\n remoteHost,\n remotePort,\n (err, stream) => {\n if (err) {\n socket.end();\n return;\n }\n // Prevent unhandled stream errors from crashing the process\n stream.on('error', () => { socket.destroy(); });\n socket.on('error', () => { stream.close(); });\n socket.pipe(stream).pipe(socket);\n }\n );\n });\n\n // Attach error handler before listen to catch bind/listen errors\n localServer.on('error', (err) => {\n cleanup();\n reject(new Error(`SSH tunnel local server error: ${err.message}`));\n });\n\n // Listen on a random available port\n localServer.listen(0, '127.0.0.1', () => {\n const address = localServer!.address() as net.AddressInfo;\n const tunnelInfo: TunnelInfo = {\n localHost: '127.0.0.1',\n localPort: address.port,\n close: cleanup,\n };\n activeTunnels.set(connectionId, tunnelInfo);\n logger.info(`Tunnel created for ${connectionId}: 127.0.0.1:${address.port} -> ${remoteHost}:${remotePort}`, { connectionId });\n resolve(tunnelInfo);\n });\n });\n\n sshClient.on('error', (err) => {\n // Ensure SSH file descriptors are released before rejecting\n sshClient.end();\n cleanup();\n reject(new Error(`SSH connection error: ${err.message}`));\n });\n\n // Build SSH connection options\n const connectOptions: Parameters<Client['connect']>[0] = {\n host: sshConfig.host,\n port: sshConfig.port || 22,\n username: sshConfig.username,\n };\n\n if (sshConfig.authMethod === 'password') {\n connectOptions.password = sshConfig.password;\n } else if (sshConfig.authMethod === 'privateKey') {\n connectOptions.privateKey = sshConfig.privateKey;\n if (sshConfig.passphrase) {\n connectOptions.passphrase = sshConfig.passphrase;\n }\n }\n\n sshClient.connect(connectOptions);\n });\n}\n\n/**\n * Close an SSH tunnel by connection ID\n */\nexport async function closeSSHTunnel(connectionId: string): Promise<void> {\n const tunnel = activeTunnels.get(connectionId);\n if (tunnel) {\n await tunnel.close();\n }\n}\n\n/**\n * Check if a tunnel exists for a connection\n */\nexport function hasTunnel(connectionId: string): boolean {\n return activeTunnels.has(connectionId);\n}\n\n/**\n * Get tunnel info for a connection\n */\nexport function getTunnelInfo(connectionId: string): TunnelInfo | undefined {\n return activeTunnels.get(connectionId);\n}\n","/**\n * Database Provider Factory\n * Creates appropriate provider instance based on connection type\n * Uses dynamic imports to reduce memory footprint - providers are loaded on demand\n */\n\nimport {\n type DatabaseProvider,\n type DatabaseConnection,\n type ProviderOptions,\n} from './types';\nimport { DatabaseConfigError } from './errors';\nimport { createSSHTunnel, closeSSHTunnel } from '@/lib/ssh/tunnel';\nimport { logger } from '@/lib/logger';\n\n// ============================================================================\n// Provider Factory\n// ============================================================================\n\n/**\n * Create a database provider based on connection configuration\n * Uses dynamic imports to load providers on-demand, reducing initial memory usage\n *\n * @param connection - Database connection configuration\n * @param options - Optional provider options (pooling, timeout, etc.)\n * @returns Promise<DatabaseProvider> instance\n * @throws DatabaseConfigError if connection type is not supported\n *\n * @example\n * // SQL Database\n * const provider = await createDatabaseProvider({\n * id: '1',\n * name: 'My PostgreSQL',\n * type: 'postgres',\n * host: 'localhost',\n * port: 5432,\n * database: 'mydb',\n * user: 'admin',\n * password: 'secret',\n * createdAt: new Date(),\n * });\n *\n * // MongoDB\n * const mongoProvider = await createDatabaseProvider({\n * id: '2',\n * name: 'My MongoDB',\n * type: 'mongodb',\n * connectionString: 'mongodb://localhost:27017/mydb',\n * createdAt: new Date(),\n * });\n *\n * await provider.connect();\n * const result = await provider.query('SELECT * FROM users');\n * await provider.disconnect();\n */\nexport async function createDatabaseProvider(\n connection: DatabaseConnection,\n options: ProviderOptions = {}\n): Promise<DatabaseProvider> {\n // Sanitize user-controlled values to prevent log injection\n const sanitize = (v: string) => v.replace(/[\\r\\n]/g, ' ').replace(/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f]/g, '');\n console.log(`[DB] Creating ${sanitize(connection.type)} provider for \"${sanitize(connection.name || '')}\"`);\n\n switch (connection.type) {\n // SQL Databases - dynamically imported to reduce memory\n case 'postgres': {\n const { PostgresProvider } = await import('./providers/sql/postgres');\n return new PostgresProvider(connection, options);\n }\n\n case 'mysql': {\n const { MySQLProvider } = await import('./providers/sql/mysql');\n return new MySQLProvider(connection, options);\n }\n\n case 'sqlite': {\n const { SQLiteProvider } = await import('./providers/sql/sqlite');\n return new SQLiteProvider(connection, options);\n }\n\n case 'oracle': {\n const { OracleProvider } = await import('./providers/sql/oracle');\n return new OracleProvider(connection, options);\n }\n\n case 'mssql': {\n const { MSSQLProvider } = await import('./providers/sql/mssql');\n return new MSSQLProvider(connection, options);\n }\n\n // Document Databases - dynamically imported\n case 'mongodb': {\n const { MongoDBProvider } = await import('./providers/document/mongodb');\n return new MongoDBProvider(connection, options);\n }\n\n // Key-Value Stores - dynamically imported\n case 'redis': {\n const { RedisProvider } = await import('./providers/keyvalue/redis');\n return new RedisProvider(connection, options);\n }\n\n default:\n throw new DatabaseConfigError(\n `Unknown database type: ${connection.type}. Supported types: postgres, mysql, sqlite, oracle, mssql, mongodb, redis`,\n connection.type\n );\n }\n}\n\n// ============================================================================\n// Provider Cache (for connection reuse)\n// ============================================================================\n\ninterface CachedProvider {\n provider: DatabaseProvider;\n lastUsed: number;\n}\n\nconst providerCache = new Map<string, CachedProvider>();\n\n/** Idle timeout: evict providers unused for 30 minutes */\nconst IDLE_TIMEOUT_MS = 30 * 60 * 1000;\n/** Sweep interval: check for idle providers every 5 minutes */\nconst SWEEP_INTERVAL_MS = 5 * 60 * 1000;\n\nlet sweepTimer: ReturnType<typeof setInterval> | null = null;\n\n/**\n * Evict providers that have been idle longer than maxIdleMs.\n * Called by the periodic sweep timer, but also exported for direct testing.\n *\n * @returns number of evicted providers\n */\nexport async function evictIdleProviders(maxIdleMs: number = IDLE_TIMEOUT_MS): Promise<number> {\n const now = Date.now();\n let evicted = 0;\n\n for (const [id, entry] of providerCache) {\n if (now - entry.lastUsed >= maxIdleMs) {\n logger.info(`[DB] Evicting idle provider: ${id} (idle ${Math.round((now - entry.lastUsed) / 60000)}min)`);\n try {\n await entry.provider.disconnect();\n } catch (error) {\n logger.warn(`[DB] Error disconnecting idle provider ${id}`, { connectionId: id, error: String(error) });\n }\n providerCache.delete(id);\n // Also close SSH tunnel\n try {\n await closeSSHTunnel(id);\n } catch { /* ignore */ }\n evicted++;\n }\n }\n\n // Stop sweeping if cache is empty\n if (providerCache.size === 0 && sweepTimer) {\n clearInterval(sweepTimer);\n sweepTimer = null;\n }\n\n return evicted;\n}\n\nfunction startIdleSweep(): void {\n if (sweepTimer) return;\n sweepTimer = setInterval(() => { evictIdleProviders(); }, SWEEP_INTERVAL_MS);\n // Allow process to exit even if timer is running\n if (sweepTimer && typeof sweepTimer === 'object' && 'unref' in sweepTimer) {\n sweepTimer.unref();\n }\n}\n\n/**\n * Get or create a database provider with caching\n * Useful for API routes to reuse connections\n *\n * @param connection - Database connection configuration\n * @param options - Optional provider options\n * @returns Cached or new DatabaseProvider instance\n */\nexport async function getOrCreateProvider(\n connection: DatabaseConnection,\n options: ProviderOptions = {}\n): Promise<DatabaseProvider> {\n const cacheKey = connection.id;\n\n // Check cache\n const cached = providerCache.get(cacheKey);\n\n if (cached?.provider.isConnected()) {\n cached.lastUsed = Date.now();\n return cached.provider;\n }\n\n // If SSH tunnel is configured, create tunnel first and rewrite connection\n let effectiveConnection = connection;\n let tunnel: Awaited<ReturnType<typeof createSSHTunnel>> | null = null;\n if (connection.sshTunnel?.enabled && connection.host && connection.port) {\n tunnel = await createSSHTunnel(\n connection.id,\n connection.sshTunnel,\n connection.host,\n connection.port\n );\n // Rewrite connection to point to local tunnel endpoint\n effectiveConnection = {\n ...connection,\n host: tunnel.localHost,\n port: tunnel.localPort,\n };\n }\n\n // Create new provider (async - dynamically loads the provider module)\n const provider = await createDatabaseProvider(effectiveConnection, options);\n try {\n await provider.connect();\n } catch (error) {\n // Clean up SSH tunnel if provider connect fails to prevent FD leak\n if (tunnel) {\n await tunnel.close().catch(() => {});\n }\n throw error;\n }\n\n // Cache it\n providerCache.set(cacheKey, { provider, lastUsed: Date.now() });\n\n // Start idle sweep if not already running\n startIdleSweep();\n\n return provider;\n}\n\n/**\n * Remove a provider from cache and disconnect\n */\nexport async function removeProvider(connectionId: string): Promise<void> {\n const cached = providerCache.get(connectionId);\n\n if (cached) {\n try {\n await cached.provider.disconnect();\n } catch (error) {\n logger.warn(`Error disconnecting provider ${connectionId}`, { connectionId, error: String(error) });\n }\n providerCache.delete(connectionId);\n }\n\n // Close SSH tunnel if exists\n try {\n await closeSSHTunnel(connectionId);\n } catch (error) {\n logger.warn(`Error closing SSH tunnel for ${connectionId}`, { connectionId, error: String(error) });\n }\n}\n\n/**\n * Clear all cached providers\n */\nexport async function clearProviderCache(): Promise<void> {\n // Stop idle sweep\n if (sweepTimer) {\n clearInterval(sweepTimer);\n sweepTimer = null;\n }\n\n const disconnectPromises: Promise<void>[] = [];\n\n for (const [id, entry] of providerCache) {\n disconnectPromises.push(\n entry.provider.disconnect().catch((error) => {\n console.error(`[DB] Error disconnecting provider ${id}:`, error);\n })\n );\n }\n\n await Promise.all(disconnectPromises);\n providerCache.clear();\n}\n\n/**\n * Get cache statistics\n */\nexport function getProviderCacheStats(): { size: number; connections: string[] } {\n return {\n size: providerCache.size,\n connections: Array.from(providerCache.keys()),\n };\n}\n\n// ============================================================================\n// Graceful Shutdown\n// ============================================================================\n\nlet shutdownRegistered = false;\n\n/**\n * Register process signal handlers for graceful shutdown.\n * Safe to call multiple times — handlers are only registered once.\n */\nexport function registerShutdownHandlers(): void {\n if (shutdownRegistered) return;\n shutdownRegistered = true;\n\n const shutdown = async (signal: string) => {\n logger.info(`[DB] Received ${signal}, closing all database connections...`);\n try {\n await clearProviderCache();\n logger.info('[DB] All database connections closed gracefully');\n } catch (error) {\n logger.error('[DB] Error during graceful shutdown', { error: String(error) });\n }\n process.exit(0);\n };\n\n process.on('SIGTERM', () => shutdown('SIGTERM'));\n process.on('SIGINT', () => shutdown('SIGINT'));\n}\n\n// Auto-register on server-side (not during tests)\nif (typeof process !== 'undefined' && process.env.NODE_ENV !== 'test') {\n registerShutdownHandlers();\n}\n","/**\n * LLM Provider Factory\n * Creates appropriate provider instance based on configuration\n * Uses dynamic imports to reduce memory footprint - providers are loaded on demand\n */\n\nimport { type LLMConfig, type LLMProvider, LLMConfigError } from './types';\nimport { resolveConfig, getSafeConfigForLogging } from './utils/config';\n\n// ============================================================================\n// Provider Factory\n// ============================================================================\n\n/**\n * Create an LLM provider based on configuration\n * Uses dynamic imports to load providers on-demand, reducing initial memory usage\n *\n * @param config - Optional configuration overrides. If not provided,\n * configuration is resolved from environment variables.\n * @returns Promise<LLMProvider> instance\n * @throws LLMConfigError if configuration is invalid\n *\n * @example\n * // Use environment configuration\n * const provider = await createLLMProvider();\n *\n * @example\n * // Override specific settings\n * const provider = await createLLMProvider({\n * provider: 'openai',\n * model: 'gpt-4-turbo',\n * });\n */\nexport async function createLLMProvider(config?: Partial<LLMConfig>): Promise<LLMProvider> {\n const resolvedConfig = resolveConfig(config);\n\n // Log configuration (safely)\n const safeConfig = getSafeConfigForLogging(resolvedConfig);\n console.log(`[LLM] Creating provider:`, safeConfig);\n\n try {\n switch (resolvedConfig.provider) {\n case 'gemini': {\n const { GeminiProvider } = await import('./providers/gemini');\n return new GeminiProvider(resolvedConfig);\n }\n\n case 'openai': {\n const { OpenAIProvider } = await import('./providers/openai');\n return new OpenAIProvider(resolvedConfig);\n }\n\n case 'ollama': {\n const { OllamaProvider } = await import('./providers/ollama');\n return new OllamaProvider(resolvedConfig);\n }\n\n case 'custom': {\n const { CustomProvider } = await import('./providers/custom');\n return new CustomProvider(resolvedConfig);\n }\n\n default:\n throw new LLMConfigError(\n `Unknown provider: ${resolvedConfig.provider}. Valid options: gemini, openai, ollama, custom`,\n resolvedConfig.provider\n );\n }\n } catch (error) {\n if (error instanceof LLMConfigError) {\n throw error;\n }\n throw new LLMConfigError(\n `Failed to load ${resolvedConfig.provider} provider: ${error instanceof Error ? error.message : String(error)}`,\n resolvedConfig.provider\n );\n }\n}\n\n// ============================================================================\n// Singleton Instance (Optional)\n// ============================================================================\n\nlet defaultProvider: LLMProvider | null = null;\n\n/**\n * Get the default LLM provider instance (singleton)\n * Creates a new instance if one doesn't exist\n */\nexport async function getDefaultProvider(): Promise<LLMProvider> {\n if (!defaultProvider) {\n defaultProvider = await createLLMProvider();\n }\n return defaultProvider;\n}\n\n/**\n * Reset the default provider (useful for testing or config changes)\n */\nexport function resetDefaultProvider(): void {\n defaultProvider = null;\n}\n"]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
+
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : /* @__PURE__ */ Symbol.for("Symbol." + name);
|
|
8
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
9
|
+
var __spreadValues = (a, b) => {
|
|
10
|
+
for (var prop in b || (b = {}))
|
|
11
|
+
if (__hasOwnProp.call(b, prop))
|
|
12
|
+
__defNormalProp(a, prop, b[prop]);
|
|
13
|
+
if (__getOwnPropSymbols)
|
|
14
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
15
|
+
if (__propIsEnum.call(b, prop))
|
|
16
|
+
__defNormalProp(a, prop, b[prop]);
|
|
17
|
+
}
|
|
18
|
+
return a;
|
|
19
|
+
};
|
|
20
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
21
|
+
var __objRest = (source, exclude) => {
|
|
22
|
+
var target = {};
|
|
23
|
+
for (var prop in source)
|
|
24
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
25
|
+
target[prop] = source[prop];
|
|
26
|
+
if (source != null && __getOwnPropSymbols)
|
|
27
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
28
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
29
|
+
target[prop] = source[prop];
|
|
30
|
+
}
|
|
31
|
+
return target;
|
|
32
|
+
};
|
|
33
|
+
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);
|
|
34
|
+
|
|
35
|
+
export { __forAwait, __objRest, __spreadProps, __spreadValues };
|
|
36
|
+
//# sourceMappingURL=chunk-4LVB3K53.mjs.map
|
|
37
|
+
//# sourceMappingURL=chunk-4LVB3K53.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-4LVB3K53.mjs"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// src/lib/logger.ts
|
|
2
|
+
var LEVEL_ORDER = {
|
|
3
|
+
debug: 0,
|
|
4
|
+
info: 1,
|
|
5
|
+
warn: 2,
|
|
6
|
+
error: 3
|
|
7
|
+
};
|
|
8
|
+
function getMinLevel() {
|
|
9
|
+
var _a, _b;
|
|
10
|
+
if (typeof process !== "undefined" && ((_a = process.env) == null ? void 0 : _a.LOG_LEVEL)) {
|
|
11
|
+
const env = process.env.LOG_LEVEL.toLowerCase();
|
|
12
|
+
if (env in LEVEL_ORDER) return env;
|
|
13
|
+
}
|
|
14
|
+
const isDev = typeof process !== "undefined" && ((_b = process.env) == null ? void 0 : _b.NODE_ENV) !== "production";
|
|
15
|
+
return isDev ? "debug" : "info";
|
|
16
|
+
}
|
|
17
|
+
function shouldLog(level) {
|
|
18
|
+
return LEVEL_ORDER[level] >= LEVEL_ORDER[getMinLevel()];
|
|
19
|
+
}
|
|
20
|
+
function formatContext(ctx) {
|
|
21
|
+
if (!ctx) return "";
|
|
22
|
+
const parts = [];
|
|
23
|
+
if (ctx.route) parts.push(`route=${ctx.route}`);
|
|
24
|
+
if (ctx.provider) parts.push(`provider=${ctx.provider}`);
|
|
25
|
+
if (ctx.connectionId) parts.push(`connId=${ctx.connectionId}`);
|
|
26
|
+
if (ctx.duration !== void 0) parts.push(`duration=${ctx.duration}ms`);
|
|
27
|
+
for (const [k, v] of Object.entries(ctx)) {
|
|
28
|
+
if (["route", "provider", "connectionId", "duration"].includes(k)) continue;
|
|
29
|
+
if (v !== void 0) parts.push(`${k}=${typeof v === "object" ? JSON.stringify(v) : v}`);
|
|
30
|
+
}
|
|
31
|
+
return parts.length ? ` {${parts.join(", ")}}` : "";
|
|
32
|
+
}
|
|
33
|
+
function extractError(error) {
|
|
34
|
+
var _a;
|
|
35
|
+
if (!error) return void 0;
|
|
36
|
+
if (error instanceof Error) {
|
|
37
|
+
const isDev = typeof process !== "undefined" && ((_a = process.env) == null ? void 0 : _a.NODE_ENV) !== "production";
|
|
38
|
+
return {
|
|
39
|
+
name: error.name,
|
|
40
|
+
message: error.message,
|
|
41
|
+
stack: isDev ? error.stack : void 0
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return { name: "Unknown", message: String(error) };
|
|
45
|
+
}
|
|
46
|
+
function sanitizeLogValue(value) {
|
|
47
|
+
return value.replace(/[\r\n]/g, " ").replace(/[\x00-\x08\x0b\x0c\x0e-\x1f]/g, "");
|
|
48
|
+
}
|
|
49
|
+
function log(level, message, error, context) {
|
|
50
|
+
if (!shouldLog(level)) return;
|
|
51
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
52
|
+
const tag = level.toUpperCase().padEnd(5);
|
|
53
|
+
const ctx = formatContext(context);
|
|
54
|
+
const errInfo = level === "error" ? extractError(error) : void 0;
|
|
55
|
+
const line = `[${tag}] [${timestamp}]${sanitizeLogValue(ctx)} ${sanitizeLogValue(message)}`;
|
|
56
|
+
if (errInfo) {
|
|
57
|
+
const errLine = ` | ${sanitizeLogValue(errInfo.name)}: ${sanitizeLogValue(errInfo.message)}`;
|
|
58
|
+
const full = line + errLine;
|
|
59
|
+
if (errInfo.stack) {
|
|
60
|
+
const safeStack = errInfo.stack.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f]/g, "");
|
|
61
|
+
console.error(full, "\n", safeStack);
|
|
62
|
+
} else {
|
|
63
|
+
console.error(full);
|
|
64
|
+
}
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const safeLine = line;
|
|
68
|
+
switch (level) {
|
|
69
|
+
case "debug":
|
|
70
|
+
console.debug(safeLine);
|
|
71
|
+
break;
|
|
72
|
+
case "info":
|
|
73
|
+
console.info(safeLine);
|
|
74
|
+
break;
|
|
75
|
+
case "warn":
|
|
76
|
+
console.warn(safeLine);
|
|
77
|
+
break;
|
|
78
|
+
case "error":
|
|
79
|
+
console.error(safeLine);
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
var logger = {
|
|
84
|
+
debug(message, context) {
|
|
85
|
+
log("debug", message, void 0, context);
|
|
86
|
+
},
|
|
87
|
+
info(message, context) {
|
|
88
|
+
log("info", message, void 0, context);
|
|
89
|
+
},
|
|
90
|
+
warn(message, context) {
|
|
91
|
+
log("warn", message, void 0, context);
|
|
92
|
+
},
|
|
93
|
+
error(message, error, context) {
|
|
94
|
+
log("error", message, error, context);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export { logger };
|
|
99
|
+
//# sourceMappingURL=chunk-6DRZXXNT.mjs.map
|
|
100
|
+
//# sourceMappingURL=chunk-6DRZXXNT.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/logger.ts"],"names":[],"mappings":"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","file":"chunk-6DRZXXNT.mjs","sourcesContent":["/**\n * Structured Logger\n * Isomorphic logger with level filtering and context support\n */\n\ntype LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nexport interface LogContext {\n route?: string;\n provider?: string;\n connectionId?: string;\n duration?: number;\n [key: string]: unknown;\n}\n\nconst LEVEL_ORDER: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\nfunction getMinLevel(): LogLevel {\n if (typeof process !== 'undefined' && process.env?.LOG_LEVEL) {\n const env = process.env.LOG_LEVEL.toLowerCase();\n if (env in LEVEL_ORDER) return env as LogLevel;\n }\n const isDev =\n typeof process !== 'undefined' &&\n process.env?.NODE_ENV !== 'production';\n return isDev ? 'debug' : 'info';\n}\n\nfunction shouldLog(level: LogLevel): boolean {\n return LEVEL_ORDER[level] >= LEVEL_ORDER[getMinLevel()];\n}\n\nfunction formatContext(ctx?: LogContext): string {\n if (!ctx) return '';\n const parts: string[] = [];\n if (ctx.route) parts.push(`route=${ctx.route}`);\n if (ctx.provider) parts.push(`provider=${ctx.provider}`);\n if (ctx.connectionId) parts.push(`connId=${ctx.connectionId}`);\n if (ctx.duration !== undefined) parts.push(`duration=${ctx.duration}ms`);\n // Extra keys\n for (const [k, v] of Object.entries(ctx)) {\n if (['route', 'provider', 'connectionId', 'duration'].includes(k)) continue;\n if (v !== undefined) parts.push(`${k}=${typeof v === 'object' ? JSON.stringify(v) : v}`);\n }\n return parts.length ? ` {${parts.join(', ')}}` : '';\n}\n\nfunction extractError(error: unknown): { name: string; message: string; stack?: string } | undefined {\n if (!error) return undefined;\n if (error instanceof Error) {\n const isDev =\n typeof process !== 'undefined' &&\n process.env?.NODE_ENV !== 'production';\n return {\n name: error.name,\n message: error.message,\n stack: isDev ? error.stack : undefined,\n };\n }\n return { name: 'Unknown', message: String(error) };\n}\n\n/** Sanitize log message to prevent log injection (newlines, control chars) */\nfunction sanitizeLogValue(value: string): string {\n return value.replace(/[\\r\\n]/g, ' ').replace(/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f]/g, '');\n}\n\nfunction log(level: LogLevel, message: string, error?: unknown, context?: LogContext): void {\n if (!shouldLog(level)) return;\n\n const timestamp = new Date().toISOString();\n const tag = level.toUpperCase().padEnd(5);\n const ctx = formatContext(context);\n const errInfo = level === 'error' ? extractError(error) : undefined;\n\n const line = `[${tag}] [${timestamp}]${sanitizeLogValue(ctx)} ${sanitizeLogValue(message)}`;\n\n if (errInfo) {\n const errLine = ` | ${sanitizeLogValue(errInfo.name)}: ${sanitizeLogValue(errInfo.message)}`;\n const full = line + errLine;\n if (errInfo.stack) {\n // Stack traces contain intentional newlines — sanitize control chars only\n const safeStack = errInfo.stack.replace(/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f]/g, '');\n console.error(full, '\\n', safeStack);\n } else {\n console.error(full);\n }\n return;\n }\n\n // All values in `line` are already sanitized via sanitizeLogValue\n const safeLine = line;\n switch (level) {\n case 'debug':\n console.debug(safeLine);\n break;\n case 'info':\n console.info(safeLine);\n break;\n case 'warn':\n console.warn(safeLine);\n break;\n case 'error':\n console.error(safeLine);\n break;\n }\n}\n\nexport const logger = {\n debug(message: string, context?: LogContext): void {\n log('debug', message, undefined, context);\n },\n info(message: string, context?: LogContext): void {\n log('info', message, undefined, context);\n },\n warn(message: string, context?: LogContext): void {\n log('warn', message, undefined, context);\n },\n error(message: string, error?: unknown, context?: LogContext): void {\n log('error', message, error, context);\n },\n};\n"]}
|