e32261f1cc4ba85170a276579033b0b847b1629643268d02ebfca4ba10876cfc4e891fe3cb104b016b0b545ac8f8f9fb114dd3b48715388e608015ee0ecef2 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. /* @flow */
  2. export function resolvePath (
  3. relative: string,
  4. base: string,
  5. append?: boolean
  6. ): string {
  7. const firstChar = relative.charAt(0)
  8. if (firstChar === '/') {
  9. return relative
  10. }
  11. if (firstChar === '?' || firstChar === '#') {
  12. return base + relative
  13. }
  14. const stack = base.split('/')
  15. // remove trailing segment if:
  16. // - not appending
  17. // - appending to trailing slash (last segment is empty)
  18. if (!append || !stack[stack.length - 1]) {
  19. stack.pop()
  20. }
  21. // resolve relative path
  22. const segments = relative.replace(/^\//, '').split('/')
  23. for (let i = 0; i < segments.length; i++) {
  24. const segment = segments[i]
  25. if (segment === '..') {
  26. stack.pop()
  27. } else if (segment !== '.') {
  28. stack.push(segment)
  29. }
  30. }
  31. // ensure leading slash
  32. if (stack[0] !== '') {
  33. stack.unshift('')
  34. }
  35. return stack.join('/')
  36. }
  37. export function parsePath (path: string): {
  38. path: string;
  39. query: string;
  40. hash: string;
  41. } {
  42. let hash = ''
  43. let query = ''
  44. const hashIndex = path.indexOf('#')
  45. if (hashIndex >= 0) {
  46. hash = path.slice(hashIndex)
  47. path = path.slice(0, hashIndex)
  48. }
  49. const queryIndex = path.indexOf('?')
  50. if (queryIndex >= 0) {
  51. query = path.slice(queryIndex + 1)
  52. path = path.slice(0, queryIndex)
  53. }
  54. return {
  55. path,
  56. query,
  57. hash
  58. }
  59. }
  60. export function cleanPath (path: string): string {
  61. return path.replace(/\/\//g, '/')
  62. }