diff options
author | Minteck <contact@minteck.org> | 2021-12-21 15:25:09 +0100 |
---|---|---|
committer | Minteck <contact@minteck.org> | 2021-12-21 15:25:09 +0100 |
commit | e703e51c9c09b22e3bcda9a1faf1e05897f60616 (patch) | |
tree | 4fd67a209ad6988fbf569d7dff8bc37ba45baf95 /_mint/node_modules/js-beautify/js/lib/cli.js | |
download | mint-e703e51c9c09b22e3bcda9a1faf1e05897f60616.tar.gz mint-e703e51c9c09b22e3bcda9a1faf1e05897f60616.tar.bz2 mint-e703e51c9c09b22e3bcda9a1faf1e05897f60616.zip |
Initial commit
Diffstat (limited to '_mint/node_modules/js-beautify/js/lib/cli.js')
-rw-r--r-- | _mint/node_modules/js-beautify/js/lib/cli.js | 692 |
1 files changed, 692 insertions, 0 deletions
diff --git a/_mint/node_modules/js-beautify/js/lib/cli.js b/_mint/node_modules/js-beautify/js/lib/cli.js new file mode 100644 index 0000000..070f423 --- /dev/null +++ b/_mint/node_modules/js-beautify/js/lib/cli.js @@ -0,0 +1,692 @@ +#!/usr/bin/env node + +/* + The MIT License (MIT) + + Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Js-Beautify Command-line for node.js + ------------------------------------- + + Written by Daniel Stockman (daniel.stockman@gmail.com) + +*/ +/*jshint strict:false */ + +var debug = process.env.DEBUG_JSBEAUTIFY || process.env.JSBEAUTIFY_DEBUG ? function() { + console.error.apply(console, arguments); +} : function() {}; + +var fs = require('fs'), + cc = require('config-chain'), + beautify = require('../index'), + nopt = require('nopt'), + glob = require('glob'); + +nopt.invalidHandler = function(key, val) { + throw new Error(key + " was invalid with value \"" + val + "\""); +}; + +nopt.typeDefs.brace_style = { + type: "brace_style", + validate: function(data, key, val) { + data[key] = val; + // TODO: expand-strict is obsolete, now identical to expand. Remove in future version + // TODO: collapse-preserve-inline is obselete, now identical to collapse,preserve-inline = true. Remove in future version + var validVals = ["collapse", "collapse-preserve-inline", "expand", "end-expand", "expand-strict", "none", "preserve-inline"]; + var valSplit = val.split(/[^a-zA-Z0-9_\-]+/); //Split will always return at least one parameter + for (var i = 0; i < valSplit.length; i++) { + if (validVals.indexOf(valSplit[i]) === -1) { + return false; + } + } + return true; + } +}; +var path = require('path'), + editorconfig = require('editorconfig'), + knownOpts = { + // Beautifier + "indent_size": Number, + "indent_char": String, + "eol": String, + "indent_level": Number, + "indent_with_tabs": Boolean, + "preserve_newlines": Boolean, + "max_preserve_newlines": Number, + "space_in_paren": Boolean, + "space_in_empty_paren": Boolean, + "jslint_happy": Boolean, + "space_after_anon_function": Boolean, + "space_after_named_function": Boolean, + "brace_style": "brace_style", //See above for validation + "unindent_chained_methods": Boolean, + "break_chained_methods": Boolean, + "keep_array_indentation": Boolean, + "unescape_strings": Boolean, + "wrap_line_length": Number, + "wrap_attributes": ["auto", "force", "force-aligned", "force-expand-multiline", "aligned-multiple", "preserve", "preserve-aligned"], + "wrap_attributes_indent_size": Number, + "e4x": Boolean, + "end_with_newline": Boolean, + "comma_first": Boolean, + "operator_position": ["before-newline", "after-newline", "preserve-newline"], + "indent_empty_lines": Boolean, + "templating": [String, Array], + // CSS-only + "selector_separator_newline": Boolean, + "newline_between_rules": Boolean, + "space_around_combinator": Boolean, + //deprecated - replaced with space_around_combinator, remove in future version + "space_around_selector_separator": Boolean, + // HTML-only + "max_char": Number, // obsolete since 1.3.5 + "inline": [String, Array], + "unformatted": [String, Array], + "content_unformatted": [String, Array], + "indent_inner_html": [Boolean], + "indent_handlebars": [Boolean], + "indent_scripts": ["keep", "separate", "normal"], + "extra_liners": [String, Array], + "unformatted_content_delimiter": String, + // CLI + "version": Boolean, + "help": Boolean, + "files": [path, Array], + "outfile": path, + "replace": Boolean, + "quiet": Boolean, + "type": ["js", "css", "html"], + "config": path, + "editorconfig": Boolean + }, + // dasherizeShorthands provides { "indent-size": ["--indent_size"] } + // translation, allowing more convenient dashes in CLI arguments + shortHands = dasherizeShorthands({ + // Beautifier + "s": ["--indent_size"], + "c": ["--indent_char"], + "e": ["--eol"], + "l": ["--indent_level"], + "t": ["--indent_with_tabs"], + "p": ["--preserve_newlines"], + "m": ["--max_preserve_newlines"], + "P": ["--space_in_paren"], + "Q": ["--space_in_empty_paren"], + "j": ["--jslint_happy"], + "a": ["--space_after_anon_function"], + "b": ["--brace_style"], + "u": ["--unindent_chained_methods"], + "B": ["--break_chained_methods"], + "k": ["--keep_array_indentation"], + "x": ["--unescape_strings"], + "w": ["--wrap_line_length"], + "X": ["--e4x"], + "n": ["--end_with_newline"], + "C": ["--comma_first"], + "O": ["--operator_position"], + // CSS-only + "L": ["--selector_separator_newline"], + "N": ["--newline_between_rules"], + // HTML-only + "A": ["--wrap_attributes"], + "i": ["--wrap_attributes_indent_size"], + "W": ["--max_char"], // obsolete since 1.3.5 + "d": ["--inline"], + "U": ["--unformatted"], + "T": ["--content_unformatted"], + "I": ["--indent_inner_html"], + "H": ["--indent_handlebars"], + "S": ["--indent_scripts"], + "E": ["--extra_liners"], + // non-dasherized hybrid shortcuts + "good-stuff": [ + "--keep_array_indentation", + "--keep_function_indentation", + "--jslint_happy" + ], + "js": ["--type", "js"], + "css": ["--type", "css"], + "html": ["--type", "html"], + // CLI + "v": ["--version"], + "h": ["--help"], + "f": ["--files"], + "file": ["--files"], + "o": ["--outfile"], + "r": ["--replace"], + "q": ["--quiet"] + // no shorthand for "config" + // no shorthand for "editorconfig" + // no shorthand for "indent_empty_lines" + // not shorthad for "templating" + }); + +function verifyExists(fullPath) { + return fs.existsSync(fullPath) ? fullPath : null; +} + +function findRecursive(dir, fileName) { + var fullPath = path.join(dir, fileName); + var nextDir = path.dirname(dir); + var result = verifyExists(fullPath); + + if (!result && (nextDir !== dir)) { + result = findRecursive(nextDir, fileName); + } + + return result; +} + +function getUserHome() { + var user_home = ''; + try { + user_home = process.env.USERPROFILE || process.env.HOME || ''; + } catch (ex) {} + return user_home; +} + +function set_file_editorconfig_opts(file, config) { + try { + var eConfigs = editorconfig.parseSync(file); + + if (eConfigs.indent_style === "tab") { + config.indent_with_tabs = true; + } else if (eConfigs.indent_style === "space") { + config.indent_with_tabs = false; + } + + if (eConfigs.indent_size) { + config.indent_size = eConfigs.indent_size; + } + + if (eConfigs.max_line_length) { + if (eConfigs.max_line_length === "off") { + config.wrap_line_length = 0; + } else { + config.wrap_line_length = parseInt(eConfigs.max_line_length, 10); + } + } + + if (eConfigs.insert_final_newline === true) { + config.end_with_newline = true; + } else if (eConfigs.insert_final_newline === false) { + config.end_with_newline = false; + } + + if (eConfigs.end_of_line) { + if (eConfigs.end_of_line === 'cr') { + config.eol = '\r'; + } else if (eConfigs.end_of_line === 'lf') { + config.eol = '\n'; + } else if (eConfigs.end_of_line === 'crlf') { + config.eol = '\r\n'; + } + } + } catch (e) { + debug(e); + } +} + +// var cli = require('js-beautify/cli'); cli.interpret(); +var interpret = exports.interpret = function(argv, slice) { + var parsed; + try { + parsed = nopt(knownOpts, shortHands, argv, slice); + } catch (ex) { + usage(ex); + // console.error(ex); + // console.error('Run `' + getScriptName() + ' -h` for help.'); + process.exit(1); + } + + + if (parsed.version) { + console.log(require('../../package.json').version); + process.exit(0); + } else if (parsed.help) { + usage(); + process.exit(0); + } + + var cfg; + var configRecursive = findRecursive(process.cwd(), '.jsbeautifyrc'); + var configHome = verifyExists(path.join(getUserHome() || "", ".jsbeautifyrc")); + var configDefault = __dirname + '/../config/defaults.json'; + + try { + cfg = cc( + parsed, + cleanOptions(cc.env('jsbeautify_'), knownOpts), + parsed.config, + configRecursive, + configHome, + configDefault + ).snapshot; + } catch (ex) { + debug(cfg); + // usage(ex); + console.error(ex); + console.error('Error while loading beautifier configuration.'); + console.error('Configuration file chain included:'); + if (parsed.config) { + console.error(parsed.config); + } + if (configRecursive) { + console.error(configRecursive); + } + if (configHome) { + console.error(configHome); + } + console.error(configDefault); + console.error('Run `' + getScriptName() + ' -h` for help.'); + process.exit(1); + } + + try { + // Verify arguments + checkType(cfg); + checkFiles(cfg); + debug(cfg); + + // Process files synchronously to avoid EMFILE error + cfg.files.forEach(processInputSync, { + cfg: cfg + }); + } catch (ex) { + debug(cfg); + // usage(ex); + console.error(ex); + console.error('Run `' + getScriptName() + ' -h` for help.'); + process.exit(1); + } +}; + +// interpret args immediately when called as executable +if (require.main === module) { + interpret(); +} + +function usage(err) { + var scriptName = getScriptName(); + var msg = [ + scriptName + '@' + require('../../package.json').version, + '', + 'CLI Options:', + ' -f, --file Input file(s) (Pass \'-\' for stdin)', + ' -r, --replace Write output in-place, replacing input', + ' -o, --outfile Write output to file (default stdout)', + ' --config Path to config file', + ' --type [js|css|html] ["js"]', + ' -q, --quiet Suppress logging to stdout', + ' -h, --help Show this help', + ' -v, --version Show the version', + '', + 'Beautifier Options:', + ' -s, --indent-size Indentation size [4]', + ' -c, --indent-char Indentation character [" "]', + ' -t, --indent-with-tabs Indent with tabs, overrides -s and -c', + ' -e, --eol Character(s) to use as line terminators.', + ' [first newline in file, otherwise "\\n]', + ' -n, --end-with-newline End output with newline', + ' --indent-empty-lines Keep indentation on empty lines', + ' --templating List of templating languages (auto,none,django,erb,handlebars,php,smarty) ["auto"] auto = none in JavaScript, all in html', + ' --editorconfig Use EditorConfig to set up the options' + ]; + + switch (scriptName.split('-').shift()) { + case "js": + msg.push(' -l, --indent-level Initial indentation level [0]'); + msg.push(' -p, --preserve-newlines Preserve line-breaks (--no-preserve-newlines disables)'); + msg.push(' -m, --max-preserve-newlines Number of line-breaks to be preserved in one chunk [10]'); + msg.push(' -P, --space-in-paren Add padding spaces within paren, ie. f( a, b )'); + msg.push(' -E, --space-in-empty-paren Add a single space inside empty paren, ie. f( )'); + msg.push(' -j, --jslint-happy Enable jslint-stricter mode'); + msg.push(' -a, --space-after-anon-function Add a space before an anonymous function\'s parens, ie. function ()'); + msg.push(' --space_after_named_function Add a space before a named function\'s parens, ie. function example ()'); + msg.push(' -b, --brace-style [collapse|expand|end-expand|none][,preserve-inline] [collapse,preserve-inline]'); + msg.push(' -u, --unindent-chained-methods Don\'t indent chained method calls'); + msg.push(' -B, --break-chained-methods Break chained method calls across subsequent lines'); + msg.push(' -k, --keep-array-indentation Preserve array indentation'); + msg.push(' -x, --unescape-strings Decode printable characters encoded in xNN notation'); + msg.push(' -w, --wrap-line-length Wrap lines that exceed N characters [0]'); + msg.push(' -X, --e4x Pass E4X xml literals through untouched'); + msg.push(' --good-stuff Warm the cockles of Crockford\'s heart'); + msg.push(' -C, --comma-first Put commas at the beginning of new line instead of end'); + msg.push(' -O, --operator-position Set operator position (before-newline|after-newline|preserve-newline) [before-newline]'); + break; + case "html": + msg.push(' -b, --brace-style [collapse|expand|end-expand] ["collapse"]'); + msg.push(' -I, --indent-inner-html Indent body and head sections. Default is false.'); + msg.push(' -H, --indent-handlebars Indent handlebars. Default is false.'); + msg.push(' -S, --indent-scripts [keep|separate|normal] ["normal"]'); + msg.push(' -w, --wrap-line-length Wrap lines that exceed N characters [0]'); + msg.push(' -A, --wrap-attributes Wrap html tag attributes to new lines [auto|force|force-aligned|force-expand-multiline|aligned-multiple|preserve|preserve-aligned] ["auto"]'); + msg.push(' -i, --wrap-attributes-indent-size Indent wrapped tags to after N characters [indent-level]'); + msg.push(' -p, --preserve-newlines Preserve line-breaks (--no-preserve-newlines disables)'); + msg.push(' -m, --max-preserve-newlines Number of line-breaks to be preserved in one chunk [10]'); + msg.push(' -U, --unformatted List of tags (defaults to inline) that should not be reformatted'); + msg.push(' -T, --content_unformatted List of tags (defaults to pre) whose content should not be reformatted'); + msg.push(' -E, --extra_liners List of tags (defaults to [head,body,/html] that should have an extra newline'); + msg.push(' --unformatted_content_delimiter Keep text content together between this string [""]'); + break; + case "css": + msg.push(' -b, --brace-style [collapse|expand] ["collapse"]'); + msg.push(' -L, --selector-separator-newline Add a newline between multiple selectors.'); + msg.push(' -N, --newline-between-rules Add a newline between CSS rules.'); + } + + if (err) { + msg.push(err); + msg.push(''); + console.error(msg.join('\n')); + } else { + console.log(msg.join('\n')); + } +} + +// main iterator, {cfg} passed as thisArg of forEach call + +function processInputSync(filepath) { + var data = null, + config = this.cfg, + outfile = config.outfile, + input; + + // -o passed with no value overwrites + if (outfile === true || config.replace) { + outfile = filepath; + } + + var fileType = getOutputType(outfile, filepath, config.type); + + if (config.editorconfig) { + var editorconfig_filepath = filepath; + + if (editorconfig_filepath === '-') { + if (outfile) { + editorconfig_filepath = outfile; + } else { + editorconfig_filepath = 'stdin.' + fileType; + } + } + + debug("EditorConfig is enabled for ", editorconfig_filepath); + config = cc(config).snapshot; + set_file_editorconfig_opts(editorconfig_filepath, config); + debug(config); + } + + if (filepath === '-') { + input = process.stdin; + + input.setEncoding('utf8'); + + input.on('error', function() { + throw 'Must pipe input or define at least one file.'; + }); + + input.on('data', function(chunk) { + data = data || ''; + data += chunk; + }); + + input.on('end', function() { + if (data === null) { + throw 'Must pipe input or define at least one file.'; + } + makePretty(fileType, data, config, outfile, writePretty); // Where things get beautified + }); + + input.resume(); + + } else { + data = fs.readFileSync(filepath, 'utf8'); + makePretty(fileType, data, config, outfile, writePretty); + } +} + +function makePretty(fileType, code, config, outfile, callback) { + try { + var pretty = beautify[fileType](code, config); + + callback(null, pretty, outfile, config); + } catch (ex) { + callback(ex); + } +} + +function writePretty(err, pretty, outfile, config) { + debug('writing ' + outfile); + if (err) { + console.error(err); + process.exit(1); + } + + if (outfile) { + fs.mkdirSync(path.dirname(outfile), { recursive: true }); + + if (isFileDifferent(outfile, pretty)) { + try { + fs.writeFileSync(outfile, pretty, 'utf8'); + logToStdout('beautified ' + path.relative(process.cwd(), outfile), config); + } catch (ex) { + onOutputError(ex); + } + } else { + logToStdout('beautified ' + path.relative(process.cwd(), outfile) + ' - unchanged', config); + } + } else { + process.stdout.write(pretty); + } +} + +function isFileDifferent(filePath, expected) { + try { + return fs.readFileSync(filePath, 'utf8') !== expected; + } catch (ex) { + // failing to read is the same as different + return true; + } +} + +// workaround the fact that nopt.clean doesn't return the object passed in :P + +function cleanOptions(data, types) { + nopt.clean(data, types); + return data; +} + +// error handler for output stream that swallows errors silently, +// allowing the loop to continue over unwritable files. + +function onOutputError(err) { + if (err.code === 'EACCES') { + console.error(err.path + " is not writable. Skipping!"); + } else { + console.error(err); + process.exit(0); + } +} + +// turn "--foo_bar" into "foo-bar" + +function dasherizeFlag(str) { + return str.replace(/^\-+/, '').replace(/_/g, '-'); +} + +// translate weird python underscored keys into dashed argv, +// avoiding single character aliases. + +function dasherizeShorthands(hash) { + // operate in-place + Object.keys(hash).forEach(function(key) { + // each key value is an array + var val = hash[key][0]; + // only dasherize one-character shorthands + if (key.length === 1 && val.indexOf('_') > -1) { + hash[dasherizeFlag(val)] = val; + } + }); + + return hash; +} + +function getOutputType(outfile, filepath, configType) { + if (outfile && /\.(js|css|html)$/.test(outfile)) { + return outfile.split('.').pop(); + } else if (filepath !== '-' && /\.(js|css|html)$/.test(filepath)) { + return filepath.split('.').pop(); + } else if (configType) { + return configType; + } else { + throw 'Could not determine appropriate beautifier from file paths: ' + filepath; + } +} + +function getScriptName() { + return path.basename(process.argv[1]); +} + +function checkType(parsed) { + var scriptType = getScriptName().split('-').shift(); + if (!/^(js|css|html)$/.test(scriptType)) { + scriptType = null; + } + + debug("executable type:", scriptType); + + var parsedType = parsed.type; + debug("parsed type:", parsedType); + + if (!parsedType) { + debug("type defaulted:", scriptType); + parsed.type = scriptType; + } +} + +function checkFiles(parsed) { + var argv = parsed.argv; + var isTTY = true; + var file_params = parsed.files || []; + var hadGlob = false; + + try { + isTTY = process.stdin.isTTY; + } catch (ex) { + debug("error querying for isTTY:", ex); + } + + debug('isTTY: ' + isTTY); + + // assume any remaining args are files + file_params = file_params.concat(argv.remain); + + parsed.files = []; + // assume any remaining args are files + file_params.forEach(function(f) { + // strip stdin path eagerly added by nopt in '-f -' case + if (f === '-') { + return; + } + + var foundFiles = []; + var isGlob = glob.hasMagic(f); + + // Input was a glob + if (isGlob) { + hadGlob = true; + foundFiles = glob(f, { + sync: true, + absolute: true, + ignore: ['**/node_modules/**', '**/.git/**'] + }); + } else { + // Input was not a glob, add it to an array so we are able to handle it in the same loop below + try { + testFilePath(f); + } catch (err) { + // if file is not found, and the resolved path indicates stdin marker + if (path.parse(f).base === '-') { + f = '-'; + } else { + throw err; + } + } + foundFiles = [f]; + } + + if (foundFiles && foundFiles.length) { + // Add files to the parsed.files if it didn't exist in the array yet + foundFiles.forEach(function(file) { + var filePath = path.resolve(file); + if (file === '-') { // case of stdin + parsed.files.push(file); + } else if (parsed.files.indexOf(filePath) === -1) { + parsed.files.push(filePath); + } + }); + } + }); + + if ('string' === typeof parsed.outfile && isTTY && !parsed.files.length) { + testFilePath(parsed.outfile); + // use outfile as input when no other files passed in args + parsed.files.push(parsed.outfile); + // operation is now an implicit overwrite + parsed.replace = true; + } + + if (hadGlob || parsed.files.length > 1) { + parsed.replace = true; + } + + if (!parsed.files.length && !hadGlob) { + // read stdin by default + parsed.files.push('-'); + } + + debug('files.length ' + parsed.files.length); + + if (parsed.files.indexOf('-') > -1 && isTTY && !hadGlob) { + throw 'Must pipe input or define at least one file.'; + } + + return parsed; +} + +function testFilePath(filepath) { + try { + if (filepath !== "-") { + fs.statSync(filepath); + } + } catch (err) { + throw 'Unable to open path "' + filepath + '"'; + } +} + +function logToStdout(str, config) { + if (typeof config.quiet === "undefined" || !config.quiet) { + console.log(str); + } +}
\ No newline at end of file |