UNPKG

waterline-postgresql

Version:
179 lines (160 loc) 4.7 kB
#!/usr/bin/env node var fs = require("fs"); var path = require("path"); var parser = require("./jsonlint").parser; var JSV = require("JSV").JSV; var formatter = require("./formatter.js").formatter; var options = require("nomnom") .script("jsonlint") .options({ file: { position: 0, help: "file to parse; otherwise uses stdin" }, version: { flag : true, string: '-v, --version', help: 'print version and exit', callback: function() { return require("../package").version; } }, sort : { flag : true, string: '-s, --sort-keys', help: 'sort object keys' }, inplace : { flag : true, string: '-i, --in-place', help: 'overwrite the file' }, indent : { string: '-t CHAR, --indent CHAR', "default": " ", help: 'character(s) to use for indentation' }, compact : { flag : true, string: '-c, --compact', help : 'compact error display' }, validate : { string: '-V, --validate', help : 'a JSON schema to use for validation' }, env : { string: '-e, --environment', "default": "json-schema-draft-03", help: 'which specification of JSON Schema the validation file uses' }, quiet: { flag: true, key: "value", string: '-q, --quiet', "default": false, help: 'do not print the parsed json to STDOUT' }, forcePrettyPrint: { flag: true, string: '-p, --pretty-print', help: 'force pretty printing even if invalid' } }).parse(); if (options.compact) { var fileName = options.file? options.file + ': ' : ''; parser.parseError = parser.lexer.parseError = function(str, hash) { console.error(fileName + 'line '+ hash.loc.first_line +', col '+ hash.loc.last_column +', found: \''+ hash.token +'\' - expected: '+ hash.expected.join(', ') +'.'); throw new Error(str); }; } function parse (source) { var parsed, formatted; try { parsed = options.sort ? sortObject(parser.parse(source)) : parser.parse(source); if (options.validate) { var env = JSV.createEnvironment(options.env); var schema = JSON.parse(fs.readFileSync(path.normalize(options.validate), "utf8")); var report = env.validate(parsed, schema); if (report.errors.length) { throw report.errors.reduce(schemaError, 'Validation Errors:'); } } return JSON.stringify(parsed,null,options.indent); } catch (e) { if ( options.forcePrettyPrint ) { /* From https://github.com/umbrae/jsonlintdotcom: * If we failed to validate, run our manual formatter and then re-validate so that we * can get a better line number. On a successful validate, we don't want to run our * manual formatter because the automatic one is faster and probably more reliable. */ try { formatted = formatter.formatJson(source, options.indent); // Re-parse so exception output gets better line numbers parsed = parser.parse(formatted); } catch (e) { if (! options.compact) { console.error(e); } return formatted; process.exit(1); } } else { if (! options.compact) { console.error(e); } process.exit(1); } } } function schemaError (str, err) { return str + "\n\n"+err.message + "\nuri: " + err.uri + "\nschemaUri: " + err.schemaUri + "\nattribute: " + err.attribute + "\ndetails: " + JSON.stringify(err.details); } function main (args) { var source = ''; if (options.file) { var json = path.normalize(options.file); source = parse(fs.readFileSync(json, "utf8")); if (options.inplace) { fs.writeSync(fs.openSync(json,'w+'), source, 0, "utf8"); } else { if (! options.quiet) { console.log(source)}; } } else { var stdin = process.openStdin(); stdin.setEncoding('utf8'); stdin.on('data', function (chunk) { source += chunk.toString('utf8'); }); stdin.on('end', function () { if (! options.quiet) {console.log(parse(source))}; }); } } // from http://stackoverflow.com/questions/1359761/sorting-a-json-object-in-javascript function sortObject(o) { if (Object.prototype.toString.call(o) !== '[object Object]') { return o; } var sorted = {}, key, a = []; for (key in o) { if (o.hasOwnProperty(key)) { a.push(key); } } a.sort(); for (key = 0; key < a.length; key++) { sorted[a[key]] = sortObject(o[a[key]]); } return sorted; } main(process.argv.slice(1));