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