46 行
1.9 KiB
JavaScript
46 行
1.9 KiB
JavaScript
import { readFileSync, writeFileSync } from 'node:fs'
|
|
import path from 'node:path'
|
|
|
|
function normalize(value) {
|
|
return value.replaceAll('\\', '/')
|
|
}
|
|
|
|
function externalSourceName(normalized) {
|
|
const nodeModulesMarker = '/node_modules/'
|
|
const markerIndex = normalized.lastIndexOf(nodeModulesMarker)
|
|
if (markerIndex >= 0) {
|
|
return `external/node_modules/${normalized.slice(markerIndex + nodeModulesMarker.length)}`
|
|
}
|
|
return `external/${normalized.split('/').filter(Boolean).at(-1) ?? 'unknown-source'}`
|
|
}
|
|
|
|
/**
|
|
* root 内绝对路径变成项目相对路径;root 外绝对路径只保留稳定的外部标识,
|
|
* 绝不把 `../` 剥掉后伪装成项目源码,也不泄露开发机用户名或目录。
|
|
*/
|
|
export function sanitizeSourcePath(source, projectRoot) {
|
|
if (typeof source !== 'string') return source
|
|
const normalizedSource = normalize(source)
|
|
const normalizedRoot = normalize(projectRoot).replace(/\/+$/, '')
|
|
const windowsAbsolute = path.win32.isAbsolute(source)
|
|
const posixAbsolute = path.posix.isAbsolute(normalizedSource)
|
|
if (!windowsAbsolute && !posixAbsolute) return normalizedSource
|
|
|
|
const pathApi = windowsAbsolute ? path.win32 : path.posix
|
|
const comparableSource = windowsAbsolute ? source : normalizedSource
|
|
const comparableRoot = windowsAbsolute ? projectRoot : normalizedRoot
|
|
const relative = pathApi.relative(comparableRoot, comparableSource)
|
|
const outside =
|
|
relative === '..' || relative.startsWith(`..${pathApi.sep}`) || pathApi.isAbsolute(relative)
|
|
return outside ? externalSourceName(normalizedSource) : normalize(relative || '.')
|
|
}
|
|
|
|
export function sanitizeSourceMapFile(sourceMapFile, projectRoot) {
|
|
const sourceMap = JSON.parse(readFileSync(sourceMapFile, 'utf8'))
|
|
delete sourceMap.sourcesContent
|
|
if (Array.isArray(sourceMap.sources)) {
|
|
sourceMap.sources = sourceMap.sources.map(source => sanitizeSourcePath(source, projectRoot))
|
|
}
|
|
writeFileSync(sourceMapFile, JSON.stringify(sourceMap))
|
|
}
|