lib: add source map support for assert messages · nodejs/node@d785929

11

'use strict';

2233

const {

4-

ArrayPrototypeIndexOf,

54

ArrayPrototypeJoin,

65

ArrayPrototypeMap,

76

ErrorPrototypeToString,

8-

RegExpPrototypeSymbolSplit,

97

SafeStringIterator,

108

StringPrototypeRepeat,

119

StringPrototypeSlice,

@@ -16,8 +14,7 @@ let debug = require('internal/util/debuglog').debuglog('source_map', (fn) => {

1614

debug = fn;

1715

});

1816

const { getStringWidth } = require('internal/util/inspect');

19-

const { readFileSync } = require('fs');

20-

const { findSourceMap } = require('internal/source_map/source_map_cache');

17+

const { findSourceMap, getSourceLine } = require('internal/source_map/source_map_cache');

2118

const {

2219

kIsNodeError,

2320

} = require('internal/errors');

@@ -155,21 +152,13 @@ function getErrorSource(

155152

originalLine,

156153

originalColumn,

157154

) {

158-

const originalSourcePathNoScheme =

159-

StringPrototypeStartsWith(originalSourcePath, 'file://') ?

160-

fileURLToPath(originalSourcePath) : originalSourcePath;

161-

const source = getOriginalSource(

162-

sourceMap.payload,

163-

originalSourcePath,

164-

);

165-

if (typeof source !== 'string') {

166-

return;

167-

}

168-

const lines = RegExpPrototypeSymbolSplit(/\r?\n/, source, originalLine + 1);

169-

const line = lines[originalLine];

155+

const line = getSourceLine(sourceMap, originalSourcePath, originalLine);

170156

if (!line) {

171157

return;

172158

}

159+

const originalSourcePathNoScheme =

160+

StringPrototypeStartsWith(originalSourcePath, 'file://') ?

161+

fileURLToPath(originalSourcePath) : originalSourcePath;

173162174163

// Display ^ in appropriate position, regardless of whether tabs or

175164

// spaces are used:

@@ -182,39 +171,10 @@ function getErrorSource(

182171

prefix = StringPrototypeSlice(prefix, 0, -1); // The last character is '^'.

183172184173

const exceptionLine =

185-

`${originalSourcePathNoScheme}:${originalLine + 1}\n${line}\n${prefix}^\n\n`;

174+

`${originalSourcePathNoScheme}:${originalLine + 1}\n${line}\n${prefix}^\n`;

186175

return exceptionLine;

187176

}

188177189-

/**

190-

* Retrieve the original source code from the source map's `sources` list or disk.

191-

* @param {import('internal/source_map/source_map').SourceMap.payload} payload

192-

* @param {string} originalSourcePath - path or url of the original source

193-

* @returns {string | undefined} - the source content or undefined if file not found

194-

*/

195-

function getOriginalSource(payload, originalSourcePath) {

196-

let source;

197-

// payload.sources has been normalized to be an array of absolute urls.

198-

const sourceContentIndex =

199-

ArrayPrototypeIndexOf(payload.sources, originalSourcePath);

200-

if (payload.sourcesContent?.[sourceContentIndex]) {

201-

// First we check if the original source content was provided in the

202-

// source map itself:

203-

source = payload.sourcesContent[sourceContentIndex];

204-

} else if (StringPrototypeStartsWith(originalSourcePath, 'file://')) {

205-

// If no sourcesContent was found, attempt to load the original source

206-

// from disk:

207-

debug(`read source of ${originalSourcePath} from filesystem`);

208-

const originalSourcePathNoScheme = fileURLToPath(originalSourcePath);

209-

try {

210-

source = readFileSync(originalSourcePathNoScheme, 'utf8');

211-

} catch (err) {

212-

debug(err);

213-

}

214-

}

215-

return source;

216-

}

217-218178

/**

219179

* Retrieve exact line in the original source code from the source map's `sources` list or disk.

220180

* @param {string} fileName - actual file name