type-flash 1.0.3 → 1.0.6
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 +44 -186
- package/dist/index.d.ts +44 -186
- package/dist/index.js +14 -6
- package/dist/index.mjs +14 -6
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* 类型定义文件
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
5
|
* 原始类型
|
|
@@ -51,14 +51,6 @@ interface LiteralType {
|
|
|
51
51
|
kind: 'literal';
|
|
52
52
|
value: string | number | boolean;
|
|
53
53
|
}
|
|
54
|
-
/**
|
|
55
|
-
* 枚举类型
|
|
56
|
-
*/
|
|
57
|
-
interface EnumType {
|
|
58
|
-
kind: 'enum';
|
|
59
|
-
name: string;
|
|
60
|
-
values: (string | number)[];
|
|
61
|
-
}
|
|
62
54
|
/**
|
|
63
55
|
* null 类型
|
|
64
56
|
*/
|
|
@@ -82,7 +74,7 @@ interface GenericType {
|
|
|
82
74
|
/**
|
|
83
75
|
* TS 类型节点(联合类型,支持 discriminated union 类型收窄)
|
|
84
76
|
*/
|
|
85
|
-
type TSTypeNode = PrimitiveType | ArrayType | ObjectType | UnionType | LiteralType |
|
|
77
|
+
type TSTypeNode = PrimitiveType | ArrayType | ObjectType | UnionType | LiteralType | NullType | UndefinedType | GenericType;
|
|
86
78
|
/**
|
|
87
79
|
* 命名风格
|
|
88
80
|
*/
|
|
@@ -115,10 +107,6 @@ interface GenerateOptions {
|
|
|
115
107
|
strictNullChecks?: boolean;
|
|
116
108
|
/** 是否将可选属性标记为 ?,默认 true */
|
|
117
109
|
markOptional?: boolean;
|
|
118
|
-
/** 是否提取枚举类型,默认 true */
|
|
119
|
-
extractEnums?: boolean;
|
|
120
|
-
/** 枚举提取阈值(字段不同值数量 ≤ 此值时提取为枚举),默认 5 */
|
|
121
|
-
enumThreshold?: number;
|
|
122
110
|
/** 是否提取泛型(如 PageResult<T>),默认 true */
|
|
123
111
|
extractGenerics?: boolean;
|
|
124
112
|
/** 缩进空格数,默认 2 */
|
|
@@ -295,11 +283,9 @@ declare class TypeCollector {
|
|
|
295
283
|
* ts-gen - 格式化输出模块
|
|
296
284
|
*
|
|
297
285
|
* 核心功能:
|
|
298
|
-
* -
|
|
286
|
+
* - 将类型节点格式化为 TypeScript 代码字符串
|
|
299
287
|
* - 支持 interface 和 type alias 两种输出风格
|
|
300
|
-
* -
|
|
301
|
-
* - 支持导出语句
|
|
302
|
-
* - 支持 JSDoc 注释生成
|
|
288
|
+
* - 自动缩进、排序、注释生成
|
|
303
289
|
*/
|
|
304
290
|
|
|
305
291
|
/**
|
|
@@ -308,23 +294,25 @@ declare class TypeCollector {
|
|
|
308
294
|
declare class CodeFormatter {
|
|
309
295
|
private options;
|
|
310
296
|
private namer;
|
|
297
|
+
/** 所有已命名的类型列表(用于查找引用) */
|
|
298
|
+
private allNamedTypes;
|
|
311
299
|
constructor(options: Required<GenerateOptions>, namer: TypeNamer);
|
|
312
300
|
/**
|
|
313
|
-
*
|
|
301
|
+
* 查找类型对应的命名(用于对象类型引用)
|
|
314
302
|
*/
|
|
315
|
-
|
|
303
|
+
private findTypeName;
|
|
316
304
|
/**
|
|
317
|
-
*
|
|
305
|
+
* 格式化单个类型定义
|
|
318
306
|
*/
|
|
319
|
-
|
|
307
|
+
formatTypeDef(typeDef: NamedTypeDef): string;
|
|
320
308
|
/**
|
|
321
|
-
*
|
|
309
|
+
* 格式化对象类型(interface 或 type)
|
|
322
310
|
*/
|
|
323
|
-
private
|
|
311
|
+
private formatObjectType;
|
|
324
312
|
/**
|
|
325
313
|
* 格式化类型节点为字符串
|
|
326
314
|
*/
|
|
327
|
-
formatType
|
|
315
|
+
private formatType;
|
|
328
316
|
/**
|
|
329
317
|
* 格式化字面量
|
|
330
318
|
*/
|
|
@@ -342,8 +330,7 @@ declare class CodeFormatter {
|
|
|
342
330
|
*/
|
|
343
331
|
private formatUnionType;
|
|
344
332
|
/**
|
|
345
|
-
*
|
|
346
|
-
* 处理非法标识符的情况(用引号包裹)
|
|
333
|
+
* 格式化属性名(非法标识符用引号包裹)
|
|
347
334
|
*/
|
|
348
335
|
private formatPropertyName;
|
|
349
336
|
/**
|
|
@@ -351,26 +338,26 @@ declare class CodeFormatter {
|
|
|
351
338
|
*/
|
|
352
339
|
private sortProperties;
|
|
353
340
|
/**
|
|
354
|
-
*
|
|
341
|
+
* 格式化多行 JSDoc 注释
|
|
355
342
|
*/
|
|
356
343
|
private formatJSDoc;
|
|
357
|
-
/**
|
|
358
|
-
* 格式化内联 JSDoc 注释(单行)
|
|
359
|
-
*/
|
|
360
|
-
private formatInlineJSDoc;
|
|
361
|
-
/**
|
|
362
|
-
* 转换为枚举键名
|
|
363
|
-
*/
|
|
364
|
-
private toEnumKey;
|
|
365
344
|
/**
|
|
366
345
|
* 格式化所有类型定义
|
|
367
346
|
*/
|
|
368
347
|
formatAll(typeDefs: NamedTypeDef[]): string;
|
|
369
348
|
/**
|
|
370
|
-
*
|
|
349
|
+
* 生成完整输出代码
|
|
371
350
|
*/
|
|
372
351
|
generateOutput(typeDefs: NamedTypeDef[], rootTypeName: string): string;
|
|
373
352
|
}
|
|
353
|
+
/**
|
|
354
|
+
* 根据字段名猜测 JSDoc 注释
|
|
355
|
+
*/
|
|
356
|
+
declare function guessCommentFromFieldName(fieldName: string): string | undefined;
|
|
357
|
+
/**
|
|
358
|
+
* 为对象类型的属性添加猜测的注释
|
|
359
|
+
*/
|
|
360
|
+
declare function addGuessedComments(type: ObjectType): ObjectType;
|
|
374
361
|
|
|
375
362
|
/**
|
|
376
363
|
* ts-gen - 类型推断引擎
|
|
@@ -409,7 +396,7 @@ declare function inferType(value: unknown): TSTypeNode;
|
|
|
409
396
|
* - 统一提取元素类型
|
|
410
397
|
* - 元素类型不一致时生成联合类型
|
|
411
398
|
*/
|
|
412
|
-
declare function inferArrayType(arr: unknown[]):
|
|
399
|
+
declare function inferArrayType(arr: unknown[]): ArrayType;
|
|
413
400
|
/**
|
|
414
401
|
* 推断对象类型
|
|
415
402
|
*/
|
|
@@ -424,198 +411,69 @@ declare function isStructurallyEqual(a: TSTypeNode, b: TSTypeNode): boolean;
|
|
|
424
411
|
* ts-gen - 增强功能模块
|
|
425
412
|
*
|
|
426
413
|
* 核心功能:
|
|
427
|
-
* -
|
|
428
|
-
* -
|
|
429
|
-
* - 空值处理(严格/非严格模式)
|
|
414
|
+
* - 泛型提取(如 PageResult<T>)
|
|
415
|
+
* - 空值处理
|
|
430
416
|
* - 可选属性处理
|
|
431
417
|
*/
|
|
432
418
|
|
|
433
|
-
/**
|
|
434
|
-
* 泛型模式定义
|
|
435
|
-
*/
|
|
436
|
-
interface GenericPattern {
|
|
437
|
-
/** 模式名称,如 'PageResult' */
|
|
438
|
-
name: string;
|
|
439
|
-
/** 匹配的属性列表 */
|
|
440
|
-
match: {
|
|
441
|
-
/** 列表字段名(可变的部分) */
|
|
442
|
-
listField?: string[];
|
|
443
|
-
/** 总数字段名 */
|
|
444
|
-
totalField?: string[];
|
|
445
|
-
/** 页码字段名 */
|
|
446
|
-
pageField?: string[];
|
|
447
|
-
/** 每页大小字段名 */
|
|
448
|
-
pageSizeField?: string[];
|
|
449
|
-
};
|
|
450
|
-
/** 泛型参数索引(哪个字段作为 T) */
|
|
451
|
-
typeParamIndex: number;
|
|
452
|
-
}
|
|
453
419
|
/**
|
|
454
420
|
* 泛型提取器
|
|
421
|
+
* 识别常见的列表结构,提取为泛型类型
|
|
455
422
|
*/
|
|
456
423
|
declare class GenericExtractor {
|
|
457
424
|
private patterns;
|
|
458
|
-
constructor(customPatterns?: GenericPattern[]);
|
|
459
|
-
/**
|
|
460
|
-
* 尝试提取泛型类型
|
|
461
|
-
* @param type 对象类型
|
|
462
|
-
* @returns 如果匹配成功返回泛型类型,否则返回原类型
|
|
463
|
-
*/
|
|
464
425
|
extract(type: TSTypeNode): TSTypeNode;
|
|
465
|
-
/**
|
|
466
|
-
* 尝试匹配泛型模式
|
|
467
|
-
*/
|
|
468
426
|
private tryMatchPattern;
|
|
469
|
-
/**
|
|
470
|
-
* 递归处理子属性
|
|
471
|
-
*/
|
|
472
|
-
private extractRecursive;
|
|
473
|
-
/**
|
|
474
|
-
* 提取属性类型中的泛型
|
|
475
|
-
*/
|
|
476
|
-
private extractPropertyType;
|
|
477
|
-
}
|
|
478
|
-
/**
|
|
479
|
-
* 枚举提取器
|
|
480
|
-
*/
|
|
481
|
-
declare class EnumExtractor {
|
|
482
|
-
private threshold;
|
|
483
|
-
constructor(threshold?: number);
|
|
484
|
-
/**
|
|
485
|
-
* 从 JSON 数据中提取枚举
|
|
486
|
-
* @param jsonData JSON 数据
|
|
487
|
-
* @param type 已推断的类型
|
|
488
|
-
* @returns 处理后的类型(可能包含枚举)
|
|
489
|
-
*/
|
|
490
|
-
extract(jsonData: unknown, type: TSTypeNode): TSTypeNode;
|
|
491
|
-
/**
|
|
492
|
-
* 递归提取
|
|
493
|
-
*/
|
|
494
|
-
private extractRecursive;
|
|
495
|
-
/**
|
|
496
|
-
* 收集数组中某个字段的所有取值
|
|
497
|
-
*/
|
|
498
|
-
private collectFieldValues;
|
|
499
|
-
/**
|
|
500
|
-
* 尝试提取枚举
|
|
501
|
-
*/
|
|
502
|
-
private tryExtractEnum;
|
|
503
427
|
}
|
|
504
428
|
/**
|
|
505
429
|
* 空值处理器
|
|
506
430
|
*/
|
|
507
431
|
declare class NullHandler {
|
|
508
|
-
private
|
|
509
|
-
constructor(
|
|
510
|
-
/**
|
|
511
|
-
* 处理类型中的 null
|
|
512
|
-
*/
|
|
432
|
+
private strict;
|
|
433
|
+
constructor(strict?: boolean);
|
|
513
434
|
process(type: TSTypeNode): TSTypeNode;
|
|
514
|
-
/**
|
|
515
|
-
* 递归处理(严格模式)
|
|
516
|
-
*/
|
|
517
|
-
private processRecursive;
|
|
518
|
-
/**
|
|
519
|
-
* 递归移除 null
|
|
520
|
-
*/
|
|
521
|
-
private removeNullRecursive;
|
|
522
435
|
}
|
|
523
436
|
/**
|
|
524
437
|
* 可选属性处理器
|
|
525
|
-
* 基于数组中对象的字段出现频率判断是否可选
|
|
526
438
|
*/
|
|
527
439
|
declare class OptionalHandler {
|
|
528
440
|
private markOptional;
|
|
529
441
|
constructor(markOptional?: boolean);
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
* @param jsonData 原始 JSON 数据
|
|
533
|
-
* @param type 已推断的类型
|
|
534
|
-
*/
|
|
535
|
-
process(jsonData: unknown, type: TSTypeNode): TSTypeNode;
|
|
536
|
-
/**
|
|
537
|
-
* 递归处理
|
|
538
|
-
*/
|
|
539
|
-
private processRecursive;
|
|
540
|
-
/**
|
|
541
|
-
* 在数组对象中标记可选属性
|
|
542
|
-
*/
|
|
543
|
-
private markOptionalInArrayObjects;
|
|
442
|
+
process(jsonData: any, type: TSTypeNode): TSTypeNode;
|
|
443
|
+
private processArrayObjects;
|
|
544
444
|
}
|
|
545
445
|
/**
|
|
546
446
|
* 应用所有增强功能
|
|
547
447
|
*/
|
|
548
|
-
declare function applyEnhancements(jsonData:
|
|
448
|
+
declare function applyEnhancements(jsonData: any, type: TSTypeNode, options: GenerateOptions): TSTypeNode;
|
|
549
449
|
|
|
550
450
|
/**
|
|
551
451
|
* ts-gen - JSON 智能生成 TypeScript 类型定义
|
|
552
452
|
*
|
|
553
453
|
* 主入口文件
|
|
554
|
-
*
|
|
555
|
-
* @example
|
|
556
|
-
* ```ts
|
|
557
|
-
* import { generate } from 'ts-gen';
|
|
558
|
-
*
|
|
559
|
-
* const json = { name: 'foo', age: 25 };
|
|
560
|
-
* const result = generate(json, { rootName: 'User' });
|
|
561
|
-
* console.log(result.code);
|
|
562
|
-
* ```
|
|
563
454
|
*/
|
|
564
455
|
|
|
565
456
|
/**
|
|
566
457
|
* 从 JSON 数据生成 TypeScript 类型定义
|
|
567
|
-
*
|
|
568
|
-
* @param
|
|
569
|
-
* @
|
|
570
|
-
* @returns 生成结果,包含代码字符串和类型定义列表
|
|
571
|
-
*
|
|
572
|
-
* @example
|
|
573
|
-
* ```ts
|
|
574
|
-
* import { generate } from 'ts-gen';
|
|
575
|
-
*
|
|
576
|
-
* const data = {
|
|
577
|
-
* id: 1,
|
|
578
|
-
* name: 'Alice',
|
|
579
|
-
* email: 'alice@example.com',
|
|
580
|
-
* profile: {
|
|
581
|
-
* avatar: 'https://...',
|
|
582
|
-
* bio: null
|
|
583
|
-
* }
|
|
584
|
-
* };
|
|
585
|
-
*
|
|
586
|
-
* const result = generate(data, {
|
|
587
|
-
* rootName: 'User',
|
|
588
|
-
* outputStyle: 'interface'
|
|
589
|
-
* });
|
|
590
|
-
*
|
|
591
|
-
* console.log(result.code);
|
|
592
|
-
* ```
|
|
458
|
+
* @param jsonData JSON 数据
|
|
459
|
+
* @param options 配置选项
|
|
460
|
+
* @returns 生成结果
|
|
593
461
|
*/
|
|
594
|
-
declare function generate(jsonData:
|
|
462
|
+
declare function generate(jsonData: any, options?: GenerateOptions): GenerateResult;
|
|
595
463
|
/**
|
|
596
|
-
* 从 JSON
|
|
597
|
-
*
|
|
464
|
+
* 从 JSON 字符串生成类型定义
|
|
598
465
|
* @param jsonString JSON 字符串
|
|
599
|
-
* @param options
|
|
466
|
+
* @param options 配置选项
|
|
600
467
|
* @returns 生成结果
|
|
601
|
-
*
|
|
602
|
-
* @example
|
|
603
|
-
* ```ts
|
|
604
|
-
* import { generateFromString } from 'ts-gen';
|
|
605
|
-
*
|
|
606
|
-
* const jsonStr = '{"name": "foo", "age": 25}';
|
|
607
|
-
* const result = generateFromString(jsonStr, { rootName: 'User' });
|
|
608
|
-
* ```
|
|
609
468
|
*/
|
|
610
469
|
declare function generateFromString(jsonString: string, options?: GenerateOptions): GenerateResult;
|
|
611
470
|
/**
|
|
612
|
-
*
|
|
613
|
-
*
|
|
471
|
+
* 生成单个类型的字符串表示
|
|
614
472
|
* @param jsonData JSON 数据
|
|
615
|
-
* @param options
|
|
616
|
-
* @returns
|
|
473
|
+
* @param options 配置选项
|
|
474
|
+
* @returns 类型字符串
|
|
617
475
|
*/
|
|
618
|
-
declare function generateType(jsonData:
|
|
476
|
+
declare function generateType(jsonData: any, options?: GenerateOptions): string;
|
|
619
477
|
|
|
620
478
|
declare const _default: {
|
|
621
479
|
generate: typeof generate;
|
|
@@ -623,4 +481,4 @@ declare const _default: {
|
|
|
623
481
|
generateType: typeof generateType;
|
|
624
482
|
};
|
|
625
483
|
|
|
626
|
-
export { type ArrayType, CodeFormatter,
|
|
484
|
+
export { type ArrayType, CodeFormatter, type GenerateOptions, type GenerateResult, GenericExtractor, type GenericType, type NamedTypeDef, type NamingStyle, NullHandler, type ObjectType, OptionalHandler, type OutputStyle, type PrimitiveType, type PropertyDef, type SortOrder, type TSTypeNode, TypeCollector, TypeNamer, type UnionType, addGuessedComments, applyEnhancements, createUnion, _default as default, generate, generateFromString, generateType, guessCommentFromFieldName, inferArrayType, inferObjectType, inferType, isStructurallyEqual, mergeObjects, mergeTypes };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* 类型定义文件
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
5
|
* 原始类型
|
|
@@ -51,14 +51,6 @@ interface LiteralType {
|
|
|
51
51
|
kind: 'literal';
|
|
52
52
|
value: string | number | boolean;
|
|
53
53
|
}
|
|
54
|
-
/**
|
|
55
|
-
* 枚举类型
|
|
56
|
-
*/
|
|
57
|
-
interface EnumType {
|
|
58
|
-
kind: 'enum';
|
|
59
|
-
name: string;
|
|
60
|
-
values: (string | number)[];
|
|
61
|
-
}
|
|
62
54
|
/**
|
|
63
55
|
* null 类型
|
|
64
56
|
*/
|
|
@@ -82,7 +74,7 @@ interface GenericType {
|
|
|
82
74
|
/**
|
|
83
75
|
* TS 类型节点(联合类型,支持 discriminated union 类型收窄)
|
|
84
76
|
*/
|
|
85
|
-
type TSTypeNode = PrimitiveType | ArrayType | ObjectType | UnionType | LiteralType |
|
|
77
|
+
type TSTypeNode = PrimitiveType | ArrayType | ObjectType | UnionType | LiteralType | NullType | UndefinedType | GenericType;
|
|
86
78
|
/**
|
|
87
79
|
* 命名风格
|
|
88
80
|
*/
|
|
@@ -115,10 +107,6 @@ interface GenerateOptions {
|
|
|
115
107
|
strictNullChecks?: boolean;
|
|
116
108
|
/** 是否将可选属性标记为 ?,默认 true */
|
|
117
109
|
markOptional?: boolean;
|
|
118
|
-
/** 是否提取枚举类型,默认 true */
|
|
119
|
-
extractEnums?: boolean;
|
|
120
|
-
/** 枚举提取阈值(字段不同值数量 ≤ 此值时提取为枚举),默认 5 */
|
|
121
|
-
enumThreshold?: number;
|
|
122
110
|
/** 是否提取泛型(如 PageResult<T>),默认 true */
|
|
123
111
|
extractGenerics?: boolean;
|
|
124
112
|
/** 缩进空格数,默认 2 */
|
|
@@ -295,11 +283,9 @@ declare class TypeCollector {
|
|
|
295
283
|
* ts-gen - 格式化输出模块
|
|
296
284
|
*
|
|
297
285
|
* 核心功能:
|
|
298
|
-
* -
|
|
286
|
+
* - 将类型节点格式化为 TypeScript 代码字符串
|
|
299
287
|
* - 支持 interface 和 type alias 两种输出风格
|
|
300
|
-
* -
|
|
301
|
-
* - 支持导出语句
|
|
302
|
-
* - 支持 JSDoc 注释生成
|
|
288
|
+
* - 自动缩进、排序、注释生成
|
|
303
289
|
*/
|
|
304
290
|
|
|
305
291
|
/**
|
|
@@ -308,23 +294,25 @@ declare class TypeCollector {
|
|
|
308
294
|
declare class CodeFormatter {
|
|
309
295
|
private options;
|
|
310
296
|
private namer;
|
|
297
|
+
/** 所有已命名的类型列表(用于查找引用) */
|
|
298
|
+
private allNamedTypes;
|
|
311
299
|
constructor(options: Required<GenerateOptions>, namer: TypeNamer);
|
|
312
300
|
/**
|
|
313
|
-
*
|
|
301
|
+
* 查找类型对应的命名(用于对象类型引用)
|
|
314
302
|
*/
|
|
315
|
-
|
|
303
|
+
private findTypeName;
|
|
316
304
|
/**
|
|
317
|
-
*
|
|
305
|
+
* 格式化单个类型定义
|
|
318
306
|
*/
|
|
319
|
-
|
|
307
|
+
formatTypeDef(typeDef: NamedTypeDef): string;
|
|
320
308
|
/**
|
|
321
|
-
*
|
|
309
|
+
* 格式化对象类型(interface 或 type)
|
|
322
310
|
*/
|
|
323
|
-
private
|
|
311
|
+
private formatObjectType;
|
|
324
312
|
/**
|
|
325
313
|
* 格式化类型节点为字符串
|
|
326
314
|
*/
|
|
327
|
-
formatType
|
|
315
|
+
private formatType;
|
|
328
316
|
/**
|
|
329
317
|
* 格式化字面量
|
|
330
318
|
*/
|
|
@@ -342,8 +330,7 @@ declare class CodeFormatter {
|
|
|
342
330
|
*/
|
|
343
331
|
private formatUnionType;
|
|
344
332
|
/**
|
|
345
|
-
*
|
|
346
|
-
* 处理非法标识符的情况(用引号包裹)
|
|
333
|
+
* 格式化属性名(非法标识符用引号包裹)
|
|
347
334
|
*/
|
|
348
335
|
private formatPropertyName;
|
|
349
336
|
/**
|
|
@@ -351,26 +338,26 @@ declare class CodeFormatter {
|
|
|
351
338
|
*/
|
|
352
339
|
private sortProperties;
|
|
353
340
|
/**
|
|
354
|
-
*
|
|
341
|
+
* 格式化多行 JSDoc 注释
|
|
355
342
|
*/
|
|
356
343
|
private formatJSDoc;
|
|
357
|
-
/**
|
|
358
|
-
* 格式化内联 JSDoc 注释(单行)
|
|
359
|
-
*/
|
|
360
|
-
private formatInlineJSDoc;
|
|
361
|
-
/**
|
|
362
|
-
* 转换为枚举键名
|
|
363
|
-
*/
|
|
364
|
-
private toEnumKey;
|
|
365
344
|
/**
|
|
366
345
|
* 格式化所有类型定义
|
|
367
346
|
*/
|
|
368
347
|
formatAll(typeDefs: NamedTypeDef[]): string;
|
|
369
348
|
/**
|
|
370
|
-
*
|
|
349
|
+
* 生成完整输出代码
|
|
371
350
|
*/
|
|
372
351
|
generateOutput(typeDefs: NamedTypeDef[], rootTypeName: string): string;
|
|
373
352
|
}
|
|
353
|
+
/**
|
|
354
|
+
* 根据字段名猜测 JSDoc 注释
|
|
355
|
+
*/
|
|
356
|
+
declare function guessCommentFromFieldName(fieldName: string): string | undefined;
|
|
357
|
+
/**
|
|
358
|
+
* 为对象类型的属性添加猜测的注释
|
|
359
|
+
*/
|
|
360
|
+
declare function addGuessedComments(type: ObjectType): ObjectType;
|
|
374
361
|
|
|
375
362
|
/**
|
|
376
363
|
* ts-gen - 类型推断引擎
|
|
@@ -409,7 +396,7 @@ declare function inferType(value: unknown): TSTypeNode;
|
|
|
409
396
|
* - 统一提取元素类型
|
|
410
397
|
* - 元素类型不一致时生成联合类型
|
|
411
398
|
*/
|
|
412
|
-
declare function inferArrayType(arr: unknown[]):
|
|
399
|
+
declare function inferArrayType(arr: unknown[]): ArrayType;
|
|
413
400
|
/**
|
|
414
401
|
* 推断对象类型
|
|
415
402
|
*/
|
|
@@ -424,198 +411,69 @@ declare function isStructurallyEqual(a: TSTypeNode, b: TSTypeNode): boolean;
|
|
|
424
411
|
* ts-gen - 增强功能模块
|
|
425
412
|
*
|
|
426
413
|
* 核心功能:
|
|
427
|
-
* -
|
|
428
|
-
* -
|
|
429
|
-
* - 空值处理(严格/非严格模式)
|
|
414
|
+
* - 泛型提取(如 PageResult<T>)
|
|
415
|
+
* - 空值处理
|
|
430
416
|
* - 可选属性处理
|
|
431
417
|
*/
|
|
432
418
|
|
|
433
|
-
/**
|
|
434
|
-
* 泛型模式定义
|
|
435
|
-
*/
|
|
436
|
-
interface GenericPattern {
|
|
437
|
-
/** 模式名称,如 'PageResult' */
|
|
438
|
-
name: string;
|
|
439
|
-
/** 匹配的属性列表 */
|
|
440
|
-
match: {
|
|
441
|
-
/** 列表字段名(可变的部分) */
|
|
442
|
-
listField?: string[];
|
|
443
|
-
/** 总数字段名 */
|
|
444
|
-
totalField?: string[];
|
|
445
|
-
/** 页码字段名 */
|
|
446
|
-
pageField?: string[];
|
|
447
|
-
/** 每页大小字段名 */
|
|
448
|
-
pageSizeField?: string[];
|
|
449
|
-
};
|
|
450
|
-
/** 泛型参数索引(哪个字段作为 T) */
|
|
451
|
-
typeParamIndex: number;
|
|
452
|
-
}
|
|
453
419
|
/**
|
|
454
420
|
* 泛型提取器
|
|
421
|
+
* 识别常见的列表结构,提取为泛型类型
|
|
455
422
|
*/
|
|
456
423
|
declare class GenericExtractor {
|
|
457
424
|
private patterns;
|
|
458
|
-
constructor(customPatterns?: GenericPattern[]);
|
|
459
|
-
/**
|
|
460
|
-
* 尝试提取泛型类型
|
|
461
|
-
* @param type 对象类型
|
|
462
|
-
* @returns 如果匹配成功返回泛型类型,否则返回原类型
|
|
463
|
-
*/
|
|
464
425
|
extract(type: TSTypeNode): TSTypeNode;
|
|
465
|
-
/**
|
|
466
|
-
* 尝试匹配泛型模式
|
|
467
|
-
*/
|
|
468
426
|
private tryMatchPattern;
|
|
469
|
-
/**
|
|
470
|
-
* 递归处理子属性
|
|
471
|
-
*/
|
|
472
|
-
private extractRecursive;
|
|
473
|
-
/**
|
|
474
|
-
* 提取属性类型中的泛型
|
|
475
|
-
*/
|
|
476
|
-
private extractPropertyType;
|
|
477
|
-
}
|
|
478
|
-
/**
|
|
479
|
-
* 枚举提取器
|
|
480
|
-
*/
|
|
481
|
-
declare class EnumExtractor {
|
|
482
|
-
private threshold;
|
|
483
|
-
constructor(threshold?: number);
|
|
484
|
-
/**
|
|
485
|
-
* 从 JSON 数据中提取枚举
|
|
486
|
-
* @param jsonData JSON 数据
|
|
487
|
-
* @param type 已推断的类型
|
|
488
|
-
* @returns 处理后的类型(可能包含枚举)
|
|
489
|
-
*/
|
|
490
|
-
extract(jsonData: unknown, type: TSTypeNode): TSTypeNode;
|
|
491
|
-
/**
|
|
492
|
-
* 递归提取
|
|
493
|
-
*/
|
|
494
|
-
private extractRecursive;
|
|
495
|
-
/**
|
|
496
|
-
* 收集数组中某个字段的所有取值
|
|
497
|
-
*/
|
|
498
|
-
private collectFieldValues;
|
|
499
|
-
/**
|
|
500
|
-
* 尝试提取枚举
|
|
501
|
-
*/
|
|
502
|
-
private tryExtractEnum;
|
|
503
427
|
}
|
|
504
428
|
/**
|
|
505
429
|
* 空值处理器
|
|
506
430
|
*/
|
|
507
431
|
declare class NullHandler {
|
|
508
|
-
private
|
|
509
|
-
constructor(
|
|
510
|
-
/**
|
|
511
|
-
* 处理类型中的 null
|
|
512
|
-
*/
|
|
432
|
+
private strict;
|
|
433
|
+
constructor(strict?: boolean);
|
|
513
434
|
process(type: TSTypeNode): TSTypeNode;
|
|
514
|
-
/**
|
|
515
|
-
* 递归处理(严格模式)
|
|
516
|
-
*/
|
|
517
|
-
private processRecursive;
|
|
518
|
-
/**
|
|
519
|
-
* 递归移除 null
|
|
520
|
-
*/
|
|
521
|
-
private removeNullRecursive;
|
|
522
435
|
}
|
|
523
436
|
/**
|
|
524
437
|
* 可选属性处理器
|
|
525
|
-
* 基于数组中对象的字段出现频率判断是否可选
|
|
526
438
|
*/
|
|
527
439
|
declare class OptionalHandler {
|
|
528
440
|
private markOptional;
|
|
529
441
|
constructor(markOptional?: boolean);
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
* @param jsonData 原始 JSON 数据
|
|
533
|
-
* @param type 已推断的类型
|
|
534
|
-
*/
|
|
535
|
-
process(jsonData: unknown, type: TSTypeNode): TSTypeNode;
|
|
536
|
-
/**
|
|
537
|
-
* 递归处理
|
|
538
|
-
*/
|
|
539
|
-
private processRecursive;
|
|
540
|
-
/**
|
|
541
|
-
* 在数组对象中标记可选属性
|
|
542
|
-
*/
|
|
543
|
-
private markOptionalInArrayObjects;
|
|
442
|
+
process(jsonData: any, type: TSTypeNode): TSTypeNode;
|
|
443
|
+
private processArrayObjects;
|
|
544
444
|
}
|
|
545
445
|
/**
|
|
546
446
|
* 应用所有增强功能
|
|
547
447
|
*/
|
|
548
|
-
declare function applyEnhancements(jsonData:
|
|
448
|
+
declare function applyEnhancements(jsonData: any, type: TSTypeNode, options: GenerateOptions): TSTypeNode;
|
|
549
449
|
|
|
550
450
|
/**
|
|
551
451
|
* ts-gen - JSON 智能生成 TypeScript 类型定义
|
|
552
452
|
*
|
|
553
453
|
* 主入口文件
|
|
554
|
-
*
|
|
555
|
-
* @example
|
|
556
|
-
* ```ts
|
|
557
|
-
* import { generate } from 'ts-gen';
|
|
558
|
-
*
|
|
559
|
-
* const json = { name: 'foo', age: 25 };
|
|
560
|
-
* const result = generate(json, { rootName: 'User' });
|
|
561
|
-
* console.log(result.code);
|
|
562
|
-
* ```
|
|
563
454
|
*/
|
|
564
455
|
|
|
565
456
|
/**
|
|
566
457
|
* 从 JSON 数据生成 TypeScript 类型定义
|
|
567
|
-
*
|
|
568
|
-
* @param
|
|
569
|
-
* @
|
|
570
|
-
* @returns 生成结果,包含代码字符串和类型定义列表
|
|
571
|
-
*
|
|
572
|
-
* @example
|
|
573
|
-
* ```ts
|
|
574
|
-
* import { generate } from 'ts-gen';
|
|
575
|
-
*
|
|
576
|
-
* const data = {
|
|
577
|
-
* id: 1,
|
|
578
|
-
* name: 'Alice',
|
|
579
|
-
* email: 'alice@example.com',
|
|
580
|
-
* profile: {
|
|
581
|
-
* avatar: 'https://...',
|
|
582
|
-
* bio: null
|
|
583
|
-
* }
|
|
584
|
-
* };
|
|
585
|
-
*
|
|
586
|
-
* const result = generate(data, {
|
|
587
|
-
* rootName: 'User',
|
|
588
|
-
* outputStyle: 'interface'
|
|
589
|
-
* });
|
|
590
|
-
*
|
|
591
|
-
* console.log(result.code);
|
|
592
|
-
* ```
|
|
458
|
+
* @param jsonData JSON 数据
|
|
459
|
+
* @param options 配置选项
|
|
460
|
+
* @returns 生成结果
|
|
593
461
|
*/
|
|
594
|
-
declare function generate(jsonData:
|
|
462
|
+
declare function generate(jsonData: any, options?: GenerateOptions): GenerateResult;
|
|
595
463
|
/**
|
|
596
|
-
* 从 JSON
|
|
597
|
-
*
|
|
464
|
+
* 从 JSON 字符串生成类型定义
|
|
598
465
|
* @param jsonString JSON 字符串
|
|
599
|
-
* @param options
|
|
466
|
+
* @param options 配置选项
|
|
600
467
|
* @returns 生成结果
|
|
601
|
-
*
|
|
602
|
-
* @example
|
|
603
|
-
* ```ts
|
|
604
|
-
* import { generateFromString } from 'ts-gen';
|
|
605
|
-
*
|
|
606
|
-
* const jsonStr = '{"name": "foo", "age": 25}';
|
|
607
|
-
* const result = generateFromString(jsonStr, { rootName: 'User' });
|
|
608
|
-
* ```
|
|
609
468
|
*/
|
|
610
469
|
declare function generateFromString(jsonString: string, options?: GenerateOptions): GenerateResult;
|
|
611
470
|
/**
|
|
612
|
-
*
|
|
613
|
-
*
|
|
471
|
+
* 生成单个类型的字符串表示
|
|
614
472
|
* @param jsonData JSON 数据
|
|
615
|
-
* @param options
|
|
616
|
-
* @returns
|
|
473
|
+
* @param options 配置选项
|
|
474
|
+
* @returns 类型字符串
|
|
617
475
|
*/
|
|
618
|
-
declare function generateType(jsonData:
|
|
476
|
+
declare function generateType(jsonData: any, options?: GenerateOptions): string;
|
|
619
477
|
|
|
620
478
|
declare const _default: {
|
|
621
479
|
generate: typeof generate;
|
|
@@ -623,4 +481,4 @@ declare const _default: {
|
|
|
623
481
|
generateType: typeof generateType;
|
|
624
482
|
};
|
|
625
483
|
|
|
626
|
-
export { type ArrayType, CodeFormatter,
|
|
484
|
+
export { type ArrayType, CodeFormatter, type GenerateOptions, type GenerateResult, GenericExtractor, type GenericType, type NamedTypeDef, type NamingStyle, NullHandler, type ObjectType, OptionalHandler, type OutputStyle, type PrimitiveType, type PropertyDef, type SortOrder, type TSTypeNode, TypeCollector, TypeNamer, type UnionType, addGuessedComments, applyEnhancements, createUnion, _default as default, generate, generateFromString, generateType, guessCommentFromFieldName, inferArrayType, inferObjectType, inferType, isStructurallyEqual, mergeObjects, mergeTypes };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`,typeNameMap:{},typePrefix:"",typeSuffix:""};function
|
|
3
|
-
`);return t.length===
|
|
4
|
-
|
|
5
|
-
* `)
|
|
6
|
-
|
|
1
|
+
"use strict";var x=Object.defineProperty;var K=Object.getOwnPropertyDescriptor;var E=Object.getOwnPropertyNames;var L=Object.prototype.hasOwnProperty;var z=(n,e)=>{for(var t in e)x(n,t,{get:e[t],enumerable:!0})},_=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of E(e))!L.call(n,i)&&i!==t&&x(n,i,{get:()=>e[i],enumerable:!(r=K(e,i))||r.enumerable});return n};var q=n=>_(x({},"__esModule",{value:!0}),n);var B={};z(B,{CodeFormatter:()=>y,GenericExtractor:()=>T,NullHandler:()=>g,OptionalHandler:()=>h,TypeCollector:()=>f,TypeNamer:()=>m,addGuessedComments:()=>k,applyEnhancements:()=>b,createUnion:()=>O,default:()=>H,generate:()=>j,generateFromString:()=>R,generateType:()=>D,guessCommentFromFieldName:()=>A,inferArrayType:()=>$,inferObjectType:()=>P,inferType:()=>l,isStructurallyEqual:()=>S,mergeObjects:()=>v,mergeTypes:()=>d});module.exports=q(B);var w={rootName:"Root",outputStyle:"interface",namingStyle:"PascalCase",sortProperties:"alpha",addExport:!0,addComments:!1,strictNullChecks:!1,markOptional:!0,extractGenerics:!0,indentSize:2,lineEnding:`
|
|
2
|
+
`,typeNameMap:{},typePrefix:"",typeSuffix:""};function N(n){return{kind:"primitive",type:n}}function I(){return{kind:"null"}}function Z(){return{kind:"undefined"}}function V(n){return{kind:"array",elementType:n}}function G(n=[]){return{kind:"object",properties:n}}function O(n){let e=[],t=new Set;for(let r of n)if(r.kind==="union")for(let i of r.types){let o=p(i);t.has(o)||(t.add(o),e.push(i))}else{let i=p(r);t.has(i)||(t.add(i),e.push(r))}return e.length===1?e[0]:{kind:"union",types:e}}function p(n){switch(n.kind){case"primitive":return`primitive:${n.type}`;case"null":return"null";case"undefined":return"undefined";case"literal":return`literal:${typeof n.value}:${String(n.value)}`;case"array":return`array:${p(n.elementType)}`;case"object":return`object:${n.properties.map(e=>`${e.name}:${p(e.type)}:${e.optional}`).join(",")}`;case"union":return`union:${n.types.map(p).sort().join("|")}`;case"generic":return`generic:${n.name}:${n.typeArgs.map(p).join(",")}`;default:return"unknown"}}function d(n,e){return p(n)===p(e)?n:n.kind==="object"&&e.kind==="object"?v(n,e):n.kind==="array"&&e.kind==="array"?V(d(n.elementType,e.elementType)):O([n,e])}function v(n,e){let t=new Map;for(let r of n.properties)t.set(r.name,{...r});for(let r of e.properties){let i=t.get(r.name);i?(i.type=d(i.type,r.type),i.optional=i.optional||r.optional,r.comment&&!i.comment&&(i.comment=r.comment)):t.set(r.name,{...r,optional:!0})}for(let[r,i]of t)e.properties.some(s=>s.name===r)||(i.optional=!0);return G(Array.from(t.values()))}function l(n){return n===null?I():n===void 0?Z():typeof n=="string"?N("string"):typeof n=="number"?N("number"):typeof n=="boolean"?N("boolean"):Array.isArray(n)?$(n):typeof n=="object"?P(n):N("unknown")}function $(n){if(n.length===0)return{kind:"array",elementType:{kind:"primitive",type:"any"}};let e=n.map(r=>l(r)),t=e[0];for(let r=1;r<e.length;r++)t=d(t,e[r]);return{kind:"array",elementType:t}}function P(n){let e=[];for(let[t,r]of Object.entries(n)){let i=l(r);e.push({name:t,type:i,optional:!1})}return G(e)}function S(n,e){return p(n)===p(e)}function u(n){switch(n.kind){case"primitive":case"null":case"undefined":return{...n};case"literal":return{...n};case"array":return{...n,elementType:u(n.elementType)};case"object":return{...n,properties:n.properties.map(e=>({...e,type:u(e.type)}))};case"union":return{...n,types:n.types.map(e=>u(e))};case"generic":return{...n,typeArgs:n.typeArgs.map(e=>u(e))};default:return{...n}}}var m=class{constructor(e={}){this.namedTypes=new Map;this.nameCounter=new Map;this.processing=new WeakSet;this.circularRefs=new Map;this.namingStyle=e.namingStyle||"PascalCase",this.prefix=e.prefix||"",this.suffix=e.suffix||"",this.customNameMap=e.customNameMap||{}}nameType(e,t={depth:0}){if(e.kind!=="object")return null;let r=this.buildPathKey(t);if(this.customNameMap[r])return this.applyAffixes(this.customNameMap[r]);let i=this.getTypeKey(e);if(this.namedTypes.has(i))return this.namedTypes.get(i);let o=this.generateName(e,t);return o=this.ensureUniqueName(o),o=this.applyAffixes(o),this.namedTypes.set(i,o),o}generateName(e,t){if(e.kind==="object"){if(t.fieldName){let r=this.toPascalCase(t.fieldName);return t.parentName?`${t.parentName}${r}`:r}return t.parentName?`${t.parentName}Item`:"AnonymousObject"}return"UnknownType"}ensureUniqueName(e){let t=this.nameCounter.get(e)||0;if(t===0)return this.nameCounter.set(e,1),e;let r=`${e}${t+1}`;return this.nameCounter.set(e,t+1),r}applyAffixes(e){let t=e;return this.prefix&&(t=this.toPascalCase(this.prefix)+t),this.suffix&&(t=t+this.toPascalCase(this.suffix)),t}buildPathKey(e){let t=[];return e.parentName&&t.push(e.parentName),e.fieldName&&t.push(e.fieldName),t.join(".")}getTypeKey(e){return e.kind==="object"?`object:${e.properties.map(t=>`${t.name}:${this.getSimpleTypeKey(t.type)}:${t.optional}`).sort().join(",")}`:e.kind}getSimpleTypeKey(e){switch(e.kind){case"primitive":return e.type;case"null":return"null";case"undefined":return"undefined";case"array":return`array<${this.getSimpleTypeKey(e.elementType)}>`;case"object":return"object";case"union":return e.types.map(t=>this.getSimpleTypeKey(t)).sort().join("|");case"generic":return`generic:${e.name}`;default:return"unknown"}}toPascalCase(e){return e?e.replace(/[-_\s]+/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").trim().split(" ").filter(Boolean).map(r=>r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join(""):""}toCamelCase(e){let t=this.toPascalCase(e);return t.charAt(0).toLowerCase()+t.slice(1)}formatName(e){return this.namingStyle==="camelCase"?this.toCamelCase(e):this.toPascalCase(e)}isCircular(e){return this.processing.has(e)}markProcessing(e){this.processing.add(e)}unmarkProcessing(e){this.processing.delete(e)}getAllNamedTypes(){return new Map(this.namedTypes)}reset(){this.namedTypes.clear(),this.nameCounter.clear(),this.processing=new WeakSet,this.circularRefs.clear()}},f=class{constructor(e){this.collected=[];this.seenStructs=new Set;this.namer=e}collect(e,t){this.collected=[],this.seenStructs.clear(),this.namer.reset();let r=this.getStructKey(e);this.namer.nameType(e,{fieldName:t,depth:0}),this.collectRecursive(e,{fieldName:t,parentName:void 0,depth:0});let i=this.collected.find(s=>s.name===t),o=this.collected.filter(s=>s.name!==t);return i?[i,...o]:this.collected}collectRecursive(e,t){let r=this.getStructKey(e);if(e.kind==="object"){let i=this.namer.nameType(e,t);if(i&&!this.seenStructs.has(r)){this.seenStructs.add(r),this.collected.push({name:i,type:u(e)});for(let o of e.properties)this.collectRecursive(o.type,{fieldName:o.name,parentName:i,depth:t.depth+1})}return}if(e.kind==="array"){this.collectRecursive(e.elementType,{fieldName:t.fieldName?t.fieldName+"Item":void 0,parentName:t.parentName,depth:t.depth+1});return}if(e.kind==="union"){for(let i of e.types)this.collectRecursive(i,t);return}if(e.kind==="generic"){for(let i of e.typeArgs)this.collectRecursive(i,{...t,depth:t.depth+1});return}}getStructKey(e){return e.kind==="object"?`object:${e.properties.map(t=>`${t.name}:${this.getPropTypeKey(t.type)}:${t.optional}`).sort().join("|")}`:e.kind}getPropTypeKey(e){switch(e.kind){case"primitive":return e.type;case"null":return"null";case"undefined":return"undefined";case"array":return`array:${this.getPropTypeKey(e.elementType)}`;case"object":return"object";case"union":return e.types.map(t=>this.getPropTypeKey(t)).sort().join("|");case"generic":return`generic:${e.name}`;default:return"unknown"}}};var y=class{constructor(e,t){this.allNamedTypes=[];this.options=e,this.namer=t}findTypeName(e){if(e.kind!=="object")return null;for(let t of this.allNamedTypes)if(S(t.type,e))return t.name;return null}formatTypeDef(e){let{name:t,type:r,comment:i}=e,o=this.options.addExport?"export ":"";return this.formatObjectType(t,r,o,i)}formatObjectType(e,t,r,i){let o=" ".repeat(this.options.indentSize),s=this.sortProperties(t.properties),a=[];i&&a.push(this.formatJSDoc(i)),this.options.outputStyle==="interface"?a.push(`${r}interface ${e} {`):a.push(`${r}type ${e} = {`);for(let c of s){let U=this.formatPropertyName(c.name),F=c.optional?"?":"",M=this.formatType(c.type),C=`${o}${U}${F}: ${M};`;c.comment&&(C+=` // ${c.comment}`),a.push(C)}return this.options.outputStyle==="interface"?a.push("}"):a.push("};"),a.join(`
|
|
3
|
+
`)}formatType(e){if(e.kind==="object"){let t=this.findTypeName(e);if(t)return t}switch(e.kind){case"primitive":return e.type;case"null":return"null";case"undefined":return"undefined";case"array":return this.formatArrayType(e);case"object":return this.formatInlineObject(e);case"union":return this.formatUnionType(e.types);case"literal":return this.formatLiteral(e.value);case"generic":return`${e.name}<${e.typeArgs.map(t=>this.formatType(t)).join(", ")}>`;default:return"unknown"}}formatLiteral(e){return typeof e=="string"?`'${e}'`:String(e)}formatArrayType(e){let t=this.formatType(e.elementType);return e.elementType.kind==="union"?`(${t})[]`:`${t}[]`}formatInlineObject(e){let t=" ".repeat(this.options.indentSize),r=this.sortProperties(e.properties);if(r.length===0)return"{}";let i=["{"];for(let o of r){let s=this.formatPropertyName(o.name),a=o.optional?"?":"",c=this.formatType(o.type);i.push(`${t}${s}${a}: ${c};`)}return i.push("}"),i.join(`
|
|
4
|
+
`)}formatUnionType(e){return e.map(t=>this.formatType(t)).join(" | ")}formatPropertyName(e){return/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(e)?e:`'${e}'`}sortProperties(e){return this.options.sortProperties==="definition"?[...e]:[...e].sort((t,r)=>t.name.localeCompare(r.name))}formatJSDoc(e){let t=e.split(`
|
|
5
|
+
`);return t.length===1?`/** ${e} */`:["/**",...t.map(r=>` * ${r}`)," */"].join(`
|
|
6
|
+
`)}formatAll(e){return this.allNamedTypes=e,e.map(t=>this.formatTypeDef(t)).join(`
|
|
7
|
+
|
|
8
|
+
`)}generateOutput(e,t){let r=`/**
|
|
9
|
+
* Generated by ts-gen
|
|
10
|
+
* Root type: ${t}
|
|
11
|
+
*/`,i=this.formatAll(e);return`${r}
|
|
12
|
+
|
|
13
|
+
${i}
|
|
14
|
+
`}};function A(n){return{id:"\u552F\u4E00\u6807\u8BC6",name:"\u540D\u79F0",title:"\u6807\u9898",desc:"\u63CF\u8FF0",description:"\u63CF\u8FF0",avatar:"\u5934\u50CF",email:"\u90AE\u7BB1",phone:"\u624B\u673A\u53F7",status:"\u72B6\u6001",type:"\u7C7B\u578B",createdAt:"\u521B\u5EFA\u65F6\u95F4",updatedAt:"\u66F4\u65B0\u65F6\u95F4",deletedAt:"\u5220\u9664\u65F6\u95F4",list:"\u6570\u636E\u5217\u8868",total:"\u603B\u6570",page:"\u9875\u7801",pageSize:"\u6BCF\u9875\u6570\u91CF"}[n]}function k(n){return{...n,properties:n.properties.map(e=>({...e,comment:e.comment||A(e.name)}))}}var T=class{constructor(){this.patterns=[{name:"PageResult",arrayFields:["list","records","rows","items"],countFields:["total","count","totalCount"]},{name:"ListResult",arrayFields:["list","data","items"],countFields:[]},{name:"ApiResponse",arrayFields:["data"],countFields:[]}]}extract(e){if(e.kind!=="object")return e;for(let t of this.patterns){let r=this.tryMatchPattern(e,t);if(r)return r}return e}tryMatchPattern(e,t){let r=null,i=t.countFields.length===0;for(let o of e.properties)t.arrayFields.includes(o.name)&&o.type.kind==="array"&&(r={name:o.name,elementType:o.type.elementType}),t.countFields.includes(o.name)&&(i=!0);return r&&i?{kind:"generic",name:t.name,typeArgs:[r.elementType]}:null}},g=class{constructor(e=!1){this.strict=e}process(e){if(this.strict)return e;if(e.kind==="union"){let t=e.types.filter(r=>r.kind!=="null");return t.length===0?{kind:"null"}:t.length===1?t[0]:{...e,types:t}}return e.kind==="array"?{...e,elementType:this.process(e.elementType)}:e.kind==="object"?{...e,properties:e.properties.map(t=>({...t,type:this.process(t.type)}))}:e}},h=class{constructor(e=!0){this.markOptional=e}process(e,t){if(!this.markOptional)return t;if(t.kind==="array"&&Array.isArray(e)){let r=t.elementType;if(r.kind==="object"){let i=this.processArrayObjects(e,r);return{...t,elementType:i}}}return t}processArrayObjects(e,t){if(e.length<=1)return t;let r={},i=e.length;for(let o of e)if(o&&typeof o=="object")for(let s of Object.keys(o))r[s]=(r[s]||0)+1;return{...t,properties:t.properties.map(o=>{let a=(r[o.name]||0)<i;return{...o,optional:a}})}}};function b(n,e,t){let r=e;return t.markOptional&&(r=new h(t.markOptional).process(n,r)),t.extractGenerics&&(r=new T().extract(r)),r=new g(t.strictNullChecks).process(r),r}function j(n,e={}){let t={...w,...e},r=l(n);r=b(n,r,t),t.addComments&&r.kind==="object"&&(r=k(r));let i=new m({namingStyle:t.namingStyle,prefix:t.typePrefix,suffix:t.typeSuffix,customNameMap:t.typeNameMap}),s=new f(i).collect(r,t.rootName);return{code:new y(t,i).generateOutput(s,t.rootName),types:s}}function R(n,e={}){let t=JSON.parse(n);return j(t,e)}function D(n,e={}){return j(n,e).code}var H={generate:j,generateFromString:R,generateType:D};0&&(module.exports={CodeFormatter,GenericExtractor,NullHandler,OptionalHandler,TypeCollector,TypeNamer,addGuessedComments,applyEnhancements,createUnion,generate,generateFromString,generateType,guessCommentFromFieldName,inferArrayType,inferObjectType,inferType,isStructurallyEqual,mergeObjects,mergeTypes});
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
var
|
|
2
|
-
`,typeNameMap:{},typePrefix:"",typeSuffix:""};function
|
|
3
|
-
`);return t.length===
|
|
4
|
-
|
|
5
|
-
* `)
|
|
6
|
-
|
|
1
|
+
var O={rootName:"Root",outputStyle:"interface",namingStyle:"PascalCase",sortProperties:"alpha",addExport:!0,addComments:!1,strictNullChecks:!1,markOptional:!0,extractGenerics:!0,indentSize:2,lineEnding:`
|
|
2
|
+
`,typeNameMap:{},typePrefix:"",typeSuffix:""};function d(n){return{kind:"primitive",type:n}}function U(){return{kind:"null"}}function F(){return{kind:"undefined"}}function M(n){return{kind:"array",elementType:n}}function v(n=[]){return{kind:"object",properties:n}}function $(n){let e=[],t=new Set;for(let r of n)if(r.kind==="union")for(let i of r.types){let o=p(i);t.has(o)||(t.add(o),e.push(i))}else{let i=p(r);t.has(i)||(t.add(i),e.push(r))}return e.length===1?e[0]:{kind:"union",types:e}}function p(n){switch(n.kind){case"primitive":return`primitive:${n.type}`;case"null":return"null";case"undefined":return"undefined";case"literal":return`literal:${typeof n.value}:${String(n.value)}`;case"array":return`array:${p(n.elementType)}`;case"object":return`object:${n.properties.map(e=>`${e.name}:${p(e.type)}:${e.optional}`).join(",")}`;case"union":return`union:${n.types.map(p).sort().join("|")}`;case"generic":return`generic:${n.name}:${n.typeArgs.map(p).join(",")}`;default:return"unknown"}}function T(n,e){return p(n)===p(e)?n:n.kind==="object"&&e.kind==="object"?P(n,e):n.kind==="array"&&e.kind==="array"?M(T(n.elementType,e.elementType)):$([n,e])}function P(n,e){let t=new Map;for(let r of n.properties)t.set(r.name,{...r});for(let r of e.properties){let i=t.get(r.name);i?(i.type=T(i.type,r.type),i.optional=i.optional||r.optional,r.comment&&!i.comment&&(i.comment=r.comment)):t.set(r.name,{...r,optional:!0})}for(let[r,i]of t)e.properties.some(s=>s.name===r)||(i.optional=!0);return v(Array.from(t.values()))}function l(n){return n===null?U():n===void 0?F():typeof n=="string"?d("string"):typeof n=="number"?d("number"):typeof n=="boolean"?d("boolean"):Array.isArray(n)?A(n):typeof n=="object"?C(n):d("unknown")}function A(n){if(n.length===0)return{kind:"array",elementType:{kind:"primitive",type:"any"}};let e=n.map(r=>l(r)),t=e[0];for(let r=1;r<e.length;r++)t=T(t,e[r]);return{kind:"array",elementType:t}}function C(n){let e=[];for(let[t,r]of Object.entries(n)){let i=l(r);e.push({name:t,type:i,optional:!1})}return v(e)}function S(n,e){return p(n)===p(e)}function u(n){switch(n.kind){case"primitive":case"null":case"undefined":return{...n};case"literal":return{...n};case"array":return{...n,elementType:u(n.elementType)};case"object":return{...n,properties:n.properties.map(e=>({...e,type:u(e.type)}))};case"union":return{...n,types:n.types.map(e=>u(e))};case"generic":return{...n,typeArgs:n.typeArgs.map(e=>u(e))};default:return{...n}}}var m=class{constructor(e={}){this.namedTypes=new Map;this.nameCounter=new Map;this.processing=new WeakSet;this.circularRefs=new Map;this.namingStyle=e.namingStyle||"PascalCase",this.prefix=e.prefix||"",this.suffix=e.suffix||"",this.customNameMap=e.customNameMap||{}}nameType(e,t={depth:0}){if(e.kind!=="object")return null;let r=this.buildPathKey(t);if(this.customNameMap[r])return this.applyAffixes(this.customNameMap[r]);let i=this.getTypeKey(e);if(this.namedTypes.has(i))return this.namedTypes.get(i);let o=this.generateName(e,t);return o=this.ensureUniqueName(o),o=this.applyAffixes(o),this.namedTypes.set(i,o),o}generateName(e,t){if(e.kind==="object"){if(t.fieldName){let r=this.toPascalCase(t.fieldName);return t.parentName?`${t.parentName}${r}`:r}return t.parentName?`${t.parentName}Item`:"AnonymousObject"}return"UnknownType"}ensureUniqueName(e){let t=this.nameCounter.get(e)||0;if(t===0)return this.nameCounter.set(e,1),e;let r=`${e}${t+1}`;return this.nameCounter.set(e,t+1),r}applyAffixes(e){let t=e;return this.prefix&&(t=this.toPascalCase(this.prefix)+t),this.suffix&&(t=t+this.toPascalCase(this.suffix)),t}buildPathKey(e){let t=[];return e.parentName&&t.push(e.parentName),e.fieldName&&t.push(e.fieldName),t.join(".")}getTypeKey(e){return e.kind==="object"?`object:${e.properties.map(t=>`${t.name}:${this.getSimpleTypeKey(t.type)}:${t.optional}`).sort().join(",")}`:e.kind}getSimpleTypeKey(e){switch(e.kind){case"primitive":return e.type;case"null":return"null";case"undefined":return"undefined";case"array":return`array<${this.getSimpleTypeKey(e.elementType)}>`;case"object":return"object";case"union":return e.types.map(t=>this.getSimpleTypeKey(t)).sort().join("|");case"generic":return`generic:${e.name}`;default:return"unknown"}}toPascalCase(e){return e?e.replace(/[-_\s]+/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").trim().split(" ").filter(Boolean).map(r=>r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join(""):""}toCamelCase(e){let t=this.toPascalCase(e);return t.charAt(0).toLowerCase()+t.slice(1)}formatName(e){return this.namingStyle==="camelCase"?this.toCamelCase(e):this.toPascalCase(e)}isCircular(e){return this.processing.has(e)}markProcessing(e){this.processing.add(e)}unmarkProcessing(e){this.processing.delete(e)}getAllNamedTypes(){return new Map(this.namedTypes)}reset(){this.namedTypes.clear(),this.nameCounter.clear(),this.processing=new WeakSet,this.circularRefs.clear()}},f=class{constructor(e){this.collected=[];this.seenStructs=new Set;this.namer=e}collect(e,t){this.collected=[],this.seenStructs.clear(),this.namer.reset();let r=this.getStructKey(e);this.namer.nameType(e,{fieldName:t,depth:0}),this.collectRecursive(e,{fieldName:t,parentName:void 0,depth:0});let i=this.collected.find(s=>s.name===t),o=this.collected.filter(s=>s.name!==t);return i?[i,...o]:this.collected}collectRecursive(e,t){let r=this.getStructKey(e);if(e.kind==="object"){let i=this.namer.nameType(e,t);if(i&&!this.seenStructs.has(r)){this.seenStructs.add(r),this.collected.push({name:i,type:u(e)});for(let o of e.properties)this.collectRecursive(o.type,{fieldName:o.name,parentName:i,depth:t.depth+1})}return}if(e.kind==="array"){this.collectRecursive(e.elementType,{fieldName:t.fieldName?t.fieldName+"Item":void 0,parentName:t.parentName,depth:t.depth+1});return}if(e.kind==="union"){for(let i of e.types)this.collectRecursive(i,t);return}if(e.kind==="generic"){for(let i of e.typeArgs)this.collectRecursive(i,{...t,depth:t.depth+1});return}}getStructKey(e){return e.kind==="object"?`object:${e.properties.map(t=>`${t.name}:${this.getPropTypeKey(t.type)}:${t.optional}`).sort().join("|")}`:e.kind}getPropTypeKey(e){switch(e.kind){case"primitive":return e.type;case"null":return"null";case"undefined":return"undefined";case"array":return`array:${this.getPropTypeKey(e.elementType)}`;case"object":return"object";case"union":return e.types.map(t=>this.getPropTypeKey(t)).sort().join("|");case"generic":return`generic:${e.name}`;default:return"unknown"}}};var y=class{constructor(e,t){this.allNamedTypes=[];this.options=e,this.namer=t}findTypeName(e){if(e.kind!=="object")return null;for(let t of this.allNamedTypes)if(S(t.type,e))return t.name;return null}formatTypeDef(e){let{name:t,type:r,comment:i}=e,o=this.options.addExport?"export ":"";return this.formatObjectType(t,r,o,i)}formatObjectType(e,t,r,i){let o=" ".repeat(this.options.indentSize),s=this.sortProperties(t.properties),a=[];i&&a.push(this.formatJSDoc(i)),this.options.outputStyle==="interface"?a.push(`${r}interface ${e} {`):a.push(`${r}type ${e} = {`);for(let c of s){let G=this.formatPropertyName(c.name),R=c.optional?"?":"",D=this.formatType(c.type),x=`${o}${G}${R}: ${D};`;c.comment&&(x+=` // ${c.comment}`),a.push(x)}return this.options.outputStyle==="interface"?a.push("}"):a.push("};"),a.join(`
|
|
3
|
+
`)}formatType(e){if(e.kind==="object"){let t=this.findTypeName(e);if(t)return t}switch(e.kind){case"primitive":return e.type;case"null":return"null";case"undefined":return"undefined";case"array":return this.formatArrayType(e);case"object":return this.formatInlineObject(e);case"union":return this.formatUnionType(e.types);case"literal":return this.formatLiteral(e.value);case"generic":return`${e.name}<${e.typeArgs.map(t=>this.formatType(t)).join(", ")}>`;default:return"unknown"}}formatLiteral(e){return typeof e=="string"?`'${e}'`:String(e)}formatArrayType(e){let t=this.formatType(e.elementType);return e.elementType.kind==="union"?`(${t})[]`:`${t}[]`}formatInlineObject(e){let t=" ".repeat(this.options.indentSize),r=this.sortProperties(e.properties);if(r.length===0)return"{}";let i=["{"];for(let o of r){let s=this.formatPropertyName(o.name),a=o.optional?"?":"",c=this.formatType(o.type);i.push(`${t}${s}${a}: ${c};`)}return i.push("}"),i.join(`
|
|
4
|
+
`)}formatUnionType(e){return e.map(t=>this.formatType(t)).join(" | ")}formatPropertyName(e){return/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(e)?e:`'${e}'`}sortProperties(e){return this.options.sortProperties==="definition"?[...e]:[...e].sort((t,r)=>t.name.localeCompare(r.name))}formatJSDoc(e){let t=e.split(`
|
|
5
|
+
`);return t.length===1?`/** ${e} */`:["/**",...t.map(r=>` * ${r}`)," */"].join(`
|
|
6
|
+
`)}formatAll(e){return this.allNamedTypes=e,e.map(t=>this.formatTypeDef(t)).join(`
|
|
7
|
+
|
|
8
|
+
`)}generateOutput(e,t){let r=`/**
|
|
9
|
+
* Generated by ts-gen
|
|
10
|
+
* Root type: ${t}
|
|
11
|
+
*/`,i=this.formatAll(e);return`${r}
|
|
12
|
+
|
|
13
|
+
${i}
|
|
14
|
+
`}};function w(n){return{id:"\u552F\u4E00\u6807\u8BC6",name:"\u540D\u79F0",title:"\u6807\u9898",desc:"\u63CF\u8FF0",description:"\u63CF\u8FF0",avatar:"\u5934\u50CF",email:"\u90AE\u7BB1",phone:"\u624B\u673A\u53F7",status:"\u72B6\u6001",type:"\u7C7B\u578B",createdAt:"\u521B\u5EFA\u65F6\u95F4",updatedAt:"\u66F4\u65B0\u65F6\u95F4",deletedAt:"\u5220\u9664\u65F6\u95F4",list:"\u6570\u636E\u5217\u8868",total:"\u603B\u6570",page:"\u9875\u7801",pageSize:"\u6BCF\u9875\u6570\u91CF"}[n]}function k(n){return{...n,properties:n.properties.map(e=>({...e,comment:e.comment||w(e.name)}))}}var g=class{constructor(){this.patterns=[{name:"PageResult",arrayFields:["list","records","rows","items"],countFields:["total","count","totalCount"]},{name:"ListResult",arrayFields:["list","data","items"],countFields:[]},{name:"ApiResponse",arrayFields:["data"],countFields:[]}]}extract(e){if(e.kind!=="object")return e;for(let t of this.patterns){let r=this.tryMatchPattern(e,t);if(r)return r}return e}tryMatchPattern(e,t){let r=null,i=t.countFields.length===0;for(let o of e.properties)t.arrayFields.includes(o.name)&&o.type.kind==="array"&&(r={name:o.name,elementType:o.type.elementType}),t.countFields.includes(o.name)&&(i=!0);return r&&i?{kind:"generic",name:t.name,typeArgs:[r.elementType]}:null}},h=class{constructor(e=!1){this.strict=e}process(e){if(this.strict)return e;if(e.kind==="union"){let t=e.types.filter(r=>r.kind!=="null");return t.length===0?{kind:"null"}:t.length===1?t[0]:{...e,types:t}}return e.kind==="array"?{...e,elementType:this.process(e.elementType)}:e.kind==="object"?{...e,properties:e.properties.map(t=>({...t,type:this.process(t.type)}))}:e}},N=class{constructor(e=!0){this.markOptional=e}process(e,t){if(!this.markOptional)return t;if(t.kind==="array"&&Array.isArray(e)){let r=t.elementType;if(r.kind==="object"){let i=this.processArrayObjects(e,r);return{...t,elementType:i}}}return t}processArrayObjects(e,t){if(e.length<=1)return t;let r={},i=e.length;for(let o of e)if(o&&typeof o=="object")for(let s of Object.keys(o))r[s]=(r[s]||0)+1;return{...t,properties:t.properties.map(o=>{let a=(r[o.name]||0)<i;return{...o,optional:a}})}}};function b(n,e,t){let r=e;return t.markOptional&&(r=new N(t.markOptional).process(n,r)),t.extractGenerics&&(r=new g().extract(r)),r=new h(t.strictNullChecks).process(r),r}function j(n,e={}){let t={...O,...e},r=l(n);r=b(n,r,t),t.addComments&&r.kind==="object"&&(r=k(r));let i=new m({namingStyle:t.namingStyle,prefix:t.typePrefix,suffix:t.typeSuffix,customNameMap:t.typeNameMap}),s=new f(i).collect(r,t.rootName);return{code:new y(t,i).generateOutput(s,t.rootName),types:s}}function K(n,e={}){let t=JSON.parse(n);return j(t,e)}function E(n,e={}){return j(n,e).code}var ee={generate:j,generateFromString:K,generateType:E};export{y as CodeFormatter,g as GenericExtractor,h as NullHandler,N as OptionalHandler,f as TypeCollector,m as TypeNamer,k as addGuessedComments,b as applyEnhancements,$ as createUnion,ee as default,j as generate,K as generateFromString,E as generateType,w as guessCommentFromFieldName,A as inferArrayType,C as inferObjectType,l as inferType,S as isStructurallyEqual,P as mergeObjects,T as mergeTypes};
|