@naman_deep_singh/js-extensions 1.0.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 ADDED
@@ -0,0 +1,89 @@
1
+ # @naman_deep_singh/js-extensions
2
+
3
+ Universal JavaScript prototype extensions for common development utilities. Works in both Node.js and browser environments.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @naman_deep_singh/js-extensions
9
+ # or
10
+ pnpm add @naman_deep_singh/js-extensions
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ### Initialize All Extensions
16
+
17
+ ```typescript
18
+ import { initExtensions } from '@naman_deep_singh/js-extensions';
19
+
20
+ // Initialize all extensions
21
+ initExtensions();
22
+
23
+ // Now use the extensions
24
+ "hello world".toCapitalize(); // "Hello world"
25
+ [1, 2, 2, 3].unique(); // [1, 2, 3]
26
+ ```
27
+
28
+ ### Selective Extensions
29
+
30
+ ```typescript
31
+ import { extend } from '@naman_deep_singh/js-extensions';
32
+
33
+ // Only extend strings
34
+ extend.string();
35
+
36
+ // Only extend arrays and objects
37
+ initExtensions({ array: true, object: true, string: false, number: false });
38
+ ```
39
+
40
+ ## String Extensions
41
+
42
+ - `toCapitalize()` - Capitalize first letter
43
+ - `toCamelCase()` - Convert to camelCase
44
+ - `toKebabCase()` - Convert to kebab-case
45
+ - `toSnakeCase()` - Convert to snake_case
46
+ - `truncate(length, suffix?)` - Truncate with optional suffix
47
+ - `isEmail()` - Check if valid email
48
+ - `isUrl()` - Check if valid URL
49
+ - `removeWhitespace()` - Remove all whitespace
50
+ - `reverse()` - Reverse string
51
+
52
+ ## Array Extensions
53
+
54
+ - `unique()` - Remove duplicates
55
+ - `shuffle()` - Randomly shuffle array
56
+ - `chunk(size)` - Split into chunks
57
+ - `groupBy(keyFn)` - Group by key function
58
+ - `sum()` - Sum numeric values
59
+ - `average()` - Calculate average
60
+ - `compact()` - Remove falsy values
61
+ - `pluck(key)` - Extract property values
62
+
63
+ ## Object Extensions
64
+
65
+ - `isEmpty()` - Check if object is empty
66
+ - `pick(keys)` - Pick specific keys
67
+ - `omit(keys)` - Omit specific keys
68
+ - `deepClone()` - Deep clone object
69
+ - `merge(other)` - Merge with another object
70
+
71
+ ## Number Extensions
72
+
73
+ - `toPercent(decimals?)` - Convert to percentage string
74
+ - `toCurrency(currency?, locale?)` - Format as currency
75
+ - `clamp(min, max)` - Clamp between min/max
76
+ - `isEven()` - Check if even
77
+ - `isOdd()` - Check if odd
78
+ - `isPrime()` - Check if prime number
79
+ - `factorial()` - Calculate factorial
80
+
81
+ ## Browser Usage
82
+
83
+ ```html
84
+ <script src="path/to/js-extensions.js"></script>
85
+ <script>
86
+ // Extensions are automatically initialized
87
+ console.log("hello".toCapitalize()); // "Hello"
88
+ </script>
89
+ ```
@@ -0,0 +1 @@
1
+ export declare function extendArray(): void;
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extendArray = extendArray;
4
+ // Array prototype extensions
5
+ function extendArray() {
6
+ Array.prototype.unique = function () {
7
+ return [...new Set(this)];
8
+ };
9
+ Array.prototype.shuffle = function () {
10
+ const arr = [...this];
11
+ for (let i = arr.length - 1; i > 0; i--) {
12
+ const j = Math.floor(Math.random() * (i + 1));
13
+ [arr[i], arr[j]] = [arr[j], arr[i]];
14
+ }
15
+ return arr;
16
+ };
17
+ Array.prototype.chunk = function (size) {
18
+ const chunks = [];
19
+ for (let i = 0; i < this.length; i += size) {
20
+ chunks.push(this.slice(i, i + size));
21
+ }
22
+ return chunks;
23
+ };
24
+ Array.prototype.groupBy = function (keyFn) {
25
+ return this.reduce((groups, item) => {
26
+ const key = keyFn(item);
27
+ if (!groups[key])
28
+ groups[key] = [];
29
+ groups[key].push(item);
30
+ return groups;
31
+ }, {});
32
+ };
33
+ Array.prototype.sum = function () {
34
+ return this.reduce((sum, num) => sum + (typeof num === 'number' ? num : 0), 0);
35
+ };
36
+ Array.prototype.average = function () {
37
+ const numbers = this.filter(item => typeof item === 'number');
38
+ return numbers.length > 0 ? numbers.reduce((sum, num) => sum + num, 0) / numbers.length : 0;
39
+ };
40
+ Array.prototype.compact = function () {
41
+ return this.filter(item => item != null && item !== '' && item !== false);
42
+ };
43
+ Array.prototype.pluck = function (key) {
44
+ return this.map(item => item && typeof item === 'object' ? item[key] : undefined).filter(val => val !== undefined);
45
+ };
46
+ Array.prototype.findLast = function (predicate) {
47
+ for (let i = this.length - 1; i >= 0; i--) {
48
+ if (predicate(this[i]))
49
+ return this[i];
50
+ }
51
+ return undefined;
52
+ };
53
+ Array.prototype.partition = function (predicate) {
54
+ const truthy = [];
55
+ const falsy = [];
56
+ this.forEach(item => predicate(item) ? truthy.push(item) : falsy.push(item));
57
+ return [truthy, falsy];
58
+ };
59
+ Array.prototype.flatten = function (depth = 1) {
60
+ return depth > 0 ? this.reduce((acc, val) => acc.concat(Array.isArray(val) ? val.flatten(depth - 1) : val), []) : this.slice();
61
+ };
62
+ Array.prototype.deepFlatten = function () {
63
+ return this.reduce((acc, val) => acc.concat(Array.isArray(val) ? val.deepFlatten() : val), []);
64
+ };
65
+ }
@@ -0,0 +1,40 @@
1
+ import { extendString } from './string-extensions';
2
+ import { extendArray } from './array-extensions';
3
+ import { extendObject } from './object-extensions';
4
+ import { extendNumber } from './number-extensions';
5
+ import './types';
6
+ export interface ExtensionOptions {
7
+ string?: boolean;
8
+ array?: boolean;
9
+ object?: boolean;
10
+ number?: boolean;
11
+ }
12
+ /**
13
+ * Initialize JavaScript prototype extensions
14
+ * @param options - Configure which extensions to enable (default: all enabled)
15
+ */
16
+ export declare function initExtensions(options?: ExtensionOptions): void;
17
+ /**
18
+ * Initialize all extensions (convenience function)
19
+ */
20
+ export declare function extendAll(): void;
21
+ /**
22
+ * Initialize only specific extensions
23
+ */
24
+ export declare const extend: {
25
+ string: typeof extendString;
26
+ array: typeof extendArray;
27
+ object: typeof extendObject;
28
+ number: typeof extendNumber;
29
+ };
30
+ declare const _default: {
31
+ initExtensions: typeof initExtensions;
32
+ extendAll: typeof extendAll;
33
+ extend: {
34
+ string: typeof extendString;
35
+ array: typeof extendArray;
36
+ object: typeof extendObject;
37
+ number: typeof extendNumber;
38
+ };
39
+ };
40
+ export default _default;
package/dist/index.js ADDED
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extend = void 0;
4
+ exports.initExtensions = initExtensions;
5
+ exports.extendAll = extendAll;
6
+ const string_extensions_1 = require("./string-extensions");
7
+ const array_extensions_1 = require("./array-extensions");
8
+ const object_extensions_1 = require("./object-extensions");
9
+ const number_extensions_1 = require("./number-extensions");
10
+ require("./types");
11
+ /**
12
+ * Initialize JavaScript prototype extensions
13
+ * @param options - Configure which extensions to enable (default: all enabled)
14
+ */
15
+ function initExtensions(options = {}) {
16
+ const { string = true, array = true, object = true, number = true } = options;
17
+ if (string)
18
+ (0, string_extensions_1.extendString)();
19
+ if (array)
20
+ (0, array_extensions_1.extendArray)();
21
+ if (object)
22
+ (0, object_extensions_1.extendObject)();
23
+ if (number)
24
+ (0, number_extensions_1.extendNumber)();
25
+ }
26
+ /**
27
+ * Initialize all extensions (convenience function)
28
+ */
29
+ function extendAll() {
30
+ initExtensions();
31
+ }
32
+ /**
33
+ * Initialize only specific extensions
34
+ */
35
+ exports.extend = {
36
+ string: string_extensions_1.extendString,
37
+ array: array_extensions_1.extendArray,
38
+ object: object_extensions_1.extendObject,
39
+ number: number_extensions_1.extendNumber
40
+ };
41
+ exports.default = {
42
+ initExtensions,
43
+ extendAll,
44
+ extend: exports.extend
45
+ };
@@ -0,0 +1 @@
1
+ export declare function extendNumber(): void;
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extendNumber = extendNumber;
4
+ // Number prototype extensions
5
+ function extendNumber() {
6
+ Number.prototype.toPercent = function (decimals = 2) {
7
+ return (this.valueOf() * 100).toFixed(decimals) + '%';
8
+ };
9
+ Number.prototype.toCurrency = function (currency = 'USD', locale = 'en-US') {
10
+ return new Intl.NumberFormat(locale, {
11
+ style: 'currency',
12
+ currency: currency
13
+ }).format(this.valueOf());
14
+ };
15
+ Number.prototype.clamp = function (min, max) {
16
+ return Math.min(Math.max(this.valueOf(), min), max);
17
+ };
18
+ Number.prototype.isEven = function () {
19
+ return this.valueOf() % 2 === 0;
20
+ };
21
+ Number.prototype.isOdd = function () {
22
+ return this.valueOf() % 2 !== 0;
23
+ };
24
+ Number.prototype.isPrime = function () {
25
+ const num = this.valueOf();
26
+ if (num < 2)
27
+ return false;
28
+ for (let i = 2; i <= Math.sqrt(num); i++) {
29
+ if (num % i === 0)
30
+ return false;
31
+ }
32
+ return true;
33
+ };
34
+ Number.prototype.factorial = function () {
35
+ const num = Math.floor(this.valueOf());
36
+ if (num < 0)
37
+ return NaN;
38
+ if (num === 0 || num === 1)
39
+ return 1;
40
+ let result = 1;
41
+ for (let i = 2; i <= num; i++) {
42
+ result *= i;
43
+ }
44
+ return result;
45
+ };
46
+ Number.prototype.toOrdinal = function () {
47
+ const num = Math.floor(this.valueOf());
48
+ const suffix = ['th', 'st', 'nd', 'rd'];
49
+ const v = num % 100;
50
+ return num + (suffix[(v - 20) % 10] || suffix[v] || suffix[0]);
51
+ };
52
+ Number.prototype.toRoman = function () {
53
+ const num = Math.floor(this.valueOf());
54
+ if (num <= 0 || num >= 4000)
55
+ return num.toString();
56
+ const values = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
57
+ const symbols = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'];
58
+ let result = '';
59
+ let n = num;
60
+ for (let i = 0; i < values.length; i++) {
61
+ while (n >= values[i]) {
62
+ result += symbols[i];
63
+ n -= values[i];
64
+ }
65
+ }
66
+ return result;
67
+ };
68
+ Number.prototype.inRange = function (min, max) {
69
+ const num = this.valueOf();
70
+ return num >= min && num <= max;
71
+ };
72
+ }
@@ -0,0 +1 @@
1
+ export declare function extendObject(): void;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extendObject = extendObject;
4
+ // Object prototype extensions
5
+ function extendObject() {
6
+ Object.prototype.isEmpty = function () {
7
+ return Object.keys(this).length === 0;
8
+ };
9
+ Object.prototype.pick = function (keys) {
10
+ const result = {};
11
+ const obj = this;
12
+ keys.forEach(key => {
13
+ if (key in obj) {
14
+ result[key] = obj[key];
15
+ }
16
+ });
17
+ return result;
18
+ };
19
+ Object.prototype.omit = function (keys) {
20
+ const result = { ...this };
21
+ keys.forEach(key => {
22
+ delete result[key];
23
+ });
24
+ return result;
25
+ };
26
+ Object.prototype.deepClone = function () {
27
+ if (this === null || typeof this !== 'object')
28
+ return this;
29
+ if (this instanceof Date)
30
+ return new Date(this.getTime());
31
+ if (this instanceof Array)
32
+ return this.map(item => item?.deepClone?.() || item);
33
+ const cloned = {};
34
+ Object.keys(this).forEach(key => {
35
+ const value = this[key];
36
+ cloned[key] = value?.deepClone?.() || value;
37
+ });
38
+ return cloned;
39
+ };
40
+ Object.prototype.merge = function (other) {
41
+ return { ...this, ...other };
42
+ };
43
+ Object.prototype.deepFreeze = function () {
44
+ const propNames = Object.getOwnPropertyNames(this);
45
+ for (const name of propNames) {
46
+ const value = this[name];
47
+ if (value && typeof value === 'object') {
48
+ value.deepFreeze();
49
+ }
50
+ }
51
+ return Object.freeze(this);
52
+ };
53
+ }
@@ -0,0 +1 @@
1
+ export declare function extendString(): void;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extendString = extendString;
4
+ // String prototype extensions
5
+ function extendString() {
6
+ String.prototype.toCapitalize = function () {
7
+ return this.charAt(0).toUpperCase() + this.slice(1).toLowerCase();
8
+ };
9
+ String.prototype.toCamelCase = function () {
10
+ return this.replace(/[-_\s]+(.)?/g, (_, char) => char ? char.toUpperCase() : '');
11
+ };
12
+ String.prototype.toKebabCase = function () {
13
+ return this.replace(/([a-z])([A-Z])/g, '$1-$2')
14
+ .replace(/[\s_]+/g, '-')
15
+ .toLowerCase();
16
+ };
17
+ String.prototype.toSnakeCase = function () {
18
+ return this.replace(/([a-z])([A-Z])/g, '$1_$2')
19
+ .replace(/[\s-]+/g, '_')
20
+ .toLowerCase();
21
+ };
22
+ String.prototype.truncate = function (length, suffix = '...') {
23
+ return this.length > length ? this.substring(0, length) + suffix : this.toString();
24
+ };
25
+ String.prototype.isEmail = function () {
26
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
27
+ return emailRegex.test(this.toString());
28
+ };
29
+ String.prototype.isUrl = function () {
30
+ try {
31
+ new URL(this.toString());
32
+ return true;
33
+ }
34
+ catch {
35
+ return false;
36
+ }
37
+ };
38
+ String.prototype.removeWhitespace = function () {
39
+ return this.replace(/\s+/g, '');
40
+ };
41
+ String.prototype.reverse = function () {
42
+ return this.split('').reverse().join('');
43
+ };
44
+ String.prototype.isPalindrome = function () {
45
+ const cleaned = this.toLowerCase().replace(/[^a-z0-9]/g, '');
46
+ return cleaned === cleaned.split('').reverse().join('');
47
+ };
48
+ String.prototype.toTitleCase = function () {
49
+ return this.replace(/\w\S*/g, (txt) => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase());
50
+ };
51
+ String.prototype.stripHtml = function () {
52
+ return this.replace(/<[^>]*>/g, '');
53
+ };
54
+ }
@@ -0,0 +1,51 @@
1
+ declare global {
2
+ interface String {
3
+ toCapitalize(): string;
4
+ toCamelCase(): string;
5
+ toKebabCase(): string;
6
+ toSnakeCase(): string;
7
+ truncate(length: number, suffix?: string): string;
8
+ isEmail(): boolean;
9
+ isUrl(): boolean;
10
+ removeWhitespace(): string;
11
+ reverse(): string;
12
+ isPalindrome(): boolean;
13
+ toTitleCase(): string;
14
+ stripHtml(): string;
15
+ }
16
+ interface Array<T> {
17
+ unique(): T[];
18
+ shuffle(): T[];
19
+ chunk(size: number): T[][];
20
+ groupBy<K extends string | number>(keyFn: (item: T) => K): Record<K, T[]>;
21
+ sum(): number;
22
+ average(): number;
23
+ compact(): T[];
24
+ pluck<K extends keyof T>(key: K): T[K][];
25
+ findLast(predicate: (item: T) => boolean): T | undefined;
26
+ partition(predicate: (item: T) => boolean): [T[], T[]];
27
+ flatten(depth?: number): any[];
28
+ deepFlatten(): any[];
29
+ }
30
+ interface Object {
31
+ isEmpty(): boolean;
32
+ pick<T extends Record<string, any>, K extends keyof T>(keys: K[]): Pick<T, K>;
33
+ omit<T extends Record<string, any>, K extends keyof T>(keys: K[]): Omit<T, K>;
34
+ deepClone<T>(): T;
35
+ merge(other: Record<string, any>): Record<string, any>;
36
+ deepFreeze<T>(): T;
37
+ }
38
+ interface Number {
39
+ toPercent(decimals?: number): string;
40
+ toCurrency(currency?: string, locale?: string): string;
41
+ clamp(min: number, max: number): number;
42
+ isEven(): boolean;
43
+ isOdd(): boolean;
44
+ isPrime(): boolean;
45
+ factorial(): number;
46
+ toOrdinal(): string;
47
+ toRoman(): string;
48
+ inRange(min: number, max: number): boolean;
49
+ }
50
+ }
51
+ export {};
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@naman_deep_singh/js-extensions",
3
+ "version": "1.0.0",
4
+ "description": "Universal JavaScript prototype extensions for common development utilities",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "browser": "dist/index.js",
8
+ "scripts": {
9
+ "build": "tsc"
10
+ },
11
+ "keywords": [
12
+ "javascript",
13
+ "utilities",
14
+ "extensions",
15
+ "prototype",
16
+ "string",
17
+ "array",
18
+ "object",
19
+ "universal"
20
+ ],
21
+ "author": "Naman Deep Singh",
22
+ "license": "ISC",
23
+ "packageManager": "pnpm@10.20.0",
24
+ "devDependencies": {
25
+ "typescript": "^5.9.3"
26
+ }
27
+ }
@@ -0,0 +1,73 @@
1
+ // Array prototype extensions
2
+ export function extendArray() {
3
+ Array.prototype.unique = function<T>(): T[] {
4
+ return [...new Set(this)];
5
+ };
6
+
7
+ Array.prototype.shuffle = function<T>(): T[] {
8
+ const arr = [...this];
9
+ for (let i = arr.length - 1; i > 0; i--) {
10
+ const j = Math.floor(Math.random() * (i + 1));
11
+ [arr[i], arr[j]] = [arr[j], arr[i]];
12
+ }
13
+ return arr;
14
+ };
15
+
16
+ Array.prototype.chunk = function<T>(size: number): T[][] {
17
+ const chunks: T[][] = [];
18
+ for (let i = 0; i < this.length; i += size) {
19
+ chunks.push(this.slice(i, i + size));
20
+ }
21
+ return chunks;
22
+ };
23
+
24
+ Array.prototype.groupBy = function<T>(keyFn: (item: T) => string | number): Record<string | number, T[]> {
25
+ return this.reduce((groups, item) => {
26
+ const key = keyFn(item);
27
+ if (!groups[key]) groups[key] = [];
28
+ groups[key].push(item);
29
+ return groups;
30
+ }, {} as Record<string | number, T[]>);
31
+ };
32
+
33
+ Array.prototype.sum = function(): number {
34
+ return this.reduce((sum, num) => sum + (typeof num === 'number' ? num : 0), 0);
35
+ };
36
+
37
+ Array.prototype.average = function(): number {
38
+ const numbers = this.filter(item => typeof item === 'number');
39
+ return numbers.length > 0 ? numbers.reduce((sum, num) => sum + num, 0) / numbers.length : 0;
40
+ };
41
+
42
+ Array.prototype.compact = function<T>(): T[] {
43
+ return this.filter(item => item != null && item !== '' && item !== false);
44
+ };
45
+
46
+ Array.prototype.pluck = function<T, K extends keyof T>(key: K): T[K][] {
47
+ return this.map(item => item && typeof item === 'object' ? item[key] : undefined).filter(val => val !== undefined);
48
+ };
49
+
50
+ Array.prototype.findLast = function<T>(predicate: (item: T) => boolean): T | undefined {
51
+ for (let i = this.length - 1; i >= 0; i--) {
52
+ if (predicate(this[i])) return this[i];
53
+ }
54
+ return undefined;
55
+ };
56
+
57
+ Array.prototype.partition = function<T>(predicate: (item: T) => boolean): [T[], T[]] {
58
+ const truthy: T[] = [];
59
+ const falsy: T[] = [];
60
+ this.forEach(item => predicate(item) ? truthy.push(item) : falsy.push(item));
61
+ return [truthy, falsy];
62
+ };
63
+
64
+ Array.prototype.flatten = function(depth: number = 1): any[] {
65
+ return depth > 0 ? this.reduce((acc, val) =>
66
+ acc.concat(Array.isArray(val) ? val.flatten(depth - 1) : val), []) : this.slice();
67
+ };
68
+
69
+ Array.prototype.deepFlatten = function(): any[] {
70
+ return this.reduce((acc, val) =>
71
+ acc.concat(Array.isArray(val) ? val.deepFlatten() : val), []);
72
+ };
73
+ }
package/src/index.ts ADDED
@@ -0,0 +1,55 @@
1
+ import { extendString } from './string-extensions';
2
+ import { extendArray } from './array-extensions';
3
+ import { extendObject } from './object-extensions';
4
+ import { extendNumber } from './number-extensions';
5
+ import './types';
6
+
7
+ export interface ExtensionOptions {
8
+ string?: boolean;
9
+ array?: boolean;
10
+ object?: boolean;
11
+ number?: boolean;
12
+ }
13
+
14
+ /**
15
+ * Initialize JavaScript prototype extensions
16
+ * @param options - Configure which extensions to enable (default: all enabled)
17
+ */
18
+ export function initExtensions(options: ExtensionOptions = {}): void {
19
+ const {
20
+ string = true,
21
+ array = true,
22
+ object = true,
23
+ number = true
24
+ } = options;
25
+
26
+ if (string) extendString();
27
+ if (array) extendArray();
28
+ if (object) extendObject();
29
+ if (number) extendNumber();
30
+ }
31
+
32
+ /**
33
+ * Initialize all extensions (convenience function)
34
+ */
35
+ export function extendAll(): void {
36
+ initExtensions();
37
+ }
38
+
39
+ /**
40
+ * Initialize only specific extensions
41
+ */
42
+ export const extend = {
43
+ string: extendString,
44
+ array: extendArray,
45
+ object: extendObject,
46
+ number: extendNumber
47
+ };
48
+
49
+
50
+
51
+ export default {
52
+ initExtensions,
53
+ extendAll,
54
+ extend
55
+ };
@@ -0,0 +1,73 @@
1
+ // Number prototype extensions
2
+ export function extendNumber() {
3
+ Number.prototype.toPercent = function(decimals: number = 2): string {
4
+ return (this.valueOf() * 100).toFixed(decimals) + '%';
5
+ };
6
+
7
+ Number.prototype.toCurrency = function(currency: string = 'USD', locale: string = 'en-US'): string {
8
+ return new Intl.NumberFormat(locale, {
9
+ style: 'currency',
10
+ currency: currency
11
+ }).format(this.valueOf());
12
+ };
13
+
14
+ Number.prototype.clamp = function(min: number, max: number): number {
15
+ return Math.min(Math.max(this.valueOf(), min), max);
16
+ };
17
+
18
+ Number.prototype.isEven = function(): boolean {
19
+ return this.valueOf() % 2 === 0;
20
+ };
21
+
22
+ Number.prototype.isOdd = function(): boolean {
23
+ return this.valueOf() % 2 !== 0;
24
+ };
25
+
26
+ Number.prototype.isPrime = function(): boolean {
27
+ const num = this.valueOf();
28
+ if (num < 2) return false;
29
+ for (let i = 2; i <= Math.sqrt(num); i++) {
30
+ if (num % i === 0) return false;
31
+ }
32
+ return true;
33
+ };
34
+
35
+ Number.prototype.factorial = function(): number {
36
+ const num = Math.floor(this.valueOf());
37
+ if (num < 0) return NaN;
38
+ if (num === 0 || num === 1) return 1;
39
+ let result = 1;
40
+ for (let i = 2; i <= num; i++) {
41
+ result *= i;
42
+ }
43
+ return result;
44
+ };
45
+
46
+ Number.prototype.toOrdinal = function(): string {
47
+ const num = Math.floor(this.valueOf());
48
+ const suffix = ['th', 'st', 'nd', 'rd'];
49
+ const v = num % 100;
50
+ return num + (suffix[(v - 20) % 10] || suffix[v] || suffix[0]);
51
+ };
52
+
53
+ Number.prototype.toRoman = function(): string {
54
+ const num = Math.floor(this.valueOf());
55
+ if (num <= 0 || num >= 4000) return num.toString();
56
+ const values = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
57
+ const symbols = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'];
58
+ let result = '';
59
+ let n = num;
60
+ for (let i = 0; i < values.length; i++) {
61
+ while (n >= values[i]) {
62
+ result += symbols[i];
63
+ n -= values[i];
64
+ }
65
+ }
66
+ return result;
67
+ };
68
+
69
+ Number.prototype.inRange = function(min: number, max: number): boolean {
70
+ const num = this.valueOf();
71
+ return num >= min && num <= max;
72
+ };
73
+ }
@@ -0,0 +1,53 @@
1
+ // Object prototype extensions
2
+ export function extendObject() {
3
+ Object.prototype.isEmpty = function(): boolean {
4
+ return Object.keys(this).length === 0;
5
+ };
6
+
7
+ Object.prototype.pick = function<T extends Record<string, any>, K extends keyof T>(keys: K[]): Pick<T, K> {
8
+ const result = {} as Pick<T, K>;
9
+ const obj = this as T;
10
+ keys.forEach(key => {
11
+ if (key in obj) {
12
+ result[key] = obj[key];
13
+ }
14
+ });
15
+ return result;
16
+ };
17
+
18
+ Object.prototype.omit = function<T extends Record<string, any>, K extends keyof T>(keys: K[]): Omit<T, K> {
19
+ const result = { ...this } as T;
20
+ keys.forEach(key => {
21
+ delete result[key];
22
+ });
23
+ return result as Omit<T, K>;
24
+ };
25
+
26
+ Object.prototype.deepClone = function<T>(): T {
27
+ if (this === null || typeof this !== 'object') return this;
28
+ if (this instanceof Date) return new Date(this.getTime()) as any;
29
+ if (this instanceof Array) return this.map(item => item?.deepClone?.() || item) as any;
30
+
31
+ const cloned = {} as T;
32
+ Object.keys(this).forEach(key => {
33
+ const value = (this as any)[key];
34
+ (cloned as any)[key] = value?.deepClone?.() || value;
35
+ });
36
+ return cloned;
37
+ };
38
+
39
+ Object.prototype.merge = function(other: Record<string, any>): Record<string, any> {
40
+ return { ...this, ...other };
41
+ };
42
+
43
+ Object.prototype.deepFreeze = function<T>(): T {
44
+ const propNames = Object.getOwnPropertyNames(this);
45
+ for (const name of propNames) {
46
+ const value = (this as any)[name];
47
+ if (value && typeof value === 'object') {
48
+ value.deepFreeze();
49
+ }
50
+ }
51
+ return Object.freeze(this) as T;
52
+ };
53
+ }
@@ -0,0 +1,63 @@
1
+ // String prototype extensions
2
+ export function extendString() {
3
+ String.prototype.toCapitalize = function(): string {
4
+ return this.charAt(0).toUpperCase() + this.slice(1).toLowerCase();
5
+ };
6
+
7
+ String.prototype.toCamelCase = function(): string {
8
+ return this.replace(/[-_\s]+(.)?/g, (_, char) => char ? char.toUpperCase() : '');
9
+ };
10
+
11
+ String.prototype.toKebabCase = function(): string {
12
+ return this.replace(/([a-z])([A-Z])/g, '$1-$2')
13
+ .replace(/[\s_]+/g, '-')
14
+ .toLowerCase();
15
+ };
16
+
17
+ String.prototype.toSnakeCase = function(): string {
18
+ return this.replace(/([a-z])([A-Z])/g, '$1_$2')
19
+ .replace(/[\s-]+/g, '_')
20
+ .toLowerCase();
21
+ };
22
+
23
+ String.prototype.truncate = function(length: number, suffix: string = '...'): string {
24
+ return this.length > length ? this.substring(0, length) + suffix : this.toString();
25
+ };
26
+
27
+ String.prototype.isEmail = function(): boolean {
28
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
29
+ return emailRegex.test(this.toString());
30
+ };
31
+
32
+ String.prototype.isUrl = function(): boolean {
33
+ try {
34
+ new URL(this.toString());
35
+ return true;
36
+ } catch {
37
+ return false;
38
+ }
39
+ };
40
+
41
+ String.prototype.removeWhitespace = function(): string {
42
+ return this.replace(/\s+/g, '');
43
+ };
44
+
45
+ String.prototype.reverse = function(): string {
46
+ return this.split('').reverse().join('');
47
+ };
48
+
49
+ String.prototype.isPalindrome = function(): boolean {
50
+ const cleaned = this.toLowerCase().replace(/[^a-z0-9]/g, '');
51
+ return cleaned === cleaned.split('').reverse().join('');
52
+ };
53
+
54
+ String.prototype.toTitleCase = function(): string {
55
+ return this.replace(/\w\S*/g, (txt) =>
56
+ txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()
57
+ );
58
+ };
59
+
60
+ String.prototype.stripHtml = function(): string {
61
+ return this.replace(/<[^>]*>/g, '');
62
+ };
63
+ }
package/src/types.ts ADDED
@@ -0,0 +1,56 @@
1
+ // TypeScript declarations for all extensions
2
+ declare global {
3
+ interface String {
4
+ toCapitalize(): string;
5
+ toCamelCase(): string;
6
+ toKebabCase(): string;
7
+ toSnakeCase(): string;
8
+ truncate(length: number, suffix?: string): string;
9
+ isEmail(): boolean;
10
+ isUrl(): boolean;
11
+ removeWhitespace(): string;
12
+ reverse(): string;
13
+ isPalindrome(): boolean;
14
+ toTitleCase(): string;
15
+ stripHtml(): string;
16
+ }
17
+
18
+ interface Array<T> {
19
+ unique(): T[];
20
+ shuffle(): T[];
21
+ chunk(size: number): T[][];
22
+ groupBy<K extends string | number>(keyFn: (item: T) => K): Record<K, T[]>;
23
+ sum(): number;
24
+ average(): number;
25
+ compact(): T[];
26
+ pluck<K extends keyof T>(key: K): T[K][];
27
+ findLast(predicate: (item: T) => boolean): T | undefined;
28
+ partition(predicate: (item: T) => boolean): [T[], T[]];
29
+ flatten(depth?: number): any[];
30
+ deepFlatten(): any[];
31
+ }
32
+
33
+ interface Object {
34
+ isEmpty(): boolean;
35
+ pick<T extends Record<string, any>, K extends keyof T>(keys: K[]): Pick<T, K>;
36
+ omit<T extends Record<string, any>, K extends keyof T>(keys: K[]): Omit<T, K>;
37
+ deepClone<T>(): T;
38
+ merge(other: Record<string, any>): Record<string, any>;
39
+ deepFreeze<T>(): T;
40
+ }
41
+
42
+ interface Number {
43
+ toPercent(decimals?: number): string;
44
+ toCurrency(currency?: string, locale?: string): string;
45
+ clamp(min: number, max: number): number;
46
+ isEven(): boolean;
47
+ isOdd(): boolean;
48
+ isPrime(): boolean;
49
+ factorial(): number;
50
+ toOrdinal(): string;
51
+ toRoman(): string;
52
+ inRange(min: number, max: number): boolean;
53
+ }
54
+ }
55
+
56
+ export {};
package/tsconfig.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "CommonJS",
5
+ "moduleResolution": "node",
6
+ "rootDir": "./src",
7
+ "outDir": "./dist",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "allowSyntheticDefaultImports": true,
11
+ "skipLibCheck": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "declaration": true,
14
+ "baseUrl": ".",
15
+ "paths": {
16
+ "*": ["*", "*.ts", "*.js"]
17
+ },
18
+ "lib": ["ES2020", "DOM"]
19
+ },
20
+ "include": ["src/**/*"],
21
+ "exclude": ["node_modules", "dist"]
22
+ }