RocketChat/Rocket.Chat

View on GitHub
apps/meteor/packages/flow-router/server/router.js

Summary

Maintainability
B
4 hrs
Test Coverage
var Qs = Npm.require('qs');

Router = function () {
    this._routes = [];
    this._routesMap = {};
    this.subscriptions = Function.prototype;

    // holds onRoute callbacks
    this._onRouteCallbacks = [];
};

Router.prototype.route = function (pathDef, options) {
    if (!/^\/.*/.test(pathDef)) {
        var message = "route's path must start with '/'";
        throw new Error(message);
    }

    options = options || {};
    var route = new Route(this, pathDef, options);
    this._routes.push(route);

    if (options.name) {
        this._routesMap[options.name] = route;
    }

    this._triggerRouteRegister(route);
    return route;
};

Router.prototype.group = function (options) {
    return new Group(this, options);
};

Router.prototype.path = function (pathDef, fields, queryParams) {
    if (this._routesMap[pathDef]) {
        pathDef = this._routesMap[pathDef].path;
    }

    fields = fields || {};
    var regExp = /(:[\w\(\)\\\+\*\.\?]+)+/g;
    var path = pathDef.replace(regExp, function (key) {
        var firstRegexpChar = key.indexOf('(');
        // get the content behind : and (\\d+/)
        key = key.substring(1, firstRegexpChar > 0 ? firstRegexpChar : undefined);
        // remove +?*
        key = key.replace(/[\+\*\?]+/g, '');

        return fields[key] || '';
    });

    path = path.replace(/\/\/+/g, '/'); // Replace multiple slashes with single slash

    // remove trailing slash
    // but keep the root slash if it's the only one
    path = path.match(/^\/{1}$/) ? path : path.replace(/\/$/, '');

    var strQueryParams = Qs.stringify(queryParams || {});
    if (strQueryParams) {
        path += '?' + strQueryParams;
    }

    return path;
};

Router.prototype.onRouteRegister = function (cb) {
    this._onRouteCallbacks.push(cb);
};

Router.prototype._triggerRouteRegister = function (currentRoute) {
    // We should only need to send a safe set of fields on the route
    // object.
    // This is not to hide what's inside the route object, but to show
    // these are the public APIs
    var routePublicApi = _.pick(currentRoute, 'name', 'pathDef', 'path');
    var omittingOptionFields = ['triggersEnter', 'triggersExit', 'action', 'subscriptions', 'name'];
    routePublicApi.options = _.omit(currentRoute.options, omittingOptionFields);

    _.each(this._onRouteCallbacks, function (cb) {
        cb(routePublicApi);
    });
};

Router.prototype.go = function () {
    // client only
};

Router.prototype.current = function () {
    // client only
};

Router.prototype.triggers = {
    enter: function () {
        // client only
    },
    exit: function () {
        // client only
    },
};

Router.prototype.middleware = function () {
    // client only
};

Router.prototype.getState = function () {
    // client only
};

Router.prototype.getAllStates = function () {
    // client only
};

Router.prototype.setState = function () {
    // client only
};

Router.prototype.removeState = function () {
    // client only
};

Router.prototype.clearStates = function () {
    // client only
};

Router.prototype.ready = function () {
    // client only
};

Router.prototype.initialize = function () {
    // client only
};

Router.prototype.wait = function () {
    // client only
};