index.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. 'use strict';
  2. var debugMessage = require('./debug-message'),
  3. toRegExp = require('./to-reg-exp'),
  4. throwErrors = require('./throw-errors'),
  5. decodeSourcesWith = require('./decode-sources-with'),
  6. locateRootWith = require('./locate-root-with'),
  7. encodeSourcesWith = require('./encode-sources-with'),
  8. testCodec = require('./test-codec');
  9. var CODECS = require('../../codec');
  10. /**
  11. * Process the given source-map per the given options.
  12. * @param {{resourcePath:string, context:string, output:{path:string}}} context A loader or compilation
  13. * @param {{debug:boolean, fail:boolean, format:string|boolean, root:string, codecs:object}} opt Options hash
  14. * @param {object|string} sourceMapOrSource An incoming source-map or single source path
  15. * @returns {undefined|object|string} An amended source-map or source path else undefined
  16. */
  17. function process(context, opt, sourceMapOrSource) {
  18. // default options
  19. var options = Object.assign({
  20. sep : '/',
  21. debug : false,
  22. fail : false,
  23. format: false,
  24. root : false,
  25. codecs: CODECS
  26. }, opt);
  27. // validate codecs
  28. var codecs = options.codecs
  29. .filter(testCodec);
  30. // determine what is present
  31. var inputMap = !!sourceMapOrSource && (typeof sourceMapOrSource === 'object') && sourceMapOrSource,
  32. inputPath = (typeof sourceMapOrSource === 'string') && sourceMapOrSource,
  33. inputSources = inputMap && inputMap.sources || inputPath && [inputPath];
  34. // what we need to produce
  35. var absoluteSources,
  36. outputSources,
  37. outputRoot,
  38. outputMap;
  39. if (inputSources) {
  40. // decode each source with the first valid codec
  41. absoluteSources = inputSources
  42. .map(decodeSourcesWith.call(context, codecs, options.fail));
  43. // check for decode errors
  44. throwErrors(context.resourcePath, absoluteSources);
  45. // output map is a copy unless absent or we are removing
  46. outputMap = (!inputMap || (options.format === 'remove')) ? undefined : Object.assign({}, inputMap);
  47. // some change in format
  48. if (options.format) {
  49. // find the specified codec in the codecs list
  50. var codec = codecs
  51. .filter(testNamedCodec)
  52. .pop();
  53. if (!codec) {
  54. throw new Error('Specified format "' + options.format + '" does not match any available codec.');
  55. }
  56. // use the encoder where specified in 'format'
  57. outputSources = absoluteSources
  58. .map(encodeSourcesWith.call(context, codec))
  59. .map(insertAbstractSources)
  60. .map(convertPathSep);
  61. outputRoot = !!options.root && locateRootWith.call(context, codec)() || undefined;
  62. // check for encode errors
  63. throwErrors(context.resourcePath, outputSources.concat(outputRoot));
  64. // commit the change
  65. if (outputMap) {
  66. outputMap.sources = outputSources;
  67. outputMap.sourceRoot = outputRoot;
  68. }
  69. }
  70. }
  71. // debugging information
  72. var isDebug = toRegExp(options.debug).test(context.resourcePath);
  73. if (isDebug) {
  74. console.log(debugMessage(context, {
  75. input : inputSources,
  76. absolute: absoluteSources,
  77. output : outputSources,
  78. root : outputRoot
  79. }));
  80. }
  81. // complete
  82. return inputMap ? outputMap : outputSources ? outputSources[0] : undefined;
  83. function testNamedCodec(value) {
  84. return (value.name === options.format);
  85. }
  86. function insertAbstractSources(value, i) {
  87. return value || inputSources[i];
  88. }
  89. function convertPathSep(value) {
  90. return (value instanceof Error) ? value : value.replace(/[\\\/]/g, options.sep);
  91. }
  92. }
  93. module.exports = process;