type-flash 1.0.6 → 1.0.8
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 +9 -17
- package/dist/index.d.ts +9 -17
- package/dist/index.js +4 -4
- package/dist/index.mjs +4 -4
- 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
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
interface PrimitiveType {
|
|
8
8
|
kind: 'primitive';
|
|
9
|
-
type: 'string' | 'number' | 'boolean' | 'any' | 'unknown' | 'never';
|
|
9
|
+
type: 'string' | 'number' | 'boolean' | 'any' | 'unknown' | 'never' | 'function';
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
12
|
* 数组类型
|
|
@@ -139,7 +139,7 @@ interface GenerateResult {
|
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
/**
|
|
142
|
-
*
|
|
142
|
+
* type-flash - 命名与去重模块
|
|
143
143
|
*
|
|
144
144
|
* 核心功能:
|
|
145
145
|
* - 根据字段名 + 上下文自动生成有意义的类型名
|
|
@@ -280,7 +280,7 @@ declare class TypeCollector {
|
|
|
280
280
|
}
|
|
281
281
|
|
|
282
282
|
/**
|
|
283
|
-
*
|
|
283
|
+
* type-flash - 格式化输出模块
|
|
284
284
|
*
|
|
285
285
|
* 核心功能:
|
|
286
286
|
* - 将类型节点格式化为 TypeScript 代码字符串
|
|
@@ -360,7 +360,7 @@ declare function guessCommentFromFieldName(fieldName: string): string | undefine
|
|
|
360
360
|
declare function addGuessedComments(type: ObjectType): ObjectType;
|
|
361
361
|
|
|
362
362
|
/**
|
|
363
|
-
*
|
|
363
|
+
* type-flash - 类型推断引擎
|
|
364
364
|
*
|
|
365
365
|
* 核心功能:
|
|
366
366
|
* - 基础类型识别(string、number、boolean、null、undefined)
|
|
@@ -408,7 +408,7 @@ declare function inferObjectType(obj: Record<string, unknown>): ObjectType;
|
|
|
408
408
|
declare function isStructurallyEqual(a: TSTypeNode, b: TSTypeNode): boolean;
|
|
409
409
|
|
|
410
410
|
/**
|
|
411
|
-
*
|
|
411
|
+
* type-flash - 增强功能模块
|
|
412
412
|
*
|
|
413
413
|
* 核心功能:
|
|
414
414
|
* - 泛型提取(如 PageResult<T>)
|
|
@@ -448,7 +448,7 @@ declare class OptionalHandler {
|
|
|
448
448
|
declare function applyEnhancements(jsonData: any, type: TSTypeNode, options: GenerateOptions): TSTypeNode;
|
|
449
449
|
|
|
450
450
|
/**
|
|
451
|
-
*
|
|
451
|
+
* type-flash - JSON 智能生成 TypeScript 类型定义
|
|
452
452
|
*
|
|
453
453
|
* 主入口文件
|
|
454
454
|
*/
|
|
@@ -459,26 +459,18 @@ declare function applyEnhancements(jsonData: any, type: TSTypeNode, options: Gen
|
|
|
459
459
|
* @param options 配置选项
|
|
460
460
|
* @returns 生成结果
|
|
461
461
|
*/
|
|
462
|
-
declare function generate(jsonData: any, options?: GenerateOptions):
|
|
462
|
+
declare function generate(jsonData: any, options?: GenerateOptions): string;
|
|
463
463
|
/**
|
|
464
464
|
* 从 JSON 字符串生成类型定义
|
|
465
465
|
* @param jsonString JSON 字符串
|
|
466
466
|
* @param options 配置选项
|
|
467
467
|
* @returns 生成结果
|
|
468
468
|
*/
|
|
469
|
-
declare function generateFromString(jsonString: string, options?: GenerateOptions):
|
|
470
|
-
/**
|
|
471
|
-
* 生成单个类型的字符串表示
|
|
472
|
-
* @param jsonData JSON 数据
|
|
473
|
-
* @param options 配置选项
|
|
474
|
-
* @returns 类型字符串
|
|
475
|
-
*/
|
|
476
|
-
declare function generateType(jsonData: any, options?: GenerateOptions): string;
|
|
469
|
+
declare function generateFromString(jsonString: string, options?: GenerateOptions): string;
|
|
477
470
|
|
|
478
471
|
declare const _default: {
|
|
479
472
|
generate: typeof generate;
|
|
480
473
|
generateFromString: typeof generateFromString;
|
|
481
|
-
generateType: typeof generateType;
|
|
482
474
|
};
|
|
483
475
|
|
|
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,
|
|
476
|
+
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, guessCommentFromFieldName, inferArrayType, inferObjectType, inferType, isStructurallyEqual, mergeObjects, mergeTypes };
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
interface PrimitiveType {
|
|
8
8
|
kind: 'primitive';
|
|
9
|
-
type: 'string' | 'number' | 'boolean' | 'any' | 'unknown' | 'never';
|
|
9
|
+
type: 'string' | 'number' | 'boolean' | 'any' | 'unknown' | 'never' | 'function';
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
12
|
* 数组类型
|
|
@@ -139,7 +139,7 @@ interface GenerateResult {
|
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
/**
|
|
142
|
-
*
|
|
142
|
+
* type-flash - 命名与去重模块
|
|
143
143
|
*
|
|
144
144
|
* 核心功能:
|
|
145
145
|
* - 根据字段名 + 上下文自动生成有意义的类型名
|
|
@@ -280,7 +280,7 @@ declare class TypeCollector {
|
|
|
280
280
|
}
|
|
281
281
|
|
|
282
282
|
/**
|
|
283
|
-
*
|
|
283
|
+
* type-flash - 格式化输出模块
|
|
284
284
|
*
|
|
285
285
|
* 核心功能:
|
|
286
286
|
* - 将类型节点格式化为 TypeScript 代码字符串
|
|
@@ -360,7 +360,7 @@ declare function guessCommentFromFieldName(fieldName: string): string | undefine
|
|
|
360
360
|
declare function addGuessedComments(type: ObjectType): ObjectType;
|
|
361
361
|
|
|
362
362
|
/**
|
|
363
|
-
*
|
|
363
|
+
* type-flash - 类型推断引擎
|
|
364
364
|
*
|
|
365
365
|
* 核心功能:
|
|
366
366
|
* - 基础类型识别(string、number、boolean、null、undefined)
|
|
@@ -408,7 +408,7 @@ declare function inferObjectType(obj: Record<string, unknown>): ObjectType;
|
|
|
408
408
|
declare function isStructurallyEqual(a: TSTypeNode, b: TSTypeNode): boolean;
|
|
409
409
|
|
|
410
410
|
/**
|
|
411
|
-
*
|
|
411
|
+
* type-flash - 增强功能模块
|
|
412
412
|
*
|
|
413
413
|
* 核心功能:
|
|
414
414
|
* - 泛型提取(如 PageResult<T>)
|
|
@@ -448,7 +448,7 @@ declare class OptionalHandler {
|
|
|
448
448
|
declare function applyEnhancements(jsonData: any, type: TSTypeNode, options: GenerateOptions): TSTypeNode;
|
|
449
449
|
|
|
450
450
|
/**
|
|
451
|
-
*
|
|
451
|
+
* type-flash - JSON 智能生成 TypeScript 类型定义
|
|
452
452
|
*
|
|
453
453
|
* 主入口文件
|
|
454
454
|
*/
|
|
@@ -459,26 +459,18 @@ declare function applyEnhancements(jsonData: any, type: TSTypeNode, options: Gen
|
|
|
459
459
|
* @param options 配置选项
|
|
460
460
|
* @returns 生成结果
|
|
461
461
|
*/
|
|
462
|
-
declare function generate(jsonData: any, options?: GenerateOptions):
|
|
462
|
+
declare function generate(jsonData: any, options?: GenerateOptions): string;
|
|
463
463
|
/**
|
|
464
464
|
* 从 JSON 字符串生成类型定义
|
|
465
465
|
* @param jsonString JSON 字符串
|
|
466
466
|
* @param options 配置选项
|
|
467
467
|
* @returns 生成结果
|
|
468
468
|
*/
|
|
469
|
-
declare function generateFromString(jsonString: string, options?: GenerateOptions):
|
|
470
|
-
/**
|
|
471
|
-
* 生成单个类型的字符串表示
|
|
472
|
-
* @param jsonData JSON 数据
|
|
473
|
-
* @param options 配置选项
|
|
474
|
-
* @returns 类型字符串
|
|
475
|
-
*/
|
|
476
|
-
declare function generateType(jsonData: any, options?: GenerateOptions): string;
|
|
469
|
+
declare function generateFromString(jsonString: string, options?: GenerateOptions): string;
|
|
477
470
|
|
|
478
471
|
declare const _default: {
|
|
479
472
|
generate: typeof generate;
|
|
480
473
|
generateFromString: typeof generateFromString;
|
|
481
|
-
generateType: typeof generateType;
|
|
482
474
|
};
|
|
483
475
|
|
|
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,
|
|
476
|
+
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, guessCommentFromFieldName, inferArrayType, inferObjectType, inferType, isStructurallyEqual, mergeObjects, mergeTypes };
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`,typeNameMap:{},typePrefix:"",typeSuffix:""};function
|
|
1
|
+
"use strict";var j=Object.defineProperty;var M=Object.getOwnPropertyDescriptor;var K=Object.getOwnPropertyNames;var E=Object.prototype.hasOwnProperty;var L=(n,e)=>{for(var t in e)j(n,t,{get:e[t],enumerable:!0})},z=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of K(e))!E.call(n,i)&&i!==t&&j(n,i,{get:()=>e[i],enumerable:!(r=M(e,i))||r.enumerable});return n};var _=n=>z(j({},"__esModule",{value:!0}),n);var H={};L(H,{CodeFormatter:()=>y,GenericExtractor:()=>g,NullHandler:()=>h,OptionalHandler:()=>N,TypeCollector:()=>m,TypeNamer:()=>f,addGuessedComments:()=>k,applyEnhancements:()=>b,createUnion:()=>x,default:()=>V,generate:()=>A,generateFromString:()=>R,guessCommentFromFieldName:()=>P,inferArrayType:()=>v,inferObjectType:()=>$,inferType:()=>l,isStructurallyEqual:()=>S,mergeObjects:()=>O,mergeTypes:()=>T});module.exports=_(H);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 d(n){return{kind:"primitive",type:n}}function q(){return{kind:"null"}}function I(){return{kind:"undefined"}}function Z(n){return{kind:"array",elementType:n}}function D(n=[]){return{kind:"object",properties:n}}function x(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"?O(n,e):n.kind==="array"&&e.kind==="array"?Z(T(n.elementType,e.elementType)):x([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(s=>s.name===r)||(i.optional=!0);return D(Array.from(t.values()))}function l(n){return n===null?q():n===void 0?I():typeof n=="function"?d("function"):typeof n=="string"?d("string"):typeof n=="number"?d("number"):typeof n=="boolean"?d("boolean"):Array.isArray(n)?v(n):typeof n=="object"?$(n):d("unknown")}function v(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 $(n){let e=[];for(let[t,r]of Object.entries(n)){let i=l(r);e.push({name:t,type:i,optional:!1})}return D(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 f=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()}},m=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),U=c.optional?"?":"",F=this.formatType(c.type),C=`${o}${G}${U}: ${F};`;c.comment&&(C+=` // ${c.comment}`),a.push(C)}return this.options.outputStyle==="interface"?a.push("}"):a.push("};"),a.join(`
|
|
3
3
|
`)}formatType(e){if(e.kind==="object"){let t=this.findTypeName(e);if(t)return t}switch(e.kind){case"primitive":return e.type;case"null":return"null";case"undefined":return"undefined";case"array":return this.formatArrayType(e);case"object":return this.formatInlineObject(e);case"union":return this.formatUnionType(e.types);case"literal":return this.formatLiteral(e.value);case"generic":return`${e.name}<${e.typeArgs.map(t=>this.formatType(t)).join(", ")}>`;default:return"unknown"}}formatLiteral(e){return typeof e=="string"?`'${e}'`:String(e)}formatArrayType(e){let t=this.formatType(e.elementType);return e.elementType.kind==="union"?`(${t})[]`:`${t}[]`}formatInlineObject(e){let t=" ".repeat(this.options.indentSize),r=this.sortProperties(e.properties);if(r.length===0)return"{}";let i=["{"];for(let o of r){let s=this.formatPropertyName(o.name),a=o.optional?"?":"",c=this.formatType(o.type);i.push(`${t}${s}${a}: ${c};`)}return i.push("}"),i.join(`
|
|
4
4
|
`)}formatUnionType(e){return e.map(t=>this.formatType(t)).join(" | ")}formatPropertyName(e){return/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(e)?e:`'${e}'`}sortProperties(e){return this.options.sortProperties==="definition"?[...e]:[...e].sort((t,r)=>t.name.localeCompare(r.name))}formatJSDoc(e){let t=e.split(`
|
|
5
5
|
`);return t.length===1?`/** ${e} */`:["/**",...t.map(r=>` * ${r}`)," */"].join(`
|
|
6
6
|
`)}formatAll(e){return this.allNamedTypes=e,e.map(t=>this.formatTypeDef(t)).join(`
|
|
7
7
|
|
|
8
8
|
`)}generateOutput(e,t){let r=`/**
|
|
9
|
-
* Generated by
|
|
9
|
+
* Generated by type-flash
|
|
10
10
|
* Root type: ${t}
|
|
11
11
|
*/`,i=this.formatAll(e);return`${r}
|
|
12
12
|
|
|
13
13
|
${i}
|
|
14
|
-
`}};function
|
|
14
|
+
`}};function P(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||P(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 A(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 f({namingStyle:t.namingStyle,prefix:t.typePrefix,suffix:t.typeSuffix,customNameMap:t.typeNameMap}),s=new m(i).collect(r,t.rootName);return new y(t,i).generateOutput(s,t.rootName)}function R(n,e={}){let t=JSON.parse(n);return A(t,e)}var V={generate:A,generateFromString:R};0&&(module.exports={CodeFormatter,GenericExtractor,NullHandler,OptionalHandler,TypeCollector,TypeNamer,addGuessedComments,applyEnhancements,createUnion,generate,generateFromString,guessCommentFromFieldName,inferArrayType,inferObjectType,inferType,isStructurallyEqual,mergeObjects,mergeTypes});
|
package/dist/index.mjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
var
|
|
2
|
-
`,typeNameMap:{},typePrefix:"",typeSuffix:""};function
|
|
1
|
+
var x={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 l(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 O(n=[]){return{kind:"object",properties:n}}function v(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"?$(n,e):n.kind==="array"&&e.kind==="array"?M(T(n.elementType,e.elementType)):v([n,e])}function $(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 O(Array.from(t.values()))}function f(n){return n===null?U():n===void 0?F():typeof n=="function"?l("function"):typeof n=="string"?l("string"):typeof n=="number"?l("number"):typeof n=="boolean"?l("boolean"):Array.isArray(n)?P(n):typeof n=="object"?A(n):l("unknown")}function P(n){if(n.length===0)return{kind:"array",elementType:{kind:"primitive",type:"any"}};let e=n.map(r=>f(r)),t=e[0];for(let r=1;r<e.length;r++)t=T(t,e[r]);return{kind:"array",elementType:t}}function A(n){let e=[];for(let[t,r]of Object.entries(n)){let i=f(r);e.push({name:t,type:i,optional:!1})}return O(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()}},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 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 d=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 D=this.formatPropertyName(c.name),R=c.optional?"?":"",G=this.formatType(c.type),j=`${o}${D}${R}: ${G};`;c.comment&&(j+=` // ${c.comment}`),a.push(j)}return this.options.outputStyle==="interface"?a.push("}"):a.push("};"),a.join(`
|
|
3
3
|
`)}formatType(e){if(e.kind==="object"){let t=this.findTypeName(e);if(t)return t}switch(e.kind){case"primitive":return e.type;case"null":return"null";case"undefined":return"undefined";case"array":return this.formatArrayType(e);case"object":return this.formatInlineObject(e);case"union":return this.formatUnionType(e.types);case"literal":return this.formatLiteral(e.value);case"generic":return`${e.name}<${e.typeArgs.map(t=>this.formatType(t)).join(", ")}>`;default:return"unknown"}}formatLiteral(e){return typeof e=="string"?`'${e}'`:String(e)}formatArrayType(e){let t=this.formatType(e.elementType);return e.elementType.kind==="union"?`(${t})[]`:`${t}[]`}formatInlineObject(e){let t=" ".repeat(this.options.indentSize),r=this.sortProperties(e.properties);if(r.length===0)return"{}";let i=["{"];for(let o of r){let s=this.formatPropertyName(o.name),a=o.optional?"?":"",c=this.formatType(o.type);i.push(`${t}${s}${a}: ${c};`)}return i.push("}"),i.join(`
|
|
4
4
|
`)}formatUnionType(e){return e.map(t=>this.formatType(t)).join(" | ")}formatPropertyName(e){return/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(e)?e:`'${e}'`}sortProperties(e){return this.options.sortProperties==="definition"?[...e]:[...e].sort((t,r)=>t.name.localeCompare(r.name))}formatJSDoc(e){let t=e.split(`
|
|
5
5
|
`);return t.length===1?`/** ${e} */`:["/**",...t.map(r=>` * ${r}`)," */"].join(`
|
|
6
6
|
`)}formatAll(e){return this.allNamedTypes=e,e.map(t=>this.formatTypeDef(t)).join(`
|
|
7
7
|
|
|
8
8
|
`)}generateOutput(e,t){let r=`/**
|
|
9
|
-
* Generated by
|
|
9
|
+
* Generated by type-flash
|
|
10
10
|
* Root type: ${t}
|
|
11
11
|
*/`,i=this.formatAll(e);return`${r}
|
|
12
12
|
|
|
13
13
|
${i}
|
|
14
|
-
`}};function
|
|
14
|
+
`}};function C(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||C(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 w(n,e={}){let t={...x,...e},r=f(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 y(i).collect(r,t.rootName);return new d(t,i).generateOutput(s,t.rootName)}function K(n,e={}){let t=JSON.parse(n);return w(t,e)}var Y={generate:w,generateFromString:K};export{d as CodeFormatter,g as GenericExtractor,h as NullHandler,N as OptionalHandler,y as TypeCollector,m as TypeNamer,k as addGuessedComments,b as applyEnhancements,v as createUnion,Y as default,w as generate,K as generateFromString,C as guessCommentFromFieldName,P as inferArrayType,A as inferObjectType,f as inferType,S as isStructurallyEqual,$ as mergeObjects,T as mergeTypes};
|