Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve integer parsing in commands #157

Merged
merged 1 commit into from
Aug 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions src/command-handlers/teamMembers.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import { getTeamMembers as getTeamMembersRequest } from '../endpoints';
import { getTeamDeviceCredentials, flattenJsonArrayOfObject, jsonToCsv, epochTimestampToIso } from '../utils';

interface GetTeamMembersParams {
page: number;
limit: number;
interface GetTeamMembersOpts {
csv: boolean;
humanReadable: boolean;
}

export const runTeamMembers = async (params: GetTeamMembersParams) => {
const { page, limit } = params;
export const runTeamMembers = async (page: number, limit: number, options: GetTeamMembersOpts) => {
const teamDeviceCredentials = getTeamDeviceCredentials();

const response = await getTeamMembersRequest({
Expand All @@ -18,7 +15,7 @@ export const runTeamMembers = async (params: GetTeamMembersParams) => {
limit,
});

if (params.humanReadable) {
if (options.humanReadable) {
response.members = response.members.map((member) => {
const memberWithHumanReadableDates = {
...member,
Expand All @@ -37,7 +34,7 @@ export const runTeamMembers = async (params: GetTeamMembersParams) => {
});
}

if (params.csv) {
if (options.csv) {
if (response.pages) {
console.log(`Page ${response.page + 1} of ${response.pages}`);
}
Expand Down
13 changes: 8 additions & 5 deletions src/commands/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Command } from 'commander';
import { Command, Option } from 'commander';
import { devicesCommands } from './devices';
import { teamCommands } from './team';
import { configureCommands } from './configure';
Expand All @@ -24,10 +24,13 @@ export const rootCommands = (params: { program: Command }) => {
.command('password')
.alias('p')
.description('Retrieve a password from the local vault and copy it to the clipboard')
.option(
'-o, --output <type>',
'How to print the passwords among `clipboard, password, json`. The JSON option outputs all the matching credentials',
'clipboard'
.addOption(
new Option(
'-o, --output <type>',
'How to print the passwords. The JSON option outputs all the matching credentials'
)
.choices(['clipboard', 'password', 'json'])
.default('clipboard')
)
.argument(
'[filters...]',
Expand Down
21 changes: 6 additions & 15 deletions src/commands/team/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Command } from 'commander';
import { teamCredentialsCommands } from './credentials';
import { CouldNotFindTeamCredentialsError } from '../../errors';
import { runTeamLogs, runTeamMembers, runTeamReport } from '../../command-handlers';
import { getTeamDeviceCredentials } from '../../utils';
import { customParseInt, getTeamDeviceCredentials } from '../../utils';

export const teamCommands = (params: { program: Command }) => {
const { program } = params;
Expand All @@ -27,18 +27,11 @@ export const teamCommands = (params: { program: Command }) => {
.command('members')
.alias('m')
.description('List team members')
.argument('[page]', 'Page number', '0')
.argument('[limit]', 'Limit of members per page', '0')
.argument('[page]', 'Page number', customParseInt, 0)
.argument('[limit]', 'Limit of members per page', customParseInt, 0)
.option('--csv', 'Output in CSV format')
.option('--human-readable', 'Output dates in human readable format')
.action(async (page: string, limit: string, options: { csv: boolean; humanReadable: boolean }) => {
await runTeamMembers({
page: parseInt(page),
limit: parseInt(limit),
csv: options.csv,
humanReadable: options.humanReadable,
});
});
.action(runTeamMembers);

teamGroup
.command('logs')
Expand All @@ -56,8 +49,6 @@ export const teamCommands = (params: { program: Command }) => {
.command('report')
.alias('r')
.description('Get team report')
.argument('[days]', 'Number of days in history', '0')
.action(async (days: string) => {
await runTeamReport({ days: parseInt(days) });
});
.argument('[days]', 'Number of days in history', customParseInt, 0)
.action(runTeamReport);
};
11 changes: 10 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import { cliVersionToString, CLI_VERSION } from './cliVersion';
import { rootCommands } from './commands';
import { initDeviceCredentials, initTeamDeviceCredentials } from './utils';

const errorColor = (str: string) => {
// Add ANSI escape codes to display text in red.
return `\x1b[31m${str}\x1b[0m`;
};

const debugLevel = process.argv.indexOf('--debug') !== -1 ? 'debug' : 'info';

winston.configure({
Expand All @@ -21,11 +26,15 @@ const program = new Command();

program.name('dcli').description('Dashlane CLI').version(cliVersionToString(CLI_VERSION));

program.configureOutput({
outputError: (str, write) => write(errorColor(str)),
});

program.option('--debug', 'Print debug messages');

rootCommands({ program });

program.parseAsync().catch((error: Error) => {
console.error(`ERROR:`, error.message);
console.error(errorColor(`error: ${error.message}`));
process.exit(1);
});
10 changes: 10 additions & 0 deletions src/utils/strings.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import commander from 'commander';
import { Parser } from '@json2csv/plainjs';
import { flatten } from '@json2csv/transforms';

Expand All @@ -14,6 +15,15 @@ export const parseBooleanString = (booleanString: string): boolean => {
throw new Error("The provided boolean variable should be either 'true' or 'false'");
};

export const customParseInt = (value: string, _dummyPrevious: unknown) => {
// parseInt takes a string and a radix
const parsedValue = parseInt(value, 10);
if (isNaN(parsedValue)) {
throw new commander.InvalidArgumentError('Not a number.');
}
return parsedValue;
};

/** Remove underscores and capitalize string */
export const removeUnderscoresAndCapitalize = (string: string): string => {
return string
Expand Down