Skip to content

Commit

Permalink
feature(traverse-keys): add keysOfValuesToIgnore option as a workaround
Browse files Browse the repository at this point in the history
  • Loading branch information
davidyuk committed Apr 28, 2021
1 parent 72f1d32 commit 8ff5afe
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 25 deletions.
37 changes: 19 additions & 18 deletions src/utils/other.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,47 @@
import * as R from 'ramda'
import { snakeToPascal, pascalToSnake } from './string'

export const pause = duration => new Promise(resolve => setTimeout(resolve, duration))

export const mapObject = (object, fn) => Object.fromEntries(Object.entries(object).map(fn))
export const filterObject = (object, fn) => Object.fromEntries(Object.entries(object).filter(fn))

/**
* Key traversal metafunction
* @static
* @function
* @rtype (fn: (s: String) => String) => (o: Object) => Object
* @param {Function} fn - Key transformation function
* @param {Object} o - Object to traverse
* @param {Object} object - Object to traverse
* @param {Array} [keysOfValuesToIgnore] - Workaround to fix serialisation
* @return {Object} Transformed object
*/
export const traverseKeys = R.curry((fn, o) => {
const dispatch = {
Object: o => R.fromPairs(R.toPairs(o).map(function (arr) {
const k = arr[0]
const v = arr[1]
return [fn(k), traverseKeys(fn, v)]
})),
Array: o => o.map(traverseKeys(fn))
}

return (dispatch[R.type(o)] || R.identity)(o)
})
export const traverseKeys = (fn, object, keysOfValuesToIgnore = []) => {
if (typeof object !== 'object') return object
if (Array.isArray(object)) return object.map(i => traverseKeys(fn, i, keysOfValuesToIgnore))
return mapObject(object, ([key, value]) => [
fn(key),
keysOfValuesToIgnore.includes(key) ? value : traverseKeys(fn, value, keysOfValuesToIgnore)
])
}

/**
* snake_case key traversal
* @static
* @rtype (o: Object) => Object
* @param {Object} o - Object to traverse
* @param {Object} object - Object to traverse
* @param {Array} keysOfValuesToIgnore
* @return {Object} Transformed object
* @see pascalToSnake
*/
export const snakizeKeys = o => traverseKeys(pascalToSnake, o)
export const snakizeKeys = traverseKeys.bind(null, pascalToSnake)

/**
* PascalCase key traversal
* @static
* @rtype (o: Object) => Object
* @param {Object} o - Object to traverse
* @param {Object} object - Object to traverse
* @param {Array} keysOfValuesToIgnore
* @return {Object} Transformed object
* @see snakeToPascal
*/
export const pascalizeKeys = o => traverseKeys(snakeToPascal, o)
export const pascalizeKeys = traverseKeys.bind(null, snakeToPascal)
5 changes: 1 addition & 4 deletions src/utils/swagger.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@
import SwaggerClient from 'swagger-client'
import fetch from 'cross-fetch'
import JsonBig from './json-big'
import { snakizeKeys, pascalizeKeys } from './other'

const mapObject = (object, fn) => Object.fromEntries(Object.entries(object).map(fn))
const filterObject = (object, fn) => Object.fromEntries(Object.entries(object).filter(fn))
import { snakizeKeys, pascalizeKeys, mapObject, filterObject } from './other'

/**
* Generator of Swagger client
Expand Down
12 changes: 9 additions & 3 deletions test/unit/other.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,23 @@ describe('Other utils', function () {
},
c: [3, {
ca: 4
}]
}],
t: {
f: 6
}
}

expect(traverseKeys(k => 'x' + k, input)).to.deep.equal({
expect(traverseKeys(k => 'x' + k, input, ['t'])).to.deep.equal({
xa: 1,
xb: {
xba: 2
},
xc: [3, {
xca: 4
}]
}],
xt: {
f: 6
}
})
})
})

0 comments on commit 8ff5afe

Please sign in to comment.