You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							205 lines
						
					
					
						
							8.3 KiB
						
					
					
				
			
		
		
	
	
							205 lines
						
					
					
						
							8.3 KiB
						
					
					
				import { decodedMappings, traceSegment, TraceMap } from '@jridgewell/trace-mapping';
 | 
						|
import { GenMapping, addSegment, setSourceContent, decodedMap, encodedMap } from '@jridgewell/gen-mapping';
 | 
						|
 | 
						|
const SOURCELESS_MAPPING = {
 | 
						|
    source: null,
 | 
						|
    column: null,
 | 
						|
    line: null,
 | 
						|
    name: null,
 | 
						|
    content: null,
 | 
						|
};
 | 
						|
const EMPTY_SOURCES = [];
 | 
						|
function Source(map, sources, source, content) {
 | 
						|
    return {
 | 
						|
        map,
 | 
						|
        sources,
 | 
						|
        source,
 | 
						|
        content,
 | 
						|
    };
 | 
						|
}
 | 
						|
/**
 | 
						|
 * MapSource represents a single sourcemap, with the ability to trace mappings into its child nodes
 | 
						|
 * (which may themselves be SourceMapTrees).
 | 
						|
 */
 | 
						|
function MapSource(map, sources) {
 | 
						|
    return Source(map, sources, '', null);
 | 
						|
}
 | 
						|
/**
 | 
						|
 * A "leaf" node in the sourcemap tree, representing an original, unmodified source file. Recursive
 | 
						|
 * segment tracing ends at the `OriginalSource`.
 | 
						|
 */
 | 
						|
function OriginalSource(source, content) {
 | 
						|
    return Source(null, EMPTY_SOURCES, source, content);
 | 
						|
}
 | 
						|
/**
 | 
						|
 * traceMappings is only called on the root level SourceMapTree, and begins the process of
 | 
						|
 * resolving each mapping in terms of the original source files.
 | 
						|
 */
 | 
						|
