diff --git a/README.md b/README.md index 80e878a..f06ac0f 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ the keys of any nested objects – according to some function. Circular references are supported. -To transform the *values* of an object rather than its keys, use +To transform the _values_ of an object rather than its keys, use [Deep Map][deep-map]. ## Install @@ -122,6 +122,9 @@ And the result will look like this: this within mapFn() +
  • + shouldTransformFn <function> Function used to customize whether a value in the object should be deeply/recursively mapped. The function receives a key and a value and must output a boolean. +
  • @@ -145,7 +148,7 @@ interface Result { userName: string; } -let result = deepMapKeys({user_name: 'Pumbaa'}, snakeToCamel); +let result = deepMapKeys({ user_name: 'Pumbaa' }, snakeToCamel); let name = result.userName; // Everything is OK :) ``` diff --git a/src/deep-map-keys.ts b/src/deep-map-keys.ts index 7148b87..ed8d07c 100644 --- a/src/deep-map-keys.ts +++ b/src/deep-map-keys.ts @@ -12,6 +12,7 @@ export interface MapFn { export interface Opts { thisArg?: any; + shouldTransformFn?: (key?: string, value?: any) => boolean; } export class DeepMapKeys { @@ -50,13 +51,16 @@ export class DeepMapKeys { return this.cache.get(obj); } - let {mapFn, opts: {thisArg}} = this; + let {mapFn, opts: {thisArg, shouldTransformFn}} = this; let result: NonPrimitive = {}; this.cache.set(obj, result); for (let key in obj) { if (obj.hasOwnProperty(key)) { - result[mapFn.call(thisArg, key, obj[key])] = this.map(obj[key]); + result[mapFn.call(thisArg, key, obj[key])] = + (!shouldTransformFn || shouldTransformFn(key, obj[key])) ? + this.map(obj[key]) : + obj[key]; } } diff --git a/src/index.test.ts b/src/index.test.ts index d6ba49b..c03d73b 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -99,6 +99,17 @@ describe('deepMapKeys(object, mapFn, [options])', () => { }); + describe('option: shouldTransformFn', () => { + it('prevents mapping through values for which @shouldTransformFn returns false', () => { + let shouldTransformFn = sinon.spy((key: string, value: any) => key !== 'noTransform'); + let obj = {one: 1, noTransform: {two: 2}}; + + deepMapKeys(obj, caps, {shouldTransformFn}).should.deep.equal({ONE: 1, NOTRANSFORM: {two: 2}}); + shouldTransformFn.should.have.been.calledWith('one', 1); + shouldTransformFn.should.have.been.calledWith('noTransform', {two: 2}); + }); + }); + }); });