diff --git a/app/package.json b/app/package.json index 340715892..92d8e534f 100644 --- a/app/package.json +++ b/app/package.json @@ -25,9 +25,10 @@ "homepage": "./", "scripts": { "start": "cross-env ELECTRON_START_URL=http://localhost:5000 electron .", + "start:local": "cross-env electron .", "dist": "electron-builder", "build": "cd ../packages/api && yarn build && cd ../web && yarn build:app && cd ../../app && yarn dist", - "wait-electron": "node src/electron-wait-react", + "build:local": "cd ../packages/api && yarn build && cd ../web && yarn build:app && cd ../../app && yarn predist", "postinstall": "electron-builder install-app-deps", "predist": "copyfiles ../packages/api/dist/* packages && copyfiles \"../packages/web/build/*\" packages && copyfiles \"../packages/web/build/**/*\" packages" }, diff --git a/app/src/electron-wait-react.js b/app/src/electron-wait-react.js deleted file mode 100644 index 3e8cc63ac..000000000 --- a/app/src/electron-wait-react.js +++ /dev/null @@ -1,27 +0,0 @@ -const net = require('net'); -const port = 5000; - -process.env.ELECTRON_START_URL = `http://localhost:${port}`; - -const client = new net.Socket(); - -let startedElectron = false; -const tryConnection = () => client.connect({port: port}, () => { - client.end(); - if(!startedElectron) { - console.log('starting electron'); - startedElectron = true; - const exec = require('child_process').exec; - const electron = exec('yarn electron'); - electron.stdout.on("data", function(data) { - console.log("stdout: " + data.toString()); - }); - } - } -); - -tryConnection(); - -client.on('error', (error) => { - setTimeout(tryConnection, 1000); -}); diff --git a/app/src/electron.js b/app/src/electron.js index 3818e15e2..1c7dbf6b7 100644 --- a/app/src/electron.js +++ b/app/src/electron.js @@ -14,18 +14,37 @@ let mainWindow; function createWindow() { // Create the browser window. - mainWindow = new BrowserWindow({ width: 800, height: 600 }); + mainWindow = new BrowserWindow({ + width: 800, + height: 600, + webPreferences: { + nodeIntegration: true, + }, + }); - const apiProcess = fork(path.join(__dirname, '../packages/api/dist/bundle.js')); + function loadMainWindow() { + const startUrl = + process.env.ELECTRON_START_URL || + url.format({ + pathname: path.join(__dirname, '../packages/web/build/index.html'), + protocol: 'file:', + slashes: true, + }); + mainWindow.loadURL(startUrl); + } - const startUrl = - process.env.ELECTRON_START_URL || - url.format({ - pathname: path.join(__dirname, '../packages/web/build/index.html'), - protocol: 'file:', - slashes: true, + if (process.env.ELECTRON_START_URL) { + loadMainWindow(); + } else { + const apiProcess = fork(path.join(__dirname, '../packages/api/dist/bundle.js'), ['--dynport']); + apiProcess.on('message', (msg) => { + if (msg.msgtype == 'listening') { + const { port } = msg; + global['port'] = port; + loadMainWindow(); + } }); - mainWindow.loadURL(startUrl); + } // and load the index.html of the app. // mainWindow.loadURL('http://localhost:3000'); @@ -34,7 +53,7 @@ function createWindow() { // mainWindow.webContents.openDevTools(); // Emitted when the window is closed. - mainWindow.on('closed', function() { + mainWindow.on('closed', function () { // Dereference the window object, usually you would store windows // in an array if your app supports multi windows, this is the time // when you should delete the corresponding element. @@ -48,7 +67,7 @@ function createWindow() { app.on('ready', createWindow); // Quit when all windows are closed. -app.on('window-all-closed', function() { +app.on('window-all-closed', function () { // On OS X it is common for applications and their menu bar // to stay active until the user quits explicitly with Cmd + Q if (process.platform !== 'darwin') { @@ -56,7 +75,7 @@ app.on('window-all-closed', function() { } }); -app.on('activate', function() { +app.on('activate', function () { // On OS X it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. if (mainWindow === null) { diff --git a/package.json b/package.json index 2c54437c9..8d2dabe31 100644 --- a/package.json +++ b/package.json @@ -16,10 +16,12 @@ "build:lib": "yarn build:sqltree && yarn build:filterparser && yarn build:datalib", "build:app": "cd app && yarn install && yarn build", "build:api": "yarn workspace @dbgate/api build", - "build:web": "yarn workspace @dbgate/web build", + "build:web:docker": "yarn workspace @dbgate/web build:docker", + "build:app:local": "cd app && yarn build:local", + "start:app:local": "cd app && yarn start:local", "copy:docker:build": "copyfiles packages/api/dist/* docker -f && copyfiles packages/web/build/* docker -u 2 && copyfiles \"packages/web/build/**/*\" docker -u 2", - "prepare:docker": "yarn build:web && yarn build:api && yarn copy:docker:build", + "prepare:docker": "yarn build:web:docker && yarn build:api && yarn copy:docker:build", "prepare": "yarn build:lib", "start": "concurrently --kill-others-on-fail \"yarn start:api\" \"yarn start:web\"", diff --git a/packages/api/package.json b/packages/api/package.json index 4f02db9e5..081ab2293 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -12,6 +12,7 @@ "cross-env": "^6.0.3", "eslint": "^6.8.0", "express": "^4.17.1", + "find-free-port": "^2.0.0", "fs-extra": "^8.1.0", "http": "^0.0.0", "line-reader": "^0.4.0", diff --git a/packages/api/src/index.js b/packages/api/src/index.js index 4bbcc39bd..a0e1c7543 100644 --- a/packages/api/src/index.js +++ b/packages/api/src/index.js @@ -5,14 +5,14 @@ // "uuid": "^3.4.0", // "uws": "10.148.1" -const processName = process.argv[2]; -if (processName && processName.endsWith('Process')) { +const argument = process.argv[2]; +if (argument && argument.endsWith('Process')) { const proc = require('./proc'); - const module = proc[processName]; + const module = proc[argument]; module.start(); } else { const main = require('./main'); - main.start(); + main.start(argument); } diff --git a/packages/api/src/main.js b/packages/api/src/main.js index 42a4e59dc..a7604c1a0 100644 --- a/packages/api/src/main.js +++ b/packages/api/src/main.js @@ -4,6 +4,7 @@ const http = require('http'); const cors = require('cors'); const io = require('socket.io'); const fs = require('fs'); +const findFreePort = require('find-free-port'); const useController = require('./utility/useController'); const socket = require('./utility/socket'); @@ -15,7 +16,7 @@ const tables = require('./controllers/tables'); const sessions = require('./controllers/sessions'); const jsldata = require('./controllers/jsldata'); -function start() { +function start(argument = null) { console.log('process.argv', process.argv); const app = express(); @@ -42,7 +43,16 @@ function start() { }); } - server.listen(3000); + if (argument == '--dynport') { + findFreePort(53911, function (err, port) { + server.listen(port, () => { + console.log(`DbGate API listening on port ${port}`); + process.send({ msgtype: 'listening', port }); + }); + }); + } else { + server.listen(3000); + } } module.exports = { start }; diff --git a/packages/web/package.json b/packages/web/package.json index 5a6dba4eb..30d679055 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -3,6 +3,9 @@ "version": "0.1.0", "private": true, "dependencies": { + "@dbgate/datalib": "^0.1.0", + "@dbgate/engines": "^0.1.0", + "@dbgate/sqltree": "^0.1.0", "@testing-library/jest-dom": "^4.2.4", "@testing-library/react": "^9.3.2", "@testing-library/user-event": "^7.1.2", @@ -21,14 +24,11 @@ "resize-observer-polyfill": "^1.5.1", "socket.io-client": "^2.3.0", "styled-components": "^4.4.1", - "uuid": "^3.4.0", - "@dbgate/sqltree": "^0.1.0", - "@dbgate/datalib": "^0.1.0", - "@dbgate/engines": "^0.1.0" + "uuid": "^3.4.0" }, "scripts": { "start": "cross-env BROWSER=none PORT=5000 react-scripts start", - "build": "cross-env CI=false react-scripts build", + "build:docker": "cross-env CI=false REACT_APP_API_URL=ORIGIN react-scripts build", "build:app": "cross-env PUBLIC_URL=. CI=false react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", @@ -47,8 +47,8 @@ ] }, "devDependencies": { - "@fortawesome/fontawesome-free": "^5.12.0", "@dbgate/types": "^0.1.0", + "@fortawesome/fontawesome-free": "^5.12.0", "@types/react": "^16.9.17", "@types/styled-components": "^4.4.2", "typescript": "^3.7.4" diff --git a/packages/web/src/utility/SocketProvider.js b/packages/web/src/utility/SocketProvider.js index 1a7740735..72797f9a3 100644 --- a/packages/web/src/utility/SocketProvider.js +++ b/packages/web/src/utility/SocketProvider.js @@ -1,5 +1,6 @@ import io from 'socket.io-client'; import React from 'react'; +import resolveApi from './resolveApi'; const SocketContext = React.createContext(null); @@ -7,7 +8,7 @@ export function SocketProvider({ children }) { const [socket, setSocket] = React.useState(); React.useEffect(() => { // const newSocket = io('http://localhost:3000', { transports: ['websocket'] }); - const newSocket = io('http://localhost:3000'); + const newSocket = io(resolveApi()); setSocket(newSocket); }, []); return {children}; diff --git a/packages/web/src/utility/axios.js b/packages/web/src/utility/axios.js index bb2629326..fb26c04df 100644 --- a/packages/web/src/utility/axios.js +++ b/packages/web/src/utility/axios.js @@ -1,5 +1,6 @@ import axios from 'axios'; +import resolveApi from './resolveApi'; export default axios.create({ - baseURL: 'http://localhost:3000', + baseURL: resolveApi(), }); diff --git a/packages/web/src/utility/resolveApi.js b/packages/web/src/utility/resolveApi.js new file mode 100644 index 000000000..2fe739d6b --- /dev/null +++ b/packages/web/src/utility/resolveApi.js @@ -0,0 +1,19 @@ +export default function resolveApi() { + if (window.require) { + const electron = window.require('electron'); + + if (electron) { + const port = electron.remote.getGlobal('port'); + return `http://localhost:${port}`; + } + } + + // eslint-disable-next-line + const apiUrl = process.env.REACT_APP_API_URL; + if (apiUrl) { + if (apiUrl == 'ORIGIN') return window.location.origin; + return apiUrl; + } + + return 'http://localhost:3000'; +} diff --git a/yarn.lock b/yarn.lock index 1397f47b3..b1279a03b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4876,6 +4876,11 @@ find-cache-dir@^3.0.0: make-dir "^3.0.0" pkg-dir "^4.1.0" +find-free-port@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/find-free-port/-/find-free-port-2.0.0.tgz#4b22e5f6579eb1a38c41ac6bcb3efed1b6da9b1b" + integrity sha1-SyLl9leesaOMQaxryz7+0bbamxs= + find-up@4.1.0, find-up@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"