diff --git a/frontend/package.json b/frontend/package.json index 211704e4ad..065309f233 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -76,11 +76,19 @@ "pretauri-build": "node scripts/build-provisioner.mjs", "predev": "npm run generate-icons", "dev": "vite", + "dev:core": "vite --mode core", + "dev:proprietary": "vite --mode proprietary", + "dev:saas": "vite --mode saas", + "dev:desktop": "vite --mode desktop", "prebuild": "npm run generate-icons", "lint": "npm run lint:eslint && npm run lint:cycles", "lint:eslint": "eslint --max-warnings=0", "lint:cycles": "dpdm src --circular --no-warning --no-tree --exit-code circular:1", "build": "vite build", + "build:core": "vite build --mode core", + "build:proprietary": "vite build --mode proprietary", + "build:saas": "vite build --mode saas", + "build:desktop": "vite build --mode desktop", "preview": "vite preview", "tauri-dev": "tauri dev --no-watch", "tauri-build": "tauri build", @@ -92,8 +100,10 @@ "typecheck": "npm run typecheck:proprietary", "typecheck:core": "tsc --noEmit --project tsconfig.core.json", "typecheck:proprietary": "tsc --noEmit --project tsconfig.proprietary.json", + "typecheck:saas": "tsc --noEmit --project tsconfig.saas.json", "typecheck:desktop": "tsc --noEmit --project tsconfig.desktop.json", - "typecheck:all": "npm run typecheck:core && npm run typecheck:proprietary && npm run typecheck:desktop", + "typecheck:scripts": "tsc --noEmit --project scripts/tsconfig.json", + "typecheck:all": "npm run typecheck:core && npm run typecheck:proprietary && npm run typecheck:saas && npm run typecheck:desktop && npm run typecheck:scripts", "check": "npm run typecheck && npm run lint && npm run test:run", "generate-licenses": "node scripts/generate-licenses.js", "generate-icons": "node scripts/generate-icons.js", diff --git a/frontend/tsconfig.saas.json b/frontend/tsconfig.saas.json new file mode 100644 index 0000000000..75e445883b --- /dev/null +++ b/frontend/tsconfig.saas.json @@ -0,0 +1,20 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "paths": { + "@app/*": [ + "src/saas/*", + "src/proprietary/*", + "src/core/*" + ], + "@proprietary/*": ["src/proprietary/*"], + "@core/*": ["src/core/*"] + } + }, + "include": [ + "src/*.js", + "src/*.ts", + "src/*.tsx", + "src/saas" + ] +} diff --git a/frontend/tsconfig.saas.vite.json b/frontend/tsconfig.saas.vite.json new file mode 100644 index 0000000000..843368ca75 --- /dev/null +++ b/frontend/tsconfig.saas.vite.json @@ -0,0 +1,22 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "paths": { + "@app/*": [ + "src/saas/*", + "src/proprietary/*", + "src/core/*" + ], + "@proprietary/*": ["src/proprietary/*"], + "@core/*": ["src/core/*"] + } + }, + "exclude": [ + "src/core/**/*.test.ts*", + "src/core/**/*.spec.ts*", + "src/proprietary/**/*.test.ts*", + "src/proprietary/**/*.spec.ts*", + "src/desktop", + "node_modules" + ] +} diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 02fc41a8ca..cbee5f9956 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -4,6 +4,16 @@ import tsconfigPaths from 'vite-tsconfig-paths'; import { viteStaticCopy } from 'vite-plugin-static-copy'; import path from 'path'; +const VALID_MODES = ['core', 'proprietary', 'saas', 'desktop'] as const; +type BuildMode = typeof VALID_MODES[number]; + +const TSCONFIG_MAP: Record = { + core: './tsconfig.core.vite.json', + proprietary: './tsconfig.proprietary.vite.json', + saas: './tsconfig.saas.vite.json', + desktop: './tsconfig.desktop.vite.json', +}; + export default defineConfig(({ mode }) => { // Load env file based on `mode` in the current working directory. @@ -11,15 +21,15 @@ export default defineConfig(({ mode }) => { // `VITE_` prefix. const env = loadEnv(mode, process.cwd(), '') - // When DISABLE_ADDITIONAL_FEATURES is false (or unset), enable proprietary features - const isProprietary = process.env.DISABLE_ADDITIONAL_FEATURES !== 'true'; - const isDesktopMode = - mode === 'desktop' || - env.STIRLING_DESKTOP === 'true' || - env.VITE_DESKTOP === 'true'; + // Resolve the effective build mode. + // Explicit --mode flags take precedence; otherwise default to proprietary + // unless DISABLE_ADDITIONAL_FEATURES=true, in which case default to core. + const effectiveMode: BuildMode = (VALID_MODES as readonly string[]).includes(mode) + ? (mode as BuildMode) + : process.env.DISABLE_ADDITIONAL_FEATURES === 'true' ? 'core' : 'proprietary'; // Validate required environment variables for desktop builds - if (isDesktopMode) { + if (effectiveMode === 'desktop') { const requiredEnvVars = [ 'VITE_SAAS_SERVER_URL', 'VITE_SUPABASE_PUBLISHABLE_DEFAULT_KEY', @@ -35,9 +45,7 @@ export default defineConfig(({ mode }) => { } } - const baseProject = isProprietary ? './tsconfig.proprietary.vite.json' : './tsconfig.core.vite.json'; - const desktopProject = isProprietary ? './tsconfig.desktop.vite.json' : baseProject; - const tsconfigProject = isDesktopMode ? desktopProject : baseProject; + const tsconfigProject = TSCONFIG_MAP[effectiveMode]; return { plugins: [ @@ -71,7 +79,7 @@ export default defineConfig(({ mode }) => { ignored: ['**/src-tauri/**'], }, // Only use proxy in web mode - Tauri handles backend connections directly - proxy: isDesktopMode ? undefined : { + proxy: effectiveMode === 'desktop' ? undefined : { '/api': { target: 'http://localhost:8080', changeOrigin: true,