diff --git a/index.js b/index.js index 78cafa8..950a29f 100644 --- a/index.js +++ b/index.js @@ -20,6 +20,22 @@ function isConstructorOrProto(obj, key) { return (key === 'constructor' && typeof obj[key] === 'function') || key === '__proto__'; } +function resolveArrays(o, key) { + var ARRAY = RegExp(/^([^[]+)\[([^\]]+)\](.*)/); + var groups; + while ((groups = ARRAY.exec(key))) { + var arr = groups[1]; + var idx = groups[2]; + var rest = groups[3]; + if (!Array.isArray(o[arr])) { + o[arr] = []; + } + o = o[arr]; + key = idx + (rest || ''); + } + return [o, key]; +} + module.exports = function (args, opts) { if (!opts) { opts = {}; } @@ -86,9 +102,13 @@ module.exports = function (args, opts) { function setKey(obj, keys, value) { var o = obj; + var resolved; for (var i = 0; i < keys.length - 1; i++) { var key = keys[i]; if (isConstructorOrProto(o, key)) { return; } + resolved = resolveArrays(o, key); + o = resolved[0]; + key = resolved[1]; if (o[key] === undefined) { o[key] = {}; } if ( o[key] === Object.prototype @@ -103,6 +123,9 @@ module.exports = function (args, opts) { var lastKey = keys[keys.length - 1]; if (isConstructorOrProto(o, lastKey)) { return; } + resolved = resolveArrays(o, lastKey); + o = resolved[0]; + lastKey = resolved[1]; if ( o === Object.prototype || o === Number.prototype diff --git a/test/dotted.js b/test/dotted.js index c606118..df48773 100644 --- a/test/dotted.js +++ b/test/dotted.js @@ -34,3 +34,14 @@ test('dotted array', function (t) { t.end(); }); + +test('dotted notation with array in square bracket syntax', function (t) { + var argv = parse(['--a[1][0].foo', 'x', '--a[1][2]', '42']); + t.ok(Array.isArray(argv.a)); + t.notOk(0 in argv.a); + t.ok(Array.isArray(argv.a[1])); + t.equal(argv.a[1][0].foo, 'x'); + t.notOk(1 in argv.a[1]); + t.equal(argv.a[1][2].foo, 42); + t.end(); +});