-
Notifications
You must be signed in to change notification settings - Fork 461
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(cli): support init and load config file
- Loading branch information
Showing
8 changed files
with
423 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { join } from 'path' | ||
import { homedir } from 'os' | ||
|
||
// Path to user's home directory | ||
const USER_HOME_DIR = homedir() | ||
|
||
// Path to the config file | ||
const CONFIG_FILE_PATH = join(USER_HOME_DIR, '.mqttx-cli', 'config') | ||
|
||
// Default configuration | ||
const DEFAULT_CONFIG: ConfigModel = { | ||
output: 'text', | ||
mqtt: { | ||
host: 'localhost', | ||
port: 1883, | ||
username: '', | ||
password: '', | ||
}, | ||
} | ||
|
||
const VALID_OUTPUT_MODES: Array<ConfigModel['output']> = ['text', 'json', 'log'] | ||
|
||
export { USER_HOME_DIR, CONFIG_FILE_PATH, DEFAULT_CONFIG, VALID_OUTPUT_MODES } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './load' | ||
export * from './init' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { writeFileSync, mkdirSync } from 'fs' | ||
import { join } from 'path' | ||
import { select, input, password } from '@inquirer/prompts' | ||
import { CONFIG_FILE_PATH, DEFAULT_CONFIG, USER_HOME_DIR } from './common' | ||
|
||
/** | ||
* Generates the content of a configuration INI file based on the provided config object. | ||
* @param config - The configuration object containing the necessary properties. | ||
* @returns The generated configuration file content as a string. | ||
*/ | ||
const generateConfigContent = (config: ConfigModel): string => { | ||
return `[default] | ||
output = ${config.output} | ||
[mqtt] | ||
host = ${config.mqtt.host} | ||
port = ${config.mqtt.port} | ||
username = ${config.mqtt.username} | ||
password = ${config.mqtt.password}` | ||
} | ||
|
||
/** | ||
* Initializes the configuration for MQTTX CLI. | ||
* Creates or updates the configuration file with the provided values. | ||
*/ | ||
async function initConfig(): Promise<void> { | ||
const output = (await select({ | ||
message: 'Select MQTTX CLI output mode', | ||
choices: [ | ||
{ name: 'Text', value: 'text', description: 'Plain text output' }, | ||
{ name: 'JSON', value: 'json', description: 'JSON formatted output' }, | ||
{ name: 'Log', value: 'log', description: 'Log file output' }, | ||
], | ||
default: DEFAULT_CONFIG.output, | ||
})) as ConfigModel['output'] | ||
|
||
const host = await input({ | ||
message: 'Enter the default MQTT broker host', | ||
default: DEFAULT_CONFIG.mqtt.host, | ||
}) | ||
|
||
const port = await input({ | ||
message: 'Enter the default MQTT port', | ||
default: DEFAULT_CONFIG.mqtt.port.toString(), | ||
validate: (input) => !isNaN(parseInt(input, 10)) || 'Port must be a number', | ||
}) | ||
|
||
const username = await input({ | ||
message: 'Enter the default username for MQTT connection authentication', | ||
default: DEFAULT_CONFIG.mqtt.username, | ||
}) | ||
|
||
const passwordAnswer = await password({ | ||
message: 'Enter the default password for MQTT connection authentication', | ||
mask: true, | ||
}) | ||
|
||
const newConfig: ConfigModel = { | ||
output, | ||
mqtt: { | ||
host, | ||
port: parseInt(port, 10), | ||
username, | ||
password: passwordAnswer, | ||
}, | ||
} | ||
|
||
try { | ||
mkdirSync(join(USER_HOME_DIR, '.mqttx-cli'), { recursive: true }) | ||
writeFileSync(CONFIG_FILE_PATH, generateConfigContent(newConfig)) | ||
console.log(`Configuration file created/updated at ${CONFIG_FILE_PATH}`) | ||
} catch (error) { | ||
console.error( | ||
`Unable to create configuration file at ${CONFIG_FILE_PATH}. Please check your permissions and try again.`, | ||
) | ||
} | ||
} | ||
|
||
export { initConfig } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { readFileSync, existsSync } from 'fs' | ||
import ini from 'ini' | ||
import { CONFIG_FILE_PATH, DEFAULT_CONFIG, VALID_OUTPUT_MODES } from './common' | ||
|
||
/** | ||
* Parses the content of a config file and returns a ConfigModel object. | ||
* @param content - The content of the config file. | ||
* @returns The parsed ConfigModel object. | ||
* @throws Error if the output mode is invalid. | ||
*/ | ||
const parseConfigFile = (content: string): ConfigModel => { | ||
const config = ini.parse(content) | ||
const output = config.default?.output | ||
if (output && !VALID_OUTPUT_MODES.includes(output)) { | ||
throw new Error(`Invalid output mode: ${output}. Valid modes are: ${VALID_OUTPUT_MODES.join(', ')}`) | ||
} | ||
|
||
return { | ||
output: config.default?.output || DEFAULT_CONFIG.output, | ||
mqtt: { | ||
host: config.mqtt?.host || DEFAULT_CONFIG.mqtt.host, | ||
port: parseInt(config.mqtt?.port, 10) || DEFAULT_CONFIG.mqtt.port, | ||
username: config.mqtt?.username || DEFAULT_CONFIG.mqtt.username, | ||
password: config.mqtt?.password || DEFAULT_CONFIG.mqtt.password, | ||
}, | ||
} | ||
} | ||
|
||
/** | ||
* Loads the configuration from a file. | ||
* If the file exists, it reads the content, parses it, and returns the configuration. | ||
* If the file doesn't exist or there is an error parsing the content, it returns the default configuration. | ||
* | ||
* @returns The loaded configuration. | ||
*/ | ||
const loadConfig = (): ConfigModel => { | ||
if (existsSync(CONFIG_FILE_PATH)) { | ||
const configFileContent = readFileSync(CONFIG_FILE_PATH, 'utf-8') | ||
try { | ||
return parseConfigFile(configFileContent) | ||
} catch (error) { | ||
console.error((error as Error).message) | ||
console.error('Invalid configuration file. Using default configuration.') | ||
} | ||
} | ||
return DEFAULT_CONFIG | ||
} | ||
|
||
export { loadConfig } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.