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!
5 void (function(root, factory) {
6 if (typeof define === "function" && define.amd) {
7 define(["source-map-url", "resolve-url"], factory)
8 } else if (typeof exports === "object") {
9 var sourceMappingURL = require("source-map-url")
10 var resolveUrl = require("resolve-url")
11 module.exports = factory(sourceMappingURL, resolveUrl)
13 root.sourceMapResolve = factory(root.sourceMappingURL, root.resolveUrl)
15 }(this, function(sourceMappingURL, resolveUrl) {
17 function callbackAsync(callback, error, result) {
18 setImmediate(function() { callback(error, result) })
21 function parseMapToJSON(string, data) {
23 return JSON.parse(string.replace(/^\)\]\}'/, ""))
25 error.sourceMapData = data
30 function readSync(read, url, data) {
33 return String(read(readUrl))
35 error.sourceMapData = data
42 function resolveSourceMap(code, codeUrl, read, callback) {
45 mapData = resolveSourceMapHelper(code, codeUrl)
47 return callbackAsync(callback, error)
49 if (!mapData || mapData.map) {
50 return callbackAsync(callback, null, mapData)
52 var readUrl = mapData.url
53 read(readUrl, function(error, result) {
55 error.sourceMapData = mapData
56 return callback(error)
58 mapData.map = String(result)
60 mapData.map = parseMapToJSON(mapData.map, mapData)
62 return callback(error)
64 callback(null, mapData)
68 function resolveSourceMapSync(code, codeUrl, read) {
69 var mapData = resolveSourceMapHelper(code, codeUrl)
70 if (!mapData || mapData.map) {
73 mapData.map = readSync(read, mapData.url, mapData)
74 mapData.map = parseMapToJSON(mapData.map, mapData)
78 var dataUriRegex = /^data:([^,;]*)(;[^,;]*)*(?:,(.*))?$/
81 * The media type for JSON text is application/json.
83 * {@link https://tools.ietf.org/html/rfc8259#section-11 | IANA Considerations }
85 * `text/json` is non-standard media type
87 var jsonMimeTypeRegex = /^(?:application|text)\/json$/
90 * JSON text exchanged between systems that are not part of a closed ecosystem
91 * MUST be encoded using UTF-8.
93 * {@link https://tools.ietf.org/html/rfc8259#section-8.1 | Character Encoding}
95 var jsonCharacterEncoding = "utf-8"
97 function base64ToBuf(b64) {
98 var binStr = atob(b64)
99 var len = binStr.length
100 var arr = new Uint8Array(len)
101 for (var i = 0; i < len; i++) {
102 arr[i] = binStr.charCodeAt(i)
107 function decodeBase64String(b64) {
108 if (typeof TextDecoder === "undefined" || typeof Uint8Array === "undefined") {
111 var buf = base64ToBuf(b64);
112 // Note: `decoder.decode` method will throw a `DOMException` with the
113 // `"EncodingError"` value when an coding error is found.
114 var decoder = new TextDecoder(jsonCharacterEncoding, {fatal: true})
115 return decoder.decode(buf);
118 function resolveSourceMapHelper(code, codeUrl) {
119 var url = sourceMappingURL.getFrom(code)
124 var dataUri = url.match(dataUriRegex)
126 var mimeType = dataUri[1] || "text/plain"
127 var lastParameter = dataUri[2] || ""
128 var encoded = dataUri[3] || ""
130 sourceMappingURL: url,
132 sourcesRelativeTo: codeUrl,
135 if (!jsonMimeTypeRegex.test(mimeType)) {
136 var error = new Error("Unuseful data uri mime type: " + mimeType)
137 error.sourceMapData = data
141 data.map = parseMapToJSON(
142 lastParameter === ";base64" ? decodeBase64String(encoded) : decodeURIComponent(encoded),
146 error.sourceMapData = data
152 var mapUrl = resolveUrl(codeUrl, url)
154 sourceMappingURL: url,
156 sourcesRelativeTo: mapUrl,
163 function resolveSources(map, mapUrl, read, options, callback) {
164 if (typeof options === "function") {
168 var pending = map.sources ? map.sources.length : 0
175 callbackAsync(callback, null, result)
179 var done = function() {
182 callback(null, result)
186 resolveSourcesHelper(map, mapUrl, options, function(fullUrl, sourceContent, index) {
187 result.sourcesResolved[index] = fullUrl
188 if (typeof sourceContent === "string") {
189 result.sourcesContent[index] = sourceContent
190 callbackAsync(done, null)
192 var readUrl = fullUrl
193 read(readUrl, function(error, source) {
194 result.sourcesContent[index] = error ? error : String(source)
201 function resolveSourcesSync(map, mapUrl, read, options) {
207 if (!map.sources || map.sources.length === 0) {
211 resolveSourcesHelper(map, mapUrl, options, function(fullUrl, sourceContent, index) {
212 result.sourcesResolved[index] = fullUrl
214 if (typeof sourceContent === "string") {
215 result.sourcesContent[index] = sourceContent
217 var readUrl = fullUrl
219 result.sourcesContent[index] = String(read(readUrl))
221 result.sourcesContent[index] = error
230 var endingSlash = /\/?$/
232 function resolveSourcesHelper(map, mapUrl, options, fn) {
233 options = options || {}
237 for (var index = 0, len = map.sources.length; index < len; index++) {
239 if (typeof options.sourceRoot === "string") {
240 sourceRoot = options.sourceRoot
241 } else if (typeof map.sourceRoot === "string" && options.sourceRoot !== false) {
242 sourceRoot = map.sourceRoot
244 // If the sourceRoot is the empty string, it is equivalent to not setting
245 // the property at all.
246 if (sourceRoot === null || sourceRoot === '') {
247 fullUrl = resolveUrl(mapUrl, map.sources[index])
249 // Make sure that the sourceRoot ends with a slash, so that `/scripts/subdir` becomes
250 // `/scripts/subdir/<source>`, not `/scripts/<source>`. Pointing to a file as source root
251 // does not make sense.
252 fullUrl = resolveUrl(mapUrl, sourceRoot.replace(endingSlash, "/"), map.sources[index])
254 sourceContent = (map.sourcesContent || [])[index]
255 fn(fullUrl, sourceContent, index)
261 function resolve(code, codeUrl, read, options, callback) {
262 if (typeof options === "function") {
269 sourceMappingURL: null,
271 sourcesRelativeTo: mapUrl,
275 read(readUrl, function(error, result) {
277 error.sourceMapData = data
278 return callback(error)
280 data.map = String(result)
282 data.map = parseMapToJSON(data.map, data)
284 return callback(error)
286 _resolveSources(data)
289 resolveSourceMap(code, codeUrl, read, function(error, mapData) {
291 return callback(error)
294 return callback(null, null)
296 _resolveSources(mapData)
300 function _resolveSources(mapData) {
301 resolveSources(mapData.map, mapData.sourcesRelativeTo, read, options, function(error, result) {
303 return callback(error)
305 mapData.sourcesResolved = result.sourcesResolved
306 mapData.sourcesContent = result.sourcesContent
307 callback(null, mapData)
312 function resolveSync(code, codeUrl, read, options) {
317 sourceMappingURL: null,
319 sourcesRelativeTo: mapUrl,
322 mapData.map = readSync(read, mapUrl, mapData)
323 mapData.map = parseMapToJSON(mapData.map, mapData)
325 mapData = resolveSourceMapSync(code, codeUrl, read)
330 var result = resolveSourcesSync(mapData.map, mapData.sourcesRelativeTo, read, options)
331 mapData.sourcesResolved = result.sourcesResolved
332 mapData.sourcesContent = result.sourcesContent
339 resolveSourceMap: resolveSourceMap,
340 resolveSourceMapSync: resolveSourceMapSync,
341 resolveSources: resolveSources,
342 resolveSourcesSync: resolveSourcesSync,
344 resolveSync: resolveSync,
345 parseMapToJSON: parseMapToJSON