Last active
October 23, 2025 09:30
-
-
Save alanning/1ff5c6dabe90e7cb6c37362da92793a5 to your computer and use it in GitHub Desktop.
Script for reading relaxed json from stdin and returning formatted json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env node | |
| const vm = require('node:vm') | |
| const readline = require('node:readline') | |
| // Safely parse relaxed json from stdin and return formatted result. | |
| // Intended for use from within VIM. | |
| // | |
| // Requirements: | |
| // 1. Linux shell | |
| // 2. NodeJS must be installed | |
| // 3. Executable flag set on script file: chmod u+x formatRelaxedJson.js | |
| // | |
| // Command line: | |
| // | |
| // echo "{ foo: 'bar' }" | ./formatRelaxedJson.js | |
| // | |
| // | |
| // VIM: | |
| // Press your leader key and then 'fj' to convert the whole file. | |
| // Also works in visual mode so you can select just the json to format | |
| // | |
| // .vimrc: | |
| // " assumes formatRelaxedJson.js is located in your home directory... | |
| // nnoremap <Leader>fj :%! ~/formatRelaxedJson.js<CR> | |
| // vnoremap <Leader>fj :! ~/formatRelaxedJson.js<CR> | |
| // | |
| // Credit for use of node:vm goes to ojosilva: | |
| // https://stackoverflow.com/a/76044884/219238 | |
| async function main () { | |
| const parts = [] | |
| for await (const line of readline.createInterface({ input: process.stdin })) { | |
| parts.push(line) | |
| } | |
| const badJson = parts.join('\n') | |
| const parsedJson = parseRelaxedJson(badJson) | |
| console.log(JSON.stringify(parsedJson, null, 2)) | |
| } | |
| function parseRelaxedJson (badJson) { | |
| try { | |
| const parsedJson = new vm.Script(`x=${badJson}`).runInNewContext( | |
| { console: undefined }, // nuke console inside the vm | |
| { timeout: 1000, displayErrors: true } | |
| ) | |
| if (typeof parsedJson !== 'object') { | |
| // in case you're expecting an object/array | |
| throw new Error(`Invalid JSON=${badJson}, parsed as: ${parsedJson}`) | |
| } | |
| return parsedJson | |
| } catch (err) { | |
| throw new Error(`Could not parse JSON: ${err}`) | |
| } | |
| } | |
| main() |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Motivation for this script was a tool that works on "relaxed" json rather than requiring the input json to be well-formatted like these do:
:%!jq .:%!python -m json.toolThis script may also be helpful to those interested in: