User Tools

Site Tools


,

Router match & list

router.js
/*
 * Author, Copyright: Oleg Borodin <onborodin@gmail.com>
 */
 
class router {
    constructor() {
        this.routes = {}
    }
    match(path, routes = this.routes) {
        let elems = path.split("/")
 
        let baseElem = elems[1]
        let basePath = "/" + elems[1]
 
        let nextElems = elems.slice(2, path.length)
        let nextPath = "/" + nextElems.join("/")
 
        let level = elems.length - 1
 
        for (let elem of routes) {
            if (basePath == elem.path && nextElems.length == 0) {
                if (elem.child == null) {
                    return {
                        path: elem.path,
                        meta: elem.meta,
                        level: level
                    }
                }
            }
            if (basePath == elem.path && nextElems.length > 0) {
                if (elem.child != null) {
                    let last = this.match(nextPath, elem.child)
                    if (last != null) {
                        return {
                            path: path,
                            meta: last.meta,
                            level: level
                        }
                    }
                }
            }
 
        }
        return null
    }
 
    list(path, level = -1, routes = this.routes, base = "") {
        let elems = path.split("/")
        let baseElem = elems[1]
        let basePath = "/" + elems[1]
 
        if (level == -1) level = elems.length
        if (base == "") { base = path }
        if (path == "/") { level = 1 }
 
        if (level == 1 && path == basePath) {
            let collection = []
            for (let elem of routes) {
                if (elem.meta != null) {
                    collection.push({
                        path: base + elem.path,
                        meta: elem.meta
                    })
                }
            }
            return collection
        }
 
        let nextElems = elems.slice(2, path.length)
        let nextPath = "/" + nextElems.join("/")
        let nextLevel = level - 1
 
        if (level > 1) {
            for (let elem of routes) {
                if (elem.child != null) {
                    return this.list(nextPath, nextLevel, elem.child, base)
                }
            }
        }
        return null
    }
}
 
var r = new router;
r.routes = [
    { path: "/",  meta: { name: "root" } },
    { path: "/ops", meta: { name: "Ops" } },
    { path: "/foo", meta: { name: "Foo" },
        child: [
            { path: "/bar", meta: { name: "Bar" } },
            { path: "/xyz", meta: { name: "Xyz" },
                child: [
                    { path: "/qwe", meta: { name: "Qwe" } },
                    { path: "/ert", meta: { name: "Ert" } },
                    { path: "/tyu", meta: { name: "Tyu" } }
                ]
            }
        ]
    }
]
 
console.log("1", r.match("/ops"))
console.log("2", r.match("/foo/bar"))
console.log("3", r.match("/foo/xyz"))
console.log("4", r.match("/foo/xyz/qwe"))
console.log("5", r.match("/foo/zztop"))
 
console.log("6", r.list("/"))
console.log("7", r.list("/foo/xyz"))

Out

$ node ./router.js
1 { path: '/ops', meta: { name: 'Ops' }, level: 1 }
2 { path: '/foo/bar', meta: { name: 'Bar' }, level: 2 }
3 null
4 { path: '/foo/xyz/qwe', meta: { name: 'Qwe' }, level: 3 }
5 null

6 [
  { path: '//', meta: { name: 'root' } },
  { path: '//ops', meta: { name: 'Ops' } },
  { path: '//foo', meta: { name: 'Foo' } }
]
7 [
  { path: '/foo/xyz/qwe', meta: { name: 'Qwe' } },
  { path: '/foo/xyz/ert', meta: { name: 'Ert' } },
  { path: '/foo/xyz/tyu', meta: { name: 'Tyu' } }
]