@jymfony/routing
Version:
Jymfony Routing component
301 lines (261 loc) • 7.85 kB
JavaScript
/**
* A RouteCollection represents a set of Route instances.
*
* When adding a route at the end of the collection, an existing route
* with the same name is removed first. So there can only be one route
* with a given name.
*
* @memberOf Jymfony.Component.Routing
*/
export default class RouteCollection {
/**
* @type {Object.<string, Jymfony.Component.Routing.Route>}
*
* @private
*/
_routes = {};
/**
* @type {Object.<string, Jymfony.Component.Config.Resource.ResourceInterface>}
*
* @private
*/
_resources = {};
/**
* Adds a route.
*
* @param {string} name
* @param {Jymfony.Component.Routing.Route} route
*
* @returns {Jymfony.Component.Routing.RouteCollection}
*/
add(name, route) {
delete this._routes[name];
this._routes[name] = route;
return this;
}
/**
* Returns all routes in this collection.
*
* @returns {Object.<string, Jymfony.Component.Routing.Route>}
*/
all() {
return Object.assign({}, this._routes);
}
/**
* Gets a route by name.
*
* @param {string} name
*
* @returns {Jymfony.Component.Routing.Route|undefined}
*/
get(name) {
return this._routes[name];
}
/**
* Removes a route or an array of routes from the collection
*
* @param {string|string[]} name
*
* @returns {Jymfony.Component.Routing.RouteCollection}
*/
remove(name) {
if (! isArray(name)) {
name = [ name ];
}
for (const n of name) {
delete this._routes[n];
}
return this;
}
/**
* Adds a route collection at the end of the current set by appending all
* routes of the added collection.
*
* @param {Jymfony.Component.Routing.RouteCollection} collection
*
* @returns {Jymfony.Component.Routing.RouteCollection}
*/
addCollection(collection) {
for (const [ name, route ] of __jymfony.getEntries(collection.all())) {
delete this._routes[name];
this._routes[name] = route;
}
for (const resource of collection.resources) {
this.addResource(resource);
}
return this;
}
/**
* Adds a prefix to the path of all child routes.
*
* @param {string} prefix An optional prefix to add before each pattern of the route collection
* @param {Object.<string, *>} [defaults = {}] A set of default values
* @param {Object.<string, string|RegExp>} [requirements = {}] A set of requirements
*
* @returns {Jymfony.Component.Routing.RouteCollection}
*/
addPrefix(prefix, defaults = {}, requirements = {}) {
prefix = __jymfony.trim(__jymfony.trim(prefix), '/');
if ('' === prefix) {
return this;
}
for (const route of Object.values(this._routes)) {
route.setPath('/' + prefix + route.path);
route.addDefaults(defaults);
route.addRequirements(requirements);
}
return this;
}
/**
* Adds a prefix to the name of all the routes within in the collection.
*
* @returns {Jymfony.Component.Routing.RouteCollection}
*/
addNamePrefix(prefix) {
const prefixedRoutes = {};
let name, route;
for ([ name, route ] of __jymfony.getEntries(this._routes)) {
prefixedRoutes[prefix + name] = route;
if (undefined !== (name = route.getDefault('_canonical_route'))) {
route.setDefault('_canonical_route', prefix + name);
}
}
this._routes = prefixedRoutes;
return this;
}
/**
* Sets the host pattern on all routes.
*
* @param {string} pattern The pattern
* @param {Object.<string, *>} [defaults = {}] A set of default values
* @param {Object.<string, string|RegExp>} [requirements = {}] A set of requirements
*
* @returns {Jymfony.Component.Routing.RouteCollection}
*/
addHost(pattern, defaults = {}, requirements = {}) {
for (const route of Object.values(this._routes)) {
route.setHost(pattern);
route.addDefaults(defaults);
route.addRequirements(requirements);
}
return this;
}
/**
* Adds a resource for this collection.
*
* @param {Jymfony.Component.Config.Resource.ResourceInterface} resource
*
* @returns {Jymfony.Component.Routing.RouteCollection}
*/
addResource(resource) {
const key = resource.toString();
if (undefined === this._resources[key]) {
this._resources[key] = resource;
}
return this;
}
/**
* Sets a condition on all routes.
* Existing conditions will be overridden.
*
* @param {string} condition The condition
*/
setCondition(/* condition */) {
// @todo
}
/**
* Adds defaults to all routes.
* An existing default value under the same name in a route will be overridden.
*
* @param {Object.<string, *>} defaults A set of default values
*
* @returns {Jymfony.Component.Routing.RouteCollection}
*/
addDefaults(defaults) {
if (0 === Object.keys(defaults).length) {
return this;
}
for (const route of Object.values(this._routes)) {
route.addDefaults(defaults);
}
return this;
}
/**
* Adds requirements to all routes.
* An existing requirement under the same name in a route will be overridden.
*
* @param {Object.<string, string|RegExp>} requirements A set of requirements
*
* @returns {Jymfony.Component.Routing.RouteCollection}
*/
addRequirements(requirements) {
if (0 === Object.keys(requirements).length) {
return this;
}
for (const route of Object.values(this._routes)) {
route.addRequirements(requirements);
}
return this;
}
/**
* Adds options to all routes.
* An existing option value under the same name in a route will be overridden.
*
* @param {Object.<string, *>} options An array of options
*
* @returns {Jymfony.Component.Routing.RouteCollection}
*/
addOptions(options) {
if (0 === Object.keys(options).length) {
return this;
}
for (const route of Object.values(this._routes)) {
route.addOptions(options);
}
return this;
}
/**
* Sets the schemes (e.g. 'https') all child routes are restricted to.
*
* @param {string|string[]} schemes The scheme or an array of schemes
*/
setSchemes(schemes) {
for (const route of Object.values(this._routes)) {
route.setSchemes(schemes);
}
}
/**
* Sets the HTTP methods (e.g. 'POST') all child routes are restricted to.
*
* @param {string|string[]} methods The method or an array of methods
*/
setMethods(methods) {
for (const route of Object.values(this._routes)) {
route.setMethods(methods);
}
}
/**
* Returns the set of resources loaded to build this collection.
*
* @returns {Jymfony.Component.Config.Resource.ResourceInterface[]}
*/
get resources() {
return Object.values(this._resources);
}
/**
* Gets the number of routes in this collection.
*
* @returns {int}
*/
get length() {
return Object.keys(this._routes).length;
}
/**
* Gets the iterator for this collection
*
* @returns {Generator}
*/
[Symbol.iterator]() {
return __jymfony.getEntries(this._routes);
}
}