UNPKG

@znode/execa

Version:
132 lines (131 loc) 4.27 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createGetCommand = exports.quote = exports.ProcessOutput = exports.substitute = exports.colorize = exports.color = void 0; const chalk = require("chalk"); // function d(m: string) { // return m.length === 1 ? "'\\''" : `'"${m}"'`; // } // const n = /\x00+/g; // const b = /^[A-Za-z0-9,:=_\.\/\-]+$/; // const p = /'+/g; // function q(o: any, x: any) { // if (!x) { // return (o.empty || "''"); // } // const s = String(x).replace(n, ''); // const m = b.exec(s); // if (m && (m[0].length === s.length)) { // const g = (o.gratuitous || ''); // return g + s + g; // } // return ("'" + s.replace(p, d) + "'") // .replace(/^''/, '') // .replace(/''$/, ''); // } // export function shq(x: string) { // return q(false, x); // } // function cfg(opt: any) { // if (!opt) { return shq; } // return function custom(x) { return q(opt, x); }; // } // Object.assign(shq, { // cfg, // always: cfg({ gratuitous: "'" }), // }); exports.color = chalk; function colorize(cmd) { return cmd.replace(/^\w+\s/, (substr) => { return chalk.greenBright(substr); }); } exports.colorize = colorize; function substitute(arg) { if (arg instanceof ProcessOutput) { return arg.stdout.replace(/\n$/, ''); } return `${arg}`; } exports.substitute = substitute; class ProcessOutput { constructor({ code, stdout, stderr, combined, __from }) { this.code = 0; this.stdout = ''; this.stderr = ''; this.combined = ''; this.__from = ''; this.code = code; this.stdout = stdout; this.stderr = stderr; this.combined = combined; this.__from = __from; } toString() { return this.combined; } } exports.ProcessOutput = ProcessOutput; function quote(arg) { if (/^[a-z0-9/_.-]+$/i.test(arg) || arg === '') { return arg; } // $'xxx' usage // => 防止 XSS 注入,比如 echo $'rm /tmp/xxx' 不会执行 rm // // $' // stackoverflow: https://unix.stackexchange.com/questions/48106/what-does-it-mean-to-have-a-dollarsign-prefixed-string-in-a-script return (`$'` + arg .replace(/\\/g, '\\\\') .replace(/'/g, "\\'") .replace(/\f/g, '\\f') .replace(/\n/g, '\\n') .replace(/\r/g, '\\r') .replace(/\t/g, '\\t') .replace(/\v/g, '\\v') .replace(/\0/g, '\\0') + `'`); } exports.quote = quote; function createGetCommand(option) { var _a; const strict = (_a = option === null || option === void 0 ? void 0 : option.strict) !== null && _a !== void 0 ? _a : true; return function getCommand(pieces, ...args) { const _pieces = [...pieces]; let cmd = _pieces[0], i = 0; // not strict mode an $`${cmd}` if (!strict && cmd === '') { // if use $`${command}`, then pieces[0] is empty, real command is args // @TODO not safe cmd = args.join(' '); } else { // $`${cmd}` if (!cmd) { throw new Error(`unsafe $\`\${cmd}\` is not allowed, use $.unsafe\`\${cmd}\` instead of`); } while (i < args.length) { let s; if (Array.isArray(args[i])) { s = args[i].map((x) => quote(substitute(x))).join(' '); } else { s = quote(substitute(args[i])); // @TODO replace ' => " // such as // from: git commit -m '$'feat: add a feature'' // ERROR COMMAND // to: git commit -m "$'feat: add a feature'" // OK // if (/['"]$/.test(_pieces[i]) && /^['"]/.test(_pieces[i + 1])) { // _pieces[i] = `${_pieces[i].slice(0, -1)}"`; _pieces[i + 1] = `${_pieces[i + 1].slice(1)}`; cmd = `${cmd.slice(0, -1)}`; } } cmd += s + _pieces[++i]; } } return cmd; }; } exports.createGetCommand = createGetCommand;