Skip to content

Commit

Permalink
fix: update defekt (#305)
Browse files Browse the repository at this point in the history
BREAKING CHANGE

The errors thrown by the library have changed, if you relied on their error codes before, you have to use the exported errors.
  • Loading branch information
Noah Hummel authored Mar 25, 2021
1 parent 09b7bea commit 89dbc77
Show file tree
Hide file tree
Showing 12 changed files with 53 additions and 30 deletions.
2 changes: 1 addition & 1 deletion lib/convertOptionDefinition.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { OptionDefinition as CLAOptionDefinition } from 'command-line-args';
import { errors } from './errors';
import { OptionDefinition } from './elements/OptionDefinition';
import * as errors from './errors';

const convertOptionDefinition = function ({ optionDefinition }: {
optionDefinition: OptionDefinition;
Expand Down
20 changes: 12 additions & 8 deletions lib/errors.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { defekt } from 'defekt';

const errors = defekt({
CommandNotFound: {},
InvalidOperation: {},
NoSuggestionAvailable: {},
OptionInvalid: {},
OptionMissing: {}
});
class CommandNotFound extends defekt({ code: 'CommandNotFound' }) {}
class InvalidOperation extends defekt({ code: 'InvalidOperation' }) {}
class NoSuggestionAvailable extends defekt({ code: 'NoSuggestionAvailable' }) {}
class OptionInvalid extends defekt({ code: 'OptionInvalid' }) {}
class OptionMissing extends defekt({ code: 'OptionMissing' }) {}

export { errors };
export {
CommandNotFound,
InvalidOperation,
NoSuggestionAvailable,
OptionInvalid,
OptionMissing
};
2 changes: 1 addition & 1 deletion lib/getCommandByPath.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Command } from './elements/Command';
import { CommandPath } from './elements/CommandPath';
import { errors } from './errors';
import * as errors from './errors';

const getCommandByPath = function ({ rootCommand, commandPath }: {
rootCommand: Command<any>;
Expand Down
2 changes: 2 additions & 0 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import { GetUsageFn } from './elements/GetUsageFn';
import { Handlers } from './Handlers';
import { OptionDefinition } from './elements/OptionDefinition';
import { runCli } from './runCli';
import * as errors from './errors';

export {
runCli,
Command,
CommandHandle,
CommandHandleOptions,
CommandPath,
errors,
GetUsageFn,
Handlers,
OptionDefinition
Expand Down
2 changes: 1 addition & 1 deletion lib/recommend/recommendCommand.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Command } from '../elements/Command';
import { CommandPath } from '../elements/CommandPath';
import { errors } from '../errors';
import { getCommandByPath } from '../getCommandByPath';
import stringSimilarity from 'string-similarity';
import * as errors from '../errors';

const recommendCommand = function ({ rootCommand, commandPath }: {
rootCommand: Command<any>;
Expand Down
5 changes: 3 additions & 2 deletions lib/runCliRecursive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { helpOption } from './commands/helpOption';
import { RecommendCommandFn } from './elements/RecommendCommandFn';
import { validateOptions } from './validateOptions';
import commandLineArgs, { OptionDefinition as CLAOptionDefinition } from 'command-line-args';
import * as errors from './errors';

const runCliRecursive = async function ({
command,
Expand Down Expand Up @@ -52,12 +53,12 @@ const runCliRecursive = async function ({
validateOptions({ options, optionDefinitions: command.optionDefinitions });
} catch (ex: unknown) {
switch ((ex as CustomError).code) {
case 'EOPTIONMISSING':
case errors.OptionMissing.code:
handlers.optionMissing({ optionDefinition: (ex as CustomError).data.optionDefinition });

// eslint-disable-next-line unicorn/no-process-exit
return process.exit(1);
case 'EOPTIONINVALID': {
case errors.OptionInvalid.code: {
handlers.optionInvalid({ optionDefinition: (ex as CustomError).data.optionDefinition, reason: (ex as CustomError).message });

// eslint-disable-next-line unicorn/no-process-exit
Expand Down
11 changes: 7 additions & 4 deletions lib/validateOptions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { CustomError } from 'defekt';
import { errors } from './errors';
import { OptionDefinition } from './elements/OptionDefinition';
import * as errors from './errors';

// Throws an error if any option does not match its defined type or is undefined.
// Since command-line-args handles default values, a check for undefined-ness here
Expand All @@ -14,7 +14,8 @@ const validateOptions = function ({ options, optionDefinitions }: {
const optionRequired = optionDefinition.isRequired ?? false;

if (optionRequired && value === undefined) {
throw new errors.OptionMissing(`Option '${optionDefinition.name}' is missing.`, {
throw new errors.OptionMissing({
message: `Option '${optionDefinition.name}' is missing.`,
data: { optionDefinition }
});
}
Expand All @@ -32,7 +33,8 @@ const validateOptions = function ({ options, optionDefinitions }: {
}

if (typeof value !== 'number' || Number.isNaN(value)) {
throw new errors.OptionInvalid(`Option '${optionDefinition.name}' must be a number.`, {
throw new errors.OptionInvalid({
message: `Option '${optionDefinition.name}' must be a number.`,
data: { optionDefinition }
});
}
Expand All @@ -47,7 +49,8 @@ const validateOptions = function ({ options, optionDefinitions }: {
try {
optionDefinition.validate(value);
} catch (ex: unknown) {
throw new errors.OptionInvalid((ex as CustomError).message, {
throw new errors.OptionInvalid({
message: (ex as CustomError).message,
data: { optionDefinition }
});
}
Expand Down
12 changes: 9 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
{
"name": "David Losert",
"email": "david@david-losert.com"
},
{
"name": "Noah Hummel",
"email": "noah.hummel@thenativeweb.io"
}
],
"main": "build/lib/index.js",
Expand All @@ -26,7 +30,7 @@
"command-line-args": "5.1.1",
"command-line-commands": "3.0.2",
"command-line-usage": "6.1.1",
"defekt": "6.0.2",
"defekt": "7.0.4",
"string-similarity": "4.0.4",
"strip-indent": "3.0.0"
},
Expand All @@ -46,4 +50,4 @@
"cli"
],
"license": "MIT"
}
}
7 changes: 4 additions & 3 deletions test/unit/getCommandByPathTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { assert } from 'assertthat';
import { Command } from '../../lib/elements/Command';
import { CustomError } from 'defekt';
import { getCommandByPath } from '../../lib/getCommandByPath';
import * as errors from '../../lib/errors';

suite('getCommandByPath', (): void => {
const rootCommand: Command<any> = {
Expand Down Expand Up @@ -94,7 +95,7 @@ suite('getCommandByPath', (): void => {

assert.that((): any => getCommandByPath({ rootCommand, commandPath })).
is.throwing(
(ex): boolean => (ex as CustomError).code === 'EINVALIDOPERATION'
(ex): boolean => (ex as CustomError).code === errors.InvalidOperation.code
);
});

Expand All @@ -103,7 +104,7 @@ suite('getCommandByPath', (): void => {

assert.that((): any => getCommandByPath({ rootCommand, commandPath })).
is.throwing(
(ex): boolean => (ex as CustomError).code === 'ECOMMANDNOTFOUND'
(ex): boolean => (ex as CustomError).code === errors.CommandNotFound.code
);
});

Expand All @@ -112,7 +113,7 @@ suite('getCommandByPath', (): void => {

assert.that((): any => getCommandByPath({ rootCommand, commandPath })).
is.throwing(
(ex): boolean => (ex as CustomError).code === 'ECOMMANDNOTFOUND'
(ex): boolean => (ex as CustomError).code === errors.CommandNotFound.code
);
});
});
3 changes: 2 additions & 1 deletion test/unit/recommend/recommendCommandTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { assert } from 'assertthat';
import { Command } from '../../../lib/elements/Command';
import { CustomError } from 'defekt';
import { recommendCommand } from '../../../lib/recommend/recommendCommand';
import * as errors from '../../../lib/errors';

suite('recommendCommand', (): void => {
const rootCommand: Command<any> = {
Expand Down Expand Up @@ -44,7 +45,7 @@ suite('recommendCommand', (): void => {

assert.that((): any => recommendCommand({ rootCommand, commandPath })).
is.throwing(
(ex): boolean => (ex as CustomError).code === 'ENOSUGGESTIONAVAILABLE'
(ex): boolean => (ex as CustomError).code === errors.NoSuggestionAvailable.code
);
});
});
9 changes: 5 additions & 4 deletions test/unit/validateOptionsTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { assert } from 'assertthat';
import { CustomError } from 'defekt';
import { OptionDefinition } from '../../lib';
import { validateOptions } from 'lib/validateOptions';
import * as errors from '../../lib/errors';

suite('validateOptions', (): void => {
suite('required', (): void => {
Expand All @@ -21,7 +22,7 @@ suite('validateOptions', (): void => {
validateOptions({ options, optionDefinitions });
}).is.throwing((ex): boolean =>
ex.message === `Option 'option' is missing.` &&
(ex as CustomError).code === 'EOPTIONMISSING');
(ex as CustomError).code === errors.OptionMissing.code);
});
});

Expand Down Expand Up @@ -110,7 +111,7 @@ suite('validateOptions', (): void => {
validateOptions({ options, optionDefinitions });
}).is.throwing((ex): boolean =>
ex.message === `Option 'option' must be a number.` &&
(ex as CustomError).code === 'EOPTIONINVALID');
(ex as CustomError).code === errors.OptionInvalid.code);
});
});

Expand All @@ -134,7 +135,7 @@ suite('validateOptions', (): void => {
validateOptions({ options, optionDefinitions });
}).is.throwing((ex): boolean =>
ex.message === `Invalid value.` &&
(ex as CustomError).code === 'EOPTIONINVALID');
(ex as CustomError).code === errors.OptionInvalid.code);
});

test('does not throw an exception for required options if validate succeeds.', async (): Promise<void> => {
Expand Down Expand Up @@ -176,7 +177,7 @@ suite('validateOptions', (): void => {
validateOptions({ options, optionDefinitions });
}).is.throwing((ex): boolean =>
ex.message === `Invalid value.` &&
(ex as CustomError).code === 'EOPTIONINVALID');
(ex as CustomError).code === errors.OptionInvalid.code);
});

test('does not throw an exception for optional options if the value is missing.', async (): Promise<void> => {
Expand Down

0 comments on commit 89dbc77

Please sign in to comment.