diff --git a/api/index.js b/api/index.js new file mode 100644 index 0000000..6077a9e --- /dev/null +++ b/api/index.js @@ -0,0 +1,14 @@ +const express = require('express') +const bodyParser = require('body-parser') + +const applicationInit = require('./routes/application') +const keyboards = require('./routes/keyboards') + +const app = express() + +app.use(bodyParser.json()) +applicationInit(app) +app.use(keyboards) + +module.exports = app + diff --git a/api/routes/application.js b/api/routes/application.js new file mode 100644 index 0000000..cf78527 --- /dev/null +++ b/api/routes/application.js @@ -0,0 +1,39 @@ +const childProcess = require('child_process') +const path = require('path') +const express = require('express') +const expressWs = require('express-ws') + +const appDir = path.join(__dirname, '..', '..', 'application') + +function init (app) { + expressWs(app) + + childProcess.execFile('npm', ['run', 'build-watch'], { cwd: appDir }, err => { + console.error(err) + console.error('Application serving failed') + process.exit(1) + }) + + app.get('/', (req, res) => res.redirect('/application')) + app.use('/application', express.static(path.join(appDir, 'dist'))) + + const subscribers = [] + app.ws('/console', (ws, req) => { + const { remoteAddress } = req.connection + subscribers.push(ws) + + console.info(`[${new Date()}] [${remoteAddress}] connected`) + + ws.onerror = err => { + console.error(`[${new Date()}] [${remoteAddress}]`, err) + } + + ws.onclose = () => { + console.info(`[${new Date()}] [${remoteAddress}] disconnected`) + const index = subscribers.indexOf(ws) + subscribers.splice(index, 1) + } + }) +} + +module.exports = init diff --git a/api/routes/keyboards.js b/api/routes/keyboards.js new file mode 100644 index 0000000..6c605a1 --- /dev/null +++ b/api/routes/keyboards.js @@ -0,0 +1,49 @@ +const { Router } = require('express') +const zmk = require('../services/zmk/zmk') + +const firmwares = { zmk } +const router = Router() + +function addFirmwareLibrary(req, res, next) { + + if (!('firmware' in req.query)) { + return res.status(400).json({ + error: 'Must include "firmware" query parameter' + }) + } + + if (!firmwares[req.query.firmware]) { + return res.status(400).json({ + error: `Unknown firmware "${req.query.firmware}"` + }) + } + + req.firmware = firmwares[req.query.firmware] + next() +} + +router.get('/behaviors', addFirmwareLibrary, (req, res) => res.json(req.firmware.loadBehaviors())) +router.get('/keycodes', addFirmwareLibrary, (req, res) => res.json(req.firmware.loadKeycodes())) +router.get('/layout', addFirmwareLibrary, (req, res) => res.json(req.firmware.loadLayout())) +router.get('/keymap', addFirmwareLibrary, (req, res) => res.json(req.firmware.loadKeymap())) +router.post('/keymap', addFirmwareLibrary, (req, res) => { + const keymap = req.body + const layout = req.firmware.loadLayout() + const generatedKeymap = req.firmware.generateKeymap(layout, keymap) + const exportStdout = req.firmware.exportKeymap(generatedKeymap, 'flash' in req.query, err => { + if (err) { + res.status(500).send(err) + return + } + + res.send() + }) + + // exportStdout.stdout.on('data', data => { + // for (let sub of subscribers) { + // sub.send(data) + // } + // }) +}) + +module.exports = router diff --git a/api/services/index.js b/api/services/index.js new file mode 100644 index 0000000..e69de29 diff --git a/data/LICENSE b/api/services/zmk/data/LICENSE similarity index 100% rename from data/LICENSE rename to api/services/zmk/data/LICENSE diff --git a/data/zmk-behaviors.json b/api/services/zmk/data/zmk-behaviors.json similarity index 100% rename from data/zmk-behaviors.json rename to api/services/zmk/data/zmk-behaviors.json diff --git a/data/zmk-keycodes.json b/api/services/zmk/data/zmk-keycodes.json similarity index 100% rename from data/zmk-keycodes.json rename to api/services/zmk/data/zmk-keycodes.json diff --git a/api/services/zmk/index.js b/api/services/zmk/index.js new file mode 100644 index 0000000..e69de29 diff --git a/layout.js b/api/services/zmk/layout.js similarity index 100% rename from layout.js rename to api/services/zmk/layout.js diff --git a/zmk.js b/api/services/zmk/zmk.js similarity index 92% rename from zmk.js rename to api/services/zmk/zmk.js index 37ce319..4b28fc5 100644 --- a/zmk.js +++ b/api/services/zmk/zmk.js @@ -3,15 +3,15 @@ const fs = require('fs') const path = require('path') const { renderTable } = require('./layout') -const ZMK_PATH = 'zmk-config' +const ZMK_PATH = path.join(__dirname, '..', '..', '..', 'zmk-config') const KEYBOARD = 'dactyl' function loadBehaviors() { - return JSON.parse(fs.readFileSync('./data/zmk-behaviors.json')) + return JSON.parse(fs.readFileSync(path.join(__dirname, 'data', 'zmk-behaviors.json'))) } function loadKeycodes() { - return JSON.parse(fs.readFileSync('./data/zmk-keycodes.json')) + return JSON.parse(fs.readFileSync(path.join(__dirname, 'data', 'zmk-keycodes.json'))) } function loadLayout (layout = 'LAYOUT') { diff --git a/index.js b/index.js index ac26fbd..772caf4 100644 --- a/index.js +++ b/index.js @@ -1,84 +1,6 @@ -const childProcess = require('child_process') const process = require('process') -const express = require('express') -const expressWs = require('express-ws') -const bodyParser = require('body-parser') -const zmk = require('./zmk') - -const app = express() -const subscribers = [] -expressWs(app) -app.use(bodyParser.json()) - -childProcess.execFile('npm', ['run', 'build-watch'], { cwd: './application' }, err => { - console.error(err) - console.error('Application serving failed') - process.exit(1) -}) - -const firmwares = { zmk } - -function addFirmwareLibrary(req, res, next) { - - if (!('firmware' in req.query)) { - return res.status(400).json({ - error: 'Must include "firmware" query parameter' - }) - } - - if (!firmwares[req.query.firmware]) { - return res.status(400).json({ - error: `Unknown firmware "${req.query.firmware}"` - }) - } - - req.firmware = firmwares[req.query.firmware] - next() -} - -app.get('/', (req, res) => res.redirect('/application')) -app.use('/application', express.static('application/dist')) -app.get('/behaviors', addFirmwareLibrary, (req, res) => res.json(req.firmware.loadBehaviors())) -app.get('/keycodes', addFirmwareLibrary, (req, res) => res.json(req.firmware.loadKeycodes())) -app.get('/layout', addFirmwareLibrary, (req, res) => res.json(req.firmware.loadLayout())) -app.get('/keymap', addFirmwareLibrary, (req, res) => res.json(req.firmware.loadKeymap())) -app.post('/keymap', addFirmwareLibrary, (req, res) => { - const keymap = req.body - const layout = req.firmware.loadLayout() - const generatedKeymap = req.firmware.generateKeymap(layout, keymap) - const exportStdout = req.firmware.exportKeymap(generatedKeymap, 'flash' in req.query, err => { - if (err) { - res.status(500).send(err) - return - } - - res.send() - }) - - exportStdout.stdout.on('data', data => { - for (let sub of subscribers) { - sub.send(data) - } - }) -}) - -app.ws('/console', (ws, req) => { - const { remoteAddress } = req.connection - subscribers.push(ws) - - console.info(`[${new Date()}] [${remoteAddress}] connected`) - - ws.onerror = err => { - console.error(`[${new Date()}] [${remoteAddress}]`, err) - } - - ws.onclose = () => { - console.info(`[${new Date()}] [${remoteAddress}] disconnected`) - const index = subscribers.indexOf(ws) - subscribers.splice(index, 1) - } -}) +const api = require('./api') const PORT = process.env.PORT || 8080 -app.listen(PORT) +api.listen(PORT) console.log('listening on', PORT) diff --git a/package-lock.json b/package-lock.json index 27812b3..af3008a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,7 @@ "": { "name": "keymap-editor", "version": "1.0.0", + "hasInstallScript": true, "license": "ISC", "dependencies": { "body-parser": "^1.19.0", diff --git a/package.json b/package.json index 4a99dbf..8e4850c 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,8 @@ "description": "", "main": "index.js", "scripts": { + "postinstall": "cd application && npm install", + "start": "node index.js", "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [],