@dan-uni/dan-any 1.3.0 → 1.3.4

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.
@@ -10,6 +10,7 @@ interface DanUniConvertTip {
10
10
  version: string;
11
11
  data?: string;
12
12
  }
13
+ export type DM_JSON_DanuniMin = Partial<UniDMTools.UniDMObj>[];
13
14
  export interface DM_XML_Bili {
14
15
  i: {
15
16
  chatserver: string;
@@ -140,6 +141,22 @@ export interface Options {
140
141
  */
141
142
  dmid?: boolean | number | UniIDTools.DMIDGenerator;
142
143
  }
144
+ type Convert2Format = DM_format.DanuniJson | DM_format.DanuniMinJson | DM_format.DanuniPbBin | DM_format.BiliXml | DM_format.DplayerJson | DM_format.ArtplayerJson | DM_format.DdplayJson;
145
+ type Convert2ResultMap = {
146
+ [DM_format.DanuniJson]: UniDM[];
147
+ [DM_format.DanuniMinJson]: DM_JSON_DanuniMin;
148
+ [DM_format.DanuniPbBin]: Uint8Array;
149
+ [DM_format.BiliXml]: string;
150
+ [DM_format.DplayerJson]: DM_JSON_Dplayer & {
151
+ danuni?: DanUniConvertTip;
152
+ };
153
+ [DM_format.ArtplayerJson]: DM_JSON_Artplayer & {
154
+ danuni?: DanUniConvertTip;
155
+ };
156
+ [DM_format.DdplayJson]: DM_JSON_DDPlay & {
157
+ danuni?: DanUniConvertTip;
158
+ };
159
+ };
143
160
  export declare class UniPool {
144
161
  dans: UniDM[];
145
162
  options: Options;
@@ -200,19 +217,15 @@ export declare class UniPool {
200
217
  minify(): (Partial<UniDMTools.UniDMObj> & Pick<UniDMTools.UniDMObj, "SOID">)[];
201
218
  static import(file: unknown, options?: Options,
202
219
  /**
203
- * 加载指定解析模块,为空则全选
220
+ * 加载指定解析模块,为空则全选,为字符串则视为文件名解析加载模块
204
221
  */
205
- mod?: ('json' | 'str' | 'bin')[]): {
222
+ mod?: string | ('json' | 'str' | 'bin')[]): {
206
223
  pool: UniPool;
207
224
  fmt: DM_format;
208
225
  };
209
- convert2(format: DM_format, continue_on_error?: boolean): string | Uint8Array<ArrayBuffer> | UniDM[] | (Partial<UniDMTools.UniDMObj> & Pick<UniDMTools.UniDMObj, "SOID">)[] | (DM_JSON_Dplayer & {
210
- danuni?: DanUniConvertTip;
211
- }) | (DM_JSON_Artplayer & {
212
- danuni?: DanUniConvertTip;
213
- }) | (DM_JSON_DDPlay & {
214
- danuni?: DanUniConvertTip;
215
- });
226
+ convert2<T extends Convert2Format>(format: T, file_wrapper: true, continue_on_error?: boolean): File;
227
+ convert2<T extends Convert2Format>(format: T, file_wrapper?: false, continue_on_error?: boolean): Convert2ResultMap[T];
228
+ static fromMin(json: DM_JSON_DanuniMin, options?: Options): UniPool;
216
229
  static fromPb(bin: Uint8Array | ArrayBuffer, options?: Options): UniPool;
217
230
  /**
218
231
  * 转为 protobuf 二进制
@@ -0,0 +1,3 @@
1
+ export declare function fileParser(file: unknown, mod: 'bin'): ArrayBuffer | Uint8Array;
2
+ export declare function fileParser(file: unknown, mod: 'string'): string;
3
+ export declare function fileParser<T extends object>(file: unknown, mod: 'json'): T;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dan-uni/dan-any",
3
3
  "type": "module",
4
- "version": "1.3.0",
4
+ "version": "1.3.4",
5
5
  "description": "A danmaku transformer lib, supporting danmaku from different platforms.",
6
6
  "author": "rinne",
7
7
  "license": "LGPL-3.0-or-later",
@@ -35,9 +35,8 @@
35
35
  "@bufbuild/protobuf": "^2.11.0",
36
36
  "base16384": "^1.0.0",
37
37
  "class-transformer": "^0.5.1",
38
- "class-validator": "^0.14.3",
39
- "fast-xml-parser": "^5.3.6",
40
- "fs-extra": "^11.3.3",
38
+ "class-validator": "^0.15.1",
39
+ "fast-xml-parser": "^5.5.8",
41
40
  "hh-mm-ss": "^1.2.0",
42
41
  "json-bigint": "^1.0.0",
43
42
  "jssha": "^3.3.1",
@@ -45,13 +44,12 @@
45
44
  "reflect-metadata": "^0.2.2"
46
45
  },
47
46
  "devDependencies": {
48
- "@bufbuild/buf": "^1.65.0",
47
+ "@bufbuild/buf": "^1.66.1",
49
48
  "@bufbuild/protoc-gen-es": "^2.11.0",
50
- "@types/fs-extra": "^11.0.4",
51
49
  "@types/hh-mm-ss": "^1.2.3",
52
50
  "@types/json-bigint": "^1.0.4",
53
51
  "@types/luxon": "^3.7.1",
54
- "canvas": "^3.2.1",
52
+ "canvas": "^3.2.2",
55
53
  "protobufjs": "^8.0.0"
56
54
  }
57
55
  }
package/src/index.test.ts CHANGED
@@ -37,6 +37,8 @@ describe('转化自', () => {
37
37
  const imp = UniPool.import(xml)
38
38
  expect(imp.fmt).toBe('bili.xml')
39
39
  expect(imp.pool).toEqual(pool)
40
+ const imp2 = UniPool.import(xml, undefined, 'test-bili.xml')
41
+ expect(imp2).toEqual(imp)
40
42
  })
41
43
  it('artplayer(json)', () => {
42
44
  const json = {
@@ -56,7 +58,10 @@ describe('转化自', () => {
56
58
  console.info(pool)
57
59
  const imp = UniPool.import(json)
58
60
  expect(imp.fmt).toBe('artplayer.json')
61
+ // 该适配器ctime始终为now,无法双向测试
59
62
  // expect(imp.pool).toEqual(pool)
63
+ UniPool.import(json, undefined, 'test-artplayer.json')
64
+ // expect(imp2).toEqual(imp)
60
65
  })
61
66
  it('ass[双向]', () => {
62
67
  const canvas = createCanvas(50, 50)
@@ -67,6 +72,8 @@ describe('转化自', () => {
67
72
  const imp = UniPool.import(ass)
68
73
  expect(imp.fmt).toBe('common.ass')
69
74
  expect(imp.pool).toEqual(pool)
75
+ const imp2 = UniPool.import(ass, undefined, 'test-common.ass')
76
+ expect(imp2).toEqual(imp)
70
77
  })
71
78
  it('pb[双向]', () => {
72
79
  const pool = UniPool.fromBiliXML(xml)
@@ -75,6 +82,8 @@ describe('转化自', () => {
75
82
  const imp = UniPool.import(pb)
76
83
  expect(imp.fmt).toBe('danuni.binpb')
77
84
  expect(imp.pool).toEqual(pool)
85
+ const imp2 = UniPool.import(pb, undefined, 'test-danuni.binpb')
86
+ expect(imp2).toEqual(imp)
78
87
  })
79
88
  it('DDplay[双向]', () => {
80
89
  const pool = UniPool.fromBiliXML(xml)
@@ -82,7 +91,20 @@ describe('转化自', () => {
82
91
  console.info(UniPool.fromDDPlay(ddplay, '1'))
83
92
  const imp = UniPool.import(ddplay)
84
93
  expect(imp.fmt).toBe('ddplay.json')
94
+ // 该适配器ctime始终为now,无法双向测试
95
+ UniPool.import(ddplay, undefined, 'test-ddplay.json')
96
+ // expect(imp2).toEqual(imp)
97
+ })
98
+ it('min[双向]', () => {
99
+ const pool = UniPool.fromBiliXML(xml)
100
+ const min = pool.minify()
101
+ console.info(min)
102
+ const imp = UniPool.import(min)
103
+ expect(imp.fmt).toBe('danuni.min.json')
104
+ // 该适配器ctime始终为now,无法双向测试
85
105
  // expect(imp.pool).toEqual(pool)
106
+ UniPool.import(min, undefined, 'test-danuni.min.json')
107
+ // expect(imp2).toEqual(imp)
86
108
  })
87
109
  })
88
110
 
package/src/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import 'reflect-metadata/lite'
2
2
 
3
- import { isJSON, isObject, isString } from 'class-validator'
3
+ import { isJSON, isString } from 'class-validator'
4
4
  import { XMLBuilder, XMLParser } from 'fast-xml-parser'
5
5
  import JSONbig from 'json-bigint'
6
6
  import type { Options as AssGenOptions, CanvasCtx } from './ass-gen'
@@ -26,6 +26,7 @@ import { ListDanResponseSchema } from './proto/gen/danuni/danmaku/v1/danmaku_pb'
26
26
 
27
27
  import { UniDM } from './utils/dm-gen'
28
28
  import * as UniDMTools from './utils/dm-gen'
29
+ import { fileParser } from './utils/fileParser'
29
30
  import { UniID as ID } from './utils/id-gen'
30
31
  import * as UniIDTools from './utils/id-gen'
31
32
  import * as platform from './utils/platform'
@@ -45,6 +46,8 @@ interface DanUniConvertTip {
45
46
  data?: string
46
47
  }
47
48
 
49
+ export type DM_JSON_DanuniMin = Partial<UniDMTools.UniDMObj>[]
50
+
48
51
  export interface DM_XML_Bili {
49
52
  i: {
50
53
  chatserver: string
@@ -197,6 +200,24 @@ export interface Options {
197
200
  dmid?: boolean | number | UniIDTools.DMIDGenerator
198
201
  }
199
202
 
203
+ type Convert2Format =
204
+ | DM_format.DanuniJson
205
+ | DM_format.DanuniMinJson
206
+ | DM_format.DanuniPbBin
207
+ | DM_format.BiliXml
208
+ | DM_format.DplayerJson
209
+ | DM_format.ArtplayerJson
210
+ | DM_format.DdplayJson
211
+ type Convert2ResultMap = {
212
+ [DM_format.DanuniJson]: UniDM[]
213
+ [DM_format.DanuniMinJson]: DM_JSON_DanuniMin
214
+ [DM_format.DanuniPbBin]: Uint8Array
215
+ [DM_format.BiliXml]: string
216
+ [DM_format.DplayerJson]: DM_JSON_Dplayer & { danuni?: DanUniConvertTip }
217
+ [DM_format.ArtplayerJson]: DM_JSON_Artplayer & { danuni?: DanUniConvertTip }
218
+ [DM_format.DdplayJson]: DM_JSON_DDPlay & { danuni?: DanUniConvertTip }
219
+ }
220
+
200
221
  export class UniPool {
201
222
  constructor(
202
223
  public dans: UniDM[],
@@ -449,10 +470,120 @@ export class UniPool {
449
470
  file: unknown,
450
471
  options?: Options,
451
472
  /**
452
- * 加载指定解析模块,为空则全选
473
+ * 加载指定解析模块,为空则全选,为字符串则视为文件名解析加载模块
453
474
  */
454
- mod?: ('json' | 'str' | 'bin')[],
475
+ mod?: string | ('json' | 'str' | 'bin')[],
455
476
  ): { pool: UniPool; fmt: DM_format } {
477
+ const handlers = {
478
+ [DM_format.DanuniJson]: (json: UniDM[]) => ({
479
+ pool: new UniPool(json, options),
480
+ fmt: DM_format.DanuniJson,
481
+ }),
482
+ [DM_format.DanuniMinJson]: (json: DM_JSON_DanuniMin) => ({
483
+ pool: this.fromMin(json, options),
484
+ fmt: DM_format.DanuniMinJson,
485
+ }),
486
+ [DM_format.DanuniPbBin]: (
487
+ file: ArrayBuffer | Uint8Array<ArrayBufferLike>,
488
+ ) => ({
489
+ pool: this.fromPb(file),
490
+ fmt: DM_format.DanuniPbBin,
491
+ }),
492
+ [DM_format.BiliXml]: (file: string) => ({
493
+ pool: this.fromBiliXML(file, options),
494
+ fmt: DM_format.BiliXml,
495
+ }),
496
+ [DM_format.BiliPbBin]: (
497
+ file: ArrayBuffer | Uint8Array<ArrayBufferLike>,
498
+ ) => ({
499
+ pool: this.fromBiliGrpc(file),
500
+ fmt: DM_format.BiliPbBin,
501
+ }),
502
+ [DM_format.BiliCmdPbBin]: (
503
+ file: ArrayBuffer | Uint8Array<ArrayBufferLike>,
504
+ ) => ({
505
+ pool: this.fromBiliCommandGrpc(file),
506
+ fmt: DM_format.BiliCmdPbBin,
507
+ }),
508
+ [DM_format.BiliUpJson]: (json: DM_JSON_BiliUp) => ({
509
+ pool: this.fromBiliUp(json, options),
510
+ fmt: DM_format.BiliUpJson,
511
+ }),
512
+ [DM_format.DplayerJson]: (
513
+ json: DM_JSON_Dplayer & {
514
+ danuni?: DanUniConvertTip
515
+ },
516
+ ) => ({
517
+ pool: this.fromDplayer(
518
+ json,
519
+ json.danuni?.data ?? '',
520
+ undefined,
521
+ options,
522
+ ),
523
+ fmt: DM_format.DplayerJson,
524
+ }),
525
+ [DM_format.ArtplayerJson]: (
526
+ json: DM_JSON_Artplayer & {
527
+ danuni?: DanUniConvertTip
528
+ },
529
+ ) => ({
530
+ pool: this.fromArtplayer(
531
+ json,
532
+ json.danuni?.data ?? '',
533
+ undefined,
534
+ options,
535
+ ),
536
+ fmt: DM_format.ArtplayerJson,
537
+ }),
538
+ [DM_format.DdplayJson]: (
539
+ json: DM_JSON_DDPlay & {
540
+ danuni?: DanUniConvertTip
541
+ },
542
+ ) => ({
543
+ pool: this.fromDDPlay(json, json.danuni?.data ?? '', options),
544
+ fmt: DM_format.DdplayJson,
545
+ }),
546
+ [DM_format.CommonAss]: (file: string) => ({
547
+ pool: this.fromASS(file, options),
548
+ fmt: DM_format.CommonAss,
549
+ }),
550
+ }
551
+
552
+ if (typeof mod === 'string') {
553
+ const fn = mod
554
+ // 直接按照默认模式处理匹配后缀的文件
555
+ try {
556
+ if (fn.endsWith(DM_format.DanuniJson)) {
557
+ return handlers[DM_format.DanuniJson](fileParser(file, 'json'))
558
+ } else if (fn.endsWith(DM_format.DanuniMinJson))
559
+ return handlers[DM_format.DanuniMinJson](fileParser(file, 'json'))
560
+ else if (fn.endsWith(DM_format.DanuniPbBin))
561
+ return handlers[DM_format.DanuniPbBin](fileParser(file, 'bin'))
562
+ else if (fn.endsWith(DM_format.BiliXml))
563
+ return handlers[DM_format.BiliXml](fileParser(file, 'string'))
564
+ else if (fn.endsWith(DM_format.BiliPbBin))
565
+ return handlers[DM_format.BiliPbBin](fileParser(file, 'bin'))
566
+ else if (fn.endsWith(DM_format.BiliCmdPbBin))
567
+ return handlers[DM_format.BiliCmdPbBin](fileParser(file, 'bin'))
568
+ else if (fn.endsWith(DM_format.BiliUpJson))
569
+ return handlers[DM_format.BiliUpJson](fileParser(file, 'json'))
570
+ else if (fn.endsWith(DM_format.DplayerJson))
571
+ return handlers[DM_format.DplayerJson](fileParser(file, 'json'))
572
+ else if (fn.endsWith(DM_format.ArtplayerJson))
573
+ return handlers[DM_format.ArtplayerJson](fileParser(file, 'json'))
574
+ else if (fn.endsWith(DM_format.DdplayJson))
575
+ return handlers[DM_format.DdplayJson](fileParser(file, 'json'))
576
+ else if (fn.endsWith(DM_format.CommonAss))
577
+ return handlers[DM_format.CommonAss](fileParser(file, 'string'))
578
+ } catch {}
579
+ // 按照后缀设定启用模块
580
+ const ext = fn.split('.').pop()?.toLowerCase()
581
+ if (ext) {
582
+ if (ext === 'json') mod = ['json']
583
+ else if (['xml', 'ass'].includes(ext)) mod = ['str']
584
+ else if (['binpb', 'bin', 'so'].includes(ext)) mod = ['bin']
585
+ }
586
+ }
456
587
  if (!mod) mod = ['json', 'str', 'bin']
457
588
  const err = '无法识别该文件,请手动指定格式!'
458
589
  const parseJSON = (
@@ -463,42 +594,23 @@ export class UniPool {
463
594
  ): { pool: UniPool; fmt: DM_format } | undefined => {
464
595
  try {
465
596
  if (Array.isArray(json) && json.every((d) => d.SOID)) {
466
- return { pool: new UniPool(json, options), fmt: DM_format.DanuniJson }
597
+ return handlers[DM_format.DanuniMinJson](json) // 使用兼容性参数,danuni.min.json解析器可以解析danuni.json
467
598
  } else if (json.danmuku && json.danmuku.every((d) => d.text)) {
468
- return {
469
- pool: this.fromArtplayer(
470
- json,
471
- json.danuni?.data ?? '',
472
- undefined,
473
- options,
474
- ),
475
- fmt: DM_format.ArtplayerJson,
476
- }
599
+ return handlers[DM_format.ArtplayerJson](json)
477
600
  } else if (
478
601
  json.count &&
479
602
  json.comments &&
480
603
  Array.isArray(json.comments) &&
481
604
  json.comments.every((d) => d.m)
482
605
  ) {
483
- return {
484
- pool: this.fromDDPlay(json, json.danuni?.data ?? '', options),
485
- fmt: DM_format.DdplayJson,
486
- }
606
+ return handlers[DM_format.DdplayJson](json)
487
607
  } else if (
488
608
  json.code == 0 &&
489
609
  json.data &&
490
610
  Array.isArray(json.data) &&
491
611
  json.data.every((d) => Array.isArray(d))
492
612
  ) {
493
- return {
494
- pool: this.fromDplayer(
495
- json,
496
- json.danuni?.data ?? '',
497
- undefined,
498
- options,
499
- ),
500
- fmt: DM_format.DplayerJson,
501
- }
613
+ return handlers[DM_format.DplayerJson](json)
502
614
  } else if (
503
615
  json.code == 0 &&
504
616
  json.message == '0' &&
@@ -508,10 +620,7 @@ export class UniPool {
508
620
  Array.isArray(json.data.result) &&
509
621
  json.data.result.every((d) => d.id && d.oid)
510
622
  ) {
511
- return {
512
- pool: this.fromBiliUp(json, options),
513
- fmt: DM_format.BiliUpJson,
514
- }
623
+ return handlers[DM_format.BiliUpJson](json)
515
624
  }
516
625
  } catch {}
517
626
  }
@@ -531,33 +640,26 @@ export class UniPool {
531
640
  try {
532
641
  const xmlParser = new XMLParser({ ignoreAttributes: false })
533
642
  const xml = xmlParser.parse(file)
534
- if (xml?.i?.d)
535
- return {
536
- pool: this.fromBiliXML(file, options),
537
- fmt: DM_format.BiliXml,
538
- }
643
+ if (xml?.i?.d) return handlers[DM_format.BiliXml](file)
539
644
  } catch {}
540
645
  try {
541
- return { pool: this.fromASS(file, options), fmt: DM_format.CommonAss }
646
+ return handlers[DM_format.CommonAss](file)
542
647
  } catch {}
543
648
  }
544
649
  }
545
650
  let errmesg
546
- if (isObject(file)) {
651
+ if (typeof file === 'object' || Array.isArray(file)) {
547
652
  if (file instanceof ArrayBuffer || file instanceof Uint8Array) {
548
653
  // pure-bin (pb)
549
654
  if (mod.includes('bin')) {
550
655
  try {
551
- return { pool: this.fromPb(file), fmt: DM_format.DanuniPbBin }
656
+ return handlers[DM_format.DanuniPbBin](file)
552
657
  } catch {}
553
658
  try {
554
- return { pool: this.fromBiliGrpc(file), fmt: DM_format.BiliPbBin }
659
+ return handlers[DM_format.BiliPbBin](file)
555
660
  } catch {}
556
661
  try {
557
- return {
558
- pool: this.fromBiliCommandGrpc(file),
559
- fmt: DM_format.BiliCmdPbBin,
560
- }
662
+ return handlers[DM_format.BiliCmdPbBin](file)
561
663
  } catch {}
562
664
  }
563
665
  // str-bin (pure-str + json-str)
@@ -585,27 +687,87 @@ export class UniPool {
585
687
  }
586
688
  throw new Error(errmesg ?? err)
587
689
  }
588
- convert2(format: DM_format, continue_on_error = false) {
690
+ convert2<T extends Convert2Format>(
691
+ format: T,
692
+ file_wrapper: true,
693
+ continue_on_error?: boolean,
694
+ ): File
695
+ convert2<T extends Convert2Format>(
696
+ format: T,
697
+ file_wrapper?: false,
698
+ continue_on_error?: boolean,
699
+ ): Convert2ResultMap[T]
700
+ convert2(
701
+ format: DM_format,
702
+ file_wrapper = false,
703
+ continue_on_error = false,
704
+ ): File | Convert2ResultMap[Convert2Format] | string {
589
705
  switch (format) {
590
- case 'danuni.json':
591
- return this.dans
592
- case 'danuni.min.json':
593
- return this.minify()
594
- case 'danuni.binpb':
595
- return this.toPb()
596
- case 'bili.xml':
597
- return this.toBiliXML()
598
- // case 'bili.binpb':
706
+ case DM_format.DanuniJson:
707
+ if (file_wrapper)
708
+ return new File([JSON.stringify(this.dans)], DM_format.DanuniJson, {
709
+ type: 'application/json',
710
+ })
711
+ else return this.dans
712
+ case DM_format.DanuniMinJson:
713
+ if (file_wrapper)
714
+ return new File(
715
+ [JSON.stringify(this.minify())],
716
+ DM_format.DanuniMinJson,
717
+ {
718
+ type: 'application/json',
719
+ },
720
+ )
721
+ else return this.minify()
722
+ case DM_format.DanuniPbBin:
723
+ if (file_wrapper)
724
+ return new File([this.toPb()], DM_format.DanuniPbBin, {
725
+ type: 'application/protobuf',
726
+ })
727
+ else return this.toPb()
728
+ case DM_format.BiliXml:
729
+ if (file_wrapper)
730
+ return new File([this.toBiliXML()], DM_format.BiliXml, {
731
+ type: 'application/xml',
732
+ })
733
+ else return this.toBiliXML()
734
+ // case DM_format.BiliPbBin:
599
735
  // return this.toBiliBin()
600
- // case 'bili.cmd.binpb':
736
+ // case DM_format.BiliCmdPbBin:
601
737
  // return this.toBiliCmdBin()
602
- case 'dplayer.json':
738
+ // case DM_format.BiliUpJson:
739
+ // return this.toBiliUp()
740
+ case DM_format.DplayerJson:
741
+ if (file_wrapper)
742
+ return new File(
743
+ [JSON.stringify(this.toDplayer())],
744
+ DM_format.DplayerJson,
745
+ {
746
+ type: 'application/json',
747
+ },
748
+ )
603
749
  return this.toDplayer()
604
- case 'artplayer.json':
750
+ case DM_format.ArtplayerJson:
751
+ if (file_wrapper)
752
+ return new File(
753
+ [JSON.stringify(this.toArtplayer())],
754
+ DM_format.ArtplayerJson,
755
+ {
756
+ type: 'application/json',
757
+ },
758
+ )
605
759
  return this.toArtplayer()
606
- case 'ddplay.json':
760
+ case DM_format.DdplayJson:
761
+ if (file_wrapper)
762
+ return new File(
763
+ [JSON.stringify(this.toDDplay())],
764
+ DM_format.DdplayJson,
765
+ {
766
+ type: 'application/json',
767
+ },
768
+ )
607
769
  return this.toDDplay()
608
- // case 'common.ass':
770
+ // case DM_format.CommonAss:
609
771
  // return this.toASS()
610
772
  default: {
611
773
  const message = '(err) Unknown format or unsupported now!'
@@ -614,6 +776,9 @@ export class UniPool {
614
776
  }
615
777
  }
616
778
  }
779
+ static fromMin(json: DM_JSON_DanuniMin, options?: Options) {
780
+ return new UniPool(json.map((d: any) => UniDM.create(d, options)))
781
+ }
617
782
  static fromPb(bin: Uint8Array | ArrayBuffer, options?: Options) {
618
783
  const data = fromBinary(ListDanResponseSchema, new Uint8Array(bin))
619
784
  return new UniPool(
@@ -479,7 +479,7 @@ export class UniDM {
479
479
  if (!this.SOID) this.SOID = def.SOID
480
480
  if (!this.progress) this.progress = def.progress
481
481
  if (!this.mode) this.mode = def.mode
482
- if (!this.fontsize) this.fontsize = def.mode
482
+ if (!this.fontsize) this.fontsize = def.fontsize
483
483
  if (!this.color) this.color = def.color
484
484
  if (!this.senderID) this.senderID = def.senderID
485
485
  if (!this.content) this.content = def.content
@@ -0,0 +1,37 @@
1
+ export function fileParser(file: unknown, mod: 'bin'): ArrayBuffer | Uint8Array
2
+ export function fileParser(file: unknown, mod: 'string'): string
3
+ export function fileParser<T extends object>(file: unknown, mod: 'json'): T
4
+ export function fileParser(
5
+ file: unknown,
6
+ mod: 'bin' | 'string' | 'json',
7
+ ): ArrayBuffer | Uint8Array | string | object {
8
+ const isBinary = file instanceof ArrayBuffer || file instanceof Uint8Array
9
+ switch (mod) {
10
+ case 'bin': {
11
+ if (isBinary) return file
12
+ throw new TypeError('Expected binary data for mod "bin"')
13
+ }
14
+ case 'string': {
15
+ if (typeof file === 'string') return file
16
+ if (isBinary) return new TextDecoder().decode(file)
17
+ throw new TypeError('Expected binary data or string for mod "string"')
18
+ }
19
+ case 'json': {
20
+ if (typeof file === 'object' && file !== null && !isBinary) return file
21
+ if (typeof file !== 'string' && !isBinary) {
22
+ throw new TypeError(
23
+ 'Expected object, JSON string, or binary data for mod "json"',
24
+ )
25
+ }
26
+ const str =
27
+ typeof file === 'string' ? file : new TextDecoder().decode(file)
28
+ try {
29
+ return JSON.parse(str)
30
+ } catch {
31
+ throw new Error('Invalid JSON string')
32
+ }
33
+ }
34
+ default:
35
+ throw new Error(`Unsupported mod "${mod}"`)
36
+ }
37
+ }