123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- "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;
|