diff --git a/lib/internal/modules/helpers.js b/lib/internal/modules/helpers.js index d466cec51cfbf7..49804df442e1ed 100644 --- a/lib/internal/modules/helpers.js +++ b/lib/internal/modules/helpers.js @@ -307,10 +307,49 @@ function lazyLoadTSParser() { return parseTS; } +function doesTSStripTypesResultMatchSource(code, source) { + if (code.length !== source.length) return false + const sourceBuf = Buffer.from(source) + const codeBuf = Buffer.from(code) + for (let i = 0; i < codeBuf.length; i++) { + // should match either the source buffer or spaces (sometimes multi-byte) or semicolon + const val = codeBuf[i] + if (val === sourceBuf[i]) continue // source match + // https://github.com/nodejs/amaro/blob/e533394f576f946add41dd8816816435e8100c3b/deps/swc/crates/swc_fast_ts_strip/src/lib.rs#L400-L414 + if (val === 0x3b) continue // Semicolon 3b + // https://github.com/nodejs/amaro/blob/e533394f576f946add41dd8816816435e8100c3b/deps/swc/crates/swc_fast_ts_strip/src/lib.rs#L200-L226 + if (val === 0x20) continue // Space 20 + if (val === 0xc2) { + // No-Break Space 00A0 + if (i + 1 >= codeBuf.length) return false + if (codeBuf[++i] !== 0xa0) return false + continue + } + if (val === 0xc2) { + // En Space 2002 + if (i + 2 >= codeBuf.length) return false + if (codeBuf[++i] !== 0x80) return false + if (codeBuf[++i] !== 0x82) return false + continue + } + if (val === 0xef) { + // ZWNBSP FEFF + if (i < 1 || codeBuf[i - 1] !== 0x20) return false // only can get insterted after a space + if (i + 2 >= codeBuf.length) return false + if (codeBuf[++i] !== 0xbb) return false + if (codeBuf[++i] !== 0xbf) return false + continue + } + return false + } + return true +} + function tsParse(source) { if (!source || typeof source !== 'string') { return; } const transformSync = lazyLoadTSParser(); const { code } = transformSync(source, { mode: 'strip-only' }); + assert(doesTSStripTypesResultMatchSource(code, source), 'Unexpected strip-types result') return code; }