Transforms commands to a normalized `Navigation`
(commands: readonly any[])
| 268 | |
| 269 | /** Transforms commands to a normalized `Navigation` */ |
| 270 | function computeNavigation(commands: readonly any[]): Navigation { |
| 271 | if (typeof commands[0] === 'string' && commands.length === 1 && commands[0] === '/') { |
| 272 | return new Navigation(true, 0, commands); |
| 273 | } |
| 274 | |
| 275 | let numberOfDoubleDots = 0; |
| 276 | let isAbsolute = false; |
| 277 | |
| 278 | const res: any[] = commands.reduce((res, cmd, cmdIdx) => { |
| 279 | if (typeof cmd === 'object' && cmd != null) { |
| 280 | if (cmd.outlets) { |
| 281 | const outlets: {[k: string]: any} = {}; |
| 282 | Object.entries(cmd.outlets).forEach(([name, commands]) => { |
| 283 | outlets[name] = typeof commands === 'string' ? commands.split('/') : commands; |
| 284 | }); |
| 285 | return [...res, {outlets}]; |
| 286 | } |
| 287 | |
| 288 | if (cmd.segmentPath) { |
| 289 | return [...res, cmd.segmentPath]; |
| 290 | } |
| 291 | } |
| 292 | |
| 293 | if (!(typeof cmd === 'string')) { |
| 294 | return [...res, cmd]; |
| 295 | } |
| 296 | |
| 297 | if (cmdIdx === 0) { |
| 298 | cmd.split('/').forEach((urlPart, partIndex) => { |
| 299 | if (partIndex == 0 && urlPart === '.') { |
| 300 | // skip './a' |
| 301 | } else if (partIndex == 0 && urlPart === '') { |
| 302 | // '/a' |
| 303 | isAbsolute = true; |
| 304 | } else if (urlPart === '..') { |
| 305 | // '../a' |
| 306 | numberOfDoubleDots++; |
| 307 | } else if (urlPart != '') { |
| 308 | res.push(urlPart); |
| 309 | } |
| 310 | }); |
| 311 | |
| 312 | return res; |
| 313 | } |
| 314 | |
| 315 | return [...res, cmd]; |
| 316 | }, []); |
| 317 | |
| 318 | return new Navigation(isAbsolute, numberOfDoubleDots, res); |
| 319 | } |
| 320 | |
| 321 | class Position { |
| 322 | constructor( |
no test coverage detected