Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions doc/api/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -1970,6 +1970,9 @@ generated code.

Getter for the payload used to construct the [`SourceMap`][] instance.

The returned object is frozen with [`Object.freeze()`][], and the same
reference is returned on every access. Do not mutate the returned object.

#### `sourceMap.findEntry(lineOffset, columnOffset)`

* `lineOffset` {number} The zero-indexed line number offset in
Expand Down Expand Up @@ -2065,6 +2068,7 @@ returned object contains the following keys:
[`module`]: #the-module-object
[`os.tmpdir()`]: os.md#ostmpdir
[`register`]: #moduleregisterspecifier-parenturl-options
[`Object.freeze()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
[`util.TextDecoder`]: util.md#class-utiltextdecoder
[accepted final formats]: #accepted-final-formats-returned-by-load
[asynchronous `load` hook]: #asynchronous-loadurl-context-nextload
Expand Down
14 changes: 6 additions & 8 deletions lib/internal/source_map/source_map.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ const {
ArrayPrototypePush,
ArrayPrototypeSlice,
ArrayPrototypeSort,
ObjectFreeze,
ObjectPrototypeHasOwnProperty,
StringPrototypeCharAt,
Symbol,
Expand Down Expand Up @@ -144,15 +145,15 @@ class SourceMap {
this.#payload = cloneSourceMapV3(payload);
this.#parseMappingPayload();
if (ArrayIsArray(lineLengths) && lineLengths.length) {
this.#lineLengths = lineLengths;
this.#lineLengths = ObjectFreeze(ArrayPrototypeSlice(lineLengths));
}
}

/**
* @returns {object} raw source map v3 payload.
*/
get payload() {
return cloneSourceMapV3(this.#payload);
return this.#payload;
}

get [kMappings]() {
Expand All @@ -163,10 +164,7 @@ class SourceMap {
* @returns {number[] | undefined} line lengths of generated source code
*/
get lineLengths() {
if (this.#lineLengths) {
return ArrayPrototypeSlice(this.#lineLengths);
}
return undefined;
return this.#lineLengths;
}

#parseMappingPayload = () => {
Expand Down Expand Up @@ -366,10 +364,10 @@ function cloneSourceMapV3(payload) {
for (const key in payload) {
if (ObjectPrototypeHasOwnProperty(payload, key) &&
ArrayIsArray(payload[key])) {
payload[key] = ArrayPrototypeSlice(payload[key]);
payload[key] = ObjectFreeze(ArrayPrototypeSlice(payload[key]));
}
}
return payload;
return ObjectFreeze(payload);
}

/**
Expand Down
13 changes: 13 additions & 0 deletions test/parallel/test-source-map-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,14 @@ const { readFileSync } = require('fs');
assert.notStrictEqual(payload, sourceMap.payload);
assert.strictEqual(payload.sources[0], sourceMap.payload.sources[0]);
assert.notStrictEqual(payload.sources, sourceMap.payload.sources);
// The payload and its arrays should be frozen to avoid unnecessary cloning:
assert(Object.isFrozen(sourceMap.payload));
assert(Object.isFrozen(sourceMap.payload.sources));
// The same frozen object is returned on each call:
assert.strictEqual(sourceMap.payload, sourceMap.payload);
// lineLengths should be frozen and return the same reference each call:
assert(Object.isFrozen(sourceMap.lineLengths));
assert.strictEqual(sourceMap.lineLengths, sourceMap.lineLengths);
}

// findEntry() and findOrigin() must return empty object instead of
Expand Down Expand Up @@ -178,6 +186,11 @@ const { readFileSync } = require('fs');
assert.notStrictEqual(payload, sourceMap.payload);
assert.strictEqual(payload.sources[0], sourceMap.payload.sources[0]);
assert.notStrictEqual(payload.sources, sourceMap.payload.sources);
// The payload and its arrays should be frozen to avoid unnecessary cloning:
assert(Object.isFrozen(sourceMap.payload));
assert(Object.isFrozen(sourceMap.payload.sources));
// The same frozen object is returned on each call:
assert.strictEqual(sourceMap.payload, sourceMap.payload);
}

// Test various known decodings to ensure decodeVLQ works correctly.
Expand Down
Loading