1+ import * as dargs from 'dargs' ;
12import * as minimist from 'minimist' ;
23
34import {
45 CommandData ,
6+ CommandLineInput ,
57 CommandLineInputs ,
68 CommandLineOptions ,
9+ CommandOption ,
10+ CommandOptionType ,
11+ CommandOptionTypeDefaults ,
12+ NormalizedCommandOption ,
13+ NormalizedMinimistOpts ,
714 ValidationError ,
815} from '../definitions' ;
916
1017import { validate , validators } from './validators' ;
1118
19+ export const parseArgs = minimist ;
20+ export { ParsedArgs } from 'minimist' ;
21+
1222export abstract class Command < T extends CommandData > {
1323 public readonly metadata : T ;
1424
@@ -19,6 +29,147 @@ export abstract class Command<T extends CommandData> {
1929 abstract run ( inputs : CommandLineInputs , options : CommandLineOptions ) : Promise < void > ;
2030}
2131
32+ const typeDefaults : CommandOptionTypeDefaults = new Map < CommandOptionType , CommandLineInput > ( )
33+ . set ( String , null )
34+ . set ( Boolean , false ) ;
35+
36+ export interface MinimistOptionsToArrayOptions extends dargs . Options {
37+ useDoubleQuotes ?: boolean ;
38+ }
39+
40+ export function minimistOptionsToArray ( options : CommandLineOptions , fnOptions : MinimistOptionsToArrayOptions = { } ) : string [ ] {
41+ if ( typeof fnOptions . ignoreFalse === 'undefined' ) {
42+ fnOptions . ignoreFalse = true ;
43+ }
44+
45+ if ( fnOptions . useDoubleQuotes ) {
46+ fnOptions . useEquals = true ;
47+ }
48+
49+ let results = dargs ( options , fnOptions ) ;
50+ results . splice ( results . length - options . _ . length ) ; // take out arguments
51+
52+ if ( fnOptions . useDoubleQuotes ) {
53+ results = results . map ( r => r . replace ( / ^ ( \- \- [ A - Z a - z 0 - 9 - ] + ) = ( .+ \s + .+ ) $ / , '$1="$2"' ) ) ;
54+ }
55+
56+ return results ;
57+ }
58+
59+ /**
60+ * Takes a Minimist command option and normalizes its values.
61+ */
62+ function normalizeOption ( option : CommandOption ) : NormalizedCommandOption {
63+ const type = option . type ? option . type : String ;
64+
65+ return {
66+ type,
67+ default : option . default ? option . default : typeDefaults . get ( type ) ,
68+ aliases : option . aliases ? option . aliases : [ ] ,
69+ ...option ,
70+ } ;
71+ }
72+
73+ export function metadataToMinimistOptions ( metadata : CommandData ) : minimist . Opts {
74+ const options : NormalizedMinimistOpts = {
75+ string : [ '_' ] ,
76+ boolean : [ ] ,
77+ alias : { } ,
78+ default : { }
79+ } ;
80+
81+ if ( ! metadata . options ) {
82+ return { boolean : true , string : '_' } ;
83+ }
84+
85+ const schema = metadataToEnvCmdOptsSchema ( metadata ) ;
86+
87+ for ( let opt of schema ) {
88+ const envvar = process . env [ opt . envvar ] ;
89+
90+ if ( typeof envvar !== 'undefined' ) {
91+ if ( opt . option . type === Boolean ) {
92+ opt . option . default = envvar && envvar !== '0' ? true : false ;
93+ } else {
94+ opt . option . default = envvar ;
95+ }
96+ }
97+ }
98+
99+ for ( let option of metadata . options ) {
100+ const normalizedOption = normalizeOption ( option ) ;
101+
102+ if ( normalizedOption . type === String ) {
103+ options . string . push ( normalizedOption . name ) ;
104+ } else if ( normalizedOption . type === Boolean ) {
105+ options . boolean . push ( normalizedOption . name ) ;
106+ }
107+
108+ options . default [ normalizedOption . name ] = normalizedOption . default ;
109+ options . alias [ normalizedOption . name ] = normalizedOption . aliases ;
110+ }
111+
112+ return options ;
113+ }
114+
115+ export interface CmdOptsSchema {
116+ envvar : string ;
117+ option : CommandOption ;
118+ }
119+
120+ export function metadataToEnvCmdOptsSchema ( metadata : CommandData ) : CmdOptsSchema [ ] {
121+ if ( ! metadata . options ) {
122+ return [ ] ;
123+ }
124+
125+ const schema : CmdOptsSchema [ ] = [ ] ;
126+ const fullName = metadata . fullName ? metadata . fullName : metadata . name ;
127+ const prefix = `IONIC_CMDOPTS_${ fullName . toUpperCase ( ) . split ( ' ' ) . join ( '_' ) } ` ;
128+
129+ for ( let option of metadata . options ) {
130+ schema . push ( { envvar : `${ prefix } _${ option . name . toUpperCase ( ) . split ( '-' ) . join ( '_' ) } ` , option } ) ;
131+ }
132+
133+ return schema ;
134+ }
135+
136+ /**
137+ * Filter command line options that match a given "intent", which are specified
138+ * in the command's metadata.
139+ *
140+ * To filter options that have no intent specified in the command's metadata,
141+ * exclude the intentName parameter.
142+ *
143+ * @param metadata
144+ * @param options The options to filter.
145+ * @param indentName
146+ *
147+ * @return The filtered options.
148+ */
149+ export function filterOptionsByIntent ( metadata : CommandData , options : CommandLineOptions , intentName ?: string ) : CommandLineOptions {
150+ const r = Object . keys ( options ) . reduce ( ( allOptions , optionName ) => {
151+ const metadataOptionFound = ( metadata . options || [ ] ) . find ( ( mdOption ) => (
152+ mdOption . name === optionName || ( mdOption . aliases || [ ] ) . includes ( optionName )
153+ ) ) ;
154+ if ( metadataOptionFound ) {
155+ if ( intentName && metadataOptionFound . intents && metadataOptionFound . intents . includes ( intentName ) ) {
156+ allOptions [ optionName ] = options [ optionName ] ;
157+ } else if ( ! intentName && ! metadataOptionFound . intents ) {
158+ allOptions [ optionName ] = options [ optionName ] ;
159+ }
160+ }
161+ return allOptions ;
162+ } , < CommandLineOptions > { } ) ;
163+
164+ r . _ = options . _ ;
165+
166+ if ( options [ '--' ] ) {
167+ r [ '--' ] = options [ '--' ] ;
168+ }
169+
170+ return r ;
171+ }
172+
22173export function validateInputs ( argv : string [ ] , metadata : CommandData ) : void {
23174 if ( ! metadata . inputs ) {
24175 return ;
@@ -46,5 +197,3 @@ export function validateInputs(argv: string[], metadata: CommandData): void {
46197 throw errors ;
47198 }
48199}
49-
50- export const parseArgs = minimist ;
0 commit comments