diff --git a/index.d.ts b/index.d.ts index 51d2ba2..90a208a 100644 --- a/index.d.ts +++ b/index.d.ts @@ -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[]; } } @@ -51,6 +75,9 @@ camelCase(['foo', 'bar']); camelCase(['__foo__', '--bar'], {pascalCase: true}); //=> 'FooBar' + +camelCase('lorem-ipsum', {locale: 'en-US'}); +//=> 'loremIpsum' ``` */ declare function camelcase( diff --git a/index.js b/index.js index dd2c490..3c7ae42 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,6 @@ 'use strict'; -const preserveCamelCase = string => { +const preserveCamelCase = (string, locale) => { let isLastCharLower = false; let isLastCharUpper = false; let isLastLastCharUpper = false; @@ -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; } } @@ -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()) @@ -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); }; diff --git a/index.test-d.ts b/index.test-d.ts index cc565d9..e39b067 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -3,6 +3,10 @@ import camelCase = require('.'); expectType(camelCase('foo-bar')); expectType(camelCase('розовый_пушистый_единороги')); +expectType(camelCase('Foo-Bar', {locale: ['tr']})); +expectType(camelCase('Foo-Bar', {locale: ['tr', 'TR', 'tr-TR']})); +expectType(camelCase('Foo-Bar', {pascalCase: true, locale: ['tr']})); +expectType(camelCase('Foo-Bar', {pascalCase: true, locale: ['tr', 'TR', 'tr-TR']})); expectType(camelCase('Foo-Bar', {pascalCase: true})); expectType(camelCase(['foo', 'bar'])); expectType(camelCase(['__foo__', '--bar'], {pascalCase: true})); diff --git a/readme.md b/readme.md index da76012..c9b4e08 100644 --- a/readme.md +++ b/readme.md @@ -48,6 +48,9 @@ camelCase(['foo', 'bar']); camelCase(['__foo__', '--bar'], {pascalCase: true}); //=> 'FooBar' + +camelCase('lorem-ipsum', {locale: 'en-US'}); +//=> 'loremIpsum' ``` ## API @@ -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. diff --git a/test.js b/test.js index 4dea4be..6de410c 100644 --- a/test.js +++ b/test.js @@ -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);