diff --git a/index.js b/index.js index ccea032..c962036 100755 --- a/index.js +++ b/index.js @@ -4,6 +4,7 @@ import { QWebChannel } from 'qwebchannel' import WebSocket from 'ws' import cli from './utils/cli.js' +import style from './utils/style.js' import { sceneHelp, sceneList, sceneSwitch, sceneCurrent } from './utils/scene.js' import { audioHelp, audioList, audioMute, audioUnmute, audioToggle, audioStatus } from './utils/audio.js' import { streamHelp, streamStart, streamStop, streamToggle, streamStatus } from './utils/stream.js' @@ -29,6 +30,14 @@ function printHelp (helpText) { process.exit(0) } +/** * Print an error message and exit the process. + * @param {string} message - The error message to print. + */ +function printError (message) { + console.error(style.err(message)) + process.exit(1) +} + /** * Helper to wrap QWebChannel usage and handle promise-based command execution. * @param {WebSocket} socket - The websocket instance. @@ -41,16 +50,14 @@ function withChannel (socket, fn) { .then((result) => { if (typeof result === 'object' && result !== null && typeof result.toString === 'function') { console.log(result.toString()) - } else { - if (result !== undefined) { - console.log(result) - } + } else if (result !== undefined) { + console.log(result) } socket.close() process.exit(0) }) .catch((err) => { - console.error(`${err}`) + console.error(style.err(err)) socket.close() process.exit(1) }) @@ -83,8 +90,7 @@ socket.onopen = function () { break case 'switch': if (!sceneArguments[0]) { - console.error('Error: Scene name is required for the switch command.') - process.exit(1) + printError('Error: Scene name is required for the switch command.') } withChannel(socket, (channel) => sceneSwitch(channel, sceneArguments[0])) break @@ -102,29 +108,25 @@ socket.onopen = function () { break case 'mute': if (!audioArguments[0]) { - console.error('Error: Audio name is required for the mute command.') - process.exit(1) + printError('Error: Audio name is required for the mute command.') } withChannel(socket, (channel) => audioMute(channel, audioArguments[0])) break case 'unmute': if (!audioArguments[0]) { - console.error('Error: Audio name is required for the unmute command.') - process.exit(1) + printError('Error: Audio name is required for the unmute command.') } withChannel(socket, (channel) => audioUnmute(channel, audioArguments[0])) break case 'toggle': if (!audioArguments[0]) { - console.error('Error: Audio name is required for the toggle command.') - process.exit(1) + printError('Error: Audio name is required for the toggle command.') } withChannel(socket, (channel) => audioToggle(channel, audioArguments[0])) break case 'status': if (!audioArguments[0]) { - console.error('Error: Audio name is required for the status command.') - process.exit(1) + printError('Error: Audio name is required for the status command.') } withChannel(socket, (channel) => audioStatus(channel, audioArguments[0])) break diff --git a/utils/audio.js b/utils/audio.js index b900ff0..bc9b428 100644 --- a/utils/audio.js +++ b/utils/audio.js @@ -1,7 +1,7 @@ import meowHelp from 'cli-meow-help' import Table from 'cli-table3' -import { highlight, error } from './style.js' +import style from './style.js' const commands = { list: { @@ -58,9 +58,9 @@ function audioList (channel, showId) { for (const [key, value] of Object.entries(meld.session.items)) { if (value.type === 'track') { if (showId) { - table.push([highlight(value.name), { content: value.muted ? highlight('✓') : '✗', hAlign: 'center' }, highlight(key)]) + table.push([style.highlight(value.name), { content: value.muted ? style.highlight('✓') : '✗', hAlign: 'center' }, style.highlight(key)]) } else { - table.push([highlight(value.name), { content: value.muted ? highlight('✓') : '✗', hAlign: 'center' }]) + table.push([style.highlight(value.name), { content: value.muted ? style.highlight('✓') : '✗', hAlign: 'center' }]) } } } @@ -73,7 +73,7 @@ function audioList (channel, showId) { function audioMute (channel, audioName) { if (!channel.objects || !channel.objects.meld) { - return Promise.reject(new Error(error('Meld object not found in channel.'))) + return Promise.reject(new Error('Meld object not found in channel.')) } const meld = channel.objects.meld let itemId @@ -87,19 +87,19 @@ function audioMute (channel, audioName) { } if (!itemId) { - return Promise.reject(new Error(`No audio device with name ${audioName} found.`)) + return Promise.reject(new Error(`No audio device with name ${style.errHighlight(audioName)} found.`)) } if (isMuted) { - return Promise.resolve(`Audio track ${highlight(audioName)} is already muted.`) + return Promise.reject(new Error(`Audio track ${style.errHighlight(audioName)} is already muted.`)) } return new Promise((resolve, reject) => { meld.toggleMute(itemId) .then(() => { - resolve(`Audio track ${highlight(audioName)} has been muted.`) + resolve(`Audio track ${style.highlight(audioName)} has been muted.`) }) .catch((err) => { - reject(new Error(`Error muting audio track: ${err}`)) + reject(new Error(`Error muting audio track: ${err.message}`)) }) }) } @@ -122,16 +122,16 @@ function audioUnmute (channel, audioName) { return Promise.reject(new Error('No audio track found.')) } if (!isMuted) { - return Promise.resolve(`Audio track ${audioName} is already unmuted.`) + return Promise.reject(new Error(`Audio track ${style.errHighlight(audioName)} is already unmuted.`)) } return new Promise((resolve, reject) => { meld.toggleMute(itemId) .then(() => { - resolve(`Audio track ${audioName} has been unmuted.`) + resolve(`Audio track ${style.highlight(audioName)} has been unmuted.`) }) .catch((err) => { - reject(new Error(`Error unmuting audio track: ${err}`)) + reject(new Error(`Error unmuting audio track: ${err.message}`)) }) }) } @@ -151,16 +151,17 @@ function audioToggle (channel, audioName) { } } if (!itemId) { - return Promise.reject(new Error(`No audio device with name ${audioName} found.`)) + return Promise.reject(new Error(`No audio device with name ${style.errHighlight(audioName)} found.`)) } + return new Promise((resolve, reject) => { meld.toggleMute(itemId) .then(() => { const status = isMuted ? 'unmuted' : 'muted' - resolve(`Audio track ${audioName} has been ${status}.`) + resolve(`Audio track ${style.highlight(audioName)} has been ${status}.`) }) .catch((err) => { - reject(new Error(`Error toggling audio track: ${err}`)) + reject(new Error(`Error toggling audio track: ${err.message}`)) }) }) } @@ -180,10 +181,11 @@ function audioStatus (channel, audioName) { } } if (!itemId) { - return Promise.reject(new Error(`No audio device with name ${audioName} found.`)) + return Promise.reject(new Error(`No audio device with name ${style.errHighlight(audioName)} found.`)) } + return new Promise((resolve, reject) => { - resolve(`${highlight(audioName)} is ${isMuted ? 'muted' : 'unmuted'}`) + resolve(`${style.highlight(audioName)} is ${isMuted ? 'muted' : 'unmuted'}`) }) } diff --git a/utils/record.js b/utils/record.js index 5e5e938..bd8e5ca 100644 --- a/utils/record.js +++ b/utils/record.js @@ -47,7 +47,7 @@ function recordStart (channel) { resolve('Recording started successfully.') }) .catch((err) => { - reject(err) + reject(new Error(`Failed to start recording: ${err.message}`)) }) }) } @@ -68,7 +68,7 @@ function recordStop (channel) { resolve('Recording stopped successfully.') }) .catch((err) => { - reject(err) + reject(new Error(`Failed to stop recording: ${err.message}`)) }) }) } @@ -85,7 +85,7 @@ function recordToggle (channel) { resolve(`Recording ${meld.isRecording ? 'stopped' : 'started'} successfully.`) }) .catch((err) => { - reject(err) + reject(new Error(`Failed to toggle recording: ${err.message}`)) }) }) } diff --git a/utils/scene.js b/utils/scene.js index ef56d40..f6e8022 100644 --- a/utils/scene.js +++ b/utils/scene.js @@ -1,7 +1,7 @@ import meowHelp from 'cli-meow-help' import Table from 'cli-table3' -import { highlight, error, errorHighlight } from './style.js' +import style from './style.js' const commands = { list: { @@ -56,14 +56,15 @@ function sceneList (channel, showId) { for (const [key, value] of Object.entries(meld.session.items)) { if (value.type === 'scene') { if (showId) { - table.push([highlight(value.name), { content: value.current ? highlight('✓') : '✗', hAlign: 'center' }, highlight(key)]) + table.push([style.highlight(value.name), { content: value.current ? style.highlight('✓') : '✗', hAlign: 'center' }, style.highlight(key)]) } else { - table.push([highlight(value.name), { content: value.current ? highlight('✓') : '✗', hAlign: 'center' }]) + table.push([style.highlight(value.name), { content: value.current ? style.highlight('✓') : '✗', hAlign: 'center' }]) } } } + if (table.length === 0) { - return Promise.reject(new Error('No scenes found.')) + return Promise.resolve('No scenes found.') } return Promise.resolve(table) } @@ -82,12 +83,12 @@ function sceneSwitch (channel, sceneName) { } } if (!itemId) { - return Promise.reject(new Error(error(`No scene with name ${errorHighlight(sceneName)} found.`))) + return Promise.reject(new Error(`No scene with name ${style.errHighlight(sceneName)} found.`)) } return new Promise((resolve, reject) => { meld.showScene(itemId).then(() => { - resolve(`Switched to scene: ${highlight(sceneName)}`) + resolve(`Switched to scene: ${style.highlight(sceneName)}`) }).catch(err => { reject(err) }) @@ -103,9 +104,9 @@ function sceneCurrent (channel, showId) { for (const [key, value] of Object.entries(meld.session.items)) { if (value.type === 'scene' && value.current) { if (showId) { - return Promise.resolve(`Current scene: ${highlight(value.name)} (ID: ${highlight(key)})`) + return Promise.resolve(`Current scene: ${style.highlight(value.name)} (ID: ${style.highlight(key)})`) } - return Promise.resolve(`Current scene: ${highlight(value.name)}`) + return Promise.resolve(`Current scene: ${style.highlight(value.name)}`) } } return Promise.reject(new Error('No current scene found.')) diff --git a/utils/stream.js b/utils/stream.js index 15ae549..1a5e4da 100644 --- a/utils/stream.js +++ b/utils/stream.js @@ -47,7 +47,7 @@ function streamStart (channel) { resolve('Streaming started successfully.') }) .catch((err) => { - reject(err) + reject(new Error(`Failed to start streaming: ${err.message}`)) }) }) } @@ -68,7 +68,7 @@ function streamStop (channel) { resolve('Streaming stopped successfully.') }) .catch((err) => { - reject(err) + reject(new Error(`Failed to stop streaming: ${err.message}`)) }) }) } @@ -85,7 +85,7 @@ function streamToggle (channel) { resolve(`Streaming ${meld.isStreaming ? 'stopped' : 'started'} successfully.`) }) .catch((err) => { - reject(err) + reject(new Error(`Failed to toggle streaming: ${err.message}`)) }) }) } diff --git a/utils/style.js b/utils/style.js index 304218a..779ea72 100644 --- a/utils/style.js +++ b/utils/style.js @@ -1,11 +1,9 @@ import clc from 'cli-color' -const highlight = clc.cyan -const error = clc.red.bold -const errorHighlight = clc.yellow.bold - -export { - highlight, - error, - errorHighlight +const style = { + highlight: clc.cyan, + err: clc.red.bold, + errHighlight: clc.yellow.bold } + +export default style