UNPKG

gatsby-cli

Version:

Gatsby command-line interface for creating new sites and running Gatsby commands

168 lines (164 loc) • 7.16 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.ErrorWithCodeFrame = void 0; exports.prepareStackTrace = prepareStackTrace; var _fs = require("fs"); var _codeFrame = require("@babel/code-frame"); var _stackTrace = _interopRequireDefault(require("stack-trace")); var _traceMapping = require("@jridgewell/trace-mapping"); var path = _interopRequireWildcard(require("path")); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /* Code borrowed and based on * https://github.com/evanw/node-source-map-support/blob/master/source-map-support.js */ class ErrorWithCodeFrame extends Error { codeFrame = ``; constructor(error) { super(error.message); // We must use getOwnProperty because keys like `stack` are not enumerable, // but we want to copy over the entire error Object.getOwnPropertyNames(error).forEach(key => { this[key] = error[key]; }); } } exports.ErrorWithCodeFrame = ErrorWithCodeFrame; function prepareStackTrace(error, sourceOfMainMap) { const newError = new ErrorWithCodeFrame(error); // source point to single map, but with code splitting for build-html we need to handle more maps // we use fact that all .map files will be in same dir as main one here const bundleDir = path.dirname(sourceOfMainMap); const bundleDirMapFiles = (0, _fs.readdirSync)(bundleDir).filter(fileName => fileName.endsWith(`.js.map`)).map(fileName => path.join(bundleDir, fileName)); const maps = bundleDirMapFiles.map(source => new _traceMapping.TraceMap((0, _fs.readFileSync)(source, `utf8`))); const stack = _stackTrace.default.parse(newError).map(frame => wrapCallSite(maps, frame)).filter(frame => `wasConverted` in frame && (!frame.getFileName() || !frame.getFileName().match(/^webpack:\/+(lib\/)?(webpack\/|\.cache\/)/))); newError.codeFrame = getErrorSource(maps, stack[0]); newError.stack = `${newError.name}: ${newError.message}\n` + stack.map(frame => ` at ${frame}`).join(`\n`); return newError; } function getErrorSource(maps, topFrame) { let source; for (const map of maps) { source = (0, _traceMapping.sourceContentFor)(map, topFrame.getFileName()); if (source) { break; } } return source ? (0, _codeFrame.codeFrameColumns)(source, { start: { line: topFrame.getLineNumber(), column: topFrame.getColumnNumber() } }, { highlightCode: true }) : ``; } function wrapCallSite(maps, frame) { const source = frame.getFileName(); if (!source) return frame; const position = getPosition({ maps, frame }); if (!position.source) return frame; return { getFileName: () => position.source || ``, getLineNumber: () => position.line || 0, getColumnNumber: () => (position.column || 0) + 1, getScriptNameOrSourceURL: () => position.source || ``, toString: CallSiteToString, wasConverted: true }; } function getPosition({ maps, frame }) { if (frame.getFileName().includes(`webpack:`)) { // if source-map-register is initiated, stack traces would already be converted return { column: frame.getColumnNumber() - 1, line: frame.getLineNumber(), source: frame.getFileName().slice(frame.getFileName().indexOf(`webpack:`)).replace(/webpack:\/+/g, `webpack://`), name: null }; } const line = frame.getLineNumber(); const column = frame.getColumnNumber(); for (const map of maps) { const test = (0, _traceMapping.originalPositionFor)(map, { line, column }); if (test.source) { return test; } } return { source: null, column: null, line: null, name: null }; } // This is copied almost verbatim from the V8 source code at // https://code.google.com/p/v8/source/browse/trunk/src/messages.js. function CallSiteToString() { // @ts-ignore const _this = this; // eslint-disable-line @typescript-eslint/no-this-alias const self = _this; let fileName; let fileLocation = ``; if (`isNative` in self && self.isNative()) { fileLocation = `native`; } else { fileName = `getScriptNameOrSourceURL` in self && self.getScriptNameOrSourceURL() || `getFileName` in self && self.getFileName(); if (!fileName && `isEval` in self && self.isEval()) { fileLocation = `${self.getEvalOrigin()}, `; } if (fileName) { fileLocation += fileName.replace(/^webpack:\/+(lib\/)?/, ``); } else { // Source code does not originate from a file and is not native, but we // can still get the source position inside the source string, e.g. in // an eval string. fileLocation += `<anonymous>`; } const lineNumber = `getLineNumber` in self ? self.getLineNumber() : null; if (lineNumber != null) { fileLocation += `:${lineNumber}`; const columnNumber = `getColumnNumber` in self ? self.getColumnNumber() : null; if (columnNumber) { fileLocation += `:${columnNumber}`; } } } let line = ``; const functionName = `getFunctionName` in self ? self.getFunctionName() : ``; let addSuffix = true; const isConstructor = `isConstructor` in self && self.isConstructor(); const methodName = `getMethodName` in self ? self.getMethodName() : ``; const typeName = `getTypeName` in self ? self.getTypeName() : ``; const isMethodCall = methodName && !(`isToplevel` in self && self.isToplevel() || isConstructor); if (isMethodCall && functionName) { if (typeName && functionName.indexOf(typeName) != 0) { line += `${typeName}.`; } line += functionName; if (functionName.indexOf(`.` + methodName) != functionName.length - (methodName || ``).length - 1) { line += ` [as ${methodName}]`; } } else if (typeName && !functionName) { line += typeName + `.` + (methodName || `<anonymous>`); } else if (isConstructor) { line += `new ` + (functionName || `<anonymous>`); } else if (functionName) { line += functionName; } else { line += fileLocation; addSuffix = false; } if (addSuffix) line += ` (${fileLocation})`; return line; }