diff --git a/CHANGELOG.md b/CHANGELOG.md index 697d4fe..081fa9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ The format is based on and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.8] - 2020-02-11 + +### Changed + - The .env and alias config files stored in home dir (```.tdxcli```). + +### Fixed + + ## [0.2.7] - 2020-02-07 ### Changed diff --git a/README.md b/README.md index 6574816..923752e 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@

-Nquiringminds TDX API client application +Command-line interface for accessing the TDX API ## Install The best use of tdxcli tool is to install it with npm globally as follows: diff --git a/config.app.json b/config.app.json new file mode 100644 index 0000000..15cbb42 --- /dev/null +++ b/config.app.json @@ -0,0 +1,3 @@ +{ + "scraperTimeout": 5000 +} \ No newline at end of file diff --git a/config.default.json b/config.default.json new file mode 100644 index 0000000..bafd104 --- /dev/null +++ b/config.default.json @@ -0,0 +1,22 @@ +{ + "nqminds": { + "tokenHref": "https://tbx.nqminds.com", + "config": { + "commandServer": "https://cmd.nqminds.com", + "ddpServer": "https://ddp.nqminds.com", + "queryServer": "https://q.nqminds.com", + "tdxServer": "https://tdx.nqminds.com", + "accessTokenTTL": 31622400 + } + }, + "nq_m": { + "tokenHref": "https://tbx.nq-m.com", + "config": { + "commandServer": "https://cmd.nq-m.com", + "ddpServer": "https://ddp.nq-m.com", + "queryServer": "https://q.nq-m.com", + "tdxServer": "https://tdx.nq-m.com", + "accessTokenTTL": 31622400 + } + } +} diff --git a/config.json b/config.json deleted file mode 100644 index 17a2f8f..0000000 --- a/config.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "scraperTimeout": 5000, - "tdxConfigs": { - "nqminds": { - "tokenHref": "https://tbx.nqminds.com", - "config": { - "commandServer": "https://cmd.nqminds.com", - "ddpServer": "https://ddp.nqminds.com", - "queryServer": "https://q.nqminds.com", - "tdxServer": "https://tdx.nqminds.com", - "accessTokenTTL": 31622400 - } - }, - "nq_m": { - "tokenHref": "https://tbx.nq-m.com", - "config": { - "commandServer": "https://cmd.nq-m.com", - "ddpServer": "https://ddp.nq-m.com", - "queryServer": "https://q.nq-m.com", - "tdxServer": "https://tdx.nq-m.com", - "accessTokenTTL": 31622400 - } - }, - "nqm1": { - "tokenHref": "https://tbx.nqminds.com", - "config": { - "commandServer": "https://cmd.nqminds.com", - "ddpServer": "https://ddp.nqminds.com", - "queryServer": "https://q.nqminds.com", - "tdxServer": "https://tdx.nqminds.com", - "accessTokenTTL": 31622400 - } - } - } -} \ No newline at end of file diff --git a/main.js b/main.js index ed95214..9c1d5f0 100644 --- a/main.js +++ b/main.js @@ -1,8 +1,10 @@ /* eslint-disable no-console */ "use strict"; +const os = require("os"); const path = require("path"); -const appConfig = require("./config.json"); +const appConfig = require("./config.app.json"); +const defaultConfig = require("./config.default.json"); const {TDX_CURRENT_ALIAS, TDX_CREDENTIALS} = require("./src/constants"); const { checkValidAlias, @@ -18,6 +20,7 @@ const { readJsonFromFile, numberToString, createFile, + mkdir, } = require("./src/utils"); const { copyAliasConfig, @@ -26,8 +29,10 @@ const { } = require("./src/alias"); const CommandHandler = require("./src"); -const envPath = path.join(__dirname, ".env"); -const configPath = path.join(__dirname, "config.json"); +const homePath = os.homedir(); +const tdxcliConfigPath = path.join(homePath, ".tdxcli"); +const envPath = path.join(tdxcliConfigPath, ".env"); +const configPath = path.join(tdxcliConfigPath, "config.json"); require("dotenv").config({path: envPath}); @@ -56,12 +61,14 @@ async function run(commandName, commandProps) { let alias = commandProps.alias; let credentials = commandProps.credentials; const { - id, secret, type, command, filepath, + id, secret, type, command, filepath, aliasName, configJson, apiArgs, apiArgsStringify, } = commandProps; try { + await mkdir(tdxcliConfigPath); await createFile(envPath); + await createFile(configPath, JSON.stringify(defaultConfig, null, 2)); if (alias === "") alias = envToAlias(process.env[TDX_CURRENT_ALIAS] || ""); if (credentials === "") credentials = process.env[TDX_CREDENTIALS] || ""; @@ -70,9 +77,9 @@ async function run(commandName, commandProps) { throw Error("No alias or wrong alias name. Only allowed [a-zA-Z0-9_]"); } + const tdxConfigs = await readJsonFromFile(configPath); const argumentSecret = {id, secret}; - const tdxConfig = appConfig.tdxConfigs[alias] || {}; - const configArgs = {tdxConfig, timeout: appConfig.scraperTimeout}; + const configArgs = {tdxConfig: tdxConfigs[alias] || {}, timeout: appConfig.scraperTimeout}; let commandHandler; if (commandName !== "signin" && credentials) { @@ -109,13 +116,13 @@ async function run(commandName, commandProps) { output = await commandHandler.getInfo({id, type}); break; case "config": - output = tdxConfig; + output = tdxConfigs[alias] || {}; break; case "list": output = await commandHandler.getList({ type, alias, - tdxConfigs: appConfig.tdxConfigs, + tdxConfigs, env: process.env, }); break; @@ -130,17 +137,17 @@ async function run(commandName, commandProps) { output = await commandHandler.upload(id, filepath); break; case "copyalias": - await copyAliasConfig({appConfig, alias, copyAliasName: aliasName, configPath}); + await copyAliasConfig({tdxConfigs, alias, copyAliasName: aliasName, configPath}); output = "OK"; break; case "modifyalias": const aliasConfig = await readJsonFromFile(configJson); - await modifyAliasConfig({appConfig, aliasName, aliasConfig, configPath}); + await modifyAliasConfig({tdxConfigs, aliasName, aliasConfig, configPath}); output = "OK"; break; case "removealias": if (alias === aliasName) throw Error("Can't remove the running alias."); - await removeAliasConfig({appConfig, aliasName, configPath}); + await removeAliasConfig({tdxConfigs, aliasName, configPath}); output = "OK"; break; case "databot": diff --git a/package.json b/package.json index 1ca2acd..70a81bb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@nqminds/nqm-tdx-terminal-cli", - "version": "0.2.7", + "version": "0.2.8", "description": "Command-line interface for accessing the TDX API", "main": "main.js", "directories": { diff --git a/src/alias.js b/src/alias.js index 5a31409..8c6a99d 100644 --- a/src/alias.js +++ b/src/alias.js @@ -7,8 +7,8 @@ function getAliasesArray(configs) { return Object.keys(configs); } -async function copyAliasConfig({appConfig, alias, copyAliasName, configPath}) { - const aliases = getAliasesArray(appConfig.tdxConfigs); +async function copyAliasConfig({tdxConfigs, alias, copyAliasName, configPath}) { + const aliases = getAliasesArray(tdxConfigs); if (!checkValidAlias(copyAliasName)) { throw Error("Invalid alias name."); @@ -18,26 +18,26 @@ async function copyAliasConfig({appConfig, alias, copyAliasName, configPath}) { throw Error("Alias already exists."); } else { return modifyAliasConfig({ - appConfig, + tdxConfigs, aliasName: copyAliasName, - aliasConfig: appConfig.tdxConfigs[alias], + aliasConfig: tdxConfigs[alias], configPath, }); } } -async function modifyAliasConfig({appConfig, aliasName, aliasConfig, configPath}) { - appConfig.tdxConfigs[aliasName] = aliasConfig; - return writeJsonToFile(appConfig, configPath); +async function modifyAliasConfig({tdxConfigs, aliasName, aliasConfig, configPath}) { + tdxConfigs[aliasName] = aliasConfig; + return writeJsonToFile(tdxConfigs, configPath); } -async function removeAliasConfig({appConfig, aliasName, configPath}) { - if (!(aliasName in appConfig.tdxConfigs)) { +async function removeAliasConfig({tdxConfigs, aliasName, configPath}) { + if (!(aliasName in tdxConfigs)) { throw Error("Alias configuration doesn't exist."); } - delete appConfig.tdxConfigs[aliasName]; - return writeJsonToFile(appConfig, configPath); + delete tdxConfigs[aliasName]; + return writeJsonToFile(tdxConfigs, configPath); } module.exports = { diff --git a/src/utils.js b/src/utils.js index 3b2fd45..a95ca87 100644 --- a/src/utils.js +++ b/src/utils.js @@ -5,6 +5,7 @@ const util = require("util"); const {TDX_TOKEN, TDX_SECRET} = require("./constants"); const writeFile = util.promisify(fs.writeFile); const readFile = util.promisify(fs.readFile); +const mkdirAsync = util.promisify(fs.mkdir); function validateEmail(email) { // eslint-disable-next-line max-len @@ -140,11 +141,11 @@ function numberToString(value) { else return value; } -function createFile(filepath) { +function createFile(filepath, content = "") { return new Promise((resolve, reject) => { fs.open(filepath, "r", (err) => { if (err) { - fs.writeFile(filepath, "", (err) => { + fs.writeFile(filepath, content, (err) => { if (err) reject(err); else resolve(); }); @@ -153,6 +154,16 @@ function createFile(filepath) { }); } +async function mkdir(path) { + try { + await mkdirAsync(path); + } catch (error) { + if (error.code !== "EEXIST") { + throw error; + } + } +} + module.exports = { base64ToJson, jsonToBase64, @@ -174,4 +185,5 @@ module.exports = { readJsonFromFile, numberToString, createFile, + mkdir, }; diff --git a/tests/upload.test.js b/tests/upload.test.js index fb902ae..7b52795 100644 --- a/tests/upload.test.js +++ b/tests/upload.test.js @@ -38,7 +38,7 @@ test("pipeStream should return error on resourceStream error", async() => { const response = upload.pipeStream(mockWriteable, mockReadable); mockReadable.emit("error", error); - expect(response).rejects.toEqual(error); + await expect(response).rejects.toEqual(error); }); test("pipeStream should return \"OK\" on end event", async() => { @@ -47,7 +47,7 @@ test("pipeStream should return \"OK\" on end event", async() => { const response = upload.pipeStream(mockWriteable, mockReadable); mockReadable.emit("end"); - expect(response).resolves.toEqual("OK"); + await expect(response).resolves; }); test("pipeStream should return error on erronous data", async() => { @@ -61,5 +61,5 @@ test("pipeStream should return error on erronous data", async() => { const response = upload.pipeStream(mockWriteable, mockReadable); mockWriteable.emit("data", buf); mockReadable.emit("end"); - expect(response).rejects.toEqual(Error(data.message)); + await expect(response).rejects.toEqual(Error(data.message)); });