mirror of
https://github.com/Sevichecc/Urara-Blog.git
synced 2025-05-02 16:29:30 +08:00
122 lines
3.4 KiB
Text
122 lines
3.4 KiB
Text
/*
|
|
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.
|
|
*/
|
|
|
|
import {RawSourceMap, SourceMapConsumer, SourceMapGenerator} from '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
|
|
*/
|
|
export async function replaceAndUpdateSourceMap({
|
|
jsFilename,
|
|
originalMap,
|
|
originalSource,
|
|
replaceString,
|
|
searchString,
|
|
}: {
|
|
jsFilename: string;
|
|
originalMap: RawSourceMap;
|
|
originalSource: string;
|
|
replaceString: string;
|
|
searchString: string;
|
|
}): Promise<{map: string; source: string}> {
|
|
const generator = new SourceMapGenerator({
|
|
file: jsFilename,
|
|
});
|
|
|
|
const consumer = await new SourceMapConsumer(originalMap);
|
|
|
|
let pos: number;
|
|
let src = originalSource;
|
|
const replacements: Array<{line: number; column: number}> = [];
|
|
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();
|
|
// JSON.parse returns any.
|
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
const updatedSourceMap: RawSourceMap = 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,
|
|
};
|
|
}
|