Skip to content

Commit

Permalink
feat: ✨ added support to add new api config to existing file (#77)
Browse files Browse the repository at this point in the history
* feat: ✨ added support to add new api config to existing file

* fix: 🐛 fixed linting issues

* refactor: ♻️ formatted error messages

* fix: 🐛 handled config file not found error
  • Loading branch information
WasiqB authored May 13, 2024
1 parent bb5047d commit 5c74c7a
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 20 deletions.
21 changes: 17 additions & 4 deletions src/commands/configure_cmds/api.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import { CommandModule } from 'yargs';
import { epiLogMessage, failureMessage } from '../../utils/constants.js';
import { epiLogMessage, errorMessage, failureMessage, helpMessage } from '../../utils/constants.js';
import { handleAddApiConfig } from '../../handler/config/init/api.js';

export const apiCommand = {
command: 'api [name]',
aliases: ['a'],
describe: 'Add API Boyka-Framework Config file',
builder: (yargs) =>
yargs
.option('p', {
alias: ['path'],
describe: 'Path to the config file',
default: `${process.cwd()}/src/test/resources`,
type: 'string',
})
.positional('name', {
demandOption: true,
describe: 'Name of the API config block',
Expand All @@ -16,12 +23,18 @@ export const apiCommand = {
if (!argv.name) {
throw new Error('API config name should be provided!');
}
return true;
})
.help('help')
.showHelpOnFail(true, failureMessage('API Config'))
.epilog(epiLogMessage),
handler: (argv) => {
// TODO: API handler
console.log(`Handle API Config ${argv.name}...`);
handler: async (argv) => {
try {
await handleAddApiConfig(argv);
console.log(helpMessage);
} catch (error: any) {
console.error(errorMessage(error));
process.exit(1);
}
},
} satisfies CommandModule;
3 changes: 2 additions & 1 deletion src/commands/configure_cmds/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { CommandModule } from 'yargs';
import {
capabilitiesHelpMessage,
epiLogMessage,
errorMessage,
failureMessage,
getTarget,
helpMessage,
Expand Down Expand Up @@ -33,7 +34,7 @@ export const initCommand = {
}
console.log(helpMessage);
} catch (error: any) {
console.error(error.message);
console.error(errorMessage(error));
process.exit(1);
}
},
Expand Down
26 changes: 26 additions & 0 deletions src/handler/config/init/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { getConfigName } from '../../../questions/inputs.js';
import { FrameworkSetting } from '../../../types/config-type.js';
import { updateApi } from '../../update/api.js';
import { defaultApiSetting } from '../../../types/default-type-values.js';
import { ArgumentsCamelCase } from 'yargs';
import { createConfigFile, loadJSON } from '../../../utils/json.js';
import { configBlockExists } from '../../../utils/constants.js';

export const createApiSetting = async () => {
const configName = await getConfigName('API');
Expand All @@ -16,3 +19,26 @@ export const createApiSetting = async () => {
if (api) await updateApi(api[configName]);
return frameworkSetting;
};

export const handleAddApiConfig = async (argv: ArgumentsCamelCase) => {
const name = argv.name as string;
const path = argv.path as string;
const configPath = path === '.' ? process.cwd() : path;

const settings = loadJSON(configPath) as FrameworkSetting;
const apiSetting = settings.api;
if (apiSetting[name]) {
throw new Error(configBlockExists('API', name));
}
const newApiSetting = {
[name]: {
...defaultApiSetting,
},
};
await updateApi(newApiSetting[name]);
settings.api = {
...apiSetting,
...newApiSetting,
};
createConfigFile(configPath, settings, 'updated');
};
2 changes: 1 addition & 1 deletion src/handler/config/init/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,6 @@ const createConfigJson = async (configPath: string) => {
setting = await createApiSetting();
break;
}
createConfigFile(path, setting);
createConfigFile(path, setting, 'created');
return true;
};
32 changes: 24 additions & 8 deletions src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const configFileName = 'boyka-config.json';

export const failureMessage = (command: string = ''): string => {
const targetCommand = command.length === 0 ? '' : ` in ${command}`;
return danger(`Something went wrong${targetCommand}! Run the command with '--help' option`);
return danger(`Something went wrong${targetCommand}! Run the command with '--help' option`);
};

let targetProviders: TargetProviders;
Expand All @@ -31,23 +31,27 @@ export const helpMessage = info(`
Check out the Boyka config documentation 👉
[https://boykaframework.github.io/boyka-framework/docs/guides/configuration]
🗒️ You can update the generated config file to include more settings 🛠️ as per your requirement.
🗒️ You can update the generated config file to include more settings 🛠️ as per your requirement.
`);

export const capabilitiesHelpMessage = warn(`
❗❗ Since you have selected Cloud platform to run your tests,
⚠️ Since you have selected Cloud platform to run your tests,
you must also add cloud specific capabilities to the empty \`capabilities\` block
added to the config file.`);

export const successMessage = (filePath: string) =>
success(`Boyka config file created at [${filePath}]`);
export const successMessage = (filePath: string, state: string) =>
success(`Boyka config file ${state} at [${filePath}]`);

export const errorMessage = (error: Error) =>
danger(`Error occurred! ${error.message}
Caused by: ${error.cause}
danger(`
❌ Error occurred!
${error.message}
`);

export const savingMessage = warn('Creating the [boyka-config.json] file...');
export const savingMessage = (state: string) => {
const savingState = state === 'created' ? 'Creating' : 'Updating';
return warn(`${savingState} the [boyka-config.json] file...`);
};

export const initMessage = (path: string) => warn(`Creating Boyka config file at ${path}...`);

Expand All @@ -59,3 +63,15 @@ export const configPathNotFolder = (path: string) =>

export const configFileExists = (path: string) =>
danger(`Boyka config file is already available at [${path}]...`);

export const configBlockExists = (platform: string, configName: string) =>
danger(`
${platform} Config already exists in the Boyka config file with the name: ${configName}...`);

export const configFileNotExists = (path: string) =>
danger(
`
Boyka config file does not exist at [${path}].
Create one by running command 'boyka config init'`,
);
23 changes: 17 additions & 6 deletions src/utils/json.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,38 @@
import fs from 'fs';
import path from 'path';
import { FrameworkSetting } from '../types/config-type.js';
import { configFileName, errorMessage, savingMessage, sleep, successMessage } from './constants.js';
import {
configFileName,
configFileNotExists,
errorMessage,
savingMessage,
sleep,
successMessage,
} from './constants.js';
import { createSpinner } from 'nanospinner';

export const createConfigFile = (filePath: string, setting: FrameworkSetting) => {
export const createConfigFile = (filePath: string, setting: FrameworkSetting, state: string) => {
const content = JSON.stringify(setting, null, 2);
fs.writeFile(path.join(filePath, configFileName), content, async (err) => {
const spinner = createSpinner(savingMessage).start();
const spinner = createSpinner(savingMessage(state)).start();
await sleep();

if (err) {
spinner.error({ text: errorMessage(err) });
process.exit(1);
} else {
spinner.success({ text: successMessage(filePath) });
spinner.success({ text: successMessage(filePath, state) });
}
});
};

export const loadJSON = (path: string) => {
export const loadJSON = (filePath: string) => {
const configPath = path.join(filePath, configFileName);
if (!fs.existsSync(configPath)) {
throw new Error(configFileNotExists(configPath));
}
return JSON.parse(
fs.readFileSync(new URL(path), {
fs.readFileSync(path.join(filePath, configFileName), {
encoding: 'utf-8',
}),
);
Expand Down

0 comments on commit 5c74c7a

Please sign in to comment.