remapping.umd.js 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@jridgewell/trace-mapping'), require('@jridgewell/gen-mapping')) :
  3. typeof define === 'function' && define.amd ? define(['@jridgewell/trace-mapping', '@jridgewell/gen-mapping'], factory) :
  4. (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.remapping = factory(global.traceMapping, global.genMapping));
  5. })(this, (function (traceMapping, genMapping) { 'use strict';
  6. const SOURCELESS_MAPPING = /* #__PURE__ */ SegmentObject('', -1, -1, '', null, false);
  7. const EMPTY_SOURCES = [];
  8. function SegmentObject(source, line, column, name, content, ignore) {
  9. return { source, line, column, name, content, ignore };
  10. }
  11. function Source(map, sources, source, content, ignore) {
  12. return {
  13. map,
  14. sources,
  15. source,
  16. content,
  17. ignore,
  18. };
  19. }
  20. /**
  21. * MapSource represents a single sourcemap, with the ability to trace mappings into its child nodes
  22. * (which may themselves be SourceMapTrees).
  23. */
  24. function MapSource(map, sources) {
  25. return Source(map, sources, '', null, false);
  26. }
  27. /**
  28. * A "leaf" node in the sourcemap tree, representing an original, unmodified source file. Recursive
  29. * segment tracing ends at the `OriginalSource`.
  30. */
  31. function OriginalSource(source, content, ignore) {
  32. return Source(null, EMPTY_SOURCES, source, content, ignore);
  33. }
  34. /**
  35. * traceMappings is only called on the root level SourceMapTree, and begins the process of
  36. * resolving each mapping in terms of the original source files.
  37. */
  38. function traceMappings(tree) {
  39. // TODO: Eventually support sourceRoot, which has to be removed because the sources are already
  40. // fully resolved. We'll need to make sources relative to the sourceRoot before adding them.
  41. const gen = new genMapping.GenMapping({ file: tree.map.file });
  42. const { sources: rootSources, map } = tree;
  43. const rootNames = map.names;
  44. const rootMappings = traceMapping.decodedMappings(map);
  45. for (let i = 0; i < rootMappings.length; i++) {
  46. const segments = rootMappings[i];
  47. for (let j = 0; j < segments.length; j++) {
  48. const segment = segments[j];
  49. const genCol = segment[0];
  50. let traced = SOURCELESS_MAPPING;
  51. // 1-length segments only move the current generated column, there's no source information
  52. // to gather from it.
  53. if (segment.length !== 1) {
  54. const source = rootSources[segment[1]];
  55. traced = originalPositionFor(source, segment[2], segment[3], segment.length === 5 ? rootNames[segment[4]] : '');
  56. // If the trace is invalid, then the trace ran into a sourcemap that doesn't contain a
  57. // respective segment into an original source.
  58. if (traced == null)
  59. continue;
  60. }
  61. const { column, line, name, content, source, ignore } = traced;
  62. genMapping.maybeAddSegment(gen, i, genCol, source, line, column, name);
  63. if (source && content != null)
  64. genMapping.setSourceContent(gen, source, content);
  65. if (ignore)
  66. genMapping.setIgnore(gen, source, true);
  67. }
  68. }
  69. return gen;
  70. }
  71. /**
  72. * originalPositionFor is only called on children SourceMapTrees. It recurses down into its own
  73. * child SourceMapTrees, until we find the original source map.
  74. */
  75. function originalPositionFor(source, line, column, name) {
  76. if (!source.map) {
  77. return SegmentObject(source.source, line, column, name, source.content, source.ignore);
  78. }
  79. const segment = traceMapping.traceSegment(source.map, line, column);
  80. // If we couldn't find a segment, then this doesn't exist in the sourcemap.
  81. if (segment == null)
  82. return null;
  83. // 1-length segments only move the current generated column, there's no source information
  84. // to gather from it.
  85. if (segment.length === 1)
  86. return SOURCELESS_MAPPING;
  87. return originalPositionFor(source.sources[segment[1]], segment[2], segment[3], segment.length === 5 ? source.map.names[segment[4]] : name);
  88. }
  89. function asArray(value) {
  90. if (Array.isArray(value))
  91. return value;
  92. return [value];
  93. }
  94. /**
  95. * Recursively builds a tree structure out of sourcemap files, with each node
  96. * being either an `OriginalSource` "leaf" or a `SourceMapTree` composed of
  97. * `OriginalSource`s and `SourceMapTree`s.
  98. *
  99. * Every sourcemap is composed of a collection of source files and mappings
  100. * into locations of those source files. When we generate a `SourceMapTree` for
  101. * the sourcemap, we attempt to load each source file's own sourcemap. If it
  102. * does not have an associated sourcemap, it is considered an original,
  103. * unmodified source file.
  104. */
  105. function buildSourceMapTree(input, loader) {
  106. const maps = asArray(input).map((m) => new traceMapping.TraceMap(m, ''));
  107. const map = maps.pop();
  108. for (let i = 0; i < maps.length; i++) {
  109. if (maps[i].sources.length > 1) {
  110. throw new Error(`Transformation map ${i} must have exactly one source file.\n` +
  111. 'Did you specify these with the most recent transformation maps first?');
  112. }
  113. }
  114. let tree = build(map, loader, '', 0);
  115. for (let i = maps.length - 1; i >= 0; i--) {
  116. tree = MapSource(maps[i], [tree]);
  117. }
  118. return tree;
  119. }
  120. function build(map, loader, importer, importerDepth) {
  121. const { resolvedSources, sourcesContent, ignoreList } = map;
  122. const depth = importerDepth + 1;
  123. const children = resolvedSources.map((sourceFile, i) => {
  124. // The loading context gives the loader more information about why this file is being loaded
  125. // (eg, from which importer). It also allows the loader to override the location of the loaded
  126. // sourcemap/original source, or to override the content in the sourcesContent field if it's
  127. // an unmodified source file.
  128. const ctx = {
  129. importer,
  130. depth,
  131. source: sourceFile || '',
  132. content: undefined,
  133. ignore: undefined,
  134. };
  135. // Use the provided loader callback to retrieve the file's sourcemap.
  136. // TODO: We should eventually support async loading of sourcemap files.
  137. const sourceMap = loader(ctx.source, ctx);
  138. const { source, content, ignore } = ctx;
  139. // If there is a sourcemap, then we need to recurse into it to load its source files.
  140. if (sourceMap)
  141. return build(new traceMapping.TraceMap(sourceMap, source), loader, source, depth);
  142. // Else, it's an unmodified source file.
  143. // The contents of this unmodified source file can be overridden via the loader context,
  144. // allowing it to be explicitly null or a string. If it remains undefined, we fall back to
  145. // the importing sourcemap's `sourcesContent` field.
  146. const sourceContent = content !== undefined ? content : sourcesContent ? sourcesContent[i] : null;
  147. const ignored = ignore !== undefined ? ignore : ignoreList ? ignoreList.includes(i) : false;
  148. return OriginalSource(source, sourceContent, ignored);
  149. });
  150. return MapSource(map, children);
  151. }
  152. /**
  153. * A SourceMap v3 compatible sourcemap, which only includes fields that were
  154. * provided to it.
  155. */
  156. class SourceMap {
  157. constructor(map, options) {
  158. const out = options.decodedMappings ? genMapping.toDecodedMap(map) : genMapping.toEncodedMap(map);
  159. this.version = out.version; // SourceMap spec says this should be first.
  160. this.file = out.file;
  161. this.mappings = out.mappings;
  162. this.names = out.names;
  163. this.ignoreList = out.ignoreList;
  164. this.sourceRoot = out.sourceRoot;
  165. this.sources = out.sources;
  166. if (!options.excludeContent) {
  167. this.sourcesContent = out.sourcesContent;
  168. }
  169. }
  170. toString() {
  171. return JSON.stringify(this);
  172. }
  173. }
  174. /**
  175. * Traces through all the mappings in the root sourcemap, through the sources
  176. * (and their sourcemaps), all the way back to the original source location.
  177. *
  178. * `loader` will be called every time we encounter a source file. If it returns
  179. * a sourcemap, we will recurse into that sourcemap to continue the trace. If
  180. * it returns a falsey value, that source file is treated as an original,
  181. * unmodified source file.
  182. *
  183. * Pass `excludeContent` to exclude any self-containing source file content
  184. * from the output sourcemap.
  185. *
  186. * Pass `decodedMappings` to receive a SourceMap with decoded (instead of
  187. * VLQ encoded) mappings.
  188. */
  189. function remapping(input, loader, options) {
  190. const opts = typeof options === 'object' ? options : { excludeContent: !!options, decodedMappings: false };
  191. const tree = buildSourceMapTree(input, loader);
  192. return new SourceMap(traceMappings(tree), opts);
  193. }
  194. return remapping;
  195. }));
  196. //# sourceMappingURL=remapping.umd.js.map