UNPKG

transform-object-keys

Version:

Transform object keys into a new one using preset or custom rules

93 lines (71 loc) 1.96 kB
'use strict'; const mapObj = require('map-obj'); const camelCase = require('camelcase'); const QuickLru = require('quick-lru'); const has = (array, key) => array.some(x => { if (typeof x === 'string') { return x === key; } x.lastIndex = 0; return x.test(key); }); const cache = new QuickLru({maxSize: 100000}); const isObject = value => typeof value === 'object' && value !== null && !(value instanceof RegExp) && !(value instanceof Error) && !(value instanceof Date); const camelCaseConvert = (input, options) => { options = { deep: false, pascalCase: false, snakeCase: false, kebabCase: false, transform: null, ...options }; const {exclude, pascalCase, snakeCase, stopPaths, deep, transform} = options; const stopPathsSet = new Set(stopPaths); const getKeyCase = key => { if (typeof transform === 'function') { return transform(key); } if (snakeCase) { const sk = string => string && string.match(/[A-Z]{2,}(?=[A-Z][a-z]+\d*|\b)|[A-Z]?[a-z]+|[A-Z]|\d+/g) .map(s => s.toLowerCase()) .join('_'); return sk(key); } return camelCase(key, {pascalCase}); }; const makeMapper = parentPath => (key, value) => { if (deep && isObject(value)) { const path = parentPath === undefined ? key : `${parentPath}.${key}`; if (!stopPathsSet.has(path)) { value = mapObj(value, makeMapper(path)); } } if (!(exclude && has(exclude, key))) { const cacheKey = getKeyCase(key); if (cache.has(cacheKey)) { key = cache.get(cacheKey); } else { const returnValue = cacheKey; if (key.length < 100) { // Prevent abuse cache.set(cacheKey, returnValue); } key = returnValue; } } return [key, value]; }; return mapObj(input, makeMapper(undefined)); }; module.exports = (input, options) => { if (Array.isArray(input)) { return Object.keys(input).map(key => camelCaseConvert(input[key], options)); } return camelCaseConvert(input, options); };