Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
f187845
refact: Improved UI
Yashh56 Jun 20, 2026
9166184
feat: implemented model selection in bridge services
Yashh56 Jun 20, 2026
b7e7123
feat: implemented model selection UI
Yashh56 Jun 20, 2026
f818df2
feat: implemented persistance storage for LLMs API keys
Yashh56 Jun 20, 2026
acc1a3e
fix: fixed cache issue while getting response from llms
Yashh56 Jun 21, 2026
45b0e9a
feat: added skeletons on the loading and improved file structure for …
Yashh56 Jun 21, 2026
85bfce5
feat: add utility functions for formatting database types, durations,…
Yashh56 Jun 21, 2026
bc90a3d
feat: added formatTimestamp for TimeStamp columns
Yashh56 Jun 21, 2026
6069f95
feat: enhance the loaders and timestamp func
Yashh56 Jun 21, 2026
c2e8f46
Merge pull request #79 from Yashh56/Yashh56/fix
Yashh56 Jun 22, 2026
b4a92c3
feat(bridge): implement LRU cache and improve connector stability
Yashh56 Jun 23, 2026
05059ca
fix(bridge): resolve flaky dbStore test and improve error handling
Yashh56 Jun 23, 2026
cb06233
refactor(ui): extract DatabasePreview and reorganize hooks
Yashh56 Jun 23, 2026
6fe7cc9
feat(ui): add read-only mode for discovered databases
Yashh56 Jun 23, 2026
9d9515a
feat: block ctrl+f
Yashh56 Jun 24, 2026
63413fe
fix: fixed cache issue and SQL Workspace UI improvement
Yashh56 Jun 24, 2026
29ca8a3
refact: enhance the preview of the new files
Yashh56 Jun 24, 2026
87e0b8e
refact: added autoComplete and spellCheck to off
Yashh56 Jun 24, 2026
a95773e
fix: resolve migration table creation error
Yashh56 Jun 25, 2026
c075f2d
refact: added className in sonner and invalidateQueries for table and…
Yashh56 Jun 25, 2026
e6f5665
refac: rm handle push functionality added revert functionality
Yashh56 Jun 30, 2026
a0e249e
Merge pull request #80 from Yashh56/Yashh56/fix
Yashh56 Jun 30, 2026
235c207
fix: sqlite path resolution for linux
Yashh56 Jun 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions bridge/__tests__/connectors/sqlite.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ describe("SQLite Connector", () => {
const connection = await sqliteConnector.testConnection({ path: tmpDir });
expect(connection.ok).toBe(false);
expect(connection.status).toBe("disconnected");
expect(connection.message).toContain("directory");
expect(connection.message).toContain("must have a valid SQLite extension");
});
});

Expand Down Expand Up @@ -261,7 +261,7 @@ describe("SQLite Connector", () => {
expect(stats).toHaveProperty("total_db_size_mb");
expect(stats).toHaveProperty("total_rows");
expect(stats.total_tables).toBeGreaterThanOrEqual(2);
expect(stats.total_rows).toBeGreaterThan(0);
expect(stats.total_rows).toBe(-1);
});
});

Expand Down
4 changes: 2 additions & 2 deletions bridge/__tests__/dbStore.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const TEST_CONFIG_FILE = path.join(TEST_CONFIG_FOLDER, "databases.json");
const TEST_CREDENTIALS_FILE = path.join(TEST_CONFIG_FOLDER, ".credentials");

// Short TTL for testing cache expiration
const SHORT_CACHE_TTL = 200; // 200ms for testing
const SHORT_CACHE_TTL = 1000; // 200ms for testing
const NORMAL_CACHE_TTL = 30000; // 30 seconds

