@nickyzj2023/utils 1.0.69 → 1.0.71
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.d.mts +788 -784
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,785 +1,789 @@
|
|
|
1
|
-
//#region src/ai/chatCompletions/types.d.ts
|
|
2
|
-
declare namespace ChatCompletions {
|
|
3
|
-
type Model = {
|
|
4
|
-
/** 模型名称(如果不传,会尝试从 /models 读取模型) */model?: string; /** API 基础地址 */
|
|
5
|
-
baseUrl: string; /** API 密钥(本地模型可不传) */
|
|
6
|
-
apiKey?: string;
|
|
7
|
-
};
|
|
8
|
-
type TextContent = {
|
|
9
|
-
type: "text";
|
|
10
|
-
text: string;
|
|
11
|
-
};
|
|
12
|
-
type ImageContent = {
|
|
13
|
-
type: "image_url";
|
|
14
|
-
image_url: {
|
|
15
|
-
url: string;
|
|
16
|
-
};
|
|
17
|
-
};
|
|
18
|
-
type AudioContent = {
|
|
19
|
-
type: "input_audio";
|
|
20
|
-
|
|
21
|
-
url
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
[key
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
* @
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
* //
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
declare
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
*
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
*
|
|
210
|
-
*
|
|
211
|
-
* log(
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
*
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
*
|
|
239
|
-
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
*
|
|
260
|
-
*
|
|
261
|
-
* @
|
|
262
|
-
*
|
|
263
|
-
*
|
|
264
|
-
*
|
|
265
|
-
* @
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
*
|
|
269
|
-
*
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
*
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
278
|
-
* fetchData
|
|
279
|
-
* await fetchData(
|
|
280
|
-
* await fetchData(urlB); //
|
|
281
|
-
*
|
|
282
|
-
* //
|
|
283
|
-
* await
|
|
284
|
-
* fetchData
|
|
285
|
-
*
|
|
286
|
-
*
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
*
|
|
303
|
-
*
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
*
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
*
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
/**
|
|
335
|
-
*
|
|
336
|
-
*/
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
*
|
|
345
|
-
*
|
|
346
|
-
*
|
|
347
|
-
*
|
|
348
|
-
*
|
|
349
|
-
*
|
|
350
|
-
* -
|
|
351
|
-
*
|
|
352
|
-
*
|
|
353
|
-
*
|
|
354
|
-
*
|
|
355
|
-
*
|
|
356
|
-
*
|
|
357
|
-
*
|
|
358
|
-
*
|
|
359
|
-
*
|
|
360
|
-
*
|
|
361
|
-
*
|
|
362
|
-
*
|
|
363
|
-
*
|
|
364
|
-
*
|
|
365
|
-
*
|
|
366
|
-
*
|
|
367
|
-
*
|
|
368
|
-
*
|
|
369
|
-
*
|
|
370
|
-
*
|
|
371
|
-
*
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
*
|
|
375
|
-
*
|
|
376
|
-
*
|
|
377
|
-
*
|
|
378
|
-
*
|
|
379
|
-
*
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
//#endregion
|
|
392
|
-
//#region src/network/
|
|
393
|
-
/**
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
*
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
*
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
*
|
|
420
|
-
*
|
|
421
|
-
*
|
|
422
|
-
* @
|
|
423
|
-
*
|
|
424
|
-
*
|
|
425
|
-
*
|
|
426
|
-
* @example
|
|
427
|
-
* //
|
|
428
|
-
* imageUrlToBase64("https://example.com/image.jpg"
|
|
429
|
-
*
|
|
430
|
-
*
|
|
431
|
-
*
|
|
432
|
-
*
|
|
433
|
-
*
|
|
434
|
-
*
|
|
435
|
-
*
|
|
436
|
-
*
|
|
437
|
-
*
|
|
438
|
-
*
|
|
439
|
-
*
|
|
440
|
-
*
|
|
441
|
-
*
|
|
442
|
-
*
|
|
443
|
-
*
|
|
444
|
-
*
|
|
445
|
-
*
|
|
446
|
-
*
|
|
447
|
-
*
|
|
448
|
-
*
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
*
|
|
459
|
-
*
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
*
|
|
482
|
-
*
|
|
483
|
-
*
|
|
484
|
-
*
|
|
485
|
-
*
|
|
486
|
-
*
|
|
487
|
-
*
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
*
|
|
497
|
-
*
|
|
498
|
-
* @
|
|
499
|
-
*
|
|
500
|
-
*
|
|
501
|
-
*
|
|
502
|
-
*
|
|
503
|
-
*
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
/**
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
*
|
|
516
|
-
*
|
|
517
|
-
*
|
|
518
|
-
*
|
|
519
|
-
*
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
*
|
|
530
|
-
*
|
|
531
|
-
* @
|
|
532
|
-
* @
|
|
533
|
-
*
|
|
534
|
-
* @
|
|
535
|
-
*
|
|
536
|
-
*
|
|
537
|
-
*
|
|
538
|
-
*
|
|
539
|
-
*
|
|
540
|
-
*
|
|
541
|
-
*
|
|
542
|
-
*
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
*
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
*
|
|
551
|
-
*
|
|
552
|
-
* @
|
|
553
|
-
*
|
|
554
|
-
* @
|
|
555
|
-
*
|
|
556
|
-
*
|
|
557
|
-
*
|
|
558
|
-
*
|
|
559
|
-
*
|
|
560
|
-
*
|
|
561
|
-
*
|
|
562
|
-
*
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
*
|
|
573
|
-
*
|
|
574
|
-
* @
|
|
575
|
-
* @
|
|
576
|
-
*
|
|
577
|
-
* @
|
|
578
|
-
*
|
|
579
|
-
*
|
|
580
|
-
*
|
|
581
|
-
*
|
|
582
|
-
*
|
|
583
|
-
*
|
|
584
|
-
*
|
|
585
|
-
*
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
*
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
*
|
|
594
|
-
*
|
|
595
|
-
* @
|
|
596
|
-
*
|
|
597
|
-
* @
|
|
598
|
-
*
|
|
599
|
-
*
|
|
600
|
-
*
|
|
601
|
-
*
|
|
602
|
-
*
|
|
603
|
-
*
|
|
604
|
-
*
|
|
605
|
-
*
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
*
|
|
650
|
-
*
|
|
651
|
-
*
|
|
652
|
-
*
|
|
653
|
-
*
|
|
654
|
-
*
|
|
655
|
-
*
|
|
656
|
-
*
|
|
657
|
-
*
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
*
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
//#endregion
|
|
681
|
-
//#region src/string/
|
|
682
|
-
/**
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
*
|
|
706
|
-
*
|
|
707
|
-
*
|
|
708
|
-
*
|
|
709
|
-
*
|
|
710
|
-
*
|
|
711
|
-
*
|
|
712
|
-
*
|
|
713
|
-
*
|
|
714
|
-
*
|
|
715
|
-
*
|
|
716
|
-
*
|
|
717
|
-
*
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
*
|
|
728
|
-
*
|
|
729
|
-
*
|
|
730
|
-
*
|
|
731
|
-
*
|
|
732
|
-
*
|
|
733
|
-
*
|
|
734
|
-
*
|
|
735
|
-
*
|
|
736
|
-
*
|
|
737
|
-
*
|
|
738
|
-
*
|
|
739
|
-
*
|
|
740
|
-
*
|
|
741
|
-
*
|
|
742
|
-
*
|
|
743
|
-
*
|
|
744
|
-
*
|
|
745
|
-
*
|
|
746
|
-
*
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
*
|
|
770
|
-
*
|
|
771
|
-
*
|
|
772
|
-
*
|
|
773
|
-
*
|
|
774
|
-
*
|
|
775
|
-
*
|
|
776
|
-
*
|
|
777
|
-
*
|
|
778
|
-
*
|
|
779
|
-
*
|
|
780
|
-
*
|
|
781
|
-
*
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
1
|
+
//#region src/ai/chatCompletions/types.d.ts
|
|
2
|
+
declare namespace ChatCompletions {
|
|
3
|
+
type Model = {
|
|
4
|
+
/** 模型名称(如果不传,会尝试从 /models 读取模型) */model?: string; /** API 基础地址 */
|
|
5
|
+
baseUrl: string; /** API 密钥(本地模型可不传) */
|
|
6
|
+
apiKey?: string;
|
|
7
|
+
};
|
|
8
|
+
type TextContent = {
|
|
9
|
+
type: "text";
|
|
10
|
+
text: string;
|
|
11
|
+
};
|
|
12
|
+
type ImageContent = {
|
|
13
|
+
type: "image_url";
|
|
14
|
+
image_url: {
|
|
15
|
+
url: string;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
type AudioContent = {
|
|
19
|
+
type: "input_audio";
|
|
20
|
+
input_audio: {
|
|
21
|
+
/** 使用公网可访问的音频文件 URL */url?: string; /** 使用 base64 */
|
|
22
|
+
data?: string;
|
|
23
|
+
format: string;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
type VideoContent = {
|
|
27
|
+
type: "video_url";
|
|
28
|
+
video_url: {
|
|
29
|
+
url: string;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
type ContentPart = TextContent | ImageContent | AudioContent | VideoContent;
|
|
33
|
+
type Message = {
|
|
34
|
+
role: "system" | "user" | "assistant" | "tool" | "function"; /** 字节的思考字段 */
|
|
35
|
+
reasoning_content?: string | null; /** OpenRouter的思考字段 */
|
|
36
|
+
reasoning?: string | null;
|
|
37
|
+
content: string | ContentPart[];
|
|
38
|
+
name?: string;
|
|
39
|
+
tool_calls?: ToolCall[];
|
|
40
|
+
tool_call_id?: string;
|
|
41
|
+
};
|
|
42
|
+
type ToolCall = {
|
|
43
|
+
id: string;
|
|
44
|
+
type: "function";
|
|
45
|
+
function: {
|
|
46
|
+
name: string;
|
|
47
|
+
arguments: string;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
type ToolDefinition = {
|
|
51
|
+
type: "function";
|
|
52
|
+
function: {
|
|
53
|
+
name: string;
|
|
54
|
+
description?: string;
|
|
55
|
+
parameters?: Record<string, any>;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
type Usage = {
|
|
59
|
+
prompt_tokens: number;
|
|
60
|
+
completion_tokens: number;
|
|
61
|
+
total_tokens: number;
|
|
62
|
+
};
|
|
63
|
+
/** 请求非流式 /chat/completions 的响应结果 */
|
|
64
|
+
type Response = {
|
|
65
|
+
id: string;
|
|
66
|
+
object: "chat.completion";
|
|
67
|
+
created: number;
|
|
68
|
+
model: string;
|
|
69
|
+
choices: Array<{
|
|
70
|
+
index: number;
|
|
71
|
+
message: Message;
|
|
72
|
+
finish_reason: "stop" | "length" | "tool_calls" | "content_filter" | null;
|
|
73
|
+
}>;
|
|
74
|
+
usage: Usage;
|
|
75
|
+
system_fingerprint?: string;
|
|
76
|
+
};
|
|
77
|
+
type ExtraBody = {
|
|
78
|
+
/** 工具列表 */tools?: ToolDefinition[]; /** 工具调用函数表,key 为工具名,value 为函数 */
|
|
79
|
+
toolHandlers?: Record<string, (args: any) => any | Promise<any>>; /** 是否使用流式传输,启用后函数返回异步迭代器 */
|
|
80
|
+
stream?: boolean; /** 其他额外参数 */
|
|
81
|
+
[key: string]: any;
|
|
82
|
+
};
|
|
83
|
+
/** 调用 chatCompletions 返回的结果,流式/非流式通用 */
|
|
84
|
+
type Result = {
|
|
85
|
+
/** 模型的最终回复内容(多模态时取所有 text 拼接) */content: string; /** Token 消耗情况 */
|
|
86
|
+
usage: Usage; /** 原始响应中的其他字段 */
|
|
87
|
+
[key: string]: any;
|
|
88
|
+
};
|
|
89
|
+
/** 流式响应中的单个 SSE 数据块(OpenAI 原始格式) */
|
|
90
|
+
type StreamResponse = {
|
|
91
|
+
id: string;
|
|
92
|
+
object: "chat.completion.chunk";
|
|
93
|
+
created: number;
|
|
94
|
+
model: string;
|
|
95
|
+
choices: Array<{
|
|
96
|
+
index: number;
|
|
97
|
+
delta: {
|
|
98
|
+
role?: Message["role"];
|
|
99
|
+
content?: string | null; /** 字节的思考字段 */
|
|
100
|
+
reasoning_content?: string | null; /** OpenRouter的思考字段 */
|
|
101
|
+
reasoning?: string | null;
|
|
102
|
+
tool_calls?: Array<{
|
|
103
|
+
index: number;
|
|
104
|
+
id?: string;
|
|
105
|
+
type?: "function";
|
|
106
|
+
function?: {
|
|
107
|
+
name?: string;
|
|
108
|
+
arguments?: string;
|
|
109
|
+
};
|
|
110
|
+
}>;
|
|
111
|
+
};
|
|
112
|
+
finish_reason: "stop" | "length" | "tool_calls" | "content_filter" | null;
|
|
113
|
+
}>;
|
|
114
|
+
usage?: Usage;
|
|
115
|
+
};
|
|
116
|
+
/** 流式调用 chatCompletions 时迭代器产出的数据块 */
|
|
117
|
+
type StreamChunk = {
|
|
118
|
+
/** 模型流式返回的思考内容增量(仅在生成过程中出现) */reasoningContent?: string; /** 模型流式返回的内容增量(仅在生成过程中出现) */
|
|
119
|
+
content?: string; /** Token 消耗情况(仅在最后一帧出现) */
|
|
120
|
+
usage?: Usage;
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
//#endregion
|
|
124
|
+
//#region src/ai/chatCompletions/index.d.ts
|
|
125
|
+
/**
|
|
126
|
+
* 兼容 OpenAI API 的聊天补全函数
|
|
127
|
+
* - 自动处理工具调用
|
|
128
|
+
* - 同时支持普通响应和流式响应
|
|
129
|
+
*
|
|
130
|
+
* @param model 模型配置,包含 model、baseUrl、apiKey
|
|
131
|
+
* @param messages OpenAI API 兼容的消息数组
|
|
132
|
+
* @param extraBody 可选的额外参数,如 tools、toolHandlers、temperature、stream 等
|
|
133
|
+
* @returns 普通模式下返回 `{ content, usage, ... }`;`stream: true` 时返回异步迭代器
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* // 最简调用
|
|
137
|
+
* // 未填写模型名,会自动使用/v1/models的第一个模型
|
|
138
|
+
* const { content, usage } = await chatCompletions(
|
|
139
|
+
* { baseUrl: "http://127.0.0.1:11434/v1" },
|
|
140
|
+
* [{ role: "user", content: "你好" }],
|
|
141
|
+
* );
|
|
142
|
+
* console.log(content); // "你好!有什么我可以帮你的吗?"
|
|
143
|
+
* console.log(usage); // { prompt_tokens: 13, completion_tokens: 9, total_tokens: 22 }
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* // 工具调用
|
|
147
|
+
* const { content, usage } = await chatCompletions(
|
|
148
|
+
* { baseUrl: "http://127.0.0.1:11434/v1", model: "model.gguf", apiKey: "sk-local-no-need-key" },
|
|
149
|
+
* [{ role: "user", content: "查询上海天气" }],
|
|
150
|
+
* {
|
|
151
|
+
* tools: [{
|
|
152
|
+
* type: "function",
|
|
153
|
+
* function: {
|
|
154
|
+
* name: "getWeather",
|
|
155
|
+
* description: "查询城市天气情况",
|
|
156
|
+
* parameters: { type: "object", properties: { city: { type: "string" } } },
|
|
157
|
+
* },
|
|
158
|
+
* }],
|
|
159
|
+
* toolHandlers: {
|
|
160
|
+
* getWeather: (args) => `${args.city}今日晴转多云,25°C`,
|
|
161
|
+
* },
|
|
162
|
+
* },
|
|
163
|
+
* );
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* // 流式传输
|
|
167
|
+
* const result = await chatCompletions(
|
|
168
|
+
* { baseUrl: "http://127.0.0.1:11434/v1" },
|
|
169
|
+
* [{ role: "user", content: "你好" }],
|
|
170
|
+
* { stream: true },
|
|
171
|
+
* );
|
|
172
|
+
* for await (const { content, usage } of result) {
|
|
173
|
+
* if (content) {
|
|
174
|
+
* console.log("流式传输中:", content);
|
|
175
|
+
* } else if (usage) {
|
|
176
|
+
* console.log("对话结束,消耗:", usage);
|
|
177
|
+
* }
|
|
178
|
+
* }
|
|
179
|
+
*/
|
|
180
|
+
declare function chatCompletions(model: ChatCompletions.Model, messages: ChatCompletions.Message[], extraBody: ChatCompletions.ExtraBody & {
|
|
181
|
+
stream: true;
|
|
182
|
+
}): Promise<AsyncGenerator<ChatCompletions.StreamChunk>>;
|
|
183
|
+
declare function chatCompletions(model: ChatCompletions.Model, messages: ChatCompletions.Message[], extraBody?: ChatCompletions.ExtraBody): Promise<ChatCompletions.Result>;
|
|
184
|
+
/**
|
|
185
|
+
* 辅助定义一个 chatCompletions 支持的模型配置
|
|
186
|
+
*/
|
|
187
|
+
declare const defineModel: (config: ChatCompletions.Model) => ChatCompletions.Model;
|
|
188
|
+
//#endregion
|
|
189
|
+
//#region src/dom/log.d.ts
|
|
190
|
+
/**
|
|
191
|
+
* log 配置选项
|
|
192
|
+
*/
|
|
193
|
+
interface LogOptions {
|
|
194
|
+
/**
|
|
195
|
+
* 是否显示时间
|
|
196
|
+
* @default true
|
|
197
|
+
*/
|
|
198
|
+
time?: boolean;
|
|
199
|
+
/**
|
|
200
|
+
* 是否显示调用者文件名
|
|
201
|
+
* @default true
|
|
202
|
+
*/
|
|
203
|
+
fileName?: boolean;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* 带额外信息的 console.log
|
|
207
|
+
* @param message - 日志消息,支持单条消息或消息数组
|
|
208
|
+
* @param options - 配置选项
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* log("调试信息"); // "[14:30:00] [index.ts:15] 调试信息"
|
|
212
|
+
* log("调试信息", { time: false }); // "[index.ts:15] 调试信息"
|
|
213
|
+
* log("调试信息", { fileName: false }); // "[14:30:00] 调试信息"
|
|
214
|
+
* log("调试信息", { time: false, fileName: false }); // "调试信息"
|
|
215
|
+
* log(["消息1", "消息2"]); // "[14:30:00] [index.ts:15] 消息1 消息2"
|
|
216
|
+
*/
|
|
217
|
+
declare const log: (message: any | any[], options?: LogOptions) => void;
|
|
218
|
+
//#endregion
|
|
219
|
+
//#region src/function/loop-until.d.ts
|
|
220
|
+
/**
|
|
221
|
+
* 循环执行函数,直到符合停止条件
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* // 循环请求大语言模型,直到其不再调用工具
|
|
225
|
+
* loopUntil(
|
|
226
|
+
* async () => {
|
|
227
|
+
* const completion = await chatCompletions();
|
|
228
|
+
* completion.tool_calls?.forEach(chooseAndHandleTool)
|
|
229
|
+
* return completion;
|
|
230
|
+
* },
|
|
231
|
+
* {
|
|
232
|
+
* shouldStop: (completion) => !completion.tool_calls,
|
|
233
|
+
* },
|
|
234
|
+
* ),
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* // 不传递 shouldStop,执行 3 次后正常返回最后结果
|
|
238
|
+
* loopUntil(
|
|
239
|
+
* () => {
|
|
240
|
+
* return doSomething();
|
|
241
|
+
* },
|
|
242
|
+
* {
|
|
243
|
+
* maxRetries: 3,
|
|
244
|
+
* },
|
|
245
|
+
* ),
|
|
246
|
+
*/
|
|
247
|
+
declare const loopUntil: <T>(fn: (count: number) => T | Promise<T>, options?: {
|
|
248
|
+
/**
|
|
249
|
+
* 最大循环次数
|
|
250
|
+
* @default 5
|
|
251
|
+
*/
|
|
252
|
+
maxRetries?: number; /** 停止循环条件。如果未传递,则执行 maxRetries 次后退出并返回最后结果 */
|
|
253
|
+
shouldStop?: (result: T) => boolean;
|
|
254
|
+
}) => Promise<T>;
|
|
255
|
+
//#endregion
|
|
256
|
+
//#region src/hoc/with-cache.d.ts
|
|
257
|
+
type SetTtl = (seconds: number) => void;
|
|
258
|
+
/**
|
|
259
|
+
* 创建一个带缓存的高阶函数
|
|
260
|
+
*
|
|
261
|
+
* @template Args 被包装函数的参数类型数组
|
|
262
|
+
* @template Result 被包装函数的返回类型
|
|
263
|
+
*
|
|
264
|
+
* @param fn 需要被缓存的函数,参数里附带的 setTtl 方法用于根据具体情况改写过期时间
|
|
265
|
+
* @param ttlSeconds 以秒为单位的过期时间,-1 表示永不过期,默认 -1,会被回调函数里的 setTtl() 覆盖
|
|
266
|
+
*
|
|
267
|
+
* @returns 返回包装后的函数,以及缓存相关的额外方法
|
|
268
|
+
*
|
|
269
|
+
* @example
|
|
270
|
+
* // 异步函数示例
|
|
271
|
+
* const fetchData = withCache(async function (url: string) {
|
|
272
|
+
* const data = await fetch(url).then((res) => res.json());
|
|
273
|
+
* this.setTtl(data.expiresIn); // 根据实际情况调整过期时间
|
|
274
|
+
* return data;
|
|
275
|
+
* });
|
|
276
|
+
*
|
|
277
|
+
* await fetchData(urlA);
|
|
278
|
+
* await fetchData(urlA); // 使用缓存结果
|
|
279
|
+
* await fetchData(urlB);
|
|
280
|
+
* await fetchData(urlB); // 使用缓存结果
|
|
281
|
+
*
|
|
282
|
+
* fetchData.clear(); // 清除缓存
|
|
283
|
+
* await fetchData(urlA); // 重新请求
|
|
284
|
+
* await fetchData(urlB); // 重新请求
|
|
285
|
+
*
|
|
286
|
+
* // 缓存过期前
|
|
287
|
+
* await sleep();
|
|
288
|
+
* fetchData.updateTtl(180); // 更新 ttl 并为所有未过期的缓存续期
|
|
289
|
+
* await fetchData(urlA); // 使用缓存结果
|
|
290
|
+
* await fetchData(urlB); // 使用缓存结果
|
|
291
|
+
*/
|
|
292
|
+
declare const withCache: <Args extends any[], Result>(fn: (this: {
|
|
293
|
+
setTtl: SetTtl;
|
|
294
|
+
}, ...args: Args) => Result, ttlSeconds?: number) => {
|
|
295
|
+
(...args: Args): Result;
|
|
296
|
+
clear(): void;
|
|
297
|
+
updateTtl(seconds: number): void;
|
|
298
|
+
};
|
|
299
|
+
//#endregion
|
|
300
|
+
//#region src/is/is-nil.d.ts
|
|
301
|
+
/**
|
|
302
|
+
* 检测传入的值是否为**空值**(null、undefined)
|
|
303
|
+
*
|
|
304
|
+
* @example
|
|
305
|
+
* isNil(null); // true
|
|
306
|
+
* isNil(undefined); // true
|
|
307
|
+
* isNil(1); // false
|
|
308
|
+
*/
|
|
309
|
+
declare const isNil: (value: any) => value is null | undefined;
|
|
310
|
+
//#endregion
|
|
311
|
+
//#region src/is/is-object.d.ts
|
|
312
|
+
/**
|
|
313
|
+
* 检测传入的值是否为**普通对象**
|
|
314
|
+
*
|
|
315
|
+
* @example
|
|
316
|
+
* const obj = { a: 1 };
|
|
317
|
+
* isObject(obj); // true
|
|
318
|
+
*/
|
|
319
|
+
declare const isObject: (value: any) => value is Record<string, any>;
|
|
320
|
+
//#endregion
|
|
321
|
+
//#region src/is/is-primitive.d.ts
|
|
322
|
+
type Primitive = number | string | boolean | symbol | bigint | undefined | null;
|
|
323
|
+
/**
|
|
324
|
+
* 检测传入的值是否为**原始值**(number、string、boolean、symbol、bigint、undefined、null)
|
|
325
|
+
*
|
|
326
|
+
* @example
|
|
327
|
+
* isPrimitive(1); // true
|
|
328
|
+
* isPrimitive([]); // false
|
|
329
|
+
*/
|
|
330
|
+
declare const isPrimitive: (value: any) => value is Primitive;
|
|
331
|
+
//#endregion
|
|
332
|
+
//#region src/network/fetcher.d.ts
|
|
333
|
+
type RequestInit = globalThis.RequestInit & {
|
|
334
|
+
/**
|
|
335
|
+
* searchParams 查询参数对象
|
|
336
|
+
*/
|
|
337
|
+
params?: Record<string, any>;
|
|
338
|
+
/**
|
|
339
|
+
* 响应解析器,默认的解析方法为 response.json()
|
|
340
|
+
*/
|
|
341
|
+
parser?: (response: Response) => Promise<any>;
|
|
342
|
+
};
|
|
343
|
+
/**
|
|
344
|
+
* 基于 Fetch API 的请求实例
|
|
345
|
+
* @param baseUrl 接口前缀
|
|
346
|
+
* @param baseOptions 应用于整个实例的请求体,后续请求都会带上
|
|
347
|
+
*
|
|
348
|
+
* @remarks
|
|
349
|
+
* 特性:
|
|
350
|
+
* - 支持在创建实例、发出请求时合并相同的请求体(后者覆盖前者)
|
|
351
|
+
* - 支持在 GET 的 params 请求体中传递对象
|
|
352
|
+
* - 支持在 POST、PUT 的 body 请求体中传递对象
|
|
353
|
+
* - 可选 to() 函数转换请求结果为 [Error, Response]
|
|
354
|
+
* - 可选 withCache() 函数缓存请求结果
|
|
355
|
+
*
|
|
356
|
+
* @example
|
|
357
|
+
* // 直接发请求
|
|
358
|
+
* const res = await fetcher().get<Blog>("https://nickyzj.run:3030/blogs/hello-world", {
|
|
359
|
+
* params: {
|
|
360
|
+
* page: 2,
|
|
361
|
+
* pageSize: 10,
|
|
362
|
+
* }
|
|
363
|
+
* });
|
|
364
|
+
*
|
|
365
|
+
* // 创建实例,发请求
|
|
366
|
+
* const api = fetcher("https://nickyzj.run:3030", {
|
|
367
|
+
* headers: {
|
|
368
|
+
* Authorization: "Bearer token"
|
|
369
|
+
* }
|
|
370
|
+
* });
|
|
371
|
+
* const res = await api.get<Blog>("/blogs/hello-world");
|
|
372
|
+
*
|
|
373
|
+
* // 安全返回请求结果,不抛异常
|
|
374
|
+
* const [error, data] = await to(api.get<Blog>("/blogs/hello-world"));
|
|
375
|
+
* if (error) {
|
|
376
|
+
* // ...
|
|
377
|
+
* }
|
|
378
|
+
* // ...
|
|
379
|
+
*
|
|
380
|
+
* // 缓存请求结果
|
|
381
|
+
* const getBlogs = withCache(api.get);
|
|
382
|
+
* await getBlogs("/blogs");
|
|
383
|
+
* await getBlogs("/blogs"); // 不发请求,使用缓存
|
|
384
|
+
*/
|
|
385
|
+
declare const fetcher: (baseUrl?: string, baseOptions?: RequestInit) => {
|
|
386
|
+
get: <T>(url: string, options?: Omit<RequestInit, "method">) => Promise<T>;
|
|
387
|
+
post: <T>(url: string, body: any, options?: Omit<RequestInit, "method" | "body">) => Promise<T>;
|
|
388
|
+
put: <T>(url: string, body: any, options?: Omit<RequestInit, "method" | "body">) => Promise<T>;
|
|
389
|
+
delete: <T>(url: string, options?: Omit<RequestInit, "method" | "body">) => Promise<T>;
|
|
390
|
+
};
|
|
391
|
+
//#endregion
|
|
392
|
+
//#region src/network/get-real-url.d.ts
|
|
393
|
+
/** 从 url 响应头获取真实链接 */
|
|
394
|
+
declare const getRealURL: (originURL: string) => Promise<string>;
|
|
395
|
+
//#endregion
|
|
396
|
+
//#region src/network/image.d.ts
|
|
397
|
+
/**
|
|
398
|
+
* 图片压缩选项
|
|
399
|
+
*/
|
|
400
|
+
type ImageCompressionOptions = {
|
|
401
|
+
/** 压缩比率,默认 0.92 */quality?: number;
|
|
402
|
+
/**
|
|
403
|
+
* 自定义压缩函数,用于覆盖默认压缩行为
|
|
404
|
+
* @param arrayBuffer 图片的 ArrayBuffer 数据
|
|
405
|
+
* @param mime 图片的 MIME 类型
|
|
406
|
+
* @param quality 压缩质量
|
|
407
|
+
* @returns 压缩后的 base64 字符串
|
|
408
|
+
*/
|
|
409
|
+
compressor?: (arrayBuffer: ArrayBuffer, mime: string, quality: number) => Promise<string> | string;
|
|
410
|
+
/**
|
|
411
|
+
* 自定义 fetch 函数,用于使用自己封装的请求库读取图片
|
|
412
|
+
* 必须返回符合 Web 标准的 Response 对象
|
|
413
|
+
* @param url 图片地址
|
|
414
|
+
* @returns Promise<Response>
|
|
415
|
+
*/
|
|
416
|
+
fetcher?: (url: string) => Promise<Response>;
|
|
417
|
+
};
|
|
418
|
+
/**
|
|
419
|
+
* 图片地址转 base64 数据
|
|
420
|
+
*
|
|
421
|
+
* @param imageUrl 图片地址
|
|
422
|
+
* @param options 可选配置
|
|
423
|
+
* @param options.quality 压缩比率,默认 0.92
|
|
424
|
+
* @param options.compressor 自定义压缩函数,用于覆盖默认压缩行为
|
|
425
|
+
*
|
|
426
|
+
* @example
|
|
427
|
+
* // 基本用法(浏览器自动使用 Canvas 压缩,Node.js 自动检测并使用 sharp)
|
|
428
|
+
* imageUrlToBase64("https://example.com/image.jpg");
|
|
429
|
+
*
|
|
430
|
+
* @example
|
|
431
|
+
* // 使用自定义 fetch 函数(如 axios 封装)
|
|
432
|
+
* imageUrlToBase64("https://example.com/image.jpg", {
|
|
433
|
+
* fetcher: async (url) => {
|
|
434
|
+
* // 使用 axios 或其他请求库,但必须返回 Response 对象
|
|
435
|
+
* const response = await axios.get(url, { responseType: 'arraybuffer' });
|
|
436
|
+
* return new Response(response.data, {
|
|
437
|
+
* status: response.status,
|
|
438
|
+
* statusText: response.statusText,
|
|
439
|
+
* headers: response.headers
|
|
440
|
+
* });
|
|
441
|
+
* }
|
|
442
|
+
* });
|
|
443
|
+
*
|
|
444
|
+
* @example
|
|
445
|
+
* // 使用自定义压缩函数覆盖默认行为
|
|
446
|
+
* imageUrlToBase64("https://example.com/image.jpg", {
|
|
447
|
+
* quality: 0.8,
|
|
448
|
+
* compressor: async (buffer, mime, quality) => {
|
|
449
|
+
* // 自定义压缩逻辑
|
|
450
|
+
* return `data:${mime};base64,...`;
|
|
451
|
+
* }
|
|
452
|
+
* });
|
|
453
|
+
*/
|
|
454
|
+
declare const imageUrlToBase64: (imageUrl: string, options?: ImageCompressionOptions) => Promise<string>;
|
|
455
|
+
//#endregion
|
|
456
|
+
//#region src/network/to.d.ts
|
|
457
|
+
/**
|
|
458
|
+
* Go 语言风格的异步处理方式
|
|
459
|
+
* @param promise 一个能被 await 的异步函数
|
|
460
|
+
* @returns 如果成功,返回 [null, 异步函数结果],否则返回 [Error, undefined]
|
|
461
|
+
*
|
|
462
|
+
* @example
|
|
463
|
+
* const [error, response] = await to(fetcher().get<Blog>("/blogs/hello-world"));
|
|
464
|
+
*/
|
|
465
|
+
declare const to: <T, E = Error>(promise: Promise<T>) => Promise<[null, T] | [E, undefined]>;
|
|
466
|
+
//#endregion
|
|
467
|
+
//#region src/number/random-int.d.ts
|
|
468
|
+
/**
|
|
469
|
+
* 在指定闭区间内生成随机整数
|
|
470
|
+
*
|
|
471
|
+
* @example
|
|
472
|
+
* randomInt(1, 10); // 1 <= x <= 10
|
|
473
|
+
*/
|
|
474
|
+
declare const randomInt: (min: number, max: number) => number;
|
|
475
|
+
//#endregion
|
|
476
|
+
//#region src/object/map.d.ts
|
|
477
|
+
type DeepMapKeys<T> = T extends Array<infer U> ? Array<DeepMapKeys<U>> : T extends object ? {
|
|
478
|
+
[key: string]: DeepMapKeys<T[keyof T]>;
|
|
479
|
+
} : T;
|
|
480
|
+
/**
|
|
481
|
+
* 递归处理对象里的 key
|
|
482
|
+
*
|
|
483
|
+
* @remarks
|
|
484
|
+
* 无法完整推导出类型,只能做到有递归,key 全为 string,value 为同层级的所有类型的联合
|
|
485
|
+
*
|
|
486
|
+
* @template T 要转换的对象
|
|
487
|
+
*
|
|
488
|
+
* @example
|
|
489
|
+
* const obj = { a: { b: 1 } };
|
|
490
|
+
* const result = mapKeys(obj, (key) => key.toUpperCase());
|
|
491
|
+
* console.log(result); // { A: { B: 1 } }
|
|
492
|
+
*/
|
|
493
|
+
declare const mapKeys: <T>(obj: T, getNewKey: (key: string) => string) => DeepMapKeys<T>;
|
|
494
|
+
type DeepMapValues<T, R> = T extends Array<infer U> ? Array<DeepMapValues<U, R>> : T extends object ? { [K in keyof T]: T[K] extends object ? DeepMapValues<T[K], R> : R } : R;
|
|
495
|
+
/**
|
|
496
|
+
* 递归处理对象里的 value
|
|
497
|
+
*
|
|
498
|
+
* @remarks
|
|
499
|
+
* 无法完整推导出类型,所有 value 最终都会变为 any
|
|
500
|
+
*
|
|
501
|
+
* @template T 要转换的对象
|
|
502
|
+
* @template R 转换后的值类型,为 any,无法进一步推导
|
|
503
|
+
*
|
|
504
|
+
* @example
|
|
505
|
+
* const obj = { a: 1, b: { c: 2 } };
|
|
506
|
+
* const result = mapValues(obj, (value, key) => isPrimitive(value) ? value + 1 : value);
|
|
507
|
+
* console.log(result); // { a: 2, b: { c: 3 } }
|
|
508
|
+
*/
|
|
509
|
+
declare const mapValues: <T, R = any>(obj: T, getNewValue: (value: any, key: string | number) => R, options?: {
|
|
510
|
+
/** 过滤函数,返回 true 表示保留该字段 */filter?: (value: any, key: string | number) => boolean;
|
|
511
|
+
}) => DeepMapValues<T, R>;
|
|
512
|
+
//#endregion
|
|
513
|
+
//#region src/object/merge.d.ts
|
|
514
|
+
/**
|
|
515
|
+
* 深度合并两个对象,规则如下:
|
|
516
|
+
* 1. 原始值覆盖:如果两个值都是原始类型,则用后者覆盖;
|
|
517
|
+
* 2. 数组拼接:如果两个值都是数组,则拼接为大数组;
|
|
518
|
+
* 3. 对象递归合并:如果两个值都是对象,则进行递归深度合并;
|
|
519
|
+
*
|
|
520
|
+
* @template T 第一个对象
|
|
521
|
+
* @template U 第二个对象
|
|
522
|
+
* @param {T} obj1 要合并的第一个对象,相同字段会被 obj2 覆盖
|
|
523
|
+
* @param {U} obj2 要合并的第二个对象
|
|
524
|
+
*/
|
|
525
|
+
declare const mergeObjects: <T extends Record<string, any>, U extends Record<string, any>>(obj1: T, obj2: U) => T & U;
|
|
526
|
+
//#endregion
|
|
527
|
+
//#region src/object/omit.d.ts
|
|
528
|
+
/**
|
|
529
|
+
* 从对象中排除指定的键,返回不包含这些键的新对象
|
|
530
|
+
*
|
|
531
|
+
* @typeParam T - 源对象的类型
|
|
532
|
+
* @typeParam K - 要排除的键,必须是源对象的键之一
|
|
533
|
+
*
|
|
534
|
+
* @param obj - 源对象
|
|
535
|
+
* @param keys - 要排除的键名数组
|
|
536
|
+
* @returns 不包含指定键的新对象
|
|
537
|
+
*
|
|
538
|
+
* @example
|
|
539
|
+
* const user = {
|
|
540
|
+
* id: 1,
|
|
541
|
+
* name: "Alice",
|
|
542
|
+
* age: 25,
|
|
543
|
+
* password: "secret"
|
|
544
|
+
* };
|
|
545
|
+
* // { id: 1, name: "Alice", age: 25 }
|
|
546
|
+
* const safeUser = omit(user, ["password"]);
|
|
547
|
+
*/
|
|
548
|
+
declare const omit: <T extends Record<string, any>, K extends keyof T>(obj: T, keys: readonly K[]) => Omit<T, K>;
|
|
549
|
+
/**
|
|
550
|
+
* 从对象中排除满足条件的键值对,返回不包含这些键的新对象
|
|
551
|
+
*
|
|
552
|
+
* @typeParam T - 源对象的类型
|
|
553
|
+
*
|
|
554
|
+
* @param obj - 源对象
|
|
555
|
+
* @param shouldOmit - 判断函数,接收键和值,返回 `true` 则排除该键值对
|
|
556
|
+
* @returns 不包含满足条件的键值对的新对象
|
|
557
|
+
*
|
|
558
|
+
* @example
|
|
559
|
+
* const user = {
|
|
560
|
+
* id: 1,
|
|
561
|
+
* name: "Alice",
|
|
562
|
+
* age: 25,
|
|
563
|
+
* password: "secret"
|
|
564
|
+
* };
|
|
565
|
+
* // { name: "Alice", password: "secret" }
|
|
566
|
+
* const stringFields = omitBy(user, (key, value) => typeof value === "number");
|
|
567
|
+
*/
|
|
568
|
+
declare const omitBy: <T extends Record<string, any>>(obj: T, shouldOmit: (key: keyof T, value: T[keyof T]) => boolean) => Partial<T>;
|
|
569
|
+
//#endregion
|
|
570
|
+
//#region src/object/pick.d.ts
|
|
571
|
+
/**
|
|
572
|
+
* 从对象中选取指定的键,返回仅包含这些键的新对象
|
|
573
|
+
*
|
|
574
|
+
* @typeParam T - 源对象的类型
|
|
575
|
+
* @typeParam K - 要选取的键,必须是源对象的键之一
|
|
576
|
+
*
|
|
577
|
+
* @param obj - 源对象
|
|
578
|
+
* @param keys - 要选取的键名数组
|
|
579
|
+
* @returns 仅包含指定键的新对象
|
|
580
|
+
*
|
|
581
|
+
* @example
|
|
582
|
+
* const user = {
|
|
583
|
+
* id: 1,
|
|
584
|
+
* name: "Alice",
|
|
585
|
+
* age: 25,
|
|
586
|
+
* password: "secret"
|
|
587
|
+
* };
|
|
588
|
+
* // { id: 1, name: "Alice", age: 25 }
|
|
589
|
+
* const safeUser = pick(user, ["id", "name", "age"]);
|
|
590
|
+
*/
|
|
591
|
+
declare const pick: <T extends Record<string, any>, K extends keyof T>(obj: T, keys: readonly K[]) => Pick<T, K>;
|
|
592
|
+
/**
|
|
593
|
+
* 从对象中选取满足条件的键值对,返回仅包含这些键的新对象
|
|
594
|
+
*
|
|
595
|
+
* @typeParam T - 源对象的类型
|
|
596
|
+
*
|
|
597
|
+
* @param obj - 源对象
|
|
598
|
+
* @param shouldPick - 判断函数,返回 `true` 时保留该字段
|
|
599
|
+
* @returns 仅包含满足条件的键值对的新对象
|
|
600
|
+
*
|
|
601
|
+
* @example
|
|
602
|
+
* const user = {
|
|
603
|
+
* id: 1,
|
|
604
|
+
* name: "Alice",
|
|
605
|
+
* age: 25,
|
|
606
|
+
* password: "secret"
|
|
607
|
+
* };
|
|
608
|
+
* // { id: 1, age: 25 }
|
|
609
|
+
* const numericFields = pickBy(user, (key, value) => typeof value === "number");
|
|
610
|
+
*/
|
|
611
|
+
declare const pickBy: <T extends Record<string, any>>(obj: T, shouldPick: (key: keyof T, value: T[keyof T]) => boolean) => Partial<T>;
|
|
612
|
+
//#endregion
|
|
613
|
+
//#region src/string/case.d.ts
|
|
614
|
+
type SnakeToCamel<S extends string> = S extends `${infer Before}_${infer After}` ? After extends `${infer First}${infer Rest}` ? `${Before}${Uppercase<First>}${SnakeToCamel<Rest>}` : Before : S;
|
|
615
|
+
/**
|
|
616
|
+
* 下划线命名法转为驼峰命名法
|
|
617
|
+
*
|
|
618
|
+
* @example
|
|
619
|
+
* snakeToCamel("user_name") // "userName"
|
|
620
|
+
*/
|
|
621
|
+
declare const snakeToCamel: <S extends string>(str: S) => SnakeToCamel<S>;
|
|
622
|
+
type CamelToSnake<S extends string> = S extends `${infer First}${infer Rest}` ? Rest extends Uncapitalize<Rest> ? `${Lowercase<First>}${CamelToSnake<Rest>}` : `${Lowercase<First>}_${CamelToSnake<Rest>}` : Lowercase<S>;
|
|
623
|
+
/**
|
|
624
|
+
* 驼峰命名法转为下划线命名法
|
|
625
|
+
*
|
|
626
|
+
* @example
|
|
627
|
+
* camelToSnake("shouldComponentUpdate") // "should_component_update"
|
|
628
|
+
*/
|
|
629
|
+
declare const camelToSnake: <S extends string>(str: S) => CamelToSnake<S>;
|
|
630
|
+
type Capitalize<S extends string> = S extends `${infer P1}${infer Rest}` ? P1 extends Capitalize<P1> ? S : `${Uppercase<P1>}${Rest}` : S;
|
|
631
|
+
/**
|
|
632
|
+
* 字符串首字母大写
|
|
633
|
+
*
|
|
634
|
+
* @example
|
|
635
|
+
* capitalize("hello") // "Hello"
|
|
636
|
+
*/
|
|
637
|
+
declare const capitalize: <S extends string>(s: S) => Capitalize<S>;
|
|
638
|
+
type Decapitalize<S extends string> = S extends `${infer P1}${infer Rest}` ? P1 extends Lowercase<P1> ? P1 : `${Lowercase<P1>}${Rest}` : S;
|
|
639
|
+
/**
|
|
640
|
+
* 字符串首字母小写
|
|
641
|
+
*
|
|
642
|
+
* @example
|
|
643
|
+
* decapitalize("Hello") // "hello"
|
|
644
|
+
*/
|
|
645
|
+
declare const decapitalize: <S extends string>(s: S) => Decapitalize<S>;
|
|
646
|
+
//#endregion
|
|
647
|
+
//#region src/string/compact.d.ts
|
|
648
|
+
/**
|
|
649
|
+
* 将字符串压缩为单行精简格式
|
|
650
|
+
*
|
|
651
|
+
* @example
|
|
652
|
+
* // "Hello\nworld"
|
|
653
|
+
* compactStr(`Hello,
|
|
654
|
+
*
|
|
655
|
+
* world
|
|
656
|
+
*
|
|
657
|
+
* !`);
|
|
658
|
+
*
|
|
659
|
+
* @example
|
|
660
|
+
* // "Hello...world"
|
|
661
|
+
* compactStr("Hello, beautiful world!", { maxLength: 15 });
|
|
662
|
+
*/
|
|
663
|
+
declare const compactStr: (text?: string, options?: {
|
|
664
|
+
/**
|
|
665
|
+
* 最大保留长度,超过该长度使用 "..." 替代
|
|
666
|
+
@default Infinity
|
|
667
|
+
*/
|
|
668
|
+
maxLength?: number;
|
|
669
|
+
/**
|
|
670
|
+
* 是否将换行符替换为字面量"\n"
|
|
671
|
+
* @default false
|
|
672
|
+
*/
|
|
673
|
+
disableNewLineReplace?: boolean;
|
|
674
|
+
/**
|
|
675
|
+
* 是否合并连续的换行符/制表符为单个
|
|
676
|
+
* @default false
|
|
677
|
+
*/
|
|
678
|
+
disableCollapse?: boolean;
|
|
679
|
+
}) => string;
|
|
680
|
+
//#endregion
|
|
681
|
+
//#region src/string/extract-error-message.d.ts
|
|
682
|
+
/** 从任意异常中提取类似 error.message 的可读文字 */
|
|
683
|
+
declare const extractErrorMessage: (error: unknown) => string;
|
|
684
|
+
//#endregion
|
|
685
|
+
//#region src/string/qs.d.ts
|
|
686
|
+
/**
|
|
687
|
+
* 针对 URL 查询字符串的解析和序列化
|
|
688
|
+
* @example
|
|
689
|
+
* qs.parse("?a=1&b=2") // { a: 1, b: 2 }
|
|
690
|
+
* qs.stringify({ a: 1, b: 2 }, { addQueryPrefix: true }) // "?a=1&b=2"
|
|
691
|
+
*/
|
|
692
|
+
declare const qs: {
|
|
693
|
+
/** queryString -> queryParams */parse: (queryString: string) => Record<string, any>;
|
|
694
|
+
stringify: (params: Record<string, any>, options?: {
|
|
695
|
+
/**
|
|
696
|
+
* 是否在结果前添加“?”
|
|
697
|
+
* @default false
|
|
698
|
+
*/
|
|
699
|
+
addQueryPrefix: boolean;
|
|
700
|
+
}) => string;
|
|
701
|
+
};
|
|
702
|
+
//#endregion
|
|
703
|
+
//#region src/time/debounce.d.ts
|
|
704
|
+
/**
|
|
705
|
+
* 防抖:在指定时间内只执行最后一次调用
|
|
706
|
+
* @param fn 要防抖的函数
|
|
707
|
+
* @param delay 延迟时间,默认 300ms
|
|
708
|
+
*
|
|
709
|
+
* @remarks
|
|
710
|
+
* 连续触发时,只有最后一次会执行。适合用于搜索框输入、窗口大小调整等场景。
|
|
711
|
+
* 例如:用户输入"hello"过程中,不会触发搜索,只有停下来时才执行。
|
|
712
|
+
*
|
|
713
|
+
* 防抖 vs 节流:
|
|
714
|
+
* - 防抖:等待触发停止后才执行(最后一次)
|
|
715
|
+
* - 节流:按固定节奏执行(每隔多久执行一次)
|
|
716
|
+
*
|
|
717
|
+
* @example
|
|
718
|
+
* const search = debounce((keyword: string) => {
|
|
719
|
+
* console.log('搜索:', keyword);
|
|
720
|
+
* });
|
|
721
|
+
* search('hello'); // 300ms 后执行
|
|
722
|
+
*/
|
|
723
|
+
declare const debounce: <T extends (...args: any[]) => any>(fn: T, delay?: number) => (...args: Parameters<T>) => void;
|
|
724
|
+
//#endregion
|
|
725
|
+
//#region src/time/lock-queue.d.ts
|
|
726
|
+
/**
|
|
727
|
+
* 排队锁
|
|
728
|
+
*
|
|
729
|
+
* @remarks
|
|
730
|
+
* 使用场景如:同时给大模型发送多条消息,使其依次回复
|
|
731
|
+
*
|
|
732
|
+
* @example
|
|
733
|
+
* const queue = new LockQueue();
|
|
734
|
+
* const messages = [];
|
|
735
|
+
*
|
|
736
|
+
* const chatCompletions = async () => {
|
|
737
|
+
* // 等待前一个队列释放
|
|
738
|
+
* const release = await queue.waitInQueue();
|
|
739
|
+
*
|
|
740
|
+
* const message = await requestLLM();
|
|
741
|
+
* messages.push(message);
|
|
742
|
+
* sendMessage(message);
|
|
743
|
+
*
|
|
744
|
+
* // 释放队列
|
|
745
|
+
* release();
|
|
746
|
+
* };
|
|
747
|
+
*
|
|
748
|
+
* chatCompletions();
|
|
749
|
+
* chatCompletions();
|
|
750
|
+
* chatCompletions();
|
|
751
|
+
*/
|
|
752
|
+
declare class LockQueue {
|
|
753
|
+
queue: Promise<any>;
|
|
754
|
+
constructor();
|
|
755
|
+
waitInQueue(): Promise<(value?: any) => void>;
|
|
756
|
+
}
|
|
757
|
+
//#endregion
|
|
758
|
+
//#region src/time/sleep.d.ts
|
|
759
|
+
/**
|
|
760
|
+
* 延迟一段时间再执行后续代码
|
|
761
|
+
* @param time 延迟时间,默认 150ms
|
|
762
|
+
* @example
|
|
763
|
+
* await sleep(1000); // 等待 1 秒执行后续代码
|
|
764
|
+
*/
|
|
765
|
+
declare const sleep: (time?: number) => Promise<unknown>;
|
|
766
|
+
//#endregion
|
|
767
|
+
//#region src/time/throttle.d.ts
|
|
768
|
+
/**
|
|
769
|
+
* 节流函数 - 在指定时间间隔内最多执行一次调用
|
|
770
|
+
* @param fn 要节流的函数
|
|
771
|
+
* @param delay 间隔时间,默认 300ms
|
|
772
|
+
*
|
|
773
|
+
* @remarks
|
|
774
|
+
* 节流:连续触发时,按照固定间隔执行。适合用于滚动、拖拽等高频触发场景。
|
|
775
|
+
* 例如:滚动页面时,每300ms最多执行一次回调,而不是每次滚动都执行。
|
|
776
|
+
*
|
|
777
|
+
* 防抖 vs 节流:
|
|
778
|
+
* - 防抖:等待触发停止后才执行(最后一次)
|
|
779
|
+
* - 节流:按固定节奏执行(每隔多久执行一次)
|
|
780
|
+
*
|
|
781
|
+
* @example
|
|
782
|
+
* const handleScroll = throttle(() => {
|
|
783
|
+
* console.log('滚动位置:', window.scrollY);
|
|
784
|
+
* }, 200);
|
|
785
|
+
* window.addEventListener('scroll', handleScroll);
|
|
786
|
+
*/
|
|
787
|
+
declare const throttle: <T extends (...args: any[]) => any>(fn: T, delay?: number) => (this: any, ...args: Parameters<T>) => void;
|
|
788
|
+
//#endregion
|
|
785
789
|
export { CamelToSnake, Capitalize, type ChatCompletions, Decapitalize, DeepMapKeys, DeepMapValues, ImageCompressionOptions, LockQueue, LogOptions, Primitive, RequestInit, SetTtl, SnakeToCamel, camelToSnake, capitalize, chatCompletions, compactStr, debounce, decapitalize, defineModel, extractErrorMessage, fetcher, getRealURL, imageUrlToBase64, isNil, isObject, isPrimitive, log, loopUntil, mapKeys, mapValues, mergeObjects, omit, omitBy, pick, pickBy, qs, randomInt, sleep, snakeToCamel, throttle, to, withCache };
|