UNPKG

fsnip

Version:

Command line utility to extract and modify text or json from a file

120 lines (109 loc) 5.56 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.cli = cli; /* =====fsnip====== fsnip is a command line utility to extract and modify json from a file. */ var fs = require('fs'); var os = require('os'); var stringify = require('json-stringify-pretty-compact'); var chalk = require('chalk'); var _require = require('./runOptions.js'), runOption = _require.runOption; function cli(args) { if (args.length === 3 && args[2] === '--help') { console.info(chalk.cyan(' fsnip is a tool for extracting json or text snippets from files.\n\n') + ' Usage: ' + chalk.whiteBright('fsnip FILE [options [arguments]]\n') + ' ' + chalk.gray('process the file and output the result to the console\n\n') + ' FILE ' + chalk.gray('specifies the file to process\n') + ' Options:\n' + ' --prettify [indent] [maxLength] [margins]\n' + chalk.grey(' applies prettification to JSON\n') + ' --snip JSONPath\n' + chalk.grey(' snips the key specified by JSONPath\n') + ' --ellipsify JSONPath [JSONPath] ... [~JSONPath] ...\n' + chalk.grey(' replaces the passed json object, array or string with\n' + ' ellipses (...) but excludes any keys which follow\n' + ' prepended by ~\n' + ' eg. fsnip myfile.json --ellipsify $..address ~postcode\n') + ' --delKeys JSONPath [JSONPath] ...\n' + chalk.grey(' deletes the keys following the option\n') + ' --from TEXT\n' + ' --to TEXT\n' + ' --start TEXT\n' + ' --finish TEXT\n' + chalk.grey(' these options work on any plain file extracting the parts of the\n' + ' file after or up to the TEXT specified. --from and --to are\n' + ' exclusive, whereas --start and --finish are inclusive of the TEXT.')); } else if (args.length >= 3) { try { var txt = fs.readFileSync(args[2]).toString(); } catch (err) { console.error(chalk.redBright("unable to read file '" + args[2] + "'")); } if (typeof txt !== 'undefined') { console.info(fsnipDo(args.slice(3), txt)); } } else { // we couldn't recognise the format on the command line console.error(chalk.redBright('Unrecognised arguments passed to fsnip. See fsnip --help')); } } function fsnipDo(cmdOpts, inputText) { // does the processing of the fsnip command // inputText is the text we want to modify if (cmdOpts === null || cmdOpts.length === 0) { return inputText; } // no processing required as no options passed in var src = { // a temporary structure containing the text we are working on its type eg. 'json' (which is set later) text: inputText, type: '', outputOptions: {}, error: [], json: null, plain: null }; parseOptions(); postProcess(src); return src.error.length === 0 ? src.text : chalk.redBright(src.error); function parseOptions() { // now we are going to parse through the options and arguments to extract individual options together with their arguments var cmdOpt = ''; // current option from the cmdOptsString list var cmdArgs = []; // array containing any arguments for the cmdOpt for (var i = 0; i < cmdOpts.length; i++) { if (cmdOpts[i].substr(0, 2) === '--') { // this is a new option eg. --ellipsify processOption(); cmdOpt = cmdOpts[i]; // store the new option we have found cmdArgs = []; // reset ready for any new arguments } else { // this must be an argument for the current option if (cmdOpt === '') { // error if we don't currently have an option src.error.push("invalid argument '" + cmdOpts[i] + "' passed without valid option to fsnip"); } else { cmdArgs.push(cleanCmdOpt(cmdOpts[i])); } } } processOption(); function processOption() { // process/run any option we've found if (cmdOpt !== '') { runOption(cmdOpt, cmdArgs, src); } } function cleanCmdOpt(cmdOpt) { // deals with any special characters dealt with for cross platform purposes // in windows \$ is replaced with $ as $ is a special character which has to be delimited in posix var r = cmdOpt; /* istanbul ignore if */ if (os.platform() === 'win32') { r = r.replace(/\\\$/g, '$'); } return r; } } } function postProcess(inpObj) { // does any post process tidying up if (inpObj.type === 'json') { // stringify as required var opts = inpObj.outputOptions; if (opts.maxLength === 'infinity' && opts.margins === false) { inpObj.text = JSON.stringify(inpObj.json); } else if (opts.maxLength === 0 && opts.margins === false) { inpObj.text = JSON.stringify(inpObj.json, null, opts.indent); } else { inpObj.text = stringify(inpObj.json, opts); } // now replace any placeholders. The placeholders are valid JSON but what we replace them with may not be valid JSON inpObj.text = inpObj.text.replace(/\[\s*"fsnipPlaceholderArrEllipses"\s*\]/g, '[...]'); inpObj.text = inpObj.text.replace(/\{\s*"fsnipPlaceholderObj"\s*:\s*"Ellipses"\s*\}/g, '{...}'); // do this separately to the one below so that if the object is empty it appears all on one line inpObj.text = inpObj.text.replace(/"fsnipPlaceholderObj"\s*:\s*"Ellipses"/g, '...'); inpObj.text = inpObj.text.replace(/"fsnipPlaceholderStrEllipses"/g, '"..."'); } else if (inpObj.type === 'plain') { inpObj.text = inpObj.plain.trim(); } }