// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
import * as fs from "fs";
import { SourceMapConsumer, RawSourceMap, SourceMapGenerator, MappingItem, Mapping, Position, MappedPosition } from "source-map";
import sourceMapResolve = require("source-map-resolve");
export class SourceMapsCombinator {
public convert(rawBundleSourcemap: RawSourceMap): RawSourceMap {
// Find user files from bundle files list
const consumers: { [key: string]: SourceMapConsumer } = rawBundleSourcemap.sources
.reduce((result, file) => {
// Skip files inside node_modules
if (file.indexOf("node_modules") >= 0) return result;
try {
let consumer: SourceMapConsumer = this.getSourceMapConsumerFrom(file);
if (consumer)
result[file] = consumer;
} finally {
return result;
}
}, {});
if (Object.keys(consumers).length === 0) {
// Sourcemaps not found, so return original bundle sourcemap
return rawBundleSourcemap;
}
const generator = new SourceMapGenerator();
const bundleConsumer = new SourceMapConsumer(rawBundleSourcemap);
bundleConsumer.eachMapping((item: MappingItem) => {
if (item.source === null) {
// Some mappings in react native bundle have no sources
return;
}
// Copy mappings
let mapping: Mapping = {
generated: { line: item.generatedLine, column: item.generatedColumn },
original: { line: item.originalLine, column: item.originalColumn },
source: item.source,
name: item.name,
};
if (consumers[item.source]) {
let jsPosition: Position = { line: item.originalLine, column: item.originalColumn };
let tsPosition: MappedPosition = consumers[item.source].originalPositionFor(jsPosition);
if (tsPosition.source === null) {
// Some positions from react native generated bundle can not translate to TS source positions
// skip them
return;
}
// Update mapping w/ mapped position values
mapping = {
...mapping, ...tsPosition,
original: { line: tsPosition.line, column: tsPosition.column },
};
}
try {
generator.addMapping(mapping);
} catch (err) {
}
});
return generator.toJSON();
}
private getSourceMapConsumerFrom(generatedFile: string): SourceMapConsumer | null {
let code = fs.readFileSync(generatedFile);
let consumer = this.readSourcemap(generatedFile, code.toString());
return consumer;
}
private readSourcemap(file: string, code: string): SourceMapConsumer | null {
let result = sourceMapResolve.resolveSync(code, file, fs.readFileSync);
if (result === null) {
return null;
}
return new SourceMapConsumer(result.map);
}
}microsoft/vscode-react-native
Publicmirrored fromhttps://github.com/microsoft/vscode-react-nativeAvailable
src/debugger/sourceMapsCombinator.ts
90lines · modepreview