mirror of
https://github.com/SamEyeBam/animate.git
synced 2025-09-28 06:55:25 +00:00
139 lines
3.5 KiB
JavaScript
139 lines
3.5 KiB
JavaScript
// @flow
|
|
import type {SourceLocation} from '@parcel/types';
|
|
import type {FileSystem} from '@parcel/fs';
|
|
import SourceMap from '@parcel/source-map';
|
|
import path from 'path';
|
|
import {normalizeSeparators, isAbsolute} from './path';
|
|
|
|
export const SOURCEMAP_RE: RegExp =
|
|
/(?:\/\*|\/\/)\s*[@#]\s*sourceMappingURL\s*=\s*([^\s*]+)(?:\s*\*\/)?\s*$/;
|
|
const DATA_URL_RE = /^data:[^;]+(?:;charset=[^;]+)?;base64,(.*)/;
|
|
export const SOURCEMAP_EXTENSIONS: Set<string> = new Set<string>([
|
|
'css',
|
|
'es',
|
|
'es6',
|
|
'js',
|
|
'jsx',
|
|
'mjs',
|
|
'ts',
|
|
'tsx',
|
|
]);
|
|
|
|
export function matchSourceMappingURL(
|
|
contents: string,
|
|
): null | RegExp$matchResult {
|
|
return contents.match(SOURCEMAP_RE);
|
|
}
|
|
|
|
export async function loadSourceMapUrl(
|
|
fs: FileSystem,
|
|
filename: string,
|
|
contents: string,
|
|
): Promise<?{|filename: string, map: any, url: string|}> {
|
|
let match = matchSourceMappingURL(contents);
|
|
if (match) {
|
|
let url = match[1].trim();
|
|
let dataURLMatch = url.match(DATA_URL_RE);
|
|
|
|
let mapFilePath;
|
|
if (dataURLMatch) {
|
|
mapFilePath = filename;
|
|
} else {
|
|
mapFilePath = url.replace(/^file:\/\//, '');
|
|
mapFilePath = isAbsolute(mapFilePath)
|
|
? mapFilePath
|
|
: path.join(path.dirname(filename), mapFilePath);
|
|
}
|
|
|
|
return {
|
|
url,
|
|
filename: mapFilePath,
|
|
map: JSON.parse(
|
|
dataURLMatch
|
|
? Buffer.from(dataURLMatch[1], 'base64').toString()
|
|
: await fs.readFile(mapFilePath, 'utf8'),
|
|
),
|
|
};
|
|
}
|
|
}
|
|
|
|
export async function loadSourceMap(
|
|
filename: string,
|
|
contents: string,
|
|
options: {fs: FileSystem, projectRoot: string, ...},
|
|
): Promise<?SourceMap> {
|
|
let foundMap = await loadSourceMapUrl(options.fs, filename, contents);
|
|
if (foundMap) {
|
|
let mapSourceRoot = path.dirname(filename);
|
|
if (
|
|
foundMap.map.sourceRoot &&
|
|
!normalizeSeparators(foundMap.map.sourceRoot).startsWith('/')
|
|
) {
|
|
mapSourceRoot = path.join(mapSourceRoot, foundMap.map.sourceRoot);
|
|
}
|
|
|
|
let sourcemapInstance = new SourceMap(options.projectRoot);
|
|
sourcemapInstance.addVLQMap({
|
|
...foundMap.map,
|
|
sources: foundMap.map.sources.map(s => {
|
|
return path.join(mapSourceRoot, s);
|
|
}),
|
|
});
|
|
return sourcemapInstance;
|
|
}
|
|
}
|
|
|
|
export function remapSourceLocation(
|
|
loc: SourceLocation,
|
|
originalMap: SourceMap,
|
|
): SourceLocation {
|
|
let {
|
|
filePath,
|
|
start: {line: startLine, column: startCol},
|
|
end: {line: endLine, column: endCol},
|
|
} = loc;
|
|
let lineDiff = endLine - startLine;
|
|
let colDiff = endCol - startCol;
|
|
let start = originalMap.findClosestMapping(startLine, startCol - 1);
|
|
let end = originalMap.findClosestMapping(endLine, endCol - 1);
|
|
|
|
if (start?.original) {
|
|
if (start.source) {
|
|
filePath = start.source;
|
|
}
|
|
|
|
({line: startLine, column: startCol} = start.original);
|
|
startCol++; // source map columns are 0-based
|
|
}
|
|
|
|
if (end?.original) {
|
|
({line: endLine, column: endCol} = end.original);
|
|
endCol++; // source map columns are 0-based
|
|
|
|
if (endLine < startLine) {
|
|
endLine = startLine;
|
|
endCol = startCol;
|
|
} else if (endLine === startLine && endCol < startCol && lineDiff === 0) {
|
|
endCol = startCol + colDiff;
|
|
} else if (endLine === startLine && startCol === endCol && lineDiff === 0) {
|
|
// Prevent 0-length ranges
|
|
endCol = startCol + 1;
|
|
}
|
|
} else {
|
|
endLine = startLine;
|
|
endCol = startCol;
|
|
}
|
|
|
|
return {
|
|
filePath,
|
|
start: {
|
|
line: startLine,
|
|
column: startCol,
|
|
},
|
|
end: {
|
|
line: endLine,
|
|
column: endCol,
|
|
},
|
|
};
|
|
}
|