Skip to content

@ttsc/banner corrupts source maps: source-level preamble shifts .js.map/.d.ts.map line numbers #211

@samchon

Description

@samchon

Summary

@ttsc/banner (and any SourcePreamblePlugin) corrupts emitted source maps: every mapping for real code points N lines too deep — onto blank lines past the end of the on-disk source — where N is the banner's line count. Both .js.map and .d.ts.map are affected. Debugging a banner'd project jumps to the wrong line.

Root cause

The banner is injected at the source level: sourcePreambleFS prepends the preamble to each source file before TypeScript-Go parses it (so it participates in comment emission, removeComments, JSDoc association and .d.ts emit). The side effect: every source coordinate the emitter records is shifted down by the preamble's line count, but the sources-referenced file on disk has no preamble. So a mapping that should say "source line 0" says "source line N".

Decoded example (4-line banner over a 5-line file): exports.first = 111 mapped to source line 9 (blank) instead of line 0. export declare const first in the .d.ts.map had the identical shift.

The existing banner test only asserted the banner text is absent from the map — it never decoded the mappings, so the line shift went unnoticed.

Fix

Post-emit, rewrite .js.map / .d.ts.map mappings: drop segments inside the preamble region (source line < N, i.e. the emitted banner comment, which has no real-source counterpart) and subtract N from every remaining segment's source line. Wired into the utility host's WriteFile so it runs for both maps, and even under removeComments (where the banner is stripped from output but the source is still preamble-shifted).

This keeps all other banner behavior (output text, .d.ts, removeComments, JSDoc) untouched — only the map's source axis is corrected. Covered by a Go unit test (VLQ round-trip on a real shifted map) and a banner e2e test that decodes both maps and asserts no mapping escapes the real source.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions