@etsoo/shared 1.2.71 → 1.2.73

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
@@ -122,6 +122,7 @@ Array related utilities
122
122
  | minItem | Get min field value item |
123
123
  | remove | Remove items by value or condition |
124
124
  | sum | Sum number items or number item properties |
125
+ | toggleItem | Toggle item in array |
125
126
  | toUnique | Make all items are unique |
126
127
 
127
128
  ## DataTypes
@@ -276,6 +277,7 @@ Numbers related utilities
276
277
  | getCurrencySymbol | Get currency symbol or name from ISO code |
277
278
  | parse | Parse to number, with or without default value |
278
279
  | toExact | To the exact precision number avoiding precision lost |
280
+ | toStep | To the step number, like 0, 10, 20, 30 for step 10 |
279
281
 
280
282
  ## StorageUtils
281
283
 
@@ -157,3 +157,39 @@ test("Tests for sortIds 2", () => {
157
157
  "SGD"
158
158
  ]);
159
159
  });
160
+
161
+ test("Tests for toggleItem", () => {
162
+ const items = [1, 2, 3];
163
+ items.toggleItem(2, false);
164
+ expect(items).toStrictEqual([1, 3]);
165
+
166
+ items.toggleItem(4, true);
167
+ expect(items).toStrictEqual([1, 3, 4]);
168
+
169
+ items.toggleItem(1, false);
170
+ expect(items).toStrictEqual([3, 4]);
171
+
172
+ items.toggleItem(3, true);
173
+ expect(items).toStrictEqual([3, 4]);
174
+ });
175
+
176
+ test("Tests for toggleItem with object", () => {
177
+ const items = [
178
+ { id: 1, label: "a" },
179
+ { id: 2, label: "b" }
180
+ ];
181
+ items.toggleItem({ id: 2, label: "b" }, false);
182
+ expect(items).toStrictEqual([{ id: 1, label: "a" }]);
183
+
184
+ items.toggleItem({ id: 3, label: "c" }, true, "id");
185
+ expect(items).toStrictEqual([
186
+ { id: 1, label: "a" },
187
+ { id: 3, label: "c" }
188
+ ]);
189
+
190
+ items.toggleItem(1, false, "id");
191
+ expect(items).toStrictEqual([{ id: 3, label: "c" }]);
192
+
193
+ items.toggleItem({ id: 3, label: "c" }, true, "id");
194
+ expect(items).toStrictEqual([{ id: 3, label: "c" }]);
195
+ });
@@ -50,3 +50,12 @@ test("Tests for toFileSize", () => {
50
50
  expect(NumberUtils.formatFileSize(1125000)).toBe("1.07 MB");
51
51
  expect(NumberUtils.formatFileSize(1125000, 1)).toBe("1.1 MB");
52
52
  });
53
+
54
+ test("Tests for toStep", () => {
55
+ const nums = [9, 13, 20, 33, 99, 101, 3009];
56
+ const results = nums.map((num) => num.toStep(10));
57
+ expect(results).toStrictEqual([0, 10, 20, 30, 90, 100, 3000]);
58
+
59
+ const results2 = nums.map((num) => num.toStep(8));
60
+ expect(results2).toStrictEqual([8, 8, 16, 32, 96, 96, 3008]);
61
+ });
@@ -1,4 +1,4 @@
1
- import { DataTypes } from "./DataTypes";
1
+ import { DataTypes, IdType } from "./DataTypes";
2
2
  declare global {
3
3
  interface Array<T> {
4
4
  /**
@@ -43,6 +43,13 @@ declare global {
43
43
  * @param field Object field to calculate
44
44
  */
45
45
  sum(...field: T extends number ? [undefined?] : T extends object ? [DataTypes.Keys<T, number>] : [never]): number;
46
+ /**
47
+ * Toggle item in array
48
+ * @param item Item to toggle
49
+ * @param add If true, add the item, otherwise remove it
50
+ * @param idField If item is an object, use this field to check for existence
51
+ */
52
+ toggleItem(item: T extends object ? T | IdType : T, add: boolean, idField?: T extends object ? keyof T : never): Array<T>;
46
53
  /**
47
54
  * Make all items are unique
48
55
  * @param this Input array
@@ -8,6 +8,31 @@ const lodash_isequal_1 = __importDefault(require("lodash.isequal"));
8
8
  Array.prototype.different = function (target, round) {
9
9
  return ArrayUtils.differences(this, target, round);
10
10
  };
11
+ Array.prototype.toggleItem = function (item, add, idField) {
12
+ const isObject = typeof item === "object" && item !== null;
13
+ const index = this.findIndex((i) => {
14
+ if (idField) {
15
+ if (isObject) {
16
+ return i[idField] === item[idField];
17
+ }
18
+ else {
19
+ return i[idField] === item;
20
+ }
21
+ }
22
+ return (0, lodash_isequal_1.default)(i, item);
23
+ });
24
+ if (add) {
25
+ if (index < 0) {
26
+ // Ignore type checking
27
+ this.push(item);
28
+ }
29
+ }
30
+ else {
31
+ if (index >= 0)
32
+ this.splice(index, 1);
33
+ }
34
+ return this;
35
+ };
11
36
  Array.prototype.toUnique = function () {
12
37
  if (this.length === 0 || typeof this[0] !== "object")
13
38
  return Array.from(new Set(this));
@@ -5,6 +5,11 @@ declare global {
5
5
  * @param precision Precision
6
6
  */
7
7
  toExact(precision?: number): number;
8
+ /**
9
+ * To the step number, like 0, 10, 20, 30 for step 10
10
+ * @param step Step
11
+ */
12
+ toStep(step: number): number;
8
13
  }
9
14
  }
