Giter Club home page Giter Club logo

humps's Introduction

humps Build status

This project is no longer maintained.

Underscore-to-camelCase converter (and vice versa) for strings and object keys in JavaScript.

When converting object keys, it will walk the structure, converting any nested objects (or arrays of nested objects) along the way. Handy for converting JSON between JavaScript and Ruby/Rails APIs.

Takes inspiration from Ember Data and copies some utility functions from Underscore.js.

Usage

Converting strings

humps.camelize('hello_world') // 'helloWorld'
humps.decamelize('fooBar') // 'foo_bar'
humps.decamelize('fooBarBaz', { separator: '-' }) // 'foo-bar-baz'

Converting object keys

var object = { attr_one: 'foo', attr_two: 'bar' }
humps.camelizeKeys(object); // { attrOne: 'foo', attrTwo: 'bar' }

Arrays of objects are also converted

var array = [{ attr_one: 'foo' }, { attr_one: 'bar' }]
humps.camelizeKeys(array); // [{ attrOne: 'foo' }, { attrOne: 'bar' }]

It also accepts a callback which can modify the conversion behavior. For example to prevent conversion of keys containing only uppercase letters or numbers:

humps.camelizeKeys(obj, function (key, convert) {
  return /^[A-Z0-9_]+$/.test(key) ? key : convert(key);
});
humps.decamelizeKeys(obj, function (key, convert, options) {
  return /^[A-Z0-9_]+$/.test(key) ? key : convert(key, options);
});

In order to use the callback with options use the process option:

humps.decamelizeKeys(obj, {
    separator: '-',
    process: function (key, convert, options) {
      return /^[A-Z0-9_]+$/.test(key) ? key : convert(key, options);
    }
});

API

humps.camelize(string)

Removes any hypens, underscores, and whitespace characters, and uppercases the first character that follows.

humps.camelize('hello_world-foo bar') // 'helloWorldFooBar'

humps.pascalize(string)

Similar to humps.camelize(string), but also ensures that the first character is uppercase.

humps.pascalize('hello_world-foo bar') // 'HelloWorldFooBar'

humps.decamelize(string, options)

Converts camelCased string to an underscore-separated string.

humps.decamelize('helloWorldFooBar') // 'hello_world_foo_bar'

The separator can be customized with the separator option.

humps.decamelize('helloWorldFooBar', { separator: '-' }) // 'hello-world-foo-bar'

By default, decamelize will only split words on capital letters (not numbers as in humps pre v1.0). To customize this behaviour, use the split option. This should be a regular expression which, when passed into String.prototype.split, produces an array of words (by default the regular expression is: /(?=[A-Z])/). For example, to treat numbers as uppercase:

humps.decamelize('helloWorld1', { split: /(?=[A-Z0-9])/ }) // 'hello_world_1'

humps.depascalize(string, options)

Same as humps.decamelize above.

humps.camelizeKeys(object, options)

Converts object keys to camelCase. It also converts arrays of objects.

humps.pascalizeKeys(object, options)

Converts object keys to PascalCase. It also converts arrays of objects.

humps.decamelizeKeys(object, options)

Separates camelCased object keys with an underscore. It also converts arrays of objects. See humps.decamelize for details of options.

humps.depascalizeKeys(object, options)

See humps.decamelizeKeys.

Licence

humps is copyright © 2012+ Dom Christie and released under the MIT license.

humps's People

Contributors

alexbeletsky avatar domchristie avatar kamui avatar lloydh avatar patrickgalbraith avatar pgilad avatar pziemkowski avatar rupurt avatar statianzo avatar willisblackburn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

humps's Issues

invalid moment object when converting string to moment inside camelizeKeys

when i try to camelize my object, i want to convert one of the field (string) into moment object, like this

  const p = camelizeKeys({
    ...myobject,
   timestamp: moment(purchase.timestamp),
  });

the camelization is ok, no error.
the thing is, moment object suppose to have .format function defined on the object.
but when i try to access it from p.timestamp.format it said that format is undefined.

what is the cause of that? how to do it 'properly' ?

support for css classes

it'd be a neat feature to correctly camelize/decamelize css classes. Since prefixes follow their own rule, it'd require something special like:

function camelCaseCSS(string) {
  if (string.indexOf("-ms-") === 0) {
    string = string.substr(1);
  }
  return string.replace(/-(\w|$)/g, (_, char) => char.toUpperCase());
}

