Skip to content

Commit

Permalink
fix JsonParser
Browse files Browse the repository at this point in the history
  • Loading branch information
victorbrambati committed Oct 18, 2022
1 parent 0737bcb commit 49c7940
Showing 1 changed file with 123 additions and 111 deletions.
234 changes: 123 additions & 111 deletions src/utils/jsonParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,125 +32,137 @@ const calculateSize = (
};
};

const filterChild = ([_, v]) => {
const isNull = v === null;
const isArray = Array.isArray(v) && v.length;
const isObject = v instanceof Object;
export const parser = (jsonStr: string, isExpanded = true) => {
let json = parse(jsonStr);
if (!Array.isArray(json)) json = [json];
let nodes: NodeData[] = [];
let edges: EdgeData[] = [];

return !isNull && (isArray || isObject);
};
let myArray: any[] = [];

const filterValues = ([k, v]) => {
if (Array.isArray(v) || v instanceof Object) return false;
return true;
};
const regex = /[^"":,}{]+|:{|}|:\[|:|{/gm;

function generateChildren(object: Object, isExpanded = true, nextId: () => string) {
if (!(object instanceof Object)) object = [object];

return Object.entries(object)
.filter(filterChild)
.flatMap(([key, v]) => {
const { width, height } = calculateSize(key, true, isExpanded);
const children = extract(v, isExpanded, nextId);

return [
{
id: nextId(),
text: key,
children,
width,
height,
data: {
isParent: true,
childrenCount: children.length,
},
},
];
});
}
const str = JSON.stringify(json);
let m: any;

function generateNodeData(object: Object) {
if (object instanceof Object) {
const entries = Object.entries(object).filter(filterValues);
return entries;
}
while ((m = regex.exec(str)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}

return String(object);
}
m.forEach((match, groupIndex) => {
myArray = [...myArray, match];
});
}

const extract = (
os: string[] | object[] | null,
isExpanded = true,
nextId = (
id => () =>
String(++id)
)(0)
) => {
if (!os) return [];

return [os].flat().map(o => {
const text = generateNodeData(o);
const { width, height } = calculateSize(text, false, isExpanded);

return {
id: nextId(),
text,
width,
height,
children: generateChildren(o, isExpanded, nextId),
data: {
isParent: false,
childrenCount: 0,
isEmpty: !text.length,
const addNodes = (text: string | any[], width, height, parent: boolean) => {
let actualId = String(nodes.length + 1);
nodes = [
...nodes,
{
id: actualId,
text: text,
width: width,
height: height,
data: {
isParent: parent,
childrenCount: parent ? 1 : 0,
},
},
};
});
};
];
return actualId;
};

const flatten = (xs: { id: string; children: never[] }[]) =>
xs.flatMap(({ children, ...rest }) => [rest, ...flatten(children)]);

const relationships = (xs: { id: string; children: never[] }[]) => {
return xs.flatMap(({ id: from, children = [] }) => [
...children.map(({ id: to }) => ({
id: `e${from}-${to}`,
from,
to,
})),
...relationships(children),
]);
};
const addEdges = (from: string, to: string) => {
edges = [
...edges,
{
id: `e${from}-${to}`,
from: from,
to: to,
},
];
};

export const parser = (jsonStr: string, isExpanded = true) => {
try {
let json = parse(jsonStr);
if (!Array.isArray(json)) json = [json];
const nodes: NodeData[] = [];
const edges: EdgeData[] = [];

const mappedElements = extract(json, isExpanded);
const res = [...flatten(mappedElements), ...relationships(mappedElements)];

res.forEach(data => {
if (isNode(data)) {
nodes.push(data);
} else {
edges.push(data);
let brothersNode: any[] = [];
let brotherNodeID = "";

let bracketOpen: string[] = [];

myArray.forEach((value, index, array) => {
if (/:{|:\[|:/g.test(value) === false) {
if (array[index + 1] === ":{" || array[index + 1] === ":[") {
const isParent = true;

const { width, height } = calculateSize(value, isParent, isExpanded);
let parentId = addNodes(value, width, height, isParent);

if (array[index - 2] === ":") {
addEdges(brotherNodeID, parentId);
} else if (bracketOpen.length > 0) {
addEdges(bracketOpen[bracketOpen.length - 1], parentId);
}

bracketOpen = [...bracketOpen, parentId];
} else if (
(value === "}" && bracketOpen.length > 0) ||
(value === "]" && bracketOpen.length > 0)
) {
let newbracketOpen = [...bracketOpen];
newbracketOpen.splice(newbracketOpen.length - 1);
bracketOpen = [...newbracketOpen];
} else if (
(value === "{" && bracketOpen.length > 0) ||
(value === "[" && bracketOpen.length > 0)
) {
bracketOpen = [...bracketOpen, bracketOpen[bracketOpen.length - 1]];
} else if (array[index + 1] === ":") {
let rightValue: string | number | boolean;

if (!isNaN(array[index + 2])) {
rightValue = Number(array[index + 2]);
} else if (array[index + 2] === "true") {
rightValue = true;
} else if (array[index + 2] === "false") {
rightValue = false;
} else {
rightValue = array[index + 2];
}

brothersNode = [...brothersNode, [value, rightValue]];
if (array[index + 4] !== ":") {
const isParent = false;

const { width, height } = calculateSize(
brothersNode,
isParent,
isExpanded
);
brotherNodeID = addNodes(brothersNode, width, height, isParent);
if (bracketOpen.length > 0) {
addEdges(bracketOpen[bracketOpen.length - 1], brotherNodeID);
}

brothersNode = [];
}
} else if (
array[index + 1] !== "}" &&
/:\{|:\[|:/g.test(array[index + 2]) === false &&
/{|}|\[|\]/g.test(value) === false
) {
const isParent = false;

const { width, height } = calculateSize(value, isParent, isExpanded);
let brotherArray = addNodes(value, width, height, isParent);

if (bracketOpen.length > 0) {
addEdges(bracketOpen[bracketOpen.length - 1], brotherArray);
}
}
});

return { nodes, edges };
} catch (error) {
console.error(error);
return {
nodes: [],
edges: [],
};
}
};
}
});

function isNode(element: NodeData | EdgeData) {
if ("text" in element) return true;
return false;
}
console.log(nodes);
return { nodes, edges };
};

0 comments on commit 49c7940

Please sign in to comment.