json-editor-parser.ts 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import toast from "react-hot-toast";
  2. export const parser = (input: string | string[]) => {
  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. const isObject = o instanceof Object;
  16. return {
  17. id: nextId(),
  18. text: !isObject
  19. ? o.toString()
  20. : Object.fromEntries(
  21. Object.entries(o).filter(
  22. ([k, v]) => !Array.isArray(v) && !(v instanceof Object)
  23. )
  24. ),
  25. parent: false,
  26. children: Object.entries(o)
  27. .filter(([k, v]) => Array.isArray(v) || typeof v === "object")
  28. .flatMap(([k, v]) => [
  29. {
  30. id: nextId(),
  31. text: k,
  32. parent: true,
  33. children: extract(v, nextId),
  34. },
  35. ]),
  36. };
  37. });
  38. };
  39. const relationships = (xs: { id: string; children: never[] }[]) => {
  40. return xs.flatMap(({ id: to, children = [] }) => [
  41. ...children.map(({ id: from }) => ({
  42. id: `e${from}-${to}`,
  43. from,
  44. to,
  45. })),
  46. ...relationships(children),
  47. ]);
  48. };
  49. const flatten = (xs: { id: string; children: never[] }[]) =>
  50. xs.flatMap(({ children, ...rest }) => [rest, ...flatten(children)]);
  51. const res = extract(input);
  52. return [...flatten(res), ...relationships(res)];
  53. } catch (error) {
  54. toast.error("An error occured while parsing JSON data!");
  55. return [];
  56. }
  57. };