Skip to content

Commit

Permalink
Add locale option (#75)
Browse files Browse the repository at this point in the history
Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
  • Loading branch information
rasgele and sindresorhus committed Oct 10, 2020
1 parent 20591fb commit a06c4d1
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 10 deletions.
27 changes: 27 additions & 0 deletions index.d.ts
Expand Up @@ -6,6 +6,30 @@ declare namespace camelcase {
@default false
*/
readonly pascalCase?: boolean;

/**
The locale parameter indicates the locale to be used to convert to upper/lower case according to any locale-specific case mappings. If multiple locales are given in an array, the best available locale is used.
Default: The host environment’s current locale.
@example
```
import camelCase = require('camelcase');
camelCase('lorem-ipsum', {locale: 'en-US'});
//=> 'loremIpsum'
camelCase('lorem-ipsum', {locale: 'tr-TR'});
//=> 'loremİpsum'
camelCase('lorem-ipsum', {locale: ['en-US', 'en-GB']});
//=> 'loremIpsum'
camelCase('lorem-ipsum', {locale: ['tr', 'TR', 'tr-TR']});
//=> 'loremİpsum'
```
*/
readonly locale?: string | readonly string[];
}
}

Expand Down Expand Up @@ -51,6 +75,9 @@ camelCase(['foo', 'bar']);
camelCase(['__foo__', '--bar'], {pascalCase: true});
//=> 'FooBar'
camelCase('lorem-ipsum', {locale: 'en-US'});
//=> 'loremIpsum'
```
*/
declare function camelcase(
Expand Down
20 changes: 10 additions & 10 deletions index.js
@@ -1,6 +1,6 @@
'use strict';

const preserveCamelCase = string => {
const preserveCamelCase = (string, locale) => {
let isLastCharLower = false;
let isLastCharUpper = false;
let isLastLastCharUpper = false;
Expand All @@ -20,9 +20,9 @@ const preserveCamelCase = string => {
isLastCharUpper = false;
isLastCharLower = true;
} else {
isLastCharLower = character.toLocaleLowerCase() === character && character.toLocaleUpperCase() !== character;
isLastCharLower = character.toLocaleLowerCase(locale) === character && character.toLocaleUpperCase(locale) !== character;
isLastLastCharUpper = isLastCharUpper;
isLastCharUpper = character.toLocaleUpperCase() === character && character.toLocaleLowerCase() !== character;
isLastCharUpper = character.toLocaleUpperCase(locale) === character && character.toLocaleLowerCase(locale) !== character;
}
}

Expand All @@ -39,7 +39,7 @@ const camelCase = (input, options) => {
...options
};

const postProcess = x => options.pascalCase ? x.charAt(0).toLocaleUpperCase() + x.slice(1) : x;
const postProcess = x => options.pascalCase ? x.charAt(0).toLocaleUpperCase(options.locale) + x.slice(1) : x;

if (Array.isArray(input)) {
input = input.map(x => x.trim())
Expand All @@ -54,20 +54,20 @@ const camelCase = (input, options) => {
}

if (input.length === 1) {
return options.pascalCase ? input.toLocaleUpperCase() : input.toLocaleLowerCase();
return options.pascalCase ? input.toLocaleUpperCase(options.locale) : input.toLocaleLowerCase(options.locale);
}

const hasUpperCase = input !== input.toLocaleLowerCase();
const hasUpperCase = input !== input.toLocaleLowerCase(options.locale);

if (hasUpperCase) {
input = preserveCamelCase(input);
input = preserveCamelCase(input, options.locale);
}

input = input
.replace(/^[_.\- ]+/, '')
.toLocaleLowerCase()
.replace(/[_.\- ]+([\p{Alpha}\p{N}_]|$)/gu, (_, p1) => p1.toLocaleUpperCase())
.replace(/\d+([\p{Alpha}\p{N}_]|$)/gu, m => m.toLocaleUpperCase());
.toLocaleLowerCase(options.locale)
.replace(/[_.\- ]+([\p{Alpha}\p{N}_]|$)/gu, (_, p1) => p1.toLocaleUpperCase(options.locale))
.replace(/\d+([\p{Alpha}\p{N}_]|$)/gu, m => m.toLocaleUpperCase(options.locale));

return postProcess(input);
};
Expand Down
4 changes: 4 additions & 0 deletions index.test-d.ts
Expand Up @@ -3,6 +3,10 @@ import camelCase = require('.');

expectType<string>(camelCase('foo-bar'));
expectType<string>(camelCase('розовый_пушистый_единороги'));
expectType<string>(camelCase('Foo-Bar', {locale: ['tr']}));
expectType<string>(camelCase('Foo-Bar', {locale: ['tr', 'TR', 'tr-TR']}));
expectType<string>(camelCase('Foo-Bar', {pascalCase: true, locale: ['tr']}));
expectType<string>(camelCase('Foo-Bar', {pascalCase: true, locale: ['tr', 'TR', 'tr-TR']}));
expectType<string>(camelCase('Foo-Bar', {pascalCase: true}));
expectType<string>(camelCase(['foo', 'bar']));
expectType<string>(camelCase(['__foo__', '--bar'], {pascalCase: true}));
26 changes: 26 additions & 0 deletions readme.md
Expand Up @@ -48,6 +48,9 @@ camelCase(['foo', 'bar']);

camelCase(['__foo__', '--bar'], {pascalCase: true});
//=> 'FooBar'

camelCase('lorem-ipsum', {locale: 'en-US'});
//=> 'loremIpsum'
```

