Skip to content

Commit 2597adb

Browse files
Move to ESM (#33)
Co-authored-by: Sindre Sorhus <[email protected]>
1 parent 0586fe4 commit 2597adb

File tree

7 files changed

+88
-94
lines changed

7 files changed

+88
-94
lines changed

.github/workflows/main.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ jobs:
1010
fail-fast: false
1111
matrix:
1212
node-version:
13+
- 16
1314
- 14
1415
- 12
15-
- 10
1616
steps:
1717
- uses: actions/checkout@v2
18-
- uses: actions/setup-node@v1
18+
- uses: actions/setup-node@v2
1919
with:
2020
node-version: ${{ matrix.node-version }}
2121
- run: npm install

index.d.ts

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,39 @@
1-
declare namespace decamelize {
2-
interface Options {
3-
/**
4-
Character or string inserted to separate words in `string`.
1+
export interface Options {
2+
/**
3+
Character or string inserted to separate words in `string`.
54
6-
@default '_'
5+
@default '_'
76
8-
@example
9-
```
10-
import decamelize = require('decamelize');
7+
@example
8+
```
9+
import decamelize from 'decamelize';
1110
12-
decamelize('unicornRainbow');
13-
//=> 'unicorn_rainbow'
11+
decamelize('unicornRainbow');
12+
//=> 'unicorn_rainbow'
1413
15-
decamelize('unicornRainbow', {separator: '-'});
16-
//=> 'unicorn-rainbow'
17-
```
18-
*/
19-
readonly separator?: string;
14+
decamelize('unicornRainbow', {separator: '-'});
15+
//=> 'unicorn-rainbow'
16+
```
17+
*/
18+
readonly separator?: string;
2019

21-
/**
22-
Preserve sequences of uppercase characters.
20+
/**
21+
Preserve sequences of uppercase characters.
2322
24-
@default false
23+
@default false
2524
26-
@example
27-
```
28-
import decamelize = require('decamelize');
25+
@example
26+
```
27+
import decamelize from 'decamelize';
2928
30-
decamelize('testGUILabel');
31-
//=> 'test_gui_label'
29+
decamelize('testGUILabel');
30+
//=> 'test_gui_label'
3231
33-
decamelize('testGUILabel', {preserveConsecutiveUppercase: true});
34-
//=> 'test_GUI_label'
35-
```
36-
*/
37-
readonly preserveConsecutiveUppercase?: boolean;
38-
}
32+
decamelize('testGUILabel', {preserveConsecutiveUppercase: true});
33+
//=> 'test_GUI_label'
34+
```
35+
*/
36+
readonly preserveConsecutiveUppercase?: boolean;
3937
}
4038

4139
/**
@@ -45,7 +43,7 @@ Convert a camelized string into a lowercased one with a custom separator: `unico
4543
4644
@example
4745
```
48-
import decamelize = require('decamelize');
46+
import decamelize from 'decamelize';
4947
5048
decamelize('unicornRainbow');
5149
//=> 'unicorn_rainbow'
@@ -54,6 +52,5 @@ decamelize('unicornRainbow', {separator: '-'});
5452
//=> 'unicorn-rainbow'
5553
```
5654
*/
57-
declare function decamelize(string: string, options?: decamelize.Options): string;
55+
export default function decamelize(string: string, options?: Options): string;
5856

59-
export = decamelize;

index.js

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,31 @@
1-
'use strict';
2-
31
const handlePreserveConsecutiveUppercase = (decamelized, separator) => {
42
// Lowercase all single uppercase characters. As we
53
// want to preserve uppercase sequences, we cannot
64
// simply lowercase the separated string at the end.
75
// `data_For_USACounties` → `data_for_USACounties`
86
decamelized = decamelized.replace(
97
/((?<![\p{Uppercase_Letter}\d])[\p{Uppercase_Letter}\d](?![\p{Uppercase_Letter}\d]))/gu,
10-
$0 => {
11-
return $0.toLowerCase();
12-
}
8+
$0 => $0.toLowerCase(),
139
);
1410

1511
// Remaining uppercase sequences will be separated from lowercase sequences.
1612
// `data_For_USACounties` → `data_for_USA_counties`
1713
return decamelized.replace(
1814
/(\p{Uppercase_Letter}+)(\p{Uppercase_Letter}\p{Lowercase_Letter}+)/gu,
19-
(_, $1, $2) => {
20-
return $1 + separator + $2.toLowerCase();
21-
}
15+
(_, $1, $2) => $1 + separator + $2.toLowerCase(),
2216
);
2317
};
2418

25-
module.exports = (
19+
export default function decamelize(
2620
text,
2721
{
2822
separator = '_',
29-
preserveConsecutiveUppercase = false
30-
} = {}
31-
) => {
23+
preserveConsecutiveUppercase = false,
24+
} = {},
25+
) {
3226
if (!(typeof text === 'string' && typeof separator === 'string')) {
3327
throw new TypeError(
34-
'The `text` and `separator` arguments should be of type `string`'
28+
'The `text` and `separator` arguments should be of type `string`',
3529
);
3630
}
3731

@@ -47,7 +41,7 @@ module.exports = (
4741
// `myURLstring → `my_URLstring`
4842
const decamelized = text.replace(
4943
/([\p{Lowercase_Letter}\d])(\p{Uppercase_Letter})/gu,
50-
replacement
44+
replacement,
5145
);
5246

5347
if (preserveConsecutiveUppercase) {
@@ -59,7 +53,7 @@ module.exports = (
5953
return decamelized
6054
.replace(
6155
/(\p{Uppercase_Letter})(\p{Uppercase_Letter}\p{Lowercase_Letter}+)/gu,
62-
replacement
56+
replacement,
6357
)
6458
.toLowerCase();
65-
};
59+
}

index.test-d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import {expectType} from 'tsd';
2-
import decamelize = require('.');
2+
import decamelize from './index.js';
33

44
expectType<string>(decamelize('unicornRainbow'));
55
expectType<string>(decamelize('unicornRainbow', {separator: '-'}));
66
expectType<string>(decamelize('unicornRainbow', {
77
separator: '-',
8-
preserveConsecutiveUppercase: true
8+
preserveConsecutiveUppercase: true,
99
}));

package.json

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010
"email": "[email protected]",
1111
"url": "https://sindresorhus.com"
1212
},
13+
"type": "module",
14+
"exports": "./index.js",
1315
"engines": {
14-
"node": ">=10"
16+
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
1517
},
1618
"scripts": {
1719
"test": "xo && ava && tsd"
@@ -33,8 +35,9 @@
3335
"convert"
3436
],
3537
"devDependencies": {
36-
"ava": "^2.4.0",
37-
"tsd": "^0.11.0",
38-
"xo": "^0.24.0"
38+
"ava": "^3.15.0",
39+
"tsd": "^0.17.0",
40+
"typescript": "^4.4.3",
41+
"xo": "^0.44.0"
3942
}
4043
}

readme.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ If you use this on untrusted user input, don't forget to limit the length to som
77

88
## Install
99

10-
```
11-
$ npm install decamelize
10+
```sh
11+
npm install decamelize
1212
```
1313

1414
## Usage
1515

1616
```js
17-
const decamelize = require('decamelize');
17+
import decamelize from 'decamelize';
1818

1919
decamelize('unicornRainbow');
2020
//=> 'unicorn_rainbow'
@@ -49,7 +49,7 @@ Default: `'_'`
4949
Character or string inserted to separate words in `string`.
5050

5151
```js
52-
cosnt decamelize = require('decamelize');
52+
import decamelize from 'decamelize';
5353

5454
decamelize('unicornRainbow');
5555
//=> 'unicorn_rainbow'
@@ -66,7 +66,7 @@ Default: `false`
6666
Preserve sequences of uppercase characters.
6767

6868
```js
69-
const decamelize = require('decamelize');
69+
import decamelize from 'decamelize';
7070

7171
decamelize('testGUILabel');
7272
//=> 'test_gui_label'

test.js

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import test from 'ava';
2-
import decamelize from '.';
2+
import decamelize from './index.js';
33

44
test('decamelize', t => {
55
t.is(decamelize(''), '');
@@ -19,7 +19,7 @@ test('decamelize', t => {
1919
t.is(decamelize('unicornRainbow', {separator: '-'}), 'unicorn-rainbow');
2020
t.is(
2121
decamelize('thisHasSpecialCharactersLikeČandŠ', {separator: ' '}),
22-
'this has special characters like čand š'
22+
'this has special characters like čand š',
2323
);
2424
});
2525

@@ -39,101 +39,101 @@ test('separator and options passed', t => {
3939
t.is(
4040
decamelize('testGUILabel', {
4141
separator: '!',
42-
preserveConsecutiveUppercase: true
42+
preserveConsecutiveUppercase: true,
4343
}),
44-
'test!GUI!label'
44+
'test!GUI!label',
4545
);
4646
});
4747

4848
test('keeping blocks of consecutive uppercase characters but split the last if lowercase characters follow', t => {
4949
t.is(
5050
decamelize('A', {
51-
preserveConsecutiveUppercase: true
51+
preserveConsecutiveUppercase: true,
5252
}),
53-
'A'
53+
'A',
5454
);
5555
t.is(
5656
decamelize('myURLString', {
57-
preserveConsecutiveUppercase: true
57+
preserveConsecutiveUppercase: true,
5858
}),
59-
'my_URL_string'
59+
'my_URL_string',
6060
);
6161
t.is(
6262
decamelize('URLString', {
63-
preserveConsecutiveUppercase: true
63+
preserveConsecutiveUppercase: true,
6464
}),
65-
'URL_string'
65+
'URL_string',
6666
);
6767
t.is(
6868
decamelize('oxygenO2Level', {
69-
preserveConsecutiveUppercase: true
69+
preserveConsecutiveUppercase: true,
7070
}),
71-
'oxygen_O2_level'
71+
'oxygen_O2_level',
7272
);
7373
t.is(
7474
decamelize('StringURL', {
75-
preserveConsecutiveUppercase: true
75+
preserveConsecutiveUppercase: true,
7676
}),
77-
'string_URL'
77+
'string_URL',
7878
);
7979
t.is(
8080
decamelize('STringURL', {
81-
preserveConsecutiveUppercase: true
81+
preserveConsecutiveUppercase: true,
8282
}),
83-
'S_tring_URL'
83+
'S_tring_URL',
8484
);
8585
t.is(
8686
decamelize('numberOfDataForUSA', {
87-
preserveConsecutiveUppercase: true
87+
preserveConsecutiveUppercase: true,
8888
}),
89-
'number_of_data_for_USA'
89+
'number_of_data_for_USA',
9090
);
9191
t.is(
9292
decamelize('testGUILabel', {
93-
preserveConsecutiveUppercase: true
93+
preserveConsecutiveUppercase: true,
9494
}),
95-
'test_GUI_label'
95+
'test_GUI_label',
9696
);
9797
t.is(
9898
decamelize('CAPLOCKED1', {
99-
preserveConsecutiveUppercase: true
99+
preserveConsecutiveUppercase: true,
100100
}),
101-
'CAPLOCKED1'
101+
'CAPLOCKED1',
102102
);
103103
});
104104

105105
test('long strings', t => {
106106
// Factor to increase the test string
107107
const times = 100;
108108
const longString = 'Lb8SvAARMshcNvfxjgGCgfot3AZAzysuxRpG9XfpLCz89TeWqAd3TUo64K45VH2MfjLYhztt4LQYzrEbTpx7gGcG4T8ueKPm6VraXKtULJdncFQhEQfCRwWGNscdFe6UTEAvN7Nze4Qy4hvZuKLX5YiohGpvNZUtLGen3WP2jot8VeprzyXQmiKdxdxrEResSRgSWENCzXZPSerYuEfApVbjuDJZ9kGMRXFRZQVyBDDGfY9ERqtxHQxPw65TtEo3dgwhcuhvC3dMyRJ6jWaonKB3Pqtv27vRv5MgYb5mgvCE55oCTBG9yASPaw2KqYVz3amBge9HggEzXJGhwSXjkL7jUYk3WjQUbwVnZNHkH3P9MpvM98DtTnGAYfK5TjD8Y5oXPRJmdCHzhByboaW2oRJ2Ft7dxGKXLs2s7qsQs8FsJHVcYrmVHRa6th5CizHSXK7vr5D3KYsfsnr92AmtR4LERam7CV9emBBuykQJMejLGFsvgTrBKmmUqijxSgY'.repeat(
109-
100
109+
100,
110110
);
111111

112112
t.is(
113113
decamelize(longString),
114-
new Array(times)
114+
Array.from({length: times})
115115
.fill(
116-
'lb8_sv_aar_mshc_nvfxjg_g_cgfot3_az_azysux_rp_g9_xfp_l_cz89_te_wq_ad3_t_uo64_k45_vh2_mfj_l_yhztt4_lq_yzr_eb_tpx7g_gc_g4_t8ue_k_pm6_vra_x_kt_ul_jdnc_f_qh_e_qf_c_rw_wg_nscd_fe6_ute_av_n7_nze4_qy4hv_zu_klx5_yioh_gpv_nz_ut_l_gen3_wp2jot8_veprzy_x_qmi_kdxdxr_e_res_s_rg_swen_cz_xzp_ser_yu_ef_ap_vbju_djz9k_gmrxfrzq_vy_bdd_gf_y9_e_rqtx_h_qx_pw65_tt_eo3dgwhcuhv_c3d_my_rj6j_waon_kb3_pqtv27v_rv5_mg_yb5mgv_ce55o_ctbg9y_as_paw2_kq_y_vz3am_bge9_hgg_ez_xj_ghw_s_xjk_l7j_u_yk3_wj_q_ubw_vn_zn_hk_h3_p9_mpv_m98_dt_tn_ga_yf_k5_tj_d8_y5o_xpr_jmd_c_hzh_byboa_w2o_rj2_ft7dx_gkx_ls2s7qs_qs8_fs_jh_vc_yrm_vh_ra6th5_ciz_hsxk7vr5_d3_k_ysfsnr92_amt_r4_le_ram7_cv9em_b_buyk_qj_mej_lg_fsvg_tr_b_kmm_uqijx_sg_y'
116+
'lb8_sv_aar_mshc_nvfxjg_g_cgfot3_az_azysux_rp_g9_xfp_l_cz89_te_wq_ad3_t_uo64_k45_vh2_mfj_l_yhztt4_lq_yzr_eb_tpx7g_gc_g4_t8ue_k_pm6_vra_x_kt_ul_jdnc_f_qh_e_qf_c_rw_wg_nscd_fe6_ute_av_n7_nze4_qy4hv_zu_klx5_yioh_gpv_nz_ut_l_gen3_wp2jot8_veprzy_x_qmi_kdxdxr_e_res_s_rg_swen_cz_xzp_ser_yu_ef_ap_vbju_djz9k_gmrxfrzq_vy_bdd_gf_y9_e_rqtx_h_qx_pw65_tt_eo3dgwhcuhv_c3d_my_rj6j_waon_kb3_pqtv27v_rv5_mg_yb5mgv_ce55o_ctbg9y_as_paw2_kq_y_vz3am_bge9_hgg_ez_xj_ghw_s_xjk_l7j_u_yk3_wj_q_ubw_vn_zn_hk_h3_p9_mpv_m98_dt_tn_ga_yf_k5_tj_d8_y5o_xpr_jmd_c_hzh_byboa_w2o_rj2_ft7dx_gkx_ls2s7qs_qs8_fs_jh_vc_yrm_vh_ra6th5_ciz_hsxk7vr5_d3_k_ysfsnr92_amt_r4_le_ram7_cv9em_b_buyk_qj_mej_lg_fsvg_tr_b_kmm_uqijx_sg_y',
117117
)
118-
.join('_')
118+
.join('_'),
119119
);
120120
t.is(
121121
decamelize(longString, {separator: '!'}),
122-
new Array(times)
122+
Array.from({length: times})
123123
.fill(
124-
'lb8!sv!aar!mshc!nvfxjg!g!cgfot3!az!azysux!rp!g9!xfp!l!cz89!te!wq!ad3!t!uo64!k45!vh2!mfj!l!yhztt4!lq!yzr!eb!tpx7g!gc!g4!t8ue!k!pm6!vra!x!kt!ul!jdnc!f!qh!e!qf!c!rw!wg!nscd!fe6!ute!av!n7!nze4!qy4hv!zu!klx5!yioh!gpv!nz!ut!l!gen3!wp2jot8!veprzy!x!qmi!kdxdxr!e!res!s!rg!swen!cz!xzp!ser!yu!ef!ap!vbju!djz9k!gmrxfrzq!vy!bdd!gf!y9!e!rqtx!h!qx!pw65!tt!eo3dgwhcuhv!c3d!my!rj6j!waon!kb3!pqtv27v!rv5!mg!yb5mgv!ce55o!ctbg9y!as!paw2!kq!y!vz3am!bge9!hgg!ez!xj!ghw!s!xjk!l7j!u!yk3!wj!q!ubw!vn!zn!hk!h3!p9!mpv!m98!dt!tn!ga!yf!k5!tj!d8!y5o!xpr!jmd!c!hzh!byboa!w2o!rj2!ft7dx!gkx!ls2s7qs!qs8!fs!jh!vc!yrm!vh!ra6th5!ciz!hsxk7vr5!d3!k!ysfsnr92!amt!r4!le!ram7!cv9em!b!buyk!qj!mej!lg!fsvg!tr!b!kmm!uqijx!sg!y'
124+
'lb8!sv!aar!mshc!nvfxjg!g!cgfot3!az!azysux!rp!g9!xfp!l!cz89!te!wq!ad3!t!uo64!k45!vh2!mfj!l!yhztt4!lq!yzr!eb!tpx7g!gc!g4!t8ue!k!pm6!vra!x!kt!ul!jdnc!f!qh!e!qf!c!rw!wg!nscd!fe6!ute!av!n7!nze4!qy4hv!zu!klx5!yioh!gpv!nz!ut!l!gen3!wp2jot8!veprzy!x!qmi!kdxdxr!e!res!s!rg!swen!cz!xzp!ser!yu!ef!ap!vbju!djz9k!gmrxfrzq!vy!bdd!gf!y9!e!rqtx!h!qx!pw65!tt!eo3dgwhcuhv!c3d!my!rj6j!waon!kb3!pqtv27v!rv5!mg!yb5mgv!ce55o!ctbg9y!as!paw2!kq!y!vz3am!bge9!hgg!ez!xj!ghw!s!xjk!l7j!u!yk3!wj!q!ubw!vn!zn!hk!h3!p9!mpv!m98!dt!tn!ga!yf!k5!tj!d8!y5o!xpr!jmd!c!hzh!byboa!w2o!rj2!ft7dx!gkx!ls2s7qs!qs8!fs!jh!vc!yrm!vh!ra6th5!ciz!hsxk7vr5!d3!k!ysfsnr92!amt!r4!le!ram7!cv9em!b!buyk!qj!mej!lg!fsvg!tr!b!kmm!uqijx!sg!y',
125125
)
126-
.join('!')
126+
.join('!'),
127127
);
128128
t.is(
129129
decamelize(longString, {
130130
separator: '!',
131-
preserveConsecutiveUppercase: true
131+
preserveConsecutiveUppercase: true,
132132
}),
133-
new Array(times)
133+
Array.from({length: times})
134134
.fill(
135-
'lb8!sv!AAR!mshc!nvfxjg!G!cgfot3!AZ!azysux!rp!G9!xfp!L!cz89!te!wq!ad3!T!uo64!K45!VH2!mfj!L!yhztt4!LQ!yzr!eb!tpx7g!gc!G4!T8ue!K!pm6!vra!X!kt!UL!jdnc!F!qh!E!qf!C!rw!WG!nscd!fe6!UTE!av!N7!nze4!qy4hv!zu!KLX5!yioh!gpv!NZ!ut!L!gen3!WP2jot8!veprzy!X!qmi!kdxdxr!E!res!S!rg!SWEN!cz!XZP!ser!yu!ef!ap!vbju!DJZ9k!GMRXFRZQ!vy!BDD!gf!Y9!E!rqtx!H!qx!pw65!tt!eo3dgwhcuhv!C3d!my!RJ6j!waon!KB3!pqtv27v!rv5!mg!yb5mgv!CE55o!CTBG9y!AS!paw2!kq!Y!vz3am!bge9!hgg!ez!XJ!ghw!S!xjk!L7j!U!yk3!wj!Q!ubw!vn!ZN!hk!H3!P9!mpv!M98!dt!tn!GA!yf!K5!tj!D8!Y5o!XPR!jmd!C!hzh!byboa!W2o!RJ2!ft7dx!GKX!ls2s7qs!qs8!fs!JH!vc!yrm!VH!ra6th5!ciz!HSXK7vr5!D3!K!ysfsnr92!amt!R4!LE!ram7!CV9em!B!buyk!QJ!mej!LG!fsvg!tr!B!kmm!uqijx!sg!'
135+
'lb8!sv!AAR!mshc!nvfxjg!G!cgfot3!AZ!azysux!rp!G9!xfp!L!cz89!te!wq!ad3!T!uo64!K45!VH2!mfj!L!yhztt4!LQ!yzr!eb!tpx7g!gc!G4!T8ue!K!pm6!vra!X!kt!UL!jdnc!F!qh!E!qf!C!rw!WG!nscd!fe6!UTE!av!N7!nze4!qy4hv!zu!KLX5!yioh!gpv!NZ!ut!L!gen3!WP2jot8!veprzy!X!qmi!kdxdxr!E!res!S!rg!SWEN!cz!XZP!ser!yu!ef!ap!vbju!DJZ9k!GMRXFRZQ!vy!BDD!gf!Y9!E!rqtx!H!qx!pw65!tt!eo3dgwhcuhv!C3d!my!RJ6j!waon!KB3!pqtv27v!rv5!mg!yb5mgv!CE55o!CTBG9y!AS!paw2!kq!Y!vz3am!bge9!hgg!ez!XJ!ghw!S!xjk!L7j!U!yk3!wj!Q!ubw!vn!ZN!hk!H3!P9!mpv!M98!dt!tn!GA!yf!K5!tj!D8!Y5o!XPR!jmd!C!hzh!byboa!W2o!RJ2!ft7dx!GKX!ls2s7qs!qs8!fs!JH!vc!yrm!VH!ra6th5!ciz!HSXK7vr5!D3!K!ysfsnr92!amt!R4!LE!ram7!CV9em!B!buyk!QJ!mej!LG!fsvg!tr!B!kmm!uqijx!sg!',
136136
)
137-
.join('Y!') + 'y'
137+
.join('Y!') + 'y',
138138
);
139139
});

0 commit comments

Comments
 (0)