UNPKG

@u4/adbkit

Version:

A Typescript client for the Android Debug Bridge.

150 lines 5.31 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const parser_1 = __importDefault(require("./parser")); const auth_1 = __importDefault(require("./auth")); const stream_1 = require("stream"); const debug_1 = __importDefault(require("debug")); class Utils { /** * Takes a [`Stream`][node-stream] and reads everything it outputs until the stream ends. Then it resolves with the collected output. Convenient with `client.shell()`. * * @param stream The [`Stream`][node-stream] to read. * @returns All the output as a [`Buffer`][node-buffer]. Use `output.toString('utf-8')` to get a readable string from it. */ static readAll(stream) { return new parser_1.default(stream).readAll(); } /** * Parses an Android-formatted mincrypt public key (e.g. `~/.android/adbkey.pub`). * * @param keyString The key String or [`Buffer`][node-buffer] to parse. Not a filename. * @returns The key as a [forge.pki](https://github.com/digitalbazaar/forge#rsa) public key. You may need [node-forge](https://github.com/digitalbazaar/forge) for complicated operations. */ static parsePublicKey(keyString) { return auth_1.default.parsePublicKey(keyString); } /** * A delay promise * * @param ms time to wait im ms * @returns void */ static delay(ms) { let timeout = null; const promise = new Promise((resolve) => { timeout = setTimeout(() => { timeout = null; resolve(); }, ms); }); promise.cancel = () => { if (timeout) clearTimeout(timeout); timeout = null; }; return promise; } /** * Promise waiter for a Duplex to be readable * * @param duplex a vanilla Duplex of a PromiseDuplex * @param timeout do not wait more than timeout * @returns is the true is duplex is readable */ // eslint-disable-next-line @typescript-eslint/no-unused-vars static async waitforReadable(duplex, timeout = 0, _debugCtxt = '') { // let t0 = Date.now(); /** * prechecks */ if (!duplex) throw Error('can not waitforReadable on a null / undefined duplex'); const stream = (duplex instanceof stream_1.Duplex || duplex instanceof stream_1.Readable) ? duplex : duplex.stream; if (stream.closed) throw Error('can not waitforReadable on a closed duplex'); // short-cut if (stream.readableLength > 0) return true; /** * readable is true by default */ let readable = true; /** * handle close event */ let onClose = () => { }; const waitClose = new Promise((resolveAsClosed) => { onClose = resolveAsClosed; stream.on('close', onClose); }); /** * Handle readable event * overwrite theResolve */ let theResolve = () => { }; const waitRead = new Promise((resolveAsReadable) => { theResolve = resolveAsReadable; stream.on('readable', theResolve); }); const promises = [waitRead, waitClose]; /** * Handle timeout event */ let timeOut = null; if (timeout) { timeOut = Utils.delay(timeout); promises.push(timeOut.then(() => { readable = false; })); } /** * single Promise race call */ await Promise.race(promises); /** * clean unused events */ stream.off('readable', theResolve); stream.off('close', onClose); if (timeOut) timeOut.cancel(); // t0 = Date.now() - t0; // console.log(`waitforReadable return after ${t0}ms`, readable, _debugCtxt); return readable; } /** * Wait for a spesific text in the Duplex * all text will be concatened in a single string to dean with segments. * * @param duplex * @param expected regexp to match * @returns matched text */ static async waitforText(duplex, expected, timeout = 10000) { let allText = ''; const t0 = Date.now(); let nextTimeout = timeout; for (;;) { await this.waitforReadable(duplex, timeout); const buf = await duplex.read(); if (buf) { const text = buf.toString(); allText += text; if (expected.test(allText)) return text; // console.log('RCV Non matching DATA:', text); } if (timeout) { const timeSpend = Date.now() - t0; if (nextTimeout <= 0) throw Error(`timeout waiting for ${expected}, receved: ${allText}`); nextTimeout = timeout - timeSpend; } } } static debug(name) { const debug = (0, debug_1.default)(name); debug.log = console.log.bind(console); return debug; } } exports.default = Utils; //# sourceMappingURL=utils.js.map