appcd-client
Advanced tools
Comparing version 1.0.1 to 1.1.0-0
@@ -1,34 +0,26 @@ | ||
'use strict'; | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
value: true | ||
}); | ||
exports.default = undefined; | ||
exports.default = void 0; | ||
var _fs = require('fs'); | ||
var _appcdLogger = _interopRequireDefault(require("appcd-logger")); | ||
var _fs2 = _interopRequireDefault(_fs); | ||
var _fs = _interopRequireDefault(require("fs")); | ||
var _msgpackLite = require('msgpack-lite'); | ||
var _msgpackLite = _interopRequireDefault(require("msgpack-lite")); | ||
var _msgpackLite2 = _interopRequireDefault(_msgpackLite); | ||
var _path = _interopRequireDefault(require("path")); | ||
var _path = require('path'); | ||
var _uuid = _interopRequireDefault(require("uuid")); | ||
var _path2 = _interopRequireDefault(_path); | ||
var _ws = _interopRequireDefault(require("ws")); | ||
var _uuid = require('uuid'); | ||
var _appcdUtil = require("appcd-util"); | ||
var _uuid2 = _interopRequireDefault(_uuid); | ||
var _events = require("events"); | ||
var _ws = require('ws'); | ||
var _appcdResponse = require("appcd-response"); | ||
var _ws2 = _interopRequireDefault(_ws); | ||
var _appcdUtil = require('appcd-util'); | ||
var _events = require('events'); | ||
var _appcdResponse = require('appcd-response'); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -38,194 +30,229 @@ | ||
if (!Error.prepareStackTrace) { | ||
require('source-map-support/register'); | ||
require('source-map-support/register'); | ||
} | ||
const { | ||
log | ||
} = (0, _appcdLogger.default)('appcd:client'); | ||
const { | ||
alert, | ||
highlight, | ||
note, | ||
ok | ||
} = _appcdLogger.default.styles; | ||
/** | ||
* The client for connecting to the appcd server. | ||
*/ | ||
let Client = class Client { | ||
/** | ||
* Initializes the client. | ||
* | ||
* @param {Object} [opts] - Various options. | ||
* @param {String} [opts.host='127.0.0.1'] - The host to connect to. | ||
* @param {Number} [opts.port=1732] - The port to connect to. | ||
* @param {String} [opts.userAgent] - The user agent containing the name and | ||
* version of the client. If not specified, one will be generated. | ||
* @access public | ||
*/ | ||
constructor(opts = {}) { | ||
/** | ||
* The websocket to the server. | ||
* @type {WebSocket} | ||
* @access private | ||
/** | ||
* Initializes the client. | ||
* | ||
* @param {Object} [opts] - Various options. | ||
* @param {String} [opts.host='127.0.0.1'] - The host to connect to. | ||
* @param {Number} [opts.port=1732] - The port to connect to. | ||
* @param {String} [opts.userAgent] - The user agent containing the name and | ||
* version of the client. If not specified, one will be generated. | ||
* @access public | ||
*/ | ||
this.socket = null; | ||
constructor(opts = {}) { | ||
/** | ||
* The websocket to the server. | ||
* @type {WebSocket} | ||
* @access private | ||
*/ | ||
this.socket = null; | ||
/** | ||
* An internal map used to dispatch responses to requesters. | ||
* @type {Object} | ||
* @access private | ||
*/ | ||
/** | ||
* An internal map used to dispatch responses to requesters. | ||
* @type {Object} | ||
* @access private | ||
*/ | ||
this.requests = {}; | ||
this.requests = {}; | ||
/** | ||
* The host to connect to. | ||
* @type {String} | ||
* @access private | ||
*/ | ||
/** | ||
* The host to connect to. | ||
* @type {String} | ||
* @access private | ||
*/ | ||
this.host = opts.host || '127.0.0.1'; | ||
this.host = opts.host || '127.0.0.1'; | ||
/** | ||
* The port to connect to. | ||
* @type {Number} | ||
* @access private | ||
*/ | ||
/** | ||
* The port to connect to. | ||
* @type {Number} | ||
* @access private | ||
*/ | ||
if (opts.port && (typeof opts.port !== 'number' || opts.port < 1 || opts.port > 65535)) { | ||
throw new TypeError('Invalid port, expected a number between 1 and 65535'); | ||
} | ||
this.port = opts.port || 1732; | ||
if (opts.port && (typeof opts.port !== 'number' || opts.port < 1 || opts.port > 65535)) { | ||
throw new TypeError('Invalid port, expected a number between 1 and 65535'); | ||
} | ||
/** | ||
* The user agent containing the name and version of the client. If not | ||
* specified, one will be generated. | ||
* @type {String} | ||
* @access private | ||
this.port = opts.port || 1732; | ||
/** | ||
* The user agent containing the name and version of the client. If not | ||
* specified, one will be generated. | ||
* @type {String} | ||
* @access private | ||
*/ | ||
this.userAgent = constructUserAgent(opts.userAgent); | ||
} | ||
/** | ||
* Connects to the server via a websocket. You do not need to call this. | ||
* `request()` will automatically call this function. | ||
* | ||
* @returns {EventEmitter} Emits events `connected`, `close`, and `error`. | ||
* @access public | ||
*/ | ||
this.userAgent = constructUserAgent(opts.userAgent); | ||
} | ||
/** | ||
* Connects to the server via a websocket. You do not need to call this. | ||
* `request()` will automatically call this function. | ||
* | ||
* @returns {EventEmitter} Emits events `connected`, `close`, and `error`. | ||
* @access public | ||
*/ | ||
connect() { | ||
const emitter = new _events.EventEmitter(); | ||
// need to delay request so event emitter can be returned and events can | ||
// be wired up | ||
setImmediate(async () => { | ||
try { | ||
if (this.socket) { | ||
emitter.emit('connected', this); | ||
return; | ||
} | ||
connect() { | ||
const emitter = new _events.EventEmitter(); // need to delay request so event emitter can be returned and events can | ||
// be wired up | ||
const headers = { | ||
'User-Agent': this.userAgent | ||
}; | ||
setImmediate(async () => { | ||
try { | ||
if (this.socket) { | ||
emitter.emit('connected', this); | ||
return; | ||
} | ||
const localeValue = process.env.APPCD_LOCALE || (await (0, _appcdResponse.locale)()); | ||
if (localeValue) { | ||
headers['Accept-Language'] = localeValue; | ||
} | ||
const headers = { | ||
'User-Agent': this.userAgent | ||
}; | ||
const localeValue = process.env.APPCD_LOCALE || (await (0, _appcdResponse.locale)()); | ||
const socket = this.socket = new _ws2.default(`ws://${this.host}:${this.port}`, { | ||
headers | ||
}); | ||
if (localeValue) { | ||
headers['Accept-Language'] = localeValue; | ||
} | ||
socket.on('message', data => { | ||
let json = null; | ||
if (typeof data === 'string') { | ||
try { | ||
json = JSON.parse(data); | ||
} catch (e) { | ||
// bad response, shouldn't ever happen | ||
emitter.emit('warning', `Server returned invalid JSON: ${e.message}`); | ||
return; | ||
} | ||
} else { | ||
json = _msgpackLite2.default.decode(data); | ||
} | ||
const url = `ws://${this.host}:${this.port}`; | ||
log(`Connecting to ${highlight(url)}`); | ||
const socket = this.socket = new _ws.default(url, { | ||
headers | ||
}); | ||
socket.on('message', data => { | ||
let json = null; | ||
if (json && typeof json === 'object' && this.requests[json.id]) { | ||
this.requests[json.id](json); | ||
} else { | ||
emitter.emit('warning', 'Server response is not an object or has an invalid id'); | ||
} | ||
}); | ||
if (typeof data === 'string') { | ||
try { | ||
json = JSON.parse(data); | ||
} catch (e) { | ||
// bad response, shouldn't ever happen | ||
emitter.emit('warning', `Server returned invalid JSON: ${e.message}`); | ||
return; | ||
} | ||
} else { | ||
json = _msgpackLite.default.decode(data); | ||
} | ||
socket.on('open', () => emitter.emit('connected', this)).once('close', () => emitter.emit('close')).once('error', err => { | ||
socket.close(); | ||
this.socket = null; | ||
emitter.emit('error', err); | ||
}); | ||
} catch (e) { | ||
emitter.emit('error', e); | ||
} | ||
}); | ||
if (json && typeof json === 'object' && this.requests[json.id]) { | ||
this.requests[json.id](json); | ||
} else { | ||
emitter.emit('warning', 'Server response is not an object or has an invalid id'); | ||
} | ||
}).on('open', () => emitter.emit('connected', this)).once('close', () => emitter.emit('close')).once('error', err => { | ||
socket.close(); | ||
this.socket = null; | ||
emitter.emit('error', err); | ||
}); | ||
} catch (e) { | ||
emitter.emit('error', e); | ||
} | ||
}); | ||
return emitter; | ||
} | ||
/** | ||
* Issues a request to the server over a websocket. | ||
* | ||
* @param {String} path - The path to send. | ||
* @param {Object} [data] - An object to send. | ||
* @param {String} [type] - The request type. Valid types include `call`, `subscribe`, and | ||
* `unsubscribe`. | ||
* @returns {EventEmitter} Emits events `response` and `error`. | ||
* @access public | ||
*/ | ||
return emitter; | ||
} | ||
/** | ||
* Issues a request to the server over a websocket. | ||
* | ||
* @param {String} path - The path to send. | ||
* @param {Object} [data] - An object to send. | ||
* @param {String} [type] - The request type. Valid types include `call`, `subscribe`, and | ||
* `unsubscribe`. | ||
* @returns {EventEmitter} Emits events `response` and `error`. | ||
* @access public | ||
*/ | ||
request({ path, data, type } = {}) { | ||
const emitter = new _events.EventEmitter(); | ||
request({ | ||
path, | ||
data, | ||
type | ||
} = {}) { | ||
const emitter = new _events.EventEmitter(); | ||
const startTime = new Date(); // need to delay request so event emitter can be returned and events can | ||
// be wired up | ||
// need to delay request so event emitter can be returned and events can | ||
// be wired up | ||
setImmediate(() => { | ||
const id = _uuid2.default.v4(); | ||
setImmediate(() => { | ||
const id = _uuid.default.v4(); | ||
return this.connect().on('connected', client => { | ||
this.requests[id] = response => { | ||
const status = ~~response.status || 500; | ||
const statusClass = Math.floor(status / 100); | ||
return this.connect().on('connected', client => { | ||
this.requests[id] = response => { | ||
const status = response.status = ~~response.status || 500; | ||
const statusClass = Math.floor(status / 100); | ||
const style = status < 400 ? ok : alert; // no need for the id anymore | ||
switch (statusClass) { | ||
case 2: | ||
emitter.emit('response', response.message, response); | ||
break; | ||
delete response.id; | ||
log(`${style(status)} ${highlight(path)} ${note(`${new Date() - startTime}ms`)}`); | ||
case 4: | ||
case 5: | ||
const err = new Error(response.message || 'Server Error'); | ||
err.errorCode = status; | ||
err.code = String(response.statusCode ? response.statusCode : status); | ||
emitter.emit('error', err, response); | ||
} | ||
}; | ||
switch (statusClass) { | ||
case 2: | ||
emitter.emit('response', response.message, response); | ||
break; | ||
client.socket.send(JSON.stringify({ | ||
version: '1.0', | ||
path: path, | ||
id: id, | ||
data, | ||
type | ||
})); | ||
}).on('warning', (...args) => emitter.emit('warning', ...args)).once('close', () => { | ||
delete this.requests[id]; | ||
}).once('error', err => { | ||
delete this.requests[id]; | ||
emitter.emit('error', err); | ||
}); | ||
}); | ||
case 4: | ||
case 5: | ||
const err = new Error(response.message || 'Server Error'); | ||
return emitter; | ||
} | ||
if (!response.statusCode) { | ||
response.statusCode = String(status); | ||
} | ||
/** | ||
* Disconnects from the server. | ||
* | ||
* @access public | ||
*/ | ||
disconnect() { | ||
if (this.socket) { | ||
this.socket.close(); | ||
} | ||
this.socket = null; | ||
} | ||
for (const prop of Object.keys(response)) { | ||
// we need to use defineProperty() to force properties to be created | ||
Object.defineProperty(err, prop, { | ||
configurable: true, | ||
enumerable: true, | ||
value: response[prop], | ||
writable: true | ||
}); | ||
} | ||
emitter.emit('error', err, response); | ||
} | ||
}; | ||
const req = { | ||
version: '1.0', | ||
path, | ||
id, | ||
data, | ||
type | ||
}; | ||
log('Sending request:', req); | ||
client.socket.send(JSON.stringify(req)); | ||
}).on('warning', (...args) => emitter.emit('warning', ...args)).once('close', () => { | ||
delete this.requests[id]; | ||
}).once('error', err => { | ||
delete this.requests[id]; | ||
emitter.emit('error', err); | ||
}); | ||
}); | ||
return emitter; | ||
} | ||
/** | ||
* Disconnects from the server. | ||
* | ||
* @access public | ||
*/ | ||
disconnect() { | ||
if (this.socket) { | ||
this.socket.close(); | ||
} | ||
this.socket = null; | ||
} | ||
}; | ||
/** | ||
@@ -241,56 +268,60 @@ * Generates a user agent string containing the name of the parent-most script | ||
exports.default = Client; | ||
function constructUserAgent(userAgent) { | ||
if (userAgent && typeof userAgent !== 'string') { | ||
throw new TypeError('Expected user agent to be a string'); | ||
} | ||
if (userAgent && typeof userAgent !== 'string') { | ||
throw new TypeError('Expected user agent to be a string'); | ||
} | ||
const parts = userAgent ? userAgent.split(' ') : []; | ||
const parts = userAgent ? userAgent.split(' ') : []; | ||
if (!parts.length) { | ||
let entry = module; | ||
while (entry.parent) { | ||
entry = entry.parent; | ||
} | ||
if (!parts.length) { | ||
let entry = module; | ||
const name = _path2.default.basename(entry.filename); | ||
const root = _path2.default.resolve('/'); | ||
let dir = _path2.default.dirname(entry.filename); | ||
while (entry.parent) { | ||
entry = entry.parent; | ||
} | ||
do { | ||
const pkgJsonFile = _path2.default.join(dir, 'package.json'); | ||
const name = _path.default.basename(entry.filename); | ||
try { | ||
if (_fs2.default.statSync(pkgJsonFile)) { | ||
parts.push(`${name}/${JSON.parse(_fs2.default.readFileSync(pkgJsonFile)).version || ''}`); | ||
break; | ||
} | ||
} catch (e) { | ||
// either the package.json doesn't exist or the JSON was malformed | ||
if (e.code !== 'ENOENT') { | ||
// must be malformed JSON, we can stop | ||
break; | ||
} | ||
} | ||
const root = _path.default.resolve('/'); | ||
dir = _path2.default.dirname(dir); | ||
} while (dir !== root); | ||
} | ||
let dir = _path.default.dirname(entry.filename); | ||
parts.push(`appcd-client/${JSON.parse(_fs2.default.readFileSync(_path2.default.resolve(__dirname, '..', 'package.json'))).version}`); | ||
do { | ||
const pkgJsonFile = _path.default.join(dir, 'package.json'); | ||
if (!parts.some(p => p.indexOf('node/') === 0)) { | ||
parts.push(`node/${process.version.replace(/^v/, '')}`); | ||
} | ||
try { | ||
if (_fs.default.statSync(pkgJsonFile)) { | ||
parts.push(`${name}/${JSON.parse(_fs.default.readFileSync(pkgJsonFile)).version || ''}`); | ||
break; | ||
} | ||
} catch (e) { | ||
// either the package.json doesn't exist or the JSON was malformed | ||
if (e.code !== 'ENOENT') { | ||
// must be malformed JSON, we can stop | ||
break; | ||
} | ||
} | ||
if (!parts.some(p => p === process.platform)) { | ||
parts.push(process.platform); | ||
} | ||
dir = _path.default.dirname(dir); | ||
} while (dir !== root); | ||
} | ||
const architecture = (0, _appcdUtil.arch)(); | ||
if (!parts.some(p => p === architecture)) { | ||
parts.push(architecture); | ||
} | ||
parts.push(`appcd-client/${JSON.parse(_fs.default.readFileSync(_path.default.resolve(__dirname, '..', 'package.json'))).version}`); | ||
return parts.join(' '); | ||
} | ||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImNsaWVudC5qcyJdLCJuYW1lcyI6WyJFcnJvciIsInByZXBhcmVTdGFja1RyYWNlIiwicmVxdWlyZSIsIkNsaWVudCIsImNvbnN0cnVjdG9yIiwib3B0cyIsInNvY2tldCIsInJlcXVlc3RzIiwiaG9zdCIsInBvcnQiLCJUeXBlRXJyb3IiLCJ1c2VyQWdlbnQiLCJjb25zdHJ1Y3RVc2VyQWdlbnQiLCJjb25uZWN0IiwiZW1pdHRlciIsInNldEltbWVkaWF0ZSIsImVtaXQiLCJoZWFkZXJzIiwibG9jYWxlVmFsdWUiLCJwcm9jZXNzIiwiZW52IiwiQVBQQ0RfTE9DQUxFIiwib24iLCJkYXRhIiwianNvbiIsIkpTT04iLCJwYXJzZSIsImUiLCJtZXNzYWdlIiwiZGVjb2RlIiwiaWQiLCJvbmNlIiwiZXJyIiwiY2xvc2UiLCJyZXF1ZXN0IiwicGF0aCIsInR5cGUiLCJ2NCIsImNsaWVudCIsInJlc3BvbnNlIiwic3RhdHVzIiwic3RhdHVzQ2xhc3MiLCJNYXRoIiwiZmxvb3IiLCJlcnJvckNvZGUiLCJjb2RlIiwiU3RyaW5nIiwic3RhdHVzQ29kZSIsInNlbmQiLCJzdHJpbmdpZnkiLCJ2ZXJzaW9uIiwiYXJncyIsImRpc2Nvbm5lY3QiLCJwYXJ0cyIsInNwbGl0IiwibGVuZ3RoIiwiZW50cnkiLCJtb2R1bGUiLCJwYXJlbnQiLCJuYW1lIiwiYmFzZW5hbWUiLCJmaWxlbmFtZSIsInJvb3QiLCJyZXNvbHZlIiwiZGlyIiwiZGlybmFtZSIsInBrZ0pzb25GaWxlIiwiam9pbiIsInN0YXRTeW5jIiwicHVzaCIsInJlYWRGaWxlU3luYyIsIl9fZGlybmFtZSIsInNvbWUiLCJwIiwiaW5kZXhPZiIsInJlcGxhY2UiLCJwbGF0Zm9ybSIsImFyY2hpdGVjdHVyZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUtBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFFQTs7QUFDQTs7QUFDQTs7OztBQWJBO0FBQ0EsSUFBSSxDQUFDQSxNQUFNQyxpQkFBWCxF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LElBQU4sQ0FBV0MsS0FBS0EsTUFBTXRELFFBQVF5RCxRQUE5QixDQUFMLEVBQThDO0FBQzdDdkIsUUFBTWdCLElBQU4sQ0FBV2xELFFBQVF5RCxRQUFuQjtBQUNBOztBQUVELE9BQU1DLGVBQWUsc0JBQXJCO0FBQ0EsS0FBSSxDQUFDeEIsTUFBTW1CLElBQU4sQ0FBV0MsS0FBS0EsTUFBTUksWUFBdEIsQ0FBTCxFQUEwQztBQUN6Q3hCLFFBQU1nQixJQUFOLENBQVdRLFlBQVg7QUFDQTs7QUFFRCxRQUFPeEIsTUFBTWMsSUFBTixDQUFXLEdBQVgsQ0FBUDtBQUNBIiwiZmlsZSI6ImNsaWVudC5qcyIsInNvdXJjZVJvb3QiOiJzcmMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbmlmICghRXJyb3IucHJlcGFyZVN0YWNrVHJhY2UpIHtcblx0cmVxdWlyZSgnc291cmNlLW1hcC1zdXBwb3J0L3JlZ2lzdGVyJyk7XG59XG5cbmltcG9ydCBmcyBmcm9tICdmcyc7XG5pbXBvcnQgbXNncGFjayBmcm9tICdtc2dwYWNrLWxpdGUnO1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgdXVpZCBmcm9tICd1dWlkJztcbmltcG9ydCBXZWJTb2NrZXQgZnJvbSAnd3MnO1xuXG5pbXBvcnQgeyBhcmNoIH0gZnJvbSAnYXBwY2QtdXRpbCc7XG5pbXBvcnQgeyBFdmVudEVtaXR0ZXIgfSBmcm9tICdldmVudHMnO1xuaW1wb3J0IHsgbG9jYWxlIH0gZnJvbSAnYXBwY2QtcmVzcG9uc2UnO1xuXG4vKipcbiAqIFRoZSBjbGllbnQgZm9yIGNvbm5lY3RpbmcgdG8gdGhlIGFwcGNkIHNlcnZlci5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ2xpZW50IHtcblx0LyoqXG5cdCAqIEluaXRpYWxpemVzIHRoZSBjbGllbnQuXG5cdCAqXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0c10gLSBWYXJpb3VzIG9wdGlvbnMuXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0cy5ob3N0PScxMjcuMC4wLjEnXSAtIFRoZSBob3N0IHRvIGNvbm5lY3QgdG8uXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0cy5wb3J0PTE3MzJdIC0gVGhlIHBvcnQgdG8gY29ubmVjdCB0by5cblx0ICogQHBhcmFtIHtTdHJpbmd9IFtvcHRzLnVzZXJBZ2VudF0gLSBUaGUgdXNlciBhZ2VudCBjb250YWluaW5nIHRoZSBuYW1lIGFuZFxuXHQgKiB2ZXJzaW9uIG9mIHRoZSBjbGllbnQuIElmIG5vdCBzcGVjaWZpZWQsIG9uZSB3aWxsIGJlIGdlbmVyYXRlZC5cblx0ICogQGFjY2VzcyBwdWJsaWNcblx0ICovXG5cdGNvbnN0cnVjdG9yKG9wdHMgPSB7fSkge1xuXHRcdC8qKlxuXHRcdCAqIFRoZSB3ZWJzb2NrZXQgdG8gdGhlIHNlcnZlci5cblx0XHQgKiBAdHlwZSB7V2ViU29ja2V0fVxuXHRcdCAqIEBhY2Nlc3MgcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdHRoaXMuc29ja2V0ID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEFuIGludGVybmFsIG1hcCB1c2VkIHRvIGRpc3BhdGNoIHJlc3BvbnNlcyB0byByZXF1ZXN0ZXJzLlxuXHRcdCAqIEB0eXBlIHtPYmplY3R9XG5cdFx0ICogQGFjY2VzcyBwcml2YXRlXG5cdFx0ICovXG5cdFx0dGhpcy5yZXF1ZXN0cyA9IHt9O1xuXG5cdFx0LyoqXG5cdFx0ICogVGhlIGhvc3QgdG8gY29ubmVjdCB0by5cblx0XHQgKiBAdHlwZSB7U3RyaW5nfVxuXHRcdCAqIEBhY2Nlc3MgcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdHRoaXMuaG9zdCA9IG9wdHMuaG9zdCB8fCAnMTI3LjAuMC4xJztcblxuXHRcdC8qKlxuXHRcdCAqIFRoZSBwb3J0IHRvIGNvbm5lY3QgdG8uXG5cdFx0ICogQHR5cGUge051bWJlcn1cblx0XHQgKiBAYWNjZXNzIHByaXZhdGVcblx0XHQgKi9cblx0XHRpZiAob3B0cy5wb3J0ICYmICh0eXBlb2Ygb3B0cy5wb3J0ICE9PSAnbnVtYmVyJyB8fCBvcHRzLnBvcnQgPCAxIHx8IG9wdHMucG9ydCA+IDY1NTM1KSkge1xuXHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBwb3J0LCBleHBlY3RlZCBhIG51bWJlciBiZXR3ZWVuIDEgYW5kIDY1NTM1Jyk7XG5cdFx0fVxuXHRcdHRoaXMucG9ydCA9IG9wdHMucG9ydCB8fCAxNzMyO1xuXG5cdFx0LyoqXG5cdFx0ICogVGhlIHVzZXIgYWdlbnQgY29udGFpbmluZyB0aGUgbmFtZSBhbmQgdmVyc2lvbiBvZiB0aGUgY2xpZW50LiBJZiBub3Rcblx0XHQgKiBzcGVjaWZpZWQsIG9uZSB3aWxsIGJlIGdlbmVyYXRlZC5cblx0XHQgKiBAdHlwZSB7U3RyaW5nfVxuXHRcdCAqIEBhY2Nlc3MgcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdHRoaXMudXNlckFnZW50ID0gY29uc3RydWN0VXNlckFnZW50KG9wdHMudXNlckFnZW50KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDb25uZWN0cyB0byB0aGUgc2VydmVyIHZpYSBhIHdlYnNvY2tldC4gWW91IGRvIG5vdCBuZWVkIHRvIGNhbGwgdGhpcy5cblx0ICogYHJlcXVlc3QoKWAgd2lsbCBhdXRvbWF0aWNhbGx5IGNhbGwgdGhpcyBmdW5jdGlvbi5cblx0ICpcblx0ICogQHJldHVybnMge0V2ZW50RW1pdHRlcn0gRW1pdHMgZXZlbnRzIGBjb25uZWN0ZWRgLCBgY2xvc2VgLCBhbmQgYGVycm9yYC5cblx0ICogQGFjY2VzcyBwdWJsaWNcblx0ICovXG5cdGNvbm5lY3QoKSB7XG5cdFx0Y29uc3QgZW1pdHRlciA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuXHRcdC8vIG5lZWQgdG8gZGVsYXkgcmVxdWVzdCBzbyBldmVudCBlbWl0dGVyIGNhbiBiZSByZXR1cm5lZCBhbmQgZXZlbnRzIGNhblxuXHRcdC8vIGJlIHdpcmVkIHVwXG5cdFx0c2V0SW1tZWRpYXRlKGFzeW5jICgpID0+IHtcblx0XHRcdHRyeSB7XG5cdFx0XHRcdGlmICh0aGlzLnNvY2tldCkge1xuXHRcdFx0XHRcdGVtaXR0ZXIuZW1pdCgnY29ubmVjdGVkJywgdGhpcyk7XG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Y29uc3QgaGVhZGVycyA9IHtcblx0XHRcdFx0XHQnVXNlci1BZ2VudCc6IHRoaXMudXNlckFnZW50XG5cdFx0XHRcdH07XG5cblx0XHRcdFx0Y29uc3QgbG9jYWxlVmFsdWUgPSBwcm9jZXNzLmVudi5BUFBDRF9MT0NBTEUgfHwgYXdhaXQgbG9jYWxlKCk7XG5cdFx0XHRcdGlmIChsb2NhbGVWYWx1ZSkge1xuXHRcdFx0XHRcdGhlYWRlcnNbJ0FjY2VwdC1MYW5ndWFnZSddID0gbG9jYWxlVmFsdWU7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRjb25zdCBzb2NrZXQgPSB0aGlzLnNvY2tldCA9IG5ldyBXZWJTb2NrZXQoYHdzOi8vJHt0aGlzLmhvc3R9OiR7dGhpcy5wb3J0fWAsIHtcblx0XHRcdFx0XHRoZWFkZXJzXG5cdFx0XHRcdH0pO1xuXG5cdFx0XHRcdHNvY2tldC5vbignbWVzc2FnZScsIGRhdGEgPT4ge1xuXHRcdFx0XHRcdGxldCBqc29uID0gbnVsbDtcblx0XHRcdFx0XHRpZiAodHlwZW9mIGRhdGEgPT09ICdzdHJpbmcnKSB7XG5cdFx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0XHRqc29uID0gSlNPTi5wYXJzZShkYXRhKTtcblx0XHRcdFx0XHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdFx0XHRcdFx0Ly8gYmFkIHJlc3BvbnNlLCBzaG91bGRuJ3QgZXZlciBoYXBwZW5cblx0XHRcdFx0XHRcdFx0ZW1pdHRlci5lbWl0KCd3YXJuaW5nJywgYFNlcnZlciByZXR1cm5lZCBpbnZhbGlkIEpTT046ICR7ZS5tZXNzYWdlfWApO1xuXHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdGpzb24gPSBtc2dwYWNrLmRlY29kZShkYXRhKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRpZiAoanNvbiAmJiB0eXBlb2YganNvbiA9PT0gJ29iamVjdCcgJiYgdGhpcy5yZXF1ZXN0c1tqc29uLmlkXSkge1xuXHRcdFx0XHRcdFx0dGhpcy5yZXF1ZXN0c1tqc29uLmlkXShqc29uKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0ZW1pdHRlci5lbWl0KCd3YXJuaW5nJywgJ1NlcnZlciByZXNwb25zZSBpcyBub3QgYW4gb2JqZWN0IG9yIGhhcyBhbiBpbnZhbGlkIGlkJyk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblxuXHRcdFx0XHRzb2NrZXRcblx0XHRcdFx0XHQub24oJ29wZW4nLCAoKSA9PiBlbWl0dGVyLmVtaXQoJ2Nvbm5lY3RlZCcsIHRoaXMpKVxuXHRcdFx0XHRcdC5vbmNlKCdjbG9zZScsICgpID0+IGVtaXR0ZXIuZW1pdCgnY2xvc2UnKSlcblx0XHRcdFx0XHQub25jZSgnZXJyb3InLCBlcnIgPT4ge1xuXHRcdFx0XHRcdFx0c29ja2V0LmNsb3NlKCk7XG5cdFx0XHRcdFx0XHR0aGlzLnNvY2tldCA9IG51bGw7XG5cdFx0XHRcdFx0XHRlbWl0dGVyLmVtaXQoJ2Vycm9yJywgZXJyKTtcblx0XHRcdFx0XHR9KTtcblx0XHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdFx0ZW1pdHRlci5lbWl0KCdlcnJvcicsIGUpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0cmV0dXJuIGVtaXR0ZXI7XG5cdH1cblxuXHQvKipcblx0ICogSXNzdWVzIGEgcmVxdWVzdCB0byB0aGUgc2VydmVyIG92ZXIgYSB3ZWJzb2NrZXQuXG5cdCAqXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBwYXRoIC0gVGhlIHBhdGggdG8gc2VuZC5cblx0ICogQHBhcmFtIHtPYmplY3R9IFtkYXRhXSAtIEFuIG9iamVjdCB0byBzZW5kLlxuXHQgKiBAcGFyYW0ge1N0cmluZ30gW3R5cGVdIC0gVGhlIHJlcXVlc3QgdHlwZS4gVmFsaWQgdHlwZXMgaW5jbHVkZSBgY2FsbGAsIGBzdWJzY3JpYmVgLCBhbmRcblx0ICogYHVuc3Vic2NyaWJlYC5cblx0ICogQHJldHVybnMge0V2ZW50RW1pdHRlcn0gRW1pdHMgZXZlbnRzIGByZXNwb25zZWAgYW5kIGBlcnJvcmAuXG5cdCAqIEBhY2Nlc3MgcHVibGljXG5cdCAqL1xuXHRyZXF1ZXN0KHsgcGF0aCwgZGF0YSwgdHlwZSB9ID0ge30pIHtcblx0XHRjb25zdCBlbWl0dGVyID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG5cdFx0Ly8gbmVlZCB0byBkZWxheSByZXF1ZXN0IHNvIGV2ZW50IGVtaXR0ZXIgY2FuIGJlIHJldHVybmVkIGFuZCBldmVudHMgY2FuXG5cdFx0Ly8gYmUgd2lyZWQgdXBcblx0XHRzZXRJbW1lZGlhdGUoKCkgPT4ge1xuXHRcdFx0Y29uc3QgaWQgPSB1dWlkLnY0KCk7XG5cblx0XHRcdHJldHVybiB0aGlzLmNvbm5lY3QoKVxuXHRcdFx0XHQub24oJ2Nvbm5lY3RlZCcsIGNsaWVudCA9PiB7XG5cdFx0XHRcdFx0dGhpcy5yZXF1ZXN0c1tpZF0gPSByZXNwb25zZSA9PiB7XG5cdFx0XHRcdFx0XHRjb25zdCBzdGF0dXMgPSB+fnJlc3BvbnNlLnN0YXR1cyB8fCA1MDA7XG5cdFx0XHRcdFx0XHRjb25zdCBzdGF0dXNDbGFzcyA9IE1hdGguZmxvb3Ioc3RhdHVzIC8gMTAwKTtcblxuXHRcdFx0XHRcdFx0c3dpdGNoIChzdGF0dXNDbGFzcykge1xuXHRcdFx0XHRcdFx0XHRjYXNlIDI6XG5cdFx0XHRcdFx0XHRcdFx0ZW1pdHRlci5lbWl0KCdyZXNwb25zZScsIHJlc3BvbnNlLm1lc3NhZ2UsIHJlc3BvbnNlKTtcblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdFx0XHRjYXNlIDQ6XG5cdFx0XHRcdFx0XHRcdGNhc2UgNTpcblx0XHRcdFx0XHRcdFx0XHRjb25zdCBlcnIgPSBuZXcgRXJyb3IocmVzcG9uc2UubWVzc2FnZSB8fCAnU2VydmVyIEVycm9yJyk7XG5cdFx0XHRcdFx0XHRcdFx0ZXJyLmVycm9yQ29kZSA9IHN0YXR1cztcblx0XHRcdFx0XHRcdFx0XHRlcnIuY29kZSA9IFN0cmluZyhyZXNwb25zZS5zdGF0dXNDb2RlID8gcmVzcG9uc2Uuc3RhdHVzQ29kZSA6IHN0YXR1cyk7XG5cdFx0XHRcdFx0XHRcdFx0ZW1pdHRlci5lbWl0KCdlcnJvcicsIGVyciwgcmVzcG9uc2UpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH07XG5cblx0XHRcdFx0XHRjbGllbnQuc29ja2V0LnNlbmQoSlNPTi5zdHJpbmdpZnkoe1xuXHRcdFx0XHRcdFx0dmVyc2lvbjogJzEuMCcsXG5cdFx0XHRcdFx0XHRwYXRoOiAgICBwYXRoLFxuXHRcdFx0XHRcdFx0aWQ6ICAgICAgaWQsXG5cdFx0XHRcdFx0XHRkYXRhLFxuXHRcdFx0XHRcdFx0dHlwZVxuXHRcdFx0XHRcdH0pKTtcblx0XHRcdFx0fSlcblx0XHRcdFx0Lm9uKCd3YXJuaW5nJywgKC4uLmFyZ3MpID0+IGVtaXR0ZXIuZW1pdCgnd2FybmluZycsIC4uLmFyZ3MpKVxuXHRcdFx0XHQub25jZSgnY2xvc2UnLCAoKSA9PiB7XG5cdFx0XHRcdFx0ZGVsZXRlIHRoaXMucmVxdWVzdHNbaWRdO1xuXHRcdFx0XHR9KVxuXHRcdFx0XHQub25jZSgnZXJyb3InLCBlcnIgPT4ge1xuXHRcdFx0XHRcdGRlbGV0ZSB0aGlzLnJlcXVlc3RzW2lkXTtcblx0XHRcdFx0XHRlbWl0dGVyLmVtaXQoJ2Vycm9yJywgZXJyKTtcblx0XHRcdFx0fSk7XG5cdFx0fSk7XG5cblx0XHRyZXR1cm4gZW1pdHRlcjtcblx0fVxuXG5cdC8qKlxuXHQgKiBEaXNjb25uZWN0cyBmcm9tIHRoZSBzZXJ2ZXIuXG5cdCAqXG5cdCAqIEBhY2Nlc3MgcHVibGljXG5cdCAqL1xuXHRkaXNjb25uZWN0KCkge1xuXHRcdGlmICh0aGlzLnNvY2tldCkge1xuXHRcdFx0dGhpcy5zb2NrZXQuY2xvc2UoKTtcblx0XHR9XG5cdFx0dGhpcy5zb2NrZXQgPSBudWxsO1xuXHR9XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIGEgdXNlciBhZ2VudCBzdHJpbmcgY29udGFpbmluZyB0aGUgbmFtZSBvZiB0aGUgcGFyZW50LW1vc3Qgc2NyaXB0XG4gKiBuYW1lLCBOb2RlLmpzIHZlcnNpb24sIHBsYXRmb3JtIG5hbWUsIGFuZCBhcmNoaXRlY3R1cmUuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IFt1c2VyQWdlbnRdIC0gVGhlIGludm9raW5nIGNsaWVudCdzIHVzZXIgYWdlbnQuIFRoaXMgc2ltcGx5IG5lZWRzIHRvIGJlIHRoZVxuICogYG5hbWUvdmVyc2lvbmAuXG4gKiBAcmV0dXJucyB7U3RyaW5nfVxuICovXG5mdW5jdGlvbiBjb25zdHJ1Y3RVc2VyQWdlbnQodXNlckFnZW50KSB7XG5cdGlmICh1c2VyQWdlbnQgJiYgdHlwZW9mIHVzZXJBZ2VudCAhPT0gJ3N0cmluZycpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdFeHBlY3RlZCB1c2VyIGFnZW50IHRvIGJlIGEgc3RyaW5nJyk7XG5cdH1cblxuXHRjb25zdCBwYXJ0cyA9IHVzZXJBZ2VudCA/IHVzZXJBZ2VudC5zcGxpdCgnICcpIDogW107XG5cblx0aWYgKCFwYXJ0cy5sZW5ndGgpIHtcblx0XHRsZXQgZW50cnkgPSBtb2R1bGU7XG5cdFx0d2hpbGUgKGVudHJ5LnBhcmVudCkge1xuXHRcdFx0ZW50cnkgPSBlbnRyeS5wYXJlbnQ7XG5cdFx0fVxuXG5cdFx0Y29uc3QgbmFtZSA9IHBhdGguYmFzZW5hbWUoZW50cnkuZmlsZW5hbWUpO1xuXHRcdGNvbnN0IHJvb3QgPSBwYXRoLnJlc29sdmUoJy8nKTtcblx0XHRsZXQgZGlyID0gcGF0aC5kaXJuYW1lKGVudHJ5LmZpbGVuYW1lKTtcblxuXHRcdGRvIHtcblx0XHRcdGNvbnN0IHBrZ0pzb25GaWxlID0gcGF0aC5qb2luKGRpciwgJ3BhY2thZ2UuanNvbicpO1xuXG5cdFx0XHR0cnkge1xuXHRcdFx0XHRpZiAoZnMuc3RhdFN5bmMocGtnSnNvbkZpbGUpKSB7XG5cdFx0XHRcdFx0cGFydHMucHVzaChgJHtuYW1lfS8ke0pTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKHBrZ0pzb25GaWxlKSkudmVyc2lvbiB8fCAnJ31gKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0XHQvLyBlaXRoZXIgdGhlIHBhY2thZ2UuanNvbiBkb2Vzbid0IGV4aXN0IG9yIHRoZSBKU09OIHdhcyBtYWxmb3JtZWRcblx0XHRcdFx0aWYgKGUuY29kZSAhPT0gJ0VOT0VOVCcpIHtcblx0XHRcdFx0XHQvLyBtdXN0IGJlIG1hbGZvcm1lZCBKU09OLCB3ZSBjYW4gc3RvcFxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGRpciA9IHBhdGguZGlybmFtZShkaXIpO1xuXHRcdH0gd2hpbGUgKGRpciAhPT0gcm9vdCk7XG5cdH1cblxuXHRwYXJ0cy5wdXNoKGBhcHBjZC1jbGllbnQvJHtKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi4nLCAncGFja2FnZS5qc29uJykpKS52ZXJzaW9ufWApO1xuXG5cdGlmICghcGFydHMuc29tZShwID0+IHAuaW5kZXhPZignbm9kZS8nKSA9PT0gMCkpIHtcblx0XHRwYXJ0cy5wdXNoKGBub2RlLyR7cHJvY2Vzcy52ZXJzaW9uLnJlcGxhY2UoL152LywgJycpfWApO1xuXHR9XG5cblx0aWYgKCFwYXJ0cy5zb21lKHAgPT4gcCA9PT0gcHJvY2Vzcy5wbGF0Zm9ybSkpIHtcblx0XHRwYXJ0cy5wdXNoKHByb2Nlc3MucGxhdGZvcm0pO1xuXHR9XG5cblx0Y29uc3QgYXJjaGl0ZWN0dXJlID0gYXJjaCgpO1xuXHRpZiAoIXBhcnRzLnNvbWUocCA9PiBwID09PSBhcmNoaXRlY3R1cmUpKSB7XG5cdFx0cGFydHMucHVzaChhcmNoaXRlY3R1cmUpO1xuXHR9XG5cblx0cmV0dXJuIHBhcnRzLmpvaW4oJyAnKTtcbn1cbiJdfQ== | ||
if (!parts.some(p => p.indexOf('node/') === 0)) { | ||
parts.push(`node/${process.version.replace(/^v/, '')}`); | ||
} | ||
if (!parts.some(p => p === process.platform)) { | ||
parts.push(process.platform); | ||
} | ||
const architecture = (0, _appcdUtil.arch)(); | ||
if (!parts.some(p => p === architecture)) { | ||
parts.push(architecture); | ||
} | ||
return parts.join(' '); | ||
} |
{ | ||
"name": "appcd-client", | ||
"version": "1.0.1", | ||
"version": "1.1.0-0", | ||
"description": "The Node.js client for connecting to the Appc Daemon.", | ||
@@ -25,11 +25,12 @@ "main": "./dist/client", | ||
"dependencies": { | ||
"appcd-response": "^1.0.1", | ||
"appcd-util": "^1.0.1", | ||
"appcd-logger": "^1.1.0-0", | ||
"appcd-response": "^1.1.0-0", | ||
"appcd-util": "^1.1.0-0", | ||
"msgpack-lite": "^0.1.26", | ||
"source-map-support": "^0.5.0", | ||
"uuid": "^3.1.0", | ||
"ws": "^3.3.2" | ||
"source-map-support": "^0.5.4", | ||
"uuid": "^3.2.1", | ||
"ws": "^5.1.0" | ||
}, | ||
"devDependencies": { | ||
"appcd-gulp": "^1.0.1", | ||
"appcd-gulp": "^1.1.0-0", | ||
"gulp": "^3.9.1" | ||
@@ -36,0 +37,0 @@ }, |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
265
10967
7
4
1
+ Addedappcd-logger@^1.1.0-0
+ Addedansi-styles@3.2.1(transitive)
+ Addedappcd-logger@1.1.5(transitive)
+ Addedbase64-js@1.5.1(transitive)
+ Addedbrotli@1.3.3(transitive)
+ Addedbryt@1.0.2(transitive)
+ Addedchalk@2.4.2(transitive)
+ Addedcolor-convert@1.9.3(transitive)
+ Addedcolor-name@1.1.3(transitive)
+ Addedescape-string-regexp@1.0.5(transitive)
+ Addedfigures@2.0.0(transitive)
+ Addedhas-flag@3.0.0(transitive)
+ Addedhumanize@0.0.9(transitive)
+ Addedmoment@2.30.1(transitive)
+ Addednanobuffer@1.1.7(transitive)
+ Addedpluralize@7.0.0(transitive)
+ Addedsnooplogg@1.13.2(transitive)
+ Addedsupports-color@5.5.0(transitive)
+ Addedws@5.2.4(transitive)
- Removedsafe-buffer@5.1.2(transitive)
- Removedultron@1.1.1(transitive)
- Removedws@3.3.3(transitive)
Updatedappcd-response@^1.1.0-0
Updatedappcd-util@^1.1.0-0
Updatedsource-map-support@^0.5.4
Updateduuid@^3.2.1
Updatedws@^5.1.0