refactor(desktop): organize lib modules by domain

This commit is contained in:
t8y2 committed 2026-07-04 13:53:52 +08:00
1 parent 90f0594e93
commit 7e7c4944e9
700 files changed
+1292 -1264

No files matched your search

+15
View File
@@ -0,0 +1,15 @@
# Desktop Library Layout
`src/lib` is organized by product/runtime domain. Keep implementation modules inside a domain folder instead of adding new files at the root.
- `backend`: Tauri, HTTP, platform, storage, and transport bridges.
- `common`: generic helpers with no DBX feature ownership.
- `app`, `tabs`, `sidebar`, `connection`: shell, navigation, and connection UI state helpers.
- `database`, `metadata`, `schema`, `table`: relational database metadata, capabilities, DDL, and table-object helpers.
- `sql`, `sql/semantic`, `editor`, `query`, `history`, `savedSql`: SQL editing, execution, diagnostics, history, and saved SQL behavior.
- `dataGrid`: result/grid rendering, editing, previews, pagination, and export helpers tied to the grid.
- `ai`, `mcp`: AI assistant and MCP configuration helpers.
- `redis`, `mongo`, `elasticsearch`, `etcd`, `kv`, `mq`, `nacos`, `zookeeper`, `webdav`: non-relational or service-specific helpers.
- `diagram`, `document`, `export`, `imports`: feature-specific utilities that are shared by more than one component.
Tests under `src/lib/__tests__` mirror the same domain folders. When moving a module, update both runtime imports and colocated tests so stale root-level aliases do not return.
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { buildSystemPrompt, type AiContext } from "@/lib/ai";
import { buildSystemPrompt, type AiContext } from "@/lib/ai/ai";
function context(overrides: Partial<AiContext> = {}): AiContext {
return {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { aiMarkdownLinkUrlFromClick, formatAiInlineMarkdown, handleAiMarkdownLinkClick, normalizeAiMarkdownLink } from "@/lib/aiMarkdown";
import { aiMarkdownLinkUrlFromClick, formatAiInlineMarkdown, handleAiMarkdownLinkClick, normalizeAiMarkdownLink } from "@/lib/ai/aiMarkdown";
describe("formatAiInlineMarkdown", () => {
it("renders http links for external browser handling", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { visibleToActualIndex } from "@/lib/aiMessageEdit";
import { visibleToActualIndex } from "@/lib/ai/aiMessageEdit";
describe("visibleToActualIndex", () => {
it("maps visible index 0 to first non-summary message", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { formatAiModelOption, shouldShowAiModelSecondaryLabel } from "@/lib/aiModelPresentation";
import { formatAiModelOption, shouldShowAiModelSecondaryLabel } from "@/lib/ai/aiModelPresentation";
describe("shouldShowAiModelSecondaryLabel", () => {
it("hides secondary text when display name only changes case", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { containsChinese, isShortAffirmative, isShortNegative, looksLikeActionProposal } from "@/lib/aiProposalDetect";
import { containsChinese, isShortAffirmative, isShortNegative, looksLikeActionProposal } from "@/lib/ai/aiProposalDetect";
describe("looksLikeActionProposal", () => {
// ---- zh-CN proposals ----
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { AI_TABLE_MENTION_CANDIDATE_LIMIT, filterAiTableMentionCandidates, formatAiTableMention, parseAiTableMentions } from "@/lib/aiTableMentions";
import { AI_TABLE_MENTION_CANDIDATE_LIMIT, filterAiTableMentionCandidates, formatAiTableMention, parseAiTableMentions } from "@/lib/ai/aiTableMentions";
describe("AI table mention parsing", () => {
it("parses plain and schema-qualified table mentions", () => {
@@ -1,6 +1,6 @@
import { describe, expect, it } from "vitest";
import { updatePinnedTreeNodeInPlace } from "@/lib/pinnedItems";
import { buildTreeNodesFromLayout } from "@/lib/sidebarLayout";
import { updatePinnedTreeNodeInPlace } from "@/lib/app/pinnedItems";
import { buildTreeNodesFromLayout } from "@/lib/sidebar/sidebarLayout";
import type { ConnectionConfig, SidebarLayout, TreeNode } from "@/types/database";
describe("sidebar pinned tree nodes", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { formatTtl } from "@/lib/ttlFormat";
import { formatTtl } from "@/lib/common/ttlFormat";
// ---------------------------------------------------------------------------
// Mock `t()` helpers — only the day unit needs localization
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { apiUrl, apiWebSocketUrl, dbxWebBasePath, webPath } from "@/lib/webPath";
import { apiUrl, apiWebSocketUrl, dbxWebBasePath, webPath } from "@/lib/common/webPath";
describe("webPath", () => {
it("keeps root deployments on root-relative API paths", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { ACCESS_AGENT_MIN_CONNECT_TIMEOUT_SECS, AGENT_DRIVER_MIN_CONNECT_TIMEOUT_SECS, connectionAttemptOriginalErrorMessage, connectionAttemptTimeoutMessage, connectionAttemptTimeoutMs, CONNECTION_ATTEMPT_TIMEOUT_BUFFER_MS } from "@/lib/connectionAttemptTimeout";
import { ACCESS_AGENT_MIN_CONNECT_TIMEOUT_SECS, AGENT_DRIVER_MIN_CONNECT_TIMEOUT_SECS, connectionAttemptOriginalErrorMessage, connectionAttemptTimeoutMessage, connectionAttemptTimeoutMs, CONNECTION_ATTEMPT_TIMEOUT_BUFFER_MS } from "@/lib/connection/connectionAttemptTimeout";
describe("connectionAttemptTimeout", () => {
it("uses a 10s default for regular database connections", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { quickConnectionOpenTarget } from "@/lib/connectionOpenTarget";
import { quickConnectionOpenTarget } from "@/lib/connection/connectionOpenTarget";
import type { ConnectionConfig } from "@/types/database";
function connection(dbType: ConnectionConfig["db_type"]): ConnectionConfig {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { parseConnectionUrl } from "../connectionUrl";
import { parseConnectionUrl } from "@/lib/connection/connectionUrl";
describe("Dremio JDBC connection URLs", () => {
it("parses legacy direct JDBC URLs into a Dremio JDBC profile", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { parseConnectionUrl } from "../connectionUrl";
import { parseConnectionUrl } from "@/lib/connection/connectionUrl";
describe("ZooKeeper connection URLs", () => {
it("preserves the host:port chroot path as a ZooKeeper connect string", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { axisColumnLabel, chartableColumnIndexes, toChartNumber } from "@/lib/chartData";
import { axisColumnLabel, chartableColumnIndexes, toChartNumber } from "@/lib/dataGrid/chartData";
import type { QueryResult } from "@/types/database";
function result(columns: string[], rows: QueryResult["rows"]): QueryResult {
@@ -1,6 +1,6 @@
import { describe, expect, test } from "vitest";
import { getDataGridConditionSuggestionPosition } from "@/lib/dataGridConditionSuggestionPosition";
import { getDataGridConditionSuggestionPosition } from "@/lib/dataGrid/dataGridConditionSuggestionPosition";
describe("getDataGridConditionSuggestionPosition", () => {
test("anchors the dropdown to the input instead of the caret", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { wktToGeoJson } from "@/lib/geometryPreview";
import { wktToGeoJson } from "@/lib/dataGrid/geometryPreview";
describe("wktToGeoJson", () => {
it("preserves polygon interior rings", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { formatSelectionAsTsv, summarizeSelection } from "@/lib/gridSelection";
import { formatSelectionAsTsv, summarizeSelection } from "@/lib/dataGrid/gridSelection";
describe("gridSelection", () => {
it("formats TSV selections without headers by default", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { CREATE_DATABASE_CHARSET_OPTIONS, createDatabaseCollationOptionsForCharset, defaultCreateDatabaseCollationForCharset, normalizeCreateDatabaseCharset, parseCreateDatabaseCharsetMetadata, nextCreateDatabaseCollation } from "@/lib/createDatabaseCharsetOptions";
import { CREATE_DATABASE_CHARSET_OPTIONS, createDatabaseCollationOptionsForCharset, defaultCreateDatabaseCollationForCharset, normalizeCreateDatabaseCharset, parseCreateDatabaseCharsetMetadata, nextCreateDatabaseCollation } from "@/lib/database/createDatabaseCharsetOptions";
describe("createDatabaseCharsetOptions", () => {
it("offers common MySQL character sets with utf8mb4 first", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { databaseRuntimeMode, usesAgentCursorForQuery } from "@/lib/databaseDriverManifest";
import { databaseRuntimeMode, usesAgentCursorForQuery } from "@/lib/database/databaseDriverManifest";
describe("databaseDriverManifest", () => {
it("uses agent cursor only for agent or external runtimes", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { supportsTransaction } from "@/lib/databaseFeatureSupport";
import { supportsTransaction } from "@/lib/database/databaseFeatureSupport";
describe("supportsTransaction", () => {
it("returns true for supported database types", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { normalizeSidebarObjectKind, sidebarObjectKindsForDatabase } from "@/lib/databaseObjectCapabilities";
import { normalizeSidebarObjectKind, sidebarObjectKindsForDatabase } from "@/lib/database/databaseObjectCapabilities";
describe("databaseObjectCapabilities", () => {
it("exposes materialized views for Dameng", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { decodeSelectableDatabaseValue, EMPTY_DATABASE_SELECT_VALUE, encodeSelectableDatabaseValue, TREE_SCHEMA_DEFAULT_DATABASE_SELECT_VALUE } from "@/lib/defaultDatabase";
import { decodeSelectableDatabaseValue, EMPTY_DATABASE_SELECT_VALUE, encodeSelectableDatabaseValue, TREE_SCHEMA_DEFAULT_DATABASE_SELECT_VALUE } from "@/lib/database/defaultDatabase";
describe("defaultDatabase selectable values", () => {
it("encodes empty tree-schema databases with the default database sentinel", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { effectiveDatabaseTypeForConnection, inferJdbcDialect } from "@/lib/jdbcDialect";
import { effectiveDatabaseTypeForConnection, inferJdbcDialect } from "@/lib/database/jdbcDialect";
describe("jdbc dialect inference", () => {
it("detects InterSystems IRIS and Caché JDBC connections", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { mysqlCleartextPasswordAuthEnabled, setMysqlCleartextPasswordAuthEnabled } from "../mysqlConnectionOptions";
import { mysqlCleartextPasswordAuthEnabled, setMysqlCleartextPasswordAuthEnabled } from "@/lib/database/mysqlConnectionOptions";
describe("mysqlConnectionOptions", () => {
it("detects cleartext password auth aliases", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { PRESTOSQL_JDBC_DRIVER_COORDINATE, prestoSqlBuiltinDriverPaths, prestoSqlBuiltinDriverRow, prestoSqlMavenBundle } from "@/lib/prestoSqlBuiltinDriver";
import { PRESTOSQL_JDBC_DRIVER_COORDINATE, prestoSqlBuiltinDriverPaths, prestoSqlBuiltinDriverRow, prestoSqlMavenBundle } from "@/lib/database/prestoSqlBuiltinDriver";
import type { JdbcMavenBundleInfo } from "@/types/database";
function bundle(coordinate: string, version = "350"): JdbcMavenBundleInfo {
@@ -1,6 +1,6 @@
import { describe, expect, it } from "vitest";
import { PostgreSQL } from "@codemirror/lang-sql";
import { postgresKeywordSyntaxTerms } from "@/lib/codemirrorSqlDialect";
import { postgresKeywordSyntaxTerms } from "@/lib/editor/codemirrorSqlDialect";
describe("codemirrorSqlDialect", () => {
it("keeps common PostgreSQL identifier names out of keyword highlighting", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { DEFAULT_SHORTCUT_SETTINGS, SHORTCUT_DEFINITIONS, findShortcutConflict, normalizeShortcutSettings, type ShortcutActionId } from "@/lib/shortcutRegistry";
import { DEFAULT_SHORTCUT_SETTINGS, SHORTCUT_DEFINITIONS, findShortcutConflict, normalizeShortcutSettings, type ShortcutActionId } from "@/lib/editor/shortcutRegistry";
describe("shortcutRegistry editor actions", () => {
const formatterEditorActionIds: ShortcutActionId[] = ["formatSql", "indentMore", "indentLess", "duplicateLine", "deleteLine", "moveLineUp", "moveLineDown", "copyLineUp", "copyLineDown", "undo", "redo", "selectAll"];
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { buildEtcdKeyTree, flattenVisibleEtcdKeyTree } from "@/lib/etcdKeyTree";
import { buildEtcdKeyTree, flattenVisibleEtcdKeyTree } from "@/lib/etcd/etcdKeyTree";
describe("etcd key tree", () => {
it("groups slash-delimited keys", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { parseNavicatConnections } from "../navicatImport";
import { parseNavicatConnections } from "@/lib/imports/navicatImport";
class TestElement {
readonly tagName: string;
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { buildKvKeyTree, collectKvGroupIds, flattenVisibleKvKeyTree, preserveKvExpandedGroupIds } from "@/lib/kvKeyTree";
import { buildKvKeyTree, collectKvGroupIds, flattenVisibleKvKeyTree, preserveKvExpandedGroupIds } from "@/lib/kv/kvKeyTree";
describe("kv key tree", () => {
it("keeps root keys as leaf nodes", () => {
@@ -1,6 +1,6 @@
import { describe, expect, it } from "vitest";
import { refreshedKvSelectionKey } from "@/lib/kvRefreshSelection";
import type { KvKeySummary } from "@/lib/api";
import { refreshedKvSelectionKey } from "@/lib/kv/kvRefreshSelection";
import type { KvKeySummary } from "@/lib/backend/api";
describe("kv refresh selection", () => {
const keys: KvKeySummary[] = [{ key: "/app/config" }, { key: "/app/feature" }];
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { kvRootNodeLabel } from "@/lib/kvRootPresentation";
import { kvRootNodeLabel } from "@/lib/kv/kvRootPresentation";
describe("kv root presentation", () => {
it("keeps etcd under Keys but shows ZooKeeper as root path", () => {
@@ -1,6 +1,6 @@
import { describe, expect, it } from "vitest";
import { formatZooKeeperMetadataRows, formatZooKeeperSummaryBadges, prettyPrintJsonText } from "@/lib/kvValueDisplay";
import type { KvKeyMetadata } from "@/lib/api";
import { formatZooKeeperMetadataRows, formatZooKeeperSummaryBadges, prettyPrintJsonText } from "@/lib/kv/kvValueDisplay";
import type { KvKeyMetadata } from "@/lib/backend/api";
describe("kv value display helpers", () => {
it("pretty prints valid JSON text", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { buildMcpCodexConfig, buildMcpJsonConfig, buildMcpOpenCodeConfig, buildMcpVsCodeConfig, type McpEnvEntry } from "@/lib/mcpConfigTemplates";
import { buildMcpCodexConfig, buildMcpJsonConfig, buildMcpOpenCodeConfig, buildMcpVsCodeConfig, type McpEnvEntry } from "@/lib/mcp/mcpConfigTemplates";
describe("MCP config templates", () => {
it("builds the standard mcpServers JSON used by Claude, Cursor, TRAE, and Windsurf", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { usesLocalOnlyEditorCompletionMetadata, usesOnDemandOnlyEditorColumnMetadata } from "@/lib/completionMetadataPolicy";
import { usesLocalOnlyEditorCompletionMetadata, usesOnDemandOnlyEditorColumnMetadata } from "@/lib/metadata/completionMetadataPolicy";
describe("completionMetadataPolicy", () => {
it("keeps Presto-like editor completion on local metadata", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { completionSchemasFromTree, completionTablesFromTree } from "@/lib/completionTreeIndex";
import { completionSchemasFromTree, completionTablesFromTree } from "@/lib/metadata/completionTreeIndex";
import type { TreeNode } from "@/types/database";
describe("completionTreeIndex", () => {
@@ -2,7 +2,7 @@ import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";
function componentSource(name: string): string {
return readFileSync(new URL(`../../components/mq/${name}`, import.meta.url), "utf8");
return readFileSync(new URL(`../../../components/mq/${name}`, import.meta.url), "utf8");
}
describe("MQ list panels", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { MQ_PINNED_VERSION_AUTO, MQ_PINNED_VERSION_OPTIONS, pinnedVersionToSelection, selectionToPinnedVersion } from "@/lib/mqPinnedVersionOptions";
import { MQ_PINNED_VERSION_AUTO, MQ_PINNED_VERSION_OPTIONS, pinnedVersionToSelection, selectionToPinnedVersion } from "@/lib/mq/mqPinnedVersionOptions";
describe("mqPinnedVersionOptions", () => {
it("offers auto-detection and the supported Pulsar 3.x profile", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { defaultMqPolicyForms, policyFormsFromEffectivePolicies } from "@/lib/mqPolicyForms";
import { defaultMqPolicyForms, policyFormsFromEffectivePolicies } from "@/lib/mq/mqPolicyForms";
describe("mqPolicyForms", () => {
it("hydrates forms from topic effective policies", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { defaultTenantConfig, mqClusterOptionsFromExtra, validateTenantForm } from "@/lib/mqTenantForm";
import { defaultTenantConfig, mqClusterOptionsFromExtra, validateTenantForm } from "@/lib/mq/mqTenantForm";
describe("mqTenantForm", () => {
it("extracts selectable cluster names from Pulsar cluster info extras", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { formatMqTokenIssueError } from "../mqTokenErrors";
import { formatMqTokenIssueError } from "@/lib/mq/mqTokenErrors";
describe("MQ token errors", () => {
it("turns missing signing configuration backend errors into actionable Chinese copy", () => {
@@ -13,7 +13,7 @@ import {
resolveNacosConfigCopyText,
sanitizeNacosConfigFileNameSegment,
summarizeNacosConfigDiff,
} from "../nacosAdmin";
} from "@/lib/nacos/nacosAdmin";
describe("nacosAdmin helpers", () => {
it("parses raw query and body text", () => {
@@ -2,7 +2,7 @@ import { describe, expect, it } from "vitest";
import type { QueryResult } from "@/types/database";
import { isNoSnapshotErrorResult } from "@/lib/queryResultError";
import { isNoSnapshotErrorResult } from "@/lib/query/queryResultError";
function errorResult(message: string): QueryResult {
return { columns: ["Error"], rows: [[message]], affected_rows: 0, execution_time_ms: 0 };
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { savedSqlFolderBranchFileCount, type SavedSqlFolderCountNode } from "../savedSqlFolderCounts";
import { savedSqlFolderBranchFileCount, type SavedSqlFolderCountNode } from "@/lib/savedSql/savedSqlFolderCounts";
describe("savedSqlFolderBranchFileCount", () => {
const folders: SavedSqlFolderCountNode[] = [{ id: "root" }, { id: "child", parentFolderId: "root" }, { id: "grandchild", parentFolderId: "child" }, { id: "sibling", parentFolderId: "root" }, { id: "other" }];
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { createConcurrencyLimiter, mapWithConcurrency, schemaDiffMetadataConcurrency } from "@/lib/schemaDiffMetadataLoad";
import { createConcurrencyLimiter, mapWithConcurrency, schemaDiffMetadataConcurrency } from "@/lib/schema/schemaDiffMetadataLoad";
function wait(ms: number) {
return new Promise<void>((resolve) => setTimeout(resolve, ms));
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { selectedConnectionDeleteTargets, selectedConnectionDuplicateTargets } from "@/lib/sidebarConnectionSelection";
import { selectedConnectionDeleteTargets, selectedConnectionDuplicateTargets } from "@/lib/sidebar/sidebarConnectionSelection";
import type { TreeNode } from "@/types/database";
function node(id: string, type: TreeNode["type"] = "connection"): TreeNode {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { shouldMeasureSidebarLabelOverflow } from "@/lib/sidebarLabelTooltip";
import { shouldMeasureSidebarLabelOverflow } from "@/lib/sidebar/sidebarLabelTooltip";
describe("shouldMeasureSidebarLabelOverflow", () => {
it("measures only plain truncated-label tooltip candidates", () => {
@@ -1,6 +1,6 @@
import { Text } from "@codemirror/state";
import { describe, expect, it, vi } from "vitest";
import { executableStatementRangeCacheForDoc, executableStatementRangeStartingAt, type ExecutableStatementRangeParser } from "@/lib/executableStatementRangeCache";
import { executableStatementRangeCacheForDoc, executableStatementRangeStartingAt, type ExecutableStatementRangeParser } from "@/lib/sql/executableStatementRangeCache";
describe("executableStatementRangeCacheForDoc", () => {
it("reuses parsed executable statement ranges for the same document and database type", () => {
@@ -1,8 +1,8 @@
import { describe, expect, it } from "vitest";
import { buildSqlCompletionItemsFromContext, getSqlCompletionContext, type SqlCompletionColumn, type SqlCompletionProviderInput } from "@/lib/sqlCompletion";
import { sqlCompletionContextFromSemantic, sqlSemanticLocalColumnsByTable } from "@/lib/sqlSemanticCompletion";
import { buildSqlSemanticModel } from "@/lib/sqlSemanticModel";
import { sqlFixtureCursor } from "@/lib/sqlSemanticFixtures";
import { buildSqlCompletionItemsFromContext, getSqlCompletionContext, type SqlCompletionColumn, type SqlCompletionProviderInput } from "@/lib/sql/sqlCompletion";
import { sqlCompletionContextFromSemantic, sqlSemanticLocalColumnsByTable } from "@/lib/sql/semantic/completion";
import { buildSqlSemanticModel } from "@/lib/sql/semantic/model";
import { sqlFixtureCursor } from "@/lib/sql/semantic/fixtures";
import type { DatabaseType } from "@/types/database";
function mergeColumns(...maps: Array<Map<string, SqlCompletionColumn[]> | undefined>): Map<string, SqlCompletionColumn[]> {
@@ -1,7 +1,7 @@
import { describe, expect, it } from "vitest";
import { sqlSemanticCompletionScope, sqlSemanticLocalColumnsByTable, sqlSemanticProjectionAliasColumns } from "@/lib/sqlSemanticCompletion";
import { SQL_SEMANTIC_BASELINE_FIXTURES, sqlFixtureCursor } from "@/lib/sqlSemanticFixtures";
import { buildSqlSemanticModel } from "@/lib/sqlSemanticModel";
import { sqlSemanticCompletionScope, sqlSemanticLocalColumnsByTable, sqlSemanticProjectionAliasColumns } from "@/lib/sql/semantic/completion";
import { SQL_SEMANTIC_BASELINE_FIXTURES, sqlFixtureCursor } from "@/lib/sql/semantic/fixtures";
import { buildSqlSemanticModel } from "@/lib/sql/semantic/model";
describe("sqlSemanticModel baseline fixtures", () => {
for (const fixture of SQL_SEMANTIC_BASELINE_FIXTURES) {
@@ -1,9 +1,9 @@
import { describe, expect, it } from "vitest";
import { buildSqlSemanticDiagnostics } from "@/lib/sqlSemanticDiagnostics";
import { buildSqlSemanticModel } from "@/lib/sqlSemanticModel";
import { sqlFixtureCursor } from "@/lib/sqlSemanticFixtures";
import { resolveSqlSemanticNavigationTarget, mergeSqlSemanticReferenceAnalysis, sqlSemanticCompletionReferenceTables, sqlSemanticTableReferences } from "@/lib/sqlSemanticReferences";
import { splitQualifiedIdentifier } from "@/lib/sqlNavigation";
import { buildSqlSemanticDiagnostics } from "@/lib/sql/semantic/diagnostics";
import { buildSqlSemanticModel } from "@/lib/sql/semantic/model";
import { sqlFixtureCursor } from "@/lib/sql/semantic/fixtures";
import { resolveSqlSemanticNavigationTarget, mergeSqlSemanticReferenceAnalysis, sqlSemanticCompletionReferenceTables, sqlSemanticTableReferences } from "@/lib/sql/semantic/references";
import { splitQualifiedIdentifier } from "@/lib/sql/sqlNavigation";
import type { SqlReferenceAnalysis } from "@/types/database";
const span = (startColumn: number, endColumn: number) => ({
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { findActiveSqlStatementSpan, isSuppressedSqlSemanticContext, tokenizeSqlSemantic, unquoteSqlSemanticIdentifier } from "@/lib/sqlSemanticTokens";
import { findActiveSqlStatementSpan, isSuppressedSqlSemanticContext, tokenizeSqlSemantic, unquoteSqlSemanticIdentifier } from "@/lib/sql/semantic/tokens";
describe("sqlSemanticTokens", () => {
it("tokenizes comments, strings, quoted identifiers, brackets, and backticks", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { buildSqlCompletionItems, getSqlCompletionContext } from "@/lib/sqlCompletion";
import { buildSqlCompletionItems, getSqlCompletionContext } from "@/lib/sql/sqlCompletion";
describe("sqlCompletion quoted schema qualifiers", () => {
it("parses quoted PostgreSQL schema names before a dot", () => {
@@ -1,5 +1,5 @@
import { describe, it, expect } from "vitest";
import { buildSnippetItemsForTest } from "@/lib/sqlCompletion";
import { buildSnippetItemsForTest } from "@/lib/sql/sqlCompletion";
import type { SqlSnippet } from "@/types/database";
const TEST_SNIPPETS: SqlSnippet[] = [
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { resolveExecutableSql } from "../sqlExecutionTarget";
import { resolveExecutableSql } from "@/lib/sql/sqlExecutionTarget";
describe("resolveExecutableSql", () => {
it("uses selected SQL before cursor-mode resolution", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { formatSqlForDisplay, formatSqlText, MAX_SQL_FORMAT_CHARS, sqlFormatDialectForDbType } from "@/lib/sqlFormatter";
import { formatSqlForDisplay, formatSqlText, MAX_SQL_FORMAT_CHARS, sqlFormatDialectForDbType } from "@/lib/sql/sqlFormatter";
describe("sqlFormatter", () => {
it("maps PostgreSQL-compatible database types to the postgres formatter dialect", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { DEFAULT_SQL_FORMATTER_SETTINGS, parseSqlFormatterConfig, serializeSqlFormatterConfig } from "@/lib/sqlFormatterConfig";
import { DEFAULT_SQL_FORMATTER_SETTINGS, parseSqlFormatterConfig, serializeSqlFormatterConfig } from "@/lib/sql/sqlFormatterConfig";
describe("sqlFormatterConfig shortcut storage", () => {
it("does not serialize JSON editor shortcut settings", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it, vi } from "vitest";
import { createSafeSqlHighlighter, escapeHtml } from "@/lib/sqlHighlighter";
import { createSafeSqlHighlighter, escapeHtml } from "@/lib/sql/sqlHighlighter";
describe("escapeHtml", () => {
it("escapes SQL text for v-html fallback rendering", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { extractIdentifierAt, matchTable, splitQualifiedIdentifier } from "@/lib/sqlNavigation";
import { extractIdentifierAt, matchTable, splitQualifiedIdentifier } from "@/lib/sql/sqlNavigation";
describe("extractIdentifierAt", () => {
it("extracts unquoted qualified identifiers", () => {
@@ -1,5 +1,5 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import { loadSqlParameterHistory, MAX_SQL_PARAMETER_HISTORY, rememberSqlParameterValue } from "../sqlParameterHistory";
import { loadSqlParameterHistory, MAX_SQL_PARAMETER_HISTORY, rememberSqlParameterValue } from "@/lib/sql/sqlParameterHistory";
const storage = new Map<string, string>();
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { extractSqlParameters, sqlParameterLiteral, substituteSqlParameters } from "../sqlParameters";
import { extractSqlParameters, sqlParameterLiteral, substituteSqlParameters } from "@/lib/sql/sqlParameters";
describe("extractSqlParameters", () => {
it("extracts unique template parameters in order", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { buildExecutionCandidates, executableStatementRanges, fullSqlRange, hasMultipleExecutionTargets, splitSqlStatementRanges, statementRangeAtCursor, supportsExecutionTargetPicker } from "../sqlStatementRanges";
import { buildExecutionCandidates, executableStatementRanges, fullSqlRange, hasMultipleExecutionTargets, splitSqlStatementRanges, statementRangeAtCursor, supportsExecutionTargetPicker } from "@/lib/sql/sqlStatementRanges";
function indexOf(sql: string, needle: string, occurrence = 1): number {
let from = 0;
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { sortTablesByFkDependency, type TableWithFk } from "@/lib/tableDependencySort";
import { sortTablesByFkDependency, type TableWithFk } from "@/lib/table/tableDependencySort";
function fk(refTable: string) {
return { name: `fk_to_${refTable}`, column: "id", ref_table: refTable, ref_column: "id" };
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { DBX_ROWID_COLUMN, canEditExistingTableRows, canUseKeylessRowPredicate, editablePrimaryKeys, editableRowIdentifierColumns, isClickHouseExistingRowReadonlyColumn, isTableDataEditable, supportsDataGridTransaction } from "@/lib/tableEditing";
import { DBX_ROWID_COLUMN, canEditExistingTableRows, canUseKeylessRowPredicate, editablePrimaryKeys, editableRowIdentifierColumns, isClickHouseExistingRowReadonlyColumn, isTableDataEditable, supportsDataGridTransaction } from "@/lib/table/tableEditing";
import type { ColumnInfo, IndexInfo } from "@/types/database";
function column(name: string, isPrimaryKey = false): ColumnInfo {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { combineDataTypeForDatabase, createColumnDrafts, dataTypeLengthInputValue, isDataTypeLengthDisabled, isSqlServerIdentityCompatibleDataType, splitDataType } from "../tableStructureEditorState";
import { combineDataTypeForDatabase, createColumnDrafts, dataTypeLengthInputValue, isDataTypeLengthDisabled, isSqlServerIdentityCompatibleDataType, splitDataType } from "@/lib/table/tableStructureEditorState";
describe("tableStructureEditorState", () => {
it("keeps mysql unsigned attributes in the editable base type", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { zookeeperDelete, zookeeperGet, zookeeperListPrefix, zookeeperPut, type KvListPrefixOptions, type KvPutOptions, type KvPutResponse } from "../api";
import { zookeeperDelete, zookeeperGet, zookeeperListPrefix, zookeeperPut, type KvListPrefixOptions, type KvPutOptions, type KvPutResponse } from "@/lib/backend/api";
import type { DatabaseType } from "@/types/database";
describe("zookeeper frontend API contract", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { firstZooKeeperEndpoint, normalizeZooKeeperConnectString } from "../zookeeperConnection";
import { firstZooKeeperEndpoint, normalizeZooKeeperConnectString } from "@/lib/zookeeper/zookeeperConnection";
describe("zookeeperConnection", () => {
it("normalizes comma, semicolon, and newline separated connect strings", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { createLazyKvKeyTreeState, flattenLazyKvKeyTree, replaceLazyKvChildren, resetLazyKvKeyTree } from "../zookeeperLazyKeyTree";
import { createLazyKvKeyTreeState, flattenLazyKvKeyTree, replaceLazyKvChildren, resetLazyKvKeyTree } from "@/lib/zookeeper/zookeeperLazyKeyTree";
describe("zookeeper lazy key tree", () => {
it("stores only the current path direct children on reset", () => {
@@ -1,14 +1,14 @@
import type { AiConfig } from "@/stores/settingsStore";
import { uuid } from "@/lib/utils";
import { uuid } from "@/lib/common/utils";
import type { ColumnInfo, ConnectionConfig, DatabaseType, ForeignKeyInfo, IndexInfo, QueryResult, QueryTab } from "@/types/database";
import * as api from "@/lib/api";
import * as api from "@/lib/backend/api";
import { currentLocale, type Locale } from "@/i18n";
import { aiTableMentionKey, type AiTableMention } from "@/lib/aiTableMentions";
import { aiSkillForAction } from "@/lib/aiSkills";
import { isSchemaAware } from "@/lib/databaseCapabilities";
import { effectiveDatabaseTypeForConnection } from "@/lib/jdbcDialect";
import { aiTableMentionKey, type AiTableMention } from "@/lib/ai/aiTableMentions";
import { aiSkillForAction } from "@/lib/ai/aiSkills";
import { isSchemaAware } from "@/lib/database/databaseCapabilities";
import { effectiveDatabaseTypeForConnection } from "@/lib/database/jdbcDialect";
import type { AgentEvent } from "@/lib/tauri";
import type { AgentEvent } from "@/lib/backend/tauri";
const VECTOR_DB_TYPES: ReadonlySet<DatabaseType> = new Set([
"qdrant",
@@ -1,5 +1,5 @@
import type { AiAction, AiAssistantMode } from "@/lib/ai";
import { classifyAiSqlExecution, shouldAttemptAiAutoExecute, stripAiSqlComments, type AiSqlExecutionDecision } from "@/lib/aiSqlExecutionPolicy";
import type { AiAction, AiAssistantMode } from "@/lib/ai/ai";
import { classifyAiSqlExecution, shouldAttemptAiAutoExecute, stripAiSqlComments, type AiSqlExecutionDecision } from "@/lib/ai/aiSqlExecutionPolicy";
import type { ConnectionConfig } from "@/types/database";
export type AiAgentStep =
@@ -1,4 +1,4 @@
import type { AiAgentPlan, AiAgentStep } from "@/lib/aiAgentPlan";
import type { AiAgentPlan, AiAgentStep } from "@/lib/ai/aiAgentPlan";
export type AiAgentStepTone = "success" | "active" | "warning" | "danger" | "muted";
@@ -1,4 +1,4 @@
import type { AppThemeAppearance } from "@/lib/appTheme";
import type { AppThemeAppearance } from "@/lib/app/appTheme";
export type AiCodeHighlighter = (content: string, lang: string, appearance?: AppThemeAppearance) => string;
File renamed without changes.
@@ -1,4 +1,4 @@
import type { AiAction } from "@/lib/ai";
import type { AiAction } from "@/lib/ai/ai";
export type AiSkillRiskPolicy = "readonly" | "readonly_preferred" | "confirmed_write" | "sample_write";
export type AiSkillContextNeed = "currentSql" | "schema" | "indexes" | "foreignKeys" | "lastError" | "lastResultPreview" | "databaseDialect";
File renamed without changes.
File renamed without changes.
@@ -1,7 +1,7 @@
import type { ComposerTranslation } from "vue-i18n";
import type { DatabaseType } from "@/types/database";
import { quoteUnquotedObjectKeys } from "@/lib/mongoShellCommand";
import { formatMongoShellLiteral } from "@/lib/mongoDocumentValues";
import { quoteUnquotedObjectKeys } from "@/lib/mongo/mongoShellCommand";
import { formatMongoShellLiteral } from "@/lib/mongo/mongoDocumentValues";
export type DocumentStoreKind = "mongodb" | "elasticsearch";
export type DocumentFilterMode = "equals" | "not-equals" | "like" | "not-like" | "greater-than" | "less-than" | "is-null" | "is-not-null";
File renamed without changes.
@@ -1,6 +1,6 @@
import { isTauriRuntime } from "./tauriRuntime";
import type * as TauriModule from "./tauri";
import { appendDebugLog } from "./debugLog";
import { isTauriRuntime } from "@/lib/backend/tauriRuntime";
import type * as TauriModule from "@/lib/backend/tauri";
import { appendDebugLog } from "@/lib/backend/debugLog";
// ---------------------------------------------------------------------------
// Lazy backend resolution (avoids top-level await)
@@ -12,7 +12,7 @@ let _backend: Backend | null = null;
async function getBackend(): Promise<Backend> {
if (_backend) return _backend;
_backend = isTauriRuntime(globalThis) ? await import("./tauri") : await import("./http");
_backend = isTauriRuntime(globalThis) ? await import("@/lib/backend/tauri") : await import("@/lib/backend/http");
return _backend;
}
@@ -501,4 +501,4 @@ export type {
TableExportRequest,
QueryResultExportRequest,
AgentEvent,
} from "./tauri";
} from "@/lib/backend/tauri";
@@ -79,9 +79,9 @@ export async function decryptConfig(payload: EncryptedPayload, passphrase: strin
key = await deriveKey(passphrase, salt);
} catch (error) {
if (error instanceof Error && error.message === CONFIG_CRYPTO_UNAVAILABLE) {
const { isTauriRuntime } = await import("@/lib/tauriRuntime");
const { isTauriRuntime } = await import("@/lib/backend/tauriRuntime");
if (!isTauriRuntime(globalThis)) {
const { decryptConfig: decryptConfigOnBackend } = await import("@/lib/api");
const { decryptConfig: decryptConfigOnBackend } = await import("@/lib/backend/api");
return decryptConfigOnBackend(payload, passphrase);
}
}
File renamed without changes.
@@ -31,8 +31,8 @@ import type {
SavedSqlLibrary,
} from "@/types/database";
import type { CollectionInfo } from "@/types/database";
import type { SchemaDiffPreparation, SchemaDiffPreparationOptions, TableDiff, FunctionDiff, SequenceDiff, RuleDiff, OwnerDiff } from "@/lib/schemaDiff";
import type { SidebarObjectKind } from "@/lib/databaseObjectCapabilities";
import type { SchemaDiffPreparation, SchemaDiffPreparationOptions, TableDiff, FunctionDiff, SequenceDiff, RuleDiff, OwnerDiff } from "@/lib/schema/schemaDiff";
import type { SidebarObjectKind } from "@/lib/database/databaseObjectCapabilities";
import type { AiConfig, AiTestConnectionResult } from "@/stores/settingsStore";
import type {
AgentDriverInfo,
@@ -91,8 +91,8 @@ import type {
ExplainSqlBuildResult,
DroppedFilePreviewSqlOptions,
MongoGridFsFileInfo,
} from "./tauri";
import type { QueryEditability } from "@/lib/sqlAnalysis";
} from "@/lib/backend/tauri";
import type { QueryEditability } from "@/lib/sql/sqlAnalysis";
import type {
DataGridColumnDistinctValuesSqlOptions,
DataGridColumnValueFilterConditionOptions,
@@ -103,19 +103,19 @@ import type {
DataGridCopyUpdateStatementOptions,
DataGridSaveStatementOptions,
HiveTablePropertiesSqlOptions,
} from "@/lib/dataGridSql";
import type { BuildTableStructureChangeSqlOptions, BuildSingleColumnAlterSqlOptions, TableStructureChangeSql } from "@/lib/tableStructureEditorSql";
import type { BuildTableSelectSqlOptions } from "@/lib/tableSelectSql";
import type { DatabaseSearchSql, DatabaseSearchSqlOptions, SearchResultWhereOptions } from "@/lib/databaseSearch";
import type { BuildEditableObjectSourceSqlInput, BuildRoutineRenameObjectSourceInput } from "@/lib/objectSourceEditor";
import type { BuildViewDdlInput } from "@/lib/viewDdl";
import type { BuildRenameObjectSqlOptions } from "@/lib/objectRenameSql";
import type { CreateDatabaseSqlOptions } from "@/lib/createDatabaseSql";
import type { DatabaseNameSqlOptions, DropTableChildObjectSqlOptions, DropObjectSqlOptions, DuplicateTableStructureSqlOptions, CopyTableDataSqlOptions, SchemaNameSqlOptions, TableAdminSqlOptions } from "@/lib/dbAdminSql";
import type { BuildDatabaseSqlExportOptions, BuildExportInsertStatementsOptions } from "@/lib/databaseExport";
import type { DataCompareFromTablesOptions, DataCompareFromTablesPreparation, DataCompareSyncPlan, DataCompareSyncPlanOptions, DataComparePreparation, DataComparePreparationOptions } from "@/lib/dataCompare";
import { apiUrl, apiWebSocketUrl } from "@/lib/webPath";
import type { DataGridSavePreparation } from "./tauri";
} from "@/lib/dataGrid/dataGridSql";
import type { BuildTableStructureChangeSqlOptions, BuildSingleColumnAlterSqlOptions, TableStructureChangeSql } from "@/lib/table/tableStructureEditorSql";
import type { BuildTableSelectSqlOptions } from "@/lib/table/tableSelectSql";
import type { DatabaseSearchSql, DatabaseSearchSqlOptions, SearchResultWhereOptions } from "@/lib/database/databaseSearch";
import type { BuildEditableObjectSourceSqlInput, BuildRoutineRenameObjectSourceInput } from "@/lib/table/objectSourceEditor";
import type { BuildViewDdlInput } from "@/lib/table/viewDdl";
import type { BuildRenameObjectSqlOptions } from "@/lib/table/objectRenameSql";
import type { CreateDatabaseSqlOptions } from "@/lib/database/createDatabaseSql";
import type { DatabaseNameSqlOptions, DropTableChildObjectSqlOptions, DropObjectSqlOptions, DuplicateTableStructureSqlOptions, CopyTableDataSqlOptions, SchemaNameSqlOptions, TableAdminSqlOptions } from "@/lib/database/dbAdminSql";
import type { BuildDatabaseSqlExportOptions, BuildExportInsertStatementsOptions } from "@/lib/export/databaseExport";
import type { DataCompareFromTablesOptions, DataCompareFromTablesPreparation, DataCompareSyncPlan, DataCompareSyncPlanOptions, DataComparePreparation, DataComparePreparationOptions } from "@/lib/dataGrid/dataCompare";
import { apiUrl, apiWebSocketUrl } from "@/lib/common/webPath";
import type { DataGridSavePreparation } from "@/lib/backend/tauri";
import type {
NacosConfigHistoryKey,
NacosConfigHistoryList,
@@ -138,7 +138,7 @@ import type {
NacosServiceList,
NacosServiceQuery,
} from "@/types/nacos";
import { safeLocalStorageGet, safeLocalStorageSet } from "@/lib/safeStorage";
import { safeLocalStorageGet, safeLocalStorageSet } from "@/lib/backend/safeStorage";
// ---------------------------------------------------------------------------
// Helpers
@@ -879,7 +879,7 @@ export async function prepareDataCompareFromTables(options: DataCompareFromTable
return post("/api/data-compare/prepare-from-tables", options);
}
export async function prepareDataCompareMissingTarget(options: import("@/lib/dataCompare").DataCompareMissingTargetOptions): Promise<DataCompareFromTablesPreparation> {
export async function prepareDataCompareMissingTarget(options: import("@/lib/dataGrid/dataCompare").DataCompareMissingTargetOptions): Promise<DataCompareFromTablesPreparation> {
return post("/api/data-compare/prepare-missing-target", options);
}
@@ -944,13 +944,13 @@ export async function aiListModels(config: AiConfig): Promise<AiModelInfo[]> {
return post("/api/ai/models", { config });
}
export type { AgentEvent } from "./tauri";
export type { AgentEvent } from "@/lib/backend/tauri";
function isAgentEvent(v: unknown): v is import("./tauri").AgentEvent {
function isAgentEvent(v: unknown): v is import("@/lib/backend/tauri").AgentEvent {
return typeof v === "object" && v !== null && "type" in v && typeof (v as Record<string, unknown>).type === "string";
}
export async function aiAgentStream(sessionId: string, request: AiCompletionRequest, connectionId: string, database: string, dbType: string, onEvent: (event: import("./tauri").AgentEvent) => void, mode?: string, signal?: AbortSignal): Promise<string> {
export async function aiAgentStream(sessionId: string, request: AiCompletionRequest, connectionId: string, database: string, dbType: string, onEvent: (event: import("@/lib/backend/tauri").AgentEvent) => void, mode?: string, signal?: AbortSignal): Promise<string> {
const res = await fetch(apiUrl("/api/ai/agent-stream"), {
method: "POST",
headers: { "Content-Type": "application/json" },
@@ -1459,7 +1459,7 @@ export async function cancelQueryResultExport(exportId: string, executionId?: st
}
export async function exportQueryResultCsv(filePath: string, columns: string[], rows: readonly (readonly XlsxCellValue[])[]): Promise<void> {
const { formatCsv } = await import("./exportFormats");
const { formatCsv } = await import("@/lib/export/exportFormats");
const content = formatCsv(columns, rows as (string | number | boolean | null)[][]);
const fileName = filePath.split(/[\\/]/).pop() || "export.csv";
const blob = new Blob(["\uFEFF", content], { type: "text/csv;charset=utf-8" });
@@ -1487,7 +1487,7 @@ function downloadTextFile(filePath: string, fallbackFileName: string, content: s
}
export async function exportQueryResultXlsx(filePath: string, sheetName: string | undefined, columns: string[], rows: readonly (readonly XlsxCellValue[])[]): Promise<void> {
const { buildXlsxWorkbook } = await import("./xlsxExport");
const { buildXlsxWorkbook } = await import("@/lib/export/xlsxExport");
const workbook = buildXlsxWorkbook({
sheetName: sheetName || "Export",
columns,
@@ -1506,7 +1506,7 @@ export async function exportQueryResultXlsx(filePath: string, sheetName: string
}
export async function exportQueryResultsXlsx(filePath: string, worksheets: readonly { sheetName?: string; columns: string[]; rows: readonly (readonly XlsxCellValue[])[] }[]): Promise<void> {
const { buildXlsxWorkbookMulti } = await import("./xlsxExport");
const { buildXlsxWorkbookMulti } = await import("@/lib/export/xlsxExport");
const workbook = buildXlsxWorkbookMulti(worksheets);
const fileName = filePath.split(/[\\/]/).pop() || "export.xlsx";
const blob = new Blob([new Uint8Array(workbook)], {
@@ -1945,7 +1945,7 @@ export async function checkForUpdates(): Promise<UpdateInfo> {
return get("/api/update/check");
}
export async function checkMcpServerStatus(): Promise<import("./tauri").McpServerStatus> {
export async function checkMcpServerStatus(): Promise<import("@/lib/backend/tauri").McpServerStatus> {
return {
installed: false,
npm_available: false,
@@ -1995,4 +1995,4 @@ export async function refreshConnections(): Promise<void> {
// Web mode doesn't maintain persistent connection pools - no-op
}
export * from "./mq-http";
export * from "@/lib/backend/mq-http";
@@ -1,5 +1,5 @@
// HTTP fetch API for message queue admin (web mode)
import { apiUrl } from "@/lib/webPath";
import { apiUrl } from "@/lib/common/webPath";
import type {
MqClusterInfo,
ClusterInfo,
File renamed without changes.
Loaded 100 of 700 files, more files were not shown because too many files have changed in this diff. Show more