json-editor-parser.ts 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /**
  2. * Copyright (C) 2022 Aykut Saraç - All Rights Reserved
  3. */
  4. import toast from "react-hot-toast";
  5. const filterChild = ([k, v]) => {
  6. const isNull = v === null;
  7. const isArray = Array.isArray(v) && v.length;
  8. const isObject = v instanceof Object;
  9. return !isNull && (isArray || isObject);
  10. };
  11. const filterValues = ([k, v]) => {
  12. if (Array.isArray(v) || v instanceof Object) return false;
  13. return true;
  14. };
  15. function generateChildren(object: Object, nextId: () => string) {
  16. if (!(object instanceof Object)) object = [object];
  17. return Object.entries(object)
  18. .filter(filterChild)
  19. .flatMap(([k, v]) => {
  20. // const isObject = v instanceof Object && !Array.isArray(v);
  21. // if (isObject) {
  22. // return [
  23. // {
  24. // id: nextId(),
  25. // text: k,
  26. // parent: true,
  27. // children: generateChildren(v, nextId),
  28. // },
  29. // ];
  30. // }
  31. return [
  32. {
  33. id: nextId(),
  34. text: k,
  35. parent: true,
  36. children: extract(v, nextId),
  37. },
  38. ];
  39. });
  40. }
  41. function generateNodeData(object: Object | number) {
  42. const isObject = object instanceof Object;
  43. if (isObject) {
  44. const entries = Object.entries(object).filter(filterValues);
  45. return Object.fromEntries(entries);
  46. }
  47. return String(object);
  48. }
  49. const extract = (
  50. os: string[] | object[] | null,
  51. nextId = (
  52. (id) => () =>
  53. String(++id)
  54. )(0)
  55. ) => {
  56. if (!os) return [];
  57. return [os].flat().map((o) => ({
  58. id: nextId(),
  59. text: generateNodeData(o),
  60. children: generateChildren(o, nextId),
  61. parent: false,
  62. }));
  63. };
  64. const flatten = (xs: { id: string; children: never[] }[]) =>
  65. xs.flatMap(({ children, ...rest }) => [rest, ...flatten(children)]);
  66. const relationships = (xs: { id: string; children: never[] }[]) => {
  67. return xs.flatMap(({ id: from, children = [] }) => [
  68. ...children.map(({ id: to }) => ({
  69. id: `e${from}-${to}`,
  70. from,
  71. to,
  72. })),
  73. ...relationships(children),
  74. ]);
  75. };
  76. export const parser = (input: string | string[]) => {
  77. try {
  78. if (!Array.isArray(input)) input = [input];
  79. const mappedElements = extract(input);
  80. const res = [...flatten(mappedElements), ...relationships(mappedElements)];
  81. return res;
  82. } catch (error) {
  83. console.error(error);
  84. toast.error("An error occured while parsing JSON data!");
  85. return [];
  86. }
  87. };