type-flash 1.0.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/LICENSE +21 -0
- package/README.md +358 -0
- package/bin/type-gen.js +302 -0
- package/dist/index.d.mts +626 -0
- package/dist/index.d.ts +626 -0
- package/dist/index.js +6 -0
- package/dist/index.mjs +6 -0
- package/package.json +59 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
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};
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "type-flash",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "JSON 智能生成 TypeScript 类型定义 - 一键从 JSON 数据生成 Interface / Type 定义",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.esm.js",
|
|
7
|
+
"types": "dist/types/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"type-flash": "bin/type-flash.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"bin"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsup src/index.ts --format cjs,esm --dts --clean --minify",
|
|
17
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
18
|
+
"lint": "eslint src --ext .ts",
|
|
19
|
+
"lint:fix": "eslint src --ext .ts --fix",
|
|
20
|
+
"prepublishOnly": "npm run build",
|
|
21
|
+
"release": "npm run build && npm publish",
|
|
22
|
+
"release:patch": "npm version patch && npm run release",
|
|
23
|
+
"release:minor": "npm version minor && npm run release",
|
|
24
|
+
"release:major": "npm version major && npm run release"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"typescript",
|
|
28
|
+
"json",
|
|
29
|
+
"type-flasherator",
|
|
30
|
+
"interface",
|
|
31
|
+
"type-definition",
|
|
32
|
+
"code-generation",
|
|
33
|
+
"ts",
|
|
34
|
+
"json-to-ts",
|
|
35
|
+
"type-inference",
|
|
36
|
+
"developer-tools"
|
|
37
|
+
],
|
|
38
|
+
"author": "lebron_shi",
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">=14.0.0"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "^20.0.0",
|
|
45
|
+
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
|
46
|
+
"@typescript-eslint/parser": "^6.0.0",
|
|
47
|
+
"eslint": "^8.0.0",
|
|
48
|
+
"tsup": "^8.5.1",
|
|
49
|
+
"typescript": "^5.0.0"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"typescript": ">=4.0.0"
|
|
53
|
+
},
|
|
54
|
+
"peerDependenciesMeta": {
|
|
55
|
+
"typescript": {
|
|
56
|
+
"optional": true
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|