UNPKG

@dada78641/bwrank

Version:

Fetches a StarCraft player's ladder rank from the BW internal API

99 lines (84 loc) 2.94 kB
// bwrank <https://github.com/msikma/bwrank> // © MIT license import {spawn} from 'child_process' /** Default options for exec(). */ const defaultOpts = { // If true, output is sent to the log function as well (process.stdout and process.stderr by default). logged: false, // Log functions for stdout and stderr. logOutFn: (str, encoding = null) => process.stdout.write(str, encoding), logErrFn: (str, encoding = null) => process.stderr.write(str, encoding) } /** Default options passed to child_process.spawn(). */ const defaultSpawnOpts = {} /** Encodes a buffer into a string, if an encoding is specified. */ const encode = (buffer, encoding) => { if (encoding) { return buffer.toString(encoding) } return buffer } /** * Runs exec() and treats the output as text with a default encoding of UTF-8. */ export const execToText = async (cmd, userOpts = {}, userSpawnOpts = {}) => { const result = await exec(cmd, {encoding: 'utf8', ...userOpts}, userSpawnOpts) return result.stdout } /** * Runs exec() and parses the result as JSON. * * Defaults to UTF-8 as the encoding. Only stdout data is used for parsing. */ export const execToJSON = async (cmd, userOpts = {}, userSpawnOpts = {}) => { const result = await exec(cmd, {encoding: 'utf8', ...userOpts}, userSpawnOpts) return JSON.parse(result.stdout) } /** * Runs an external command and returns an object with the result and an exit code. * * The result is decoded into a string if an encoding is specified, or returned as a Buffer otherwise. * Output is split into stdout and stderr, with an additional stdall containing both of them interlaced. */ export const exec = (cmd, userOpts = {}, userSpawnOpts = {}) => new Promise((resolve, reject) => { const opts = {...defaultOpts, ...userOpts} const spawnOpts = {...defaultSpawnOpts, ...userSpawnOpts} const {logOutFn, logErrFn, logged} = opts const proc = spawn(cmd.slice(0, 1)[0], cmd.slice(1), {...spawnOpts}) const output = { stdout: [], stderr: [], stdall: [], code: null, signal: null, error: null } /** Returns the final state of the output; only ever called when exiting. */ const finalize = () => { return { ...output, stdout: encode(Buffer.concat(output.stdout), opts.encoding), stderr: encode(Buffer.concat(output.stderr), opts.encoding), stdall: encode(Buffer.concat(output.stdall), opts.encoding) } } proc.stdout.on('data', (data) => { logOutFn && logged && logOutFn(data) output.stdout.push(data) output.stdall.push(data) }) proc.stderr.on('data', (data) => { logErrFn && logged && logErrFn(data) output.stderr.push(data) output.stdall.push(data) }) proc.on('close', (code, signal) => { output.code = code output.signal = signal return resolve(finalize()) }) proc.on('error', (err) => { output.error = err return reject(finalize()) }) })