extra-asciinema
Version:
asciinema is a terminal screen recorder.
132 lines (129 loc) • 4.06 kB
JavaScript
import * as path from 'path';
import * as cp from 'child_process';
import * as fs from 'fs';
import * as os from 'os';
function escapePath(p) {
return p.replace(/[`$&{}[;|]/g, "");
}
function recCmd(f, o = null) {
var o = o || {};
if (o.input) {
var pth = escapePath(o.input);
var dir = path.dirname(pth);
var fil = path.basename(pth);
o.command = `cd "${dir}" && cat "${fil}" | node -i`;
}
o.overwrite = true;
o.yes = true;
var args = ["rec"];
if (f)
args.push(f);
if (o.stdin)
args.push("--stdin");
if (o.append)
args.push("--append");
if (o.raw)
args.push("--raw");
if (o.overwrite)
args.push("--overwrite");
if (o.command)
args.push("--command", o.command);
if (o.env)
args.push("-env", o.env);
if (o.title)
args.push("--title", o.title);
if (o.idleTimeLimit)
args.push("--idle-time-limit", "" + o.idleTimeLimit);
if (o.yes)
args.push("--yes");
if (o.quiet)
args.push("--quiet");
return args;
}
function rec(f = null, o = null, fn = null) {
var f = f || path.join(fs.mkdtempSync(path.join(os.tmpdir(), "asciinema-")), "0.cast");
var p = new Promise((fres, frej) => {
cp.execFile("asciinema", recCmd(f, o), { encoding: "utf8" }, (err) => {
if (err)
return frej(err);
fres(f);
});
});
return fn ? p.then(a => fn(null, a), fn) : p;
}
function recSync(f, o = null) {
var f = f || path.join(fs.mkdtempSync(path.join(os.tmpdir(), "asciinema-")), "0.cast");
cp.execFileSync("asciinema", recCmd(f, o), { encoding: "utf8" });
return f;
}
function cat(f, fn = null) {
var p = new Promise((fres, frej) => {
cp.execFile("asciinema", ["cat", f], { encoding: "utf8" }, (err, stdout) => {
if (err)
return frej(err);
fres(stdout);
});
});
return fn ? p.then(a => fn(null, a), fn) : p;
}
function catSync(f) {
return cp.execFileSync("asciinema", ["cat", f], { encoding: "utf8" });
}
function retimeData(d, o = null) {
var o = o || {};
var { input } = o, i = 0;
var output = "", t = o.delay || 0;
var rate = [o.outputRate || 0.1, o.inputRate || 0.1];
var delay = [o.outputDelay || 0.1, o.inputDelay || 1];
var oldState = 0, state = 0;
for (var l of d.split(/\r?\n/g)) {
if (l.startsWith("{") || l.trim() === "") {
output += l + "\n";
continue;
}
var [, , x] = JSON.parse(l);
var x1 = x.replace(/\r*\n/g, "\n");
if (input) {
var i1 = input.substring(i, i + x1.length);
i += x1 === i1 ? x1.length : 0;
state = x1 === i1 ? 1 : 0;
}
if (state !== oldState)
t += delay[state];
output += JSON.stringify([t, "o", x]) + "\n";
t += rate[state];
oldState = state;
if (!input) {
if (x.endsWith("\u001b[3G"))
state = 1;
else if (x === "\r\r\n")
state = 0;
}
}
return output;
}
async function retime(f, o = null) {
var d = await fs.promises.readFile(f, "utf8");
d = retimeData(d, o);
await fs.promises.writeFile(f, d);
}
function retimeSync(f, o = null) {
var d = fs.readFileSync(f, "utf8");
d = retimeData(d, o);
fs.writeFileSync(f, d);
}
function upload(f, fn = null) {
var p = new Promise((fres, frej) => {
cp.execFile("asciinema", ["upload", f], { encoding: "utf8" }, (err, stdout) => {
if (err)
return frej(err);
fres(stdout.replace(/.*?(https?:\S+).*/s, "$1"));
});
});
return fn ? p.then(a => fn(null, a), fn) : p;
}
function uploadSync(f) {
var stdout = cp.execFileSync("asciinema", ["upload", f], { encoding: "utf8" });
return stdout.replace(/.*?(https?:\S+).*/s, "$1");
}
export { cat, catSync, rec, recSync, retime, retimeData, retimeSync, upload, uploadSync };