nhb-toolbox 4.13.0 β 4.13.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -1
- package/README.md +56 -23
- package/dist/cjs/pluralize/Pluralizer.js +47 -22
- package/dist/cjs/pluralize/rules.js +100 -87
- package/dist/cjs/string/convert.js +2 -0
- package/dist/dts/pluralize/Pluralizer.d.ts +16 -9
- package/dist/dts/pluralize/Pluralizer.d.ts.map +1 -1
- package/dist/dts/pluralize/rules.d.ts +5 -0
- package/dist/dts/pluralize/rules.d.ts.map +1 -1
- package/dist/dts/string/convert.d.ts +2 -0
- package/dist/dts/string/convert.d.ts.map +1 -1
- package/dist/esm/pluralize/Pluralizer.js +48 -23
- package/dist/esm/pluralize/rules.js +99 -86
- package/dist/esm/string/convert.js +2 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,7 +6,16 @@ All notable changes to the package will be documented here.
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
## [4.13.
|
|
9
|
+
## [4.13.3] - 2025-07-22
|
|
10
|
+
|
|
11
|
+
- **Updated** pluralization/uncountable rules, case restoration method and fixed other bugs in `pluralizer`.
|
|
12
|
+
- **Updated** docs for `pluralizer`, `Pluralizer` and `formatUnitWithPlural`.
|
|
13
|
+
|
|
14
|
+
## [4.13.1] - 2025-07-22
|
|
15
|
+
|
|
16
|
+
- **Updated** docs in [README](README.md) for `pluralizer`.
|
|
17
|
+
|
|
18
|
+
## [4.13.0] - 2025-07-22
|
|
10
19
|
|
|
11
20
|
- **Added** new `Pluralizer` class and utility `pluralizer` (shared instance of `Pluralizer` class) with multiple methods.
|
|
12
21
|
- **Refactored** codes in number utilities, introduced new `normalizeNumber` utility.
|
package/README.md
CHANGED
|
@@ -68,7 +68,7 @@ See [Changelog](CHANGELOG.md) for recent updates.
|
|
|
68
68
|
|
|
69
69
|
## Signature Utilities
|
|
70
70
|
|
|
71
|
-
### π°οΈ
|
|
71
|
+
### π°οΈ Chronos - Time Mastery
|
|
72
72
|
|
|
73
73
|
The ultimate date/time manipulation class with 100+ methods for parsing, formatting, calculating, and comparing dates. Handles all edge cases and timezones safely.
|
|
74
74
|
|
|
@@ -82,7 +82,9 @@ chronos('2025-01-01').addDays(3).format('YYYY-MM-DD'); // "2025-01-04"
|
|
|
82
82
|
|
|
83
83
|
[Documentation β](https://nhb-toolbox.vercel.app/docs/classes/Chronos)
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
### π¨ Color - Professional Color Manipulation
|
|
86
88
|
|
|
87
89
|
Convert between color formats, generate palettes, check accessibility contrast, and perform advanced color math with perfect type safety.
|
|
88
90
|
|
|
@@ -94,7 +96,9 @@ console.log(darkerBlue.hsl); // "hsl(240, 100%, 40%)" (was 50%)
|
|
|
94
96
|
|
|
95
97
|
[Documentation β](https://nhb-toolbox.vercel.app/docs/classes/Color)
|
|
96
98
|
|
|
97
|
-
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
### π Finder - Optimized Array Search
|
|
98
102
|
|
|
99
103
|
Blazing-fast array searching with binary search, fuzzy matching, and smart caching. Perfect for large datasets.
|
|
100
104
|
|
|
@@ -109,9 +113,11 @@ const laptop = productFinder.findOne('laptop', 'category', {
|
|
|
109
113
|
|
|
110
114
|
[Documentation β](https://nhb-toolbox.vercel.app/docs/classes/Finder)
|
|
111
115
|
|
|
112
|
-
|
|
116
|
+
---
|
|
113
117
|
|
|
114
|
-
|
|
118
|
+
### π Random ID Generation
|
|
119
|
+
|
|
120
|
+
**`generateRandomID`** - Enterprise-grade unique ID generation with prefixes, timestamps, and formatting.
|
|
115
121
|
|
|
116
122
|
```typescript
|
|
117
123
|
generateRandomID({
|
|
@@ -124,7 +130,32 @@ generateRandomID({
|
|
|
124
130
|
|
|
125
131
|
[Documentation β](https://nhb-toolbox.vercel.app/docs/utilities/string/generateRandomID)
|
|
126
132
|
|
|
127
|
-
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
### π’ Pluralize Strings and More
|
|
136
|
+
|
|
137
|
+
**`pluralizer`** - Handles English word pluralization and singularization with support for irregular forms and uncountable nouns.
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
import { pluralizer } from 'nhb-toolbox';
|
|
141
|
+
|
|
142
|
+
pluralizer.pluralize('child'); // "children"
|
|
143
|
+
pluralizer.pluralize('category', { count: 3 }); // "categories"
|
|
144
|
+
pluralizer.pluralize('child', { count: 1, inclusive: true }); // "1 child"
|
|
145
|
+
|
|
146
|
+
pluralizer.toSingular('geese'); // "goose"
|
|
147
|
+
pluralizer.toSingular('children'); // "child"
|
|
148
|
+
|
|
149
|
+
pluralizer.isPlural('children'); // true
|
|
150
|
+
pluralizer.isSingular('child'); // true
|
|
151
|
+
pluralizer.isPlural('fish'); // false (uncountable)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
[Documentation β](https://nhb-toolbox.vercel.app/docs/utilities/string/pluralizer)
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
### π¨ Color System Utilities
|
|
128
159
|
|
|
129
160
|
**`getColorForInitial`** - Deterministic color mapping system for consistent UI theming
|
|
130
161
|
|
|
@@ -138,6 +169,8 @@ getColorForInitial('Banana', 50); // '#00376E80' (50% opacity)
|
|
|
138
169
|
|
|
139
170
|
[Documentation β](https://nhb-toolbox.vercel.app/docs/utilities/color/getColorForInitial)
|
|
140
171
|
|
|
172
|
+
---
|
|
173
|
+
|
|
141
174
|
### FormData Preparation
|
|
142
175
|
|
|
143
176
|
Convert JavaScript objects into `FormData` with extensive configuration options for handling nested structures, files, and data transformations.
|
|
@@ -169,7 +202,9 @@ const formData = createFormData({
|
|
|
169
202
|
|
|
170
203
|
[Documentation β](https://nhb-toolbox.vercel.app/docs/utilities/form/createFormData)
|
|
171
204
|
|
|
172
|
-
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
### π‘οΈ Data Sanitization
|
|
173
208
|
|
|
174
209
|
Clean and normalize strings/objects by trimming whitespace, removing empty values, and applying customizable filters.
|
|
175
210
|
|
|
@@ -192,7 +227,9 @@ sanitizeData(user, { ignoreNullish: true }, 'partial');
|
|
|
192
227
|
|
|
193
228
|
[Documentation β](https://nhb-toolbox.vercel.app/docs/utilities/object/sanitizeData)
|
|
194
229
|
|
|
195
|
-
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
### π JSON Hydration
|
|
196
233
|
|
|
197
234
|
**`parseJSON`** - Bulletproof JSON parsing with primitive conversion
|
|
198
235
|
|
|
@@ -202,19 +239,9 @@ parseJSON('{"value":"42"}'); // { value: 42 } (auto-converts numbers)
|
|
|
202
239
|
|
|
203
240
|
[Documentation β](https://nhb-toolbox.vercel.app/docs/utilities/misc/parseJSON)
|
|
204
241
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
Intelligent currency formatting with automatic locale detection and 150+ supported currencies.
|
|
208
|
-
|
|
209
|
-
```typescript
|
|
210
|
-
console.log(formatCurrency(99.99, 'EUR')); // "99,99 β¬"
|
|
211
|
-
console.log(formatCurrency('5000', 'JPY')); // "οΏ₯5,000" (ja-JP locale)
|
|
212
|
-
console.log(formatCurrency('5000', 'BDT')); // "৫,০০০.০০৳" (bn-BD locale)
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
[Documentation β](https://nhb-toolbox.vercel.app/docs/utilities/number/formatCurrency)
|
|
242
|
+
---
|
|
216
243
|
|
|
217
|
-
### π’
|
|
244
|
+
### π’ Number to Words
|
|
218
245
|
|
|
219
246
|
Convert numbers to human-readable words (supports up to 100 quintillion).
|
|
220
247
|
|
|
@@ -224,7 +251,9 @@ numberToWords(125); // "one hundred twenty-five"
|
|
|
224
251
|
|
|
225
252
|
[Documentation β](https://nhb-toolbox.vercel.app/docs/utilities/number/numberToWords)
|
|
226
253
|
|
|
227
|
-
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
### π’ Advanced Number Operations
|
|
228
257
|
|
|
229
258
|
**`getNumbersInRange`** - Generate intelligent number sequences with prime, even/odd, and custom filtering capabilities
|
|
230
259
|
|
|
@@ -249,7 +278,9 @@ calculatePercentage({
|
|
|
249
278
|
|
|
250
279
|
[Documentation β](https://nhb-toolbox.vercel.app/docs/utilities/number/calculatePercentage)
|
|
251
280
|
|
|
252
|
-
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
### π Extract Updated Fields
|
|
253
284
|
|
|
254
285
|
Detect exactly what changed between two objects (including deep nested changes).
|
|
255
286
|
|
|
@@ -262,7 +293,9 @@ extractUpdatedFields(dbRecord, update);
|
|
|
262
293
|
|
|
263
294
|
[Documentation β](https://nhb-toolbox.vercel.app/docs/utilities/object/extractUpdatedFields)
|
|
264
295
|
|
|
265
|
-
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
### β‘ Performance Optimizers
|
|
266
299
|
|
|
267
300
|
**`throttleAction`** - Precision control for high-frequency events
|
|
268
301
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.pluralizer = exports.Pluralizer = void 0;
|
|
4
|
+
const primitives_1 = require("../guards/primitives");
|
|
4
5
|
const utilities_1 = require("../number/utilities");
|
|
5
6
|
const rules_1 = require("./rules");
|
|
6
7
|
/**
|
|
@@ -12,6 +13,11 @@ const rules_1 = require("./rules");
|
|
|
12
13
|
* - Automatically loads common irregular forms and uncountable nouns.
|
|
13
14
|
* - Supports options for count-based pluralization, allowing for inclusive formatting.
|
|
14
15
|
* - This class is useful for applications that need to handle natural language processing, such as chatbots, content management systems, or any text processing tasks that require accurate pluralization.
|
|
16
|
+
*
|
|
17
|
+
* @remarks For simpler pluralization (plural with only 's'), please refer to {@link https://nhb-toolbox.vercel.app/docs/utilities/string/formatUnitWithPlural formatUnitWithPlural} instead.
|
|
18
|
+
*
|
|
19
|
+
* @remarks For ready to use instance, please refer to {@link https://nhb-toolbox.vercel.app/docs/utilities/string/pluralizer pluralizer} instead.
|
|
20
|
+
*
|
|
15
21
|
* @example
|
|
16
22
|
* const pluralizer = new Pluralizer();
|
|
17
23
|
* pluralizer.pluralize('child'); // "children"
|
|
@@ -26,7 +32,7 @@ class Pluralizer {
|
|
|
26
32
|
#irregularPlurals = {};
|
|
27
33
|
/**
|
|
28
34
|
* Initializes the Pluralizer with default rules and exceptions.
|
|
29
|
-
* Automatically loads irregular
|
|
35
|
+
* Automatically loads irregular, pluralization and singular rules along with pre-defined uncountable nouns.
|
|
30
36
|
*/
|
|
31
37
|
constructor() {
|
|
32
38
|
this.#loadRules();
|
|
@@ -40,21 +46,38 @@ class Pluralizer {
|
|
|
40
46
|
rules_1.pluralRules.forEach(([rule, replacement]) => {
|
|
41
47
|
this.addPluralRule(rule, replacement);
|
|
42
48
|
});
|
|
49
|
+
// ! Load singular rules
|
|
50
|
+
rules_1.singularRules.forEach(([rule, replacement]) => {
|
|
51
|
+
this.addSingularRule(rule, replacement);
|
|
52
|
+
});
|
|
43
53
|
// ! Load uncountables
|
|
44
54
|
rules_1.uncountables.forEach((word) => {
|
|
45
55
|
this.addUncountable(word);
|
|
46
56
|
});
|
|
47
57
|
}
|
|
48
|
-
#restoreCase(
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
58
|
+
#restoreCase(original, transformed) {
|
|
59
|
+
let result = '';
|
|
60
|
+
for (let i = 0; i < transformed.length; i++) {
|
|
61
|
+
const origChar = original[i];
|
|
62
|
+
if (origChar) {
|
|
63
|
+
if (origChar.toUpperCase() === origChar &&
|
|
64
|
+
origChar.toLowerCase() !== origChar) {
|
|
65
|
+
result += transformed[i].toUpperCase();
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
result += transformed[i].toLowerCase();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
result += transformed[i].toLowerCase();
|
|
73
|
+
}
|
|
53
74
|
}
|
|
54
|
-
return
|
|
75
|
+
return result;
|
|
55
76
|
}
|
|
56
77
|
#sanitizeWord(word, rules) {
|
|
57
|
-
if (!
|
|
78
|
+
if (!(0, primitives_1.isNonEmptyString)(word))
|
|
79
|
+
return '';
|
|
80
|
+
if (this.#isUncountable(word)) {
|
|
58
81
|
return word;
|
|
59
82
|
}
|
|
60
83
|
for (let i = rules.length - 1; i >= 0; i--) {
|
|
@@ -70,7 +93,7 @@ class Pluralizer {
|
|
|
70
93
|
* Supports both string and RegExp entries.
|
|
71
94
|
*/
|
|
72
95
|
#isUncountable(word) {
|
|
73
|
-
const lower = word
|
|
96
|
+
const lower = word?.toLowerCase();
|
|
74
97
|
for (const entry of this.#uncountables) {
|
|
75
98
|
if (typeof entry === 'string') {
|
|
76
99
|
if (entry === lower)
|
|
@@ -94,7 +117,7 @@ class Pluralizer {
|
|
|
94
117
|
this.#pluralRules.push([rule, replacement]);
|
|
95
118
|
}
|
|
96
119
|
/**
|
|
97
|
-
* Add a new singularization rule.
|
|
120
|
+
* * Add a new singularization rule.
|
|
98
121
|
* @param rule Pattern to match plural words.
|
|
99
122
|
* @param replacement Replacement pattern for singular form.
|
|
100
123
|
* @example
|
|
@@ -104,23 +127,23 @@ class Pluralizer {
|
|
|
104
127
|
this.#singularRules.push([rule, replacement]);
|
|
105
128
|
}
|
|
106
129
|
addUncountable(word) {
|
|
107
|
-
this.#uncountables.add(typeof word === 'string' ? word
|
|
130
|
+
this.#uncountables.add(typeof word === 'string' ? word?.toLowerCase() : word);
|
|
108
131
|
}
|
|
109
132
|
/**
|
|
110
|
-
* Add a word or pattern that should never change between singular and plural.
|
|
133
|
+
* * Add a word or pattern that should never change between singular and plural.
|
|
111
134
|
* @param word A word or regex pattern.
|
|
112
135
|
* @example
|
|
113
136
|
* pluralizer.addUncountable('fish');
|
|
114
137
|
* pluralizer.addUncountable(/pok[eΓ©]mon$/i);
|
|
115
138
|
*/
|
|
116
139
|
addIrregular(single, plural) {
|
|
117
|
-
const singleLower = single
|
|
118
|
-
const pluralLower = plural
|
|
140
|
+
const singleLower = single?.toLowerCase();
|
|
141
|
+
const pluralLower = plural?.toLowerCase();
|
|
119
142
|
this.#irregularSingles[singleLower] = pluralLower;
|
|
120
143
|
this.#irregularPlurals[pluralLower] = singleLower;
|
|
121
144
|
}
|
|
122
145
|
/**
|
|
123
|
-
* Get the proper singular or plural form based on count.
|
|
146
|
+
* * Get the proper singular or plural form based on optional count.
|
|
124
147
|
* @param word Target word to pluralize or singularize.
|
|
125
148
|
* @param options Optional count and inclusive formatting.
|
|
126
149
|
* @returns The transformed word.
|
|
@@ -137,14 +160,14 @@ class Pluralizer {
|
|
|
137
160
|
return this.toPlural(word);
|
|
138
161
|
}
|
|
139
162
|
/**
|
|
140
|
-
* Convert a word to its plural form.
|
|
163
|
+
* * Convert a word to its plural form.
|
|
141
164
|
* @param word Singular form of the word.
|
|
142
165
|
* @returns Plural form of the word.
|
|
143
166
|
* @example
|
|
144
167
|
* pluralizer.toPlural('analysis'); // "analyses"
|
|
145
168
|
*/
|
|
146
169
|
toPlural(word) {
|
|
147
|
-
if (!word)
|
|
170
|
+
if (!(0, primitives_1.isNonEmptyString)(word))
|
|
148
171
|
return '';
|
|
149
172
|
const lower = word.toLowerCase();
|
|
150
173
|
if (this.#isUncountable(word))
|
|
@@ -155,14 +178,14 @@ class Pluralizer {
|
|
|
155
178
|
return this.#restoreCase(word, this.#sanitizeWord(lower, this.#pluralRules));
|
|
156
179
|
}
|
|
157
180
|
/**
|
|
158
|
-
* Convert a word to its singular form.
|
|
181
|
+
* * Convert a word to its singular form.
|
|
159
182
|
* @param word Plural form of the word.
|
|
160
183
|
* @returns Singular form of the word.
|
|
161
184
|
* @example
|
|
162
185
|
* pluralizer.toSingular('geese'); // "goose"
|
|
163
186
|
*/
|
|
164
187
|
toSingular(word) {
|
|
165
|
-
if (!word)
|
|
188
|
+
if (!(0, primitives_1.isNonEmptyString)(word))
|
|
166
189
|
return '';
|
|
167
190
|
const lower = word.toLowerCase();
|
|
168
191
|
if (this.#isUncountable(word))
|
|
@@ -173,7 +196,7 @@ class Pluralizer {
|
|
|
173
196
|
return this.#restoreCase(word, this.#sanitizeWord(lower, this.#singularRules));
|
|
174
197
|
}
|
|
175
198
|
/**
|
|
176
|
-
* Check if a given word is plural.
|
|
199
|
+
* * Check if a given word is plural.
|
|
177
200
|
* @param word Word to check.
|
|
178
201
|
* @returns True if the word is plural, otherwise false.
|
|
179
202
|
* @example
|
|
@@ -188,7 +211,7 @@ class Pluralizer {
|
|
|
188
211
|
return this.toSingular(lower) !== lower;
|
|
189
212
|
}
|
|
190
213
|
/**
|
|
191
|
-
* Check if a given word is singular.
|
|
214
|
+
* * Check if a given word is singular.
|
|
192
215
|
* @param word Word to check.
|
|
193
216
|
* @returns True if the word is singular, otherwise false.
|
|
194
217
|
* @example
|
|
@@ -205,11 +228,13 @@ class Pluralizer {
|
|
|
205
228
|
}
|
|
206
229
|
exports.Pluralizer = Pluralizer;
|
|
207
230
|
/**
|
|
208
|
-
* Default shared instance of {@link Pluralizer}.
|
|
231
|
+
* Default shared instance of {@link https://nhb-toolbox.vercel.app/docs/classes/Pluralizer Pluralizer}.
|
|
209
232
|
*
|
|
210
233
|
* - _Use this when you donβt need multiple configurations._
|
|
211
234
|
* - _It comes preloaded with standard pluralization rules, irregular forms, and uncountable nouns._
|
|
212
235
|
*
|
|
236
|
+
* @remarks For simpler pluralization (plural with only 's'), please refer to {@link https://nhb-toolbox.vercel.app/docs/utilities/string/formatUnitWithPlural formatUnitWithPlural} instead.
|
|
237
|
+
*
|
|
213
238
|
* * Handles English word pluralization and singularization with support for irregular forms and uncountable nouns.
|
|
214
239
|
*
|
|
215
240
|
* - Provides methods to convert words between singular and plural forms, check if a word is plural or singular, and manage custom pluralization rules.
|