@akadenia/helpers 1.7.3 → 1.8.0

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/README.MD CHANGED
@@ -1,543 +1,1008 @@
1
- ## Getting Started
1
+ <div align="center">
2
+ <img src="https://cdn.akadenia.com/images/akadenia-webp/logo/horizontal-logo.svg" alt="Akadenia" width="200" />
2
3
 
4
+ ## @akadenia/helpers
5
+
6
+ <img src="https://cdn.akadenia.com/images/badges/npm-version-helpers.svg" alt="npm version" />
7
+ <img src="https://cdn.akadenia.com/images/badges/license-mit.svg" alt="License: MIT" />
8
+ <img src="https://cdn.akadenia.com/images/badges/typescript.svg" alt="TypeScript" />
9
+
10
+ A comprehensive collection of utility functions for common JavaScript/TypeScript operations including date manipulation, text processing, object handling, map calculations, and more.
11
+
12
+ [Documentation](https://akadenia.com/packages/akadenia-helpers) • [GitHub](https://github.com/akadenia/AkadeniaHelpers) • [Issues](https://github.com/akadenia/AkadeniaHelpers/issues)
13
+ </div>
14
+
15
+ ## Features
16
+
17
+ - **Date Helpers**: Comprehensive date manipulation and formatting utilities
18
+ - **Text Helpers**: String processing, validation, and transformation functions
19
+ - **Object Helpers**: Object manipulation, filtering, and utility functions
20
+ - **Map Helpers**: Geographical calculations and coordinate operations
21
+ - **Generic Helpers**: General utility functions for common operations
22
+ - **File Helpers**: File validation and processing utilities
23
+ - **TypeScript Support**: Full type definitions included
24
+ - **Zero Dependencies**: Lightweight with no external dependencies
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ npm install @akadenia/helpers
30
+ ```
31
+
32
+ ## Usage
33
+
34
+ ```typescript
35
+ import { DateHelpers, TextHelpers, ObjectHelpers, MapHelpers, GenericHelpers, FileHelpers } from '@akadenia/helpers'
36
+ ```
37
+
38
+ ## Table of Contents
39
+
40
+ - [Installation](#installation)
41
+ - [Usage](#usage)
3
42
  - [DateHelpers](#datehelpers)
4
- - [`DateHelpers.getReadableDateTime(datetime)`](#datehelpersgetreadabledatetimedatetime)
5
- - [`DateHelpers.getReadableDate(datetime)`](#datehelpersgetreadabledatedatetime)
6
- - [`DateHelpers.getDateString(date)`](#datehelpersgetdatestringdate)
7
- - [`DateHelpers.parseDate(date)`](#datehelpersparsedatedate)
8
- - [`DateHelpers.getShortOrdinalDate(date)`](#datehelpersgetshortordinaldatedate)
9
- - [MapHelpers](#maphelpers)
10
- - [`MapHelpers.getDistanceBetweenPoints(point1, point2)`](#maphelpersgetdistancebetweenpointspoint1-point2)
11
- - [`MapHelpers.compareLocations(location1, location2, precision)`](#maphelperscomparelocationslocation1-location2-precision)
12
- - [`MapHelpers.getBearingToCoordinate({startCoordinate, endCoordinate})`](#maphelpersgetbearingtocoordinatestartcoordinate-endcoordinate)
13
43
  - [TextHelpers](#texthelpers)
14
- - [`TextHelpers.uuidv4()`](#texthelpersuuidv4)
15
- - [`TextHelpers.formatPosition(position)`](#texthelpersformatpositionposition)
16
- - [`TextHelpers.truncateText(text, characterLimit)`](#texthelperstruncatetexttext-characterlimit)
17
- - [`TextHelpers.fileNameFromPath(path)`](#texthelpersfilenamefrompathpath)
18
- - [`TextHelpers.replaceSpacesWithUnderscore(s)`](#texthelpersreplacespaceswithunderscores)
19
- - [`TextHelpers.replaceUnderscoreWithSpaces(s)`](#texthelpersreplaceunderscorewithspacess)
20
- - [`TextHelpers.pluralizeOnCondition(word, condition)`](#texthelperspluralizeonconditionword-condition)
21
- - [`TextHelpers.convertSnakeToCamelCase(data)`](#texthelpersconvertsnaketocamelcasedata)
22
- - [`TextHelpers.convertCamelToSnakeCase(data)`](#texthelpersconvertcameltosnakecasedata)
23
- - [`TextHelpers.convertCamelToKebabCase(data)`](#texthelpersconvertcameltokebabcasedata)
24
- - [`TextHelpers.convertKebabToCamelCase(data)`](#texthelpersconvertkebabtocamelcasedata)
25
- - [`TextHelpers.generateAcronym(term)`](#texthelpersgenerateacronymterm)
26
- - [`TextHelpers.isAcronym(data)`](#texthelpersisacronymdata)
27
- - [`TextHelpers.acronymToKebabCase(data)`](#texthelpersacronymtokebabcasedata)
28
- - [`TextHelpers.handleNullDisplay(value, defaultValue="N/A")`](#texthelpershandlenulldisplayvalue-defaultvaluena)
29
- - [`TextHelpers.enforceCharacterLimit({text, characterLimit, onCharacterLimit})`](#texthelpersenforcecharacterlimittext-characterlimit-oncharacterlimit)
30
- - [`TextHelpers.isValidEmail(email)`](#texthelpersisvalidemailemail)
31
- - [`TextHelpers.generateIdFromWord(word)`](#texthelpersgenerateidfromwordword)
32
- - [`TextHelpers.generateWordFromId(word)`](#texthelpersgeneratewordfromidword)
33
- - [`TextHelpers.generateSlugFromWords(id, ...words)`](#texthelpersgenerateslugfromwordsid-words)
34
- - [`TextHelpers.extractIDfromSlug(slug)`](#texthelpersextractidfromslugslug)
35
- - [`TextHelpers.abbreviateNumber(number)`](#texthelpersabbreviatenumbernumber)
36
44
  - [ObjectHelpers](#objecthelpers)
37
- - [`ObjectHelpers.isPureObject(any)`](#objecthelpersispureobjectany)
38
- - [`ObjectHelpers.parseCookie(str)`](#objecthelpersparsecookiestr)
39
- - [`ObjectHelpers.filterObjectsByProperty ( array, propertyName, propertyValue)`](#objecthelpersfilterobjectsbyproperty--array-propertyname-propertyvalue)
40
- - [`ObjectHelpers.containsSubObject(mainObject, subObject)`](#objecthelperscontainssubobjectmainobject-subobject)
41
- - [`ObjectHelpers.findObjectBySubObject(array, subObject)`](#objecthelpersfindobjectbysubobjectarray-subobject)
42
- - [`ObjectHelpers.filterObjectsBySubObject(array, subObject)`](#objecthelpersfilterobjectsbysubobjectarray-subobject)
43
- - [`ObjectHelpers.objectPropHasValue({object, key, value)}`](#objecthelpersobjectprophasvalueobject-key-value)
44
- - [`ObjectHelpers.findEntry(array, predicate)`](#objecthelpersfindentryarray-predicate)
45
+ - [MapHelpers](#maphelpers)
45
46
  - [GenericHelpers](#generichelpers)
46
- - [`GenericHelpers.delay(ms)`](#generichelpersdelayms)
47
- - [`GenericHelpers.getPreferredUriScheme(host)`](#generichelpersgetpreferredurischemehost)
48
47
  - [FileHelpers](#filehelpers)
49
- - [`FileHelpers.checkFileExtension(filePath, validExtensions)`](#filehelperscheckfileextensionfilepath-validextensions)
50
- - [Contributing to this package](#contributing-to-this-package)
48
+ - [Contributing](#contributing)
51
49
  - [License](#license)
52
50
 
53
51
  ## DateHelpers
54
52
 
55
- Import the DateHelpers utility.
56
-
57
- `import { DateHelpers } from "@akadenia/helpers`
53
+ Utility functions for date and time operations.
58
54
 
59
- ## `DateHelpers.getReadableDateTime(datetime)`
55
+ ### `getReadableDateTime(datetime?)`
60
56
 
61
57
  Returns the date in `yyyy-mm-dd hh:mm:ss` format.
62
58
 
63
- Arguments
64
- |Name|Type|Required|Description|
65
- |--|--|--|--|
66
- |`datetime`|`Date`|`false`|The date to convert to readable date time. Default is current datetime. i.e. `new Date()`|
59
+ **Parameters:**
60
+ - `datetime` (optional): `Date` - The date to convert. Defaults to current date.
67
61
 
68
- ## `DateHelpers.getReadableDate(datetime)`
62
+ **Example:**
63
+ ```typescript
64
+ import { DateHelpers } from '@akadenia/helpers'
65
+
66
+ // Using current date
67
+ const now = DateHelpers.getReadableDateTime()
68
+ console.log(now) // "2024-01-15 14:30:25"
69
+
70
+ // Using specific date
71
+ const specificDate = DateHelpers.getReadableDateTime(new Date('2024-01-15T10:30:00Z'))
72
+ console.log(specificDate) // "2024-01-15 10:30:00"
73
+ ```
74
+
75
+ ### `getReadableDate(datetime?)`
69
76
 
70
77
  Returns the date in `yyyy-mm-dd` format.
71
78
 
72
- Arguments
73
- |Name|Type|Required|Description|
74
- |--|--|--|--|
75
- |`datetime`|`Date`|`false`|The date to convert to readable date time. Default is current datetime. i.e. `new Date()`|
79
+ **Parameters:**
80
+ - `datetime` (optional): `Date` - The date to convert. Defaults to current date.
81
+
82
+ **Example:**
83
+ ```typescript
84
+ const date = DateHelpers.getReadableDate()
85
+ console.log(date) // "2024-01-15"
86
+
87
+ const specificDate = DateHelpers.getReadableDate(new Date('2024-01-15T10:30:00Z'))
88
+ console.log(specificDate) // "2024-01-15"
89
+ ```
76
90
 
77
- ## `DateHelpers.getDateString(date)`
91
+ ### `getDateString(date)`
78
92
 
79
93
  Returns a string representing the date in the user's local timezone.
80
94
 
81
- Arguments
82
- |Name|Type|Required|Description|
83
- |--|--|--|--|
84
- |`date`|`string` or `Date`|`true`|The date string to convert to the string in the user's local timezone|
95
+ **Parameters:**
96
+ - `date`: `string | Date` - The date to convert.
85
97
 
86
- ## `DateHelpers.parseDate(date)`
98
+ **Example:**
99
+ ```typescript
100
+ const dateString = DateHelpers.getDateString('2024-01-15')
101
+ console.log(dateString) // "1/15/2024" (format depends on locale)
102
+
103
+ const dateString2 = DateHelpers.getDateString(new Date('2024-01-15T10:30:00Z'))
104
+ console.log(dateString2) // "1/15/2024"
105
+ ```
106
+
107
+ ### `formatDateTime(date, options, localTimezone?)`
87
108
 
88
- Returns a date representing the new date object.
109
+ Returns a formatted date string using Intl.DateTimeFormat options.
110
+
111
+ **Parameters:**
112
+ - `date`: `string | Date` - The date to format.
113
+ - `options`: `Intl.DateTimeFormatOptions` - Formatting options.
114
+ - `localTimezone` (optional): `string | Intl.Locale` - Locale for formatting. Defaults to "en-US".
115
+
116
+ **Example:**
117
+ ```typescript
118
+ const formatted = DateHelpers.formatDateTime(
119
+ new Date('2024-01-15T10:30:00Z'),
120
+ {
121
+ year: 'numeric',
122
+ month: 'long',
123
+ day: 'numeric',
124
+ hour: '2-digit',
125
+ minute: '2-digit'
126
+ },
127
+ 'en-US'
128
+ )
129
+ console.log(formatted) // "January 15, 2024 at 10:30 AM"
130
+ ```
131
+
132
+ ### `parseDate(date)`
133
+
134
+ Returns a Date object from a string or Date input. Throws an error for invalid dates.
135
+
136
+ **Parameters:**
137
+ - `date`: `string | Date` - The date to parse.
138
+
139
+ **Example:**
140
+ ```typescript
141
+ const parsedDate = DateHelpers.parseDate('2024-01-15')
142
+ console.log(parsedDate) // Date object for 2024-01-15
89
143
 
90
- Arguments
91
- |Name|Type|Required|Description|
92
- |--|--|--|--|
93
- |`date`|`string`|`true`|The date string that needs to be returned as a date object|
144
+ const parsedDate2 = DateHelpers.parseDate('invalid-date')
145
+ // Throws: Error: Cannot parse date: "invalid-date"
146
+ ```
94
147
 
95
- ## `DateHelpers.getShortOrdinalDate(date)`
148
+ ### `getShortOrdinalDate(date, appendTime?)`
96
149
 
97
150
  Returns a string representing the date in short ordinal format.
98
151
 
99
- Arguments
100
- |Name|Type|Required|Description|
101
- |--|--|--|--|
102
- |`date`|`string`|`true`|The date string that needs to be formatted|
152
+ **Parameters:**
153
+ - `date`: `string | Date` - The date to format.
154
+ - `appendTime` (optional): `boolean` - Whether to include time. Defaults to false.
103
155
 
104
- # MapHelpers
156
+ **Example:**
157
+ ```typescript
158
+ const ordinalDate = DateHelpers.getShortOrdinalDate('2024-01-15')
159
+ console.log(ordinalDate) // "Jan 15th 2024"
105
160
 
106
- Import the MapHelpers utility.
161
+ const ordinalDateTime = DateHelpers.getShortOrdinalDate('2024-01-15T10:30:00Z', true)
162
+ console.log(ordinalDateTime) // "Jan 15th 2024 10:30:00"
163
+ ```
107
164
 
108
- `import { MapHelpers } from "@akadenia/helpers`
165
+ ## MapHelpers
109
166
 
110
- ## `MapHelpers.getDistanceBetweenPoints(point1, point2)`
167
+ Utility functions for geographical calculations and map operations.
111
168
 
112
- Returns the distance between two points in meters. Returns `null` if either point is invalid.
169
+ ### `getDistanceBetweenPoints(point1, point2)`
113
170
 
114
- Arguments
115
- |Name|Type|Required|Description|
116
- |--|--|--|--|
117
- |`point1`|`Array<number>`|false| The coordinates of the first point. i.e. `[lat, lng]` |
118
- |`point2`|`Array<number>`|false|The coordinates of the second point. i.e. `[lat, lng]`|
171
+ Calculates the distance between two geographical points using the Haversine formula.
119
172
 
120
- ## `MapHelpers.compareLocations(location1, location2, precision)`
173
+ **Parameters:**
174
+ - `point1`: `number[] | undefined` - First point coordinates [longitude, latitude].
175
+ - `point2`: `number[] | undefined` - Second point coordinates [longitude, latitude].
121
176
 
122
- Returns a boolean value that indicates whether or not the two locations are the same based on precision provided.
177
+ **Example:**
178
+ ```typescript
179
+ // Distance between New York and Los Angeles
180
+ const nyc = [-74.006, 40.7128] // [lng, lat]
181
+ const la = [-118.2437, 34.0522] // [lng, lat]
182
+
183
+ const distance = MapHelpers.getDistanceBetweenPoints(nyc, la)
184
+ console.log(distance) // 3944419.5 (meters, approximately 3944 km)
185
+
186
+ // Returns null for invalid points
187
+ const invalid = MapHelpers.getDistanceBetweenPoints(nyc, undefined)
188
+ console.log(invalid) // null
189
+ ```
123
190
 
124
- Arguments
125
- |Name|Type|Required|Description|
126
- |--|--|--|--|
127
- |`location1`|`Array<number>`|false| The coordinates of the first location. i.e. `[lat, lng]` |
128
- |`location2`|`Array<number>`|false|The coordinates of the second location. i.e. `[lat, lng]`|
129
- |`precision`|`number`|false|The precision to compare the locations to. Default is `6`|
191
+ ### `compareLocations(location1, location2, precision?)`
130
192
 
131
- ## `MapHelpers.getBearingToCoordinate({startCoordinate, endCoordinate})`
193
+ Compares two locations to see if they are the same within a specified precision.
194
+
195
+ **Parameters:**
196
+ - `location1`: `number[] | undefined` - First location coordinates [longitude, latitude].
197
+ - `location2`: `number[] | undefined` - Second location coordinates [longitude, latitude].
198
+ - `precision` (optional): `number` - Decimal precision for comparison. Defaults to 6.
199
+
200
+ **Example:**
201
+ ```typescript
202
+ const loc1 = [-74.006, 40.7128]
203
+ const loc2 = [-74.006001, 40.712801] // Very close to loc1
204
+ const loc3 = [-74.01, 40.72] // Further from loc1
205
+
206
+ console.log(MapHelpers.compareLocations(loc1, loc2)) // true (within 6 decimal precision)
207
+ console.log(MapHelpers.compareLocations(loc1, loc3)) // false
208
+ console.log(MapHelpers.compareLocations(loc1, loc2, 3)) // true (within 3 decimal precision)
209
+
210
+ // Throws error for undefined locations
211
+ MapHelpers.compareLocations(loc1, undefined) // Error: location1 and location2 are required
212
+ ```
132
213
 
133
- Returns the bearing to the end coordinate from the start coordinate in degrees.
214
+ ### `getBearingToCoordinate({startCoordinate, endCoordinate})`
134
215
 
135
- Arguments
136
- |Name|Type|Required|Description|
137
- |--|--|--|--|
138
- |`coordinates`|`object`|`true`|An object containing the start and end coordinates. i.e. `{startCoordinate: [lat, lng], endCoordinate: [lat, lng]}`|
216
+ Calculates the bearing (direction) from one coordinate to another in degrees.
217
+
218
+ **Parameters:**
219
+ - `startCoordinate`: `number[] | undefined` - Starting point [longitude, latitude].
220
+ - `endCoordinate`: `number[] | undefined` - Ending point [longitude, latitude].
221
+
222
+ **Example:**
223
+ ```typescript
224
+ const start = [-74.006, 40.7128] // New York
225
+ const end = [-118.2437, 34.0522] // Los Angeles
226
+
227
+ const bearing = MapHelpers.getBearingToCoordinate({ startCoordinate: start, endCoordinate: end })
228
+ console.log(bearing) // 277.5 (degrees, approximately west)
229
+
230
+ // Throws error for undefined coordinates
231
+ MapHelpers.getBearingToCoordinate({ startCoordinate: start, endCoordinate: undefined })
232
+ // Error: startCoordinate and endCoordinate are required
233
+ ```
139
234
 
140
235
  ## TextHelpers
141
236
 
142
- Import the TextHelpers utility.
237
+ Utility functions for text manipulation and processing.
143
238
 
144
- `import { TextHelpers } from "@akadenia/helpers`
239
+ ### `uuidv4()`
145
240
 
146
- ## `TextHelpers.uuidv4()`
241
+ Returns a randomly generated UUID v4 string.
147
242
 
148
- Returns a randomly generated string.
243
+ **Example:**
244
+ ```typescript
245
+ const id = TextHelpers.uuidv4()
246
+ console.log(id) // "f47ac10b-58cc-4372-a567-0e02b2c3d479"
247
+ ```
149
248
 
150
- Arguments
151
- |Name|Type|Required|Description|
152
- |--|--|--|--|
249
+ ### `formatPosition(position)`
153
250
 
154
- ## `TextHelpers.formatPosition(position)`
251
+ Returns a string position with appropriate suffix (st, nd, rd, th).
155
252
 
156
- Returns a string position for a provided number. eg. `"2nd"`, `"3rd"` etc.
253
+ **Parameters:**
254
+ - `position`: `number` - The position number.
157
255
 
158
- Arguments
159
- |Name|Type|Required|Description|
160
- |--|--|--|--|
161
- |`position`|`number`|`true`|A position number to add the appropriate suffix to|
256
+ **Example:**
257
+ ```typescript
258
+ console.log(TextHelpers.formatPosition(1)) // "1st"
259
+ console.log(TextHelpers.formatPosition(2)) // "2nd"
260
+ console.log(TextHelpers.formatPosition(3)) // "3rd"
261
+ console.log(TextHelpers.formatPosition(4)) // "4th"
262
+ console.log(TextHelpers.formatPosition(21)) // "21st"
263
+ ```
162
264
 
163
- ## `TextHelpers.truncateText(text, characterLimit)`
265
+ ### `truncateText(text, characterLimit)`
164
266
 
165
- Returns a string ending in an ellipsis `...` or returns the input string if maximum character limit isn't met.
267
+ Returns truncated text with ellipsis if it exceeds the character limit.
166
268
 
167
- Arguments
168
- |Name|Type|Required|Description|
169
- |--|--|--|--|
170
- |`text`|`string`|`true`|The text to truncate|
171
- |`characterLimit`|`number`|`true`|The target number of characters to truncate text to|
269
+ **Parameters:**
270
+ - `text`: `string` - The text to truncate.
271
+ - `characterLimit`: `number` - Maximum number of characters.
172
272
 
173
- ## `TextHelpers.fileNameFromPath(path)`
273
+ **Example:**
274
+ ```typescript
275
+ const short = TextHelpers.truncateText("Hello World", 5)
276
+ console.log(short) // "He..."
174
277
 
175
- Returns a file name.
278
+ const long = TextHelpers.truncateText("Hello World", 20)
279
+ console.log(long) // "Hello World"
280
+ ```
176
281
 
177
- Arguments
178
- |Name|Type|Required|Description|
179
- |--|--|--|--|
180
- |`path`|`string`|`true`|The path to extract the file name from|
282
+ ### `fileNameFromPath(path)`
181
283
 
182
- ## `TextHelpers.replaceSpacesWithUnderscore(s)`
284
+ Extracts the filename from a file path.
183
285
 
184
- Returns a string where the spaces have been replaced with underscores.
286
+ **Parameters:**
287
+ - `path`: `string` - The file path.
185
288
 
186
- Arguments
187
- |Name|Type|Required|Description|
188
- |--|--|--|--|
189
- |`s`|`string`|`false`|The text to replace spaces with underscores in|
289
+ **Example:**
290
+ ```typescript
291
+ const filename = TextHelpers.fileNameFromPath('/path/to/file.txt')
292
+ console.log(filename) // "file.txt"
190
293
 
191
- ## `TextHelpers.replaceUnderscoreWithSpaces(s)`
294
+ const filename2 = TextHelpers.fileNameFromPath('C:\\Users\\file.pdf')
295
+ console.log(filename2) // "file.pdf"
296
+ ```
192
297
 
193
- Returns a string where the underscores have been replaced with spaces.
298
+ ### `replaceSpacesWithUnderscore(s?)`
194
299
 
195
- Arguments
196
- |Name|Type|Required|Description|
197
- |--|--|--|--|
198
- |`s`|`string`|`false`|The text to replace underscores with spaces in|
300
+ Replaces spaces with underscores in a string.
199
301
 
200
- ## `TextHelpers.pluralizeOnCondition(word, condition)`
302
+ **Parameters:**
303
+ - `s` (optional): `string` - The string to process.
201
304
 
202
- Returns a pluralised version of the input string or returns the same string.
305
+ **Example:**
306
+ ```typescript
307
+ const result = TextHelpers.replaceSpacesWithUnderscore("hello world test")
308
+ console.log(result) // "hello_world_test"
203
309
 
204
- Arguments
205
- |Name|Type|Required|Description|
206
- |--|--|--|--|
207
- |`word`|`string`|`true`|The word to pluralise|
208
- |`condition`|`boolean`|`true`|The condition that determines whether to plurize the input word|
310
+ const result2 = TextHelpers.replaceSpacesWithUnderscore()
311
+ console.log(result2) // ""
312
+ ```
209
313
 
210
- ## `TextHelpers.convertSnakeToCamelCase(data)`
314
+ ### `replaceUnderscoreWithSpaces(s?)`
211
315
 
212
- Returns the input object or array with all object keys recursively transformed to camelCase. Returns input object if type is invalid.
316
+ Replaces underscores with spaces in a string.
213
317
 
214
- Arguments
215
- |Name|Type|Required|Description|
216
- |--|--|--|--|
217
- |`data`|`Object` or `Array<Object>`|`true`|The object whose keys to transform|
318
+ **Parameters:**
319
+ - `s` (optional): `string` - The string to process.
218
320
 
219
- ## `TextHelpers.convertCamelToSnakeCase(data)`
321
+ **Example:**
322
+ ```typescript
323
+ const result = TextHelpers.replaceUnderscoreWithSpaces("hello_world_test")
324
+ console.log(result) // "hello world test"
325
+ ```
220
326
 
221
- Returns the input object or array with all object keys recursively transformed to snake_case. Returns input object if type is invalid.
327
+ ### `pluralizeOnCondition(word, condition)`
222
328
 
223
- Arguments
224
- |Name|Type|Required|Description|
225
- |--|--|--|--|
226
- |`data`|`Object` or `Array<Object>`|`true`|The object whose keys to transform|
329
+ Returns pluralized version of the word if condition is true.
227
330
 
228
- ## `TextHelpers.convertCamelToKebabCase(data)`
331
+ **Parameters:**
332
+ - `word`: `string` - The word to pluralize.
333
+ - `condition`: `boolean` - Whether to pluralize.
229
334
 
230
- Convert camel case to kebab case
231
- The word returned as kebab case
335
+ **Example:**
336
+ ```typescript
337
+ const plural = TextHelpers.pluralizeOnCondition("item", true)
338
+ console.log(plural) // "items"
232
339
 
233
- Arguments
234
- |Name|Type|Required|Description|
235
- |--|--|--|--|
236
- |`data`|`string`|The word needed to be converted to kebab case from camel case|
340
+ const plural2 = TextHelpers.pluralizeOnCondition("address", true)
341
+ console.log(plural2) // "addresses"
237
342
 
238
- ## `TextHelpers.convertKebabToCamelCase(data)`
343
+ const plural3 = TextHelpers.pluralizeOnCondition("library", true)
344
+ console.log(plural3) // "libraries"
239
345
 
240
- Convert kebab case to camel case
241
- The word returned as camel case
346
+ const singular = TextHelpers.pluralizeOnCondition("item", false)
347
+ console.log(singular) // "item"
348
+ ```
242
349
 
243
- Arguments
244
- |Name|Type|Required|Description|
245
- |--|--|--|--|
246
- |`data`|`string`|The word needed to be converted from kebab case to camel case|
350
+ ### `convertSnakeToCamelCase(data)`
247
351
 
248
- ## `TextHelpers.generateAcronym(term)`
352
+ Converts snake_case to camelCase for strings, objects, or arrays of objects.
249
353
 
250
- Generate an acronym from a term
251
- an acronym generated from the term
354
+ **Parameters:**
355
+ - `data`: `string | Object | Array<Object>` - The data to convert.
252
356
 
253
- Arguments
254
- |Name|Type|Required|Description|
255
- |--|--|--|--|
256
- |`term`|`string`|The term to be converted to an acronym|
357
+ **Example:**
358
+ ```typescript
359
+ // String conversion
360
+ const camelString = TextHelpers.convertSnakeToCamelCase("hello_world")
361
+ console.log(camelString) // "helloWorld"
362
+
363
+ // Object conversion
364
+ const camelObject = TextHelpers.convertSnakeToCamelCase({
365
+ first_name: "John",
366
+ last_name: "Doe",
367
+ user_info: {
368
+ phone_number: "123-456-7890"
369
+ }
370
+ })
371
+ console.log(camelObject)
372
+ // {
373
+ // firstName: "John",
374
+ // lastName: "Doe",
375
+ // userInfo: {
376
+ // phoneNumber: "123-456-7890"
377
+ // }
378
+ // }
379
+ ```
257
380
 
258
- ## `TextHelpers.isAcronym(data)`
381
+ ### `convertCamelToSnakeCase(data)`
259
382
 
260
- Validate if a word is acronym
261
- The boolean value when the condition is met
383
+ Converts camelCase to snake_case for strings, objects, or arrays of objects.
262
384
 
263
- Arguments
264
- |Name|Type|Required|Description|
265
- |--|--|--|--|
266
- |`data`|`string`|The word that is being validated as acronym|
385
+ **Parameters:**
386
+ - `data`: `string | Object | Array<Object>` - The data to convert.
267
387
 
268
- ## `TextHelpers.acronymToKebabCase(data)`
388
+ **Example:**
389
+ ```typescript
390
+ // String conversion
391
+ const snakeString = TextHelpers.convertCamelToSnakeCase("helloWorld")
392
+ console.log(snakeString) // "hello_world"
393
+
394
+ // Object conversion
395
+ const snakeObject = TextHelpers.convertCamelToSnakeCase({
396
+ firstName: "John",
397
+ lastName: "Doe",
398
+ userInfo: {
399
+ phoneNumber: "123-456-7890"
400
+ }
401
+ })
402
+ console.log(snakeObject)
403
+ // {
404
+ // first_name: "John",
405
+ // last_name: "Doe",
406
+ // user_info: {
407
+ // phone_number: "123-456-7890"
408
+ // }
409
+ // }
410
+ ```
269
411
 
270
- Convert acronym to kebab case
271
- The word returned as camel case
412
+ ### `convertCamelToKebabCase(word)`
272
413
 
273
- Arguments
274
- |Name|Type|Required|Description|
275
- |--|--|--|--|
276
- |`data`|`string`|The acronym to be converted to kebab case|
414
+ Converts camelCase to kebab-case.
277
415
 
278
- ## `TextHelpers.handleNullDisplay(value, defaultValue="N/A")`
416
+ **Parameters:**
417
+ - `word`: `string` - The word to convert.
279
418
 
280
- Returns the input string or the default string if the input value is null or undefined.
281
- Arguments
282
- |Name|Type|Required|Description|
283
- |--|--|--|--|
284
- |`value`|`string`|`true`|The string to display in the ui|
285
- |`defaultValue`|`string`|`false`|The default string to display if the input value is null or undefined defaults to `N/A`|
419
+ **Example:**
420
+ ```typescript
421
+ const kebab = TextHelpers.convertCamelToKebabCase("helloWorld")
422
+ console.log(kebab) // "hello-world"
286
423
 
287
- ## `TextHelpers.enforceCharacterLimit({text, characterLimit, onCharacterLimit})`
424
+ const kebab2 = TextHelpers.convertCamelToKebabCase("XMLHttpRequest")
425
+ console.log(kebab2) // "xml-http-request"
426
+ ```
288
427
 
289
- Returns the input string if the character limit is not exceeded or returns the truncated string when the character limit is exceeded. Calls the `onCharacterLimit` callback when the character limit is exceeded.
290
- Arguments
291
- |Name|Type|Required|Description|
292
- |--|--|--|--|
293
- |`text`|`string`|`true`|The string to truncate|
294
- |`characterLimit`|`number`|`true`|The target number of characters to truncate text to|
295
- |`onCharacterLimit`|`function`|`true`|The callback to call when the character limit is exceeded|
428
+ ### `convertKebabToCamelCase(word)`
296
429
 
297
- ## `TextHelpers.isValidEmail(email)`
430
+ Converts kebab-case to camelCase.
298
431
 
299
- Returns true when the email is a proper email and returns false when the email is not a proper email
300
- Arguments
301
- |Name|Type|Required|Description|
302
- |--|--|--|--|
303
- |`email`|`string`|`true`|The email to be validated|
432
+ **Parameters:**
433
+ - `word`: `string` - The word to convert.
304
434
 
305
- ## `TextHelpers.generateIdFromWord(word)`
435
+ **Example:**
436
+ ```typescript
437
+ const camel = TextHelpers.convertKebabToCamelCase("hello-world")
438
+ console.log(camel) // "HelloWorld"
306
439
 
307
- Generate ID from word
308
- Returns the generated ID from the word
440
+ const camel2 = TextHelpers.convertKebabToCamelCase("xml-http-request")
441
+ console.log(camel2) // "XmlHttpRequest"
442
+ ```
309
443
 
310
- Arguments
311
- |Name|Type|Required|Description|
312
- |--|--|--|--|
313
- |`word`|`string`|`true`|The word needed to generate ID from|
444
+ ### `convertCamelCaseToReadableText(name)`
314
445
 
315
- ## `TextHelpers.generateWordFromId(word)`
446
+ Converts camelCase to readable text format with proper capitalization.
316
447
 
317
- Get the word from the generated ID
318
- Returns the word that is got from the id
448
+ **Parameters:**
319
449
 
320
- Arguments
321
- |Name|Type|Required|Description|
322
- |--|--|--|--|
323
- |`words`|`string`|`true`|The id that is needed to get the word from|
324
- |`customList`|`Record<string, string>`|`false`|The custom lists that has the id with the custom list of words|
450
+ - `name`: `string` - The camelCase string to convert.
325
451
 
326
- ## `TextHelpers.generateSlugFromWords(id, ...words)`
452
+ **Example:**
327
453
 
328
- Get the slug from words
329
- Returns the slug from the words and it will be url path safe
454
+ ```typescript
455
+ const readable = TextHelpers.convertCamelCaseToReadableText("helloWorld")
456
+ console.log(readable) // "Hello World"
330
457
 
331
- Arguments
332
- |Name|Type|Required|Description|
333
- |--|--|--|--|
334
- |`id`|`string`|`true`|The id that is needed to be concatenated with the slug|
335
- |`words`|`string[]`|`true`|The words that will be in the slug|
458
+ const readable2 = TextHelpers.convertCamelCaseToReadableText("XMLHttpRequest")
459
+ console.log(readable2) // "XML Http Request"
336
460
 
337
- ## `TextHelpers.extractIDfromSlug(slug)`
461
+ const readable3 = TextHelpers.convertCamelCaseToReadableText("userName")
462
+ console.log(readable3) // "User Name"
463
+ ```
338
464
 
339
- Extracts the id from the slug
340
- Returns the id from the slug
341
- Throws error if the string is empty, null or undefined
465
+ ### `generateAcronym(term)`
342
466
 
343
- Arguments
344
- |Name|Type|Required|Description|
345
- |--|--|--|--|
346
- |`slug`|`string`|`true`|The slug associated with the id|
467
+ Generates an acronym from a term.
347
468
 
348
- ## `TextHelpers.abbreviateNumber(number)`
469
+ **Parameters:**
470
+ - `term`: `string` - The term to convert to acronym.
349
471
 
350
- Returns the string representation of the abbreviated number, rounded to two decimal places.
472
+ **Example:**
473
+ ```typescript
474
+ const acronym = TextHelpers.generateAcronym("Hyper Text Markup Language")
475
+ console.log(acronym) // "HTML"
351
476
 
352
- Arguments
353
- |Name|Type|Required|Description|
354
- |--|--|--|--|
355
- |`number`|`number`|`true`|The number to be abbreviated|
477
+ const acronym2 = TextHelpers.generateAcronym("JavaScript Object Notation")
478
+ console.log(acronym2) // "JSON"
479
+ ```
356
480
 
357
- Examples
481
+ ### `isAcronym(word)`
358
482
 
359
- - Numbers below 1,000 are displayed without abbreviation
360
- - Numbers between 1,000 and 1,000,000 are displayed in thousands (e.g. 1.23K)
361
- - Numbers between 1,000,000 and 1,000,000,000 are displayed in millions (e.g. 1.23M)
362
- - Numbers above 1,000,000,000 are displayed in billions (e.g. 1.23B)
483
+ Validates if a word is an acronym (all uppercase).
363
484
 
364
- Note: If the input `number` is null or undefined, the function returns null.
485
+ **Parameters:**
486
+ - `word`: `string` - The word to validate.
365
487
 
366
- ## ObjectHelpers
488
+ **Example:**
489
+ ```typescript
490
+ console.log(TextHelpers.isAcronym("HTML")) // true
491
+ console.log(TextHelpers.isAcronym("html")) // false
492
+ console.log(TextHelpers.isAcronym("JavaScript")) // false
493
+ ```
494
+
495
+ ### `acronymToKebabCase(word)`
496
+
497
+ Converts an acronym to kebab-case.
498
+
499
+ **Parameters:**
500
+ - `word`: `string` - The acronym to convert.
501
+
502
+ **Example:**
503
+ ```typescript
504
+ const kebab = TextHelpers.acronymToKebabCase("HTML")
505
+ console.log(kebab) // "h-t-m-l"
506
+
507
+ const kebab2 = TextHelpers.acronymToKebabCase("API")
508
+ console.log(kebab2) // "a-p-i"
509
+
510
+ // Throws error if not an acronym
511
+ TextHelpers.acronymToKebabCase("html") // Error: The text passed: html is not an acronym.
512
+ ```
513
+
514
+ ### `handleNullDisplay(value, defaultValue?)`
515
+
516
+ Returns the value or a default string if the value is null or undefined.
517
+
518
+ **Parameters:**
519
+ - `value`: `string | null | undefined` - The value to display.
520
+ - `defaultValue` (optional): `string` - Default value. Defaults to "N/A".
521
+
522
+ **Example:**
523
+ ```typescript
524
+ console.log(TextHelpers.handleNullDisplay("Hello")) // "Hello"
525
+ console.log(TextHelpers.handleNullDisplay(null)) // "N/A"
526
+ console.log(TextHelpers.handleNullDisplay(undefined)) // "N/A"
527
+ console.log(TextHelpers.handleNullDisplay(null, "No data")) // "No data"
528
+ ```
529
+
530
+ ### `capitalizeText(text?)`
531
+
532
+ Capitalizes the first letter of a text.
367
533
 
368
- Import the ObjectHelpers utility.
534
+ **Parameters:**
535
+ - `text` (optional): `string` - The text to capitalize.
369
536
 
370
- `import { ObjectHelpers } from "@akadenia/helpers`
537
+ **Example:**
538
+ ```typescript
539
+ console.log(TextHelpers.capitalizeText("hello world")) // "Hello world"
540
+ console.log(TextHelpers.capitalizeText("HELLO")) // "Hello"
541
+ console.log(TextHelpers.capitalizeText()) // ""
542
+ ```
543
+
544
+ ### `enforceCharacterLimit({text, characterLimit, onCharacterLimit})`
545
+
546
+ Enforces a character limit and calls a callback when exceeded.
547
+
548
+ **Parameters:**
549
+ - `text`: `string` - The text to limit.
550
+ - `characterLimit`: `number` - Maximum characters allowed.
551
+ - `onCharacterLimit`: `() => void` - Callback when limit is exceeded.
552
+
553
+ **Example:**
554
+ ```typescript
555
+ const result = TextHelpers.enforceCharacterLimit({
556
+ text: "This is a very long text that exceeds the limit",
557
+ characterLimit: 10,
558
+ onCharacterLimit: () => console.log("Character limit exceeded!")
559
+ })
560
+ console.log(result) // "This is a" (truncated)
561
+ // Console: "Character limit exceeded!"
562
+ ```
563
+
564
+ ### `isValidEmail(email)`
565
+
566
+ Validates if an email address is properly formatted.
567
+
568
+ **Parameters:**
569
+ - `email`: `string` - The email to validate.
570
+
571
+ **Example:**
572
+ ```typescript
573
+ console.log(TextHelpers.isValidEmail("user@example.com")) // true
574
+ console.log(TextHelpers.isValidEmail("invalid-email")) // false
575
+ console.log(TextHelpers.isValidEmail("user@domain.co.uk")) // true
576
+ console.log(TextHelpers.isValidEmail("")) // false
577
+ ```
578
+
579
+ ### `generateIDFromWord(text)`
371
580
 
372
- ## `ObjectHelpers.isPureObject(any)`
581
+ Generates an ID from a word by converting to lowercase and replacing spaces with hyphens.
373
582
 
374
- Returns a boolean indicating whether or not the input is a pure object.
583
+ **Parameters:**
584
+ - `text`: `string` - The text to convert to ID.
375
585
 
376
- Arguments
377
- |Name|Type|Required|Description|
378
- |--|--|--|--|
379
- |`object`|`any`|`true`|The object to test for pureness|
586
+ **Example:**
587
+ ```typescript
588
+ const id = TextHelpers.generateIDFromWord("Hello World Test")
589
+ console.log(id) // "hello-world-test"
380
590
 
381
- ## `ObjectHelpers.parseCookie(str)`
591
+ const id2 = TextHelpers.generateIDFromWord("My Awesome Feature")
592
+ console.log(id2) // "my-awesome-feature"
593
+ ```
382
594
 
383
- Returns an object containing the key-value pairs of the parsed cookies.
595
+ ### `generateWordFromId(id, customList?)`
384
596
 
385
- Arguments
386
- |Name|Type|Required|Description|
387
- |--|--|--|--|
388
- |`str`|`string`|`true`|The string of cookies to parse|
597
+ Converts an ID back to a readable word format.
389
598
 
390
- ## `ObjectHelpers.filterObjectsByProperty ( array, propertyName, propertyValue)`
599
+ **Parameters:**
600
+ - `id`: `string` - The ID to convert.
601
+ - `customList` (optional): `Record<string, string>` - Custom mapping for specific IDs.
391
602
 
392
- Filter an array of objects based on a specific property and its corresponding value.
393
- Returns an array containing all objects that have the specified property with the given value.
603
+ **Example:**
604
+ ```typescript
605
+ const word = TextHelpers.generateWordFromId("hello-world-test")
606
+ console.log(word) // "Hello World Test"
607
+
608
+ const customWord = TextHelpers.generateWordFromId("api", { "api": "Application Programming Interface" })
609
+ console.log(customWord) // "Application Programming Interface"
610
+ ```
394
611
 
395
- Template
612
+ ### `generateSlugFromWordsWithID(id, ...words)`
396
613
 
614
+ Generates a URL-safe slug from an ID and additional words.
615
+
616
+ **Parameters:**
617
+ - `id`: `string` - The ID to include in the slug.
618
+ - `...words`: `string[]` - Additional words to include.
619
+
620
+ **Example:**
397
621
  ```typescript
398
- T extends Record<string, any>
622
+ const slug = TextHelpers.generateSlugFromWordsWithID("user", "profile", "settings")
623
+ console.log(slug) // "profile-settings-user"
624
+
625
+ const slug2 = TextHelpers.generateSlugFromWordsWithID("123", "hello world", "test")
626
+ console.log(slug2) // "hello%20world-test-123"
399
627
  ```
400
628
 
401
- Arguments
402
- |Name|Type|Required|Description|
403
- |--|--|--|--|
404
- |`array`|`T[]`|`true`|An array of objects to be searched|
405
- |`propertyName`|`keyof T`|`true`|The name of the property to match against|
406
- |`propertyValue`|`T[keyof T]`|`true`|The value that the property should have to be considered|
629
+ ### `extractIDfromSlug(slug)`
630
+
631
+ Extracts the ID from a slug (last part after splitting by hyphens).
632
+
633
+ **Parameters:**
634
+ - `slug`: `string` - The slug to extract ID from.
635
+
636
+ **Example:**
637
+ ```typescript
638
+ const id = TextHelpers.extractIDfromSlug("hello-world-test-123")
639
+ console.log(id) // "123"
640
+
641
+ const id2 = TextHelpers.extractIDfromSlug("user-profile-abc")
642
+ console.log(id2) // "abc"
643
+
644
+ // Throws error for empty slug
645
+ TextHelpers.extractIDfromSlug("") // Error: slug cannot be empty, null or undefined string
646
+ ```
407
647
 
408
- ## `ObjectHelpers.containsSubObject(mainObject, subObject)`
648
+ ### `abbreviateNumber(number)`
409
649
 
410
- It compares the key-value pairs of the sub-object with the corresponding key-value pairs in the main object.
411
- Returns true If all key-value pairs in the sub-object are found in the main object; otherwise, it returns false.
650
+ Abbreviates large numbers with K, M, B suffixes.
412
651
 
413
- Template
652
+ **Parameters:**
653
+ - `number`: `number | undefined | null` - The number to abbreviate.
414
654
 
655
+ **Example:**
415
656
  ```typescript
416
- T extends Record<string, any>
657
+ console.log(TextHelpers.abbreviateNumber(500)) // "500"
658
+ console.log(TextHelpers.abbreviateNumber(1500)) // "1.5K"
659
+ console.log(TextHelpers.abbreviateNumber(1500000)) // "1.5M"
660
+ console.log(TextHelpers.abbreviateNumber(1500000000)) // "1.5B"
661
+ console.log(TextHelpers.abbreviateNumber(null)) // null
417
662
  ```
418
663
 
419
- Arguments
420
- |Name|Type|Required|Description|
421
- |--|--|--|--|
422
- |`mainObject`|`T`|`true`|The main object to be checked|
423
- |`subObject`|`Partial<T>`|`true`|The sub-object to be searched for|
664
+ ## ObjectHelpers
665
+
666
+ Utility functions for object manipulation and processing.
424
667
 
425
- ## `ObjectHelpers.findObjectBySubObject(array, subObject)`
668
+ ### `isPureObject(object)`
426
669
 
427
- Searches an array of objects for an object that contains a specific sub-object.
428
- Returns the first object found in the array that contains the sub-object or null
429
- if no match is found.
670
+ Checks if an object is a pure object (not array, date, or function).
430
671
 
431
- Template
672
+ **Parameters:**
673
+ - `object`: `any` - The object to check.
432
674
 
675
+ **Example:**
433
676
  ```typescript
434
- T extends Record<string, any>
677
+ console.log(ObjectHelpers.isPureObject({})) // true
678
+ console.log(ObjectHelpers.isPureObject([])) // false
679
+ console.log(ObjectHelpers.isPureObject(new Date())) // false
680
+ console.log(ObjectHelpers.isPureObject(() => {})) // false
681
+ console.log(ObjectHelpers.isPureObject("string")) // false
682
+ ```
683
+
684
+ ### `parseCookie(str)`
685
+
686
+ Parses a cookie string into an object.
687
+
688
+ **Parameters:**
689
+ - `str`: `string` - The cookie string to parse.
690
+
691
+ **Example:**
692
+ ```typescript
693
+ const cookies = ObjectHelpers.parseCookie("name=John; age=30; city=New York")
694
+ console.log(cookies) // { name: "John", age: "30", city: "New York" }
695
+
696
+ const cookies2 = ObjectHelpers.parseCookie("session=abc123; theme=dark")
697
+ console.log(cookies2) // { session: "abc123", theme: "dark" }
435
698
  ```
436
699
 
437
- Arguments
438
- |Name|Type|Required|Description|
439
- |--|--|--|--|
440
- |`array`|`T[]`|`true`|An array of objects to be searched|
441
- |`array`|`Partial<T>`|`true`|The sub-object to be searched for in the array|
700
+ ### `filterObjectsByProperty(array, propertyName, propertyValue)`
442
701
 
443
- ## `ObjectHelpers.filterObjectsBySubObject(array, subObject)`
702
+ Filters an array of objects based on a specific property and value.
444
703
 
445
- Filters an array of objects based on the presence of a specific sub-object within each object.
446
- Returns an array containing all objects from the input array that contain the specified sub-object.
704
+ **Parameters:**
705
+ - `array`: `T[]` - Array of objects to filter.
706
+ - `propertyName`: `keyof T` - Name of the property to filter on.
707
+ - `propertyValue`: `T[keyof T]` - Value to match.
447
708
 
448
- Template
709
+ **Example:**
710
+ ```typescript
711
+ const users = [
712
+ { id: 1, name: "John", age: 30 },
713
+ { id: 2, name: "Jane", age: 25 },
714
+ { id: 3, name: "John", age: 35 }
715
+ ]
716
+
717
+ const johns = ObjectHelpers.filterObjectsByProperty(users, "name", "John")
718
+ console.log(johns) // [{ id: 1, name: "John", age: 30 }, { id: 3, name: "John", age: 35 }]
719
+
720
+ const adults = ObjectHelpers.filterObjectsByProperty(users, "age", 30)
721
+ console.log(adults) // [{ id: 1, name: "John", age: 30 }]
722
+ ```
723
+
724
+ ### `containsSubObject(mainObject, subObject)`
725
+
726
+ Checks if the main object contains all key-value pairs from the sub-object.
727
+
728
+ **Parameters:**
729
+ - `mainObject`: `T` - The main object to check.
730
+ - `subObject`: `Partial<T>` - The sub-object to search for.
449
731
 
732
+ **Example:**
450
733
  ```typescript
451
- T extends Record<string, any>
734
+ const mainObj = { id: 1, name: "John", age: 30, city: "New York" }
735
+ const subObj = { name: "John", age: 30 }
736
+
737
+ console.log(ObjectHelpers.containsSubObject(mainObj, subObj)) // true
738
+
739
+ const subObj2 = { name: "Jane", age: 30 }
740
+ console.log(ObjectHelpers.containsSubObject(mainObj, subObj2)) // false
452
741
  ```
453
742
 
454
- Arguments
455
- |Name|Type|Required|Description|
456
- |--|--|--|--|
457
- |`array`|`T[]`|`true`|An array of objects to be filtered|
458
- |`array`|`Partial<T>`|`true`|The sub-object to be searched for in the array|
743
+ ### `findObjectBySubObject(array, subObject)`
744
+
745
+ Finds the first object in an array that contains the specified sub-object.
459
746
 
460
- ## `ObjectHelpers.objectPropHasValue({object, key, value)}`
747
+ **Parameters:**
748
+ - `array`: `T[]` - Array of objects to search.
749
+ - `subObject`: `Partial<T>` - The sub-object to search for.
461
750
 
462
- Checks if the object has the key with the value.
751
+ **Example:**
752
+ ```typescript
753
+ const users = [
754
+ { id: 1, name: "John", age: 30, city: "New York" },
755
+ { id: 2, name: "Jane", age: 25, city: "Boston" },
756
+ { id: 3, name: "Bob", age: 30, city: "Chicago" }
757
+ ]
758
+
759
+ const result = ObjectHelpers.findObjectBySubObject(users, { age: 30, city: "New York" })
760
+ console.log(result) // { id: 1, name: "John", age: 30, city: "New York" }
463
761
 
464
- Arguments
465
- |Name|Type|Required|Description|
466
- |--|--|--|--|
467
- |`object`|`Object`|`true`|The object to check|
468
- |`key`|`string`|`true`|The key to check|
469
- |`value`|`any`|`true`|The value to check|
762
+ const result2 = ObjectHelpers.findObjectBySubObject(users, { name: "Alice" })
763
+ console.log(result2) // null
764
+ ```
470
765
 
471
- ## `ObjectHelpers.findEntry(array, predicate)`
766
+ ### `filterObjectsBySubObject(array, subObject)`
472
767
 
473
- Finds the first entry in the array that satisfies the predicate.
768
+ Filters an array of objects based on containing the specified sub-object.
474
769
 
475
- Arguments
476
- |Name|Type|Required|Description|
477
- |--|--|--|--|
478
- |`array`|`Array<any>`|`true`|The array of entries to search|
479
- |`predicate`|`(item: any) => boolean`|`true`|The predicate function to use to search the array|
770
+ **Parameters:**
771
+ - `array`: `T[]` - Array of objects to filter.
772
+ - `subObject`: `Partial<T>` - The sub-object to search for.
773
+
774
+ **Example:**
775
+ ```typescript
776
+ const users = [
777
+ { id: 1, name: "John", age: 30, city: "New York" },
778
+ { id: 2, name: "Jane", age: 25, city: "Boston" },
779
+ { id: 3, name: "Bob", age: 30, city: "Chicago" }
780
+ ]
781
+
782
+ const results = ObjectHelpers.filterObjectsBySubObject(users, { age: 30 })
783
+ console.log(results) // [{ id: 1, name: "John", age: 30, city: "New York" }, { id: 3, name: "Bob", age: 30, city: "Chicago" }]
784
+ ```
785
+
786
+ ### `objectPropHasValue({object, propName, value})`
787
+
788
+ Checks if an object has a specific property with a specific value.
789
+
790
+ **Parameters:**
791
+ - `object`: `ObjectType` - The object to check.
792
+ - `propName`: `keyof ObjectType` - The property name.
793
+ - `value`: `ObjectType[keyof ObjectType]` - The expected value.
794
+
795
+ **Example:**
796
+ ```typescript
797
+ const user = { id: 1, name: "John", age: 30 }
798
+
799
+ console.log(ObjectHelpers.objectPropHasValue({ object: user, propName: "name", value: "John" })) // true
800
+ console.log(ObjectHelpers.objectPropHasValue({ object: user, propName: "age", value: 25 })) // false
801
+ ```
802
+
803
+ ### `findEntry(array, predicate)`
804
+
805
+ Finds the first entry in an array that satisfies a predicate function.
806
+
807
+ **Parameters:**
808
+ - `array`: `EntryType[]` - Array to search.
809
+ - `predicate`: `(item: EntryType) => boolean` - Predicate function.
810
+
811
+ **Example:**
812
+ ```typescript
813
+ const numbers = [1, 2, 3, 4, 5, 6]
814
+
815
+ const even = ObjectHelpers.findEntry(numbers, (n) => n % 2 === 0)
816
+ console.log(even) // 2
817
+
818
+ const greaterThan5 = ObjectHelpers.findEntry(numbers, (n) => n > 5)
819
+ console.log(greaterThan5) // 6
820
+
821
+ const greaterThan10 = ObjectHelpers.findEntry(numbers, (n) => n > 10)
822
+ console.log(greaterThan10) // null
823
+ ```
824
+
825
+ ### `convertArrayToMap(arrayData, keyProp)`
826
+
827
+ Converts an array of objects to a map using a specified key property.
828
+
829
+ **Parameters:**
830
+ - `arrayData`: `T[]` - Array of objects to convert.
831
+ - `keyProp`: `keyof T` - Property to use as the key.
832
+
833
+ **Example:**
834
+ ```typescript
835
+ const users = [
836
+ { id: 1, name: "John", age: 30 },
837
+ { id: 2, name: "Jane", age: 25 },
838
+ { id: 3, name: "Bob", age: 35 }
839
+ ]
840
+
841
+ const userMap = ObjectHelpers.convertArrayToMap(users, "id")
842
+ console.log(userMap)
843
+ // {
844
+ // "1": { id: 1, name: "John", age: 30 },
845
+ // "2": { id: 2, name: "Jane", age: 25 },
846
+ // "3": { id: 3, name: "Bob", age: 35 }
847
+ // }
848
+ ```
849
+
850
+ Converts object keys from camelCase to kebab-case.
851
+
852
+ **Parameters:**
853
+
854
+ - `obj`: `T | undefined` - The object to convert.
855
+
856
+ **Example:**
857
+
858
+ ```typescript
859
+ const camelCaseObj = { firstName: "John", lastName: "Doe", age: 30 }
860
+ const result = ObjectHelpers.convertObjectKeysToKebabCase(camelCaseObj)
861
+ console.log(result) // { "first-name": "John", "last-name": "Doe", age: 30 }
862
+
863
+ // Handles mixed case keys
864
+ const mixedObj = { firstName: "John", "last-name": "Doe", userName: "johndoe" }
865
+ const result2 = ObjectHelpers.convertObjectKeysToKebabCase(mixedObj)
866
+ console.log(result2) // { "first-name": "John", "last-name": "Doe", "user-name": "johndoe" }
867
+
868
+ // Returns undefined for undefined input
869
+ const result3 = ObjectHelpers.convertObjectKeysToKebabCase(undefined)
870
+ console.log(result3) // undefined
871
+ ```
480
872
 
481
873
  ## GenericHelpers
482
874
 
483
- Import the GenericHelpers utility.
875
+ General utility functions for common operations.
484
876
 
485
- `import { GenericHelpers } from "@akadenia/helpers`
877
+ ### `delay(ms)`
486
878
 
487
- ## `GenericHelpers.delay(ms)`
879
+ Creates a delay (sleep) for the specified number of milliseconds.
488
880
 
489
- A "modern" sleep statement.
881
+ **Parameters:**
882
+ - `ms`: `number` - Number of milliseconds to wait.
490
883
 
491
- Arguments
492
- |Name|Type|Required|Description|
493
- |--|--|--|--|
494
- |`ms`|`number`|`true`|The number of milliseconds to wait|
884
+ **Example:**
885
+ ```typescript
886
+ // Using with async/await
887
+ async function example() {
888
+ console.log("Starting...")
889
+ await GenericHelpers.delay(2000) // Wait 2 seconds
890
+ console.log("Done!")
891
+ }
892
+
893
+ // Using with promises
894
+ GenericHelpers.delay(1000).then(() => {
895
+ console.log("1 second has passed")
896
+ })
897
+ ```
898
+
899
+ ### `getPreferredUriScheme(host)`
495
900
 
496
- ## `GenericHelpers.getPreferredUriScheme(host)`
901
+ Determines the preferred URI scheme (http or https) for a given host.
497
902
 
498
- Get the preferred scheme for a host
903
+ **Parameters:**
904
+ - `host`: `string` - IP address or domain name.
499
905
 
500
- Arguments
501
- |Name|Type|Required|Description|
502
- |--|--|--|--|
503
- |`host`|`string`|`true`|An IP address or a domain name|
906
+ **Example:**
907
+ ```typescript
908
+ console.log(GenericHelpers.getPreferredUriScheme("example.com")) // "https"
909
+ console.log(GenericHelpers.getPreferredUriScheme("localhost")) // "http"
910
+ console.log(GenericHelpers.getPreferredUriScheme("127.0.0.1")) // "http"
911
+ console.log(GenericHelpers.getPreferredUriScheme("192.168.1.1")) // "http"
912
+ console.log(GenericHelpers.getPreferredUriScheme("10.0.0.1")) // "http"
913
+ ```
504
914
 
505
915
  ## FileHelpers
506
916
 
507
- ## `FileHelpers.checkFileExtension(filePath, validExtensions)`
917
+ Utility functions for file operations and validation.
508
918
 
509
- Check if a file path has a valid extension
919
+ ### `checkFileExtension(filePath, validExtensions)`
510
920
 
511
- Arguments
512
- |Name|Type|Required|Description|
513
- |--|--|--|--|
514
- |`filePath`|`string`|`true`|The file path to check|
515
- |`validExtensions`|`string[]`|`true`|The valid extensions|
921
+ Checks if a file path has one of the valid extensions.
516
922
 
517
- ## Contributing to this package
923
+ **Parameters:**
924
+ - `filePath`: `string` - The file path to check.
925
+ - `validExtensions`: `string[]` - Array of valid file extensions.
518
926
 
519
- This package follows the commitlint and conventional commits standards. As such the commit messages should follow the following format:
927
+ **Example:**
928
+ ```typescript
929
+ console.log(FileHelpers.checkFileExtension("document.pdf", ["pdf", "doc", "docx"])) // true
930
+ console.log(FileHelpers.checkFileExtension("image.jpg", ["png", "gif", "svg"])) // false
931
+ console.log(FileHelpers.checkFileExtension("data.geojson", ["geojson", "json"])) // true
932
+ console.log(FileHelpers.checkFileExtension("script.js", ["js", "ts", "jsx"])) // true
933
+ console.log(FileHelpers.checkFileExtension("file", ["txt", "md"])) // false (no extension)
934
+ ```
520
935
 
521
- ```text
522
- <type>(optional scope): <description> eg: feat: add new feature OR fix(map-loading): fix rendering on ipad devices
936
+ ## Contributing
937
+
938
+ We welcome contributions! Please feel free to submit a Pull Request.
939
+
940
+ ### Development Setup
941
+
942
+ ```bash
943
+ git clone https://github.com/akadenia/AkadeniaHelpers.git
944
+ cd AkadeniaHelpers
945
+ npm install
946
+ npm run build
947
+ npm test
948
+ ```
949
+
950
+ ### Commit Message Guidelines
951
+
952
+ We follow [Conventional Commits](https://www.conventionalcommits.org/) for our semantic release process. **We prefer commit messages to include a scope in parentheses** for better categorization and changelog generation.
953
+
954
+ ### Preferred Format
523
955
  ```
956
+ type(scope): description
957
+
958
+ [optional body]
524
959
 
525
- Common types according to [commitlint-config-conventional (based on the Angular convention)](https://github.com/conventional-changelog/commitlint/tree/master/@commitlint/config-conventional#type-enum) can be:
960
+ [optional footer]
961
+ ```
526
962
 
527
- - build
528
- - chore
529
- - ci
530
- - docs
531
- - feat
532
- - fix
533
- - perf
534
- - refactor
535
- - revert
536
- - style
537
- - test
963
+ ### Examples
964
+ ```bash
965
+ ## ✅ Preferred - with scope
966
+ feat(date): add new date formatting options
967
+ fix(text): resolve string validation issue
968
+ docs(readme): add troubleshooting section
969
+ chore(deps): update dependencies
970
+
971
+ ## ❌ Less preferred - without scope
972
+ feat: add new date formatting options
973
+ fix: resolve string validation issue
974
+ docs: add troubleshooting section
975
+ chore: update dependencies
976
+ ```
538
977
 
539
- if you introduce a breaking change, please add BREAKING CHANGE in the pull request description
978
+ ### Common Scopes
979
+ - `date` - Date manipulation functions
980
+ - `text` - Text processing functions
981
+ - `object` - Object manipulation functions
982
+ - `map` - Map and geographical functions
983
+ - `generic` - Generic utility functions
984
+ - `file` - File processing functions
985
+ - `docs` - Documentation updates
986
+ - `deps` - Dependency updates
987
+ - `test` - Test-related changes
988
+ - `build` - Build and build tooling
989
+ - `ci` - CI/CD configuration
990
+
991
+ ### Commit Types
992
+ - `feat` - New features
993
+ - `fix` - Bug fixes
994
+ - `docs` - Documentation changes
995
+ - `style` - Code style changes (formatting, etc.)
996
+ - `refactor` - Code refactoring
997
+ - `test` - Adding or updating tests
998
+ - `chore` - Maintenance tasks
999
+
1000
+ If you introduce a breaking change, please add `BREAKING CHANGE` in the pull request description.
540
1001
 
541
1002
  ## License
542
1003
 
543
- MIT
1004
+ [MIT](https://github.com/akadenia/AkadeniaHelpers/blob/main/LICENSE)
1005
+
1006
+ ## Support
1007
+
1008
+ For support, please open an issue on [GitHub](https://github.com/akadenia/AkadeniaHelpers/issues).