danholibraryjs 1.11.0 → 2.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.
Files changed (210) hide show
  1. package/README.md +0 -1
  2. package/_package.github-release.json +6 -0
  3. package/_package.npm-release.json +6 -0
  4. package/dist/Classes/DanhoLogger.d.ts +23 -0
  5. package/dist/Classes/DanhoLogger.js +65 -0
  6. package/dist/Classes/Events/Event.d.ts +66 -66
  7. package/dist/Classes/Events/Event.js +114 -114
  8. package/dist/Classes/Events/EventCollection.d.ts +57 -57
  9. package/dist/Classes/Events/EventCollection.js +109 -109
  10. package/dist/Classes/Events/EventEmitter.d.ts +74 -74
  11. package/dist/Classes/Events/EventEmitter.js +97 -97
  12. package/dist/Classes/Events/index.d.ts +3 -3
  13. package/dist/Classes/Events/index.js +19 -19
  14. package/dist/Classes/Time/Date.d.ts +148 -147
  15. package/dist/Classes/Time/Date.js +241 -238
  16. package/dist/Classes/Time/Time.d.ts +66 -65
  17. package/dist/Classes/Time/Time.js +120 -117
  18. package/dist/Classes/Time/TimeProperties.d.ts +3 -3
  19. package/dist/Classes/Time/TimeProperties.js +2 -2
  20. package/dist/Classes/Time/TimeSpan.d.ts +123 -123
  21. package/dist/Classes/Time/TimeSpan.js +179 -179
  22. package/dist/Classes/Time/index.d.ts +4 -4
  23. package/dist/Classes/Time/index.js +20 -20
  24. package/dist/Classes/index.d.ts +4 -3
  25. package/dist/Classes/index.js +20 -19
  26. package/dist/Classes/store.d.ts +75 -75
  27. package/dist/Classes/store.js +84 -84
  28. package/dist/Extensions/Array/array.extension.d.ts +42 -0
  29. package/dist/Extensions/Array/array.extension.js +57 -0
  30. package/dist/Extensions/Array/crud.extension.d.ts +24 -0
  31. package/dist/Extensions/Array/crud.extension.js +28 -0
  32. package/dist/Extensions/Array/index.d.ts +6 -0
  33. package/dist/Extensions/Array/index.js +22 -0
  34. package/dist/Extensions/Array/loop.extension.d.ts +18 -0
  35. package/dist/Extensions/Array/loop.extension.js +23 -0
  36. package/dist/Extensions/Array/random.extension.d.ts +23 -0
  37. package/dist/Extensions/Array/random.extension.js +35 -0
  38. package/dist/Extensions/Array/sort.extension.d.ts +27 -0
  39. package/dist/Extensions/Array/sort.extension.js +31 -0
  40. package/dist/Extensions/Array/string.extension.d.ts +13 -0
  41. package/dist/Extensions/Array/string.extension.js +14 -0
  42. package/dist/Extensions/Function.d.ts +29 -14
  43. package/dist/Extensions/Function.js +23 -10
  44. package/dist/Extensions/Map.d.ts +54 -54
  45. package/dist/Extensions/Map.js +42 -42
  46. package/dist/Extensions/Number.d.ts +13 -0
  47. package/dist/Extensions/Number.js +40 -0
  48. package/dist/Extensions/Object/arrays.extension.d.ts +17 -0
  49. package/dist/Extensions/Object/arrays.extension.js +13 -0
  50. package/dist/Extensions/Object/booleans.extension.d.ts +18 -0
  51. package/dist/Extensions/Object/booleans.extension.js +37 -0
  52. package/dist/Extensions/Object/extracts.extension.d.ts +38 -0
  53. package/dist/Extensions/Object/extracts.extension.js +72 -0
  54. package/dist/Extensions/Object/index.d.ts +4 -49
  55. package/dist/Extensions/Object/index.js +20 -38
  56. package/dist/Extensions/Object/properties.d.ts +28 -28
  57. package/dist/Extensions/Object/properties.extension.d.ts +33 -0
  58. package/dist/Extensions/Object/properties.extension.js +21 -0
  59. package/dist/Extensions/Object/properties.js +20 -20
  60. package/dist/Extensions/String/case.extension.d.ts +12 -0
  61. package/dist/Extensions/String/case.extension.js +55 -0
  62. package/dist/Extensions/String/index.d.ts +1 -0
  63. package/dist/{Functions → Extensions/String}/index.js +17 -21
  64. package/dist/Extensions/index.d.ts +6 -17
  65. package/dist/Extensions/index.js +22 -30
  66. package/dist/Interfaces/ElementOptions.d.ts +15 -15
  67. package/dist/Interfaces/ElementOptions.js +2 -2
  68. package/dist/Interfaces/IReplacement.d.ts +12 -12
  69. package/dist/Interfaces/IReplacement.js +2 -2
  70. package/dist/Interfaces/index.d.ts +2 -2
  71. package/dist/Interfaces/index.js +18 -18
  72. package/dist/Types/Able.d.ts +16 -0
  73. package/dist/Types/Able.js +2 -0
  74. package/dist/Types/Array.d.ts +6 -0
  75. package/dist/Types/Array.js +2 -0
  76. package/dist/Types/BetterTypes.d.ts +9 -9
  77. package/dist/Types/BetterTypes.js +2 -2
  78. package/dist/Types/C#.d.ts +8 -0
  79. package/dist/Types/C#.js +2 -0
  80. package/dist/Types/Date.d.ts +6 -6
  81. package/dist/Types/Date.js +2 -2
  82. package/dist/Types/Events.d.ts +10 -10
  83. package/dist/Types/Events.js +2 -2
  84. package/dist/Types/Function.d.ts +5 -0
  85. package/dist/Types/Function.js +2 -0
  86. package/dist/Types/Object.d.ts +4 -0
  87. package/dist/Types/Object.js +2 -0
  88. package/dist/Types/PropertiesWith.d.ts +34 -13
  89. package/dist/Types/PropertiesWith.js +2 -2
  90. package/dist/Types/String.d.ts +1 -0
  91. package/dist/Types/String.js +2 -0
  92. package/dist/Types/TransformTypes.d.ts +22 -16
  93. package/dist/Types/TransformTypes.js +2 -2
  94. package/dist/Types/index.d.ts +24 -65
  95. package/dist/Types/index.js +27 -21
  96. package/dist/Utils/{ApiUtil → ApiUtils}/ApiTypes.d.ts +15 -15
  97. package/dist/Utils/{ApiUtil → ApiUtils}/ApiTypes.js +15 -15
  98. package/dist/Utils/{ApiUtil → ApiUtils}/RequestUtil.d.ts +19 -19
  99. package/dist/Utils/{ApiUtil → ApiUtils}/RequestUtil.js +73 -73
  100. package/dist/Utils/{ApiUtil → ApiUtils}/index.d.ts +20 -20
  101. package/dist/Utils/{ApiUtil → ApiUtils}/index.js +33 -33
  102. package/dist/Utils/ColorUtils.d.ts +11 -0
  103. package/dist/Utils/ColorUtils.js +93 -0
  104. package/dist/Utils/{FormUtil.d.ts → FormUtils.d.ts} +6 -6
  105. package/dist/Utils/{FormUtil.js → FormUtils.js} +35 -35
  106. package/dist/Utils/NumberUtils.d.ts +1 -0
  107. package/dist/Utils/NumberUtils.js +7 -0
  108. package/dist/Utils/PatcherUtils.d.ts +6 -0
  109. package/dist/Utils/PatcherUtils.js +80 -0
  110. package/dist/Utils/StringUtils.d.ts +3 -0
  111. package/dist/Utils/StringUtils.js +47 -0
  112. package/dist/Utils/TimeUtils/debounce.util.d.ts +22 -0
  113. package/dist/Utils/TimeUtils/debounce.util.js +78 -0
  114. package/dist/Utils/TimeUtils/functions.util.d.ts +4 -0
  115. package/dist/Utils/TimeUtils/functions.util.js +21 -0
  116. package/dist/Utils/TimeUtils/index.d.ts +15 -0
  117. package/dist/Utils/TimeUtils/index.js +34 -0
  118. package/dist/Utils/TimeUtils/throttle.util.d.ts +15 -0
  119. package/dist/Utils/TimeUtils/throttle.util.js +43 -0
  120. package/dist/Utils/index.d.ts +7 -2
  121. package/dist/Utils/index.js +23 -18
  122. package/dist/index.d.ts +4 -5
  123. package/dist/index.js +20 -21
  124. package/docs/Classes.md +78 -3
  125. package/docs/Extensions.md +219 -78
  126. package/docs/Types.md +202 -58
  127. package/docs/index.md +0 -1
  128. package/package.json +4 -2
  129. package/src/Classes/DanhoLogger.ts +78 -0
  130. package/src/Classes/Events/Event.ts +96 -96
  131. package/src/Classes/Events/EventCollection.ts +90 -90
  132. package/src/Classes/Events/EventEmitter.ts +68 -68
  133. package/src/Classes/Time/Date.ts +219 -216
  134. package/src/Classes/Time/Time.ts +109 -104
  135. package/src/Classes/Time/TimeSpan.ts +171 -171
  136. package/src/Classes/index.ts +1 -0
  137. package/src/Classes/store.ts +22 -22
  138. package/src/Extensions/Array/array.extension.ts +103 -0
  139. package/src/Extensions/Array/crud.extension.ts +46 -0
  140. package/src/Extensions/Array/index.ts +6 -0
  141. package/src/Extensions/Array/loop.extension.ts +38 -0
  142. package/src/Extensions/Array/random.extension.ts +56 -0
  143. package/src/Extensions/Array/sort.extension.ts +52 -0
  144. package/src/Extensions/Array/string.extension.ts +22 -0
  145. package/src/Extensions/Function.ts +37 -10
  146. package/src/Extensions/Map.ts +56 -56
  147. package/src/Extensions/Number.ts +50 -0
  148. package/src/Extensions/Object/arrays.extension.ts +27 -0
  149. package/src/Extensions/Object/booleans.extension.ts +46 -0
  150. package/src/Extensions/Object/extracts.extension.ts +102 -0
  151. package/src/Extensions/Object/index.ts +4 -82
  152. package/src/Extensions/Object/properties.extension.ts +59 -0
  153. package/src/Extensions/Object/properties.ts +36 -36
  154. package/src/Extensions/String/case.extension.ts +95 -0
  155. package/src/Extensions/String/index.ts +1 -0
  156. package/src/Extensions/index.ts +3 -21
  157. package/src/Interfaces/ElementOptions.ts +7 -7
  158. package/src/Interfaces/IReplacement.ts +2 -2
  159. package/src/Types/Able.ts +22 -0
  160. package/src/Types/Array.ts +7 -0
  161. package/src/Types/C#.ts +9 -0
  162. package/src/Types/Date.ts +1 -1
  163. package/src/Types/Events.ts +12 -12
  164. package/src/Types/Function.ts +10 -0
  165. package/src/Types/Object.ts +4 -0
  166. package/src/Types/PropertiesWith.ts +35 -4
  167. package/src/Types/String.ts +1 -0
  168. package/src/Types/TransformTypes.ts +21 -13
  169. package/src/Types/index.ts +7 -69
  170. package/src/Utils/{ApiUtil → ApiUtils}/ApiTypes.ts +2 -1
  171. package/src/Utils/{ApiUtil → ApiUtils}/index.ts +1 -1
  172. package/src/Utils/ColorUtils.ts +102 -0
  173. package/src/Utils/{FormUtil.ts → FormUtils.ts} +2 -2
  174. package/src/Utils/NumberUtils.ts +3 -0
  175. package/src/Utils/PatcherUtils.ts +111 -0
  176. package/src/Utils/StringUtils.ts +44 -0
  177. package/src/Utils/TimeUtils/debounce.util.ts +85 -0
  178. package/src/Utils/TimeUtils/functions.util.ts +18 -0
  179. package/src/Utils/TimeUtils/index.ts +9 -0
  180. package/src/Utils/TimeUtils/throttle.util.ts +44 -0
  181. package/src/Utils/index.ts +8 -2
  182. package/src/index.ts +0 -1
  183. package/dist/Extensions/Array.d.ts +0 -52
  184. package/dist/Extensions/Array.js +0 -51
  185. package/dist/Extensions/Document.d.ts +0 -27
  186. package/dist/Extensions/Document.js +0 -32
  187. package/dist/Extensions/String.d.ts +0 -36
  188. package/dist/Extensions/String.js +0 -25
  189. package/dist/Functions/CopyToClipboard.d.ts +0 -7
  190. package/dist/Functions/CopyToClipboard.js +0 -15
  191. package/dist/Functions/GetCSSProperty.d.ts +0 -15
  192. package/dist/Functions/GetCSSProperty.js +0 -26
  193. package/dist/Functions/GetNestedProperty.d.ts +0 -9
  194. package/dist/Functions/GetNestedProperty.js +0 -23
  195. package/dist/Functions/HTMLEvent.d.ts +0 -11
  196. package/dist/Functions/HTMLEvent.js +0 -14
  197. package/dist/Functions/SetNavigationSelected.d.ts +0 -9
  198. package/dist/Functions/SetNavigationSelected.js +0 -25
  199. package/dist/Functions/index.d.ts +0 -5
  200. package/docs/Functions.md +0 -61
  201. package/src/Extensions/Array.ts +0 -95
  202. package/src/Extensions/Document.ts +0 -58
  203. package/src/Extensions/String.ts +0 -54
  204. package/src/Functions/CopyToClipboard.ts +0 -10
  205. package/src/Functions/GetCSSProperty.ts +0 -27
  206. package/src/Functions/GetNestedProperty.ts +0 -29
  207. package/src/Functions/HTMLEvent.ts +0 -13
  208. package/src/Functions/SetNavigationSelected.ts +0 -19
  209. package/src/Functions/index.ts +0 -5
  210. /package/src/Utils/{ApiUtil → ApiUtils}/RequestUtil.ts +0 -0