## API
Expand All @@ -71,6 +74,29 @@ Default: `false`

Uppercase the first character: `foo-bar``FooBar`

##### locale

Type: `string | string[]`\
Default: The host environment’s current locale.

The locale parameter indicates the locale to be used to convert to upper/lower case according to any locale-specific case mappings. If multiple locales are given in an array, the best available locale is used.

```js
const camelCase = require('camelcase');

camelCase('lorem-ipsum', {locale: 'en-US'});
//=> 'loremIpsum'

camelCase('lorem-ipsum', {locale: 'tr-TR'});
//=> 'loremİpsum'

camelCase('lorem-ipsum', {locale: ['en-US', 'en-GB']});
//=> 'loremIpsum'

camelCase('lorem-ipsum', {locale: ['tr', 'TR', 'tr-TR']});
//=> 'loremİpsum'
```

## camelcase for enterprise

Available as part of the Tidelift Subscription.
Expand Down
11 changes: 11 additions & 0 deletions test.js
Expand Up @@ -130,6 +130,17 @@ test('camelCase with pascalCase option', t => {
t.is(camelCase('桑德_在这里。', {pascalCase: true}), '桑德在这里。');
});

test('camelCase with locale option', t => {
t.is(camelCase('lorem-ipsum', {locale: 'tr-TR'}), 'loremİpsum');
t.is(camelCase('lorem-ipsum', {locale: 'en-EN'}), 'loremIpsum');
t.is(camelCase('lorem-ipsum', {locale: ['tr', 'TR', 'tr-TR']}), 'loremİpsum');
t.is(camelCase('lorem-ipsum', {locale: ['en-EN', 'en-GB']}), 'loremIpsum');
t.is(camelCase('ipsum-dolor', {pascalCase: true, locale: 'tr-TR'}), 'İpsumDolor');
t.is(camelCase('ipsum-dolor', {pascalCase: true, locale: 'en-EN'}), 'IpsumDolor');
t.is(camelCase('ipsum-dolor', {pascalCase: true, locale: ['tr', 'TR', 'tr-TR']}), 'İpsumDolor');
t.is(camelCase('ipsum-dolor', {pascalCase: true, locale: ['en-EN', 'en-GB']}), 'IpsumDolor');
});

test('invalid input', t => {
t.throws(() => {
camelCase(1);
Expand Down

0 comments on commit a06c4d1

Please sign in to comment.