feat(core): split foundational capabilities into dedicated crates
This commit is contained in:
402 files changed
+4386
-3367
No files matched your search
@@ -4413,7 +4413,7 @@ function globalInstructionsTooLong(): boolean {
|
||||
}
|
||||
|
||||
// Agent turn limit for DBX's API-backed agent loop. CLI providers enforce their own limits.
|
||||
// Mirrors DEFAULT/MIN/MAX_MAX_AGENT_TURNS in crates/dbx-core/src/agent_loop.rs —
|
||||
// Mirrors DEFAULT/MIN/MAX_MAX_AGENT_TURNS in crates/dbx-core/src/ai/agent_loop.rs —
|
||||
// keep in sync; the backend clamp on save/load is the actual source of truth.
|
||||
const editMaxAgentTurns = ref<number | undefined>(undefined);
|
||||
const maxAgentTurnsSaving = ref(false);
|
||||
|
||||
@@ -1001,7 +1001,7 @@ describe("RedisKeyBrowser continuation ownership (issue #7779)", () => {
|
||||
|
||||
// `iterations` (aka `max_iterations`) is the 6th positional arg the frontend
|
||||
// sends to `redisScanKeysBatch` — the same unit the backend spends as real
|
||||
// Redis SCAN calls (see `crates/dbx-core/src/db/redis_driver.rs`).
|
||||
// Redis SCAN calls (see `crates/dbx-drivers/src/db/redis_driver.rs`).
|
||||
function totalIterationsRequested(): number {
|
||||
return mocks.redisScanKeysBatch.mock.calls.reduce((sum: number, call: unknown[]) => sum + (call[5] as number), 0);
|
||||
}
|
||||
|
||||
+1
-1
@@ -220,7 +220,7 @@ describe("useSidebarTableMutationRuntime SAP HANA schema-scoped actions", () =>
|
||||
|
||||
it("classifies a JDBC-agent-routed timeout (SAP HANA/Oracle/DB2/SQL Server) as timed-out, not failed, even though its message has no timeout wording", async () => {
|
||||
const { feature } = runtime("");
|
||||
// AgentCallError::Timeout carries no `detail` (crates/dbx-core/src/backend_error.rs),
|
||||
// AgentCallError::Timeout carries no `detail` (crates/dbx-drivers/src/backend_error.rs),
|
||||
// so BackendErrorException.message degrades to a generic fallback with no
|
||||
// "timed out" text — only the structured backendError distinguishes it.
|
||||
const agentTimeoutError = {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Issue #6189 — SQL Server "focus jumps to the message result".
|
||||
*
|
||||
* Background:
|
||||
* - `crates/dbx-core/src/db/sqlserver.rs:523-542` synthesizes a pseudo result with a
|
||||
* - `crates/dbx-drivers/src/db/sqlserver.rs:523-542` synthesizes a pseudo result with a
|
||||
* single "Message" column and `server_message: true` for any batch segment that
|
||||
* produced only server messages (PRINT / "DBCC execution completed" / ...).
|
||||
* - `stores/queryStore.ts:4727` then picks the first result that HAS COLUMNS as the
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import { ANNOTATION_FILE_KEYS, COLUMN_ANNOTATION_KEYS, GROUP_ANNOTATION_KEYS, PR
|
||||
// that Rust does not declare turns every save into a deserialization error at
|
||||
// runtime. vue-tsc cannot see across the language boundary, so this reads the
|
||||
// Rust source and compares the field sets directly.
|
||||
const rustSource = readFileSync(path.resolve(__dirname, "../../../../../crates/dbx-core/src/docs/annotations.rs"), "utf8");
|
||||
const rustSource = readFileSync(path.resolve(__dirname, "../../../../../crates/dbx-core/src/data/docs/annotations.rs"), "utf8");
|
||||
|
||||
function rustFields(structName: string): string[] {
|
||||
const start = rustSource.indexOf(`pub struct ${structName} {`);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Mirrors crates/dbx-core/src/docs/snapshot.rs. There is no Rust->TS codegen
|
||||
// Mirrors crates/dbx-core/src/data/docs/snapshot.rs. There is no Rust->TS codegen
|
||||
// in this repo, so this file is maintained by hand — see
|
||||
// __tests__/fixtureConformance.spec.ts, which validates it against a snapshot
|
||||
// generated by the real Rust code and fails if the two drift apart.
|
||||
|
||||
+11
-11
@@ -46,7 +46,7 @@ const STRUCTURED_BACKEND_ERROR_KEYS = [
|
||||
"backendErrors.unknown",
|
||||
] as const;
|
||||
|
||||
// Reproduces the exact string crates/dbx-core/src/agent_service.rs builds on
|
||||
// Reproduces the exact string crates/dbx-drivers/src/agent_service.rs builds on
|
||||
// Windows: `\` line continuations strip the newline plus the following indent.
|
||||
const WINDOWS_JRE_REMOVE_ERROR = [
|
||||
"Failed to remove the old JRE directory: C:\\dbx\\jre21",
|
||||
@@ -123,7 +123,7 @@ const CASES: { name: string; message: string; key: string; params?: Record<strin
|
||||
key: "mongo.import.legacyInsertUnsupported",
|
||||
},
|
||||
{
|
||||
// crates/dbx-core/src/mongodb_import_export.rs attributes a batch-level failure to a row.
|
||||
// crates/dbx-core/src/data/mongodb_import_export.rs attributes a batch-level failure to a row.
|
||||
name: "MongoDB Legacy insertMany unsupported on a located row",
|
||||
message: "row 1: MongoDB Legacy Agent does not support insertMany; upgrade or reinstall the MongoDB Legacy driver",
|
||||
key: "mongo.import.legacyInsertUnsupported",
|
||||
@@ -602,15 +602,15 @@ describe("backend error wording is pinned to the Rust sources", () => {
|
||||
const rust = (path: string) => readFileSync(new URL(`../../../../../${path}`, import.meta.url), "utf8");
|
||||
|
||||
test.each([
|
||||
["crates/dbx-core/src/query_result_export.rs", "Streaming export is unsupported for this query. Simplify it or use a supported driver."],
|
||||
["crates/dbx-core/src/query_result_export.rs", "Streaming export needs a result-set session, but this driver returned no session_id."],
|
||||
["crates/dbx-core/src/mongodb_import_export.rs", "MongoDB Legacy Agent does not support insertMany; upgrade or reinstall the MongoDB Legacy driver"],
|
||||
["crates/dbx-core/src/mongodb_import_export.rs", "MongoDB Legacy Agent returned an invalid find cursor"],
|
||||
["crates/dbx-core/src/mongo_ops.rs", "MongoDB Legacy Agent rejected "],
|
||||
["crates/dbx-core/src/agent_service.rs", "Failed to remove the old JRE directory: "],
|
||||
["crates/dbx-core/src/agent_service.rs", "is in use by drivers: "],
|
||||
["crates/dbx-core/src/agent_service.rs", "agent-registry.json not found in the ZIP; not a valid offline driver package."],
|
||||
["crates/dbx-core/src/mq/adapters/kafka.rs", "Kafka does not support unloading topics"],
|
||||
["crates/dbx-core/src/data/query_result_export.rs", "Streaming export is unsupported for this query. Simplify it or use a supported driver."],
|
||||
["crates/dbx-core/src/data/query_result_export.rs", "Streaming export needs a result-set session, but this driver returned no session_id."],
|
||||
["crates/dbx-core/src/data/mongodb_import_export.rs", "MongoDB Legacy Agent does not support insertMany; upgrade or reinstall the MongoDB Legacy driver"],
|
||||
["crates/dbx-core/src/data/mongodb_import_export.rs", "MongoDB Legacy Agent returned an invalid find cursor"],
|
||||
["crates/dbx-core/src/query/mongo_ops.rs", "MongoDB Legacy Agent rejected "],
|
||||
["crates/dbx-drivers/src/agent_service.rs", "Failed to remove the old JRE directory: "],
|
||||
["crates/dbx-drivers/src/agent_service.rs", "is in use by drivers: "],
|
||||
["crates/dbx-drivers/src/agent_service.rs", "agent-registry.json not found in the ZIP; not a valid offline driver package."],
|
||||
["crates/dbx-core/src/admin/mq/adapters/kafka.rs", "Kafka does not support unloading topics"],
|
||||
["crates/dbx-web/src/auth.rs", "Please try again in {remaining}s"],
|
||||
["crates/dbx-web/src/routes/agents.rs", "Close these database connections before updating drivers: "],
|
||||
["src-tauri/src/commands/agents.rs", "Close these database connections before updating drivers: "],
|
||||
|
||||
@@ -128,7 +128,7 @@ const patterns: [RegExp, string][] = [
|
||||
// SSH keyboard-interactive prompts (for example JumpServer TOTP).
|
||||
[/^(?:SSH layer \d+ failed:\s*)?SSH keyboard-interactive authentication was cancelled$/, "connection.sshTotpCancelled"],
|
||||
|
||||
// Query result export limits (crates/dbx-core/src/query_result_export.rs)
|
||||
// Query result export limits (crates/dbx-core/src/data/query_result_export.rs)
|
||||
[/^Streaming export is unsupported for this query\. Simplify it or use a supported driver\.$/, "exportProgress.streamingUnsupported"],
|
||||
// MongoDB Legacy agent failures: messages raised by the agent arrive wrapped in "Agent RPC
|
||||
// error (<code>): ", and the import path prefixes the row a batch-level failure belongs to.
|
||||
@@ -146,7 +146,7 @@ const patterns: [RegExp, string][] = [
|
||||
// Legacy bundled DuckDB error kept for compatibility with older backends.
|
||||
[/^The previous DuckDB query is still stopping\. Please try again shortly\.$/, "editor.duckdbDraining"],
|
||||
|
||||
// Driver / JRE management (crates/dbx-core/src/agent_service.rs, routes/agents.rs)
|
||||
// Driver / JRE management (crates/dbx-drivers/src/agent_service.rs, routes/agents.rs)
|
||||
// The Windows variant is multi-line, so it must be tried before the single-line one.
|
||||
[/^Failed to remove the old JRE directory: (.+)\nPossible causes:[\s\S]*\(original error: ([\s\S]+)\)$/, "driverStore.jreDirRemoveFailedWindows"],
|
||||
[/^Failed to remove the old JRE directory: (.+) \(original error: ([\s\S]+)\)$/, "driverStore.jreDirRemoveFailed"],
|
||||
@@ -154,7 +154,7 @@ const patterns: [RegExp, string][] = [
|
||||
[/^agent-registry\.json not found in the ZIP; not a valid offline driver package\.$/, "driverStore.offlinePackageRegistryMissing"],
|
||||
[/^Close these database connections before updating drivers: (.+)$/, "driverStore.driverUpdateBlocked"],
|
||||
|
||||
// Message queues (crates/dbx-core/src/mq/adapters/kafka.rs)
|
||||
// Message queues (crates/dbx-core/src/admin/mq/adapters/kafka.rs)
|
||||
[/^Kafka does not support unloading topics$/, "mqClients.unloadTopicUnsupportedKafka"],
|
||||
|
||||
// Filesystem (src-tauri/src/commands/fs_open.rs)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
- `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.
|
||||
Keep fixed SQL completion statements and their database-specific variants in `sql/sqlSnippetTemplates.ts`; cross-check row-limiting families against `crates/dbx-core/src/sql_dialect/capabilities.rs` and authoritative dialect documentation, and never replace a user-customized built-in body with a generated default.
|
||||
Keep fixed SQL completion statements and their database-specific variants in `sql/sqlSnippetTemplates.ts`; cross-check row-limiting families against `crates/dbx-sql/src/sql_dialect/capabilities.rs` and authoritative dialect documentation, and never replace a user-customized built-in body with a generated default.
|
||||
- `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.
|
||||
@@ -38,5 +38,5 @@ Schema Diff review and execution must preserve these invariants:
|
||||
Regression coverage belongs in:
|
||||
|
||||
- `packages/app-tests/schemaDiff.test.ts`
|
||||
- `crates/dbx-core/src/query.rs`
|
||||
- `crates/dbx-core/src/query/mod.rs`
|
||||
- `src-tauri/src/commands/query.rs`
|
||||
@@ -101,7 +101,7 @@ describe("isNumericColumnType", () => {
|
||||
|
||||
it("covers the full cross-database numeric whitelist used by the alignment classifier", () => {
|
||||
// Cross-database coverage matrix. Every entry here MUST stay in sync with
|
||||
// the Rust classifier in crates/dbx-core/src/xlsx_export.rs so that the
|
||||
// the Rust classifier in crates/dbx-formats/src/xlsx_export.rs so that the
|
||||
// grid, the front-end XLSX exporter and the Rust XLSX exporter agree.
|
||||
const numericTypesByDatabase: Record<string, string[]> = {
|
||||
mysql: ["tinyint", "smallint", "mediumint", "int", "integer", "bigint", "float", "double", "decimal", "dec", "fixed"],
|
||||
|
||||
@@ -70,7 +70,7 @@ describe("databaseObjectCapabilities", () => {
|
||||
|
||||
it("exposes materialized views for StarRocks only", () => {
|
||||
// StarRocks has a dedicated MV listing/classification path in
|
||||
// crates/dbx-core/src/db/mysql.rs (`list_starrocks_tables` +
|
||||
// crates/dbx-drivers/src/db/mysql.rs (`list_starrocks_tables` +
|
||||
// `classify_starrocks_materialized_views`).
|
||||
expect(sidebarObjectKindsForDatabase("starrocks")).toContain("MATERIALIZED_VIEW");
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ const VECTOR_DB_TYPES: ReadonlySet<DatabaseType> = new Set([
|
||||
"milvus",
|
||||
"weaviate",
|
||||
"chromadb",
|
||||
// If modifying this, also update is_vector_db() in crates/dbx-core/src/agent_tools.rs.
|
||||
// If modifying this, also update is_vector_db() in crates/dbx-core/src/ai/agent_tools.rs.
|
||||
]);
|
||||
|
||||
export function isVectorDbType(dbType: DatabaseType): boolean {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Mirrors DEFAULT/MIN/MAX_MAX_AGENT_TURNS in crates/dbx-core/src/agent_loop.rs.
|
||||
// Mirrors DEFAULT/MIN/MAX_MAX_AGENT_TURNS in crates/dbx-core/src/ai/agent_loop.rs.
|
||||
// The backend clamp remains the source of truth for persisted values.
|
||||
export const MAX_AGENT_TURNS_DEFAULT = 30;
|
||||
export const MAX_AGENT_TURNS_MIN = 5;
|
||||
|
||||
@@ -106,7 +106,7 @@ const contracts: Contract[] = [
|
||||
|
||||
const sourceCache = new Map<string, string>();
|
||||
function source(file: string): string {
|
||||
if (!sourceCache.has(file)) sourceCache.set(file, readFileSync(join(process.cwd(), "crates/dbx-core/src/consul", file), "utf8"));
|
||||
if (!sourceCache.has(file)) sourceCache.set(file, readFileSync(join(process.cwd(), "crates/dbx-core/src/admin/consul", file), "utf8"));
|
||||
return sourceCache.get(file)!;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ const http = readFileSync(new URL("../http.ts", import.meta.url), "utf8");
|
||||
const api = readFileSync(new URL("../api.ts", import.meta.url), "utf8");
|
||||
const tauriRegistry = readFileSync(new URL("../../../../../../src-tauri/src/lib.rs", import.meta.url), "utf8");
|
||||
const webRegistry = readFileSync(new URL("../../../../../../crates/dbx-web/src/main.rs", import.meta.url), "utf8");
|
||||
const coreOps = readFileSync(new URL("../../../../../../crates/dbx-core/src/document_ops.rs", import.meta.url), "utf8");
|
||||
const coreOps = readFileSync(new URL("../../../../../../crates/dbx-core/src/query/document_ops.rs", import.meta.url), "utf8");
|
||||
|
||||
function functionBody(source: string, operation: string): string {
|
||||
const start = source.indexOf(`export async function ${operation}(`);
|
||||
|
||||
@@ -123,7 +123,7 @@ export function spannerSchemaDisplayName(schema: string): string {
|
||||
/**
|
||||
* Percent-encode a Spanner resource path for display, keeping the `/` separators
|
||||
* intact — they are structure, not data. Mirrors `encode_spanner_resource_path`
|
||||
* in crates/dbx-core/src/models/connection.rs.
|
||||
* in crates/dbx-types/src/models/connection.rs.
|
||||
*
|
||||
* Every other database type keeps whole-value encoding, where a slash inside a
|
||||
* database name really is data and should be escaped.
|
||||
|
||||
@@ -267,7 +267,7 @@ const ORACLE_STICKY_TRANSACTION_TYPES: ReadonlySet<string> = new Set(["oracle",
|
||||
|
||||
/** Databases whose manual-transaction toolbar hides Commit/Rollback until an
|
||||
* unproven statement dirties the session. Mirrors the Rust proof gate
|
||||
* (crates/dbx-core/src/query.rs + sql_risk.rs `prove_read_only_for_database`).
|
||||
* (crates/dbx-core/src/query/mod.rs + sql_risk.rs `prove_read_only_for_database`).
|
||||
* Every member must also be in TRANSACTION_SUPPORTED_TYPES above: a database
|
||||
* cannot reach manual mode (and this UX) without explicit transaction control
|
||||
* (#9018). Family members like doris/kingbase join only when their transaction
|
||||
|
||||
@@ -68,7 +68,7 @@ const DATABASE_TYPE_OBJECTS = new Map<DatabaseType, SidebarObjectKind[]>([
|
||||
["duckdb", TABLE_VIEW_OBJECTS],
|
||||
["clickhouse", TABLE_VIEW_OBJECTS],
|
||||
// Doris: backend listing path still uses the generic SHOW TABLES path (see
|
||||
// `list_tables_once` for `PoolKind::Mysql` in crates/dbx-core/src/schema.rs)
|
||||
// `list_tables_once` for `PoolKind::Mysql` in crates/dbx-core/src/schema/mod.rs)
|
||||
// and lacks a MV classifier. Keep Doris on TABLE_VIEW_OBJECTS until a
|
||||
// Doris-specific MV listing/classification lands, otherwise the UI advertises
|
||||
// MV support that the backend cannot route.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Read/write classification for Elasticsearch-compatible REST requests.
|
||||
*
|
||||
* Mirrors `classify_search_engine_query_risk` in
|
||||
* `crates/dbx-core/src/query_execution_sql.rs` so the desktop guards (read-only
|
||||
* `crates/dbx-sql/src/query_execution_sql.rs` so the desktop guards (read-only
|
||||
* unlock, production safety) agree with the backend read-only gate instead of
|
||||
* treating every `GET`/`POST` request as an unrecognized — and therefore
|
||||
* unsafe — statement.
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { PluginFieldCondition, PluginFormField, PluginFormFieldValue } from
|
||||
|
||||
/**
|
||||
* Canonical string form of a form value, matching the Rust host
|
||||
* (`condition_value_text` in `crates/dbx-core/src/plugins/manifest.rs`).
|
||||
* (`condition_value_text` in `crates/dbx-plugin-runtime/src/plugins/manifest.rs`).
|
||||
* `false` renders as `"false"` and `22.0` as `"22"`.
|
||||
*/
|
||||
export function pluginConditionValueText(value: PluginFormFieldValue): string {
|
||||
|
||||
@@ -243,7 +243,7 @@ export class PluginHostBridge {
|
||||
/**
|
||||
* Parse `host.network:<origin>` permission entries into CSP connect-src
|
||||
* origins. Must stay aligned with `parse_host_network_permission` in
|
||||
* crates/dbx-core/src/plugins/manifest.rs.
|
||||
* crates/dbx-plugin-runtime/src/plugins/manifest.rs.
|
||||
*/
|
||||
export function pluginNetworkOrigins(permissions: readonly string[] | undefined): string[] {
|
||||
const origins = new Set<string>();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Mirrors dbx-core `redis_database_index()` (crates/dbx-core/src/db/redis_driver.rs):
|
||||
// Mirrors dbx-core `redis_database_index()` (crates/dbx-drivers/src/db/redis_driver.rs):
|
||||
// a Redis database is a numeric index. Anything else (e.g. redis-cli flags like
|
||||
// "0 --tls --insecure" pasted into the field or imported from a dirty URL) fails
|
||||
// to parse on the backend and silently falls back to db 0, so every frontend
|
||||
|
||||
@@ -151,7 +151,7 @@ export function resolveNewQueryTable(input: ResolveNewQueryTableInput): NewQuery
|
||||
*
|
||||
* Time-series engines get the same rolling-window scoping the sidebar
|
||||
* quick-open uses (see `default_time_series_predicate` in
|
||||
* `crates/dbx-core/src/sql_dialect/table_select.rs`). Without a `time`
|
||||
* `crates/dbx-sql/src/sql_dialect/table_select.rs`). Without a `time`
|
||||
* predicate InfluxDB scans every shard (v1/v2) or every Parquet file
|
||||
* (v3), which turns "let me draft a query against this table" into a
|
||||
* full-history scan the moment the user hits Run. VictoriaMetrics
|
||||
|
||||
Reference in new issue
Block a user