json-convert-ts
Advanced tools
Comparing version 0.0.2 to 0.0.3
@@ -1,326 +0,315 @@ | ||
(function (factory) { | ||
typeof define === 'function' && define.amd ? define(factory) : | ||
factory(); | ||
}((function () { 'use strict'; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.json2ts = exports.parser = exports.formatter = void 0; | ||
const space = (size) => ' '.repeat(size); | ||
const linebreak = '\n'; | ||
const ArrayType = 'A'; | ||
const ObjectType = 'T'; | ||
// (number | string | number[] | (number | string)[])[] | ||
function getArrayTypeList(identifier) { | ||
if (identifier === undefined) { | ||
throw new Error('undefined'); | ||
} | ||
const types = []; | ||
const iterate = (nodes) => { | ||
nodes.forEach(node => { | ||
if (node.type === 'array') { | ||
types.push(getArrayTypeList(node.identifier)); | ||
} | ||
else { | ||
types.push(node.type); | ||
} | ||
}); | ||
}; | ||
iterate(identifier); | ||
if (types.length > 1) { | ||
return `(${types.join(' | ')})[]`; | ||
} | ||
else if (types.length == 1) { | ||
return `${types[0]}[]`; | ||
} | ||
else { | ||
return `any[]`; | ||
} | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.json2ts = exports.parser = exports.formatter = void 0; | ||
const space = (size) => ' '.repeat(size); | ||
const linebreak = '\n'; | ||
const ArrayType = 'A'; | ||
const ObjectType = 'T'; | ||
// (number | string | number[] | (number | string)[])[] | ||
function getArrayTypeList(identifier) { | ||
if (identifier === undefined) { | ||
throw new Error('undefined'); | ||
} | ||
function getMixedTypeList(identifier) { | ||
if (identifier === undefined) { | ||
throw new Error('undefined'); | ||
} | ||
const types = []; | ||
identifier.forEach(id => { | ||
if (id.type === 'array') { | ||
types.push(getArrayTypeList(id.identifier)); | ||
const types = []; | ||
const iterate = (nodes) => { | ||
nodes.forEach(node => { | ||
if (node.type === 'array') { | ||
types.push(getArrayTypeList(node.identifier)); | ||
} | ||
else if (id.type === 'mixed') { | ||
types.push(getMixedTypeList(id.identifier)); | ||
} | ||
else { | ||
types.push(id.type); | ||
types.push(node.type); | ||
} | ||
}); | ||
return types.join(' | '); | ||
}; | ||
iterate(identifier); | ||
if (types.length > 1) { | ||
return `(${types.join(' | ')})[]`; | ||
} | ||
function getNodeByIndex(map, index) { | ||
return map.get([...map.keys()][index]); | ||
else if (types.length == 1) { | ||
return `${types[0]}[]`; | ||
} | ||
function getObjectKeyName(line) { | ||
return `${line.key}${line.optional ? '?' : ''}: `; | ||
else { | ||
return `any[]`; | ||
} | ||
function isArray(value) { | ||
return Array.isArray(value); | ||
} | ||
function getMixedTypeList(identifier) { | ||
if (identifier === undefined) { | ||
throw new Error('undefined'); | ||
} | ||
function isObject(value) { | ||
return !isArray(value) && typeof value === 'object'; | ||
} | ||
function getType(value) { | ||
if (isObject(value)) { | ||
return 'object'; | ||
const types = []; | ||
identifier.forEach(id => { | ||
if (id.type === 'array') { | ||
types.push(getArrayTypeList(id.identifier)); | ||
} | ||
else if (isArray(value)) { | ||
return 'array'; | ||
else if (id.type === 'mixed') { | ||
types.push(getMixedTypeList(id.identifier)); | ||
} | ||
else { | ||
return typeof value; | ||
types.push(id.type); | ||
} | ||
}); | ||
return types.join(' | '); | ||
} | ||
function getNodeByIndex(map, index) { | ||
return map.get([...map.keys()][index]); | ||
} | ||
function getObjectKeyName(line) { | ||
return `${line.key}${line.optional ? '?' : ''}: `; | ||
} | ||
function isArray(value) { | ||
return Array.isArray(value); | ||
} | ||
function isObject(value) { | ||
return !isArray(value) && typeof value === 'object'; | ||
} | ||
function getType(value) { | ||
if (isObject(value)) { | ||
return 'object'; | ||
} | ||
function getKey(map, key) { | ||
key = key[0].toUpperCase() + key.slice(1); | ||
if (map.get(key) === undefined) { | ||
return key; | ||
else if (isArray(value)) { | ||
return 'array'; | ||
} | ||
else { | ||
return typeof value; | ||
} | ||
} | ||
function getKey(map, key) { | ||
key = key[0].toUpperCase() + key.slice(1); | ||
if (map.get(key) === undefined) { | ||
return key; | ||
} | ||
let index = 1; | ||
let res = key + `_${index}`; | ||
while (map.get(res) !== undefined) { | ||
index++; | ||
res = key + `_${index}`; | ||
} | ||
return res; | ||
} | ||
function formatter(map) { | ||
let text = ``; | ||
for (const [name, node] of map.entries()) { | ||
debugger; | ||
if (node.type === 'array') { | ||
text += `type ${name} = ${getArrayTypeList(node.identifier)};`; | ||
text += linebreak; | ||
} | ||
let index = 1; | ||
let res = key + `_${index}`; | ||
while (map.get(res) !== undefined) { | ||
index++; | ||
res = key + `_${index}`; | ||
else if (node.type === 'object') { | ||
text += `interface ${name} {` + linebreak; | ||
node.identifier?.forEach(line => { | ||
if (line.type === 'array') { | ||
text += space(4) + `${getObjectKeyName(line)}${getArrayTypeList(line.identifier)};` + linebreak; | ||
} | ||
else if (line.type === 'mixed') { | ||
text += space(4) + `${getObjectKeyName(line)}${getMixedTypeList(line.identifier)};` + linebreak; | ||
} | ||
else { | ||
text += space(4) + `${getObjectKeyName(line)}${line.type};` + linebreak; | ||
} | ||
}); | ||
text += `}`; | ||
text += linebreak; | ||
} | ||
return res; | ||
else { | ||
throw new Error('never'); | ||
} | ||
text += linebreak; | ||
} | ||
function formatter(map) { | ||
let text = ``; | ||
for (const [name, node] of map.entries()) { | ||
debugger; | ||
if (node.type === 'array') { | ||
text += `type ${name} = ${getArrayTypeList(node.identifier)};`; | ||
text += linebreak; | ||
} | ||
else if (node.type === 'object') { | ||
text += `interface ${name} {` + linebreak; | ||
node.identifier?.forEach(line => { | ||
if (line.type === 'array') { | ||
text += space(4) + `${getObjectKeyName(line)}${getArrayTypeList(line.identifier)};` + linebreak; | ||
if (text.endsWith('\n\n')) { | ||
text = text.slice(0, -1); | ||
} | ||
return text; | ||
} | ||
exports.formatter = formatter; | ||
function parser(data) { | ||
const map = new Map(); | ||
if (isArray(data)) { | ||
map.set(ArrayType, { | ||
type: 'array', | ||
identifier: data.length > 0 ? [] : undefined, | ||
values: [...data], | ||
}); | ||
} | ||
else if (isObject(data)) { | ||
map.set('Root', { | ||
type: 'object', | ||
identifier: Object.keys(data).length > 0 ? [] : undefined, | ||
values: [data], | ||
}); | ||
} | ||
const status = { count: 1, index: 0 }; | ||
while (status.index < map.size) { | ||
const node = getNodeByIndex(map, status.index); | ||
if (node.type === 'array') { | ||
const objects = node.values.filter(t => isObject(t)); | ||
const arrays = node.values.filter(t => isArray(t)); | ||
const primitives = node.values.filter(t => !isArray(t) && !isObject(t)); | ||
if (primitives.length > 0) { | ||
primitives.forEach(item => { | ||
const find = node.identifier?.find(t => t.type === getType(item)); | ||
if (find) { | ||
if (!find.values.includes(item)) { | ||
find.values.push(item); | ||
} | ||
} | ||
else if (line.type === 'mixed') { | ||
text += space(4) + `${getObjectKeyName(line)}${getMixedTypeList(line.identifier)};` + linebreak; | ||
} | ||
else { | ||
text += space(4) + `${getObjectKeyName(line)}${line.type};` + linebreak; | ||
node.identifier?.push({ type: getType(item), values: [item] }); | ||
} | ||
}); | ||
text += `}`; | ||
text += linebreak; | ||
} | ||
else { | ||
throw new Error('never'); | ||
if (objects.length > 0) { | ||
// merge object | ||
const type = getKey(map, ObjectType); | ||
node.identifier?.push({ type, values: [...objects] }); | ||
map.set(type, { type: 'object', values: [...objects], identifier: [] }); | ||
} | ||
text += linebreak; | ||
} | ||
if (text.endsWith('\n\n')) { | ||
text = text.slice(0, -1); | ||
} | ||
return text; | ||
} | ||
exports.formatter = formatter; | ||
function parser(data) { | ||
const map = new Map(); | ||
if (isArray(data)) { | ||
map.set(ArrayType, { | ||
type: 'array', | ||
identifier: data.length > 0 ? [] : undefined, | ||
values: [...data], | ||
}); | ||
} | ||
else if (isObject(data)) { | ||
map.set('Root', { | ||
type: 'object', | ||
identifier: Object.keys(data).length > 0 ? [] : undefined, | ||
values: [data], | ||
}); | ||
} | ||
const status = { count: 1, index: 0 }; | ||
while (status.index < map.size) { | ||
const node = getNodeByIndex(map, status.index); | ||
if (node.type === 'array') { | ||
const objects = node.values.filter(t => isObject(t)); | ||
const arrays = node.values.filter(t => isArray(t)); | ||
const primitives = node.values.filter(t => !isArray(t) && !isObject(t)); | ||
if (primitives.length > 0) { | ||
primitives.forEach(item => { | ||
const find = node.identifier?.find(t => t.type === getType(item)); | ||
if (find) { | ||
if (!find.values.includes(item)) { | ||
find.values.push(item); | ||
} | ||
if (arrays.length > 0) { | ||
// merge array | ||
const values = []; | ||
arrays.forEach(item => { | ||
item.forEach((value) => { | ||
if (!values.includes(value)) { | ||
values.push(value); | ||
} | ||
else { | ||
node.identifier?.push({ type: getType(item), values: [item] }); | ||
} | ||
}); | ||
} | ||
if (objects.length > 0) { | ||
// merge object | ||
const type = getKey(map, ObjectType); | ||
node.identifier?.push({ type, values: [...objects] }); | ||
map.set(type, { type: 'object', values: [...objects], identifier: [] }); | ||
} | ||
if (arrays.length > 0) { | ||
// merge array | ||
const values = []; | ||
arrays.forEach(item => { | ||
item.forEach((value) => { | ||
if (!values.includes(value)) { | ||
values.push(value); | ||
} | ||
}); | ||
}); | ||
const type = getKey(map, ArrayType); | ||
node.identifier?.push({ type, values: arrays }); | ||
map.set(type, { type: 'array', values, identifier: [] }); | ||
} | ||
}); | ||
const type = getKey(map, ArrayType); | ||
node.identifier?.push({ type, values: arrays }); | ||
map.set(type, { type: 'array', values, identifier: [] }); | ||
} | ||
else if (node.type === 'object') { | ||
// 合并数组中的对象类型 [{a:1},{b:2}] | ||
if (node.values.length >= 2) { | ||
node.values.forEach(item => { | ||
Object.keys(item).forEach(key => { | ||
const value = item[key]; | ||
const type = getType(value); | ||
const sameKey = node.identifier?.find(t => t.key === key); | ||
if (sameKey) { | ||
if (sameKey.type === 'mixed') { | ||
const sameType = sameKey.identifier?.find(t => t.type === type); | ||
if (sameType) { | ||
sameType.values.push(value); | ||
} | ||
else { | ||
sameKey.identifier?.push({ type, values: [value] }); | ||
} | ||
} | ||
else if (node.type === 'object') { | ||
// 合并数组中的对象类型 [{a:1},{b:2}] | ||
if (node.values.length >= 2) { | ||
node.values.forEach(item => { | ||
Object.keys(item).forEach(key => { | ||
const value = item[key]; | ||
const type = getType(value); | ||
const sameKey = node.identifier?.find(t => t.key === key); | ||
if (sameKey) { | ||
if (sameKey.type === 'mixed') { | ||
const sameType = sameKey.identifier?.find(t => t.type === type); | ||
if (sameType) { | ||
sameType.values.push(value); | ||
} | ||
else if (sameKey.values.some(t => getType(t) !== type)) { | ||
if (!sameKey.identifier) { | ||
sameKey.identifier = [{ type: sameKey.type, values: sameKey.values }]; | ||
} | ||
const sameType = sameKey.identifier?.find(t => t.type === type); | ||
if (sameType) { | ||
sameType.values.push(value); | ||
} | ||
else { | ||
sameKey.identifier?.push({ type, values: [value] }); | ||
} | ||
sameKey.type = 'mixed'; | ||
else { | ||
sameKey.identifier?.push({ type, values: [value] }); | ||
} | ||
else if (sameKey.values.every(t => getType(t) === type)) { | ||
if (!sameKey.values.includes(value)) { | ||
sameKey.values.push(value); | ||
} | ||
} | ||
else if (sameKey.values.some(t => getType(t) !== type)) { | ||
if (!sameKey.identifier) { | ||
sameKey.identifier = [{ type: sameKey.type, values: sameKey.values }]; | ||
} | ||
const sameType = sameKey.identifier?.find(t => t.type === type); | ||
if (sameType) { | ||
sameType.values.push(value); | ||
} | ||
else { | ||
throw new Error('never'); | ||
sameKey.identifier?.push({ type, values: [value] }); | ||
} | ||
sameKey.type = 'mixed'; | ||
} | ||
else if (sameKey.values.every(t => getType(t) === type)) { | ||
if (!sameKey.values.includes(value)) { | ||
sameKey.values.push(value); | ||
} | ||
} | ||
else { | ||
node.identifier?.push({ key, type, values: [value] }); | ||
throw new Error('never'); | ||
} | ||
}); | ||
} | ||
else { | ||
node.identifier?.push({ key, type, values: [value] }); | ||
} | ||
}); | ||
} | ||
else { | ||
node.values.forEach(item => { | ||
Object.keys(item).forEach(key => { | ||
const value = item[key]; | ||
const type = getType(value); | ||
if (type === 'array') { | ||
}); | ||
} | ||
else { | ||
node.values.forEach(item => { | ||
Object.keys(item).forEach(key => { | ||
const value = item[key]; | ||
const type = getType(value); | ||
if (type === 'array') { | ||
// const type = `T_${status.count++}`; | ||
const type = getKey(map, key); | ||
node.identifier?.push({ key, type, values: [value] }); | ||
map.set(type, { type: 'array', values: [...value], identifier: [] }); | ||
} | ||
else if (type === 'object') { | ||
// const type = `T_${status.count++}`; | ||
const type = getKey(map, key); | ||
node.identifier?.push({ key, type, values: [value] }); | ||
map.set(type, { type: 'object', values: [value], identifier: [] }); | ||
} | ||
else { | ||
node.identifier?.push({ key, type, values: [value] }); | ||
} | ||
}); | ||
}); | ||
} | ||
if (node.identifier?.some(t => t.key)) { | ||
node.identifier?.sort((a, b) => ((a.key || '') > (b.key || '') ? 1 : -1)); | ||
node.identifier?.forEach(item => { | ||
if (item.type === 'mixed') { | ||
item.identifier?.forEach(id => { | ||
if (id.type === 'object') { | ||
// const type = `T_${status.count++}`; | ||
const type = getKey(map, key); | ||
node.identifier?.push({ key, type, values: [value] }); | ||
map.set(type, { type: 'array', values: [...value], identifier: [] }); | ||
const type = getKey(map, item.key); | ||
id.type = type; | ||
map.set(type, { type: 'object', values: [...id.values], identifier: [] }); | ||
} | ||
else if (type === 'object') { | ||
else if (id.type === 'array') { | ||
const values = []; | ||
id.values.forEach(t => { | ||
t.forEach((value) => { | ||
if (!values.includes(value)) { | ||
values.push(value); | ||
} | ||
}); | ||
}); | ||
// const type = `T_${status.count++}`; | ||
const type = getKey(map, key); | ||
node.identifier?.push({ key, type, values: [value] }); | ||
map.set(type, { type: 'object', values: [value], identifier: [] }); | ||
const type = getKey(map, item.key); | ||
id.type = type; | ||
map.set(type, { type: 'array', values, identifier: [] }); | ||
} | ||
else { | ||
node.identifier?.push({ key, type, values: [value] }); | ||
} | ||
}); | ||
} | ||
}); | ||
// #region 判断是否optional | ||
const count = {}; | ||
node.values.forEach(item => { | ||
Object.keys(item).forEach(key => { | ||
count[key] = (count[key] || 0) + 1; | ||
}); | ||
} | ||
if (node.identifier?.some(t => t.key)) { | ||
node.identifier?.sort((a, b) => ((a.key || '') > (b.key || '') ? 1 : -1)); | ||
node.identifier?.forEach(item => { | ||
if (item.type === 'mixed') { | ||
item.identifier?.forEach(id => { | ||
if (id.type === 'object') { | ||
// const type = `T_${status.count++}`; | ||
const type = getKey(map, item.key); | ||
id.type = type; | ||
map.set(type, { type: 'object', values: [...id.values], identifier: [] }); | ||
} | ||
else if (id.type === 'array') { | ||
const values = []; | ||
id.values.forEach(t => { | ||
t.forEach((value) => { | ||
if (!values.includes(value)) { | ||
values.push(value); | ||
} | ||
}); | ||
}); | ||
// const type = `T_${status.count++}`; | ||
const type = getKey(map, item.key); | ||
id.type = type; | ||
map.set(type, { type: 'array', values, identifier: [] }); | ||
} | ||
}); | ||
}); | ||
Object.keys(count).forEach(key => { | ||
if (count[key] !== node.values.length) { | ||
const find = node.identifier?.find(t => t.key === key); | ||
if (find) { | ||
find.optional = true; | ||
} | ||
}); | ||
// #region 判断是否optional | ||
const count = {}; | ||
node.values.forEach(item => { | ||
Object.keys(item).forEach(key => { | ||
count[key] = (count[key] || 0) + 1; | ||
}); | ||
}); | ||
Object.keys(count).forEach(key => { | ||
if (count[key] !== node.values.length) { | ||
const find = node.identifier?.find(t => t.key === key); | ||
if (find) { | ||
find.optional = true; | ||
} | ||
} | ||
}); | ||
// #endregion | ||
} | ||
} | ||
}); | ||
// #endregion | ||
} | ||
else { | ||
throw new Error('never'); | ||
} | ||
status.index++; | ||
} | ||
return map; | ||
else { | ||
throw new Error('never'); | ||
} | ||
status.index++; | ||
} | ||
exports.parser = parser; | ||
function json2ts(text) { | ||
if (!text) | ||
return ''; | ||
const json = JSON.parse(text); | ||
const map = parser(json); | ||
debugger; | ||
const res = formatter(map); | ||
return res; | ||
} | ||
exports.json2ts = json2ts; | ||
// import { case_1, case_3, case_4, case_2, case_5 } from '../test/cases'; | ||
// import { toMap } from '../test/tools'; | ||
// let map: json2ts.Map2; | ||
// map = parser(case_5); | ||
// console.dir(map, { depth: null }); | ||
// console.log(formatter(map)); | ||
// console.log(toMap(map)); | ||
}))); | ||
return map; | ||
} | ||
exports.parser = parser; | ||
function json2ts(json) { | ||
const map = parser(json); | ||
const res = formatter(map); | ||
return res; | ||
} | ||
exports.json2ts = json2ts; | ||
// import { case_1, case_3, case_4, case_2, case_5 } from '../test/cases'; | ||
// import { toMap } from '../test/tools'; | ||
// let map: json2ts.Map2; | ||
// map = parser(case_5); | ||
// console.dir(map, { depth: null }); | ||
// console.log(formatter(map)); | ||
// console.log(toMap(map)); |
{ | ||
"name": "json-convert-ts", | ||
"version": "0.0.2", | ||
"version": "0.0.3", | ||
"description": "将json转换typescript类型定义。", | ||
@@ -32,2 +32,3 @@ "keywords": [], | ||
"devDependencies": { | ||
"@rollup/plugin-typescript": "^8.1.0", | ||
"@types/jest": "^25.2.3", | ||
@@ -34,0 +35,0 @@ "@types/node": "^14.14.12", |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
0
32440
8
874