import { spawnSync, SpawnSyncOptions } from 'child_process' import { randomBytes } from 'crypto' export const exec = (command: string, args: string[], { env, ...rest }: SpawnSyncOptions = {}) => { const cmd = spawnSync(command, args, { ...rest, env: { ...process.env, ...env, }, }) const out = cmd.stdout && cmd.stdout.toString().trim() const err = cmd.stderr && cmd.stderr.toString().trim() return { out, err } } export const checkIfResticIsAvailable = () => checkIfCommandIsAvailable( 'restic', 'Restic is not installed'.red + ' https://restic.readthedocs.io/en/latest/020_installation.html#stable-releases', ) export const checkIfCommandIsAvailable = (cmd: string, errorMsg?: string) => { if (require('child_process').spawnSync(cmd).error) throw new Error(errorMsg ? errorMsg : `"${errorMsg}" is not installed`.red) } export const makeObjectKeysLowercase = (object: Object): any => Object.fromEntries( Object.entries(object) .map(([key, value]) => [key.toLowerCase(), value]), ) export function rand(length = 32): string { return randomBytes(length / 2).toString('hex') } export const singleToArray = (singleOrArray: T | T[]): T[] => Array.isArray(singleOrArray) ? singleOrArray : [singleOrArray] export const filterObject = (obj: { [key: string]: T }, filter: (item: [string, T]) => boolean): { [key: string]: T } => Object.fromEntries(Object.entries(obj).filter(filter)) export const filterObjectByKey = (obj: { [key: string]: T }, keys: string[]) => filterObject(obj, ([key]) => keys.includes(key))