Comparing version 0.3.6 to 0.3.7
@@ -15,4 +15,6 @@ "use strict"; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let version = yield client.listDevices(); | ||
let version = yield client.version(); | ||
console.log(version); | ||
let listDevicesWithPaths = yield client.listDevicesWithPaths(); | ||
console.log(listDevicesWithPaths); | ||
}); | ||
@@ -19,0 +21,0 @@ } |
@@ -9,4 +9,6 @@ //测试 | ||
let version = await client.listDevices(); | ||
let version = await client.version(); | ||
console.log(version); | ||
let listDevicesWithPaths = await client.listDevicesWithPaths(); | ||
console.log(listDevicesWithPaths); | ||
// return client | ||
@@ -13,0 +15,0 @@ // .listDevicesWithPaths() |
{ | ||
"name": "xadb", | ||
"version": "0.3.6", | ||
"version": "0.3.7", | ||
"main": "./index", | ||
@@ -5,0 +5,0 @@ "scripts": { |
@@ -52,3 +52,3 @@ /* eslint-disable | ||
// Get n | ||
const n = new Buffer(len) | ||
const n = Buffer.alloc(len) | ||
struct.copy(n, 0, offset, offset + len); | ||
@@ -91,3 +91,3 @@ [].reverse.call(n) | ||
if (match = RE.exec(buffer)) { | ||
const struct = new Buffer(match[1], 'base64') | ||
const struct = Buffer.from(match[1], 'base64') | ||
const comment = match[2] | ||
@@ -94,0 +94,0 @@ return resolve(readPublicKeyFromStruct(struct, comment)) |
@@ -11,4 +11,4 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const connection_1 = require("./connection"); | ||
const debug = require('debug')('adb:client'); | ||
const Connection = require('./connection'); | ||
const Sync = require('./sync'); | ||
@@ -76,3 +76,3 @@ const Parser = require('./parser'); | ||
let conn = yield new Promise((resolve, reject) => { | ||
let my_conn = new Connection(this.options) | ||
let my_conn = new connection_1.Connection(this.options) | ||
.on('error', (err => reject(err))).on('connect', (() => resolve(my_conn))).connect(); | ||
@@ -79,0 +79,0 @@ }); |
@@ -0,5 +1,6 @@ | ||
import {Connection} from "./connection"; | ||
const debug = require('debug')('adb:client'); | ||
const Connection = require('./connection'); | ||
const Sync = require('./sync'); | ||
@@ -6,0 +7,0 @@ const Parser = require('./parser'); |
@@ -7,61 +7,61 @@ /* eslint-disable | ||
// Fix any style issues and re-enable lint. | ||
const debug = require('debug')('adb:command') | ||
const debug = require('debug')('adb:command'); | ||
const Parser = require('./parser') | ||
const Protocol = require('./protocol') | ||
const Parser = require('./parser'); | ||
const Protocol = require('./Protocol'); | ||
var Command = (function() { | ||
let RE_SQUOT = undefined | ||
let RE_ESCAPE = undefined | ||
Command = class Command { | ||
static initClass() { | ||
RE_SQUOT = /'/g | ||
RE_ESCAPE = /([$`\\!"])/g | ||
} | ||
var Command = (function () { | ||
let RE_SQUOT = undefined; | ||
let RE_ESCAPE = undefined; | ||
Command = class Command { | ||
static initClass() { | ||
RE_SQUOT = /'/g; | ||
RE_ESCAPE = /([$`\\!"])/g | ||
} | ||
constructor(connection) { | ||
this.connection = connection | ||
this.parser = this.connection.parser | ||
this.protocol = Protocol | ||
} | ||
constructor(connection) { | ||
this.connection = connection; | ||
this.parser = this.connection.parser; | ||
this.protocol = Protocol | ||
} | ||
execute() { | ||
throw new Exception('Missing implementation') | ||
} | ||
execute() { | ||
throw new Exception('Missing implementation') | ||
} | ||
_send(data) { | ||
const encoded = Protocol.encodeData(data) | ||
debug(`Send '${encoded}'`) | ||
this.connection.write(encoded) | ||
return this | ||
} | ||
_send(data) { | ||
const encoded = Protocol.encodeData(data); | ||
debug(`Send '${encoded}'`); | ||
this.connection.write(encoded); | ||
return this | ||
} | ||
// Note that this is just for convenience, not security. | ||
_escape(arg) { | ||
switch (typeof arg) { | ||
case 'number': | ||
return arg | ||
default: | ||
return `'${arg.toString().replace(RE_SQUOT, '\'"\'"\'')}'` | ||
} | ||
} | ||
// Note that this is just for convenience, not security. | ||
_escape(arg) { | ||
switch (typeof arg) { | ||
case 'number': | ||
return arg; | ||
default: | ||
return `'${arg.toString().replace(RE_SQUOT, '\'"\'"\'')}'` | ||
} | ||
} | ||
// Note that this is just for convenience, not security. Also, for some | ||
// incomprehensible reason, some Lenovo devices (e.g. Lenovo A806) behave | ||
// differently when arguments are given inside single quotes. See | ||
// https://github.com/openstf/stf/issues/471 for more information. So that's | ||
// why we now use double quotes here. | ||
_escapeCompat(arg) { | ||
switch (typeof arg) { | ||
case 'number': | ||
return arg | ||
default: | ||
return `"${arg.toString().replace(RE_ESCAPE, '\\$1')}"` | ||
} | ||
} | ||
} | ||
Command.initClass() | ||
return Command | ||
})() | ||
// Note that this is just for convenience, not security. Also, for some | ||
// incomprehensible reason, some Lenovo devices (e.g. Lenovo A806) behave | ||
// differently when arguments are given inside single quotes. See | ||
// https://github.com/openstf/stf/issues/471 for more information. So that's | ||
// why we now use double quotes here. | ||
_escapeCompat(arg) { | ||
switch (typeof arg) { | ||
case 'number': | ||
return arg; | ||
default: | ||
return `"${arg.toString().replace(RE_ESCAPE, '\\$1')}"` | ||
} | ||
} | ||
}; | ||
Command.initClass(); | ||
return Command | ||
})(); | ||
module.exports = Command | ||
module.exports = Command; |
@@ -1,82 +0,77 @@ | ||
// TODO: This file was created by bulk-decaffeinate. | ||
// Sanity-check the conversion and remove this comment. | ||
const Net = require('net') | ||
const debug = require('debug')('adb:connection') | ||
const {EventEmitter} = require('events') | ||
const {execFile} = require('child_process') | ||
const Parser = require('./parser') | ||
const dump = require('./dump') | ||
class Connection extends EventEmitter { | ||
constructor(options) { | ||
super() | ||
this.options = options | ||
this.socket = null | ||
this.parser = null | ||
this.triedStarting = false | ||
} | ||
connect() { | ||
this.socket = Net.connect(this.options) | ||
this.socket.setNoDelay(true) | ||
this.parser = new Parser(this.socket) | ||
this.socket.on('connect', () => { | ||
return this.emit('connect') | ||
}) | ||
this.socket.on('end', () => { | ||
return this.emit('end') | ||
}) | ||
this.socket.on('drain', () => { | ||
return this.emit('drain') | ||
}) | ||
this.socket.on('timeout', () => { | ||
return this.emit('timeout') | ||
}) | ||
this.socket.on('error', err => { | ||
return this._handleError(err) | ||
}) | ||
this.socket.on('close', hadError => { | ||
return this.emit('close', hadError) | ||
}) | ||
return this | ||
} | ||
end() { | ||
this.socket.end() | ||
return this | ||
} | ||
write(data, callback) { | ||
this.socket.write(dump(data), callback) | ||
return this | ||
} | ||
startServer(callback) { | ||
debug(`Starting ADB server via '${this.options.bin} start-server'`) | ||
return this._exec(['start-server'], {}, callback) | ||
} | ||
_exec(args, options, callback) { | ||
debug(`CLI: ${this.options.bin} ${args.join(' ')}`) | ||
execFile(this.options.bin, args, options, callback) | ||
return this | ||
} | ||
_handleError(err) { | ||
if ((err.code === 'ECONNREFUSED') && !this.triedStarting) { | ||
debug('Connection was refused, let\'s try starting the server once') | ||
this.triedStarting = true | ||
this.startServer(err => { | ||
if (err) { return this._handleError(err) } | ||
return this.connect() | ||
}) | ||
} else { | ||
debug(`Connection had an error: ${err.message}`) | ||
this.emit('error', err) | ||
this.end() | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const Net = require("net"); | ||
const events_1 = require("events"); | ||
const child_process_1 = require("child_process"); | ||
const debug = require("debug"); | ||
const parser_1 = require("./parser"); | ||
const dump = require('./dump'); | ||
class Connection extends events_1.EventEmitter { | ||
constructor(options) { | ||
super(); | ||
this.options = options; | ||
this.socket = null; | ||
this.parser = null; | ||
this.triedStarting = false; | ||
} | ||
} | ||
connect() { | ||
this.socket = Net.connect(this.options); | ||
this.socket.setNoDelay(true); | ||
this.parser = new parser_1.Parser(this.socket); | ||
this.socket.on('connect', () => { | ||
return this.emit('connect'); | ||
}); | ||
this.socket.on('end', () => { | ||
return this.emit('end'); | ||
}); | ||
this.socket.on('drain', () => { | ||
return this.emit('drain'); | ||
}); | ||
this.socket.on('timeout', () => { | ||
return this.emit('timeout'); | ||
}); | ||
this.socket.on('error', err => { | ||
return this._handleError(err); | ||
}); | ||
this.socket.on('close', hadError => { | ||
return this.emit('close', hadError); | ||
}); | ||
return this; | ||
} | ||
end() { | ||
this.socket.end(); | ||
return this; | ||
} | ||
write(data, callback) { | ||
this.socket.write(dump(data), callback); | ||
return this; | ||
} | ||
startServer(callback) { | ||
debug(`Starting ADB server via '${this.options.bin} start-server'`); | ||
return this._exec(['start-server'], {}, callback); | ||
} | ||
_exec(args, options, callback) { | ||
debug(`CLI: ${this.options.bin} ${args.join(' ')}`); | ||
child_process_1.execFile(this.options.bin, args, options, callback); | ||
return this; | ||
} | ||
_handleError(err) { | ||
if ((err.code === 'ECONNREFUSED') && !this.triedStarting) { | ||
debug('Connection was refused, let\'s try starting the server once'); | ||
this.triedStarting = true; | ||
this.startServer(err => { | ||
if (err) { | ||
return this._handleError(err); | ||
} | ||
return this.connect(); | ||
}); | ||
} | ||
else { | ||
debug(`Connection had an error: ${err.message}`); | ||
this.emit('error', err); | ||
this.end(); | ||
} | ||
} | ||
} | ||
module.exports = Connection | ||
exports.Connection = Connection; | ||
//# sourceMappingURL=connection.js.map |
@@ -10,3 +10,3 @@ // TODO: This file was created by bulk-decaffeinate. | ||
this.meta = meta | ||
this._buffer = new Buffer('') | ||
this._buffer = Buffer.from('') | ||
Assert.ok(((this.meta.bpp === 24) || (this.meta.bpp === 32)), | ||
@@ -31,3 +31,3 @@ 'Only 24-bit and 32-bit raw images with 8-bits per color are supported') | ||
? this._buffer | ||
: new Buffer(Math.max(4, (chunk.length / this._pixel_bytes) * 3)) | ||
: Buffer.alloc(Math.max(4, (chunk.length / this._pixel_bytes) * 3)) | ||
while ((this._buffer.length - sourceCursor) >= this._pixel_bytes) { | ||
@@ -34,0 +34,0 @@ const r = this._buffer[sourceCursor + this._r_pos] |
@@ -1,259 +0,227 @@ | ||
/* eslint-disable | ||
no-cond-assign, | ||
*/ | ||
// TODO: This file was created by bulk-decaffeinate. | ||
// Fix any style issues and re-enable lint. | ||
const Promise = require('bluebird') | ||
const Protocol = require('./protocol') | ||
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const Protocol = require("./protocol"); | ||
class Parser { | ||
constructor(stream) { | ||
this.stream = stream | ||
this.ended = false | ||
} | ||
end() { | ||
let endListener, errorListener | ||
if (this.ended) { return Promise.resolve(true) } | ||
const resolver = Promise.defer() | ||
const tryRead = () => { | ||
while (this.stream.read()) { | ||
continue | ||
} | ||
constructor(stream) { | ||
this.stream = stream; | ||
this.ended = false; | ||
} | ||
this.stream.on('readable', tryRead) | ||
this.stream.on('error', (errorListener = err => resolver.reject(err)) | ||
) | ||
this.stream.on('end', (endListener = () => { | ||
this.ended = true | ||
return resolver.resolve(true) | ||
}) | ||
) | ||
this.stream.read(0) | ||
this.stream.end() | ||
return resolver.promise.cancellable().finally(() => { | ||
this.stream.removeListener('readable', tryRead) | ||
this.stream.removeListener('error', errorListener) | ||
return this.stream.removeListener('end', endListener) | ||
}) | ||
} | ||
raw() { | ||
return this.stream | ||
} | ||
readAll() { | ||
let endListener, errorListener | ||
let all = new Buffer(0) | ||
const resolver = Promise.defer() | ||
const tryRead = () => { | ||
let chunk | ||
while ((chunk = this.stream.read())) { | ||
all = Buffer.concat([all, chunk]) | ||
} | ||
if (this.ended) { return resolver.resolve(all) } | ||
end() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let work = yield new Promise((resolve, reject) => { | ||
if (this.ended) { | ||
return resolve(true); | ||
} | ||
const tryRead = () => { | ||
while (this.stream.read()) { | ||
} | ||
}; | ||
this.stream.on('readable', tryRead); | ||
this.stream.on('error', (err => reject(err))); | ||
this.stream.on('end', (() => { | ||
this.ended = true; | ||
return resolve(true); | ||
})); | ||
this.stream.read(0); | ||
this.stream.end(); | ||
}); | ||
this.stream.removeAllListeners(); | ||
return work; | ||
}); | ||
} | ||
this.stream.on('readable', tryRead) | ||
this.stream.on('error', (errorListener = err => resolver.reject(err)) | ||
) | ||
this.stream.on('end', (endListener = () => { | ||
this.ended = true | ||
return resolver.resolve(all) | ||
}) | ||
) | ||
tryRead() | ||
return resolver.promise.cancellable().finally(() => { | ||
this.stream.removeListener('readable', tryRead) | ||
this.stream.removeListener('error', errorListener) | ||
return this.stream.removeListener('end', endListener) | ||
}) | ||
} | ||
readAscii(howMany) { | ||
return this.readBytes(howMany) | ||
.then(chunk => chunk.toString('ascii')) | ||
} | ||
readBytes(howMany) { | ||
const resolver = Promise.defer() | ||
const tryRead = () => { | ||
if (howMany) { | ||
let chunk | ||
if (chunk = this.stream.read(howMany)) { | ||
// If the stream ends while still having unread bytes, the read call | ||
// will ignore the limit and just return what it's got. | ||
howMany -= chunk.length | ||
if (howMany === 0) { return resolver.resolve(chunk) } | ||
} | ||
if (this.ended) { return resolver.reject(new Parser.PrematureEOFError(howMany)) } | ||
} else { | ||
return resolver.resolve(new Buffer(0)) | ||
} | ||
raw() { | ||
return this.stream; | ||
} | ||
const endListener = () => { | ||
this.ended = true | ||
return resolver.reject(new Parser.PrematureEOFError(howMany)) | ||
readAll() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let work = yield new Promise((resolve, reject) => { | ||
let all = Buffer.alloc(0); | ||
const tryRead = () => { | ||
let chunk; | ||
while ((chunk = this.stream.read())) { | ||
all = Buffer.concat([all, chunk]); | ||
} | ||
if (this.ended) { | ||
return resolve(all); | ||
} | ||
}; | ||
this.stream.on('readable', tryRead); | ||
this.stream.on('error', (err => reject(err))); | ||
this.stream.on('end', (() => { | ||
this.ended = true; | ||
return resolve(all); | ||
})); | ||
tryRead(); | ||
}); | ||
this.stream.removeAllListeners(); | ||
return work; | ||
}); | ||
} | ||
const errorListener = err => resolver.reject(err) | ||
this.stream.on('readable', tryRead) | ||
this.stream.on('error', errorListener) | ||
this.stream.on('end', endListener) | ||
tryRead() | ||
return resolver.promise.cancellable().finally(() => { | ||
this.stream.removeListener('readable', tryRead) | ||
this.stream.removeListener('error', errorListener) | ||
return this.stream.removeListener('end', endListener) | ||
}) | ||
} | ||
readByteFlow(howMany, targetStream) { | ||
const resolver = Promise.defer() | ||
const tryRead = () => { | ||
if (howMany) { | ||
// Try to get the exact amount we need first. If unsuccessful, take | ||
// whatever is available, which will be less than the needed amount. | ||
let chunk | ||
while ((chunk = this.stream.read(howMany) || this.stream.read())) { | ||
howMany -= chunk.length | ||
targetStream.write(chunk) | ||
if (howMany === 0) { return resolver.resolve() } | ||
} | ||
if (this.ended) { return resolver.reject(new Parser.PrematureEOFError(howMany)) } | ||
} else { | ||
return resolver.resolve() | ||
} | ||
readAscii(howMany) { | ||
return this.readBytes(howMany) | ||
.then(chunk => chunk.toString('ascii')); | ||
} | ||
const endListener = () => { | ||
this.ended = true | ||
return resolver.reject(new Parser.PrematureEOFError(howMany)) | ||
readBytes(howMany) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let work = yield new Promise((resolve, reject) => { | ||
const tryRead = () => { | ||
if (howMany) { | ||
let chunk; | ||
if (chunk = this.stream.read(howMany)) { | ||
howMany -= chunk.length; | ||
if (howMany === 0) { | ||
return resolve(chunk); | ||
} | ||
} | ||
if (this.ended) { | ||
return reject(new Parser.PrematureEOFError(howMany)); | ||
} | ||
} | ||
else { | ||
return resolve(Buffer.alloc(0)); | ||
} | ||
}; | ||
const endListener = () => { | ||
this.ended = true; | ||
return reject(new Parser.PrematureEOFError(howMany)); | ||
}; | ||
const errorListener = err => reject(err); | ||
this.stream.on('readable', tryRead); | ||
this.stream.on('error', errorListener); | ||
this.stream.on('end', endListener); | ||
tryRead(); | ||
}); | ||
this.stream.removeAllListeners(); | ||
return work; | ||
}); | ||
} | ||
const errorListener = err => resolver.reject(err) | ||
this.stream.on('readable', tryRead) | ||
this.stream.on('error', errorListener) | ||
this.stream.on('end', endListener) | ||
tryRead() | ||
return resolver.promise.cancellable().finally(() => { | ||
this.stream.removeListener('readable', tryRead) | ||
this.stream.removeListener('error', errorListener) | ||
return this.stream.removeListener('end', endListener) | ||
}) | ||
} | ||
readError() { | ||
return this.readValue() | ||
.then(value => Promise.reject(new Parser.FailError(value.toString()))) | ||
} | ||
readValue() { | ||
return this.readAscii(4) | ||
.then(value => { | ||
const length = Protocol.decodeLength(value) | ||
return this.readBytes(length) | ||
}) | ||
} | ||
readUntil(code) { | ||
let skipped = new Buffer(0) | ||
var read = () => { | ||
return this.readBytes(1) | ||
.then(function(chunk) { | ||
if (chunk[0] === code) { | ||
return skipped | ||
} else { | ||
skipped = Buffer.concat([skipped, chunk]) | ||
return read() | ||
} | ||
}) | ||
readByteFlow(howMany, targetStream) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let work = yield new Promise((resolve, reject) => { | ||
const tryRead = () => { | ||
if (howMany) { | ||
let chunk; | ||
while ((chunk = this.stream.read(howMany) || this.stream.read())) { | ||
howMany -= chunk.length; | ||
targetStream.write(chunk); | ||
if (howMany === 0) { | ||
return resolve(); | ||
} | ||
} | ||
if (this.ended) { | ||
return reject(new Parser.PrematureEOFError(howMany)); | ||
} | ||
} | ||
else { | ||
return resolve(); | ||
} | ||
}; | ||
const endListener = () => { | ||
this.ended = true; | ||
return reject(new Parser.PrematureEOFError(howMany)); | ||
}; | ||
const errorListener = err => reject(err); | ||
this.stream.on('readable', tryRead); | ||
this.stream.on('error', errorListener); | ||
this.stream.on('end', endListener); | ||
tryRead(); | ||
}); | ||
this.stream.removeAllListeners(); | ||
return work; | ||
}); | ||
} | ||
return read() | ||
} | ||
searchLine(re) { | ||
return this.readLine() | ||
.then(line => { | ||
let match | ||
if ((match = re.exec(line))) { | ||
return match | ||
} else { | ||
return this.searchLine(re) | ||
} | ||
}) | ||
} | ||
readLine() { | ||
return this.readUntil(0x0a) // '\n' | ||
.then(function(line) { | ||
if (line[line.length - 1] === 0x0d) { // '\r' | ||
return line.slice(0, -1) | ||
} else { | ||
return line | ||
} | ||
}) | ||
} | ||
unexpected(data, expected) { | ||
return Promise.reject(new Parser.UnexpectedDataError(data, expected)) | ||
} | ||
readError() { | ||
return this.readValue() | ||
.then(value => Promise.reject(new Parser.FailError(value.toString()))); | ||
} | ||
readValue() { | ||
return this.readAscii(4) | ||
.then(value => { | ||
const length = Protocol.decodeLength(value); | ||
return this.readBytes(length); | ||
}); | ||
} | ||
readUntil(code) { | ||
let skipped = Buffer.alloc(0); | ||
var read = () => { | ||
return this.readBytes(1) | ||
.then(function (chunk) { | ||
if (chunk[0] === code) { | ||
return skipped; | ||
} | ||
else { | ||
skipped = Buffer.concat([skipped, chunk]); | ||
return read(); | ||
} | ||
}); | ||
}; | ||
return read(); | ||
} | ||
searchLine(re) { | ||
return this.readLine() | ||
.then(line => { | ||
let match; | ||
if ((match = re.exec(line))) { | ||
return match; | ||
} | ||
else { | ||
return this.searchLine(re); | ||
} | ||
}); | ||
} | ||
readLine() { | ||
return this.readUntil(0x0a) | ||
.then(function (line) { | ||
if (line[line.length - 1] === 0x0d) { | ||
return line.slice(0, -1); | ||
} | ||
else { | ||
return line; | ||
} | ||
}); | ||
} | ||
unexpected(data, expected) { | ||
return Promise.reject(new Parser.UnexpectedDataError(data, expected)); | ||
} | ||
} | ||
Parser.FailError = class FailError extends Error { | ||
constructor(message) { | ||
super() // TODO check sanity | ||
Error.call(this) | ||
this.name = 'FailError' | ||
this.message = `Failure: '${message}'` | ||
Error.captureStackTrace(this, Parser.FailError) | ||
} | ||
} | ||
constructor(message) { | ||
super(); | ||
Error.call(this); | ||
this.name = 'FailError'; | ||
this.message = `Failure: '${message}'`; | ||
Error.captureStackTrace(this, Parser.FailError); | ||
} | ||
}; | ||
Parser.PrematureEOFError = class PrematureEOFError extends Error { | ||
constructor(howManyMissing) { | ||
super() // TODO check sanity | ||
Error.call(this) | ||
this.name = 'PrematureEOFError' | ||
this.message = `Premature end of stream, needed ${howManyMissing} \ | ||
more bytes` | ||
this.missingBytes = howManyMissing | ||
Error.captureStackTrace(this, Parser.PrematureEOFError) | ||
} | ||
} | ||
constructor(howManyMissing) { | ||
super(); | ||
Error.call(this); | ||
this.name = 'PrematureEOFError'; | ||
this.message = `Premature end of stream, needed ${howManyMissing} \ | ||
more bytes`; | ||
this.missingBytes = howManyMissing; | ||
Error.captureStackTrace(this, Parser.PrematureEOFError); | ||
} | ||
}; | ||
Parser.UnexpectedDataError = class UnexpectedDataError extends Error { | ||
constructor(unexpected, expected) { | ||
super() // TODO check sanity | ||
Error.call(this) | ||
this.name = 'UnexpectedDataError' | ||
this.message = `Unexpected '${unexpected}', was expecting ${expected}` | ||
this.unexpected = unexpected | ||
this.expected = expected | ||
Error.captureStackTrace(this, Parser.UnexpectedDataError) | ||
} | ||
} | ||
module.exports = Parser | ||
constructor(unexpected, expected) { | ||
super(); | ||
Error.call(this); | ||
this.name = 'UnexpectedDataError'; | ||
this.message = `Unexpected '${unexpected}', was expecting ${expected}`; | ||
this.unexpected = unexpected; | ||
this.expected = expected; | ||
Error.captureStackTrace(this, Parser.UnexpectedDataError); | ||
} | ||
}; | ||
exports.Parser = Parser; | ||
//# sourceMappingURL=parser.js.map |
@@ -1,34 +0,27 @@ | ||
// TODO: This file was created by bulk-decaffeinate. | ||
// Sanity-check the conversion and remove this comment. | ||
"use strict"; | ||
class Protocol { | ||
static initClass() { | ||
this.OKAY = 'OKAY' | ||
this.FAIL = 'FAIL' | ||
this.STAT = 'STAT' | ||
this.LIST = 'LIST' | ||
this.DENT = 'DENT' | ||
this.RECV = 'RECV' | ||
this.DATA = 'DATA' | ||
this.DONE = 'DONE' | ||
this.SEND = 'SEND' | ||
this.QUIT = 'QUIT' | ||
} | ||
static decodeLength(length) { | ||
return parseInt(length, 16) | ||
} | ||
static encodeLength(length) { | ||
return (`0000${length.toString(16)}`).slice(-4).toUpperCase() | ||
} | ||
static encodeData(data) { | ||
if (!Buffer.isBuffer(data)) { | ||
data = new Buffer(data) | ||
static decodeLength(length) { | ||
return parseInt(length, 16); | ||
} | ||
return Buffer.concat([new Buffer(Protocol.encodeLength(data.length)), data]) | ||
} | ||
static encodeLength(length) { | ||
return (`0000${length.toString(16)}`).slice(-4).toUpperCase(); | ||
} | ||
static encodeData(data) { | ||
if (!Buffer.isBuffer(data)) { | ||
data = Buffer.from(data); | ||
} | ||
return Buffer.concat([Buffer.from(Protocol.encodeLength(data.length)), data]); | ||
} | ||
} | ||
Protocol.initClass() | ||
module.exports = Protocol | ||
Protocol.OKAY = 'OKAY'; | ||
Protocol.FAIL = 'FAIL'; | ||
Protocol.STAT = 'STAT'; | ||
Protocol.LIST = 'LIST'; | ||
Protocol.DENT = 'DENT'; | ||
Protocol.RECV = 'RECV'; | ||
Protocol.DATA = 'DATA'; | ||
Protocol.DONE = 'DONE'; | ||
Protocol.SEND = 'SEND'; | ||
Protocol.QUIT = 'QUIT'; | ||
module.exports = Protocol; | ||
//# sourceMappingURL=protocol.js.map |
@@ -1,328 +0,273 @@ | ||
/* eslint-disable | ||
no-cond-assign, | ||
no-unused-vars, | ||
*/ | ||
// TODO: This file was created by bulk-decaffeinate. | ||
// Fix any style issues and re-enable lint. | ||
const Fs = require('fs') | ||
const Path = require('path') | ||
const Promise = require('bluebird') | ||
const {EventEmitter} = require('events') | ||
const debug = require('debug')('adb:sync') | ||
const Parser = require('./parser') | ||
const Protocol = require('./protocol') | ||
const Stats = require('./sync/stats') | ||
const Entry = require('./sync/entry') | ||
const PushTransfer = require('./sync/pushtransfer') | ||
const PullTransfer = require('./sync/pulltransfer') | ||
var Sync = (function() { | ||
let TEMP_PATH = undefined | ||
let DEFAULT_CHMOD = undefined | ||
let DATA_MAX_LENGTH = undefined | ||
Sync = class Sync extends EventEmitter { | ||
static initClass() { | ||
TEMP_PATH = '/data/local/tmp' | ||
DEFAULT_CHMOD = 0o644 | ||
DATA_MAX_LENGTH = 65536 | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const Fs = require('fs'); | ||
const Path = require('path'); | ||
const Promise = require('bluebird'); | ||
const { EventEmitter } = require('events'); | ||
const debug = require('debug')('adb:sync'); | ||
const Parser = require('./parser'); | ||
const Protocol = require('./protocol'); | ||
const Stats = require('./sync/stats'); | ||
const Entry = require('./sync/entry'); | ||
const PushTransfer = require('./sync/pushtransfer'); | ||
const PullTransfer = require('./sync/pulltransfer'); | ||
class Sync extends EventEmitter { | ||
constructor(connection) { | ||
super(); | ||
this.DEFAULT_CHMOD = 0o644; | ||
this.DATA_MAX_LENGTH = 65536; | ||
this.connection = connection; | ||
this.parser = this.connection.parser; | ||
} | ||
static temp(path) { | ||
return `${TEMP_PATH}/${Path.basename(path)}` | ||
return `${Sync.TEMP_PATH}/${Path.basename(path)}`; | ||
} | ||
constructor(connection) { | ||
super() | ||
this.connection = connection | ||
this.parser = this.connection.parser | ||
} | ||
stat(path, callback) { | ||
this._sendCommandWithArg(Protocol.STAT, path) | ||
return this.parser.readAscii(4) | ||
.then(reply => { | ||
switch (reply) { | ||
case Protocol.STAT: | ||
return this.parser.readBytes(12) | ||
.then(stat => { | ||
const mode = stat.readUInt32LE(0) | ||
const size = stat.readUInt32LE(4) | ||
const mtime = stat.readUInt32LE(8) | ||
if (mode === 0) { | ||
return this._enoent(path) | ||
} else { | ||
return new Stats(mode, size, mtime) | ||
} | ||
}) | ||
case Protocol.FAIL: | ||
return this._readError() | ||
default: | ||
return this.parser.unexpected(reply, 'STAT or FAIL') | ||
} | ||
}).nodeify(callback) | ||
} | ||
readdir(path, callback) { | ||
const files = [] | ||
var readNext = () => { | ||
this._sendCommandWithArg(Protocol.STAT, path); | ||
return this.parser.readAscii(4) | ||
.then(reply => { | ||
.then(reply => { | ||
switch (reply) { | ||
case Protocol.DENT: | ||
return this.parser.readBytes(16) | ||
.then(stat => { | ||
const mode = stat.readUInt32LE(0) | ||
const size = stat.readUInt32LE(4) | ||
const mtime = stat.readUInt32LE(8) | ||
const namelen = stat.readUInt32LE(12) | ||
return this.parser.readBytes(namelen) | ||
.then(function(name) { | ||
name = name.toString() | ||
// Skip '.' and '..' to match Node's fs.readdir(). | ||
if ((name !== '.') && (name !== '..')) { | ||
files.push(new Entry(name, mode, size, mtime)) | ||
} | ||
return readNext() | ||
}) | ||
}) | ||
case Protocol.DONE: | ||
return this.parser.readBytes(16) | ||
.then(zero => files) | ||
case Protocol.FAIL: | ||
return this._readError() | ||
default: | ||
return this.parser.unexpected(reply, 'DENT, DONE or FAIL') | ||
case Protocol.STAT: | ||
return this.parser.readBytes(12) | ||
.then(stat => { | ||
const mode = stat.readUInt32LE(0); | ||
const size = stat.readUInt32LE(4); | ||
const mtime = stat.readUInt32LE(8); | ||
if (mode === 0) { | ||
return this._enoent(path); | ||
} | ||
else { | ||
return new Stats(mode, size, mtime); | ||
} | ||
}); | ||
case Protocol.FAIL: | ||
return this._readError(); | ||
default: | ||
return this.parser.unexpected(reply, 'STAT or FAIL'); | ||
} | ||
}) | ||
} | ||
this._sendCommandWithArg(Protocol.LIST, path) | ||
return readNext() | ||
.nodeify(callback) | ||
}).nodeify(callback); | ||
} | ||
readdir(path, callback) { | ||
const files = []; | ||
var readNext = () => { | ||
return this.parser.readAscii(4) | ||
.then(reply => { | ||
switch (reply) { | ||
case Protocol.DENT: | ||
return this.parser.readBytes(16) | ||
.then(stat => { | ||
const mode = stat.readUInt32LE(0); | ||
const size = stat.readUInt32LE(4); | ||
const mtime = stat.readUInt32LE(8); | ||
const namelen = stat.readUInt32LE(12); | ||
return this.parser.readBytes(namelen) | ||
.then(function (name) { | ||
name = name.toString(); | ||
if ((name !== '.') && (name !== '..')) { | ||
files.push(new Entry(name, mode, size, mtime)); | ||
} | ||
return readNext(); | ||
}); | ||
}); | ||
case Protocol.DONE: | ||
return this.parser.readBytes(16) | ||
.then(zero => files); | ||
case Protocol.FAIL: | ||
return this._readError(); | ||
default: | ||
return this.parser.unexpected(reply, 'DENT, DONE or FAIL'); | ||
} | ||
}); | ||
}; | ||
this._sendCommandWithArg(Protocol.LIST, path); | ||
return readNext() | ||
.nodeify(callback); | ||
} | ||
push(contents, path, mode) { | ||
if (typeof contents === 'string') { | ||
return this.pushFile(contents, path, mode) | ||
} else { | ||
return this.pushStream(contents, path, mode) | ||
} | ||
if (typeof contents === 'string') { | ||
return this.pushFile(contents, path, mode); | ||
} | ||
else { | ||
return this.pushStream(contents, path, mode); | ||
} | ||
} | ||
pushFile(file, path, mode = DEFAULT_CHMOD) { | ||
if (!mode) { mode = DEFAULT_CHMOD } | ||
return this.pushStream(Fs.createReadStream(file), path, mode) | ||
pushFile(file, path, mode = this.DEFAULT_CHMOD) { | ||
if (!mode) { | ||
mode = this.DEFAULT_CHMOD; | ||
} | ||
return this.pushStream(Fs.createReadStream(file), path, mode); | ||
} | ||
pushStream(stream, path, mode = DEFAULT_CHMOD) { | ||
mode |= Stats.S_IFREG | ||
this._sendCommandWithArg(Protocol.SEND, `${path},${mode}`) | ||
return this._writeData(stream, Math.floor(Date.now() / 1000)) | ||
pushStream(stream, path, mode = this.DEFAULT_CHMOD) { | ||
mode |= Stats.S_IFREG; | ||
this._sendCommandWithArg(Protocol.SEND, `${path},${mode}`); | ||
return this._writeData(stream, Math.floor(Date.now() / 1000)); | ||
} | ||
pull(path) { | ||
this._sendCommandWithArg(Protocol.RECV, `${path}`) | ||
return this._readData() | ||
this._sendCommandWithArg(Protocol.RECV, `${path}`); | ||
return this._readData(); | ||
} | ||
end() { | ||
this.connection.end() | ||
return this | ||
this.connection.end(); | ||
return this; | ||
} | ||
tempFile(path) { | ||
return Sync.temp(path) | ||
return Sync.temp(path); | ||
} | ||
_writeData(stream, timeStamp) { | ||
let writer | ||
const transfer = new PushTransfer | ||
const writeData = () => { | ||
let endListener, errorListener, readableListener | ||
let resolver = Promise.defer() | ||
writer = Promise.resolve() | ||
.cancellable() | ||
stream.on('end', (endListener = () => { | ||
return writer.then(() => { | ||
this._sendCommandWithLength(Protocol.DONE, timeStamp) | ||
return resolver.resolve() | ||
}) | ||
}) | ||
) | ||
const waitForDrain = () => { | ||
let drainListener | ||
resolver = Promise.defer() | ||
this.connection.on('drain', (drainListener = () => resolver.resolve()) | ||
) | ||
return resolver.promise.finally(() => { | ||
return this.connection.removeListener('drain', drainListener) | ||
}) | ||
} | ||
const track = () => transfer.pop() | ||
var writeNext = () => { | ||
let chunk | ||
if (chunk = stream.read(DATA_MAX_LENGTH) || stream.read()) { | ||
this._sendCommandWithLength(Protocol.DATA, chunk.length) | ||
transfer.push(chunk.length) | ||
if (this.connection.write(chunk, track)) { | ||
return writeNext() | ||
} else { | ||
return waitForDrain() | ||
.then(writeNext) | ||
} | ||
} else { | ||
return Promise.resolve() | ||
} | ||
} | ||
stream.on('readable', (readableListener = () => writer.then(writeNext)) | ||
) | ||
stream.on('error', (errorListener = err => resolver.reject(err)) | ||
) | ||
return resolver.promise.finally(function() { | ||
stream.removeListener('end', endListener) | ||
stream.removeListener('readable', readableListener) | ||
stream.removeListener('error', errorListener) | ||
return writer.cancel() | ||
}) | ||
} | ||
const readReply = () => { | ||
return this.parser.readAscii(4) | ||
.then(reply => { | ||
switch (reply) { | ||
case Protocol.OKAY: | ||
return this.parser.readBytes(4) | ||
.then(zero => true) | ||
case Protocol.FAIL: | ||
return this._readError() | ||
default: | ||
return this.parser.unexpected(reply, 'OKAY or FAIL') | ||
} | ||
}) | ||
} | ||
// While I can't think of a case that would break this double-Promise | ||
// writer-reader arrangement right now, it's not immediately obvious | ||
// that the code is correct and it may or may not have some failing | ||
// edge cases. Refactor pending. | ||
writer = writeData() | ||
.cancellable() | ||
.catch(Promise.CancellationError, err => { | ||
return this.connection.end() | ||
}).catch(function(err) { | ||
transfer.emit('error', err) | ||
return reader.cancel() | ||
}) | ||
var reader = readReply() | ||
.cancellable() | ||
.catch(Promise.CancellationError, err => true).catch(function(err) { | ||
transfer.emit('error', err) | ||
return writer.cancel()}).finally(() => transfer.end()) | ||
transfer.on('cancel', function() { | ||
writer.cancel() | ||
return reader.cancel() | ||
}) | ||
return transfer | ||
let writer; | ||
const transfer = new PushTransfer; | ||
const writeData = () => { | ||
let endListener, errorListener, readableListener; | ||
let resolver = Promise.defer(); | ||
writer = Promise.resolve() | ||
.cancellable(); | ||
stream.on('end', (endListener = () => { | ||
return writer.then(() => { | ||
this._sendCommandWithLength(Protocol.DONE, timeStamp); | ||
return resolver.resolve(); | ||
}); | ||
})); | ||
const waitForDrain = () => { | ||
let drainListener; | ||
resolver = Promise.defer(); | ||
this.connection.on('drain', (drainListener = () => resolver.resolve())); | ||
return resolver.promise.finally(() => { | ||
return this.connection.removeListener('drain', drainListener); | ||
}); | ||
}; | ||
const track = () => transfer.pop(); | ||
var writeNext = () => { | ||
let chunk; | ||
if (chunk = stream.read(this.DATA_MAX_LENGTH) || stream.read()) { | ||
this._sendCommandWithLength(Protocol.DATA, chunk.length); | ||
transfer.push(chunk.length); | ||
if (this.connection.write(chunk, track)) { | ||
return writeNext(); | ||
} | ||
else { | ||
return waitForDrain() | ||
.then(writeNext); | ||
} | ||
} | ||
else { | ||
return Promise.resolve(); | ||
} | ||
}; | ||
stream.on('readable', (readableListener = () => writer.then(writeNext))); | ||
stream.on('error', (errorListener = err => resolver.reject(err))); | ||
return resolver.promise.finally(function () { | ||
stream.removeListener('end', endListener); | ||
stream.removeListener('readable', readableListener); | ||
stream.removeListener('error', errorListener); | ||
return writer.cancel(); | ||
}); | ||
}; | ||
const readReply = () => { | ||
return this.parser.readAscii(4) | ||
.then(reply => { | ||
switch (reply) { | ||
case Protocol.OKAY: | ||
return this.parser.readBytes(4) | ||
.then(zero => true); | ||
case Protocol.FAIL: | ||
return this._readError(); | ||
default: | ||
return this.parser.unexpected(reply, 'OKAY or FAIL'); | ||
} | ||
}); | ||
}; | ||
writer = writeData() | ||
.cancellable() | ||
.catch(Promise.CancellationError, err => { | ||
return this.connection.end(); | ||
}).catch(function (err) { | ||
transfer.emit('error', err); | ||
return reader.cancel(); | ||
}); | ||
var reader = readReply() | ||
.cancellable() | ||
.catch(Promise.CancellationError, err => true).catch(function (err) { | ||
transfer.emit('error', err); | ||
return writer.cancel(); | ||
}).finally(() => transfer.end()); | ||
transfer.on('cancel', function () { | ||
writer.cancel(); | ||
return reader.cancel(); | ||
}); | ||
return transfer; | ||
} | ||
_readData() { | ||
let cancelListener | ||
const transfer = new PullTransfer | ||
var readNext = () => { | ||
return this.parser.readAscii(4) | ||
.cancellable() | ||
.then(reply => { | ||
switch (reply) { | ||
case Protocol.DATA: | ||
return this.parser.readBytes(4) | ||
.then(lengthData => { | ||
const length = lengthData.readUInt32LE(0) | ||
return this.parser.readByteFlow(length, transfer) | ||
.then(readNext) | ||
}) | ||
case Protocol.DONE: | ||
return this.parser.readBytes(4) | ||
.then(zero => true) | ||
case Protocol.FAIL: | ||
return this._readError() | ||
default: | ||
return this.parser.unexpected(reply, 'DATA, DONE or FAIL') | ||
} | ||
}) | ||
} | ||
const reader = readNext() | ||
.catch(Promise.CancellationError, err => { | ||
return this.connection.end() | ||
}).catch(err => transfer.emit('error', err)).finally(function() { | ||
transfer.removeListener('cancel', cancelListener) | ||
return transfer.end() | ||
}) | ||
transfer.on('cancel', (cancelListener = () => reader.cancel()) | ||
) | ||
return transfer | ||
let cancelListener; | ||
const transfer = new PullTransfer; | ||
var readNext = () => { | ||
return this.parser.readAscii(4) | ||
.cancellable() | ||
.then(reply => { | ||
switch (reply) { | ||
case Protocol.DATA: | ||
return this.parser.readBytes(4) | ||
.then(lengthData => { | ||
const length = lengthData.readUInt32LE(0); | ||
return this.parser.readByteFlow(length, transfer) | ||
.then(readNext); | ||
}); | ||
case Protocol.DONE: | ||
return this.parser.readBytes(4) | ||
.then(zero => true); | ||
case Protocol.FAIL: | ||
return this._readError(); | ||
default: | ||
return this.parser.unexpected(reply, 'DATA, DONE or FAIL'); | ||
} | ||
}); | ||
}; | ||
const reader = readNext() | ||
.catch(Promise.CancellationError, err => { | ||
return this.connection.end(); | ||
}).catch(err => transfer.emit('error', err)).finally(function () { | ||
transfer.removeListener('cancel', cancelListener); | ||
return transfer.end(); | ||
}); | ||
transfer.on('cancel', (cancelListener = () => reader.cancel())); | ||
return transfer; | ||
} | ||
_readError() { | ||
return this.parser.readBytes(4) | ||
.then(length => { | ||
return this.parser.readBytes(length.readUInt32LE(0)) | ||
.then(buf => Promise.reject(new Parser.FailError(buf.toString()))) | ||
return this.parser.readBytes(4) | ||
.then(length => { | ||
return this.parser.readBytes(length.readUInt32LE(0)) | ||
.then(buf => Promise.reject(new Parser.FailError(buf.toString()))); | ||
}).finally(() => { | ||
return this.parser.end() | ||
}) | ||
return this.parser.end(); | ||
}); | ||
} | ||
_sendCommandWithLength(cmd, length) { | ||
if (cmd !== Protocol.DATA) { debug(cmd) } | ||
const payload = new Buffer(cmd.length + 4) | ||
payload.write(cmd, 0, cmd.length) | ||
payload.writeUInt32LE(length, cmd.length) | ||
return this.connection.write(payload) | ||
if (cmd !== Protocol.DATA) { | ||
debug(cmd); | ||
} | ||
const payload = Buffer.alloc(cmd.length + 4); | ||
payload.write(cmd, 0, cmd.length); | ||
payload.writeUInt32LE(length, cmd.length); | ||
return this.connection.write(payload); | ||
} | ||
_sendCommandWithArg(cmd, arg) { | ||
debug(`${cmd} ${arg}`) | ||
const payload = new Buffer(cmd.length + 4 + arg.length) | ||
let pos = 0 | ||
payload.write(cmd, pos, cmd.length) | ||
pos += cmd.length | ||
payload.writeUInt32LE(arg.length, pos) | ||
pos += 4 | ||
payload.write(arg, pos) | ||
return this.connection.write(payload) | ||
debug(`${cmd} ${arg}`); | ||
const payload = Buffer.alloc(cmd.length + 4 + arg.length); | ||
let pos = 0; | ||
payload.write(cmd, pos, cmd.length); | ||
pos += cmd.length; | ||
payload.writeUInt32LE(arg.length, pos); | ||
pos += 4; | ||
payload.write(arg, pos); | ||
return this.connection.write(payload); | ||
} | ||
_enoent(path) { | ||
const err = new Error(`ENOENT, no such file or directory '${path}'`) | ||
err.errno = 34 | ||
err.code = 'ENOENT' | ||
err.path = path | ||
return Promise.reject(err) | ||
const err = new Error(`ENOENT, no such file or directory '${path}'`); | ||
err.errno = 34; | ||
err.code = 'ENOENT'; | ||
err.path = path; | ||
return Promise.reject(err); | ||
} | ||
} | ||
Sync.initClass() | ||
return Sync | ||
})() | ||
module.exports = Sync | ||
} | ||
Sync.TEMP_PATH = '/data/local/tmp'; | ||
exports.Sync = Sync; | ||
//# sourceMappingURL=sync.js.map |
@@ -28,3 +28,3 @@ // TODO: This file was created by bulk-decaffeinate. | ||
if (data) { | ||
chunk = new Buffer(24 + data.length) | ||
chunk = Buffer.alloc(24 + data.length) | ||
chunk.writeUInt32LE(command, 0) | ||
@@ -39,3 +39,3 @@ chunk.writeUInt32LE(arg0, 4) | ||
} else { | ||
chunk = new Buffer(24) | ||
chunk = Buffer.alloc(24) | ||
chunk.writeUInt32LE(command, 0) | ||
@@ -52,3 +52,3 @@ chunk.writeUInt32LE(arg0, 4) | ||
static swap32(n) { | ||
const buffer = new Buffer(4) | ||
const buffer = Buffer.alloc(4) | ||
buffer.writeUInt32LE(n, 0) | ||
@@ -55,0 +55,0 @@ return buffer.readUInt32BE(0) |
// TODO: This file was created by bulk-decaffeinate. | ||
// Sanity-check the conversion and remove this comment. | ||
const {EventEmitter} = require('events') | ||
const {EventEmitter} = require('events'); | ||
const Packet = require('./packet') | ||
const Packet = require('./packet'); | ||
class PacketReader extends EventEmitter { | ||
constructor(stream) { | ||
super() | ||
this.stream = stream | ||
this.inBody = false | ||
this.buffer = null | ||
this.packet = null | ||
this.stream.on('readable', this._tryRead.bind(this)) | ||
this.stream.on('error', err => this.emit('error', err)) | ||
this.stream.on('end', () => this.emit('end')) | ||
setImmediate(this._tryRead.bind(this)) | ||
} | ||
constructor(stream) { | ||
super(); | ||
this.stream = stream; | ||
this.inBody = false; | ||
this.buffer = null; | ||
this.packet = null; | ||
this.stream.on('readable', this._tryRead.bind(this)); | ||
this.stream.on('error', err => this.emit('error', err)); | ||
this.stream.on('end', () => this.emit('end')); | ||
setImmediate(this._tryRead.bind(this)) | ||
} | ||
_tryRead() { | ||
while (this._appendChunk()) { | ||
while (this.buffer) { | ||
if (this.inBody) { | ||
if (!(this.buffer.length >= this.packet.length)) { break } | ||
this.packet.data = this._consume(this.packet.length) | ||
if (!this.packet.verifyChecksum()) { | ||
this.emit('error', new PacketReader.ChecksumError(this.packet)) | ||
return | ||
} | ||
this.emit('packet', this.packet) | ||
this.inBody = false | ||
_tryRead() { | ||
while (this._appendChunk()) { | ||
while (this.buffer) { | ||
if (this.inBody) { | ||
if (!(this.buffer.length >= this.packet.length)) { | ||
break | ||
} | ||
this.packet.data = this._consume(this.packet.length); | ||
if (!this.packet.verifyChecksum()) { | ||
this.emit('error', new PacketReader.ChecksumError(this.packet)); | ||
return | ||
} | ||
this.emit('packet', this.packet); | ||
this.inBody = false | ||
} else { | ||
if (!(this.buffer.length >= 24)) { | ||
break | ||
} | ||
const header = this._consume(24); | ||
this.packet = new Packet( | ||
header.readUInt32LE(0), | ||
header.readUInt32LE(4), | ||
header.readUInt32LE(8), | ||
header.readUInt32LE(12), | ||
header.readUInt32LE(16), | ||
header.readUInt32LE(20), | ||
Buffer.alloc(0) | ||
); | ||
if (!this.packet.verifyMagic()) { | ||
this.emit('error', new PacketReader.MagicError(this.packet)); | ||
return | ||
} | ||
if (this.packet.length === 0) { | ||
this.emit('packet', this.packet) | ||
} else { | ||
this.inBody = true | ||
} | ||
} | ||
} | ||
} | ||
} | ||
_appendChunk() { | ||
let chunk; | ||
if ((chunk = this.stream.read())) { | ||
if (this.buffer) { | ||
return this.buffer = Buffer.concat([this.buffer, chunk], this.buffer.length + chunk.length) | ||
} else { | ||
return this.buffer = chunk | ||
} | ||
} else { | ||
if (!(this.buffer.length >= 24)) { break } | ||
const header = this._consume(24) | ||
this.packet = new Packet( | ||
header.readUInt32LE(0), | ||
header.readUInt32LE(4), | ||
header.readUInt32LE(8), | ||
header.readUInt32LE(12), | ||
header.readUInt32LE(16), | ||
header.readUInt32LE(20), | ||
new Buffer(0) | ||
) | ||
if (!this.packet.verifyMagic()) { | ||
this.emit('error', new PacketReader.MagicError(this.packet)) | ||
return | ||
} | ||
if (this.packet.length === 0) { | ||
this.emit('packet', this.packet) | ||
} else { | ||
this.inBody = true | ||
} | ||
return null | ||
} | ||
} | ||
} | ||
} | ||
_appendChunk() { | ||
let chunk | ||
if ((chunk = this.stream.read())) { | ||
if (this.buffer) { | ||
return this.buffer = Buffer.concat([this.buffer, chunk], this.buffer.length + chunk.length) | ||
} else { | ||
return this.buffer = chunk | ||
} | ||
} else { | ||
return null | ||
_consume(length) { | ||
const chunk = this.buffer.slice(0, length); | ||
this.buffer = length === this.buffer.length ? null : this.buffer.slice(length); | ||
return chunk | ||
} | ||
} | ||
_consume(length) { | ||
const chunk = this.buffer.slice(0, length) | ||
this.buffer = length === this.buffer.length ? null : this.buffer.slice(length) | ||
return chunk | ||
} | ||
} | ||
PacketReader.ChecksumError = class ChecksumError extends Error { | ||
constructor(packet) { | ||
super() // TODO check sanity | ||
Error.call(this) | ||
this.name = 'ChecksumError' | ||
this.message = 'Checksum mismatch' | ||
this.packet = packet | ||
Error.captureStackTrace(this, PacketReader.ChecksumError) | ||
} | ||
} | ||
constructor(packet) { | ||
super(); // TODO check sanity | ||
Error.call(this); | ||
this.name = 'ChecksumError'; | ||
this.message = 'Checksum mismatch'; | ||
this.packet = packet; | ||
Error.captureStackTrace(this, PacketReader.ChecksumError) | ||
} | ||
}; | ||
PacketReader.MagicError = class MagicError extends Error { | ||
constructor(packet) { | ||
super() // TODO check sanity | ||
Error.call(this) | ||
this.name = 'MagicError' | ||
this.message = 'Magic value mismatch' | ||
this.packet = packet | ||
Error.captureStackTrace(this, PacketReader.MagicError) | ||
} | ||
} | ||
constructor(packet) { | ||
super(); // TODO check sanity | ||
Error.call(this); | ||
this.name = 'MagicError'; | ||
this.message = 'Magic value mismatch'; | ||
this.packet = packet; | ||
Error.captureStackTrace(this, PacketReader.MagicError) | ||
} | ||
}; | ||
module.exports = PacketReader | ||
module.exports = PacketReader; |
@@ -1,56 +0,51 @@ | ||
// TODO: This file was created by bulk-decaffeinate. | ||
// Sanity-check the conversion and remove this comment. | ||
const Net = require('net') | ||
const {EventEmitter} = require('events') | ||
const Socket = require('./socket') | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const socket_1 = require("./socket"); | ||
const Net = require('net'); | ||
const { EventEmitter } = require('events'); | ||
class Server extends EventEmitter { | ||
constructor(client, serial, options) { | ||
super() | ||
this.client = client | ||
this.serial = serial | ||
this.options = options | ||
this.connections = [] | ||
this.server = Net.createServer({allowHalfOpen: true}) | ||
this.server.on('error', err => { | ||
return this.emit('error', err) | ||
}) | ||
this.server.on('listening', () => { | ||
return this.emit('listening') | ||
}) | ||
this.server.on('close', () => { | ||
return this.emit('close') | ||
}) | ||
this.server.on('connection', conn => { | ||
const socket = new Socket(this.client, this.serial, conn, this.options) | ||
this.connections.push(socket) | ||
socket.on('error', err => { | ||
// 'conn' is guaranteed to get ended | ||
return this.emit('error', err) | ||
}) | ||
socket.once('end', () => { | ||
// 'conn' is guaranteed to get ended | ||
return this.connections = this.connections.filter(val => val !== socket) | ||
}) | ||
return this.emit('connection', socket) | ||
}) | ||
} | ||
listen() { | ||
this.server.listen.apply(this.server, arguments) | ||
return this | ||
} | ||
close() { | ||
this.server.close() | ||
return this | ||
} | ||
end() { | ||
for (let conn of this.connections) { conn.end() } | ||
return this | ||
} | ||
constructor(client, serial, options) { | ||
super(); | ||
this.client = client; | ||
this.serial = serial; | ||
this.options = options; | ||
this.connections = []; | ||
this.server = Net.createServer({ allowHalfOpen: true }); | ||
this.server.on('error', err => { | ||
return this.emit('error', err); | ||
}); | ||
this.server.on('listening', () => { | ||
return this.emit('listening'); | ||
}); | ||
this.server.on('close', () => { | ||
return this.emit('close'); | ||
}); | ||
this.server.on('connection', conn => { | ||
const socket = new socket_1.Socket(this.client, this.serial, conn, this.options); | ||
this.connections.push(socket); | ||
socket.on('error', err => { | ||
return this.emit('error', err); | ||
}); | ||
socket.once('end', () => { | ||
return this.connections = this.connections.filter(val => val !== socket); | ||
}); | ||
return this.emit('connection', socket); | ||
}); | ||
} | ||
listen() { | ||
this.server.listen.apply(this.server, arguments); | ||
return this; | ||
} | ||
close() { | ||
this.server.close(); | ||
return this; | ||
} | ||
end() { | ||
for (let conn of this.connections) { | ||
conn.end(); | ||
} | ||
return this; | ||
} | ||
} | ||
module.exports = Server | ||
exports.Server = Server; | ||
//# sourceMappingURL=server.js.map |
@@ -1,261 +0,235 @@ | ||
/* eslint-disable | ||
no-unused-vars, | ||
*/ | ||
// TODO: This file was created by bulk-decaffeinate. | ||
// Fix any style issues and re-enable lint. | ||
const crypto = require('crypto') | ||
const {EventEmitter} = require('events') | ||
const Promise = require('bluebird') | ||
const Forge = require('node-forge') | ||
const debug = require('debug')('adb:tcpusb:socket') | ||
const Parser = require('../parser') | ||
const Protocol = require('../protocol') | ||
const Auth = require('../auth') | ||
const Packet = require('./packet') | ||
const PacketReader = require('./packetreader') | ||
const Service = require('./service') | ||
const ServiceMap = require('./servicemap') | ||
const RollingCounter = require('./rollingcounter') | ||
var Socket = (function() { | ||
let UINT32_MAX = undefined | ||
let UINT16_MAX = undefined | ||
let AUTH_TOKEN = undefined | ||
let AUTH_SIGNATURE = undefined | ||
let AUTH_RSAPUBLICKEY = undefined | ||
let TOKEN_LENGTH = undefined | ||
Socket = class Socket extends EventEmitter { | ||
static initClass() { | ||
UINT32_MAX = 0xFFFFFFFF | ||
UINT16_MAX = 0xFFFF | ||
AUTH_TOKEN = 1 | ||
AUTH_SIGNATURE = 2 | ||
AUTH_RSAPUBLICKEY = 3 | ||
TOKEN_LENGTH = 20 | ||
} | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const bluebird_1 = require("bluebird"); | ||
const crypto = require('crypto'); | ||
const { EventEmitter } = require('events'); | ||
const debug = require('debug')('adb:tcpusb:socket'); | ||
const Auth = require('../auth'); | ||
const Packet = require('./packet'); | ||
const PacketReader = require('./packetreader'); | ||
const Service = require('./service'); | ||
const ServiceMap = require('./servicemap'); | ||
const RollingCounter = require('./rollingcounter'); | ||
class Socket extends EventEmitter { | ||
constructor(client, serial, socket, options = {}) { | ||
super() | ||
this.client = client | ||
this.serial = serial | ||
this.socket = socket | ||
this.options = options | ||
if (!this.options.auth) { this.options.auth = Promise.resolve(true) } | ||
this.ended = false | ||
this.socket.setNoDelay(true) | ||
this.reader = new PacketReader(this.socket) | ||
.on('packet', this._handle.bind(this)) | ||
.on('error', err => { | ||
debug(`PacketReader error: ${err.message}`) | ||
return this.end() | ||
}).on('end', this.end.bind(this)) | ||
this.version = 1 | ||
this.maxPayload = 4096 | ||
this.authorized = false | ||
this.syncToken = new RollingCounter(UINT32_MAX) | ||
this.remoteId = new RollingCounter(UINT32_MAX) | ||
this.services = new ServiceMap | ||
this.remoteAddress = this.socket.remoteAddress | ||
this.token = null | ||
this.signature = null | ||
super(); | ||
this.UINT32_MAX = 0xFFFFFFFF; | ||
this.UINT16_MAX = 0xFFFF; | ||
this.AUTH_TOKEN = 1; | ||
this.AUTH_SIGNATURE = 2; | ||
this.AUTH_RSAPUBLICKEY = 3; | ||
this.TOKEN_LENGTH = 20; | ||
this.client = client; | ||
this.serial = serial; | ||
this.socket = socket; | ||
this.options = options; | ||
if (!this.options.auth) { | ||
this.options.auth = bluebird_1.default.resolve(true); | ||
} | ||
this.ended = false; | ||
this.socket.setNoDelay(true); | ||
this.reader = new PacketReader(this.socket) | ||
.on('packet', this._handle.bind(this)) | ||
.on('error', err => { | ||
debug(`PacketReader error: ${err.message}`); | ||
return this.end(); | ||
}).on('end', this.end.bind(this)); | ||
this.version = 1; | ||
this.maxPayload = 4096; | ||
this.authorized = false; | ||
this.syncToken = new RollingCounter(this.UINT32_MAX); | ||
this.remoteId = new RollingCounter(this.UINT32_MAX); | ||
this.services = new ServiceMap; | ||
this.remoteAddress = this.socket.remoteAddress; | ||
this.token = null; | ||
this.signature = null; | ||
} | ||
end() { | ||
if (this.ended) { return this } | ||
// End services first so that they can send a final payload before FIN. | ||
this.services.end() | ||
this.socket.end() | ||
this.ended = true | ||
this.emit('end') | ||
return this | ||
if (this.ended) { | ||
return this; | ||
} | ||
this.services.end(); | ||
this.socket.end(); | ||
this.ended = true; | ||
this.emit('end'); | ||
return this; | ||
} | ||
_error(err) { | ||
this.emit('error', err) | ||
return this.end() | ||
this.emit('error', err); | ||
return this.end(); | ||
} | ||
_handle(packet) { | ||
if (this.ended) { return } | ||
this.emit('userActivity', packet) | ||
return Promise.try(() => { | ||
switch (packet.command) { | ||
case Packet.A_SYNC: | ||
return this._handleSyncPacket(packet) | ||
case Packet.A_CNXN: | ||
return this._handleConnectionPacket(packet) | ||
case Packet.A_OPEN: | ||
return this._handleOpenPacket(packet) | ||
case Packet.A_OKAY: case Packet.A_WRTE: case Packet.A_CLSE: | ||
return this._forwardServicePacket(packet) | ||
case Packet.A_AUTH: | ||
return this._handleAuthPacket(packet) | ||
default: | ||
throw new Error(`Unknown command ${packet.command}`) | ||
if (this.ended) { | ||
return; | ||
} | ||
}).catch(Socket.AuthError, () => { | ||
return this.end() | ||
}).catch(Socket.UnauthorizedError, () => { | ||
return this.end() | ||
}).catch(err => { | ||
return this._error(err) | ||
}) | ||
this.emit('userActivity', packet); | ||
return bluebird_1.default.try(() => { | ||
switch (packet.command) { | ||
case Packet.A_SYNC: | ||
return this._handleSyncPacket(packet); | ||
case Packet.A_CNXN: | ||
return this._handleConnectionPacket(packet); | ||
case Packet.A_OPEN: | ||
return this._handleOpenPacket(packet); | ||
case Packet.A_OKAY: | ||
case Packet.A_WRTE: | ||
case Packet.A_CLSE: | ||
return this._forwardServicePacket(packet); | ||
case Packet.A_AUTH: | ||
return this._handleAuthPacket(packet); | ||
default: | ||
throw new Error(`Unknown command ${packet.command}`); | ||
} | ||
}).catch(Socket.AuthError, () => { | ||
return this.end(); | ||
}).catch(Socket.UnauthorizedError, () => { | ||
return this.end(); | ||
}).catch(err => { | ||
return this._error(err); | ||
}); | ||
} | ||
_handleSyncPacket(packet) { | ||
// No need to do anything? | ||
debug('I:A_SYNC') | ||
debug('O:A_SYNC') | ||
return this.write(Packet.assemble(Packet.A_SYNC, 1, this.syncToken.next(), null)) | ||
debug('I:A_SYNC'); | ||
debug('O:A_SYNC'); | ||
return this.write(Packet.assemble(Packet.A_SYNC, 1, this.syncToken.next(), null)); | ||
} | ||
_handleConnectionPacket(packet) { | ||
debug('I:A_CNXN', packet) | ||
const version = Packet.swap32(packet.arg0) | ||
this.maxPayload = Math.min(UINT16_MAX, packet.arg1) | ||
return this._createToken() | ||
.then(token => { | ||
this.token = token | ||
debug(`Created challenge '${this.token.toString('base64')}'`) | ||
debug('O:A_AUTH') | ||
return this.write(Packet.assemble(Packet.A_AUTH, AUTH_TOKEN, 0, this.token)) | ||
}) | ||
debug('I:A_CNXN', packet); | ||
const version = Packet.swap32(packet.arg0); | ||
this.maxPayload = Math.min(this.UINT16_MAX, packet.arg1); | ||
return this._createToken() | ||
.then(token => { | ||
this.token = token; | ||
debug(`Created challenge '${this.token.toString('base64')}'`); | ||
debug('O:A_AUTH'); | ||
return this.write(Packet.assemble(Packet.A_AUTH, this.AUTH_TOKEN, 0, this.token)); | ||
}); | ||
} | ||
_handleAuthPacket(packet) { | ||
debug('I:A_AUTH', packet) | ||
switch (packet.arg0) { | ||
case AUTH_SIGNATURE: | ||
// Store first signature, ignore the rest | ||
debug(`Received signature '${packet.data.toString('base64')}'`) | ||
if (!this.signature) { this.signature = packet.data } | ||
debug('O:A_AUTH') | ||
return this.write(Packet.assemble(Packet.A_AUTH, AUTH_TOKEN, 0, this.token)) | ||
case AUTH_RSAPUBLICKEY: | ||
if (!this.signature) { | ||
throw new Socket.AuthError('Public key sent before signature') | ||
debug('I:A_AUTH', packet); | ||
switch (packet.arg0) { | ||
case this.AUTH_SIGNATURE: | ||
debug(`Received signature '${packet.data.toString('base64')}'`); | ||
if (!this.signature) { | ||
this.signature = packet.data; | ||
} | ||
debug('O:A_AUTH'); | ||
return this.write(Packet.assemble(Packet.A_AUTH, this.AUTH_TOKEN, 0, this.token)); | ||
case this.AUTH_RSAPUBLICKEY: | ||
if (!this.signature) { | ||
throw new Socket.AuthError('Public key sent before signature'); | ||
} | ||
if (!packet.data || !(packet.data.length >= 2)) { | ||
throw new Socket.AuthError('Empty RSA public key'); | ||
} | ||
debug(`Received RSA public key '${packet.data.toString('base64')}'`); | ||
return Auth.parsePublicKey(this._skipNull(packet.data)) | ||
.then(key => { | ||
const digest = this.token.toString('binary'); | ||
const sig = this.signature.toString('binary'); | ||
if (!key.verify(digest, sig)) { | ||
debug('Signature mismatch'); | ||
throw new Socket.AuthError('Signature mismatch'); | ||
} | ||
debug('Signature verified'); | ||
return key; | ||
}).then(key => { | ||
return this.options.auth(key) | ||
.catch(function (err) { | ||
debug('Connection rejected by user-defined auth handler'); | ||
throw new Socket.AuthError('Rejected by user-defined handler'); | ||
}); | ||
}).then(() => { | ||
return this._deviceId(); | ||
}).then(id => { | ||
this.authorized = true; | ||
debug('O:A_CNXN'); | ||
return this.write(Packet.assemble(Packet.A_CNXN, Packet.swap32(this.version), this.maxPayload, id)); | ||
}); | ||
default: | ||
throw new Error(`Unknown authentication method ${packet.arg0}`); | ||
} | ||
} | ||
_handleOpenPacket(packet) { | ||
if (!this.authorized) { | ||
throw new Socket.UnauthorizedError(); | ||
} | ||
const remoteId = packet.arg0; | ||
const localId = this.remoteId.next(); | ||
if (!packet.data || !(packet.data.length >= 2)) { | ||
throw new Socket.AuthError('Empty RSA public key') | ||
throw new Error('Empty service name'); | ||
} | ||
debug(`Received RSA public key '${packet.data.toString('base64')}'`) | ||
return Auth.parsePublicKey(this._skipNull(packet.data)) | ||
.then(key => { | ||
const digest = this.token.toString('binary') | ||
const sig = this.signature.toString('binary') | ||
if (!key.verify(digest, sig)) { | ||
debug('Signature mismatch') | ||
throw new Socket.AuthError('Signature mismatch') | ||
} | ||
debug('Signature verified') | ||
return key | ||
}).then(key => { | ||
return this.options.auth(key) | ||
.catch(function(err) { | ||
debug('Connection rejected by user-defined auth handler') | ||
throw new Socket.AuthError('Rejected by user-defined handler') | ||
}) | ||
}).then(() => { | ||
return this._deviceId() | ||
}).then(id => { | ||
this.authorized = true | ||
debug('O:A_CNXN') | ||
return this.write(Packet.assemble(Packet.A_CNXN, | ||
Packet.swap32(this.version), this.maxPayload, id) | ||
) | ||
}) | ||
default: | ||
throw new Error(`Unknown authentication method ${packet.arg0}`) | ||
} | ||
const name = this._skipNull(packet.data); | ||
debug(`Calling ${name}`); | ||
const service = new Service(this.client, this.serial, localId, remoteId, this); | ||
return new bluebird_1.default((resolve, reject) => { | ||
service.on('error', reject); | ||
service.on('end', resolve); | ||
this.services.insert(localId, service); | ||
debug(`Handling ${this.services.count} services simultaneously`); | ||
return service.handle(packet); | ||
}).catch(err => true).finally(() => { | ||
this.services.remove(localId); | ||
debug(`Handling ${this.services.count} services simultaneously`); | ||
return service.end(); | ||
}); | ||
} | ||
_handleOpenPacket(packet) { | ||
if (!this.authorized) { throw new Socket.UnauthorizedError() } | ||
const remoteId = packet.arg0 | ||
const localId = this.remoteId.next() | ||
if (!packet.data || !(packet.data.length >= 2)) { | ||
throw new Error('Empty service name') | ||
} | ||
const name = this._skipNull(packet.data) | ||
debug(`Calling ${name}`) | ||
const service = new Service(this.client, this.serial, localId, remoteId, this) | ||
return new Promise((resolve, reject) => { | ||
service.on('error', reject) | ||
service.on('end', resolve) | ||
this.services.insert(localId, service) | ||
debug(`Handling ${this.services.count} services simultaneously`) | ||
return service.handle(packet) | ||
}).catch(err => true).finally(() => { | ||
this.services.remove(localId) | ||
debug(`Handling ${this.services.count} services simultaneously`) | ||
return service.end() | ||
}) | ||
} | ||
_forwardServicePacket(packet) { | ||
let service | ||
if (!this.authorized) { throw new Socket.UnauthorizedError() } | ||
const remoteId = packet.arg0 | ||
const localId = packet.arg1 | ||
if ((service = this.services.get(localId))) { | ||
return service.handle(packet) | ||
} else { | ||
return debug('Received a packet to a service that may have been closed already') | ||
} | ||
let service; | ||
if (!this.authorized) { | ||
throw new Socket.UnauthorizedError(); | ||
} | ||
const remoteId = packet.arg0; | ||
const localId = packet.arg1; | ||
if ((service = this.services.get(localId))) { | ||
return service.handle(packet); | ||
} | ||
else { | ||
return debug('Received a packet to a service that may have been closed already'); | ||
} | ||
} | ||
write(chunk) { | ||
if (this.ended) { return } | ||
return this.socket.write(chunk) | ||
if (this.ended) { | ||
return; | ||
} | ||
return this.socket.write(chunk); | ||
} | ||
_createToken() { | ||
return Promise.promisify(crypto.randomBytes)(TOKEN_LENGTH) | ||
return bluebird_1.default.promisify(crypto.randomBytes)(this.TOKEN_LENGTH); | ||
} | ||
_skipNull(data) { | ||
return data.slice(0, -1) // Discard null byte at end | ||
return data.slice(0, -1); | ||
} | ||
_deviceId() { | ||
debug('Loading device properties to form a standard device ID') | ||
return this.client.getProperties(this.serial) | ||
.then(function(properties) { | ||
const id = (([ | ||
'ro.product.name', | ||
'ro.product.model', | ||
'ro.product.device' | ||
]).map((prop) => `${prop}=${properties[prop]};`)).join('') | ||
return new Buffer(`device::${id}\0`) | ||
}) | ||
debug('Loading device properties to form a standard device ID'); | ||
return this.client.getProperties(this.serial) | ||
.then(function (properties) { | ||
const id = (([ | ||
'ro.product.name', | ||
'ro.product.model', | ||
'ro.product.device' | ||
]).map((prop) => `${prop}=${properties[prop]};`)).join(''); | ||
return Buffer.from(`device::${id}\0`); | ||
}); | ||
} | ||
} | ||
Socket.initClass() | ||
return Socket | ||
})() | ||
} | ||
Socket.AuthError = class AuthError extends Error { | ||
constructor(message) { | ||
super() // TODO check sanity | ||
Error.call(this) | ||
this.name = 'AuthError' | ||
this.message = message | ||
Error.captureStackTrace(this, Socket.AuthError) | ||
} | ||
} | ||
constructor(message) { | ||
super(); | ||
Error.call(this); | ||
this.name = 'AuthError'; | ||
this.message = message; | ||
Error.captureStackTrace(this, Socket.AuthError); | ||
} | ||
}; | ||
Socket.UnauthorizedError = class UnauthorizedError extends Error { | ||
constructor() { | ||
super() // TODO check sanity | ||
Error.call(this) | ||
this.name = 'UnauthorizedError' | ||
this.message = 'Unauthorized access' | ||
Error.captureStackTrace(this, Socket.UnauthorizedError) | ||
} | ||
} | ||
module.exports = Socket | ||
constructor() { | ||
super(); | ||
Error.call(this); | ||
this.name = 'UnauthorizedError'; | ||
this.message = 'Unauthorized access'; | ||
Error.captureStackTrace(this, Socket.UnauthorizedError); | ||
} | ||
}; | ||
exports.Socket = Socket; | ||
//# sourceMappingURL=socket.js.map |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
274494
101
5550