source-map-resolve.js 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. // Note: source-map-resolve.js is generated from source-map-resolve-node.js and
  2. // source-map-resolve-template.js. Only edit the two latter files, _not_
  3. // source-map-resolve.js!
  4. void (function(root, factory) {
  5. if (typeof define === "function" && define.amd) {
  6. define(["source-map-url", "resolve-url"], factory)
  7. } else if (typeof exports === "object") {
  8. var sourceMappingURL = require("source-map-url")
  9. var resolveUrl = require("resolve-url")
  10. module.exports = factory(sourceMappingURL, resolveUrl)
  11. } else {
  12. root.sourceMapResolve = factory(root.sourceMappingURL, root.resolveUrl)
  13. }
  14. }(this, function(sourceMappingURL, resolveUrl) {
  15. function callbackAsync(callback, error, result) {
  16. setImmediate(function() { callback(error, result) })
  17. }
  18. function parseMapToJSON(string, data) {
  19. try {
  20. return JSON.parse(string.replace(/^\)\]\}'/, ""))
  21. } catch (error) {
  22. error.sourceMapData = data
  23. throw error
  24. }
  25. }
  26. function readSync(read, url, data) {
  27. var readUrl = url
  28. try {
  29. return String(read(readUrl))
  30. } catch (error) {
  31. error.sourceMapData = data
  32. throw error
  33. }
  34. }
  35. function resolveSourceMap(code, codeUrl, read, callback) {
  36. var mapData
  37. try {
  38. mapData = resolveSourceMapHelper(code, codeUrl)
  39. } catch (error) {
  40. return callbackAsync(callback, error)
  41. }
  42. if (!mapData || mapData.map) {
  43. return callbackAsync(callback, null, mapData)
  44. }
  45. var readUrl = mapData.url
  46. read(readUrl, function(error, result) {
  47. if (error) {
  48. error.sourceMapData = mapData
  49. return callback(error)
  50. }
  51. mapData.map = String(result)
  52. try {
  53. mapData.map = parseMapToJSON(mapData.map, mapData)
  54. } catch (error) {
  55. return callback(error)
  56. }
  57. callback(null, mapData)
  58. })
  59. }
  60. function resolveSourceMapSync(code, codeUrl, read) {
  61. var mapData = resolveSourceMapHelper(code, codeUrl)
  62. if (!mapData || mapData.map) {
  63. return mapData
  64. }
  65. mapData.map = readSync(read, mapData.url, mapData)
  66. mapData.map = parseMapToJSON(mapData.map, mapData)
  67. return mapData
  68. }
  69. var dataUriRegex = /^data:([^,;]*)(;[^,;]*)*(?:,(.*))?$/
  70. /**
  71. * The media type for JSON text is application/json.
  72. *
  73. * {@link https://tools.ietf.org/html/rfc8259#section-11 | IANA Considerations }
  74. *
  75. * `text/json` is non-standard media type
  76. */
  77. var jsonMimeTypeRegex = /^(?:application|text)\/json$/
  78. /**
  79. * JSON text exchanged between systems that are not part of a closed ecosystem
  80. * MUST be encoded using UTF-8.
  81. *
  82. * {@link https://tools.ietf.org/html/rfc8259#section-8.1 | Character Encoding}
  83. */
  84. var jsonCharacterEncoding = "utf-8"
  85. function base64ToBuf(b64) {
  86. var binStr = atob(b64)
  87. var len = binStr.length
  88. var arr = new Uint8Array(len)
  89. for (var i = 0; i < len; i++) {
  90. arr[i] = binStr.charCodeAt(i)
  91. }
  92. return arr
  93. }
  94. function decodeBase64String(b64) {
  95. if (typeof TextDecoder === "undefined" || typeof Uint8Array === "undefined") {
  96. return atob(b64)
  97. }
  98. var buf = base64ToBuf(b64);
  99. // Note: `decoder.decode` method will throw a `DOMException` with the
  100. // `"EncodingError"` value when an coding error is found.
  101. var decoder = new TextDecoder(jsonCharacterEncoding, {fatal: true})
  102. return decoder.decode(buf);
  103. }
  104. function resolveSourceMapHelper(code, codeUrl) {
  105. var url = sourceMappingURL.getFrom(code)
  106. if (!url) {
  107. return null
  108. }
  109. var dataUri = url.match(dataUriRegex)
  110. if (dataUri) {
  111. var mimeType = dataUri[1] || "text/plain"
  112. var lastParameter = dataUri[2] || ""
  113. var encoded = dataUri[3] || ""
  114. var data = {
  115. sourceMappingURL: url,
  116. url: null,
  117. sourcesRelativeTo: codeUrl,
  118. map: encoded
  119. }
  120. if (!jsonMimeTypeRegex.test(mimeType)) {
  121. var error = new Error("Unuseful data uri mime type: " + mimeType)
  122. error.sourceMapData = data
  123. throw error
  124. }
  125. try {
  126. data.map = parseMapToJSON(
  127. lastParameter === ";base64" ? decodeBase64String(encoded) : decodeURIComponent(encoded),
  128. data
  129. )
  130. } catch (error) {
  131. error.sourceMapData = data
  132. throw error
  133. }
  134. return data
  135. }
  136. var mapUrl = resolveUrl(codeUrl, url)
  137. return {
  138. sourceMappingURL: url,
  139. url: mapUrl,
  140. sourcesRelativeTo: mapUrl,
  141. map: null
  142. }
  143. }
  144. function resolveSources(map, mapUrl, read, options, callback) {
  145. if (typeof options === "function") {
  146. callback = options
  147. options = {}
  148. }
  149. var pending = map.sources ? map.sources.length : 0
  150. var result = {
  151. sourcesResolved: [],
  152. sourcesContent: []
  153. }
  154. if (pending === 0) {
  155. callbackAsync(callback, null, result)
  156. return
  157. }
  158. var done = function() {
  159. pending--
  160. if (pending === 0) {
  161. callback(null, result)
  162. }
  163. }
  164. resolveSourcesHelper(map, mapUrl, options, function(fullUrl, sourceContent, index) {
  165. result.sourcesResolved[index] = fullUrl
  166. if (typeof sourceContent === "string") {
  167. result.sourcesContent[index] = sourceContent
  168. callbackAsync(done, null)
  169. } else {
  170. var readUrl = fullUrl
  171. read(readUrl, function(error, source) {
  172. result.sourcesContent[index] = error ? error : String(source)
  173. done()
  174. })
  175. }
  176. })
  177. }
  178. function resolveSourcesSync(map, mapUrl, read, options) {
  179. var result = {
  180. sourcesResolved: [],
  181. sourcesContent: []
  182. }
  183. if (!map.sources || map.sources.length === 0) {
  184. return result
  185. }
  186. resolveSourcesHelper(map, mapUrl, options, function(fullUrl, sourceContent, index) {
  187. result.sourcesResolved[index] = fullUrl
  188. if (read !== null) {
  189. if (typeof sourceContent === "string") {
  190. result.sourcesContent[index] = sourceContent
  191. } else {
  192. var readUrl = fullUrl
  193. try {
  194. result.sourcesContent[index] = String(read(readUrl))
  195. } catch (error) {
  196. result.sourcesContent[index] = error
  197. }
  198. }
  199. }
  200. })
  201. return result
  202. }
  203. var endingSlash = /\/?$/
  204. function resolveSourcesHelper(map, mapUrl, options, fn) {
  205. options = options || {}
  206. var fullUrl
  207. var sourceContent
  208. var sourceRoot
  209. for (var index = 0, len = map.sources.length; index < len; index++) {
  210. sourceRoot = null
  211. if (typeof options.sourceRoot === "string") {
  212. sourceRoot = options.sourceRoot
  213. } else if (typeof map.sourceRoot === "string" && options.sourceRoot !== false) {
  214. sourceRoot = map.sourceRoot
  215. }
  216. // If the sourceRoot is the empty string, it is equivalent to not setting
  217. // the property at all.
  218. if (sourceRoot === null || sourceRoot === '') {
  219. fullUrl = resolveUrl(mapUrl, map.sources[index])
  220. } else {
  221. // Make sure that the sourceRoot ends with a slash, so that `/scripts/subdir` becomes
  222. // `/scripts/subdir/<source>`, not `/scripts/<source>`. Pointing to a file as source root
  223. // does not make sense.
  224. fullUrl = resolveUrl(mapUrl, sourceRoot.replace(endingSlash, "/"), map.sources[index])
  225. }
  226. sourceContent = (map.sourcesContent || [])[index]
  227. fn(fullUrl, sourceContent, index)
  228. }
  229. }
  230. function resolve(code, codeUrl, read, options, callback) {
  231. if (typeof options === "function") {
  232. callback = options
  233. options = {}
  234. }
  235. if (code === null) {
  236. var mapUrl = codeUrl
  237. var data = {
  238. sourceMappingURL: null,
  239. url: mapUrl,
  240. sourcesRelativeTo: mapUrl,
  241. map: null
  242. }
  243. var readUrl = mapUrl
  244. read(readUrl, function(error, result) {
  245. if (error) {
  246. error.sourceMapData = data
  247. return callback(error)
  248. }
  249. data.map = String(result)
  250. try {
  251. data.map = parseMapToJSON(data.map, data)
  252. } catch (error) {
  253. return callback(error)
  254. }
  255. _resolveSources(data)
  256. })
  257. } else {
  258. resolveSourceMap(code, codeUrl, read, function(error, mapData) {
  259. if (error) {
  260. return callback(error)
  261. }
  262. if (!mapData) {
  263. return callback(null, null)
  264. }
  265. _resolveSources(mapData)
  266. })
  267. }
  268. function _resolveSources(mapData) {
  269. resolveSources(mapData.map, mapData.sourcesRelativeTo, read, options, function(error, result) {
  270. if (error) {
  271. return callback(error)
  272. }
  273. mapData.sourcesResolved = result.sourcesResolved
  274. mapData.sourcesContent = result.sourcesContent
  275. callback(null, mapData)
  276. })
  277. }
  278. }
  279. function resolveSync(code, codeUrl, read, options) {
  280. var mapData
  281. if (code === null) {
  282. var mapUrl = codeUrl
  283. mapData = {
  284. sourceMappingURL: null,
  285. url: mapUrl,
  286. sourcesRelativeTo: mapUrl,
  287. map: null
  288. }
  289. mapData.map = readSync(read, mapUrl, mapData)
  290. mapData.map = parseMapToJSON(mapData.map, mapData)
  291. } else {
  292. mapData = resolveSourceMapSync(code, codeUrl, read)
  293. if (!mapData) {
  294. return null
  295. }
  296. }
  297. var result = resolveSourcesSync(mapData.map, mapData.sourcesRelativeTo, read, options)
  298. mapData.sourcesResolved = result.sourcesResolved
  299. mapData.sourcesContent = result.sourcesContent
  300. return mapData
  301. }
  302. return {
  303. resolveSourceMap: resolveSourceMap,
  304. resolveSourceMapSync: resolveSourceMapSync,
  305. resolveSources: resolveSources,
  306. resolveSourcesSync: resolveSourcesSync,
  307. resolve: resolve,
  308. resolveSync: resolveSync,
  309. parseMapToJSON: parseMapToJSON
  310. }
  311. }));