@hairy/utils 1.29.0 → 1.31.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.
package/dist/index.cjs CHANGED
@@ -49,7 +49,10 @@ __export(index_exports, {
49
49
  debounce: () => debounce_default,
50
50
  decimal: () => decimal,
51
51
  delay: () => delay,
52
+ dialsPhone: () => dialsPhone,
52
53
  dotCase: () => dotCase,
54
+ downloadBlobFile: () => downloadBlobFile,
55
+ downloadNetworkFile: () => downloadNetworkFile,
53
56
  find: () => find_default,
54
57
  formToObject: () => formToObject,
55
58
  formatNumeric: () => formatNumeric,
@@ -104,6 +107,8 @@ __export(index_exports, {
104
107
  noop: () => noop2,
105
108
  numerfix: () => numerfix,
106
109
  objectToForm: () => objectToForm,
110
+ off: () => off,
111
+ on: () => on,
107
112
  parseNumeric: () => parseNumeric,
108
113
  pascalCase: () => pascalCase,
109
114
  pascalSnakeCase: () => pascalSnakeCase,
@@ -111,10 +116,16 @@ __export(index_exports, {
111
116
  percentage: () => percentage,
112
117
  pipe: () => pipe,
113
118
  plus: () => plus,
119
+ proxy: () => proxy,
114
120
  randomArray: () => randomArray,
115
121
  randomNumer: () => randomNumer,
122
+ readFileReader: () => readFileReader,
123
+ redirectTo: () => redirectTo,
116
124
  riposte: () => riposte,
125
+ selectImages: () => selectImages,
117
126
  sentenceCase: () => sentenceCase,
127
+ showOpenFilePicker: () => showOpenFilePicker,
128
+ showOpenImagePicker: () => showOpenImagePicker,
118
129
  snakeCase: () => snakeCase,
119
130
  to: () => to,
120
131
  trainCase: () => trainCase,
@@ -130,6 +141,81 @@ __export(index_exports, {
130
141
  });
131
142
  module.exports = __toCommonJS(index_exports);
132
143
 
144
+ // src/browser/file.ts
145
+ function showOpenFilePicker(option = {}) {
146
+ const { multiple = true, accept } = option;
147
+ return new Promise((resolve, reject) => {
148
+ const inputElement = document.createElement("input");
149
+ inputElement.type = "file";
150
+ inputElement.multiple = multiple;
151
+ accept && (inputElement.accept = accept);
152
+ inputElement.click();
153
+ const timer = setTimeout(reject, 20 * 1e3);
154
+ inputElement.addEventListener("change", (event) => {
155
+ const files = event.target.files;
156
+ if (files) {
157
+ resolve(Object.values(files));
158
+ clearTimeout(timer);
159
+ }
160
+ });
161
+ });
162
+ }
163
+ function showOpenImagePicker(options = {}) {
164
+ const { multiple = true } = options;
165
+ return showOpenFilePicker({ multiple, accept: "image/jpeg,image/x-png,image/gif" });
166
+ }
167
+ var selectImages = showOpenImagePicker;
168
+ function downloadBlobFile(data, name) {
169
+ const blob = new Blob([data]);
170
+ const link = document.createElement("a");
171
+ const url = window.URL.createObjectURL(blob);
172
+ link.href = url;
173
+ link.download = name;
174
+ link.click();
175
+ }
176
+ function downloadNetworkFile(url, name) {
177
+ const a = document.createElement("a");
178
+ name && (a.download = name);
179
+ a.href = url;
180
+ a.click();
181
+ }
182
+ function readFileReader(formType, file) {
183
+ return new Promise((resolve, reject) => {
184
+ if (typeof FileReader === "undefined") {
185
+ console.warn("\u5F53\u524D\u73AF\u5883\u4E0D\u652F\u6301\u4F7F\u7528 FileReader Api");
186
+ reject();
187
+ }
188
+ const reader = new FileReader();
189
+ reader[formType](file);
190
+ reader.onloadend = function() {
191
+ isNull(this.result) ? reject() : resolve(this.result);
192
+ };
193
+ });
194
+ }
195
+
196
+ // src/browser/util.ts
197
+ function redirectTo(url, target = "_blank") {
198
+ const link = document.createElement("a");
199
+ link.href = url;
200
+ link.target = target;
201
+ link.click();
202
+ link.remove();
203
+ }
204
+ function dialsPhone(phoneNumber) {
205
+ const aTag = document.createElement("a");
206
+ aTag.setAttribute("href", `tel:${phoneNumber}`);
207
+ aTag.setAttribute("target", "_blank");
208
+ aTag.click();
209
+ }
210
+ function on(obj, ...args) {
211
+ if (obj && obj.addEventListener)
212
+ obj.addEventListener(...args);
213
+ }
214
+ function off(obj, ...args) {
215
+ if (obj && obj.removeEventListener)
216
+ obj.removeEventListener(...args);
217
+ }
218
+
133
219
  // ../../node_modules/.pnpm/change-case@5.4.4/node_modules/change-case/dist/index.js
134
220
  var SPLIT_LOWER_UPPER_RE = /([\p{Ll}\d])(\p{Lu})/gu;
135
221
  var SPLIT_UPPER_UPPER_RE = /(\p{Lu})([\p{Lu}][\p{Ll}])/gu;
@@ -2807,10 +2893,10 @@ function isNative(value) {
2807
2893
  var isNative_default = isNative;
2808
2894
 
2809
2895
  // ../../node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/isNull.js
2810
- function isNull(value) {
2896
+ function isNull2(value) {
2811
2897
  return value === null;
2812
2898
  }
2813
- var isNull_default = isNull;
2899
+ var isNull_default = isNull2;
2814
2900
 
2815
2901
  // ../../node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_baseIsRegExp.js
2816
2902
  var regexpTag5 = "[object RegExp]";
@@ -3278,6 +3364,36 @@ function pipe(...fns) {
3278
3364
  }
3279
3365
  pipe.promise = pPipe;
3280
3366
 
3367
+ // src/util/proxy.ts
3368
+ function proxy(initObject) {
3369
+ initObject && Reflect.set(initObject, "proxyUpdated", true);
3370
+ let target = initObject || { proxyUpdated: false };
3371
+ const proxy2 = new Proxy({}, {
3372
+ get: (_, p) => {
3373
+ return typeof target?.[p] === "function" ? target?.[p].bind(target) : target?.[p];
3374
+ },
3375
+ set: (_, p, v) => {
3376
+ target[p] = v;
3377
+ return true;
3378
+ }
3379
+ });
3380
+ function update(object) {
3381
+ if (!object) {
3382
+ target = void 0;
3383
+ return;
3384
+ }
3385
+ Reflect.set(object, "proxyUpdated", true);
3386
+ target = object;
3387
+ }
3388
+ return {
3389
+ proxy: proxy2,
3390
+ update
3391
+ };
3392
+ }
3393
+ proxy.resolve = (target) => {
3394
+ return Reflect.get(target, "proxyUpdated") ? target : void 0;
3395
+ };
3396
+
3281
3397
  // src/util/random.ts
3282
3398
  function randomNumer(min, max) {
3283
3399
  return Math.random() * (max - min) + min;
@@ -3339,7 +3455,10 @@ function whenever(value, callback) {
3339
3455
  debounce,
3340
3456
  decimal,
3341
3457
  delay,
3458
+ dialsPhone,
3342
3459
  dotCase,
3460
+ downloadBlobFile,
3461
+ downloadNetworkFile,
3343
3462
  find,
3344
3463
  formToObject,
3345
3464
  formatNumeric,
@@ -3394,6 +3513,8 @@ function whenever(value, callback) {
3394
3513
  noop,
3395
3514
  numerfix,
3396
3515
  objectToForm,
3516
+ off,
3517
+ on,
3397
3518
  parseNumeric,
3398
3519
  pascalCase,
3399
3520
  pascalSnakeCase,
@@ -3401,10 +3522,16 @@ function whenever(value, callback) {
3401
3522
  percentage,
3402
3523
  pipe,
3403
3524
  plus,
3525
+ proxy,
3404
3526
  randomArray,
3405
3527
  randomNumer,
3528
+ readFileReader,
3529
+ redirectTo,
3406
3530
  riposte,
3531
+ selectImages,
3407
3532
  sentenceCase,
3533
+ showOpenFilePicker,
3534
+ showOpenImagePicker,
3408
3535
  snakeCase,
3409
3536
  to,
3410
3537
  trainCase,
package/dist/index.d.ts CHANGED
@@ -2,77 +2,51 @@ export { clone, cloneDeep, cloneDeepWith, cloneWith, concat, debounce, find, isA
2
2
  import Bignumber from 'bignumber.js';
3
3
  export { default as Bignumber } from 'bignumber.js';
4
4
 
5
- /**
6
- * Supported locale values. Use `false` to ignore locale.
7
- * Defaults to `undefined`, which uses the host environment.
8
- */
9
- type Locale = string[] | string | false | undefined;
10
- /**
11
- * Options used for converting strings to pascal/camel case.
12
- */
13
- interface PascalCaseOptions extends Options {
14
- mergeAmbiguousCharacters?: boolean;
5
+ interface OpenFilePickerOptions {
6
+ /**
7
+ * select multiple files
8
+ */
9
+ multiple?: boolean;
10
+ /**
11
+ * Choose the default format for the file
12
+ */
13
+ accept?: string;
15
14
  }
16
15
  /**
17
- * Options used for converting strings to any case.
16
+ * Select multiple files
18
17
  */
19
- interface Options {
20
- locale?: Locale;
21
- split?: (value: string) => string[];
22
- /** @deprecated Pass `split: splitSeparateNumbers` instead. */
23
- separateNumbers?: boolean;
24
- delimiter?: string;
25
- prefixCharacters?: string;
26
- suffixCharacters?: string;
18
+ declare function showOpenFilePicker(option?: OpenFilePickerOptions): Promise<File[]>;
19
+ interface OpenImagePickerOptions {
20
+ /**
21
+ * select multiple images
22
+ */
23
+ multiple?: boolean;
27
24
  }
28
25
  /**
29
- * Convert a string to space separated lower case (`foo bar`).
30
- */
31
- declare function noCase(input: string, options?: Options): string;
32
- /**
33
- * Convert a string to camel case (`fooBar`).
34
- */
35
- declare function camelCase(input: string, options?: PascalCaseOptions): string;
36
- /**
37
- * Convert a string to pascal case (`FooBar`).
38
- */
39
- declare function pascalCase(input: string, options?: PascalCaseOptions): string;
40
- /**
41
- * Convert a string to pascal snake case (`Foo_Bar`).
42
- */
43
- declare function pascalSnakeCase(input: string, options?: Options): string;
44
- /**
45
- * Convert a string to capital case (`Foo Bar`).
46
- */
47
- declare function capitalCase(input: string, options?: Options): string;
48
- /**
49
- * Convert a string to constant case (`FOO_BAR`).
50
- */
51
- declare function constantCase(input: string, options?: Options): string;
52
- /**
53
- * Convert a string to dot case (`foo.bar`).
54
- */
55
- declare function dotCase(input: string, options?: Options): string;
56
- /**
57
- * Convert a string to kebab case (`foo-bar`).
58
- */
59
- declare function kebabCase(input: string, options?: Options): string;
60
- /**
61
- * Convert a string to path case (`foo/bar`).
26
+ * Select multiple images
62
27
  */
63
- declare function pathCase(input: string, options?: Options): string;
28
+ declare function showOpenImagePicker(options?: OpenImagePickerOptions): Promise<File[]>;
29
+ /** @deprecated use chooseFile */
30
+ declare const selectImages: typeof showOpenImagePicker;
64
31
  /**
65
- * Convert a string to path case (`Foo bar`).
32
+ * Generate Blob | string file and download it
33
+ * @param data Blob data, or string
34
+ * @param name file name
66
35
  */
67
- declare function sentenceCase(input: string, options?: Options): string;
36
+ declare function downloadBlobFile(data: Blob | string, name: string): void;
68
37
  /**
69
- * Convert a string to snake case (`foo_bar`).
38
+ * Download network files
39
+ * @param url Download link
40
+ * @param name file name
70
41
  */
71
- declare function snakeCase(input: string, options?: Options): string;
42
+ declare function downloadNetworkFile(url: string, name?: string): void;
43
+ type ReaderType = 'readAsArrayBuffer' | 'readAsBinaryString' | 'readAsDataURL' | 'readAsText';
72
44
  /**
73
- * Convert a string to header case (`Foo-Bar`).
45
+ * Read File file
46
+ * @param formType Transform type
47
+ * @param file file object
74
48
  */
75
- declare function trainCase(input: string, options?: Options): string;
49
+ declare function readFileReader<T extends ReaderType>(formType: T, file: File): Promise<T extends "readAsArrayBuffer" ? ArrayBuffer : string>;
76
50
 
77
51
  type Numeric = string | number | bigint;
78
52
  interface DynamicObject {
@@ -135,6 +109,83 @@ type Option<L extends Key = 'label', V extends Key = 'value', C extends Key = 'c
135
109
  [P in C]?: Option<L, V, C>[];
136
110
  };
137
111
 
112
+ declare function redirectTo(url: string, target?: string): void;
113
+ declare function dialsPhone(phoneNumber: string): void;
114
+ declare function on<T extends Window | Document | HTMLElement | EventTarget>(obj: T | null, ...args: Parameters<T['addEventListener']> | [string, Fn$1 | null, ...any]): void;
115
+ declare function off<T extends Window | Document | HTMLElement | EventTarget>(obj: T | null, ...args: Parameters<T['removeEventListener']> | [string, Fn$1 | null, ...any]): void;
116
+
117
+ /**
118
+ * Supported locale values. Use `false` to ignore locale.
119
+ * Defaults to `undefined`, which uses the host environment.
120
+ */
121
+ type Locale = string[] | string | false | undefined;
122
+ /**
123
+ * Options used for converting strings to pascal/camel case.
124
+ */
125
+ interface PascalCaseOptions extends Options {
126
+ mergeAmbiguousCharacters?: boolean;
127
+ }
128
+ /**
129
+ * Options used for converting strings to any case.
130
+ */
131
+ interface Options {
132
+ locale?: Locale;
133
+ split?: (value: string) => string[];
134
+ /** @deprecated Pass `split: splitSeparateNumbers` instead. */
135
+ separateNumbers?: boolean;
136
+ delimiter?: string;
137
+ prefixCharacters?: string;
138
+ suffixCharacters?: string;
139
+ }
140
+ /**
141
+ * Convert a string to space separated lower case (`foo bar`).
142
+ */
143
+ declare function noCase(input: string, options?: Options): string;
144
+ /**
145
+ * Convert a string to camel case (`fooBar`).
146
+ */
147
+ declare function camelCase(input: string, options?: PascalCaseOptions): string;
148
+ /**
149
+ * Convert a string to pascal case (`FooBar`).
150
+ */
151
+ declare function pascalCase(input: string, options?: PascalCaseOptions): string;
152
+ /**
153
+ * Convert a string to pascal snake case (`Foo_Bar`).
154
+ */
155
+ declare function pascalSnakeCase(input: string, options?: Options): string;
156
+ /**
157
+ * Convert a string to capital case (`Foo Bar`).
158
+ */
159
+ declare function capitalCase(input: string, options?: Options): string;
160
+ /**
161
+ * Convert a string to constant case (`FOO_BAR`).
162
+ */
163
+ declare function constantCase(input: string, options?: Options): string;
164
+ /**
165
+ * Convert a string to dot case (`foo.bar`).
166
+ */
167
+ declare function dotCase(input: string, options?: Options): string;
168
+ /**
169
+ * Convert a string to kebab case (`foo-bar`).
170
+ */
171
+ declare function kebabCase(input: string, options?: Options): string;
172
+ /**
173
+ * Convert a string to path case (`foo/bar`).
174
+ */
175
+ declare function pathCase(input: string, options?: Options): string;
176
+ /**
177
+ * Convert a string to path case (`Foo bar`).
178
+ */
179
+ declare function sentenceCase(input: string, options?: Options): string;
180
+ /**
181
+ * Convert a string to snake case (`foo_bar`).
182
+ */
183
+ declare function snakeCase(input: string, options?: Options): string;
184
+ /**
185
+ * Convert a string to header case (`Foo-Bar`).
186
+ */
187
+ declare function trainCase(input: string, options?: Options): string;
188
+
138
189
  declare const BIG_INTS: {
139
190
  t: {
140
191
  v: number;
@@ -459,6 +510,14 @@ declare namespace pipe {
459
510
  var promise: typeof pPipe;
460
511
  }
461
512
 
513
+ declare function proxy<T extends object>(initObject?: T): {
514
+ proxy: T;
515
+ update: (object?: T) => void;
516
+ };
517
+ declare namespace proxy {
518
+ var resolve: <T extends object>(target: T) => T | undefined;
519
+ }
520
+
462
521
  declare function randomNumer(min: number, max: number): number;
463
522
  declare function randomArray<T>(array: T[]): T;
464
523
 
@@ -469,4 +528,4 @@ declare function riposte<T>(...args: [cond: boolean, value: T][]): T;
469
528
  declare function unwrap<T extends object>(value: T | (() => T)): T;
470
529
  declare function whenever<T, C extends (value: Exclude<T, null | undefined>) => any>(value: T, callback: C): ReturnType<C> | undefined;
471
530
 
472
- export { type AnyFn, type ArgumentsType, type Arrayable, type Awaitable, BIG_INTS, BigNum, type BooleanLike, type ConstructorType, type DecimalOptions, type DeepKeyof, type DeepMerge, type DeepPartial, type DeepReadonly, type DeepReplace, type DeepRequired, Deferred, type Delimiter, type Dimension, type DynamicObject, type ElementOf, type Fn$1 as Fn, type FormatGroupOptions, type FormatNumericOptions, type IfAny, type IsAny, type Key, type Looper, type MergeInsertions, type Noop, type Nullable, type NumberObject, type Numberish, type Numeric, type NumericObject, type Option, type PromiseFn, type PromiseType, type Promisify, type StringObject, type SymbolObject, type Typeof, arange, average, camelCase, capitalCase, compose, constantCase, cover, decimal, delay, dotCase, formToObject, formatNumeric, formatSize, formatUnit, getTypeof, gt, gte, integer, isAndroid, isBrowser, isChrome, isEdge, isFF, isFormData, isIE, isIE11, isIE9, isIOS, isMobile, isPhantomJS, isTruthy, isTypeof, isWeex, isWindow, jsonTryParse, kebabCase, loop, lt, lte, noCase, noop, numerfix, objectToForm, parseNumeric, pascalCase, pascalSnakeCase, pathCase, percentage, pipe, plus, randomArray, randomNumer, riposte, sentenceCase, snakeCase, to, trainCase, unwrap, whenever, zerofill, zeromove };
531
+ export { type AnyFn, type ArgumentsType, type Arrayable, type Awaitable, BIG_INTS, BigNum, type BooleanLike, type ConstructorType, type DecimalOptions, type DeepKeyof, type DeepMerge, type DeepPartial, type DeepReadonly, type DeepReplace, type DeepRequired, Deferred, type Delimiter, type Dimension, type DynamicObject, type ElementOf, type Fn$1 as Fn, type FormatGroupOptions, type FormatNumericOptions, type IfAny, type IsAny, type Key, type Looper, type MergeInsertions, type Noop, type Nullable, type NumberObject, type Numberish, type Numeric, type NumericObject, type OpenFilePickerOptions, type OpenImagePickerOptions, type Option, type PromiseFn, type PromiseType, type Promisify, type ReaderType, type StringObject, type SymbolObject, type Typeof, arange, average, camelCase, capitalCase, compose, constantCase, cover, decimal, delay, dialsPhone, dotCase, downloadBlobFile, downloadNetworkFile, formToObject, formatNumeric, formatSize, formatUnit, getTypeof, gt, gte, integer, isAndroid, isBrowser, isChrome, isEdge, isFF, isFormData, isIE, isIE11, isIE9, isIOS, isMobile, isPhantomJS, isTruthy, isTypeof, isWeex, isWindow, jsonTryParse, kebabCase, loop, lt, lte, noCase, noop, numerfix, objectToForm, off, on, parseNumeric, pascalCase, pascalSnakeCase, pathCase, percentage, pipe, plus, proxy, randomArray, randomNumer, readFileReader, redirectTo, riposte, selectImages, sentenceCase, showOpenFilePicker, showOpenImagePicker, snakeCase, to, trainCase, unwrap, whenever, zerofill, zeromove };
@@ -1,5 +1,80 @@
1
1
  "use strict";
2
2
  (() => {
3
+ // src/browser/file.ts
4
+ function showOpenFilePicker(option = {}) {
5
+ const { multiple = true, accept } = option;
6
+ return new Promise((resolve, reject) => {
7
+ const inputElement = document.createElement("input");
8
+ inputElement.type = "file";
9
+ inputElement.multiple = multiple;
10
+ accept && (inputElement.accept = accept);
11
+ inputElement.click();
12
+ const timer = setTimeout(reject, 20 * 1e3);
13
+ inputElement.addEventListener("change", (event) => {
14
+ const files = event.target.files;
15
+ if (files) {
16
+ resolve(Object.values(files));
17
+ clearTimeout(timer);
18
+ }
19
+ });
20
+ });
21
+ }
22
+ function showOpenImagePicker(options = {}) {
23
+ const { multiple = true } = options;
24
+ return showOpenFilePicker({ multiple, accept: "image/jpeg,image/x-png,image/gif" });
25
+ }
26
+ var selectImages = showOpenImagePicker;
27
+ function downloadBlobFile(data, name) {
28
+ const blob = new Blob([data]);
29
+ const link = document.createElement("a");
30
+ const url = window.URL.createObjectURL(blob);
31
+ link.href = url;
32
+ link.download = name;
33
+ link.click();
34
+ }
35
+ function downloadNetworkFile(url, name) {
36
+ const a = document.createElement("a");
37
+ name && (a.download = name);
38
+ a.href = url;
39
+ a.click();
40
+ }
41
+ function readFileReader(formType, file) {
42
+ return new Promise((resolve, reject) => {
43
+ if (typeof FileReader === "undefined") {
44
+ console.warn("\u5F53\u524D\u73AF\u5883\u4E0D\u652F\u6301\u4F7F\u7528 FileReader Api");
45
+ reject();
46
+ }
47
+ const reader = new FileReader();
48
+ reader[formType](file);
49
+ reader.onloadend = function() {
50
+ isNull(this.result) ? reject() : resolve(this.result);
51
+ };
52
+ });
53
+ }
54
+
55
+ // src/browser/util.ts
56
+ function redirectTo(url, target = "_blank") {
57
+ const link = document.createElement("a");
58
+ link.href = url;
59
+ link.target = target;
60
+ link.click();
61
+ link.remove();
62
+ }
63
+ function dialsPhone(phoneNumber) {
64
+ const aTag = document.createElement("a");
65
+ aTag.setAttribute("href", `tel:${phoneNumber}`);
66
+ aTag.setAttribute("target", "_blank");
67
+ aTag.click();
68
+ }
69
+ function on(obj, ...args) {
70
+ if (obj && obj.addEventListener)
71
+ obj.addEventListener(...args);
72
+ }
73
+ function off(obj, ...args) {
74
+ if (obj && obj.removeEventListener)
75
+ obj.removeEventListener(...args);
76
+ }
77
+
3
78
  // ../../node_modules/.pnpm/change-case@5.4.4/node_modules/change-case/dist/index.js
4
79
  var SPLIT_LOWER_UPPER_RE = /([\p{Ll}\d])(\p{Lu})/gu;
5
80
  var SPLIT_UPPER_UPPER_RE = /(\p{Lu})([\p{Lu}][\p{Ll}])/gu;
@@ -2677,10 +2752,10 @@
2677
2752
  var isNative_default = isNative;
2678
2753
 
2679
2754
  // ../../node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/isNull.js
2680
- function isNull(value) {
2755
+ function isNull2(value) {
2681
2756
  return value === null;
2682
2757
  }
2683
- var isNull_default = isNull;
2758
+ var isNull_default = isNull2;
2684
2759
 
2685
2760
  // ../../node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_baseIsRegExp.js
2686
2761
  var regexpTag5 = "[object RegExp]";
@@ -4491,6 +4566,36 @@
4491
4566
  }
4492
4567
  pipe.promise = pPipe;
4493
4568
 
4569
+ // src/util/proxy.ts
4570
+ function proxy(initObject) {
4571
+ initObject && Reflect.set(initObject, "proxyUpdated", true);
4572
+ let target = initObject || { proxyUpdated: false };
4573
+ const proxy2 = new Proxy({}, {
4574
+ get: (_, p) => {
4575
+ return typeof target?.[p] === "function" ? target?.[p].bind(target) : target?.[p];
4576
+ },
4577
+ set: (_, p, v) => {
4578
+ target[p] = v;
4579
+ return true;
4580
+ }
4581
+ });
4582
+ function update(object) {
4583
+ if (!object) {
4584
+ target = void 0;
4585
+ return;
4586
+ }
4587
+ Reflect.set(object, "proxyUpdated", true);
4588
+ target = object;
4589
+ }
4590
+ return {
4591
+ proxy: proxy2,
4592
+ update
4593
+ };
4594
+ }
4595
+ proxy.resolve = (target) => {
4596
+ return Reflect.get(target, "proxyUpdated") ? target : void 0;
4597
+ };
4598
+
4494
4599
  // src/util/random.ts
4495
4600
  function randomNumer(min, max) {
4496
4601
  return Math.random() * (max - min) + min;
package/dist/index.js CHANGED
@@ -1,3 +1,78 @@
1
+ // src/browser/file.ts
2
+ function showOpenFilePicker(option = {}) {
3
+ const { multiple = true, accept } = option;
4
+ return new Promise((resolve, reject) => {
5
+ const inputElement = document.createElement("input");
6
+ inputElement.type = "file";
7
+ inputElement.multiple = multiple;
8
+ accept && (inputElement.accept = accept);
9
+ inputElement.click();
10
+ const timer = setTimeout(reject, 20 * 1e3);
11
+ inputElement.addEventListener("change", (event) => {
12
+ const files = event.target.files;
13
+ if (files) {
14
+ resolve(Object.values(files));
15
+ clearTimeout(timer);
16
+ }
17
+ });
18
+ });
19
+ }
20
+ function showOpenImagePicker(options = {}) {
21
+ const { multiple = true } = options;
22
+ return showOpenFilePicker({ multiple, accept: "image/jpeg,image/x-png,image/gif" });
23
+ }
24
+ var selectImages = showOpenImagePicker;
25
+ function downloadBlobFile(data, name) {
26
+ const blob = new Blob([data]);
27
+ const link = document.createElement("a");
28
+ const url = window.URL.createObjectURL(blob);
29
+ link.href = url;
30
+ link.download = name;
31
+ link.click();
32
+ }
33
+ function downloadNetworkFile(url, name) {
34
+ const a = document.createElement("a");
35
+ name && (a.download = name);
36
+ a.href = url;
37
+ a.click();
38
+ }
39
+ function readFileReader(formType, file) {
40
+ return new Promise((resolve, reject) => {
41
+ if (typeof FileReader === "undefined") {
42
+ console.warn("\u5F53\u524D\u73AF\u5883\u4E0D\u652F\u6301\u4F7F\u7528 FileReader Api");
43
+ reject();
44
+ }
45
+ const reader = new FileReader();
46
+ reader[formType](file);
47
+ reader.onloadend = function() {
48
+ isNull(this.result) ? reject() : resolve(this.result);
49
+ };
50
+ });
51
+ }
52
+
53
+ // src/browser/util.ts
54
+ function redirectTo(url, target = "_blank") {
55
+ const link = document.createElement("a");
56
+ link.href = url;
57
+ link.target = target;
58
+ link.click();
59
+ link.remove();
60
+ }
61
+ function dialsPhone(phoneNumber) {
62
+ const aTag = document.createElement("a");
63
+ aTag.setAttribute("href", `tel:${phoneNumber}`);
64
+ aTag.setAttribute("target", "_blank");
65
+ aTag.click();
66
+ }
67
+ function on(obj, ...args) {
68
+ if (obj && obj.addEventListener)
69
+ obj.addEventListener(...args);
70
+ }
71
+ function off(obj, ...args) {
72
+ if (obj && obj.removeEventListener)
73
+ obj.removeEventListener(...args);
74
+ }
75
+
1
76
  // ../../node_modules/.pnpm/change-case@5.4.4/node_modules/change-case/dist/index.js
2
77
  var SPLIT_LOWER_UPPER_RE = /([\p{Ll}\d])(\p{Lu})/gu;
3
78
  var SPLIT_UPPER_UPPER_RE = /(\p{Lu})([\p{Lu}][\p{Ll}])/gu;
@@ -2675,10 +2750,10 @@ function isNative(value) {
2675
2750
  var isNative_default = isNative;
2676
2751
 
2677
2752
  // ../../node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/isNull.js
2678
- function isNull(value) {
2753
+ function isNull2(value) {
2679
2754
  return value === null;
2680
2755
  }
2681
- var isNull_default = isNull;
2756
+ var isNull_default = isNull2;
2682
2757
 
2683
2758
  // ../../node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_baseIsRegExp.js
2684
2759
  var regexpTag5 = "[object RegExp]";
@@ -3146,6 +3221,36 @@ function pipe(...fns) {
3146
3221
  }
3147
3222
  pipe.promise = pPipe;
3148
3223
 
3224
+ // src/util/proxy.ts
3225
+ function proxy(initObject) {
3226
+ initObject && Reflect.set(initObject, "proxyUpdated", true);
3227
+ let target = initObject || { proxyUpdated: false };
3228
+ const proxy2 = new Proxy({}, {
3229
+ get: (_, p) => {
3230
+ return typeof target?.[p] === "function" ? target?.[p].bind(target) : target?.[p];
3231
+ },
3232
+ set: (_, p, v) => {
3233
+ target[p] = v;
3234
+ return true;
3235
+ }
3236
+ });
3237
+ function update(object) {
3238
+ if (!object) {
3239
+ target = void 0;
3240
+ return;
3241
+ }
3242
+ Reflect.set(object, "proxyUpdated", true);
3243
+ target = object;
3244
+ }
3245
+ return {
3246
+ proxy: proxy2,
3247
+ update
3248
+ };
3249
+ }
3250
+ proxy.resolve = (target) => {
3251
+ return Reflect.get(target, "proxyUpdated") ? target : void 0;
3252
+ };
3253
+
3149
3254
  // src/util/random.ts
3150
3255
  function randomNumer(min, max) {
3151
3256
  return Math.random() * (max - min) + min;
@@ -3206,7 +3311,10 @@ export {
3206
3311
  debounce_default as debounce,
3207
3312
  decimal,
3208
3313
  delay,
3314
+ dialsPhone,
3209
3315
  dotCase,
3316
+ downloadBlobFile,
3317
+ downloadNetworkFile,
3210
3318
  find_default as find,
3211
3319
  formToObject,
3212
3320
  formatNumeric,
@@ -3261,6 +3369,8 @@ export {
3261
3369
  noop2 as noop,
3262
3370
  numerfix,
3263
3371
  objectToForm,
3372
+ off,
3373
+ on,
3264
3374
  parseNumeric,
3265
3375
  pascalCase,
3266
3376
  pascalSnakeCase,
@@ -3268,10 +3378,16 @@ export {
3268
3378
  percentage,
3269
3379
  pipe,
3270
3380
  plus,
3381
+ proxy,
3271
3382
  randomArray,
3272
3383
  randomNumer,
3384
+ readFileReader,
3385
+ redirectTo,
3273
3386
  riposte,
3387
+ selectImages,
3274
3388
  sentenceCase,
3389
+ showOpenFilePicker,
3390
+ showOpenImagePicker,
3275
3391
  snakeCase,
3276
3392
  to,
3277
3393
  trainCase,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hairy/utils",
3
3
  "type": "module",
4
- "version": "1.29.0",
4
+ "version": "1.31.0",
5
5
  "description": "Library for anywhere",
6
6
  "author": "Hairyf <wwu710632@gmail.com>",
7
7
  "license": "MIT",