function traceMappings(tree) {
 | 
						|
    const gen = new GenMapping({ file: tree.map.file });
 | 
						|
    const { sources: rootSources, map } = tree;
 | 
						|
    const rootNames = map.names;
 | 
						|
    const rootMappings = decodedMappings(map);
 | 
						|
    for (let i = 0; i < rootMappings.length; i++) {
 | 
						|
        const segments = rootMappings[i];
 | 
						|
        let lastSource = null;
 | 
						|
        let lastSourceLine = null;
 | 
						|
        let lastSourceColumn = null;
 | 
						|
        for (let j = 0; j < segments.length; j++) {
 | 
						|
            const segment = segments[j];
 | 
						|
            const genCol = segment[0];
 | 
						|
            let traced = SOURCELESS_MAPPING;
 | 
						|
            // 1-length segments only move the current generated column, there's no source information
 | 
						|
            // to gather from it.
 | 
						|
            if (segment.length !== 1) {
 | 
						|
                const source = rootSources[segment[1]];
 | 
						|
                traced = originalPositionFor(source, segment[2], segment[3], segment.length === 5 ? rootNames[segment[4]] : '');
 | 
						|
                // If the trace is invalid, then the trace ran into a sourcemap that doesn't contain a
 | 
						|
                // respective segment into an original source.
 | 
						|
                if (traced == null)
 | 
						|
                    continue;
 | 
						|
            }
 | 
						|
            // So we traced a segment down into its original source file. Now push a
 | 
						|
            // new segment pointing to this location.
 | 
						|
            const { column, line, name, content, source } = traced;
 | 
						|
            if (line === lastSourceLine && column === lastSourceColumn && source === lastSource) {
 | 
						|
                continue;
 | 
						|
            }
 | 
						|
            lastSourceLine = line;
 | 
						|
            lastSourceColumn = column;
 | 
						|
            lastSource = source;
 | 
						|
            // Sigh, TypeScript can't figure out source/line/column are either all null, or all non-null...
 | 
						|
            addSegment(gen, i, genCol, source, line, column, name);
 | 
						|
            if (content != null)
 | 
						|
                setSourceContent(gen, source, content);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return gen;
 | 
						|
}
 | 
						|
/**
 | 
						|
 * originalPositionFor is only called on children SourceMapTrees. It recurses down into its own
 | 
						|
 * child SourceMapTrees, until we find the original source map.
 | 
						|
 */
 | 
						|
function originalPositionFor(source, line, column, name) {
 | 
						|
    if (!source.map) {
 | 
						|
        return { column, line, name, source: source.source, content: source.content };
 | 
						|
    }
 | 
						|
    const segment = traceSegment(source.map, line, column);
 | 
						|
    // If we couldn't find a segment, then this doesn't exist in the sourcemap.
 | 
						|
    if (segment == null)
 | 
						|
        return null;
 | 
						|
    // 1-length segments only move the current generated column, there's no source information
 | 
						|
    // to gather from it.
 | 
						|
    if (segment.length === 1)
 | 
						|
        return SOURCELESS_MAPPING;
 | 
						|
    return originalPositionFor(source.sources[segment[1]], segment[2], segment[3], segment.length === 5 ? source.map.names[segment[4]] : name);
 | 
						|
}
 | 
						|
 | 
						|
function asArray(value) {
 | 
						|
    if (Array.isArray(value))
 | 
						|
        return value;
 | 
						|
    return [value];
 | 
						|
}
 | 
						|
/**
 | 
						|
 * Recursively builds a tree structure out of sourcemap files, with each node
 | 
						|
 * being either an `OriginalSource` "leaf" or a `SourceMapTree` composed of
 | 
						|
 * `OriginalSource`s and `SourceMapTree`s.
 | 
						|
 *
 | 
						|
 * Every sourcemap is composed of a collection of source files and mappings
 | 
						|
 * into locations of those source files. When we generate a `SourceMapTree` for
 | 
						|
 * the sourcemap, we attempt to load each source file's own sourcemap. If it
 | 
						|
 * does not have an associated sourcemap, it is considered an original,
 | 
						|
 * unmodified source file.
 | 
						|
 */
 | 
						|
function buildSourceMapTree(input, loader) {
 | 
						|
    const maps = asArray(input).map((m) => new TraceMap(m, ''));
 | 
						|
    const map = maps.pop();
 | 
						|
    for (let i = 0; i < maps.length; i++) {
 | 
						|
        if (maps[i].sources.length > 1) {
 | 
						|
            throw new Error(`Transformation map ${i} must have exactly one source file.\n` +
 | 
						|
                'Did you specify these with the most recent transformation maps first?');
 | 
						|
        }
 | 
						|
    }
 | 
						|
    let tree = build(map, loader, '', 0);
 | 
						|
    for (let i = maps.length - 1; i >= 0; i--) {
 | 
						|
        tree = MapSource(maps[i], [tree]);
 | 
						|
    }
 | 
						|
    return tree;
 | 
						|
}
 | 
						|
function build(map, loader, importer, importerDepth) {
 | 
						|
    const { resolvedSources, sourcesContent } = map;
 | 
						|
    const depth = importerDepth + 1;
 | 
						|
    const children = resolvedSources.map((sourceFile, i) => {
 | 
						|
        // The loading context gives the loader more information about why this file is being loaded
 | 
						|
        // (eg, from which importer). It also allows the loader to override the location of the loaded
 | 
						|
        // sourcemap/original source, or to override the content in the sourcesContent field if it's
 | 
						|
        // an unmodified source file.
 | 
						|
        const ctx = {
 | 
						|
            importer,
 | 
						|
            depth,
 | 
						|
            source: sourceFile || '',
 | 
						|
            content: undefined,
 | 
						|
        };
 | 
						|
        // Use the provided loader callback to retrieve the file's sourcemap.
 | 
						|
        // TODO: We should eventually support async loading of sourcemap files.
 | 
						|
        const sourceMap = loader(ctx.source, ctx);
 | 
						|
        const { source, content } = ctx;
 | 
						|
        // If there is a sourcemap, then we need to recurse into it to load its source files.
 | 
						|
        if (sourceMap)
 | 
						|
            return build(new TraceMap(sourceMap, source), loader, source, depth);
 | 
						|
        // Else, it's an an unmodified source file.
 | 
						|
        // The contents of this unmodified source file can be overridden via the loader context,
 | 
						|
        // allowing it to be explicitly null or a string. If it remains undefined, we fall back to
 | 
						|
        // the importing sourcemap's `sourcesContent` field.
 | 
						|
        const sourceContent = content !== undefined ? content : sourcesContent ? sourcesContent[i] : null;
 | 
						|
        return OriginalSource(source, sourceContent);
 | 
						|
    });
 | 
						|
    return MapSource(map, children);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * A SourceMap v3 compatible sourcemap, which only includes fields that were
 | 
						|
 * provided to it.
 | 
						|
 */
 | 
						|
class SourceMap {
 | 
						|
    constructor(map, options) {
 | 
						|
        const out = options.decodedMappings ? decodedMap(map) : encodedMap(map);
 | 
						|
        this.version = out.version; // SourceMap spec says this should be first.
 | 
						|
        this.file = out.file;
 | 
						|
        this.mappings = out.mappings;
 | 
						|
        this.names = out.names;
 | 
						|
        this.sourceRoot = out.sourceRoot;
 | 
						|
        this.sources = out.sources;
 | 
						|
        if (!options.excludeContent) {
 | 
						|
            this.sourcesContent = out.sourcesContent;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    toString() {
 | 
						|
        return JSON.stringify(this);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Traces through all the mappings in the root sourcemap, through the sources
 | 
						|
 * (and their sourcemaps), all the way back to the original source location.
 | 
						|
 *
 | 
						|
 * `loader` will be called every time we encounter a source file. If it returns
 | 
						|
 * a sourcemap, we will recurse into that sourcemap to continue the trace. If
 | 
						|
 * it returns a falsey value, that source file is treated as an original,
 | 
						|
 * unmodified source file.
 | 
						|
 *
 | 
						|
 * Pass `excludeContent` to exclude any self-containing source file content
 | 
						|
 * from the output sourcemap.
 | 
						|
 *
 | 
						|
 * Pass `decodedMappings` to receive a SourceMap with decoded (instead of
 | 
						|
 * VLQ encoded) mappings.
 | 
						|
 */
 | 
						|
function remapping(input, loader, options) {
 | 
						|
    const opts = typeof options === 'object' ? options : { excludeContent: !!options, decodedMappings: false };
 | 
						|
    const tree = buildSourceMapTree(input, loader);
 | 
						|
    return new SourceMap(traceMappings(tree), opts);
 | 
						|
}
 | 
						|
 | 
						|
export { remapping as default };
 | 
						|
//# sourceMappingURL=remapping.mjs.map
 |