Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions apps/admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@trpc/server": "^11.7.1",
"@trpc/tanstack-react-query": "^11.7.1",
"date-fns": "^4.1.0",
"drizzle-orm": "0.45.1",
"import-in-the-middle": "2.0.1",
"next": "^16.0.10",
"next-themes": "^0.4.6",
Expand Down
3 changes: 2 additions & 1 deletion apps/admin/src/proxy.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { clerkMiddleware } from "@clerk/nextjs/server";
import { db, eq } from "@superset/db";
import { db } from "@superset/db/client";
import { users } from "@superset/db/schema";
import { COMPANY } from "@superset/shared/constants";
import { eq } from "drizzle-orm";
import { NextResponse } from "next/server";

import { env } from "./env";
Expand Down
14 changes: 13 additions & 1 deletion apps/desktop/electron-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const config: Configuration = {
// ASAR configuration for native modules and external resources
asar: true,
asarUnpack: [
"**/node_modules/better-sqlite3/**/*",
"**/node_modules/node-pty/**/*",
// Sound files must be unpacked so external audio players (afplay, paplay, etc.) can access them
"**/resources/sounds/**/*",
Expand All @@ -46,9 +47,20 @@ const config: Configuration = {
to: "resources",
filter: ["**/*"],
},
// Native module that can't be bundled by Vite.
// Database migrations from local-db package (copied to dist/resources/migrations by vite)
{
from: "dist/resources/migrations",
to: "resources/migrations",
filter: ["**/*"],
},
// Native modules that can't be bundled by Vite.
// The copy:native-modules script replaces symlinks with real files
// before building (required for Bun 1.3+ isolated installs).
{
from: "node_modules/better-sqlite3",
to: "node_modules/better-sqlite3",
filter: ["**/*"],
},
{
from: "node_modules/node-pty",
to: "node_modules/node-pty",
Expand Down
32 changes: 24 additions & 8 deletions apps/desktop/electron.vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,31 @@ function copyResourcesPlugin(): Plugin {
return {
name: "copy-resources",
writeBundle() {
const srcDir = resolve(resources, "sounds");
const destDir = resolve(devPath, "resources/sounds");
// Copy sounds
const soundsSrc = resolve(resources, "sounds");
const soundsDest = resolve(devPath, "resources/sounds");

if (existsSync(srcDir)) {
// Clean destination to avoid stale files
if (existsSync(destDir)) {
rmSync(destDir, { recursive: true });
if (existsSync(soundsSrc)) {
if (existsSync(soundsDest)) {
rmSync(soundsDest, { recursive: true });
}
mkdirSync(destDir, { recursive: true });
cpSync(srcDir, destDir, { recursive: true });
mkdirSync(soundsDest, { recursive: true });
cpSync(soundsSrc, soundsDest, { recursive: true });
}

// Copy database migrations from local-db package
const migrationsSrc = resolve(
__dirname,
"../../packages/local-db/drizzle",
);
const migrationsDest = resolve(devPath, "resources/migrations");

if (existsSync(migrationsSrc)) {
if (existsSync(migrationsDest)) {
rmSync(migrationsDest, { recursive: true });
}
mkdirSync(migrationsDest, { recursive: true });
cpSync(migrationsSrc, migrationsDest, { recursive: true });
Comment on lines +50 to +62
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copyResourcesPlugin() copies the entire packages/local-db/drizzle directory into resources/migrations. That directory includes meta/ and possibly other non-migration artifacts, and the migrator generally expects SQL migration files (and possibly a meta folder depending on how you run it).

This may work today but is brittle: any future generated artifacts in drizzle/ will get packaged into the app resources unnecessarily. Also, the code comment says these are “migrations”, but you’re actually copying the whole Drizzle output folder.

At minimum, consider copying only *.sql (and whatever the migrator truly requires).

Suggestion

Narrow the copy filter to expected files, e.g.:

cpSync(migrationsSrc, migrationsDest, {
  recursive: true,
  filter: (src) => src.endsWith(".sql") || src.includes("meta"),
});

Or keep the Drizzle folder structure but explicitly justify which subfolders are required.

Reply with "@CharlieHelps yes please" if you'd like me to add a commit with this suggestion.

}
},
};
Expand Down Expand Up @@ -86,6 +101,7 @@ export default defineConfig({
// Only externalize native modules that can't be bundled
external: [
"electron",
"better-sqlite3", // Native module - must stay external
"node-pty", // Native module - must stay external
],
},
Expand Down
4 changes: 4 additions & 0 deletions apps/desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"@monaco-editor/react": "^4.7.0",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-label": "^2.1.8",
"@superset/local-db": "workspace:*",
"@superset/shared": "workspace:*",
"@superset/trpc": "workspace:*",
"@superset/ui": "workspace:*",
Expand All @@ -57,12 +58,14 @@
"@xterm/addon-web-links": "^0.11.0",
"@xterm/addon-webgl": "^0.18.0",
"@xterm/xterm": "^5.5.0",
"better-sqlite3": "12.5.0",
"clsx": "^2.1.1",
"culori": "^4.0.2",
"date-fns": "^4.1.0",
"default-shell": "^2.2.0",
"dnd-core": "^16.0.1",
"dotenv": "^17.2.3",
"drizzle-orm": "0.45.1",
"electron-router-dom": "^2.1.0",
"electron-updater": "6",
"execa": "^9.6.0",
Expand Down Expand Up @@ -106,6 +109,7 @@
"@biomejs/biome": "^2.3.8",
"@superset/typescript": "workspace:*",
"@tailwindcss/vite": "^4.0.9",
"@types/better-sqlite3": "^7.6.13",
"@types/culori": "^4.0.1",
"@types/http-proxy": "^1.17.17",
"@types/lodash": "^4.17.20",
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/scripts/copy-native-modules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import { cpSync, existsSync, lstatSync, realpathSync, rmSync } from "node:fs";
import { dirname, join } from "node:path";

const NATIVE_MODULES = ["node-pty"] as const;
const NATIVE_MODULES = ["better-sqlite3", "node-pty"] as const;

function prepareNativeModules() {
console.log("Preparing native modules for electron-builder...");
Expand Down
34 changes: 21 additions & 13 deletions apps/desktop/src/lib/trpc/routers/changes/branches.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { db } from "main/lib/db";
import { worktrees } from "@superset/local-db";
import { eq } from "drizzle-orm";
import { localDb } from "main/lib/local-db";
import simpleGit from "simple-git";
import { z } from "zod";
import { publicProcedure, router } from "../..";
Expand Down Expand Up @@ -59,24 +61,30 @@ export const createBranchesRouter = () => {
.mutation(async ({ input }): Promise<{ success: boolean }> => {
const git = simpleGit(input.worktreePath);

const worktree = db.data.worktrees.find(
(wt) => wt.path === input.worktreePath,
);
const worktree = localDb
.select()
.from(worktrees)
.where(eq(worktrees.path, input.worktreePath))
.get();
if (!worktree) {
throw new Error(`No worktree found at path "${input.worktreePath}"`);
}

await git.checkout(input.branch);

await db.update((data) => {
const wt = data.worktrees.find((w) => w.path === input.worktreePath);
if (wt) {
wt.branch = input.branch;
if (wt.gitStatus) {
wt.gitStatus.branch = input.branch;
}
}
});
// Update the branch in the worktree record
const gitStatus = worktree.gitStatus
? { ...worktree.gitStatus, branch: input.branch }
: null;

localDb
.update(worktrees)
.set({
branch: input.branch,
gitStatus,
})
.where(eq(worktrees.path, input.worktreePath))
.run();

return { success: true };
}),
Expand Down
35 changes: 24 additions & 11 deletions apps/desktop/src/lib/trpc/routers/config/config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { db } from "main/lib/db";
import { projects } from "@superset/local-db";
import { eq } from "drizzle-orm";
import { localDb } from "main/lib/local-db";
import { z } from "zod";
import { publicProcedure, router } from "../..";

Expand Down Expand Up @@ -41,7 +43,11 @@ export const createConfigRouter = () => {
shouldShowConfigToast: publicProcedure
.input(z.object({ projectId: z.string() }))
.query(({ input }) => {
const project = db.data.projects.find((p) => p.id === input.projectId);
const project = localDb
.select()
.from(projects)
.where(eq(projects.id, input.projectId))
.get();
if (!project) {
return false;
}
Expand All @@ -57,21 +63,24 @@ export const createConfigRouter = () => {
// Mark the config toast as dismissed for a project
dismissConfigToast: publicProcedure
.input(z.object({ projectId: z.string() }))
.mutation(async ({ input }) => {
await db.update((data) => {
const project = data.projects.find((p) => p.id === input.projectId);
if (project) {
project.configToastDismissed = true;
}
});
.mutation(({ input }) => {
localDb
.update(projects)
.set({ configToastDismissed: true })
.where(eq(projects.id, input.projectId))
.run();
return { success: true };
}),

// Get the config file path (creates it if it doesn't exist)
getConfigFilePath: publicProcedure
.input(z.object({ projectId: z.string() }))
.query(({ input }) => {
const project = db.data.projects.find((p) => p.id === input.projectId);
const project = localDb
.select()
.from(projects)
.where(eq(projects.id, input.projectId))
.get();
if (!project) {
return null;
}
Expand All @@ -82,7 +91,11 @@ export const createConfigRouter = () => {
getConfigContent: publicProcedure
.input(z.object({ projectId: z.string() }))
.query(({ input }) => {
const project = db.data.projects.find((p) => p.id === input.projectId);
const project = localDb
.select()
.from(projects)
.where(eq(projects.id, input.projectId))
.get();
if (!project) {
return { content: null, exists: false };
}
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src/lib/trpc/routers/external/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { spawn } from "node:child_process";
import nodePath from "node:path";
import { EXTERNAL_APPS, type ExternalApp } from "main/lib/db/schemas";
import { EXTERNAL_APPS, type ExternalApp } from "@superset/local-db";

/** Map of app IDs to their macOS application names */
const APP_NAMES: Record<ExternalApp, string | null> = {
Expand Down
17 changes: 12 additions & 5 deletions apps/desktop/src/lib/trpc/routers/external/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { settings } from "@superset/local-db";
import { clipboard, shell } from "electron";
import { db } from "main/lib/db";
import { localDb } from "main/lib/local-db";
import { z } from "zod";
import { publicProcedure, router } from "../..";
import {
Expand Down Expand Up @@ -54,9 +55,14 @@ export const createExternalRouter = () => {
}),
)
.mutation(async ({ input }) => {
await db.update((data) => {
data.settings.lastUsedApp = input.app;
});
localDb
.insert(settings)
.values({ id: 1, lastUsedApp: input.app })
.onConflictDoUpdate({
target: settings.id,
set: { lastUsedApp: input.app },
})
.run();
await openPathInApp(input.path, input.app);
}),

Expand All @@ -75,7 +81,8 @@ export const createExternalRouter = () => {
)
.mutation(async ({ input }) => {
const filePath = resolvePath(input.path, input.cwd);
const app = db.data.settings.lastUsedApp ?? "cursor";
const settingsRow = localDb.select().from(settings).get();
const app = settingsRow?.lastUsedApp ?? "cursor";
await openPathInApp(filePath, app);
}),
});
Expand Down
Loading