es-toolkit 1.22.0 → 1.23.0-dev.715

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 (83) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/_chunk/{flowRight-BzdOZX.js → flowRight-Dv8J0U.js} +21 -3
  3. package/dist/_chunk/{toMerged-2WPeoI.js → isObjectLike-aywuSF.js} +20 -10
  4. package/dist/_chunk/{isPlainObject-BIekvL.js → isPlainObject-DgrsU7.js} +11 -11
  5. package/dist/_chunk/{isWeakSet-clQklw.js → isWeakSet-BAMm2l.js} +85 -22
  6. package/dist/_chunk/noop-2IwLUk.js +5 -0
  7. package/dist/_chunk/{pad-Cw2pvt.js → pad-BWiShN.js} +21 -21
  8. package/dist/browser.global.js +1 -1
  9. package/dist/browser.global.js.map +1 -1
  10. package/dist/compat/array/dropWhile.d.mts +20 -0
  11. package/dist/compat/array/dropWhile.d.ts +20 -0
  12. package/dist/compat/array/every.d.mts +11 -11
  13. package/dist/compat/array/every.d.ts +11 -11
  14. package/dist/compat/array/filter.d.mts +10 -11
  15. package/dist/compat/array/filter.d.ts +10 -11
  16. package/dist/compat/array/filter.mjs +13 -0
  17. package/dist/compat/array/includes.mjs +1 -4
  18. package/dist/compat/function/flow.d.mts +133 -0
  19. package/dist/compat/function/flow.d.ts +133 -0
  20. package/dist/compat/function/flow.mjs +12 -0
  21. package/dist/compat/function/flowRight.d.mts +145 -0
  22. package/dist/compat/function/flowRight.d.ts +145 -0
  23. package/dist/compat/function/flowRight.mjs +12 -0
  24. package/dist/compat/index.d.mts +8 -2
  25. package/dist/compat/index.d.ts +8 -2
  26. package/dist/compat/index.js +87 -51
  27. package/dist/compat/index.mjs +9 -3
  28. package/dist/compat/math/random.mjs +1 -1
  29. package/dist/compat/object/has.mjs +2 -2
  30. package/dist/compat/object/mapKeys.mjs +1 -1
  31. package/dist/compat/object/mapValues.mjs +1 -1
  32. package/dist/compat/object/merge.mjs +1 -1
  33. package/dist/compat/object/mergeWith.mjs +1 -1
  34. package/dist/compat/object/omit.mjs +1 -1
  35. package/dist/compat/object/pick.mjs +2 -2
  36. package/dist/compat/object/unset.mjs +1 -1
  37. package/dist/compat/predicate/isMatch.mjs +4 -0
  38. package/dist/compat/predicate/matches.mjs +1 -1
  39. package/dist/compat/predicate/matchesProperty.mjs +1 -1
  40. package/dist/function/curryRight.d.mts +140 -0
  41. package/dist/function/curryRight.d.ts +140 -0
  42. package/dist/function/curryRight.mjs +21 -0
  43. package/dist/function/index.d.mts +1 -0
  44. package/dist/function/index.d.ts +1 -0
  45. package/dist/function/index.js +4 -2
  46. package/dist/function/index.mjs +1 -0
  47. package/dist/index.d.mts +6 -0
  48. package/dist/index.d.ts +6 -0
  49. package/dist/index.js +23 -16
  50. package/dist/index.mjs +6 -0
  51. package/dist/object/clone.mjs +1 -1
  52. package/dist/object/cloneDeep.mjs +2 -2
  53. package/dist/object/index.js +13 -13
  54. package/dist/object/merge.mjs +14 -4
  55. package/dist/object/pick.mjs +1 -1
  56. package/dist/predicate/index.d.mts +5 -0
  57. package/dist/predicate/index.d.ts +5 -0
  58. package/dist/predicate/index.js +7 -2
  59. package/dist/predicate/index.mjs +5 -0
  60. package/dist/predicate/isArrayBuffer.d.mts +20 -0
  61. package/dist/predicate/isArrayBuffer.d.ts +20 -0
  62. package/dist/predicate/isArrayBuffer.mjs +5 -0
  63. package/dist/predicate/isEqual.mjs +3 -171
  64. package/dist/predicate/isEqualWith.d.mts +38 -0
  65. package/dist/predicate/isEqualWith.d.ts +38 -0
  66. package/dist/predicate/isEqualWith.mjs +184 -0
  67. package/dist/predicate/isJSONArray.d.mts +17 -0
  68. package/dist/predicate/isJSONArray.d.ts +17 -0
  69. package/dist/predicate/isJSONArray.mjs +10 -0
  70. package/dist/predicate/isJSONObject.d.mts +16 -0
  71. package/dist/predicate/isJSONObject.d.ts +16 -0
  72. package/dist/predicate/isJSONObject.mjs +22 -0
  73. package/dist/predicate/isJSONValue.d.mts +27 -0
  74. package/dist/predicate/isJSONValue.d.ts +27 -0
  75. package/dist/predicate/isJSONValue.mjs +20 -0
  76. package/dist/predicate/isPlainObject.d.mts +3 -3
  77. package/dist/predicate/isPlainObject.d.ts +3 -3
  78. package/dist/predicate/isPlainObject.mjs +7 -7
  79. package/dist/string/_internal/getWords.mjs +1 -1
  80. package/dist/string/camelCase.mjs +1 -1
  81. package/dist/string/index.js +1 -1
  82. package/dist/string/trim.mjs +1 -1
  83. package/package.json +11 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # es-toolkit Changelog
