uni-stacktracey.cjs.js 94 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974
  1. 'use strict';
  2. var fs = require('fs');
  3. var path = require('path');
  4. var os = require('os');
  5. function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
  6. var fs__default = /*#__PURE__*/_interopDefault(fs);
  7. var path__default = /*#__PURE__*/_interopDefault(path);
  8. var os__default = /*#__PURE__*/_interopDefault(os);
  9. /* ------------------------------------------------------------------------ */
  10. const O = Object, isBrowser =
  11. /* eslint-disable */
  12. typeof window !== 'undefined' &&
  13. /* eslint-disable */
  14. window.window === window &&
  15. /* eslint-disable */
  16. window.navigator, nodeRequire = isBrowser ? null : module.require, // to prevent bundlers from expanding the require call
  17. lastOf = (x) => x[x.length - 1], nixSlashes$1 = (x) => x.replace(/\\/g, '/'), pathRoot = isBrowser ? window.location.href : nixSlashes$1(process.cwd()) + '/';
  18. /* ------------------------------------------------------------------------ */
  19. class StackTracey {
  20. constructor(input, uniPlatform, offset) {
  21. this.itemsHeader = [];
  22. this.isMP = false;
  23. const originalInput = input, isParseableSyntaxError = input && input instanceof SyntaxError && !isBrowser;
  24. /* new StackTracey () */
  25. if (!input) {
  26. input = new Error();
  27. offset = offset === undefined ? 1 : offset;
  28. }
  29. /* new StackTracey (Error) */
  30. if (input instanceof Error) {
  31. input = input.stack || '';
  32. }
  33. /* new StackTracey (string) */
  34. if (typeof input === 'string') {
  35. this.isMP = uniPlatform === 'mp-weixin';
  36. input = this.rawParse(input)
  37. .slice(offset)
  38. .map((x) => this.extractEntryMetadata(x));
  39. }
  40. /* new StackTracey (array) */
  41. if (Array.isArray(input)) {
  42. if (isParseableSyntaxError) {
  43. const rawLines = nodeRequire('util')
  44. .inspect(originalInput)
  45. .split('\n'), fileLine = rawLines[0].split(':'), line = fileLine.pop(), file = fileLine.join(':');
  46. if (file) {
  47. input.unshift({
  48. file: nixSlashes$1(file),
  49. line: line,
  50. column: (rawLines[2] || '').indexOf('^') + 1,
  51. sourceLine: rawLines[1],
  52. callee: '(syntax error)',
  53. syntaxError: true,
  54. });
  55. }
  56. }
  57. this.items = input;
  58. }
  59. else {
  60. this.items = [];
  61. }
  62. }
  63. extractEntryMetadata(e) {
  64. const decomposedPath = this.decomposePath(e.file || '');
  65. const fileRelative = decomposedPath[0];
  66. const externalDomain = decomposedPath[1];
  67. return O.assign(e, {
  68. calleeShort: e.calleeShort || lastOf((e.callee || '').split('.')),
  69. fileRelative: fileRelative,
  70. fileShort: this.shortenPath(fileRelative),
  71. fileName: lastOf((e.file || '').split('/')),
  72. thirdParty: this.isThirdParty(fileRelative, externalDomain) && !e.index,
  73. externalDomain: externalDomain,
  74. });
  75. }
  76. shortenPath(relativePath) {
  77. return relativePath
  78. .replace(/^node_modules\//, '')
  79. .replace(/^webpack\/bootstrap\//, '')
  80. .replace(/^__parcel_source_root\//, '');
  81. }
  82. decomposePath(fullPath) {
  83. let result = fullPath;
  84. if (isBrowser)
  85. result = result.replace(pathRoot, '');
  86. const externalDomainMatch = result.match(/^(http|https)\:\/\/?([^\/]+)\/{1,}(.*)/);
  87. const externalDomain = externalDomainMatch
  88. ? externalDomainMatch[2]
  89. : undefined;
  90. result = externalDomainMatch ? externalDomainMatch[3] : result;
  91. // if (!isBrowser) result = nodeRequire!('path').relative(pathRoot, result)
  92. return [
  93. nixSlashes$1(result).replace(/^.*\:\/\/?\/?/, ''),
  94. externalDomain,
  95. ];
  96. }
  97. isThirdParty(relativePath, externalDomain) {
  98. if (this.isMP) {
  99. if (typeof externalDomain === 'undefined')
  100. return false;
  101. return externalDomain !== 'usr';
  102. }
  103. return (
  104. // 由于 hello-uniapp web 端报错携带 hellouniapp.dcloud.net.cn
  105. // externalDomain ||
  106. relativePath[0] === '~' || // webpack-specific heuristic
  107. relativePath[0] === '/' || // external source
  108. relativePath.indexOf('@dcloudio') !== -1 ||
  109. relativePath.indexOf('weex-main-jsfm') !== -1 ||
  110. relativePath.indexOf('webpack/bootstrap') === 0);
  111. }
  112. rawParse(str) {
  113. const lines = (str || '').split('\n');
  114. const entries = lines.map((line, index) => {
  115. line = line.trim();
  116. let callee, fileLineColumn = [], native, planA, planB;
  117. if (line.indexOf('file:') !== -1) {
  118. line = line.replace(/file:\/\/(.*)www/, 'file://');
  119. }
  120. if ((planA = line.match(/at (.+) \(eval at .+ \((.+)\), .+\)/)) || // eval calls
  121. (planA = line.match(/at (.+) \((.+)\)/)) ||
  122. (line.slice(0, 3) !== 'at ' && (planA = line.match(/(.*)@(.*)/)))) {
  123. this.itemsHeader.push('%StacktraceyItem%');
  124. callee = planA[1];
  125. native = planA[2] === 'native';
  126. fileLineColumn = (planA[2].match(/(.*):(\d+):(\d+)/) ||
  127. planA[2].match(/(.*):(\d+)/) ||
  128. planA[2].match(/\[(.*)\]/) ||
  129. []).slice(1);
  130. }
  131. else if ((planB = line.match(/^(at\s*)*(.*)\s+(.+):(\d+):(\d+)/))) {
  132. this.itemsHeader.push('%StacktraceyItem%');
  133. callee = planB[2].trim();
  134. fileLineColumn = planB.slice(3);
  135. }
  136. else {
  137. this.itemsHeader.push(line);
  138. return undefined;
  139. }
  140. /* Detect things like Array.reduce
  141. TODO: detect more built-in types */
  142. if (callee && !fileLineColumn[0]) {
  143. const type = callee.split('.')[0];
  144. if (type === 'Array') {
  145. native = true;
  146. }
  147. }
  148. return {
  149. beforeParse: line,
  150. callee: callee || '',
  151. /* eslint-disable */
  152. index: isBrowser && fileLineColumn[0] === window.location.href,
  153. native: native || false,
  154. file: nixSlashes$1(fileLineColumn[0] || ''),
  155. line: parseInt(fileLineColumn[1] || '', 10) || undefined,
  156. column: parseInt(fileLineColumn[2] || '', 10) || undefined,
  157. };
  158. });
  159. return entries.filter((x) => x !== undefined);
  160. }
  161. maxColumnWidths() {
  162. return {
  163. callee: 30,
  164. file: 60,
  165. sourceLine: 80,
  166. };
  167. }
  168. asTable(opts) {
  169. const maxColumnWidths = (opts && opts.maxColumnWidths) || this.maxColumnWidths();
  170. const trimmed = this
  171. .filter((e) => !e.thirdParty)
  172. .map((e) => parseItem(e, maxColumnWidths, this.isMP));
  173. const trimmedThirdParty = this
  174. .filter((e) => e.thirdParty)
  175. .map((e) => parseItem(e, maxColumnWidths, this.isMP));
  176. return {
  177. items: trimmed.items,
  178. thirdPartyItems: trimmedThirdParty.items,
  179. };
  180. }
  181. }
  182. const trimEnd = (s, n) => s && (s.length > n ? s.slice(0, n - 1) + '…' : s);
  183. const trimStart = (s, n) => s && (s.length > n ? '…' + s.slice(-(n - 1)) : s);
  184. function parseItem(e, maxColumnWidths, isMP) {
  185. if (!e.parsed) {
  186. return e.beforeParse;
  187. }
  188. const filePath = (isMP ? e.file && e.file : e.fileShort && e.fileShort) +
  189. `${e.line ? ':' + e.line : ''}` +
  190. `${e.column ? ':' + e.column : ''}`;
  191. return [
  192. 'at ' + trimEnd(isMP ? e.callee : e.calleeShort, maxColumnWidths.callee),
  193. trimStart(filePath || '', maxColumnWidths.file),
  194. trimEnd((e.sourceLine || '').trim() || '', maxColumnWidths.sourceLine),
  195. ];
  196. }
  197. ['map', 'filter', 'slice', 'concat'].forEach((method) => {
  198. StackTracey.prototype[method] = function ( /*...args */) {
  199. // no support for ...args in Node v4 :(
  200. return new StackTracey(this.items[method].apply(this.items, arguments));
  201. };
  202. });
  203. /* ------------------------------------------------------------------------ */
  204. var StackTracey$1 = StackTracey;
  205. var util$1 = {};
  206. /* -*- Mode: js; js-indent-level: 2; -*- */
  207. (function (exports) {
  208. /*
  209. * Copyright 2011 Mozilla Foundation and contributors
  210. * Licensed under the New BSD license. See LICENSE or:
  211. * http://opensource.org/licenses/BSD-3-Clause
  212. */
  213. /**
  214. * This is a helper function for getting values from parameter/options
  215. * objects.
  216. *
  217. * @param args The object we are extracting values from
  218. * @param name The name of the property we are getting.
  219. * @param defaultValue An optional value to return if the property is missing
  220. * from the object. If this is not specified and the property is missing, an
  221. * error will be thrown.
  222. */
  223. function getArg(aArgs, aName, aDefaultValue) {
  224. if (aName in aArgs) {
  225. return aArgs[aName]
  226. } else if (arguments.length === 3) {
  227. return aDefaultValue
  228. }
  229. throw new Error('"' + aName + '" is a required argument.')
  230. }
  231. exports.getArg = getArg;
  232. const urlRegexp =
  233. /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
  234. const dataUrlRegexp = /^data:.+\,.+$/;
  235. function urlParse(aUrl) {
  236. const match = aUrl.match(urlRegexp);
  237. if (!match) {
  238. return null
  239. }
  240. return {
  241. scheme: match[1],
  242. auth: match[2],
  243. host: match[3],
  244. port: match[4],
  245. path: match[5],
  246. }
  247. }
  248. exports.urlParse = urlParse;
  249. function urlGenerate(aParsedUrl) {
  250. let url = '';
  251. if (aParsedUrl.scheme) {
  252. url += aParsedUrl.scheme + ':';
  253. }
  254. url += '//';
  255. if (aParsedUrl.auth) {
  256. url += aParsedUrl.auth + '@';
  257. }
  258. if (aParsedUrl.host) {
  259. url += aParsedUrl.host;
  260. }
  261. if (aParsedUrl.port) {
  262. url += ':' + aParsedUrl.port;
  263. }
  264. if (aParsedUrl.path) {
  265. url += aParsedUrl.path;
  266. }
  267. return url
  268. }
  269. exports.urlGenerate = urlGenerate;
  270. const MAX_CACHED_INPUTS = 32;
  271. /**
  272. * Takes some function `f(input) -> result` and returns a memoized version of
  273. * `f`.
  274. *
  275. * We keep at most `MAX_CACHED_INPUTS` memoized results of `f` alive. The
  276. * memoization is a dumb-simple, linear least-recently-used cache.
  277. */
  278. function lruMemoize(f) {
  279. const cache = [];
  280. return function (input) {
  281. for (let i = 0; i < cache.length; i++) {
  282. if (cache[i].input === input) {
  283. const temp = cache[0];
  284. cache[0] = cache[i];
  285. cache[i] = temp;
  286. return cache[0].result
  287. }
  288. }
  289. const result = f(input);
  290. cache.unshift({
  291. input,
  292. result,
  293. });
  294. if (cache.length > MAX_CACHED_INPUTS) {
  295. cache.pop();
  296. }
  297. return result
  298. }
  299. }
  300. /**
  301. * Normalizes a path, or the path portion of a URL:
  302. *
  303. * - Replaces consecutive slashes with one slash.
  304. * - Removes unnecessary '.' parts.
  305. * - Removes unnecessary '<dir>/..' parts.
  306. *
  307. * Based on code in the Node.js 'path' core module.
  308. *
  309. * @param aPath The path or url to normalize.
  310. */
  311. const normalize = lruMemoize(function normalize(aPath) {
  312. let path = aPath;
  313. const url = urlParse(aPath);
  314. if (url) {
  315. if (!url.path) {
  316. return aPath
  317. }
  318. path = url.path;
  319. }
  320. const isAbsolute = exports.isAbsolute(path);
  321. // Split the path into parts between `/` characters. This is much faster than
  322. // using `.split(/\/+/g)`.
  323. const parts = [];
  324. let start = 0;
  325. let i = 0;
  326. while (true) {
  327. start = i;
  328. i = path.indexOf('/', start);
  329. if (i === -1) {
  330. parts.push(path.slice(start));
  331. break
  332. } else {
  333. parts.push(path.slice(start, i));
  334. while (i < path.length && path[i] === '/') {
  335. i++;
  336. }
  337. }
  338. }
  339. let up = 0;
  340. for (i = parts.length - 1; i >= 0; i--) {
  341. const part = parts[i];
  342. if (part === '.') {
  343. parts.splice(i, 1);
  344. } else if (part === '..') {
  345. up++;
  346. } else if (up > 0) {
  347. if (part === '') {
  348. // The first part is blank if the path is absolute. Trying to go
  349. // above the root is a no-op. Therefore we can remove all '..' parts
  350. // directly after the root.
  351. parts.splice(i + 1, up);
  352. up = 0;
  353. } else {
  354. parts.splice(i, 2);
  355. up--;
  356. }
  357. }
  358. }
  359. path = parts.join('/');
  360. if (path === '') {
  361. path = isAbsolute ? '/' : '.';
  362. }
  363. if (url) {
  364. url.path = path;
  365. return urlGenerate(url)
  366. }
  367. return path
  368. });
  369. exports.normalize = normalize;
  370. /**
  371. * Joins two paths/URLs.
  372. *
  373. * @param aRoot The root path or URL.
  374. * @param aPath The path or URL to be joined with the root.
  375. *
  376. * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a
  377. * scheme-relative URL: Then the scheme of aRoot, if any, is prepended
  378. * first.
  379. * - Otherwise aPath is a path. If aRoot is a URL, then its path portion
  380. * is updated with the result and aRoot is returned. Otherwise the result
  381. * is returned.
  382. * - If aPath is absolute, the result is aPath.
  383. * - Otherwise the two paths are joined with a slash.
  384. * - Joining for example 'http://' and 'www.example.com' is also supported.
  385. */
  386. function join(aRoot, aPath) {
  387. if (aRoot === '') {
  388. aRoot = '.';
  389. }
  390. if (aPath === '') {
  391. aPath = '.';
  392. }
  393. const aPathUrl = urlParse(aPath);
  394. const aRootUrl = urlParse(aRoot);
  395. if (aRootUrl) {
  396. aRoot = aRootUrl.path || '/';
  397. }
  398. // `join(foo, '//www.example.org')`
  399. if (aPathUrl && !aPathUrl.scheme) {
  400. if (aRootUrl) {
  401. aPathUrl.scheme = aRootUrl.scheme;
  402. }
  403. return urlGenerate(aPathUrl)
  404. }
  405. if (aPathUrl || aPath.match(dataUrlRegexp)) {
  406. return aPath
  407. }
  408. // `join('http://', 'www.example.com')`
  409. if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {
  410. aRootUrl.host = aPath;
  411. return urlGenerate(aRootUrl)
  412. }
  413. const joined =
  414. aPath.charAt(0) === '/'
  415. ? aPath
  416. : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath);
  417. if (aRootUrl) {
  418. aRootUrl.path = joined;
  419. return urlGenerate(aRootUrl)
  420. }
  421. return joined
  422. }
  423. exports.join = join;
  424. exports.isAbsolute = function (aPath) {
  425. return aPath.charAt(0) === '/' || urlRegexp.test(aPath)
  426. };
  427. /**
  428. * Make a path relative to a URL or another path.
  429. *
  430. * @param aRoot The root path or URL.
  431. * @param aPath The path or URL to be made relative to aRoot.
  432. */
  433. function relative(aRoot, aPath) {
  434. if (aRoot === '') {
  435. aRoot = '.';
  436. }
  437. aRoot = aRoot.replace(/\/$/, '');
  438. // It is possible for the path to be above the root. In this case, simply
  439. // checking whether the root is a prefix of the path won't work. Instead, we
  440. // need to remove components from the root one by one, until either we find
  441. // a prefix that fits, or we run out of components to remove.
  442. let level = 0;
  443. while (aPath.indexOf(aRoot + '/') !== 0) {
  444. const index = aRoot.lastIndexOf('/');
  445. if (index < 0) {
  446. return aPath
  447. }
  448. // If the only part of the root that is left is the scheme (i.e. http://,
  449. // file:///, etc.), one or more slashes (/), or simply nothing at all, we
  450. // have exhausted all components, so the path is not relative to the root.
  451. aRoot = aRoot.slice(0, index);
  452. if (aRoot.match(/^([^\/]+:\/)?\/*$/)) {
  453. return aPath
  454. }
  455. ++level;
  456. }
  457. // Make sure we add a "../" for each component we removed from the root.
  458. return Array(level + 1).join('../') + aPath.substr(aRoot.length + 1)
  459. }
  460. exports.relative = relative;
  461. const supportsNullProto = (function () {
  462. const obj = Object.create(null);
  463. return !('__proto__' in obj)
  464. })();
  465. function identity(s) {
  466. return s
  467. }
  468. /**
  469. * Because behavior goes wacky when you set `__proto__` on objects, we
  470. * have to prefix all the strings in our set with an arbitrary character.
  471. *
  472. * See https://github.com/mozilla/source-map/pull/31 and
  473. * https://github.com/mozilla/source-map/issues/30
  474. *
  475. * @param String aStr
  476. */
  477. function toSetString(aStr) {
  478. if (isProtoString(aStr)) {
  479. return '$' + aStr
  480. }
  481. return aStr
  482. }
  483. exports.toSetString = supportsNullProto ? identity : toSetString;
  484. function fromSetString(aStr) {
  485. if (isProtoString(aStr)) {
  486. return aStr.slice(1)
  487. }
  488. return aStr
  489. }
  490. exports.fromSetString = supportsNullProto ? identity : fromSetString;
  491. function isProtoString(s) {
  492. if (!s) {
  493. return false
  494. }
  495. const length = s.length;
  496. if (length < 9 /* "__proto__".length */) {
  497. return false
  498. }
  499. /* eslint-disable no-multi-spaces */
  500. if (
  501. s.charCodeAt(length - 1) !== 95 /* '_' */ ||
  502. s.charCodeAt(length - 2) !== 95 /* '_' */ ||
  503. s.charCodeAt(length - 3) !== 111 /* 'o' */ ||
  504. s.charCodeAt(length - 4) !== 116 /* 't' */ ||
  505. s.charCodeAt(length - 5) !== 111 /* 'o' */ ||
  506. s.charCodeAt(length - 6) !== 114 /* 'r' */ ||
  507. s.charCodeAt(length - 7) !== 112 /* 'p' */ ||
  508. s.charCodeAt(length - 8) !== 95 /* '_' */ ||
  509. s.charCodeAt(length - 9) !== 95 /* '_' */
  510. ) {
  511. return false
  512. }
  513. /* eslint-enable no-multi-spaces */
  514. for (let i = length - 10; i >= 0; i--) {
  515. if (s.charCodeAt(i) !== 36 /* '$' */) {
  516. return false
  517. }
  518. }
  519. return true
  520. }
  521. /**
  522. * Comparator between two mappings where the original positions are compared.
  523. *
  524. * Optionally pass in `true` as `onlyCompareGenerated` to consider two
  525. * mappings with the same original source/line/column, but different generated
  526. * line and column the same. Useful when searching for a mapping with a
  527. * stubbed out mapping.
  528. */
  529. function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
  530. let cmp = strcmp(mappingA.source, mappingB.source);
  531. if (cmp !== 0) {
  532. return cmp
  533. }
  534. cmp = mappingA.originalLine - mappingB.originalLine;
  535. if (cmp !== 0) {
  536. return cmp
  537. }
  538. cmp = mappingA.originalColumn - mappingB.originalColumn;
  539. if (cmp !== 0 || onlyCompareOriginal) {
  540. return cmp
  541. }
  542. cmp = mappingA.generatedColumn - mappingB.generatedColumn;
  543. if (cmp !== 0) {
  544. return cmp
  545. }
  546. cmp = mappingA.generatedLine - mappingB.generatedLine;
  547. if (cmp !== 0) {
  548. return cmp
  549. }
  550. return strcmp(mappingA.name, mappingB.name)
  551. }
  552. exports.compareByOriginalPositions = compareByOriginalPositions;
  553. /**
  554. * Comparator between two mappings with deflated source and name indices where
  555. * the generated positions are compared.
  556. *
  557. * Optionally pass in `true` as `onlyCompareGenerated` to consider two
  558. * mappings with the same generated line and column, but different
  559. * source/name/original line and column the same. Useful when searching for a
  560. * mapping with a stubbed out mapping.
  561. */
  562. function compareByGeneratedPositionsDeflated(
  563. mappingA,
  564. mappingB,
  565. onlyCompareGenerated
  566. ) {
  567. let cmp = mappingA.generatedLine - mappingB.generatedLine;
  568. if (cmp !== 0) {
  569. return cmp
  570. }
  571. cmp = mappingA.generatedColumn - mappingB.generatedColumn;
  572. if (cmp !== 0 || onlyCompareGenerated) {
  573. return cmp
  574. }
  575. cmp = strcmp(mappingA.source, mappingB.source);
  576. if (cmp !== 0) {
  577. return cmp
  578. }
  579. cmp = mappingA.originalLine - mappingB.originalLine;
  580. if (cmp !== 0) {
  581. return cmp
  582. }
  583. cmp = mappingA.originalColumn - mappingB.originalColumn;
  584. if (cmp !== 0) {
  585. return cmp
  586. }
  587. return strcmp(mappingA.name, mappingB.name)
  588. }
  589. exports.compareByGeneratedPositionsDeflated =
  590. compareByGeneratedPositionsDeflated;
  591. function strcmp(aStr1, aStr2) {
  592. if (aStr1 === aStr2) {
  593. return 0
  594. }
  595. if (aStr1 === null) {
  596. return 1 // aStr2 !== null
  597. }
  598. if (aStr2 === null) {
  599. return -1 // aStr1 !== null
  600. }
  601. if (aStr1 > aStr2) {
  602. return 1
  603. }
  604. return -1
  605. }
  606. /**
  607. * Comparator between two mappings with inflated source and name strings where
  608. * the generated positions are compared.
  609. */
  610. function compareByGeneratedPositionsInflated(mappingA, mappingB) {
  611. let cmp = mappingA.generatedLine - mappingB.generatedLine;
  612. if (cmp !== 0) {
  613. return cmp
  614. }
  615. cmp = mappingA.generatedColumn - mappingB.generatedColumn;
  616. if (cmp !== 0) {
  617. return cmp
  618. }
  619. cmp = strcmp(mappingA.source, mappingB.source);
  620. if (cmp !== 0) {
  621. return cmp
  622. }
  623. cmp = mappingA.originalLine - mappingB.originalLine;
  624. if (cmp !== 0) {
  625. return cmp
  626. }
  627. cmp = mappingA.originalColumn - mappingB.originalColumn;
  628. if (cmp !== 0) {
  629. return cmp
  630. }
  631. return strcmp(mappingA.name, mappingB.name)
  632. }
  633. exports.compareByGeneratedPositionsInflated =
  634. compareByGeneratedPositionsInflated;
  635. /**
  636. * Strip any JSON XSSI avoidance prefix from the string (as documented
  637. * in the source maps specification), and then parse the string as
  638. * JSON.
  639. */
  640. function parseSourceMapInput(str) {
  641. return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ''))
  642. }
  643. exports.parseSourceMapInput = parseSourceMapInput;
  644. /**
  645. * Compute the URL of a source given the the source root, the source's
  646. * URL, and the source map's URL.
  647. */
  648. function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
  649. sourceURL = sourceURL || '';
  650. if (sourceRoot) {
  651. // This follows what Chrome does.
  652. if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {
  653. sourceRoot += '/';
  654. }
  655. // The spec says:
  656. // Line 4: An optional source root, useful for relocating source
  657. // files on a server or removing repeated values in the
  658. // “sources” entry. This value is prepended to the individual
  659. // entries in the “source” field.
  660. sourceURL = sourceRoot + sourceURL;
  661. }
  662. // Historically, SourceMapConsumer did not take the sourceMapURL as
  663. // a parameter. This mode is still somewhat supported, which is why
  664. // this code block is conditional. However, it's preferable to pass
  665. // the source map URL to SourceMapConsumer, so that this function
  666. // can implement the source URL resolution algorithm as outlined in
  667. // the spec. This block is basically the equivalent of:
  668. // new URL(sourceURL, sourceMapURL).toString()
  669. // ... except it avoids using URL, which wasn't available in the
  670. // older releases of node still supported by this library.
  671. //
  672. // The spec says:
  673. // If the sources are not absolute URLs after prepending of the
  674. // “sourceRoot”, the sources are resolved relative to the
  675. // SourceMap (like resolving script src in a html document).
  676. if (sourceMapURL) {
  677. const parsed = urlParse(sourceMapURL);
  678. if (!parsed) {
  679. throw new Error('sourceMapURL could not be parsed')
  680. }
  681. if (parsed.path) {
  682. // Strip the last path component, but keep the "/".
  683. const index = parsed.path.lastIndexOf('/');
  684. if (index >= 0) {
  685. parsed.path = parsed.path.substring(0, index + 1);
  686. }
  687. }
  688. sourceURL = join(urlGenerate(parsed), sourceURL);
  689. }
  690. return normalize(sourceURL)
  691. }
  692. exports.computeSourceURL = computeSourceURL;
  693. } (util$1));
  694. var arraySet = {};
  695. /* -*- Mode: js; js-indent-level: 2; -*- */
  696. /*
  697. * Copyright 2011 Mozilla Foundation and contributors
  698. * Licensed under the New BSD license. See LICENSE or:
  699. * http://opensource.org/licenses/BSD-3-Clause
  700. */
  701. /**
  702. * A data structure which is a combination of an array and a set. Adding a new
  703. * member is O(1), testing for membership is O(1), and finding the index of an
  704. * element is O(1). Removing elements from the set is not supported. Only
  705. * strings are supported for membership.
  706. */
  707. let ArraySet$1 = class ArraySet {
  708. constructor() {
  709. this._array = [];
  710. this._set = new Map();
  711. }
  712. /**
  713. * Static method for creating ArraySet instances from an existing array.
  714. */
  715. static fromArray(aArray, aAllowDuplicates) {
  716. const set = new ArraySet();
  717. for (let i = 0, len = aArray.length; i < len; i++) {
  718. set.add(aArray[i], aAllowDuplicates);
  719. }
  720. return set
  721. }
  722. /**
  723. * Return how many unique items are in this ArraySet. If duplicates have been
  724. * added, than those do not count towards the size.
  725. *
  726. * @returns Number
  727. */
  728. size() {
  729. return this._set.size
  730. }
  731. /**
  732. * Add the given string to this set.
  733. *
  734. * @param String aStr
  735. */
  736. add(aStr, aAllowDuplicates) {
  737. const isDuplicate = this.has(aStr);
  738. const idx = this._array.length;
  739. if (!isDuplicate || aAllowDuplicates) {
  740. this._array.push(aStr);
  741. }
  742. if (!isDuplicate) {
  743. this._set.set(aStr, idx);
  744. }
  745. }
  746. /**
  747. * Is the given string a member of this set?
  748. *
  749. * @param String aStr
  750. */
  751. has(aStr) {
  752. return this._set.has(aStr)
  753. }
  754. /**
  755. * What is the index of the given string in the array?
  756. *
  757. * @param String aStr
  758. */
  759. indexOf(aStr) {
  760. const idx = this._set.get(aStr);
  761. if (idx >= 0) {
  762. return idx
  763. }
  764. throw new Error('"' + aStr + '" is not in the set.')
  765. }
  766. /**
  767. * What is the element at the given index?
  768. *
  769. * @param Number aIdx
  770. */
  771. at(aIdx) {
  772. if (aIdx >= 0 && aIdx < this._array.length) {
  773. return this._array[aIdx]
  774. }
  775. throw new Error('No element indexed by ' + aIdx)
  776. }
  777. /**
  778. * Returns the array representation of this set (which has the proper indices
  779. * indicated by indexOf). Note that this is a copy of the internal array used
  780. * for storing the members so that no one can mess with internal state.
  781. */
  782. toArray() {
  783. return this._array.slice()
  784. }
  785. };
  786. arraySet.ArraySet = ArraySet$1;
  787. var sourceMapConsumer = {};
  788. var binarySearch$1 = {};
  789. /* -*- Mode: js; js-indent-level: 2; -*- */
  790. (function (exports) {
  791. /*
  792. * Copyright 2011 Mozilla Foundation and contributors
  793. * Licensed under the New BSD license. See LICENSE or:
  794. * http://opensource.org/licenses/BSD-3-Clause
  795. */
  796. exports.GREATEST_LOWER_BOUND = 1;
  797. exports.LEAST_UPPER_BOUND = 2;
  798. /**
  799. * Recursive implementation of binary search.
  800. *
  801. * @param aLow Indices here and lower do not contain the needle.
  802. * @param aHigh Indices here and higher do not contain the needle.
  803. * @param aNeedle The element being searched for.
  804. * @param aHaystack The non-empty array being searched.
  805. * @param aCompare Function which takes two elements and returns -1, 0, or 1.
  806. * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or
  807. * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the
  808. * closest element that is smaller than or greater than the one we are
  809. * searching for, respectively, if the exact element cannot be found.
  810. */
  811. function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) {
  812. // This function terminates when one of the following is true:
  813. //
  814. // 1. We find the exact element we are looking for.
  815. //
  816. // 2. We did not find the exact element, but we can return the index of
  817. // the next-closest element.
  818. //
  819. // 3. We did not find the exact element, and there is no next-closest
  820. // element than the one we are searching for, so we return -1.
  821. const mid = Math.floor((aHigh - aLow) / 2) + aLow;
  822. const cmp = aCompare(aNeedle, aHaystack[mid], true);
  823. if (cmp === 0) {
  824. // Found the element we are looking for.
  825. return mid
  826. } else if (cmp > 0) {
  827. // Our needle is greater than aHaystack[mid].
  828. if (aHigh - mid > 1) {
  829. // The element is in the upper half.
  830. return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias)
  831. }
  832. // The exact needle element was not found in this haystack. Determine if
  833. // we are in termination case (3) or (2) and return the appropriate thing.
  834. if (aBias == exports.LEAST_UPPER_BOUND) {
  835. return aHigh < aHaystack.length ? aHigh : -1
  836. }
  837. return mid
  838. }
  839. // Our needle is less than aHaystack[mid].
  840. if (mid - aLow > 1) {
  841. // The element is in the lower half.
  842. return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias)
  843. }
  844. // we are in termination case (3) or (2) and return the appropriate thing.
  845. if (aBias == exports.LEAST_UPPER_BOUND) {
  846. return mid
  847. }
  848. return aLow < 0 ? -1 : aLow
  849. }
  850. /**
  851. * This is an implementation of binary search which will always try and return
  852. * the index of the closest element if there is no exact hit. This is because
  853. * mappings between original and generated line/col pairs are single points,
  854. * and there is an implicit region between each of them, so a miss just means
  855. * that you aren't on the very start of a region.
  856. *
  857. * @param aNeedle The element you are looking for.
  858. * @param aHaystack The array that is being searched.
  859. * @param aCompare A function which takes the needle and an element in the
  860. * array and returns -1, 0, or 1 depending on whether the needle is less
  861. * than, equal to, or greater than the element, respectively.
  862. * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or
  863. * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the
  864. * closest element that is smaller than or greater than the one we are
  865. * searching for, respectively, if the exact element cannot be found.
  866. * Defaults to 'binarySearch.GREATEST_LOWER_BOUND'.
  867. */
  868. exports.search = function search(aNeedle, aHaystack, aCompare, aBias) {
  869. if (aHaystack.length === 0) {
  870. return -1
  871. }
  872. let index = recursiveSearch(
  873. -1,
  874. aHaystack.length,
  875. aNeedle,
  876. aHaystack,
  877. aCompare,
  878. aBias || exports.GREATEST_LOWER_BOUND
  879. );
  880. if (index < 0) {
  881. return -1
  882. }
  883. // We have found either the exact element, or the next-closest element than
  884. // the one we are searching for. However, there may be more than one such
  885. // element. Make sure we always return the smallest of these.
  886. while (index - 1 >= 0) {
  887. if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) {
  888. break
  889. }
  890. --index;
  891. }
  892. return index
  893. };
  894. } (binarySearch$1));
  895. var readWasmExports = {};
  896. var readWasm$2 = {
  897. get exports(){ return readWasmExports; },
  898. set exports(v){ readWasmExports = v; },
  899. };
  900. /* 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 */
  901. {
  902. // Node version of reading a wasm file into an array buffer.
  903. const fs = fs__default.default;
  904. const path = path__default.default;
  905. readWasm$2.exports = function readWasm() {
  906. return new Promise((resolve, reject) => {
  907. const wasmPath = path.join(
  908. __dirname,
  909. '../lib/source-map/lib',
  910. 'mappings.wasm'
  911. );
  912. fs.readFile(wasmPath, null, (error, data) => {
  913. if (error) {
  914. reject(error);
  915. return
  916. }
  917. resolve(data.buffer);
  918. });
  919. })
  920. };
  921. readWasmExports.initialize = (_) => {
  922. console.debug(
  923. 'SourceMapConsumer.initialize is a no-op when running in node.js'
  924. );
  925. };
  926. }
  927. const readWasm$1 = readWasmExports;
  928. /**
  929. * Provide the JIT with a nice shape / hidden class.
  930. */
  931. function Mapping() {
  932. this.generatedLine = 0;
  933. this.generatedColumn = 0;
  934. this.lastGeneratedColumn = null;
  935. this.source = null;
  936. this.originalLine = null;
  937. this.originalColumn = null;
  938. this.name = null;
  939. }
  940. let cachedWasm = null;
  941. var wasm$1 = function wasm() {
  942. if (cachedWasm) {
  943. return cachedWasm
  944. }
  945. const callbackStack = [];
  946. cachedWasm = readWasm$1()
  947. .then((buffer) => {
  948. return WebAssembly.instantiate(buffer, {
  949. env: {
  950. mapping_callback(
  951. generatedLine,
  952. generatedColumn,
  953. hasLastGeneratedColumn,
  954. lastGeneratedColumn,
  955. hasOriginal,
  956. source,
  957. originalLine,
  958. originalColumn,
  959. hasName,
  960. name
  961. ) {
  962. const mapping = new Mapping();
  963. // JS uses 1-based line numbers, wasm uses 0-based.
  964. mapping.generatedLine = generatedLine + 1;
  965. mapping.generatedColumn = generatedColumn;
  966. if (hasLastGeneratedColumn) {
  967. // JS uses inclusive last generated column, wasm uses exclusive.
  968. mapping.lastGeneratedColumn = lastGeneratedColumn - 1;
  969. }
  970. if (hasOriginal) {
  971. mapping.source = source;
  972. // JS uses 1-based line numbers, wasm uses 0-based.
  973. mapping.originalLine = originalLine + 1;
  974. mapping.originalColumn = originalColumn;
  975. if (hasName) {
  976. mapping.name = name;
  977. }
  978. }
  979. callbackStack[callbackStack.length - 1](mapping);
  980. },
  981. start_all_generated_locations_for() {
  982. console.time('all_generated_locations_for');
  983. },
  984. end_all_generated_locations_for() {
  985. console.timeEnd('all_generated_locations_for');
  986. },
  987. start_compute_column_spans() {
  988. console.time('compute_column_spans');
  989. },
  990. end_compute_column_spans() {
  991. console.timeEnd('compute_column_spans');
  992. },
  993. start_generated_location_for() {
  994. console.time('generated_location_for');
  995. },
  996. end_generated_location_for() {
  997. console.timeEnd('generated_location_for');
  998. },
  999. start_original_location_for() {
  1000. console.time('original_location_for');
  1001. },
  1002. end_original_location_for() {
  1003. console.timeEnd('original_location_for');
  1004. },
  1005. start_parse_mappings() {
  1006. console.time('parse_mappings');
  1007. },
  1008. end_parse_mappings() {
  1009. console.timeEnd('parse_mappings');
  1010. },
  1011. start_sort_by_generated_location() {
  1012. console.time('sort_by_generated_location');
  1013. },
  1014. end_sort_by_generated_location() {
  1015. console.timeEnd('sort_by_generated_location');
  1016. },
  1017. start_sort_by_original_location() {
  1018. console.time('sort_by_original_location');
  1019. },
  1020. end_sort_by_original_location() {
  1021. console.timeEnd('sort_by_original_location');
  1022. },
  1023. },
  1024. })
  1025. })
  1026. .then((Wasm) => {
  1027. return {
  1028. exports: Wasm.instance.exports,
  1029. withMappingCallback: (mappingCallback, f) => {
  1030. callbackStack.push(mappingCallback);
  1031. try {
  1032. f();
  1033. } finally {
  1034. callbackStack.pop();
  1035. }
  1036. },
  1037. }
  1038. })
  1039. .then(null, (e) => {
  1040. cachedWasm = null;
  1041. throw e
  1042. });
  1043. return cachedWasm
  1044. };
  1045. /* -*- Mode: js; js-indent-level: 2; -*- */
  1046. /*
  1047. * Copyright 2011 Mozilla Foundation and contributors
  1048. * Licensed under the New BSD license. See LICENSE or:
  1049. * http://opensource.org/licenses/BSD-3-Clause
  1050. */
  1051. const util = util$1;
  1052. const binarySearch = binarySearch$1;
  1053. const ArraySet = arraySet.ArraySet;
  1054. const readWasm = readWasmExports;
  1055. const wasm = wasm$1;
  1056. const INTERNAL = Symbol('smcInternal');
  1057. let SourceMapConsumer$1 = class SourceMapConsumer {
  1058. constructor(aSourceMap, aSourceMapURL) {
  1059. // If the constructor was called by super(), just return Promise<this>.
  1060. // Yes, this is a hack to retain the pre-existing API of the base-class
  1061. // constructor also being an async factory function.
  1062. if (aSourceMap == INTERNAL) {
  1063. return Promise.resolve(this)
  1064. }
  1065. return _factory(aSourceMap, aSourceMapURL)
  1066. }
  1067. static initialize(opts) {
  1068. readWasm.initialize(opts['lib/mappings.wasm']);
  1069. }
  1070. static fromSourceMap(aSourceMap, aSourceMapURL) {
  1071. return _factoryBSM(aSourceMap, aSourceMapURL)
  1072. }
  1073. /**
  1074. * Construct a new `SourceMapConsumer` from `rawSourceMap` and `sourceMapUrl`
  1075. * (see the `SourceMapConsumer` constructor for details. Then, invoke the `async
  1076. * function f(SourceMapConsumer) -> T` with the newly constructed consumer, wait
  1077. * for `f` to complete, call `destroy` on the consumer, and return `f`'s return
  1078. * value.
  1079. *
  1080. * You must not use the consumer after `f` completes!
  1081. *
  1082. * By using `with`, you do not have to remember to manually call `destroy` on
  1083. * the consumer, since it will be called automatically once `f` completes.
  1084. *
  1085. * ```js
  1086. * const xSquared = await SourceMapConsumer.with(
  1087. * myRawSourceMap,
  1088. * null,
  1089. * async function (consumer) {
  1090. * // Use `consumer` inside here and don't worry about remembering
  1091. * // to call `destroy`.
  1092. *
  1093. * const x = await whatever(consumer);
  1094. * return x * x;
  1095. * }
  1096. * );
  1097. *
  1098. * // You may not use that `consumer` anymore out here; it has
  1099. * // been destroyed. But you can use `xSquared`.
  1100. * console.log(xSquared);
  1101. * ```
  1102. */
  1103. static async with(rawSourceMap, sourceMapUrl, f) {
  1104. const consumer = await new SourceMapConsumer(rawSourceMap, sourceMapUrl);
  1105. try {
  1106. return await f(consumer)
  1107. } finally {
  1108. consumer.destroy();
  1109. }
  1110. }
  1111. /**
  1112. * Parse the mappings in a string in to a data structure which we can easily
  1113. * query (the ordered arrays in the `this.__generatedMappings` and
  1114. * `this.__originalMappings` properties).
  1115. */
  1116. _parseMappings(aStr, aSourceRoot) {
  1117. throw new Error('Subclasses must implement _parseMappings')
  1118. }
  1119. /**
  1120. * Iterate over each mapping between an original source/line/column and a
  1121. * generated line/column in this source map.
  1122. *
  1123. * @param Function aCallback
  1124. * The function that is called with each mapping.
  1125. * @param Object aContext
  1126. * Optional. If specified, this object will be the value of `this` every
  1127. * time that `aCallback` is called.
  1128. * @param aOrder
  1129. * Either `SourceMapConsumer.GENERATED_ORDER` or
  1130. * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to
  1131. * iterate over the mappings sorted by the generated file's line/column
  1132. * order or the original's source/line/column order, respectively. Defaults to
  1133. * `SourceMapConsumer.GENERATED_ORDER`.
  1134. */
  1135. eachMapping(aCallback, aContext, aOrder) {
  1136. throw new Error('Subclasses must implement eachMapping')
  1137. }
  1138. /**
  1139. * Returns all generated line and column information for the original source,
  1140. * line, and column provided. If no column is provided, returns all mappings
  1141. * corresponding to a either the line we are searching for or the next
  1142. * closest line that has any mappings. Otherwise, returns all mappings
  1143. * corresponding to the given line and either the column we are searching for
  1144. * or the next closest column that has any offsets.
  1145. *
  1146. * The only argument is an object with the following properties:
  1147. *
  1148. * - source: The filename of the original source.
  1149. * - line: The line number in the original source. The line number is 1-based.
  1150. * - column: Optional. the column number in the original source.
  1151. * The column number is 0-based.
  1152. *
  1153. * and an array of objects is returned, each with the following properties:
  1154. *
  1155. * - line: The line number in the generated source, or null. The
  1156. * line number is 1-based.
  1157. * - column: The column number in the generated source, or null.
  1158. * The column number is 0-based.
  1159. */
  1160. allGeneratedPositionsFor(aArgs) {
  1161. throw new Error('Subclasses must implement allGeneratedPositionsFor')
  1162. }
  1163. destroy() {
  1164. throw new Error('Subclasses must implement destroy')
  1165. }
  1166. };
  1167. /**
  1168. * The version of the source mapping spec that we are consuming.
  1169. */
  1170. SourceMapConsumer$1.prototype._version = 3;
  1171. SourceMapConsumer$1.GENERATED_ORDER = 1;
  1172. SourceMapConsumer$1.ORIGINAL_ORDER = 2;
  1173. SourceMapConsumer$1.GREATEST_LOWER_BOUND = 1;
  1174. SourceMapConsumer$1.LEAST_UPPER_BOUND = 2;
  1175. sourceMapConsumer.SourceMapConsumer = SourceMapConsumer$1;
  1176. /**
  1177. * A BasicSourceMapConsumer instance represents a parsed source map which we can
  1178. * query for information about the original file positions by giving it a file
  1179. * position in the generated source.
  1180. *
  1181. * The first parameter is the raw source map (either as a JSON string, or
  1182. * already parsed to an object). According to the spec, source maps have the
  1183. * following attributes:
  1184. *
  1185. * - version: Which version of the source map spec this map is following.
  1186. * - sources: An array of URLs to the original source files.
  1187. * - names: An array of identifiers which can be referenced by individual mappings.
  1188. * - sourceRoot: Optional. The URL root from which all sources are relative.
  1189. * - sourcesContent: Optional. An array of contents of the original source files.
  1190. * - mappings: A string of base64 VLQs which contain the actual mappings.
  1191. * - file: Optional. The generated file this source map is associated with.
  1192. *
  1193. * Here is an example source map, taken from the source map spec[0]:
  1194. *
  1195. * {
  1196. * version : 3,
  1197. * file: "out.js",
  1198. * sourceRoot : "",
  1199. * sources: ["foo.js", "bar.js"],
  1200. * names: ["src", "maps", "are", "fun"],
  1201. * mappings: "AA,AB;;ABCDE;"
  1202. * }
  1203. *
  1204. * The second parameter, if given, is a string whose value is the URL
  1205. * at which the source map was found. This URL is used to compute the
  1206. * sources array.
  1207. *
  1208. * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#
  1209. */
  1210. class BasicSourceMapConsumer extends SourceMapConsumer$1 {
  1211. constructor(aSourceMap, aSourceMapURL) {
  1212. return super(INTERNAL).then((that) => {
  1213. let sourceMap = aSourceMap;
  1214. if (typeof aSourceMap === 'string') {
  1215. sourceMap = util.parseSourceMapInput(aSourceMap);
  1216. }
  1217. const version = util.getArg(sourceMap, 'version');
  1218. let sources = util.getArg(sourceMap, 'sources');
  1219. // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which
  1220. // requires the array) to play nice here.
  1221. const names = util.getArg(sourceMap, 'names', []);
  1222. let sourceRoot = util.getArg(sourceMap, 'sourceRoot', null);
  1223. const sourcesContent = util.getArg(sourceMap, 'sourcesContent', null);
  1224. const mappings = util.getArg(sourceMap, 'mappings');
  1225. const file = util.getArg(sourceMap, 'file', null);
  1226. // Once again, Sass deviates from the spec and supplies the version as a
  1227. // string rather than a number, so we use loose equality checking here.
  1228. if (version != that._version) {
  1229. throw new Error('Unsupported version: ' + version)
  1230. }
  1231. if (sourceRoot) {
  1232. sourceRoot = util.normalize(sourceRoot);
  1233. }
  1234. sources = sources
  1235. .map(String)
  1236. // Some source maps produce relative source paths like "./foo.js" instead of
  1237. // "foo.js". Normalize these first so that future comparisons will succeed.
  1238. // See bugzil.la/1090768.
  1239. .map(util.normalize)
  1240. // Always ensure that absolute sources are internally stored relative to
  1241. // the source root, if the source root is absolute. Not doing this would
  1242. // be particularly problematic when the source root is a prefix of the
  1243. // source (valid, but why??). See github issue #199 and bugzil.la/1188982.
  1244. .map(function (source) {
  1245. return sourceRoot &&
  1246. util.isAbsolute(sourceRoot) &&
  1247. util.isAbsolute(source)
  1248. ? util.relative(sourceRoot, source)
  1249. : source
  1250. });
  1251. // Pass `true` below to allow duplicate names and sources. While source maps
  1252. // are intended to be compressed and deduplicated, the TypeScript compiler
  1253. // sometimes generates source maps with duplicates in them. See Github issue
  1254. // #72 and bugzil.la/889492.
  1255. that._names = ArraySet.fromArray(names.map(String), true);
  1256. that._sources = ArraySet.fromArray(sources, true);
  1257. that._absoluteSources = that._sources.toArray().map(function (s) {
  1258. return util.computeSourceURL(sourceRoot, s, aSourceMapURL)
  1259. });
  1260. that.sourceRoot = sourceRoot;
  1261. that.sourcesContent = sourcesContent;
  1262. that._mappings = mappings;
  1263. that._sourceMapURL = aSourceMapURL;
  1264. that.file = file;
  1265. that._computedColumnSpans = false;
  1266. that._mappingsPtr = 0;
  1267. that._wasm = null;
  1268. return wasm().then((w) => {
  1269. that._wasm = w;
  1270. return that
  1271. })
  1272. })
  1273. }
  1274. /**
  1275. * Utility function to find the index of a source. Returns -1 if not
  1276. * found.
  1277. */
  1278. _findSourceIndex(aSource) {
  1279. let relativeSource = aSource;
  1280. if (this.sourceRoot != null) {
  1281. relativeSource = util.relative(this.sourceRoot, relativeSource);
  1282. }
  1283. if (this._sources.has(relativeSource)) {
  1284. return this._sources.indexOf(relativeSource)
  1285. }
  1286. // Maybe aSource is an absolute URL as returned by |sources|. In
  1287. // this case we can't simply undo the transform.
  1288. for (let i = 0; i < this._absoluteSources.length; ++i) {
  1289. if (this._absoluteSources[i] == aSource) {
  1290. return i
  1291. }
  1292. }
  1293. return -1
  1294. }
  1295. /**
  1296. * Create a BasicSourceMapConsumer from a SourceMapGenerator.
  1297. *
  1298. * @param SourceMapGenerator aSourceMap
  1299. * The source map that will be consumed.
  1300. * @param String aSourceMapURL
  1301. * The URL at which the source map can be found (optional)
  1302. * @returns BasicSourceMapConsumer
  1303. */
  1304. static fromSourceMap(aSourceMap, aSourceMapURL) {
  1305. return new BasicSourceMapConsumer(aSourceMap.toString())
  1306. }
  1307. get sources() {
  1308. return this._absoluteSources.slice()
  1309. }
  1310. _getMappingsPtr() {
  1311. if (this._mappingsPtr === 0) {
  1312. this._parseMappings(this._mappings, this.sourceRoot);
  1313. }
  1314. return this._mappingsPtr
  1315. }
  1316. /**
  1317. * Parse the mappings in a string in to a data structure which we can easily
  1318. * query (the ordered arrays in the `this.__generatedMappings` and
  1319. * `this.__originalMappings` properties).
  1320. */
  1321. _parseMappings(aStr, aSourceRoot) {
  1322. const size = aStr.length;
  1323. const mappingsBufPtr = this._wasm.exports.allocate_mappings(size);
  1324. const mappingsBuf = new Uint8Array(
  1325. this._wasm.exports.memory.buffer,
  1326. mappingsBufPtr,
  1327. size
  1328. );
  1329. for (let i = 0; i < size; i++) {
  1330. mappingsBuf[i] = aStr.charCodeAt(i);
  1331. }
  1332. const mappingsPtr = this._wasm.exports.parse_mappings(mappingsBufPtr);
  1333. if (!mappingsPtr) {
  1334. const error = this._wasm.exports.get_last_error();
  1335. let msg = `Error parsing mappings (code ${error}): `;
  1336. // XXX: keep these error codes in sync with `fitzgen/source-map-mappings`.
  1337. switch (error) {
  1338. case 1:
  1339. msg +=
  1340. 'the mappings contained a negative line, column, source index, or name index';
  1341. break
  1342. case 2:
  1343. msg += 'the mappings contained a number larger than 2**32';
  1344. break
  1345. case 3:
  1346. msg += 'reached EOF while in the middle of parsing a VLQ';
  1347. break
  1348. case 4:
  1349. msg += 'invalid base 64 character while parsing a VLQ';
  1350. break
  1351. default:
  1352. msg += 'unknown error code';
  1353. break
  1354. }
  1355. throw new Error(msg)
  1356. }
  1357. this._mappingsPtr = mappingsPtr;
  1358. }
  1359. eachMapping(aCallback, aContext, aOrder) {
  1360. const context = aContext || null;
  1361. const order = aOrder || SourceMapConsumer$1.GENERATED_ORDER;
  1362. const sourceRoot = this.sourceRoot;
  1363. this._wasm.withMappingCallback(
  1364. (mapping) => {
  1365. if (mapping.source !== null) {
  1366. mapping.source = this._sources.at(mapping.source);
  1367. mapping.source = util.computeSourceURL(
  1368. sourceRoot,
  1369. mapping.source,
  1370. this._sourceMapURL
  1371. );
  1372. if (mapping.name !== null) {
  1373. mapping.name = this._names.at(mapping.name);
  1374. }
  1375. }
  1376. aCallback.call(context, mapping);
  1377. },
  1378. () => {
  1379. switch (order) {
  1380. case SourceMapConsumer$1.GENERATED_ORDER:
  1381. this._wasm.exports.by_generated_location(this._getMappingsPtr());
  1382. break
  1383. case SourceMapConsumer$1.ORIGINAL_ORDER:
  1384. this._wasm.exports.by_original_location(this._getMappingsPtr());
  1385. break
  1386. default:
  1387. throw new Error('Unknown order of iteration.')
  1388. }
  1389. }
  1390. );
  1391. }
  1392. allGeneratedPositionsFor(aArgs) {
  1393. let source = util.getArg(aArgs, 'source');
  1394. const originalLine = util.getArg(aArgs, 'line');
  1395. const originalColumn = aArgs.column || 0;
  1396. source = this._findSourceIndex(source);
  1397. if (source < 0) {
  1398. return []
  1399. }
  1400. if (originalLine < 1) {
  1401. throw new Error('Line numbers must be >= 1')
  1402. }
  1403. if (originalColumn < 0) {
  1404. throw new Error('Column numbers must be >= 0')
  1405. }
  1406. const mappings = [];
  1407. this._wasm.withMappingCallback(
  1408. (m) => {
  1409. let lastColumn = m.lastGeneratedColumn;
  1410. if (this._computedColumnSpans && lastColumn === null) {
  1411. lastColumn = Infinity;
  1412. }
  1413. mappings.push({
  1414. line: m.generatedLine,
  1415. column: m.generatedColumn,
  1416. lastColumn,
  1417. });
  1418. },
  1419. () => {
  1420. this._wasm.exports.all_generated_locations_for(
  1421. this._getMappingsPtr(),
  1422. source,
  1423. originalLine - 1,
  1424. 'column' in aArgs,
  1425. originalColumn
  1426. );
  1427. }
  1428. );
  1429. return mappings
  1430. }
  1431. destroy() {
  1432. if (this._mappingsPtr !== 0) {
  1433. this._wasm.exports.free_mappings(this._mappingsPtr);
  1434. this._mappingsPtr = 0;
  1435. }
  1436. }
  1437. /**
  1438. * Compute the last column for each generated mapping. The last column is
  1439. * inclusive.
  1440. */
  1441. computeColumnSpans() {
  1442. if (this._computedColumnSpans) {
  1443. return
  1444. }
  1445. this._wasm.exports.compute_column_spans(this._getMappingsPtr());
  1446. this._computedColumnSpans = true;
  1447. }
  1448. /**
  1449. * Returns the original source, line, and column information for the generated
  1450. * source's line and column positions provided. The only argument is an object
  1451. * with the following properties:
  1452. *
  1453. * - line: The line number in the generated source. The line number
  1454. * is 1-based.
  1455. * - column: The column number in the generated source. The column
  1456. * number is 0-based.
  1457. * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
  1458. * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
  1459. * closest element that is smaller than or greater than the one we are
  1460. * searching for, respectively, if the exact element cannot be found.
  1461. * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.
  1462. *
  1463. * and an object is returned with the following properties:
  1464. *
  1465. * - source: The original source file, or null.
  1466. * - line: The line number in the original source, or null. The
  1467. * line number is 1-based.
  1468. * - column: The column number in the original source, or null. The
  1469. * column number is 0-based.
  1470. * - name: The original identifier, or null.
  1471. */
  1472. originalPositionFor(aArgs) {
  1473. const needle = {
  1474. generatedLine: util.getArg(aArgs, 'line'),
  1475. generatedColumn: util.getArg(aArgs, 'column'),
  1476. };
  1477. if (needle.generatedLine < 1) {
  1478. throw new Error('Line numbers must be >= 1')
  1479. }
  1480. if (needle.generatedColumn < 0) {
  1481. throw new Error('Column numbers must be >= 0')
  1482. }
  1483. let bias = util.getArg(
  1484. aArgs,
  1485. 'bias',
  1486. SourceMapConsumer$1.GREATEST_LOWER_BOUND
  1487. );
  1488. if (bias == null) {
  1489. bias = SourceMapConsumer$1.GREATEST_LOWER_BOUND;
  1490. }
  1491. let mapping;
  1492. this._wasm.withMappingCallback(
  1493. (m) => (mapping = m),
  1494. () => {
  1495. this._wasm.exports.original_location_for(
  1496. this._getMappingsPtr(),
  1497. needle.generatedLine - 1,
  1498. needle.generatedColumn,
  1499. bias
  1500. );
  1501. }
  1502. );
  1503. if (mapping) {
  1504. if (mapping.generatedLine === needle.generatedLine) {
  1505. let source = util.getArg(mapping, 'source', null);
  1506. if (source !== null) {
  1507. source = this._sources.at(source);
  1508. source = util.computeSourceURL(
  1509. this.sourceRoot,
  1510. source,
  1511. this._sourceMapURL
  1512. );
  1513. }
  1514. let name = util.getArg(mapping, 'name', null);
  1515. if (name !== null) {
  1516. name = this._names.at(name);
  1517. }
  1518. return {
  1519. source,
  1520. line: util.getArg(mapping, 'originalLine', null),
  1521. column: util.getArg(mapping, 'originalColumn', null),
  1522. name,
  1523. }
  1524. }
  1525. }
  1526. return {
  1527. source: null,
  1528. line: null,
  1529. column: null,
  1530. name: null,
  1531. }
  1532. }
  1533. /**
  1534. * Return true if we have the source content for every source in the source
  1535. * map, false otherwise.
  1536. */
  1537. hasContentsOfAllSources() {
  1538. if (!this.sourcesContent) {
  1539. return false
  1540. }
  1541. return (
  1542. this.sourcesContent.length >= this._sources.size() &&
  1543. !this.sourcesContent.some(function (sc) {
  1544. return sc == null
  1545. })
  1546. )
  1547. }
  1548. /**
  1549. * Returns the original source content. The only argument is the url of the
  1550. * original source file. Returns null if no original source content is
  1551. * available.
  1552. */
  1553. sourceContentFor(aSource, nullOnMissing) {
  1554. if (!this.sourcesContent) {
  1555. return null
  1556. }
  1557. const index = this._findSourceIndex(aSource);
  1558. if (index >= 0) {
  1559. return this.sourcesContent[index]
  1560. }
  1561. let relativeSource = aSource;
  1562. if (this.sourceRoot != null) {
  1563. relativeSource = util.relative(this.sourceRoot, relativeSource);
  1564. }
  1565. let url;
  1566. if (this.sourceRoot != null && (url = util.urlParse(this.sourceRoot))) {
  1567. // XXX: file:// URIs and absolute paths lead to unexpected behavior for
  1568. // many users. We can help them out when they expect file:// URIs to
  1569. // behave like it would if they were running a local HTTP server. See
  1570. // https://bugzilla.mozilla.org/show_bug.cgi?id=885597.
  1571. const fileUriAbsPath = relativeSource.replace(/^file:\/\//, '');
  1572. if (url.scheme == 'file' && this._sources.has(fileUriAbsPath)) {
  1573. return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]
  1574. }
  1575. if (
  1576. (!url.path || url.path == '/') &&
  1577. this._sources.has('/' + relativeSource)
  1578. ) {
  1579. return this.sourcesContent[this._sources.indexOf('/' + relativeSource)]
  1580. }
  1581. }
  1582. // This function is used recursively from
  1583. // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we
  1584. // don't want to throw if we can't find the source - we just want to
  1585. // return null, so we provide a flag to exit gracefully.
  1586. if (nullOnMissing) {
  1587. return null
  1588. }
  1589. throw new Error('"' + relativeSource + '" is not in the SourceMap.')
  1590. }
  1591. /**
  1592. * Returns the generated line and column information for the original source,
  1593. * line, and column positions provided. The only argument is an object with
  1594. * the following properties:
  1595. *
  1596. * - source: The filename of the original source.
  1597. * - line: The line number in the original source. The line number
  1598. * is 1-based.
  1599. * - column: The column number in the original source. The column
  1600. * number is 0-based.
  1601. * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
  1602. * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
  1603. * closest element that is smaller than or greater than the one we are
  1604. * searching for, respectively, if the exact element cannot be found.
  1605. * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.
  1606. *
  1607. * and an object is returned with the following properties:
  1608. *
  1609. * - line: The line number in the generated source, or null. The
  1610. * line number is 1-based.
  1611. * - column: The column number in the generated source, or null.
  1612. * The column number is 0-based.
  1613. */
  1614. generatedPositionFor(aArgs) {
  1615. let source = util.getArg(aArgs, 'source');
  1616. source = this._findSourceIndex(source);
  1617. if (source < 0) {
  1618. return {
  1619. line: null,
  1620. column: null,
  1621. lastColumn: null,
  1622. }
  1623. }
  1624. const needle = {
  1625. source,
  1626. originalLine: util.getArg(aArgs, 'line'),
  1627. originalColumn: util.getArg(aArgs, 'column'),
  1628. };
  1629. if (needle.originalLine < 1) {
  1630. throw new Error('Line numbers must be >= 1')
  1631. }
  1632. if (needle.originalColumn < 0) {
  1633. throw new Error('Column numbers must be >= 0')
  1634. }
  1635. let bias = util.getArg(
  1636. aArgs,
  1637. 'bias',
  1638. SourceMapConsumer$1.GREATEST_LOWER_BOUND
  1639. );
  1640. if (bias == null) {
  1641. bias = SourceMapConsumer$1.GREATEST_LOWER_BOUND;
  1642. }
  1643. let mapping;
  1644. this._wasm.withMappingCallback(
  1645. (m) => (mapping = m),
  1646. () => {
  1647. this._wasm.exports.generated_location_for(
  1648. this._getMappingsPtr(),
  1649. needle.source,
  1650. needle.originalLine - 1,
  1651. needle.originalColumn,
  1652. bias
  1653. );
  1654. }
  1655. );
  1656. if (mapping) {
  1657. if (mapping.source === needle.source) {
  1658. let lastColumn = mapping.lastGeneratedColumn;
  1659. if (this._computedColumnSpans && lastColumn === null) {
  1660. lastColumn = Infinity;
  1661. }
  1662. return {
  1663. line: util.getArg(mapping, 'generatedLine', null),
  1664. column: util.getArg(mapping, 'generatedColumn', null),
  1665. lastColumn,
  1666. }
  1667. }
  1668. }
  1669. return {
  1670. line: null,
  1671. column: null,
  1672. lastColumn: null,
  1673. }
  1674. }
  1675. }
  1676. BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer$1;
  1677. sourceMapConsumer.BasicSourceMapConsumer = BasicSourceMapConsumer;
  1678. /**
  1679. * An IndexedSourceMapConsumer instance represents a parsed source map which
  1680. * we can query for information. It differs from BasicSourceMapConsumer in
  1681. * that it takes "indexed" source maps (i.e. ones with a "sections" field) as
  1682. * input.
  1683. *
  1684. * The first parameter is a raw source map (either as a JSON string, or already
  1685. * parsed to an object). According to the spec for indexed source maps, they
  1686. * have the following attributes:
  1687. *
  1688. * - version: Which version of the source map spec this map is following.
  1689. * - file: Optional. The generated file this source map is associated with.
  1690. * - sections: A list of section definitions.
  1691. *
  1692. * Each value under the "sections" field has two fields:
  1693. * - offset: The offset into the original specified at which this section
  1694. * begins to apply, defined as an object with a "line" and "column"
  1695. * field.
  1696. * - map: A source map definition. This source map could also be indexed,
  1697. * but doesn't have to be.
  1698. *
  1699. * Instead of the "map" field, it's also possible to have a "url" field
  1700. * specifying a URL to retrieve a source map from, but that's currently
  1701. * unsupported.
  1702. *
  1703. * Here's an example source map, taken from the source map spec[0], but
  1704. * modified to omit a section which uses the "url" field.
  1705. *
  1706. * {
  1707. * version : 3,
  1708. * file: "app.js",
  1709. * sections: [{
  1710. * offset: {line:100, column:10},
  1711. * map: {
  1712. * version : 3,
  1713. * file: "section.js",
  1714. * sources: ["foo.js", "bar.js"],
  1715. * names: ["src", "maps", "are", "fun"],
  1716. * mappings: "AAAA,E;;ABCDE;"
  1717. * }
  1718. * }],
  1719. * }
  1720. *
  1721. * The second parameter, if given, is a string whose value is the URL
  1722. * at which the source map was found. This URL is used to compute the
  1723. * sources array.
  1724. *
  1725. * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt
  1726. */
  1727. class IndexedSourceMapConsumer extends SourceMapConsumer$1 {
  1728. constructor(aSourceMap, aSourceMapURL) {
  1729. return super(INTERNAL).then((that) => {
  1730. let sourceMap = aSourceMap;
  1731. if (typeof aSourceMap === 'string') {
  1732. sourceMap = util.parseSourceMapInput(aSourceMap);
  1733. }
  1734. const version = util.getArg(sourceMap, 'version');
  1735. const sections = util.getArg(sourceMap, 'sections');
  1736. if (version != that._version) {
  1737. throw new Error('Unsupported version: ' + version)
  1738. }
  1739. that._sources = new ArraySet();
  1740. that._names = new ArraySet();
  1741. that.__generatedMappings = null;
  1742. that.__originalMappings = null;
  1743. that.__generatedMappingsUnsorted = null;
  1744. that.__originalMappingsUnsorted = null;
  1745. let lastOffset = {
  1746. line: -1,
  1747. column: 0,
  1748. };
  1749. return Promise.all(
  1750. sections.map((s) => {
  1751. if (s.url) {
  1752. // The url field will require support for asynchronicity.
  1753. // See https://github.com/mozilla/source-map/issues/16
  1754. throw new Error(
  1755. 'Support for url field in sections not implemented.'
  1756. )
  1757. }
  1758. const offset = util.getArg(s, 'offset');
  1759. const offsetLine = util.getArg(offset, 'line');
  1760. const offsetColumn = util.getArg(offset, 'column');
  1761. if (
  1762. offsetLine < lastOffset.line ||
  1763. (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)
  1764. ) {
  1765. throw new Error(
  1766. 'Section offsets must be ordered and non-overlapping.'
  1767. )
  1768. }
  1769. lastOffset = offset;
  1770. const cons = new SourceMapConsumer$1(
  1771. util.getArg(s, 'map'),
  1772. aSourceMapURL
  1773. );
  1774. return cons.then((consumer) => {
  1775. return {
  1776. generatedOffset: {
  1777. // The offset fields are 0-based, but we use 1-based indices when
  1778. // encoding/decoding from VLQ.
  1779. generatedLine: offsetLine + 1,
  1780. generatedColumn: offsetColumn + 1,
  1781. },
  1782. consumer,
  1783. }
  1784. })
  1785. })
  1786. ).then((s) => {
  1787. that._sections = s;
  1788. return that
  1789. })
  1790. })
  1791. }
  1792. // `__generatedMappings` and `__originalMappings` are arrays that hold the
  1793. // parsed mapping coordinates from the source map's "mappings" attribute. They
  1794. // are lazily instantiated, accessed via the `_generatedMappings` and
  1795. // `_originalMappings` getters respectively, and we only parse the mappings
  1796. // and create these arrays once queried for a source location. We jump through
  1797. // these hoops because there can be many thousands of mappings, and parsing
  1798. // them is expensive, so we only want to do it if we must.
  1799. //
  1800. // Each object in the arrays is of the form:
  1801. //
  1802. // {
  1803. // generatedLine: The line number in the generated code,
  1804. // generatedColumn: The column number in the generated code,
  1805. // source: The path to the original source file that generated this
  1806. // chunk of code,
  1807. // originalLine: The line number in the original source that
  1808. // corresponds to this chunk of generated code,
  1809. // originalColumn: The column number in the original source that
  1810. // corresponds to this chunk of generated code,
  1811. // name: The name of the original symbol which generated this chunk of
  1812. // code.
  1813. // }
  1814. //
  1815. // All properties except for `generatedLine` and `generatedColumn` can be
  1816. // `null`.
  1817. //
  1818. // `_generatedMappings` is ordered by the generated positions.
  1819. //
  1820. // `_originalMappings` is ordered by the original positions.
  1821. get _generatedMappings() {
  1822. if (!this.__generatedMappings) {
  1823. this._sortGeneratedMappings();
  1824. }
  1825. return this.__generatedMappings
  1826. }
  1827. get _originalMappings() {
  1828. if (!this.__originalMappings) {
  1829. this._sortOriginalMappings();
  1830. }
  1831. return this.__originalMappings
  1832. }
  1833. get _generatedMappingsUnsorted() {
  1834. if (!this.__generatedMappingsUnsorted) {
  1835. this._parseMappings(this._mappings, this.sourceRoot);
  1836. }
  1837. return this.__generatedMappingsUnsorted
  1838. }
  1839. get _originalMappingsUnsorted() {
  1840. if (!this.__originalMappingsUnsorted) {
  1841. this._parseMappings(this._mappings, this.sourceRoot);
  1842. }
  1843. return this.__originalMappingsUnsorted
  1844. }
  1845. _sortGeneratedMappings() {
  1846. const mappings = this._generatedMappingsUnsorted;
  1847. mappings.sort(util.compareByGeneratedPositionsDeflated);
  1848. this.__generatedMappings = mappings;
  1849. }
  1850. _sortOriginalMappings() {
  1851. const mappings = this._originalMappingsUnsorted;
  1852. mappings.sort(util.compareByOriginalPositions);
  1853. this.__originalMappings = mappings;
  1854. }
  1855. /**
  1856. * The list of original sources.
  1857. */
  1858. get sources() {
  1859. const sources = [];
  1860. for (let i = 0; i < this._sections.length; i++) {
  1861. for (let j = 0; j < this._sections[i].consumer.sources.length; j++) {
  1862. sources.push(this._sections[i].consumer.sources[j]);
  1863. }
  1864. }
  1865. return sources
  1866. }
  1867. /**
  1868. * Returns the original source, line, and column information for the generated
  1869. * source's line and column positions provided. The only argument is an object
  1870. * with the following properties:
  1871. *
  1872. * - line: The line number in the generated source. The line number
  1873. * is 1-based.
  1874. * - column: The column number in the generated source. The column
  1875. * number is 0-based.
  1876. *
  1877. * and an object is returned with the following properties:
  1878. *
  1879. * - source: The original source file, or null.
  1880. * - line: The line number in the original source, or null. The
  1881. * line number is 1-based.
  1882. * - column: The column number in the original source, or null. The
  1883. * column number is 0-based.
  1884. * - name: The original identifier, or null.
  1885. */
  1886. originalPositionFor(aArgs) {
  1887. const needle = {
  1888. generatedLine: util.getArg(aArgs, 'line'),
  1889. generatedColumn: util.getArg(aArgs, 'column'),
  1890. };
  1891. // Find the section containing the generated position we're trying to map
  1892. // to an original position.
  1893. const sectionIndex = binarySearch.search(
  1894. needle,
  1895. this._sections,
  1896. function (aNeedle, section) {
  1897. const cmp =
  1898. aNeedle.generatedLine - section.generatedOffset.generatedLine;
  1899. if (cmp) {
  1900. return cmp
  1901. }
  1902. return aNeedle.generatedColumn - section.generatedOffset.generatedColumn
  1903. }
  1904. );
  1905. const section = this._sections[sectionIndex];
  1906. if (!section) {
  1907. return {
  1908. source: null,
  1909. line: null,
  1910. column: null,
  1911. name: null,
  1912. }
  1913. }
  1914. return section.consumer.originalPositionFor({
  1915. line: needle.generatedLine - (section.generatedOffset.generatedLine - 1),
  1916. column:
  1917. needle.generatedColumn -
  1918. (section.generatedOffset.generatedLine === needle.generatedLine
  1919. ? section.generatedOffset.generatedColumn - 1
  1920. : 0),
  1921. bias: aArgs.bias,
  1922. })
  1923. }
  1924. /**
  1925. * Return true if we have the source content for every source in the source
  1926. * map, false otherwise.
  1927. */
  1928. hasContentsOfAllSources() {
  1929. return this._sections.every(function (s) {
  1930. return s.consumer.hasContentsOfAllSources()
  1931. })
  1932. }
  1933. /**
  1934. * Returns the original source content. The only argument is the url of the
  1935. * original source file. Returns null if no original source content is
  1936. * available.
  1937. */
  1938. sourceContentFor(aSource, nullOnMissing) {
  1939. for (let i = 0; i < this._sections.length; i++) {
  1940. const section = this._sections[i];
  1941. const content = section.consumer.sourceContentFor(aSource, true);
  1942. if (content) {
  1943. return content
  1944. }
  1945. }
  1946. if (nullOnMissing) {
  1947. return null
  1948. }
  1949. throw new Error('"' + aSource + '" is not in the SourceMap.')
  1950. }
  1951. /**
  1952. * Returns the generated line and column information for the original source,
  1953. * line, and column positions provided. The only argument is an object with
  1954. * the following properties:
  1955. *
  1956. * - source: The filename of the original source.
  1957. * - line: The line number in the original source. The line number
  1958. * is 1-based.
  1959. * - column: The column number in the original source. The column
  1960. * number is 0-based.
  1961. *
  1962. * and an object is returned with the following properties:
  1963. *
  1964. * - line: The line number in the generated source, or null. The
  1965. * line number is 1-based.
  1966. * - column: The column number in the generated source, or null.
  1967. * The column number is 0-based.
  1968. */
  1969. generatedPositionFor(aArgs) {
  1970. for (let i = 0; i < this._sections.length; i++) {
  1971. const section = this._sections[i];
  1972. // Only consider this section if the requested source is in the list of
  1973. // sources of the consumer.
  1974. if (
  1975. section.consumer._findSourceIndex(util.getArg(aArgs, 'source')) === -1
  1976. ) {
  1977. continue
  1978. }
  1979. const generatedPosition = section.consumer.generatedPositionFor(aArgs);
  1980. if (generatedPosition) {
  1981. const ret = {
  1982. line:
  1983. generatedPosition.line +
  1984. (section.generatedOffset.generatedLine - 1),
  1985. column:
  1986. generatedPosition.column +
  1987. (section.generatedOffset.generatedLine === generatedPosition.line
  1988. ? section.generatedOffset.generatedColumn - 1
  1989. : 0),
  1990. };
  1991. return ret
  1992. }
  1993. }
  1994. return {
  1995. line: null,
  1996. column: null,
  1997. }
  1998. }
  1999. /**
  2000. * Parse the mappings in a string in to a data structure which we can easily
  2001. * query (the ordered arrays in the `this.__generatedMappings` and
  2002. * `this.__originalMappings` properties).
  2003. */
  2004. _parseMappings(aStr, aSourceRoot) {
  2005. const generatedMappings = (this.__generatedMappingsUnsorted = []);
  2006. const originalMappings = (this.__originalMappingsUnsorted = []);
  2007. for (let i = 0; i < this._sections.length; i++) {
  2008. const section = this._sections[i];
  2009. const sectionMappings = [];
  2010. section.consumer.eachMapping((m) => sectionMappings.push(m));
  2011. for (let j = 0; j < sectionMappings.length; j++) {
  2012. const mapping = sectionMappings[j];
  2013. // TODO: test if null is correct here. The original code used
  2014. // `source`, which would actually have gotten used as null because
  2015. // var's get hoisted.
  2016. // See: https://github.com/mozilla/source-map/issues/333
  2017. let source = util.computeSourceURL(
  2018. section.consumer.sourceRoot,
  2019. null,
  2020. this._sourceMapURL
  2021. );
  2022. this._sources.add(source);
  2023. source = this._sources.indexOf(source);
  2024. let name = null;
  2025. if (mapping.name) {
  2026. this._names.add(mapping.name);
  2027. name = this._names.indexOf(mapping.name);
  2028. }
  2029. // The mappings coming from the consumer for the section have
  2030. // generated positions relative to the start of the section, so we
  2031. // need to offset them to be relative to the start of the concatenated
  2032. // generated file.
  2033. const adjustedMapping = {
  2034. source,
  2035. generatedLine:
  2036. mapping.generatedLine + (section.generatedOffset.generatedLine - 1),
  2037. generatedColumn:
  2038. mapping.generatedColumn +
  2039. (section.generatedOffset.generatedLine === mapping.generatedLine
  2040. ? section.generatedOffset.generatedColumn - 1
  2041. : 0),
  2042. originalLine: mapping.originalLine,
  2043. originalColumn: mapping.originalColumn,
  2044. name,
  2045. };
  2046. generatedMappings.push(adjustedMapping);
  2047. if (typeof adjustedMapping.originalLine === 'number') {
  2048. originalMappings.push(adjustedMapping);
  2049. }
  2050. }
  2051. }
  2052. }
  2053. eachMapping(aCallback, aContext, aOrder) {
  2054. const context = aContext || null;
  2055. const order = aOrder || SourceMapConsumer$1.GENERATED_ORDER;
  2056. let mappings;
  2057. switch (order) {
  2058. case SourceMapConsumer$1.GENERATED_ORDER:
  2059. mappings = this._generatedMappings;
  2060. break
  2061. case SourceMapConsumer$1.ORIGINAL_ORDER:
  2062. mappings = this._originalMappings;
  2063. break
  2064. default:
  2065. throw new Error('Unknown order of iteration.')
  2066. }
  2067. const sourceRoot = this.sourceRoot;
  2068. mappings
  2069. .map(function (mapping) {
  2070. let source = null;
  2071. if (mapping.source !== null) {
  2072. source = this._sources.at(mapping.source);
  2073. source = util.computeSourceURL(sourceRoot, source, this._sourceMapURL);
  2074. }
  2075. return {
  2076. source,
  2077. generatedLine: mapping.generatedLine,
  2078. generatedColumn: mapping.generatedColumn,
  2079. originalLine: mapping.originalLine,
  2080. originalColumn: mapping.originalColumn,
  2081. name: mapping.name === null ? null : this._names.at(mapping.name),
  2082. }
  2083. }, this)
  2084. .forEach(aCallback, context);
  2085. }
  2086. /**
  2087. * Find the mapping that best matches the hypothetical "needle" mapping that
  2088. * we are searching for in the given "haystack" of mappings.
  2089. */
  2090. _findMapping(aNeedle, aMappings, aLineName, aColumnName, aComparator, aBias) {
  2091. // To return the position we are searching for, we must first find the
  2092. // mapping for the given position and then return the opposite position it
  2093. // points to. Because the mappings are sorted, we can use binary search to
  2094. // find the best mapping.
  2095. if (aNeedle[aLineName] <= 0) {
  2096. throw new TypeError(
  2097. 'Line must be greater than or equal to 1, got ' + aNeedle[aLineName]
  2098. )
  2099. }
  2100. if (aNeedle[aColumnName] < 0) {
  2101. throw new TypeError(
  2102. 'Column must be greater than or equal to 0, got ' + aNeedle[aColumnName]
  2103. )
  2104. }
  2105. return binarySearch.search(aNeedle, aMappings, aComparator, aBias)
  2106. }
  2107. allGeneratedPositionsFor(aArgs) {
  2108. const line = util.getArg(aArgs, 'line');
  2109. // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping
  2110. // returns the index of the closest mapping less than the needle. By
  2111. // setting needle.originalColumn to 0, we thus find the last mapping for
  2112. // the given line, provided such a mapping exists.
  2113. const needle = {
  2114. source: util.getArg(aArgs, 'source'),
  2115. originalLine: line,
  2116. originalColumn: util.getArg(aArgs, 'column', 0),
  2117. };
  2118. needle.source = this._findSourceIndex(needle.source);
  2119. if (needle.source < 0) {
  2120. return []
  2121. }
  2122. if (needle.originalLine < 1) {
  2123. throw new Error('Line numbers must be >= 1')
  2124. }
  2125. if (needle.originalColumn < 0) {
  2126. throw new Error('Column numbers must be >= 0')
  2127. }
  2128. const mappings = [];
  2129. let index = this._findMapping(
  2130. needle,
  2131. this._originalMappings,
  2132. 'originalLine',
  2133. 'originalColumn',
  2134. util.compareByOriginalPositions,
  2135. binarySearch.LEAST_UPPER_BOUND
  2136. );
  2137. if (index >= 0) {
  2138. let mapping = this._originalMappings[index];
  2139. if (aArgs.column === undefined) {
  2140. const originalLine = mapping.originalLine;
  2141. // Iterate until either we run out of mappings, or we run into
  2142. // a mapping for a different line than the one we found. Since
  2143. // mappings are sorted, this is guaranteed to find all mappings for
  2144. // the line we found.
  2145. while (mapping && mapping.originalLine === originalLine) {
  2146. let lastColumn = mapping.lastGeneratedColumn;
  2147. if (this._computedColumnSpans && lastColumn === null) {
  2148. lastColumn = Infinity;
  2149. }
  2150. mappings.push({
  2151. line: util.getArg(mapping, 'generatedLine', null),
  2152. column: util.getArg(mapping, 'generatedColumn', null),
  2153. lastColumn,
  2154. });
  2155. mapping = this._originalMappings[++index];
  2156. }
  2157. } else {
  2158. const originalColumn = mapping.originalColumn;
  2159. // Iterate until either we run out of mappings, or we run into
  2160. // a mapping for a different line than the one we were searching for.
  2161. // Since mappings are sorted, this is guaranteed to find all mappings for
  2162. // the line we are searching for.
  2163. while (
  2164. mapping &&
  2165. mapping.originalLine === line &&
  2166. mapping.originalColumn == originalColumn
  2167. ) {
  2168. let lastColumn = mapping.lastGeneratedColumn;
  2169. if (this._computedColumnSpans && lastColumn === null) {
  2170. lastColumn = Infinity;
  2171. }
  2172. mappings.push({
  2173. line: util.getArg(mapping, 'generatedLine', null),
  2174. column: util.getArg(mapping, 'generatedColumn', null),
  2175. lastColumn,
  2176. });
  2177. mapping = this._originalMappings[++index];
  2178. }
  2179. }
  2180. }
  2181. return mappings
  2182. }
  2183. destroy() {
  2184. for (let i = 0; i < this._sections.length; i++) {
  2185. this._sections[i].consumer.destroy();
  2186. }
  2187. }
  2188. }
  2189. sourceMapConsumer.IndexedSourceMapConsumer = IndexedSourceMapConsumer;
  2190. /*
  2191. * Cheat to get around inter-twingled classes. `factory()` can be at the end
  2192. * where it has access to non-hoisted classes, but it gets hoisted itself.
  2193. */
  2194. function _factory(aSourceMap, aSourceMapURL) {
  2195. let sourceMap = aSourceMap;
  2196. if (typeof aSourceMap === 'string') {
  2197. sourceMap = util.parseSourceMapInput(aSourceMap);
  2198. }
  2199. const consumer =
  2200. sourceMap.sections != null
  2201. ? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL)
  2202. : new BasicSourceMapConsumer(sourceMap, aSourceMapURL);
  2203. return Promise.resolve(consumer)
  2204. }
  2205. function _factoryBSM(aSourceMap, aSourceMapURL) {
  2206. return BasicSourceMapConsumer.fromSourceMap(aSourceMap, aSourceMapURL)
  2207. }
  2208. /*
  2209. * Copyright 2009-2011 Mozilla Foundation and contributors
  2210. * Licensed under the New BSD license. See LICENSE.txt or:
  2211. * http://opensource.org/licenses/BSD-3-Clause
  2212. */
  2213. var SourceMapConsumer = sourceMapConsumer.SourceMapConsumer;
  2214. const splitRE = /\r?\n/;
  2215. const range = 2;
  2216. function posToNumber(source, pos) {
  2217. if (typeof pos === 'number')
  2218. return pos;
  2219. const lines = source.split(splitRE);
  2220. const { line, column } = pos;
  2221. let start = 0;
  2222. for (let i = 0; i < line - 1; i++) {
  2223. start += lines[i].length + 1;
  2224. }
  2225. return start + column;
  2226. }
  2227. function generateCodeFrame(source, start = 0, end) {
  2228. start = posToNumber(source, start);
  2229. end = end || start;
  2230. const lines = source.split(splitRE);
  2231. let count = 0;
  2232. const res = [];
  2233. for (let i = 0; i < lines.length; i++) {
  2234. count += lines[i].length + 1;
  2235. if (count >= start) {
  2236. for (let j = i - range; j <= i + range || end > count; j++) {
  2237. if (j < 0 || j >= lines.length)
  2238. continue;
  2239. const line = j + 1;
  2240. res.push(`${line}${' '.repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`);
  2241. const lineLength = lines[j].length;
  2242. if (j === i) {
  2243. // push underline
  2244. const pad = start - (count - lineLength) + 1;
  2245. const length = Math.max(1, end > count ? lineLength - pad : end - start);
  2246. res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length));
  2247. }
  2248. else if (j > i) {
  2249. if (end > count) {
  2250. const length = Math.max(Math.min(end - count, lineLength), 1);
  2251. res.push(` | ` + '^'.repeat(length));
  2252. }
  2253. count += lineLength + 1;
  2254. }
  2255. }
  2256. break;
  2257. }
  2258. }
  2259. return res.join('\n');
  2260. }
  2261. let isWindows = false;
  2262. try {
  2263. isWindows = os__default.default.platform() === 'win32';
  2264. }
  2265. catch (error) { }
  2266. function normalizePath(id) {
  2267. return isWindows ? id.replace(/\\/g, '/') : id;
  2268. }
  2269. function generateCodeFrameSourceMapConsumer(consumer, m, options = {}) {
  2270. if (m.file) {
  2271. const res = consumer.originalPositionFor({
  2272. line: m.line,
  2273. column: m.column,
  2274. });
  2275. if (res.source != null && res.line != null && res.column != null) {
  2276. let code = consumer.sourceContentFor(res.source, true);
  2277. if (code) {
  2278. code = generateCodeFrame(code, { line: res.line, column: res.column });
  2279. if (options.replaceTabsWithSpace) {
  2280. code = code.replace(/\t/g, ' ');
  2281. }
  2282. return {
  2283. type: m.type,
  2284. file: options.sourceRoot
  2285. ? normalizePath(path__default.default.relative(options.sourceRoot, res.source.replace('\\\\?\\', '')))
  2286. : res.source,
  2287. line: res.line,
  2288. column: res.column,
  2289. message: m.message,
  2290. code,
  2291. };
  2292. }
  2293. }
  2294. }
  2295. }
  2296. function initConsumer(filename) {
  2297. if (fs__default.default.existsSync(filename)) {
  2298. return new SourceMapConsumer(fs__default.default.readFileSync(filename, 'utf8'));
  2299. }
  2300. return Promise.resolve(undefined);
  2301. }
  2302. function generateCodeFrameWithSourceMapPath(filename, messages, options = {}) {
  2303. if (typeof messages === 'string') {
  2304. try {
  2305. messages = JSON.parse(messages);
  2306. }
  2307. catch (e) { }
  2308. }
  2309. if (Array.isArray(messages) && messages.length) {
  2310. return new Promise((resolve) => {
  2311. initConsumer(filename).then((consumer) => {
  2312. resolve(messages
  2313. .map((m) => {
  2314. if (m.file && consumer) {
  2315. const message = generateCodeFrameSourceMapConsumer(consumer, m, options);
  2316. if (message) {
  2317. return message;
  2318. }
  2319. }
  2320. if (!m.file) {
  2321. m.file = '';
  2322. }
  2323. return m;
  2324. })
  2325. .filter(Boolean));
  2326. });
  2327. });
  2328. }
  2329. return Promise.resolve([]);
  2330. }
  2331. function resolveSourceMapPath(sourceMapFilename, name, outputDir) {
  2332. const is_uni_modules = path__default.default.basename(path__default.default.dirname(name)) === 'uni_modules';
  2333. return path__default.default.resolve(outputDir, '../.sourcemap/app', name, is_uni_modules ? 'utssdk' : '', sourceMapFilename);
  2334. }
  2335. function generateCodeFrameWithKotlinStacktrace(stacktrace, { name, inputDir, outputDir }) {
  2336. const sourceMapFilename = resolveSourceMapPath('app-android/index.kt.map', name, outputDir);
  2337. return generateCodeFrameWithStacktrace(stacktrace, /e:\s+(.*):\s+\(([0-9]+),\s+([0-9]+)\):\s+(.*)/g, {
  2338. sourceRoot: inputDir,
  2339. sourceMapFilename,
  2340. });
  2341. }
  2342. function generateCodeFrameWithSwiftStacktrace(stacktrace, { name, inputDir, outputDir }) {
  2343. const sourceMapFilename = resolveSourceMapPath('app-ios/index.swift.map', name, outputDir);
  2344. return generateCodeFrameWithStacktrace(stacktrace, /(.*):([0-9]+):([0-9]+):\s+error:\s+(.*)/g, {
  2345. sourceRoot: inputDir,
  2346. sourceMapFilename,
  2347. });
  2348. }
  2349. function generateCodeFrameWithStacktrace(stacktrace, regexp, { sourceRoot, sourceMapFilename, replaceTabsWithSpace, }) {
  2350. return new Promise((resolve) => {
  2351. initConsumer(sourceMapFilename).then((consumer) => {
  2352. if (!consumer) {
  2353. return resolve(stacktrace);
  2354. }
  2355. resolve(stacktrace.replace(regexp, (substring, file, line, column, message) => {
  2356. const m = generateCodeFrameSourceMapConsumer(consumer, {
  2357. type: 'error',
  2358. file,
  2359. message,
  2360. line: parseInt(line),
  2361. column: parseInt(column),
  2362. }, { sourceRoot, replaceTabsWithSpace });
  2363. if (!m) {
  2364. return substring;
  2365. }
  2366. return `error: ${message}
  2367. at ${m.file}:${m.line}:${m.column}
  2368. ${m.code}
  2369. `;
  2370. }));
  2371. });
  2372. });
  2373. }
  2374. const nixSlashes = (x) => x.replace(/\\/g, '/');
  2375. const sourcemapCatch = {};
  2376. function stacktracey(stacktrace, opts) {
  2377. const stack = opts.preset.parseStacktrace(stacktrace);
  2378. let parseStack = Promise.resolve();
  2379. stack.items.forEach((item, index) => {
  2380. const fn = (item, index) => {
  2381. const { line = 0, column = 0, file, fileName, fileRelative } = item;
  2382. if (item.thirdParty) {
  2383. return Promise.resolve();
  2384. }
  2385. function _getSourceMapContent(file, fileName, fileRelative) {
  2386. return opts.preset
  2387. .getSourceMapContent(file, fileName, fileRelative)
  2388. .then((content) => {
  2389. if (content) {
  2390. return getConsumer(content).then((consumer) => {
  2391. return parseSourceMapContent(consumer, {
  2392. line: line + (opts.preset.lineOffset || 0),
  2393. column,
  2394. }, !!opts.withSourceContent);
  2395. });
  2396. }
  2397. });
  2398. }
  2399. try {
  2400. return _getSourceMapContent(file, fileName, fileRelative).then((sourceMapContent) => {
  2401. if (sourceMapContent) {
  2402. const { source, sourcePath, sourceLine, sourceColumn, sourceContent, fileName = '', } = sourceMapContent;
  2403. stack.items[index] = Object.assign({}, item, {
  2404. file: source,
  2405. line: sourceLine,
  2406. column: sourceColumn,
  2407. fileShort: sourcePath,
  2408. fileRelative: source,
  2409. fileName,
  2410. thirdParty: isThirdParty(sourcePath),
  2411. parsed: true,
  2412. sourceContent,
  2413. });
  2414. /**
  2415. * 以 .js 结尾
  2416. * 包含 app-service.js 则需要再解析 两次
  2417. * 不包含 app-service.js 则无需再解析 一次
  2418. */
  2419. const curItem = stack.items[index];
  2420. if (stack.isMP &&
  2421. curItem.beforeParse.indexOf('app-service') !== -1) {
  2422. return fn(curItem, index);
  2423. }
  2424. }
  2425. });
  2426. }
  2427. catch (error) {
  2428. return Promise.resolve();
  2429. }
  2430. };
  2431. parseStack = parseStack.then(() => {
  2432. return new Promise((resolve, reject) => {
  2433. setTimeout(() => {
  2434. fn(item, index).then(resolve);
  2435. }, 0);
  2436. });
  2437. });
  2438. });
  2439. const _promise = new Promise((resolve, reject) => {
  2440. parseStack
  2441. .then(() => {
  2442. const parseError = opts.preset.asTableStacktrace({
  2443. stack,
  2444. maxColumnWidths: {
  2445. callee: 999,
  2446. file: 999,
  2447. sourceLine: 999,
  2448. },
  2449. stacktrace,
  2450. });
  2451. resolve(parseError);
  2452. })
  2453. .catch(() => {
  2454. resolve(stacktrace);
  2455. });
  2456. });
  2457. return _promise;
  2458. }
  2459. function isThirdParty(relativePath) {
  2460. return relativePath.indexOf('@dcloudio') !== -1;
  2461. }
  2462. function getConsumer(content) {
  2463. return new Promise((resolve, reject) => {
  2464. try {
  2465. if (SourceMapConsumer.with) {
  2466. SourceMapConsumer.with(content, null, (consumer) => {
  2467. resolve(consumer);
  2468. });
  2469. }
  2470. else {
  2471. // @ts-ignore
  2472. const consumer = SourceMapConsumer(content);
  2473. resolve(consumer);
  2474. }
  2475. }
  2476. catch (error) {
  2477. reject();
  2478. }
  2479. });
  2480. }
  2481. function getSourceMapContent(sourcemapUrl) {
  2482. try {
  2483. return (sourcemapCatch[sourcemapUrl] ||
  2484. (sourcemapCatch[sourcemapUrl] = new Promise((resolve, reject) => {
  2485. try {
  2486. if (/^[http|https]+:/i.test(sourcemapUrl)) {
  2487. uni.request({
  2488. url: sourcemapUrl,
  2489. success: (res) => {
  2490. if (res.statusCode === 200) {
  2491. sourcemapCatch[sourcemapUrl] = res.data;
  2492. resolve(sourcemapCatch[sourcemapUrl]);
  2493. }
  2494. else {
  2495. resolve((sourcemapCatch[sourcemapUrl] = ''));
  2496. }
  2497. },
  2498. fail() {
  2499. resolve((sourcemapCatch[sourcemapUrl] = ''));
  2500. },
  2501. });
  2502. }
  2503. else {
  2504. sourcemapCatch[sourcemapUrl] = fs__default.default.readFileSync(sourcemapUrl, 'utf-8');
  2505. resolve(sourcemapCatch[sourcemapUrl]);
  2506. }
  2507. }
  2508. catch (error) {
  2509. resolve('');
  2510. }
  2511. })));
  2512. }
  2513. catch (error) {
  2514. return '';
  2515. }
  2516. }
  2517. function parseSourceMapContent(consumer, obj, withSourceContent) {
  2518. // source -> 'uni-app:///node_modules/@sentry/browser/esm/helpers.js'
  2519. const { source, line: sourceLine, column: sourceColumn, } = consumer.originalPositionFor(obj);
  2520. if (source) {
  2521. const sourcePathSplit = source.split('/');
  2522. const sourcePath = sourcePathSplit.slice(3).join('/');
  2523. const fileName = sourcePathSplit.pop();
  2524. return {
  2525. source,
  2526. sourcePath,
  2527. sourceLine: sourceLine === null ? 0 : sourceLine,
  2528. sourceColumn: sourceColumn === null ? 0 : sourceColumn,
  2529. fileName,
  2530. sourceContent: withSourceContent
  2531. ? consumer.sourceContentFor(source) || ''
  2532. : '',
  2533. };
  2534. }
  2535. }
  2536. function joinItem(item) {
  2537. if (typeof item === 'string') {
  2538. return item;
  2539. }
  2540. const a = item[0];
  2541. const b = item[1] ? ` ${item[1]}` : '';
  2542. const c = item[2] ? ` ${item[2]}` : '';
  2543. return `${a}${b}${c}`;
  2544. }
  2545. function uniStracktraceyPreset(opts) {
  2546. const { base, sourceRoot, splitThirdParty, uniPlatform, lineOffset } = opts;
  2547. let stack;
  2548. return {
  2549. /**
  2550. *
  2551. * 微信特殊处理
  2552. * 微信解析步骤:
  2553. * 1. //usr/app-service.js -> 'weixin/__APP__/app-service.map.map'
  2554. * 2. //usr/pages/API/app-service.js -> 'weixin/pages/API/app-service.map.map'
  2555. * 3. uni-list-item/uni-list-item.js -> ${base}/uni-list-item/uni-list-item.js.map
  2556. */
  2557. parseSourceMapUrl(file, fileName, fileRelative) {
  2558. // 组合 sourceMapUrl
  2559. if (fileRelative.indexOf('(') !== -1)
  2560. fileRelative = fileRelative.match(/\((.*)/)[1];
  2561. if (!base || !fileRelative)
  2562. return '';
  2563. if (sourceRoot) {
  2564. return `${fileRelative.replace(sourceRoot, base + '/')}.map`;
  2565. }
  2566. let baseAfter = '';
  2567. if (stack.isMP) {
  2568. if (fileRelative.indexOf('app-service.js') !== -1) {
  2569. baseAfter = (base.match(/\w$/) ? '/' : '') + '__WEIXIN__';
  2570. if (fileRelative === fileName) {
  2571. baseAfter += '/__APP__';
  2572. }
  2573. fileRelative = fileRelative.replace('.js', '.map');
  2574. }
  2575. if (baseAfter && !!fileRelative.match(/^\w/))
  2576. baseAfter += '/';
  2577. }
  2578. return `${base}${baseAfter}${fileRelative}.map`;
  2579. },
  2580. getSourceMapContent(file, fileName, fileRelative) {
  2581. if (stack.isMP && fileRelative.indexOf('.js') === -1) {
  2582. return Promise.resolve('');
  2583. }
  2584. const sourcemapUrl = this.parseSourceMapUrl(file, fileName, fileRelative);
  2585. return Promise.resolve(getSourceMapContent(sourcemapUrl));
  2586. },
  2587. parseStacktrace(stacktrace) {
  2588. stack = new StackTracey$1(stacktrace, uniPlatform);
  2589. return stack;
  2590. },
  2591. asTableStacktrace({ maxColumnWidths, stacktrace, stack }) {
  2592. const errorName = stacktrace.split('\n')[0];
  2593. const lines = stack.asTable
  2594. ? stack.asTable(maxColumnWidths ? { maxColumnWidths } : undefined)
  2595. : { items: [], thirdPartyItems: [] };
  2596. if (lines.items.length || lines.thirdPartyItems.length) {
  2597. const { items: stackLines, thirdPartyItems: stackThirdPartyLines } = lines;
  2598. const userError = stack.itemsHeader
  2599. .map((item) => {
  2600. if (item === '%StacktraceyItem%') {
  2601. const _stack = stackLines.shift();
  2602. return _stack ? joinItem(_stack) : '';
  2603. }
  2604. return item;
  2605. })
  2606. .filter(Boolean)
  2607. .join('\n');
  2608. const thirdParty = stackThirdPartyLines.length
  2609. ? stackThirdPartyLines.map(joinItem).join('\n')
  2610. : '';
  2611. if (splitThirdParty) {
  2612. return {
  2613. userError,
  2614. thirdParty,
  2615. };
  2616. }
  2617. return userError + '\n' + thirdParty;
  2618. }
  2619. else {
  2620. if (splitThirdParty) {
  2621. return {
  2622. userError: errorName,
  2623. thirdParty: '',
  2624. };
  2625. }
  2626. return errorName;
  2627. }
  2628. },
  2629. lineOffset,
  2630. };
  2631. }
  2632. function utsStracktraceyPreset(opts) {
  2633. const { inputRoot, outputRoot, sourceMapRoot } = opts;
  2634. let errStack = [];
  2635. return {
  2636. parseSourceMapUrl(file, fileName, fileRelative) {
  2637. return path__default.default.resolve(sourceMapRoot, path__default.default.relative(outputRoot, file) + '.map');
  2638. },
  2639. getSourceMapContent(file, fileName, fileRelative) {
  2640. // 根据 base,filename 组合 sourceMapUrl
  2641. return Promise.resolve(getSourceMapContent(this.parseSourceMapUrl(file, fileName, fileRelative)));
  2642. },
  2643. parseStacktrace(str) {
  2644. const lines = (str || '').split('\n');
  2645. const entries = lines
  2646. .map((line, index) => {
  2647. line = line.trim();
  2648. const matches = line.match(/\s*(.+\.kt):([0-9]+):([0-9]+):\s+(.*)/);
  2649. if (matches) {
  2650. errStack.push('%StacktraceyItem%');
  2651. }
  2652. else {
  2653. errStack.push(line);
  2654. return;
  2655. }
  2656. const fileName = matches[1].replace(/^.*(\\|\/|\:)/, '');
  2657. return {
  2658. beforeParse: line,
  2659. callee: '',
  2660. index: false,
  2661. native: false,
  2662. file: nixSlashes(matches[1]),
  2663. line: parseInt(matches[2]),
  2664. column: parseInt(matches[3]),
  2665. fileName,
  2666. fileShort: line,
  2667. errMsg: matches[4] || '',
  2668. calleeShort: '',
  2669. fileRelative: '',
  2670. thirdParty: false,
  2671. };
  2672. })
  2673. .filter((x) => x !== undefined);
  2674. return {
  2675. items: entries,
  2676. itemsHeader: [],
  2677. };
  2678. },
  2679. asTableStacktrace({ maxColumnWidths, stacktrace, stack }) {
  2680. return errStack
  2681. .map((item) => {
  2682. if (item === '%StacktraceyItem%') {
  2683. const _stack = stack.items.shift();
  2684. if (_stack) {
  2685. return `at ${nixSlashes(path__default.default.relative(inputRoot, _stack.file.replace('\\\\?\\', '')))}:${_stack.line}:${_stack.column}
  2686. ${_stack.errMsg}`;
  2687. }
  2688. return '';
  2689. }
  2690. return item;
  2691. })
  2692. .join('\n');
  2693. },
  2694. };
  2695. }
  2696. exports.SourceMapConsumer = SourceMapConsumer;
  2697. exports.generateCodeFrame = generateCodeFrame;
  2698. exports.generateCodeFrameSourceMapConsumer = generateCodeFrameSourceMapConsumer;
  2699. exports.generateCodeFrameWithKotlinStacktrace = generateCodeFrameWithKotlinStacktrace;
  2700. exports.generateCodeFrameWithSourceMapPath = generateCodeFrameWithSourceMapPath;
  2701. exports.generateCodeFrameWithSwiftStacktrace = generateCodeFrameWithSwiftStacktrace;
  2702. exports.stacktracey = stacktracey;
  2703. exports.uniStracktraceyPreset = uniStracktraceyPreset;
  2704. exports.utsStracktraceyPreset = utsStracktraceyPreset;