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