'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var fs = require('fs'); var path = require('path'); var os = require('os'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs); var path__default = /*#__PURE__*/_interopDefaultLegacy(path); var os__default = /*#__PURE__*/_interopDefaultLegacy(os); /* ------------------------------------------------------------------------ */ const O = Object, isBrowser = /* eslint-disable */ typeof window !== 'undefined' && /* eslint-disable */ window.window === window && /* eslint-disable */ window.navigator, nodeRequire = isBrowser ? null : module.require, // to prevent bundlers from expanding the require call lastOf = (x) => x[x.length - 1], nixSlashes$1 = (x) => x.replace(/\\/g, '/'), pathRoot = isBrowser ? window.location.href : nixSlashes$1(process.cwd()) + '/'; /* ------------------------------------------------------------------------ */ class StackTracey { constructor(input, uniPlatform, offset) { this.itemsHeader = []; this.isMP = false; const originalInput = input, isParseableSyntaxError = input && input instanceof SyntaxError && !isBrowser; /* new StackTracey () */ if (!input) { input = new Error(); offset = offset === undefined ? 1 : offset; } /* new StackTracey (Error) */ if (input instanceof Error) { input = input.stack || ''; } /* new StackTracey (string) */ if (typeof input === 'string') { this.isMP = uniPlatform === 'mp-weixin'; input = this.rawParse(input) .slice(offset) .map((x) => this.extractEntryMetadata(x)); } /* new StackTracey (array) */ if (Array.isArray(input)) { if (isParseableSyntaxError) { const rawLines = nodeRequire('util') .inspect(originalInput) .split('\n'), fileLine = rawLines[0].split(':'), line = fileLine.pop(), file = fileLine.join(':'); if (file) { input.unshift({ file: nixSlashes$1(file), line: line, column: (rawLines[2] || '').indexOf('^') + 1, sourceLine: rawLines[1], callee: '(syntax error)', syntaxError: true, }); } } this.items = input; } else { this.items = []; } } extractEntryMetadata(e) { const decomposedPath = this.decomposePath(e.file || ''); const fileRelative = decomposedPath[0]; const externalDomain = decomposedPath[1]; return O.assign(e, { calleeShort: e.calleeShort || lastOf((e.callee || '').split('.')), fileRelative: fileRelative, fileShort: this.shortenPath(fileRelative), fileName: lastOf((e.file || '').split('/')), thirdParty: this.isThirdParty(fileRelative, externalDomain) && !e.index, externalDomain: externalDomain, }); } shortenPath(relativePath) { return relativePath .replace(/^node_modules\//, '') .replace(/^webpack\/bootstrap\//, '') .replace(/^__parcel_source_root\//, ''); } decomposePath(fullPath) { let result = fullPath; if (isBrowser) result = result.replace(pathRoot, ''); const externalDomainMatch = result.match(/^(http|https)\:\/\/?([^\/]+)\/{1,}(.*)/); const externalDomain = externalDomainMatch ? externalDomainMatch[2] : undefined; result = externalDomainMatch ? externalDomainMatch[3] : result; // if (!isBrowser) result = nodeRequire!('path').relative(pathRoot, result) return [ nixSlashes$1(result).replace(/^.*\:\/\/?\/?/, ''), externalDomain, ]; } isThirdParty(relativePath, externalDomain) { if (this.isMP) { if (typeof externalDomain === 'undefined') return false; return externalDomain !== 'usr'; } return ( // 由于 hello-uniapp web 端报错携带 hellouniapp.dcloud.net.cn // externalDomain || relativePath[0] === '~' || // webpack-specific heuristic relativePath[0] === '/' || // external source relativePath.indexOf('@dcloudio') !== -1 || relativePath.indexOf('weex-main-jsfm') !== -1 || relativePath.indexOf('webpack/bootstrap') === 0); } rawParse(str) { const lines = (str || '').split('\n'); const entries = lines.map((line, index) => { line = line.trim(); let callee, fileLineColumn = [], native, planA, planB; if (line.indexOf('file:') !== -1) { line = line.replace(/file:\/\/(.*)www/, 'file://'); } if ((planA = line.match(/at (.+) \(eval at .+ \((.+)\), .+\)/)) || // eval calls (planA = line.match(/at (.+) \((.+)\)/)) || (line.slice(0, 3) !== 'at ' && (planA = line.match(/(.*)@(.*)/)))) { this.itemsHeader.push('%StacktraceyItem%'); callee = planA[1]; native = planA[2] === 'native'; fileLineColumn = (planA[2].match(/(.*):(\d+):(\d+)/) || planA[2].match(/(.*):(\d+)/) || planA[2].match(/\[(.*)\]/) || []).slice(1); } else if ((planB = line.match(/^(at\s*)*(.*)\s+(.+):(\d+):(\d+)/))) { this.itemsHeader.push('%StacktraceyItem%'); callee = planB[2].trim(); fileLineColumn = planB.slice(3); } else { this.itemsHeader.push(line); return undefined; } /* Detect things like Array.reduce TODO: detect more built-in types */ if (callee && !fileLineColumn[0]) { const type = callee.split('.')[0]; if (type === 'Array') { native = true; } } return { beforeParse: line, callee: callee || '', /* eslint-disable */ index: isBrowser && fileLineColumn[0] === window.location.href, native: native || false, file: nixSlashes$1(fileLineColumn[0] || ''), line: parseInt(fileLineColumn[1] || '', 10) || undefined, column: parseInt(fileLineColumn[2] || '', 10) || undefined, }; }); return entries.filter((x) => x !== undefined); } maxColumnWidths() { return { callee: 30, file: 60, sourceLine: 80, }; } asTable(opts) { const maxColumnWidths = (opts && opts.maxColumnWidths) || this.maxColumnWidths(); const trimmed = this .filter((e) => !e.thirdParty) .map((e) => parseItem(e, maxColumnWidths, this.isMP)); const trimmedThirdParty = this .filter((e) => e.thirdParty) .map((e) => parseItem(e, maxColumnWidths, this.isMP)); return { items: trimmed.items, thirdPartyItems: trimmedThirdParty.items, }; } } const trimEnd = (s, n) => s && (s.length > n ? s.slice(0, n - 1) + '…' : s); const trimStart = (s, n) => s && (s.length > n ? '…' + s.slice(-(n - 1)) : s); function parseItem(e, maxColumnWidths, isMP) { if (!e.parsed) { return e.beforeParse; } const filePath = (isMP ? e.file && e.file : e.fileShort && e.fileShort) + `${e.line ? ':' + e.line : ''}` + `${e.column ? ':' + e.column : ''}`; return [ 'at ' + trimEnd(isMP ? e.callee : e.calleeShort, maxColumnWidths.callee), trimStart(filePath || '', maxColumnWidths.file), trimEnd((e.sourceLine || '').trim() || '', maxColumnWidths.sourceLine), ]; } ['map', 'filter', 'slice', 'concat'].forEach((method) => { StackTracey.prototype[method] = function ( /*...args */) { // no support for ...args in Node v4 :( return new StackTracey(this.items[method].apply(this.items, arguments)); }; }); /* ------------------------------------------------------------------------ */ var StackTracey$1 = StackTracey; /* -*- Mode: js; js-indent-level: 2; -*- */ /* * Copyright 2011 Mozilla Foundation and contributors * Licensed under the New BSD license. See LICENSE or: * http://opensource.org/licenses/BSD-3-Clause */ const intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split(''); /** * Encode an integer in the range of 0 to 63 to a single base 64 digit. */ var encode$1 = function (number) { if (0 <= number && number < intToCharMap.length) { return intToCharMap[number] } throw new TypeError('Must be between 0 and 63: ' + number) }; var base64$1 = { encode: encode$1 }; var base64 = base64$1; /* -*- Mode: js; js-indent-level: 2; -*- */ /* * Copyright 2011 Mozilla Foundation and contributors * Licensed under the New BSD license. See LICENSE or: * http://opensource.org/licenses/BSD-3-Clause * * Based on the Base 64 VLQ implementation in Closure Compiler: * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java * * Copyright 2011 The Closure Compiler Authors. All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // A single base 64 digit can contain 6 bits of data. For the base 64 variable // length quantities we use in the source map spec, the first bit is the sign, // the next four bits are the actual value, and the 6th bit is the // continuation bit. The continuation bit tells us whether there are more // digits in this value following this digit. // // Continuation // | Sign // | | // V V // 101011 const VLQ_BASE_SHIFT = 5; // binary: 100000 const VLQ_BASE = 1 << VLQ_BASE_SHIFT; // binary: 011111 const VLQ_BASE_MASK = VLQ_BASE - 1; // binary: 100000 const VLQ_CONTINUATION_BIT = VLQ_BASE; /** * Converts from a two-complement value to a value where the sign bit is * placed in the least significant bit. For example, as decimals: * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary) * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary) */ function toVLQSigned(aValue) { return aValue < 0 ? (-aValue << 1) + 1 : (aValue << 1) + 0 } /** * Returns the base 64 VLQ encoded value. */ var encode = function base64VLQ_encode(aValue) { let encoded = ''; let digit; let vlq = toVLQSigned(aValue); do { digit = vlq & VLQ_BASE_MASK; vlq >>>= VLQ_BASE_SHIFT; if (vlq > 0) { // There are still more digits in this value, so we must make sure the // continuation bit is marked. digit |= VLQ_CONTINUATION_BIT; } encoded += base64.encode(digit); } while (vlq > 0) return encoded }; var base64Vlq = { encode: encode }; function createCommonjsModule(fn) { var module = { exports: {} }; return fn(module, module.exports), module.exports; } /* -*- Mode: js; js-indent-level: 2; -*- */ var util$1 = createCommonjsModule(function (module, exports) { /* * Copyright 2011 Mozilla Foundation and contributors * Licensed under the New BSD license. See LICENSE or: * http://opensource.org/licenses/BSD-3-Clause */ /** * This is a helper function for getting values from parameter/options * objects. * * @param args The object we are extracting values from * @param name The name of the property we are getting. * @param defaultValue An optional value to return if the property is missing * from the object. If this is not specified and the property is missing, an * error will be thrown. */ function getArg(aArgs, aName, aDefaultValue) { if (aName in aArgs) { return aArgs[aName] } else if (arguments.length === 3) { return aDefaultValue } throw new Error('"' + aName + '" is a required argument.') } exports.getArg = getArg; const urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/; const dataUrlRegexp = /^data:.+\,.+$/; function urlParse(aUrl) { const match = aUrl.match(urlRegexp); if (!match) { return null } return { scheme: match[1], auth: match[2], host: match[3], port: match[4], path: match[5], } } exports.urlParse = urlParse; function urlGenerate(aParsedUrl) { let url = ''; if (aParsedUrl.scheme) { url += aParsedUrl.scheme + ':'; } url += '//'; if (aParsedUrl.auth) { url += aParsedUrl.auth + '@'; } if (aParsedUrl.host) { url += aParsedUrl.host; } if (aParsedUrl.port) { url += ':' + aParsedUrl.port; } if (aParsedUrl.path) { url += aParsedUrl.path; } return url } exports.urlGenerate = urlGenerate; const MAX_CACHED_INPUTS = 32; /** * Takes some function `f(input) -> result` and returns a memoized version of * `f`. * * We keep at most `MAX_CACHED_INPUTS` memoized results of `f` alive. The * memoization is a dumb-simple, linear least-recently-used cache. */ function lruMemoize(f) { const cache = []; return function (input) { for (let i = 0; i < cache.length; i++) { if (cache[i].input === input) { const temp = cache[0]; cache[0] = cache[i]; cache[i] = temp; return cache[0].result } } const result = f(input); cache.unshift({ input, result, }); if (cache.length > MAX_CACHED_INPUTS) { cache.pop(); } return result } } /** * Normalizes a path, or the path portion of a URL: * * - Replaces consecutive slashes with one slash. * - Removes unnecessary '.' parts. * - Removes unnecessary '/..' parts. * * Based on code in the Node.js 'path' core module. * * @param aPath The path or url to normalize. */ const normalize = lruMemoize(function normalize(aPath) { let path = aPath; const url = urlParse(aPath); if (url) { if (!url.path) { return aPath } path = url.path; } const isAbsolute = exports.isAbsolute(path); // Split the path into parts between `/` characters. This is much faster than // using `.split(/\/+/g)`. const parts = []; let start = 0; let i = 0; while (true) { start = i; i = path.indexOf('/', start); if (i === -1) { parts.push(path.slice(start)); break } else { parts.push(path.slice(start, i)); while (i < path.length && path[i] === '/') { i++; } } } let up = 0; for (i = parts.length - 1; i >= 0; i--) { const part = parts[i]; if (part === '.') { parts.splice(i, 1); } else if (part === '..') { up++; } else if (up > 0) { if (part === '') { // The first part is blank if the path is absolute. Trying to go // above the root is a no-op. Therefore we can remove all '..' parts // directly after the root. parts.splice(i + 1, up); up = 0; } else { parts.splice(i, 2); up--; } } } path = parts.join('/'); if (path === '') { path = isAbsolute ? '/' : '.'; } if (url) { url.path = path; return urlGenerate(url) } return path }); exports.normalize = normalize; /** * Joins two paths/URLs. * * @param aRoot The root path or URL. * @param aPath The path or URL to be joined with the root. * * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a * scheme-relative URL: Then the scheme of aRoot, if any, is prepended * first. * - Otherwise aPath is a path. If aRoot is a URL, then its path portion * is updated with the result and aRoot is returned. Otherwise the result * is returned. * - If aPath is absolute, the result is aPath. * - Otherwise the two paths are joined with a slash. * - Joining for example 'http://' and 'www.example.com' is also supported. */ function join(aRoot, aPath) { if (aRoot === '') { aRoot = '.'; } if (aPath === '') { aPath = '.'; } const aPathUrl = urlParse(aPath); const aRootUrl = urlParse(aRoot); if (aRootUrl) { aRoot = aRootUrl.path || '/'; } // `join(foo, '//www.example.org')` if (aPathUrl && !aPathUrl.scheme) { if (aRootUrl) { aPathUrl.scheme = aRootUrl.scheme; } return urlGenerate(aPathUrl) } if (aPathUrl || aPath.match(dataUrlRegexp)) { return aPath } // `join('http://', 'www.example.com')` if (aRootUrl && !aRootUrl.host && !aRootUrl.path) { aRootUrl.host = aPath; return urlGenerate(aRootUrl) } const joined = aPath.charAt(0) === '/' ? aPath : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath); if (aRootUrl) { aRootUrl.path = joined; return urlGenerate(aRootUrl) } return joined } exports.join = join; exports.isAbsolute = function (aPath) { return aPath.charAt(0) === '/' || urlRegexp.test(aPath) }; /** * Make a path relative to a URL or another path. * * @param aRoot The root path or URL. * @param aPath The path or URL to be made relative to aRoot. */ function relative(aRoot, aPath) { if (aRoot === '') { aRoot = '.'; } aRoot = aRoot.replace(/\/$/, ''); // It is possible for the path to be above the root. In this case, simply // checking whether the root is a prefix of the path won't work. Instead, we // need to remove components from the root one by one, until either we find // a prefix that fits, or we run out of components to remove. let level = 0; while (aPath.indexOf(aRoot + '/') !== 0) { const index = aRoot.lastIndexOf('/'); if (index < 0) { return aPath } // If the only part of the root that is left is the scheme (i.e. http://, // file:///, etc.), one or more slashes (/), or simply nothing at all, we // have exhausted all components, so the path is not relative to the root. aRoot = aRoot.slice(0, index); if (aRoot.match(/^([^\/]+:\/)?\/*$/)) { return aPath } ++level; } // Make sure we add a "../" for each component we removed from the root. return Array(level + 1).join('../') + aPath.substr(aRoot.length + 1) } exports.relative = relative; const supportsNullProto = (function () { const obj = Object.create(null); return !('__proto__' in obj) })(); function identity(s) { return s } /** * Because behavior goes wacky when you set `__proto__` on objects, we * have to prefix all the strings in our set with an arbitrary character. * * See https://github.com/mozilla/source-map/pull/31 and * https://github.com/mozilla/source-map/issues/30 * * @param String aStr */ function toSetString(aStr) { if (isProtoString(aStr)) { return '$' + aStr } return aStr } exports.toSetString = supportsNullProto ? identity : toSetString; function fromSetString(aStr) { if (isProtoString(aStr)) { return aStr.slice(1) } return aStr } exports.fromSetString = supportsNullProto ? identity : fromSetString; function isProtoString(s) { if (!s) { return false } const length = s.length; if (length < 9 /* "__proto__".length */) { return false } /* eslint-disable no-multi-spaces */ if ( s.charCodeAt(length - 1) !== 95 /* '_' */ || s.charCodeAt(length - 2) !== 95 /* '_' */ || s.charCodeAt(length - 3) !== 111 /* 'o' */ || s.charCodeAt(length - 4) !== 116 /* 't' */ || s.charCodeAt(length - 5) !== 111 /* 'o' */ || s.charCodeAt(length - 6) !== 114 /* 'r' */ || s.charCodeAt(length - 7) !== 112 /* 'p' */ || s.charCodeAt(length - 8) !== 95 /* '_' */ || s.charCodeAt(length - 9) !== 95 /* '_' */ ) { return false } /* eslint-enable no-multi-spaces */ for (let i = length - 10; i >= 0; i--) { if (s.charCodeAt(i) !== 36 /* '$' */) { return false } } return true } /** * Comparator between two mappings where the original positions are compared. * * Optionally pass in `true` as `onlyCompareGenerated` to consider two * mappings with the same original source/line/column, but different generated * line and column the same. Useful when searching for a mapping with a * stubbed out mapping. */ function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) { let cmp = strcmp(mappingA.source, mappingB.source); if (cmp !== 0) { return cmp } cmp = mappingA.originalLine - mappingB.originalLine; if (cmp !== 0) { return cmp } cmp = mappingA.originalColumn - mappingB.originalColumn; if (cmp !== 0 || onlyCompareOriginal) { return cmp } cmp = mappingA.generatedColumn - mappingB.generatedColumn; if (cmp !== 0) { return cmp } cmp = mappingA.generatedLine - mappingB.generatedLine; if (cmp !== 0) { return cmp } return strcmp(mappingA.name, mappingB.name) } exports.compareByOriginalPositions = compareByOriginalPositions; /** * Comparator between two mappings with deflated source and name indices where * the generated positions are compared. * * Optionally pass in `true` as `onlyCompareGenerated` to consider two * mappings with the same generated line and column, but different * source/name/original line and column the same. Useful when searching for a * mapping with a stubbed out mapping. */ function compareByGeneratedPositionsDeflated( mappingA, mappingB, onlyCompareGenerated ) { let cmp = mappingA.generatedLine - mappingB.generatedLine; if (cmp !== 0) { return cmp } cmp = mappingA.generatedColumn - mappingB.generatedColumn; if (cmp !== 0 || onlyCompareGenerated) { return cmp } cmp = strcmp(mappingA.source, mappingB.source); if (cmp !== 0) { return cmp } cmp = mappingA.originalLine - mappingB.originalLine; if (cmp !== 0) { return cmp } cmp = mappingA.originalColumn - mappingB.originalColumn; if (cmp !== 0) { return cmp } return strcmp(mappingA.name, mappingB.name) } exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated; function strcmp(aStr1, aStr2) { if (aStr1 === aStr2) { return 0 } if (aStr1 === null) { return 1 // aStr2 !== null } if (aStr2 === null) { return -1 // aStr1 !== null } if (aStr1 > aStr2) { return 1 } return -1 } /** * Comparator between two mappings with inflated source and name strings where * the generated positions are compared. */ function compareByGeneratedPositionsInflated(mappingA, mappingB) { let cmp = mappingA.generatedLine - mappingB.generatedLine; if (cmp !== 0) { return cmp } cmp = mappingA.generatedColumn - mappingB.generatedColumn; if (cmp !== 0) { return cmp } cmp = strcmp(mappingA.source, mappingB.source); if (cmp !== 0) { return cmp } cmp = mappingA.originalLine - mappingB.originalLine; if (cmp !== 0) { return cmp } cmp = mappingA.originalColumn - mappingB.originalColumn; if (cmp !== 0) { return cmp } return strcmp(mappingA.name, mappingB.name) } exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated; /** * Strip any JSON XSSI avoidance prefix from the string (as documented * in the source maps specification), and then parse the string as * JSON. */ function parseSourceMapInput(str) { return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, '')) } exports.parseSourceMapInput = parseSourceMapInput; /** * Compute the URL of a source given the the source root, the source's * URL, and the source map's URL. */ function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) { sourceURL = sourceURL || ''; if (sourceRoot) { // This follows what Chrome does. if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') { sourceRoot += '/'; } // The spec says: // Line 4: An optional source root, useful for relocating source // files on a server or removing repeated values in the // “sources” entry. This value is prepended to the individual // entries in the “source” field. sourceURL = sourceRoot + sourceURL; } // Historically, SourceMapConsumer did not take the sourceMapURL as // a parameter. This mode is still somewhat supported, which is why // this code block is conditional. However, it's preferable to pass // the source map URL to SourceMapConsumer, so that this function // can implement the source URL resolution algorithm as outlined in // the spec. This block is basically the equivalent of: // new URL(sourceURL, sourceMapURL).toString() // ... except it avoids using URL, which wasn't available in the // older releases of node still supported by this library. // // The spec says: // If the sources are not absolute URLs after prepending of the // “sourceRoot”, the sources are resolved relative to the // SourceMap (like resolving script src in a html document). if (sourceMapURL) { const parsed = urlParse(sourceMapURL); if (!parsed) { throw new Error('sourceMapURL could not be parsed') } if (parsed.path) { // Strip the last path component, but keep the "/". const index = parsed.path.lastIndexOf('/'); if (index >= 0) { parsed.path = parsed.path.substring(0, index + 1); } } sourceURL = join(urlGenerate(parsed), sourceURL); } return normalize(sourceURL) } exports.computeSourceURL = computeSourceURL; }); /* -*- Mode: js; js-indent-level: 2; -*- */ /* * Copyright 2011 Mozilla Foundation and contributors * Licensed under the New BSD license. See LICENSE or: * http://opensource.org/licenses/BSD-3-Clause */ /** * A data structure which is a combination of an array and a set. Adding a new * member is O(1), testing for membership is O(1), and finding the index of an * element is O(1). Removing elements from the set is not supported. Only * strings are supported for membership. */ class ArraySet$2 { constructor() { this._array = []; this._set = new Map(); } /** * Static method for creating ArraySet instances from an existing array. */ static fromArray(aArray, aAllowDuplicates) { const set = new ArraySet$2(); for (let i = 0, len = aArray.length; i < len; i++) { set.add(aArray[i], aAllowDuplicates); } return set } /** * Return how many unique items are in this ArraySet. If duplicates have been * added, than those do not count towards the size. * * @returns Number */ size() { return this._set.size } /** * Add the given string to this set. * * @param String aStr */ add(aStr, aAllowDuplicates) { const isDuplicate = this.has(aStr); const idx = this._array.length; if (!isDuplicate || aAllowDuplicates) { this._array.push(aStr); } if (!isDuplicate) { this._set.set(aStr, idx); } } /** * Is the given string a member of this set? * * @param String aStr */ has(aStr) { return this._set.has(aStr) } /** * What is the index of the given string in the array? * * @param String aStr */ indexOf(aStr) { const idx = this._set.get(aStr); if (idx >= 0) { return idx } throw new Error('"' + aStr + '" is not in the set.') } /** * What is the element at the given index? * * @param Number aIdx */ at(aIdx) { if (aIdx >= 0 && aIdx < this._array.length) { return this._array[aIdx] } throw new Error('No element indexed by ' + aIdx) } /** * Returns the array representation of this set (which has the proper indices * indicated by indexOf). Note that this is a copy of the internal array used * for storing the members so that no one can mess with internal state. */ toArray() { return this._array.slice() } } var ArraySet_1 = ArraySet$2; var arraySet = { ArraySet: ArraySet_1 }; var util = util$1; /* -*- Mode: js; js-indent-level: 2; -*- */ /* * Copyright 2014 Mozilla Foundation and contributors * Licensed under the New BSD license. See LICENSE or: * http://opensource.org/licenses/BSD-3-Clause */ /** * Determine whether mappingB is after mappingA with respect to generated * position. */ function generatedPositionAfter(mappingA, mappingB) { // Optimized for most common case const lineA = mappingA.generatedLine; const lineB = mappingB.generatedLine; const columnA = mappingA.generatedColumn; const columnB = mappingB.generatedColumn; return ( lineB > lineA || (lineB == lineA && columnB >= columnA) || util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0 ) } /** * A data structure to provide a sorted view of accumulated mappings in a * performance conscious manner. It trades a negligible overhead in general * case for a large speedup in case of mappings being added in order. */ class MappingList$1 { constructor() { this._array = []; this._sorted = true; // Serves as infimum this._last = { generatedLine: -1, generatedColumn: 0 }; } /** * Iterate through internal items. This method takes the same arguments that * `Array.prototype.forEach` takes. * * NOTE: The order of the mappings is NOT guaranteed. */ unsortedForEach(aCallback, aThisArg) { this._array.forEach(aCallback, aThisArg); } /** * Add the given source mapping. * * @param Object aMapping */ add(aMapping) { if (generatedPositionAfter(this._last, aMapping)) { this._last = aMapping; this._array.push(aMapping); } else { this._sorted = false; this._array.push(aMapping); } } /** * Returns the flat, sorted array of mappings. The mappings are sorted by * generated position. * * WARNING: This method returns internal data without copying, for * performance. The return value must NOT be mutated, and should be treated as * an immutable borrow. If you want to take ownership, you must make your own * copy. */ toArray() { if (!this._sorted) { this._array.sort(util.compareByGeneratedPositionsInflated); this._sorted = true; } return this._array } } var MappingList_1 = MappingList$1; var mappingList = { MappingList: MappingList_1 }; var base64VLQ = base64Vlq; var require$$0$1 = arraySet; var require$$1$1 = mappingList; /* -*- Mode: js; js-indent-level: 2; -*- */ /* * Copyright 2011 Mozilla Foundation and contributors * Licensed under the New BSD license. See LICENSE or: * http://opensource.org/licenses/BSD-3-Clause */ const ArraySet$1 = require$$0$1.ArraySet; const MappingList = require$$1$1.MappingList; /** * An instance of the SourceMapGenerator represents a source map which is * being built incrementally. You may pass an object with the following * properties: * * - file: The filename of the generated source. * - sourceRoot: A root for all relative URLs in this source map. */ class SourceMapGenerator$1 { constructor(aArgs) { if (!aArgs) { aArgs = {}; } this._file = util.getArg(aArgs, 'file', null); this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null); this._skipValidation = util.getArg(aArgs, 'skipValidation', false); this._sources = new ArraySet$1(); this._names = new ArraySet$1(); this._mappings = new MappingList(); this._sourcesContents = null; } /** * Creates a new SourceMapGenerator based on a SourceMapConsumer * * @param aSourceMapConsumer The SourceMap. */ static fromSourceMap(aSourceMapConsumer) { const sourceRoot = aSourceMapConsumer.sourceRoot; const generator = new SourceMapGenerator$1({ file: aSourceMapConsumer.file, sourceRoot, }); aSourceMapConsumer.eachMapping(function (mapping) { const newMapping = { generated: { line: mapping.generatedLine, column: mapping.generatedColumn, }, }; if (mapping.source != null) { newMapping.source = mapping.source; if (sourceRoot != null) { newMapping.source = util.relative(sourceRoot, newMapping.source); } newMapping.original = { line: mapping.originalLine, column: mapping.originalColumn, }; if (mapping.name != null) { newMapping.name = mapping.name; } } generator.addMapping(newMapping); }); aSourceMapConsumer.sources.forEach(function (sourceFile) { let sourceRelative = sourceFile; if (sourceRoot !== null) { sourceRelative = util.relative(sourceRoot, sourceFile); } if (!generator._sources.has(sourceRelative)) { generator._sources.add(sourceRelative); } const content = aSourceMapConsumer.sourceContentFor(sourceFile); if (content != null) { generator.setSourceContent(sourceFile, content); } }); return generator } /** * Add a single mapping from original source line and column to the generated * source's line and column for this source map being created. The mapping * object should have the following properties: * * - generated: An object with the generated line and column positions. * - original: An object with the original line and column positions. * - source: The original source file (relative to the sourceRoot). * - name: An optional original token name for this mapping. */ addMapping(aArgs) { const generated = util.getArg(aArgs, 'generated'); const original = util.getArg(aArgs, 'original', null); let source = util.getArg(aArgs, 'source', null); let name = util.getArg(aArgs, 'name', null); if (!this._skipValidation) { this._validateMapping(generated, original, source, name); } if (source != null) { source = String(source); if (!this._sources.has(source)) { this._sources.add(source); } } if (name != null) { name = String(name); if (!this._names.has(name)) { this._names.add(name); } } this._mappings.add({ generatedLine: generated.line, generatedColumn: generated.column, originalLine: original != null && original.line, originalColumn: original != null && original.column, source, name, }); } /** * Set the source content for a source file. */ setSourceContent(aSourceFile, aSourceContent) { let source = aSourceFile; if (this._sourceRoot != null) { source = util.relative(this._sourceRoot, source); } if (aSourceContent != null) { // Add the source content to the _sourcesContents map. // Create a new _sourcesContents map if the property is null. if (!this._sourcesContents) { this._sourcesContents = Object.create(null); } this._sourcesContents[util.toSetString(source)] = aSourceContent; } else if (this._sourcesContents) { // Remove the source file from the _sourcesContents map. // If the _sourcesContents map is empty, set the property to null. delete this._sourcesContents[util.toSetString(source)]; if (Object.keys(this._sourcesContents).length === 0) { this._sourcesContents = null; } } } /** * Applies the mappings of a sub-source-map for a specific source file to the * source map being generated. Each mapping to the supplied source file is * rewritten using the supplied source map. Note: The resolution for the * resulting mappings is the minimium of this map and the supplied map. * * @param aSourceMapConsumer The source map to be applied. * @param aSourceFile Optional. The filename of the source file. * If omitted, SourceMapConsumer's file property will be used. * @param aSourceMapPath Optional. The dirname of the path to the source map * to be applied. If relative, it is relative to the SourceMapConsumer. * This parameter is needed when the two source maps aren't in the same * directory, and the source map to be applied contains relative source * paths. If so, those relative source paths need to be rewritten * relative to the SourceMapGenerator. */ applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) { let sourceFile = aSourceFile; // If aSourceFile is omitted, we will use the file property of the SourceMap if (aSourceFile == null) { if (aSourceMapConsumer.file == null) { throw new Error( 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' + 'or the source map\'s "file" property. Both were omitted.' ) } sourceFile = aSourceMapConsumer.file; } const sourceRoot = this._sourceRoot; // Make "sourceFile" relative if an absolute Url is passed. if (sourceRoot != null) { sourceFile = util.relative(sourceRoot, sourceFile); } // Applying the SourceMap can add and remove items from the sources and // the names array. const newSources = this._mappings.toArray().length > 0 ? new ArraySet$1() : this._sources; const newNames = new ArraySet$1(); // Find mappings for the "sourceFile" this._mappings.unsortedForEach(function (mapping) { if (mapping.source === sourceFile && mapping.originalLine != null) { // Check if it can be mapped by the source map, then update the mapping. const original = aSourceMapConsumer.originalPositionFor({ line: mapping.originalLine, column: mapping.originalColumn, }); if (original.source != null) { // Copy mapping mapping.source = original.source; if (aSourceMapPath != null) { mapping.source = util.join(aSourceMapPath, mapping.source); } if (sourceRoot != null) { mapping.source = util.relative(sourceRoot, mapping.source); } mapping.originalLine = original.line; mapping.originalColumn = original.column; if (original.name != null) { mapping.name = original.name; } } } const source = mapping.source; if (source != null && !newSources.has(source)) { newSources.add(source); } const name = mapping.name; if (name != null && !newNames.has(name)) { newNames.add(name); } }, this); this._sources = newSources; this._names = newNames; // Copy sourcesContents of applied map. aSourceMapConsumer.sources.forEach(function (srcFile) { const content = aSourceMapConsumer.sourceContentFor(srcFile); if (content != null) { if (aSourceMapPath != null) { srcFile = util.join(aSourceMapPath, srcFile); } if (sourceRoot != null) { srcFile = util.relative(sourceRoot, srcFile); } this.setSourceContent(srcFile, content); } }, this); } /** * A mapping can have one of the three levels of data: * * 1. Just the generated position. * 2. The Generated position, original position, and original source. * 3. Generated and original position, original source, as well as a name * token. * * To maintain consistency, we validate that any new mapping being added falls * in to one of these categories. */ _validateMapping(aGenerated, aOriginal, aSource, aName) { // When aOriginal is truthy but has empty values for .line and .column, // it is most likely a programmer error. In this case we throw a very // specific error message to try to guide them the right way. // For example: https://github.com/Polymer/polymer-bundler/pull/519 if ( aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number' ) { throw new Error( 'original.line and original.column are not numbers -- you probably meant to omit ' + 'the original mapping entirely and only map the generated position. If so, pass ' + 'null for the original mapping instead of an object with empty or null values.' ) } if ( aGenerated && 'line' in aGenerated && 'column' in aGenerated && aGenerated.line > 0 && aGenerated.column >= 0 && !aOriginal && !aSource && !aName ) ; else if ( aGenerated && 'line' in aGenerated && 'column' in aGenerated && aOriginal && 'line' in aOriginal && 'column' in aOriginal && aGenerated.line > 0 && aGenerated.column >= 0 && aOriginal.line > 0 && aOriginal.column >= 0 && aSource ) ; else { throw new Error( 'Invalid mapping: ' + JSON.stringify({ generated: aGenerated, source: aSource, original: aOriginal, name: aName, }) ) } } /** * Serialize the accumulated mappings in to the stream of base 64 VLQs * specified by the source map format. */ _serializeMappings() { let previousGeneratedColumn = 0; let previousGeneratedLine = 1; let previousOriginalColumn = 0; let previousOriginalLine = 0; let previousName = 0; let previousSource = 0; let result = ''; let next; let mapping; let nameIdx; let sourceIdx; const mappings = this._mappings.toArray(); for (let i = 0, len = mappings.length; i < len; i++) { mapping = mappings[i]; next = ''; if (mapping.generatedLine !== previousGeneratedLine) { previousGeneratedColumn = 0; while (mapping.generatedLine !== previousGeneratedLine) { next += ';'; previousGeneratedLine++; } } else if (i > 0) { if ( !util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1]) ) { continue } next += ','; } next += base64VLQ.encode( mapping.generatedColumn - previousGeneratedColumn ); previousGeneratedColumn = mapping.generatedColumn; if (mapping.source != null) { sourceIdx = this._sources.indexOf(mapping.source); next += base64VLQ.encode(sourceIdx - previousSource); previousSource = sourceIdx; // lines are stored 0-based in SourceMap spec version 3 next += base64VLQ.encode( mapping.originalLine - 1 - previousOriginalLine ); previousOriginalLine = mapping.originalLine - 1; next += base64VLQ.encode( mapping.originalColumn - previousOriginalColumn ); previousOriginalColumn = mapping.originalColumn; if (mapping.name != null) { nameIdx = this._names.indexOf(mapping.name); next += base64VLQ.encode(nameIdx - previousName); previousName = nameIdx; } } result += next; } return result } _generateSourcesContent(aSources, aSourceRoot) { return aSources.map(function (source) { if (!this._sourcesContents) { return null } if (aSourceRoot != null) { source = util.relative(aSourceRoot, source); } const key = util.toSetString(source); return Object.prototype.hasOwnProperty.call(this._sourcesContents, key) ? this._sourcesContents[key] : null }, this) } /** * Externalize the source map. */ toJSON() { const map = { version: this._version, sources: this._sources.toArray(), names: this._names.toArray(), mappings: this._serializeMappings(), }; if (this._file != null) { map.file = this._file; } if (this._sourceRoot != null) { map.sourceRoot = this._sourceRoot; } if (this._sourcesContents) { map.sourcesContent = this._generateSourcesContent( map.sources, map.sourceRoot ); } return map } /** * Render the source map being generated to a string. */ toString() { return JSON.stringify(this.toJSON()) } } SourceMapGenerator$1.prototype._version = 3; var SourceMapGenerator_1 = SourceMapGenerator$1; var sourceMapGenerator = { SourceMapGenerator: SourceMapGenerator_1 }; /* -*- Mode: js; js-indent-level: 2; -*- */ var binarySearch$1 = createCommonjsModule(function (module, exports) { /* * Copyright 2011 Mozilla Foundation and contributors * Licensed under the New BSD license. See LICENSE or: * http://opensource.org/licenses/BSD-3-Clause */ exports.GREATEST_LOWER_BOUND = 1; exports.LEAST_UPPER_BOUND = 2; /** * Recursive implementation of binary search. * * @param aLow Indices here and lower do not contain the needle. * @param aHigh Indices here and higher do not contain the needle. * @param aNeedle The element being searched for. * @param aHaystack The non-empty array being searched. * @param aCompare Function which takes two elements and returns -1, 0, or 1. * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the * closest element that is smaller than or greater than the one we are * searching for, respectively, if the exact element cannot be found. */ function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) { // This function terminates when one of the following is true: // // 1. We find the exact element we are looking for. // // 2. We did not find the exact element, but we can return the index of // the next-closest element. // // 3. We did not find the exact element, and there is no next-closest // element than the one we are searching for, so we return -1. const mid = Math.floor((aHigh - aLow) / 2) + aLow; const cmp = aCompare(aNeedle, aHaystack[mid], true); if (cmp === 0) { // Found the element we are looking for. return mid } else if (cmp > 0) { // Our needle is greater than aHaystack[mid]. if (aHigh - mid > 1) { // The element is in the upper half. return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias) } // The exact needle element was not found in this haystack. Determine if // we are in termination case (3) or (2) and return the appropriate thing. if (aBias == exports.LEAST_UPPER_BOUND) { return aHigh < aHaystack.length ? aHigh : -1 } return mid } // Our needle is less than aHaystack[mid]. if (mid - aLow > 1) { // The element is in the lower half. return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias) } // we are in termination case (3) or (2) and return the appropriate thing. if (aBias == exports.LEAST_UPPER_BOUND) { return mid } return aLow < 0 ? -1 : aLow } /** * This is an implementation of binary search which will always try and return * the index of the closest element if there is no exact hit. This is because * mappings between original and generated line/col pairs are single points, * and there is an implicit region between each of them, so a miss just means * that you aren't on the very start of a region. * * @param aNeedle The element you are looking for. * @param aHaystack The array that is being searched. * @param aCompare A function which takes the needle and an element in the * array and returns -1, 0, or 1 depending on whether the needle is less * than, equal to, or greater than the element, respectively. * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the * closest element that is smaller than or greater than the one we are * searching for, respectively, if the exact element cannot be found. * Defaults to 'binarySearch.GREATEST_LOWER_BOUND'. */ exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { if (aHaystack.length === 0) { return -1 } let index = recursiveSearch( -1, aHaystack.length, aNeedle, aHaystack, aCompare, aBias || exports.GREATEST_LOWER_BOUND ); if (index < 0) { return -1 } // We have found either the exact element, or the next-closest element than // the one we are searching for. However, there may be more than one such // element. Make sure we always return the smallest of these. while (index - 1 >= 0) { if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) { break } --index; } return index }; }); /* Determine browser vs node environment by testing the default top level context. Solution courtesy of: https://stackoverflow.com/questions/17575790/environment-detection-node-js-or-browser */ var readWasm$1 = createCommonjsModule(function (module) { { // Node version of reading a wasm file into an array buffer. const fs = fs__default["default"]; const path = path__default["default"]; module.exports = function readWasm() { return new Promise((resolve, reject) => { const wasmPath = path.join( __dirname, '../lib/source-map/lib', 'mappings.wasm' ); fs.readFile(wasmPath, null, (error, data) => { if (error) { reject(error); return } resolve(data.buffer); }); }) }; module.exports.initialize = (_) => { console.debug( 'SourceMapConsumer.initialize is a no-op when running in node.js' ); }; } }); var readWasm = readWasm$1; /** * Provide the JIT with a nice shape / hidden class. */ function Mapping() { this.generatedLine = 0; this.generatedColumn = 0; this.lastGeneratedColumn = null; this.source = null; this.originalLine = null; this.originalColumn = null; this.name = null; } let cachedWasm = null; var wasm$1 = function wasm() { if (cachedWasm) { return cachedWasm } const callbackStack = []; cachedWasm = readWasm() .then((buffer) => { return WebAssembly.instantiate(buffer, { env: { mapping_callback( generatedLine, generatedColumn, hasLastGeneratedColumn, lastGeneratedColumn, hasOriginal, source, originalLine, originalColumn, hasName, name ) { const mapping = new Mapping(); // JS uses 1-based line numbers, wasm uses 0-based. mapping.generatedLine = generatedLine + 1; mapping.generatedColumn = generatedColumn; if (hasLastGeneratedColumn) { // JS uses inclusive last generated column, wasm uses exclusive. mapping.lastGeneratedColumn = lastGeneratedColumn - 1; } if (hasOriginal) { mapping.source = source; // JS uses 1-based line numbers, wasm uses 0-based. mapping.originalLine = originalLine + 1; mapping.originalColumn = originalColumn; if (hasName) { mapping.name = name; } } callbackStack[callbackStack.length - 1](mapping); }, start_all_generated_locations_for() { console.time('all_generated_locations_for'); }, end_all_generated_locations_for() { console.timeEnd('all_generated_locations_for'); }, start_compute_column_spans() { console.time('compute_column_spans'); }, end_compute_column_spans() { console.timeEnd('compute_column_spans'); }, start_generated_location_for() { console.time('generated_location_for'); }, end_generated_location_for() { console.timeEnd('generated_location_for'); }, start_original_location_for() { console.time('original_location_for'); }, end_original_location_for() { console.timeEnd('original_location_for'); }, start_parse_mappings() { console.time('parse_mappings'); }, end_parse_mappings() { console.timeEnd('parse_mappings'); }, start_sort_by_generated_location() { console.time('sort_by_generated_location'); }, end_sort_by_generated_location() { console.timeEnd('sort_by_generated_location'); }, start_sort_by_original_location() { console.time('sort_by_original_location'); }, end_sort_by_original_location() { console.timeEnd('sort_by_original_location'); }, }, }) }) .then((Wasm) => { return { exports: Wasm.instance.exports, withMappingCallback: (mappingCallback, f) => { callbackStack.push(mappingCallback); try { f(); } finally { callbackStack.pop(); } }, } }) .then(null, (e) => { cachedWasm = null; throw e }); return cachedWasm }; var binarySearch = binarySearch$1; var wasm = wasm$1; /* -*- Mode: js; js-indent-level: 2; -*- */ /* * Copyright 2011 Mozilla Foundation and contributors * Licensed under the New BSD license. See LICENSE or: * http://opensource.org/licenses/BSD-3-Clause */ const ArraySet = require$$0$1.ArraySet; // eslint-disable-line no-unused-vars const INTERNAL = Symbol('smcInternal'); class SourceMapConsumer$1 { constructor(aSourceMap, aSourceMapURL) { // If the constructor was called by super(), just return Promise. // Yes, this is a hack to retain the pre-existing API of the base-class // constructor also being an async factory function. if (aSourceMap == INTERNAL) { return Promise.resolve(this) } return _factory(aSourceMap, aSourceMapURL) } static initialize(opts) { readWasm.initialize(opts['lib/mappings.wasm']); } static fromSourceMap(aSourceMap, aSourceMapURL) { return _factoryBSM(aSourceMap, aSourceMapURL) } /** * Construct a new `SourceMapConsumer` from `rawSourceMap` and `sourceMapUrl` * (see the `SourceMapConsumer` constructor for details. Then, invoke the `async * function f(SourceMapConsumer) -> T` with the newly constructed consumer, wait * for `f` to complete, call `destroy` on the consumer, and return `f`'s return * value. * * You must not use the consumer after `f` completes! * * By using `with`, you do not have to remember to manually call `destroy` on * the consumer, since it will be called automatically once `f` completes. * * ```js * const xSquared = await SourceMapConsumer.with( * myRawSourceMap, * null, * async function (consumer) { * // Use `consumer` inside here and don't worry about remembering * // to call `destroy`. * * const x = await whatever(consumer); * return x * x; * } * ); * * // You may not use that `consumer` anymore out here; it has * // been destroyed. But you can use `xSquared`. * console.log(xSquared); * ``` */ static async with(rawSourceMap, sourceMapUrl, f) { const consumer = await new SourceMapConsumer$1(rawSourceMap, sourceMapUrl); try { return await f(consumer) } finally { consumer.destroy(); } } /** * Parse the mappings in a string in to a data structure which we can easily * query (the ordered arrays in the `this.__generatedMappings` and * `this.__originalMappings` properties). */ _parseMappings(aStr, aSourceRoot) { throw new Error('Subclasses must implement _parseMappings') } /** * Iterate over each mapping between an original source/line/column and a * generated line/column in this source map. * * @param Function aCallback * The function that is called with each mapping. * @param Object aContext * Optional. If specified, this object will be the value of `this` every * time that `aCallback` is called. * @param aOrder * Either `SourceMapConsumer.GENERATED_ORDER` or * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to * iterate over the mappings sorted by the generated file's line/column * order or the original's source/line/column order, respectively. Defaults to * `SourceMapConsumer.GENERATED_ORDER`. */ eachMapping(aCallback, aContext, aOrder) { throw new Error('Subclasses must implement eachMapping') } /** * Returns all generated line and column information for the original source, * line, and column provided. If no column is provided, returns all mappings * corresponding to a either the line we are searching for or the next * closest line that has any mappings. Otherwise, returns all mappings * corresponding to the given line and either the column we are searching for * or the next closest column that has any offsets. * * The only argument is an object with the following properties: * * - source: The filename of the original source. * - line: The line number in the original source. The line number is 1-based. * - column: Optional. the column number in the original source. * The column number is 0-based. * * and an array of objects is returned, each with the following properties: * * - line: The line number in the generated source, or null. The * line number is 1-based. * - column: The column number in the generated source, or null. * The column number is 0-based. */ allGeneratedPositionsFor(aArgs) { throw new Error('Subclasses must implement allGeneratedPositionsFor') } destroy() { throw new Error('Subclasses must implement destroy') } } /** * The version of the source mapping spec that we are consuming. */ SourceMapConsumer$1.prototype._version = 3; SourceMapConsumer$1.GENERATED_ORDER = 1; SourceMapConsumer$1.ORIGINAL_ORDER = 2; SourceMapConsumer$1.GREATEST_LOWER_BOUND = 1; SourceMapConsumer$1.LEAST_UPPER_BOUND = 2; var SourceMapConsumer_1 = SourceMapConsumer$1; /** * A BasicSourceMapConsumer instance represents a parsed source map which we can * query for information about the original file positions by giving it a file * position in the generated source. * * The first parameter is the raw source map (either as a JSON string, or * already parsed to an object). According to the spec, source maps have the * following attributes: * * - version: Which version of the source map spec this map is following. * - sources: An array of URLs to the original source files. * - names: An array of identifiers which can be referenced by individual mappings. * - sourceRoot: Optional. The URL root from which all sources are relative. * - sourcesContent: Optional. An array of contents of the original source files. * - mappings: A string of base64 VLQs which contain the actual mappings. * - file: Optional. The generated file this source map is associated with. * * Here is an example source map, taken from the source map spec[0]: * * { * version : 3, * file: "out.js", * sourceRoot : "", * sources: ["foo.js", "bar.js"], * names: ["src", "maps", "are", "fun"], * mappings: "AA,AB;;ABCDE;" * } * * The second parameter, if given, is a string whose value is the URL * at which the source map was found. This URL is used to compute the * sources array. * * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1# */ class BasicSourceMapConsumer extends SourceMapConsumer$1 { constructor(aSourceMap, aSourceMapURL) { return super(INTERNAL).then((that) => { let sourceMap = aSourceMap; if (typeof aSourceMap === 'string') { sourceMap = util.parseSourceMapInput(aSourceMap); } const version = util.getArg(sourceMap, 'version'); let sources = util.getArg(sourceMap, 'sources'); // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which // requires the array) to play nice here. const names = util.getArg(sourceMap, 'names', []); let sourceRoot = util.getArg(sourceMap, 'sourceRoot', null); const sourcesContent = util.getArg(sourceMap, 'sourcesContent', null); const mappings = util.getArg(sourceMap, 'mappings'); const file = util.getArg(sourceMap, 'file', null); // Once again, Sass deviates from the spec and supplies the version as a // string rather than a number, so we use loose equality checking here. if (version != that._version) { throw new Error('Unsupported version: ' + version) } if (sourceRoot) { sourceRoot = util.normalize(sourceRoot); } sources = sources .map(String) // Some source maps produce relative source paths like "./foo.js" instead of // "foo.js". Normalize these first so that future comparisons will succeed. // See bugzil.la/1090768. .map(util.normalize) // Always ensure that absolute sources are internally stored relative to // the source root, if the source root is absolute. Not doing this would // be particularly problematic when the source root is a prefix of the // source (valid, but why??). See github issue #199 and bugzil.la/1188982. .map(function (source) { return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source) ? util.relative(sourceRoot, source) : source }); // Pass `true` below to allow duplicate names and sources. While source maps // are intended to be compressed and deduplicated, the TypeScript compiler // sometimes generates source maps with duplicates in them. See Github issue // #72 and bugzil.la/889492. that._names = ArraySet.fromArray(names.map(String), true); that._sources = ArraySet.fromArray(sources, true); that._absoluteSources = that._sources.toArray().map(function (s) { return util.computeSourceURL(sourceRoot, s, aSourceMapURL) }); that.sourceRoot = sourceRoot; that.sourcesContent = sourcesContent; that._mappings = mappings; that._sourceMapURL = aSourceMapURL; that.file = file; that._computedColumnSpans = false; that._mappingsPtr = 0; that._wasm = null; return wasm().then((w) => { that._wasm = w; return that }) }) } /** * Utility function to find the index of a source. Returns -1 if not * found. */ _findSourceIndex(aSource) { let relativeSource = aSource; if (this.sourceRoot != null) { relativeSource = util.relative(this.sourceRoot, relativeSource); } if (this._sources.has(relativeSource)) { return this._sources.indexOf(relativeSource) } // Maybe aSource is an absolute URL as returned by |sources|. In // this case we can't simply undo the transform. for (let i = 0; i < this._absoluteSources.length; ++i) { if (this._absoluteSources[i] == aSource) { return i } } return -1 } /** * Create a BasicSourceMapConsumer from a SourceMapGenerator. * * @param SourceMapGenerator aSourceMap * The source map that will be consumed. * @param String aSourceMapURL * The URL at which the source map can be found (optional) * @returns BasicSourceMapConsumer */ static fromSourceMap(aSourceMap, aSourceMapURL) { return new BasicSourceMapConsumer(aSourceMap.toString()) } get sources() { return this._absoluteSources.slice() } _getMappingsPtr() { if (this._mappingsPtr === 0) { this._parseMappings(this._mappings, this.sourceRoot); } return this._mappingsPtr } /** * Parse the mappings in a string in to a data structure which we can easily * query (the ordered arrays in the `this.__generatedMappings` and * `this.__originalMappings` properties). */ _parseMappings(aStr, aSourceRoot) { const size = aStr.length; const mappingsBufPtr = this._wasm.exports.allocate_mappings(size); const mappingsBuf = new Uint8Array( this._wasm.exports.memory.buffer, mappingsBufPtr, size ); for (let i = 0; i < size; i++) { mappingsBuf[i] = aStr.charCodeAt(i); } const mappingsPtr = this._wasm.exports.parse_mappings(mappingsBufPtr); if (!mappingsPtr) { const error = this._wasm.exports.get_last_error(); let msg = `Error parsing mappings (code ${error}): `; // XXX: keep these error codes in sync with `fitzgen/source-map-mappings`. switch (error) { case 1: msg += 'the mappings contained a negative line, column, source index, or name index'; break case 2: msg += 'the mappings contained a number larger than 2**32'; break case 3: msg += 'reached EOF while in the middle of parsing a VLQ'; break case 4: msg += 'invalid base 64 character while parsing a VLQ'; break default: msg += 'unknown error code'; break } throw new Error(msg) } this._mappingsPtr = mappingsPtr; } eachMapping(aCallback, aContext, aOrder) { const context = aContext || null; const order = aOrder || SourceMapConsumer$1.GENERATED_ORDER; const sourceRoot = this.sourceRoot; this._wasm.withMappingCallback( (mapping) => { if (mapping.source !== null) { mapping.source = this._sources.at(mapping.source); mapping.source = util.computeSourceURL( sourceRoot, mapping.source, this._sourceMapURL ); if (mapping.name !== null) { mapping.name = this._names.at(mapping.name); } } aCallback.call(context, mapping); }, () => { switch (order) { case SourceMapConsumer$1.GENERATED_ORDER: this._wasm.exports.by_generated_location(this._getMappingsPtr()); break case SourceMapConsumer$1.ORIGINAL_ORDER: this._wasm.exports.by_original_location(this._getMappingsPtr()); break default: throw new Error('Unknown order of iteration.') } } ); } allGeneratedPositionsFor(aArgs) { let source = util.getArg(aArgs, 'source'); const originalLine = util.getArg(aArgs, 'line'); const originalColumn = aArgs.column || 0; source = this._findSourceIndex(source); if (source < 0) { return [] } if (originalLine < 1) { throw new Error('Line numbers must be >= 1') } if (originalColumn < 0) { throw new Error('Column numbers must be >= 0') } const mappings = []; this._wasm.withMappingCallback( (m) => { let lastColumn = m.lastGeneratedColumn; if (this._computedColumnSpans && lastColumn === null) { lastColumn = Infinity; } mappings.push({ line: m.generatedLine, column: m.generatedColumn, lastColumn, }); }, () => { this._wasm.exports.all_generated_locations_for( this._getMappingsPtr(), source, originalLine - 1, 'column' in aArgs, originalColumn ); } ); return mappings } destroy() { if (this._mappingsPtr !== 0) { this._wasm.exports.free_mappings(this._mappingsPtr); this._mappingsPtr = 0; } } /** * Compute the last column for each generated mapping. The last column is * inclusive. */ computeColumnSpans() { if (this._computedColumnSpans) { return } this._wasm.exports.compute_column_spans(this._getMappingsPtr()); this._computedColumnSpans = true; } /** * Returns the original source, line, and column information for the generated * source's line and column positions provided. The only argument is an object * with the following properties: * * - line: The line number in the generated source. The line number * is 1-based. * - column: The column number in the generated source. The column * number is 0-based. * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the * closest element that is smaller than or greater than the one we are * searching for, respectively, if the exact element cannot be found. * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. * * and an object is returned with the following properties: * * - source: The original source file, or null. * - line: The line number in the original source, or null. The * line number is 1-based. * - column: The column number in the original source, or null. The * column number is 0-based. * - name: The original identifier, or null. */ originalPositionFor(aArgs) { const needle = { generatedLine: util.getArg(aArgs, 'line'), generatedColumn: util.getArg(aArgs, 'column'), }; if (needle.generatedLine < 1) { throw new Error('Line numbers must be >= 1') } if (needle.generatedColumn < 0) { throw new Error('Column numbers must be >= 0') } let bias = util.getArg( aArgs, 'bias', SourceMapConsumer$1.GREATEST_LOWER_BOUND ); if (bias == null) { bias = SourceMapConsumer$1.GREATEST_LOWER_BOUND; } let mapping; this._wasm.withMappingCallback( (m) => (mapping = m), () => { this._wasm.exports.original_location_for( this._getMappingsPtr(), needle.generatedLine - 1, needle.generatedColumn, bias ); } ); if (mapping) { if (mapping.generatedLine === needle.generatedLine) { let source = util.getArg(mapping, 'source', null); if (source !== null) { source = this._sources.at(source); source = util.computeSourceURL( this.sourceRoot, source, this._sourceMapURL ); } let name = util.getArg(mapping, 'name', null); if (name !== null) { name = this._names.at(name); } return { source, line: util.getArg(mapping, 'originalLine', null), column: util.getArg(mapping, 'originalColumn', null), name, } } } return { source: null, line: null, column: null, name: null, } } /** * Return true if we have the source content for every source in the source * map, false otherwise. */ hasContentsOfAllSources() { if (!this.sourcesContent) { return false } return ( this.sourcesContent.length >= this._sources.size() && !this.sourcesContent.some(function (sc) { return sc == null }) ) } /** * Returns the original source content. The only argument is the url of the * original source file. Returns null if no original source content is * available. */ sourceContentFor(aSource, nullOnMissing) { if (!this.sourcesContent) { return null } const index = this._findSourceIndex(aSource); if (index >= 0) { return this.sourcesContent[index] } let relativeSource = aSource; if (this.sourceRoot != null) { relativeSource = util.relative(this.sourceRoot, relativeSource); } let url; if (this.sourceRoot != null && (url = util.urlParse(this.sourceRoot))) { // XXX: file:// URIs and absolute paths lead to unexpected behavior for // many users. We can help them out when they expect file:// URIs to // behave like it would if they were running a local HTTP server. See // https://bugzilla.mozilla.org/show_bug.cgi?id=885597. const fileUriAbsPath = relativeSource.replace(/^file:\/\//, ''); if (url.scheme == 'file' && this._sources.has(fileUriAbsPath)) { return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)] } if ( (!url.path || url.path == '/') && this._sources.has('/' + relativeSource) ) { return this.sourcesContent[this._sources.indexOf('/' + relativeSource)] } } // This function is used recursively from // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we // don't want to throw if we can't find the source - we just want to // return null, so we provide a flag to exit gracefully. if (nullOnMissing) { return null } throw new Error('"' + relativeSource + '" is not in the SourceMap.') } /** * Returns the generated line and column information for the original source, * line, and column positions provided. The only argument is an object with * the following properties: * * - source: The filename of the original source. * - line: The line number in the original source. The line number * is 1-based. * - column: The column number in the original source. The column * number is 0-based. * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the * closest element that is smaller than or greater than the one we are * searching for, respectively, if the exact element cannot be found. * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. * * and an object is returned with the following properties: * * - line: The line number in the generated source, or null. The * line number is 1-based. * - column: The column number in the generated source, or null. * The column number is 0-based. */ generatedPositionFor(aArgs) { let source = util.getArg(aArgs, 'source'); source = this._findSourceIndex(source); if (source < 0) { return { line: null, column: null, lastColumn: null, } } const needle = { source, originalLine: util.getArg(aArgs, 'line'), originalColumn: util.getArg(aArgs, 'column'), }; if (needle.originalLine < 1) { throw new Error('Line numbers must be >= 1') } if (needle.originalColumn < 0) { throw new Error('Column numbers must be >= 0') } let bias = util.getArg( aArgs, 'bias', SourceMapConsumer$1.GREATEST_LOWER_BOUND ); if (bias == null) { bias = SourceMapConsumer$1.GREATEST_LOWER_BOUND; } let mapping; this._wasm.withMappingCallback( (m) => (mapping = m), () => { this._wasm.exports.generated_location_for( this._getMappingsPtr(), needle.source, needle.originalLine - 1, needle.originalColumn, bias ); } ); if (mapping) { if (mapping.source === needle.source) { let lastColumn = mapping.lastGeneratedColumn; if (this._computedColumnSpans && lastColumn === null) { lastColumn = Infinity; } return { line: util.getArg(mapping, 'generatedLine', null), column: util.getArg(mapping, 'generatedColumn', null), lastColumn, } } } return { line: null, column: null, lastColumn: null, } } } BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer$1; var BasicSourceMapConsumer_1 = BasicSourceMapConsumer; /** * An IndexedSourceMapConsumer instance represents a parsed source map which * we can query for information. It differs from BasicSourceMapConsumer in * that it takes "indexed" source maps (i.e. ones with a "sections" field) as * input. * * The first parameter is a raw source map (either as a JSON string, or already * parsed to an object). According to the spec for indexed source maps, they * have the following attributes: * * - version: Which version of the source map spec this map is following. * - file: Optional. The generated file this source map is associated with. * - sections: A list of section definitions. * * Each value under the "sections" field has two fields: * - offset: The offset into the original specified at which this section * begins to apply, defined as an object with a "line" and "column" * field. * - map: A source map definition. This source map could also be indexed, * but doesn't have to be. * * Instead of the "map" field, it's also possible to have a "url" field * specifying a URL to retrieve a source map from, but that's currently * unsupported. * * Here's an example source map, taken from the source map spec[0], but * modified to omit a section which uses the "url" field. * * { * version : 3, * file: "app.js", * sections: [{ * offset: {line:100, column:10}, * map: { * version : 3, * file: "section.js", * sources: ["foo.js", "bar.js"], * names: ["src", "maps", "are", "fun"], * mappings: "AAAA,E;;ABCDE;" * } * }], * } * * The second parameter, if given, is a string whose value is the URL * at which the source map was found. This URL is used to compute the * sources array. * * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt */ class IndexedSourceMapConsumer extends SourceMapConsumer$1 { constructor(aSourceMap, aSourceMapURL) { return super(INTERNAL).then((that) => { let sourceMap = aSourceMap; if (typeof aSourceMap === 'string') { sourceMap = util.parseSourceMapInput(aSourceMap); } const version = util.getArg(sourceMap, 'version'); const sections = util.getArg(sourceMap, 'sections'); if (version != that._version) { throw new Error('Unsupported version: ' + version) } that._sources = new ArraySet(); that._names = new ArraySet(); that.__generatedMappings = null; that.__originalMappings = null; that.__generatedMappingsUnsorted = null; that.__originalMappingsUnsorted = null; let lastOffset = { line: -1, column: 0, }; return Promise.all( sections.map((s) => { if (s.url) { // The url field will require support for asynchronicity. // See https://github.com/mozilla/source-map/issues/16 throw new Error( 'Support for url field in sections not implemented.' ) } const offset = util.getArg(s, 'offset'); const offsetLine = util.getArg(offset, 'line'); const offsetColumn = util.getArg(offset, 'column'); if ( offsetLine < lastOffset.line || (offsetLine === lastOffset.line && offsetColumn < lastOffset.column) ) { throw new Error( 'Section offsets must be ordered and non-overlapping.' ) } lastOffset = offset; const cons = new SourceMapConsumer$1( util.getArg(s, 'map'), aSourceMapURL ); return cons.then((consumer) => { return { generatedOffset: { // The offset fields are 0-based, but we use 1-based indices when // encoding/decoding from VLQ. generatedLine: offsetLine + 1, generatedColumn: offsetColumn + 1, }, consumer, } }) }) ).then((s) => { that._sections = s; return that }) }) } // `__generatedMappings` and `__originalMappings` are arrays that hold the // parsed mapping coordinates from the source map's "mappings" attribute. They // are lazily instantiated, accessed via the `_generatedMappings` and // `_originalMappings` getters respectively, and we only parse the mappings // and create these arrays once queried for a source location. We jump through // these hoops because there can be many thousands of mappings, and parsing // them is expensive, so we only want to do it if we must. // // Each object in the arrays is of the form: // // { // generatedLine: The line number in the generated code, // generatedColumn: The column number in the generated code, // source: The path to the original source file that generated this // chunk of code, // originalLine: The line number in the original source that // corresponds to this chunk of generated code, // originalColumn: The column number in the original source that // corresponds to this chunk of generated code, // name: The name of the original symbol which generated this chunk of // code. // } // // All properties except for `generatedLine` and `generatedColumn` can be // `null`. // // `_generatedMappings` is ordered by the generated positions. // // `_originalMappings` is ordered by the original positions. get _generatedMappings() { if (!this.__generatedMappings) { this._sortGeneratedMappings(); } return this.__generatedMappings } get _originalMappings() { if (!this.__originalMappings) { this._sortOriginalMappings(); } return this.__originalMappings } get _generatedMappingsUnsorted() { if (!this.__generatedMappingsUnsorted) { this._parseMappings(this._mappings, this.sourceRoot); } return this.__generatedMappingsUnsorted } get _originalMappingsUnsorted() { if (!this.__originalMappingsUnsorted) { this._parseMappings(this._mappings, this.sourceRoot); } return this.__originalMappingsUnsorted } _sortGeneratedMappings() { const mappings = this._generatedMappingsUnsorted; mappings.sort(util.compareByGeneratedPositionsDeflated); this.__generatedMappings = mappings; } _sortOriginalMappings() { const mappings = this._originalMappingsUnsorted; mappings.sort(util.compareByOriginalPositions); this.__originalMappings = mappings; } /** * The list of original sources. */ get sources() { const sources = []; for (let i = 0; i < this._sections.length; i++) { for (let j = 0; j < this._sections[i].consumer.sources.length; j++) { sources.push(this._sections[i].consumer.sources[j]); } } return sources } /** * Returns the original source, line, and column information for the generated * source's line and column positions provided. The only argument is an object * with the following properties: * * - line: The line number in the generated source. The line number * is 1-based. * - column: The column number in the generated source. The column * number is 0-based. * * and an object is returned with the following properties: * * - source: The original source file, or null. * - line: The line number in the original source, or null. The * line number is 1-based. * - column: The column number in the original source, or null. The * column number is 0-based. * - name: The original identifier, or null. */ originalPositionFor(aArgs) { const needle = { generatedLine: util.getArg(aArgs, 'line'), generatedColumn: util.getArg(aArgs, 'column'), }; // Find the section containing the generated position we're trying to map // to an original position. const sectionIndex = binarySearch.search( needle, this._sections, function (aNeedle, section) { const cmp = aNeedle.generatedLine - section.generatedOffset.generatedLine; if (cmp) { return cmp } return aNeedle.generatedColumn - section.generatedOffset.generatedColumn } ); const section = this._sections[sectionIndex]; if (!section) { return { source: null, line: null, column: null, name: null, } } return section.consumer.originalPositionFor({ line: needle.generatedLine - (section.generatedOffset.generatedLine - 1), column: needle.generatedColumn - (section.generatedOffset.generatedLine === needle.generatedLine ? section.generatedOffset.generatedColumn - 1 : 0), bias: aArgs.bias, }) } /** * Return true if we have the source content for every source in the source * map, false otherwise. */ hasContentsOfAllSources() { return this._sections.every(function (s) { return s.consumer.hasContentsOfAllSources() }) } /** * Returns the original source content. The only argument is the url of the * original source file. Returns null if no original source content is * available. */ sourceContentFor(aSource, nullOnMissing) { for (let i = 0; i < this._sections.length; i++) { const section = this._sections[i]; const content = section.consumer.sourceContentFor(aSource, true); if (content) { return content } } if (nullOnMissing) { return null } throw new Error('"' + aSource + '" is not in the SourceMap.') } /** * Returns the generated line and column information for the original source, * line, and column positions provided. The only argument is an object with * the following properties: * * - source: The filename of the original source. * - line: The line number in the original source. The line number * is 1-based. * - column: The column number in the original source. The column * number is 0-based. * * and an object is returned with the following properties: * * - line: The line number in the generated source, or null. The * line number is 1-based. * - column: The column number in the generated source, or null. * The column number is 0-based. */ generatedPositionFor(aArgs) { for (let i = 0; i < this._sections.length; i++) { const section = this._sections[i]; // Only consider this section if the requested source is in the list of // sources of the consumer. if ( section.consumer._findSourceIndex(util.getArg(aArgs, 'source')) === -1 ) { continue } const generatedPosition = section.consumer.generatedPositionFor(aArgs); if (generatedPosition) { const ret = { line: generatedPosition.line + (section.generatedOffset.generatedLine - 1), column: generatedPosition.column + (section.generatedOffset.generatedLine === generatedPosition.line ? section.generatedOffset.generatedColumn - 1 : 0), }; return ret } } return { line: null, column: null, } } /** * Parse the mappings in a string in to a data structure which we can easily * query (the ordered arrays in the `this.__generatedMappings` and * `this.__originalMappings` properties). */ _parseMappings(aStr, aSourceRoot) { const generatedMappings = (this.__generatedMappingsUnsorted = []); const originalMappings = (this.__originalMappingsUnsorted = []); for (let i = 0; i < this._sections.length; i++) { const section = this._sections[i]; const sectionMappings = []; section.consumer.eachMapping((m) => sectionMappings.push(m)); for (let j = 0; j < sectionMappings.length; j++) { const mapping = sectionMappings[j]; // TODO: test if null is correct here. The original code used // `source`, which would actually have gotten used as null because // var's get hoisted. // See: https://github.com/mozilla/source-map/issues/333 let source = util.computeSourceURL( section.consumer.sourceRoot, null, this._sourceMapURL ); this._sources.add(source); source = this._sources.indexOf(source); let name = null; if (mapping.name) { this._names.add(mapping.name); name = this._names.indexOf(mapping.name); } // The mappings coming from the consumer for the section have // generated positions relative to the start of the section, so we // need to offset them to be relative to the start of the concatenated // generated file. const adjustedMapping = { source, generatedLine: mapping.generatedLine + (section.generatedOffset.generatedLine - 1), generatedColumn: mapping.generatedColumn + (section.generatedOffset.generatedLine === mapping.generatedLine ? section.generatedOffset.generatedColumn - 1 : 0), originalLine: mapping.originalLine, originalColumn: mapping.originalColumn, name, }; generatedMappings.push(adjustedMapping); if (typeof adjustedMapping.originalLine === 'number') { originalMappings.push(adjustedMapping); } } } } eachMapping(aCallback, aContext, aOrder) { const context = aContext || null; const order = aOrder || SourceMapConsumer$1.GENERATED_ORDER; let mappings; switch (order) { case SourceMapConsumer$1.GENERATED_ORDER: mappings = this._generatedMappings; break case SourceMapConsumer$1.ORIGINAL_ORDER: mappings = this._originalMappings; break default: throw new Error('Unknown order of iteration.') } const sourceRoot = this.sourceRoot; mappings .map(function (mapping) { let source = null; if (mapping.source !== null) { source = this._sources.at(mapping.source); source = util.computeSourceURL(sourceRoot, source, this._sourceMapURL); } return { source, generatedLine: mapping.generatedLine, generatedColumn: mapping.generatedColumn, originalLine: mapping.originalLine, originalColumn: mapping.originalColumn, name: mapping.name === null ? null : this._names.at(mapping.name), } }, this) .forEach(aCallback, context); } /** * Find the mapping that best matches the hypothetical "needle" mapping that * we are searching for in the given "haystack" of mappings. */ _findMapping(aNeedle, aMappings, aLineName, aColumnName, aComparator, aBias) { // To return the position we are searching for, we must first find the // mapping for the given position and then return the opposite position it // points to. Because the mappings are sorted, we can use binary search to // find the best mapping. if (aNeedle[aLineName] <= 0) { throw new TypeError( 'Line must be greater than or equal to 1, got ' + aNeedle[aLineName] ) } if (aNeedle[aColumnName] < 0) { throw new TypeError( 'Column must be greater than or equal to 0, got ' + aNeedle[aColumnName] ) } return binarySearch.search(aNeedle, aMappings, aComparator, aBias) } allGeneratedPositionsFor(aArgs) { const line = util.getArg(aArgs, 'line'); // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping // returns the index of the closest mapping less than the needle. By // setting needle.originalColumn to 0, we thus find the last mapping for // the given line, provided such a mapping exists. const needle = { source: util.getArg(aArgs, 'source'), originalLine: line, originalColumn: util.getArg(aArgs, 'column', 0), }; needle.source = this._findSourceIndex(needle.source); if (needle.source < 0) { return [] } if (needle.originalLine < 1) { throw new Error('Line numbers must be >= 1') } if (needle.originalColumn < 0) { throw new Error('Column numbers must be >= 0') } const mappings = []; let index = this._findMapping( needle, this._originalMappings, 'originalLine', 'originalColumn', util.compareByOriginalPositions, binarySearch.LEAST_UPPER_BOUND ); if (index >= 0) { let mapping = this._originalMappings[index]; if (aArgs.column === undefined) { const originalLine = mapping.originalLine; // Iterate until either we run out of mappings, or we run into // a mapping for a different line than the one we found. Since // mappings are sorted, this is guaranteed to find all mappings for // the line we found. while (mapping && mapping.originalLine === originalLine) { let lastColumn = mapping.lastGeneratedColumn; if (this._computedColumnSpans && lastColumn === null) { lastColumn = Infinity; } mappings.push({ line: util.getArg(mapping, 'generatedLine', null), column: util.getArg(mapping, 'generatedColumn', null), lastColumn, }); mapping = this._originalMappings[++index]; } } else { const originalColumn = mapping.originalColumn; // Iterate until either we run out of mappings, or we run into // a mapping for a different line than the one we were searching for. // Since mappings are sorted, this is guaranteed to find all mappings for // the line we are searching for. while ( mapping && mapping.originalLine === line && mapping.originalColumn == originalColumn ) { let lastColumn = mapping.lastGeneratedColumn; if (this._computedColumnSpans && lastColumn === null) { lastColumn = Infinity; } mappings.push({ line: util.getArg(mapping, 'generatedLine', null), column: util.getArg(mapping, 'generatedColumn', null), lastColumn, }); mapping = this._originalMappings[++index]; } } } return mappings } destroy() { for (let i = 0; i < this._sections.length; i++) { this._sections[i].consumer.destroy(); } } } var IndexedSourceMapConsumer_1 = IndexedSourceMapConsumer; /* * Cheat to get around inter-twingled classes. `factory()` can be at the end * where it has access to non-hoisted classes, but it gets hoisted itself. */ function _factory(aSourceMap, aSourceMapURL) { let sourceMap = aSourceMap; if (typeof aSourceMap === 'string') { sourceMap = util.parseSourceMapInput(aSourceMap); } const consumer = sourceMap.sections != null ? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL) : new BasicSourceMapConsumer(sourceMap, aSourceMapURL); return Promise.resolve(consumer) } function _factoryBSM(aSourceMap, aSourceMapURL) { return BasicSourceMapConsumer.fromSourceMap(aSourceMap, aSourceMapURL) } var sourceMapConsumer = { SourceMapConsumer: SourceMapConsumer_1, BasicSourceMapConsumer: BasicSourceMapConsumer_1, IndexedSourceMapConsumer: IndexedSourceMapConsumer_1 }; var require$$0 = sourceMapGenerator; /* -*- Mode: js; js-indent-level: 2; -*- */ /* * Copyright 2011 Mozilla Foundation and contributors * Licensed under the New BSD license. See LICENSE or: * http://opensource.org/licenses/BSD-3-Clause */ const SourceMapGenerator = require$$0.SourceMapGenerator; // Matches a Windows-style `\r\n` newline or a `\n` newline used by all other // operating systems these days (capturing the result). const REGEX_NEWLINE = /(\r?\n)/; // Newline character code for charCodeAt() comparisons const NEWLINE_CODE = 10; // Private symbol for identifying `SourceNode`s when multiple versions of // the source-map library are loaded. This MUST NOT CHANGE across // versions! const isSourceNode = '$$$isSourceNode$$$'; /** * SourceNodes provide a way to abstract over interpolating/concatenating * snippets of generated JavaScript source code while maintaining the line and * column information associated with the original source code. * * @param aLine The original line number. * @param aColumn The original column number. * @param aSource The original source's filename. * @param aChunks Optional. An array of strings which are snippets of * generated JS, or other SourceNodes. * @param aName The original identifier. */ class SourceNode { constructor(aLine, aColumn, aSource, aChunks, aName) { this.children = []; this.sourceContents = {}; this.line = aLine == null ? null : aLine; this.column = aColumn == null ? null : aColumn; this.source = aSource == null ? null : aSource; this.name = aName == null ? null : aName; this[isSourceNode] = true; if (aChunks != null) this.add(aChunks); } /** * Creates a SourceNode from generated code and a SourceMapConsumer. * * @param aGeneratedCode The generated code * @param aSourceMapConsumer The SourceMap for the generated code * @param aRelativePath Optional. The path that relative sources in the * SourceMapConsumer should be relative to. */ static fromStringWithSourceMap( aGeneratedCode, aSourceMapConsumer, aRelativePath ) { // The SourceNode we want to fill with the generated code // and the SourceMap const node = new SourceNode(); // All even indices of this array are one line of the generated code, // while all odd indices are the newlines between two adjacent lines // (since `REGEX_NEWLINE` captures its match). // Processed fragments are accessed by calling `shiftNextLine`. const remainingLines = aGeneratedCode.split(REGEX_NEWLINE); let remainingLinesIndex = 0; const shiftNextLine = function () { const lineContents = getNextLine(); // The last line of a file might not have a newline. const newLine = getNextLine() || ''; return lineContents + newLine function getNextLine() { return remainingLinesIndex < remainingLines.length ? remainingLines[remainingLinesIndex++] : undefined } }; // We need to remember the position of "remainingLines" let lastGeneratedLine = 1, lastGeneratedColumn = 0; // The generate SourceNodes we need a code range. // To extract it current and last mapping is used. // Here we store the last mapping. let lastMapping = null; let nextLine; aSourceMapConsumer.eachMapping(function (mapping) { if (lastMapping !== null) { // We add the code from "lastMapping" to "mapping": // First check if there is a new line in between. if (lastGeneratedLine < mapping.generatedLine) { // Associate first line with "lastMapping" addMappingWithCode(lastMapping, shiftNextLine()); lastGeneratedLine++; lastGeneratedColumn = 0; // The remaining code is added without mapping } else { // There is no new line in between. // Associate the code between "lastGeneratedColumn" and // "mapping.generatedColumn" with "lastMapping" nextLine = remainingLines[remainingLinesIndex] || ''; const code = nextLine.substr( 0, mapping.generatedColumn - lastGeneratedColumn ); remainingLines[remainingLinesIndex] = nextLine.substr( mapping.generatedColumn - lastGeneratedColumn ); lastGeneratedColumn = mapping.generatedColumn; addMappingWithCode(lastMapping, code); // No more remaining code, continue lastMapping = mapping; return } } // We add the generated code until the first mapping // to the SourceNode without any mapping. // Each line is added as separate string. while (lastGeneratedLine < mapping.generatedLine) { node.add(shiftNextLine()); lastGeneratedLine++; } if (lastGeneratedColumn < mapping.generatedColumn) { nextLine = remainingLines[remainingLinesIndex] || ''; node.add(nextLine.substr(0, mapping.generatedColumn)); remainingLines[remainingLinesIndex] = nextLine.substr( mapping.generatedColumn ); lastGeneratedColumn = mapping.generatedColumn; } lastMapping = mapping; }, this); // We have processed all mappings. if (remainingLinesIndex < remainingLines.length) { if (lastMapping) { // Associate the remaining code in the current line with "lastMapping" addMappingWithCode(lastMapping, shiftNextLine()); } // and add the remaining lines without any mapping node.add(remainingLines.splice(remainingLinesIndex).join('')); } // Copy sourcesContent into SourceNode aSourceMapConsumer.sources.forEach(function (sourceFile) { const content = aSourceMapConsumer.sourceContentFor(sourceFile); if (content != null) { if (aRelativePath != null) { sourceFile = util.join(aRelativePath, sourceFile); } node.setSourceContent(sourceFile, content); } }); return node function addMappingWithCode(mapping, code) { if (mapping === null || mapping.source === undefined) { node.add(code); } else { const source = aRelativePath ? util.join(aRelativePath, mapping.source) : mapping.source; node.add( new SourceNode( mapping.originalLine, mapping.originalColumn, source, code, mapping.name ) ); } } } /** * Add a chunk of generated JS to this source node. * * @param aChunk A string snippet of generated JS code, another instance of * SourceNode, or an array where each member is one of those things. */ add(aChunk) { if (Array.isArray(aChunk)) { aChunk.forEach(function (chunk) { this.add(chunk); }, this); } else if (aChunk[isSourceNode] || typeof aChunk === 'string') { if (aChunk) { this.children.push(aChunk); } } else { throw new TypeError( 'Expected a SourceNode, string, or an array of SourceNodes and strings. Got ' + aChunk ) } return this } /** * Add a chunk of generated JS to the beginning of this source node. * * @param aChunk A string snippet of generated JS code, another instance of * SourceNode, or an array where each member is one of those things. */ prepend(aChunk) { if (Array.isArray(aChunk)) { for (let i = aChunk.length - 1; i >= 0; i--) { this.prepend(aChunk[i]); } } else if (aChunk[isSourceNode] || typeof aChunk === 'string') { this.children.unshift(aChunk); } else { throw new TypeError( 'Expected a SourceNode, string, or an array of SourceNodes and strings. Got ' + aChunk ) } return this } /** * Walk over the tree of JS snippets in this node and its children. The * walking function is called once for each snippet of JS and is passed that * snippet and the its original associated source's line/column location. * * @param aFn The traversal function. */ walk(aFn) { let chunk; for (let i = 0, len = this.children.length; i < len; i++) { chunk = this.children[i]; if (chunk[isSourceNode]) { chunk.walk(aFn); } else if (chunk !== '') { aFn(chunk, { source: this.source, line: this.line, column: this.column, name: this.name, }); } } } /** * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between * each of `this.children`. * * @param aSep The separator. */ join(aSep) { let newChildren; let i; const len = this.children.length; if (len > 0) { newChildren = []; for (i = 0; i < len - 1; i++) { newChildren.push(this.children[i]); newChildren.push(aSep); } newChildren.push(this.children[i]); this.children = newChildren; } return this } /** * Call String.prototype.replace on the very right-most source snippet. Useful * for trimming whitespace from the end of a source node, etc. * * @param aPattern The pattern to replace. * @param aReplacement The thing to replace the pattern with. */ replaceRight(aPattern, aReplacement) { const lastChild = this.children[this.children.length - 1]; if (lastChild[isSourceNode]) { lastChild.replaceRight(aPattern, aReplacement); } else if (typeof lastChild === 'string') { this.children[this.children.length - 1] = lastChild.replace( aPattern, aReplacement ); } else { this.children.push(''.replace(aPattern, aReplacement)); } return this } /** * Set the source content for a source file. This will be added to the SourceMapGenerator * in the sourcesContent field. * * @param aSourceFile The filename of the source file * @param aSourceContent The content of the source file */ setSourceContent(aSourceFile, aSourceContent) { this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent; } /** * Walk over the tree of SourceNodes. The walking function is called for each * source file content and is passed the filename and source content. * * @param aFn The traversal function. */ walkSourceContents(aFn) { for (let i = 0, len = this.children.length; i < len; i++) { if (this.children[i][isSourceNode]) { this.children[i].walkSourceContents(aFn); } } const sources = Object.keys(this.sourceContents); for (let i = 0, len = sources.length; i < len; i++) { aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]); } } /** * Return the string representation of this source node. Walks over the tree * and concatenates all the various snippets together to one string. */ toString() { let str = ''; this.walk(function (chunk) { str += chunk; }); return str } /** * Returns the string representation of this source node along with a source * map. */ toStringWithSourceMap(aArgs) { const generated = { code: '', line: 1, column: 0, }; const map = new SourceMapGenerator(aArgs); let sourceMappingActive = false; let lastOriginalSource = null; let lastOriginalLine = null; let lastOriginalColumn = null; let lastOriginalName = null; this.walk(function (chunk, original) { generated.code += chunk; if ( original.source !== null && original.line !== null && original.column !== null ) { if ( lastOriginalSource !== original.source || lastOriginalLine !== original.line || lastOriginalColumn !== original.column || lastOriginalName !== original.name ) { map.addMapping({ source: original.source, original: { line: original.line, column: original.column, }, generated: { line: generated.line, column: generated.column, }, name: original.name, }); } lastOriginalSource = original.source; lastOriginalLine = original.line; lastOriginalColumn = original.column; lastOriginalName = original.name; sourceMappingActive = true; } else if (sourceMappingActive) { map.addMapping({ generated: { line: generated.line, column: generated.column, }, }); lastOriginalSource = null; sourceMappingActive = false; } for (let idx = 0, length = chunk.length; idx < length; idx++) { if (chunk.charCodeAt(idx) === NEWLINE_CODE) { generated.line++; generated.column = 0; // Mappings end at eol if (idx + 1 === length) { lastOriginalSource = null; sourceMappingActive = false; } else if (sourceMappingActive) { map.addMapping({ source: original.source, original: { line: original.line, column: original.column, }, generated: { line: generated.line, column: generated.column, }, name: original.name, }); } } else { generated.column++; } } }); this.walkSourceContents(function (sourceFile, sourceContent) { map.setSourceContent(sourceFile, sourceContent); }); return { code: generated.code, map } } } var SourceNode_1 = SourceNode; var sourceNode = { SourceNode: SourceNode_1 }; var require$$1 = sourceMapConsumer; var require$$2 = sourceNode; /* * Copyright 2009-2011 Mozilla Foundation and contributors * Licensed under the New BSD license. See LICENSE.txt or: * http://opensource.org/licenses/BSD-3-Clause */ require$$0.SourceMapGenerator; var SourceMapConsumer = require$$1.SourceMapConsumer; require$$2.SourceNode; const splitRE = /\r?\n/; const range = 2; function posToNumber(source, pos) { if (typeof pos === 'number') return pos; const lines = source.split(splitRE); const { line, column } = pos; let start = 0; for (let i = 0; i < line - 1; i++) { start += lines[i].length + 1; } return start + column; } function generateCodeFrame(source, start = 0, end) { start = posToNumber(source, start); end = end || start; const lines = source.split(splitRE); let count = 0; const res = []; for (let i = 0; i < lines.length; i++) { count += lines[i].length + 1; if (count >= start) { for (let j = i - range; j <= i + range || end > count; j++) { if (j < 0 || j >= lines.length) continue; const line = j + 1; res.push(`${line}${' '.repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`); const lineLength = lines[j].length; if (j === i) { // push underline const pad = start - (count - lineLength) + 1; const length = Math.max(1, end > count ? lineLength - pad : end - start); res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length)); } else if (j > i) { if (end > count) { const length = Math.max(Math.min(end - count, lineLength), 1); res.push(` | ` + '^'.repeat(length)); } count += lineLength + 1; } } break; } } return res.join('\n'); } const isWindows = os__default["default"].platform() === 'win32'; function normalizePath(id) { return isWindows ? id.replace(/\\/g, '/') : id; } function generateCodeFrameSourceMapConsumer(consumer, m, options = {}) { if (m.file) { const res = consumer.originalPositionFor({ line: m.line, column: m.column, }); if (res.source != null && res.line != null && res.column != null) { const code = consumer.sourceContentFor(res.source, true); if (code) { return { type: m.type, file: options.sourceRoot ? normalizePath(path__default["default"].relative(options.sourceRoot, res.source.replace('\\\\?\\', ''))) : res.source, line: res.line, column: res.column, message: m.message, code: generateCodeFrame(code, { line: res.line, column: res.column }), }; } } } } function initConsumer(filename) { if (fs__default["default"].existsSync(filename)) { return new SourceMapConsumer(fs__default["default"].readFileSync(filename, 'utf8')); } return Promise.resolve(undefined); } function generateCodeFrameWithSourceMapPath(filename, messages, options = {}) { if (typeof messages === 'string') { try { messages = JSON.parse(messages); } catch (e) { } } if (Array.isArray(messages) && messages.length) { return new Promise((resolve) => { initConsumer(filename).then((consumer) => { resolve(messages .map((m) => { if (m.file && consumer) { const message = generateCodeFrameSourceMapConsumer(consumer, m, options); if (message) { return message; } } if (!m.file) { m.file = ''; } return m; }) .filter(Boolean)); }); }); } return Promise.resolve([]); } const nixSlashes = (x) => x.replace(/\\/g, '/'); const sourcemapCatch = {}; function stacktracey(stacktrace, opts) { const stack = opts.preset.parseStacktrace(stacktrace); let parseStack = Promise.resolve(); stack.items.forEach((item, index) => { const fn = (item, index) => { const { line = 0, column = 0, file, fileName, fileRelative } = item; if (item.thirdParty) { return Promise.resolve(); } function _getSourceMapContent(file, fileName, fileRelative) { return opts.preset .getSourceMapContent(file, fileName, fileRelative) .then((content) => { if (content) { return getConsumer(content).then((consumer) => { return parseSourceMapContent(consumer, { line, column, }, !!opts.withSourceContent); }); } }); } try { return _getSourceMapContent(file, fileName, fileRelative).then((sourceMapContent) => { if (sourceMapContent) { const { source, sourcePath, sourceLine, sourceColumn, sourceContent, fileName = '', } = sourceMapContent; stack.items[index] = Object.assign({}, item, { file: source, line: sourceLine, column: sourceColumn, fileShort: sourcePath, fileRelative: source, fileName, thirdParty: isThirdParty(sourcePath), parsed: true, sourceContent, }); /** * 以 .js 结尾 * 包含 app-service.js 则需要再解析 两次 * 不包含 app-service.js 则无需再解析 一次 */ const curItem = stack.items[index]; if (stack.isMP && curItem.beforeParse.indexOf('app-service') !== -1) { return fn(curItem, index); } } }); } catch (error) { return Promise.resolve(); } }; parseStack = parseStack.then(() => { return new Promise((resolve, reject) => { setTimeout(() => { fn(item, index).then(resolve); }, 0); }); }); }); const _promise = new Promise((resolve, reject) => { parseStack .then(() => { const parseError = opts.preset.asTableStacktrace({ stack, maxColumnWidths: { callee: 999, file: 999, sourceLine: 999, }, stacktrace, }); resolve(parseError); }) .catch(() => { resolve(stacktrace); }); }); return _promise; } function isThirdParty(relativePath) { return relativePath.indexOf('@dcloudio') !== -1; } function getConsumer(content) { return new Promise((resolve, reject) => { try { if (SourceMapConsumer.with) { SourceMapConsumer.with(content, null, (consumer) => { resolve(consumer); }); } else { // @ts-ignore const consumer = SourceMapConsumer(content); resolve(consumer); } } catch (error) { reject(); } }); } function getSourceMapContent(sourcemapUrl) { try { return (sourcemapCatch[sourcemapUrl] || (sourcemapCatch[sourcemapUrl] = new Promise((resolve, reject) => { try { if (/^[http|https]+:/i.test(sourcemapUrl)) { uni.request({ url: sourcemapUrl, success: (res) => { if (res.statusCode === 200) { sourcemapCatch[sourcemapUrl] = res.data; resolve(sourcemapCatch[sourcemapUrl]); } else { resolve((sourcemapCatch[sourcemapUrl] = '')); } }, fail() { resolve((sourcemapCatch[sourcemapUrl] = '')); }, }); } else { sourcemapCatch[sourcemapUrl] = fs__default["default"].readFileSync(sourcemapUrl, 'utf-8'); resolve(sourcemapCatch[sourcemapUrl]); } } catch (error) { resolve(''); } }))); } catch (error) { return ''; } } function parseSourceMapContent(consumer, obj, withSourceContent) { // source -> 'uni-app:///node_modules/@sentry/browser/esm/helpers.js' const { source, line: sourceLine, column: sourceColumn, } = consumer.originalPositionFor(obj); if (source) { const sourcePathSplit = source.split('/'); const sourcePath = sourcePathSplit.slice(3).join('/'); const fileName = sourcePathSplit.pop(); return { source, sourcePath, sourceLine: sourceLine === null ? 0 : sourceLine, sourceColumn: sourceColumn === null ? 0 : sourceColumn, fileName, sourceContent: withSourceContent ? consumer.sourceContentFor(source) || '' : '', }; } } function joinItem(item) { if (typeof item === 'string') { return item; } const a = item[0]; const b = item[1] ? ` ${item[1]}` : ''; const c = item[2] ? ` ${item[2]}` : ''; return `${a}${b}${c}`; } function uniStracktraceyPreset(opts) { const { base, sourceRoot, splitThirdParty, uniPlatform } = opts; let stack; return { /** * * 微信特殊处理 * 微信解析步骤: * 1. //usr/app-service.js -> 'weixin/__APP__/app-service.map.map' * 2. //usr/pages/API/app-service.js -> 'weixin/pages/API/app-service.map.map' * 3. uni-list-item/uni-list-item.js -> ${base}/uni-list-item/uni-list-item.js.map */ parseSourceMapUrl(file, fileName, fileRelative) { // 组合 sourceMapUrl if (fileRelative.indexOf('(') !== -1) fileRelative = fileRelative.match(/\((.*)/)[1]; if (!base || !fileRelative) return ''; if (sourceRoot) { return `${fileRelative.replace(sourceRoot, base + '/')}.map`; } let baseAfter = ''; if (stack.isMP) { if (fileRelative.indexOf('app-service.js') !== -1) { baseAfter = (base.match(/\w$/) ? '/' : '') + '__WEIXIN__'; if (fileRelative === fileName) { baseAfter += '/__APP__'; } fileRelative = fileRelative.replace('.js', '.map'); } if (baseAfter && !!fileRelative.match(/^\w/)) baseAfter += '/'; } return `${base}${baseAfter}${fileRelative}.map`; }, getSourceMapContent(file, fileName, fileRelative) { if (stack.isMP && fileRelative.indexOf('.js') === -1) { return Promise.resolve(''); } const sourcemapUrl = this.parseSourceMapUrl(file, fileName, fileRelative); return Promise.resolve(getSourceMapContent(sourcemapUrl)); }, parseStacktrace(stacktrace) { stack = new StackTracey$1(stacktrace, uniPlatform); return stack; }, asTableStacktrace({ maxColumnWidths, stacktrace, stack }) { const errorName = stacktrace.split('\n')[0]; const lines = stack.asTable ? stack.asTable(maxColumnWidths ? { maxColumnWidths } : undefined) : { items: [], thirdPartyItems: [] }; if (lines.items.length || lines.thirdPartyItems.length) { const { items: stackLines, thirdPartyItems: stackThirdPartyLines } = lines; const userError = stack.itemsHeader .map((item) => { if (item === '%StacktraceyItem%') { const _stack = stackLines.shift(); return _stack ? joinItem(_stack) : ''; } return item; }) .filter(Boolean) .join('\n'); const thirdParty = stackThirdPartyLines.length ? stackThirdPartyLines.map(joinItem).join('\n') : ''; if (splitThirdParty) { return { userError, thirdParty, }; } return userError + '\n' + thirdParty; } else { if (splitThirdParty) { return { userError: errorName, thirdParty: '', }; } return errorName; } }, }; } function utsStracktraceyPreset(opts) { const { inputRoot, outputRoot, sourceMapRoot } = opts; let errStack = []; return { parseSourceMapUrl(file, fileName, fileRelative) { return path__default["default"].resolve(sourceMapRoot, path__default["default"].relative(outputRoot, file) + '.map'); }, getSourceMapContent(file, fileName, fileRelative) { // 根据 base,filename 组合 sourceMapUrl return Promise.resolve(getSourceMapContent(this.parseSourceMapUrl(file, fileName, fileRelative))); }, parseStacktrace(str) { const lines = (str || '').split('\n'); const entries = lines .map((line, index) => { line = line.trim(); const matches = line.match(/\s*(.+\.kt):([0-9]+):([0-9]+):\s+(.*)/); if (matches) { errStack.push('%StacktraceyItem%'); } else { errStack.push(line); return; } const fileName = matches[1].replace(/^.*(\\|\/|\:)/, ''); return { beforeParse: line, callee: '', index: false, native: false, file: nixSlashes(matches[1]), line: parseInt(matches[2]), column: parseInt(matches[3]), fileName, fileShort: line, errMsg: matches[4] || '', calleeShort: '', fileRelative: '', thirdParty: false, }; }) .filter((x) => x !== undefined); return { items: entries, itemsHeader: [], }; }, asTableStacktrace({ maxColumnWidths, stacktrace, stack }) { return errStack .map((item) => { if (item === '%StacktraceyItem%') { const _stack = stack.items.shift(); if (_stack) { return `at ${nixSlashes(path__default["default"].relative(inputRoot, _stack.file.replace('\\\\?\\', '')))}:${_stack.line}:${_stack.column} ${_stack.errMsg}`; } return ''; } return item; }) .join('\n'); }, }; } exports.SourceMapConsumer = SourceMapConsumer; exports.generateCodeFrame = generateCodeFrame; exports.generateCodeFrameSourceMapConsumer = generateCodeFrameSourceMapConsumer; exports.generateCodeFrameWithSourceMapPath = generateCodeFrameWithSourceMapPath; exports.stacktracey = stacktracey; exports.uniStracktraceyPreset = uniStracktraceyPreset; exports.utsStracktraceyPreset = utsStracktraceyPreset;