| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- /**
- * Normalize a path to use forward slashes (works on both macOS and Windows).
- * Windows APIs accept forward slashes, so normalizing to / is safe everywhere.
- */
- export function normalizePath(p: string): string {
- return p.replace(/\\/g, "/")
- }
- /**
- * Join path segments with forward slashes.
- */
- export function joinPath(...segments: string[]): string {
- return segments
- .map((s) => s.replace(/\\/g, "/"))
- .join("/")
- .replace(/\/+/g, "/")
- }
- /**
- * Get the filename from a path (handles both / and \).
- */
- export function getFileName(p: string): string {
- const normalized = p.replace(/\\/g, "/")
- return normalized.split("/").pop() ?? p
- }
- /**
- * Get the file stem (filename without extension).
- */
- export function getFileStem(p: string): string {
- const name = getFileName(p)
- const lastDot = name.lastIndexOf(".")
- return lastDot > 0 ? name.slice(0, lastDot) : name
- }
- /**
- * Get relative path from base.
- */
- export function getRelativePath(fullPath: string, basePath: string): string {
- const normalFull = normalizePath(fullPath)
- const normalBase = normalizePath(basePath).replace(/\/$/, "")
- if (normalFull.startsWith(normalBase + "/")) {
- return normalFull.slice(normalBase.length + 1)
- }
- return normalFull
- }
- /**
- * Cross-platform absolute-path detection.
- *
- * Unix: "/foo/bar"
- * Windows: "C:\foo", "C:/foo", "\\server\share", "//server/share"
- *
- * A bare `.startsWith("/")` check wrongly treats Windows paths like
- * "C:/project/file.pdf" as relative, which produced double-joined
- * garbage like "C:/project/C:/project/file.pdf" in the ingest queue.
- */
- export function isAbsolutePath(p: string): boolean {
- if (!p) return false
- if (p.startsWith("/")) return true
- if (/^[A-Za-z]:[\\/]/.test(p)) return true
- if (p.startsWith("\\\\") || p.startsWith("//")) return true
- return false
- }
|