js-utils-core 1.0.1

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/arrayUtils.js ADDED
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Array utilities with clean, composable functions
3
+ */
4
+
5
+ /**
6
+ * Get the first element or n elements from an array
7
+ */
8
+ const head = (arr, n = 1) => {
9
+ if (n === 1) return arr[0];
10
+ return arr.slice(0, n);
11
+ };
12
+
13
+ /**
14
+ * Get the last element or n elements from an array
15
+ */
16
+ const tail = (arr, n = 1) => {
17
+ if (n === 1) return arr[arr.length - 1];
18
+ return arr.slice(-n);
19
+ };
20
+
21
+ /**
22
+ * Flatten array by one level or completely
23
+ */
24
+ const flatten = (arr, depth = Infinity) => {
25
+ return arr.reduce((acc, val) => {
26
+ if (Array.isArray(val) && depth > 0) {
27
+ acc.push(...flatten(val, depth - 1));
28
+ } else {
29
+ acc.push(val);
30
+ }
31
+ return acc;
32
+ }, []);
33
+ };
34
+
35
+ /**
36
+ * Remove duplicate values, keeping first occurrence
37
+ */
38
+ const unique = (arr, key = null) => {
39
+ if (!key) return [...new Set(arr)];
40
+ const seen = new Set();
41
+ return arr.filter((item) => {
42
+ const keyVal = key(item);
43
+ if (seen.has(keyVal)) return false;
44
+ seen.add(keyVal);
45
+ return true;
46
+ });
47
+ };
48
+
49
+ /**
50
+ * Group array elements by a key function
51
+ */
52
+ const groupBy = (arr, key) => {
53
+ return arr.reduce((acc, item) => {
54
+ const k = typeof key === "function" ? key(item) : item[key];
55
+ if (!acc[k]) acc[k] = [];
56
+ acc[k].push(item);
57
+ return acc;
58
+ }, {});
59
+ };
60
+
61
+ /**
62
+ * Create chunks of specified size
63
+ */
64
+ const chunk = (arr, size) => {
65
+ const chunks = [];
66
+ for (let i = 0; i < arr.length; i += size) {
67
+ chunks.push(arr.slice(i, i + size));
68
+ }
69
+ return chunks;
70
+ };
71
+
72
+ /**
73
+ * Find the minimum or maximum value
74
+ */
75
+ const minBy = (arr, key) => {
76
+ return arr.reduce((min, item) => (key(item) < key(min) ? item : min));
77
+ };
78
+
79
+ const maxBy = (arr, key) => {
80
+ return arr.reduce((max, item) => (key(item) > key(max) ? item : max));
81
+ };
82
+
83
+ /**
84
+ * Sum array values
85
+ */
86
+ const sum = (arr, key = null) => {
87
+ return arr.reduce((acc, item) => {
88
+ const val = key ? key(item) : item;
89
+ return acc + (typeof val === "number" ? val : 0);
90
+ }, 0);
91
+ };
92
+
93
+ /**
94
+ * Deep clone an object or array
95
+ */
96
+
97
+ const deepClone = (obj) => {
98
+ if (obj === null || typeof obj !== "object") {
99
+ return obj;
100
+ }
101
+
102
+ return structuredClone(obj);
103
+ };
104
+
105
+ module.exports = {
106
+ head,
107
+ tail,
108
+ flatten,
109
+ unique,
110
+ groupBy,
111
+ chunk,
112
+ minBy,
113
+ maxBy,
114
+ sum,
115
+ deepClone,
116
+ };
package/index.js ADDED
@@ -0,0 +1,27 @@
1
+ /**
2
+ * JS Utils - A clean utility library
3
+ * Inspired by lodash and radash with modern, functional approach
4
+ */
5
+
6
+ const arrayUtils = require("./arrayUtils");
7
+ const objectUtils = require("./objectUtils");
8
+ const stringUtils = require("./stringUtils");
9
+ const typeUtils = require("./typeUtils");
10
+ const mathUtils = require("./mathUtils");
11
+
12
+ module.exports = {
13
+ // Array utilities
14
+ ...arrayUtils,
15
+
16
+ // Object utilities
17
+ ...objectUtils,
18
+
19
+ // String utilities
20
+ ...stringUtils,
21
+
22
+ // Type utilities
23
+ ...typeUtils,
24
+
25
+ // Math utilities
26
+ ...mathUtils,
27
+ };
package/mathUtils.js ADDED
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Math utilities for common calculations
3
+ */
4
+
5
+ /**
6
+ * Calculate average of numbers
7
+ */
8
+ const average = (numbers) => {
9
+ if (numbers.length === 0) return 0;
10
+ return numbers.reduce((a, b) => a + b, 0) / numbers.length;
11
+ };
12
+
13
+ /**
14
+ * Calculate sum of numbers
15
+ */
16
+ const sum = (numbers) => {
17
+ return numbers.reduce((a, b) => a + b, 0);
18
+ };
19
+
20
+ /**
21
+ * Find minimum value
22
+ */
23
+ const min = (...numbers) => {
24
+ return Math.min(...numbers);
25
+ };
26
+
27
+ /**
28
+ * Find maximum value
29
+ */
30
+ const max = (...numbers) => {
31
+ return Math.max(...numbers);
32
+ };
33
+
34
+ /**
35
+ * Clamp value between min and max
36
+ */
37
+ const clamp = (value, min, max) => {
38
+ return Math.max(min, Math.min(value, max));
39
+ };
40
+
41
+ /**
42
+ * Round to n decimal places
43
+ */
44
+ const round = (num, decimals = 0) => {
45
+ return Math.round(num * Math.pow(10, decimals)) / Math.pow(10, decimals);
46
+ };
47
+
48
+ /**
49
+ * Calculate percentage
50
+ */
51
+ const percentage = (value, total) => {
52
+ return (value / total) * 100;
53
+ };
54
+
55
+ /**
56
+ * Calculate percentage of value
57
+ */
58
+ const percentageOf = (percent, total) => {
59
+ return (percent / 100) * total;
60
+ };
61
+
62
+ /**
63
+ * Check if number is even
64
+ */
65
+ const isEven = (num) => {
66
+ return num % 2 === 0;
67
+ };
68
+
69
+ /**
70
+ * Check if number is odd
71
+ */
72
+ const isOdd = (num) => {
73
+ return num % 2 !== 0;
74
+ };
75
+
76
+ /**
77
+ * Check if number is prime
78
+ */
79
+ const isPrime = (num) => {
80
+ if (num <= 1) return false;
81
+ if (num <= 3) return true;
82
+ if (num % 2 === 0 || num % 3 === 0) return false;
83
+ for (let i = 5; i * i <= num; i += 6) {
84
+ if (num % i === 0 || num % (i + 2) === 0) return false;
85
+ }
86
+ return true;
87
+ };
88
+
89
+ /**
90
+ * Generate random number between min and max
91
+ */
92
+ const random = (min = 0, max = 1) => {
93
+ return Math.random() * (max - min) + min;
94
+ };
95
+
96
+ /**
97
+ * Generate random integer between min and max (inclusive)
98
+ */
99
+ const randomInt = (min, max) => {
100
+ return Math.floor(Math.random() * (max - min + 1)) + min;
101
+ };
102
+
103
+ /**
104
+ * Calculate absolute difference
105
+ */
106
+ const difference = (a, b) => {
107
+ return Math.abs(a - b);
108
+ };
109
+
110
+ /**
111
+ * Check if two numbers are approximately equal
112
+ */
113
+ const approximatelyEqual = (a, b, tolerance = 0.0001) => {
114
+ return Math.abs(a - b) < tolerance;
115
+ };
116
+
117
+ module.exports = {
118
+ average,
119
+ sum,
120
+ min,
121
+ max,
122
+ clamp,
123
+ round,
124
+ percentage,
125
+ percentageOf,
126
+ isEven,
127
+ isOdd,
128
+ isPrime,
129
+ random,
130
+ randomInt,
131
+ difference,
132
+ approximatelyEqual,
133
+ };
package/objectUtils.js ADDED
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Object utilities with functional approach
3
+ */
4
+
5
+ /**
6
+ * Deep clone using structuredClone or fallback
7
+ */
8
+ const clone = (obj) => {
9
+ if (typeof structuredClone === "function") {
10
+ return structuredClone(obj);
11
+ }
12
+ // Fallback for older environments
13
+ return JSON.parse(JSON.stringify(obj));
14
+ };
15
+
16
+ /**
17
+ * Pick specified keys from object
18
+ */
19
+ const pick = (obj, keys) => {
20
+ return keys.reduce((acc, key) => {
21
+ if (key in obj) acc[key] = obj[key];
22
+ return acc;
23
+ }, {});
24
+ };
25
+
26
+ /**
27
+ * Omit specified keys from object
28
+ */
29
+ const omit = (obj, keys) => {
30
+ const keySet = new Set(keys);
31
+ return Object.entries(obj).reduce((acc, [key, val]) => {
32
+ if (!keySet.has(key)) acc[key] = val;
33
+ return acc;
34
+ }, {});
35
+ };
36
+
37
+ /**
38
+ * Merge multiple objects (shallow)
39
+ */
40
+ const merge = (...objects) => {
41
+ return Object.assign({}, ...objects);
42
+ };
43
+
44
+ /**
45
+ * Deep merge objects
46
+ */
47
+ const deepMerge = (target, ...sources) => {
48
+ if (!sources.length) return target;
49
+
50
+ const result = clone(target);
51
+
52
+ for (const source of sources) {
53
+ for (const key in source) {
54
+ if (source.hasOwnProperty(key)) {
55
+ if (isPlainObject(source[key]) && isPlainObject(result[key])) {
56
+ result[key] = deepMerge(result[key], source[key]);
57
+ } else {
58
+ result[key] = source[key];
59
+ }
60
+ }
61
+ }
62
+ }
63
+
64
+ return result;
65
+ };
66
+
67
+ /**
68
+ * Check if value is a plain object
69
+ */
70
+ const isPlainObject = (val) => {
71
+ return val !== null && typeof val === "object" && val.constructor === Object;
72
+ };
73
+
74
+ /**
75
+ * Flatten nested object with dot notation
76
+ */
77
+ const flatten = (obj, prefix = "") => {
78
+ const result = {};
79
+
80
+ const traverse = (current, key) => {
81
+ const newKey = prefix ? `${prefix}.${key}` : key;
82
+
83
+ if (isPlainObject(current[key]) && Object.keys(current[key]).length > 0) {
84
+ traverse(current[key], "");
85
+ for (const k in current[key]) {
86
+ traverse(current[key], k);
87
+ }
88
+ } else {
89
+ result[newKey] = current[key];
90
+ }
91
+ };
92
+
93
+ for (const key in obj) {
94
+ traverse(obj, key);
95
+ }
96
+
97
+ return result;
98
+ };
99
+
100
+ /**
101
+ * Get nested object value safely
102
+ */
103
+ const get = (obj, path, defaultValue = undefined) => {
104
+ const keys = path.split(".");
105
+ let result = obj;
106
+
107
+ for (const key of keys) {
108
+ if (result == null) return defaultValue;
109
+ result = result[key];
110
+ }
111
+
112
+ return result !== undefined ? result : defaultValue;
113
+ };
114
+
115
+ /**
116
+ * Set nested object value
117
+ */
118
+ const set = (obj, path, value) => {
119
+ const keys = path.split(".");
120
+ let current = obj;
121
+
122
+ for (let i = 0; i < keys.length - 1; i++) {
123
+ const key = keys[i];
124
+ if (!(key in current) || typeof current[key] !== "object") {
125
+ current[key] = {};
126
+ }
127
+ current = current[key];
128
+ }
129
+
130
+ current[keys[keys.length - 1]] = value;
131
+ return obj;
132
+ };
133
+
134
+ module.exports = {
135
+ clone,
136
+ pick,
137
+ omit,
138
+ merge,
139
+ deepMerge,
140
+ isPlainObject,
141
+ flatten,
142
+ get,
143
+ set,
144
+ };
package/package.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "js-utils-core",
3
+ "version": "1.0.1",
4
+ "description": "A lightweight collection of reusable JavaScript utility functions designed to simplify everyday development tasks and promote clean, consistent code.",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "author": "Manasa",
10
+ "license": "ISC",
11
+ "publishConfig": {
12
+ "access": "public"
13
+ }
14
+ }
package/stringUtils.js ADDED
@@ -0,0 +1,121 @@
1
+ /**
2
+ * String utilities with common transformations
3
+ */
4
+
5
+ /**
6
+ * Convert string to camelCase
7
+ */
8
+ const camelCase = (str) => {
9
+ return str
10
+ .replace(/[-_\s](.)/g, (_, char) => char.toUpperCase())
11
+ .replace(/^(.)/, (char) => char.toLowerCase());
12
+ };
13
+
14
+ /**
15
+ * Convert string to snake_case
16
+ */
17
+ const snakeCase = (str) => {
18
+ return str
19
+ .replace(/([A-Z])/g, "_$1")
20
+ .replace(/[-\s]/g, "_")
21
+ .toLowerCase()
22
+ .replace(/^_/, "");
23
+ };
24
+
25
+ /**
26
+ * Convert string to PascalCase
27
+ */
28
+ const pascalCase = (str) => {
29
+ return str
30
+ .split(/[-_\s]/)
31
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
32
+ .join("");
33
+ };
34
+
35
+ /**
36
+ * Convert string to kebab-case
37
+ */
38
+ const kebabCase = (str) => {
39
+ return str
40
+ .replace(/([A-Z])/g, "-$1")
41
+ .replace(/[-_\s]+/g, "-")
42
+ .toLowerCase()
43
+ .replace(/^-/, "");
44
+ };
45
+
46
+ /**
47
+ * Capitalize first letter
48
+ */
49
+ const capitalize = (str) => {
50
+ return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
51
+ };
52
+
53
+ /**
54
+ * Repeat string n times
55
+ */
56
+ const repeat = (str, n) => {
57
+ return str.repeat(Math.max(0, n));
58
+ };
59
+
60
+ /**
61
+ * Pad string to desired length
62
+ */
63
+ const padStart = (str, length, padString = " ") => {
64
+ return String(str).padStart(length, padString);
65
+ };
66
+
67
+ const padEnd = (str, length, padString = " ") => {
68
+ return String(str).padEnd(length, padString);
69
+ };
70
+
71
+ /**
72
+ * Truncate string with ellipsis
73
+ */
74
+ const truncate = (str, length, suffix = "...") => {
75
+ if (str.length <= length) return str;
76
+ return str.slice(0, length - suffix.length) + suffix;
77
+ };
78
+
79
+ /**
80
+ * Check if string starts with prefix
81
+ */
82
+ const startsWith = (str, prefix) => {
83
+ return String(str).startsWith(prefix);
84
+ };
85
+
86
+ /**
87
+ * Check if string ends with suffix
88
+ */
89
+ const endsWith = (str, suffix) => {
90
+ return String(str).endsWith(suffix);
91
+ };
92
+
93
+ /**
94
+ * Remove whitespace from both ends
95
+ */
96
+ const trim = (str) => {
97
+ return String(str).trim();
98
+ };
99
+
100
+ /**
101
+ * Reverse a string
102
+ */
103
+ const reverse = (str) => {
104
+ return String(str).split("").reverse().join("");
105
+ };
106
+
107
+ module.exports = {
108
+ camelCase,
109
+ snakeCase,
110
+ pascalCase,
111
+ kebabCase,
112
+ capitalize,
113
+ repeat,
114
+ padStart,
115
+ padEnd,
116
+ truncate,
117
+ startsWith,
118
+ endsWith,
119
+ trim,
120
+ reverse,
121
+ };
package/typeUtils.js ADDED
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Type checking utilities
3
+ */
4
+
5
+ /**
6
+ * Get exact type of value
7
+ */
8
+ const typeOf = (val) => {
9
+ if (val === null) return "null";
10
+ if (val === undefined) return "undefined";
11
+ if (Array.isArray(val)) return "array";
12
+ if (val instanceof Date) return "date";
13
+ if (val instanceof RegExp) return "regexp";
14
+ if (val instanceof Map) return "map";
15
+ if (val instanceof Set) return "set";
16
+ return typeof val;
17
+ };
18
+
19
+ /**
20
+ * Check if value is null or undefined
21
+ */
22
+ const isEmpty = (val) => {
23
+ if (val === null || val === undefined) return true;
24
+ if (typeof val === "string" || Array.isArray(val)) return val.length === 0;
25
+ if (val instanceof Map || val instanceof Set) return val.size === 0;
26
+ if (typeof val === "object") return Object.keys(val).length === 0;
27
+ return false;
28
+ };
29
+
30
+ /**
31
+ * Check if value is truthy (not empty, null, undefined, false, 0, NaN)
32
+ */
33
+ const isTruthy = (val) => {
34
+ return !!val && !isEmpty(val);
35
+ };
36
+
37
+ /**
38
+ * Check various types
39
+ */
40
+ const isNull = (val) => val === null;
41
+ const isUndefined = (val) => val === undefined;
42
+ const isBoolean = (val) => typeof val === "boolean";
43
+ const isNumber = (val) => typeof val === "number" && !isNaN(val);
44
+ const isString = (val) => typeof val === "string";
45
+ const isFunction = (val) => typeof val === "function";
46
+ const isObject = (val) => val !== null && typeof val === "object";
47
+ const isArray = (val) => Array.isArray(val);
48
+ const isDate = (val) => val instanceof Date && !isNaN(val.getTime());
49
+ const isRegExp = (val) => val instanceof RegExp;
50
+ const isMap = (val) => val instanceof Map;
51
+ const isSet = (val) => val instanceof Set;
52
+
53
+ /**
54
+ * Check if value is a plain object (not array, Date, etc.)
55
+ */
56
+ const isPlainObject = (val) => {
57
+ return val !== null && typeof val === "object" && val.constructor === Object;
58
+ };
59
+
60
+ /**
61
+ * Check if value is numeric (including string numbers)
62
+ */
63
+ const isNumeric = (val) => {
64
+ return !isNaN(val) && !isNaN(parseFloat(val));
65
+ };
66
+
67
+ /**
68
+ * Check if value is integer
69
+ */
70
+ const isInteger = (val) => {
71
+ return Number.isInteger(val);
72
+ };
73
+
74
+ /**
75
+ * Check if value is finite number
76
+ */
77
+ const isFinite = (val) => {
78
+ return Number.isFinite(val);
79
+ };
80
+
81
+ module.exports = {
82
+ typeOf,
83
+ isEmpty,
84
+ isTruthy,
85
+ isNull,
86
+ isUndefined,
87
+ isBoolean,
88
+ isNumber,
89
+ isString,
90
+ isFunction,
91
+ isObject,
92
+ isArray,
93
+ isDate,
94
+ isRegExp,
95
+ isMap,
96
+ isSet,
97
+ isPlainObject,
98
+ isNumeric,
99
+ isInteger,
100
+ isFinite,
101
+ };