Files
hoppscotch/helpers/newOutline.ts
2021-09-14 21:33:13 +05:30

101 lines
2.1 KiB
TypeScript

import {
JSONArrayValue,
JSONObjectMember,
JSONObjectValue,
JSONValue,
} from "./jsonParse"
type RootEntry =
| {
kind: "RootObject"
astValue: JSONObjectValue
}
| {
kind: "RootArray"
astValue: JSONArrayValue
}
type ObjectMemberEntry = {
kind: "ObjectMember"
name: string
astValue: JSONObjectMember
astParent: JSONObjectValue
}
type ArrayMemberEntry = {
kind: "ArrayMember"
index: number
astValue: JSONValue
astParent: JSONArrayValue
}
type PathEntry = RootEntry | ObjectMemberEntry | ArrayMemberEntry
export function getJSONOutlineAtPos(
jsonRootAst: JSONObjectValue | JSONArrayValue,
posIndex: number
): PathEntry[] | null {
try {
const rootObj = jsonRootAst
if (posIndex > rootObj.end || posIndex < rootObj.start)
throw new Error("Invalid position")
let current: JSONValue = rootObj
const path: PathEntry[] = []
if (rootObj.kind === "Object") {
path.push({
kind: "RootObject",
astValue: rootObj,
})
} else {
path.push({
kind: "RootArray",
astValue: rootObj,
})
}
while (current.kind === "Object" || current.kind === "Array") {
if (current.kind === "Object") {
const next: JSONObjectMember | undefined = current.members.find(
(member) => member.start <= posIndex && member.end >= posIndex
)
if (!next) throw new Error("Couldn't find child")
path.push({
kind: "ObjectMember",
name: next.key.value,
astValue: next,
astParent: current,
})
current = next.value
} else {
const nextIndex = current.values.findIndex(
(value) => value.start <= posIndex && value.end >= posIndex
)
if (nextIndex < 0) throw new Error("Couldn't find child")
const next: JSONValue = current.values[nextIndex]
path.push({
kind: "ArrayMember",
index: nextIndex,
astValue: next,
astParent: current,
})
current = next
}
}
return path
} catch (e: any) {
return null
}
}