UNPKG

@tsed/cli

Version:
74 lines (73 loc) 3.05 kB
import { homedir } from "node:os"; import { basename, relative, resolve } from "node:path"; const GLOBAL_MODULE_MARKER = "/node_modules/"; function toPosixPath(pathname) { return pathname.replace(/\\/g, "/"); } function normalizePath(pathname) { return toPosixPath(resolve(pathname)); } function isSubPath(pathname, parentPath) { return pathname === parentPath || pathname.startsWith(`${parentPath}/`); } function splitPathAndLocation(pathname) { const match = pathname.match(/^(.*?)(:\d+(?::\d+)?)?$/); return { path: match?.[1] || pathname, location: match?.[2] || "" }; } function getGlobalModulePath(absolutePath, absolutePathForCompare) { const index = absolutePathForCompare.indexOf(GLOBAL_MODULE_MARKER); if (index === -1) { return; } const pathAfterNodeModules = absolutePath.slice(index + GLOBAL_MODULE_MARKER.length); const segments = pathAfterNodeModules.split("/").filter(Boolean); if (!segments.length) { return; } const isScoped = segments[0].startsWith("@"); const moduleName = isScoped ? segments.slice(0, 2).join("/") : segments[0]; if (!moduleName || (isScoped && segments.length < 2)) { return; } const suffixSegments = segments.slice(isScoped ? 2 : 1); const suffix = suffixSegments.length ? `/${suffixSegments.join("/")}` : ""; return `<global>/${moduleName}${suffix}`; } function anonymizeAbsolutePath(pathname, cwd, home) { const absolutePath = normalizePath(pathname); const absolutePathForCompare = absolutePath.toLowerCase(); const cwdForCompare = cwd.toLowerCase(); const homeForCompare = home.toLowerCase(); if (isSubPath(absolutePathForCompare, cwdForCompare)) { const relativePath = toPosixPath(relative(cwd, absolutePath)); return relativePath ? `<cwd>/${relativePath}` : "<cwd>"; } const globalModulePath = getGlobalModulePath(absolutePath, absolutePathForCompare); if (globalModulePath) { return globalModulePath; } if (isSubPath(absolutePathForCompare, homeForCompare)) { return `~/${toPosixPath(relative(home, absolutePath))}`; } return `<external>/${basename(absolutePath)}`; } function anonymizeTokenWithContext(token, cwd, home) { const { path, location } = splitPathAndLocation(token); return `${anonymizeAbsolutePath(path, cwd, home)}${location}`; } function toPathFromFileUrl(token) { const decodedPath = decodeURIComponent(token.replace(/^file:\/\//, "")); return decodedPath.replace(/^\/([A-Za-z]:[\\/])/, "$1"); } export function anonymizePaths(stack, options = {}) { const cwd = normalizePath(options.cwd || process.cwd()); const home = normalizePath(options.home || homedir()); return stack .replace(/file:\/\/\/[^\s)]+/g, (token) => anonymizeTokenWithContext(toPathFromFileUrl(token), cwd, home)) .replace(/(^|[\s(])((?:[A-Za-z]:\\|\/)[^\s)]+)/g, (_full, prefix, token) => { return `${prefix}${anonymizeTokenWithContext(token, cwd, home)}`; }); }