json-editor-parser.ts 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import { FlowElement } from "react-flow-renderer";
  2. export const parser = (input: string | string[]): FlowElement[] => {
  3. try {
  4. if (typeof input !== "object") input = JSON.parse(input);
  5. if (!Array.isArray(input)) input = [input];
  6. const extract = (
  7. os: string[] | object[] | null,
  8. nextId = (
  9. (id) => () =>
  10. String(++id)
  11. )(0)
  12. ) => {
  13. if (!os) return [];
  14. return [os].flat().map((o) => ({
  15. id: nextId(),
  16. data: {
  17. label: Object.fromEntries(
  18. Object.entries(o).filter(
  19. ([k, v]) => !Array.isArray(v) && !(v instanceof Object)
  20. )
  21. ),
  22. },
  23. position: { x: 0, y: 0 },
  24. type: "special",
  25. children: Object.entries(o)
  26. .filter(([k, v]) => Array.isArray(v) || typeof v === "object")
  27. .flatMap(([k, v]) => [
  28. {
  29. id: nextId(),
  30. data: { label: k },
  31. position: { x: 0, y: 0 },
  32. children: extract(v, nextId),
  33. type: "special",
  34. },
  35. ]),
  36. }));
  37. };
  38. const relationships = (xs: { id: string; children: never[] }[]) => {
  39. return xs.flatMap(({ id: target, children = [] }) => [
  40. ...children.map(({ id: source }) => ({
  41. id: `e${source}-${target}`,
  42. source,
  43. target,
  44. })),
  45. ...relationships(children),
  46. ]);
  47. };
  48. const flatten = (xs: { id: string; children: never[] }[]) =>
  49. xs.flatMap(({ children, ...rest }) => [rest, ...flatten(children)]);
  50. const res = extract(input);
  51. return [...flatten(res), ...relationships(res)];
  52. } catch (error) {
  53. console.error("An error occured while parsin JSON data!");
  54. return [];
  55. }
  56. };