type-flash 1.0.5 → 1.0.7
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/README.md +0 -18
- package/bin/type-flash.js +0 -14
- package/dist/index.d.mts +27 -93
- package/dist/index.d.ts +27 -93
- package/dist/index.js +6 -7
- package/dist/index.mjs +6 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -29,7 +29,6 @@
|
|
|
29
29
|
|
|
30
30
|
### ⚡ 增强功能
|
|
31
31
|
|
|
32
|
-
- **📑 枚举自动提取** - 字符串字段取值有限时,自动提取为 `enum` 枚举类型
|
|
33
32
|
- **🧬 泛型模式识别** - 智能识别分页结构 `{ list: T[], total: number }`,提取为 `PageResult<T>`
|
|
34
33
|
- **📝 JSDoc 注释生成** - 根据字段名猜测含义,自动生成文档注释
|
|
35
34
|
- **🎨 多种输出风格** - 支持 `interface` 和 `type alias` 两种输出风格
|
|
@@ -146,7 +145,6 @@ const apiResponse = {
|
|
|
146
145
|
|
|
147
146
|
const result = generate(apiResponse, {
|
|
148
147
|
rootName: 'ApiResponse',
|
|
149
|
-
extractEnums: true,
|
|
150
148
|
extractGenerics: true,
|
|
151
149
|
});
|
|
152
150
|
|
|
@@ -172,12 +170,6 @@ export interface ApiResponseData {
|
|
|
172
170
|
export interface ListItem {
|
|
173
171
|
id: number;
|
|
174
172
|
name: string;
|
|
175
|
-
status: StatusEnum;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
export enum StatusEnum {
|
|
179
|
-
ACTIVE = 'active',
|
|
180
|
-
INACTIVE = 'inactive',
|
|
181
173
|
}
|
|
182
174
|
```
|
|
183
175
|
|
|
@@ -232,8 +224,6 @@ type-flash types.json --no-export
|
|
|
232
224
|
| `--comments` | 生成 JSDoc 注释 | - |
|
|
233
225
|
| `--strict-null` | 严格空值模式 | - |
|
|
234
226
|
| `--no-optional` | 不标记可选属性 | - |
|
|
235
|
-
| `--no-enums` | 不提取枚举类型 | - |
|
|
236
|
-
| `--enum-threshold <n>` | 枚举提取阈值 | `5` |
|
|
237
227
|
| `--no-generics` | 不提取泛型类型 | - |
|
|
238
228
|
| `--indent <n>` | 缩进空格数 | `2` |
|
|
239
229
|
| `--prefix <prefix>` | 类型名前缀 | - |
|
|
@@ -273,12 +263,6 @@ interface GenerateOptions {
|
|
|
273
263
|
/** 是否标记可选属性,默认 true */
|
|
274
264
|
markOptional?: boolean;
|
|
275
265
|
|
|
276
|
-
/** 是否提取枚举类型,默认 true */
|
|
277
|
-
extractEnums?: boolean;
|
|
278
|
-
|
|
279
|
-
/** 枚举提取阈值,默认 5 */
|
|
280
|
-
enumThreshold?: number;
|
|
281
|
-
|
|
282
266
|
/** 是否提取泛型,默认 true */
|
|
283
267
|
extractGenerics?: boolean;
|
|
284
268
|
|
|
@@ -312,8 +296,6 @@ const result = generate(jsonData, {
|
|
|
312
296
|
addExport: true,
|
|
313
297
|
addComments: true,
|
|
314
298
|
sortProperties: 'alpha',
|
|
315
|
-
extractEnums: true,
|
|
316
|
-
enumThreshold: 8,
|
|
317
299
|
extractGenerics: true,
|
|
318
300
|
strictNullChecks: true,
|
|
319
301
|
indentSize: 2,
|
package/bin/type-flash.js
CHANGED
|
@@ -31,8 +31,6 @@ function parseArgs(argv) {
|
|
|
31
31
|
addComments: false,
|
|
32
32
|
strictNullChecks: false,
|
|
33
33
|
markOptional: true,
|
|
34
|
-
extractEnums: true,
|
|
35
|
-
enumThreshold: 5,
|
|
36
34
|
extractGenerics: true,
|
|
37
35
|
indentSize: 2,
|
|
38
36
|
typePrefix: '',
|
|
@@ -101,14 +99,6 @@ function parseArgs(argv) {
|
|
|
101
99
|
args.markOptional = false;
|
|
102
100
|
break;
|
|
103
101
|
|
|
104
|
-
case '--no-enums':
|
|
105
|
-
args.extractEnums = false;
|
|
106
|
-
break;
|
|
107
|
-
|
|
108
|
-
case '--enum-threshold':
|
|
109
|
-
args.enumThreshold = parseInt(argv[++i], 10);
|
|
110
|
-
break;
|
|
111
|
-
|
|
112
102
|
case '--no-generics':
|
|
113
103
|
args.extractGenerics = false;
|
|
114
104
|
break;
|
|
@@ -160,8 +150,6 @@ type-flash - JSON 智能生成 TypeScript 类型定义
|
|
|
160
150
|
--comments 生成 JSDoc 注释
|
|
161
151
|
--strict-null 严格空值模式(保留 null 类型)
|
|
162
152
|
--no-optional 不标记可选属性
|
|
163
|
-
--no-enums 不提取枚举类型
|
|
164
|
-
--enum-threshold <n> 枚举提取阈值(默认: 5)
|
|
165
153
|
--no-generics 不提取泛型类型
|
|
166
154
|
--indent <n> 缩进空格数(默认: 2)
|
|
167
155
|
--prefix <prefix> 类型名前缀
|
|
@@ -273,8 +261,6 @@ async function main() {
|
|
|
273
261
|
addComments: args.addComments,
|
|
274
262
|
strictNullChecks: args.strictNullChecks,
|
|
275
263
|
markOptional: args.markOptional,
|
|
276
|
-
extractEnums: args.extractEnums,
|
|
277
|
-
enumThreshold: args.enumThreshold,
|
|
278
264
|
extractGenerics: args.extractGenerics,
|
|
279
265
|
indentSize: args.indentSize,
|
|
280
266
|
typePrefix: args.typePrefix,
|
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 */
|
|
@@ -151,7 +139,7 @@ interface GenerateResult {
|
|
|
151
139
|
}
|
|
152
140
|
|
|
153
141
|
/**
|
|
154
|
-
*
|
|
142
|
+
* type-flash - 命名与去重模块
|
|
155
143
|
*
|
|
156
144
|
* 核心功能:
|
|
157
145
|
* - 根据字段名 + 上下文自动生成有意义的类型名
|
|
@@ -292,7 +280,7 @@ declare class TypeCollector {
|
|
|
292
280
|
}
|
|
293
281
|
|
|
294
282
|
/**
|
|
295
|
-
*
|
|
283
|
+
* type-flash - 格式化输出模块
|
|
296
284
|
*
|
|
297
285
|
* 核心功能:
|
|
298
286
|
* - 将类型节点格式化为 TypeScript 代码字符串
|
|
@@ -310,7 +298,7 @@ declare class CodeFormatter {
|
|
|
310
298
|
private allNamedTypes;
|
|
311
299
|
constructor(options: Required<GenerateOptions>, namer: TypeNamer);
|
|
312
300
|
/**
|
|
313
|
-
*
|
|
301
|
+
* 查找类型对应的命名(用于对象类型引用)
|
|
314
302
|
*/
|
|
315
303
|
private findTypeName;
|
|
316
304
|
/**
|
|
@@ -321,10 +309,6 @@ declare class CodeFormatter {
|
|
|
321
309
|
* 格式化对象类型(interface 或 type)
|
|
322
310
|
*/
|
|
323
311
|
private formatObjectType;
|
|
324
|
-
/**
|
|
325
|
-
* 格式化枚举类型
|
|
326
|
-
*/
|
|
327
|
-
private formatEnumType;
|
|
328
312
|
/**
|
|
329
313
|
* 格式化类型节点为字符串
|
|
330
314
|
*/
|
|
@@ -357,10 +341,6 @@ declare class CodeFormatter {
|
|
|
357
341
|
* 格式化多行 JSDoc 注释
|
|
358
342
|
*/
|
|
359
343
|
private formatJSDoc;
|
|
360
|
-
/**
|
|
361
|
-
* 转换为枚举键名(UPPER_SNAKE_CASE)
|
|
362
|
-
*/
|
|
363
|
-
private toEnumKey;
|
|
364
344
|
/**
|
|
365
345
|
* 格式化所有类型定义
|
|
366
346
|
*/
|
|
@@ -370,9 +350,17 @@ declare class CodeFormatter {
|
|
|
370
350
|
*/
|
|
371
351
|
generateOutput(typeDefs: NamedTypeDef[], rootTypeName: string): string;
|
|
372
352
|
}
|
|
353
|
+
/**
|
|
354
|
+
* 根据字段名猜测 JSDoc 注释
|
|
355
|
+
*/
|
|
356
|
+
declare function guessCommentFromFieldName(fieldName: string): string | undefined;
|
|
357
|
+
/**
|
|
358
|
+
* 为对象类型的属性添加猜测的注释
|
|
359
|
+
*/
|
|
360
|
+
declare function addGuessedComments(type: ObjectType): ObjectType;
|
|
373
361
|
|
|
374
362
|
/**
|
|
375
|
-
*
|
|
363
|
+
* type-flash - 类型推断引擎
|
|
376
364
|
*
|
|
377
365
|
* 核心功能:
|
|
378
366
|
* - 基础类型识别(string、number、boolean、null、undefined)
|
|
@@ -420,11 +408,10 @@ declare function inferObjectType(obj: Record<string, unknown>): ObjectType;
|
|
|
420
408
|
declare function isStructurallyEqual(a: TSTypeNode, b: TSTypeNode): boolean;
|
|
421
409
|
|
|
422
410
|
/**
|
|
423
|
-
*
|
|
411
|
+
* type-flash - 增强功能模块
|
|
424
412
|
*
|
|
425
413
|
* 核心功能:
|
|
426
414
|
* - 泛型提取(如 PageResult<T>)
|
|
427
|
-
* - 枚举提取
|
|
428
415
|
* - 空值处理
|
|
429
416
|
* - 可选属性处理
|
|
430
417
|
*/
|
|
@@ -438,17 +425,6 @@ declare class GenericExtractor {
|
|
|
438
425
|
extract(type: TSTypeNode): TSTypeNode;
|
|
439
426
|
private tryMatchPattern;
|
|
440
427
|
}
|
|
441
|
-
/**
|
|
442
|
-
* 枚举提取器
|
|
443
|
-
* 从字符串字段中提取枚举类型
|
|
444
|
-
*/
|
|
445
|
-
declare class EnumExtractor {
|
|
446
|
-
private threshold;
|
|
447
|
-
constructor(threshold?: number);
|
|
448
|
-
extract(jsonData: any, type: TSTypeNode): TSTypeNode;
|
|
449
|
-
private tryExtractEnum;
|
|
450
|
-
private isValidEnumValues;
|
|
451
|
-
}
|
|
452
428
|
/**
|
|
453
429
|
* 空值处理器
|
|
454
430
|
*/
|
|
@@ -472,74 +448,32 @@ declare class OptionalHandler {
|
|
|
472
448
|
declare function applyEnhancements(jsonData: any, type: TSTypeNode, options: GenerateOptions): TSTypeNode;
|
|
473
449
|
|
|
474
450
|
/**
|
|
475
|
-
*
|
|
451
|
+
* type-flash - JSON 智能生成 TypeScript 类型定义
|
|
476
452
|
*
|
|
477
453
|
* 主入口文件
|
|
478
|
-
*
|
|
479
|
-
* @example
|
|
480
|
-
* ```ts
|
|
481
|
-
* import { generate } from 'ts-gen';
|
|
482
|
-
*
|
|
483
|
-
* const json = { name: 'foo', age: 25 };
|
|
484
|
-
* const result = generate(json, { rootName: 'User' });
|
|
485
|
-
* console.log(result.code);
|
|
486
|
-
* ```
|
|
487
454
|
*/
|
|
488
455
|
|
|
489
456
|
/**
|
|
490
457
|
* 从 JSON 数据生成 TypeScript 类型定义
|
|
491
|
-
*
|
|
492
|
-
* @param
|
|
493
|
-
* @
|
|
494
|
-
* @returns 生成结果,包含代码字符串和类型定义列表
|
|
495
|
-
*
|
|
496
|
-
* @example
|
|
497
|
-
* ```ts
|
|
498
|
-
* import { generate } from 'ts-gen';
|
|
499
|
-
*
|
|
500
|
-
* const data = {
|
|
501
|
-
* id: 1,
|
|
502
|
-
* name: 'Alice',
|
|
503
|
-
* email: 'alice@example.com',
|
|
504
|
-
* profile: {
|
|
505
|
-
* avatar: 'https://...',
|
|
506
|
-
* bio: null
|
|
507
|
-
* }
|
|
508
|
-
* };
|
|
509
|
-
*
|
|
510
|
-
* const result = generate(data, {
|
|
511
|
-
* rootName: 'User',
|
|
512
|
-
* outputStyle: 'interface'
|
|
513
|
-
* });
|
|
514
|
-
*
|
|
515
|
-
* console.log(result.code);
|
|
516
|
-
* ```
|
|
458
|
+
* @param jsonData JSON 数据
|
|
459
|
+
* @param options 配置选项
|
|
460
|
+
* @returns 生成结果
|
|
517
461
|
*/
|
|
518
|
-
declare function generate(jsonData:
|
|
462
|
+
declare function generate(jsonData: any, options?: GenerateOptions): GenerateResult;
|
|
519
463
|
/**
|
|
520
|
-
* 从 JSON
|
|
521
|
-
*
|
|
464
|
+
* 从 JSON 字符串生成类型定义
|
|
522
465
|
* @param jsonString JSON 字符串
|
|
523
|
-
* @param options
|
|
466
|
+
* @param options 配置选项
|
|
524
467
|
* @returns 生成结果
|
|
525
|
-
*
|
|
526
|
-
* @example
|
|
527
|
-
* ```ts
|
|
528
|
-
* import { generateFromString } from 'ts-gen';
|
|
529
|
-
*
|
|
530
|
-
* const jsonStr = '{"name": "foo", "age": 25}';
|
|
531
|
-
* const result = generateFromString(jsonStr, { rootName: 'User' });
|
|
532
|
-
* ```
|
|
533
468
|
*/
|
|
534
469
|
declare function generateFromString(jsonString: string, options?: GenerateOptions): GenerateResult;
|
|
535
470
|
/**
|
|
536
|
-
*
|
|
537
|
-
*
|
|
471
|
+
* 生成单个类型的字符串表示
|
|
538
472
|
* @param jsonData JSON 数据
|
|
539
|
-
* @param options
|
|
540
|
-
* @returns
|
|
473
|
+
* @param options 配置选项
|
|
474
|
+
* @returns 类型字符串
|
|
541
475
|
*/
|
|
542
|
-
declare function generateType(jsonData:
|
|
476
|
+
declare function generateType(jsonData: any, options?: GenerateOptions): string;
|
|
543
477
|
|
|
544
478
|
declare const _default: {
|
|
545
479
|
generate: typeof generate;
|
|
@@ -547,4 +481,4 @@ declare const _default: {
|
|
|
547
481
|
generateType: typeof generateType;
|
|
548
482
|
};
|
|
549
483
|
|
|
550
|
-
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 */
|
|
@@ -151,7 +139,7 @@ interface GenerateResult {
|
|
|
151
139
|
}
|
|
152
140
|
|
|
153
141
|
/**
|
|
154
|
-
*
|
|
142
|
+
* type-flash - 命名与去重模块
|
|
155
143
|
*
|
|
156
144
|
* 核心功能:
|
|
157
145
|
* - 根据字段名 + 上下文自动生成有意义的类型名
|
|
@@ -292,7 +280,7 @@ declare class TypeCollector {
|
|
|
292
280
|
}
|
|
293
281
|
|
|
294
282
|
/**
|
|
295
|
-
*
|
|
283
|
+
* type-flash - 格式化输出模块
|
|
296
284
|
*
|
|
297
285
|
* 核心功能:
|
|
298
286
|
* - 将类型节点格式化为 TypeScript 代码字符串
|
|
@@ -310,7 +298,7 @@ declare class CodeFormatter {
|
|
|
310
298
|
private allNamedTypes;
|
|
311
299
|
constructor(options: Required<GenerateOptions>, namer: TypeNamer);
|
|
312
300
|
/**
|
|
313
|
-
*
|
|
301
|
+
* 查找类型对应的命名(用于对象类型引用)
|
|
314
302
|
*/
|
|
315
303
|
private findTypeName;
|
|
316
304
|
/**
|
|
@@ -321,10 +309,6 @@ declare class CodeFormatter {
|
|
|
321
309
|
* 格式化对象类型(interface 或 type)
|
|
322
310
|
*/
|
|
323
311
|
private formatObjectType;
|
|
324
|
-
/**
|
|
325
|
-
* 格式化枚举类型
|
|
326
|
-
*/
|
|
327
|
-
private formatEnumType;
|
|
328
312
|
/**
|
|
329
313
|
* 格式化类型节点为字符串
|
|
330
314
|
*/
|
|
@@ -357,10 +341,6 @@ declare class CodeFormatter {
|
|
|
357
341
|
* 格式化多行 JSDoc 注释
|
|
358
342
|
*/
|
|
359
343
|
private formatJSDoc;
|
|
360
|
-
/**
|
|
361
|
-
* 转换为枚举键名(UPPER_SNAKE_CASE)
|
|
362
|
-
*/
|
|
363
|
-
private toEnumKey;
|
|
364
344
|
/**
|
|
365
345
|
* 格式化所有类型定义
|
|
366
346
|
*/
|
|
@@ -370,9 +350,17 @@ declare class CodeFormatter {
|
|
|
370
350
|
*/
|
|
371
351
|
generateOutput(typeDefs: NamedTypeDef[], rootTypeName: string): string;
|
|
372
352
|
}
|
|
353
|
+
/**
|
|
354
|
+
* 根据字段名猜测 JSDoc 注释
|
|
355
|
+
*/
|
|
356
|
+
declare function guessCommentFromFieldName(fieldName: string): string | undefined;
|
|
357
|
+
/**
|
|
358
|
+
* 为对象类型的属性添加猜测的注释
|
|
359
|
+
*/
|
|
360
|
+
declare function addGuessedComments(type: ObjectType): ObjectType;
|
|
373
361
|
|
|
374
362
|
/**
|
|
375
|
-
*
|
|
363
|
+
* type-flash - 类型推断引擎
|
|
376
364
|
*
|
|
377
365
|
* 核心功能:
|
|
378
366
|
* - 基础类型识别(string、number、boolean、null、undefined)
|
|
@@ -420,11 +408,10 @@ declare function inferObjectType(obj: Record<string, unknown>): ObjectType;
|
|
|
420
408
|
declare function isStructurallyEqual(a: TSTypeNode, b: TSTypeNode): boolean;
|
|
421
409
|
|
|
422
410
|
/**
|
|
423
|
-
*
|
|
411
|
+
* type-flash - 增强功能模块
|
|
424
412
|
*
|
|
425
413
|
* 核心功能:
|
|
426
414
|
* - 泛型提取(如 PageResult<T>)
|
|
427
|
-
* - 枚举提取
|
|
428
415
|
* - 空值处理
|
|
429
416
|
* - 可选属性处理
|
|
430
417
|
*/
|
|
@@ -438,17 +425,6 @@ declare class GenericExtractor {
|
|
|
438
425
|
extract(type: TSTypeNode): TSTypeNode;
|
|
439
426
|
private tryMatchPattern;
|
|
440
427
|
}
|
|
441
|
-
/**
|
|
442
|
-
* 枚举提取器
|
|
443
|
-
* 从字符串字段中提取枚举类型
|
|
444
|
-
*/
|
|
445
|
-
declare class EnumExtractor {
|
|
446
|
-
private threshold;
|
|
447
|
-
constructor(threshold?: number);
|
|
448
|
-
extract(jsonData: any, type: TSTypeNode): TSTypeNode;
|
|
449
|
-
private tryExtractEnum;
|
|
450
|
-
private isValidEnumValues;
|
|
451
|
-
}
|
|
452
428
|
/**
|
|
453
429
|
* 空值处理器
|
|
454
430
|
*/
|
|
@@ -472,74 +448,32 @@ declare class OptionalHandler {
|
|
|
472
448
|
declare function applyEnhancements(jsonData: any, type: TSTypeNode, options: GenerateOptions): TSTypeNode;
|
|
473
449
|
|
|
474
450
|
/**
|
|
475
|
-
*
|
|
451
|
+
* type-flash - JSON 智能生成 TypeScript 类型定义
|
|
476
452
|
*
|
|
477
453
|
* 主入口文件
|
|
478
|
-
*
|
|
479
|
-
* @example
|
|
480
|
-
* ```ts
|
|
481
|
-
* import { generate } from 'ts-gen';
|
|
482
|
-
*
|
|
483
|
-
* const json = { name: 'foo', age: 25 };
|
|
484
|
-
* const result = generate(json, { rootName: 'User' });
|
|
485
|
-
* console.log(result.code);
|
|
486
|
-
* ```
|
|
487
454
|
*/
|
|
488
455
|
|
|
489
456
|
/**
|
|
490
457
|
* 从 JSON 数据生成 TypeScript 类型定义
|
|
491
|
-
*
|
|
492
|
-
* @param
|
|
493
|
-
* @
|
|
494
|
-
* @returns 生成结果,包含代码字符串和类型定义列表
|
|
495
|
-
*
|
|
496
|
-
* @example
|
|
497
|
-
* ```ts
|
|
498
|
-
* import { generate } from 'ts-gen';
|
|
499
|
-
*
|
|
500
|
-
* const data = {
|
|
501
|
-
* id: 1,
|
|
502
|
-
* name: 'Alice',
|
|
503
|
-
* email: 'alice@example.com',
|
|
504
|
-
* profile: {
|
|
505
|
-
* avatar: 'https://...',
|
|
506
|
-
* bio: null
|
|
507
|
-
* }
|
|
508
|
-
* };
|
|
509
|
-
*
|
|
510
|
-
* const result = generate(data, {
|
|
511
|
-
* rootName: 'User',
|
|
512
|
-
* outputStyle: 'interface'
|
|
513
|
-
* });
|
|
514
|
-
*
|
|
515
|
-
* console.log(result.code);
|
|
516
|
-
* ```
|
|
458
|
+
* @param jsonData JSON 数据
|
|
459
|
+
* @param options 配置选项
|
|
460
|
+
* @returns 生成结果
|
|
517
461
|
*/
|
|
518
|
-
declare function generate(jsonData:
|
|
462
|
+
declare function generate(jsonData: any, options?: GenerateOptions): GenerateResult;
|
|
519
463
|
/**
|
|
520
|
-
* 从 JSON
|
|
521
|
-
*
|
|
464
|
+
* 从 JSON 字符串生成类型定义
|
|
522
465
|
* @param jsonString JSON 字符串
|
|
523
|
-
* @param options
|
|
466
|
+
* @param options 配置选项
|
|
524
467
|
* @returns 生成结果
|
|
525
|
-
*
|
|
526
|
-
* @example
|
|
527
|
-
* ```ts
|
|
528
|
-
* import { generateFromString } from 'ts-gen';
|
|
529
|
-
*
|
|
530
|
-
* const jsonStr = '{"name": "foo", "age": 25}';
|
|
531
|
-
* const result = generateFromString(jsonStr, { rootName: 'User' });
|
|
532
|
-
* ```
|
|
533
468
|
*/
|
|
534
469
|
declare function generateFromString(jsonString: string, options?: GenerateOptions): GenerateResult;
|
|
535
470
|
/**
|
|
536
|
-
*
|
|
537
|
-
*
|
|
471
|
+
* 生成单个类型的字符串表示
|
|
538
472
|
* @param jsonData JSON 数据
|
|
539
|
-
* @param options
|
|
540
|
-
* @returns
|
|
473
|
+
* @param options 配置选项
|
|
474
|
+
* @returns 类型字符串
|
|
541
475
|
*/
|
|
542
|
-
declare function generateType(jsonData:
|
|
476
|
+
declare function generateType(jsonData: any, options?: GenerateOptions): string;
|
|
543
477
|
|
|
544
478
|
declare const _default: {
|
|
545
479
|
generate: typeof generate;
|
|
@@ -547,4 +481,4 @@ declare const _default: {
|
|
|
547
481
|
generateType: typeof generateType;
|
|
548
482
|
};
|
|
549
483
|
|
|
550
|
-
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,15 +1,14 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`,typeNameMap:{},typePrefix:"",typeSuffix:""};function
|
|
3
|
-
`)}
|
|
4
|
-
`)}formatType(e){if(e.kind==="object"||e.kind==="enum"){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"enum":return e.name;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 s of r){let o=this.formatPropertyName(s.name),a=s.optional?"?":"",p=this.formatType(s.type);i.push(`${t}${o}${a}: ${p};`)}return i.push("}"),i.join(`
|
|
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(`
|
|
5
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(`
|
|
6
5
|
`);return t.length===1?`/** ${e} */`:["/**",...t.map(r=>` * ${r}`)," */"].join(`
|
|
7
|
-
`)}
|
|
6
|
+
`)}formatAll(e){return this.allNamedTypes=e,e.map(t=>this.formatTypeDef(t)).join(`
|
|
8
7
|
|
|
9
8
|
`)}generateOutput(e,t){let r=`/**
|
|
10
|
-
* Generated by
|
|
9
|
+
* Generated by type-flash
|
|
11
10
|
* Root type: ${t}
|
|
12
11
|
*/`,i=this.formatAll(e);return`${r}
|
|
13
12
|
|
|
14
13
|
${i}
|
|
15
|
-
`}};function
|
|
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,15 +1,14 @@
|
|
|
1
|
-
var
|
|
2
|
-
`,typeNameMap:{},typePrefix:"",typeSuffix:""};function
|
|
3
|
-
`)}
|
|
4
|
-
`)}formatType(e){if(e.kind==="object"||e.kind==="enum"){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"enum":return e.name;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 s of r){let o=this.formatPropertyName(s.name),a=s.optional?"?":"",p=this.formatType(s.type);i.push(`${t}${o}${a}: ${p};`)}return i.push("}"),i.join(`
|
|
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(`
|
|
5
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(`
|
|
6
5
|
`);return t.length===1?`/** ${e} */`:["/**",...t.map(r=>` * ${r}`)," */"].join(`
|
|
7
|
-
`)}
|
|
6
|
+
`)}formatAll(e){return this.allNamedTypes=e,e.map(t=>this.formatTypeDef(t)).join(`
|
|
8
7
|
|
|
9
8
|
`)}generateOutput(e,t){let r=`/**
|
|
10
|
-
* Generated by
|
|
9
|
+
* Generated by type-flash
|
|
11
10
|
* Root type: ${t}
|
|
12
11
|
*/`,i=this.formatAll(e);return`${r}
|
|
13
12
|
|
|
14
13
|
${i}
|
|
15
|
-
`}};function
|
|
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};
|