41 lines
1.3 KiB
TypeScript
41 lines
1.3 KiB
TypeScript
type CleanFullPathReturn = { path: string } | { error: string };
|
|
|
|
export default function cleanFullPath(input: string, isWindows): CleanFullPathReturn {
|
|
//Path must be a string
|
|
if (typeof input !== 'string') {
|
|
return { error: 'path must be a string' };
|
|
}
|
|
|
|
//Path must not be a windows extended path (namespace?)
|
|
if (input.startsWith('\\\\?\\')) {
|
|
return { error: 'unsupported windows path format' };
|
|
}
|
|
|
|
//Convert backslashes to slashes and remove duplicate slashes
|
|
const slashified = input.replaceAll(/\\/g, '/').replaceAll(/\/+/g, '/');
|
|
|
|
//Path must not be empty
|
|
if (slashified.length === 0) {
|
|
return { error: 'empty path' };
|
|
}
|
|
|
|
//Path must be absolute
|
|
if (isWindows && !/^[a-zA-Z]:\//.test(slashified)) {
|
|
return { error: 'windows paths must be absolute and start with a drive letter like `c:/`' };
|
|
} else if (!isWindows && !/^\//.test(slashified)) {
|
|
return { error: 'linux paths must be absolute and start with a slash' };
|
|
}
|
|
|
|
//Path must be fully resolved
|
|
if (/\/[\s\.](\/|$)/.test(slashified)) {
|
|
return { error: 'path contains unresolved parts (eg. `/../`)' };
|
|
}
|
|
|
|
//Return without the trailing slash
|
|
if (slashified.endsWith('/')) {
|
|
return { path: slashified.slice(0, -1) };
|
|
} else {
|
|
return { path: slashified };
|
|
}
|
|
}
|