@mountainpass/hooked-cli
Version:
A tool for runnable scripts
92 lines (91 loc) • 3.53 kB
JavaScript
import fs from 'fs';
import { stripEmojis } from './config.js';
import defaults from './defaults.js';
import logger from './utils/logger.js';
/**
* Retrieves the history log of previous commands.
* @param max (default: 20) - max number of records to fetch
* @returns
*/
export const fetchHistory = (max = 20) => {
const filepath = defaults.getDefaults().HISTORY_PATH;
if (fs.existsSync(filepath)) {
const lines = fs.readFileSync(filepath, 'utf-8').split(/\r?\n/g);
return lines
.filter((line) => line.trim().length > 0)
.map((line) => JSON.parse(line))
.sort((a, b) => b.ts - a.ts)
.filter((_, i) => i < max);
}
else {
return [];
}
};
export const fetchHistoryAsRunnableLogs = (max = 20) => {
const history = fetchHistory(max);
return history.map(script => displaySuccessfulScript(script, true));
};
/**
* Prints a history of previous commands.
*/
export const printHistory = (max = 20) => {
const history = fetchHistoryAsRunnableLogs(max);
if (history.length > 0) {
history.forEach((line) => { logger.info(line); });
}
else {
logger.debug('No history found.');
}
};
/**
* Formats the given timestamp as a local ISO string.
* @param ts
* @param tzoffsetMinutes
* @returns
*/
export const formatLocalISOString = (ts, tzoffsetMinutes = new Date().getTimezoneOffset()) => {
const tzoffsetMs = tzoffsetMinutes * 60000; // offset in milliseconds
const localISOTime = (new Date(ts - tzoffsetMs)).toISOString().slice(0, -5) +
(tzoffsetMinutes > 0 ? '-' : '+') +
(`0${Math.abs(tzoffsetMinutes / 60)}`).slice(-2) +
':' +
(`0${Math.abs(tzoffsetMinutes % 60)}`).slice(-2);
return localISOTime;
};
/**
* Show the rerunnable script.
* @param script
* @param showTimestamp
* @returns
*/
export const displaySuccessfulScript = (script, showTimestamp = false, tzoffsetMinutes = new Date().getTimezoneOffset()) => {
return displayReRunnableScript(script.scriptPath, script.envNames, script.stdin, undefined, script.ts, showTimestamp, tzoffsetMinutes);
};
export const displayInvocationResult = (script, showTimestamp = false, tzoffsetMinutes = new Date().getTimezoneOffset()) => {
return displayReRunnableScript(script.paths, script.envNames, script.envVars, undefined, script.finishedAt, showTimestamp, tzoffsetMinutes);
};
export const displayReRunnableScript = (scriptPath, envNames, stdin, configFilePath, ts = Date.now(), showTimestamp = false, tzoffsetMinutes = new Date().getTimezoneOffset()) => {
const timestamp = formatLocalISOString(ts, tzoffsetMinutes);
const scriptstr = scriptPath.map(s => {
const script = stripEmojis(s);
// if has whitespace, add quotes
return (/[^\w]/).test(script) ? `"${script}"` : script;
}).join(' ');
const envstr = envNames.length > 0 ? `--env ${envNames.join(',')}` : '';
const stdinstr = Object.keys(stdin).length > 0 ? `--stdin '${JSON.stringify(stdin)}'` : '';
const config = configFilePath ? `--config ${configFilePath}` : '';
return `${showTimestamp ? `${timestamp}: ` : ''}j ${[
scriptstr,
envstr,
stdinstr,
config
].filter(f => f).join(' ')}`;
};
/**
* Append a line onto the end of a file.
* @param script
*/
export const addHistory = (script) => {
const filepath = defaults.getDefaults().HISTORY_PATH;
fs.writeFileSync(filepath, JSON.stringify(script) + '\n', { flag: 'a', encoding: 'utf-8' });
};