setup electron app for production
This commit is contained in:
+3
-3
@@ -7,9 +7,9 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "electron-forge start",
|
||||
"package": "electron-forge package --arch=arm64 && electron-forge package --arch=x64",
|
||||
"make": "electron-forge make --arch=arm64 && electron-forge make --arch=x64",
|
||||
"release": "echo '\n⚠️ Have you bumped the version in package.json? (current: '$(node -p \"require('./package.json').version\")') [y/N]' && read -r answer && [ \"$answer\" = \"y\" ] && electron-forge publish --arch=arm64 && electron-forge publish --arch=x64 && gsutil setmeta -h 'Cache-Control:no-cache, no-store, must-revalidate' gs://flowy-releases/llink/darwin/arm64/RELEASES.json && gsutil setmeta -h 'Cache-Control:no-cache, no-store, must-revalidate' gs://flowy-releases/llink/darwin/x64/RELEASES.json",
|
||||
"package": "APP_ENV=prod electron-forge package --arch=arm64 && APP_ENV=prod electron-forge package --arch=x64",
|
||||
"make": "APP_ENV=prod electron-forge make --arch=arm64 && APP_ENV=prod electron-forge make --arch=x64",
|
||||
"release": "echo '\n⚠️ Have you bumped the version in package.json? (current: '$(node -p \"require('./package.json').version\")') [y/N]' && read -r answer && [ \"$answer\" = \"y\" ] && APP_ENV=prod electron-forge publish --arch=arm64 && APP_ENV=prod electron-forge publish --arch=x64 && gsutil setmeta -h 'Cache-Control:no-cache, no-store, must-revalidate' gs://flowy-releases/llink/darwin/arm64/RELEASES.json && gsutil setmeta -h 'Cache-Control:no-cache, no-store, must-revalidate' gs://flowy-releases/llink/darwin/x64/RELEASES.json",
|
||||
"invalidate-gcs-cache": "gsutil -h \"Cache-Control:no-cache, no-store, max-age=0\" cp gs://flowy-releases/llink/darwin/arm64/RELEASES.json gs://flowy-releases/llink/darwin/arm64/RELEASES.json ; gsutil -h \"Cache-Control:no-cache, no-store, max-age=0\" cp gs://flowy-releases/llink/darwin/x64/RELEASES.json gs://flowy-releases/llink/darwin/x64/RELEASES.json",
|
||||
"lint": "eslint --ext .ts,.tsx .",
|
||||
"compile": "npx tsc --noEmit 2>&1 | grep '^src/'"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { appConfig } from "@/config/env";
|
||||
import { useSessionStore } from "@/stores/session-store";
|
||||
import type { z } from "zod";
|
||||
import {
|
||||
@@ -218,7 +219,7 @@ class ApiClient {
|
||||
}
|
||||
|
||||
export const apiClient = new ApiClient({
|
||||
baseUrl: "https://orion.dev.flowy.live",
|
||||
baseUrl: appConfig.orionUrl,
|
||||
getToken: () => useSessionStore.getState().token,
|
||||
onUnauthorized: () => useSessionStore.getState().clearToken(),
|
||||
});
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
// Build-time environment selection.
|
||||
//
|
||||
// __APP_ENV__ is replaced by Vite via `define` in each vite.*.config.ts. Selected
|
||||
// via the APP_ENV env var at build/dev time (defaults to 'dev'). `yarn package`,
|
||||
// `yarn make`, and `yarn release` set APP_ENV=prod.
|
||||
//
|
||||
// Firebase web config is public by design (security is enforced via Firestore
|
||||
// rules + App Check), so both configs live in source. To refresh, run:
|
||||
// cd infra/gcp/{dev,prod} && terraform output -json firebase_config
|
||||
|
||||
declare const __APP_ENV__: "dev" | "prod";
|
||||
|
||||
type FirebaseConfig = {
|
||||
apiKey: string;
|
||||
appId: string;
|
||||
authDomain: string;
|
||||
messagingSenderId: string;
|
||||
projectId: string;
|
||||
storageBucket: string;
|
||||
};
|
||||
|
||||
type AppConfig = {
|
||||
orionUrl: string;
|
||||
pusherUrl: string;
|
||||
firebase: FirebaseConfig;
|
||||
};
|
||||
|
||||
const configs: Record<"dev" | "prod", AppConfig> = {
|
||||
dev: {
|
||||
orionUrl: "https://orion.dev.flowy.live",
|
||||
pusherUrl: "wss://pusher.dev.flowy.live/ws",
|
||||
firebase: {
|
||||
apiKey: "AIzaSyDF_fbk7tDY9tNxUiOwwi--2nYZWZygMGk",
|
||||
appId: "1:1006580076785:web:e2a0736d60a78e02b15950",
|
||||
authDomain: "flowy-dev-440017.firebaseapp.com",
|
||||
messagingSenderId: "1006580076785",
|
||||
projectId: "flowy-dev-440017",
|
||||
storageBucket: "flowy-dev-440017.firebasestorage.app",
|
||||
},
|
||||
},
|
||||
prod: {
|
||||
orionUrl: "https://orion.flowy.live",
|
||||
pusherUrl: "wss://pusher.flowy.live/ws",
|
||||
firebase: {
|
||||
apiKey: "AIzaSyB8it3SKr9DHScHGlpu4uwWicvt8wzjdBg",
|
||||
appId: "1:68063426854:web:5054f16f50898f5706e9e7",
|
||||
authDomain: "flowy-prod-440017.firebaseapp.com",
|
||||
messagingSenderId: "68063426854",
|
||||
projectId: "flowy-prod-440017",
|
||||
storageBucket: "flowy-prod-440017.firebasestorage.app",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const appConfig: AppConfig = configs[__APP_ENV__];
|
||||
export const appEnv: "dev" | "prod" = __APP_ENV__;
|
||||
+2
-10
@@ -1,16 +1,8 @@
|
||||
import { initializeApp } from 'firebase/app';
|
||||
import { getFirestore } from "firebase/firestore";
|
||||
import { appConfig } from "@/config/env";
|
||||
|
||||
const firebaseConfig = {
|
||||
apiKey: "AIzaSyDF_fbk7tDY9tNxUiOwwi--2nYZWZygMGk",
|
||||
appId: "1:1006580076785:web:e2a0736d60a78e02b15950",
|
||||
authDomain: "flowy-dev-440017.firebaseapp.com",
|
||||
messagingSenderId: "1006580076785",
|
||||
projectId: "flowy-dev-440017",
|
||||
storageBucket: "flowy-dev-440017.firebasestorage.app",
|
||||
};
|
||||
|
||||
export const firebaseApp = initializeApp(firebaseConfig);
|
||||
export const firebaseApp = initializeApp(appConfig.firebase);
|
||||
|
||||
export const firestoreDb = getFirestore(firebaseApp);
|
||||
// simplifying setup to debug production issues
|
||||
|
||||
@@ -8,13 +8,11 @@ import {
|
||||
} from "react";
|
||||
import { PusherClient, type ConnectionState } from "./pusher-client";
|
||||
import { useSessionStore } from "@/stores/session-store";
|
||||
import { appConfig } from "@/config/env";
|
||||
|
||||
const PusherContext = createContext<PusherClient | null>(null);
|
||||
const PusherStateContext = createContext<ConnectionState>("disconnected");
|
||||
|
||||
// TODO: make this configurable per environment
|
||||
const PUSHER_URL = "wss://pusher.dev.flowy.live/ws";
|
||||
|
||||
export function PusherProvider({ children }: { children: ReactNode }) {
|
||||
const token = useSessionStore((s) => s.token);
|
||||
const clientRef = useRef<PusherClient | null>(null);
|
||||
@@ -33,7 +31,7 @@ export function PusherProvider({ children }: { children: ReactNode }) {
|
||||
}
|
||||
|
||||
const client = new PusherClient({
|
||||
url: PUSHER_URL,
|
||||
url: appConfig.pusherUrl,
|
||||
getToken: () => useSessionStore.getState().token,
|
||||
});
|
||||
|
||||
|
||||
+2
-1
@@ -4,6 +4,7 @@ import started from 'electron-squirrel-startup';
|
||||
import { updateElectronApp, UpdateSourceType } from 'update-electron-app';
|
||||
|
||||
import type { LinkMetadata } from './lib/link-metadata';
|
||||
import { appConfig } from './config/env';
|
||||
|
||||
if (app.isPackaged) {
|
||||
updateElectronApp({
|
||||
@@ -484,7 +485,7 @@ app.on('ready', () => {
|
||||
// The server doesn't handle OPTIONS preflight, so we intercept at the
|
||||
// Electron network layer: inject CORS headers and return 200 for preflight.
|
||||
session.defaultSession.webRequest.onHeadersReceived(
|
||||
{ urls: ['https://orion.dev.flowy.live/*', 'https://storage.googleapis.com/*'] },
|
||||
{ urls: [`${appConfig.orionUrl}/*`, 'https://storage.googleapis.com/*'] },
|
||||
(details, callback) => {
|
||||
const headers = { ...details.responseHeaders };
|
||||
headers['access-control-allow-origin'] = ['*'];
|
||||
|
||||
@@ -2,6 +2,7 @@ import path from "path"
|
||||
import tailwindcss from "@tailwindcss/vite"
|
||||
import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import { defineEnv } from './vite.env';
|
||||
|
||||
// https://vitejs.dev/config
|
||||
export default defineConfig({
|
||||
@@ -20,4 +21,5 @@ export default defineConfig({
|
||||
allow: [path.resolve(__dirname)],
|
||||
},
|
||||
},
|
||||
define: defineEnv,
|
||||
});
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// Shared Vite `define` block that injects the build-time __APP_ENV__ constant
|
||||
// consumed by src/config/env.ts. Sourced from process.env.APP_ENV (default 'dev').
|
||||
|
||||
const raw = process.env.APP_ENV ?? "dev";
|
||||
if (raw !== "dev" && raw !== "prod") {
|
||||
throw new Error(`APP_ENV must be "dev" or "prod", got: ${raw}`);
|
||||
}
|
||||
|
||||
export const appEnv = raw;
|
||||
|
||||
export const defineEnv = {
|
||||
__APP_ENV__: JSON.stringify(appEnv),
|
||||
};
|
||||
@@ -2,6 +2,7 @@ import path from "path"
|
||||
import tailwindcss from "@tailwindcss/vite"
|
||||
import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import { defineEnv } from './vite.env';
|
||||
|
||||
// https://vitejs.dev/config
|
||||
export default defineConfig({
|
||||
@@ -20,4 +21,5 @@ export default defineConfig({
|
||||
allow: [path.resolve(__dirname)],
|
||||
},
|
||||
},
|
||||
define: defineEnv,
|
||||
});
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { defineConfig } from 'vite';
|
||||
import { defineEnv } from './vite.env';
|
||||
|
||||
// https://vitejs.dev/config
|
||||
export default defineConfig({});
|
||||
export default defineConfig({
|
||||
define: defineEnv,
|
||||
});
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { defineConfig } from 'vite';
|
||||
import { defineEnv } from './vite.env';
|
||||
|
||||
// https://vitejs.dev/config
|
||||
export default defineConfig({});
|
||||
export default defineConfig({
|
||||
define: defineEnv,
|
||||
});
|
||||
|
||||
@@ -2,6 +2,7 @@ import path from "path"
|
||||
import tailwindcss from "@tailwindcss/vite"
|
||||
import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import { defineEnv } from './vite.env';
|
||||
|
||||
// https://vitejs.dev/config
|
||||
export default defineConfig({
|
||||
@@ -11,4 +12,5 @@ export default defineConfig({
|
||||
"@": path.resolve(__dirname, "./src"),
|
||||
},
|
||||
},
|
||||
define: defineEnv,
|
||||
});
|
||||
|
||||
@@ -2,6 +2,7 @@ import path from "path"
|
||||
import tailwindcss from "@tailwindcss/vite"
|
||||
import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import { defineEnv } from './vite.env';
|
||||
|
||||
// https://vitejs.dev/config
|
||||
export default defineConfig({
|
||||
@@ -20,4 +21,5 @@ export default defineConfig({
|
||||
allow: [path.resolve(__dirname)],
|
||||
},
|
||||
},
|
||||
define: defineEnv,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user