added json2yaml
This commit is contained in:
commit
a7ed9d461a
|
@ -0,0 +1,73 @@
|
||||||
|
JSON to YAML
|
||||||
|
===
|
||||||
|
|
||||||
|
The purpose of this utility is to pretty-print JSON in the human-readable YAML object notation
|
||||||
|
(ignore the misnomer, it's not a markup language at all)
|
||||||
|
|
||||||
|
You see, JSON is a proper subset of YAML, The difference is that YAML can use whitespace instead of syntax, which is more human-readable.
|
||||||
|
Also, YAML supports comments.
|
||||||
|
|
||||||
|
So, for all the times you want to turn JSON int YAML (YML):
|
||||||
|
|
||||||
|
{
|
||||||
|
"foo": "bar",
|
||||||
|
"baz": [
|
||||||
|
"qux",
|
||||||
|
"quxx"
|
||||||
|
],
|
||||||
|
"corge": null,
|
||||||
|
"grault": 1,
|
||||||
|
"garply": true,
|
||||||
|
"waldo": "false",
|
||||||
|
"fred": "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
becomes
|
||||||
|
|
||||||
|
---
|
||||||
|
foo: "bar"
|
||||||
|
baz:
|
||||||
|
- "qux"
|
||||||
|
- "quxx"
|
||||||
|
corge: null
|
||||||
|
grault: 1
|
||||||
|
garply: true
|
||||||
|
waldo: "false"
|
||||||
|
fred: "undefined"
|
||||||
|
|
||||||
|
Usage
|
||||||
|
---
|
||||||
|
|
||||||
|
Specify a file:
|
||||||
|
|
||||||
|
json2yaml ./example.json
|
||||||
|
|
||||||
|
yaml2json ./example.kml | json2yaml
|
||||||
|
|
||||||
|
Or pipe from stdin:
|
||||||
|
|
||||||
|
curl -s http://foobar3000.com/echo/echo.json | json2yaml
|
||||||
|
|
||||||
|
wget -qO- http://foobar3000.com/echo/echo.json | json2yaml
|
||||||
|
|
||||||
|
Or require:
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var YAML = require('json2yaml')
|
||||||
|
, ymlText
|
||||||
|
;
|
||||||
|
|
||||||
|
ymlText = YAML.stringify({
|
||||||
|
"foo": "bar"
|
||||||
|
, "baz": "corge"
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(ymlText);
|
||||||
|
}());
|
||||||
|
|
||||||
|
Installation
|
||||||
|
---
|
||||||
|
|
||||||
|
npm install -g json2yaml
|
|
@ -0,0 +1,93 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var fs = require('fs')
|
||||||
|
, filename = process.argv[2]
|
||||||
|
, YAML = require('./index')
|
||||||
|
;
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Begin real handler
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function printUsage() {
|
||||||
|
console.warn("Usages:");
|
||||||
|
console.warn("json2yaml example.json");
|
||||||
|
console.warn("cat example.json | json2yaml");
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleInput(err, text) {
|
||||||
|
var data
|
||||||
|
;
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
printUsage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = JSON.parse(text);
|
||||||
|
console.info(YAML.stringify(data, null, ' '));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* End real handler
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
readInput(handleInput, filename);
|
||||||
|
|
||||||
|
//
|
||||||
|
// this could (and probably should) be its own module
|
||||||
|
//
|
||||||
|
function readInput(cb, filename) {
|
||||||
|
|
||||||
|
function readFile() {
|
||||||
|
fs.readFile(filename, 'utf8', function (err, text) {
|
||||||
|
if (err) {
|
||||||
|
console.error("[ERROR] couldn't read from '" + filename + "':");
|
||||||
|
console.error(err.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cb(err, text);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function readStdin() {
|
||||||
|
var text = ''
|
||||||
|
, timeoutToken
|
||||||
|
, stdin = process.stdin
|
||||||
|
;
|
||||||
|
|
||||||
|
stdin.resume();
|
||||||
|
|
||||||
|
// how to tell piping vs waiting for user input?
|
||||||
|
timeoutToken = setTimeout(function () {
|
||||||
|
cb(new Error('no stdin data'));
|
||||||
|
stdin.pause();
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
stdin.on('data', function (chunk) {
|
||||||
|
clearTimeout(timeoutToken);
|
||||||
|
text += chunk;
|
||||||
|
});
|
||||||
|
|
||||||
|
stdin.on('end', function () {
|
||||||
|
cb(null, text);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filename) {
|
||||||
|
readFile();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
readStdin();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}());
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"foo": "bar",
|
||||||
|
"baz": [
|
||||||
|
"qux",
|
||||||
|
"quxx"
|
||||||
|
],
|
||||||
|
"corge": null,
|
||||||
|
"grault": 1,
|
||||||
|
"garply": true,
|
||||||
|
"waldo": "false",
|
||||||
|
"fred": "undefined"
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
foo: bar
|
||||||
|
baz:
|
||||||
|
- qux
|
||||||
|
- quxx
|
||||||
|
corge: null
|
||||||
|
grault: 1
|
||||||
|
garply: true
|
||||||
|
waldo: "false"
|
||||||
|
fred: undefined
|
|
@ -0,0 +1,93 @@
|
||||||
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var typeOf = require('remedial').typeOf
|
||||||
|
;
|
||||||
|
|
||||||
|
function stringify(data) {
|
||||||
|
var handlers
|
||||||
|
, indentLevel = ''
|
||||||
|
;
|
||||||
|
|
||||||
|
handlers = {
|
||||||
|
"undefined": function () {
|
||||||
|
// objects will not have `undefined` converted to `null`
|
||||||
|
// as this may have unintended consequences
|
||||||
|
// For arrays, however, this behavior seems appropriate
|
||||||
|
return 'null';
|
||||||
|
}
|
||||||
|
, "null": function () {
|
||||||
|
return 'null';
|
||||||
|
}
|
||||||
|
, "number": function (x) {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
, "boolean": function (x) {
|
||||||
|
return x ? 'true' : 'false';
|
||||||
|
}
|
||||||
|
, "string": function (x) {
|
||||||
|
// to avoid the string "true" being confused with the
|
||||||
|
// the literal `true`, we always wrap strings in quotes
|
||||||
|
return JSON.stringify(x);
|
||||||
|
}
|
||||||
|
, "array": function (x) {
|
||||||
|
var output = ''
|
||||||
|
;
|
||||||
|
|
||||||
|
indentLevel = indentLevel.replace(/$/, ' ');
|
||||||
|
x.forEach(function (y) {
|
||||||
|
// TODO how should `undefined` be handled?
|
||||||
|
var handler = handlers[typeOf(y)]
|
||||||
|
;
|
||||||
|
|
||||||
|
if (!handler) {
|
||||||
|
throw new Error('what the crap: ' + typeOf(y));
|
||||||
|
}
|
||||||
|
|
||||||
|
output += '\n' + indentLevel + '- ' + handler(y);
|
||||||
|
|
||||||
|
});
|
||||||
|
indentLevel = indentLevel.replace(/ /, '');
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
, "object": function (x) {
|
||||||
|
var output = ''
|
||||||
|
;
|
||||||
|
|
||||||
|
indentLevel = indentLevel.replace(/$/, ' ');
|
||||||
|
Object.keys(x).forEach(function (k) {
|
||||||
|
var val = x[k]
|
||||||
|
, handler = handlers[typeOf(val)]
|
||||||
|
;
|
||||||
|
|
||||||
|
if ('undefined' === typeof val) {
|
||||||
|
// the user should do
|
||||||
|
// delete obj.key
|
||||||
|
// and not
|
||||||
|
// obj.key = undefined
|
||||||
|
// but we'll error on the side of caution
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!handler) {
|
||||||
|
throw new Error('what the crap: ' + typeOf(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
output += '\n' + indentLevel + k + ': ' + handler(val);
|
||||||
|
});
|
||||||
|
indentLevel = indentLevel.replace(/ /, '');
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
, "function": function () {
|
||||||
|
// TODO this should throw or otherwise be ignored
|
||||||
|
return '[object Function]';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return '---' + handlers[typeOf(data)](data);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.stringify = stringify;
|
||||||
|
}());
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"author": "AJ ONeal <coolaj86@gmail.com> (http://coolaj86.info)",
|
||||||
|
"name": "json2yaml",
|
||||||
|
"description": "A commandline utility to convert JSON to YAML / YML",
|
||||||
|
"keywords": ["yml", "yaml", "json", "cli", "util"],
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "index.js",
|
||||||
|
"bin": {
|
||||||
|
"json2yaml": "./cli.js",
|
||||||
|
"json2yml": "./cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.2.0"
|
||||||
|
},
|
||||||
|
"test": ["a", "b", "c"],
|
||||||
|
"dependencies": {
|
||||||
|
"remedial": "1.x"
|
||||||
|
},
|
||||||
|
"devDependencies": {},
|
||||||
|
"preferGlobal": true
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# npm install -g yaml2json
|
||||||
|
node cli.js tests/object.json | yaml2json > /dev/null
|
||||||
|
node cli.js tests/array.json | yaml2json > /dev/null
|
||||||
|
# These tests would probably fail and seem a moot point to me
|
||||||
|
# Why use YAML for literal values? It's general used for config
|
||||||
|
# files will multiple teirs of data
|
||||||
|
#node cli.js tests/string.json | yaml2json
|
||||||
|
#node cli.js tests/number.json | yaml2json
|
||||||
|
#node cli.js tests/boolean.json | yaml2json
|
||||||
|
#node cli.js tests/null.json | yaml2json
|
||||||
|
echo "Passed if no errors are listed above (and yaml2json is installed)"
|
|
@ -0,0 +1,22 @@
|
||||||
|
[
|
||||||
|
"baz",
|
||||||
|
"qux",
|
||||||
|
"quxx",
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
{
|
||||||
|
"foo": "bar",
|
||||||
|
"corge": null,
|
||||||
|
"grault": 1,
|
||||||
|
"garply": true,
|
||||||
|
"waldo": "false",
|
||||||
|
"fred": "undefined"
|
||||||
|
},
|
||||||
|
[
|
||||||
|
"hello",
|
||||||
|
"world"
|
||||||
|
],
|
||||||
|
42,
|
||||||
|
[
|
||||||
|
]
|
||||||
|
]
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"foo": "bar",
|
||||||
|
"baz": [
|
||||||
|
"qux",
|
||||||
|
"quxx"
|
||||||
|
],
|
||||||
|
"corge": {
|
||||||
|
"grault": 1,
|
||||||
|
"garply": true,
|
||||||
|
"waldo": "false",
|
||||||
|
"fred": null
|
||||||
|
},
|
||||||
|
"empty": {
|
||||||
|
},
|
||||||
|
"hello": "world",
|
||||||
|
"answer": 42
|
||||||
|
}
|
Loading…
Reference in New Issue