const mockDBPayload = {
Expand Down Expand Up @@ -223,7 +223,7 @@ describe("DbStore Cache Tests", () => {
expect(shortTtlStore.getCacheStats().configCached).toBe(true);

// Wait for TTL to expire (add extra buffer for system lag)
await new Promise((resolve) => setTimeout(resolve, SHORT_CACHE_TTL + 150));
await new Promise((resolve) => setTimeout(resolve, SHORT_CACHE_TTL + 500));

// Cache should be expired now
expect(shortTtlStore.getCacheStats().configCached).toBe(false);
Expand Down
4 changes: 2 additions & 2 deletions bridge/__tests__/discoveryService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ describe("DiscoveryService", () => {
// Actual discovery depends on system state
const result = await service.discoverLocalDatabases();
expect(Array.isArray(result)).toBe(true);
});
}, 30000); // Increased timeout for docker commands

test("each discovered database should have required fields", async () => {
const result = await service.discoverLocalDatabases();
Expand All @@ -355,6 +355,6 @@ describe("DiscoveryService", () => {
expect(db.defaultUser).toBeDefined();
expect(db.defaultDatabase).toBeDefined();
}
});
}, 30000); // Increased timeout for docker commands
});
});
8 changes: 5 additions & 3 deletions bridge/src/ai/providers/anthropic.provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ const DEFAULT_MODEL = "claude-3-5-haiku-20241022";