@@ -1,9 +1,9 @@
1
1
  import { Arrayable, TransformType } from "../Types";
2
2
  import { EventEmitter } from "./Events";
3
3
 
4
- export type Reducer<State, Types extends Record<string, any[]>, Action extends keyof Types> = (state: State, ...args: Types[Action]) => State
5
- export type Actions<State, ActionTypes extends Record<string, any[]>> = {
6
- [Action in keyof ActionTypes]?: Arrayable<Reducer<State, ActionTypes, Action>>
4
+ export type Reducer<State, Types extends Record<string, any[]>, Action extends keyof Types> = (state: State, ...args: Types[Action]) => State;
5
+ export type Actions<State, ActionTypes extends Record<string, any[]>> = {
6
+ [Action in keyof ActionTypes]?: Arrayable<Reducer<State, ActionTypes, Action>>
7
7
  };
8
8
 
9
9
  /**
@@ -70,29 +70,29 @@ export type Actions<State, ActionTypes extends Record<string, any[]>> = {
70
70
  * ```
71
71
  */
72
72
  export class Store<
73
- State extends object,
74
- ActionTypes extends Record<string, any[]>,
75
- StoreActions extends Actions<State, ActionTypes> = Actions<State, ActionTypes>
73
+ State extends object,
74
+ ActionTypes extends Record<string, any[]>,
75
+ StoreActions extends Actions<State, ActionTypes> = Actions<State, ActionTypes>
76
76
  > extends EventEmitter<
77
- Record<keyof StoreActions, ActionTypes[keyof ActionTypes]>
78
- & Record<'stateChange', [previous: State, current: State]>
77
+ Record<keyof StoreActions, ActionTypes[keyof ActionTypes]>
78
+ & Record<'stateChange', [previous: State, current: State]>
79
79
  > {
80
- constructor(state: State, actions: StoreActions = {} as StoreActions) {
81
- super(new Map(...Object.entries(actions).map(([action, reducers]) => [action, reducers as any])));
80
+ constructor(state: State, actions: StoreActions = {} as StoreActions) {
81
+ super(new Map(...Object.entries(actions).map(([action, reducers]) => [action, reducers as any])));
82
82
 
83
- this._state = state;
84
- }
83
+ this._state = state;
84
+ }
85
85
 
86
- private _state: State;
87
- public get state(): State {
88
- return this._state;
89
- }
86
+ private _state: State;
87
+ public get state(): State {
88
+ return this._state;
89
+ }
90
90
 
91
- public dispatch<Action extends keyof ActionTypes>(action: Action, ...args: ActionTypes[Action]): State {
92
- const previous = { ...this._state };
93
- this._state = super.emit<State, Action>(action, ...args as any).reduce((state, returned) => ({ ...state, ...returned }), this.state);
91
+ public dispatch<Action extends keyof ActionTypes>(action: Action, ...args: ActionTypes[Action]): State {
92
+ const previous = { ...this._state };
93
+ this._state = super.emit<State, Action>(action, ...args as any).reduce((state, returned) => ({ ...state, ...returned }), this.state);
94
94
 
95
- super.emit<void, 'stateChange'>('stateChange', ...[previous, this.state] as any);
96
- return this.state;
97
- }
95
+ super.emit<void, 'stateChange'>('stateChange', ...[previous, this.state] as any);
96
+ return this.state;
97
+ }
98
98
  }
@@ -0,0 +1,103 @@
1
+ import { Arrayable } from "../../Types";
2
+
3
+ declare global {
4
+ interface Array<T> {
5
+ /**
6
+ * Returns the first `count` elements from the array.
7
+ * @param count Number of elements to take.
8
+ * @returns Array containing the first `count` elements.
9
+ */
10
+ take(count: number): Array<T>;
11
+
12
+ /**
13
+ * Returns a new array with only unique elements from the original array.
14
+ * @returns An array containing only unique elements.
15
+ */
16
+ unique(): Array<T>;
17
+
18
+ /**
19
+ * Splits the array into chunks of a specified size or by a splitter function.
20
+ * @param chunkSizeOrSplitter The size of each chunk or a function that determines where to split the array.
21
+ * @returns An array of arrays, where each sub-array is a chunk of the original array.
22
+ */
23
+ splitBy(chunkSizeOrSplitter: number | ((value: T, index: number, array: Array<T>) => boolean)): Array<Array<T>>;
24
+
25
+ /**
26
+ * Groups the elements of the array based on a key selector function.
27
+ * @param keySelector A function that selects a key for each element in the array.
28
+ * @returns A Map where each key is a group identifier and the value is an array of elements in that group.
29
+ */
30
+ groupBy<K>(keySelector: (value: T, index: number, array: Array<T>) => K): Map<K, Array<T>>;
31
+ }
32
+
33
+ interface ArrayConstructor {
34
+ /**
35
+ * Forces an arrayable object into an array
36
+ * @param arrayable The arrayable object to force into an array
37
+ * @returns An array containing the elements of the input or the single value.
38
+ */
39
+ forceArray<T>(arrayable: Arrayable<T>): Array<T>;
40
+ }
41
+ }
42
+
43
+ export function take<T>(this: Array<T>, count: number): Array<T> {
44
+ return this.slice(0, count);
45
+ }
46
+ Array.prototype.take = take;
47
+
48
+ export function forceArray<T>(arrayable: Arrayable<T>): Array<T> {
49
+ return Array.isArray(arrayable) ? arrayable : [arrayable];
50
+ }
51
+ Array.forceArray = forceArray;
52
+
53
+ export function unique<T>(this: Array<T>): Array<T> {
54
+ return [...new Set(this)];
55
+ }
56
+ Array.prototype.unique = unique;
57
+
58
+ export function splitBy<T>(this: Array<T>, chunkSize: number): Array<Array<T>>;
59
+ export function splitBy<T>(this: Array<T>, splitter: (value: T, index: number, array: Array<T>) => boolean): Array<Array<T>>;
60
+ export function splitBy<T>(this: Array<T>, chunkSizeOrSplitter: number | ((value: T, index: number, array: Array<T>) => boolean)): Array<Array<T>> {
61
+ const chunkSize = typeof chunkSizeOrSplitter === 'number' ? chunkSizeOrSplitter : undefined;
62
+ const splitter = typeof chunkSizeOrSplitter === 'function' ? chunkSizeOrSplitter : undefined;
63
+
64
+ const result: Array<Array<T>> = [];
65
+
66
+ if (chunkSize !== undefined) {
67
+ for (let i = 0; i < this.length; i += chunkSize) {
68
+ result.push(this.slice(i, i + chunkSize));
69
+ }
70
+ } else if (splitter !== undefined) {
71
+ const chunk = new Array<T>();
72
+
73
+ for (let i = 0; i < this.length; i++) {
74
+ const value = this[i];
75
+ if (splitter(value, i, this)) {
76
+ if (chunk.length) {
77
+ result.push(chunk.splice(0, chunk.length));
78
+ }
79
+ }
80
+
81
+ chunk.push(value);
82
+ }
83
+
84
+ if (chunk.length) {
85
+ result.push(chunk);
86
+ }
87
+ }
88
+
89
+ return result;
90
+ }
91
+ Array.prototype.splitBy = splitBy;
92
+
93
+ export function groupBy<T, K>(this: Array<T>, keySelector: (value: T, index: number, array: Array<T>) => K): Map<K, Array<T>> {
94
+ return this.reduce((map, item, index, array) => {
95
+ const key = keySelector(item, index, array);
96
+ const group = map.get(key) ?? new Array<T>();
97
+
98
+ group.push(item);
99
+ map.set(key, group);
100
+ return map;
101
+ }, new Map<K, Array<T>>());
102
+ }
103
+ Array.prototype.groupBy = groupBy;
@@ -0,0 +1,46 @@
1
+ export type UpdateFinder<T> = (item: T, index: number, self: Array<T>) => boolean
2
+
3
+ declare global {
4
+ interface Array<T> {
5
+ /**
6
+ * Pushes items to array and returns self with new items
7
+ * @param items Items to add to array
8
+ */
9
+ add(...items: Array<T>): this;
10
+ /**
11
+ * Update an item in array
12
+ * @param old The old value or index to update
13
+ * @param updated Updated value
14
+ */
15
+ update(old: T | number | UpdateFinder<T>, updated: T): T;
16
+ /**
17
+ * Removes item from array and returns self without item
18
+ * @param item Item or index to remove
19
+ */
20
+ remove(item: T | number): this;
21
+ }
22
+ }
23
+
24
+ export function add<T>(this: Array<T>, ...items: Array<T>) {
25
+ this.push(...items);
26
+ return this;
27
+ }
28
+ Array.prototype.add = add;
29
+
30
+ export function update<T>(this: Array<T>, old: T | number | UpdateFinder<T>, updated: T) {
31
+ const item = typeof old === 'number' ? this[old]
32
+ : typeof old === 'function' ? this.find(old as UpdateFinder<T>)
33
+ : old;
34
+ if (!item) throw new Error('Old was not found in array!');
35
+
36
+ const index = this.indexOf(item);
37
+ return this[index] = updated;
38
+ }
39
+ Array.prototype.update = update;
40
+
41
+ export function remove<T>(this: Array<T>, value: T | number): Array<T> {
42
+ const index = typeof value === 'number' ? value : this.indexOf(value);
43
+ if (index > -1) this.splice(index, 1);
44
+ return this;
45
+ }
46
+ Array.prototype.remove = remove;
@@ -0,0 +1,6 @@
1
+ export * from './array.extension';
2
+ export * from './crud.extension';
3
+ export * from './loop.extension';
4
+ export * from './random.extension';
5
+ export * from './sort.extension';
6
+ export * from './string.extension';
@@ -0,0 +1,38 @@
1
+ declare global {
2
+ interface Array<T> {
3
+ /**
4
+ * For every x in array, execute callback
5
+ * @param every i.e every 2nd item in array
6
+ * @param callback Function to execute
7
+ * @returns Array of results
8
+ */
9
+ nth<U>(every: number, callback: (item: T, index: number, collection: Array<T>, self: this) => U): Array<U>;
10
+ }
11
+ }
12
+
13
+ /**
14
+ * For every x in array, execute callback
15
+ * @param every i.e every 2nd item in array
16
+ * @param callback Function to execute. This includes a collection of items prior to last callback run
17
+ * @returns Array of results
18
+ */
19
+ export function nth<T, U>(
20
+ this: Array<T>,
21
+ every: number,
22
+ callback: (item: T, index: number, collection: Array<T>, self: Array<T>) => U
23
+ ): Array<U> {
24
+ const result = new Array<U>();
25
+ let collection = new Array<T>();
26
+
27
+ for (let i = 0; i < this.length; i++) {
28
+ collection.push(this[i]);
29
+
30
+ if ((i + 1) % every === 0) {
31
+ result.push(callback(this[i], i, collection, this));
32
+ collection = new Array<T>();
33
+ }
34
+ }
35
+
36
+ return result;
37
+ }
38
+ Array.prototype.nth = nth;
@@ -0,0 +1,56 @@
1
+ declare global {
2
+ interface Array<T> {
3
+ /**
4
+ * Returns a random element from the array.
5
+ * @returns A random element from the array.
6
+ */
7
+ random(): T;
8
+
9
+ /**
10
+ * Returns a new array with the elements of the original array in random order.
11
+ * @returns A new array with the elements shuffled.
12
+ */
13
+ shuffle(): Array<T>;
14
+
15
+ /**
16
+ * Selects a random item from an array based on specified weights.
17
+ * @param items An array of tuples where each tuple contains an item and its corresponding weight.
18
+ * @returns A randomly selected item based on the provided weights.
19
+ */
20
+ randomWithPercentages(items: [item: T, weight: number][]): T;
21
+ }
22
+ }
23
+
24
+ export function random<T>(this: Array<T>): T {
25
+ const randomIndex = Math.floor(Math.random() * this.length);
26
+ return this[randomIndex];
27
+ }
28
+ Array.prototype.random = random;
29
+
30
+ export function shuffle<T>(this: Array<T>): Array<T> {
31
+ return this.sort(() => Math.random() - 0.5);
32
+ }
33
+ Array.prototype.shuffle = shuffle;
34
+
35
+ export function randomWithPercentages<T>(items: [item: T, weight: number][]): T {
36
+ if (items.length === 0) throw new Error('Items array cannot be empty');
37
+
38
+ // Calculate total weight in case weights don't sum to 100
39
+ const totalWeight = items.reduce((sum, [, weight]) => sum + weight, 0);
40
+ if (totalWeight === 0) throw new Error('Total weight must be greater than zero');
41
+
42
+ // Generate random number between 0 and totalWeight
43
+ const random = Math.random() * totalWeight;
44
+
45
+ // Find the item that corresponds to this random value
46
+ let currentWeight = 0;
47
+ for (const [item, weight] of items) {
48
+ currentWeight += weight;
49
+ if (random <= currentWeight) {
50
+ return item;
51
+ }
52
+ }
53
+
54
+ throw new Error('Unable to select an item based on weights');
55
+ }
56
+ Array.prototype.randomWithPercentages = randomWithPercentages;
@@ -0,0 +1,52 @@
1
+ type Comparator<T> = (a: T, b: T) => number;
2
+
3
+ declare global {
4
+ interface Array<T> {
5
+ /**
6
+ * Sorts the array using multiple comparators.
7
+ * @param comparators Functions to compare elements.
8
+ * @returns Sorted array.
9
+ */
10
+ orderBy(...comparators: Array<Comparator<T>>): Array<T>;
11
+
12
+ /**
13
+ * Sorts the array using multiple comparators in descending order.
14
+ * @param comparators Functions to compare elements.
15
+ * @returns Sorted array in descending order.
16
+ */
17
+ orderByDescending(...comparators: Array<Comparator<T>>): Array<T>;
18
+
19
+ /**
20
+ * Sorts the array by specified properties.
21
+ * @param properties Properties to sort by.
22
+ * @returns Sorted array.
23
+ */
24
+ sortByProperty(...properties: Array<keyof T>): Array<T>;
25
+ }
26
+ }
27
+
28
+ export function orderBy<T>(this: Array<T>, ...comparators: Array<Comparator<T>>): Array<T> {
29
+ return this.sort((a, b) => {
30
+ for (const comparator of comparators) {
31
+ const result = comparator(a, b);
32
+ if (result !== 0) return result;
33
+ }
34
+
35
+ return 0;
36
+ });
37
+ }
38
+ Array.prototype.orderBy = orderBy;
39
+
40
+ export function orderByDescending<T>(this: Array<T>, ...comparators: Array<Comparator<T>>): Array<T> {
41
+ return this.orderBy(...comparators).reverse();
42
+ }
43
+ Array.prototype.orderByDescending = orderByDescending;
44
+
45
+ export function sortByProperty<T extends object>(this: Array<T>, ...properties: Array<keyof T>): Array<T> {
46
+ return this.orderBy(...properties.map(property => (a: T, b: T) => {
47
+ if (a[property] < b[property]) return -1;
48
+ if (a[property] > b[property]) return 1;
49
+ return 0;
50
+ }));
51
+ }
52
+ Array.prototype.sortByProperty = sortByProperty;
@@ -0,0 +1,22 @@
1
+ declare global {
2
+ interface Array<T> {
3
+ /**
4
+ * Joins the elements of the array into a string, with optional custom separators.
5
+ * @param args An array of strings or undefined values to be used as separators between elements.
6
+ * @param separator The default separator to use between elements if args is not provided or undefined.
7
+ * @param endSeparator The separator to use before the last element.
8
+ * @returns A string with the joined elements.
9
+ */
10
+ join(args?: Array<string | undefined>, separator?: string, endSeparator?: string): string;
11
+ }
12
+ }
13
+
14
+ export function join<T>(this: Array<T>, separator = ',', endSeparator = '&'): string {
15
+ const validArgs = this.filter(arg => !Object.isNullOrUndefined(arg) && arg !== '');
16
+ if (!validArgs.length) return '';
17
+ if (validArgs.length === 1) return validArgs.shift()!.toString();
18
+
19
+ const lastArg = validArgs.pop()!;
20
+ const combinedArgs = validArgs.join(separator);
21
+ return `${combinedArgs}${endSeparator ? ` ${endSeparator} ` : ''}${lastArg}`;
22
+ }
@@ -1,18 +1,45 @@
1
+ import { Functionable } from "../Types";
2
+
1
3
  declare global {
2
- interface Function {
3
- /**
4
- * Checks if obj is a function
5
- * @param obj Object to check
6
- */
7
- is(obj: any): obj is Function;
8
- }
4
+ interface Function {
5
+ /**
6
+ * Checks if obj is a function
7
+ * @param obj Object to check
8
+ */
9
+ is(obj: any): obj is Function;
10
+
11
+ /**
12
+ * Resolves a Functionable<T> to T, if it's a function, it will be called with the provided arguments and its return value will be returned, otherwise the value itself will be returned.
13
+ * @param functionable The Functionable<T> to resolve
14
+ * @param args Arguments to call the function with if functionable is a function
15
+ */
16
+ resolveFunctionable<T, TArgs extends any[] = any[]>(functionable: Functionable<T, TArgs>, ...args: TArgs): T;
17
+
18
+ /**
19
+ * Forces a Functionable<T> to be a function, if it's already a function, it will be returned as is, otherwise a function that returns the value will be returned.
20
+ * @param functionable The Functionable<T> to force to be a function
21
+ */
22
+ forceFunction<T, TArgs extends any[] = any[]>(functionable: Functionable<T, TArgs>): (...args: TArgs) => T;
23
+ }
9
24
  }
10
25
 
11
- function is(obj: any): obj is Function {
12
- return typeof obj === 'function';
26
+ export function is(obj: any): obj is Function {
27
+ return typeof obj === 'function';
13
28
  }
14
29
  Function.is = is;
15
30
 
31
+ export function resolveFunctionable<T, TArgs extends any[] = any[]>(functionable: Functionable<T, TArgs>, ...args: TArgs): T {
32
+ return is(functionable) ? functionable(...args) : functionable;
33
+ }
34
+ Function.resolveFunctionable = resolveFunctionable;
35
+
36
+ export function forceFunction<T, TArgs extends any[] = any[]>(functionable: Functionable<T, TArgs>): (...args: TArgs) => T {
37
+ return is(functionable) ? functionable : () => functionable;
38
+ }
39
+ Function.forceFunction = forceFunction;
40
+
16
41
  export const FunctionExtensions = {
17
- is
42
+ is,
43
+ resolveFunctionable,
44
+ forceFunction
18
45
  };
@@ -1,88 +1,88 @@
1
1
  declare global {
2
- interface Map<K, V> {
3
- /**
4
- * Converts into Array<[Key, Value]>
5
- */
6
- array(): Array<[K, V]>
7
- /**
8
- * Maps values into new types of generics
9
- * @param callback Callbacking function to map values
10
- */
11
- map<EK, EV>(callback: (value: V, key: K, index: number, self: this) => [EK, EV]): Map<EK, EV>
12
- /**
13
- * Returns array of "accepted" values. Criteria defined in callback param
14
- * @param callback Callbacking function to filter away unwanted values
15
- */
16
- filter(callback: (value: V, key: K, index: number, self: this) => boolean): Map<K, V>
17
- /**
18
- * Returns array of keys
19
- */
20
- keyArr(): Array<K>
21
- /**
22
- * Returns array of values
23
- */
24
- valueArr(): Array<V>
25
- /**
26
- * Returns first [key, value] match to callback param. Returns undefined if nothing found
27
- * @param callback Callbacking function to find KeyValuePair
28
- */
29
- find(callback: (value: V, key: K, index: number, self: this) => boolean): [K, V] | undefined
30
- /**
31
- * Whether or not map includes a value. Returns true if it does, false if not ¯\_(ツ)_/¯
32
- * @param value Value that may be includded in map
33
- * @param fromIndex Start looking for value from specific index+. Default: 0
34
- */
35
- includes(value: V, fromIndex?: number): boolean
36
- }
2
+ interface Map<K, V> {
3
+ /**
4
+ * Converts into Array<[Key, Value]>
5
+ */
6
+ array(): Array<[K, V]>;
7
+ /**
8
+ * Maps values into new types of generics
9
+ * @param callback Callbacking function to map values
10
+ */
11
+ map<EK, EV>(callback: (value: V, key: K, index: number, self: this) => [EK, EV]): Map<EK, EV>;
12
+ /**
13
+ * Returns array of "accepted" values. Criteria defined in callback param
14
+ * @param callback Callbacking function to filter away unwanted values
15
+ */
16
+ filter(callback: (value: V, key: K, index: number, self: this) => boolean): Map<K, V>;
17
+ /**
18
+ * Returns array of keys
19
+ */
20
+ keyArr(): Array<K>;
21
+ /**
22
+ * Returns array of values
23
+ */
24
+ valueArr(): Array<V>;
25
+ /**
26
+ * Returns first [key, value] match to callback param. Returns undefined if nothing found
27
+ * @param callback Callbacking function to find KeyValuePair
28
+ */
29
+ find(callback: (value: V, key: K, index: number, self: this) => boolean): [K, V] | undefined;
30
+ /**
31
+ * Whether or not map includes a value. Returns true if it does, false if not ¯\_(ツ)_/¯
32
+ * @param value Value that may be includded in map
33
+ * @param fromIndex Start looking for value from specific index+. Default: 0
34
+ */
35
+ includes(value: V, fromIndex?: number): boolean;
36
+ }
37
37
  }
38
38
 
39
39
  function array<K, V>(this: Map<K, V>): Array<[K, V]> {
40
- let result = new Array<[K, V]>();
41
- for (const kvp of this) {
42
- result.push(kvp);
43
- }
44
- return result;
40
+ let result = new Array<[K, V]>();
41
+ for (const kvp of this) {
42
+ result.push(kvp);
43
+ }
44
+ return result;
45
45
  }
46
46
  Map.prototype.array = array;
47
47
 
48
48
  function map<K, V, EK, EV>(this: Map<K, V>, callback: (value: V, key: K, index: number, map: Map<K, V>) => [EK, EV]): Map<EK, EV> {
49
- return this.array()
50
- .map(([k, v], i) => callback(v, k, i, this))
51
- .reduce((map, [key, value]) =>
52
- map.set(key, value),
53
- new Map<EK, EV>())
49
+ return this.array()
50
+ .map(([k, v], i) => callback(v, k, i, this))
51
+ .reduce((map, [key, value]) =>
52
+ map.set(key, value),
53
+ new Map<EK, EV>());
54
54
  }
55
55
  Map.prototype.map = map;
56
56
 
57
57
  function filter<K, V>(this: Map<K, V>, callback: (value: V, key: K, index: number, map: Map<K, V>) => boolean): Map<K, V> {
58
- return this.array()
59
- .filter(([k, v], i) => callback(v, k, i, this))
60
- .reduce((map, [key, value]) =>
61
- map.set(key, value),
62
- new Map<K, V>())
58
+ return this.array()
59
+ .filter(([k, v], i) => callback(v, k, i, this))
60
+ .reduce((map, [key, value]) =>
61
+ map.set(key, value),
62
+ new Map<K, V>());
63
63
  }
64
64
  Map.prototype.filter = filter;
65
65
 
66
66
  function keyArr<K, V>(this: Map<K, V>): Array<K> {
67
- return this.array().map(([k]) => k);
67
+ return this.array().map(([k]) => k);
68
68
  }
69
69
  Map.prototype.keyArr = keyArr;
70
70
 
71
71
  function valueArr<K, V>(this: Map<K, V>): Array<V> {
72
- return this.array().map(([_, v]) => v);
72
+ return this.array().map(([_, v]) => v);
73
73
  }
74
74
  Map.prototype.valueArr = valueArr;
75
75
 
76
76
  function find<K, V>(this: Map<K, V>, callback: (value: V, key: K, index: number, map: Map<K, V>) => boolean) {
77
- return this.array().find(([k, v], i) => callback(v, k, i, this));
77
+ return this.array().find(([k, v], i) => callback(v, k, i, this));
78
78
  }
79
79
  Map.prototype.find = find;
80
80
 
81
81
  function includes<K, V>(this: Map<K, V>, item: V, fromIndex?: number) {
82
- return this.valueArr().includes(item, fromIndex);
82
+ return this.valueArr().includes(item, fromIndex);
83
83
  }
84
84
  Map.prototype.includes = includes;
85
85
 
86
86
  export const MapExtensions = {
87
- array, map, filter, keyArr, valueArr, find, includes
88
- }
87
+ array, map, filter, keyArr, valueArr, find, includes
88
+ };
@@ -0,0 +1,50 @@
1
+ type Separators = {
2
+ thousand: string;
3
+ decimal: string;
4
+ }
5
+
6
+ declare global {
7
+ interface Number {
8
+ toSeparationString(separators: Partial<Separators>): string;
9
+ toRomanNumeral(): string;
10
+ }
11
+ }
12
+
13
+ export function toSeparationString(this: number, separators: Partial<Separators>): string {
14
+ const { thousand = '.', decimal = '.' } = separators;
15
+ const [integerPart, decimalPart] = this.toString().split('.');
16
+ const formattedInteger = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, thousand);
17
+ return decimalPart ? `${formattedInteger}${decimal}${decimalPart}` : formattedInteger;
18
+ }
19
+ Number.prototype.toSeparationString = toSeparationString;
20
+
21
+ export function toRomanNumeral(this: number): string {
22
+ if (this <= 0 || this >= 4000) throw new RangeError('Number must be between 1 and 3999 to convert to Roman numeral');
23
+
24
+ const numeralMap: [number, string][] = [
25
+ [1000, 'M'],
26
+ [900, 'CM'],
27
+ [500, 'D'],
28
+ [400, 'CD'],
29
+ [100, 'C'],
30
+ [90, 'XC'],
31
+ [50, 'L'],
32
+ [40, 'XL'],
33
+ [10, 'X'],
34
+ [9, 'IX'],
35
+ [5, 'V'],
36
+ [4, 'IV'],
37
+ [1, 'I']
38
+ ];
39
+
40
+ let value = this;
41
+ return numeralMap.reduce((acc, [numeralValue, numeral]) => {
42
+ while (value >= numeralValue) {
43
+ acc += numeral;
44
+ value -= numeralValue;
45
+ }
46
+
47
+ return acc;
48
+ }, '');
49
+ }
50
+ Number.prototype.toRomanNumeral = toRomanNumeral;
@@ -0,0 +1,27 @@
1
+ import { ValueOf } from "../../Types";
2
+
3
+ declare global {
4
+ interface ObjectConstructor {
5
+ /**
6
+ * Destructures object into array of [property, value]
7
+ * @param from Object to destruct
8
+ */
9
+ array<From extends {} = {}>(from: From): Array<[keyof From, ValueOf<From>]>;
10
+
11
+ /**
12
+ * Destructures object into array of property keys
13
+ * @param from Object to destruct
14
+ */
15
+ keysOf<From extends {} = {}>(from: From): Array<keyof From>;
16
+ }
17
+ }
18
+
19
+ export function array<From extends {} = {}>(this: object, from: From): Array<[keyof From, ValueOf<From>]> {
20
+ return Object.entries(from) as Array<[keyof From, ValueOf<From>]>;
21
+ }
22
+ Object.array = array;
23
+
24
+ export function keysOf<From extends {} = {}>(this: object, from: From): Array<keyof From> {
25
+ return Object.keys(from) as Array<keyof From>;
26
+ }
27
+ Object.keysOf = keysOf;