Skip to content

Commit e445b77

Browse files
committed
Require Node.js 14 and move to ESM
1 parent 87c57ac commit e445b77

File tree

9 files changed

+235
-228
lines changed

9 files changed

+235
-228
lines changed

.github/workflows/main.yml

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

bench/bench.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
/* globals bench suite set */
2-
'use strict';
3-
const camelcaseKeysNpm = require('camelcase-keys');
4-
const fixture = require('./fixture');
5-
const camelcaseKeys = require('..');
2+
import camelcaseKeysNpm from 'camelcase-keys';
3+
import camelcaseKeys from '../index.js';
4+
import fixture from './fixture.js';
65

76
suite('camelcaseKeys', () => {
87
set('mintime', 1000);

fixtures/child-process-for-test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
'use strict';
2-
const camelcaseKeys = require('..');
1+
import process from 'node:process';
2+
import camelcaseKeys from '../index.js';
33

44
const camelcaseKeysArgs = JSON.parse(process.argv[2]);
55

index.d.ts

Lines changed: 75 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,11 @@ Return a default type if input type is nil.
99
@template T - Input type.
1010
@template U - Default type.
1111
*/
12-
type WithDefault<T, U extends T> = T extends undefined | void | null ? U : T;
12+
type WithDefault<T, U extends T> = T extends undefined | void | null ? U : T; // eslint-disable-line @typescript-eslint/ban-types
1313

14+
// TODO: Replace this with https://github.com/sindresorhus/type-fest/blob/main/source/includes.d.ts
1415
/**
1516
Check if an element is included in a tuple.
16-
17-
TODO: Remove this once https://github.com/sindresorhus/type-fest/pull/217 is merged.
1817
*/
1918
type IsInclude<List extends readonly unknown[], Target> = List extends undefined
2019
? false
@@ -42,7 +41,7 @@ export type CamelCaseKeys<
4241
IsPascalCase extends boolean = false,
4342
Exclude extends readonly unknown[] = EmptyTuple,
4443
StopPaths extends readonly string[] = EmptyTuple,
45-
Path extends string = ''
44+
Path extends string = '',
4645
> = T extends readonly any[]
4746
// Handle arrays or tuples.
4847
? {
@@ -62,7 +61,7 @@ export type CamelCaseKeys<
6261
: [IsPascalCase] extends [true]
6362
? PascalCase<P>
6463
: CamelCase<P>]: [IsInclude<StopPaths, AppendPath<Path, P & string>>] extends [
65-
true
64+
true,
6665
]
6766
? T[P]
6867
: [Deep] extends [true]
@@ -79,68 +78,68 @@ export type CamelCaseKeys<
7978
// Return anything else as-is.
8079
: T;
8180

82-
declare namespace camelcaseKeys {
83-
interface Options {
84-
/**
85-
Recurse nested objects and objects in arrays.
81+
type Options = {
82+
/**
83+
Recurse nested objects and objects in arrays.
84+
85+
@default false
86+
*/
87+
readonly deep?: boolean;
8688

87-
@default false
88-
*/
89-
readonly deep?: boolean;
89+
/**
90+
Exclude keys from being camel-cased.
9091
91-
/**
92-
Exclude keys from being camel-cased.
92+
If this option can be statically determined, it's recommended to add `as const` to it.
9393
94-
If this option can be statically determined, it's recommended to add `as const` to it.
94+
@default []
95+
*/
96+
readonly exclude?: ReadonlyArray<string | RegExp>;
9597

96-
@default []
97-
*/
98-
readonly exclude?: ReadonlyArray<string | RegExp>;
98+
/**
99+
Exclude children at the given object paths in dot-notation from being camel-cased. For example, with an object like `{a: {b: '🦄'}}`, the object path to reach the unicorn is `'a.b'`.
99100
100-
/**
101-
Exclude children at the given object paths in dot-notation from being camel-cased. For example, with an object like `{a: {b: '🦄'}}`, the object path to reach the unicorn is `'a.b'`.
101+
If this option can be statically determined, it's recommended to add `as const` to it.
102102
103-
If this option can be statically determined, it's recommended to add `as const` to it.
103+
@default []
104104
105-
@default []
105+
@example
106+
```
107+
import camelcaseKeys from 'camelcase-keys';
106108
107-
@example
108-
```
109-
camelcaseKeys({
110-
a_b: 1,
111-
a_c: {
112-
c_d: 1,
113-
c_e: {
114-
e_f: 1
115-
}
109+
camelcaseKeys({
110+
a_b: 1,
111+
a_c: {
112+
c_d: 1,
113+
c_e: {
114+
e_f: 1
116115
}
117-
}, {
118-
deep: true,
119-
stopPaths: [
120-
'a_c.c_e'
121-
]
122-
}),
123-
// {
124-
// aB: 1,
125-
// aC: {
126-
// cD: 1,
127-
// cE: {
128-
// e_f: 1
129-
// }
130-
// }
131-
// }
132-
```
133-
*/
134-
readonly stopPaths?: readonly string[];
135-
136-
/**
137-
Uppercase the first character as in `bye-bye` → `ByeBye`.
138-
139-
@default false
140-
*/
141-
readonly pascalCase?: boolean;
142-
}
143-
}
116+
}
117+
}, {
118+
deep: true,
119+
stopPaths: [
120+
'a_c.c_e'
121+
]
122+
}),
123+
// {
124+
// aB: 1,
125+
// aC: {
126+
// cD: 1,
127+
// cE: {
128+
// e_f: 1
129+
// }
130+
// }
131+
// }
132+
```
133+
*/
134+
readonly stopPaths?: readonly string[];
135+
136+
/**
137+
Uppercase the first character as in `bye-bye` → `ByeBye`.
138+
139+
@default false
140+
*/
141+
readonly pascalCase?: boolean;
142+
};
144143

145144
/**
146145
Convert object keys to camel case using [`camelcase`](https://github.com/sindresorhus/camelcase).
@@ -149,7 +148,7 @@ Convert object keys to camel case using [`camelcase`](https://github.com/sindres
149148
150149
@example
151150
```
152-
import camelcaseKeys = require('camelcase-keys');
151+
import camelcaseKeys from 'camelcase-keys';
153152
154153
// Convert an object
155154
camelcaseKeys({'foo-bar': true});
@@ -162,31 +161,36 @@ camelcaseKeys([{'foo-bar': true}, {'bar-foo': false}]);
162161
camelcaseKeys({'foo-bar': true, nested: {unicorn_rainbow: true}}, {deep: true});
163162
//=> {fooBar: true, nested: {unicornRainbow: true}}
164163
164+
camelcaseKeys({a_b: 1, a_c: {c_d: 1, c_e: {e_f: 1}}}, {deep: true, stopPaths: ['a_c.c_e']}),
165+
//=> {aB: 1, aC: {cD: 1, cE: {e_f: 1}}}
166+
165167
// Convert object keys to pascal case
166168
camelcaseKeys({'foo-bar': true, nested: {unicorn_rainbow: true}}, {deep: true, pascalCase: true});
167169
//=> {FooBar: true, Nested: {UnicornRainbow: true}}
170+
```
168171
169-
import minimist = require('minimist');
172+
@example
173+
```
174+
import {parseArgs} from 'node:utils';
175+
import camelcaseKeys from 'camelcase-keys';
170176
171-
const argv = minimist(process.argv.slice(2));
177+
const commandLineArguments = parseArgs();
172178
//=> {_: [], 'foo-bar': true}
173179
174-
camelcaseKeys(argv);
180+
camelcaseKeys(commandLineArguments);
175181
//=> {_: [], fooBar: true}
176182
```
177183
*/
178-
declare function camelcaseKeys<
184+
export default function camelcaseKeys<
179185
T extends Record<string, any> | readonly any[],
180-
Options extends camelcaseKeys.Options = camelcaseKeys.Options
186+
OptionsType extends Options = Options,
181187
>(
182188
input: T,
183-
options?: Options
189+
options?: OptionsType
184190
): CamelCaseKeys<
185191
T,
186-
WithDefault<Options['deep'], false>,
187-
WithDefault<Options['pascalCase'], false>,
188-
WithDefault<Options['exclude'], EmptyTuple>,
189-
WithDefault<Options['stopPaths'], EmptyTuple>
192+
WithDefault<OptionsType['deep'], false>,
193+
WithDefault<OptionsType['pascalCase'], false>,
194+
WithDefault<OptionsType['exclude'], EmptyTuple>,
195+
WithDefault<OptionsType['stopPaths'], EmptyTuple>
190196
>;
191-
192-
export default camelcaseKeys;

index.js

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
1-
'use strict';
2-
const mapObj = require('map-obj');
3-
const camelCase = require('camelcase');
4-
const QuickLru = require('quick-lru');
5-
6-
const has = (array, key) => array.some(x => {
7-
if (typeof x === 'string') {
8-
return x === key;
1+
import mapObject from 'map-obj';
2+
import camelCase from 'camelcase';
3+
import QuickLru from 'quick-lru';
4+
5+
const has = (array, key) => array.some(element => {
6+
if (typeof element === 'string') {
7+
return element === key;
98
}
109

11-
x.lastIndex = 0;
12-
return x.test(key);
10+
element.lastIndex = 0;
11+
12+
return element.test(key);
1313
});
1414

15-
const cache = new QuickLru({maxSize: 100000});
15+
const cache = new QuickLru({maxSize: 100_000});
1616

17-
// Reproduces behavior from `map-obj`
17+
// Reproduces behavior from `map-obj`.
1818
const isObject = value =>
19-
typeof value === 'object' &&
20-
value !== null &&
21-
!(value instanceof RegExp) &&
22-
!(value instanceof Error) &&
23-
!(value instanceof Date);
19+
typeof value === 'object'
20+
&& value !== null
21+
&& !(value instanceof RegExp)
22+
&& !(value instanceof Error)
23+
&& !(value instanceof Date);
2424

2525
const camelCaseConvert = (input, options) => {
2626
if (!isObject(input)) {
@@ -30,7 +30,7 @@ const camelCaseConvert = (input, options) => {
3030
options = {
3131
deep: false,
3232
pascalCase: false,
33-
...options
33+
...options,
3434
};
3535

3636
const {exclude, pascalCase, stopPaths, deep} = options;
@@ -42,7 +42,7 @@ const camelCaseConvert = (input, options) => {
4242
const path = parentPath === undefined ? key : `${parentPath}.${key}`;
4343

4444
if (!stopPathsSet.has(path)) {
45-
value = mapObj(value, makeMapper(path));
45+
value = mapObject(value, makeMapper(path));
4646
}
4747
}
4848

@@ -65,13 +65,13 @@ const camelCaseConvert = (input, options) => {
6565
return [key, value];
6666
};
6767

68-
return mapObj(input, makeMapper(undefined));
68+
return mapObject(input, makeMapper(undefined));
6969
};
7070

71-
module.exports = (input, options) => {
71+
export default function camelcaseKeys(input, options) {
7272
if (Array.isArray(input)) {
7373
return Object.keys(input).map(key => camelCaseConvert(input[key], options));
7474
}
7575

7676
return camelCaseConvert(input, options);
77-
};
77+
}

0 commit comments

Comments
 (0)