"use strict";
|
|
Object.defineProperty(exports, "__esModule", {
|
value: true
|
});
|
exports.default = mergeSourceMap;
|
|
function _sourceMap() {
|
const data = require("source-map");
|
|
_sourceMap = function () {
|
return data;
|
};
|
|
return data;
|
}
|
|
function mergeSourceMap(inputMap, map) {
|
const input = buildMappingData(inputMap);
|
const output = buildMappingData(map);
|
const mergedGenerator = new (_sourceMap().SourceMapGenerator)();
|
|
for (const {
|
source
|
} of input.sources) {
|
if (typeof source.content === "string") {
|
mergedGenerator.setSourceContent(source.path, source.content);
|
}
|
}
|
|
if (output.sources.length === 1) {
|
const defaultSource = output.sources[0];
|
const insertedMappings = new Map();
|
eachInputGeneratedRange(input, (generated, original, source) => {
|
eachOverlappingGeneratedOutputRange(defaultSource, generated, item => {
|
const key = makeMappingKey(item);
|
if (insertedMappings.has(key)) return;
|
insertedMappings.set(key, item);
|
mergedGenerator.addMapping({
|
source: source.path,
|
original: {
|
line: original.line,
|
column: original.columnStart
|
},
|
generated: {
|
line: item.line,
|
column: item.columnStart
|
},
|
name: original.name
|
});
|
});
|
});
|
|
for (const item of insertedMappings.values()) {
|
if (item.columnEnd === Infinity) {
|
continue;
|
}
|
|
const clearItem = {
|
line: item.line,
|
columnStart: item.columnEnd
|
};
|
const key = makeMappingKey(clearItem);
|
|
if (insertedMappings.has(key)) {
|
continue;
|
}
|
|
mergedGenerator.addMapping({
|
generated: {
|
line: clearItem.line,
|
column: clearItem.columnStart
|
}
|
});
|
}
|
}
|
|
const result = mergedGenerator.toJSON();
|
|
if (typeof input.sourceRoot === "string") {
|
result.sourceRoot = input.sourceRoot;
|
}
|
|
return result;
|
}
|
|
function makeMappingKey(item) {
|
return `${item.line}/${item.columnStart}`;
|
}
|
|
function eachOverlappingGeneratedOutputRange(outputFile, inputGeneratedRange, callback) {
|
const overlappingOriginal = filterApplicableOriginalRanges(outputFile, inputGeneratedRange);
|
|
for (const {
|
generated
|
} of overlappingOriginal) {
|
for (const item of generated) {
|
callback(item);
|
}
|
}
|
}
|
|
function filterApplicableOriginalRanges({
|
mappings
|
}, {
|
line,
|
columnStart,
|
columnEnd
|
}) {
|
return filterSortedArray(mappings, ({
|
original: outOriginal
|
}) => {
|
if (line > outOriginal.line) return -1;
|
if (line < outOriginal.line) return 1;
|
if (columnStart >= outOriginal.columnEnd) return -1;
|
if (columnEnd <= outOriginal.columnStart) return 1;
|
return 0;
|
});
|
}
|
|
function eachInputGeneratedRange(map, callback) {
|
for (const {
|
source,
|
mappings
|
} of map.sources) {
|
for (const {
|
original,
|
generated
|
} of mappings) {
|
for (const item of generated) {
|
callback(item, original, source);
|
}
|
}
|
}
|
}
|
|
function buildMappingData(map) {
|
const consumer = new (_sourceMap().SourceMapConsumer)(Object.assign({}, map, {
|
sourceRoot: null
|
}));
|
const sources = new Map();
|
const mappings = new Map();
|
let last = null;
|
consumer.computeColumnSpans();
|
consumer.eachMapping(m => {
|
if (m.originalLine === null) return;
|
let source = sources.get(m.source);
|
|
if (!source) {
|
source = {
|
path: m.source,
|
content: consumer.sourceContentFor(m.source, true)
|
};
|
sources.set(m.source, source);
|
}
|
|
let sourceData = mappings.get(source);
|
|
if (!sourceData) {
|
sourceData = {
|
source,
|
mappings: []
|
};
|
mappings.set(source, sourceData);
|
}
|
|
const obj = {
|
line: m.originalLine,
|
columnStart: m.originalColumn,
|
columnEnd: Infinity,
|
name: m.name
|
};
|
|
if (last && last.source === source && last.mapping.line === m.originalLine) {
|
last.mapping.columnEnd = m.originalColumn;
|
}
|
|
last = {
|
source,
|
mapping: obj
|
};
|
sourceData.mappings.push({
|
original: obj,
|
generated: consumer.allGeneratedPositionsFor({
|
source: m.source,
|
line: m.originalLine,
|
column: m.originalColumn
|
}).map(item => ({
|
line: item.line,
|
columnStart: item.column,
|
columnEnd: item.lastColumn + 1
|
}))
|
});
|
}, null, _sourceMap().SourceMapConsumer.ORIGINAL_ORDER);
|
return {
|
file: map.file,
|
sourceRoot: map.sourceRoot,
|
sources: Array.from(mappings.values())
|
};
|
}
|
|
function findInsertionLocation(array, callback) {
|
let left = 0;
|
let right = array.length;
|
|
while (left < right) {
|
const mid = Math.floor((left + right) / 2);
|
const item = array[mid];
|
const result = callback(item);
|
|
if (result === 0) {
|
left = mid;
|
break;
|
}
|
|
if (result >= 0) {
|
right = mid;
|
} else {
|
left = mid + 1;
|
}
|
}
|
|
let i = left;
|
|
if (i < array.length) {
|
while (i >= 0 && callback(array[i]) >= 0) {
|
i--;
|
}
|
|
return i + 1;
|
}
|
|
return i;
|
}
|
|
function filterSortedArray(array, callback) {
|
const start = findInsertionLocation(array, callback);
|
const results = [];
|
|
for (let i = start; i < array.length && callback(array[i]) === 0; i++) {
|
results.push(array[i]);
|
}
|
|
return results;
|
}
|