@znode/execa
Version:
Node.js Exec Sub Shell
132 lines (131 loc) • 4.27 kB
JavaScript
;
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;