UNPKG

@hacxy/json2ts

Version:

Json to typescript types generator

96 lines (93 loc) 3.13 kB
import { jsonInputForTargetLanguage as S, InputData as w, quicktype as C } from "quicktype-core"; import s from "typescript"; function I(u) { const r = s.createSourceFile("virtual.ts", u, s.ScriptTarget.Latest, !0), g = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Set(), l = /* @__PURE__ */ new Map(); s.forEachChild(r, (e) => { if (s.isTypeAliasDeclaration(e) || s.isInterfaceDeclaration(e)) { const i = e.name.getText(r); c.add(i), g.set(i, e), l.set(i, e.getFullText(r).trim()); } }), s.forEachChild(r, (e) => { if (s.isTypeAliasDeclaration(e) || s.isInterfaceDeclaration(e)) { const i = e.name.getText(r), n = /* @__PURE__ */ new Set(), a = (t) => { if (s.isTypeReferenceNode(t)) { const y = t.typeName.getText(r); c.has(y) && y !== i && n.add(y); } else s.isArrayTypeNode(t) ? a(t.elementType) : s.isUnionTypeNode(t) || s.isIntersectionTypeNode(t) ? t.types.forEach(a) : (s.isPropertySignature(t) && t.type || s.isMethodSignature(t) && t.type || s.isIndexSignatureDeclaration(t) && t.type) && a(t.type); s.forEachChild(t, a); }; s.isTypeAliasDeclaration(e) && e.type && a(e.type), s.isInterfaceDeclaration(e) && e.members.forEach((t) => { a(t); }), s.isInterfaceDeclaration(e) && e.heritageClauses && e.heritageClauses.forEach((t) => { t.types.forEach((y) => { const x = y.expression.getText(r); c.has(x) && x !== i && n.add(x); }); }), f.set(i, Array.from(n)); } }); const o = [], d = /* @__PURE__ */ new Map(), p = /* @__PURE__ */ new Set(), h = [], T = (e, i = []) => { if (d.has(e)) return; if (p.has(e)) { const t = i.indexOf(e); t !== -1 && h.push(i.slice(t)); return; } p.add(e); const n = [...i, e], a = f.get(e) || []; for (const t of a) T(t, n); p.delete(e), d.set(e, !0), o.push(e); }; f.forEach((e, i) => { d.has(i) || T(i); }), h.forEach((e) => { const i = o.findIndex((n) => e.includes(n)); i !== -1 && (e.forEach((n) => { const a = o.indexOf(n); a !== -1 && o.splice(a, 1); }), o.splice(i, 0, ...e)); }); const E = []; return s.forEachChild(r, (e) => { !s.isTypeAliasDeclaration(e) && !s.isInterfaceDeclaration(e) && E.push(e.getFullText(r)); }), { sortedCode: `${o.map((e) => l.get(e)).filter(Boolean).join(` `)} ${E.join("")}`, sortedTypes: o }; } async function $(u, r = "Root", g = {}) { const { indentation: f = 2 } = g; let c = !1; try { c = Array.isArray(JSON.parse(u)); } catch (T) { throw new Error(String(T)); } const l = S("typescript"); await l.addSource({ name: c ? `${r}Element` : r, samples: [u] }); const o = new w(); o.addInput(l); const { lines: d } = await C({ inputData: o, lang: "typescript", rendererOptions: { "just-types": !0 }, indentation: " ".repeat(f) }); let p = d.join(` `); c && (p = `${p} export type ${r} = ${r}Element[];`); const { sortedCode: h } = I(p); return h.trim(); } export { $ as default };