Skip to content

Commit 14c3ff0

Browse files
authored
Merge pull request #150 from webdeveric/dev
Remove `lodash` dependencies
2 parents 1f9165c + fbad5f7 commit 14c3ff0

File tree

10 files changed

+806
-722
lines changed

10 files changed

+806
-722
lines changed

package.json

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
"url": "https://github.com/webdeveric/utils/issues"
6767
},
6868
"homepage": "https://github.com/webdeveric/utils/#readme",
69-
"packageManager": "pnpm@9.11.0+sha512.0a203ffaed5a3f63242cd064c8fb5892366c103e328079318f78062f24ea8c9d50bc6a47aa3567cabefd824d170e78fa2745ed1f16b132e16436146b7688f19b",
69+
"packageManager": "pnpm@9.13.2+sha512.88c9c3864450350e65a33587ab801acf946d7c814ed1134da4a924f6df5a2120fd36b46aab68f7cd1d413149112d53c7db3a4136624cfd00ff1846a0c6cef48a",
7070
"scripts": {
7171
"clean": "rimraf ./dist/",
7272
"prebuild": "pnpm clean",
@@ -87,29 +87,23 @@
8787
"prepare": "husky"
8888
},
8989
"prettier": "@webdeveric/prettier-config",
90-
"dependencies": {
91-
"lodash.clonedeep": "^4.5.0",
92-
"lodash.escaperegexp": "^4.1.2"
93-
},
9490
"devDependencies": {
95-
"@types/lodash.clonedeep": "^4.5.9",
96-
"@types/lodash.escaperegexp": "^4.1.9",
97-
"@types/node": "^20.16.10",
98-
"@vitest/coverage-v8": "^2.1.1",
91+
"@types/node": "^20.17.6",
92+
"@vitest/coverage-v8": "^2.1.5",
9993
"@webdeveric/eslint-config-ts": "^0.11.0",
10094
"@webdeveric/prettier-config": "^0.3.0",
101-
"cspell": "^8.14.4",
95+
"cspell": "^8.16.0",
10296
"eslint": "^8.57.1",
10397
"eslint-config-prettier": "^9.1.0",
10498
"eslint-import-resolver-typescript": "^3.6.3",
105-
"eslint-plugin-import": "^2.30.0",
106-
"husky": "^9.1.6",
99+
"eslint-plugin-import": "^2.31.0",
100+
"husky": "^9.1.7",
107101
"jsdom": "^25.0.1",
108102
"lint-staged": "^15.2.10",
109103
"prettier": "^3.3.3",
110104
"rimraf": "^6.0.1",
111-
"typescript": "^5.6.2",
105+
"typescript": "^5.6.3",
112106
"validate-package-exports": "^0.7.0",
113-
"vitest": "^2.1.1"
107+
"vitest": "^2.1.5"
114108
}
115109
}

pnpm-lock.yaml

Lines changed: 731 additions & 690 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/describeInput.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,24 @@ import { isNumericString } from './predicate/isNumericString.js';
44

