type-flash 1.0.8 → 1.1.0
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 -11
- package/bin/type-flash.js +2 -9
- package/dist/index.d.mts +2 -18
- package/dist/index.d.ts +2 -18
- package/dist/index.js +5 -7
- package/dist/index.mjs +5 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -30,7 +30,6 @@
|
|
|
30
30
|
### ⚡ 增强功能
|
|
31
31
|
|
|
32
32
|
- **🧬 泛型模式识别** - 智能识别分页结构 `{ list: T[], total: number }`,提取为 `PageResult<T>`
|
|
33
|
-
- **📝 JSDoc 注释生成** - 根据字段名猜测含义,自动生成文档注释
|
|
34
33
|
- **🎨 多种输出风格** - 支持 `interface` 和 `type alias` 两种输出风格
|
|
35
34
|
- **📏 灵活命名控制** - 支持 PascalCase / camelCase、前缀后缀、自定义类型名映射
|
|
36
35
|
|
|
@@ -39,7 +38,6 @@
|
|
|
39
38
|
- **💻 CLI 命令行工具** - 开箱即用的命令行工具,支持管道输入
|
|
40
39
|
- **📦 双模块输出** - 同时提供 CommonJS 和 ESM 两种模块格式
|
|
41
40
|
- **🔩 TypeScript 原生** - 纯 TypeScript 编写,类型定义开箱即用
|
|
42
|
-
- **🧪 完整测试覆盖** - Jest 单元测试,确保核心功能稳定可靠
|
|
43
41
|
|
|
44
42
|
---
|
|
45
43
|
|
|
@@ -197,9 +195,6 @@ type-flash data.json --style type
|
|
|
197
195
|
# 从标准输入读取(管道)
|
|
198
196
|
curl https://api.example.com/users | type-flash -n UserList
|
|
199
197
|
|
|
200
|
-
# 生成带注释的类型定义
|
|
201
|
-
type-flash api.json --comments -o api-types.ts
|
|
202
|
-
|
|
203
198
|
# 严格空值模式
|
|
204
199
|
type-flash data.json --strict-null
|
|
205
200
|
|
|
@@ -221,7 +216,6 @@ type-flash types.json --no-export
|
|
|
221
216
|
| `--naming-style <s>` | 命名风格: `PascalCase` \| `camelCase` | `PascalCase` |
|
|
222
217
|
| `--sort <order>` | 属性排序: `alpha` \| `definition` | `alpha` |
|
|
223
218
|
| `--no-export` | 不添加 export 关键字 | - |
|
|
224
|
-
| `--comments` | 生成 JSDoc 注释 | - |
|
|
225
219
|
| `--strict-null` | 严格空值模式 | - |
|
|
226
220
|
| `--no-optional` | 不标记可选属性 | - |
|
|
227
221
|
| `--no-generics` | 不提取泛型类型 | - |
|
|
@@ -254,9 +248,6 @@ interface GenerateOptions {
|
|
|
254
248
|
/** 是否添加 export 语句,默认 true */
|
|
255
249
|
addExport?: boolean;
|
|
256
250
|
|
|
257
|
-
/** 是否生成 JSDoc 注释,默认 false */
|
|
258
|
-
addComments?: boolean;
|
|
259
|
-
|
|
260
251
|
/** 是否严格空值,默认 false */
|
|
261
252
|
strictNullChecks?: boolean;
|
|
262
253
|
|
|
@@ -294,7 +285,6 @@ const result = generate(jsonData, {
|
|
|
294
285
|
typePrefix: 'I',
|
|
295
286
|
typeSuffix: 'DTO',
|
|
296
287
|
addExport: true,
|
|
297
|
-
addComments: true,
|
|
298
288
|
sortProperties: 'alpha',
|
|
299
289
|
extractGenerics: true,
|
|
300
290
|
strictNullChecks: true,
|
|
@@ -330,7 +320,6 @@ const result = generate(jsonData, {
|
|
|
330
320
|
| **泛型模式识别** | ✅ | ❌ | ❌ | ❌ |
|
|
331
321
|
| **结构等价去重** | ✅ | ⚠️ 有限 | ❌ | ✅ |
|
|
332
322
|
| **循环引用处理** | ✅ | ✅ | ❌ | ✅ |
|
|
333
|
-
| **JSDoc 注释生成** | ✅ | ✅ | ❌ | ✅ |
|
|
334
323
|
| **CLI 命令行** | ✅ | ✅ | ❌ | ✅ |
|
|
335
324
|
| **编程式 API** | ✅ | ✅ | ❌ | ✅ |
|
|
336
325
|
| **零依赖** | ✅ | ❌ 依赖多 | - | ❌ 包体大 |
|
package/bin/type-flash.js
CHANGED
|
@@ -28,7 +28,6 @@ function parseArgs(argv) {
|
|
|
28
28
|
namingStyle: 'PascalCase',
|
|
29
29
|
sortProperties: 'alpha',
|
|
30
30
|
addExport: true,
|
|
31
|
-
addComments: false,
|
|
32
31
|
strictNullChecks: false,
|
|
33
32
|
markOptional: true,
|
|
34
33
|
extractGenerics: true,
|
|
@@ -87,10 +86,6 @@ function parseArgs(argv) {
|
|
|
87
86
|
args.addExport = false;
|
|
88
87
|
break;
|
|
89
88
|
|
|
90
|
-
case '--comments':
|
|
91
|
-
args.addComments = true;
|
|
92
|
-
break;
|
|
93
|
-
|
|
94
89
|
case '--strict-null':
|
|
95
90
|
args.strictNullChecks = true;
|
|
96
91
|
break;
|
|
@@ -147,7 +142,6 @@ type-flash - JSON 智能生成 TypeScript 类型定义
|
|
|
147
142
|
--naming-style <s> 命名风格: PascalCase | camelCase(默认: PascalCase)
|
|
148
143
|
--sort <order> 属性排序: alpha | definition(默认: alpha)
|
|
149
144
|
--no-export 不添加 export 关键字
|
|
150
|
-
--comments 生成 JSDoc 注释
|
|
151
145
|
--strict-null 严格空值模式(保留 null 类型)
|
|
152
146
|
--no-optional 不标记可选属性
|
|
153
147
|
--no-generics 不提取泛型类型
|
|
@@ -167,8 +161,8 @@ type-flash - JSON 智能生成 TypeScript 类型定义
|
|
|
167
161
|
# 从标准输入读取
|
|
168
162
|
curl https://api.example.com/data | type-flash -n ApiResponse
|
|
169
163
|
|
|
170
|
-
#
|
|
171
|
-
type-flash api.json --prefix Api
|
|
164
|
+
# 带前缀
|
|
165
|
+
type-flash api.json --prefix Api -o api-types.ts
|
|
172
166
|
`);
|
|
173
167
|
}
|
|
174
168
|
|
|
@@ -258,7 +252,6 @@ async function main() {
|
|
|
258
252
|
namingStyle: args.namingStyle,
|
|
259
253
|
sortProperties: args.sortProperties,
|
|
260
254
|
addExport: args.addExport,
|
|
261
|
-
addComments: args.addComments,
|
|
262
255
|
strictNullChecks: args.strictNullChecks,
|
|
263
256
|
markOptional: args.markOptional,
|
|
264
257
|
extractGenerics: args.extractGenerics,
|
package/dist/index.d.mts
CHANGED
|
@@ -34,8 +34,6 @@ interface PropertyDef {
|
|
|
34
34
|
type: TSTypeNode;
|
|
35
35
|
/** 是否可选 */
|
|
36
36
|
optional: boolean;
|
|
37
|
-
/** JSDoc 注释 */
|
|
38
|
-
comment?: string;
|
|
39
37
|
}
|
|
40
38
|
/**
|
|
41
39
|
* 联合类型
|
|
@@ -101,8 +99,6 @@ interface GenerateOptions {
|
|
|
101
99
|
sortProperties?: SortOrder;
|
|
102
100
|
/** 是否添加 export 语句,默认 true */
|
|
103
101
|
addExport?: boolean;
|
|
104
|
-
/** 是否生成 JSDoc 注释,默认 false */
|
|
105
|
-
addComments?: boolean;
|
|
106
102
|
/** 是否严格空值(null 单独类型),默认 false */
|
|
107
103
|
strictNullChecks?: boolean;
|
|
108
104
|
/** 是否将可选属性标记为 ?,默认 true */
|
|
@@ -285,7 +281,7 @@ declare class TypeCollector {
|
|
|
285
281
|
* 核心功能:
|
|
286
282
|
* - 将类型节点格式化为 TypeScript 代码字符串
|
|
287
283
|
* - 支持 interface 和 type alias 两种输出风格
|
|
288
|
-
* -
|
|
284
|
+
* - 自动缩进、排序
|
|
289
285
|
*/
|
|
290
286
|
|
|
291
287
|
/**
|
|
@@ -337,10 +333,6 @@ declare class CodeFormatter {
|
|
|
337
333
|
* 排序属性
|
|
338
334
|
*/
|
|
339
335
|
private sortProperties;
|
|
340
|
-
/**
|
|
341
|
-
* 格式化多行 JSDoc 注释
|
|
342
|
-
*/
|
|
343
|
-
private formatJSDoc;
|
|
344
336
|
/**
|
|
345
337
|
* 格式化所有类型定义
|
|
346
338
|
*/
|
|
@@ -350,14 +342,6 @@ declare class CodeFormatter {
|
|
|
350
342
|
*/
|
|
351
343
|
generateOutput(typeDefs: NamedTypeDef[], rootTypeName: string): string;
|
|
352
344
|
}
|
|
353
|
-
/**
|
|
354
|
-
* 根据字段名猜测 JSDoc 注释
|
|
355
|
-
*/
|
|
356
|
-
declare function guessCommentFromFieldName(fieldName: string): string | undefined;
|
|
357
|
-
/**
|
|
358
|
-
* 为对象类型的属性添加猜测的注释
|
|
359
|
-
*/
|
|
360
|
-
declare function addGuessedComments(type: ObjectType): ObjectType;
|
|
361
345
|
|
|
362
346
|
/**
|
|
363
347
|
* type-flash - 类型推断引擎
|
|
@@ -473,4 +457,4 @@ declare const _default: {
|
|
|
473
457
|
generateFromString: typeof generateFromString;
|
|
474
458
|
};
|
|
475
459
|
|
|
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,
|
|
460
|
+
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, applyEnhancements, createUnion, _default as default, generate, generateFromString, inferArrayType, inferObjectType, inferType, isStructurallyEqual, mergeObjects, mergeTypes };
|
package/dist/index.d.ts
CHANGED
|
@@ -34,8 +34,6 @@ interface PropertyDef {
|
|
|
34
34
|
type: TSTypeNode;
|
|
35
35
|
/** 是否可选 */
|
|
36
36
|
optional: boolean;
|
|
37
|
-
/** JSDoc 注释 */
|
|
38
|
-
comment?: string;
|
|
39
37
|
}
|
|
40
38
|
/**
|
|
41
39
|
* 联合类型
|
|
@@ -101,8 +99,6 @@ interface GenerateOptions {
|
|
|
101
99
|
sortProperties?: SortOrder;
|
|
102
100
|
/** 是否添加 export 语句,默认 true */
|
|
103
101
|
addExport?: boolean;
|
|
104
|
-
/** 是否生成 JSDoc 注释,默认 false */
|
|
105
|
-
addComments?: boolean;
|
|
106
102
|
/** 是否严格空值(null 单独类型),默认 false */
|
|
107
103
|
strictNullChecks?: boolean;
|
|
108
104
|
/** 是否将可选属性标记为 ?,默认 true */
|
|
@@ -285,7 +281,7 @@ declare class TypeCollector {
|
|
|
285
281
|
* 核心功能:
|
|
286
282
|
* - 将类型节点格式化为 TypeScript 代码字符串
|
|
287
283
|
* - 支持 interface 和 type alias 两种输出风格
|
|
288
|
-
* -
|
|
284
|
+
* - 自动缩进、排序
|
|
289
285
|
*/
|
|
290
286
|
|
|
291
287
|
/**
|
|
@@ -337,10 +333,6 @@ declare class CodeFormatter {
|
|
|
337
333
|
* 排序属性
|
|
338
334
|
*/
|
|
339
335
|
private sortProperties;
|
|
340
|
-
/**
|
|
341
|
-
* 格式化多行 JSDoc 注释
|
|
342
|
-
*/
|
|
343
|
-
private formatJSDoc;
|
|
344
336
|
/**
|
|
345
337
|
* 格式化所有类型定义
|
|
346
338
|
*/
|
|
@@ -350,14 +342,6 @@ declare class CodeFormatter {
|
|
|
350
342
|
*/
|
|
351
343
|
generateOutput(typeDefs: NamedTypeDef[], rootTypeName: string): string;
|
|
352
344
|
}
|
|
353
|
-
/**
|
|
354
|
-
* 根据字段名猜测 JSDoc 注释
|
|
355
|
-
*/
|
|
356
|
-
declare function guessCommentFromFieldName(fieldName: string): string | undefined;
|
|
357
|
-
/**
|
|
358
|
-
* 为对象类型的属性添加猜测的注释
|
|
359
|
-
*/
|
|
360
|
-
declare function addGuessedComments(type: ObjectType): ObjectType;
|
|
361
345
|
|
|
362
346
|
/**
|
|
363
347
|
* type-flash - 类型推断引擎
|
|
@@ -473,4 +457,4 @@ declare const _default: {
|
|
|
473
457
|
generateFromString: typeof generateFromString;
|
|
474
458
|
};
|
|
475
459
|
|
|
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,
|
|
460
|
+
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, applyEnhancements, createUnion, _default as default, generate, generateFromString, inferArrayType, inferObjectType, inferType, isStructurallyEqual, mergeObjects, mergeTypes };
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`,typeNameMap:{},typePrefix:"",typeSuffix:""};function
|
|
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?"?":"",
|
|
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))}
|
|
5
|
-
`);return t.length===1?`/** ${e} */`:["/**",...t.map(r=>` * ${r}`)," */"].join(`
|
|
6
|
-
`)}formatAll(e){return this.allNamedTypes=e,e.map(t=>this.formatTypeDef(t)).join(`
|
|
1
|
+
"use strict";var k=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var R=Object.prototype.hasOwnProperty;var G=(n,e)=>{for(var t in e)k(n,t,{get:e[t],enumerable:!0})},U=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of D(e))!R.call(n,i)&&i!==t&&k(n,i,{get:()=>e[i],enumerable:!(r=C(e,i))||r.enumerable});return n};var K=n=>U(k({},"__esModule",{value:!0}),n);var _={};G(_,{CodeFormatter:()=>y,GenericExtractor:()=>T,NullHandler:()=>g,OptionalHandler:()=>h,TypeCollector:()=>f,TypeNamer:()=>l,applyEnhancements:()=>S,createUnion:()=>b,default:()=>L,generate:()=>v,generateFromString:()=>A,inferArrayType:()=>j,inferObjectType:()=>O,inferType:()=>c,isStructurallyEqual:()=>N,mergeObjects:()=>x,mergeTypes:()=>d});module.exports=K(_);var P={rootName:"Root",outputStyle:"interface",namingStyle:"PascalCase",sortProperties:"alpha",addExport:!0,strictNullChecks:!1,markOptional:!0,extractGenerics:!0,indentSize:2,lineEnding:`
|
|
2
|
+
`,typeNameMap:{},typePrefix:"",typeSuffix:""};function m(n){return{kind:"primitive",type:n}}function M(){return{kind:"null"}}function E(){return{kind:"undefined"}}function F(n){return{kind:"array",elementType:n}}function $(n=[]){return{kind:"object",properties:n}}function b(n){let e=[],t=new Set;for(let r of n)if(r.kind==="union")for(let i of r.types){let o=p(i);t.has(o)||(t.add(o),e.push(i))}else{let i=p(r);t.has(i)||(t.add(i),e.push(r))}return e.length===1?e[0]:{kind:"union",types:e}}function p(n){switch(n.kind){case"primitive":return`primitive:${n.type}`;case"null":return"null";case"undefined":return"undefined";case"literal":return`literal:${typeof n.value}:${String(n.value)}`;case"array":return`array:${p(n.elementType)}`;case"object":return`object:${n.properties.map(e=>`${e.name}:${p(e.type)}:${e.optional}`).join(",")}`;case"union":return`union:${n.types.map(p).sort().join("|")}`;case"generic":return`generic:${n.name}:${n.typeArgs.map(p).join(",")}`;default:return"unknown"}}function d(n,e){return p(n)===p(e)?n:n.kind==="object"&&e.kind==="object"?x(n,e):n.kind==="array"&&e.kind==="array"?F(d(n.elementType,e.elementType)):b([n,e])}function x(n,e){let t=new Map;for(let r of n.properties)t.set(r.name,{...r});for(let r of e.properties){let i=t.get(r.name);i?(i.type=d(i.type,r.type),i.optional=i.optional||r.optional):t.set(r.name,{...r,optional:!0})}for(let[r,i]of t)e.properties.some(s=>s.name===r)||(i.optional=!0);return $(Array.from(t.values()))}function c(n){return n===null?M():n===void 0?E():typeof n=="function"?m("function"):typeof n=="string"?m("string"):typeof n=="number"?m("number"):typeof n=="boolean"?m("boolean"):Array.isArray(n)?j(n):typeof n=="object"?O(n):m("unknown")}function j(n){if(n.length===0)return{kind:"array",elementType:{kind:"primitive",type:"any"}};let e=n.map(r=>c(r)),t=e[0];for(let r=1;r<e.length;r++)t=d(t,e[r]);return{kind:"array",elementType:t}}function O(n){let e=[];for(let[t,r]of Object.entries(n)){let i=c(r);e.push({name:t,type:i,optional:!1})}return $(e)}function N(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 l=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.formatName(o),o=this.ensureUniqueName(o),o=this.applyAffixes(o),this.namedTypes.set(i,o),o}generateName(e,t){if(e.kind==="object"){if(t.fieldName){let r=this.toPascalCase(t.fieldName);return t.parentName?`${t.parentName}${r}`:r}return t.parentName?`${t.parentName}Item`:"AnonymousObject"}return"UnknownType"}ensureUniqueName(e){let t=this.nameCounter.get(e)||0;if(t===0)return this.nameCounter.set(e,1),e;let r=`${e}${t+1}`;return this.nameCounter.set(e,t+1),r}applyAffixes(e){let t=e;return this.prefix&&(t=this.toPascalCase(this.prefix)+t),this.suffix&&(t=t+this.toPascalCase(this.suffix)),t}buildPathKey(e){let t=[];return e.parentName&&t.push(e.parentName),e.fieldName&&t.push(e.fieldName),t.join(".")}getTypeKey(e){return e.kind==="object"?`object:${e.properties.map(t=>`${t.name}:${this.getSimpleTypeKey(t.type)}:${t.optional}`).sort().join(",")}`:e.kind}getSimpleTypeKey(e){switch(e.kind){case"primitive":return e.type;case"null":return"null";case"undefined":return"undefined";case"array":return`array<${this.getSimpleTypeKey(e.elementType)}>`;case"object":return"object";case"union":return e.types.map(t=>this.getSimpleTypeKey(t)).sort().join("|");case"generic":return`generic:${e.name}`;default:return"unknown"}}toPascalCase(e){return e?e.replace(/[-_\s]+/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").trim().split(" ").filter(Boolean).map(r=>r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join(""):""}toCamelCase(e){let t=this.toPascalCase(e);return t.charAt(0).toLowerCase()+t.slice(1)}formatName(e){return this.namingStyle==="camelCase"?this.toCamelCase(e):this.toPascalCase(e)}isCircular(e){return this.processing.has(e)}markProcessing(e){this.processing.add(e)}unmarkProcessing(e){this.processing.delete(e)}getAllNamedTypes(){return new Map(this.namedTypes)}reset(){this.namedTypes.clear(),this.nameCounter.clear(),this.processing=new WeakSet,this.circularRefs.clear()}},f=class{constructor(e){this.collected=[];this.seenStructs=new Set;this.namer=e}collect(e,t){this.collected=[],this.seenStructs.clear(),this.namer.reset();let r=this.getStructKey(e);this.namer.nameType(e,{fieldName:t,depth:0}),this.collectRecursive(e,{fieldName:t,parentName:void 0,depth:0});let i=this.collected.find(s=>s.name===t),o=this.collected.filter(s=>s.name!==t);return i?[i,...o]:this.collected}collectRecursive(e,t){let r=this.getStructKey(e);if(e.kind==="object"){let i=this.namer.nameType(e,t);if(i&&!this.seenStructs.has(r)){this.seenStructs.add(r),this.collected.push({name:i,type:u(e)});for(let o of e.properties)this.collectRecursive(o.type,{fieldName:o.name,parentName:i,depth:t.depth+1})}return}if(e.kind==="array"){this.collectRecursive(e.elementType,{fieldName:t.fieldName?t.fieldName+"Item":void 0,parentName:t.parentName,depth:t.depth+1});return}if(e.kind==="union"){for(let i of e.types)this.collectRecursive(i,t);return}if(e.kind==="generic"){for(let i of e.typeArgs)this.collectRecursive(i,{...t,depth:t.depth+1});return}}getStructKey(e){return e.kind==="object"?`object:${e.properties.map(t=>`${t.name}:${this.getPropTypeKey(t.type)}:${t.optional}`).sort().join("|")}`:e.kind}getPropTypeKey(e){switch(e.kind){case"primitive":return e.type;case"null":return"null";case"undefined":return"undefined";case"array":return`array:${this.getPropTypeKey(e.elementType)}`;case"object":return"object";case"union":return e.types.map(t=>this.getPropTypeKey(t)).sort().join("|");case"generic":return`generic:${e.name}`;default:return"unknown"}}};var y=class{constructor(e,t){this.allNamedTypes=[];this.options=e,this.namer=t}findTypeName(e){if(e.kind!=="object")return null;for(let t of this.allNamedTypes)if(N(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=[];return this.options.outputStyle==="interface"?a.push(`${r}interface ${e} {`):a.push(`${r}type ${e} = {`),this.options.outputStyle==="interface"?a.push("}"):a.push("};"),a.join(`
|
|
3
|
+
`)}formatType(e){if(e.kind==="object"){let t=this.findTypeName(e);if(t)return t}switch(e.kind){case"primitive":return e.type;case"null":return"null";case"undefined":return"undefined";case"array":return this.formatArrayType(e);case"object":return this.formatInlineObject(e);case"union":return this.formatUnionType(e.types);case"literal":return this.formatLiteral(e.value);case"generic":return`${e.name}<${e.typeArgs.map(t=>this.formatType(t)).join(", ")}>`;default:return"unknown"}}formatLiteral(e){return typeof e=="string"?`'${e}'`:String(e)}formatArrayType(e){let t=this.formatType(e.elementType);return e.elementType.kind==="union"?`(${t})[]`:`${t}[]`}formatInlineObject(e){let t=" ".repeat(this.options.indentSize),r=this.sortProperties(e.properties);if(r.length===0)return"{}";let i=["{"];for(let o of r){let s=this.formatPropertyName(o.name),a=o.optional?"?":"",w=this.formatType(o.type);i.push(`${t}${s}${a}: ${w};`)}return i.push("}"),i.join(`
|
|
4
|
+
`)}formatUnionType(e){return e.map(t=>this.formatType(t)).join(" | ")}formatPropertyName(e){return/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(e)?e:`'${e}'`}sortProperties(e){return this.options.sortProperties==="definition"?[...e]:[...e].sort((t,r)=>t.name.localeCompare(r.name))}formatAll(e){return this.allNamedTypes=e,e.map(t=>this.formatTypeDef(t)).join(`
|
|
7
5
|
|
|
8
6
|
`)}generateOutput(e,t){let r=`/**
|
|
9
7
|
* Generated by type-flash
|
|
@@ -11,4 +9,4 @@
|
|
|
11
9
|
*/`,i=this.formatAll(e);return`${r}
|
|
12
10
|
|
|
13
11
|
${i}
|
|
14
|
-
`}};
|
|
12
|
+
`}};var T=class{constructor(){this.patterns=[{name:"PageResult",arrayFields:["list","records","rows","items"],countFields:["total","count","totalCount"]},{name:"ListResult",arrayFields:["list","data","items"],countFields:[]},{name:"ApiResponse",arrayFields:["data"],countFields:[]}]}extract(e){if(e.kind!=="object")return e;for(let t of this.patterns){let r=this.tryMatchPattern(e,t);if(r)return r}return e}tryMatchPattern(e,t){let r=null,i=t.countFields.length===0;for(let o of e.properties)t.arrayFields.includes(o.name)&&o.type.kind==="array"&&(r={name:o.name,elementType:o.type.elementType}),t.countFields.includes(o.name)&&(i=!0);return r&&i?{kind:"generic",name:t.name,typeArgs:[r.elementType]}:null}},g=class{constructor(e=!1){this.strict=e}process(e){if(this.strict)return e;if(e.kind==="union"){let t=e.types.filter(r=>r.kind!=="null");return t.length===0?{kind:"null"}:t.length===1?t[0]:{...e,types:t}}return e.kind==="array"?{...e,elementType:this.process(e.elementType)}:e.kind==="object"?{...e,properties:e.properties.map(t=>({...t,type:this.process(t.type)}))}:e}},h=class{constructor(e=!0){this.markOptional=e}process(e,t){if(!this.markOptional)return t;if(t.kind==="array"&&Array.isArray(e)){let r=t.elementType;if(r.kind==="object"){let i=this.processArrayObjects(e,r);return{...t,elementType:i}}}return t}processArrayObjects(e,t){if(e.length<=1)return t;let r={},i=e.length;for(let o of e)if(o&&typeof o=="object")for(let s of Object.keys(o))r[s]=(r[s]||0)+1;return{...t,properties:t.properties.map(o=>{let a=(r[o.name]||0)<i;return{...o,optional:a}})}}};function S(n,e,t){let r=e;return t.markOptional&&(r=new h(t.markOptional).process(n,r)),t.extractGenerics&&(r=new T().extract(r)),r=new g(t.strictNullChecks).process(r),r}function v(n,e={}){let t={...P,...e},r=c(n);r=S(n,r,t);let i=new l({namingStyle:t.namingStyle,prefix:t.typePrefix,suffix:t.typeSuffix,customNameMap:t.typeNameMap}),s=new f(i).collect(r,t.rootName);return new y(t,i).generateOutput(s,t.rootName)}function A(n,e={}){let t=JSON.parse(n);return v(t,e)}var L={generate:v,generateFromString:A};0&&(module.exports={CodeFormatter,GenericExtractor,NullHandler,OptionalHandler,TypeCollector,TypeNamer,applyEnhancements,createUnion,generate,generateFromString,inferArrayType,inferObjectType,inferType,isStructurallyEqual,mergeObjects,mergeTypes});
|
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
var
|
|
2
|
-
`,typeNameMap:{},typePrefix:"",typeSuffix:""};function
|
|
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?"?":""
|
|
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))}
|
|
5
|
-
`);return t.length===1?`/** ${e} */`:["/**",...t.map(r=>` * ${r}`)," */"].join(`
|
|
6
|
-
`)}formatAll(e){return this.allNamedTypes=e,e.map(t=>this.formatTypeDef(t)).join(`
|
|
1
|
+
var k={rootName:"Root",outputStyle:"interface",namingStyle:"PascalCase",sortProperties:"alpha",addExport:!0,strictNullChecks:!1,markOptional:!0,extractGenerics:!0,indentSize:2,lineEnding:`
|
|
2
|
+
`,typeNameMap:{},typePrefix:"",typeSuffix:""};function c(n){return{kind:"primitive",type:n}}function A(){return{kind:"null"}}function w(){return{kind:"undefined"}}function C(n){return{kind:"array",elementType:n}}function b(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 d(n,e){return p(n)===p(e)?n:n.kind==="object"&&e.kind==="object"?j(n,e):n.kind==="array"&&e.kind==="array"?C(d(n.elementType,e.elementType)):x([n,e])}function j(n,e){let t=new Map;for(let r of n.properties)t.set(r.name,{...r});for(let r of e.properties){let i=t.get(r.name);i?(i.type=d(i.type,r.type),i.optional=i.optional||r.optional):t.set(r.name,{...r,optional:!0})}for(let[r,i]of t)e.properties.some(s=>s.name===r)||(i.optional=!0);return b(Array.from(t.values()))}function l(n){return n===null?A():n===void 0?w():typeof n=="function"?c("function"):typeof n=="string"?c("string"):typeof n=="number"?c("number"):typeof n=="boolean"?c("boolean"):Array.isArray(n)?O(n):typeof n=="object"?v(n):c("unknown")}function O(n){if(n.length===0)return{kind:"array",elementType:{kind:"primitive",type:"any"}};let e=n.map(r=>l(r)),t=e[0];for(let r=1;r<e.length;r++)t=d(t,e[r]);return{kind:"array",elementType:t}}function v(n){let e=[];for(let[t,r]of Object.entries(n)){let i=l(r);e.push({name:t,type:i,optional:!1})}return b(e)}function N(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.formatName(o),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 m=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(N(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=[];return this.options.outputStyle==="interface"?a.push(`${r}interface ${e} {`):a.push(`${r}type ${e} = {`),this.options.outputStyle==="interface"?a.push("}"):a.push("};"),a.join(`
|
|
3
|
+
`)}formatType(e){if(e.kind==="object"){let t=this.findTypeName(e);if(t)return t}switch(e.kind){case"primitive":return e.type;case"null":return"null";case"undefined":return"undefined";case"array":return this.formatArrayType(e);case"object":return this.formatInlineObject(e);case"union":return this.formatUnionType(e.types);case"literal":return this.formatLiteral(e.value);case"generic":return`${e.name}<${e.typeArgs.map(t=>this.formatType(t)).join(", ")}>`;default:return"unknown"}}formatLiteral(e){return typeof e=="string"?`'${e}'`:String(e)}formatArrayType(e){let t=this.formatType(e.elementType);return e.elementType.kind==="union"?`(${t})[]`:`${t}[]`}formatInlineObject(e){let t=" ".repeat(this.options.indentSize),r=this.sortProperties(e.properties);if(r.length===0)return"{}";let i=["{"];for(let o of r){let s=this.formatPropertyName(o.name),a=o.optional?"?":"",$=this.formatType(o.type);i.push(`${t}${s}${a}: ${$};`)}return i.push("}"),i.join(`
|
|
4
|
+
`)}formatUnionType(e){return e.map(t=>this.formatType(t)).join(" | ")}formatPropertyName(e){return/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(e)?e:`'${e}'`}sortProperties(e){return this.options.sortProperties==="definition"?[...e]:[...e].sort((t,r)=>t.name.localeCompare(r.name))}formatAll(e){return this.allNamedTypes=e,e.map(t=>this.formatTypeDef(t)).join(`
|
|
7
5
|
|
|
8
6
|
`)}generateOutput(e,t){let r=`/**
|
|
9
7
|
* Generated by type-flash
|
|
@@ -11,4 +9,4 @@ var x={rootName:"Root",outputStyle:"interface",namingStyle:"PascalCase",sortProp
|
|
|
11
9
|
*/`,i=this.formatAll(e);return`${r}
|
|
12
10
|
|
|
13
11
|
${i}
|
|
14
|
-
`}};
|
|
12
|
+
`}};var T=class{constructor(){this.patterns=[{name:"PageResult",arrayFields:["list","records","rows","items"],countFields:["total","count","totalCount"]},{name:"ListResult",arrayFields:["list","data","items"],countFields:[]},{name:"ApiResponse",arrayFields:["data"],countFields:[]}]}extract(e){if(e.kind!=="object")return e;for(let t of this.patterns){let r=this.tryMatchPattern(e,t);if(r)return r}return e}tryMatchPattern(e,t){let r=null,i=t.countFields.length===0;for(let o of e.properties)t.arrayFields.includes(o.name)&&o.type.kind==="array"&&(r={name:o.name,elementType:o.type.elementType}),t.countFields.includes(o.name)&&(i=!0);return r&&i?{kind:"generic",name:t.name,typeArgs:[r.elementType]}:null}},g=class{constructor(e=!1){this.strict=e}process(e){if(this.strict)return e;if(e.kind==="union"){let t=e.types.filter(r=>r.kind!=="null");return t.length===0?{kind:"null"}:t.length===1?t[0]:{...e,types:t}}return e.kind==="array"?{...e,elementType:this.process(e.elementType)}:e.kind==="object"?{...e,properties:e.properties.map(t=>({...t,type:this.process(t.type)}))}:e}},h=class{constructor(e=!0){this.markOptional=e}process(e,t){if(!this.markOptional)return t;if(t.kind==="array"&&Array.isArray(e)){let r=t.elementType;if(r.kind==="object"){let i=this.processArrayObjects(e,r);return{...t,elementType:i}}}return t}processArrayObjects(e,t){if(e.length<=1)return t;let r={},i=e.length;for(let o of e)if(o&&typeof o=="object")for(let s of Object.keys(o))r[s]=(r[s]||0)+1;return{...t,properties:t.properties.map(o=>{let a=(r[o.name]||0)<i;return{...o,optional:a}})}}};function S(n,e,t){let r=e;return t.markOptional&&(r=new h(t.markOptional).process(n,r)),t.extractGenerics&&(r=new T().extract(r)),r=new g(t.strictNullChecks).process(r),r}function P(n,e={}){let t={...k,...e},r=l(n);r=S(n,r,t);let i=new f({namingStyle:t.namingStyle,prefix:t.typePrefix,suffix:t.typeSuffix,customNameMap:t.typeNameMap}),s=new y(i).collect(r,t.rootName);return new m(t,i).generateOutput(s,t.rootName)}function D(n,e={}){let t=JSON.parse(n);return P(t,e)}var H={generate:P,generateFromString:D};export{m as CodeFormatter,T as GenericExtractor,g as NullHandler,h as OptionalHandler,y as TypeCollector,f as TypeNamer,S as applyEnhancements,x as createUnion,H as default,P as generate,D as generateFromString,O as inferArrayType,v as inferObjectType,l as inferType,N as isStructurallyEqual,j as mergeObjects,d as mergeTypes};
|