10
15
  export declare namespace NumberUtils {
@@ -9,6 +9,11 @@ Number.prototype.toExact = function (precision) {
9
9
  const p = Math.pow(10, precision);
10
10
  return Math.round(this * p) / p;
11
11
  };
12
+ Number.prototype.toStep = function (step) {
13
+ if (step <= 0)
14
+ return this;
15
+ return Math.floor(this / step) * step;
16
+ };
12
17
  var NumberUtils;
13
18
  (function (NumberUtils) {
14
19
  /**
@@ -1,4 +1,4 @@
1
- import { DataTypes } from "./DataTypes";
1
+ import { DataTypes, IdType } from "./DataTypes";
2
2
  declare global {
3
3
  interface Array<T> {
4
4
  /**
@@ -43,6 +43,13 @@ declare global {
43
43
  * @param field Object field to calculate
44
44
  */
45
45
  sum(...field: T extends number ? [undefined?] : T extends object ? [DataTypes.Keys<T, number>] : [never]): number;
46
+ /**
47
+ * Toggle item in array
48
+ * @param item Item to toggle
49
+ * @param add If true, add the item, otherwise remove it
50
+ * @param idField If item is an object, use this field to check for existence
51
+ */
52
+ toggleItem(item: T extends object ? T | IdType : T, add: boolean, idField?: T extends object ? keyof T : never): Array<T>;
46
53
  /**
47
54
  * Make all items are unique
48
55
  * @param this Input array
@@ -2,6 +2,31 @@ import isEqual from "lodash.isequal";
2
2
  Array.prototype.different = function (target, round) {
3
3
  return ArrayUtils.differences(this, target, round);
4
4
  };
5
+ Array.prototype.toggleItem = function (item, add, idField) {
6
+ const isObject = typeof item === "object" && item !== null;
7
+ const index = this.findIndex((i) => {
8
+ if (idField) {
9
+ if (isObject) {
10
+ return i[idField] === item[idField];
11
+ }
12
+ else {
13
+ return i[idField] === item;
14
+ }
15
+ }
16
+ return isEqual(i, item);
17
+ });
18
+ if (add) {
19
+ if (index < 0) {
20
+ // Ignore type checking
21
+ this.push(item);
22
+ }
23
+ }
24
+ else {
25
+ if (index >= 0)
26
+ this.splice(index, 1);
27
+ }
28
+ return this;
29
+ };
5
30
  Array.prototype.toUnique = function () {
6
31
  if (this.length === 0 || typeof this[0] !== "object")
7
32
  return Array.from(new Set(this));
@@ -5,6 +5,11 @@ declare global {
5
5
  * @param precision Precision
6
6
  */
7
7
  toExact(precision?: number): number;
8
+ /**
9
+ * To the step number, like 0, 10, 20, 30 for step 10
10
+ * @param step Step
11
+ */
12
+ toStep(step: number): number;
8
13
  }
9
14
  }
10
15
  export declare namespace NumberUtils {
@@ -6,6 +6,11 @@ Number.prototype.toExact = function (precision) {
6
6
  const p = Math.pow(10, precision);
7
7
  return Math.round(this * p) / p;
8
8
  };
9
+ Number.prototype.toStep = function (step) {
10
+ if (step <= 0)
11
+ return this;
12
+ return Math.floor(this / step) * step;
13
+ };
9
14
  export var NumberUtils;
10
15
  (function (NumberUtils) {
11
16
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/shared",
3
- "version": "1.2.71",
3
+ "version": "1.2.73",
4
4
  "description": "TypeScript shared utilities and functions",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/mjs/index.js",
@@ -37,10 +37,10 @@
37
37
  "homepage": "https://github.com/ETSOO/Shared#readme",
38
38
  "devDependencies": {
39
39
  "@types/lodash.isequal": "^4.5.8",
40
- "@vitejs/plugin-react": "^4.4.1",
40
+ "@vitejs/plugin-react": "^4.5.0",
41
41
  "jsdom": "^26.1.0",
42
42
  "typescript": "^5.8.3",
43
- "vitest": "^3.1.3"
43
+ "vitest": "^3.1.4"
44
44
  },
45
45
  "dependencies": {
46
46
  "lodash.isequal": "^4.5.0"
package/src/ArrayUtils.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import isEqual from "lodash.isequal";
2
- import { DataTypes } from "./DataTypes";
2
+ import { DataTypes, IdType } from "./DataTypes";
3
3
 
4
4
  declare global {
5
5
  interface Array<T> {
@@ -77,6 +77,18 @@ declare global {
77
77
  : [never]
78
78
  ): number;
79
79
 
80
+ /**
81
+ * Toggle item in array
82
+ * @param item Item to toggle
83
+ * @param add If true, add the item, otherwise remove it
84
+ * @param idField If item is an object, use this field to check for existence
85
+ */
86
+ toggleItem(
87
+ item: T extends object ? T | IdType : T,
88
+ add: boolean,
89
+ idField?: T extends object ? keyof T : never
90
+ ): Array<T>;
91
+
80
92
  /**
81
93
  * Make all items are unique
82
94
  * @param this Input array
@@ -93,6 +105,36 @@ Array.prototype.different = function <T>(
93
105
  return ArrayUtils.differences(this, target, round);
94
106
  };
95
107
 
108
+ Array.prototype.toggleItem = function <T>(
109
+ this: Array<T>,
110
+ item: T extends object ? T | IdType : T,
111
+ add: boolean,
112
+ idField?: T extends object ? keyof T : never
113
+ ) {
114
+ const isObject = typeof item === "object" && item !== null;
115
+ const index = this.findIndex((i) => {
116
+ if (idField) {
117
+ if (isObject) {
118
+ return i[idField] === (item as any)[idField];
119
+ } else {
120
+ return i[idField] === item;
121
+ }
122
+ }
123
+ return isEqual(i, item);
124
+ });
125
+
126
+ if (add) {
127
+ if (index < 0) {
128
+ // Ignore type checking
129
+ this.push(item as T);
130
+ }
131
+ } else {
132
+ if (index >= 0) this.splice(index, 1);
133
+ }
134
+
135
+ return this;
136
+ };
137
+
96
138
  Array.prototype.toUnique = function <T>(this: Array<T>) {
97
139
  if (this.length === 0 || typeof this[0] !== "object")
98
140
  return Array.from(new Set(this));
@@ -5,6 +5,12 @@ declare global {
5
5
  * @param precision Precision
6
6
  */
7
7
  toExact(precision?: number): number;
8
+
9
+ /**
10
+ * To the step number, like 0, 10, 20, 30 for step 10
11
+ * @param step Step
12
+ */
13
+ toStep(step: number): number;
8
14
  }
9
15
  }
10
16
 
@@ -17,6 +23,12 @@ Number.prototype.toExact = function (this: number, precision?: number) {
17
23
  return Math.round(this * p) / p;
18
24
  };
19
25
 
26
+ Number.prototype.toStep = function (this: number, step: number) {
27
+ if (step <= 0) return this;
28
+
29
+ return Math.floor(this / step) * step;
30
+ };
31
+
20
32
  export namespace NumberUtils {
21
33
  /**
22
34
  * Format number