UNPKG

1.75 kBJavaScriptView Raw
1// @flow
2import type {FileSystem} from '@parcel/fs';
3import SourceMap from '@parcel/source-map';
4import path from 'path';
5import {normalizeSeparators} from './path';
6
7const SOURCEMAP_RE = /(?:\/\*|\/\/)\s*[@#]\s*sourceMappingURL\s*=\s*([^\s*]+)(?:\s*\*\/)?\s*$/;
8const DATA_URL_RE = /^data:[^;]+(?:;charset=[^;]+)?;base64,(.*)/;
9
10export function matchSourceMappingURL(contents: string) {
11 return contents.match(SOURCEMAP_RE);
12}
13
14export async function loadSourceMapUrl(
15 fs: FileSystem,
16 filename: string,
17 contents: string,
18) {
19 let match = matchSourceMappingURL(contents);
20 if (match) {
21 let url = match[1].trim();
22 let dataURLMatch = url.match(DATA_URL_RE);
23 filename = dataURLMatch ? filename : path.join(path.dirname(filename), url);
24
25 return {
26 url,
27 filename,
28 map: JSON.parse(
29 dataURLMatch
30 ? Buffer.from(dataURLMatch[1], 'base64').toString()
31 : await fs.readFile(filename, 'utf8'),
32 ),
33 };
34 }
35}
36
37export async function loadSourceMap(
38 filename: string,
39 contents: string,
40 options: {fs: FileSystem, projectRoot: string, ...},
41): Promise<?SourceMap> {
42 let foundMap = await loadSourceMapUrl(options.fs, filename, contents);
43 if (foundMap) {
44 let mapSourceRoot = path.dirname(filename);
45 if (
46 foundMap.map.sourceRoot &&
47 !normalizeSeparators(foundMap.map.sourceRoot).startsWith('/')
48 ) {
49 mapSourceRoot = path.join(mapSourceRoot, foundMap.map.sourceRoot);
50 }
51
52 let sourcemapInstance = new SourceMap();
53 sourcemapInstance.addRawMappings({
54 ...foundMap.map,
55 sources: foundMap.map.sources.map(s => {
56 return path.relative(options.projectRoot, path.join(mapSourceRoot, s));
57 }),
58 });
59 return sourcemapInstance;
60 }
61}