@ntnyq/utils 0.9.2 → 0.11.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.
Files changed (3) hide show
  1. package/dist/index.d.ts +97 -14
  2. package/dist/index.js +183 -93
  3. package/package.json +22 -24
package/dist/index.d.ts CHANGED
@@ -9,13 +9,26 @@ declare function noop(): void;
9
9
  declare const NOOP: typeof noop;
10
10
  //#endregion
11
11
  //#region src/fn/once.d.ts
12
+ /**
13
+ * Creates a function that is restricted to invoking `func` once. Repeat calls to the function return `false`.
14
+ *
15
+ * @param func - The function to restrict.
16
+ * @returns A new function that returns `true` when `func` is invoked for the first time and `false` on subsequent calls.
17
+ *
18
+ * @example
19
+ *
20
+ * ```ts
21
+ * const initialize = once(() => {
22
+ * console.log('Initialized')
23
+ * })
24
+ *
25
+ * initialize() // Logs: 'Initialized', returns true
26
+ * ```
27
+ */
12
28
  declare function once<T extends unknown[]>(func: (...args: T) => void): (this: unknown, ...args: T) => boolean;
13
29
  //#endregion
14
30
  //#region src/is/dom.d.ts
15
31
  /**
16
- * @file is/dom.ts
17
- */
18
- /**
19
32
  * Check if given value is an HTMLElement
20
33
  * @param value - The value to check
21
34
  * @returns True if the value is an HTMLElement, false otherwise
@@ -104,7 +117,7 @@ type Nullable<T> = T | null;
104
117
  /**
105
118
  * Overwrite some keys type
106
119
  */
107
- type Overwrite<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U;
120
+ type Overwrite<T, U$1> = Pick<T, Exclude<keyof T, keyof U$1>> & U$1;
108
121
  /**
109
122
  * Prettify object type
110
123
  */
@@ -136,7 +149,7 @@ type LiteralUnion<Union extends Base, Base = string> = Union | (Base & {
136
149
  /**
137
150
  * @see {@link TODO:}
138
151
  */
139
- type Merge<T, U> = keyof T & keyof U extends never ? T & U : Omit<T, keyof T & keyof U> & U;
152
+ type Merge<T, U$1> = keyof T & keyof U$1 extends never ? T & U$1 : Omit<T, keyof T & keyof U$1> & U$1;
140
153
  /**
141
154
  * Non empty object `{}`
142
155
  */
@@ -190,16 +203,13 @@ declare function isElementVisibleInViewport(element: HTMLElement, targetWindow?:
190
203
  //#endregion
191
204
  //#region src/env/isBrowser.d.ts
192
205
  /**
193
- * @file env.ts
194
- */
195
- /**
196
206
  * Checks if the code is running in a browser
197
207
  *
198
- * @returns boolean - true if the code is running in a browser
208
+ * @returns true if the code is running in a browser
199
209
  */
200
210
  declare function isBrowser(): boolean;
201
211
  //#endregion
202
- //#region src/file/removeExtension.d.ts
212
+ //#region src/file/extension.d.ts
203
213
  /**
204
214
  * Removes the file extension from a filename.
205
215
  *
@@ -207,6 +217,12 @@ declare function isBrowser(): boolean;
207
217
  * @returns The filename without the extension.
208
218
  */
209
219
  declare function removeFileExtension(filename: string): string;
220
+ /**
221
+ * Gets the file extension from a filename.
222
+ * @param filePath - The filePath to get the extension from.
223
+ * @returns The file extension, or undefined if there is none.
224
+ */
225
+ declare function getFileExtension(filePath?: string): string | undefined;
210
226
  //#endregion
211
227
  //#region src/html/escape.d.ts
212
228
  /**
@@ -434,6 +450,15 @@ declare function last<T>(array: readonly T[]): T | undefined;
434
450
  */
435
451
  declare function chunk<T>(array: T[], size: number): T[][];
436
452
  //#endregion
453
+ //#region src/array/remove.d.ts
454
+ /**
455
+ * Remove given item from an array
456
+ * @param array - given array
457
+ * @param value - item to be removed
458
+ * @returns true if item was removed, otherwise false
459
+ */
460
+ declare function remove<T>(array: T[], value: T): boolean;
461
+ //#endregion
437
462
  //#region src/array/unique.d.ts
438
463
  /**
439
464
  * Returns a new array with unique values.
@@ -449,6 +474,15 @@ declare function unique<T>(array: T[]): T[];
449
474
  */
450
475
  declare function uniqueBy<T>(array: T[], equalFn: (a: T, b: T) => boolean): T[];
451
476
  //#endregion
477
+ //#region src/array/shuffle.d.ts
478
+ /**
479
+ * Fisher–Yates shuffle
480
+ *
481
+ * @param array - array to shuffle
482
+ * @returns shuffled array
483
+ */
484
+ declare function shuffle<T>(array: T[]): T[];
485
+ //#endregion
452
486
  //#region src/array/toArray.d.ts
453
487
  /**
454
488
  * Converts a value to an array.
@@ -593,7 +627,7 @@ declare function interopDefault<T>(mod: Awaitable<T>): Promise<InteropModuleDefa
593
627
  * // => {}
594
628
  * ```
595
629
  */
596
- declare function resolveSubOptions<T extends Record<string, any>, K extends keyof T>(options: T, key: K): Partial<ResolvedOptions<T[K]>>;
630
+ declare function resolveSubOptions<T extends Record<string, any>, K$1 extends keyof T>(options: T, key: K$1): Partial<ResolvedOptions<T[K$1]>>;
597
631
  //#endregion
598
632
  //#region src/number/random.d.ts
599
633
  interface RamdomNumberOptions {
@@ -655,10 +689,10 @@ interface ToIntegerOptions {
655
689
  declare function toInteger(value: unknown, options?: ToIntegerOptions): number;
656
690
  //#endregion
657
691
  //#region src/object/omit.d.ts
658
- declare function omit<T, K extends keyof T>(object: T, ...keys: K[]): Omit<T, K>;
692
+ declare function omit<T, K$1 extends keyof T>(object: T, ...keys: K$1[]): Omit<T, K$1>;
659
693
  //#endregion
660
694
  //#region src/object/pick.d.ts
661
- declare function pick<T, K extends keyof T>(object: T, keys: K[]): Pick<T, K>;
695
+ declare function pick<T, K$1 extends keyof T>(object: T, keys: K$1[]): Pick<T, K$1>;
662
696
  //#endregion
663
697
  //#region src/object/clean.d.ts
664
698
  interface CleanObjectOptions {
@@ -728,6 +762,17 @@ declare function cleanObject<T extends object>(obj: T, options?: CleanObjectOpti
728
762
  */
729
763
  declare function hasOwn<T>(object: T, key: PropertyKey): boolean;
730
764
  //#endregion
765
+ //#region src/object/isKeyOf.d.ts
766
+ /**
767
+ * Type guard for any key, `k`
768
+ * marks `k` as a key of `T` if `k` is a key of `T`
769
+ *
770
+ * @param obj - object to query for key
771
+ * @param k - key to check for
772
+ * @returns true if `k` is a key of `T`
773
+ */
774
+ declare function isKeyOf<T extends object>(obj: T, k: keyof T): k is keyof T;
775
+ //#endregion
731
776
  //#region src/object/sortObject.d.ts
732
777
  interface SortObjectOptions {
733
778
  /**
@@ -745,6 +790,15 @@ interface SortObjectOptions {
745
790
  */
746
791
  declare function sortObject<T extends Record<string, any>>(obj: T, options?: SortObjectOptions): T;
747
792
  //#endregion
793
+ //#region src/object/isPlainObject.d.ts
794
+ /**
795
+ * Check if a value is a plain object (not an array, Date, RegExp, Map, Set, etc.)
796
+ *
797
+ * @param value - Checked value
798
+ * @copyright {@link https://github.com/sindresorhus/is/blob/main/source/index.ts}
799
+ */
800
+ declare function isPlainObject<Value = unknown>(value: unknown): value is Record<PropertyKey, Value>;
801
+ //#endregion
748
802
  //#region src/string/pad.d.ts
749
803
  interface CreatePadStringOptions {
750
804
  length: number;
@@ -774,6 +828,12 @@ declare function join(array: JoinableValue[], options?: JoinOptions): string;
774
828
  */
775
829
  declare function slash(input: string): string;
776
830
  //#endregion
831
+ //#region src/string/escape.d.ts
832
+ /**
833
+ * @copyright {@link https://github.com/sindresorhus/escape-string-regexp}
834
+ */
835
+ declare function escapeStringRegexp(value: string): string;
836
+ //#endregion
777
837
  //#region src/string/random.d.ts
778
838
  /**
779
839
  * randome a string useing given chars
@@ -845,7 +905,30 @@ declare function getStringSimilarity(str1: string, str2: string, options?: GetSt
845
905
  * Special chars
846
906
  */
847
907
  declare const SPECIAL_CHAR: {
908
+ /**
909
+ * 中文顿号
910
+ */
911
+ chineseComma: string;
912
+ /**
913
+ * 英文逗号
914
+ */
915
+ englishComma: string;
916
+ /**
917
+ * 英文句号
918
+ */
919
+ englishPeriod: string;
920
+ /**
921
+ * 连接符
922
+ */
923
+ hyphen: string;
924
+ /**
925
+ * 换行
926
+ */
848
927
  newline: string;
928
+ /**
929
+ * 空格
930
+ */
931
+ whitespace: string;
849
932
  };
850
933
  //#endregion
851
934
  //#region src/constants/regexp.d.ts
@@ -864,4 +947,4 @@ declare const RE_LINE_COMMENT: RegExp;
864
947
  */
865
948
  declare const RE_BLOCK_COMMENT: RegExp;
866
949
  //#endregion
867
- export { AnyFn, Arrayable, Awaitable, Callable, CleanObjectOptions, Color, CreatePadStringOptions, DeepRequired, ElementOf, GetStringSimilarityOptions, InteropModuleDefault, JsonArray, JsonObject, JsonPrimitive, JsonValue, LiteralUnion, MayBe, Merge, NOOP, NonEmptyObject, NonEmptyString, Nullable, OpenExternalURLOptions, Overwrite, Prettify, PrettifyV2, Primitive, RE_BLOCK_COMMENT, RE_COMMENTS, RE_LINE_COMMENT, RamdomNumberOptions, ResolvedOptions, SPECIAL_CHAR, STORAGE_UNITS, SortObjectOptions, StorageUnit, TIME_UNITS, ThrottleDebounceOptions, TimeUnit, ToIntegerOptions, UrlString, ValueOf, Whitespace, at, cAF, chunk, clamp, cleanObject, convertFromBytes, convertFromMilliseconds, convertStorageUnit, convertTimeUnit, convertToBytes, convertToMilliseconds, createPadString, debounce, enhance, ensurePrefix, ensureSuffix, escapeHTML, flattenArrayable, getObjectType, getRoot, getStringLength, getStringSimilarity, hasOwn, interopDefault, intersect, isArray, isArrayEqual, isBigInt, isBlob, isBoolean, isBrowser, isDeepEqual, isElementVisibleInViewport, isEmptyArray, isEmptyMap, isEmptyObject, isEmptySet, isEmptyString, isEmptyStringOrWhitespace, isError, isFile, isFormData, isFunction, isHTMLElement, isInteger, isIterable, isMap, isNaN, isNativePromise, isNil, isNonEmptyArray, isNonEmptyString, isNull, isNullOrUndefined, isNumber, isNumbericString, isObject, isPromise, isRegExp, isSet, isString, isTruthy, isUndefined, isUrlString, isWhitespaceString, isZero, join, last, mergeArrayable, noop, omit, once, openExternalURL, pick, rAF, randomHexColor, randomNumber, randomRGBAColor, randomRGBColor, randomString, removeFileExtension, resolveSubOptions, scrollElementIntoView, slash, slugify, sortObject, throttle, toArray, toInteger, unescapeHTML, unindent, unique, uniqueBy, waitFor, warnOnce };
950
+ export { AnyFn, Arrayable, Awaitable, Callable, CleanObjectOptions, Color, CreatePadStringOptions, DeepRequired, ElementOf, GetStringSimilarityOptions, InteropModuleDefault, JsonArray, JsonObject, JsonPrimitive, JsonValue, LiteralUnion, MayBe, Merge, NOOP, NonEmptyObject, NonEmptyString, Nullable, OpenExternalURLOptions, Overwrite, Prettify, PrettifyV2, Primitive, RE_BLOCK_COMMENT, RE_COMMENTS, RE_LINE_COMMENT, RamdomNumberOptions, ResolvedOptions, SPECIAL_CHAR, STORAGE_UNITS, SortObjectOptions, StorageUnit, TIME_UNITS, ThrottleDebounceOptions, TimeUnit, ToIntegerOptions, UrlString, ValueOf, Whitespace, at, cAF, chunk, clamp, cleanObject, convertFromBytes, convertFromMilliseconds, convertStorageUnit, convertTimeUnit, convertToBytes, convertToMilliseconds, createPadString, debounce, enhance, ensurePrefix, ensureSuffix, escapeHTML, escapeStringRegexp, flattenArrayable, getFileExtension, getObjectType, getRoot, getStringLength, getStringSimilarity, hasOwn, interopDefault, intersect, isArray, isArrayEqual, isBigInt, isBlob, isBoolean, isBrowser, isDeepEqual, isElementVisibleInViewport, isEmptyArray, isEmptyMap, isEmptyObject, isEmptySet, isEmptyString, isEmptyStringOrWhitespace, isError, isFile, isFormData, isFunction, isHTMLElement, isInteger, isIterable, isKeyOf, isMap, isNaN, isNativePromise, isNil, isNonEmptyArray, isNonEmptyString, isNull, isNullOrUndefined, isNumber, isNumbericString, isObject, isPlainObject, isPromise, isRegExp, isSet, isString, isTruthy, isUndefined, isUrlString, isWhitespaceString, isZero, join, last, mergeArrayable, noop, omit, once, openExternalURL, pick, rAF, randomHexColor, randomNumber, randomRGBAColor, randomRGBColor, randomString, remove, removeFileExtension, resolveSubOptions, scrollElementIntoView, shuffle, slash, slugify, sortObject, throttle, toArray, toInteger, unescapeHTML, unindent, unique, uniqueBy, waitFor, warnOnce };
package/dist/index.js CHANGED
@@ -10,6 +10,22 @@ const NOOP = noop;
10
10
 
11
11
  //#endregion
12
12
  //#region src/fn/once.ts
13
+ /**
14
+ * Creates a function that is restricted to invoking `func` once. Repeat calls to the function return `false`.
15
+ *
16
+ * @param func - The function to restrict.
17
+ * @returns A new function that returns `true` when `func` is invoked for the first time and `false` on subsequent calls.
18
+ *
19
+ * @example
20
+ *
21
+ * ```ts
22
+ * const initialize = once(() => {
23
+ * console.log('Initialized')
24
+ * })
25
+ *
26
+ * initialize() // Logs: 'Initialized', returns true
27
+ * ```
28
+ */
13
29
  function once(func) {
14
30
  let called = false;
15
31
  return function(...args) {
@@ -20,6 +36,17 @@ function once(func) {
20
36
  };
21
37
  }
22
38
 
39
+ //#endregion
40
+ //#region src/env/isBrowser.ts
41
+ /**
42
+ * Checks if the code is running in a browser
43
+ *
44
+ * @returns true if the code is running in a browser
45
+ */
46
+ function isBrowser() {
47
+ return typeof document !== "undefined" && typeof window !== "undefined" && typeof navigator !== "undefined" && window === self;
48
+ }
49
+
23
50
  //#endregion
24
51
  //#region src/is/dom.ts
25
52
  /**
@@ -31,6 +58,7 @@ function once(func) {
31
58
  * @returns True if the value is an HTMLElement, false otherwise
32
59
  */
33
60
  function isHTMLElement(value) {
61
+ if (!isBrowser()) return false;
34
62
  return typeof value === "object" && value !== null && "nodeType" in value && value.nodeType === Node.ELEMENT_NODE && value instanceof HTMLElement;
35
63
  }
36
64
 
@@ -164,9 +192,7 @@ function isUrlString(value) {
164
192
  * check if two values are deeply equal
165
193
  */
166
194
  function isDeepEqual(value1, value2) {
167
- const type1 = getObjectType(value1);
168
- const type2 = getObjectType(value2);
169
- if (type1 !== type2) return false;
195
+ if (getObjectType(value1) !== getObjectType(value2)) return false;
170
196
  if (isArray(value1) && isArray(value2)) {
171
197
  if (value1.length !== value2.length) return false;
172
198
  return value1.every((item, index) => isDeepEqual(item, value2[index]));
@@ -189,7 +215,7 @@ function isDeepEqual(value1, value2) {
189
215
  */
190
216
  function scrollElementIntoView(element, options = {}) {
191
217
  const body = document.body;
192
- const { parent = body,...scrollIntoViewOptions } = options;
218
+ const { parent = body, ...scrollIntoViewOptions } = options;
193
219
  if (parent === body) {
194
220
  parent.scrollIntoView(scrollIntoViewOptions);
195
221
  return;
@@ -227,21 +253,7 @@ function isElementVisibleInViewport(element, targetWindow = window) {
227
253
  }
228
254
 
229
255
  //#endregion
230
- //#region src/env/isBrowser.ts
231
- /**
232
- * @file env.ts
233
- */
234
- /**
235
- * Checks if the code is running in a browser
236
- *
237
- * @returns boolean - true if the code is running in a browser
238
- */
239
- function isBrowser() {
240
- return typeof document !== "undefined";
241
- }
242
-
243
- //#endregion
244
- //#region src/file/removeExtension.ts
256
+ //#region src/file/extension.ts
245
257
  /**
246
258
  * Removes the file extension from a filename.
247
259
  *
@@ -251,6 +263,15 @@ function isBrowser() {
251
263
  function removeFileExtension(filename) {
252
264
  return filename.replace(/\.[^/.]+$/, "");
253
265
  }
266
+ /**
267
+ * Gets the file extension from a filename.
268
+ * @param filePath - The filePath to get the extension from.
269
+ * @returns The file extension, or undefined if there is none.
270
+ */
271
+ function getFileExtension(filePath) {
272
+ if (!filePath) return;
273
+ return filePath.match(/\.([^.]+)$/)?.[1];
274
+ }
254
275
 
255
276
  //#endregion
256
277
  //#region src/html/escape.ts
@@ -291,6 +312,9 @@ function unescapeHTML(str) {
291
312
  //#endregion
292
313
  //#region src/misc/raf.ts
293
314
  /**
315
+ * @file raf.ts
316
+ */
317
+ /**
294
318
  * Gets the global root object.
295
319
  * @returns the global root object
296
320
  */
@@ -480,8 +504,7 @@ function convertFromMilliseconds(milliseconds, toUnit = "SECOND") {
480
504
  * ```
481
505
  */
482
506
  function convertTimeUnit(value, fromUnit, toUnit) {
483
- const milliseconds = convertToMilliseconds(value, fromUnit);
484
- return convertFromMilliseconds(milliseconds, toUnit);
507
+ return convertFromMilliseconds(convertToMilliseconds(value, fromUnit), toUnit);
485
508
  }
486
509
 
487
510
  //#endregion
@@ -544,8 +567,7 @@ function convertFromBytes(bytes, toUnit = "MB") {
544
567
  * ```
545
568
  */
546
569
  function convertStorageUnit(value, fromUnit, toUnit) {
547
- const bytes = convertToBytes(value, fromUnit);
548
- return convertFromBytes(bytes, toUnit);
570
+ return convertFromBytes(convertToBytes(value, fromUnit), toUnit);
549
571
  }
550
572
 
551
573
  //#endregion
@@ -585,6 +607,24 @@ function chunk(array, size) {
585
607
  return result;
586
608
  }
587
609
 
610
+ //#endregion
611
+ //#region src/array/remove.ts
612
+ /**
613
+ * Remove given item from an array
614
+ * @param array - given array
615
+ * @param value - item to be removed
616
+ * @returns true if item was removed, otherwise false
617
+ */
618
+ function remove(array, value) {
619
+ if (!array) return false;
620
+ const index = array.indexOf(value);
621
+ if (index !== -1) {
622
+ array.splice(index, 1);
623
+ return true;
624
+ }
625
+ return false;
626
+ }
627
+
588
628
  //#endregion
589
629
  //#region src/array/unique.ts
590
630
  /**
@@ -608,6 +648,89 @@ function uniqueBy(array, equalFn) {
608
648
  }, []);
609
649
  }
610
650
 
651
+ //#endregion
652
+ //#region src/number/random.ts
653
+ /**
654
+ * random an integer by given range
655
+ *
656
+ * @param min - min value
657
+ * @param max - max value
658
+ * @returns random integer in range
659
+ */
660
+ function randomNumber(min, max = 0, options = {}) {
661
+ if (max === 0) {
662
+ max = min;
663
+ min = 0;
664
+ }
665
+ if (min > max) [min, max] = [max, min];
666
+ return Math.trunc(Math.random() * (max - min + (options.includeMax ? 1 : 0)) + min);
667
+ }
668
+
669
+ //#endregion
670
+ //#region src/number/toInteger.ts
671
+ /**
672
+ * Transforms a value to an integer.
673
+ * @param value - The value to convert to an integer.
674
+ * @param options - Options for the conversion.
675
+ * @returns The converted integer.
676
+ */
677
+ function toInteger(value, options = {}) {
678
+ const { defaultValue = 0, allowDecimal = false, allowNaN = false, onError = "useDefault", min, max, outOfRange = "clamp" } = options;
679
+ let numberValue;
680
+ let result;
681
+ if (isNumber(value)) numberValue = value;
682
+ else if (isString(value)) {
683
+ const trimmed = value.trim();
684
+ if (isEmptyString(trimmed)) {
685
+ if (onError === "throwError") throw new TypeError("Cannot convert empty string to an integer");
686
+ return onError === "returnOriginal" ? value : defaultValue;
687
+ }
688
+ numberValue = Number(trimmed);
689
+ } else if (isNullOrUndefined(value)) {
690
+ if (onError === "throwError") throw new TypeError(`Cannot convert ${value} to an integer`);
691
+ return onError === "useDefault" ? value : defaultValue;
692
+ } else numberValue = Number(value);
693
+ if (isNaN(numberValue)) {
694
+ if (allowNaN) return numberValue;
695
+ if (onError === "throwError") throw new TypeError(`Cannot convert NaN to an integer`);
696
+ return onError === "returnOriginal" ? value : defaultValue;
697
+ }
698
+ if (allowDecimal) result = numberValue > 0 ? Math.floor(numberValue) : Math.ceil(numberValue);
699
+ else {
700
+ if (numberValue % 1 !== 0) {
701
+ if (onError === "throwError") throw new Error("Decimal values are not allowed");
702
+ return onError === "returnOriginal" ? value : defaultValue;
703
+ }
704
+ result = numberValue;
705
+ }
706
+ if (!isUndefined(min) || !isUndefined(max)) {
707
+ const minVal = min ?? -Infinity;
708
+ const maxVal = max ?? Infinity;
709
+ if (result < minVal || result > maxVal) {
710
+ if (outOfRange === "throwError") throw new RangeError(`Value ${result} is out of range [${minVal}, ${maxVal}]`);
711
+ if (outOfRange === "useDefault") return defaultValue;
712
+ if (outOfRange === "clamp") result = Math.max(minVal, Math.min(maxVal, numberValue));
713
+ }
714
+ }
715
+ return result;
716
+ }
717
+
718
+ //#endregion
719
+ //#region src/array/shuffle.ts
720
+ /**
721
+ * Fisher–Yates shuffle
722
+ *
723
+ * @param array - array to shuffle
724
+ * @returns shuffled array
725
+ */
726
+ function shuffle(array) {
727
+ for (let i = array.length - 1; i > 0; i--) {
728
+ const j = randomNumber(0, i, { includeMax: true });
729
+ [array[i], array[j]] = [array[j], array[i]];
730
+ }
731
+ return array;
732
+ }
733
+
611
734
  //#endregion
612
735
  //#region src/array/toArray.ts
613
736
  /**
@@ -694,70 +817,12 @@ function slash(input) {
694
817
  }
695
818
 
696
819
  //#endregion
697
- //#region src/number/random.ts
820
+ //#region src/string/escape.ts
698
821
  /**
699
- * random an integer by given range
700
- *
701
- * @param min - min value
702
- * @param max - max value
703
- * @returns random integer in range
822
+ * @copyright {@link https://github.com/sindresorhus/escape-string-regexp}
704
823
  */
705
- function randomNumber(min, max = 0, options = {}) {
706
- if (max === 0) {
707
- max = min;
708
- min = 0;
709
- }
710
- if (min > max) [min, max] = [max, min];
711
- return Math.trunc(Math.random() * (max - min + (options.includeMax ? 1 : 0)) + min);
712
- }
713
-
714
- //#endregion
715
- //#region src/number/toInteger.ts
716
- /**
717
- * Transforms a value to an integer.
718
- * @param value - The value to convert to an integer.
719
- * @param options - Options for the conversion.
720
- * @returns The converted integer.
721
- */
722
- function toInteger(value, options = {}) {
723
- const { defaultValue = 0, allowDecimal = false, allowNaN = false, onError = "useDefault", min, max, outOfRange = "clamp" } = options;
724
- let numberValue;
725
- let result;
726
- if (isNumber(value)) numberValue = value;
727
- else if (isString(value)) {
728
- const trimmed = value.trim();
729
- if (isEmptyString(trimmed)) {
730
- if (onError === "throwError") throw new TypeError("Cannot convert empty string to an integer");
731
- return onError === "returnOriginal" ? value : defaultValue;
732
- }
733
- numberValue = Number(trimmed);
734
- } else if (isNullOrUndefined(value)) {
735
- if (onError === "throwError") throw new TypeError(`Cannot convert ${value} to an integer`);
736
- return onError === "useDefault" ? value : defaultValue;
737
- } else numberValue = Number(value);
738
- if (isNaN(numberValue)) {
739
- if (allowNaN) return numberValue;
740
- if (onError === "throwError") throw new TypeError(`Cannot convert NaN to an integer`);
741
- return onError === "returnOriginal" ? value : defaultValue;
742
- }
743
- if (allowDecimal) result = numberValue > 0 ? Math.floor(numberValue) : Math.ceil(numberValue);
744
- else {
745
- if (numberValue % 1 !== 0) {
746
- if (onError === "throwError") throw new Error("Decimal values are not allowed");
747
- return onError === "returnOriginal" ? value : defaultValue;
748
- }
749
- result = numberValue;
750
- }
751
- if (!isUndefined(min) || !isUndefined(max)) {
752
- const minVal = min ?? -Infinity;
753
- const maxVal = max ?? Infinity;
754
- if (result < minVal || result > maxVal) {
755
- if (outOfRange === "throwError") throw new RangeError(`Value ${result} is out of range [${minVal}, ${maxVal}]`);
756
- if (outOfRange === "useDefault") return defaultValue;
757
- if (outOfRange === "clamp") result = Math.max(minVal, Math.min(maxVal, numberValue));
758
- }
759
- }
760
- return result;
824
+ function escapeStringRegexp(value) {
825
+ return value.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d");
761
826
  }
762
827
 
763
828
  //#endregion
@@ -771,7 +836,10 @@ function toInteger(value, options = {}) {
771
836
  */
772
837
  function randomString(length = 16, chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") {
773
838
  const result = [];
774
- for (let i = length; i > 0; --i) result.push(chars[randomNumber(chars.length)]);
839
+ for (let i = length; i > 0; --i) {
840
+ const matchedChar = chars[randomNumber(chars.length)];
841
+ if (matchedChar) result.push(matchedChar);
842
+ }
775
843
  return result.join("");
776
844
  }
777
845
 
@@ -806,7 +874,7 @@ const _RE_FULL_WS = /^\s*$/;
806
874
  * ```
807
875
  */
808
876
  function unindent(input) {
809
- const lines = (typeof input === "string" ? input : input[0]).split("\n");
877
+ const lines = (isString(input) ? input : input[0])?.split("\n") ?? [];
810
878
  const whitespaceLines = lines.map((line) => _RE_FULL_WS.test(line));
811
879
  const commonIndent = lines.reduce((min, line, idx) => {
812
880
  if (whitespaceLines[idx]) return min;
@@ -1084,9 +1152,10 @@ function hasOwn(object, key) {
1084
1152
  //#endregion
1085
1153
  //#region src/object/pick.ts
1086
1154
  function pick(object, keys) {
1087
- return Object.assign({}, ...keys.map((key) => {
1088
- if (object && hasOwn(object, key)) return { [key]: object[key] };
1089
- }));
1155
+ return keys.reduce((result, key) => {
1156
+ if (object && hasOwn(object, key)) result[key] = object[key];
1157
+ return result;
1158
+ }, {});
1090
1159
  }
1091
1160
 
1092
1161
  //#endregion
@@ -1104,7 +1173,7 @@ function cleanObject(obj, options = {}) {
1104
1173
  if (cleanUndefined && isUndefined(v)) delete obj[key];
1105
1174
  if (cleanNull && isNull(v)) delete obj[key];
1106
1175
  if (cleanZero && isZero(v)) delete obj[key];
1107
- if (cleanNaN && isZero(v)) delete obj[key];
1176
+ if (cleanNaN && isNaN(v)) delete obj[key];
1108
1177
  if (cleanEmptyString && isEmptyString(v)) delete obj[key];
1109
1178
  if (cleanEmptyArray && isEmptyArray(v)) delete obj[key];
1110
1179
  if (cleanEmptyObject && isEmptyObject(v)) delete obj[key];
@@ -1113,6 +1182,20 @@ function cleanObject(obj, options = {}) {
1113
1182
  return obj;
1114
1183
  }
1115
1184
 
1185
+ //#endregion
1186
+ //#region src/object/isKeyOf.ts
1187
+ /**
1188
+ * Type guard for any key, `k`
1189
+ * marks `k` as a key of `T` if `k` is a key of `T`
1190
+ *
1191
+ * @param obj - object to query for key
1192
+ * @param k - key to check for
1193
+ * @returns true if `k` is a key of `T`
1194
+ */
1195
+ function isKeyOf(obj, k) {
1196
+ return k in obj;
1197
+ }
1198
+
1116
1199
  //#endregion
1117
1200
  //#region src/object/isPlainObject.ts
1118
1201
  /**
@@ -1157,7 +1240,14 @@ function sortObject(obj, options = {}) {
1157
1240
  /**
1158
1241
  * Special chars
1159
1242
  */
1160
- const SPECIAL_CHAR = { newline: "\n" };
1243
+ const SPECIAL_CHAR = {
1244
+ chineseComma: "、",
1245
+ englishComma: ",",
1246
+ englishPeriod: ".",
1247
+ hyphen: "-",
1248
+ newline: "\n",
1249
+ whitespace: " "
1250
+ };
1161
1251
 
1162
1252
  //#endregion
1163
1253
  //#region src/constants/regexp.ts
@@ -1177,4 +1267,4 @@ const RE_LINE_COMMENT = /\/\/.*/;
1177
1267
  const RE_BLOCK_COMMENT = /\/\*[\s\S]*?\*\//g;
1178
1268
 
1179
1269
  //#endregion
1180
- export { Color, NOOP, RE_BLOCK_COMMENT, RE_COMMENTS, RE_LINE_COMMENT, SPECIAL_CHAR, STORAGE_UNITS, TIME_UNITS, at, cAF, chunk, clamp, cleanObject, convertFromBytes, convertFromMilliseconds, convertStorageUnit, convertTimeUnit, convertToBytes, convertToMilliseconds, createPadString, debounce, enhance, ensurePrefix, ensureSuffix, escapeHTML, flattenArrayable, getObjectType, getRoot, getStringLength, getStringSimilarity, hasOwn, interopDefault, intersect, isArray, isArrayEqual, isBigInt, isBlob, isBoolean, isBrowser, isDeepEqual, isElementVisibleInViewport, isEmptyArray, isEmptyMap, isEmptyObject, isEmptySet, isEmptyString, isEmptyStringOrWhitespace, isError, isFile, isFormData, isFunction, isHTMLElement, isInteger, isIterable, isMap, isNaN, isNativePromise, isNil, isNonEmptyArray, isNonEmptyString, isNull, isNullOrUndefined, isNumber, isNumbericString, isObject, isPromise, isRegExp, isSet, isString, isTruthy, isUndefined, isUrlString, isWhitespaceString, isZero, join, last, mergeArrayable, noop, omit, once, openExternalURL, pick, rAF, randomHexColor, randomNumber, randomRGBAColor, randomRGBColor, randomString, removeFileExtension, resolveSubOptions, scrollElementIntoView, slash, slugify, sortObject, throttle, toArray, toInteger, unescapeHTML, unindent, unique, uniqueBy, waitFor, warnOnce };
1270
+ export { Color, NOOP, RE_BLOCK_COMMENT, RE_COMMENTS, RE_LINE_COMMENT, SPECIAL_CHAR, STORAGE_UNITS, TIME_UNITS, at, cAF, chunk, clamp, cleanObject, convertFromBytes, convertFromMilliseconds, convertStorageUnit, convertTimeUnit, convertToBytes, convertToMilliseconds, createPadString, debounce, enhance, ensurePrefix, ensureSuffix, escapeHTML, escapeStringRegexp, flattenArrayable, getFileExtension, getObjectType, getRoot, getStringLength, getStringSimilarity, hasOwn, interopDefault, intersect, isArray, isArrayEqual, isBigInt, isBlob, isBoolean, isBrowser, isDeepEqual, isElementVisibleInViewport, isEmptyArray, isEmptyMap, isEmptyObject, isEmptySet, isEmptyString, isEmptyStringOrWhitespace, isError, isFile, isFormData, isFunction, isHTMLElement, isInteger, isIterable, isKeyOf, isMap, isNaN, isNativePromise, isNil, isNonEmptyArray, isNonEmptyString, isNull, isNullOrUndefined, isNumber, isNumbericString, isObject, isPlainObject, isPromise, isRegExp, isSet, isString, isTruthy, isUndefined, isUrlString, isWhitespaceString, isZero, join, last, mergeArrayable, noop, omit, once, openExternalURL, pick, rAF, randomHexColor, randomNumber, randomRGBAColor, randomRGBColor, randomString, remove, removeFileExtension, resolveSubOptions, scrollElementIntoView, shuffle, slash, slugify, sortObject, throttle, toArray, toInteger, unescapeHTML, unindent, unique, uniqueBy, waitFor, warnOnce };
package/package.json CHANGED
@@ -1,8 +1,7 @@
1
1
  {
2
2
  "name": "@ntnyq/utils",
3
3
  "type": "module",
4
- "version": "0.9.2",
5
- "packageManager": "pnpm@10.16.1",
4
+ "version": "0.11.0",
6
5
  "description": "Common used utils.",
7
6
  "keywords": [
8
7
  "utils"
@@ -30,35 +29,34 @@
30
29
  "dist"
31
30
  ],
32
31
  "sideEffects": false,
33
- "scripts": {
34
- "build": "tsdown",
35
- "dev": "tsdown --watch src",
36
- "lint": "eslint",
37
- "prepare": "husky",
38
- "prepublishOnly": "pnpm run build",
39
- "release": "run-s release:check release:version",
40
- "release:check": "run-s lint typecheck test",
41
- "release:version": "bumpp",
42
- "test": "vitest",
43
- "typecheck": "tsc --noEmit"
44
- },
45
32
  "devDependencies": {
46
- "@ntnyq/eslint-config": "^5.5.0",
33
+ "@ntnyq/eslint-config": "^5.9.0",
47
34
  "@ntnyq/prettier-config": "^3.0.1",
48
- "bumpp": "^10.2.3",
49
- "eslint": "^9.35.0",
35
+ "@ntnyq/tsconfig": "^3.1.0",
36
+ "bumpp": "^10.3.2",
37
+ "eslint": "^9.39.2",
50
38
  "husky": "^9.1.7",
51
- "nano-staged": "^0.8.0",
39
+ "nano-staged": "^0.9.0",
52
40
  "npm-run-all2": "^8.0.4",
53
- "prettier": "^3.6.2",
54
- "tsdown": "^0.15.1",
55
- "typescript": "^5.9.2",
56
- "vitest": "^3.2.4"
41
+ "prettier": "^3.7.4",
42
+ "tsdown": "^0.18.3",
43
+ "typescript": "^5.9.3",
44
+ "vitest": "^4.0.16"
57
45
  },
58
46
  "engines": {
59
- "node": ">=18.18.0"
47
+ "node": "^20.19.0 || ^22.13.0 || >=24"
60
48
  },
61
49
  "nano-staged": {
62
50
  "*.{js,ts,mjs,cjs,md,yml,yaml,toml,json}": "eslint --fix"
51
+ },
52
+ "scripts": {
53
+ "build": "tsdown",
54
+ "dev": "tsdown --watch src",
55
+ "lint": "eslint",
56
+ "release": "run-s release:check release:version",
57
+ "release:check": "run-s lint typecheck test",
58
+ "release:version": "bumpp",
59
+ "test": "vitest",
60
+ "typecheck": "tsc --noEmit"
63
61
  }
64
- }
62
+ }