mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 16:02:32 +00:00
77 lines
2.3 KiB
TypeScript
77 lines
2.3 KiB
TypeScript
const WINDOWS_DRIVE_PATH_PREFIX = /^\/[A-Za-z]:\//
|
|
const UNC_PATH_PREFIX = /^(?:\\\\|\/\/)([^\\/]+)[\\/]+([^\\/]+)(?:[\\/](.*))?$/
|
|
|
|
function encodePathSegments(path: string): string {
|
|
return path
|
|
.split('/')
|
|
.map((segment, index) => {
|
|
if (index === 0 && /^[A-Za-z]:$/.test(segment)) {
|
|
return segment
|
|
}
|
|
return encodeURIComponent(segment)
|
|
})
|
|
.join('/')
|
|
}
|
|
|
|
export function filesystemPathToFileUri(filePath: string): string {
|
|
const uncMatch = UNC_PATH_PREFIX.exec(filePath)
|
|
if (uncMatch) {
|
|
const [, host, share, rest = ''] = uncMatch
|
|
const pathSegments = [share, ...rest.replaceAll('\\', '/').split('/').filter(Boolean)]
|
|
// Why: UNC hosts belong in the file URI authority; putting them in the
|
|
// pathname produces file:////server/share and loses the host on decode.
|
|
return `file://${encodeURIComponent(host)}/${pathSegments.map(encodeURIComponent).join('/')}`
|
|
}
|
|
|
|
const normalizedPath = filePath.replaceAll('\\', '/')
|
|
const encodedPath = encodePathSegments(normalizedPath)
|
|
return normalizedPath.startsWith('/') ? `file://${encodedPath}` : `file:///${encodedPath}`
|
|
}
|
|
|
|
export function filesystemPathHrefToFileUri(filePathHref: string): string {
|
|
const suffixIndex = filePathHref.search(/[?#]/)
|
|
if (suffixIndex === -1) {
|
|
return filesystemPathToFileUri(filePathHref)
|
|
}
|
|
|
|
const pathPart = filePathHref.slice(0, suffixIndex)
|
|
const suffix = filePathHref.slice(suffixIndex)
|
|
const url = new URL(filesystemPathToFileUri(pathPart))
|
|
if (suffix.startsWith('#')) {
|
|
// Why: markdown href fragments like `#L10` should stay URL fragments,
|
|
// not become `%23L10` inside the Windows filesystem path.
|
|
url.hash = suffix
|
|
return url.toString()
|
|
}
|
|
|
|
const hashIndex = suffix.indexOf('#')
|
|
url.search = hashIndex === -1 ? suffix : suffix.slice(0, hashIndex)
|
|
if (hashIndex !== -1) {
|
|
url.hash = suffix.slice(hashIndex)
|
|
}
|
|
return url.toString()
|
|
}
|
|
|
|
export function fileUriToFilesystemPath(url: URL): string | null {
|
|
if (url.protocol !== 'file:') {
|
|
return null
|
|
}
|
|
|
|
let decodedPath: string
|
|
try {
|
|
decodedPath = decodeURIComponent(url.pathname)
|
|
} catch {
|
|
return null
|
|
}
|
|
|
|
if (url.hostname && url.hostname !== 'localhost') {
|
|
return `//${url.hostname}${decodedPath}`
|
|
}
|
|
|
|
if (WINDOWS_DRIVE_PATH_PREFIX.test(decodedPath)) {
|
|
return decodedPath.slice(1)
|
|
}
|
|
|
|
return decodedPath
|
|
}
|