diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index e11ebac..51c66c3 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -27,5 +27,6 @@ jobs: node-version: ${{ matrix.node-version }} cache: 'npm' - run: npm ci - - run: npm run build --if-present + - run: npm run lint + - run: npm run build - run: npm test diff --git a/README.md b/README.md index 97e2500..17bee7d 100644 --- a/README.md +++ b/README.md @@ -80,22 +80,47 @@ Wide-JSON: ## Rules for Compact Layout -Wide-JSON will use the following rules in layout out JSON: - -- Maps (Objects) will always include the first property on the - same line as the opening '{'. -- Subsequent properties will be included on the same line if they - will fit within the available width. -- If a property will not fit in the available width, it will be - indented on a new line at the same indentation level as it's sibling - properties. - -- Arrays will always include the first value on the same line as the - opening '['. -- Subsequent values will the included on the same line if they will fit - in the available width. -- Additions array values will be "word-wrapped" to subsequent lines with - the same indentation as the first value of the array. +Wide-JSON will use the following rules in layout out JSON +Maps (Objects) and Arrays. + +- The first child (element or property) will appear + on the same line as the opening `{` or `[`. +- Subsequent children will be included on the same line + if they will fit in the available width. +- If a child will not fit in the available width, it will be + indented on a new line at the same indentation level as + the first child. +- The closing `}` or `]` will always appear on the same + line as the last child. + +## Using the CLI + +Wide-JSON exports a command-line utility which reads +a JSON file and outputs a reformatted version on the +command line: + +``` +$ npx wide-json input.json > output.json + +$ npx wide-json --help + +Usage: + wide-json [options] filename.json > output.json + wide-json [options] < input.json > output.json + +Options: + --help Show this help message. + --width=N Set the target width of the output. + (default: 80) +``` + +## Using the Node Package + +```js +const wideJSON = require('wide-json'); + +console.log(wideJSON.stringify(myJSON)); +``` ## Note about maximum line length diff --git a/package.json b/package.json index e132dba..c8d7fd0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wide-json", - "version": "0.2.1", + "version": "0.3.0", "description": "JSON formatter - preferring wide layout to tall layout", "main": "dist/index.js", "bin": "dist/cli.js", diff --git a/src/cli.ts b/src/cli.ts index aedcacc..5cb3b4a 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,3 +1,66 @@ #!/usr/bin/env node -console.log("wide-json"); +import { exit } from "process"; +import { readFile } from 'fs/promises'; +import { stringify } from './index.js'; + +async function main(args: string[]) { + let width = 80; + let useStdin = true; + + for (const option of args) { + if (option.startsWith('--')) { + const [, name, value] = option.match(/^--([^=]+)=?(.*)$/) || []; + if (name === 'help') { + help(); + } else if (name === 'width') { + width = parseInt(value, 10); + if (isNaN(width) || width < 0) { + help("width must be a positive number"); + } + } else { + help(`Unknown option: ${option}`); + } + } else { + const fileName = option; + useStdin = false; + + try { + const json = await readFile(fileName, 'utf8'); + console.log(stringify(JSON.parse(json), width) + '\n'); + } catch (e) { + help(`Could not read ${fileName}:\n${e}`); + } + } + } + + if (!useStdin) { + return; + } + + const json = await readFile('/dev/stdin', 'utf8'); + console.log(stringify(JSON.parse(json), width) + '\n'); +} + +function help(msg?: string) { + if (msg) { + console.error(msg + '\n'); + } + + console.log(` +Usage: + wide-json [options] filename.json > output.json + wide-json [options] < input.json > output.json + +Options: + --help Show this help message. + --width=N Set the target width of the output. + (default: 80) +`); + + exit(msg === undefined ? 0 : 1); +} + +if (require.main === module) { + main(process.argv.slice(2)); +}