type-flash 1.0.2 → 1.0.5

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 CHANGED
@@ -295,11 +295,9 @@ declare class TypeCollector {
295
295
  * ts-gen - 格式化输出模块
296
296
  *
297
297
  * 核心功能:
298
- * - 将类型节点转换为 TypeScript 代码字符串
298
+ * - 将类型节点格式化为 TypeScript 代码字符串
299
299
  * - 支持 interface 和 type alias 两种输出风格
300
- * - 自动缩进、排序
301
- * - 支持导出语句
302
- * - 支持 JSDoc 注释生成
300
+ * - 自动缩进、排序、注释生成
303
301
  */
304
302
 
305
303
  /**
@@ -308,13 +306,19 @@ declare class TypeCollector {
308
306
  declare class CodeFormatter {
309
307
  private options;
310
308
  private namer;
309
+ /** 所有已命名的类型列表(用于查找引用) */
310
+ private allNamedTypes;
311
311
  constructor(options: Required<GenerateOptions>, namer: TypeNamer);
312
312
  /**
313
- * 格式化单个类型定义为代码
313
+ * 查找类型对应的命名(用于对象/枚举类型引用)
314
+ */
315
+ private findTypeName;
316
+ /**
317
+ * 格式化单个类型定义
314
318
  */
315
319
  formatTypeDef(typeDef: NamedTypeDef): string;
316
320
  /**
317
- * 格式化对象类型
321
+ * 格式化对象类型(interface 或 type)
318
322
  */
319
323
  private formatObjectType;
320
324
  /**
@@ -324,7 +328,7 @@ declare class CodeFormatter {
324
328
  /**
325
329
  * 格式化类型节点为字符串
326
330
  */
327
- formatType(type: TSTypeNode): string;
331
+ private formatType;
328
332
  /**
329
333
  * 格式化字面量
330
334
  */
@@ -342,8 +346,7 @@ declare class CodeFormatter {
342
346
  */
343
347
  private formatUnionType;
344
348
  /**
345
- * 格式化属性名
346
- * 处理非法标识符的情况(用引号包裹)
349
+ * 格式化属性名(非法标识符用引号包裹)
347
350
  */
348
351
  private formatPropertyName;
349
352
  /**
@@ -351,15 +354,11 @@ declare class CodeFormatter {
351
354
  */
352
355
  private sortProperties;
353
356
  /**
354
- * 格式化 JSDoc 注释(多行)
357
+ * 格式化多行 JSDoc 注释
355
358
  */
356
359
  private formatJSDoc;
357
360
  /**
358
- * 格式化内联 JSDoc 注释(单行)
359
- */
360
- private formatInlineJSDoc;
361
- /**
362
- * 转换为枚举键名
361
+ * 转换为枚举键名(UPPER_SNAKE_CASE)
363
362
  */
364
363
  private toEnumKey;
365
364
  /**
@@ -367,7 +366,7 @@ declare class CodeFormatter {
367
366
  */
368
367
  formatAll(typeDefs: NamedTypeDef[]): string;
369
368
  /**
370
- * 生成完整的输出代码
369
+ * 生成完整输出代码
371
370
  */
372
371
  generateOutput(typeDefs: NamedTypeDef[], rootTypeName: string): string;
373
372
  }
@@ -409,7 +408,7 @@ declare function inferType(value: unknown): TSTypeNode;
409
408
  * - 统一提取元素类型
410
409
  * - 元素类型不一致时生成联合类型
411
410
  */
412
- declare function inferArrayType(arr: unknown[]): TSTypeNode;
411
+ declare function inferArrayType(arr: unknown[]): ArrayType;
413
412
  /**
414
413
  * 推断对象类型
415
414
  */
@@ -424,128 +423,53 @@ declare function isStructurallyEqual(a: TSTypeNode, b: TSTypeNode): boolean;
424
423
  * ts-gen - 增强功能模块
425
424
  *
426
425
  * 核心功能:
427
- * - 泛型提取(识别列表结构,提取为 PageResult<T>)
428
- * - 枚举提取(字符串字段取值有限时自动提取为枚举)
429
- * - 空值处理(严格/非严格模式)
426
+ * - 泛型提取(如 PageResult<T>)
427
+ * - 枚举提取
428
+ * - 空值处理
430
429
  * - 可选属性处理
431
430
  */
432
431
 
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
432
  /**
454
433
  * 泛型提取器
434
+ * 识别常见的列表结构,提取为泛型类型
455
435
  */
456
436
  declare class GenericExtractor {
457
437
  private patterns;
458
- constructor(customPatterns?: GenericPattern[]);
459
- /**
460
- * 尝试提取泛型类型
461
- * @param type 对象类型
462
- * @returns 如果匹配成功返回泛型类型,否则返回原类型
463
- */
464
438
  extract(type: TSTypeNode): TSTypeNode;
465
- /**
466
- * 尝试匹配泛型模式
467
- */
468
439
  private tryMatchPattern;
469
- /**
470
- * 递归处理子属性
471
- */
472
- private extractRecursive;
473
- /**
474
- * 提取属性类型中的泛型
475
- */
476
- private extractPropertyType;
477
440
  }
478
441
  /**
479
442
  * 枚举提取器
443
+ * 从字符串字段中提取枚举类型
480
444
  */
481
445
  declare class EnumExtractor {
482
446
  private threshold;
483
447
  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
- */
448
+ extract(jsonData: any, type: TSTypeNode): TSTypeNode;
502
449
  private tryExtractEnum;
450
+ private isValidEnumValues;
503
451
  }
504
452
  /**
505
453
  * 空值处理器
506
454
  */
507
455
  declare class NullHandler {
508
- private strictNullChecks;
509
- constructor(strictNullChecks?: boolean);
510
- /**
511
- * 处理类型中的 null
512
- */
456
+ private strict;
457
+ constructor(strict?: boolean);
513
458
  process(type: TSTypeNode): TSTypeNode;
514
- /**
515
- * 递归处理(严格模式)
516
- */
517
- private processRecursive;
518
- /**
519
- * 递归移除 null
520
- */
521
- private removeNullRecursive;
522
459
  }
523
460
  /**
524
461
  * 可选属性处理器
525
- * 基于数组中对象的字段出现频率判断是否可选
526
462
  */
527
463
  declare class OptionalHandler {
528
464
  private markOptional;
529
465
  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;
466
+ process(jsonData: any, type: TSTypeNode): TSTypeNode;
467
+ private processArrayObjects;
544
468
  }
545
469
  /**
546
470
  * 应用所有增强功能
547
471
  */
548
- declare function applyEnhancements(jsonData: unknown, type: TSTypeNode, options: Required<GenerateOptions>): TSTypeNode;
472
+ declare function applyEnhancements(jsonData: any, type: TSTypeNode, options: GenerateOptions): TSTypeNode;
549
473
 
550
474
  /**
551
475
  * ts-gen - JSON 智能生成 TypeScript 类型定义
package/dist/index.d.ts CHANGED
@@ -295,11 +295,9 @@ declare class TypeCollector {
295
295
  * ts-gen - 格式化输出模块
296
296
  *
297
297
  * 核心功能:
298
- * - 将类型节点转换为 TypeScript 代码字符串
298
+ * - 将类型节点格式化为 TypeScript 代码字符串
299
299
  * - 支持 interface 和 type alias 两种输出风格
300
- * - 自动缩进、排序
301
- * - 支持导出语句
302
- * - 支持 JSDoc 注释生成
300
+ * - 自动缩进、排序、注释生成
303
301
  */
304
302
 
305
303
  /**
@@ -308,13 +306,19 @@ declare class TypeCollector {
308
306
  declare class CodeFormatter {
309
307
  private options;
310
308
  private namer;
309
+ /** 所有已命名的类型列表(用于查找引用) */
310
+ private allNamedTypes;
311
311
  constructor(options: Required<GenerateOptions>, namer: TypeNamer);
312
312
  /**
313
- * 格式化单个类型定义为代码
313
+ * 查找类型对应的命名(用于对象/枚举类型引用)
314
+ */
315
+ private findTypeName;
316
+ /**
317
+ * 格式化单个类型定义
314
318
  */
315
319
  formatTypeDef(typeDef: NamedTypeDef): string;
316
320
  /**
317
- * 格式化对象类型
321
+ * 格式化对象类型(interface 或 type)
318
322
  */
319
323
  private formatObjectType;
320
324
  /**
@@ -324,7 +328,7 @@ declare class CodeFormatter {
324
328
  /**
325
329
  * 格式化类型节点为字符串
326
330
  */
327
- formatType(type: TSTypeNode): string;
331
+ private formatType;
328
332
  /**
329
333
  * 格式化字面量
330
334
  */
@@ -342,8 +346,7 @@ declare class CodeFormatter {
342
346
  */
343
347
  private formatUnionType;
344
348
  /**
345
- * 格式化属性名
346
- * 处理非法标识符的情况(用引号包裹)
349
+ * 格式化属性名(非法标识符用引号包裹)
347
350
  */
348
351
  private formatPropertyName;
349
352
  /**
@@ -351,15 +354,11 @@ declare class CodeFormatter {
351
354
  */
352
355
  private sortProperties;
353
356
  /**
354
- * 格式化 JSDoc 注释(多行)
357
+ * 格式化多行 JSDoc 注释
355
358
  */
356
359
  private formatJSDoc;
357
360
  /**
358
- * 格式化内联 JSDoc 注释(单行)
359
- */
360
- private formatInlineJSDoc;
361
- /**
362
- * 转换为枚举键名
361
+ * 转换为枚举键名(UPPER_SNAKE_CASE)
363
362
  */
364
363
  private toEnumKey;
365
364
  /**
@@ -367,7 +366,7 @@ declare class CodeFormatter {
367
366
  */
368
367
  formatAll(typeDefs: NamedTypeDef[]): string;
369
368
  /**
370
- * 生成完整的输出代码
369
+ * 生成完整输出代码
371
370
  */
372
371
  generateOutput(typeDefs: NamedTypeDef[], rootTypeName: string): string;
373
372
  }
@@ -409,7 +408,7 @@ declare function inferType(value: unknown): TSTypeNode;
409
408
  * - 统一提取元素类型
410
409
  * - 元素类型不一致时生成联合类型
411
410
  */
412
- declare function inferArrayType(arr: unknown[]): TSTypeNode;
411
+ declare function inferArrayType(arr: unknown[]): ArrayType;
413
412
  /**
414
413
  * 推断对象类型
415
414
  */
@@ -424,128 +423,53 @@ declare function isStructurallyEqual(a: TSTypeNode, b: TSTypeNode): boolean;
424
423
  * ts-gen - 增强功能模块
425
424
  *
426
425
  * 核心功能:
427
- * - 泛型提取(识别列表结构,提取为 PageResult<T>)
428
- * - 枚举提取(字符串字段取值有限时自动提取为枚举)
429
- * - 空值处理(严格/非严格模式)
426
+ * - 泛型提取(如 PageResult<T>)
427
+ * - 枚举提取
428
+ * - 空值处理
430
429
  * - 可选属性处理
431
430
  */
432
431
 
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
432
  /**
454
433
  * 泛型提取器
434
+ * 识别常见的列表结构,提取为泛型类型
455
435
  */
456
436
  declare class GenericExtractor {
457
437
  private patterns;
458
- constructor(customPatterns?: GenericPattern[]);
459
- /**
460
- * 尝试提取泛型类型
461
- * @param type 对象类型
462
- * @returns 如果匹配成功返回泛型类型,否则返回原类型
463
- */
464
438
  extract(type: TSTypeNode): TSTypeNode;
465
- /**
466
- * 尝试匹配泛型模式
467
- */
468
439
  private tryMatchPattern;
469
- /**
470
- * 递归处理子属性
471
- */
472
- private extractRecursive;
473
- /**
474
- * 提取属性类型中的泛型
475
- */
476
- private extractPropertyType;
477
440
  }
478
441
  /**
479
442
  * 枚举提取器
443
+ * 从字符串字段中提取枚举类型
480
444
  */
481
445
  declare class EnumExtractor {
482
446
  private threshold;
483
447
  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
- */
448
+ extract(jsonData: any, type: TSTypeNode): TSTypeNode;
502
449
  private tryExtractEnum;
450
+ private isValidEnumValues;
503
451
  }
504
452
  /**
505
453
  * 空值处理器
506
454
  */
507
455
  declare class NullHandler {
508
- private strictNullChecks;
509
- constructor(strictNullChecks?: boolean);
510
- /**
511
- * 处理类型中的 null
512
- */
456
+ private strict;
457
+ constructor(strict?: boolean);
513
458
  process(type: TSTypeNode): TSTypeNode;
514
- /**
515
- * 递归处理(严格模式)
516
- */
517
- private processRecursive;
518
- /**
519
- * 递归移除 null
520
- */
521
- private removeNullRecursive;
522
459
  }
523
460
  /**
524
461
  * 可选属性处理器
525
- * 基于数组中对象的字段出现频率判断是否可选
526
462
  */
527
463
  declare class OptionalHandler {
528
464
  private markOptional;
529
465
  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;
466
+ process(jsonData: any, type: TSTypeNode): TSTypeNode;
467
+ private processArrayObjects;
544
468
  }
545
469
  /**
546
470
  * 应用所有增强功能
547
471
  */
548
- declare function applyEnhancements(jsonData: unknown, type: TSTypeNode, options: Required<GenerateOptions>): TSTypeNode;
472
+ declare function applyEnhancements(jsonData: any, type: TSTypeNode, options: GenerateOptions): TSTypeNode;
549
473
 
550
474
  /**
551
475
  * ts-gen - JSON 智能生成 TypeScript 类型定义
package/dist/index.js CHANGED
@@ -1,6 +1,15 @@
1
- "use strict";var P=Object.defineProperty;var L=Object.getOwnPropertyDescriptor;var V=Object.getOwnPropertyNames;var z=Object.prototype.hasOwnProperty;var _=(i,e)=>{for(var t in e)P(i,t,{get:e[t],enumerable:!0})},q=(i,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of V(e))!z.call(i,n)&&n!==t&&P(i,n,{get:()=>e[n],enumerable:!(r=L(e,n))||r.enumerable});return i};var J=i=>q(P({},"__esModule",{value:!0}),i);var X={};_(X,{CodeFormatter:()=>T,EnumExtractor:()=>S,GenericExtractor:()=>k,NullHandler:()=>v,OptionalHandler:()=>b,TypeCollector:()=>y,TypeNamer:()=>d,applyEnhancements:()=>x,createUnion:()=>h,default:()=>Q,generate:()=>$,generateFromString:()=>M,generateType:()=>F,inferArrayType:()=>A,inferObjectType:()=>E,inferType:()=>f,isStructurallyEqual:()=>U,mergeObjects:()=>R,mergeTypes:()=>N});module.exports=J(X);var D={rootName:"Root",outputStyle:"interface",namingStyle:"PascalCase",sortProperties:"alpha",addExport:!0,addComments:!1,strictNullChecks:!1,markOptional:!0,extractEnums:!0,enumThreshold:5,extractGenerics:!0,indentSize:2,lineEnding:`
2
- `,typeNameMap:{},typePrefix:"",typeSuffix:""};function m(i){return{kind:"primitive",type:i}}function Z(){return{kind:"null"}}function B(){return{kind:"undefined"}}function w(i){return{kind:"array",elementType:i}}function G(i=[]){return{kind:"object",properties:i}}function h(i){let e=[],t=new Set;for(let r of i)if(r.kind==="union")for(let n of r.types){let o=c(n);t.has(o)||(t.add(o),e.push(n))}else{let n=c(r);t.has(n)||(t.add(n),e.push(r))}return e.length===1?e[0]:{kind:"union",types:e}}function c(i){switch(i.kind){case"primitive":return`primitive:${i.type}`;case"null":return"null";case"undefined":return"undefined";case"literal":return`literal:${typeof i.value}:${String(i.value)}`;case"array":return`array:${c(i.elementType)}`;case"object":return`object:${i.properties.map(e=>`${e.name}:${c(e.type)}:${e.optional}`).join(",")}`;case"union":return`union:${i.types.map(c).sort().join("|")}`;case"enum":return`enum:${i.name}:${i.values.join(",")}`;case"generic":return`generic:${i.name}:${i.typeArgs.map(c).join(",")}`;default:return"unknown"}}function N(i,e){return c(i)===c(e)?i:i.kind==="object"&&e.kind==="object"?R(i,e):i.kind==="array"&&e.kind==="array"?w(N(i.elementType,e.elementType)):h([i,e])}function R(i,e){let t=new Map;for(let r of i.properties)t.set(r.name,{...r});for(let r of e.properties){let n=t.get(r.name);n?(n.type=N(n.type,r.type),n.optional=n.optional||r.optional,r.comment&&!n.comment&&(n.comment=r.comment)):t.set(r.name,{...r,optional:!0})}for(let[r,n]of t)e.properties.some(s=>s.name===r)||(n.optional=!0);return G(Array.from(t.values()))}function f(i){return i===null?Z():i===void 0?B():typeof i=="string"?m("string"):typeof i=="number"?m("number"):typeof i=="boolean"?m("boolean"):Array.isArray(i)?A(i):typeof i=="object"?E(i):m("unknown")}function A(i){if(i.length===0)return w(m("never"));let e=f(i[0]);for(let t=1;t<i.length;t++){let r=f(i[t]);e=N(e,r)}return w(e)}function E(i){let e=[];for(let[t,r]of Object.entries(i)){let n=f(r);e.push({name:t,type:n,optional:!1})}return G(e)}function U(i,e){return c(i)===c(e)}function l(i){switch(i.kind){case"primitive":case"null":case"undefined":return{...i};case"literal":return{...i};case"array":return{...i,elementType:l(i.elementType)};case"object":return{...i,properties:i.properties.map(e=>({...e,type:l(e.type)}))};case"union":return{...i,types:i.types.map(e=>l(e))};case"enum":return{...i,values:[...i.values]};case"generic":return{...i,typeArgs:i.typeArgs.map(e=>l(e))};default:return{...i}}}var d=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"&&e.kind!=="enum")return null;let r=this.buildPathKey(t);if(this.customNameMap[r])return this.applyAffixes(this.customNameMap[r]);let n=this.getTypeKey(e);if(this.namedTypes.has(n))return this.namedTypes.get(n);let o=this.generateName(e,t);return o=this.ensureUniqueName(o),o=this.applyAffixes(o),this.namedTypes.set(n,o),o}generateName(e,t){if(e.kind==="enum")return t.fieldName?this.toPascalCase(t.fieldName)+"Enum":"AnonymousEnum";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==="enum"?`enum:${e.values.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"enum":return`enum:${e.name}`;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()}},y=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 n=this.collected.find(s=>s.name===t),o=this.collected.filter(s=>s.name!==t);return n?[n,...o]:this.collected}collectRecursive(e,t){let r=this.getStructKey(e);if(e.kind==="object"){let n=this.namer.nameType(e,t);if(n&&!this.seenStructs.has(r)){this.seenStructs.add(r),this.collected.push({name:n,type:l(e)});for(let o of e.properties)this.collectRecursive(o.type,{fieldName:o.name,parentName:n,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 n of e.types)this.collectRecursive(n,t);return}if(e.kind==="enum"){let n=this.namer.nameType(e,t);n&&!this.seenStructs.has(r)&&(this.seenStructs.add(r),this.collected.push({name:n,type:l(e)}));return}if(e.kind==="generic"){for(let n of e.typeArgs)this.collectRecursive(n,{...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==="enum"?`enum:${[...e.values].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"enum":return`enum:${e.name}`;case"generic":return`generic:${e.name}`;default:return"unknown"}}};function I(i){let e=i.replace(/[^a-zA-Z0-9_$]/g,"_");return/^\d/.test(e)&&(e="_"+e),e}function C(i){return/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(i)}var T=class{constructor(e,t){this.options=e,this.namer=t}formatTypeDef(e){let{name:t,type:r,comment:n}=e,o="";this.options.addComments&&n&&(o+=this.formatJSDoc(n)+this.options.lineEnding);let s=this.options.addExport?"export ":"";return r.kind==="object"?o+=this.formatObjectType(t,r,s):r.kind==="enum"?o+=this.formatEnumType(t,r,s):o+=`${s}type ${t} = ${this.formatType(r)};`,o}formatObjectType(e,t,r){let n=this.options.outputStyle,o=" ".repeat(this.options.indentSize),s=this.options.lineEnding,u=this.sortProperties(t.properties);if(n==="interface"){let a=`${r}interface ${e} {${s}`;for(let p of u){this.options.addComments&&p.comment&&(a+=o+this.formatInlineJSDoc(p.comment)+s);let g=this.formatPropertyName(p.name),j=p.optional&&this.options.markOptional?"?":"",O=this.formatType(p.type);a+=`${o}${g}${j}: ${O};${s}`}return a+=`}${s}`,a}else{let a=`${r}type ${e} = {${s}`;for(let p of u){this.options.addComments&&p.comment&&(a+=o+this.formatInlineJSDoc(p.comment)+s);let g=this.formatPropertyName(p.name),j=p.optional&&this.options.markOptional?"?":"",O=this.formatType(p.type);a+=`${o}${g}${j}: ${O};${s}`}return a+=`};${s}`,a}}formatEnumType(e,t,r){let n=" ".repeat(this.options.indentSize),o=this.options.lineEnding,s=t.values.every(a=>typeof a=="string"),u=`${r}enum ${e} {${o}`;for(let a of t.values)if(s){let p=this.toEnumKey(String(a));u+=`${n}${p} = '${a}',${o}`}else{let p=`Value${a}`;u+=`${n}${p} = ${a},${o}`}return u+=`}${o}`,u}formatType(e){switch(e.kind){case"primitive":return e.type;case"null":return"null";case"undefined":return"undefined";case"literal":return this.formatLiteral(e.value);case"array":return this.formatArrayType(e.elementType);case"object":return this.formatInlineObject(e);case"union":return this.formatUnionType(e.types);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.replace(/'/g,"\\'")}'`:String(e)}formatArrayType(e){let t=this.formatType(e);return e.kind==="union"?`(${t})[]`:`${t}[]`}formatInlineObject(e){let t=" ".repeat(this.options.indentSize),r=this.options.lineEnding,n=this.sortProperties(e.properties);if(n.length===0)return"{}";let o=`{${r}`;for(let s of n){let u=this.formatPropertyName(s.name),a=s.optional&&this.options.markOptional?"?":"",p=this.formatType(s.type);o+=`${t}${u}${a}: ${p};${r}`}return o+="}",o}formatUnionType(e){return e.map(t=>this.formatType(t)).join(" | ")}formatPropertyName(e){return C(e)?e:`'${e.replace(/'/g,"\\'")}'`}sortProperties(e){return this.options.sortProperties==="alpha"?[...e].sort((r,n)=>r.name.localeCompare(n.name)):[...e]}formatJSDoc(e){let t=e.split(`
3
- `);return t.length===1?`/** ${e} */`:`/**
4
- * ${t.join(`
5
- * `)}
6
- */`}formatInlineJSDoc(e){return`/** ${e} */`}toEnumKey(e){let r=e.replace(/[-_\s]+/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").trim().split(" ").filter(Boolean).map(n=>n.toUpperCase()).join("_");return/^\d/.test(r)&&(r="VALUE_"+r),C(r)||(r=I(r)),r}formatAll(e){let t=this.options.lineEnding,r=[];for(let n of e)r.push(this.formatTypeDef(n));return r.join(t)}generateOutput(e,t){let r=this.options.lineEnding,n="";return n+=`/**${r}`,n+=` * Generated by ts-gen${r}`,n+=` * Root type: ${t}${r}`,n+=` */${r}`,n+=r,n+=this.formatAll(e),n}};function H(i){let e=i.toLowerCase();return{id:"\u552F\u4E00\u6807\u8BC6\u7B26",name:"\u540D\u79F0",title:"\u6807\u9898",desc:"\u63CF\u8FF0",description:"\u63CF\u8FF0",type:"\u7C7B\u578B",status:"\u72B6\u6001",code:"\u7F16\u7801/\u72B6\u6001\u7801",msg:"\u6D88\u606F",message:"\u6D88\u606F",data:"\u6570\u636E",list:"\u5217\u8868\u6570\u636E",total:"\u603B\u6570",page:"\u9875\u7801",pageSize:"\u6BCF\u9875\u6570\u91CF",pageNum:"\u9875\u7801",pageIndex:"\u9875\u7801",size:"\u6570\u91CF/\u5927\u5C0F",count:"\u6570\u91CF",createTime:"\u521B\u5EFA\u65F6\u95F4",updateTime:"\u66F4\u65B0\u65F6\u95F4",createdAt:"\u521B\u5EFA\u65F6\u95F4",updatedAt:"\u66F4\u65B0\u65F6\u95F4",deleted:"\u662F\u5426\u5DF2\u5220\u9664",enabled:"\u662F\u5426\u542F\u7528",active:"\u662F\u5426\u6FC0\u6D3B",url:"\u94FE\u63A5\u5730\u5740",avatar:"\u5934\u50CF",email:"\u90AE\u7BB1",phone:"\u624B\u673A\u53F7",mobile:"\u624B\u673A\u53F7",username:"\u7528\u6237\u540D",password:"\u5BC6\u7801",token:"\u4EE4\u724C",userId:"\u7528\u6237ID",userName:"\u7528\u6237\u540D"}[e]}function K(i){return{...i,properties:i.properties.map(e=>({...e,comment:e.comment||H(e.name)}))}}var W=[{name:"PageResult",match:{listField:["list","records","rows","items","dataList"],totalField:["total","totalCount","count"]},typeParamIndex:0},{name:"ListResult",match:{listField:["list","records","rows","items"]},typeParamIndex:0},{name:"ApiResponse",match:{listField:["data"],totalField:["code","status"]},typeParamIndex:0}],k=class{constructor(e){this.patterns=e||W}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 this.extractRecursive(e)}tryMatchPattern(e,t){let r=e.properties,n=r.map(a=>a.name),o;if(t.match.listField)for(let a of t.match.listField){let p=r.find(g=>g.name===a);if(p&&p.type.kind==="array"){o=p;break}}if(!o||t.match.totalField&&!t.match.totalField.some(p=>n.includes(p)))return null;let s=o.type.elementType,u=this.extract(s);return{kind:"generic",name:t.name,typeArgs:[u]}}extractRecursive(e){return{...e,properties:e.properties.map(t=>({...t,type:this.extractPropertyType(t.type)}))}}extractPropertyType(e){return e.kind==="object"?this.extract(e):e.kind==="array"?{...e,elementType:this.extractPropertyType(e.elementType)}:e.kind==="union"?{...e,types:e.types.map(t=>this.extractPropertyType(t))}:e}},S=class{constructor(e=5){this.threshold=e}extract(e,t){return this.extractRecursive(e,t,"")}extractRecursive(e,t,r){if(t.kind==="object"&&e&&typeof e=="object"){let n=e;return{...t,properties:t.properties.map(o=>{let s=r?`${r}.${o.name}`:o.name,u=n[o.name];return{...o,type:this.extractRecursive(u,o.type,s)}})}}if(t.kind==="array"&&Array.isArray(e)){let n=t.elementType;if(n.kind==="object"){let o=n.properties.map(s=>{let u=this.collectFieldValues(e,s.name),a=this.tryExtractEnum(u,s.type,s.name);return{...s,type:a}});return{...t,elementType:{...n,properties:o}}}if(n.kind==="primitive"&&n.type==="string"){let o=e.filter(u=>typeof u=="string"),s=[...new Set(o)];if(s.length>0&&s.length<=this.threshold)return{...t,elementType:{kind:"enum",name:"",values:s}}}return t}return t}collectFieldValues(e,t){let r=[];for(let n of e)if(n&&typeof n=="object"){let o=n[t];o!==void 0&&r.push(o)}return r}tryExtractEnum(e,t,r){if(t.kind!=="primitive"||t.type!=="string")return t;let n=e.filter(a=>typeof a=="string"),o=[...new Set(n)];return o.length===0||o.length>this.threshold||!o.every(a=>a.length<=50&&/^[a-zA-Z0-9_\-]+$/.test(a))?t:{kind:"enum",name:"",values:o}}},v=class{constructor(e=!1){this.strictNullChecks=e}process(e){return this.strictNullChecks?this.processRecursive(e):this.removeNullRecursive(e)}processRecursive(e){return e.kind==="object"?{...e,properties:e.properties.map(t=>({...t,type:this.processRecursive(t.type)}))}:e.kind==="array"?{...e,elementType:this.processRecursive(e.elementType)}:e.kind==="union"?{...e,types:e.types.map(t=>this.processRecursive(t))}:e}removeNullRecursive(e){if(e.kind==="object")return{...e,properties:e.properties.map(t=>({...t,type:this.removeNullRecursive(t.type)}))};if(e.kind==="array")return{...e,elementType:this.removeNullRecursive(e.elementType)};if(e.kind==="union"){let t=e.types.map(r=>this.removeNullRecursive(r)).filter(r=>r.kind!=="null");return t.length===0?m("unknown"):t.length===1?t[0]:h(t)}return e}},b=class{constructor(e=!0){this.markOptional=e}process(e,t){return this.markOptional?this.processRecursive(e,t):t}processRecursive(e,t){if(t.kind==="array"&&Array.isArray(e)&&e.length>1){let r=t.elementType;if(r.kind==="object"){let n=e.filter(o=>o!==null&&typeof o=="object"&&!Array.isArray(o));if(n.length>0){let o=this.markOptionalInArrayObjects(n,r);return{...t,elementType:o}}}return{...t,elementType:this.processRecursive(e[0],t.elementType)}}if(t.kind==="object"&&e&&typeof e=="object"){let r=e;return{...t,properties:t.properties.map(n=>{let o=r[n.name];return{...n,type:this.processRecursive(o,n.type)}})}}return t.kind==="union"?{...t,types:t.types.map(r=>this.processRecursive(e,r))}:t}markOptionalInArrayObjects(e,t){let r=e.length;return{...t,properties:t.properties.map(n=>{let o=0;for(let p of e)n.name in p&&o++;let s=o<r,u=e.map(p=>p[n.name]).filter(p=>p!==void 0),a=u.length>0?this.processRecursive(u[0],n.type):n.type;return{...n,optional:n.optional||s,type:a}})}}};function x(i,e,t){let r=l(e);return t.markOptional&&(r=new b(t.markOptional).process(i,r)),t.extractEnums&&(r=new S(t.enumThreshold).extract(i,r)),t.extractGenerics&&(r=new k().extract(r)),r=new v(t.strictNullChecks).process(r),r}function $(i,e={}){let t={...D,...e},r=f(i);r=x(i,r,t),t.addComments&&r.kind==="object"&&(r=K(r));let n=new d({namingStyle:t.namingStyle,prefix:t.typePrefix,suffix:t.typeSuffix,customNameMap:t.typeNameMap}),o=new y(n),s=t.rootName||"Root",u=o.collect(r,s);return{code:new T(t,n).generateOutput(u,s),types:u}}function M(i,e={}){let t=JSON.parse(i);return $(t,e)}function F(i,e={}){return $(i,e).code}var Q={generate:$,generateFromString:M,generateType:F};0&&(module.exports={CodeFormatter,EnumExtractor,GenericExtractor,NullHandler,OptionalHandler,TypeCollector,TypeNamer,applyEnhancements,createUnion,generate,generateFromString,generateType,inferArrayType,inferObjectType,inferType,isStructurallyEqual,mergeObjects,mergeTypes});
1
+ "use strict";var $=Object.defineProperty;var F=Object.getOwnPropertyDescriptor;var _=Object.getOwnPropertyNames;var z=Object.prototype.hasOwnProperty;var V=(n,e)=>{for(var t in e)$(n,t,{get:e[t],enumerable:!0})},L=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of _(e))!z.call(n,i)&&i!==t&&$(n,i,{get:()=>e[i],enumerable:!(r=F(e,i))||r.enumerable});return n};var q=n=>L($({},"__esModule",{value:!0}),n);var W={};V(W,{CodeFormatter:()=>d,EnumExtractor:()=>h,GenericExtractor:()=>g,NullHandler:()=>N,OptionalHandler:()=>S,TypeCollector:()=>f,TypeNamer:()=>y,applyEnhancements:()=>x,createUnion:()=>j,default:()=>B,generate:()=>v,generateFromString:()=>U,generateType:()=>D,inferArrayType:()=>A,inferObjectType:()=>P,inferType:()=>m,isStructurallyEqual:()=>b,mergeObjects:()=>O,mergeTypes:()=>T});module.exports=q(W);var E={rootName:"Root",outputStyle:"interface",namingStyle:"PascalCase",sortProperties:"alpha",addExport:!0,addComments:!1,strictNullChecks:!1,markOptional:!0,extractEnums:!0,enumThreshold:5,extractGenerics:!0,indentSize:2,lineEnding:`
2
+ `,typeNameMap:{},typePrefix:"",typeSuffix:""};function k(n){return{kind:"primitive",type:n}}function I(){return{kind:"null"}}function Z(){return{kind:"undefined"}}function H(n){return{kind:"array",elementType:n}}function C(n=[]){return{kind:"object",properties:n}}function j(n){let e=[],t=new Set;for(let r of n)if(r.kind==="union")for(let i of r.types){let s=u(i);t.has(s)||(t.add(s),e.push(i))}else{let i=u(r);t.has(i)||(t.add(i),e.push(r))}return e.length===1?e[0]:{kind:"union",types:e}}function u(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:${u(n.elementType)}`;case"object":return`object:${n.properties.map(e=>`${e.name}:${u(e.type)}:${e.optional}`).join(",")}`;case"union":return`union:${n.types.map(u).sort().join("|")}`;case"enum":return`enum:${n.name}:${n.values.join(",")}`;case"generic":return`generic:${n.name}:${n.typeArgs.map(u).join(",")}`;default:return"unknown"}}function T(n,e){return u(n)===u(e)?n:n.kind==="object"&&e.kind==="object"?O(n,e):n.kind==="array"&&e.kind==="array"?H(T(n.elementType,e.elementType)):j([n,e])}function O(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(o=>o.name===r)||(i.optional=!0);return C(Array.from(t.values()))}function m(n){return n===null?I():n===void 0?Z():typeof n=="string"?k("string"):typeof n=="number"?k("number"):typeof n=="boolean"?k("boolean"):Array.isArray(n)?A(n):typeof n=="object"?P(n):k("unknown")}function A(n){if(n.length===0)return{kind:"array",elementType:{kind:"primitive",type:"any"}};let e=n.map(r=>m(r)),t=e[0];for(let r=1;r<e.length;r++)t=T(t,e[r]);return{kind:"array",elementType:t}}function P(n){let e=[];for(let[t,r]of Object.entries(n)){let i=m(r);e.push({name:t,type:i,optional:!1})}return C(e)}function b(n,e){return u(n)===u(e)}function l(n){switch(n.kind){case"primitive":case"null":case"undefined":return{...n};case"literal":return{...n};case"array":return{...n,elementType:l(n.elementType)};case"object":return{...n,properties:n.properties.map(e=>({...e,type:l(e.type)}))};case"union":return{...n,types:n.types.map(e=>l(e))};case"enum":return{...n,values:[...n.values]};case"generic":return{...n,typeArgs:n.typeArgs.map(e=>l(e))};default:return{...n}}}var y=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"&&e.kind!=="enum")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 s=this.generateName(e,t);return s=this.ensureUniqueName(s),s=this.applyAffixes(s),this.namedTypes.set(i,s),s}generateName(e,t){if(e.kind==="enum")return t.fieldName?this.toPascalCase(t.fieldName)+"Enum":"AnonymousEnum";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==="enum"?`enum:${e.values.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"enum":return`enum:${e.name}`;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(o=>o.name===t),s=this.collected.filter(o=>o.name!==t);return i?[i,...s]: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:l(e)});for(let s of e.properties)this.collectRecursive(s.type,{fieldName:s.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==="enum"){let i=this.namer.nameType(e,t);i&&!this.seenStructs.has(r)&&(this.seenStructs.add(r),this.collected.push({name:i,type:l(e)}));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==="enum"?`enum:${[...e.values].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"enum":return`enum:${e.name}`;case"generic":return`generic:${e.name}`;default:return"unknown"}}};var d=class{constructor(e,t){this.allNamedTypes=[];this.options=e,this.namer=t}findTypeName(e){for(let t of this.allNamedTypes)if(b(t.type,e))return t.name;return null}formatTypeDef(e){let{name:t,type:r,comment:i}=e,s=this.options.addExport?"export ":"";return r.kind==="enum"?this.formatEnumType(t,r,s,i):this.formatObjectType(t,r,s,i)}formatObjectType(e,t,r,i){let s=" ".repeat(this.options.indentSize),o=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 p of o){let c=this.formatPropertyName(p.name),K=p.optional?"?":"",M=this.formatType(p.type),w=`${s}${c}${K}: ${M};`;p.comment&&(w+=` // ${p.comment}`),a.push(w)}return this.options.outputStyle==="interface"?a.push("}"):a.push("};"),a.join(`
3
+ `)}formatEnumType(e,t,r,i){let s=" ".repeat(this.options.indentSize),o=[];i&&o.push(this.formatJSDoc(i)),o.push(`${r}enum ${e} {`);for(let a of t.values){let p=this.toEnumKey(String(a)),c=typeof a=="string"?`'${a}'`:String(a);o.push(`${s}${p} = ${c},`)}return o.push("}"),o.join(`
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(`
5
+ `)}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
+ `);return t.length===1?`/** ${e} */`:["/**",...t.map(r=>` * ${r}`)," */"].join(`
7
+ `)}toEnumKey(e){return e.replace(/[-_\s]+/g,"_").replace(/([a-z])([A-Z])/g,"$1_$2").toUpperCase().replace(/^_+|_+$/g,"")}formatAll(e){return this.allNamedTypes=e,e.map(t=>this.formatTypeDef(t)).join(`
8
+
9
+ `)}generateOutput(e,t){let r=`/**
10
+ * Generated by ts-gen
11
+ * Root type: ${t}
12
+ */`,i=this.formatAll(e);return`${r}
13
+
14
+ ${i}
15
+ `}};function J(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 R(n){return{...n,properties:n.properties.map(e=>({...e,comment:e.comment||J(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 s of e.properties)t.arrayFields.includes(s.name)&&s.type.kind==="array"&&(r={name:s.name,elementType:s.type.elementType}),t.countFields.includes(s.name)&&(i=!0);return r&&i?{kind:"generic",name:t.name,typeArgs:[r.elementType]}:null}},h=class{constructor(e=5){this.threshold=e}extract(e,t){if(t.kind==="object"&&e&&typeof e=="object"){let r=t.properties.map(i=>{let s=e[i.name];if(i.type.kind==="primitive"&&i.type.type==="string"){let o=this.tryExtractEnum([s],i.type,i.name);if(o)return{...i,type:o}}if(i.type.kind==="array"&&Array.isArray(s)){let o=i.type.elementType;if(o.kind==="primitive"&&o.type==="string"){let p=[...new Set(s.filter(c=>typeof c=="string"))];if(p.length>0&&p.length<=this.threshold&&this.isValidEnumValues(p)){let c={kind:"enum",name:`${G(i.name)}ItemEnum`,values:p};return{...i,type:{kind:"array",elementType:c}}}}let a=this.extract(s.length>0?s[0]:void 0,o);return{...i,type:{kind:"array",elementType:a}}}return{...i,type:this.extract(s,i.type)}});return{...t,properties:r}}if(t.kind==="array"&&Array.isArray(e)){let r=t.elementType,i=this.extract(e.length>0?e[0]:void 0,r);return{...t,elementType:i}}return t}tryExtractEnum(e,t,r){let i=e.filter(o=>typeof o=="string"),s=[...new Set(i)];return s.length===0||s.length>this.threshold||!this.isValidEnumValues(s)?null:{kind:"enum",name:`${G(r)}Enum`,values:s}}isValidEnumValues(e){return e.every(t=>/^[a-zA-Z0-9_-]+$/.test(t))}},N=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}},S=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 s of e)if(s&&typeof s=="object")for(let o of Object.keys(s))r[o]=(r[o]||0)+1;return{...t,properties:t.properties.map(s=>{let a=(r[s.name]||0)<i;return{...s,optional:a}})}}};function x(n,e,t){let r=e;return t.markOptional&&(r=new S(t.markOptional).process(n,r)),t.extractEnums&&(r=new h(t.enumThreshold||5).extract(n,r)),t.extractGenerics&&(r=new g().extract(r)),r=new N(t.strictNullChecks).process(r),r}function G(n){return n.charAt(0).toUpperCase()+n.slice(1)}function v(n,e={}){let t={...E,...e},r=m(n);r=x(n,r,t),t.addComments&&r.kind==="object"&&(r=R(r));let i=new y({namingStyle:t.namingStyle,prefix:t.typePrefix,suffix:t.typeSuffix,customNameMap:t.typeNameMap}),s=new f(i),o=t.rootName||"Root",a=s.collect(r,o);return{code:new d(t,i).generateOutput(a,o),types:a}}function U(n,e={}){let t=JSON.parse(n);return v(t,e)}function D(n,e={}){return v(n,e).code}var B={generate:v,generateFromString:U,generateType:D};0&&(module.exports={CodeFormatter,EnumExtractor,GenericExtractor,NullHandler,OptionalHandler,TypeCollector,TypeNamer,applyEnhancements,createUnion,generate,generateFromString,generateType,inferArrayType,inferObjectType,inferType,isStructurallyEqual,mergeObjects,mergeTypes});
package/dist/index.mjs CHANGED
@@ -1,6 +1,15 @@
1
- var R={rootName:"Root",outputStyle:"interface",namingStyle:"PascalCase",sortProperties:"alpha",addExport:!0,addComments:!1,strictNullChecks:!1,markOptional:!0,extractEnums:!0,enumThreshold:5,extractGenerics:!0,indentSize:2,lineEnding:`
2
- `,typeNameMap:{},typePrefix:"",typeSuffix:""};function m(i){return{kind:"primitive",type:i}}function I(){return{kind:"null"}}function K(){return{kind:"undefined"}}function j(i){return{kind:"array",elementType:i}}function A(i=[]){return{kind:"object",properties:i}}function h(i){let e=[],t=new Set;for(let r of i)if(r.kind==="union")for(let n of r.types){let o=c(n);t.has(o)||(t.add(o),e.push(n))}else{let n=c(r);t.has(n)||(t.add(n),e.push(r))}return e.length===1?e[0]:{kind:"union",types:e}}function c(i){switch(i.kind){case"primitive":return`primitive:${i.type}`;case"null":return"null";case"undefined":return"undefined";case"literal":return`literal:${typeof i.value}:${String(i.value)}`;case"array":return`array:${c(i.elementType)}`;case"object":return`object:${i.properties.map(e=>`${e.name}:${c(e.type)}:${e.optional}`).join(",")}`;case"union":return`union:${i.types.map(c).sort().join("|")}`;case"enum":return`enum:${i.name}:${i.values.join(",")}`;case"generic":return`generic:${i.name}:${i.typeArgs.map(c).join(",")}`;default:return"unknown"}}function N(i,e){return c(i)===c(e)?i:i.kind==="object"&&e.kind==="object"?E(i,e):i.kind==="array"&&e.kind==="array"?j(N(i.elementType,e.elementType)):h([i,e])}function E(i,e){let t=new Map;for(let r of i.properties)t.set(r.name,{...r});for(let r of e.properties){let n=t.get(r.name);n?(n.type=N(n.type,r.type),n.optional=n.optional||r.optional,r.comment&&!n.comment&&(n.comment=r.comment)):t.set(r.name,{...r,optional:!0})}for(let[r,n]of t)e.properties.some(s=>s.name===r)||(n.optional=!0);return A(Array.from(t.values()))}function f(i){return i===null?I():i===void 0?K():typeof i=="string"?m("string"):typeof i=="number"?m("number"):typeof i=="boolean"?m("boolean"):Array.isArray(i)?C(i):typeof i=="object"?D(i):m("unknown")}function C(i){if(i.length===0)return j(m("never"));let e=f(i[0]);for(let t=1;t<i.length;t++){let r=f(i[t]);e=N(e,r)}return j(e)}function D(i){let e=[];for(let[t,r]of Object.entries(i)){let n=f(r);e.push({name:t,type:n,optional:!1})}return A(e)}function M(i,e){return c(i)===c(e)}function l(i){switch(i.kind){case"primitive":case"null":case"undefined":return{...i};case"literal":return{...i};case"array":return{...i,elementType:l(i.elementType)};case"object":return{...i,properties:i.properties.map(e=>({...e,type:l(e.type)}))};case"union":return{...i,types:i.types.map(e=>l(e))};case"enum":return{...i,values:[...i.values]};case"generic":return{...i,typeArgs:i.typeArgs.map(e=>l(e))};default:return{...i}}}var y=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"&&e.kind!=="enum")return null;let r=this.buildPathKey(t);if(this.customNameMap[r])return this.applyAffixes(this.customNameMap[r]);let n=this.getTypeKey(e);if(this.namedTypes.has(n))return this.namedTypes.get(n);let o=this.generateName(e,t);return o=this.ensureUniqueName(o),o=this.applyAffixes(o),this.namedTypes.set(n,o),o}generateName(e,t){if(e.kind==="enum")return t.fieldName?this.toPascalCase(t.fieldName)+"Enum":"AnonymousEnum";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==="enum"?`enum:${e.values.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"enum":return`enum:${e.name}`;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()}},T=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 n=this.collected.find(s=>s.name===t),o=this.collected.filter(s=>s.name!==t);return n?[n,...o]:this.collected}collectRecursive(e,t){let r=this.getStructKey(e);if(e.kind==="object"){let n=this.namer.nameType(e,t);if(n&&!this.seenStructs.has(r)){this.seenStructs.add(r),this.collected.push({name:n,type:l(e)});for(let o of e.properties)this.collectRecursive(o.type,{fieldName:o.name,parentName:n,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 n of e.types)this.collectRecursive(n,t);return}if(e.kind==="enum"){let n=this.namer.nameType(e,t);n&&!this.seenStructs.has(r)&&(this.seenStructs.add(r),this.collected.push({name:n,type:l(e)}));return}if(e.kind==="generic"){for(let n of e.typeArgs)this.collectRecursive(n,{...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==="enum"?`enum:${[...e.values].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"enum":return`enum:${e.name}`;case"generic":return`generic:${e.name}`;default:return"unknown"}}};function G(i){let e=i.replace(/[^a-zA-Z0-9_$]/g,"_");return/^\d/.test(e)&&(e="_"+e),e}function O(i){return/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(i)}var g=class{constructor(e,t){this.options=e,this.namer=t}formatTypeDef(e){let{name:t,type:r,comment:n}=e,o="";this.options.addComments&&n&&(o+=this.formatJSDoc(n)+this.options.lineEnding);let s=this.options.addExport?"export ":"";return r.kind==="object"?o+=this.formatObjectType(t,r,s):r.kind==="enum"?o+=this.formatEnumType(t,r,s):o+=`${s}type ${t} = ${this.formatType(r)};`,o}formatObjectType(e,t,r){let n=this.options.outputStyle,o=" ".repeat(this.options.indentSize),s=this.options.lineEnding,u=this.sortProperties(t.properties);if(n==="interface"){let a=`${r}interface ${e} {${s}`;for(let p of u){this.options.addComments&&p.comment&&(a+=o+this.formatInlineJSDoc(p.comment)+s);let d=this.formatPropertyName(p.name),x=p.optional&&this.options.markOptional?"?":"",$=this.formatType(p.type);a+=`${o}${d}${x}: ${$};${s}`}return a+=`}${s}`,a}else{let a=`${r}type ${e} = {${s}`;for(let p of u){this.options.addComments&&p.comment&&(a+=o+this.formatInlineJSDoc(p.comment)+s);let d=this.formatPropertyName(p.name),x=p.optional&&this.options.markOptional?"?":"",$=this.formatType(p.type);a+=`${o}${d}${x}: ${$};${s}`}return a+=`};${s}`,a}}formatEnumType(e,t,r){let n=" ".repeat(this.options.indentSize),o=this.options.lineEnding,s=t.values.every(a=>typeof a=="string"),u=`${r}enum ${e} {${o}`;for(let a of t.values)if(s){let p=this.toEnumKey(String(a));u+=`${n}${p} = '${a}',${o}`}else{let p=`Value${a}`;u+=`${n}${p} = ${a},${o}`}return u+=`}${o}`,u}formatType(e){switch(e.kind){case"primitive":return e.type;case"null":return"null";case"undefined":return"undefined";case"literal":return this.formatLiteral(e.value);case"array":return this.formatArrayType(e.elementType);case"object":return this.formatInlineObject(e);case"union":return this.formatUnionType(e.types);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.replace(/'/g,"\\'")}'`:String(e)}formatArrayType(e){let t=this.formatType(e);return e.kind==="union"?`(${t})[]`:`${t}[]`}formatInlineObject(e){let t=" ".repeat(this.options.indentSize),r=this.options.lineEnding,n=this.sortProperties(e.properties);if(n.length===0)return"{}";let o=`{${r}`;for(let s of n){let u=this.formatPropertyName(s.name),a=s.optional&&this.options.markOptional?"?":"",p=this.formatType(s.type);o+=`${t}${u}${a}: ${p};${r}`}return o+="}",o}formatUnionType(e){return e.map(t=>this.formatType(t)).join(" | ")}formatPropertyName(e){return O(e)?e:`'${e.replace(/'/g,"\\'")}'`}sortProperties(e){return this.options.sortProperties==="alpha"?[...e].sort((r,n)=>r.name.localeCompare(n.name)):[...e]}formatJSDoc(e){let t=e.split(`
3
- `);return t.length===1?`/** ${e} */`:`/**
4
- * ${t.join(`
5
- * `)}
6
- */`}formatInlineJSDoc(e){return`/** ${e} */`}toEnumKey(e){let r=e.replace(/[-_\s]+/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").trim().split(" ").filter(Boolean).map(n=>n.toUpperCase()).join("_");return/^\d/.test(r)&&(r="VALUE_"+r),O(r)||(r=G(r)),r}formatAll(e){let t=this.options.lineEnding,r=[];for(let n of e)r.push(this.formatTypeDef(n));return r.join(t)}generateOutput(e,t){let r=this.options.lineEnding,n="";return n+=`/**${r}`,n+=` * Generated by ts-gen${r}`,n+=` * Root type: ${t}${r}`,n+=` */${r}`,n+=r,n+=this.formatAll(e),n}};function F(i){let e=i.toLowerCase();return{id:"\u552F\u4E00\u6807\u8BC6\u7B26",name:"\u540D\u79F0",title:"\u6807\u9898",desc:"\u63CF\u8FF0",description:"\u63CF\u8FF0",type:"\u7C7B\u578B",status:"\u72B6\u6001",code:"\u7F16\u7801/\u72B6\u6001\u7801",msg:"\u6D88\u606F",message:"\u6D88\u606F",data:"\u6570\u636E",list:"\u5217\u8868\u6570\u636E",total:"\u603B\u6570",page:"\u9875\u7801",pageSize:"\u6BCF\u9875\u6570\u91CF",pageNum:"\u9875\u7801",pageIndex:"\u9875\u7801",size:"\u6570\u91CF/\u5927\u5C0F",count:"\u6570\u91CF",createTime:"\u521B\u5EFA\u65F6\u95F4",updateTime:"\u66F4\u65B0\u65F6\u95F4",createdAt:"\u521B\u5EFA\u65F6\u95F4",updatedAt:"\u66F4\u65B0\u65F6\u95F4",deleted:"\u662F\u5426\u5DF2\u5220\u9664",enabled:"\u662F\u5426\u542F\u7528",active:"\u662F\u5426\u6FC0\u6D3B",url:"\u94FE\u63A5\u5730\u5740",avatar:"\u5934\u50CF",email:"\u90AE\u7BB1",phone:"\u624B\u673A\u53F7",mobile:"\u624B\u673A\u53F7",username:"\u7528\u6237\u540D",password:"\u5BC6\u7801",token:"\u4EE4\u724C",userId:"\u7528\u6237ID",userName:"\u7528\u6237\u540D"}[e]}function U(i){return{...i,properties:i.properties.map(e=>({...e,comment:e.comment||F(e.name)}))}}var L=[{name:"PageResult",match:{listField:["list","records","rows","items","dataList"],totalField:["total","totalCount","count"]},typeParamIndex:0},{name:"ListResult",match:{listField:["list","records","rows","items"]},typeParamIndex:0},{name:"ApiResponse",match:{listField:["data"],totalField:["code","status"]},typeParamIndex:0}],k=class{constructor(e){this.patterns=e||L}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 this.extractRecursive(e)}tryMatchPattern(e,t){let r=e.properties,n=r.map(a=>a.name),o;if(t.match.listField)for(let a of t.match.listField){let p=r.find(d=>d.name===a);if(p&&p.type.kind==="array"){o=p;break}}if(!o||t.match.totalField&&!t.match.totalField.some(p=>n.includes(p)))return null;let s=o.type.elementType,u=this.extract(s);return{kind:"generic",name:t.name,typeArgs:[u]}}extractRecursive(e){return{...e,properties:e.properties.map(t=>({...t,type:this.extractPropertyType(t.type)}))}}extractPropertyType(e){return e.kind==="object"?this.extract(e):e.kind==="array"?{...e,elementType:this.extractPropertyType(e.elementType)}:e.kind==="union"?{...e,types:e.types.map(t=>this.extractPropertyType(t))}:e}},S=class{constructor(e=5){this.threshold=e}extract(e,t){return this.extractRecursive(e,t,"")}extractRecursive(e,t,r){if(t.kind==="object"&&e&&typeof e=="object"){let n=e;return{...t,properties:t.properties.map(o=>{let s=r?`${r}.${o.name}`:o.name,u=n[o.name];return{...o,type:this.extractRecursive(u,o.type,s)}})}}if(t.kind==="array"&&Array.isArray(e)){let n=t.elementType;if(n.kind==="object"){let o=n.properties.map(s=>{let u=this.collectFieldValues(e,s.name),a=this.tryExtractEnum(u,s.type,s.name);return{...s,type:a}});return{...t,elementType:{...n,properties:o}}}if(n.kind==="primitive"&&n.type==="string"){let o=e.filter(u=>typeof u=="string"),s=[...new Set(o)];if(s.length>0&&s.length<=this.threshold)return{...t,elementType:{kind:"enum",name:"",values:s}}}return t}return t}collectFieldValues(e,t){let r=[];for(let n of e)if(n&&typeof n=="object"){let o=n[t];o!==void 0&&r.push(o)}return r}tryExtractEnum(e,t,r){if(t.kind!=="primitive"||t.type!=="string")return t;let n=e.filter(a=>typeof a=="string"),o=[...new Set(n)];return o.length===0||o.length>this.threshold||!o.every(a=>a.length<=50&&/^[a-zA-Z0-9_\-]+$/.test(a))?t:{kind:"enum",name:"",values:o}}},v=class{constructor(e=!1){this.strictNullChecks=e}process(e){return this.strictNullChecks?this.processRecursive(e):this.removeNullRecursive(e)}processRecursive(e){return e.kind==="object"?{...e,properties:e.properties.map(t=>({...t,type:this.processRecursive(t.type)}))}:e.kind==="array"?{...e,elementType:this.processRecursive(e.elementType)}:e.kind==="union"?{...e,types:e.types.map(t=>this.processRecursive(t))}:e}removeNullRecursive(e){if(e.kind==="object")return{...e,properties:e.properties.map(t=>({...t,type:this.removeNullRecursive(t.type)}))};if(e.kind==="array")return{...e,elementType:this.removeNullRecursive(e.elementType)};if(e.kind==="union"){let t=e.types.map(r=>this.removeNullRecursive(r)).filter(r=>r.kind!=="null");return t.length===0?m("unknown"):t.length===1?t[0]:h(t)}return e}},b=class{constructor(e=!0){this.markOptional=e}process(e,t){return this.markOptional?this.processRecursive(e,t):t}processRecursive(e,t){if(t.kind==="array"&&Array.isArray(e)&&e.length>1){let r=t.elementType;if(r.kind==="object"){let n=e.filter(o=>o!==null&&typeof o=="object"&&!Array.isArray(o));if(n.length>0){let o=this.markOptionalInArrayObjects(n,r);return{...t,elementType:o}}}return{...t,elementType:this.processRecursive(e[0],t.elementType)}}if(t.kind==="object"&&e&&typeof e=="object"){let r=e;return{...t,properties:t.properties.map(n=>{let o=r[n.name];return{...n,type:this.processRecursive(o,n.type)}})}}return t.kind==="union"?{...t,types:t.types.map(r=>this.processRecursive(e,r))}:t}markOptionalInArrayObjects(e,t){let r=e.length;return{...t,properties:t.properties.map(n=>{let o=0;for(let p of e)n.name in p&&o++;let s=o<r,u=e.map(p=>p[n.name]).filter(p=>p!==void 0),a=u.length>0?this.processRecursive(u[0],n.type):n.type;return{...n,optional:n.optional||s,type:a}})}}};function P(i,e,t){let r=l(e);return t.markOptional&&(r=new b(t.markOptional).process(i,r)),t.extractEnums&&(r=new S(t.enumThreshold).extract(i,r)),t.extractGenerics&&(r=new k().extract(r)),r=new v(t.strictNullChecks).process(r),r}function w(i,e={}){let t={...R,...e},r=f(i);r=P(i,r,t),t.addComments&&r.kind==="object"&&(r=U(r));let n=new y({namingStyle:t.namingStyle,prefix:t.typePrefix,suffix:t.typeSuffix,customNameMap:t.typeNameMap}),o=new T(n),s=t.rootName||"Root",u=o.collect(r,s);return{code:new g(t,n).generateOutput(u,s),types:u}}function V(i,e={}){let t=JSON.parse(i);return w(t,e)}function z(i,e={}){return w(i,e).code}var le={generate:w,generateFromString:V,generateType:z};export{g as CodeFormatter,S as EnumExtractor,k as GenericExtractor,v as NullHandler,b as OptionalHandler,T as TypeCollector,y as TypeNamer,P as applyEnhancements,h as createUnion,le as default,w as generate,V as generateFromString,z as generateType,C as inferArrayType,D as inferObjectType,f as inferType,M as isStructurallyEqual,E as mergeObjects,N as mergeTypes};
1
+ var j={rootName:"Root",outputStyle:"interface",namingStyle:"PascalCase",sortProperties:"alpha",addExport:!0,addComments:!1,strictNullChecks:!1,markOptional:!0,extractEnums:!0,enumThreshold:5,extractGenerics:!0,indentSize:2,lineEnding:`
2
+ `,typeNameMap:{},typePrefix:"",typeSuffix:""};function T(n){return{kind:"primitive",type:n}}function D(){return{kind:"null"}}function K(){return{kind:"undefined"}}function M(n){return{kind:"array",elementType:n}}function O(n=[]){return{kind:"object",properties:n}}function A(n){let e=[],t=new Set;for(let r of n)if(r.kind==="union")for(let i of r.types){let s=u(i);t.has(s)||(t.add(s),e.push(i))}else{let i=u(r);t.has(i)||(t.add(i),e.push(r))}return e.length===1?e[0]:{kind:"union",types:e}}function u(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:${u(n.elementType)}`;case"object":return`object:${n.properties.map(e=>`${e.name}:${u(e.type)}:${e.optional}`).join(",")}`;case"union":return`union:${n.types.map(u).sort().join("|")}`;case"enum":return`enum:${n.name}:${n.values.join(",")}`;case"generic":return`generic:${n.name}:${n.typeArgs.map(u).join(",")}`;default:return"unknown"}}function g(n,e){return u(n)===u(e)?n:n.kind==="object"&&e.kind==="object"?P(n,e):n.kind==="array"&&e.kind==="array"?M(g(n.elementType,e.elementType)):A([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=g(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(o=>o.name===r)||(i.optional=!0);return O(Array.from(t.values()))}function m(n){return n===null?D():n===void 0?K():typeof n=="string"?T("string"):typeof n=="number"?T("number"):typeof n=="boolean"?T("boolean"):Array.isArray(n)?w(n):typeof n=="object"?E(n):T("unknown")}function w(n){if(n.length===0)return{kind:"array",elementType:{kind:"primitive",type:"any"}};let e=n.map(r=>m(r)),t=e[0];for(let r=1;r<e.length;r++)t=g(t,e[r]);return{kind:"array",elementType:t}}function E(n){let e=[];for(let[t,r]of Object.entries(n)){let i=m(r);e.push({name:t,type:i,optional:!1})}return O(e)}function b(n,e){return u(n)===u(e)}function l(n){switch(n.kind){case"primitive":case"null":case"undefined":return{...n};case"literal":return{...n};case"array":return{...n,elementType:l(n.elementType)};case"object":return{...n,properties:n.properties.map(e=>({...e,type:l(e.type)}))};case"union":return{...n,types:n.types.map(e=>l(e))};case"enum":return{...n,values:[...n.values]};case"generic":return{...n,typeArgs:n.typeArgs.map(e=>l(e))};default:return{...n}}}var y=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"&&e.kind!=="enum")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 s=this.generateName(e,t);return s=this.ensureUniqueName(s),s=this.applyAffixes(s),this.namedTypes.set(i,s),s}generateName(e,t){if(e.kind==="enum")return t.fieldName?this.toPascalCase(t.fieldName)+"Enum":"AnonymousEnum";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==="enum"?`enum:${e.values.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"enum":return`enum:${e.name}`;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(o=>o.name===t),s=this.collected.filter(o=>o.name!==t);return i?[i,...s]: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:l(e)});for(let s of e.properties)this.collectRecursive(s.type,{fieldName:s.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==="enum"){let i=this.namer.nameType(e,t);i&&!this.seenStructs.has(r)&&(this.seenStructs.add(r),this.collected.push({name:i,type:l(e)}));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==="enum"?`enum:${[...e.values].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"enum":return`enum:${e.name}`;case"generic":return`generic:${e.name}`;default:return"unknown"}}};var d=class{constructor(e,t){this.allNamedTypes=[];this.options=e,this.namer=t}findTypeName(e){for(let t of this.allNamedTypes)if(b(t.type,e))return t.name;return null}formatTypeDef(e){let{name:t,type:r,comment:i}=e,s=this.options.addExport?"export ":"";return r.kind==="enum"?this.formatEnumType(t,r,s,i):this.formatObjectType(t,r,s,i)}formatObjectType(e,t,r,i){let s=" ".repeat(this.options.indentSize),o=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 p of o){let c=this.formatPropertyName(p.name),G=p.optional?"?":"",U=this.formatType(p.type),$=`${s}${c}${G}: ${U};`;p.comment&&($+=` // ${p.comment}`),a.push($)}return this.options.outputStyle==="interface"?a.push("}"):a.push("};"),a.join(`
3
+ `)}formatEnumType(e,t,r,i){let s=" ".repeat(this.options.indentSize),o=[];i&&o.push(this.formatJSDoc(i)),o.push(`${r}enum ${e} {`);for(let a of t.values){let p=this.toEnumKey(String(a)),c=typeof a=="string"?`'${a}'`:String(a);o.push(`${s}${p} = ${c},`)}return o.push("}"),o.join(`
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(`
5
+ `)}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
+ `);return t.length===1?`/** ${e} */`:["/**",...t.map(r=>` * ${r}`)," */"].join(`
7
+ `)}toEnumKey(e){return e.replace(/[-_\s]+/g,"_").replace(/([a-z])([A-Z])/g,"$1_$2").toUpperCase().replace(/^_+|_+$/g,"")}formatAll(e){return this.allNamedTypes=e,e.map(t=>this.formatTypeDef(t)).join(`
8
+
9
+ `)}generateOutput(e,t){let r=`/**
10
+ * Generated by ts-gen
11
+ * Root type: ${t}
12
+ */`,i=this.formatAll(e);return`${r}
13
+
14
+ ${i}
15
+ `}};function F(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 C(n){return{...n,properties:n.properties.map(e=>({...e,comment:e.comment||F(e.name)}))}}var h=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 s of e.properties)t.arrayFields.includes(s.name)&&s.type.kind==="array"&&(r={name:s.name,elementType:s.type.elementType}),t.countFields.includes(s.name)&&(i=!0);return r&&i?{kind:"generic",name:t.name,typeArgs:[r.elementType]}:null}},N=class{constructor(e=5){this.threshold=e}extract(e,t){if(t.kind==="object"&&e&&typeof e=="object"){let r=t.properties.map(i=>{let s=e[i.name];if(i.type.kind==="primitive"&&i.type.type==="string"){let o=this.tryExtractEnum([s],i.type,i.name);if(o)return{...i,type:o}}if(i.type.kind==="array"&&Array.isArray(s)){let o=i.type.elementType;if(o.kind==="primitive"&&o.type==="string"){let p=[...new Set(s.filter(c=>typeof c=="string"))];if(p.length>0&&p.length<=this.threshold&&this.isValidEnumValues(p)){let c={kind:"enum",name:`${R(i.name)}ItemEnum`,values:p};return{...i,type:{kind:"array",elementType:c}}}}let a=this.extract(s.length>0?s[0]:void 0,o);return{...i,type:{kind:"array",elementType:a}}}return{...i,type:this.extract(s,i.type)}});return{...t,properties:r}}if(t.kind==="array"&&Array.isArray(e)){let r=t.elementType,i=this.extract(e.length>0?e[0]:void 0,r);return{...t,elementType:i}}return t}tryExtractEnum(e,t,r){let i=e.filter(o=>typeof o=="string"),s=[...new Set(i)];return s.length===0||s.length>this.threshold||!this.isValidEnumValues(s)?null:{kind:"enum",name:`${R(r)}Enum`,values:s}}isValidEnumValues(e){return e.every(t=>/^[a-zA-Z0-9_-]+$/.test(t))}},S=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}},k=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 s of e)if(s&&typeof s=="object")for(let o of Object.keys(s))r[o]=(r[o]||0)+1;return{...t,properties:t.properties.map(s=>{let a=(r[s.name]||0)<i;return{...s,optional:a}})}}};function x(n,e,t){let r=e;return t.markOptional&&(r=new k(t.markOptional).process(n,r)),t.extractEnums&&(r=new N(t.enumThreshold||5).extract(n,r)),t.extractGenerics&&(r=new h().extract(r)),r=new S(t.strictNullChecks).process(r),r}function R(n){return n.charAt(0).toUpperCase()+n.slice(1)}function v(n,e={}){let t={...j,...e},r=m(n);r=x(n,r,t),t.addComments&&r.kind==="object"&&(r=C(r));let i=new y({namingStyle:t.namingStyle,prefix:t.typePrefix,suffix:t.typeSuffix,customNameMap:t.typeNameMap}),s=new f(i),o=t.rootName||"Root",a=s.collect(r,o);return{code:new d(t,i).generateOutput(a,o),types:a}}function _(n,e={}){let t=JSON.parse(n);return v(t,e)}function z(n,e={}){return v(n,e).code}var re={generate:v,generateFromString:_,generateType:z};export{d as CodeFormatter,N as EnumExtractor,h as GenericExtractor,S as NullHandler,k as OptionalHandler,f as TypeCollector,y as TypeNamer,x as applyEnhancements,A as createUnion,re as default,v as generate,_ as generateFromString,z as generateType,w as inferArrayType,E as inferObjectType,m as inferType,b as isStructurallyEqual,P as mergeObjects,g as mergeTypes};
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "type-flash",
3
- "version": "1.0.2",
3
+ "version": "1.0.5",
4
4
  "description": "JSON 智能生成 TypeScript 类型定义 - 一键从 JSON 数据生成 Interface / Type 定义",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
7
- "types": "dist/types/index.d.ts",
7
+ "types": "dist/index.d.ts",
8
8
  "bin": {
9
9
  "type-flash": "bin/type-flash.js"
10
10
  },