|
| 1 | +import { decode as decode_mappings } from 'sourcemap-codec'; |
| 2 | +import { Processed } from './types'; |
| 3 | + |
| 4 | +/** |
| 5 | + * Import decoded sourcemap from mozilla/source-map/SourceMapGenerator |
| 6 | + * Forked from source-map/lib/source-map-generator.js |
| 7 | + * from methods _serializeMappings and toJSON. |
| 8 | + * We cannot use source-map.d.ts types, because we access hidden properties. |
| 9 | + */ |
| 10 | +function decoded_sourcemap_from_generator(generator: any) { |
| 11 | + let previous_generated_line = 1; |
| 12 | + const converted_mappings = [[]]; |
| 13 | + let result_line; |
| 14 | + let result_segment; |
| 15 | + let mapping; |
| 16 | + |
| 17 | + const source_idx = generator._sources.toArray() |
| 18 | + .reduce((acc, val, idx) => (acc[val] = idx, acc), {}); |
| 19 | + |
| 20 | + const name_idx = generator._names.toArray() |
| 21 | + .reduce((acc, val, idx) => (acc[val] = idx, acc), {}); |
| 22 | + |
| 23 | + const mappings = generator._mappings.toArray(); |
| 24 | + result_line = converted_mappings[0]; |
| 25 | + |
| 26 | + for (let i = 0, len = mappings.length; i < len; i++) { |
| 27 | + mapping = mappings[i]; |
| 28 | + |
| 29 | + if (mapping.generatedLine > previous_generated_line) { |
| 30 | + while (mapping.generatedLine > previous_generated_line) { |
| 31 | + converted_mappings.push([]); |
| 32 | + previous_generated_line++; |
| 33 | + } |
| 34 | + result_line = converted_mappings[mapping.generatedLine - 1]; // line is one-based |
| 35 | + } else if (i > 0) { |
| 36 | + const previous_mapping = mappings[i - 1]; |
| 37 | + if ( |
| 38 | + // sorted by selectivity |
| 39 | + mapping.generatedColumn === previous_mapping.generatedColumn && |
| 40 | + mapping.originalColumn === previous_mapping.originalColumn && |
| 41 | + mapping.name === previous_mapping.name && |
| 42 | + mapping.generatedLine === previous_mapping.generatedLine && |
| 43 | + mapping.originalLine === previous_mapping.originalLine && |
| 44 | + mapping.source === previous_mapping.source |
| 45 | + ) { |
| 46 | + continue; |
| 47 | + } |
| 48 | + } |
| 49 | + result_line.push([mapping.generatedColumn]); |
| 50 | + result_segment = result_line[result_line.length - 1]; |
| 51 | + |
| 52 | + if (mapping.source != null) { |
| 53 | + result_segment.push(...[ |
| 54 | + source_idx[mapping.source], |
| 55 | + mapping.originalLine - 1, // line is one-based |
| 56 | + mapping.originalColumn |
| 57 | + ]); |
| 58 | + if (mapping.name != null) { |
| 59 | + result_segment.push(name_idx[mapping.name]); |
| 60 | + } |
| 61 | + } |
| 62 | + } |
| 63 | + |
| 64 | + const map = { |
| 65 | + version: generator._version, |
| 66 | + sources: generator._sources.toArray(), |
| 67 | + names: generator._names.toArray(), |
| 68 | + mappings: converted_mappings |
| 69 | + }; |
| 70 | + if (generator._file != null) { |
| 71 | + (map as any).file = generator._file; |
| 72 | + } |
| 73 | + // not needed: map.sourcesContent and map.sourceRoot |
| 74 | + return map; |
| 75 | +} |
| 76 | + |
| 77 | +export function decode_map(processed: Processed) { |
| 78 | + let decoded_map = typeof processed.map === 'string' ? JSON.parse(processed.map) : processed.map; |
| 79 | + if (typeof(decoded_map.mappings) === 'string') { |
| 80 | + decoded_map.mappings = decode_mappings(decoded_map.mappings); |
| 81 | + } |
| 82 | + if ((decoded_map as any)._mappings && decoded_map.constructor.name === 'SourceMapGenerator') { |
| 83 | + // import decoded sourcemap from mozilla/source-map/SourceMapGenerator |
| 84 | + decoded_map = decoded_sourcemap_from_generator(decoded_map); |
| 85 | + } |
| 86 | + |
| 87 | + return decoded_map; |
| 88 | +} |
0 commit comments