Socket
Socket
Sign inDemoInstall

webpack-sources

Package Overview
Dependencies
Maintainers
5
Versions
50
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

webpack-sources - npm Package Compare versions

Comparing version 2.3.1 to 3.0.0

lib/helpers/createMappingsSerializer.js

157

lib/CachedSource.js

@@ -8,7 +8,6 @@ /*

const Source = require("./Source");
const { SourceMapConsumer, SourceNode } = require("source-map");
const { SourceListMap, fromStringWithSourceMap } = require("source-list-map");
const streamChunksOfSourceMap = require("./helpers/streamChunksOfSourceMap");
const streamChunksOfRawSource = require("./helpers/streamChunksOfRawSource");
const streamAndGetSourceAndMap = require("./helpers/streamAndGetSourceAndMap");
const LIST_MAP_OPTIONS = { columns: false };
const mapToBufferedMap = map => {

@@ -42,21 +41,2 @@ if (typeof map !== "object" || !map) return map;

const sourceAndMapToNode = (source, map) => {
if (map) {
return SourceNode.fromStringWithSourceMap(
source,
new SourceMapConsumer(map)
);
} else {
return new SourceNode(null, null, null, source);
}
};
const sourceAndMapToListMap = (source, map) => {
if (map) {
return fromStringWithSourceMap(source, map);
} else {
return new SourceListMap(source);
}
};
class CachedSource extends Source {

@@ -85,4 +65,2 @@ constructor(source, cachedData) {

map: undefined,
node: undefined,
listMap: undefined,
bufferedMap: cacheEntry.bufferedMap

@@ -134,14 +112,2 @@ });

return (cacheEntry.map = bufferedMapToMap(cacheEntry.bufferedMap));
} else if (cacheEntry.node !== undefined) {
const result = cacheEntry.node.toStringWithSourceMap({
file: "x"
});
if (this._cachedSource === undefined) this._cachedSource = result.code;
return (cacheEntry.map = result.map.toJSON());
} else if (cacheEntry.listMap !== undefined) {
const result = cacheEntry.listMap.toStringWithSourceMap({
file: "x"
});
if (this._cachedSource === undefined) this._cachedSource = result.source;
return (cacheEntry.map = result.map);
}

@@ -157,10 +123,2 @@ }

}
for (const cacheEntry of this._cachedMaps.values()) {
if (cacheEntry.node !== undefined) {
return (this._cachedSource = cacheEntry.node.toString());
}
if (cacheEntry.listMap !== undefined) {
return (this._cachedSource = cacheEntry.listMap.toString());
}
}
}

@@ -223,4 +181,2 @@

map,
node: undefined,
listMap: undefined,
bufferedMap: undefined

@@ -231,74 +187,41 @@ });

node(options) {
streamChunks(options, onChunk, onSource, onName) {
const key = options ? JSON.stringify(options) : "{}";
let cacheEntry = this._cachedMaps.get(key);
// Check cache
if (cacheEntry !== undefined) {
// Directly cached
if (cacheEntry.node) return cacheEntry.node;
// Construct from cached map
const map = this._getMapFromCacheEntry(cacheEntry);
const source = this.source();
const node = sourceAndMapToNode(source, map);
cacheEntry.node = node;
return node;
}
let node;
const original = this.original();
if (typeof original.node === "function") {
node = original.node(options);
this._cachedMaps.set(key, {
map: undefined,
node,
listMap: undefined,
bufferedMap: undefined
});
} else {
const sourceAndMap = this.sourceAndMap(options);
node = sourceAndMapToNode(sourceAndMap.source, sourceAndMap.map);
this._cachedMaps.get(key).node = node;
}
return node;
}
listMap(options) {
let key;
// Enforce options must include columns: false
if (!options) {
key = '{"columns":false}';
options = LIST_MAP_OPTIONS;
} else {
if (options.columns !== false) {
options = Object.assign({}, options, LIST_MAP_OPTIONS);
if (
this._cachedMaps.has(key) &&
(this._cachedBuffer !== undefined || this._cachedSource !== undefined)
) {
const { source, map } = this.sourceAndMap(options);
if (map) {
return streamChunksOfSourceMap(
source,
map,
onChunk,
onSource,
onName,
!!(options && options.finalSource)
);
} else {
return streamChunksOfRawSource(
source,
onChunk,
onSource,
onName,
!!(options && options.finalSource)
);
}
key = JSON.stringify(options);
}
// Check cache
let cacheEntry = this._cachedMaps.get(key);
if (cacheEntry !== undefined) {
// Directly cached
if (cacheEntry.listMap) return cacheEntry.listMap;
// Construct from cached map
const map = this._getMapFromCacheEntry(cacheEntry);
const source = this.source();
const listMap = sourceAndMapToListMap(source, map);
cacheEntry.listMap = listMap;
return listMap;
}
let listMap;
const original = this.original();
if (typeof original.listMap === "function") {
listMap = original.listMap(options);
this._cachedMaps.set(key, {
map: undefined,
node: undefined,
listMap,
bufferedMap: undefined
});
} else {
const sourceAndMap = this.sourceAndMap(options);
listMap = sourceAndMapToListMap(sourceAndMap.source, sourceAndMap.map);
this._cachedMaps.get(key).listMap = listMap;
}
return listMap;
const { result, source, map } = streamAndGetSourceAndMap(
this.original(),
options,
onChunk,
onSource,
onName
);
this._cachedSource = source;
this._cachedMaps.set(key, {
map,
bufferedMap: undefined
});
return result;
}

@@ -315,4 +238,2 @@

map,
node: undefined,
listMap: undefined,
bufferedMap: undefined

@@ -319,0 +240,0 @@ });

@@ -9,5 +9,4 @@ /*

const RawSource = require("./RawSource");
const { SourceNode, SourceMapConsumer } = require("source-map");
const { SourceListMap, fromStringWithSourceMap } = require("source-list-map");
const { getSourceAndMap, getMap } = require("./helpers");
const streamChunks = require("./helpers/streamChunks");
const { getMap, getSourceAndMap } = require("./helpers/getFromStreamChunks");

@@ -99,44 +98,135 @@ const stringsAsRawSources = new WeakSet();

node(options) {
streamChunks(options, onChunk, onSource, onName) {
if (!this._isOptimized) this._optimize();
const node = new SourceNode(
null,
null,
null,
this._children.map(function (item) {
if (typeof item.node === "function") return item.node(options);
const sourceAndMap = item.sourceAndMap(options);
if (sourceAndMap.map) {
return SourceNode.fromStringWithSourceMap(
sourceAndMap.source,
new SourceMapConsumer(sourceAndMap.map)
);
} else {
return sourceAndMap.source;
if (this._children.length === 1)
return this._children[0].streamChunks(options, onChunk, onSource, onName);
let currentLineOffset = 0;
let currentColumnOffset = 0;
let sourceMapping = new Map();
let nameMapping = new Map();
const finalSource = !!(options && options.finalSource);
let code = "";
let needToCloseMapping = false;
for (const item of this._children) {
const sourceIndexMapping = [];
const nameIndexMapping = [];
let lastMappingLine = 0;
const { generatedLine, generatedColumn, source } = streamChunks(
item,
options,
// eslint-disable-next-line no-loop-func
(
chunk,
generatedLine,
generatedColumn,
sourceIndex,
originalLine,
originalColumn,
nameIndex
) => {
const line = generatedLine + currentLineOffset;
const column =
generatedLine === 1
? generatedColumn + currentColumnOffset
: generatedColumn;
if (needToCloseMapping) {
if (generatedLine !== 1 || generatedColumn !== 0) {
onChunk(
undefined,
currentLineOffset + 1,
currentColumnOffset,
-1,
-1,
-1,
-1
);
}
needToCloseMapping = false;
}
const resultSourceIndex =
sourceIndex < 0 ? -1 : sourceIndexMapping[sourceIndex];
const resultNameIndex =
nameIndex < 0 ? -1 : nameIndexMapping[nameIndex];
lastMappingLine = resultSourceIndex < 0 ? 0 : generatedLine;
if (finalSource && chunk !== undefined) {
code += chunk;
onChunk(
undefined,
line,
column,
resultSourceIndex,
originalLine,
originalColumn,
resultNameIndex
);
} else {
onChunk(
chunk,
line,
column,
resultSourceIndex,
originalLine,
originalColumn,
resultNameIndex
);
}
},
(i, source, sourceContent) => {
let globalIndex = sourceMapping.get(source);
if (globalIndex === undefined) {
sourceMapping.set(source, (globalIndex = sourceMapping.size));
onSource(globalIndex, source, sourceContent);
}
sourceIndexMapping[i] = globalIndex;
},
(i, name) => {
let globalIndex = nameMapping.get(name);
if (globalIndex === undefined) {
nameMapping.set(name, (globalIndex = nameMapping.size));
onName(globalIndex, name);
}
nameIndexMapping[i] = globalIndex;
}
})
);
return node;
}
listMap(options) {
if (!this._isOptimized) this._optimize();
const map = new SourceListMap();
for (const item of this._children) {
if (typeof item === "string") {
map.add(item);
} else if (typeof item.listMap === "function") {
map.add(item.listMap(options));
} else {
const sourceAndMap = item.sourceAndMap(options);
if (sourceAndMap.map) {
map.add(
fromStringWithSourceMap(sourceAndMap.source, sourceAndMap.map)
);
if (source !== undefined) code += source;
if (needToCloseMapping) {
if (generatedLine !== 1 || generatedColumn !== 0) {
onChunk(
undefined,
currentLineOffset + 1,
currentColumnOffset,
-1,
-1,
-1,
-1
);
} else {
map.add(sourceAndMap.source);
needToCloseMapping = false;
}
}
if (generatedLine > 1) {
currentColumnOffset = generatedColumn;
} else {
currentColumnOffset += generatedColumn;
}
needToCloseMapping =
needToCloseMapping ||
(finalSource && lastMappingLine === generatedLine);
currentLineOffset += generatedLine - 1;
}
return map;
if (needToCloseMapping) {
onChunk(
undefined,
currentLineOffset + 1,
currentColumnOffset,
-1,
-1,
-1,
-1
);
}
return {
generatedLine: currentLineOffset,
generatedColumn: currentColumnOffset,
source: finalSource ? code : undefined
};
}

@@ -143,0 +233,0 @@

@@ -7,13 +7,9 @@ /*

const { getMap, getSourceAndMap } = require("./helpers/getFromStreamChunks");
const getGeneratedSourceInfo = require("./helpers/getGeneratedSourceInfo");
const Source = require("./Source");
const { SourceNode } = require("source-map");
const { SourceListMap } = require("source-list-map");
const { getSourceAndMap, getMap } = require("./helpers");
const SPLIT_REGEX = /(?!$)[^\n\r;{}]*[\n\r;{}]*/g;
const SPLIT_REGEX = /[^\n;{}]+[;{} \r\t]*\n?|[;{} \r\t]+\n?|\n/g;
const SPLIT_LINES_REGEX = /[^\n]+\n?|\n/g;
function _splitCode(code) {
return code.match(SPLIT_REGEX) || [];
}
class OriginalSource extends Source {

@@ -54,46 +50,84 @@ constructor(value, name) {

node(options) {
/**
* @param {object} options options
* @param {function(string, number, number, number, number, number, number): void} onChunk called for each chunk of code
* @param {function(number, string, string)} onSource called for each source
* @param {function(number, string)} onName called for each name
* @returns {void}
*/
streamChunks(options, onChunk, onSource, onName) {
if (this._value === undefined) {
this._value = this._valueAsBuffer.toString("utf-8");
}
const value = this._value;
const name = this._name;
const lines = value.split("\n");
const node = new SourceNode(
null,
null,
null,
lines.map(function (line, idx) {
let pos = 0;
if (options && options.columns === false) {
const content = line + (idx !== lines.length - 1 ? "\n" : "");
return new SourceNode(idx + 1, 0, name, content);
onSource(0, this._name, this._value);
const finalSource = !!(options && options.finalSource);
if (!options || options.columns !== false) {
// With column info we need to read all lines and split them
const matches = this._value.match(SPLIT_REGEX);
let line = 1;
let column = 0;
if (matches !== null) {
for (const match of matches) {
const isEndOfLine = match.endsWith("\n");
if (isEndOfLine && match.length === 1) {
if (!finalSource) onChunk(match, line, column, -1, -1, -1, -1);
} else {
const chunk = finalSource ? undefined : match;
onChunk(chunk, line, column, 0, line, column, -1);
}
if (isEndOfLine) {
line++;
column = 0;
} else {
column += match.length;
}
}
return new SourceNode(
null,
null,
null,
_splitCode(line + (idx !== lines.length - 1 ? "\n" : "")).map(
function (item) {
if (/^\s*$/.test(item)) {
pos += item.length;
return item;
}
const res = new SourceNode(idx + 1, pos, name, item);
pos += item.length;
return res;
}
)
);
})
);
node.setSourceContent(name, value);
return node;
}
listMap(options) {
if (this._value === undefined) {
this._value = this._valueAsBuffer.toString("utf-8");
}
return {
generatedLine: line,
generatedColumn: column,
source: finalSource ? this._value : undefined
};
} else if (finalSource) {
// Without column info and with final source we only
// need meta info to generate mapping
const result = getGeneratedSourceInfo(this._value);
const { generatedLine, generatedColumn } = result;
if (generatedColumn === 0) {
for (let line = 1; line < generatedLine; line++)
onChunk(undefined, line, 0, 0, line, 0, -1);
} else {
for (let line = 1; line <= generatedLine; line++)
onChunk(undefined, line, 0, 0, line, 0, -1);
}
return result;
} else {
// Without column info, but also without final source
// we need to split source by lines
let line = 1;
const matches = this._value.match(SPLIT_LINES_REGEX);
if (matches !== null) {
let match;
for (match of matches) {
onChunk(finalSource ? undefined : match, line, 0, 0, line, 0, -1);
line++;
}
return match.endsWith("\n")
? {
generatedLine: matches.length + 1,
generatedColumn: 0,
source: finalSource ? this._value : undefined
}
: {
generatedLine: matches.length,
generatedColumn: match.length,
source: finalSource ? this._value : undefined
};
}
return {
generatedLine: 1,
generatedColumn: 0,
source: finalSource ? this._value : undefined
};
}
return new SourceListMap(this._value, this._name, this._value);
}

@@ -100,0 +134,0 @@

@@ -9,4 +9,4 @@ /*

const RawSource = require("./RawSource");
const { SourceNode } = require("source-map");
const { getSourceAndMap, getMap } = require("./helpers");
const streamChunks = require("./helpers/streamChunks");
const { getMap, getSourceAndMap } = require("./helpers/getFromStreamChunks");

@@ -49,49 +49,61 @@ const REPLACE_REGEX = /\n(?=.|\s)/g;

node(options) {
const node = this._source.node(options);
streamChunks(options, onChunk, onSource, onName) {
const prefix = this._prefix;
const output = [];
const result = new SourceNode();
node.walkSourceContents(function (source, content) {
result.setSourceContent(source, content);
});
let needPrefix = true;
node.walk(function (chunk, mapping) {
const parts = chunk.split(/(\n)/);
for (let i = 0; i < parts.length; i += 2) {
const nl = i + 1 < parts.length;
const part = parts[i] + (nl ? "\n" : "");
if (part) {
if (needPrefix) {
output.push(prefix);
const prefixOffset = prefix.length;
const linesOnly = !!(options && options.columns === false);
const { generatedLine, generatedColumn, source } = streamChunks(
this._source,
options,
(
chunk,
generatedLine,
generatedColumn,
sourceIndex,
originalLine,
originalColumn,
nameIndex
) => {
if (generatedColumn !== 0) {
// In the middle of the line, we just adject the column
generatedColumn += prefixOffset;
} else if (chunk !== undefined) {
// At the start of the line, when we have source content
// add the prefix as generated mapping
// (in lines only mode we just add it to the original mapping
// for performance reasons)
if (linesOnly || sourceIndex < 0) {
chunk = prefix + chunk;
} else {
onChunk(prefix, generatedLine, generatedColumn, -1, -1, -1, -1);
generatedColumn += prefixOffset;
}
output.push(
new SourceNode(
mapping.line,
mapping.column,
mapping.source,
part,
mapping.name
)
);
needPrefix = nl;
} else if (!linesOnly) {
// Without source content, we only need to adject the column info
// expect in lines only mode where prefix is added to original mapping
generatedColumn += prefixOffset;
}
}
});
result.add(output);
return result;
onChunk(
chunk,
generatedLine,
generatedColumn,
sourceIndex,
originalLine,
originalColumn,
nameIndex
);
},
onSource,
onName
);
return {
generatedLine,
generatedColumn:
generatedColumn === 0 ? 0 : prefixOffset + generatedColumn,
source:
source !== undefined
? prefix + source.replace(REPLACE_REGEX, "\n" + prefix)
: undefined
};
}
listMap(options) {
const prefix = this._prefix;
const map = this._source.listMap(options);
let prefixNextLine = true;
return map.mapGeneratedCode(function (code) {
let updatedCode = code.replace(REPLACE_REGEX, "\n" + prefix);
if (prefixNextLine) updatedCode = prefix + updatedCode;
prefixNextLine = code.charCodeAt(code.length - 1) === 10; // === /\n$/.test(code)
return updatedCode;
});
}
updateHash(hash) {

@@ -98,0 +110,0 @@ hash.update("PrefixSource");

@@ -5,7 +5,7 @@ /*

*/
"use strict";
const streamChunksOfRawSource = require("./helpers/streamChunksOfRawSource");
const Source = require("./Source");
const { SourceNode } = require("source-map");
const { SourceListMap } = require("source-list-map");

@@ -46,16 +46,22 @@ class RawSource extends Source {

node(options) {
/**
* @param {object} options options
* @param {function(string, number, number, number, number, number, number): void} onChunk called for each chunk of code
* @param {function(number, string, string)} onSource called for each source
* @param {function(number, string)} onName called for each name
* @returns {void}
*/
streamChunks(options, onChunk, onSource, onName) {
if (this._value === undefined) {
this._value = this._valueAsBuffer.toString("utf-8");
}
return new SourceNode(null, null, null, this._value);
return streamChunksOfRawSource(
this._value,
onChunk,
onSource,
onName,
!!(options && options.finalSource)
);
}
listMap(options) {
if (this._value === undefined) {
this._value = this._valueAsBuffer.toString("utf-8");
}
return new SourceListMap(this._value);
}
updateHash(hash) {

@@ -62,0 +68,0 @@ if (this._valueAsBuffer === undefined) {

@@ -7,13 +7,27 @@ /*

const { getMap, getSourceAndMap } = require("./helpers/getFromStreamChunks");
const streamChunks = require("./helpers/streamChunks");
const Source = require("./Source");
const { SourceNode } = require("source-map");
const { getSourceAndMap, getMap, getNode, getListMap } = require("./helpers");
// since v8 7.0, Array.prototype.sort is stable
const hasStableSort =
typeof process === "object" &&
process.versions &&
typeof process.versions.v8 === "string" &&
!/^[0-6]\./.test(process.versions.v8);
// This is larger than max string length
const MAX_SOURCE_POSITION = 0x20000000;
const SPLIT_LINES_REGEX = /[^\n]+\n?|\n/g;
class Replacement {
constructor(start, end, content, insertIndex, name) {
constructor(start, end, content, name) {
this.start = start;
this.end = end;
this.content = content;
this.insertIndex = insertIndex;
this.name = name;
if (!hasStableSort) {
this.index = -1;
}
}

@@ -37,7 +51,4 @@ }

getReplacements() {
const replacements = Array.from(this._replacements);
replacements.sort((a, b) => {
return a.insertIndex - b.insertIndex;
});
return replacements;
this._sortReplacements();
return this._replacements;
}

@@ -50,5 +61,3 @@

);
this._replacements.push(
new Replacement(start, end, newValue, this._replacements.length, name)
);
this._replacements.push(new Replacement(start, end + 1, newValue, name));
this._isSorted = false;

@@ -65,5 +74,3 @@ }

);
this._replacements.push(
new Replacement(pos, pos - 1, newValue, this._replacements.length, name)
);
this._replacements.push(new Replacement(pos, pos, newValue, name));
this._isSorted = false;

@@ -73,3 +80,28 @@ }

source() {
return this._replaceString(this._source.source());
if (this._replacements.length === 0) {
return this._source.source();
}
let current = this._source.source();
let pos = 0;
const result = [];
this._sortReplacements();
for (const replacement of this._replacements) {
const start = Math.floor(replacement.start);
const end = Math.floor(replacement.end);
if (pos < start) {
const offset = start - pos;
result.push(current.slice(0, offset));
current = current.slice(offset);
pos = start;
}
result.push(replacement.content);
if (pos < end) {
const offset = end - pos;
current = current.slice(offset);
pos = end;
}
}
result.push(current);
return result.join("");
}

@@ -97,244 +129,330 @@

if (this._isSorted) return;
this._replacements.sort(function (a, b) {
const diff1 = b.end - a.end;
if (diff1 !== 0) return diff1;
const diff2 = b.start - a.start;
if (diff2 !== 0) return diff2;
return b.insertIndex - a.insertIndex;
});
if (hasStableSort) {
this._replacements.sort(function (a, b) {
const diff1 = a.start - b.start;
if (diff1 !== 0) return diff1;
const diff2 = a.end - b.end;
if (diff2 !== 0) return diff2;
return 0;
});
} else {
this._replacements.forEach((repl, i) => (repl.index = i));
this._replacements.sort(function (a, b) {
const diff1 = a.start - b.start;
if (diff1 !== 0) return diff1;
const diff2 = a.end - b.end;
if (diff2 !== 0) return diff2;
return a.index - b.index;
});
}
this._isSorted = true;
}
_replaceString(str) {
if (typeof str !== "string")
throw new Error(
"str must be a string, but is a " + typeof str + ": " + str
streamChunks(options, onChunk, onSource, onName) {
this._sortReplacements();
const repls = this._replacements;
let pos = 0;
let i = 0;
let replacmentEnd = -1;
let nextReplacement =
i < repls.length ? Math.floor(repls[i].start) : MAX_SOURCE_POSITION;
let generatedLineOffset = 0;
let generatedColumnOffset = 0;
let generatedColumnOffsetLine = 0;
const sourceContents = [];
const nameMapping = new Map();
const nameIndexMapping = [];
const checkOriginalContent = (sourceIndex, line, column, expectedChunk) => {
let content =
sourceIndex < sourceContents.length
? sourceContents[sourceIndex]
: undefined;
if (content === undefined) return false;
if (typeof content === "string") {
content = content.match(SPLIT_LINES_REGEX) || [];
sourceContents[sourceIndex] = content;
}
const contentLine = line <= content.length ? content[line - 1] : null;
if (contentLine === null) return false;
return (
contentLine.slice(column, column + expectedChunk.length) ===
expectedChunk
);
this._sortReplacements();
const result = [str];
this._replacements.forEach(function (repl) {
const remSource = result.pop();
const splitted1 = this._splitString(remSource, Math.floor(repl.end + 1));
const splitted2 = this._splitString(splitted1[0], Math.floor(repl.start));
result.push(splitted1[1], repl.content, splitted2[0]);
}, this);
};
let { generatedLine, generatedColumn } = streamChunks(
this._source,
Object.assign({}, options, { finalSource: false }),
(
chunk,
generatedLine,
generatedColumn,
sourceIndex,
originalLine,
originalColumn,
nameIndex
) => {
let chunkPos = 0;
let endPos = pos + chunk.length;
// write out result array in reverse order
let resultStr = "";
for (let i = result.length - 1; i >= 0; --i) {
resultStr += result[i];
}
return resultStr;
}
// Skip over when it has been replaced
if (replacmentEnd > pos) {
// Skip over the whole chunk
if (replacmentEnd >= endPos) {
const line = generatedLine + generatedLineOffset;
if (chunk.endsWith("\n")) {
generatedLineOffset--;
} else if (generatedColumnOffsetLine === line) {
generatedColumnOffset -= chunk.length;
} else {
generatedColumnOffset = chunk.length;
generatedColumnOffsetLine = line;
}
pos = endPos;
return;
}
node(options) {
const node = getNode(this._source, options);
if (this._replacements.length === 0) {
return node;
}
this._sortReplacements();
const replace = new ReplacementEnumerator(this._replacements);
const output = [];
let position = 0;
const sources = Object.create(null);
const sourcesInLines = Object.create(null);
// Partially skip over chunk
chunkPos = replacmentEnd - pos;
if (
checkOriginalContent(
sourceIndex,
originalLine,
originalColumn,
chunk.slice(0, chunkPos)
)
) {
originalColumn += chunkPos;
}
pos += chunkPos;
const line = generatedLine + generatedLineOffset;
if (generatedColumnOffsetLine === line) {
generatedColumnOffset -= chunkPos;
} else {
generatedColumnOffset = chunkPos;
generatedColumnOffsetLine = line;
}
generatedColumn += chunkPos;
}
// We build a new list of SourceNodes in "output"
// from the original mapping data
// Is a replacement in the chunk?
if (nextReplacement < endPos) {
do {
let line = generatedLine + generatedLineOffset;
if (nextReplacement > pos) {
// Emit chunk until replacement
const offset = nextReplacement - pos;
const chunkSlice = chunk.slice(chunkPos, chunkPos + offset);
onChunk(
chunkSlice,
line,
generatedColumn +
(line === generatedColumnOffsetLine
? generatedColumnOffset
: 0),
sourceIndex,
originalLine,
originalColumn,
nameIndex < 0 ? -1 : nameIndexMapping[nameIndex]
);
generatedColumn += offset;
chunkPos += offset;
pos = nextReplacement;
if (
checkOriginalContent(
sourceIndex,
originalLine,
originalColumn,
chunkSlice
)
) {
originalColumn += chunkSlice.length;
}
}
const result = new SourceNode();
// Insert replacement content splitted into chunks by lines
const regexp = /[^\n]+\n?|\n/g;
const { content, name } = repls[i];
let match = regexp.exec(content);
let replacementNameIndex = nameIndex;
if (name) {
let globalIndex = nameMapping.get(name);
if (globalIndex === undefined) {
globalIndex = nameMapping.size;
nameMapping.set(name, globalIndex);
onName(globalIndex, name);
}
replacementNameIndex = globalIndex;
}
while (match !== null) {
const contentLine = match[0];
onChunk(
contentLine,
line,
generatedColumn +
(line === generatedColumnOffsetLine
? generatedColumnOffset
: 0),
sourceIndex,
originalLine,
originalColumn,
replacementNameIndex
);
// We need to add source contents manually
// because "walk" will not handle it
node.walkSourceContents(function (sourceFile, sourceContent) {
result.setSourceContent(sourceFile, sourceContent);
sources["$" + sourceFile] = sourceContent;
});
// Only the first chunk has name assigned
replacementNameIndex = -1;
const replaceInStringNode = this._replaceInStringNode.bind(
this,
output,
replace,
function getOriginalSource(mapping) {
const key = "$" + mapping.source;
let lines = sourcesInLines[key];
if (!lines) {
const source = sources[key];
if (!source) return null;
lines = source.split("\n").map(function (line) {
return line + "\n";
});
sourcesInLines[key] = lines;
}
// line is 1-based
if (mapping.line > lines.length) return null;
const line = lines[mapping.line - 1];
return line.substr(mapping.column);
}
);
match = regexp.exec(content);
if (match === null && !contentLine.endsWith("\n")) {
if (generatedColumnOffsetLine === line) {
generatedColumnOffset += contentLine.length;
} else {
generatedColumnOffset = contentLine.length;
generatedColumnOffsetLine = line;
}
} else {
generatedLineOffset++;
line++;
generatedColumnOffset = -generatedColumn;
generatedColumnOffsetLine = line;
}
}
node.walk(function (chunk, mapping) {
position = replaceInStringNode(chunk, position, mapping);
});
// Remove replaced content by settings this variable
replacmentEnd = Math.max(replacmentEnd, Math.floor(repls[i].end));
// If any replacements occur after the end of the original file, then we append them
// directly to the end of the output
const remaining = replace.footer();
if (remaining) {
output.push(remaining);
}
// Move to next replacment
i++;
nextReplacement =
i < repls.length
? Math.floor(repls[i].start)
: MAX_SOURCE_POSITION;
result.add(output);
// Skip over when it has been replaced
const offset = chunk.length - endPos + replacmentEnd - chunkPos;
if (offset > 0) {
// Skip over whole chunk
if (replacmentEnd >= endPos) {
let line = generatedLine + generatedLineOffset;
if (chunk.endsWith("\n")) {
generatedLineOffset--;
if (generatedColumnOffsetLine === line) {
generatedColumnOffset += generatedColumn;
} else {
generatedColumnOffset = generatedColumn;
generatedColumnOffsetLine = line;
}
} else if (generatedColumnOffsetLine === line) {
generatedColumnOffset -= chunk.length - chunkPos;
} else {
generatedColumnOffset = chunk.length - chunkPos;
generatedColumnOffsetLine = line;
}
pos = endPos;
return;
}
return result;
}
listMap(options) {
let map = getListMap(this._source, options);
this._sortReplacements();
let currentIndex = 0;
const replacements = this._replacements;
let idxReplacement = replacements.length - 1;
let removeChars = 0;
map = map.mapGeneratedCode(function (str) {
const newCurrentIndex = currentIndex + str.length;
if (removeChars > str.length) {
removeChars -= str.length;
str = "";
} else {
if (removeChars > 0) {
str = str.substr(removeChars);
currentIndex += removeChars;
removeChars = 0;
// Partially skip over chunk
const line = generatedLine + generatedLineOffset;
if (
checkOriginalContent(
sourceIndex,
originalLine,
originalColumn,
chunk.slice(chunkPos, chunkPos + offset)
)
) {
originalColumn += offset;
}
chunkPos += offset;
pos += offset;
if (generatedColumnOffsetLine === line) {
generatedColumnOffset -= offset;
} else {
generatedColumnOffset = offset;
generatedColumnOffsetLine = line;
}
generatedColumn += offset;
}
} while (nextReplacement < endPos);
}
let finalStr = "";
while (
idxReplacement >= 0 &&
replacements[idxReplacement].start < newCurrentIndex
) {
const repl = replacements[idxReplacement];
const start = Math.floor(repl.start);
const end = Math.floor(repl.end + 1);
const before = str.substr(0, Math.max(0, start - currentIndex));
if (end <= newCurrentIndex) {
const after = str.substr(Math.max(0, end - currentIndex));
finalStr += before + repl.content;
str = after;
currentIndex = Math.max(currentIndex, end);
} else {
finalStr += before + repl.content;
str = "";
removeChars = end - newCurrentIndex;
}
idxReplacement--;
}
str = finalStr + str;
}
currentIndex = newCurrentIndex;
return str;
});
let extraCode = "";
while (idxReplacement >= 0) {
extraCode += replacements[idxReplacement].content;
idxReplacement--;
}
if (extraCode) {
map.add(extraCode);
}
return map;
}
_splitString(str, position) {
return position <= 0
? ["", str]
: [str.substr(0, position), str.substr(position)];
}
_replaceInStringNode(
output,
replace,
getOriginalSource,
node,
position,
mapping
) {
let original = undefined;
do {
let splitPosition = replace.position - position;
// If multiple replaces occur in the same location then the splitPosition may be
// before the current position for the subsequent splits. Ensure it is >= 0
if (splitPosition < 0) {
splitPosition = 0;
}
if (splitPosition >= node.length || replace.done) {
if (replace.emit) {
const nodeEnd = new SourceNode(
mapping.line,
mapping.column,
mapping.source,
node,
mapping.name
// Emit remaining chunk
if (chunkPos < chunk.length) {
const chunkSlice = chunkPos === 0 ? chunk : chunk.slice(chunkPos);
const line = generatedLine + generatedLineOffset;
onChunk(
chunkSlice,
line,
generatedColumn +
(line === generatedColumnOffsetLine ? generatedColumnOffset : 0),
sourceIndex,
originalLine,
originalColumn,
nameIndex < 0 ? -1 : nameIndexMapping[nameIndex]
);
output.push(nodeEnd);
}
return position + node.length;
pos = endPos;
},
(sourceIndex, source, sourceContent) => {
while (sourceContents.length < sourceIndex)
sourceContents.push(undefined);
sourceContents[sourceIndex] = sourceContent;
onSource(sourceIndex, source, sourceContent);
},
(nameIndex, name) => {
let globalIndex = nameMapping.get(name);
if (globalIndex === undefined) {
globalIndex = nameMapping.size;
nameMapping.set(name, globalIndex);
onName(globalIndex, name);
}
nameIndexMapping[nameIndex] = globalIndex;
}
);
const originalColumn = mapping.column;
// Handle remaining replacements
let remainer = "";
for (; i < repls.length; i++) {
remainer += repls[i].content;
}
// Try to figure out if generated code matches original code of this segement
// If this is the case we assume that it's allowed to move mapping.column
// Because getOriginalSource can be expensive we only do it when neccessary
// Insert remaining replacements content splitted into chunks by lines
let line = generatedLine + generatedLineOffset;
const regexp = /[^\n]+\n?|\n/g;
let match = regexp.exec(remainer);
while (match !== null) {
const contentLine = match[0];
onChunk(
contentLine,
line,
generatedColumn +
(line === generatedColumnOffsetLine ? generatedColumnOffset : 0),
-1,
-1,
-1,
-1
);
let nodePart;
if (splitPosition > 0) {
nodePart = node.slice(0, splitPosition);
if (original === undefined) {
original = getOriginalSource(mapping);
match = regexp.exec(remainer);
if (match === null && !contentLine.endsWith("\n")) {
if (generatedColumnOffsetLine === line) {
generatedColumnOffset += contentLine.length;
} else {
generatedColumnOffset = contentLine.length;
generatedColumnOffsetLine = line;
}
if (
original &&
original.length >= splitPosition &&
original.startsWith(nodePart)
) {
mapping.column += splitPosition;
original = original.substr(splitPosition);
}
} else {
generatedLineOffset++;
line++;
generatedColumnOffset = -generatedColumn;
generatedColumnOffsetLine = line;
}
}
const emit = replace.next();
if (!emit) {
// Stop emitting when we have found the beginning of the string to replace.
// Emit the part of the string before splitPosition
if (splitPosition > 0) {
const nodeStart = new SourceNode(
mapping.line,
originalColumn,
mapping.source,
nodePart,
mapping.name
);
output.push(nodeStart);
}
// Emit the replacement value
if (replace.value) {
output.push(
new SourceNode(
mapping.line,
mapping.column,
mapping.source,
replace.value,
mapping.name || replace.name
)
);
}
}
// Recurse with remainder of the string as there may be multiple replaces within a single node
node = node.substr(splitPosition);
position += splitPosition;
// eslint-disable-next-line no-constant-condition
} while (true);
return {
generatedLine: line,
generatedColumn:
generatedColumn +
(line === generatedColumnOffsetLine ? generatedColumnOffset : 0)
};
}

@@ -357,57 +475,2 @@

class ReplacementEnumerator {
/**
* @param {Replacement[]} replacements list of replacements
*/
constructor(replacements) {
this.replacements = replacements || [];
this.index = this.replacements.length;
this.done = false;
this.emit = false;
// Set initial start position
this.next();
}
next() {
if (this.done) return true;
if (this.emit) {
// Start point found. stop emitting. set position to find end
const repl = this.replacements[this.index];
const end = Math.floor(repl.end + 1);
this.position = end;
this.value = repl.content;
this.name = repl.name;
} else {
// End point found. start emitting. set position to find next start
this.index--;
if (this.index < 0) {
this.done = true;
} else {
const nextRepl = this.replacements[this.index];
const start = Math.floor(nextRepl.start);
this.position = start;
}
}
if (this.position < 0) this.position = 0;
this.emit = !this.emit;
return this.emit;
}
footer() {
if (!this.done && !this.emit) this.next(); // If we finished _replaceInNode mid emit we advance to next entry
if (this.done) {
return [];
} else {
let resultStr = "";
for (let i = this.index; i >= 0; i--) {
const repl = this.replacements[i];
// this doesn't need to handle repl.name, because in SourceMaps generated code
// without pointer to original source can't have a name
resultStr += repl.content;
}
return resultStr;
}
}
}
module.exports = ReplaceSource;

@@ -8,6 +8,5 @@ /*

const Source = require("./Source");
const { SourceNode, SourceMapConsumer } = require("source-map");
const { SourceListMap, fromStringWithSourceMap } = require("source-list-map");
const { getSourceAndMap, getMap } = require("./helpers");
const applySourceMap = require("./applySourceMap");
const streamChunksOfSourceMap = require("./helpers/streamChunksOfSourceMap");
const streamChunksOfCombinedSourceMap = require("./helpers/streamChunksOfCombinedSourceMap");
const { getMap, getSourceAndMap } = require("./helpers/getFromStreamChunks");

@@ -188,38 +187,30 @@ class SourceMapSource extends Source {

node(options) {
streamChunks(options, onChunk, onSource, onName) {
this._ensureValueString();
this._ensureSourceMapObject();
this._ensureOriginalSourceString();
let node = SourceNode.fromStringWithSourceMap(
this._valueAsString,
new SourceMapConsumer(this._sourceMapAsObject)
);
node.setSourceContent(this._name, this._originalSourceAsString);
if (this._hasInnerSourceMap) {
this._ensureInnerSourceMapObject();
node = applySourceMap(
node,
new SourceMapConsumer(this._innerSourceMapAsObject),
return streamChunksOfCombinedSourceMap(
this._valueAsString,
this._sourceMapAsObject,
this._name,
this._removeOriginalSource
this._originalSourceAsString,
this._innerSourceMapAsObject,
this._removeOriginalSource,
onChunk,
onSource,
onName,
!!(options && options.finalSource)
);
}
return node;
}
listMap(options) {
this._ensureValueString();
this._ensureSourceMapObject();
options = options || {};
if (options.module === false)
return new SourceListMap(
} else {
return streamChunksOfSourceMap(
this._valueAsString,
this._name,
this._valueAsString
this._sourceMapAsObject,
onChunk,
onSource,
onName,
!!(options && options.finalSource)
);
return fromStringWithSourceMap(
this._valueAsString,
this._sourceMapAsObject
);
}
}

@@ -226,0 +217,0 @@

{
"name": "webpack-sources",
"version": "2.3.1",
"version": "3.0.0",
"description": "Source code handling classes for webpack",

@@ -9,11 +9,5 @@ "main": "./lib/index.js",

"test": "jest",
"travis": "yarn cover",
"lint": "eslint --cache lib test",
"precover": "yarn lint",
"cover": "jest --coverage"
},
"dependencies": {
"source-list-map": "^2.0.1",
"source-map": "^0.6.1"
},
"devDependencies": {

@@ -31,2 +25,3 @@ "coveralls": "^3.0.2",

"prettier": "^2.0.5",
"source-map": "^0.7.3",
"sourcemap-validator": "^2.1.0"

@@ -33,0 +28,0 @@ },

@@ -48,3 +48,2 @@ # webpack-sources

- `columns: Boolean` (default `true`): If set to false the implementation may omit mappings for columns.
- `module: Boolean` (default `true`): If set to false the implementation may omit inner mappings for modules.

@@ -77,3 +76,3 @@ #### `sourceAndMap`

```typescript
new RawSource(sourceCode: String)
new RawSource(sourceCode: String | Buffer)
```

@@ -87,3 +86,3 @@

new OriginalSource(
sourceCode: String,
sourceCode: String | Buffer,
name: String

@@ -104,7 +103,7 @@ )

new SourceMapSource(
sourceCode: String,
sourceCode: String | Buffer,
name: String,
sourceMap: Object | String,
originalSource?: String,
innerSourceMap?: Object | String,
sourceMap: Object | String | Buffer,
originalSource?: String | Buffer,
innerSourceMap?: Object | String | Buffer,
removeOriginalSource?: boolean

@@ -157,3 +156,3 @@ )

prefix: String,
source: Source
source: Source | String | Buffer
)

@@ -160,0 +159,0 @@ ```

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc