11import { Command as Base } from '@oclif/core'
2+ import { ArgOutput , FlagOutput , Input , ParserOutput } from '@oclif/core/lib/interfaces/parser'
3+ import { NonExistentFlagsError } from '@oclif/core/lib/parser/errors'
24import { deprecate } from 'util'
5+ import parser from 'yargs-parser'
6+ import unparser from 'yargs-unparser'
37
48const pjson = require ( '../package.json' )
59
@@ -14,6 +18,7 @@ export abstract class Command extends Base {
1418 base = `${ pjson . name } @${ pjson . version } `
1519 _heroku ! : APIClient
1620 _legacyHerokuClient : any
21+ allowArbitraryFlags : boolean = false ;
1722
1823 get heroku ( ) : APIClient {
1924 if ( this . _heroku ) return this . _heroku
@@ -43,4 +48,34 @@ export abstract class Command extends Base {
4348 get out ( ) : any {
4449 return deprecatedCLI ( )
4550 }
51+
52+ protected async parse < F extends FlagOutput , B extends FlagOutput , A extends ArgOutput > ( options ?: Input < F , B , A > , argv ?: string [ ] ) : Promise < ParserOutput < F , B , A > > {
53+ if ( this . allowArbitraryFlags ) {
54+ try {
55+ return await super . parse ( options , argv )
56+ } catch ( error ) {
57+ const { flags : nonExistentFlags } = error as NonExistentFlagsError
58+ const parsed = parser ( this . argv )
59+ const nonExistentFlagsWithValues = { ...parsed }
60+
61+ for ( const flag of nonExistentFlags ) {
62+ const key = flag . replace ( '--' , '' )
63+ delete parsed [ key ]
64+ }
65+
66+ for ( const key in parsed ) {
67+ if ( Reflect . has ( parsed , key ) ) {
68+ delete nonExistentFlagsWithValues [ key ]
69+ }
70+ }
71+
72+ this . argv = unparser ( parsed as unparser . Arguments )
73+ const result = await super . parse ( options , argv )
74+ result . nonExistentFlags = unparser ( nonExistentFlagsWithValues as unparser . Arguments )
75+ return result
76+ }
77+ }
78+
79+ return super . parse ( options , argv )
80+ }
4681}
0 commit comments