1var fs = require('fs'); 2var path = require('path'); 3 4var isAllowedResource = require('./is-allowed-resource'); 5 6var hasProtocol = require('../utils/has-protocol'); 7var isRemoteResource = require('../utils/is-remote-resource'); 8 9function loadOriginalSources(context, callback) { 10 var loadContext = { 11 callback: callback, 12 fetch: context.options.fetch, 13 index: 0, 14 inline: context.options.inline, 15 inlineRequest: context.options.inlineRequest, 16 inlineTimeout: context.options.inlineTimeout, 17 localOnly: context.localOnly, 18 rebaseTo: context.options.rebaseTo, 19 sourcesContent: context.sourcesContent, 20 uriToSource: uriToSourceMapping(context.inputSourceMapTracker.all()), 21 warnings: context.warnings 22 }; 23 24 return context.options.sourceMap && context.options.sourceMapInlineSources ? 25 doLoadOriginalSources(loadContext) : 26 callback(); 27} 28 29function uriToSourceMapping(allSourceMapConsumers) { 30 var mapping = {}; 31 var consumer; 32 var uri; 33 var source; 34 var i, l; 35 36 for (source in allSourceMapConsumers) { 37 consumer = allSourceMapConsumers[source]; 38 39 for (i = 0, l = consumer.sources.length; i < l; i++) { 40 uri = consumer.sources[i]; 41 source = consumer.sourceContentFor(uri, true); 42 43 mapping[uri] = source; 44 } 45 } 46 47 return mapping; 48} 49 50function doLoadOriginalSources(loadContext) { 51 var uris = Object.keys(loadContext.uriToSource); 52 var uri; 53 var source; 54 var total; 55 56 for (total = uris.length; loadContext.index < total; loadContext.index++) { 57 uri = uris[loadContext.index]; 58 source = loadContext.uriToSource[uri]; 59 60 if (source) { 61 loadContext.sourcesContent[uri] = source; 62 } else { 63 return loadOriginalSource(uri, loadContext); 64 } 65 } 66 67 return loadContext.callback(); 68} 69 70function loadOriginalSource(uri, loadContext) { 71 var content; 72 73 if (isRemoteResource(uri)) { 74 return loadOriginalSourceFromRemoteUri(uri, loadContext, function (content) { 75 loadContext.index++; 76 loadContext.sourcesContent[uri] = content; 77 return doLoadOriginalSources(loadContext); 78 }); 79 } else { 80 content = loadOriginalSourceFromLocalUri(uri, loadContext); 81 loadContext.index++; 82 loadContext.sourcesContent[uri] = content; 83 return doLoadOriginalSources(loadContext); 84 } 85} 86 87function loadOriginalSourceFromRemoteUri(uri, loadContext, whenLoaded) { 88 var isAllowed = isAllowedResource(uri, true, loadContext.inline); 89 var isRuntimeResource = !hasProtocol(uri); 90 91 if (loadContext.localOnly) { 92 loadContext.warnings.push('Cannot fetch remote resource from "' + uri + '" as no callback given.'); 93 return whenLoaded(null); 94 } else if (isRuntimeResource) { 95 loadContext.warnings.push('Cannot fetch "' + uri + '" as no protocol given.'); 96 return whenLoaded(null); 97 } else if (!isAllowed) { 98 loadContext.warnings.push('Cannot fetch "' + uri + '" as resource is not allowed.'); 99 return whenLoaded(null); 100 } 101 102 loadContext.fetch(uri, loadContext.inlineRequest, loadContext.inlineTimeout, function (error, content) { 103 if (error) { 104 loadContext.warnings.push('Missing original source at "' + uri + '" - ' + error); 105 } 106 107 whenLoaded(content); 108 }); 109} 110 111function loadOriginalSourceFromLocalUri(relativeUri, loadContext) { 112 var isAllowed = isAllowedResource(relativeUri, false, loadContext.inline); 113 var absoluteUri = path.resolve(loadContext.rebaseTo, relativeUri); 114 115 if (!fs.existsSync(absoluteUri) || !fs.statSync(absoluteUri).isFile()) { 116 loadContext.warnings.push('Ignoring local source map at "' + absoluteUri + '" as resource is missing.'); 117 return null; 118 } else if (!isAllowed) { 119 loadContext.warnings.push('Cannot fetch "' + absoluteUri + '" as resource is not allowed.'); 120 return null; 121 } 122 123 return fs.readFileSync(absoluteUri, 'utf8'); 124} 125 126module.exports = loadOriginalSources; 127