'use strict';
|
|
|
|
var assign = require('lodash.assign'),
|
|
defaults = require('lodash.defaults'),
|
|
camelcase = require('camelcase');
|
|
|
|
var debugMessage = require('./debug-message'),
|
|
toRegExp = require('./to-reg-exp'),
|
|
throwErrors = require('./throw-errors'),
|
|
decodeSourcesWith = require('./decode-sources-with'),
|
|
locateRootWith = require('./locate-root-with'),
|
|
encodeSourcesWith = require('./encode-sources-with'),
|
|
testCodec = require('./test-codec');
|
|
|
|
const CODECS = require('../../codec');
|
|
|
|
/**
|
|
* Process the given source-map per the given options.
|
|
* @param {{resourcePath:string, context:string, output:{path:string}}} context A loader or compilation
|
|
* @param {{debug:boolean, fail:boolean, format:string|boolean, root:string, codecs:object}} options Options hash
|
|
* @param {object|string} sourceMapOrSource An incoming source-map or single source path
|
|
* @returns {undefined|object|string} An amended source-map or source path else undefined
|
|
*/
|
|
function process(context, options, sourceMapOrSource) {
|
|
|
|
// default options
|
|
defaults(options, {
|
|
sep : '/',
|
|
debug : false,
|
|
fail : false,
|
|
format: false,
|
|
root : false,
|
|
codecs: CODECS
|
|
});
|
|
|
|
// validate codecs
|
|
var codecs = options.codecs
|
|
.filter(testCodec);
|
|
|
|
// determine what is present
|
|
var inputMap = !!sourceMapOrSource && (typeof sourceMapOrSource === 'object') && sourceMapOrSource,
|
|
inputPath = (typeof sourceMapOrSource === 'string') && sourceMapOrSource,
|
|
inputSources = inputMap && inputMap.sources || inputPath && [inputPath];
|
|
|
|
// what we need to produce
|
|
var absoluteSources,
|
|
outputSources,
|
|
outputRoot,
|
|
outputMap;
|
|
|
|
if (inputSources) {
|
|
|
|
// decode each source with the first valid codec
|
|
absoluteSources = inputSources
|
|
.map(decodeSourcesWith.call(context, codecs, options.fail));
|
|
|
|
// check for decode errors
|
|
throwErrors(context.resourcePath, absoluteSources);
|
|
|
|
// output map is a copy unless absent or we are removing
|
|
outputMap = (!inputMap || (options.format === 'remove')) ? undefined : assign({}, inputMap);
|
|
|
|
// some change in format
|
|
if (options.format) {
|
|
|
|
// find the specified codec in the codecs list
|
|
var codec = codecs
|
|
.filter(testNamedCodec)
|
|
.pop();
|
|
|
|
if (!codec) {
|
|
throw new Error('Specified format "' + options.format + '" does not match any available codec.');
|
|
}
|
|
|
|
// use the encoder where specified in 'format'
|
|
outputSources = absoluteSources
|
|
.map(encodeSourcesWith.call(context, codec))
|
|
.map(insertAbstractSources)
|
|
.map(convertPathSep);
|
|
|
|
outputRoot = !!options.root && locateRootWith.call(context, codec)() || undefined;
|
|
|
|
// check for encode errors
|
|
throwErrors(context.resourcePath, outputSources.concat(outputRoot));
|
|
|
|
// commit the change
|
|
if (outputMap) {
|
|
outputMap.sources = outputSources;
|
|
outputMap.sourceRoot = outputRoot;
|
|
}
|
|
}
|
|
}
|
|
|
|
// debugging information
|
|
var isDebug = toRegExp(options.debug).test(context.resourcePath);
|
|
if (isDebug) {
|
|
console.log(debugMessage(context, {
|
|
input : inputSources,
|
|
absolute: absoluteSources,
|
|
output : outputSources,
|
|
root : outputRoot
|
|
}));
|
|
}
|
|
|
|
// complete
|
|
return inputMap ? outputMap : outputSources ? outputSources[0] : undefined;
|
|
|
|
function testNamedCodec(value) {
|
|
return (camelcase(value.name) === options.format);
|
|
}
|
|
|
|
function insertAbstractSources(value, i) {
|
|
return value || inputSources[i];
|
|
}
|
|
|
|
function convertPathSep(value) {
|
|
return (value instanceof Error) ? value : value.replace(/[\\\/]/g, options.sep);
|
|
}
|
|
}
|
|
|
|
module.exports = process;
|