Skip to content

Instantly share code, notes, and snippets.

@isaacs
Created August 30, 2021 20:07
Show Gist options
  • Save isaacs/2de1c4003aa02efc33b2a96b9b7598ba to your computer and use it in GitHub Desktop.
Save isaacs/2de1c4003aa02efc33b2a96b9b7598ba to your computer and use it in GitHub Desktop.
#!/usr/bin/env node
const args = process.argv.slice(2)
if (args.length < 3)
console.error(`usage: node ${process.argv[1]} <file> <key> [<subkey> ...] <value>`)
const file = args.shift()
const value = args.pop()
const { readFileSync, writeFileSync } = require('fs')
const jsonParse = require('json-parse-even-better-errors')
const kIndent = Symbol.for('indent')
const kNewline = Symbol.for('newline')
const getData = file => {
try {
const data = jsonParse(readFileSync(file, 'utf8'))
if (!data || typeof data !== 'object' || Array.isArray(data))
throw new Error('not an object')
return data
} catch (er) {
console.error('file borked or missing, clobbering it', er.message)
return { [kIndent]: 2, [kNewline]: '\n' }
}
}
const data = getData(file)
const { [kIndent]: indent, [kNewline]: newline } = data
let o = data
const finalKey = args.pop()
for (const key of args) {
console.error(o, key)
if (typeof o[key] === 'object' && o[key])
o = o[key]
else
o = o[key] = Object.create(null)
}
o[finalKey] = value
writeFileSync(file, JSON.stringify(data, null, indent).split('\n').join(newline) + newline)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment