qsu 1.16.0 → 1.18.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 (90) hide show
  1. package/README.md +165 -11
  2. package/dist/_types/global.d.ts +4 -0
  3. package/dist/array/arrCount.d.ts +1 -1
  4. package/dist/array/arrMove.d.ts +1 -1
  5. package/dist/array/arrRepeat.d.ts +1 -1
  6. package/dist/array/sortByObjectKey.js +1 -1
  7. package/dist/array/sortNumeric.js +1 -1
  8. package/dist/format/duration.d.ts +1 -1
  9. package/dist/format/fileSizeFormat.d.ts +1 -1
  10. package/dist/format/numberFormat.js +1 -1
  11. package/dist/format/safeJSONParse.d.ts +1 -1
  12. package/dist/math/_decimalShift.d.ts +10 -0
  13. package/dist/math/_decimalShift.js +1 -0
  14. package/dist/math/ceil.d.ts +1 -0
  15. package/dist/math/ceil.js +1 -0
  16. package/dist/math/clamp.d.ts +1 -0
  17. package/dist/math/clamp.js +1 -0
  18. package/dist/math/floor.d.ts +1 -0
  19. package/dist/math/floor.js +1 -0
  20. package/dist/math/index.d.ts +6 -0
  21. package/dist/math/index.js +1 -1
  22. package/dist/math/max.d.ts +2 -0
  23. package/dist/math/max.js +1 -0
  24. package/dist/math/min.d.ts +2 -0
  25. package/dist/math/min.js +1 -0
  26. package/dist/math/round.d.ts +1 -0
  27. package/dist/math/round.js +1 -0
  28. package/dist/misc/debounce.d.ts +1 -1
  29. package/dist/misc/funcTimes.d.ts +1 -1
  30. package/dist/misc/retry.d.ts +1 -1
  31. package/dist/misc/sleep.d.ts +1 -1
  32. package/dist/misc/throttle.d.ts +1 -1
  33. package/dist/node/file/getFileInfo.d.ts +1 -1
  34. package/dist/node/net/fetchData.d.ts +1 -1
  35. package/dist/node/os/getUptime.d.ts +1 -1
  36. package/dist/object/index.d.ts +4 -0
  37. package/dist/object/index.js +1 -1
  38. package/dist/object/objClone.d.ts +3 -0
  39. package/dist/object/objClone.js +1 -0
  40. package/dist/object/objDeleteKeyByValue.d.ts +1 -1
  41. package/dist/object/objFindItemRecursiveByKey.d.ts +1 -1
  42. package/dist/object/objGet.d.ts +4 -0
  43. package/dist/object/objGet.js +1 -0
  44. package/dist/object/objInvert.d.ts +1 -1
  45. package/dist/object/objMapKeys.d.ts +1 -1
  46. package/dist/object/objMerge.d.ts +2 -0
  47. package/dist/object/objMerge.js +1 -0
  48. package/dist/object/objMergeNewKey.d.ts +1 -1
  49. package/dist/object/objPick.d.ts +2 -0
  50. package/dist/object/objPick.js +1 -0
  51. package/dist/object/objPickBy.d.ts +1 -1
  52. package/dist/object/objTo1d.d.ts +1 -1
  53. package/dist/object/objToArray.d.ts +1 -1
  54. package/dist/object/objToPrettyStr.d.ts +1 -1
  55. package/dist/object/objToQueryString.d.ts +1 -1
  56. package/dist/object/objUpdate.d.ts +1 -1
  57. package/dist/string/_capitalizeWord.d.ts +10 -0
  58. package/dist/string/_capitalizeWord.js +1 -0
  59. package/dist/string/deburr.js +1 -1
  60. package/dist/string/index.d.ts +6 -0
  61. package/dist/string/index.js +1 -1
  62. package/dist/string/pad.d.ts +2 -0
  63. package/dist/string/pad.js +1 -0
  64. package/dist/string/strBlindRandom.d.ts +1 -1
  65. package/dist/string/strRandom.d.ts +1 -1
  66. package/dist/string/strToCamelCase.d.ts +1 -0
  67. package/dist/string/strToCamelCase.js +1 -0
  68. package/dist/string/strToConstantCase.d.ts +1 -0
  69. package/dist/string/strToConstantCase.js +1 -0
  70. package/dist/string/strToKebabCase.d.ts +1 -0
  71. package/dist/string/strToKebabCase.js +1 -0
  72. package/dist/string/strToPascalCase.d.ts +1 -0
  73. package/dist/string/strToPascalCase.js +1 -0
  74. package/dist/string/strToSnakeCase.d.ts +1 -0
  75. package/dist/string/strToSnakeCase.js +1 -0
  76. package/dist/string/truncate.d.ts +1 -1
  77. package/dist/string/truncate.js +1 -1
  78. package/dist/string/truncateExpect.d.ts +2 -2
  79. package/dist/string/truncateExpect.js +1 -1
  80. package/dist/verify/hasBadWords.js +1 -1
  81. package/dist/web/escapeHtml.d.ts +1 -0
  82. package/dist/web/escapeHtml.js +1 -0
  83. package/dist/web/generateLicense.d.ts +1 -1
  84. package/dist/web/getParsedInfoFromAddress.d.ts +1 -1
  85. package/dist/web/getSlug.d.ts +1 -1
  86. package/dist/web/index.d.ts +2 -0
  87. package/dist/web/index.js +1 -1
  88. package/dist/web/unescapeHtml.d.ts +1 -0
  89. package/dist/web/unescapeHtml.js +1 -0
  90. package/package.json +104 -21
package/README.md CHANGED
@@ -2,29 +2,183 @@
2
2
 
3
3
  # qsu - Quick & Simple Utility
4
4
 
5
- [![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/jooy2/qsu/blob/main/LICENSE) ![Commit Count](https://img.shields.io/github/commit-activity/y/jooy2/qsu) [![Followers](https://img.shields.io/github/followers/jooy2?style=social)](https://github.com/jooy2) ![Stars](https://img.shields.io/github/stars/jooy2/qsu?style=social)
5
+ [![npm latest package](https://img.shields.io/npm/v/qsu/latest.svg)](https://www.npmjs.com/package/qsu) [![npm downloads](https://img.shields.io/npm/dm/qsu.svg)](https://www.npmjs.com/package/qsu) ![minified size](https://img.shields.io/bundlephobia/min/qsu) ![node version](https://img.shields.io/node/v/qsu) [![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/jooy2/qsu/blob/main/LICENSE) [![test](https://github.com/jooy2/qsu/actions/workflows/run-test-javascript.yml/badge.svg)](https://github.com/jooy2/qsu/actions/workflows/run-test-javascript.yml)
6
6
 
7
- **qsu** is a library that collects frequently used utility functions. Streamline repetitive code with useful functions. Optimized for modern development environments, it supports various programming languages.
7
+ **qsu** is a library that collects frequently used utility functions slugs, text case, date math, number and file size formatting, deep clone and merge, validation, hashing, file and OS helpers. Stop rewriting the same small helpers in every project and stop pulling in a large toolkit for three of them.
8
8
 
9
- The following are the advantages of the qsu:
9
+ ```javascript
10
+ import { getSlug, fileSizeFormat, objMerge } from 'qsu';
10
11
 
11
- - Fast, lightweight bundle size
12
- - Install and use easily.
13
- - It is suitable for use on websites or applications.
14
- - Documents, prepared for secure data types.
15
- - Reduce defects through fast maintenance and various test cases.
16
- - Support for multiple programming languages for the same operation. (JavaScript, Dart)
12
+ getSlug('Hello World!'); // 'hello-world'
13
+ fileSizeFormat(1000000); // '976.56 KB'
14
+ objMerge({ a: { b: 1 } }, { a: { c: 2 } }); // { a: { b: 1, c: 2 } }
15
+ ```
16
+
17
+ ## Why qsu
18
+
19
+ - **No runtime dependencies.** Nothing is installed alongside it.
20
+ - **Tree-shakeable.** The package is marked side-effect free, so your bundler keeps only the functions you actually import.
21
+ - **ESM only.** Written for modern toolchains, from bundlers to serverless runtimes.
22
+ - **Typed.** TypeScript declarations ship with the package, and the shared option types are importable from `qsu/types`.
23
+ - **Browser-safe by default.** Functions that need a Node.js runtime live behind the `qsu/node` subpath, so the main entry point never reaches for `node:fs` or `node:crypto`.
24
+ - **Predictable.** Arguments are validated and edge cases — `null`, empty values, surrogate pairs, nested arrays — return a sensible result instead of throwing.
25
+ - **Tested.** The suite runs on Node.js 22, 24 and 26 across Linux, macOS and Windows in CI.
26
+
27
+ ## Installation
28
+
29
+ **qsu** requires `Node.js 18` or later.
30
+
31
+ ```bash
32
+ npm install qsu
33
+ ```
34
+
35
+ ```bash
36
+ pnpm add qsu
37
+ ```
38
+
39
+ ```bash
40
+ yarn add qsu
41
+ ```
42
+
43
+ ## How to use
44
+
45
+ Import only the functions you need:
46
+
47
+ ```javascript
48
+ import { today, strCount } from 'qsu';
49
+
50
+ console.log(today()); // '20xx-xx-xx'
51
+ console.log(strCount('123412341234', '1')); // 3
52
+ ```
53
+
54
+ You can also import the package under a single name. It makes qsu's functions easy to spot in a file, but it is not the recommended default: a bundler can still drop untouched functions while every access is a plain property (`_.today()`), but as soon as a name is looked up dynamically (`_[name]()`) or `_` is handed to something else, the whole library has to be kept.
55
+
56
+ ```javascript
57
+ import * as _ from 'qsu';
58
+
59
+ console.log(_.today()); // '20xx-xx-xx'
60
+ console.log(_.strCount('123412341234', '1')); // 3
61
+ ```
62
+
63
+ ### Node.js only functions
64
+
65
+ Functions for the filesystem, hashing, networking and the operating system need a Node.js runtime, so they are published under the `qsu/node` subpath and are not part of the browser-safe entry point:
66
+
67
+ ```javascript
68
+ import { createFile, md5Hash } from 'qsu/node';
69
+
70
+ md5Hash('test'); // '098f6bcd4621d373cade4e832627b4f6'
71
+ await createFile('/home/user/Hello.txt');
72
+ ```
73
+
74
+ Every reference page states whether the function has to be imported from `qsu/node`.
75
+
76
+ ### Importing a single category
77
+
78
+ If you are not running a bundler at all — a script, a serverless function, a test — you can import a single category so that only that category's modules are loaded:
79
+
80
+ ```javascript
81
+ import { arrUnique } from 'qsu/array';
82
+ import { getSlug } from 'qsu/web';
83
+ import { md5Hash } from 'qsu/node/crypto';
84
+ ```
85
+
86
+ ### Types
87
+
88
+ Option types are shared and can be imported directly:
89
+
90
+ ```typescript
91
+ import type { SlugOptions, DurationOptions } from 'qsu/types';
92
+
93
+ const options: SlugOptions = { separator: '_', includeNumbers: false };
94
+ ```
95
+
96
+ ## Examples
97
+
98
+ ```javascript
99
+ import {
100
+ arrUnique,
101
+ duration,
102
+ numberFormat,
103
+ objPick,
104
+ pad,
105
+ strToCamelCase,
106
+ truncate,
107
+ isEmail
108
+ } from 'qsu';
109
+
110
+ // Arrays
111
+ arrUnique([1, 1, 2, 3, 3]); // [1, 2, 3]
112
+
113
+ // Formatting
114
+ numberFormat(1234567); // '1,234,567'
115
+ duration(1234567890); // '14 Days 6 Hours 56 Minutes 7 Seconds'
116
+
117
+ // Objects
118
+ objPick({ a: 1, b: 2, c: 3 }, ['a', 'c']); // { a: 1, c: 3 }
119
+
120
+ // Strings
121
+ strToCamelCase('foo bar'); // 'fooBar'
122
+ truncate('Hello world', 5, '...'); // 'Hello...'
123
+ pad('7', 3, { char: '0', position: 'start' }); // '007'
124
+
125
+ // Validation
126
+ isEmail('abc@example.com'); // true
127
+ ```
128
+
129
+ Optional arguments are passed as an options object, and every option has a documented default:
130
+
131
+ ```javascript
132
+ getSlug('Hello World!', { separator: '_' }); // 'hello_world'
133
+ fileSizeFormat(100000000, 3, true); // '96 MB'
134
+ ```
135
+
136
+ ## API overview
137
+
138
+ Functions are grouped into categories, each with an import subpath of its own.
139
+
140
+ | Category | Import path | Examples |
141
+ | --- | --- | --- |
142
+ | `array` | `qsu/array` | `arrUnique`, `arrGroupByMaxCount`, `sortNumeric` |
143
+ | `date` | `qsu/date` | `today`, `dayDiff`, `createDateListFromRange` |
144
+ | `format` | `qsu/format` | `numberFormat`, `fileSizeFormat`, `duration` |
145
+ | `math` | `qsu/math` | `sum`, `clamp`, `round`, `numPick` |
146
+ | `misc` | `qsu/misc` | `debounce`, `throttle`, `retry`, `sleep` |
147
+ | `object` | `qsu/object` | `objClone`, `objMerge`, `objPick`, `objGet` |
148
+ | `string` | `qsu/string` | `trim`, `truncate`, `strToCamelCase`, `pad` |
149
+ | `verify` | `qsu/verify` | `isEmail`, `isUrl`, `isEmpty`, `isEqual` |
150
+ | `web` | `qsu/web` | `getSlug`, `escapeHtml`, `isMobile`, `isBotAgent` |
151
+ | `crypto` | `qsu/node/crypto` | `md5Hash`, `sha256Hash`, `encodeBase64`, `objectId` |
152
+ | `file` | `qsu/node/file` | `getFileSize`, `moveFile`, `joinFilePath` |
153
+ | `misc` | `qsu/node/misc` | `logBox` |
154
+ | `net` | `qsu/node/net` | `fetchData` |
155
+ | `os` | `qsu/node/os` | `getCpu`, `getRamSize`, `runCommand` |
156
+
157
+ The categories in the top half are exported from `qsu` and are safe to bundle for the browser. The `crypto`, `file`, `net` and `os` categories, and `logBox`, need a Node.js runtime and are exported from `qsu/node`.
17
158
 
18
159
  ## Documentation
19
160
 
20
161
  Installing and using the package and defining all the utility methods can be found on the documentation page below.
21
162
 
22
163
  - [Installation](https://qsu.cdget.com/installation/javascript)
23
- - [Reference](https://qsu.cdget.com/reference)
164
+ - [Reference](https://qsu.cdget.com/reference) — every function, with parameters, defaults and examples
165
+ - [Changelog](https://qsu.cdget.com/changelog/javascript)
166
+
167
+ ## Development
168
+
169
+ The package lives in the [qsu monorepo](https://github.com/jooy2/qsu) under `packages/javascript`. Source is TypeScript in `lib/`, built to `dist/`.
170
+
171
+ ```bash
172
+ npm install # install dev dependencies
173
+ npm test # build, then run the test suite
174
+ npm run build # compile with tsc and minify with terser
175
+ npm run lint # ESLint
176
+ npm run format # Prettier
177
+ ```
24
178
 
25
179
  ## Contributing
26
180
 
27
- Anyone can contribute to the project by reporting new issues or submitting a pull request. For more information, please see [CONTRIBUTING.md](CONTRIBUTING.md).
181
+ Anyone can contribute to the project by reporting new issues or submitting a pull request. For more information, please see [CONTRIBUTING.md](https://github.com/jooy2/qsu/blob/main/CONTRIBUTING.md).
28
182
 
29
183
  ## License
30
184
 
@@ -20,6 +20,10 @@ export type RetryOptions = {
20
20
  delay?: number;
21
21
  backoff?: number;
22
22
  };
23
+ export type PadOptions = {
24
+ position?: 'start' | 'end' | 'both';
25
+ char?: string;
26
+ };
23
27
  export type ThrottleOptions = {
24
28
  leading?: boolean;
25
29
  trailing?: boolean;
@@ -1,2 +1,2 @@
1
- import type { NumberValueObject } from '../_types/global';
1
+ import type { NumberValueObject } from '../_types/global.js';
2
2
  export declare function arrCount(array: string[] | number[]): NumberValueObject;
@@ -1,2 +1,2 @@
1
- import { PositiveNumber } from '../_types/global';
1
+ import type { PositiveNumber } from '../_types/global.js';
2
2
  export declare function arrMove<N extends number>(array: any[], from: PositiveNumber<N>, to: PositiveNumber<N>): any[];
@@ -1,2 +1,2 @@
1
- import { PositiveNumber } from '../_types/global';
1
+ import type { PositiveNumber } from '../_types/global.js';
2
2
  export declare function arrRepeat<N extends number>(array: any, count: PositiveNumber<N>): any[];
@@ -1 +1 @@
1
- const o=new Intl.Collator([],{numeric:!0});export function sortByObjectKey(r,t,e=!1,n=!1){return n?[...r].sort((r,n)=>e?o.compare(n[t],r[t]):o.compare(r[t],n[t])):[...r].sort((o,r)=>e?o[t]>r[t]?-1:o[t]<r[t]?1:0:o[t]<r[t]?-1:o[t]>r[t]?1:0)}
1
+ let r;export function sortByObjectKey(t,e,o=!1,n=!1){if(n){const n=r??=new Intl.Collator([],{numeric:!0});return[...t].sort((r,t)=>o?n.compare(t[e],r[e]):n.compare(r[e],t[e]))}return[...t].sort((r,t)=>o?r[e]>t[e]?-1:r[e]<t[e]?1:0:r[e]<t[e]?-1:r[e]>t[e]?1:0)}
@@ -1 +1 @@
1
- const r=new Intl.Collator([],{numeric:!0});export function sortNumeric(o,t=!1){return[...o].sort((o,e)=>t?r.compare(e,o):r.compare(o,e))}
1
+ let r;export function sortNumeric(o,t=!1){const e=r??=new Intl.Collator([],{numeric:!0});return[...o].sort((r,o)=>t?e.compare(o,r):e.compare(r,o))}
@@ -1,2 +1,2 @@
1
- import type { DurationOptions } from '../_types/global';
1
+ import type { DurationOptions } from '../_types/global.js';
2
2
  export declare function duration(milliseconds: number, options?: DurationOptions): string;
@@ -1,2 +1,2 @@
1
- import type { PositiveNumber } from '../_types/global';
1
+ import type { PositiveNumber } from '../_types/global.js';
2
2
  export declare function fileSizeFormat<N extends number>(bytes: PositiveNumber<N>, decimals?: number, ceil?: boolean): string;
@@ -1 +1 @@
1
- const t=/^\d+$/,n=new Intl.NumberFormat("en-US",{roundingPriority:"morePrecision"});export function numberFormat(r){if(null==r)return"";const e="string"==typeof r?r:r.toString(),o=e.startsWith("-"),i=(o?e.slice(1):e).split("."),s=t.test(i[0])?function(t){let n="";for(let r=t.length;r>0;r-=3){const e=t.slice(Math.max(0,r-3),r);n=""===n?e:`${e},${n}`}return n}(i[0]):n.format(parseInt(i[0],10)),l=`${s}${i.length>1?`.${i[1]}`:""}`;return o?`-${l}`:l}
1
+ const t=/^\d+$/;let n;export function numberFormat(r){if(null==r)return"";const e="string"==typeof r?r:r.toString(),o=e.startsWith("-"),i=(o?e.slice(1):e).split("."),s=t.test(i[0])?function(t){let n="";for(let r=t.length;r>0;r-=3){const e=t.slice(Math.max(0,r-3),r);n=""===n?e:`${e},${n}`}return n}(i[0]):(n??=new Intl.NumberFormat("en-US",{roundingPriority:"morePrecision"})).format(parseInt(i[0],10)),l=`${s}${i.length>1?`.${i[1]}`:""}`;return o?`-${l}`:l}
@@ -1,2 +1,2 @@
1
- import type { AnyValueObject } from '../_types/global';
1
+ import type { AnyValueObject } from '../_types/global.js';
2
2
  export declare function safeJSONParse(jsonString: any, fallback?: {}): AnyValueObject;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * (Private, not exported from the package) Multiplies a number by a power of ten by moving
3
+ * the exponent of its shortest string representation, instead of multiplying by `10 ** n`.
4
+ *
5
+ * `1.005 * 100` is `100.49999999999999`, so the naive form answers `1` for `round(1.005, 2)`
6
+ * and `1.1 * 10` is `11.000000000000002`, so `ceil(1.1, 1)` answers `1.2`. Parsing
7
+ * `'1.005e2'` yields exactly `100.5` instead, because the shortest representation is the
8
+ * decimal the caller wrote and the parser rounds it to the nearest double exactly once.
9
+ */
10
+ export declare function decimalShift(value: number, exponent: number): number;
@@ -0,0 +1 @@
1
+ export function decimalShift(e,t){const[r,i]=String(e).split("e");return Number(`${r}e${(i?Number(i):0)+t}`)}
@@ -0,0 +1 @@
1
+ export declare function ceil(value: number, precision?: number): number;
@@ -0,0 +1 @@
1
+ import{decimalShift as i}from"./_decimalShift.js";export function ceil(e,t=0){return Number.isFinite(e)?i(Math.ceil(i(e,t)),-t):e}
@@ -0,0 +1 @@
1
+ export declare function clamp(value: number, min: number, max: number): number;
@@ -0,0 +1 @@
1
+ export function clamp(t,a,n){return Math.max(Math.min(t,n),a)}
@@ -0,0 +1 @@
1
+ export declare function floor(value: number, precision?: number): number;
@@ -0,0 +1 @@
1
+ import{decimalShift as o}from"./_decimalShift.js";export function floor(r,i=0){return Number.isFinite(r)?o(Math.floor(o(r,i)),-i):r}
@@ -1,6 +1,12 @@
1
+ export { ceil } from './ceil.js';
2
+ export { clamp } from './clamp.js';
1
3
  export { div } from './div.js';
4
+ export { floor } from './floor.js';
5
+ export { max } from './max.js';
6
+ export { min } from './min.js';
2
7
  export { mul } from './mul.js';
3
8
  export { numPick } from './numPick.js';
4
9
  export { numUnique } from './numUnique.js';
10
+ export { round } from './round.js';
5
11
  export { sub } from './sub.js';
6
12
  export { sum } from './sum.js';
@@ -1 +1 @@
1
- export{div}from"./div.js";export{mul}from"./mul.js";export{numPick}from"./numPick.js";export{numUnique}from"./numUnique.js";export{sub}from"./sub.js";export{sum}from"./sum.js";
1
+ export{ceil}from"./ceil.js";export{clamp}from"./clamp.js";export{div}from"./div.js";export{floor}from"./floor.js";export{max}from"./max.js";export{min}from"./min.js";export{mul}from"./mul.js";export{numPick}from"./numPick.js";export{numUnique}from"./numUnique.js";export{round}from"./round.js";export{sub}from"./sub.js";export{sum}from"./sum.js";
@@ -0,0 +1,2 @@
1
+ export declare function max(...args: any[]): number | null;
2
+ export declare function max(...args: Array<number>): number | null;
@@ -0,0 +1 @@
1
+ export function max(...n){const r=n.length>0&&Array.isArray(n[0])?n[0]:n;let t=null;for(let n=0,e=r.length;n<e;n+=1){const e=r[n];"number"==typeof e&&!Number.isNaN(e)&&(null===t||e>t)&&(t=e)}return t}
@@ -0,0 +1,2 @@
1
+ export declare function min(...args: any[]): number | null;
2
+ export declare function min(...args: Array<number>): number | null;
@@ -0,0 +1 @@
1
+ export function min(...n){const r=n.length>0&&Array.isArray(n[0])?n[0]:n;let t=null;for(let n=0,e=r.length;n<e;n+=1){const e=r[n];"number"==typeof e&&!Number.isNaN(e)&&(null===t||e<t)&&(t=e)}return t}
@@ -0,0 +1 @@
1
+ export declare function round(value: number, precision?: number): number;
@@ -0,0 +1 @@
1
+ import{decimalShift as r}from"./_decimalShift.js";export function round(t,n=0){if(!Number.isFinite(t))return t;const i=r(t,n),o=i<0?-Math.round(-i):Math.round(i);return r(o,-n)}
@@ -1,2 +1,2 @@
1
- import type { PositiveNumber } from '../_types/global';
1
+ import type { PositiveNumber } from '../_types/global.js';
2
2
  export declare function debounce<N extends number>(func: (...args: any[]) => void, timeout: PositiveNumber<N>): (...args: any[]) => void;
@@ -1,2 +1,2 @@
1
- import type { PositiveNumber } from '../_types/global';
1
+ import type { PositiveNumber } from '../_types/global.js';
2
2
  export declare function funcTimes<N extends number>(times: PositiveNumber<N>, iteratee: any): Array<any>;
@@ -1,2 +1,2 @@
1
- import type { RetryOptions } from '../_types/global';
1
+ import type { RetryOptions } from '../_types/global.js';
2
2
  export declare function retry<T>(func: () => T | Promise<T>, options?: RetryOptions): Promise<T>;
@@ -1,2 +1,2 @@
1
- import type { PositiveNumber } from '../_types/global';
1
+ import type { PositiveNumber } from '../_types/global.js';
2
2
  export declare function sleep<N extends number>(delay: PositiveNumber<N>): Promise<void>;
@@ -1,2 +1,2 @@
1
- import type { PositiveNumber, ThrottleOptions } from '../_types/global';
1
+ import type { PositiveNumber, ThrottleOptions } from '../_types/global.js';
2
2
  export declare function throttle<N extends number>(func: (...args: any[]) => void, wait: PositiveNumber<N>, options?: ThrottleOptions): (...args: any[]) => void;
@@ -1,2 +1,2 @@
1
- import { FileInfo } from '../../_types/global';
1
+ import type { FileInfo } from '../../_types/global.js';
2
2
  export declare function getFileInfo(filePath: string): Promise<FileInfo>;
@@ -1,2 +1,2 @@
1
- import type { HTTPRequestOption } from '../../_types/global';
1
+ import type { HTTPRequestOption } from '../../_types/global.js';
2
2
  export declare function fetchData(url: string, options?: HTTPRequestOption): Promise<any>;
@@ -1,2 +1,2 @@
1
- import { GetUptimeOption } from '../../_types/global';
1
+ import type { GetUptimeOption } from '../../_types/global.js';
2
2
  export declare function getUptime(opt?: GetUptimeOption): number | string;
@@ -1,8 +1,12 @@
1
+ export { objClone } from './objClone.js';
1
2
  export { objDeleteKeyByValue } from './objDeleteKeyByValue.js';
2
3
  export { objFindItemRecursiveByKey } from './objFindItemRecursiveByKey.js';
4
+ export { objGet } from './objGet.js';
3
5
  export { objInvert } from './objInvert.js';
4
6
  export { objMapKeys } from './objMapKeys.js';
7
+ export { objMerge } from './objMerge.js';
5
8
  export { objMergeNewKey } from './objMergeNewKey.js';
9
+ export { objPick } from './objPick.js';
6
10
  export { objPickBy } from './objPickBy.js';
7
11
  export { objTo1d } from './objTo1d.js';
8
12
  export { objToArray } from './objToArray.js';
@@ -1 +1 @@
1
- export{objDeleteKeyByValue}from"./objDeleteKeyByValue.js";export{objFindItemRecursiveByKey}from"./objFindItemRecursiveByKey.js";export{objInvert}from"./objInvert.js";export{objMapKeys}from"./objMapKeys.js";export{objMergeNewKey}from"./objMergeNewKey.js";export{objPickBy}from"./objPickBy.js";export{objTo1d}from"./objTo1d.js";export{objToArray}from"./objToArray.js";export{objToPrettyStr}from"./objToPrettyStr.js";export{objToQueryString}from"./objToQueryString.js";export{objUpdate}from"./objUpdate.js";
1
+ export{objClone}from"./objClone.js";export{objDeleteKeyByValue}from"./objDeleteKeyByValue.js";export{objFindItemRecursiveByKey}from"./objFindItemRecursiveByKey.js";export{objGet}from"./objGet.js";export{objInvert}from"./objInvert.js";export{objMapKeys}from"./objMapKeys.js";export{objMerge}from"./objMerge.js";export{objMergeNewKey}from"./objMergeNewKey.js";export{objPick}from"./objPick.js";export{objPickBy}from"./objPickBy.js";export{objTo1d}from"./objTo1d.js";export{objToArray}from"./objToArray.js";export{objToPrettyStr}from"./objToPrettyStr.js";export{objToQueryString}from"./objToQueryString.js";export{objUpdate}from"./objUpdate.js";
@@ -0,0 +1,3 @@
1
+ export declare function objClone(obj: any, options?: {
2
+ deep?: boolean;
3
+ }): any;
@@ -0,0 +1 @@
1
+ import{isObject as e}from"../verify/isObject.js";function t(n,r){if(null===n||"object"!=typeof n)return n;if(r.has(n))return r.get(n);if(n instanceof Date)return new Date(n.getTime());if(n instanceof RegExp)return new RegExp(n.source,n.flags);if(Array.isArray(n)){const e=[];r.set(n,e);for(let a=0,o=n.length;a<o;a+=1)e[a]=t(n[a],r);return e}if(n instanceof Map){const e=new Map;return r.set(n,e),n.forEach((n,a)=>{e.set(t(a,r),t(n,r))}),e}if(n instanceof Set){const e=new Set;return r.set(n,e),n.forEach(n=>{e.add(t(n,r))}),e}if(e(n)){const e={};return r.set(n,e),Object.keys(n).forEach(a=>{e[a]=t(n[a],r)}),e}return n}export function objClone(n,r){return null===n||"object"!=typeof n?n:!1===r?.deep?Array.isArray(n)?[...n]:n instanceof Date?new Date(n.getTime()):n instanceof RegExp?new RegExp(n.source,n.flags):n instanceof Map?new Map(n):n instanceof Set?new Set(n):e(n)?{...n}:n:t(n,new WeakMap)}
@@ -1,2 +1,2 @@
1
- import type { AnyValueObject } from '../_types/global';
1
+ import type { AnyValueObject } from '../_types/global.js';
2
2
  export declare function objDeleteKeyByValue(obj: AnyValueObject, searchValue: string | number | null | undefined, recursive?: boolean): AnyValueObject | null;
@@ -1,2 +1,2 @@
1
- import type { AnyValueObject } from '../_types/global';
1
+ import type { AnyValueObject } from '../_types/global.js';
2
2
  export declare function objFindItemRecursiveByKey(obj: AnyValueObject | any[], searchKey: string, searchValue: any, childKey: string): AnyValueObject | null;
@@ -0,0 +1,4 @@
1
+ import type { AnyValueObject } from '../_types/global.js';
2
+ export declare function objGet(obj: AnyValueObject, path: string, options?: {
3
+ fallback?: any;
4
+ }): any;
@@ -0,0 +1 @@
1
+ export function objGet(t,n,e){const o=e?.fallback??null;if(!t||"object"!=typeof t||"string"!=typeof n)return o;const c=function(t){const n=[],e=t.length;let o="",c=0;for(;c<e;){const e=t[c];if("["===e){const l=t.indexOf("]",c);if(-1===l){o+=e,c+=1;continue}""!==o&&(n.push(o),o="");let s=t.slice(c+1,l);const u=s[0];s.length>=2&&("'"===u||'"'===u)&&s.endsWith(u)&&(s=s.slice(1,-1)),n.push(s),c=l+1,"."===t[c]&&(c+=1);continue}"."!==e?(o+=e,c+=1):(n.push(o),o="",c+=1)}return""===o&&0!==n.length||n.push(o),n}(n);let l=t;for(let t=0,n=c.length;t<n;t+=1){if(null===l||"object"!=typeof l||!Object.hasOwn(l,c[t]))return o;l=l[c[t]]}return l}
@@ -1,4 +1,4 @@
1
- import type { AnyValueObject } from '../_types/global';
1
+ import type { AnyValueObject } from '../_types/global.js';
2
2
  export declare function objInvert(obj: AnyValueObject): {
3
3
  [key: string]: string;
4
4
  } | null;
@@ -1,2 +1,2 @@
1
- import type { AnyValueObject } from '../_types/global';
1
+ import type { AnyValueObject } from '../_types/global.js';
2
2
  export declare function objMapKeys(obj: AnyValueObject, iteratee: (value: any, key: string) => string): AnyValueObject | null;
@@ -0,0 +1,2 @@
1
+ import type { AnyValueObject } from '../_types/global.js';
2
+ export declare function objMerge(...objects: AnyValueObject[]): AnyValueObject | null;
@@ -0,0 +1 @@
1
+ import{isObject as e}from"../verify/isObject.js";export function objMerge(...t){if(0===t.length)return null;const n={};for(let r=0,o=t.length;r<o;r+=1){const o=t[r];if(!e(o))return null;const l=Object.keys(o);for(let t=0,r=l.length;t<r;t+=1){const r=l[t],c=o[r];n[r]=e(n[r])&&e(c)?objMerge(n[r],c):c}}return n}
@@ -1,4 +1,4 @@
1
- import type { AnyValueObject } from '../_types/global';
1
+ import type { AnyValueObject } from '../_types/global.js';
2
2
  export declare function objMergeNewKey(obj: AnyValueObject, obj2: AnyValueObject, options?: {
3
3
  arrayAction?: 'original' | 'replace' | 'append';
4
4
  }): AnyValueObject | null;
@@ -0,0 +1,2 @@
1
+ import type { AnyValueObject } from '../_types/global.js';
2
+ export declare function objPick(obj: AnyValueObject, keys: string | string[]): AnyValueObject | null;
@@ -0,0 +1 @@
1
+ export function objPick(t,r){if(!t||"object"!=typeof t)return null;const n=Array.isArray(r)?r:[r],e={};for(let r=0,o=n.length;r<o;r+=1){const o=n[r];Object.hasOwn(t,o)&&(e[o]=t[o])}return e}
@@ -1,2 +1,2 @@
1
- import type { AnyValueObject } from '../_types/global';
1
+ import type { AnyValueObject } from '../_types/global.js';
2
2
  export declare function objPickBy(obj: AnyValueObject, predicate: (value: any, key: string) => boolean): AnyValueObject | null;
@@ -1,2 +1,2 @@
1
- import type { AnyValueObject } from '../_types/global';
1
+ import type { AnyValueObject } from '../_types/global.js';
2
2
  export declare function objTo1d(obj: AnyValueObject, separator?: string): AnyValueObject;
@@ -1,2 +1,2 @@
1
- import type { AnyValueObject } from '../_types/global';
1
+ import type { AnyValueObject } from '../_types/global.js';
2
2
  export declare function objToArray(obj: AnyValueObject, recursive?: boolean): any[];
@@ -1,2 +1,2 @@
1
- import type { AnyValueObject } from '../_types/global';
1
+ import type { AnyValueObject } from '../_types/global.js';
2
2
  export declare function objToPrettyStr(obj: AnyValueObject): string;
@@ -1,2 +1,2 @@
1
- import type { AnyValueObject } from '../_types/global';
1
+ import type { AnyValueObject } from '../_types/global.js';
2
2
  export declare function objToQueryString(obj: AnyValueObject): string;
@@ -1,2 +1,2 @@
1
- import { AnyValueObject } from '../_types/global';
1
+ import type { AnyValueObject } from '../_types/global.js';
2
2
  export declare function objUpdate(obj: AnyValueObject, key: string, value: any, recursive?: boolean, upsert?: boolean): AnyValueObject | null;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * (Private, not exported from the package) Uppercases the first character of a word and
3
+ * lowercases the rest, so `XML` becomes `Xml`.
4
+ *
5
+ * The word is split by code point rather than indexed, because indexing a JavaScript string
6
+ * walks UTF-16 units and would cut a surrogate pair in half, disagreeing with the Dart and
7
+ * Python implementations. This is what the case-conversion family needs, and it is not the
8
+ * same as the public `capitalizeFirst`, which leaves the rest of the string alone.
9
+ */
10
+ export declare function capitalizeWord(word: string): string;
@@ -0,0 +1 @@
1
+ export function capitalizeWord(r){if(!r)return"";const e=Array.from(r);return e[0].toUpperCase()+e.slice(1).join("").toLowerCase()}
@@ -1 +1 @@
1
- const t=[["ÀÁÂÃÄÅĀĂĄ","A"],["àáâãäåāăą","a"],["ÇĆĈĊČ","C"],["çćĉċč","c"],["ÐĎĐ","D"],["ðďđ","d"],["ÈÉÊËĒĔĖĘĚ","E"],["èéêëēĕėęě","e"],["ĜĞĠĢ","G"],["ĝğġģ","g"],["ĤĦ","H"],["ĥħ","h"],["ÌÍÎÏĨĪĬĮİ","I"],["ìíîïĩīĭįı","i"],["Ĵ","J"],["ĵ","j"],["Ķ","K"],["ķĸ","k"],["ĹĻĽĿŁ","L"],["ĺļľŀł","l"],["ÑŃŅŇŊ","N"],["ñńņňŋ","n"],["ÒÓÔÕÖØŌŎŐ","O"],["òóôõöøōŏő","o"],["ŔŖŘ","R"],["ŕŗř","r"],["ŚŜŞŠ","S"],["śŝşšſ","s"],["ŢŤŦ","T"],["ţťŧ","t"],["ÙÚÛÜŨŪŬŮŰŲ","U"],["ùúûüũūŭůűų","u"],["Ŵ","W"],["ŵ","w"],["ÝŶŸ","Y"],["ýÿŷ","y"],["ŹŻŽ","Z"],["źżž","z"],["Æ","Ae"],["æ","ae"],["Þ","Th"],["þ","th"],["ß","ss"],["IJ","IJ"],["ij","ij"],["Œ","Oe"],["œ","oe"],["ʼn","'n"]],e=new Map;for(let n=0,r=t.length;n<r;n+=1){const[s,c]=t[n];for(const f of s)e.set(f,c)}const o=t=>t>=768&&t<=879||t>=8400&&t<=8432||t>=65056&&t<=65071;export function deburr(t){if(!t)return"";let n="";for(const r of t)o(r.codePointAt(0))||(n+=e.get(r)??r);return n}
1
+ const t=[["ÀÁÂÃÄÅĀĂĄ","A"],["àáâãäåāăą","a"],["ÇĆĈĊČ","C"],["çćĉċč","c"],["ÐĎĐ","D"],["ðďđ","d"],["ÈÉÊËĒĔĖĘĚ","E"],["èéêëēĕėęě","e"],["ĜĞĠĢ","G"],["ĝğġģ","g"],["ĤĦ","H"],["ĥħ","h"],["ÌÍÎÏĨĪĬĮİ","I"],["ìíîïĩīĭįı","i"],["Ĵ","J"],["ĵ","j"],["Ķ","K"],["ķĸ","k"],["ĹĻĽĿŁ","L"],["ĺļľŀł","l"],["ÑŃŅŇŊ","N"],["ñńņňŋ","n"],["ÒÓÔÕÖØŌŎŐ","O"],["òóôõöøōŏő","o"],["ŔŖŘ","R"],["ŕŗř","r"],["ŚŜŞŠ","S"],["śŝşšſ","s"],["ŢŤŦ","T"],["ţťŧ","t"],["ÙÚÛÜŨŪŬŮŰŲ","U"],["ùúûüũūŭůűų","u"],["Ŵ","W"],["ŵ","w"],["ÝŶŸ","Y"],["ýÿŷ","y"],["ŹŻŽ","Z"],["źżž","z"],["Æ","Ae"],["æ","ae"],["Þ","Th"],["þ","th"],["ß","ss"],["IJ","IJ"],["ij","ij"],["Œ","Oe"],["œ","oe"],["ʼn","'n"]];let e;const o=t=>t>=768&&t<=879||t>=8400&&t<=8432||t>=65056&&t<=65071;export function deburr(n){if(!n)return"";const r=(()=>{if(void 0!==e)return e;e=new Map;for(let o=0,n=t.length;o<n;o+=1){const[n,r]=t[o];for(const t of n)e.set(t,r)}return e})();let s="";for(const t of n)o(t.codePointAt(0))||(s+=r.get(t)??t);return s}
@@ -5,6 +5,7 @@ export { deburr } from './deburr.js';
5
5
  export { escapeRegExp } from './escapeRegExp.js';
6
6
  export { getGroupKeys } from './getGroupKeys.js';
7
7
  export { getStrBytes } from './getStrBytes.js';
8
+ export { pad } from './pad.js';
8
9
  export { removeNewLine } from './removeNewLine.js';
9
10
  export { removeSpecialChar } from './removeSpecialChar.js';
10
11
  export { replaceBetween } from './replaceBetween.js';
@@ -14,6 +15,11 @@ export { strCount } from './strCount.js';
14
15
  export { strRandom } from './strRandom.js';
15
16
  export { strShuffle } from './strShuffle.js';
16
17
  export { strToAscii } from './strToAscii.js';
18
+ export { strToCamelCase } from './strToCamelCase.js';
19
+ export { strToConstantCase } from './strToConstantCase.js';
20
+ export { strToKebabCase } from './strToKebabCase.js';
21
+ export { strToPascalCase } from './strToPascalCase.js';
22
+ export { strToSnakeCase } from './strToSnakeCase.js';
17
23
  export { strUnique } from './strUnique.js';
18
24
  export { trim } from './trim.js';
19
25
  export { truncate } from './truncate.js';
@@ -1 +1 @@
1
- export{capitalizeEachWords}from"./capitalizeEachWords.js";export{capitalizeEverySentence}from"./capitalizeEverySentence.js";export{capitalizeFirst}from"./capitalizeFirst.js";export{deburr}from"./deburr.js";export{escapeRegExp}from"./escapeRegExp.js";export{getGroupKeys}from"./getGroupKeys.js";export{getStrBytes}from"./getStrBytes.js";export{removeNewLine}from"./removeNewLine.js";export{removeSpecialChar}from"./removeSpecialChar.js";export{replaceBetween}from"./replaceBetween.js";export{split}from"./split.js";export{strBlindRandom}from"./strBlindRandom.js";export{strCount}from"./strCount.js";export{strRandom}from"./strRandom.js";export{strShuffle}from"./strShuffle.js";export{strToAscii}from"./strToAscii.js";export{strUnique}from"./strUnique.js";export{trim}from"./trim.js";export{truncate}from"./truncate.js";export{truncateExpect}from"./truncateExpect.js";export{uncapitalizeFirst}from"./uncapitalizeFirst.js";export{urlJoin}from"./urlJoin.js";export{words}from"./words.js";
1
+ export{capitalizeEachWords}from"./capitalizeEachWords.js";export{capitalizeEverySentence}from"./capitalizeEverySentence.js";export{capitalizeFirst}from"./capitalizeFirst.js";export{deburr}from"./deburr.js";export{escapeRegExp}from"./escapeRegExp.js";export{getGroupKeys}from"./getGroupKeys.js";export{getStrBytes}from"./getStrBytes.js";export{pad}from"./pad.js";export{removeNewLine}from"./removeNewLine.js";export{removeSpecialChar}from"./removeSpecialChar.js";export{replaceBetween}from"./replaceBetween.js";export{split}from"./split.js";export{strBlindRandom}from"./strBlindRandom.js";export{strCount}from"./strCount.js";export{strRandom}from"./strRandom.js";export{strShuffle}from"./strShuffle.js";export{strToAscii}from"./strToAscii.js";export{strToCamelCase}from"./strToCamelCase.js";export{strToConstantCase}from"./strToConstantCase.js";export{strToKebabCase}from"./strToKebabCase.js";export{strToPascalCase}from"./strToPascalCase.js";export{strToSnakeCase}from"./strToSnakeCase.js";export{strUnique}from"./strUnique.js";export{trim}from"./trim.js";export{truncate}from"./truncate.js";export{truncateExpect}from"./truncateExpect.js";export{uncapitalizeFirst}from"./uncapitalizeFirst.js";export{urlJoin}from"./urlJoin.js";export{words}from"./words.js";
@@ -0,0 +1,2 @@
1
+ import type { PadOptions } from '../_types/global.js';
2
+ export declare function pad(str: string, length: number, options?: PadOptions): string;
@@ -0,0 +1 @@
1
+ function t(t,r){if(r<=0)return"";const n=Array.from(t);let o="";for(let t=0;t<r;t+=1)o+=n[t%n.length];return o}export function pad(r,n,o){const e=r||"",f=o?.char??" ",a=Array.from(e).length;if(a>=n||!f)return e;const c=n-a,i=o?.position??"both";let l=Math.floor(c/2);return"start"===i?l=c:"end"===i&&(l=0),t(f,l)+e+t(f,c-l)}
@@ -1,2 +1,2 @@
1
- import type { PositiveNumber } from '../_types/global';
1
+ import type { PositiveNumber } from '../_types/global.js';
2
2
  export declare function strBlindRandom<N extends number>(str: string, blindLength: PositiveNumber<N>, blindStr?: string): string;
@@ -1,2 +1,2 @@
1
- import type { PositiveNumber } from '../_types/global';
1
+ import type { PositiveNumber } from '../_types/global.js';
2
2
  export declare function strRandom<N extends number>(length: PositiveNumber<N>, additionalCharacters?: string): string;
@@ -0,0 +1 @@
1
+ export declare function strToCamelCase(str: string): string;
@@ -0,0 +1 @@
1
+ import{capitalizeWord as o}from"./_capitalizeWord.js";import{words as r}from"./words.js";export function strToCamelCase(t){return t?r(t).map((r,t)=>0===t?r.toLowerCase():o(r)).join(""):""}
@@ -0,0 +1 @@
1
+ export declare function strToConstantCase(str: string): string;
@@ -0,0 +1 @@
1
+ import{words as o}from"./words.js";export function strToConstantCase(r){return r?o(r).map(o=>o.toUpperCase()).join("_"):""}
@@ -0,0 +1 @@
1
+ export declare function strToKebabCase(str: string): string;
@@ -0,0 +1 @@
1
+ import{words as o}from"./words.js";export function strToKebabCase(r){return r?o(r).map(o=>o.toLowerCase()).join("-"):""}
@@ -0,0 +1 @@
1
+ export declare function strToPascalCase(str: string): string;
@@ -0,0 +1 @@
1
+ import{capitalizeWord as o}from"./_capitalizeWord.js";import{words as r}from"./words.js";export function strToPascalCase(t){return t?r(t).map(o).join(""):""}
@@ -0,0 +1 @@
1
+ export declare function strToSnakeCase(str: string): string;
@@ -0,0 +1 @@
1
+ import{words as o}from"./words.js";export function strToSnakeCase(r){return r?o(r).map(o=>o.toLowerCase()).join("_"):""}
@@ -1,2 +1,2 @@
1
- import type { PositiveNumber } from '../_types/global';
1
+ import type { PositiveNumber } from '../_types/global.js';
2
2
  export declare function truncate<N extends number>(str: string, length: PositiveNumber<N>, ellipsis?: string): string;
@@ -1 +1 @@
1
- export function truncate(t,n,r=""){if(!t)return"";let e=t;return t.length>n&&(e=t.substring(0,n)+r),e}
1
+ export function truncate(r,n,t=""){if(!r)return"";const e=Array.from(r);return e.length<=n?r:e.slice(0,n).join("")+t}
@@ -1,2 +1,2 @@
1
- import type { PositiveNumber } from '../_types/global';
2
- export declare function truncateExpect<N extends number>(str: string, expectLength: PositiveNumber<N>, endStringChar?: string): string;
1
+ import type { PositiveNumber } from '../_types/global.js';
2
+ export declare function truncateExpect<N extends number>(str: string, expectLength: PositiveNumber<N>, endStringChar?: string | string[]): string;
@@ -1 +1 @@
1
- export function truncateExpect(t,e,n="."){if(!t)return"";if(t.length<=e)return t;const r=t.slice(-1)===n,l=t.split(n),c=l.length;let i="",u=0;for(let t=0;t<c&&u<e;t+=1)i+=`${l[t]}${t!==c-1||r?n:""}`,u+=l[t].length+n.length;return i}
1
+ const r=[".","。",".","。"];function t(r,t,n){if(n+t.length>r.length)return!1;for(let e=0;e<t.length;e+=1)if(r[n+e]!==t[e])return!1;return!0}export function truncateExpect(n,e,f=r){if(!n)return"";const i=Array.from(n),l=i.length;if(l<=e)return n;const o=(Array.isArray(f)?f:[f]).filter(r=>r.length>0).map(r=>Array.from(r)).sort((r,t)=>t.length-r.length);if(0===o.length)return n;let u=0;for(;u<l;){const r=o.find(r=>t(i,r,u));if(r){if(u+=r.length,u>=e)return i.slice(0,u).join("")}else u+=1}return n}
@@ -1 +1 @@
1
- const o="ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ",t="ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ",n=" ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅅㅆㅇㅈㅊㅋㅌㅍㅎ",e={"ㅗㅏ":"ㅘ","ㅗㅐ":"ㅙ","ㅗㅣ":"ㅚ","ㅜㅓ":"ㅝ","ㅜㅔ":"ㅞ","ㅜㅣ":"ㅟ","ㅡㅣ":"ㅢ"},r={"ㄱㅅ":"ㄳ","ㄴㅈ":"ㄵ","ㄴㅎ":"ㄶ","ㄹㄱ":"ㄺ","ㄹㅁ":"ㄻ","ㄹㅂ":"ㄼ","ㄹㅅ":"ㄽ","ㄹㅌ":"ㄾ","ㄹㅍ":"ㄿ","ㄹㅎ":"ㅀ","ㅂㅅ":"ㅄ"},s={r:"ㅏ",i:"ㅣ"},f=o=>{const t={};for(const n of o)for(const o of n.slice(1))t[o]=n[0];return t},i=[9398,119808,119860,119912,120224,120276,120328,120380,120432],c=o=>{for(const t of i)if(o>=t&&o<=t+51)return String.fromCharCode(97+(o-t)%26)},l=f(["a4àáâãäåāăąаα","b8вβ","cçćčс","dďđ","e3èéêëēĕėęěеёε","g69ğ","hн","i1lìíîïīįıłіι","jј","kкκ","mм","nñńň","o0òóôõöøōőоο","pрρ","s5śšşѕ","t7ţťтτ","uùúûüūůűų","xхχ","yýÿу","z2źżž"]),u=f(["a@","c¢(","e€£","i!|¡/","s$§","t+","o°"]),h=/[\p{L}\p{N}]/u,d=o=>void 0!==o&&(t.includes(o)||void 0!==s[o]),p=(f,i,p)=>{const g=[],a=[];for(const e of f.toLowerCase()){let r=e;const s=r.codePointAt(0);s>=65281&&s<=65374?r=String.fromCharCode(s-65248).toLowerCase():s>=4352&&s<=4370?r=o[s-4352]:s>=4449&&s<=4469?r=t[s-4449]:s>=4520&&s<=4546?r=n[s-4519]:s>=9398&&(r=c(s)??r);const f=r>="0"&&r<="9";void 0!==l[r]?(g.push(l[r]),a.push(f)):h.test(r)?(g.push(r),a.push(f)):i&&void 0!==u[r]&&(g.push(u[r]),a.push(!1))}const x=p?((o,t)=>{const n=[],e=o.length;let r=0;for(;r<e;){if(!t[r]){n.push(o[r]),r+=1;continue}let s=r;for(;s<e&&t[s];)s+=1;if(0===r||s===e)for(let t=r;t<s;t+=1)n.push(o[t]);r=s}return n})(g,a):g;for(let o=1,t=x.length;o<t;o+=1)"ㅇ"===x[o]&&x[o-1]>="a"&&x[o-1]<="z"&&(x[o]="o");return(f=>{const i=[],c=f.length;let l=0;for(;l<c;){const u=o.indexOf(f[l]);let h=l+1,p=h<c?t.indexOf(s[f[h]]??f[h]):-1;if(-1===u||-1===p){i.push(f[l]),l+=1;continue}h+=1;const g=h<c?e[t[p]+f[h]]:void 0;void 0!==g&&(p=t.indexOf(g),h+=1);let a=h<c&&!d(f[h+1])?Math.max(n.indexOf(f[h]),0):0;if(a>0){h+=1;const o=h<c?r[n[a]+f[h]]:void 0;void 0===o||d(f[h+1])||(a=n.indexOf(o),h+=1)}i.push(String.fromCharCode(44032+28*(21*u+p)+a)),l=h}return i.join("")})(x).replace(/ㅇ/g,"o")},g=(o,t,n,e)=>{for(let r=0,s=n.length;r<s;r+=1)if(o>=n[r]&&o<e[r])return o===n[r]||o+t<=e[r];return!1},a=[[!0,!1],[!1,!1],[!0,!0],[!1,!0]],x=o=>{const t=[];for(const n of o){if("string"!=typeof n)continue;const o=p(n,!0,!1);o&&t.push(o)}return t};export function hasBadWords(o,t=[],n=[]){if(!o||!t||0===t.length)return!1;const e=x(t);if(0===e.length)return!1;const r=n?x(n):[],s=o.split(/\s+/).filter(o=>""!==o);for(const[o,t]of a){const n=[],f=[];let i="";for(const e of s){const r=p(e,o,t);r&&(n.push(i.length),i+=r,f.push(i.length))}for(const o of r){let t=i.indexOf(o);for(;-1!==t;)i=i.slice(0,t)+"\0".repeat(o.length)+i.slice(t+o.length),t=i.indexOf(o,t+o.length)}for(const o of e){let t=i.indexOf(o);for(;-1!==t;){if(g(t,o.length,n,f))return!0;t=i.indexOf(o,t+1)}}}return!1}
1
+ const t="ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ",o="ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ",n=" ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅅㅆㅇㅈㅊㅋㅌㅍㅎ",e={"ㅗㅏ":"ㅘ","ㅗㅐ":"ㅙ","ㅗㅣ":"ㅚ","ㅜㅓ":"ㅝ","ㅜㅔ":"ㅞ","ㅜㅣ":"ㅟ","ㅡㅣ":"ㅢ"},r={"ㄱㅅ":"ㄳ","ㄴㅈ":"ㄵ","ㄴㅎ":"ㄶ","ㄹㄱ":"ㄺ","ㄹㅁ":"ㄻ","ㄹㅂ":"ㄼ","ㄹㅅ":"ㄽ","ㄹㅌ":"ㄾ","ㄹㅍ":"ㄿ","ㄹㅎ":"ㅀ","ㅂㅅ":"ㅄ"},s={r:"ㅏ",i:"ㅣ"},f=["a4àáâãäåāăąаα","b8вβ","cçćčс","dďđ","e3èéêëēĕėęěеёε","g69ğ","hн","i1lìíîïīįıłіι","jј","kкκ","mм","nñńň","o0òóôõöøōőоο","pрρ","s5śšşѕ","t7ţťтτ","uùúûüūůűų","xхχ","yýÿу","z2źżž"],i=["a@","c¢(","e€£","i!|¡/","s$§","t+","o°"],c=t=>{const o={};for(const n of t)for(const t of n.slice(1))o[t]=n[0];return o},l=[9398,119808,119860,119912,120224,120276,120328,120380,120432],u=t=>{for(const o of l)if(t>=o&&t<=o+51)return String.fromCharCode(97+(t-o)%26)};let h,d;const p=/[\p{L}\p{N}]/u,g=t=>void 0!==t&&(o.includes(t)||void 0!==s[t]),a=(l,a,x)=>{const O=h??=c(f),v=d??=c(i),C=[],m=[];for(const e of l.toLowerCase()){let r=e;const s=r.codePointAt(0);s>=65281&&s<=65374?r=String.fromCharCode(s-65248).toLowerCase():s>=4352&&s<=4370?r=t[s-4352]:s>=4449&&s<=4469?r=o[s-4449]:s>=4520&&s<=4546?r=n[s-4519]:s>=9398&&(r=u(s)??r);const f=r>="0"&&r<="9";void 0!==O[r]?(C.push(O[r]),m.push(f)):p.test(r)?(C.push(r),m.push(f)):a&&void 0!==v[r]&&(C.push(v[r]),m.push(!1))}const L=x?((t,o)=>{const n=[],e=t.length;let r=0;for(;r<e;){if(!o[r]){n.push(t[r]),r+=1;continue}let s=r;for(;s<e&&o[s];)s+=1;if(0===r||s===e)for(let o=r;o<s;o+=1)n.push(t[o]);r=s}return n})(C,m):C;for(let t=1,o=L.length;t<o;t+=1)"ㅇ"===L[t]&&L[t-1]>="a"&&L[t-1]<="z"&&(L[t]="o");return(f=>{const i=[],c=f.length;let l=0;for(;l<c;){const u=t.indexOf(f[l]);let h=l+1,d=h<c?o.indexOf(s[f[h]]??f[h]):-1;if(-1===u||-1===d){i.push(f[l]),l+=1;continue}h+=1;const p=h<c?e[o[d]+f[h]]:void 0;void 0!==p&&(d=o.indexOf(p),h+=1);let a=h<c&&!g(f[h+1])?Math.max(n.indexOf(f[h]),0):0;if(a>0){h+=1;const t=h<c?r[n[a]+f[h]]:void 0;void 0===t||g(f[h+1])||(a=n.indexOf(t),h+=1)}i.push(String.fromCharCode(44032+28*(21*u+d)+a)),l=h}return i.join("")})(L).replace(/ㅇ/g,"o")},x=(t,o,n,e)=>{for(let r=0,s=n.length;r<s;r+=1)if(t>=n[r]&&t<e[r])return t===n[r]||t+o<=e[r];return!1},O=[[!0,!1],[!1,!1],[!0,!0],[!1,!0]],v=t=>{const o=[];for(const n of t){if("string"!=typeof n)continue;const t=a(n,!0,!1);t&&o.push(t)}return o};export function hasBadWords(t,o=[],n=[]){if(!t||!o||0===o.length)return!1;const e=v(o);if(0===e.length)return!1;const r=n?v(n):[],s=t.split(/\s+/).filter(t=>""!==t);for(const[t,o]of O){const n=[],f=[];let i="";for(const e of s){const r=a(e,t,o);r&&(n.push(i.length),i+=r,f.push(i.length))}for(const t of r){let o=i.indexOf(t);for(;-1!==o;)i=i.slice(0,o)+"\0".repeat(t.length)+i.slice(o+t.length),o=i.indexOf(t,o+t.length)}for(const t of e){let o=i.indexOf(t);for(;-1!==o;){if(x(o,t.length,n,f))return!0;o=i.indexOf(t,o+1)}}}return!1}
@@ -0,0 +1 @@
1
+ export declare function escapeHtml(str: string): string;
@@ -0,0 +1 @@
1
+ const t=/[&<>"']/g,e={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};export function escapeHtml(c){return c?c.replace(t,t=>e[t]):""}
@@ -1,2 +1,2 @@
1
- import { LicenseOption } from '../_types/global';
1
+ import type { LicenseOption } from '../_types/global.js';
2
2
  export declare function generateLicense(options: LicenseOption): string;
@@ -1,2 +1,2 @@
1
- import type { ParsedAddress } from '../_types/global';
1
+ import type { ParsedAddress } from '../_types/global.js';
2
2
  export declare function getParsedInfoFromAddress(url: string): ParsedAddress;
@@ -1,2 +1,2 @@
1
- import type { SlugOptions } from '../_types/global';
1
+ import type { SlugOptions } from '../_types/global.js';
2
2
  export declare function getSlug(text: string, options?: SlugOptions): string;
@@ -1,3 +1,4 @@
1
+ export { escapeHtml } from './escapeHtml.js';
1
2
  export { generateLicense } from './generateLicense.js';
2
3
  export { getParsedInfoFromAddress } from './getParsedInfoFromAddress.js';
3
4
  export { getSlug } from './getSlug.js';
@@ -5,3 +6,4 @@ export { isBotAgent } from './isBotAgent.js';
5
6
  export { isMatchPathname } from './isMatchPathname.js';
6
7
  export { isMobile } from './isMobile.js';
7
8
  export { removeLocalePrefix } from './removeLocalePrefix.js';
9
+ export { unescapeHtml } from './unescapeHtml.js';
package/dist/web/index.js CHANGED
@@ -1 +1 @@
1
- export{generateLicense}from"./generateLicense.js";export{getParsedInfoFromAddress}from"./getParsedInfoFromAddress.js";export{getSlug}from"./getSlug.js";export{isBotAgent}from"./isBotAgent.js";export{isMatchPathname}from"./isMatchPathname.js";export{isMobile}from"./isMobile.js";export{removeLocalePrefix}from"./removeLocalePrefix.js";
1
+ export{escapeHtml}from"./escapeHtml.js";export{generateLicense}from"./generateLicense.js";export{getParsedInfoFromAddress}from"./getParsedInfoFromAddress.js";export{getSlug}from"./getSlug.js";export{isBotAgent}from"./isBotAgent.js";export{isMatchPathname}from"./isMatchPathname.js";export{isMobile}from"./isMobile.js";export{removeLocalePrefix}from"./removeLocalePrefix.js";export{unescapeHtml}from"./unescapeHtml.js";
@@ -0,0 +1 @@
1
+ export declare function unescapeHtml(str: string): string;
@@ -0,0 +1 @@
1
+ const t=/&(?:amp|lt|gt|quot|#39);/g,e={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'"};export function unescapeHtml(n){return n?n.replace(t,t=>e[t]):""}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "qsu",
3
- "version": "1.16.0",
4
- "description": "qsu is a utility library that contains useful and frequently used functions. Start with your preferred language and the modern development environment.",
3
+ "version": "1.18.0",
4
+ "description": "Everyday helpers you would otherwise write yourself: slugs, text case, date math, number and file size formatting, deep clone and merge, email and URL validation, debounce, throttle and hashing. No dependencies.",
5
5
  "author": "CDGet <jooy2.contact@gmail.com>",
6
6
  "license": "MIT",
7
7
  "homepage": "https://qsu.cdget.com",
@@ -13,6 +13,7 @@
13
13
  "url": "https://github.com/jooy2/qsu/issues"
14
14
  },
15
15
  "type": "module",
16
+ "sideEffects": false,
16
17
  "types": "dist/index.d.ts",
17
18
  "scripts": {
18
19
  "build": "tsc --project tsconfig.prod.json && npm run minify",
@@ -21,8 +22,7 @@
21
22
  "lint:fix": "eslint . --ext .js,.ts --fix .",
22
23
  "minify": "terser-glob 'dist/**/*.js' --config-file terser.config.json",
23
24
  "prepare": "npm run build",
24
- "format": "prettier .",
25
- "format:fix": "prettier . --write"
25
+ "format": "prettier . --write"
26
26
  },
27
27
  "engines": {
28
28
  "node": ">=18.0.0"
@@ -35,15 +35,86 @@
35
35
  "default": "./dist/index.js"
36
36
  },
37
37
  "./types": {
38
- "types": "./dist/types/global.d.ts",
39
- "module": "./dist/types/global.js",
40
- "default": "./dist/types/global.js"
38
+ "types": "./dist/_types/global.d.ts",
39
+ "module": "./dist/_types/global.js",
40
+ "default": "./dist/_types/global.js"
41
+ },
42
+ "./array": {
43
+ "types": "./dist/array/index.d.ts",
44
+ "module": "./dist/array/index.js",
45
+ "default": "./dist/array/index.js"
46
+ },
47
+ "./date": {
48
+ "types": "./dist/date/index.d.ts",
49
+ "module": "./dist/date/index.js",
50
+ "default": "./dist/date/index.js"
51
+ },
52
+ "./format": {
53
+ "types": "./dist/format/index.d.ts",
54
+ "module": "./dist/format/index.js",
55
+ "default": "./dist/format/index.js"
56
+ },
57
+ "./math": {
58
+ "types": "./dist/math/index.d.ts",
59
+ "module": "./dist/math/index.js",
60
+ "default": "./dist/math/index.js"
61
+ },
62
+ "./misc": {
63
+ "types": "./dist/misc/index.d.ts",
64
+ "module": "./dist/misc/index.js",
65
+ "default": "./dist/misc/index.js"
66
+ },
67
+ "./object": {
68
+ "types": "./dist/object/index.d.ts",
69
+ "module": "./dist/object/index.js",
70
+ "default": "./dist/object/index.js"
71
+ },
72
+ "./string": {
73
+ "types": "./dist/string/index.d.ts",
74
+ "module": "./dist/string/index.js",
75
+ "default": "./dist/string/index.js"
76
+ },
77
+ "./verify": {
78
+ "types": "./dist/verify/index.d.ts",
79
+ "module": "./dist/verify/index.js",
80
+ "default": "./dist/verify/index.js"
81
+ },
82
+ "./web": {
83
+ "types": "./dist/web/index.d.ts",
84
+ "module": "./dist/web/index.js",
85
+ "default": "./dist/web/index.js"
41
86
  },
42
87
  "./node": {
43
88
  "types": "./dist/node/index.d.ts",
44
89
  "module": "./dist/node/index.js",
45
90
  "default": "./dist/node/index.js"
46
- }
91
+ },
92
+ "./node/crypto": {
93
+ "types": "./dist/node/crypto/index.d.ts",
94
+ "module": "./dist/node/crypto/index.js",
95
+ "default": "./dist/node/crypto/index.js"
96
+ },
97
+ "./node/file": {
98
+ "types": "./dist/node/file/index.d.ts",
99
+ "module": "./dist/node/file/index.js",
100
+ "default": "./dist/node/file/index.js"
101
+ },
102
+ "./node/misc": {
103
+ "types": "./dist/node/misc/index.d.ts",
104
+ "module": "./dist/node/misc/index.js",
105
+ "default": "./dist/node/misc/index.js"
106
+ },
107
+ "./node/net": {
108
+ "types": "./dist/node/net/index.d.ts",
109
+ "module": "./dist/node/net/index.js",
110
+ "default": "./dist/node/net/index.js"
111
+ },
112
+ "./node/os": {
113
+ "types": "./dist/node/os/index.d.ts",
114
+ "module": "./dist/node/os/index.js",
115
+ "default": "./dist/node/os/index.js"
116
+ },
117
+ "./package.json": "./package.json"
47
118
  },
48
119
  "typesVersions": {
49
120
  "*": {
@@ -55,36 +126,48 @@
55
126
  "keywords": [
56
127
  "util",
57
128
  "utility",
58
- "tool",
129
+ "utils",
59
130
  "toolkit",
60
- "underscore",
61
- "web",
62
131
  "helper",
132
+ "lodash",
133
+ "underscore",
134
+ "typescript",
135
+ "esm",
136
+ "tree-shaking",
137
+ "zero-dependency",
63
138
  "array",
139
+ "object",
64
140
  "string",
65
141
  "date",
66
142
  "math",
143
+ "format",
144
+ "validation",
67
145
  "verify",
146
+ "crypto",
147
+ "hash",
68
148
  "encrypt",
69
149
  "decrypt",
70
- "format",
71
- "crypto",
72
- "file"
150
+ "base64",
151
+ "file",
152
+ "web",
153
+ "slug",
154
+ "debounce",
155
+ "throttle"
73
156
  ],
74
157
  "devDependencies": {
75
158
  "@eslint/js": "^9.39.2",
76
- "@types/node": "^26.1.2",
77
- "@typescript-eslint/parser": "^8.66.0",
78
- "dayjs": "^1.11.21",
159
+ "@types/node": "^26.4.0",
160
+ "@typescript-eslint/parser": "^8.68.0",
161
+ "dayjs": "^1.11.23",
79
162
  "eslint": "^9.39.2",
80
163
  "eslint-config-prettier": "^10.1.8",
81
- "eslint-plugin-n": "^18.2.2",
82
- "globals": "^17.9.0",
164
+ "eslint-plugin-n": "^18.3.0",
165
+ "globals": "^17.11.0",
83
166
  "jiti": "^2.7.0",
84
167
  "prettier": "^3.9.6",
85
168
  "terser-glob": "^1.2.1",
86
- "tsx": "^4.23.5",
169
+ "tsx": "^4.23.12",
87
170
  "typescript": "6.0.3",
88
- "typescript-eslint": "^8.66.0"
171
+ "typescript-eslint": "^8.68.0"
89
172
  }
90
173
  }