diff options
-rw-r--r-- | README.md | 3 | ||||
-rw-r--r-- | api/config.js | 26 | ||||
-rw-r--r-- | api/index.js | 9 | ||||
-rw-r--r-- | api/routes/application.js | 6 | ||||
-rw-r--r-- | api/services/github/auth.js | 15 | ||||
-rw-r--r-- | api/services/zmk/layout.js | 1 | ||||
-rw-r--r-- | application/README.md | 57 | ||||
-rw-r--r-- | application/components/key-value.vue | 2 | ||||
-rw-r--r-- | application/components/key.vue | 6 | ||||
-rw-r--r-- | application/components/keyboard-picker.vue | 2 | ||||
-rw-r--r-- | application/data/keymap.json | 231 | ||||
-rw-r--r-- | application/data/layers.json | 56 | ||||
-rw-r--r-- | application/data/layout.json | 62 | ||||
-rw-r--r-- | application/keycodes.js | 4 | ||||
-rw-r--r-- | editor-screenshot.png | bin | 292465 -> 169899 bytes | |||
-rw-r--r-- | index.js | 7 | ||||
-rw-r--r-- | package-lock.json | 46 | ||||
-rw-r--r-- | package.json | 3 |
18 files changed, 146 insertions, 390 deletions
@@ -4,6 +4,9 @@ A browser app (plus NodeJS server) to edit ZMK keymaps. This is still in its infancy and doesn't yet support parsing existing ZMK keymaps which limits some kinds of functionality (mainly those involving custom/configured behaviours). +**Try it live!** Go to the [keymap-editor] and try it out with the built-in +[zmk-config-corne-demo] before setting up your own repo. + ![Screenshot](editor-screenshot.png) ## Features diff --git a/api/config.js b/api/config.js new file mode 100644 index 0000000..ff9644f --- /dev/null +++ b/api/config.js @@ -0,0 +1,26 @@ +const process = require('process') +require('dotenv/config') + +const PORT = process.env.PORT || 8080 +const ENABLE_DEV_SERVER = process.env.ENABLE_DEV_SERVER +const ENABLE_GITHUB = process.env.ENABLE_GITHUB +const GITHUB_APP_NAME = process.env.GITHUB_APP_NAME +const GITHUB_APP_PRIVATE_KEY = process.env.GITHUB_APP_PRIVATE_KEY +const GITHUB_APP_ID = process.env.GITHUB_APP_ID +const GITHUB_CLIENT_ID = process.env.GITHUB_CLIENT_ID +const GITHUB_CLIENT_SECRET = process.env.GITHUB_CLIENT_SECRET +const GITHUB_OAUTH_CALLBACK_URL = process.env.GITHUB_OAUTH_CALLBACK_URL +const APP_BASE_URL = process.env.APP_BASE_URL + +module.exports = { + PORT, + ENABLE_DEV_SERVER, + ENABLE_GITHUB, + GITHUB_APP_NAME, + GITHUB_APP_PRIVATE_KEY, + GITHUB_APP_ID, + GITHUB_CLIENT_ID, + GITHUB_CLIENT_SECRET, + GITHUB_OAUTH_CALLBACK_URL, + APP_BASE_URL +} diff --git a/api/index.js b/api/index.js index d45471c..9c7e63c 100644 --- a/api/index.js +++ b/api/index.js @@ -1,9 +1,9 @@ -require('dotenv/config') const express = require('express') const bodyParser = require('body-parser') const cors = require('cors') const morgan = require('morgan') +const config = require('./config') const applicationInit = require('./routes/application') const keyboards = require('./routes/keyboards') @@ -14,14 +14,15 @@ app.use(cors({ origin: 'https://nickcoutsos.github.io' })) -if (process.env.ENABLE_DEV_SERVER) { +if (config.ENABLE_DEV_SERVER) { applicationInit(app) } app.use(morgan('dev')) -app.use(keyboards) -app.use('/github', require('./routes/github')) app.get('/health', (req, res) => res.sendStatus(200)) +app.use(keyboards) +config.ENABLE_GITHUB && app.use('/github', require('./routes/github')) + module.exports = app diff --git a/api/routes/application.js b/api/routes/application.js index 3ecac87..add60be 100644 --- a/api/routes/application.js +++ b/api/routes/application.js @@ -3,6 +3,8 @@ const path = require('path') const express = require('express') const expressWs = require('express-ws') +const config = require('../config') + const appDir = path.join(__dirname, '..', '..', 'application') function init (app) { @@ -12,8 +14,8 @@ function init (app) { cwd: appDir, env: Object.assign({}, process.env, { ENABLE_LOCAL: true, - ENABLE_GITHUB: true, - GITHUB_APP_NAME: process.env.GITHUB_APP_NAME, + ENABLE_GITHUB: config.ENABLE_GITHUB, + GITHUB_APP_NAME: config.GITHUB_APP_NAME, API_BASE_URL: 'http://localhost:8080', APP_BASE_URL: 'http://localhost:8080/application' }) diff --git a/api/services/github/auth.js b/api/services/github/auth.js index 175e5f7..fcb3ec4 100644 --- a/api/services/github/auth.js +++ b/api/services/github/auth.js @@ -3,12 +3,13 @@ const path = require('path') const jwt = require('jsonwebtoken') const api = require('./api') +const config = require('../../config') const pemPath = path.join(__dirname, '..', '..', '..', 'private-key.pem') -const privateKey = process.env.GITHUB_APP_PRIVATE_KEY || fs.readFileSync(pemPath) +const privateKey = config.GITHUB_APP_PRIVATE_KEY || fs.readFileSync(pemPath) function createAppToken () { - return jwt.sign({ iss: process.env.GITHUB_APP_ID }, privateKey, { + return jwt.sign({ iss: config.GITHUB_APP_ID }, privateKey, { algorithm: 'RS256', expiresIn: '10m' }) @@ -24,8 +25,8 @@ function createOauthFlowUrl () { const redirectUrl = new URL('https://github.com/login/oauth/authorize') redirectUrl.search = new URLSearchParams({ - client_id: process.env.GITHUB_CLIENT_ID, - redirect_uri: process.env.GITHUB_OAUTH_CALLBACK_URL, + client_id: config.GITHUB_CLIENT_ID, + redirect_uri: config.GITHUB_OAUTH_CALLBACK_URL, state: 'foo' }).toString() @@ -33,7 +34,7 @@ function createOauthFlowUrl () { } function createOauthReturnUrl (token) { - const url = new URL(process.env.APP_BASE_URL) + const url = new URL(config.APP_BASE_URL) url.search = new URLSearchParams({ token }).toString() return url.toString() } @@ -46,8 +47,8 @@ function getOauthToken (code) { Accept: 'application/json' }, data: { - client_id: process.env.GITHUB_CLIENT_ID, - client_secret: process.env.GITHUB_CLIENT_SECRET, + client_id: config.GITHUB_CLIENT_ID, + client_secret: config.GITHUB_CLIENT_SECRET, code } }) diff --git a/api/services/zmk/layout.js b/api/services/zmk/layout.js index c914177..17bd7e4 100644 --- a/api/services/zmk/layout.js +++ b/api/services/zmk/layout.js @@ -36,7 +36,6 @@ function renderTable (layout, layer, opts={}) { (row[i] || []).length + columnSeparator.length + (useQuotes ? 2 : 0) // wrapping with quotes adds 2 characters - + (i === 6 ? 10 : 0) // sloppily add a little space between halves (right half starts at column 6) )) )) diff --git a/application/README.md b/application/README.md new file mode 100644 index 0000000..6b967e1 --- /dev/null +++ b/application/README.md @@ -0,0 +1,57 @@ +# Keymap Editor - Web Application + +This is a single page application currently written in Vue (but I'm starting to +experiment with porting it to React) to integrate with the Keymap Editor API. + +It handles keyboard selection and rendering of parsed keymap data into a visual +editor. This application is _aware_ of some of the particulars of ZMK, but it +receives key bindings already parsed into a tree of values and parameters. + +## Building + +The easiest way to use this is the [hosted version](https://nickcoutsos.github.io/keymap-editor). +The second easiest is locally, served up via the API itself (in the repo root, +run `npm run dev` and open `http://localhost:8080` in your browser). + +If you must deploy this app to the web then you'll need to take care of building +it. This requires some configuration, as seen in the [config module](./config.js). + +All configuration is provided via environment variables. + +Variable | Description +------------------|------------- +`API_BASE_URL` | Fully qualified publicly accessible URL of the backend API. +`APP_BASE_URL` | Fully qualified publicly accessible URL of _this_ app. +`GITHUB_APP_NAME` | The app name (slug?) of the GitHub app integration (only required if using with GitHub). +`ENABLE_GITHUB` | Whether to enable fetching keyboard data from GitHub. Default is false, values `"1"`, `"on"`, `"yes"`, `"true"` are interpreted as `true`. +`ENABLE_LOCAL` | Whether to enable fetching keyboard data from locally. Default is false, values `"1"`, `"on"`, `"yes"`, `"true"` are interpreted as `true`. + +_Note: choosing to use the GitHub integration in your own environment isn't a +matter of flipping a switch, you will need to set up your own app in GitHub and +configure your API accordingly._ + +With these set you can run the npm build script, e.g. + +```bash +export API_BASE_URL=... +export APP_BASE_URL=... +export GITHUB_APP_NAME=... +export ENABLE_GITHUB=... +export ENABLE_LOCAL=... +npm run build +``` + +_(make sure you're in this directory, not the repository root!)_ + +This will have webpack produce bundles in the `dist/` directory which you can +deploy however you like. + +### Deploying to GitHub Pages + +On your GitHub repository's settings page, select _Pages_ in the sidebar. Pick a +branch you want to serve the app from (I use `pages`) and choose the `/ (root)` +directory. Check out that branch (I have another working repository locally for +this) locally, or make a new orphaned branch if such a branch doesn't exist, and +copy the contents of `dist/` to it. Commit and push to the GitHub remote. + +If you're not familiar with this it's worth reading up on the [GitHub Pages docs](https://docs.github.com/en/pages).
\ No newline at end of file diff --git a/application/components/key-value.vue b/application/components/key-value.vue index 776a37b..1bc6b10 100644 --- a/application/components/key-value.vue +++ b/application/components/key-value.vue @@ -5,7 +5,7 @@ @click.stop="onSelect({ target: $event.target, codeIndex: index, code: value, param })" > <template v-if="source"> - <span v-if="source.faIcon" class="['fa', `fa-${source.faIcon}" /> + <span v-if="source.faIcon" :class="['fa', `fa-${source.faIcon}`]" /> <template v-else>{{source.symbol || source.code}}</template> </template> <template v-else>⦸</template> diff --git a/application/components/key.vue b/application/components/key.vue index dcc6972..1c135bb 100644 --- a/application/components/key.vue +++ b/application/components/key.vue @@ -140,15 +140,17 @@ export default { }, isSimple() { const [first] = this.normalized.params + const icon = get(first, 'source.faIcon') const symbol = get(first, 'source.symbol', get(first, 'source.code', '')) - const shortSymbol = symbol.length === 1 + const shortSymbol = !!icon || symbol.length === 1 const singleParam = this.normalized.params.length === 1 return singleParam && shortSymbol }, isComplex() { const [first] = this.normalized.params + const icon = get(first, 'source.faIcon') const symbol = get(first, 'source.symbol', get(first, 'value', '')) - const isLongSymbol = symbol.length > 4 + const isLongSymbol = !icon && symbol.length > 4 const isMultiParam = this.behaviourParams.length > 1 const isNestedParam = get(first, 'params', []).length > 0 diff --git a/application/components/keyboard-picker.vue b/application/components/keyboard-picker.vue index c3b6383..dec3e37 100644 --- a/application/components/keyboard-picker.vue +++ b/application/components/keyboard-picker.vue @@ -41,7 +41,7 @@ export default { sourceChoices, source: onlySource || ( sourceChoices.find(source => source.id === selectedSource) - ? selectedSource.id + ? selectedSource : null ) } diff --git a/application/data/keymap.json b/application/data/keymap.json deleted file mode 100644 index c8678a6..0000000 --- a/application/data/keymap.json +++ /dev/null @@ -1,231 +0,0 @@ -{ - "keyboard": "handwired/dactyl_reduced", - "keymap": "default", - "layout": "LAYOUT", - "layers": [ - [ - "KC_TAB", - "KC_Q", - "KC_W", - "KC_E", - "KC_R", - "KC_T", - "KC_Y", - "KC_U", - "KC_I", - "KC_O", - "KC_P", - "KC_BSLS", - "KC_CAPS", - "KC_A", - "KC_S", - "KC_D", - "KC_F", - "KC_G", - "KC_H", - "KC_J", - "KC_K", - "KC_L", - "LT(2,KC_SCLN)", - "KC_QUOT", - "KC_LSPO", - "KC_Z", - "KC_X", - "KC_C", - "KC_V", - "KC_B", - "KC_N", - "KC_M", - "KC_COMM", - "KC_DOT", - "KC_SLSH", - "KC_RSPC", - "KC_LCTL", - "KC_LEFT", - "KC_RGHT", - "KC_DOWN", - "KC_UP", - "KC_LBRC", - "KC_LCTL", - "KC_BSPC", - "KC_RALT", - "KC_ESC", - "KC_LALT", - "KC_LGUI", - "MO(1)", - "KC_PGUP", - "KC_ENT", - "KC_SPC", - "MO(2)", - "KC_PGDN" - ], - [ - "KC_TRNS", - "KC_TRNS", - "KC_GRAVE", - "KC_MINS", - "KC_EQL", - "KC_TRNS", - "KC_LBRC", - "KC_7", - "KC_8", - "KC_9", - "KC_RBRC", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_KP_PLUS", - "KC_4", - "KC_5", - "KC_6", - "KC_KP_ASTERISK", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_KP_MINUS", - "KC_1", - "KC_2", - "KC_3", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_0", - "KC_DOT", - "KC_TRNS", - "KC_TRNS", - "KC_LCMD", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_LSHIFT", - "KC_TRNS" - ], - [ - "RESET", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "LCMD(KC_LBRC)", - "LCMD(LSFT(KC_LBRC))", - "LCMD(LSFT(KC_RBRC))", - "LCMD(KC_RBRC)", - "KC_TRNS", - "KC_TRNS", - "RGB_MODE_FORWARD", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_F8", - "KC_F9", - "KC_F7", - "LCMD(LALT(KC_GRAVE))", - "KC_TRNS", - "KC_TRNS", - "RGB_HUI", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC__VOLDOWN", - "KC__VOLUP", - "KC__MUTE", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS" - ], - [ - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_F7", - "KC_F8", - "KC_F9", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_F4", - "KC_F5", - "KC_F6", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_F1", - "KC_F2", - "KC_F3", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS", - "KC_TRNS" - ] - ] -}
\ No newline at end of file diff --git a/application/data/layers.json b/application/data/layers.json deleted file mode 100644 index 3edf07b..0000000 --- a/application/data/layers.json +++ /dev/null @@ -1,56 +0,0 @@ -[ - { "code": "KC_TAB" }, - { "code": "KC_Q" }, - { "code": "KC_W" }, - { "code": "KC_E" }, - { "code": "KC_R" }, - { "code": "KC_T" }, - { "code": "KC_Y" }, - { "code": "KC_U" }, - { "code": "KC_I" }, - { "code": "KC_O" }, - { "code": "KC_P" }, - { "code": "KC_BSLS" }, - { "code": "KC_CAPS" }, - { "code": "KC_A" }, - { "code": "KC_S" }, - { "code": "KC_D" }, - { "code": "KC_F" }, - { "code": "KC_G" }, - { "code": "KC_H" }, - { "code": "KC_J" }, - { "code": "KC_K" }, - { "code": "KC_L" }, - { "code": "LT(2, KC_SCLN)" }, - { "code": "KC_QUOT" }, - { "code": "KC_LSPO" }, - { "code": "KC_Z" }, - { "code": "KC_X" }, - { "code": "KC_C" }, - { "code": "KC_V" }, - { "code": "KC_B" }, - { "code": "KC_N" }, - { "code": "KC_M" }, - { "code": "KC_COMM" }, - { "code": "KC_DOT" }, - { "code": "KC_SLSH" }, - { "code": "KC_RSPC" }, - { "code": "KC_LCTL" }, - { "code": "KC_LEFT" }, - { "code": "KC_RGHT" }, - { "code": "KC_DOWN" }, - { "code": "KC_UP" }, - { "code": "KC_LBRC" }, - { "code": "KC_LCTL" }, - { "code": "KC_BSPC" }, - { "code": "KC_RALT" }, - { "code": "KC_ESC" }, - { "code": "KC_LALT" }, - { "code": "KC_LGUI" }, - { "code": "MO(1)" }, - { "code": "KC_PGUP" }, - { "code": "KC_ENT" }, - { "code": "KC_SPC" }, - { "code": "MO(2)" }, - { "code": "KC_PGDN" } -] diff --git a/application/data/layout.json b/application/data/layout.json deleted file mode 100644 index 6095cd6..0000000 --- a/application/data/layout.json +++ /dev/null @@ -1,62 +0,0 @@ -[ - { "label": "L00", "row": 0, "col": 0, "x": 0, "y": 0.5 }, - { "label": "L01", "row": 0, "col": 1, "x": 1, "y": 0.5 }, - { "label": "L02", "row": 0, "col": 2, "x": 2, "y": 0.2 }, - { "label": "L03", "row": 0, "col": 3, "x": 3, "y": 0 }, - { "label": "L04", "row": 0, "col": 4, "x": 4, "y": 0.25 }, - { "label": "L05", "row": 0, "col": 5, "x": 5, "y": 0.25 }, - { "label": "R06", "row": 0, "col": 6, "x": 13, "y": 0.25 }, - { "label": "R07", "row": 0, "col": 7, "x": 14, "y": 0.25 }, - { "label": "R08", "row": 0, "col": 8, "x": 15, "y": 0 }, - { "label": "R09", "row": 0, "col": 9, "x": 16, "y": 0.2 }, - { "label": "R0A", "row": 0, "col": 10, "x": 17, "y": 0.5 }, - { "label": "R0B", "row": 0, "col": 11, "x": 18, "y": 0.5 }, - - { "label": "L10", "row": 1, "col": 0, "x": 0, "y": 1.5 }, - { "label": "L11", "row": 1, "col": 1, "x": 1, "y": 1.5 }, - { "label": "L12", "row": 1, "col": 2, "x": 2, "y": 1.2 }, - { "label": "L13", "row": 1, "col": 3, "x": 3, "y": 1 }, - { "label": "L14", "row": 1, "col": 4, "x": 4, "y": 1.25 }, - { "label": "L15", "row": 1, "col": 5, "x": 5, "y": 1.25 }, - { "label": "R16", "row": 1, "col": 6, "x": 13, "y": 1.25 }, - { "label": "R17", "row": 1, "col": 7, "x": 14, "y": 1.25 }, - { "label": "R18", "row": 1, "col": 8, "x": 15, "y": 1 }, - { "label": "R19", "row": 1, "col": 9, "x": 16, "y": 1.2 }, - { "label": "R1A", "row": 1, "col": 10, "x": 17, "y": 1.5 }, - { "label": "R1B", "row": 1, "col": 11, "x": 18, "y": 1.5 }, - - { "label": "L20", "row": 2, "col": 0, "x": 0, "y": 2.5 }, - { "label": "L21", "row": 2, "col": 1, "x": 1, "y": 2.5 }, - { "label": "L22", "row": 2, "col": 2, "x": 2, "y": 2.2 }, - { "label": "L23", "row": 2, "col": 3, "x": 3, "y": 2 }, - { "label": "L24", "row": 2, "col": 4, "x": 4, "y": 2.25 }, - { "label": "L25", "row": 2, "col": 5, "x": 5, "y": 2.25 }, - { "label": "R26", "row": 2, "col": 6, "x": 13, "y": 2.25 }, - { "label": "R27", "row": 2, "col": 7, "x": 14, "y": 2.25 }, - { "label": "R28", "row": 2, "col": 8, "x": 15, "y": 2 }, - { "label": "R29", "row": 2, "col": 9, "x": 16, "y": 2.2 }, - { "label": "R2A", "row": 2, "col": 10, "x": 17, "y": 2.5 }, - { "label": "R2B", "row": 2, "col": 11, "x": 18, "y": 2.5 }, - - { "label": "L32", "row": 3, "col": 2, "x": 2, "y": 3.2 }, - { "label": "L33", "row": 3, "col": 3, "x": 3, "y": 3 }, - { "label": "L34", "row": 3, "col": 4, "x": 4, "y": 3.25 }, - { "label": "R37", "row": 3, "col": 7, "x": 14, "y": 3.25 }, - { "label": "R38", "row": 3, "col": 8, "x": 15, "y": 3 }, - { "label": "R39", "row": 3, "col": 9, "x": 16, "y": 3.2 }, - - { "label": "L42", "row": 4, "col": 4, "x": 6.5, "y": 2, "r": 20, "rx": 4.5, "ry": 3 }, - { "label": "L43", "row": 4, "col": 5, "x": 7.5, "y": 2, "r": 20, "rx": 4.5, "ry": 3 }, - { "label": "R48", "row": 4, "col": 6, "x": 10.5, "y": 2, "r": -20, "rx": 14.5, "ry": 3 }, - { "label": "R49", "row": 4, "col": 7, "x": 11.5, "y": 2, "r": -20, "rx": 14.5, "ry": 3 }, - - { "label": "L40", "row": 5, "col": 3, "x": 5.5, "y": 3, "r": 20, "rx": 4.5, "ry": 3, "h": 2 }, - { "label": "L41", "row": 5, "col": 4, "x": 6.5, "y": 3, "r": 20, "rx": 4.5, "ry": 3, "h": 2 }, - { "label": "L44", "row": 5, "col": 5, "x": 7.5, "y": 3, "r": 20, "rx": 4.5, "ry": 3 }, - { "label": "R47", "row": 5, "col": 6, "x": 10.5, "y": 3, "r": -20, "rx": 14.5, "ry": 3 }, - { "label": "R4A", "row": 5, "col": 7, "x": 11.5, "y": 3, "r": -20, "rx": 14.5, "ry": 3, "h": 2 }, - { "label": "R4B", "row": 5, "col": 8, "x": 12.5, "y": 3, "r": -20, "rx": 14.5, "ry": 3, "h": 2 }, - - { "label": "L45", "row": 6, "col": 5, "x": 7.5, "y": 4, "r": 20, "rx": 4.5, "ry": 3 }, - { "label": "R46", "row": 6, "col": 6, "x": 10.5, "y": 4, "r": -20, "rx": 14.5, "ry": 3 } -]
\ No newline at end of file diff --git a/application/keycodes.js b/application/keycodes.js index 743bc76..7a65f5b 100644 --- a/application/keycodes.js +++ b/application/keycodes.js @@ -18,10 +18,10 @@ function normalizeZmkKeycodes (keycodes) { const fnPattern = /^(.+?)\((code)\)$/ return keycodes.reduce((keycodes, keycode) => { - const { description, context, symbol } = keycode + const { description, context, symbol, faIcon } = keycode const aliases = keycode.names.filter(name => !name.match(fnPattern)) const fnCode = keycode.names.map(name => name.match(fnPattern)).filter(v => !!v)[0] - const base = { aliases, description, context, symbol: symbol || shortestAlias(aliases), params: [] } + const base = { aliases, description, context, faIcon, symbol: symbol || shortestAlias(aliases), params: [] } for (let code of aliases) { keycodes.push(Object.assign({}, base, { diff --git a/editor-screenshot.png b/editor-screenshot.png Binary files differindex 5d64bbf..86113cf 100644 --- a/editor-screenshot.png +++ b/editor-screenshot.png @@ -1,6 +1,5 @@ -const process = require('process') const api = require('./api') +const config = require('./api/config') -const PORT = process.env.PORT || 8080 -api.listen(PORT) -console.log('listening on', PORT) +api.listen(config.PORT) +console.log('listening on', config.PORT) diff --git a/package-lock.json b/package-lock.json index 1df314c..0ad2ad6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "axios": "^0.21.4", "body-parser": "^1.19.0", "cors": "^2.8.5", + "cross-env": "^7.0.3", "dotenv": "^10.0.0", "express": "^4.17.1", "express-ws": "^4.0.0", @@ -448,11 +449,27 @@ "node": ">= 0.10" } }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -1682,8 +1699,7 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "node_modules/js-yaml": { "version": "4.1.0", @@ -2154,7 +2170,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "engines": { "node": ">=8" } @@ -2354,7 +2369,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -2366,7 +2380,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "engines": { "node": ">=8" } @@ -2603,7 +2616,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -2991,11 +3003,18 @@ "vary": "^1" } }, + "cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "requires": { + "cross-spawn": "^7.0.1" + } + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -3899,8 +3918,7 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "js-yaml": { "version": "4.1.0", @@ -4274,8 +4292,7 @@ "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" }, "path-parse": { "version": "1.0.7", @@ -4426,7 +4443,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "requires": { "shebang-regex": "^3.0.0" } @@ -4434,8 +4450,7 @@ "shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" }, "side-channel": { "version": "1.0.4", @@ -4609,7 +4624,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "requires": { "isexe": "^2.0.0" } diff --git a/package.json b/package.json index e428342..2c54a91 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "postinstall": "cd application && npm install", "start": "node index.js", - "dev": "ENABLE_DEV_SERVER=true node index.js", + "dev": "cross-env ENABLE_DEV_SERVER=true node index.js", "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], @@ -16,6 +16,7 @@ "axios": "^0.21.4", "body-parser": "^1.19.0", "cors": "^2.8.5", + "cross-env": "^7.0.3", "dotenv": "^10.0.0", "express": "^4.17.1", "express-ws": "^4.0.0", |