2
2
 
3
+ ## Version v1.23.0
4
+
5
+ Released on October 1st, 2024.
6
+
7
+ - Added support for [isEqualWith](https://es-toolkit.slash.page/reference/predicate/isEqualWith.html), [isArrayBuffer](https://es-toolkit.slash.page/reference/predicate/isArrayBuffer.html), [curryRight](https://es-toolkit.slash.page/reference/function/curryRight.html), [isJSONValue](https://es-toolkit.slash.page/reference/predicate/isJSONValue.html), [isJSONObject](https://es-toolkit.slash.page/reference/predicate/isJSONObject.html), [isJSONArray](https://es-toolkit.slash.page/reference/predicate/isJSONArray.html).
8
+ - Fixed a bug in [merge](https://es-toolkit.slash.page/reference/object/merge.html) that copied the reference from the `source` object to the `target` object.
9
+ - Fixed a bug in [includes](https://es-toolkit.slash.page/reference/compat/array/includes.html) that returned `true` for inherited properties.
10
+ - Fixed a bug in [startCase](https://es-toolkit.slash.page/reference/string/startCase.html) and other string methods that did not correctly split the words when using accented letters.
11
+ - Fixed a bug in [filter](https://es-toolkit.slash.page/reference/compat/array/filter.html) that did not provide correct arguments to the predicate function.
12
+ - Fixed a bug in [isMatch](https://es-toolkit.slash.page/reference/compat/predicate/isMatch.html) that did not strictly compare primitive falsy values.
13
+
14
+ This version includes contributions from @D-Sketon, @wojtekmaj, @mass2527, @chhw130, and @knott11. Thank you for your valuable contributions!
15
+
3
16
  ## Version v1.22.0
4
17
 
5
18
  Released on September 28th, 2024.
@@ -88,8 +88,6 @@ function debounce(func, debounceMs, { signal, edges } = {}) {
88
88
  return debounced;
89
89
  }
90
90
 
91
- function noop() { }
92
-
93
91
  function once(func) {
94
92
  let called = false;
95
93
  let cache;
@@ -190,6 +188,26 @@ function rest(func, startIndex = func.length - 1) {
190
188
  };
191
189
  }
192
190
 
191
+ function curryRight(func) {
192
+ if (func.length === 0 || func.length === 1) {
193
+ return func;
194
+ }
195
+ return function (arg) {
196
+ return makeCurryRight(func, func.length, [arg]);
197
+ };
198
+ }
199
+ function makeCurryRight(origin, argsLength, args) {
200
+ if (args.length === argsLength) {
201
+ return origin(...args);
202
+ }
203
+ else {
204
+ const next = function (arg) {
205
+ return makeCurryRight(origin, argsLength, [arg, ...args]);
206
+ };
207
+ return next;
208
+ }
209
+ }
210
+
193
211
  function flow(...funcs) {
194
212
  return function (...args) {
195
213
  let result = funcs.length ? funcs[0].apply(this, args) : args[0];
@@ -207,12 +225,12 @@ function flowRight(...funcs) {
207
225
  exports.after = after;
208
226
  exports.ary = ary;
209
227
  exports.before = before;
228
+ exports.curryRight = curryRight;
210
229
  exports.debounce = debounce;
211
230
  exports.flow = flow;
212
231
  exports.flowRight = flowRight;
213
232
  exports.memoize = memoize;
214
233
  exports.negate = negate;
215
- exports.noop = noop;
216
234
  exports.once = once;
217
235
  exports.partial = partial;
218
236
  exports.partialRight = partialRight;
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const isPlainObject = require('./isPlainObject-BIekvL.js');
3
+ const isPlainObject = require('./isPlainObject-DgrsU7.js');
4
4
 
5
5
  function omitBy(obj, shouldOmit) {
6
6
  const result = {};
@@ -141,10 +141,10 @@ function cloneDeepImpl(obj, stack = new Map()) {
141
141
  for (let i = 0; i < obj.length; i++) {
142
142
  result[i] = cloneDeepImpl(obj[i], stack);
143
143
  }
144
- if (Object.prototype.hasOwnProperty.call(obj, 'index')) {
144
+ if (Object.hasOwn(obj, 'index')) {
145
145
  result.index = obj.index;
146
146
  }
147
- if (Object.prototype.hasOwnProperty.call(obj, 'input')) {
147
+ if (Object.hasOwn(obj, 'input')) {
148
148
  result.input = obj.input;
149
149
  }
150
150
  return result;
@@ -234,10 +234,6 @@ function copyProperties(target, source, stack) {
234
234
  }
235
235
  }
236
236
 
237
- function isObjectLike(value) {
238
- return typeof value === 'object' && value !== null;
239
- }
240
-
241
237
  function merge(target, source) {
242
238
  const sourceKeys = Object.keys(source);
243
239
  for (let i = 0; i < sourceKeys.length; i++) {
@@ -245,10 +241,20 @@ function merge(target, source) {
245
241
  const sourceValue = source[key];
246
242
  const targetValue = target[key];
247
243
  if (Array.isArray(sourceValue)) {
248
- target[key] = merge(targetValue ?? [], sourceValue);
244
+ if (Array.isArray(targetValue)) {
245
+ target[key] = merge(targetValue, sourceValue);
246
+ }
247
+ else {
248
+ target[key] = merge([], sourceValue);
249
+ }
249
250
  }
250
- else if (isObjectLike(targetValue) && isObjectLike(sourceValue)) {
251
- target[key] = merge(targetValue ?? {}, sourceValue);
251
+ else if (isPlainObject.isPlainObject(sourceValue)) {
252
+ if (isPlainObject.isPlainObject(targetValue)) {
253
+ target[key] = merge(targetValue, sourceValue);
254
+ }
255
+ else {
256
+ target[key] = merge({}, sourceValue);
257
+ }
252
258
  }
253
259
  else if (targetValue === undefined || sourceValue !== undefined) {
254
260
  target[key] = sourceValue;
@@ -261,6 +267,10 @@ function toMerged(target, source) {
261
267
  return merge(cloneDeep(target), source);
262
268
  }
263
269
 
270
+ function isObjectLike(value) {
271
+ return typeof value === 'object' && value !== null;
272
+ }
273
+
264
274
  exports.clone = clone;
265
275
  exports.cloneDeep = cloneDeep;
266
276
  exports.copyProperties = copyProperties;
@@ -1,31 +1,31 @@
1
1
  'use strict';
2
2
 
3
- function isTypedArray(x) {
4
- return ArrayBuffer.isView(x) && !(x instanceof DataView);
5
- }
6
-
7
3
  function isPrimitive(value) {
8
4
  return value == null || (typeof value !== 'object' && typeof value !== 'function');
9
5
  }
10
6
 
11
- function isPlainObject(object) {
12
- if (typeof object !== 'object') {
7
+ function isTypedArray(x) {
8
+ return ArrayBuffer.isView(x) && !(x instanceof DataView);
9
+ }
10
+
11
+ function isPlainObject(value) {
12
+ if (typeof value !== 'object') {
13
13
  return false;
14
14
  }
15
- if (object == null) {
15
+ if (value == null) {
16
16
  return false;
17
17
  }
18
- if (Object.getPrototypeOf(object) === null) {
18
+ if (Object.getPrototypeOf(value) === null) {
19
19
  return true;
20
20
  }
21
- if (object.toString() !== '[object Object]') {
21
+ if (value.toString() !== '[object Object]') {
22
22
  return false;
23
23
  }
24
- let proto = object;
24
+ let proto = value;
25
25
  while (Object.getPrototypeOf(proto) !== null) {
26
26
  proto = Object.getPrototypeOf(proto);
27
27
  }
28
- return Object.getPrototypeOf(object) === proto;
28
+ return Object.getPrototypeOf(value) === proto;
29
29
  }
30
30
 
31
31
  exports.isPlainObject = isPlainObject;
@@ -1,11 +1,27 @@
1
1
  'use strict';
2
2
 
3
- const isPlainObject = require('./isPlainObject-BIekvL.js');
3
+ const isPlainObject = require('./isPlainObject-DgrsU7.js');
4
+ const noop = require('./noop-2IwLUk.js');
5
+
6
+ function isArrayBuffer(value) {
7
+ return value instanceof ArrayBuffer;
8
+ }
4
9
 
5
10
  function isDate(value) {
6
11
  return value instanceof Date;
7
12
  }
8
13
 
14
+ function getSymbols(object) {
15
+ return Object.getOwnPropertySymbols(object).filter(symbol => Object.prototype.propertyIsEnumerable.call(object, symbol));
16
+ }
17
+
18
+ function getTag(value) {
19
+ if (value == null) {
20
+ return value === undefined ? '[object Undefined]' : '[object Null]';
21
+ }
22
+ return Object.prototype.toString.call(value);
23
+ }
24
+
9
25
  const regexpTag = '[object RegExp]';
10
26
  const stringTag = '[object String]';
11
27
  const numberTag = '[object Number]';
@@ -33,18 +49,14 @@ const bigInt64ArrayTag = '[object BigInt64Array]';
33
49
  const float32ArrayTag = '[object Float32Array]';
34
50
  const float64ArrayTag = '[object Float64Array]';
35
51
 
36
- function getSymbols(object) {
37
- return Object.getOwnPropertySymbols(object).filter(symbol => Object.prototype.propertyIsEnumerable.call(object, symbol));
52
+ function isEqualWith(a, b, areValuesEqual) {
53
+ return isEqualWithImpl(a, b, undefined, undefined, undefined, undefined, areValuesEqual);
38
54
  }
39
-
40
- function getTag(value) {
41
- if (value == null) {
42
- return value === undefined ? '[object Undefined]' : '[object Null]';
55
+ function isEqualWithImpl(a, b, property, aParent, bParent, stack, areValuesEqual) {
56
+ const result = areValuesEqual(a, b, property, aParent, bParent, stack);
57
+ if (result !== undefined) {
58
+ return result;
43
59
  }
44
- return Object.prototype.toString.call(value);
45
- }
46
-
47
- function isEqual(a, b) {
48
60
  if (typeof a === typeof b) {
49
61
  switch (typeof a) {
50
62
  case 'bigint':
@@ -61,13 +73,13 @@ function isEqual(a, b) {
61
73
  return a === b;
62
74
  }
63
75
  case 'object': {
64
- return areObjectsEqual(a, b);
76
+ return areObjectsEqual(a, b, stack, areValuesEqual);
65
77
  }
66
78
  }
67
79
  }
68
- return areObjectsEqual(a, b);
80
+ return areObjectsEqual(a, b, stack, areValuesEqual);
69
81
  }
70
- function areObjectsEqual(a, b, stack) {
82
+ function areObjectsEqual(a, b, stack, areValuesEqual) {
71
83
  if (Object.is(a, b)) {
72
84
  return true;
73
85
  }
@@ -116,7 +128,7 @@ function areObjectsEqual(a, b, stack) {
116
128
  return false;
117
129
  }
118
130
  for (const [key, value] of a.entries()) {
119
- if (!b.has(key) || !areObjectsEqual(value, b.get(key), stack)) {
131
+ if (!b.has(key) || !isEqualWithImpl(value, b.get(key), key, a, b, stack, areValuesEqual)) {
120
132
  return false;
121
133
  }
122
134
  }
@@ -131,7 +143,7 @@ function areObjectsEqual(a, b, stack) {
131
143
  for (let i = 0; i < aValues.length; i++) {
132
144
  const aValue = aValues[i];
133
145
  const index = bValues.findIndex(bValue => {
134
- return areObjectsEqual(aValue, bValue, stack);
146
+ return isEqualWithImpl(aValue, bValue, undefined, a, b, stack, areValuesEqual);
135
147
  });
136
148
  if (index === -1) {
137
149
  return false;
@@ -159,7 +171,7 @@ function areObjectsEqual(a, b, stack) {
159
171
  return false;
160
172
  }
161
173
  for (let i = 0; i < a.length; i++) {
162
- if (!areObjectsEqual(a[i], b[i], stack)) {
174
+ if (!isEqualWithImpl(a[i], b[i], i, a, b, stack, areValuesEqual)) {
163
175
  return false;
164
176
  }
165
177
  }
@@ -169,19 +181,20 @@ function areObjectsEqual(a, b, stack) {
169
181
  if (a.byteLength !== b.byteLength) {
170
182
  return false;
171
183
  }
172
- return areObjectsEqual(new Uint8Array(a), new Uint8Array(b), stack);
184
+ return areObjectsEqual(new Uint8Array(a), new Uint8Array(b), stack, areValuesEqual);
173
185
  }
174
186
  case dataViewTag: {
175
187
  if (a.byteLength !== b.byteLength || a.byteOffset !== b.byteOffset) {
176
188
  return false;
177
189
  }
178
- return areObjectsEqual(a.buffer, b.buffer, stack);
190
+ return areObjectsEqual(new Uint8Array(a), new Uint8Array(b), stack, areValuesEqual);
179
191
  }
180
192
  case errorTag: {
181
193
  return a.name === b.name && a.message === b.message;
182
194
  }
183
195
  case objectTag: {
184
- const areEqualInstances = areObjectsEqual(a.constructor, b.constructor, stack) || (isPlainObject.isPlainObject(a) && isPlainObject.isPlainObject(b));
196
+ const areEqualInstances = areObjectsEqual(a.constructor, b.constructor, stack, areValuesEqual) ||
197
+ (isPlainObject.isPlainObject(a) && isPlainObject.isPlainObject(b));
185
198
  if (!areEqualInstances) {
186
199
  return false;
187
200
  }
@@ -193,11 +206,11 @@ function areObjectsEqual(a, b, stack) {
193
206
  for (let i = 0; i < aKeys.length; i++) {
194
207
  const propKey = aKeys[i];
195
208
  const aProp = a[propKey];
196
- if (!Object.prototype.hasOwnProperty.call(b, propKey)) {
209
+ if (!Object.hasOwn(b, propKey)) {
197
210
  return false;
198
211
  }
199
212
  const bProp = b[propKey];
200
- if (!areObjectsEqual(aProp, bProp, stack)) {
213
+ if (!isEqualWithImpl(aProp, bProp, propKey, a, b, stack, areValuesEqual)) {
201
214
  return false;
202
215
  }
203
216
  }
@@ -214,6 +227,10 @@ function areObjectsEqual(a, b, stack) {
214
227
  }
215
228
  }
216
229
 
230
+ function isEqual(a, b) {
231
+ return isEqualWith(a, b, noop.noop);
232
+ }
233
+
217
234
  function isMap(value) {
218
235
  return value instanceof Map;
219
236
  }
@@ -246,6 +263,47 @@ function isRegExp(value) {
246
263
  return value instanceof RegExp;
247
264
  }
248
265
 
266
+ function isJSONArray(value) {
267
+ if (!Array.isArray(value)) {
268
+ return false;
269
+ }
270
+ return value.every(item => isJSONValue(item));
271
+ }
272
+
273
+ function isJSONValue(value) {
274
+ switch (typeof value) {
275
+ case 'object': {
276
+ return value === null || isJSONArray(value) || isJSONObject(value);
277
+ }
278
+ case 'string':
279
+ case 'number':
280
+ case 'boolean': {
281
+ return true;
282
+ }
283
+ default: {
284
+ return false;
285
+ }
286
+ }
287
+ }
288
+
289
+ function isJSONObject(obj) {
290
+ if (!isPlainObject.isPlainObject(obj)) {
291
+ return false;
292
+ }
293
+ const keys = Reflect.ownKeys(obj);
294
+ for (let i = 0; i < keys.length; i++) {
295
+ const key = keys[i];
296
+ const value = obj[key];
297
+ if (typeof key !== 'string') {
298
+ return false;
299
+ }
300
+ if (!isJSONValue(value)) {
301
+ return false;
302
+ }
303
+ }
304
+ return true;
305
+ }
306
+
249
307
  function isSet(value) {
250
308
  return value instanceof Set;
251
309
  }
@@ -262,9 +320,14 @@ exports.argumentsTag = argumentsTag;
262
320
  exports.booleanTag = booleanTag;
263
321
  exports.getSymbols = getSymbols;
264
322
  exports.getTag = getTag;
323
+ exports.isArrayBuffer = isArrayBuffer;
265
324
  exports.isDate = isDate;
266
325
  exports.isEqual = isEqual;
326
+ exports.isEqualWith = isEqualWith;
267
327
  exports.isFunction = isFunction;
328
+ exports.isJSONArray = isJSONArray;
329
+ exports.isJSONObject = isJSONObject;
330
+ exports.isJSONValue = isJSONValue;
268
331
  exports.isLength = isLength;
269
332
  exports.isMap = isMap;
270
333
  exports.isNil = isNil;
@@ -0,0 +1,5 @@
1
+ 'use strict';
2
+
3
+ function noop() { }
4
+
5
+ exports.noop = noop;
@@ -1,14 +1,14 @@
1
1
  'use strict';
2
2
 
3
- function capitalize(str) {
4
- return (str.charAt(0).toUpperCase() + str.slice(1).toLowerCase());
5
- }
6
-
7
- const CASE_SPLIT_PATTERN = /[A-Z]?[a-z]+|[0-9]+|[A-Z]+(?![a-z])|\p{Emoji_Presentation}|\p{Extended_Pictographic}|\p{L}+/gu;
3
+ const CASE_SPLIT_PATTERN = /\p{Lu}?\p{Ll}+|[0-9]+|\p{Lu}+(?!\p{Ll})|\p{Emoji_Presentation}|\p{Extended_Pictographic}|\p{L}+/gu;
8
4
  function getWords(str) {
9
5
  return Array.from(str.match(CASE_SPLIT_PATTERN) ?? []);
10
6
  }
11
7
 
8
+ function capitalize(str) {
9
+ return (str.charAt(0).toUpperCase() + str.slice(1).toLowerCase());
10
+ }
11
+
12
12
  function camelCase(str) {
13
13
  const words = getWords(str);
14
14
  if (words.length === 0) {
@@ -55,46 +55,46 @@ function constantCase(str) {
55
55
  return words.map(word => word.toUpperCase()).join('_');
56
56
  }
57
57
 
58
- function trimStart(str, chars) {
58
+ function trimEnd(str, chars) {
59
59
  if (chars === undefined) {
60
- return str.trimStart();
60
+ return str.trimEnd();
61
61
  }
62
- let startIndex = 0;
62
+ let endIndex = str.length;
63
63
  switch (typeof chars) {
64
64
  case 'string': {
65
- while (startIndex < str.length && str[startIndex] === chars) {
66
- startIndex++;
65
+ while (endIndex > 0 && str[endIndex - 1] === chars) {
66
+ endIndex--;
67
67
  }
68
68
  break;
69
69
  }
70
70
  case 'object': {
71
- while (startIndex < str.length && chars.includes(str[startIndex])) {
72
- startIndex++;
71
+ while (endIndex > 0 && chars.includes(str[endIndex - 1])) {
72
+ endIndex--;
73
73
  }
74
74
  }
75
75
  }
76
- return str.substring(startIndex);
76
+ return str.substring(0, endIndex);
77
77
  }
78
78
 
79
- function trimEnd(str, chars) {
79
+ function trimStart(str, chars) {
80
80
  if (chars === undefined) {
81
- return str.trimEnd();
81
+ return str.trimStart();
82
82
  }
83
- let endIndex = str.length;
83
+ let startIndex = 0;
84
84
  switch (typeof chars) {
85
85
  case 'string': {
86
- while (endIndex > 0 && str[endIndex - 1] === chars) {
87
- endIndex--;
86
+ while (startIndex < str.length && str[startIndex] === chars) {
87
+ startIndex++;
88
88
  }
89
89
  break;
90
90
  }
91
91
  case 'object': {
92
- while (endIndex > 0 && chars.includes(str[endIndex - 1])) {
93
- endIndex--;
92
+ while (startIndex < str.length && chars.includes(str[startIndex])) {
93
+ startIndex++;
94
94
  }
95
95
  }
96
96
  }
97
- return str.substring(0, endIndex);
97
+ return str.substring(startIndex);
98
98
  }
99
99
 
100
100
  function trim(str, chars) {