(path, relativePath)
| 66 | const SPECIAL_PATH_SEGMENT = /^\.+$/; |
| 67 | |
| 68 | export function resolveRelativePath(path, relativePath) { |
| 69 | // while has segment |
| 70 | // if ( segment == . ) |
| 71 | // ignore segment |
| 72 | // else if segment == .. |
| 73 | // remove one segment from stack, throw exception if there is none |
| 74 | // else |
| 75 | // add segment to stack |
| 76 | // combine segments in stack with '/' |
| 77 | |
| 78 | const match = ANY_SPECIAL_PATH_SEGMENT.exec(relativePath); |
| 79 | if ( match ) { |
| 80 | // process segments only if there is at least one special segment |
| 81 | let segments = []; |
| 82 | |
| 83 | const p = path.lastIndexOf("/"); |
| 84 | if ( match.index == 0 && p > 0 ) { |
| 85 | // if first segment is ./ or ../, start with parent path, otherwise start empty |
| 86 | segments = path.slice(0, p).split("/"); |
| 87 | } |
| 88 | |
| 89 | const relativePathSegments = relativePath.split("/"); |
| 90 | for ( let i = 0; i < relativePathSegments.length; i++ ) { |
| 91 | const segment = relativePathSegments[i]; |
| 92 | if ( SPECIAL_PATH_SEGMENT.test(segment) ) { |
| 93 | switch ( segment.length ) { |
| 94 | case 1: |
| 95 | // segment './' -> ignore |
| 96 | continue; |
| 97 | case 2: |
| 98 | // segment '../' -> navigate to parent if possible |
| 99 | if ( segments.length === 0 ) { |
| 100 | throw new Error(`Can't navigate to parent of root (${path}, ${relativePath})`); |
| 101 | } |
| 102 | segments.pop(); |
| 103 | break; |
| 104 | default: |
| 105 | // segment '...' or more dots: not allowed |
| 106 | throw new Error(`Illegal path segment '${segment}'`); |
| 107 | } |
| 108 | } else { |
| 109 | // normal segment: add |
| 110 | segments.push(segment); |
| 111 | } |
| 112 | } |
| 113 | // console.log("resolution of (%s,%s): %s%n", getPackagePath(), relativePath, StringUtils.join(segments, "/")); |
| 114 | relativePath = segments.join("/"); |
| 115 | } |
| 116 | return relativePath; |
| 117 | } |
| 118 | |
| 119 | export function resolveRelativeRequireJSName(path, relativeName) { |
| 120 | return resolveRelativePath(path, relativeName + ".js"); |
no outgoing calls
no test coverage detected