mirror of
https://github.com/idanoo/GoScrobble.git
synced 2024-11-25 09:55:15 +00:00
109 lines
3.1 KiB
JavaScript
109 lines
3.1 KiB
JavaScript
"use strict";
|
|
|
|
/*
|
|
Copyright 2019 Google LLC
|
|
|
|
Use of this source code is governed by an MIT-style
|
|
license that can be found in the LICENSE file or at
|
|
https://opensource.org/licenses/MIT.
|
|
*/
|
|
const {
|
|
SourceMapConsumer,
|
|
SourceMapGenerator
|
|
} = require('source-map');
|
|
/**
|
|
* Adapted from https://github.com/nsams/sourcemap-aware-replace, with modern
|
|
* JavaScript updates, along with additional properties copied from originalMap.
|
|
*
|
|
* @param {Object} options
|
|
* @param {string} options.jsFilename The name for the file whose contents
|
|
* correspond to originalSource.
|
|
* @param {Object} options.originalMap The sourcemap for originalSource,
|
|
* prior to any replacements.
|
|
* @param {string} options.originalSource The source code, prior to any
|
|
* replacements.
|
|
* @param {string} options.replaceString A string to swap in for searchString.
|
|
* @param {string} options.searchString A string in originalSource to replace.
|
|
* Only the first occurrence will be replaced.
|
|
* @return {{source: string, map: string}} An object containing both
|
|
* originalSource with the replacement applied, and the modified originalMap.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
|
|
async function replaceAndUpdateSourceMap({
|
|
jsFilename,
|
|
originalMap,
|
|
originalSource,
|
|
replaceString,
|
|
searchString
|
|
}) {
|
|
const generator = new SourceMapGenerator({
|
|
file: jsFilename
|
|
});
|
|
const consumer = await new SourceMapConsumer(originalMap);
|
|
let pos;
|
|
let src = originalSource;
|
|
const replacements = [];
|
|
let lineNum = 0;
|
|
let filePos = 0;
|
|
const lines = src.split('\n');
|
|
|
|
for (let line of lines) {
|
|
lineNum++;
|
|
let searchPos = 0;
|
|
|
|
while ((pos = line.indexOf(searchString, searchPos)) !== -1) {
|
|
src = src.substring(0, filePos + pos) + replaceString + src.substring(filePos + pos + searchString.length);
|
|
line = line.substring(0, pos) + replaceString + line.substring(pos + searchString.length);
|
|
replacements.push({
|
|
line: lineNum,
|
|
column: pos
|
|
});
|
|
searchPos = pos + replaceString.length;
|
|
}
|
|
|
|
filePos += line.length + 1;
|
|
}
|
|
|
|
replacements.reverse();
|
|
consumer.eachMapping(mapping => {
|
|
for (const replacement of replacements) {
|
|
if (replacement.line == mapping.generatedLine && mapping.generatedColumn > replacement.column) {
|
|
const offset = searchString.length - replaceString.length;
|
|
mapping.generatedColumn -= offset;
|
|
}
|
|
}
|
|
|
|
if (mapping.source) {
|
|
const newMapping = {
|
|
generated: {
|
|
line: mapping.generatedLine,
|
|
column: mapping.generatedColumn
|
|
},
|
|
original: {
|
|
line: mapping.originalLine,
|
|
column: mapping.originalColumn
|
|
},
|
|
source: mapping.source
|
|
};
|
|
return generator.addMapping(newMapping);
|
|
}
|
|
|
|
return mapping;
|
|
});
|
|
consumer.destroy();
|
|
const updatedSourceMap = Object.assign(JSON.parse(generator.toString()), {
|
|
names: originalMap.names,
|
|
sourceRoot: originalMap.sourceRoot,
|
|
sources: originalMap.sources,
|
|
sourcesContent: originalMap.sourcesContent
|
|
});
|
|
return {
|
|
map: JSON.stringify(updatedSourceMap),
|
|
source: src
|
|
};
|
|
}
|
|
|
|
module.exports = replaceAndUpdateSourceMap; |