UNPKG

@webos-tools/cli

Version:

Command Line Interface for development webOS application and service

179 lines (158 loc) 6.99 kB
/* * Copyright (c) 2020-2024 LG Electronics Inc. * * SPDX-License-Identifier: Apache-2.0 */ const npmlog = require('npmlog'), errHndl = require('./error-handler'), Eof = require('../util/eof'); (function() { const log = npmlog; log.heading = 'luna'; log.level = 'http'; const luna = { /** * send a command on a luna bus * @property options {novacom.Session} session * @param {Object} options * @param {Object} addr * @property addr {String} service luna service name * @property addr {String} [folder] containing folder of the requested method * @property addr {String} method the luna method to invoke * @param {Object} param the unique luna parameter * @param {Function} onResponse the callback invoked at each JSON object received from luna-send * @property onResponse {Object} obj the JSON object received * @property onResponse {Function} next a common-js callback * @param next {Function} next a common-js callback */ send: function(options, addr, param, onResponse, next) { const session = options && options.session; // 'is' is used to transmit an EOF to // terminate the remote luna-send. this is // the only way to terminate an interactive // request 'luna-send -i'... const is = new Eof(), url = ['luna:/', addr.service, addr.folder, addr.method].join('/'); let result, mode, sessionCall = ""; is.pause(); if (options && options.nReplies) { mode = "-n " + options.nReplies + " "; } else { mode = "-i "; } if (options && options.sessionCall && options.sessionId) { sessionCall = "-c " + options.sessionId + " "; } log.verbose("luna#send()", "calling:", mode + sessionCall + url + " '" + JSON.stringify(param) + "'"); session.run(session.getDevice().lunaSend + " " + mode + sessionCall + url + " '" + JSON.stringify(param) + "'", is /* stdin*/, _onData, process.stderr, function(err) { if (err) { next(err); } // success when the output of the // command is correctly interpreted, // not simply when the command exit // with a success exit code. }); let jsonLine = ""; // Break string into lines (JSON.parse needs a // single object per call). function _onData(data) { let str; if (Buffer.isBuffer(data)) { str = data.toString(); } else { str = data; } str.split(/\r?\n/).forEach(_onLine); } function _onLine(line) { jsonLine += line; try { result = JSON.parse(jsonLine); log.verbose('luna#send()', 'response:', result); jsonLine = ""; if (result.returnValue === false) { is.destroy(); const errValue = (result.errorText ? result.errorText : (result.errorMessage ? result.errorMessage : '')); next(errHndl.getErrMsg("FAILED_CALL_LUNA", errValue, null, addr.service)); } else { onResponse(result, function(err, value) { log.silly('luna#send()', "err:", err, ", value:", value); if (err || value) { log.silly('luna#send()', "closing exec stream"); // processing completed or failed next(err, value); } }); } } catch(e) { // ignore the parsing error: // the line may be incomplete // & not yet JSON-parseable } } }, sendWithoutErrorHandle: function(options, addr, param, onResponse, next) { const session = options && options.session; // 'is' is used to transmit an EOF to // terminate the remote luna-send. this is // the only way to terminate an interactive // request 'luna-send -i'... const is = new Eof(), url = ['luna:/', addr.service, addr.folder, addr.method].join('/'); let result, mode; is.pause(); if (options && options.nReplies) { mode = "-n " + options.nReplies + " "; } else { mode = "-i "; } log.verbose("luna#sendWithoutErrorHandle()", "calling:", url + " '" + JSON.stringify(param) + "'"); session.run(session.getDevice().lunaSend + " " + mode + url + " '" + JSON.stringify(param) + "'", is /* stdin*/, _onData, process.stderr, function(err) { if (err) { next(err); } // success when the output of the // command is correctly interpreted, // not simply when the command exit // with a success exit code. }); let jsonLine = ""; // Break string into lines (JSON.parse needs a // single object per call). function _onData(data) { let str; if (Buffer.isBuffer(data)) { str = data.toString(); } else { str = data; } str.split(/\r?\n/).forEach(_onLine); } function _onLine(line) { jsonLine += line; try { result = JSON.parse(jsonLine); log.verbose('luna#sendWithoutErrorHandle()', 'response:', result); jsonLine = ""; onResponse(result, function(err, value) { log.silly('luna#sendWithoutErrorHandle()', "err:", err, ", value:", value); if (err || value) { log.silly('luna#sendWithoutErrorHandle()', "closing exec stream"); // processing completed or failed next(err, value); } }); } catch(e) { // ignore the parsing error: // the line may be incomplete // & not yet JSON-parseable } } } }; if (typeof module !== 'undefined' && module.exports) { module.exports = luna; } }());