cli.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #!/usr/bin/env node
  2. const fs = require('fs')
  3. const path = require('path')
  4. const pkg = require('../package.json')
  5. const JSON5 = require('./')
  6. const argv = parseArgs()
  7. if (argv.version) {
  8. version()
  9. } else if (argv.help) {
  10. usage()
  11. } else {
  12. const inFilename = argv.defaults[0]
  13. let readStream
  14. if (inFilename) {
  15. readStream = fs.createReadStream(inFilename)
  16. } else {
  17. readStream = process.stdin
  18. }
  19. let json5 = ''
  20. readStream.on('data', data => {
  21. json5 += data
  22. })
  23. readStream.on('end', () => {
  24. let space
  25. if (argv.space === 't' || argv.space === 'tab') {
  26. space = '\t'
  27. } else {
  28. space = Number(argv.space)
  29. }
  30. let value
  31. try {
  32. value = JSON5.parse(json5)
  33. if (!argv.validate) {
  34. const json = JSON.stringify(value, null, space)
  35. let writeStream
  36. // --convert is for backward compatibility with v0.5.1. If
  37. // specified with <file> and not --out-file, then a file with
  38. // the same name but with a .json extension will be written.
  39. if (argv.convert && inFilename && !argv.outFile) {
  40. const parsedFilename = path.parse(inFilename)
  41. const outFilename = path.format(
  42. Object.assign(
  43. parsedFilename,
  44. {base: path.basename(parsedFilename.base, parsedFilename.ext) + '.json'}
  45. )
  46. )
  47. writeStream = fs.createWriteStream(outFilename)
  48. } else if (argv.outFile) {
  49. writeStream = fs.createWriteStream(argv.outFile)
  50. } else {
  51. writeStream = process.stdout
  52. }
  53. writeStream.write(json)
  54. }
  55. } catch (err) {
  56. console.error(err.message)
  57. process.exit(1)
  58. }
  59. })
  60. }
  61. function parseArgs () {
  62. let convert
  63. let space
  64. let validate
  65. let outFile
  66. let version
  67. let help
  68. const defaults = []
  69. const args = process.argv.slice(2)
  70. for (let i = 0; i < args.length; i++) {
  71. const arg = args[i]
  72. switch (arg) {
  73. case '--convert':
  74. case '-c':
  75. convert = true
  76. break
  77. case '--space':
  78. case '-s':
  79. space = args[++i]
  80. break
  81. case '--validate':
  82. case '-v':
  83. validate = true
  84. break
  85. case '--out-file':
  86. case '-o':
  87. outFile = args[++i]
  88. break
  89. case '--version':
  90. case '-V':
  91. version = true
  92. break
  93. case '--help':
  94. case '-h':
  95. help = true
  96. break
  97. default:
  98. defaults.push(arg)
  99. break
  100. }
  101. }
  102. return {
  103. convert,
  104. space,
  105. validate,
  106. outFile,
  107. version,
  108. help,
  109. defaults,
  110. }
  111. }
  112. function version () {
  113. console.log(pkg.version)
  114. }
  115. function usage () {
  116. console.log(
  117. `
  118. Usage: json5 [options] <file>
  119. If <file> is not provided, then STDIN is used.
  120. Options:
  121. -s, --space The number of spaces to indent or 't' for tabs
  122. -o, --out-file [file] Output to the specified file, otherwise STDOUT
  123. -v, --validate Validate JSON5 but do not output JSON
  124. -V, --version Output the version number
  125. -h, --help Output usage information`
  126. )
  127. }