react / wstein / node_modules / browserify / node_modules / browser-pack / node_modules / combine-source-map / index.js
80538 views'use strict';12var path = require('path');3var convert = require('convert-source-map');4var memoize = require('lodash.memoize');5var createGenerator = require('inline-source-map');6var pathIsAbsolute = require('./lib/path-is-absolute');7var mappingsFromMap = require('./lib/mappings-from-map');89var protocolRx = /^[a-z]+:\/\//;1011/**12* Rebases a relative path in 'sourceFile' to be relative13* to the path where 'sourceFile' is located.14*15* This is necessary before adding relative paths to the16* new combined map to ensure all paths are relative to their17* original source.18*19* The 'sourceRoot' from the original source map is joined20* as well to ensure the complete path.21*22* Resulting paths that are absolute are passed along directly.23*24* @param sourceFile {String} path to the original source file that references a map25* @param relativeRoot {String} sourceRoot in sourceFile's map to combine with relativePath26* @param relativePath {String} source path from sourceFile's map27*/28var rebaseRelativePath = memoize(function(sourceFile, relativeRoot, relativePath) {29if (!relativePath) {30return relativePath;31}3233// join relative path to root (e.g. 'src/' + 'file.js')34var relativeRootedPath = relativeRoot ? path.join(relativeRoot, relativePath) : relativePath;3536if (sourceFile === relativeRootedPath || // same path,37pathIsAbsolute(relativeRootedPath) || // absolute path, nor38protocolRx.test(relativeRootedPath)) { // absolute protocol need rebasing39return relativeRootedPath;40}4142// make relative to source file43return path.join(path.dirname(sourceFile), relativeRootedPath);44}, function(a, b, c) {45return a + '::' + b + '::' + c;46});4748function resolveMap(source) {49var gen = convert.fromSource(source);50return gen ? gen.toObject() : null;51}5253function hasInlinedSource(existingMap) {54return existingMap.sourcesContent && !!existingMap.sourcesContent[0];55}5657function Combiner(file, sourceRoot) {58// since we include the original code in the map sourceRoot actually not needed59this.generator = createGenerator({ file: file || 'generated.js', sourceRoot: sourceRoot });60}6162Combiner.prototype._addGeneratedMap = function (sourceFile, source, offset) {63this.generator.addGeneratedMappings(sourceFile, source, offset);64this.generator.addSourceContent(sourceFile, source);65return this;66};6768Combiner.prototype._addExistingMap = function (sourceFile, source, existingMap, offset) {69var mappings = mappingsFromMap(existingMap);7071// add all of the sources from the map72for (var i = 0, len = existingMap.sources.length; i < len; i++) {73if (!existingMap.sourcesContent) continue;7475this.generator.addSourceContent(76rebaseRelativePath(sourceFile, existingMap.sourceRoot, existingMap.sources[i]),77existingMap.sourcesContent[i]);78}7980// add the mappings, preserving the original mapping 'source'81mappings.forEach(function(mapping) {82// Add the mappings one at a time because 'inline-source-map' doesn't handle83// mapping source filenames. The mapping.source already takes sourceRoot into account84// per the SMConsumer.eachMapping function, so pass null for the root here.85this.generator.addMappings(86rebaseRelativePath(sourceFile, null, mapping.source), [mapping], offset);87}, this);8889return this;90};9192/**93* Adds map to underlying source map.94* If source contains a source map comment that has the source of the original file inlined it will offset these95* mappings and include them.96* If no source map comment is found or it has no source inlined, mappings for the file will be generated and included97*98* @name addMap99* @function100* @param opts {Object} { sourceFile: {String}, source: {String} }101* @param offset {Object} { line: {Number}, column: {Number} }102*/103Combiner.prototype.addFile = function (opts, offset) {104105offset = offset || {};106if (!offset.hasOwnProperty('line')) offset.line = 0;107if (!offset.hasOwnProperty('column')) offset.column = 0;108109var existingMap = resolveMap(opts.source);110111return existingMap && hasInlinedSource(existingMap)112? this._addExistingMap(opts.sourceFile, opts.source, existingMap, offset)113: this._addGeneratedMap(opts.sourceFile, opts.source, offset);114};115116/**117* @name base64118* @function119* @return {String} base64 encoded combined source map120*/121Combiner.prototype.base64 = function () {122return this.generator.base64Encode();123};124125/**126* @name comment127* @function128* @return {String} base64 encoded sourceMappingUrl comment of the combined source map129*/130Combiner.prototype.comment = function () {131return this.generator.inlineMappingUrl();132};133134/**135* @name create136* @function137* @param file {String} optional name of the generated file138* @param sourceRoot {String} optional sourceRoot of the map to be generated139* @return {Object} Combiner instance to which source maps can be added and later combined140*/141exports.create = function (file, sourceRoot) { return new Combiner(file, sourceRoot); };142143/**144* @name removeComments145* @function146* @param src147* @return {String} src with all sourceMappingUrl comments removed148*/149exports.removeComments = function (src) {150if (!src.replace) return src;151return src.replace(convert.commentRegex, '').replace(convert.mapFileCommentRegex, '');152};153154155