diff --git a/examples/dot-nested-options.js b/examples/dot-nested-options.js index d485b53..9b8eedd 100644 --- a/examples/dot-nested-options.js +++ b/examples/dot-nested-options.js @@ -4,6 +4,7 @@ const cli = require('../src/index')() cli .command('build', 'desc') .option('--env ', 'Set envs') + .option('--foo-bar ', 'Set foo bar') .example('--env.API_SECRET xxx') .action(options => { console.log(options) diff --git a/src/index.ts b/src/index.ts index ca1a483..fabc722 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,7 +3,7 @@ import path from 'path' import mri, { Options as MriOpts } from 'mri' import Command, { CommandConfig, HelpCallback, CommandExample } from './Command' import { OptionConfig } from './Option' -import { getMriOptions, camelcase } from './utils' +import { getMriOptions, camelcase, setDotProp } from './utils' interface ParsedArgv { args: ReadonlyArray @@ -192,7 +192,10 @@ class CAC extends EventEmitter { '--': argsAfterDoubleDashes } for (const key of Object.keys(parsed)) { - options[camelcase(key)] = parsed[key] + const keys = key.split('.').map((v, i) => { + return i === 0 ? camelcase(v) : v + }) + setDotProp(options, keys, parsed[key]) } return { diff --git a/src/utils.ts b/src/utils.ts index 55a611b..fce1f20 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -84,3 +84,25 @@ export const camelcase = (input: string) => { return p1 + p2.toUpperCase() }) } + +export const setDotProp = ( + obj: { [k: string]: any }, + keys: string[], + val: any +) => { + let i = 0 + let length = keys.length + let t = obj + let x + for (; i < length; ++i) { + x = t[keys[i]] + t = t[keys[i]] = + i === length - 1 + ? val + : x != null + ? x + : !!~keys[i + 1].indexOf('.') || !(+keys[i + 1] > -1) + ? {} + : [] + } +}