Skip to content

Commit

Permalink
feat(command): add support for custom type class's
Browse files Browse the repository at this point in the history
  • Loading branch information
c4spar committed Mar 27, 2020
1 parent d1bc510 commit 7006a67
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 38 deletions.
66 changes: 28 additions & 38 deletions packages/command/lib/base-command.ts
@@ -1,35 +1,30 @@
const { stdout, stderr } = Deno;
import { dim, red } from 'https://deno.land/std/fmt/colors.ts';
import { parseFlags, parseFlagValue } from '../../flags/lib/flags.ts';
import {
IFlags,
IFlagsResult,
IFlagValue,
IFlagValueHandler,
IFlagValueType,
ITypeHandler,
ITypeHandlerMap,
OptionType
} from '../../flags/lib/types.ts';
import { parseFlags } from '../../flags/lib/flags.ts';
import { IFlagArgument, IFlagOptions, IFlags, IFlagsResult, IFlagValue, IFlagValueHandler, IFlagValueType, IGenericObject, ITypeHandler, OptionType } from '../../flags/lib/types.ts';
import { fill } from '../../flags/lib/utils.ts';
import format from '../../x/format.ts';
import {
CommandMap,
IAction,
IArgumentDetails,
ICommandOption,
IEnvVariable,
IExample,
IFlagsParseResult,
IOption
} from './types.ts';
import { BooleanType } from '../types/boolean.ts';
import { NumberType } from '../types/number.ts';
import { StringType } from '../types/string.ts';
import { Type } from '../types/type.ts';
import { CommandMap, IAction, IArgumentDetails, ICommandOption, IEnvVariable, IExample, IFlagsParseResult, IOption } from './types.ts';

/**
* Map of type's.
*/
export type ITypeMap = IGenericObject<Type<any> | ITypeHandler<any>>

/**
* Base command implementation without pre configured command's and option's.
*/
export class BaseCommand {

protected static types: ITypeHandlerMap = {};
protected types: ITypeMap = {
string: new StringType(),
number: new NumberType(),
boolean: new BooleanType()
};
protected rawArgs: string[] = [];
protected name: string = location.pathname.split( '/' ).pop() as string;
protected path: string = this.name;
Expand All @@ -40,7 +35,6 @@ export class BaseCommand {
protected commands: CommandMap[] = [];
protected examples: IExample[] = [];
protected envVars: IEnvVariable[] = [];
protected types: ITypeHandlerMap = {};
protected cmd: BaseCommand = this;
protected argsDefinition: string | undefined;
protected isExecutable: boolean = false;
Expand All @@ -50,14 +44,6 @@ export class BaseCommand {
protected defaultCommand: string | undefined;
protected _useRawArgs: boolean = false;

/**
* Register global custom type.
*/
public static type( type: string, typeHandler: ITypeHandler<any>, override?: boolean ): void {

this.types[ type ] = typeHandler;
}

/**
* Add new sub-command.
*/
Expand Down Expand Up @@ -243,9 +229,9 @@ export class BaseCommand {
/**
* Register command specific custom type.
*/
public type( type: string, typeHandler: ITypeHandler<any> ): this {
public type( type: string, typeHandler: Type<any> | ITypeHandler<any>, override?: boolean ): this {

if ( this.cmd.types[ type ] ) {
if ( this.cmd.types[ type ] && !override ) {
throw this.error( new Error( `Type '${ type }' already exists.` ) );
}

Expand Down Expand Up @@ -537,10 +523,13 @@ export class BaseCommand {
try {
return parseFlags( args, {
stopEarly,
knownFlaks,
allowEmpty: this._allowEmpty,
flags: this.options,
types: Object.assign( {}, BaseCommand.types, this.types ),
knownFlaks
parse: ( type: string, option: IFlagOptions, arg: IFlagArgument, nextValue: string | false ) => {
const parser = this.types[ type ];
return parser instanceof Type ? parser.parse( option, arg, nextValue ) : parser( option, arg, nextValue );
}
} );
} catch ( e ) {
throw this.error( e );
Expand All @@ -556,16 +545,17 @@ export class BaseCommand {
return;
}

const types = Object.assign( {}, BaseCommand.types, this.types );
const denoEnv = Deno.env();

this.envVars.forEach( ( env: IEnvVariable ) => {
const name = env.names.find( name => name in denoEnv );
if ( name ) {
try {
parseFlagValue( { name }, env.details, denoEnv[ name ], { types } );
// @TODO: optimize handling for environment variable error message: parseFlag & parseEnv ?
const parser = this.types[ env.type ];
parser instanceof Type ? parser.parse( { name }, env, denoEnv[ name ] ) : parser( { name }, env, denoEnv[ name ] );
} catch ( e ) {
throw new Error( `Environment variable '${ name }' must be of type ${ env.details.type } but got: ${ denoEnv[ name ] }` );
throw new Error( `Environment variable '${ name }' must be of type ${ env.type } but got: ${ denoEnv[ name ] }` );
}
}
} );
Expand Down
11 changes: 11 additions & 0 deletions packages/command/types/boolean.ts
@@ -0,0 +1,11 @@
import { IFlagArgument, IFlagOptions } from '../../flags/lib/types.ts';
import { boolean } from '../../flags/lib/types/boolean.ts';
import { Type } from './type.ts';

export class BooleanType extends Type<boolean> {

public parse( option: IFlagOptions, arg: IFlagArgument, value: string | false ): boolean | undefined {

return boolean( option, arg, value );
}
}
11 changes: 11 additions & 0 deletions packages/command/types/number.ts
@@ -0,0 +1,11 @@
import { IFlagArgument, IFlagOptions } from '../../flags/lib/types.ts';
import { number } from '../../flags/lib/types/number.ts';
import { Type } from './type.ts';

export class NumberType extends Type<number> {

public parse( option: IFlagOptions, arg: IFlagArgument, value: string | false ): number | undefined {

return number( option, arg, value );
}
}
11 changes: 11 additions & 0 deletions packages/command/types/string.ts
@@ -0,0 +1,11 @@
import { IFlagArgument, IFlagOptions } from '../../flags/lib/types.ts';
import { string } from '../../flags/lib/types/string.ts';
import { Type } from './type.ts';

export class StringType extends Type<string> {

public parse( option: IFlagOptions, arg: IFlagArgument, value: string | false ): string | undefined {

return string( option, arg, value );
}
}
6 changes: 6 additions & 0 deletions packages/command/types/type.ts
@@ -0,0 +1,6 @@
import { IFlagArgument, IFlagOptions } from '../../flags/lib/types.ts';

export abstract class Type<T> {

public abstract parse( option: IFlagOptions, arg: IFlagArgument, value: string | false ): T | undefined
}

0 comments on commit 7006a67

Please sign in to comment.