webpack-sources
Advanced tools
Comparing version
@@ -5,12 +5,43 @@ /* | ||
*/ | ||
"use strict"; | ||
const Source = require("./Source"); | ||
const streamAndGetSourceAndMap = require("./helpers/streamAndGetSourceAndMap"); | ||
const streamChunksOfRawSource = require("./helpers/streamChunksOfRawSource"); | ||
const streamChunksOfSourceMap = require("./helpers/streamChunksOfSourceMap"); | ||
const streamChunksOfRawSource = require("./helpers/streamChunksOfRawSource"); | ||
const streamAndGetSourceAndMap = require("./helpers/streamAndGetSourceAndMap"); | ||
const { | ||
isDualStringBufferCachingEnabled | ||
} = require("./helpers/stringBufferUtils"); | ||
const mapToBufferedMap = map => { | ||
/** @typedef {import("./Source").Hash} Hash */ | ||
/** @typedef {import("./Source").MapOptions} MapOptions */ | ||
/** @typedef {import("./Source").RawSourceMap} RawSourceMap */ | ||
/** @typedef {import("./Source").SourceAndMap} SourceAndMap */ | ||
/** @typedef {import("./Source").SourceValue} SourceValue */ | ||
/** @typedef {import("./helpers/getGeneratedSourceInfo").GeneratedSourceInfo} GeneratedSourceInfo */ | ||
/** @typedef {import("./helpers/streamChunks").OnChunk} OnChunk */ | ||
/** @typedef {import("./helpers/streamChunks").OnName} OnName */ | ||
/** @typedef {import("./helpers/streamChunks").OnSource} OnSource */ | ||
/** @typedef {import("./helpers/streamChunks").Options} Options */ | ||
/** | ||
* @typedef {object} BufferedMap | ||
* @property {number} version | ||
* @property {string[]} sources | ||
* @property {string[]} names | ||
* @property {string=} sourceRoot | ||
* @property {(Buffer | "")[]=} sourcesContent | ||
* @property {Buffer=} mappings | ||
* @property {string} file | ||
*/ | ||
/** | ||
* @param {null | RawSourceMap} map map | ||
* @returns {null | BufferedMap} buffered map | ||
*/ | ||
const mapToBufferedMap = (map) => { | ||
if (typeof map !== "object" || !map) return map; | ||
const bufferedMap = Object.assign({}, map); | ||
/** @type {BufferedMap} */ | ||
const bufferedMap = Object.assign(/** @type {BufferedMap} */ ({}), map); | ||
if (map.mappings) { | ||
@@ -21,3 +52,3 @@ bufferedMap.mappings = Buffer.from(map.mappings, "utf-8"); | ||
bufferedMap.sourcesContent = map.sourcesContent.map( | ||
str => str && Buffer.from(str, "utf-8") | ||
(str) => str && Buffer.from(str, "utf-8") | ||
); | ||
@@ -28,5 +59,10 @@ } | ||
const bufferedMapToMap = bufferedMap => { | ||
/** | ||
* @param {null | BufferedMap} bufferedMap buffered map | ||
* @returns {null | RawSourceMap} map | ||
*/ | ||
const bufferedMapToMap = (bufferedMap) => { | ||
if (typeof bufferedMap !== "object" || !bufferedMap) return bufferedMap; | ||
const map = Object.assign({}, bufferedMap); | ||
/** @type {RawSourceMap} */ | ||
const map = Object.assign(/** @type {RawSourceMap} */ ({}), bufferedMap); | ||
if (bufferedMap.mappings) { | ||
@@ -37,3 +73,3 @@ map.mappings = bufferedMap.mappings.toString("utf-8"); | ||
map.sourcesContent = bufferedMap.sourcesContent.map( | ||
buffer => buffer && buffer.toString("utf-8") | ||
(buffer) => buffer && buffer.toString("utf-8") | ||
); | ||
@@ -44,3 +80,20 @@ } | ||
/** @typedef {{ map?: null | RawSourceMap, bufferedMap?: null | BufferedMap }} BufferEntry */ | ||
/** @typedef {Map<string, BufferEntry>} BufferedMaps */ | ||
/** | ||
* @typedef {object} CachedData | ||
* @property {boolean=} source | ||
* @property {Buffer} buffer | ||
* @property {number=} size | ||
* @property {BufferedMaps} maps | ||
* @property {(string | Buffer)[]=} hash | ||
*/ | ||
class CachedSource extends Source { | ||
// eslint-disable-next-line valid-jsdoc | ||
/** | ||
* @param {Source | (() => Source)} source source | ||
* @param {CachedData=} cachedData cached data | ||
*/ | ||
constructor(source, cachedData) { | ||
@@ -50,5 +103,13 @@ super(); | ||
this._cachedSourceType = cachedData ? cachedData.source : undefined; | ||
/** | ||
* @private | ||
* @type {undefined | string} | ||
*/ | ||
this._cachedSource = undefined; | ||
this._cachedBuffer = cachedData ? cachedData.buffer : undefined; | ||
this._cachedSize = cachedData ? cachedData.size : undefined; | ||
/** | ||
* @private | ||
* @type {BufferedMaps} | ||
*/ | ||
this._cachedMaps = cachedData ? cachedData.maps : new Map(); | ||
@@ -58,3 +119,7 @@ this._cachedHashUpdate = cachedData ? cachedData.hash : undefined; | ||
/** | ||
* @returns {CachedData} cached data | ||
*/ | ||
getCachedData() { | ||
/** @type {BufferedMaps} */ | ||
const bufferedMaps = new Map(); | ||
@@ -73,11 +138,10 @@ for (const pair of this._cachedMaps) { | ||
} | ||
// We don't want to cache strings | ||
// So if we have a caches sources | ||
// create a buffer from it and only store | ||
// if it was a Buffer or string | ||
if (this._cachedSource) { | ||
this.buffer(); | ||
} | ||
return { | ||
buffer: this._cachedBuffer, | ||
// We don't want to cache strings | ||
// So if we have a caches sources | ||
// create a buffer from it and only store | ||
// if it was a Buffer or string | ||
buffer: this._cachedSource | ||
? this.buffer() | ||
: /** @type {Buffer} */ (this._cachedBuffer), | ||
source: | ||
@@ -106,8 +170,18 @@ this._cachedSourceType !== undefined | ||
/** | ||
* @returns {SourceValue} source | ||
*/ | ||
source() { | ||
const source = this._getCachedSource(); | ||
if (source !== undefined) return source; | ||
return (this._cachedSource = this.original().source()); | ||
return (this._cachedSource = | ||
/** @type {string} */ | ||
(this.original().source())); | ||
} | ||
/** | ||
* @private | ||
* @param {BufferEntry} cacheEntry cache entry | ||
* @returns {null | RawSourceMap} raw source map | ||
*/ | ||
_getMapFromCacheEntry(cacheEntry) { | ||
@@ -119,20 +193,36 @@ if (cacheEntry.map !== undefined) { | ||
} | ||
return null; | ||
} | ||
/** | ||
* @private | ||
* @returns {undefined | string} cached source | ||
*/ | ||
_getCachedSource() { | ||
if (this._cachedSource !== undefined) return this._cachedSource; | ||
if (this._cachedBuffer && this._cachedSourceType !== undefined) { | ||
return (this._cachedSource = this._cachedSourceType | ||
const value = this._cachedSourceType | ||
? this._cachedBuffer.toString("utf-8") | ||
: this._cachedBuffer); | ||
: this._cachedBuffer; | ||
if (isDualStringBufferCachingEnabled()) { | ||
this._cachedSource = /** @type {string} */ (value); | ||
} | ||
return /** @type {string} */ (value); | ||
} | ||
} | ||
/** | ||
* @returns {Buffer} buffer | ||
*/ | ||
buffer() { | ||
if (this._cachedBuffer !== undefined) return this._cachedBuffer; | ||
if (this._cachedSource !== undefined) { | ||
if (Buffer.isBuffer(this._cachedSource)) { | ||
return (this._cachedBuffer = this._cachedSource); | ||
const value = Buffer.isBuffer(this._cachedSource) | ||
? this._cachedSource | ||
: Buffer.from(this._cachedSource, "utf-8"); | ||
if (isDualStringBufferCachingEnabled()) { | ||
this._cachedBuffer = value; | ||
} | ||
return (this._cachedBuffer = Buffer.from(this._cachedSource, "utf-8")); | ||
return value; | ||
} | ||
@@ -146,5 +236,12 @@ if (typeof this.original().buffer === "function") { | ||
} | ||
return (this._cachedBuffer = Buffer.from(bufferOrString, "utf-8")); | ||
const value = Buffer.from(bufferOrString, "utf-8"); | ||
if (isDualStringBufferCachingEnabled()) { | ||
this._cachedBuffer = value; | ||
} | ||
return value; | ||
} | ||
/** | ||
* @returns {number} size | ||
*/ | ||
size() { | ||
@@ -162,2 +259,6 @@ if (this._cachedSize !== undefined) return this._cachedSize; | ||
/** | ||
* @param {MapOptions=} options map options | ||
* @returns {SourceAndMap} source and map | ||
*/ | ||
sourceAndMap(options) { | ||
@@ -170,2 +271,3 @@ const key = options ? JSON.stringify(options) : "{}"; | ||
const map = this._getMapFromCacheEntry(cacheEntry); | ||
// Either get the cached source or compute it | ||
@@ -183,3 +285,3 @@ return { source: this.source(), map }; | ||
const sourceAndMap = this.original().sourceAndMap(options); | ||
source = sourceAndMap.source; | ||
source = /** @type {string} */ (sourceAndMap.source); | ||
map = sourceAndMap.map; | ||
@@ -195,2 +297,9 @@ this._cachedSource = source; | ||
/** | ||
* @param {Options} options options | ||
* @param {OnChunk} onChunk called for each chunk of code | ||
* @param {OnSource} onSource called for each source | ||
* @param {OnName} onName called for each name | ||
* @returns {GeneratedSourceInfo} generated source info | ||
*/ | ||
streamChunks(options, onChunk, onSource, onName) { | ||
@@ -205,3 +314,4 @@ const key = options ? JSON.stringify(options) : "{}"; | ||
return streamChunksOfSourceMap( | ||
source, | ||
/** @type {string} */ | ||
(source), | ||
map, | ||
@@ -216,3 +326,4 @@ onChunk, | ||
return streamChunksOfRawSource( | ||
source, | ||
/** @type {string} */ | ||
(source), | ||
onChunk, | ||
@@ -234,3 +345,3 @@ onSource, | ||
this._cachedMaps.set(key, { | ||
map, | ||
map: /** @type {RawSourceMap} */ (map), | ||
bufferedMap: undefined | ||
@@ -241,2 +352,6 @@ }); | ||
/** | ||
* @param {MapOptions=} options map options | ||
* @returns {RawSourceMap | null} map | ||
*/ | ||
map(options) { | ||
@@ -256,2 +371,6 @@ const key = options ? JSON.stringify(options) : "{}"; | ||
/** | ||
* @param {Hash} hash hash | ||
* @returns {void} | ||
*/ | ||
updateHash(hash) { | ||
@@ -262,6 +381,12 @@ if (this._cachedHashUpdate !== undefined) { | ||
} | ||
/** @type {(string | Buffer)[]} */ | ||
const update = []; | ||
/** @type {string | undefined} */ | ||
let currentString = undefined; | ||
const tracker = { | ||
update: item => { | ||
/** | ||
* @param {string | Buffer} item item | ||
* @returns {void} | ||
*/ | ||
update: (item) => { | ||
if (typeof item === "string" && item.length < 10240) { | ||
@@ -286,3 +411,3 @@ if (currentString === undefined) { | ||
}; | ||
this.original().updateHash(tracker); | ||
this.original().updateHash(/** @type {Hash} */ (tracker)); | ||
if (currentString !== undefined) { | ||
@@ -289,0 +414,0 @@ update.push(Buffer.from(currentString)); |
@@ -5,2 +5,3 @@ /* | ||
*/ | ||
"use strict"; | ||
@@ -10,3 +11,23 @@ | ||
/** @typedef {import("./Source").Hash} Hash */ | ||
/** @typedef {import("./Source").MapOptions} MapOptions */ | ||
/** @typedef {import("./Source").RawSourceMap} RawSourceMap */ | ||
/** @typedef {import("./Source").SourceAndMap} SourceAndMap */ | ||
/** @typedef {import("./Source").SourceValue} SourceValue */ | ||
/** | ||
* @typedef {object} SourceLike | ||
* @property {() => SourceValue} source | ||
* @property {(() => Buffer)=} buffer | ||
* @property {(() => number)=} size | ||
* @property {((options?: MapOptions) => RawSourceMap | null)=} map | ||
* @property {((options?: MapOptions) => SourceAndMap)=} sourceAndMap | ||
* @property {((hash: Hash) => void)=} updateHash | ||
*/ | ||
class CompatSource extends Source { | ||
/** | ||
* @param {SourceLike} sourceLike source like | ||
* @returns {Source} source | ||
*/ | ||
static from(sourceLike) { | ||
@@ -18,2 +39,5 @@ return sourceLike instanceof Source | ||
/** | ||
* @param {SourceLike} sourceLike source like | ||
*/ | ||
constructor(sourceLike) { | ||
@@ -24,2 +48,5 @@ super(); | ||
/** | ||
* @returns {SourceValue} source | ||
*/ | ||
source() { | ||
@@ -43,2 +70,6 @@ return this._sourceLike.source(); | ||
/** | ||
* @param {MapOptions=} options map options | ||
* @returns {RawSourceMap | null} map | ||
*/ | ||
map(options) { | ||
@@ -51,2 +82,6 @@ if (typeof this._sourceLike.map === "function") { | ||
/** | ||
* @param {MapOptions=} options map options | ||
* @returns {SourceAndMap} source and map | ||
*/ | ||
sourceAndMap(options) { | ||
@@ -59,2 +94,6 @@ if (typeof this._sourceLike.sourceAndMap === "function") { | ||
/** | ||
* @param {Hash} hash hash | ||
* @returns {void} | ||
*/ | ||
updateHash(hash) { | ||
@@ -61,0 +100,0 @@ if (typeof this._sourceLike.updateHash === "function") { |
@@ -5,17 +5,41 @@ /* | ||
*/ | ||
"use strict"; | ||
const RawSource = require("./RawSource"); | ||
const Source = require("./Source"); | ||
const RawSource = require("./RawSource"); | ||
const { getMap, getSourceAndMap } = require("./helpers/getFromStreamChunks"); | ||
const streamChunks = require("./helpers/streamChunks"); | ||
const { getMap, getSourceAndMap } = require("./helpers/getFromStreamChunks"); | ||
/** @typedef {import("./CompatSource").SourceLike} SourceLike */ | ||
/** @typedef {import("./Source").Hash} Hash */ | ||
/** @typedef {import("./Source").MapOptions} MapOptions */ | ||
/** @typedef {import("./Source").RawSourceMap} RawSourceMap */ | ||
/** @typedef {import("./Source").SourceAndMap} SourceAndMap */ | ||
/** @typedef {import("./Source").SourceValue} SourceValue */ | ||
/** @typedef {import("./helpers/getGeneratedSourceInfo").GeneratedSourceInfo} GeneratedSourceInfo */ | ||
/** @typedef {import("./helpers/streamChunks").OnChunk} OnChunk */ | ||
/** @typedef {import("./helpers/streamChunks").OnName} OnName */ | ||
/** @typedef {import("./helpers/streamChunks").OnSource} OnSource */ | ||
/** @typedef {import("./helpers/streamChunks").Options} Options */ | ||
/** @typedef {string | Source | SourceLike} Child */ | ||
const stringsAsRawSources = new WeakSet(); | ||
class ConcatSource extends Source { | ||
constructor() { | ||
/** | ||
* | ||
* @param {Child[]} args children | ||
*/ | ||
constructor(...args) { | ||
super(); | ||
/** | ||
* @private | ||
* @type {Child[]} | ||
*/ | ||
this._children = []; | ||
for (let i = 0; i < arguments.length; i++) { | ||
const item = arguments[i]; | ||
for (let i = 0; i < args.length; i++) { | ||
const item = args[i]; | ||
if (item instanceof ConcatSource) { | ||
@@ -29,10 +53,18 @@ for (const child of item._children) { | ||
} | ||
this._isOptimized = arguments.length === 0; | ||
this._isOptimized = args.length === 0; | ||
} | ||
/** | ||
* @returns {Source[]} children | ||
*/ | ||
getChildren() { | ||
if (!this._isOptimized) this._optimize(); | ||
return this._children; | ||
return /** @type {Source[]} */ (this._children); | ||
} | ||
/** | ||
* @param {Child} item item | ||
* @returns {void} | ||
*/ | ||
add(item) { | ||
@@ -49,2 +81,6 @@ if (item instanceof ConcatSource) { | ||
/** | ||
* @param {Child[]} items items | ||
* @returns {void} | ||
*/ | ||
addAllSkipOptimizing(items) { | ||
@@ -58,4 +94,5 @@ for (const item of items) { | ||
if (!this._isOptimized) this._optimize(); | ||
/** @type {Buffer[]} */ | ||
const buffers = []; | ||
for (const child of this._children) { | ||
for (const child of /** @type {SourceLike[]} */ (this._children)) { | ||
if (typeof child.buffer === "function") { | ||
@@ -76,2 +113,5 @@ buffers.push(child.buffer()); | ||
/** | ||
* @returns {SourceValue} source | ||
*/ | ||
source() { | ||
@@ -81,3 +121,3 @@ if (!this._isOptimized) this._optimize(); | ||
for (const child of this._children) { | ||
source += child.source(); | ||
source += /** @type {Source} */ (child).source(); | ||
} | ||
@@ -91,3 +131,3 @@ return source; | ||
for (const child of this._children) { | ||
size += child.size(); | ||
size += /** @type {Source} */ (child).size(); | ||
} | ||
@@ -97,2 +137,6 @@ return size; | ||
/** | ||
* @param {MapOptions=} options map options | ||
* @returns {RawSourceMap | null} map | ||
*/ | ||
map(options) { | ||
@@ -102,2 +146,6 @@ return getMap(this, options); | ||
/** | ||
* @param {MapOptions=} options map options | ||
* @returns {SourceAndMap} source and map | ||
*/ | ||
sourceAndMap(options) { | ||
@@ -107,6 +155,19 @@ return getSourceAndMap(this, options); | ||
/** | ||
* @param {Options} options options | ||
* @param {OnChunk} onChunk called for each chunk of code | ||
* @param {OnSource} onSource called for each source | ||
* @param {OnName} onName called for each name | ||
* @returns {GeneratedSourceInfo} generated source info | ||
*/ | ||
streamChunks(options, onChunk, onSource, onName) { | ||
if (!this._isOptimized) this._optimize(); | ||
if (this._children.length === 1) | ||
return this._children[0].streamChunks(options, onChunk, onSource, onName); | ||
if (this._children.length === 1) { | ||
return /** @type {ConcatSource[]} */ (this._children)[0].streamChunks( | ||
options, | ||
onChunk, | ||
onSource, | ||
onName | ||
); | ||
} | ||
let currentLineOffset = 0; | ||
@@ -119,4 +180,6 @@ let currentColumnOffset = 0; | ||
let needToCloseMapping = false; | ||
for (const item of this._children) { | ||
for (const item of /** @type {Source[]} */ (this._children)) { | ||
/** @type {number[]} */ | ||
const sourceIndexMapping = []; | ||
/** @type {number[]} */ | ||
const nameIndexMapping = []; | ||
@@ -226,6 +289,6 @@ let lastMappingLine = 0; | ||
} | ||
if (generatedLine > 1) { | ||
currentColumnOffset = generatedColumn; | ||
if (/** @type {number} */ (generatedLine) > 1) { | ||
currentColumnOffset = /** @type {number} */ (generatedColumn); | ||
} else { | ||
currentColumnOffset += generatedColumn; | ||
currentColumnOffset += /** @type {number} */ (generatedColumn); | ||
} | ||
@@ -235,3 +298,3 @@ needToCloseMapping = | ||
(finalSource && lastMappingLine === generatedLine); | ||
currentLineOffset += generatedLine - 1; | ||
currentLineOffset += /** @type {number} */ (generatedLine) - 1; | ||
} | ||
@@ -245,2 +308,6 @@ return { | ||
/** | ||
* @param {Hash} hash hash | ||
* @returns {void} | ||
*/ | ||
updateHash(hash) { | ||
@@ -250,3 +317,4 @@ if (!this._isOptimized) this._optimize(); | ||
for (const item of this._children) { | ||
item.updateHash(hash); | ||
/** @type {Source} */ | ||
(item).updateHash(hash); | ||
} | ||
@@ -258,4 +326,9 @@ } | ||
let currentString = undefined; | ||
/** @type {undefined | string | [string, string] | SourceLike} */ | ||
let currentRawSources = undefined; | ||
const addStringToRawSources = string => { | ||
/** | ||
* @param {string} string string | ||
* @returns {void} | ||
*/ | ||
const addStringToRawSources = (string) => { | ||
if (currentRawSources === undefined) { | ||
@@ -269,3 +342,3 @@ currentRawSources = string; | ||
? currentRawSources | ||
: currentRawSources.source(), | ||
: /** @type {string} */ (currentRawSources.source()), | ||
string | ||
@@ -275,7 +348,14 @@ ]; | ||
}; | ||
const addSourceToRawSources = source => { | ||
/** | ||
* @param {SourceLike} source source | ||
* @returns {void} | ||
*/ | ||
const addSourceToRawSources = (source) => { | ||
if (currentRawSources === undefined) { | ||
currentRawSources = source; | ||
} else if (Array.isArray(currentRawSources)) { | ||
currentRawSources.push(source.source()); | ||
currentRawSources.push( | ||
/** @type {string} */ | ||
(source.source()) | ||
); | ||
} else { | ||
@@ -285,4 +365,5 @@ currentRawSources = [ | ||
? currentRawSources | ||
: currentRawSources.source(), | ||
source.source() | ||
: /** @type {string} */ (currentRawSources.source()), | ||
/** @type {string} */ | ||
(source.source()) | ||
]; | ||
@@ -317,3 +398,6 @@ } | ||
if (stringsAsRawSources.has(child)) { | ||
addSourceToRawSources(child); | ||
addSourceToRawSources( | ||
/** @type {SourceLike} */ | ||
(child) | ||
); | ||
} else { | ||
@@ -320,0 +404,0 @@ if (currentRawSources !== undefined) { |
@@ -8,9 +8,24 @@ /* | ||
const ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split( | ||
"" | ||
); | ||
const ALPHABET = | ||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""); | ||
const CONTINUATION_BIT = 0x20; | ||
const createMappingsSerializer = options => { | ||
/** | ||
* @callback MappingsSerializer | ||
* @param {number} generatedLine generated line | ||
* @param {number} generatedColumn generated column | ||
* @param {number} sourceIndex source index | ||
* @param {number} originalLine original line | ||
* @param {number} originalColumn generated line | ||
* @param {number} nameIndex generated line | ||
* @returns {string} result | ||
*/ | ||
// eslint-disable-next-line valid-jsdoc | ||
/** | ||
* @param {{ columns?: boolean }=} options options | ||
* @returns {MappingsSerializer} mappings serializer | ||
*/ | ||
const createMappingsSerializer = (options) => { | ||
const linesOnly = options && options.columns === false; | ||
@@ -32,2 +47,4 @@ return linesOnly | ||
let initial = true; | ||
// eslint-disable-next-line valid-jsdoc | ||
/** @type {MappingsSerializer} */ | ||
return ( | ||
@@ -61,2 +78,3 @@ generatedLine, | ||
/** @type {undefined | string} */ | ||
let str; | ||
@@ -75,3 +93,7 @@ if (currentLine < generatedLine) { | ||
const writeValue = value => { | ||
/** | ||
* @param {number} value value | ||
* @returns {void} | ||
*/ | ||
const writeValue = (value) => { | ||
const sign = (value >>> 31) & 1; | ||
@@ -129,2 +151,4 @@ const mask = value >> 31; | ||
let currentOriginalLine = 1; | ||
// eslint-disable-next-line valid-jsdoc | ||
/** @type {MappingsSerializer} */ | ||
return ( | ||
@@ -146,4 +170,9 @@ generatedLine, | ||
} | ||
/** @type {undefined | string} */ | ||
let str; | ||
const writeValue = value => { | ||
/** | ||
* @param {number} value value | ||
* @returns {void} | ||
*/ | ||
const writeValue = (value) => { | ||
const sign = (value >>> 31) & 1; | ||
@@ -168,3 +197,2 @@ const mask = value >> 31; | ||
if (sourceIndex === currentSourceIndex) { | ||
currentSourceIndex = sourceIndex; | ||
if (originalLine === currentOriginalLine + 1) { | ||
@@ -191,3 +219,2 @@ currentOriginalLine = originalLine; | ||
if (sourceIndex === currentSourceIndex) { | ||
currentSourceIndex = sourceIndex; | ||
if (originalLine === currentOriginalLine + 1) { | ||
@@ -194,0 +221,0 @@ currentOriginalLine = originalLine; |
@@ -10,7 +10,22 @@ /* | ||
/** @typedef {import("../Source").RawSourceMap} RawSourceMap */ | ||
/** @typedef {import("../Source").SourceAndMap} SourceAndMap */ | ||
/** @typedef {import("./streamChunks").Options} Options */ | ||
/** @typedef {import("./streamChunks").StreamChunksFunction} StreamChunksFunction */ | ||
/** @typedef {{ streamChunks: StreamChunksFunction }} SourceLikeWithStreamChunks */ | ||
/** | ||
* @param {SourceLikeWithStreamChunks} inputSource input source | ||
* @param {Options=} options options | ||
* @returns {SourceAndMap} map | ||
*/ | ||
exports.getSourceAndMap = (inputSource, options) => { | ||
let code = ""; | ||
let mappings = ""; | ||
/** @type {(string | null)[]} */ | ||
let sources = []; | ||
/** @type {(string | null)[]} */ | ||
let sourcesContent = []; | ||
/** @type {(string | null)[]} */ | ||
let names = []; | ||
@@ -66,6 +81,9 @@ const addMapping = createMappingsSerializer(options); | ||
mappings, | ||
sources, | ||
// We handle broken sources as `null`, in spec this field should be string, but no information what we should do in such cases if we change type it will be breaking change | ||
sources: /** @type {string[]} */ (sources), | ||
sourcesContent: | ||
sourcesContent.length > 0 ? sourcesContent : undefined, | ||
names | ||
sourcesContent.length > 0 | ||
? /** @type {string[]} */ (sourcesContent) | ||
: undefined, | ||
names: /** @type {string[]} */ (names) | ||
} | ||
@@ -76,6 +94,14 @@ : null | ||
/** | ||
* @param {SourceLikeWithStreamChunks} source source | ||
* @param {Options=} options options | ||
* @returns {RawSourceMap | null} map | ||
*/ | ||
exports.getMap = (source, options) => { | ||
let mappings = ""; | ||
/** @type {(string | null)[]} */ | ||
let sources = []; | ||
/** @type {(string | null)[]} */ | ||
let sourcesContent = []; | ||
/** @type {(string | null)[]} */ | ||
let names = []; | ||
@@ -127,7 +153,11 @@ const addMapping = createMappingsSerializer(options); | ||
mappings, | ||
sources, | ||
sourcesContent: sourcesContent.length > 0 ? sourcesContent : undefined, | ||
names | ||
// We handle broken sources as `null`, in spec this field should be string, but no information what we should do in such cases if we change type it will be breaking change | ||
sources: /** @type {string[]} */ (sources), | ||
sourcesContent: | ||
sourcesContent.length > 0 | ||
? /** @type {string[]} */ (sourcesContent) | ||
: undefined, | ||
names: /** @type {string[]} */ (names) | ||
} | ||
: null; | ||
}; |
@@ -10,3 +10,14 @@ /* | ||
const getGeneratedSourceInfo = source => { | ||
/** | ||
* @typedef {object} GeneratedSourceInfo | ||
* @property {number=} generatedLine | ||
* @property {number=} generatedColumn | ||
* @property {string=} source | ||
*/ | ||
/** | ||
* @param {string | undefined} source source | ||
* @returns {GeneratedSourceInfo} source info | ||
*/ | ||
const getGeneratedSourceInfo = (source) => { | ||
if (source === undefined) { | ||
@@ -13,0 +24,0 @@ return {}; |
@@ -8,2 +8,9 @@ /* | ||
/** @typedef {import("../Source").RawSourceMap} RawSourceMap */ | ||
/** | ||
* @param {RawSourceMap} sourceMap source map | ||
* @param {number} index index | ||
* @returns {string | undefined | null} name | ||
*/ | ||
const getName = (sourceMap, index) => { | ||
@@ -10,0 +17,0 @@ if (index < 0) return null; |
@@ -8,2 +8,9 @@ /* | ||
/** @typedef {import("../Source").RawSourceMap} RawSourceMap */ | ||
/** | ||
* @param {RawSourceMap} sourceMap source map | ||
* @param {number} index index | ||
* @returns {string | null} name | ||
*/ | ||
const getSource = (sourceMap, index) => { | ||
@@ -10,0 +17,0 @@ if (index < 0) return null; |
@@ -28,5 +28,7 @@ /* | ||
/** @typedef {function(number, number, number, number, number, number): void} OnMapping */ | ||
/** | ||
* @param {string} mappings the mappings string | ||
* @param {function(number, number, number, number, number, number): void} onMapping called for each mapping | ||
* @param {OnMapping} onMapping called for each mapping | ||
* @returns {void} | ||
@@ -33,0 +35,0 @@ */ |
@@ -1,2 +0,13 @@ | ||
const splitIntoLines = str => { | ||
/* | ||
MIT License http://www.opensource.org/licenses/mit-license.php | ||
Author Tobias Koppers @sokra | ||
*/ | ||
"use strict"; | ||
/** | ||
* @param {string} str string | ||
* @returns {string[]} array of string separated by lines | ||
*/ | ||
const splitIntoLines = (str) => { | ||
const results = []; | ||
@@ -21,2 +32,3 @@ const len = str.length; | ||
}; | ||
module.exports = splitIntoLines; |
@@ -0,1 +1,8 @@ | ||
/* | ||
MIT License http://www.opensource.org/licenses/mit-license.php | ||
Author Tobias Koppers @sokra | ||
*/ | ||
"use strict"; | ||
// \n = 10 | ||
@@ -9,3 +16,7 @@ // ; = 59 | ||
const splitIntoPotentialTokens = str => { | ||
/** | ||
* @param {string} str string | ||
* @returns {string[] | null} array of string separated by potential tokens | ||
*/ | ||
const splitIntoPotentialTokens = (str) => { | ||
const len = str.length; | ||
@@ -42,2 +53,3 @@ if (len === 0) return null; | ||
}; | ||
module.exports = splitIntoPotentialTokens; |
@@ -11,2 +11,19 @@ /* | ||
/** @typedef {import("../Source").RawSourceMap} RawSourceMap */ | ||
/** @typedef {import("./streamChunks").GeneratedSourceInfo} GeneratedSourceInfo */ | ||
/** @typedef {import("./streamChunks").OnChunk} OnChunk */ | ||
/** @typedef {import("./streamChunks").OnName} OnName */ | ||
/** @typedef {import("./streamChunks").OnSource} OnSource */ | ||
/** @typedef {import("./streamChunks").Options} Options */ | ||
/** @typedef {import("./streamChunks").SourceMaybeWithStreamChunksFunction} SourceMaybeWithStreamChunksFunction */ | ||
// eslint-disable-next-line valid-jsdoc | ||
/** | ||
* @param {SourceMaybeWithStreamChunksFunction} inputSource input source | ||
* @param {Options} options options | ||
* @param {OnChunk} onChunk on chunk | ||
* @param {OnSource} onSource on source | ||
* @param {OnName} onName on name | ||
* @returns {{ result: GeneratedSourceInfo, source: string, map: RawSourceMap | null }} result | ||
*/ | ||
const streamAndGetSourceAndMap = ( | ||
@@ -21,4 +38,7 @@ inputSource, | ||
let mappings = ""; | ||
/** @type {(string | null)[]} */ | ||
let sources = []; | ||
/** @type {(string | null)[]} */ | ||
let sourcesContent = []; | ||
/** @type {(string | null)[]} */ | ||
let names = []; | ||
@@ -82,2 +102,3 @@ const addMapping = createMappingsSerializer( | ||
const resultSource = source !== undefined ? source : code; | ||
return { | ||
@@ -96,6 +117,9 @@ result: { | ||
mappings, | ||
sources, | ||
// We handle broken sources as `null`, in spec this field should be string, but no information what we should do in such cases if we change type it will be breaking change | ||
sources: /** @type {string[]} */ (sources), | ||
sourcesContent: | ||
sourcesContent.length > 0 ? sourcesContent : undefined, | ||
names | ||
sourcesContent.length > 0 | ||
? /** @type {string[]} */ (sourcesContent) | ||
: undefined, | ||
names: /** @type {string[]} */ (names) | ||
} | ||
@@ -102,0 +126,0 @@ : null |
@@ -11,2 +11,28 @@ /* | ||
/** @typedef {import("../Source")} Source */ | ||
/** @typedef {import("./getGeneratedSourceInfo").GeneratedSourceInfo} GeneratedSourceInfo */ | ||
/** @typedef {(chunk: string | undefined, generatedLine: number, generatedColumn: number, sourceIndex: number, originalLine: number, originalColumn: number, nameIndex: number) => void} OnChunk */ | ||
/** @typedef {(sourceIndex: number, source: string | null, sourceContent: string | undefined) => void} OnSource */ | ||
/** @typedef {(nameIndex: number, name: string) => void} OnName */ | ||
/** @typedef {{ source?: boolean, finalSource?: boolean, columns?: boolean }} Options */ | ||
/** | ||
* @callback StreamChunksFunction | ||
* @param {Options} options options | ||
* @param {OnChunk} onChunk on chunk | ||
* @param {OnSource} onSource on source | ||
* @param {OnName} onName on name | ||
*/ | ||
/** @typedef {Source & { streamChunks?: StreamChunksFunction }} SourceMaybeWithStreamChunksFunction */ | ||
/** | ||
* @param {SourceMaybeWithStreamChunksFunction} source source | ||
* @param {Options} options options | ||
* @param {OnChunk} onChunk on chunk | ||
* @param {OnSource} onSource on source | ||
* @param {OnName} onName on name | ||
* @returns {GeneratedSourceInfo} generated source info | ||
*/ | ||
module.exports = (source, options, onChunk, onSource, onName) => { | ||
@@ -19,3 +45,4 @@ if (typeof source.streamChunks === "function") { | ||
return streamChunksOfSourceMap( | ||
sourceAndMap.source, | ||
/** @type {string} */ | ||
(sourceAndMap.source), | ||
sourceAndMap.map, | ||
@@ -30,3 +57,4 @@ onChunk, | ||
return streamChunksOfRawSource( | ||
sourceAndMap.source, | ||
/** @type {string} */ | ||
(sourceAndMap.source), | ||
onChunk, | ||
@@ -33,0 +61,0 @@ onSource, |
@@ -8,5 +8,25 @@ /* | ||
const splitIntoLines = require("./splitIntoLines"); | ||
const streamChunksOfSourceMap = require("./streamChunksOfSourceMap"); | ||
const splitIntoLines = require("./splitIntoLines"); | ||
/** @typedef {import("../Source").RawSourceMap} RawSourceMap */ | ||
/** @typedef {import("./getGeneratedSourceInfo").GeneratedSourceInfo} GeneratedSourceInfo */ | ||
/** @typedef {import("./streamChunks").OnChunk} onChunk */ | ||
/** @typedef {import("./streamChunks").OnName} OnName */ | ||
/** @typedef {import("./streamChunks").OnSource} OnSource */ | ||
/** | ||
* @param {string} source source | ||
* @param {RawSourceMap} sourceMap source map | ||
* @param {string} innerSourceName inner source name | ||
* @param {string} innerSource inner source | ||
* @param {RawSourceMap} innerSourceMap inner source map | ||
* @param {boolean | undefined} removeInnerSource do remove inner source | ||
* @param {onChunk} onChunk on chunk | ||
* @param {OnSource} onSource on source | ||
* @param {OnName} onName on name | ||
* @param {boolean} finalSource finalSource | ||
* @param {boolean} columns columns | ||
* @returns {GeneratedSourceInfo} generated source info | ||
*/ | ||
const streamChunksOfCombinedSourceMap = ( | ||
@@ -25,15 +45,33 @@ source, | ||
) => { | ||
/** @type {Map<string | null, number>} */ | ||
let sourceMapping = new Map(); | ||
/** @type {Map<string, number>} */ | ||
let nameMapping = new Map(); | ||
/** @type {number[]} */ | ||
const sourceIndexMapping = []; | ||
/** @type {number[]} */ | ||
const nameIndexMapping = []; | ||
/** @type {string[]} */ | ||
const nameIndexValueMapping = []; | ||
let innerSourceIndex = -2; | ||
/** @type {number[]} */ | ||
const innerSourceIndexMapping = []; | ||
/** @type {[string | null, string | undefined][]} */ | ||
const innerSourceIndexValueMapping = []; | ||
/** @type {(string | undefined)[]} */ | ||
const innerSourceContents = []; | ||
/** @type {(null | undefined | string[])[]} */ | ||
const innerSourceContentLines = []; | ||
/** @type {number[]} */ | ||
const innerNameIndexMapping = []; | ||
/** @type {string[]} */ | ||
const innerNameIndexValueMapping = []; | ||
/** @typedef {[number, number, number, number, number]} MappingsData */ | ||
/** @type {{ chunks: string[], mappingsData: MappingsData }[]} */ | ||
const innerSourceMapLineData = []; | ||
/** | ||
* @param {number} line line | ||
* @param {number} column column | ||
* @returns {number} result | ||
*/ | ||
const findInnerMapping = (line, column) => { | ||
@@ -72,5 +110,4 @@ if (line > innerSourceMapLineData.length) return -1; | ||
if (idx !== -1) { | ||
const { chunks, mappingsData } = innerSourceMapLineData[ | ||
originalLine - 1 | ||
]; | ||
const { chunks, mappingsData } = | ||
innerSourceMapLineData[originalLine - 1]; | ||
const mi = idx * 5; | ||
@@ -271,6 +308,7 @@ const innerSourceIndex = mappingsData[mi + 1]; | ||
if (innerSource !== undefined) sourceContent = innerSource; | ||
else innerSource = sourceContent; | ||
else innerSource = /** @type {string} */ (sourceContent); | ||
sourceIndexMapping[i] = -2; | ||
streamChunksOfSourceMap( | ||
sourceContent, | ||
/** @type {string} */ | ||
(sourceContent), | ||
innerSourceMap, | ||
@@ -288,3 +326,3 @@ ( | ||
innerSourceMapLineData.push({ | ||
mappingsData: [], | ||
mappingsData: /** @type {any} */ ([]), | ||
chunks: [] | ||
@@ -301,3 +339,3 @@ }); | ||
); | ||
data.chunks.push(chunk); | ||
data.chunks.push(/** @type {string} */ (chunk)); | ||
}, | ||
@@ -304,0 +342,0 @@ (i, source, sourceContent) => { |
@@ -11,5 +11,18 @@ /* | ||
/** @typedef {import("./getGeneratedSourceInfo").GeneratedSourceInfo} GeneratedSourceInfo */ | ||
/** @typedef {import("./streamChunks").OnChunk} OnChunk */ | ||
/** @typedef {import("./streamChunks").OnName} OnName */ | ||
/** @typedef {import("./streamChunks").OnSource} OnSource */ | ||
/** | ||
* @param {string} source source | ||
* @param {OnChunk} onChunk on chunk | ||
* @param {OnSource} onSource on source | ||
* @param {OnName} onName on name | ||
* @returns {GeneratedSourceInfo} source info | ||
*/ | ||
const streamChunksOfRawSource = (source, onChunk, onSource, onName) => { | ||
let line = 1; | ||
const matches = splitIntoLines(source); | ||
/** @type {undefined | string} */ | ||
let match; | ||
@@ -20,3 +33,3 @@ for (match of matches) { | ||
} | ||
return matches.length === 0 || match.endsWith("\n") | ||
return matches.length === 0 || /** @type {string} */ (match).endsWith("\n") | ||
? { | ||
@@ -28,6 +41,14 @@ generatedLine: matches.length + 1, | ||
generatedLine: matches.length, | ||
generatedColumn: match.length | ||
generatedColumn: /** @type {string} */ (match).length | ||
}; | ||
}; | ||
/** | ||
* @param {string} source source | ||
* @param {OnChunk} onChunk on chunk | ||
* @param {OnSource} onSource on source | ||
* @param {OnName} onName on name | ||
* @param {boolean} finalSource is final source | ||
* @returns {GeneratedSourceInfo} source info | ||
*/ | ||
module.exports = (source, onChunk, onSource, onName, finalSource) => { | ||
@@ -34,0 +55,0 @@ return finalSource |
@@ -13,2 +13,16 @@ /* | ||
/** @typedef {import("../Source").RawSourceMap} RawSourceMap */ | ||
/** @typedef {import("./getGeneratedSourceInfo").GeneratedSourceInfo} GeneratedSourceInfo */ | ||
/** @typedef {import("./streamChunks").OnChunk} OnChunk */ | ||
/** @typedef {import("./streamChunks").OnName} OnName */ | ||
/** @typedef {import("./streamChunks").OnSource} OnSource */ | ||
/** | ||
* @param {string} source source | ||
* @param {RawSourceMap} sourceMap source map | ||
* @param {OnChunk} onChunk on chunk | ||
* @param {OnSource} onSource on source | ||
* @param {OnName} onName on name | ||
* @returns {GeneratedSourceInfo} generated source info | ||
*/ | ||
const streamChunksOfSourceMapFull = ( | ||
@@ -56,2 +70,11 @@ source, | ||
/** | ||
* @param {number} generatedLine generated line | ||
* @param {number} generatedColumn generated column | ||
* @param {number} sourceIndex source index | ||
* @param {number} originalLine original line | ||
* @param {number} originalColumn original column | ||
* @param {number} nameIndex name index | ||
* @returns {void} | ||
*/ | ||
const onMapping = ( | ||
@@ -161,2 +184,10 @@ generatedLine, | ||
/** | ||
* @param {string} source source | ||
* @param {RawSourceMap} sourceMap source map | ||
* @param {OnChunk} onChunk on chunk | ||
* @param {OnSource} onSource on source | ||
* @param {OnName} _onName on name | ||
* @returns {GeneratedSourceInfo} generated source info | ||
*/ | ||
const streamChunksOfSourceMapLinesFull = ( | ||
@@ -187,2 +218,11 @@ source, | ||
/** | ||
* @param {number} generatedLine generated line | ||
* @param {number} _generatedColumn generated column | ||
* @param {number} sourceIndex source index | ||
* @param {number} originalLine original line | ||
* @param {number} originalColumn original column | ||
* @param {number} _nameIndex name index | ||
* @returns {void} | ||
*/ | ||
const onMapping = ( | ||
@@ -255,2 +295,10 @@ generatedLine, | ||
/** | ||
* @param {string} source source | ||
* @param {RawSourceMap} sourceMap source map | ||
* @param {OnChunk} onChunk on chunk | ||
* @param {OnSource} onSource on source | ||
* @param {OnName} onName on name | ||
* @returns {GeneratedSourceInfo} generated source info | ||
*/ | ||
const streamChunksOfSourceMapFinal = ( | ||
@@ -283,2 +331,11 @@ source, | ||
/** | ||
* @param {number} generatedLine generated line | ||
* @param {number} generatedColumn generated column | ||
* @param {number} sourceIndex source index | ||
* @param {number} originalLine original line | ||
* @param {number} originalColumn original column | ||
* @param {number} nameIndex name index | ||
* @returns {void} | ||
*/ | ||
const onMapping = ( | ||
@@ -293,4 +350,5 @@ generatedLine, | ||
if ( | ||
generatedLine >= finalLine && | ||
(generatedColumn >= finalColumn || generatedLine > finalLine) | ||
generatedLine >= /** @type {number} */ (finalLine) && | ||
(generatedColumn >= /** @type {number} */ (finalColumn) || | ||
generatedLine > /** @type {number} */ (finalLine)) | ||
) { | ||
@@ -319,2 +377,10 @@ return; | ||
/** | ||
* @param {string} source source | ||
* @param {RawSourceMap} sourceMap source map | ||
* @param {OnChunk} onChunk on chunk | ||
* @param {OnSource} onSource on source | ||
* @param {OnName} _onName on name | ||
* @returns {GeneratedSourceInfo} generated source info | ||
*/ | ||
const streamChunksOfSourceMapLinesFinal = ( | ||
@@ -345,6 +411,18 @@ source, | ||
const finalLine = generatedColumn === 0 ? generatedLine - 1 : generatedLine; | ||
const finalLine = | ||
generatedColumn === 0 | ||
? /** @type {number} */ (generatedLine) - 1 | ||
: /** @type {number} */ (generatedLine); | ||
let currentGeneratedLine = 1; | ||
/** | ||
* @param {number} generatedLine generated line | ||
* @param {number} _generatedColumn generated column | ||
* @param {number} sourceIndex source index | ||
* @param {number} originalLine original line | ||
* @param {number} originalColumn original column | ||
* @param {number} _nameIndex name index | ||
* @returns {void} | ||
*/ | ||
const onMapping = ( | ||
@@ -379,2 +457,12 @@ generatedLine, | ||
/** | ||
* @param {string} source source | ||
* @param {RawSourceMap} sourceMap source map | ||
* @param {OnChunk} onChunk on chunk | ||
* @param {OnSource} onSource on source | ||
* @param {OnName} onName on name | ||
* @param {boolean} finalSource final source | ||
* @param {boolean} columns columns | ||
* @returns {GeneratedSourceInfo} generated source info | ||
*/ | ||
module.exports = ( | ||
@@ -381,0 +469,0 @@ source, |
136
lib/index.js
@@ -6,26 +6,118 @@ /* | ||
const defineExport = (name, fn) => { | ||
let value; | ||
Object.defineProperty(exports, name, { | ||
get: () => { | ||
if (fn !== undefined) { | ||
value = fn(); | ||
fn = undefined; | ||
} | ||
return value; | ||
}, | ||
configurable: true | ||
}); | ||
"use strict"; | ||
/** @typedef {import("./CachedSource").CachedData} CachedData */ | ||
/** @typedef {import("./CompatSource").SourceLike} SourceLike */ | ||
/** @typedef {import("./ConcatSource").Child} ConcatSourceChild */ | ||
/** @typedef {import("./ReplaceSource").Replacement} Replacement */ | ||
/** @typedef {import("./Source").Hash} Hash */ | ||
/** @typedef {import("./Source").MapOptions} MapOptions */ | ||
/** @typedef {import("./Source").RawSourceMap} RawSourceMap */ | ||
/** @typedef {import("./Source").SourceAndMap} SourceAndMap */ | ||
/** @typedef {import("./Source").SourceValue} SourceValue */ | ||
/** @typedef {import("./helpers/getGeneratedSourceInfo").GeneratedSourceInfo} GeneratedSourceInfo */ | ||
/** @typedef {import("./helpers/streamChunks").OnChunk} OnChunk */ | ||
/** @typedef {import("./helpers/streamChunks").OnName} OnName */ | ||
/** @typedef {import("./helpers/streamChunks").OnSource} OnSource */ | ||
/** @typedef {import("./helpers/streamChunks").Options} StreamChunksOptions */ | ||
// eslint-disable-next-line valid-jsdoc | ||
/** | ||
* @template T | ||
* @param {() => T} fn memorized function | ||
* @returns {() => T} new function | ||
*/ | ||
const memoize = (fn) => { | ||
let cache = false; | ||
/** @type {T | undefined} */ | ||
let result; | ||
return () => { | ||
if (cache) { | ||
return /** @type {T} */ (result); | ||
} | ||
result = fn(); | ||
cache = true; | ||
// Allow to clean up memory for fn | ||
// and all dependent resources | ||
/** @type {(() => T) | undefined} */ | ||
(fn) = undefined; | ||
return /** @type {T} */ (result); | ||
}; | ||
}; | ||
defineExport("Source", () => require("./Source")); | ||
// eslint-disable-next-line valid-jsdoc | ||
/** | ||
* @template A | ||
* @template B | ||
* @param {A} obj input a | ||
* @param {B} exports input b | ||
* @returns {A & B} merged | ||
*/ | ||
const mergeExports = (obj, exports) => { | ||
const descriptors = Object.getOwnPropertyDescriptors(exports); | ||
for (const name of Object.keys(descriptors)) { | ||
const descriptor = descriptors[name]; | ||
if (descriptor.get) { | ||
const fn = descriptor.get; | ||
Object.defineProperty(obj, name, { | ||
configurable: false, | ||
enumerable: true, | ||
get: memoize(fn) | ||
}); | ||
} else if (typeof descriptor.value === "object") { | ||
Object.defineProperty(obj, name, { | ||
configurable: false, | ||
enumerable: true, | ||
writable: false, | ||
value: mergeExports({}, descriptor.value) | ||
}); | ||
} else { | ||
throw new Error( | ||
"Exposed values must be either a getter or an nested object" | ||
); | ||
} | ||
} | ||
return /** @type {A & B} */ (Object.freeze(obj)); | ||
}; | ||
defineExport("RawSource", () => require("./RawSource")); | ||
defineExport("OriginalSource", () => require("./OriginalSource")); | ||
defineExport("SourceMapSource", () => require("./SourceMapSource")); | ||
defineExport("CachedSource", () => require("./CachedSource")); | ||
defineExport("ConcatSource", () => require("./ConcatSource")); | ||
defineExport("ReplaceSource", () => require("./ReplaceSource")); | ||
defineExport("PrefixSource", () => require("./PrefixSource")); | ||
defineExport("SizeOnlySource", () => require("./SizeOnlySource")); | ||
defineExport("CompatSource", () => require("./CompatSource")); | ||
module.exports = mergeExports( | ||
{}, | ||
{ | ||
get Source() { | ||
return require("./Source"); | ||
}, | ||
get RawSource() { | ||
return require("./RawSource"); | ||
}, | ||
get OriginalSource() { | ||
return require("./OriginalSource"); | ||
}, | ||
get SourceMapSource() { | ||
return require("./SourceMapSource"); | ||
}, | ||
get CachedSource() { | ||
return require("./CachedSource"); | ||
}, | ||
get ConcatSource() { | ||
return require("./ConcatSource"); | ||
}, | ||
get ReplaceSource() { | ||
return require("./ReplaceSource"); | ||
}, | ||
get PrefixSource() { | ||
return require("./PrefixSource"); | ||
}, | ||
get SizeOnlySource() { | ||
return require("./SizeOnlySource"); | ||
}, | ||
get CompatSource() { | ||
return require("./CompatSource"); | ||
}, | ||
util: { | ||
get stringBufferUtils() { | ||
return require("./helpers/stringBufferUtils"); | ||
} | ||
} | ||
} | ||
); |
@@ -5,15 +5,44 @@ /* | ||
*/ | ||
"use strict"; | ||
const Source = require("./Source"); | ||
const { getMap, getSourceAndMap } = require("./helpers/getFromStreamChunks"); | ||
const getGeneratedSourceInfo = require("./helpers/getGeneratedSourceInfo"); | ||
const splitIntoLines = require("./helpers/splitIntoLines"); | ||
const getGeneratedSourceInfo = require("./helpers/getGeneratedSourceInfo"); | ||
const Source = require("./Source"); | ||
const splitIntoPotentialTokens = require("./helpers/splitIntoPotentialTokens"); | ||
const { | ||
isDualStringBufferCachingEnabled | ||
} = require("./helpers/stringBufferUtils"); | ||
/** @typedef {import("./Source").Hash} Hash */ | ||
/** @typedef {import("./Source").MapOptions} MapOptions */ | ||
/** @typedef {import("./Source").RawSourceMap} RawSourceMap */ | ||
/** @typedef {import("./Source").SourceAndMap} SourceAndMap */ | ||
/** @typedef {import("./Source").SourceValue} SourceValue */ | ||
/** @typedef {import("./helpers/getGeneratedSourceInfo").GeneratedSourceInfo} GeneratedSourceInfo */ | ||
/** @typedef {import("./helpers/streamChunks").OnChunk} OnChunk */ | ||
/** @typedef {import("./helpers/streamChunks").OnName} OnName */ | ||
/** @typedef {import("./helpers/streamChunks").OnSource} OnSource */ | ||
/** @typedef {import("./helpers/streamChunks").Options} Options */ | ||
class OriginalSource extends Source { | ||
/** | ||
* @param {string | Buffer} value value | ||
* @param {string} name name | ||
*/ | ||
constructor(value, name) { | ||
super(); | ||
const isBuffer = Buffer.isBuffer(value); | ||
/** | ||
* @private | ||
* @type {undefined | string} | ||
*/ | ||
this._value = isBuffer ? undefined : value; | ||
/** | ||
* @private | ||
* @type {undefined | Buffer} | ||
*/ | ||
this._valueAsBuffer = isBuffer ? value : undefined; | ||
@@ -27,5 +56,14 @@ this._name = name; | ||
/** | ||
* @returns {SourceValue} source | ||
*/ | ||
source() { | ||
if (this._value === undefined) { | ||
this._value = this._valueAsBuffer.toString("utf-8"); | ||
const value = | ||
/** @type {Buffer} */ | ||
(this._valueAsBuffer).toString("utf-8"); | ||
if (isDualStringBufferCachingEnabled()) { | ||
this._value = value; | ||
} | ||
return value; | ||
} | ||
@@ -37,3 +75,7 @@ return this._value; | ||
if (this._valueAsBuffer === undefined) { | ||
this._valueAsBuffer = Buffer.from(this._value, "utf-8"); | ||
const value = Buffer.from(/** @type {string} */ (this._value), "utf-8"); | ||
if (isDualStringBufferCachingEnabled()) { | ||
this._valueAsBuffer = value; | ||
} | ||
return value; | ||
} | ||
@@ -43,2 +85,6 @@ return this._valueAsBuffer; | ||
/** | ||
* @param {MapOptions=} options map options | ||
* @returns {RawSourceMap | null} map | ||
*/ | ||
map(options) { | ||
@@ -48,2 +94,6 @@ return getMap(this, options); | ||
/** | ||
* @param {MapOptions=} options map options | ||
* @returns {SourceAndMap} source and map | ||
*/ | ||
sourceAndMap(options) { | ||
@@ -54,11 +104,13 @@ return getSourceAndMap(this, 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} | ||
* @param {Options} options options | ||
* @param {OnChunk} onChunk called for each chunk of code | ||
* @param {OnSource} onSource called for each source | ||
* @param {OnName} onName called for each name | ||
* @returns {GeneratedSourceInfo} generated source info | ||
*/ | ||
streamChunks(options, onChunk, onSource, onName) { | ||
if (this._value === undefined) { | ||
this._value = this._valueAsBuffer.toString("utf-8"); | ||
this._value = | ||
/** @type {Buffer} */ | ||
(this._valueAsBuffer).toString("utf-8"); | ||
} | ||
@@ -100,6 +152,10 @@ onSource(0, this._name, this._value); | ||
if (generatedColumn === 0) { | ||
for (let line = 1; line < generatedLine; line++) | ||
for (let line = 1; line < /** @type {number} */ (generatedLine); line++) | ||
onChunk(undefined, line, 0, 0, line, 0, -1); | ||
} else { | ||
for (let line = 1; line <= generatedLine; line++) | ||
for ( | ||
let line = 1; | ||
line <= /** @type {number} */ (generatedLine); | ||
line++ | ||
) | ||
onChunk(undefined, line, 0, 0, line, 0, -1); | ||
@@ -113,2 +169,3 @@ } | ||
const matches = splitIntoLines(this._value); | ||
/** @type {string | undefined} */ | ||
let match; | ||
@@ -119,3 +176,4 @@ for (match of matches) { | ||
} | ||
return matches.length === 0 || match.endsWith("\n") | ||
return matches.length === 0 || | ||
/** @type {string} */ (match).endsWith("\n") | ||
? { | ||
@@ -128,3 +186,3 @@ generatedLine: matches.length + 1, | ||
generatedLine: matches.length, | ||
generatedColumn: match.length, | ||
generatedColumn: /** @type {string} */ (match).length, | ||
source: finalSource ? this._value : undefined | ||
@@ -135,8 +193,13 @@ }; | ||
/** | ||
* @param {Hash} hash hash | ||
* @returns {void} | ||
*/ | ||
updateHash(hash) { | ||
if (this._valueAsBuffer === undefined) { | ||
this._valueAsBuffer = Buffer.from(this._value, "utf-8"); | ||
} | ||
hash.update("OriginalSource"); | ||
hash.update(this._valueAsBuffer); | ||
hash.update( | ||
this._valueAsBuffer | ||
? /** @type {Buffer} */ (this._valueAsBuffer) | ||
: /** @type {string} */ (this._value) | ||
); | ||
hash.update(this._name || ""); | ||
@@ -143,0 +206,0 @@ } |
@@ -5,14 +5,34 @@ /* | ||
*/ | ||
"use strict"; | ||
const RawSource = require("./RawSource"); | ||
const Source = require("./Source"); | ||
const RawSource = require("./RawSource"); | ||
const { getMap, getSourceAndMap } = require("./helpers/getFromStreamChunks"); | ||
const streamChunks = require("./helpers/streamChunks"); | ||
const { getMap, getSourceAndMap } = require("./helpers/getFromStreamChunks"); | ||
/** @typedef {import("./Source").Hash} Hash */ | ||
/** @typedef {import("./Source").MapOptions} MapOptions */ | ||
/** @typedef {import("./Source").RawSourceMap} RawSourceMap */ | ||
/** @typedef {import("./Source").SourceAndMap} SourceAndMap */ | ||
/** @typedef {import("./Source").SourceValue} SourceValue */ | ||
/** @typedef {import("./helpers/getGeneratedSourceInfo").GeneratedSourceInfo} GeneratedSourceInfo */ | ||
/** @typedef {import("./helpers/streamChunks").OnChunk} OnChunk */ | ||
/** @typedef {import("./helpers/streamChunks").OnName} OnName */ | ||
/** @typedef {import("./helpers/streamChunks").OnSource} OnSource */ | ||
/** @typedef {import("./helpers/streamChunks").Options} Options */ | ||
const REPLACE_REGEX = /\n(?=.|\s)/g; | ||
class PrefixSource extends Source { | ||
/** | ||
* @param {string} prefix prefix | ||
* @param {string | Buffer | Source} source source | ||
*/ | ||
constructor(prefix, source) { | ||
super(); | ||
/** | ||
* @private | ||
* @type {Source} | ||
*/ | ||
this._source = | ||
@@ -33,4 +53,7 @@ typeof source === "string" || Buffer.isBuffer(source) | ||
/** | ||
* @returns {SourceValue} source | ||
*/ | ||
source() { | ||
const node = this._source.source(); | ||
const node = /** @type {string} */ (this._source.source()); | ||
const prefix = this._prefix; | ||
@@ -42,2 +65,6 @@ return prefix + node.replace(REPLACE_REGEX, "\n" + prefix); | ||
/** | ||
* @param {MapOptions=} options map options | ||
* @returns {RawSourceMap | null} map | ||
*/ | ||
map(options) { | ||
@@ -47,2 +74,6 @@ return getMap(this, options); | ||
/** | ||
* @param {MapOptions=} options map options | ||
* @returns {SourceAndMap} source and map | ||
*/ | ||
sourceAndMap(options) { | ||
@@ -52,2 +83,9 @@ return getSourceAndMap(this, options); | ||
/** | ||
* @param {Options} options options | ||
* @param {OnChunk} onChunk called for each chunk of code | ||
* @param {OnSource} onSource called for each source | ||
* @param {OnName} onName called for each name | ||
* @returns {GeneratedSourceInfo} generated source info | ||
*/ | ||
streamChunks(options, onChunk, onSource, onName) { | ||
@@ -104,3 +142,5 @@ const prefix = this._prefix; | ||
generatedColumn: | ||
generatedColumn === 0 ? 0 : prefixOffset + generatedColumn, | ||
generatedColumn === 0 | ||
? 0 | ||
: prefixOffset + /** @type {number} */ (generatedColumn), | ||
source: | ||
@@ -113,2 +153,6 @@ source !== undefined | ||
/** | ||
* @param {Hash} hash hash | ||
* @returns {void} | ||
*/ | ||
updateHash(hash) { | ||
@@ -115,0 +159,0 @@ hash.update("PrefixSource"); |
@@ -8,6 +8,24 @@ /* | ||
const Source = require("./Source"); | ||
const streamChunksOfRawSource = require("./helpers/streamChunksOfRawSource"); | ||
const Source = require("./Source"); | ||
const { | ||
internString, | ||
isDualStringBufferCachingEnabled | ||
} = require("./helpers/stringBufferUtils"); | ||
/** @typedef {import("./Source").Hash} Hash */ | ||
/** @typedef {import("./Source").MapOptions} MapOptions */ | ||
/** @typedef {import("./Source").RawSourceMap} RawSourceMap */ | ||
/** @typedef {import("./Source").SourceValue} SourceValue */ | ||
/** @typedef {import("./helpers/getGeneratedSourceInfo").GeneratedSourceInfo} GeneratedSourceInfo */ | ||
/** @typedef {import("./helpers/streamChunks").OnChunk} OnChunk */ | ||
/** @typedef {import("./helpers/streamChunks").OnName} OnName */ | ||
/** @typedef {import("./helpers/streamChunks").OnSource} OnSource */ | ||
/** @typedef {import("./helpers/streamChunks").Options} Options */ | ||
class RawSource extends Source { | ||
/** | ||
* @param {string | Buffer} value value | ||
* @param {boolean=} convertToString convert to string | ||
*/ | ||
constructor(value, convertToString = false) { | ||
@@ -17,8 +35,27 @@ super(); | ||
if (!isBuffer && typeof value !== "string") { | ||
throw new TypeError("argument 'value' must be either string of Buffer"); | ||
throw new TypeError("argument 'value' must be either string or Buffer"); | ||
} | ||
this._valueIsBuffer = !convertToString && isBuffer; | ||
this._value = convertToString && isBuffer ? undefined : value; | ||
const internedString = | ||
typeof value === "string" ? internString(value) : undefined; | ||
/** | ||
* @private | ||
* @type {undefined | string | Buffer} | ||
*/ | ||
this._value = | ||
convertToString && isBuffer | ||
? undefined | ||
: typeof value === "string" | ||
? internedString | ||
: value; | ||
/** | ||
* @private | ||
* @type {undefined | Buffer} | ||
*/ | ||
this._valueAsBuffer = isBuffer ? value : undefined; | ||
this._valueAsString = isBuffer ? undefined : value; | ||
/** | ||
* @private | ||
* @type {undefined | string} | ||
*/ | ||
this._valueAsString = isBuffer ? undefined : internedString; | ||
} | ||
@@ -30,5 +67,14 @@ | ||
/** | ||
* @returns {SourceValue} source | ||
*/ | ||
source() { | ||
if (this._value === undefined) { | ||
this._value = this._valueAsBuffer.toString("utf-8"); | ||
const value = | ||
/** @type {Buffer} */ | ||
(this._valueAsBuffer).toString("utf-8"); | ||
if (isDualStringBufferCachingEnabled()) { | ||
this._value = internString(value); | ||
} | ||
return value; | ||
} | ||
@@ -40,3 +86,7 @@ return this._value; | ||
if (this._valueAsBuffer === undefined) { | ||
this._valueAsBuffer = Buffer.from(this._value, "utf-8"); | ||
const value = Buffer.from(/** @type {string} */ (this._value), "utf-8"); | ||
if (isDualStringBufferCachingEnabled()) { | ||
this._valueAsBuffer = value; | ||
} | ||
return value; | ||
} | ||
@@ -46,2 +96,6 @@ return this._valueAsBuffer; | ||
/** | ||
* @param {MapOptions=} options map options | ||
* @returns {RawSourceMap | null} map | ||
*/ | ||
map(options) { | ||
@@ -52,20 +106,19 @@ return null; | ||
/** | ||
* @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} | ||
* @param {Options} options options | ||
* @param {OnChunk} onChunk called for each chunk of code | ||
* @param {OnSource} onSource called for each source | ||
* @param {OnName} onName called for each name | ||
* @returns {GeneratedSourceInfo} generated source info | ||
*/ | ||
streamChunks(options, onChunk, onSource, onName) { | ||
if (this._value === undefined) { | ||
this._value = Buffer.from(this._valueAsBuffer, "utf-8"); | ||
let strValue = this._valueAsString; | ||
if (strValue === undefined) { | ||
const value = this.source(); | ||
strValue = typeof value === "string" ? value : value.toString("utf-8"); | ||
if (isDualStringBufferCachingEnabled()) { | ||
this._valueAsString = internString(strValue); | ||
} | ||
} | ||
if (this._valueAsString === undefined) { | ||
this._valueAsString = | ||
typeof this._value === "string" | ||
? this._value | ||
: this._value.toString("utf-8"); | ||
} | ||
return streamChunksOfRawSource( | ||
this._valueAsString, | ||
strValue, | ||
onChunk, | ||
@@ -78,8 +131,13 @@ onSource, | ||
/** | ||
* @param {Hash} hash hash | ||
* @returns {void} | ||
*/ | ||
updateHash(hash) { | ||
if (this._valueAsBuffer === undefined) { | ||
this._valueAsBuffer = Buffer.from(this._value, "utf-8"); | ||
} | ||
hash.update("RawSource"); | ||
hash.update(this._valueAsBuffer); | ||
hash.update( | ||
this._valueAsBuffer | ||
? /** @type {Buffer} */ (this._valueAsBuffer) | ||
: /** @type {string} */ (this._valueAsString) | ||
); | ||
} | ||
@@ -86,0 +144,0 @@ } |
@@ -5,9 +5,21 @@ /* | ||
*/ | ||
"use strict"; | ||
const Source = require("./Source"); | ||
const { getMap, getSourceAndMap } = require("./helpers/getFromStreamChunks"); | ||
const splitIntoLines = require("./helpers/splitIntoLines"); | ||
const streamChunks = require("./helpers/streamChunks"); | ||
const Source = require("./Source"); | ||
const splitIntoLines = require("./helpers/splitIntoLines"); | ||
/** @typedef {import("./Source").Hash} Hash */ | ||
/** @typedef {import("./Source").MapOptions} MapOptions */ | ||
/** @typedef {import("./Source").RawSourceMap} RawSourceMap */ | ||
/** @typedef {import("./Source").SourceAndMap} SourceAndMap */ | ||
/** @typedef {import("./Source").SourceValue} SourceValue */ | ||
/** @typedef {import("./helpers/getGeneratedSourceInfo").GeneratedSourceInfo} GeneratedSourceInfo */ | ||
/** @typedef {import("./helpers/streamChunks").OnChunk} OnChunk */ | ||
/** @typedef {import("./helpers/streamChunks").OnName} OnName */ | ||
/** @typedef {import("./helpers/streamChunks").OnSource} OnSource */ | ||
/** @typedef {import("./helpers/streamChunks").Options} Options */ | ||
// since v8 7.0, Array.prototype.sort is stable | ||
@@ -24,2 +36,8 @@ const hasStableSort = | ||
class Replacement { | ||
/** | ||
* @param {number} start start | ||
* @param {number} end end | ||
* @param {string} content content | ||
* @param {string=} name name | ||
*/ | ||
constructor(start, end, content, name) { | ||
@@ -37,2 +55,6 @@ this.start = start; | ||
class ReplaceSource extends Source { | ||
/** | ||
* @param {Source} source source | ||
* @param {string=} name name | ||
*/ | ||
constructor(source, name) { | ||
@@ -56,2 +78,9 @@ super(); | ||
/** | ||
* @param {number} start start | ||
* @param {number} end end | ||
* @param {string} newValue new value | ||
* @param {string=} name name | ||
* @returns {void} | ||
*/ | ||
replace(start, end, newValue, name) { | ||
@@ -66,2 +95,8 @@ if (typeof newValue !== "string") | ||
/** | ||
* @param {number} pos pos | ||
* @param {string} newValue new value | ||
* @param {string=} name name | ||
* @returns {void} | ||
*/ | ||
insert(pos, newValue, name) { | ||
@@ -79,2 +114,5 @@ if (typeof newValue !== "string") | ||
/** | ||
* @returns {SourceValue} source | ||
*/ | ||
source() { | ||
@@ -109,2 +147,6 @@ if (this._replacements.length === 0) { | ||
/** | ||
* @param {MapOptions=} options map options | ||
* @returns {RawSourceMap | null} map | ||
*/ | ||
map(options) { | ||
@@ -117,2 +159,6 @@ if (this._replacements.length === 0) { | ||
/** | ||
* @param {MapOptions=} options map options | ||
* @returns {SourceAndMap} source and map | ||
*/ | ||
sourceAndMap(options) { | ||
@@ -146,3 +192,5 @@ if (this._replacements.length === 0) { | ||
if (diff2 !== 0) return diff2; | ||
return a.index - b.index; | ||
return ( | ||
/** @type {number} */ (a.index) - /** @type {number} */ (b.index) | ||
); | ||
}); | ||
@@ -153,5 +201,12 @@ } | ||
/** | ||
* @param {Options} options options | ||
* @param {OnChunk} onChunk called for each chunk of code | ||
* @param {OnSource} onSource called for each source | ||
* @param {OnName} onName called for each name | ||
* @returns {GeneratedSourceInfo} generated source info | ||
*/ | ||
streamChunks(options, onChunk, onSource, onName) { | ||
this._sortReplacements(); | ||
const repls = this._replacements; | ||
const replacements = this._replacements; | ||
let pos = 0; | ||
@@ -161,10 +216,23 @@ let i = 0; | ||
let nextReplacement = | ||
i < repls.length ? Math.floor(repls[i].start) : MAX_SOURCE_POSITION; | ||
i < replacements.length | ||
? Math.floor(replacements[i].start) | ||
: MAX_SOURCE_POSITION; | ||
let generatedLineOffset = 0; | ||
let generatedColumnOffset = 0; | ||
let generatedColumnOffsetLine = 0; | ||
/** @type {(string | string[] | undefined)[]} */ | ||
const sourceContents = []; | ||
/** @type {Map<string, number>} */ | ||
const nameMapping = new Map(); | ||
/** @type {number[]} */ | ||
const nameIndexMapping = []; | ||
/** | ||
* @param {number} sourceIndex source index | ||
* @param {number} line line | ||
* @param {number} column column | ||
* @param {string} expectedChunk expected chunk | ||
* @returns {boolean} result | ||
*/ | ||
const checkOriginalContent = (sourceIndex, line, column, expectedChunk) => { | ||
/** @type {undefined | string | string[]} */ | ||
let content = | ||
@@ -190,3 +258,3 @@ sourceIndex < sourceContents.length | ||
( | ||
chunk, | ||
_chunk, | ||
generatedLine, | ||
@@ -200,2 +268,3 @@ generatedColumn, | ||
let chunkPos = 0; | ||
const chunk = /** @type {string} */ (_chunk); | ||
let endPos = pos + chunk.length; | ||
@@ -285,3 +354,3 @@ | ||
// Insert replacement content splitted into chunks by lines | ||
const { content, name } = repls[i]; | ||
const { content, name } = replacements[i]; | ||
let matches = splitIntoLines(content); | ||
@@ -334,3 +403,3 @@ let replacementNameIndex = nameIndex; | ||
replacmentEnd, | ||
Math.floor(repls[i].end + 1) | ||
Math.floor(replacements[i].end + 1) | ||
); | ||
@@ -341,4 +410,4 @@ | ||
nextReplacement = | ||
i < repls.length | ||
? Math.floor(repls[i].start) | ||
i < replacements.length | ||
? Math.floor(replacements[i].start) | ||
: MAX_SOURCE_POSITION; | ||
@@ -429,8 +498,8 @@ | ||
let remainer = ""; | ||
for (; i < repls.length; i++) { | ||
remainer += repls[i].content; | ||
for (; i < replacements.length; i++) { | ||
remainer += replacements[i].content; | ||
} | ||
// Insert remaining replacements content splitted into chunks by lines | ||
let line = generatedLine + generatedLineOffset; | ||
let line = /** @type {number} */ (generatedLine) + generatedLineOffset; | ||
let matches = splitIntoLines(remainer); | ||
@@ -442,3 +511,4 @@ for (let m = 0; m < matches.length; m++) { | ||
line, | ||
generatedColumn + | ||
/** @type {number} */ | ||
(generatedColumn) + | ||
(line === generatedColumnOffsetLine ? generatedColumnOffset : 0), | ||
@@ -461,3 +531,3 @@ -1, | ||
line++; | ||
generatedColumnOffset = -generatedColumn; | ||
generatedColumnOffset = -(/** @type {number} */ (generatedColumn)); | ||
generatedColumnOffsetLine = line; | ||
@@ -470,3 +540,4 @@ } | ||
generatedColumn: | ||
generatedColumn + | ||
/** @type {number} */ | ||
(generatedColumn) + | ||
(line === generatedColumnOffsetLine ? generatedColumnOffset : 0) | ||
@@ -476,2 +547,6 @@ }; | ||
/** | ||
* @param {Hash} hash hash | ||
* @returns {void} | ||
*/ | ||
updateHash(hash) { | ||
@@ -483,3 +558,5 @@ this._sortReplacements(); | ||
for (const repl of this._replacements) { | ||
hash.update(`${repl.start}${repl.end}${repl.content}${repl.name}`); | ||
hash.update( | ||
`${repl.start}${repl.end}${repl.content}${repl.name ? repl.name : ""}` | ||
); | ||
} | ||
@@ -490,1 +567,2 @@ } | ||
module.exports = ReplaceSource; | ||
module.exports.Replacement = Replacement; |
@@ -5,2 +5,3 @@ /* | ||
*/ | ||
"use strict"; | ||
@@ -10,3 +11,11 @@ | ||
/** @typedef {import("./Source").Hash} Hash */ | ||
/** @typedef {import("./Source").MapOptions} MapOptions */ | ||
/** @typedef {import("./Source").RawSourceMap} RawSourceMap */ | ||
/** @typedef {import("./Source").SourceValue} SourceValue */ | ||
class SizeOnlySource extends Source { | ||
/** | ||
* @param {number} size size | ||
*/ | ||
constructor(size) { | ||
@@ -27,2 +36,5 @@ super(); | ||
/** | ||
* @returns {SourceValue} source | ||
*/ | ||
source() { | ||
@@ -32,2 +44,5 @@ throw this._error(); | ||
/** | ||
* @returns {Buffer} buffer | ||
*/ | ||
buffer() { | ||
@@ -37,2 +52,6 @@ throw this._error(); | ||
/** | ||
* @param {MapOptions=} options map options | ||
* @returns {RawSourceMap | null} map | ||
*/ | ||
map(options) { | ||
@@ -42,3 +61,7 @@ throw this._error(); | ||
updateHash() { | ||
/** | ||
* @param {Hash} hash hash | ||
* @returns {void} | ||
*/ | ||
updateHash(hash) { | ||
throw this._error(); | ||
@@ -45,0 +68,0 @@ } |
@@ -5,5 +5,40 @@ /* | ||
*/ | ||
"use strict"; | ||
/** | ||
* @typedef {object} MapOptions | ||
* @property {boolean=} columns | ||
* @property {boolean=} module | ||
*/ | ||
/** | ||
* @typedef {object} RawSourceMap | ||
* @property {number} version | ||
* @property {string[]} sources | ||
* @property {string[]} names | ||
* @property {string=} sourceRoot | ||
* @property {string[]=} sourcesContent | ||
* @property {string} mappings | ||
* @property {string} file | ||
*/ | ||
/** @typedef {string | Buffer} SourceValue */ | ||
/** | ||
* @typedef {object} SourceAndMap | ||
* @property {SourceValue} source | ||
* @property {RawSourceMap | null} map | ||
*/ | ||
/** | ||
* @typedef {object} Hash | ||
* @property {(data: string | Buffer, inputEncoding?: string) => Hash} update | ||
* @property {(encoding?: string) => string | Buffer} digest | ||
*/ | ||
class Source { | ||
/** | ||
* @returns {SourceValue} source | ||
*/ | ||
source() { | ||
@@ -23,2 +58,6 @@ throw new Error("Abstract"); | ||
/** | ||
* @param {MapOptions=} options map options | ||
* @returns {RawSourceMap | null} map | ||
*/ | ||
map(options) { | ||
@@ -28,2 +67,6 @@ return null; | ||
/** | ||
* @param {MapOptions=} options map options | ||
* @returns {SourceAndMap} source and map | ||
*/ | ||
sourceAndMap(options) { | ||
@@ -36,2 +79,6 @@ return { | ||
/** | ||
* @param {Hash} hash hash | ||
* @returns {void} | ||
*/ | ||
updateHash(hash) { | ||
@@ -38,0 +85,0 @@ throw new Error("Abstract"); |
@@ -5,10 +5,33 @@ /* | ||
*/ | ||
"use strict"; | ||
const Source = require("./Source"); | ||
const { getMap, getSourceAndMap } = require("./helpers/getFromStreamChunks"); | ||
const streamChunksOfCombinedSourceMap = require("./helpers/streamChunksOfCombinedSourceMap"); | ||
const streamChunksOfSourceMap = require("./helpers/streamChunksOfSourceMap"); | ||
const streamChunksOfCombinedSourceMap = require("./helpers/streamChunksOfCombinedSourceMap"); | ||
const { getMap, getSourceAndMap } = require("./helpers/getFromStreamChunks"); | ||
const { | ||
isDualStringBufferCachingEnabled | ||
} = require("./helpers/stringBufferUtils"); | ||
/** @typedef {import("./Source").Hash} Hash */ | ||
/** @typedef {import("./Source").MapOptions} MapOptions */ | ||
/** @typedef {import("./Source").RawSourceMap} RawSourceMap */ | ||
/** @typedef {import("./Source").SourceAndMap} SourceAndMap */ | ||
/** @typedef {import("./Source").SourceValue} SourceValue */ | ||
/** @typedef {import("./helpers/getGeneratedSourceInfo").GeneratedSourceInfo} GeneratedSourceInfo */ | ||
/** @typedef {import("./helpers/streamChunks").OnChunk} OnChunk */ | ||
/** @typedef {import("./helpers/streamChunks").OnName} OnName */ | ||
/** @typedef {import("./helpers/streamChunks").OnSource} OnSource */ | ||
/** @typedef {import("./helpers/streamChunks").Options} Options */ | ||
class SourceMapSource extends Source { | ||
/** | ||
* @param {string | Buffer} value value | ||
* @param {string} name name | ||
* @param {string | Buffer | RawSourceMap=} sourceMap source map | ||
* @param {SourceValue=} originalSource original source | ||
* @param {(string | Buffer | RawSourceMap)=} innerSourceMap inner source map | ||
* @param {boolean=} removeOriginalSource do remove original source | ||
*/ | ||
constructor( | ||
@@ -24,3 +47,11 @@ value, | ||
const valueIsBuffer = Buffer.isBuffer(value); | ||
/** | ||
* @private | ||
* @type {undefined | string} | ||
*/ | ||
this._valueAsString = valueIsBuffer ? undefined : value; | ||
/** | ||
* @private | ||
* @type {undefined | Buffer} | ||
*/ | ||
this._valueAsBuffer = valueIsBuffer ? value : undefined; | ||
@@ -33,5 +64,17 @@ | ||
const sourceMapIsString = typeof sourceMap === "string"; | ||
/** | ||
* @private | ||
* @type {undefined | RawSourceMap} | ||
*/ | ||
this._sourceMapAsObject = | ||
sourceMapIsBuffer || sourceMapIsString ? undefined : sourceMap; | ||
/** | ||
* @private | ||
* @type {undefined | string} | ||
*/ | ||
this._sourceMapAsString = sourceMapIsString ? sourceMap : undefined; | ||
/** | ||
* @private | ||
* @type {undefined | Buffer} | ||
*/ | ||
this._sourceMapAsBuffer = sourceMapIsBuffer ? sourceMap : undefined; | ||
@@ -51,2 +94,6 @@ | ||
const innerSourceMapIsString = typeof innerSourceMap === "string"; | ||
/** | ||
* @private | ||
* @type {undefined | RawSourceMap} | ||
*/ | ||
this._innerSourceMapAsObject = | ||
@@ -56,5 +103,13 @@ innerSourceMapIsBuffer || innerSourceMapIsString | ||
: innerSourceMap; | ||
/** | ||
* @private | ||
* @type {undefined | string} | ||
*/ | ||
this._innerSourceMapAsString = innerSourceMapIsString | ||
? innerSourceMap | ||
: undefined; | ||
/** | ||
* @private | ||
* @type {undefined | Buffer} | ||
*/ | ||
this._innerSourceMapAsBuffer = innerSourceMapIsBuffer | ||
@@ -67,115 +122,172 @@ ? innerSourceMap | ||
_ensureValueBuffer() { | ||
// eslint-disable-next-line valid-jsdoc | ||
/** | ||
* @returns {[Buffer, string, Buffer, Buffer | undefined, Buffer | undefined, boolean | undefined]} args | ||
*/ | ||
getArgsAsBuffers() { | ||
return [ | ||
this.buffer(), | ||
this._name, | ||
this._sourceMapBuffer(), | ||
this._originalSourceBuffer(), | ||
this._innerSourceMapBuffer(), | ||
this._removeOriginalSource | ||
]; | ||
} | ||
buffer() { | ||
if (this._valueAsBuffer === undefined) { | ||
this._valueAsBuffer = Buffer.from(this._valueAsString, "utf-8"); | ||
const value = Buffer.from( | ||
/** @type {string} */ (this._valueAsString), | ||
"utf-8" | ||
); | ||
if (isDualStringBufferCachingEnabled()) { | ||
this._valueAsBuffer = value; | ||
} | ||
return value; | ||
} | ||
return this._valueAsBuffer; | ||
} | ||
_ensureValueString() { | ||
/** | ||
* @returns {SourceValue} source | ||
*/ | ||
source() { | ||
if (this._valueAsString === undefined) { | ||
this._valueAsString = this._valueAsBuffer.toString("utf-8"); | ||
const value = | ||
/** @type {Buffer} */ | ||
(this._valueAsBuffer).toString("utf-8"); | ||
if (isDualStringBufferCachingEnabled()) { | ||
this._valueAsString = value; | ||
} | ||
return value; | ||
} | ||
return this._valueAsString; | ||
} | ||
_ensureOriginalSourceBuffer() { | ||
/** | ||
* @private | ||
* @returns {undefined | Buffer} buffer | ||
*/ | ||
_originalSourceBuffer() { | ||
if (this._originalSourceAsBuffer === undefined && this._hasOriginalSource) { | ||
this._originalSourceAsBuffer = Buffer.from( | ||
this._originalSourceAsString, | ||
const value = Buffer.from( | ||
/** @type {string} */ | ||
(this._originalSourceAsString), | ||
"utf-8" | ||
); | ||
if (isDualStringBufferCachingEnabled()) { | ||
this._originalSourceAsBuffer = value; | ||
} | ||
return value; | ||
} | ||
return this._originalSourceAsBuffer; | ||
} | ||
_ensureOriginalSourceString() { | ||
_originalSourceString() { | ||
if (this._originalSourceAsString === undefined && this._hasOriginalSource) { | ||
this._originalSourceAsString = this._originalSourceAsBuffer.toString( | ||
"utf-8" | ||
); | ||
const value = | ||
/** @type {Buffer} */ | ||
(this._originalSourceAsBuffer).toString("utf-8"); | ||
if (isDualStringBufferCachingEnabled()) { | ||
this._originalSourceAsString = value; | ||
} | ||
return value; | ||
} | ||
return this._originalSourceAsString; | ||
} | ||
_ensureInnerSourceMapObject() { | ||
_innerSourceMapObject() { | ||
if (this._innerSourceMapAsObject === undefined && this._hasInnerSourceMap) { | ||
this._ensureInnerSourceMapString(); | ||
this._innerSourceMapAsObject = JSON.parse(this._innerSourceMapAsString); | ||
const value = JSON.parse(this._innerSourceMapString()); | ||
if (isDualStringBufferCachingEnabled()) { | ||
this._innerSourceMapAsObject = value; | ||
} | ||
return value; | ||
} | ||
return this._innerSourceMapAsObject; | ||
} | ||
_ensureInnerSourceMapBuffer() { | ||
_innerSourceMapBuffer() { | ||
if (this._innerSourceMapAsBuffer === undefined && this._hasInnerSourceMap) { | ||
this._ensureInnerSourceMapString(); | ||
this._innerSourceMapAsBuffer = Buffer.from( | ||
this._innerSourceMapAsString, | ||
"utf-8" | ||
); | ||
const value = Buffer.from(this._innerSourceMapString(), "utf-8"); | ||
if (isDualStringBufferCachingEnabled()) { | ||
this._innerSourceMapAsBuffer = value; | ||
} | ||
return value; | ||
} | ||
return this._innerSourceMapAsBuffer; | ||
} | ||
_ensureInnerSourceMapString() { | ||
/** | ||
* @private | ||
* @returns {string} result | ||
*/ | ||
_innerSourceMapString() { | ||
if (this._innerSourceMapAsString === undefined && this._hasInnerSourceMap) { | ||
if (this._innerSourceMapAsBuffer !== undefined) { | ||
this._innerSourceMapAsString = this._innerSourceMapAsBuffer.toString( | ||
"utf-8" | ||
); | ||
const value = this._innerSourceMapAsBuffer.toString("utf-8"); | ||
if (isDualStringBufferCachingEnabled()) { | ||
this._innerSourceMapAsString = value; | ||
} | ||
return value; | ||
} else { | ||
this._innerSourceMapAsString = JSON.stringify( | ||
this._innerSourceMapAsObject | ||
); | ||
const value = JSON.stringify(this._innerSourceMapAsObject); | ||
if (isDualStringBufferCachingEnabled()) { | ||
this._innerSourceMapAsString = value; | ||
} | ||
return value; | ||
} | ||
} | ||
return /** @type {string} */ (this._innerSourceMapAsString); | ||
} | ||
_ensureSourceMapObject() { | ||
_sourceMapObject() { | ||
if (this._sourceMapAsObject === undefined) { | ||
this._ensureSourceMapString(); | ||
this._sourceMapAsObject = JSON.parse(this._sourceMapAsString); | ||
const value = JSON.parse(this._sourceMapString()); | ||
if (isDualStringBufferCachingEnabled()) { | ||
this._sourceMapAsObject = value; | ||
} | ||
return value; | ||
} | ||
return this._sourceMapAsObject; | ||
} | ||
_ensureSourceMapBuffer() { | ||
_sourceMapBuffer() { | ||
if (this._sourceMapAsBuffer === undefined) { | ||
this._ensureSourceMapString(); | ||
this._sourceMapAsBuffer = Buffer.from(this._sourceMapAsString, "utf-8"); | ||
const value = Buffer.from(this._sourceMapString(), "utf-8"); | ||
if (isDualStringBufferCachingEnabled()) { | ||
this._sourceMapAsBuffer = value; | ||
} | ||
return value; | ||
} | ||
return this._sourceMapAsBuffer; | ||
} | ||
_ensureSourceMapString() { | ||
_sourceMapString() { | ||
if (this._sourceMapAsString === undefined) { | ||
if (this._sourceMapAsBuffer !== undefined) { | ||
this._sourceMapAsString = this._sourceMapAsBuffer.toString("utf-8"); | ||
const value = this._sourceMapAsBuffer.toString("utf-8"); | ||
if (isDualStringBufferCachingEnabled()) { | ||
this._sourceMapAsString = value; | ||
} | ||
return value; | ||
} else { | ||
this._sourceMapAsString = JSON.stringify(this._sourceMapAsObject); | ||
const value = JSON.stringify(this._sourceMapAsObject); | ||
if (isDualStringBufferCachingEnabled()) { | ||
this._sourceMapAsString = value; | ||
} | ||
return value; | ||
} | ||
} | ||
return this._sourceMapAsString; | ||
} | ||
getArgsAsBuffers() { | ||
this._ensureValueBuffer(); | ||
this._ensureSourceMapBuffer(); | ||
this._ensureOriginalSourceBuffer(); | ||
this._ensureInnerSourceMapBuffer(); | ||
return [ | ||
this._valueAsBuffer, | ||
this._name, | ||
this._sourceMapAsBuffer, | ||
this._originalSourceAsBuffer, | ||
this._innerSourceMapAsBuffer, | ||
this._removeOriginalSource | ||
]; | ||
} | ||
buffer() { | ||
this._ensureValueBuffer(); | ||
return this._valueAsBuffer; | ||
} | ||
source() { | ||
this._ensureValueString(); | ||
return this._valueAsString; | ||
} | ||
/** | ||
* @param {MapOptions=} options map options | ||
* @returns {RawSourceMap | null} map | ||
*/ | ||
map(options) { | ||
if (!this._hasInnerSourceMap) { | ||
this._ensureSourceMapObject(); | ||
return this._sourceMapAsObject; | ||
return this._sourceMapObject(); | ||
} | ||
@@ -185,9 +297,11 @@ return getMap(this, options); | ||
/** | ||
* @param {MapOptions=} options map options | ||
* @returns {SourceAndMap} source and map | ||
*/ | ||
sourceAndMap(options) { | ||
if (!this._hasInnerSourceMap) { | ||
this._ensureValueString(); | ||
this._ensureSourceMapObject(); | ||
return { | ||
source: this._valueAsString, | ||
map: this._sourceMapAsObject | ||
source: this.source(), | ||
map: this._sourceMapObject() | ||
}; | ||
@@ -198,14 +312,19 @@ } | ||
/** | ||
* @param {Options} options options | ||
* @param {OnChunk} onChunk called for each chunk of code | ||
* @param {OnSource} onSource called for each source | ||
* @param {OnName} onName called for each name | ||
* @returns {GeneratedSourceInfo} generated source info | ||
*/ | ||
streamChunks(options, onChunk, onSource, onName) { | ||
this._ensureValueString(); | ||
this._ensureSourceMapObject(); | ||
this._ensureOriginalSourceString(); | ||
if (this._hasInnerSourceMap) { | ||
this._ensureInnerSourceMapObject(); | ||
return streamChunksOfCombinedSourceMap( | ||
this._valueAsString, | ||
this._sourceMapAsObject, | ||
/** @type {string} */ | ||
(this.source()), | ||
this._sourceMapObject(), | ||
this._name, | ||
this._originalSourceAsString, | ||
this._innerSourceMapAsObject, | ||
/** @type {string} */ | ||
(this._originalSourceString()), | ||
this._innerSourceMapObject(), | ||
this._removeOriginalSource, | ||
@@ -220,4 +339,5 @@ onChunk, | ||
return streamChunksOfSourceMap( | ||
this._valueAsString, | ||
this._sourceMapAsObject, | ||
/** @type {string} */ | ||
(this.source()), | ||
this._sourceMapObject(), | ||
onChunk, | ||
@@ -232,20 +352,37 @@ onSource, | ||
/** | ||
* @param {Hash} hash hash | ||
* @returns {void} | ||
*/ | ||
updateHash(hash) { | ||
this._ensureValueBuffer(); | ||
this._ensureSourceMapBuffer(); | ||
this._ensureOriginalSourceBuffer(); | ||
this._ensureInnerSourceMapBuffer(); | ||
hash.update("SourceMapSource"); | ||
hash.update( | ||
this._valueAsBuffer | ||
? this._valueAsBuffer | ||
: typeof this._valueAsString === "string" | ||
? this._valueAsString | ||
: // Fallback when memory optimization enabled | ||
this.buffer() | ||
); | ||
hash.update( | ||
this._sourceMapAsBuffer | ||
? this._sourceMapAsBuffer | ||
: typeof this._sourceMapAsString === "string" | ||
? this._sourceMapAsString | ||
: // Fallback when memory optimization enabled | ||
this._sourceMapBuffer() | ||
); | ||
hash.update(this._valueAsBuffer); | ||
hash.update(this._sourceMapAsBuffer); | ||
if (this._hasOriginalSource) { | ||
hash.update(this._originalSourceAsBuffer); | ||
hash.update( | ||
/** @type {Buffer} */ | ||
(this._originalSourceBuffer()) | ||
); | ||
} | ||
if (this._hasInnerSourceMap) { | ||
hash.update(this._innerSourceMapAsBuffer); | ||
hash.update( | ||
/** @type {Buffer} */ | ||
(this._innerSourceMapBuffer()) | ||
); | ||
} | ||
@@ -252,0 +389,0 @@ |
{ | ||
"name": "webpack-sources", | ||
"version": "3.2.3", | ||
"version": "3.3.0", | ||
"description": "Source code handling classes for webpack", | ||
"main": "./lib/index.js", | ||
"main": "lib/index.js", | ||
"types": "types.d.ts", | ||
"scripts": { | ||
"lint": "yarn lint:code && yarn lint:types && yarn lint:types-test && yarn lint:special", | ||
"lint:code": "eslint --cache lib/**/*.js test/*.js", | ||
"lint:special": "node node_modules/tooling/lockfile-lint && node node_modules/tooling/inherit-types && node node_modules/tooling/format-file-header && node node_modules/tooling/generate-types", | ||
"lint:types": "tsc", | ||
"lint:types-test": "tsc -p tsconfig.types.test.json", | ||
"fmt": "yarn fmt:base --loglevel warn --write", | ||
"fmt:check": "yarn fmt:base --check", | ||
"fmt:base": "prettier --cache --ignore-unknown .", | ||
"fix": "yarn fix:code && yarn fix:special", | ||
"fix:code": "yarn lint:code --fix", | ||
"fix:special": "node node_modules/tooling/inherit-types --write && node node_modules/tooling/format-file-header --write && node node_modules/tooling/generate-types --write", | ||
"pretest": "yarn lint", | ||
"test": "jest", | ||
"lint": "eslint --cache lib test/*.js", | ||
"cover": "jest --coverage" | ||
}, | ||
"devDependencies": { | ||
"@types/jest": "^27.5.2", | ||
"coveralls": "^3.0.2", | ||
@@ -17,3 +29,2 @@ "eslint": "^7.7.0", | ||
"eslint-plugin-jest": "^23.20.0", | ||
"eslint-plugin-mocha": "^8.0.0", | ||
"eslint-plugin-node": "^11.1.0", | ||
@@ -23,10 +34,13 @@ "eslint-plugin-nodeca": "^1.0.3", | ||
"istanbul": "^0.4.1", | ||
"jest": "^26.4.0", | ||
"jest": "^27.5.1", | ||
"prettier": "^2.0.5", | ||
"source-map": "^0.7.3", | ||
"sourcemap-validator": "^2.1.0" | ||
"sourcemap-validator": "^2.1.0", | ||
"tooling": "webpack/tooling#v1.23.9", | ||
"typescript": "^5.3.3", | ||
"webpack": "^5.99.9" | ||
}, | ||
"files": [ | ||
"lib/", | ||
"!lib/helpers/__mocks__" | ||
"types.d.ts" | ||
], | ||
@@ -33,0 +47,0 @@ "engines": { |
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
136590
49.59%29
7.41%4546
47.93%16
23.08%1
Infinity%