UNPKG

fixjson

Version:

JSON fixer for humans using (relaxed) JSON5

177 lines 5.98 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.fixFile = exports.fixString = void 0; const fs = require("fs"); const JSON5R = require("json5-relaxed"); const glob = require("glob"); const detectIndent = require("detect-indent"); function readFromStdin() { process.stdin.setEncoding('utf8'); return new Promise(resolve => { let buf = ''; process.stdin.on('data', chunk => { buf += chunk; }); process.stdin.on('end', () => { resolve(buf); }); }); } function readFile(path) { return new Promise((resolve, reject) => { fs.readFile(path, 'utf8', (err, data) => { if (err) { reject(err); return; } resolve(data); }); }); } function write(writer, chunk) { return new Promise(resolve => writer.write(chunk, 'utf8', resolve)); } function isDirectory(path) { return new Promise((resolve, reject) => { fs.stat(path, (err, stat) => { if (err) { reject(err); } else { resolve(stat.isDirectory()); } }); }); } function globPath(path) { return new Promise((resolve, reject) => { glob(path, (err, p) => (err ? reject(err) : resolve(p))); }); } function globOne(pattern) { return __awaiter(this, void 0, void 0, function* () { const globbed = yield globPath(pattern); const paths = []; for (const path of globbed) { if (!(yield isDirectory(path))) { paths.push(path); } let pat = path; if (pat[pat.length - 1] !== '/') { pat += '/'; } pat += '**/*.json'; Array.prototype.push.apply(paths, yield globPath(pat)); } return paths; }); } function globAll(pats) { return __awaiter(this, void 0, void 0, function* () { if (pats.length === 0) { // shortcut return []; } // flatten const paths = []; for (const p of yield Promise.all(pats.map(globOne))) { Array.prototype.push.apply(paths, p); } return paths; }); } class FixJSON { constructor(config) { this.config = Object.assign({ write: false, minify: false, stdout: process.stdout }, config); this.stdout = this.config.stdout || process.stdout; } main(argv) { return __awaiter(this, void 0, void 0, function* () { const stdin = argv.length === 0; if (stdin) { const src = yield this.parseStdin(); if (this.stdout.setEncoding) { this.stdout.setEncoding('utf8'); } this.stdout.write(this.unparse(src)); return 1; } const files = yield globAll(argv); yield this.fixFiles(files); return files.length; }); } fixFiles(paths) { return __awaiter(this, void 0, void 0, function* () { const parsed = Promise.all(paths.map(p => this.parseFile(p))); if (!this.config.write && this.stdout.setEncoding) { this.stdout.setEncoding('utf8'); } for (const src of yield parsed) { const writer = this.config.write ? fs.createWriteStream(src.name) : this.stdout; yield write(writer, this.unparse(src)); } }); } convertString(input) { return this.unparse({ name: '', parsed: JSON5R.parse(input), indent: this.indent(input) }); } convertFile(path) { return __awaiter(this, void 0, void 0, function* () { return this.unparse(yield this.parseFile(path)); }); } indent(code) { const { indent, minify } = this.config; const spaces = minify ? '' : indent ? ' '.repeat(indent) : detectIndent(code).indent; return spaces || ' '; } unparse(src) { return JSON.stringify(src.parsed, null, src.indent) + '\n'; } parseString(code, file) { try { return JSON5R.parse(code); } catch (e) { e.message = `${file}: ${e.message}`; throw e; } } parseStdin() { return __awaiter(this, void 0, void 0, function* () { const name = this.config.stdinFilename || '<stdin>'; const code = yield readFromStdin(); const parsed = this.parseString(code, name); return { name, parsed, indent: this.indent(code) }; }); } parseFile(path) { return __awaiter(this, void 0, void 0, function* () { const code = yield readFile(path); const parsed = this.parseString(code, path); const indent = this.indent(code); return { name: path, parsed, indent }; }); } } exports.default = FixJSON; // Helper APIs function fixString(input, config) { return new FixJSON(config).convertString(input); } exports.fixString = fixString; function fixFile(file, config) { return new FixJSON(config).convertFile(file); } exports.fixFile = fixFile; //# sourceMappingURL=index.js.map