You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

path.js 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /**
  2. * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
  3. *
  4. * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
  5. *
  6. * @license GNU AGPL version 3 or any later version
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU Affero General Public License as
  10. * published by the Free Software Foundation, either version 3 of the
  11. * License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU Affero General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. /**
  22. * URI-Encodes a file path but keep the path slashes.
  23. *
  24. * @param {String} path path
  25. * @returns {String} encoded path
  26. */
  27. export const encodePath = path => {
  28. if (!path) {
  29. return path
  30. }
  31. const parts = path.split('/')
  32. const result = []
  33. for (let i = 0; i < parts.length; i++) {
  34. result.push(encodeURIComponent(parts[i]))
  35. }
  36. return result.join('/')
  37. }
  38. /**
  39. * Returns the base name of the given path.
  40. * For example for "/abc/somefile.txt" it will return "somefile.txt"
  41. *
  42. * @param {String} path path
  43. * @returns {String} base name
  44. */
  45. export const basename = path => path.replace(/\\/g, '/').replace(/.*\//, '')
  46. /**
  47. * Returns the dir name of the given path.
  48. * For example for "/abc/somefile.txt" it will return "/abc"
  49. *
  50. * @param {String} path path
  51. * @returns {String} dir name
  52. */
  53. export const dirname = path => path.replace(/\\/g, '/').replace(/\/[^/]*$/, '')
  54. /**
  55. * Returns whether the given paths are the same, without
  56. * leading, trailing or doubled slashes and also removing
  57. * the dot sections.
  58. *
  59. * @param {String} path1 first path
  60. * @param {String} path2 second path
  61. * @returns {bool} true if the paths are the same
  62. *
  63. * @since 9.0
  64. */
  65. export const isSamePath = (path1, path2) => {
  66. const pathSections1 = (path1 || '').split('/').filter(p => p !== '.')
  67. const pathSections2 = (path2 || '').split('/').filter(p => p !== '.')
  68. path1 = joinPaths.apply(undefined, pathSections1)
  69. path2 = joinPaths.apply(undefined, pathSections2)
  70. return path1 === path2
  71. }
  72. /**
  73. * Join path sections
  74. *
  75. * @param {...String} path sections
  76. *
  77. * @returns {String} joined path, any leading or trailing slash
  78. * will be kept
  79. *
  80. * @since 8.2
  81. */
  82. export const joinPaths = (...args) => {
  83. if (args.length < 1) {
  84. return ''
  85. }
  86. // discard empty arguments
  87. const nonEmptyArgs = args.filter(arg => arg.length > 0)
  88. if (nonEmptyArgs.length < 1) {
  89. return ''
  90. }
  91. const lastArg = nonEmptyArgs[nonEmptyArgs.length - 1]
  92. const leadingSlash = nonEmptyArgs[0].charAt(0) === '/'
  93. const trailingSlash = lastArg.charAt(lastArg.length - 1) === '/'
  94. const sections = nonEmptyArgs.reduce((acc, section) => acc.concat(section.split('/')), [])
  95. let first = !leadingSlash
  96. const path = sections.reduce((acc, section) => {
  97. if (section === '') {
  98. return acc
  99. }
  100. if (first) {
  101. first = false
  102. return acc + section
  103. }
  104. return acc + '/' + section
  105. }, '')
  106. if (trailingSlash) {
  107. // add it back
  108. return path + '/'
  109. }
  110. return path
  111. }