55
export const describeInput = (input: unknown): string => {
66
switch (typeof input) {
7+
case 'boolean':
8+
case 'symbol':
9+
return input.toString();
10+
case 'function': {
11+
const args = input.toString().match(/^(function\s*\w*)?(?<args>\([^)]*\))/)?.groups?.args;
12+
13+
return `${input.name || 'anonymous'}${args}`;
14+
}
715
case 'string':
816
{
917
if (isNumericString(input)) {
1018
return 'Numeric String';
1119
}
1220

13-
const tokenMatch = input.match(/^(Basic|Bearer)\s.+/i);
21+
const authType = input.match(/^(?<authType>Basic|Bearer)\s.+/i)?.groups?.authType;
1422

15-
if (Array.isArray(tokenMatch) && tokenMatch[1]) {
16-
return tokenMatch[1];
23+
if (authType) {
24+
return `${authType} Authorization`;
1725
}
1826

1927
if (looksLikeURL(input)) {
@@ -27,26 +35,31 @@ export const describeInput = (input: unknown): string => {
2735
}
2836
}
2937
break;
30-
case 'number':
31-
if (input === Infinity) {
32-
return 'Infinity';
38+
case 'number': {
39+
if (input === Number.POSITIVE_INFINITY) {
40+
return 'Positive Infinity';
3341
}
3442

35-
if (input === -Infinity) {
43+
if (input === Number.NEGATIVE_INFINITY) {
3644
return 'Negative Infinity';
3745
}
3846

47+
if (Number.isSafeInteger(input)) {
48+
return 'Safe Integer';
49+
}
50+
3951
if (Number.isInteger(input)) {
4052
return 'Integer';
4153
}
4254

4355
if (Number.isFinite(input)) {
44-
return 'Number';
56+
return 'Finite Number';
4557
}
4658

4759
if (Number.isNaN(input)) {
4860
return 'NaN';
4961
}
62+
}
5063
}
5164

5265
return getType(input);

src/escapeRegExp.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const pattern = /[.*+?^${}()|[\]\\]/g;
2+
3+
export function escapeRegExp(input: string): string {
4+
return input.length ? input.replace(pattern, '\\$&') : input;
5+
}

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export * from './delay.js';
2020
export * from './delayAnimationFrame.js';
2121
export * from './delayAnimationFrames.js';
2222
export * from './describeInput.js';
23+
export * from './escapeRegExp.js';
2324
export * from './getDateString.js';
2425
export * from './getISODateString.js';
2526
export * from './getMaxValue.js';

src/normalize.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import cloneDeep from 'lodash.clonedeep';
2-
31
import { getOwnProperties } from './getOwnProperties.js';
42
import { isObject } from './predicate/isObject.js';
53

@@ -63,7 +61,7 @@ export function normalize<Data extends object, ContextData extends AnyRecord = A
6361
normalizers: AnyNormalizer<Data, Data, ContextData>,
6462
initContextData: ContextInitializer<Data, ContextData> = (): AnyRecord => ({}),
6563
): Data {
66-
const current = cloneDeep(input);
64+
const current = structuredClone(input);
6765

6866
const context: NormalizeContext<Data, ContextData> = Object.seal({
6967
original: input,

src/trimEnd.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import escapeRegExp from 'lodash.escaperegexp';
1+
import { escapeRegExp } from './escapeRegExp.js';
22

33
export function trimEnd(str: string, char?: string): string {
44
return char ? str.replace(new RegExp(`${escapeRegExp(char)}+$`), '') : str.trimEnd();

src/trimStart.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import escapeRegExp from 'lodash.escaperegexp';
1+
import { escapeRegExp } from './escapeRegExp.js';
22

33
export function trimStart(str: string, char?: string): string {
44
return char ? str.replace(new RegExp(`^${escapeRegExp(char)}+`), '') : str.trimStart();

test/describeInput.test.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,33 @@ import { describeInput } from '../src/describeInput.js';
44

55
describe('describeInput()', () => {
66
it('Returns a string describing the input', () => {
7+
expect(describeInput(true)).toBe('true');
8+
expect(describeInput(false)).toBe('false');
79
expect(describeInput({})).toBe('Object');
8-
expect(describeInput(Infinity)).toBe('Infinity');
10+
expect(describeInput([])).toBe('Array');
11+
expect(describeInput(new Set())).toBe('Set');
12+
expect(describeInput(() => {})).toBe('anonymous()');
13+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
14+
expect(describeInput(function namedFunction(_name: unknown) {})).toBe('namedFunction(_name)');
15+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
16+
expect(describeInput(function (_name: unknown) {})).toBe('anonymous(_name)');
17+
expect(describeInput(Infinity)).toBe('Positive Infinity');
18+
expect(describeInput(Number.POSITIVE_INFINITY)).toBe('Positive Infinity');
919
expect(describeInput(-Infinity)).toBe('Negative Infinity');
10-
expect(describeInput(1)).toBe('Integer');
11-
expect(describeInput(1.2)).toBe('Number');
20+
expect(describeInput(Number.NEGATIVE_INFINITY)).toBe('Negative Infinity');
21+
expect(describeInput(-1)).toBe('Safe Integer');
22+
expect(describeInput(2 ** 52)).toBe('Safe Integer');
23+
expect(describeInput(2 ** 53)).toBe('Integer');
24+
expect(describeInput(1.2)).toBe('Finite Number');
1225
expect(describeInput(Number.NaN)).toBe('NaN');
1326
expect(describeInput('123')).toBe('Numeric String');
14-
expect(describeInput('Basic TOKEN')).toBe('Basic');
15-
expect(describeInput('Bearer TOKEN')).toBe('Bearer');
27+
expect(describeInput('Basic TOKEN')).toBe('Basic Authorization');
28+
expect(describeInput('Bearer TOKEN')).toBe('Bearer Authorization');
1629
expect(describeInput('ftp://example.com/')).toContain('URL');
1730
expect(describeInput('https://user:[email protected]/')).toContain('credentials');
1831
expect(describeInput('https:///')).toBe('Invalid URL');
1932
expect(describeInput('Test')).toBe('String');
33+
expect(describeInput(Symbol())).toBe('Symbol()');
34+
expect(describeInput(Symbol('test'))).toBe('Symbol(test)');
2035
});
2136
});

test/escapeRegExp.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { describe, expect, it } from 'vitest';
2+
3+
import { escapeRegExp } from '../src/escapeRegExp.js';
4+
5+
describe('escapeRegExp()', () => {
6+
it('escapes special regexp characters', () => {
7+
expect(escapeRegExp('')).toBe('');
8+
expect(escapeRegExp('test')).toBe('test');
9+
expect(escapeRegExp('\\')).toBe('\\\\');
10+
expect(escapeRegExp('image.jpg')).toBe('image\\.jpg');
11+
expect(escapeRegExp('star*')).toBe('star\\*');
12+
expect(escapeRegExp('{}')).toBe('\\{\\}');
13+
expect(escapeRegExp('[]')).toBe('\\[\\]');
14+
expect(escapeRegExp('()')).toBe('\\(\\)');
15+
expect(escapeRegExp('^|+$')).toBe('\\^\\|\\+\\$');
16+
});
17+
});

0 commit comments

Comments
 (0)