diff --git a/lib/internal/source_map/source_map_cache.js b/lib/internal/source_map/source_map_cache.js index 2813da21dfdc63..b4b1d8b33b566b 100644 --- a/lib/internal/source_map/source_map_cache.js +++ b/lib/internal/source_map/source_map_cache.js @@ -39,6 +39,7 @@ const kLeadingProtocol = /^\w+:\/\//; const kSourceMappingURLMagicComment = /\/[*/]#\s+sourceMappingURL=(?[^\s]+)/g; const kSourceURLMagicComment = /\/[*/]#\s+sourceURL=(?[^\s]+)/g; +const { isAbsolute } = require('path'); const { fileURLToPath, pathToFileURL, URL } = require('internal/url'); let SourceMap; @@ -254,6 +255,9 @@ function sourceMapFromDataUrl(sourceURL, url) { function sourcesToAbsolute(baseURL, data) { data.sources = data.sources.map((source) => { source = (data.sourceRoot || '') + source; + if (isAbsolute(source)) { + return pathToFileURL(source).href; + } return new URL(source, baseURL).href; }); // The sources array is now resolved to absolute URLs, sourceRoot should diff --git a/test/fixtures/source-map/ts-node-win32.js b/test/fixtures/source-map/ts-node-win32.js new file mode 100644 index 00000000000000..3c1ab9363544d2 --- /dev/null +++ b/test/fixtures/source-map/ts-node-win32.js @@ -0,0 +1,10 @@ +function foo(str) { + return str; +} +foo('noop'); +// To recreate (only on windows): +// +// const filePath = require.resolve('./test/fixtures/source-map/ts-node.ts'); +// const compiled = require('ts-node').create({ transpileOnly: true }).compile(fs.readFileSync(filePath, 'utf8'), filePath); +// fs.writeFileSync('test/fixtures/source-map/ts-node-win32.js', compiled); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRDovd29ya3NwYWNlcy9ub2RlL3Rlc3QvZml4dHVyZXMvc291cmNlLW1hcC90cy1ub2RlLnRzIiwic291cmNlcyI6WyJEOi93b3Jrc3BhY2VzL25vZGUvdGVzdC9maXh0dXJlcy9zb3VyY2UtbWFwL3RzLW5vZGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsU0FBUyxHQUFHLENBQUMsR0FBVztJQUN0QixPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFFRCxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7QUFFWixpQ0FBaUM7QUFDakMsRUFBRTtBQUNGLDZFQUE2RTtBQUM3RSw0SEFBNEg7QUFDNUgsMkVBQTJFIiwic291cmNlc0NvbnRlbnQiOlsiZnVuY3Rpb24gZm9vKHN0cjogc3RyaW5nKSB7XHJcbiAgcmV0dXJuIHN0cjtcclxufVxyXG5cclxuZm9vKCdub29wJyk7XHJcblxyXG4vLyBUbyByZWNyZWF0ZSAob25seSBvbiB3aW5kb3dzKTpcclxuLy9cclxuLy8gY29uc3QgZmlsZVBhdGggPSByZXF1aXJlLnJlc29sdmUoJy4vdGVzdC9maXh0dXJlcy9zb3VyY2UtbWFwL3RzLW5vZGUudHMnKTtcclxuLy8gY29uc3QgY29tcGlsZWQgPSByZXF1aXJlKCd0cy1ub2RlJykuY3JlYXRlKHsgdHJhbnNwaWxlT25seTogdHJ1ZSB9KS5jb21waWxlKGZzLnJlYWRGaWxlU3luYyhmaWxlUGF0aCwgJ3V0ZjgnKSwgZmlsZVBhdGgpO1xyXG4vLyBmcy53cml0ZUZpbGVTeW5jKCd0ZXN0L2ZpeHR1cmVzL3NvdXJjZS1tYXAvdHMtbm9kZS13aW4zMi5qcycsIGNvbXBpbGVkKTtcclxuIl19 \ No newline at end of file diff --git a/test/fixtures/source-map/ts-node.ts b/test/fixtures/source-map/ts-node.ts new file mode 100644 index 00000000000000..ac0a7293915695 --- /dev/null +++ b/test/fixtures/source-map/ts-node.ts @@ -0,0 +1,11 @@ +function foo(str: string) { + return str; +} + +foo('noop'); + +// To recreate (only on windows): +// +// const filePath = require.resolve('./test/fixtures/source-map/ts-node.ts'); +// const compiled = require('ts-node').create({ transpileOnly: true }).compile(fs.readFileSync(filePath, 'utf8'), filePath); +// fs.writeFileSync('test/fixtures/source-map/ts-node-win32.js', compiled); diff --git a/test/parallel/test-source-map-enable.js b/test/parallel/test-source-map-enable.js index 5038aff360e518..e7d24d9e6da022 100644 --- a/test/parallel/test-source-map-enable.js +++ b/test/parallel/test-source-map-enable.js @@ -289,6 +289,30 @@ function nextdir() { assert.match(output.stderr.toString(), /at functionC.*10:3/); } +// Properly converts windows absolute paths to absolute URLs +// Refs: https://github.com/nodejs/node/issues/50523 +// Refs: https://github.com/TypeStrong/ts-node/issues/1769 +{ + const coverageDirectory = nextdir(); + const output = spawnSync(process.execPath, [ + require.resolve('../fixtures/source-map/ts-node-win32.js'), + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + assert.strictEqual(output.status, 0); + assert.strictEqual(output.stderr.toString(), ''); + const sourceMap = getSourceMapFromCache( + 'ts-node-win32.js', + coverageDirectory + ); + // base64 JSON should have been decoded, the D: in the sources field should + // have been taken as the drive letter on Windows, the scheme on POSIX. + assert.strictEqual( + sourceMap.data.sources[0], + common.isWindows ? + 'file:///D:/workspaces/node/test/fixtures/source-map/ts-node.ts' : + 'd:/workspaces/node/test/fixtures/source-map/ts-node.ts' + ); +} + // Stores and applies source map associated with file that throws while // being required. {