diff --git a/client/.env b/client/.env index 94adcae..6f02e43 100644 --- a/client/.env +++ b/client/.env @@ -1,3 +1,5 @@ -VITE_API_URL="http://localhost:8080/api" +VITE_API_PORT=8080 +VITE_API_URL="http://localhost:$VITE_API_PORT/api" +VITE_WEBSOCKET_URL="ws://localhost:$VITE_API_PORT/ws" VITE_APP_NAME="Launchr Web UI" -VITE_API_POLL_INTERVAL=3000 \ No newline at end of file +VITE_API_POLL_INTERVAL=3000 diff --git a/client/package.json b/client/package.json index 22ec5ba..1d42d92 100644 --- a/client/package.json +++ b/client/package.json @@ -82,7 +82,8 @@ "ts-jest": "^29.2.4", "ts-node": "^10.9.2", "typescript": "^4.9.5", - "vite": "^5.2.12" + "vite": "^5.2.12", + "vite-plugin-env-compatible": "^2.0.1" }, "scripts": { "lint": "eslint .", diff --git a/client/src/App.tsx b/client/src/App.tsx index 67f0355..3d96b9e 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -24,8 +24,9 @@ import { ActionList, ActionShow } from './pages/actions' import { FlowShow } from './pages/flow' import { dataProvider as launchrDataProvider } from './rest-data-provider' import { ThemeProvider } from './ThemeProvider' +import { getApiUrl } from './utils/app-urls-resolver' -const apiUrl = import.meta.env.VITE_API_URL +const apiUrl = getApiUrl() export function App() { return ( diff --git a/client/src/index.tsx b/client/src/index.tsx index 8a1f627..bb06a06 100644 --- a/client/src/index.tsx +++ b/client/src/index.tsx @@ -2,6 +2,7 @@ import './I18n' import * as React from 'react' import { createRoot } from 'react-dom/client' + import { App } from './App' const container = document.getElementById('root') as HTMLElement diff --git a/client/src/live-provider/index.ts b/client/src/live-provider/index.ts index fa06500..abbdd47 100644 --- a/client/src/live-provider/index.ts +++ b/client/src/live-provider/index.ts @@ -5,7 +5,9 @@ import { w3cwebsocket as W3CWebSocket, } from 'websocket' -const websocketUrl = 'ws://localhost:8080/ws' +import { getWebSocketUrl } from '../utils/app-urls-resolver' + +const websocketUrl = getWebSocketUrl() let actionsSocket = new W3CWebSocket(websocketUrl) const reconnectInterval = 5000 diff --git a/client/src/utils/app-urls-resolver.ts b/client/src/utils/app-urls-resolver.ts new file mode 100644 index 0000000..979222f --- /dev/null +++ b/client/src/utils/app-urls-resolver.ts @@ -0,0 +1,37 @@ +const isProductionMode = import.meta.env.MODE === 'production' +const addDefaultPort = (protocol: string) => + protocol === 'https:' ? ':433' : ':80' + +export function getApiUrl() { + let url = import.meta.env.VITE_API_URL + + if (isProductionMode) { + const { location } = window + url = location.origin + + if (!location.port) { + url += addDefaultPort(location.protocol) + } + + url += '/api' + } + + return url +} + +export function getWebSocketUrl() { + let url = import.meta.env.VITE_WEBSOCKET_URL + + if (isProductionMode) { + const { location } = window + url = location.protocol === 'https:' ? 'wss://' : 'ws://' + url += location.host + if (!location.port) { + url += addDefaultPort(location.protocol) + } + + url += '/ws' + } + + return url +} diff --git a/client/vite.config.ts b/client/vite.config.ts index ae74518..11f1730 100644 --- a/client/vite.config.ts +++ b/client/vite.config.ts @@ -1,6 +1,7 @@ import react from '@vitejs/plugin-react' import { defineConfig } from 'vite' +import env from 'vite-plugin-env-compatible' export default defineConfig({ - plugins: [react()], + plugins: [react(), env()], }) diff --git a/client/yarn.lock b/client/yarn.lock index 76a24f6..ada0397 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -6207,6 +6207,20 @@ __metadata: languageName: node linkType: hard +"dotenv-expand@npm:5.1.0": + version: 5.1.0 + resolution: "dotenv-expand@npm:5.1.0" + checksum: 10c0/24ac633de853ef474d0421cc639328b7134109c8dc2baaa5e3afb7495af5e9237136d7e6971e55668e4dce915487eb140967cdd2b3e99aa439e0f6bf8b56faeb + languageName: node + linkType: hard + +"dotenv@npm:8.2.0": + version: 8.2.0 + resolution: "dotenv@npm:8.2.0" + checksum: 10c0/b6a07a2c400b13ad4e59c34e4682256e6bb846469781a3963b36861ee608ed312e6125c4a7635a9edcf957bb294a6966e218f0e26b82ff0bda9184211d4bc141 + languageName: node + linkType: hard + "dotenv@npm:^16.0.3": version: 16.4.5 resolution: "dotenv@npm:16.4.5" @@ -9431,6 +9445,7 @@ __metadata: ts-node: "npm:^10.9.2" typescript: "npm:^4.9.5" vite: "npm:^5.2.12" + vite-plugin-env-compatible: "npm:^2.0.1" websocket: "npm:^1.0.35" languageName: unknown linkType: soft @@ -13105,6 +13120,16 @@ __metadata: languageName: node linkType: hard +"vite-plugin-env-compatible@npm:^2.0.1": + version: 2.0.1 + resolution: "vite-plugin-env-compatible@npm:2.0.1" + dependencies: + dotenv: "npm:8.2.0" + dotenv-expand: "npm:5.1.0" + checksum: 10c0/356ddda4d9d8d3e26053392cba374f9bdc0804c74816eb88d2384df817c921d697519bad272feffcfb4fa8dda38a5ea7f8a6802eaf4fd65caa74171c9df6ff12 + languageName: node + linkType: hard + "vite@npm:^5.2.12": version: 5.3.5 resolution: "vite@npm:5.3.5"