export class AnthropicProvider implements AIProvider {
private client: Anthropic;
private model: string;

constructor(apiKey: string) {
constructor(apiKey: string, model?: string) {
this.client = new Anthropic({ apiKey });
this.model = model?.trim() || DEFAULT_MODEL;
}

private async complete(system: string, user: string): Promise<string> {
try {
const msg = await this.client.messages.create({
model: DEFAULT_MODEL,
model: this.model,
max_tokens: 4096,
system,
messages: [{ role: "user", content: user }],
Expand Down Expand Up @@ -53,7 +55,7 @@ export class AnthropicProvider implements AIProvider {
async testConnection(): Promise<string> {
try {
await this.client.messages.create({
model: DEFAULT_MODEL,
model: this.model,
max_tokens: 10,
messages: [{ role: "user", content: "ping" }],
});
Expand Down
8 changes: 5 additions & 3 deletions bridge/src/ai/providers/gemini.provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ const DEFAULT_MODEL = "gemini-1.5-flash";

export class GeminiProvider implements AIProvider {
private genAI: GoogleGenerativeAI;
private model: string;

constructor(apiKey: string) {
constructor(apiKey: string, model?: string) {
this.genAI = new GoogleGenerativeAI(apiKey);
this.model = model?.trim() || DEFAULT_MODEL;
}

private async complete(system: string, user: string): Promise<string> {
try {
const model = this.genAI.getGenerativeModel({
model: DEFAULT_MODEL,
model: this.model,
systemInstruction: system,
generationConfig: { maxOutputTokens: 4096 },
});
Expand Down Expand Up @@ -51,7 +53,7 @@ export class GeminiProvider implements AIProvider {

async testConnection(): Promise<string> {
try {
const model = this.genAI.getGenerativeModel({ model: DEFAULT_MODEL });
const model = this.genAI.getGenerativeModel({ model: this.model });
await model.generateContent("ping");
return "";
} catch (err) {
Expand Down
8 changes: 5 additions & 3 deletions bridge/src/ai/providers/groq.provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ const DEFAULT_MODEL = "llama-3.3-70b-versatile";

export class GroqProvider implements AIProvider {
private client: Groq;
private model: string;

constructor(apiKey: string) {
constructor(apiKey: string, model?: string) {
this.client = new Groq({ apiKey });
this.model = model?.trim() || DEFAULT_MODEL;
}

private async complete(system: string, user: string): Promise<string> {
try {
const res = await this.client.chat.completions.create({
model: DEFAULT_MODEL,
model: this.model,
messages: [
{ role: "system", content: system },
{ role: "user", content: user },
Expand Down Expand Up @@ -54,7 +56,7 @@ export class GroqProvider implements AIProvider {
async testConnection(): Promise<string> {
try {
await this.client.chat.completions.create({
model: DEFAULT_MODEL,
model: this.model,
messages: [{ role: "user", content: "ping" }],
max_tokens: 5,
});
Expand Down
8 changes: 5 additions & 3 deletions bridge/src/ai/providers/mistral.provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ const DEFAULT_MODEL = "mistral-small-latest";

export class MistralProvider implements AIProvider {
private client: Mistral;
private model: string;

constructor(apiKey: string) {
constructor(apiKey: string, model?: string) {
this.client = new Mistral({ apiKey });
this.model = model?.trim() || DEFAULT_MODEL;
}

private async complete(system: string, user: string): Promise<string> {
try {
const res = await this.client.chat.complete({
model: DEFAULT_MODEL,
model: this.model,
messages: [
{ role: "system", content: system },
{ role: "user", content: user },
Expand Down Expand Up @@ -60,7 +62,7 @@ export class MistralProvider implements AIProvider {
async testConnection(): Promise<string> {
try {
await this.client.chat.complete({
model: DEFAULT_MODEL,
model: this.model,
messages: [{ role: "user", content: "ping" }],
maxTokens: 5,
});
Expand Down
8 changes: 5 additions & 3 deletions bridge/src/ai/providers/openai.provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ const DEFAULT_MODEL = "gpt-4o-mini";

export class OpenAIProvider implements AIProvider {
private client: OpenAI;
private model: string;

constructor(apiKey: string) {
constructor(apiKey: string, model?: string) {
this.client = new OpenAI({ apiKey });
this.model = model?.trim() || DEFAULT_MODEL;
}

private async complete(system: string, user: string): Promise<string> {
try {
const res = await this.client.chat.completions.create({
model: DEFAULT_MODEL,
model: this.model,
messages: [
{ role: "system", content: system },
{ role: "user", content: user },
Expand Down Expand Up @@ -54,7 +56,7 @@ export class OpenAIProvider implements AIProvider {
async testConnection(): Promise<string> {
try {
await this.client.chat.completions.create({
model: DEFAULT_MODEL,
model: this.model,
messages: [{ role: "user", content: "ping" }],
max_tokens: 5,
});
Expand Down
23 changes: 19 additions & 4 deletions bridge/src/connectors/mariadb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1331,16 +1331,26 @@ export async function ensureMigrationTable(conn: MariaDBConfig) {
const pool = mysql.createPool(createPoolConfig(conn));
const connection = await pool.getConnection();

await connection.query(CREATE_MIGRATION_TABLE);
try {
await connection.query(CREATE_MIGRATION_TABLE);
} finally {
connection.release();
await pool.end();
}
}


export async function hasAnyMigrations(conn: MariaDBConfig): Promise<boolean> {
const pool = mysql.createPool(createPoolConfig(conn));
const connection = await pool.getConnection();

const [rows] = await connection.query<any[]>(CHECK_MIGRATIONS_EXIST);
return rows.length > 0;
try {
const [rows] = await connection.query<any[]>(CHECK_MIGRATIONS_EXIST);
return rows.length > 0;
} finally {
connection.release();
await pool.end();
}
}


Expand All @@ -1353,7 +1363,12 @@ export async function insertBaseline(
const pool = mysql.createPool(createPoolConfig(conn));
const connection = await pool.getConnection();

await connection.query(INSERT_MIGRATION, [version, name, checksum]);
try {
await connection.query(INSERT_MIGRATION, [version, name, checksum]);
} finally {
connection.release();
await pool.end();
}
}

export async function baselineIfNeeded(
Expand Down
23 changes: 19 additions & 4 deletions bridge/src/connectors/mysql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1306,16 +1306,26 @@ export async function ensureMigrationTable(conn: MySQLConfig) {
const pool = mysql.createPool(conn);
const connection = await pool.getConnection();

await connection.query(CREATE_MIGRATION_TABLE);
try {
await connection.query(CREATE_MIGRATION_TABLE);
} finally {
connection.release();
await pool.end();
}
}


export async function hasAnyMigrations(conn: MySQLConfig): Promise<boolean> {
const pool = mysql.createPool(conn);
const connection = await pool.getConnection();

const [rows] = await connection.query<any[]>(CHECK_MIGRATIONS_EXIST);
return rows.length > 0;
try {
const [rows] = await connection.query<any[]>(CHECK_MIGRATIONS_EXIST);
return rows.length > 0;
} finally {
connection.release();
await pool.end();
}
}


Expand All @@ -1328,7 +1338,12 @@ export async function insertBaseline(
const pool = mysql.createPool(conn);
const connection = await pool.getConnection();

await connection.query(INSERT_MIGRATION, [version, name, checksum]);
try {
await connection.query(INSERT_MIGRATION, [version, name, checksum]);
} finally {
connection.release();
await pool.end();
}
}

export async function baselineIfNeeded(
Expand Down
Loading
Loading