Maybe have an isCSS options prop for the API? It could detect css automatically & use this function, but that's seems a little too magical.

Camelizing ID

How can I camelize something such as ID? Right now camelizeKeys() is returning me back iD.

Do not convert names starting with underscore

names starting and ending with underscore can not be camelized and then decamelized back safely.
camelizeKeys({_id: 123}) will result to {id: 123}. But if you want to decamelize it back decamelizeKeys({id: 123} you will receive {id: 123} and not {_id: 123}.

Also you will loose id key when doing camelizeKeys({id: 456, _id: 123})

Maybe we should ignore such keys and return them as is? At least as an option.

Cannot split on numbers properly with the readme example

When dealing with 1 digit numbers the readme example is ok

humps.decamelize('helloWorld1', { split: /(?=[A-Z0-9])/ }) // 'hello_world_1'

But for 1+ digit numbers it does not produce the expected result

humps.decamelize('helloWorld12', { split: /(?=[A-Z0-9])/ }) // 'hello_world_1_2'

I am unsure that we could solve this issue only using split option.

Best I could do:

humps.decamelize('helloWorld12', { split: /(?=[A-Z])|[^0-9](?=[0-9])/ }) // 'hello_worl_12'

Changelog for 2.0.0 missing

Sadly the Changelog for the new Release 2.0.0 is missing.

My main question is: Is there any breaking change when upgrading from 1.1.0 to 2.0.0?

Decamelizing uppercase keys

I'm having a problem decamelizing keys that are all uppercase, here is what's happening:

const options = { URL: 'www.google.com' };

decamelizeKeys(options);

is returning { u_r_l: (...) }, instead of just ignoring that key

Exclude specific path(s) from being converted

Is it possible to exclude parts of a bigger nested object from being converted? I currently am receiving an object in the following form:

{
  some_key: 12345,
  important_stuff: {
    '53GF_6D2F9Q_x5HF89': {
      some_name: 'first'
    },
    '_1fH-Gc76Zd_djkDF3': {
      some_name: 'second'
    }
  },
  another_key: {}
}

All keys in important_stuff need to be preserved because they are identifiers and all others should be converted. Since I have no control over the format and content of those, I cannot just use a regex to identify them from the conversion function.
If not yet possible, how about passing information about the parents of the current key to the conversion function?

unexpected behavior with ES6 imports & classes

something like this:

import { depascalizeKeys } from 'humps'

class SomeClass {
  someMethod(obj) {
    return depascalizeKeys(obj)
  }
}

const instance = new SomeClass()
instance.someMethod({KeyName: 'value'})

will throw:
TypeError: Cannot read property 'apply' of undefined

because of this structure:

    depascalizeKeys: function () {
      return this.decamelizeKeys.apply(this, arguments);
    }

I guess this refers to instance so it's looking for instance.decamelizeKeys.

Would bind work with an object literal like this ? not sure...

workaround is to just use decamelizeKeys instead of depascaliseKeys

Using `camelizeKeys` on array

If I use camelizeKeys on an array, the array becomes an object with keys of 0, 1, 2, etc.

var ret = humps.camelizeKeys([
  {first_name: 'Sam'},
  {first_name: 'Jenna'},
  ..
]);

// ret = {0: {firstName: 'Sam'}, 1: {firstName: 'Jenna'}, ...}

`_isNumerical` implementation doesn't make sense

I was just reviewing this code, and noticed that the following doesn't seem to make sense:

humps/humps.js

Lines 94 to 98 in d612998

// Performant way to determine if obj coerces to a number
var _isNumerical = function(obj) {
obj = obj - 0;
return obj === obj;
};

As, obviously, this code could never return false. You could replace the entire implementation with return true and it would behave the same way.

Perhaps this would be more in-line with the original intent?

var _isNumerical = function(obj) { 
  var num = obj - 0; 
  return num === obj; 
}; 

That would check if the input was precisely that number (including the type), but the comment states that it checks whether the value coerces to a number, so perhaps it should also really be double equals, rather than triple? Or perhaps the comment should be corrected?

humps corrupted FormData structure

Hi,

I have a problem, when i send a multipart-form request with axios, humps transform request into json and rails returns 422.

How can i resolve this?

Thanks for help!

screen shot 2018-07-19 at 12 29 10

Customise conversion based on some criteria

As has been noted in other issues/pull requests (#26) the default conversion behaviour does not work in all cases, e.g.

  • when the key is all uppercase (#20)
  • when the key starts with an underscore (#22)
  • or some other criteria (#26)

Rather than add options for each of these cases, may I propose that just a single option be added that will handle all of the above. Something like:

humps.camelizeKeys(obj, {
  filters: [
    {
      filter: function (key) { return /^[A-Z_]+$/ },
      convert: function (key) { return key }
    },
    {
      filter: function (key) { return /^_/ },
      convert: function (key) { return key }
    },
    {
      filter: function (key) { return ['exclude_me', 'and_me'].indexOf(key) > _1 },
      convert: function (key) { return key }
    }
  ]
})

Although all the conversion functions in these cases simply return the original key unmodified, it may be useful to allow custom conversion e.g. #18.

Thoughts?

/cc @mattkrick, @GiovanniFrigo, @patrickgalbraith, @rufman

Option to not camelize all-caps CONSTANTS

When I bootstrap data into my app, the constants are named ENV and PUSHER_KEY but running camelizeKeys changes them to eNV and pUSHERKEY. Probably never intended, but an option to skip over constants would be lovely.

Recurse nested objects

I suggest that let the recursion or deep as an option. Sometimes I don't want to convert nested keys, only outside keys.

Add direct PascalCase -> camelCase method

There are backend frameworks that return already pascalised properties (e.g. .NET MVC).

It would be nice to skip the regexp that removes separators and makes uppercase chars when we are sure that input data already doesn't need that for performance reasons. The only modification that should be applied would be to make first chars lowercased.

If you wouldn't like to add this specific function, we could add a way to register new transform functions (a kind of config call) and allow users to call them later on.

I could implement those.

Conversion of screaming snake case to camel case

I was surprised by the behavior of converting a screaming snake case string to camel case.

Currently,

const camelize = require('humps').camelize
camelize('HELLO_WORLD') === 'hELLOWORLD'

whereas I expected it to be more like

camelize('HELLO_WORLD') === 'helloWorld'

Which (if any) is the intended behavior?

Camelize keys & uppercase

I noticed that some uppercased keys were camelized in a weird way:

humps.camelizeKeys({ "USERNAME":  "foo" }) // returns { uSERNAME: "foo" }

I've used a custom function & lodash to prevent this from happening, but I was wondering if that was the expected behaviour from humps.

    // Use lowercase instead of camelization for uppercase-only keys
    // (to prevent USERNAME from becoming uSERNAME)
    humps.camelizeKeys(data, function (key, convert, options) {
      return /^[A-Z0-9_]+$/.test(key) ? lowerCase(key) : convert(key, options);
    });

[🐛BUG] Unexpected underscore when using decamelize function

Desc

Hey guys, brilliant module! But I ran into a few problems when I used it

here is my test code:

const humps = require('humps')

const formatTestStr = (target, result) => `Test case: ${target}, result: ${result}`

console.log(formatTestStr('Raw_Message', humps.decamelize('Raw_Message')))

console.log(formatTestStr('raw_Message', humps.decamelize('raw_Message')))

console.log(formatTestStr('Raw_message', humps.decamelize('Raw_message')))

console.log(formatTestStr('raw_Message_Another', humps.decamelize('raw_Message_Another')))

and it comes out:

Test case: Raw_Message, result: raw__message // <- oops
Test case: raw_Message, result: raw__message  // <- oops
Test case: Raw_message, result: raw_message
Test case: raw_Message_Another, result: raw__message__another  // <- oops

as you can see, there is an unexpected underscore when target string is an underscore case string and _ is followed by an upper case character

Version

2.0.1

Expect

just turn underscore case string into lower case

decamelizeKeys fails in chrome 51

I'm not totally sure if this is a bug in chrome 51 or in this library, but in chrome 52, i get this result

window.humps.decamelizeKeys({fooBar: 123})
Object {foo_bar: 123}

and in chrome 51, i get this

window.humps.decamelizeKeys({fooBar: 123})
Object {foobar: 123}

chrome 50 seems fine so it's just 51

Mutate original object

It would be a very good idea to have methods camelizeKeys and pascalizeKeys perform the operation on the original object that's passed, without creating a copy. As an option that is.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.