export function insert()

in compiler/src/dump/extract-routes.ts [173:268]


export function insert (node: Node, url: string, name: string): void {
  if (url.length === 0) {
    return
  }

  // Check if we're not on root anymore,
  // otherwise the value of url is set as
  // the default path for the current node
  // to bootstrap the insertion making this
  // de facto root of the tree.
  if (url[0] === node.path[0]) {
    const match = matches(url, node.path)
    const rest = url.slice(match.length)

    // If the matched part is shorter than the current node path
    // we need to split the node.
    // eg: _search with _select added becomes
    // _se ->
    //  -> arch
    //  -> lect
    if (match.length < node.path.length) {
      // If the current node already has children we move them to the newly created node.
      if (match.startsWith('{') && node.path.startsWith('{')) {
        node.path = match
        insert(node, rest, name)
      } else {
        const child = new Node()
        insert(child, rest, name)

        const oldNode = new Node(node.path, node.name, node.children)
        oldNode.path = oldNode.path.slice(match.length)
        node.children = []
        node.children.push(oldNode)

        node.name = ''
        node.path = match
        if (child.path.length > 0) {
          node.children.push(child)
        }
      }
    }

    // if the url is lengthier than the current node we have children to populate/match
    if (url.length > node.path.length) {
      let found: boolean = false

      // first we iterate over existing children to check if there's a match
      for (const child of node.children) {
        if (child.path[0] === rest[0]) {
          found = true
          insert(child, rest, name)
        }
      }

      // if there's no match found we create a new child to this node
      if (!found) {
        const n = new Node()
        insert(n, rest, name)
        node.children.push(n)
      }
    }
  } else if (node.path.length === 0) {
    node.path = url
    const match = matches(url, node.path)
    const rest = url.slice(match.length)

    node.path = match
    if (rest.length > 0) {
      insert(node, rest, name)
    }

    if (node.path.startsWith('{')) {
      node.isVariable = true
    }
  } else if (url[0] !== node.path[0]) {
    childrenPresent: { // eslint-disable-line
      for (const nodeChildren of node.children) {
        if (nodeChildren.path[0] === url[0]) {
          insert(nodeChildren, url, name)
          break childrenPresent // eslint-disable-line
        }
      }
      const child = new Node()
      insert(child, url, name)
      node.children.push(child)
    }
  }

  if (node.path === url) {
    node.name = name
  } else if (node.children.length === 1 && node.children[0].isVariable) {
    node.name = name
  } else if (node.isVariable && node.name.length === 0 && url.startsWith('{') && url.endsWith('}')) {
    node.name = name
  }
}