Skip to content

Commit c0f5b1e

Browse files
committed
fix esm/file URI support
1 parent d9cc113 commit c0f5b1e

File tree

2 files changed

+56
-18
lines changed

2 files changed

+56
-18
lines changed

source-map-support.js

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const { TraceMap, originalPositionFor, AnyMap } = require('@jridgewell/trace-mapping');
22
const resolveUri = require('@jridgewell/resolve-uri');
33
var path = require('path');
4-
const { fileURLToPath } = require('url');
4+
const { fileURLToPath, pathToFileURL } = require('url');
55
var util = require('util');
66

77
var fs;
@@ -94,11 +94,11 @@ var sharedData = initializeSharedData({
9494
emptyCacheBetweenOperations: false,
9595

9696
// Maps a file path to a string containing the file contents
97-
fileContentsCache: {},
97+
fileContentsCache: Object.create(null),
9898

9999
// Maps a file path to a source map for that file
100100
/** @type {Record<string, {url: string, map: TraceMap}} */
101-
sourceMapCache: {},
101+
sourceMapCache: Object.create(null),
102102

103103
// Priority list of retrieve handlers
104104
retrieveFileHandlers: [],
@@ -129,6 +129,44 @@ function hasGlobalProcessEventEmitter() {
129129
return ((typeof process === 'object') && (process !== null) && (typeof process.on === 'function'));
130130
}
131131

132+
// #region Caches
133+
/** @param {string} pathOrFileUrl */
134+
function getCacheKey(pathOrFileUrl) {
135+
if(pathOrFileUrl.startsWith('file:/')) {
136+
// Must normalize spaces to %20, stuff like that
137+
return new URL(pathOrFileUrl).toString();
138+
} else {
139+
try {
140+
return pathToFileURL(pathOrFileUrl).toString();
141+
} catch {
142+
return pathOrFileUrl;
143+
}
144+
}
145+
}
146+
function getFileContentsCache(key) {
147+
return sharedData.fileContentsCache[getCacheKey(key)];
148+
}
149+
function hasFileContentsCacheFromKey(key) {
150+
return Object.prototype.hasOwnProperty.call(sharedData.fileContentsCache, key);
151+
}
152+
function getFileContentsCacheFromKey(key) {
153+
return sharedData.fileContentsCache[key];
154+
}
155+
function setFileContentsCache(key, value) {
156+
return sharedData.fileContentsCache[getCacheKey(key)] = value;
157+
}
158+
function getSourceMapCache(key) {
159+
return sharedData.sourceMapCache[getCacheKey(key)];
160+
}
161+
function setSourceMapCache(key, value) {
162+
return sharedData.sourceMapCache[getCacheKey(key)] = value;
163+
}
164+
function clearCaches() {
165+
sharedData.fileContentsCache = Object.create(null);
166+
sharedData.sourceMapCache = Object.create(null);
167+
}
168+
// #endregion Caches
169+
132170
function handlerExec(list, internalList) {
133171
return function(arg) {
134172
for (var i = 0; i < list.length; i++) {
@@ -160,8 +198,9 @@ sharedData.internalRetrieveFileHandlers.push(function(path) {
160198
'/'; // file:///root-dir/file -> /root-dir/file
161199
});
162200
}
163-
if (path in sharedData.fileContentsCache) {
164-
return sharedData.fileContentsCache[path];
201+
const key = getCacheKey(path);
202+
if(hasFileContentsCacheFromKey(key)) {
203+
return getFileContentsCacheFromKey(key);
165204
}
166205

167206
var contents = '';
@@ -182,7 +221,7 @@ sharedData.internalRetrieveFileHandlers.push(function(path) {
182221
/* ignore any errors */
183222
}
184223

185-
return sharedData.fileContentsCache[path] = contents;
224+
return setFileContentsCache(path, contents);
186225
});
187226

188227
// Support URLs relative to a directory, but be careful about a protocol prefix
@@ -257,15 +296,15 @@ sharedData.internalRetrieveMapHandlers.push(function(source) {
257296
});
258297

259298
function mapSourcePosition(position) {
260-
var sourceMap = sharedData.sourceMapCache[position.source];
299+
var sourceMap = getSourceMapCache(position.source);
261300
if (!sourceMap) {
262301
// Call the (overrideable) retrieveSourceMap function to get the source map.
263302
var urlAndMap = retrieveSourceMap(position.source);
264303
if (urlAndMap) {
265-
sourceMap = sharedData.sourceMapCache[position.source] = {
304+
sourceMap = setSourceMapCache(position.source, {
266305
url: urlAndMap.url,
267306
map: new AnyMap(urlAndMap.map, urlAndMap.url)
268-
};
307+
});
269308

270309
// Load all sources stored inline with the source map into the file cache
271310
// to pretend like they are already loaded. They may not exist on disk.
@@ -274,15 +313,15 @@ function mapSourcePosition(position) {
274313
var contents = sourceMap.map.sourcesContent[i];
275314
if (contents) {
276315
var url = supportRelativeURL(sourceMap.url, source);
277-
sharedData.fileContentsCache[url] = contents;
316+
setFileContentsCache(url, contents);
278317
}
279318
});
280319
}
281320
} else {
282-
sourceMap = sharedData.sourceMapCache[position.source] = {
321+
sourceMap = setSourceMapCache(position.source, {
283322
url: null,
284323
map: null
285-
};
324+
});
286325
}
287326
}
288327

@@ -509,8 +548,7 @@ function createPrepareStackTrace(hookState) {
509548
if(!hookState.enabled) return hookState.originalValue.apply(this, arguments);
510549

511550
if (sharedData.emptyCacheBetweenOperations) {
512-
sharedData.fileContentsCache = {};
513-
sharedData.sourceMapCache = {};
551+
clearCaches();
514552
}
515553

516554
// node gives its own errors special treatment. Mimic that behavior
@@ -550,7 +588,7 @@ function getErrorSource(error) {
550588
var column = +match[3];
551589

552590
// Support the inline sourceContents inside the source map
553-
var contents = sharedData.fileContentsCache[source];
591+
var contents = getFileContentsCache(source);
554592

555593
// Support files on disk
556594
if (!contents && fs && fs.existsSync(source)) {
@@ -705,8 +743,8 @@ exports.install = function(options) {
705743

706744
if (!$compile.__sourceMapSupport) {
707745
Module.prototype._compile = function(content, filename) {
708-
sharedData.fileContentsCache[filename] = content;
709-
sharedData.sourceMapCache[filename] = undefined;
746+
setFileContentsCache(filename, content);
747+
setSourceMapCache(filename, undefined);
710748
return $compile.call(this, content, filename);
711749
};
712750

test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ it('specifically requested error source', function(done) {
594594
]);
595595
});
596596

597-
it.only('sourcesContent', function(done) {
597+
it('sourcesContent', function(done) {
598598
compareStdout(done, createMultiLineSourceMapWithSourcesContent(), [
599599
'',
600600
'function foo() { throw new Error("this is the error"); }',

0 commit comments

Comments
 (0)