1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | 45x 206x 206x 206x 206x 1x 205x 1x 204x 1x 203x 203x 200x 200x 200x 200x 1189x 1189x 193x 193x 579x 193x 193x 193x 193x 193x 608x 608x 608x 608x 608x 608x 608x 3238x 3238x 3236x 216x 3020x 3020x 390x 390x 390x 290x 290x 290x 290x 290x 1712x 1712x 276x 276x 2x 274x 18x 18x 6x 268x 593x 593x 291x 291x 2x | import { joinUri, forEachPartName, chooseTemplate } from './utils.js'; import RouteOptions from './RouteOptions.js'; import RouteParams from './RouteParams.js'; import TemplateUri from './TemplateUri.js'; import UserUri from './UserUri.js'; import RouterError from './RouterError.js'; const metaDataProperties = ['payload', 'key', 'data']; export default class Route { constructor (routeName, rawRoute) { const rawRouteParams = rawRoute.params || {}; const rawRouteOptions = rawRoute.options || {}; const rawRouteUri = rawRoute.uri || ''; if (typeof rawRouteParams !== 'object') { throw new RouterError(RouterError.INVALID_INPUT_TYPE, { entity: 'route\'s params', type: 'object', routeName }); } if (typeof rawRouteOptions !== 'object') { throw new RouterError(RouterError.INVALID_INPUT_TYPE, { entity: 'route\'s options', type: 'object', routeName }); } if (typeof rawRouteUri !== 'string') { throw new RouterError(RouterError.INVALID_INPUT_TYPE, { entity: 'route\'s URI template', type: 'string', routeName }); } this.name = routeName; const templateUri = new TemplateUri(rawRouteUri); const parsedOptions = new RouteOptions(rawRouteOptions, routeName); const parsedParams = new RouteParams(rawRouteParams); const parsedTemplate = {}; forEachPartName((partName) => { const Template = chooseTemplate(templateUri, partName); parsedTemplate[partName] = new Template(templateUri, parsedParams, routeName); }); const parsedMetaData = {}; for (let metaDataProperty of metaDataProperties) { parsedMetaData[metaDataProperty] = rawRoute[metaDataProperty]; } this._templateUri = templateUri; this._parsedOptions = parsedOptions; this._parsedParams = parsedParams; this._parsedTemplate = parsedTemplate; this._parsedMetaData = parsedMetaData; } matchUri (userUri, contextOptions) { const routeName = this.name; const parsedTemplate = this._parsedTemplate; const matchObject = {}; const params = {}; const options = Object.assign( {}, contextOptions.router.getParsedOptions(), this._parsedOptions ); Object.assign(contextOptions, options); for (let p in parsedTemplate) { contextOptions.partName = p; const matchFragment = parsedTemplate[p].matchParsedValue(userUri, contextOptions); if (!matchFragment) { return null; } matchObject[p] = matchFragment.value; Object.assign(params, matchFragment.params); } delete options.routeName; Object.assign(matchObject, this._parsedMetaData, { name: routeName, params, options }); return matchObject; } generateUri (userParams, contextOptions) { const routeName = this.name; const parsedTemplate = this._parsedTemplate; const generatingUri = {}; Object.assign( contextOptions, contextOptions.router.getParsedOptions(), this._parsedOptions, {generatingUri, routeName} ); for (let p in parsedTemplate) { contextOptions.partName = p; generatingUri[p] = parsedTemplate[p].generateParsedValue(userParams, contextOptions); } let rawUri; try { rawUri = joinUri(generatingUri, contextOptions); } catch (error) { throw new RouterError(RouterError[error.code], {routeName}); } if (contextOptions.dataConsistency) { const userUri = new UserUri(contextOptions.router.resolveUri(rawUri), contextOptions); if (!this.matchUri(userUri, {router: contextOptions.router})) { throw new RouterError(RouterError.INCONSISTENT_DATA, {routeName}); } } return rawUri; } canBeMatched () { const parsedOptions = this._parsedOptions; return parsedOptions.canBeMatched; } canBeGenerated () { const parsedOptions = this._parsedOptions; return parsedOptions.canBeGenerated; } getParsedOptions () { return this._parsedOptions; } } |