transpileForNode
uses Buffer
The TypeScript runtime tcm uses, for compiling generated modules that use non-erasable syntax (JSX, enums). The output keeps the module's own source map, composed through the compilation, so it still leads to the definition (or scratch file) the code came from.
import { decodeMappings, encodeMappings, INLINE_MAP } from "#codebase/tcmts/core/program"; import { compiler } from "#codebase/tcmts/core/ts"; import { ScriptTarget as ts_ScriptTarget } from "typescript/ast"; import { JsxEmit as ts_JsxEmit, ModuleKind as ts_ModuleKind } from "typescript/sync"; export function transpileForNode(source: string, fileName: string): string { const input = INLINE_MAP.exec(source); const out = compiler().transpileModule(input ? source.slice(0, input.index) : source, { fileName, compilerOptions: { module: ts_ModuleKind.ESNext, target: ts_ScriptTarget.ES2022, preserveConstEnums: true, isolatedModules: true, verbatimModuleSyntax: false, jsx: ts_JsxEmit.ReactJSX, sourceMap: true, } as never, }); const code = out.outputText.replace(/\n?\/\/# sourceMappingURL=.*$/, ""); if (!input || !out.sourceMapText) return code; const outer = JSON.parse(out.sourceMapText) as { mappings: string }; const inner = JSON.parse(Buffer.from(input[1]!, "base64").toString("utf8")) as { sources: string[]; mappings: string }; const innerLines = decodeMappings(inner.mappings); // each compiled position → where it was in the module → where that was in the definition const composed = decodeMappings(outer.mappings).map((segs) => segs.flatMap(([gen, , line, col]) => { const at = (innerLines[line!] ?? []).filter((s) => s[0]! <= col!).at(-1); return at ? [[gen!, at[1]!, at[2]!, at[3]! + (col! - at[0]!)]] : []; }), ); const map = JSON.stringify({ version: 3, sources: inner.sources, names: [], mappings: encodeMappings(composed) }); return `${code}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,${Buffer.from(map).toString("base64")}\n`; }
uses
- tcmts.core.program.INLINE_MAP
- tcmts.core.program.decodeMappings
- tcmts.core.program.encodeMappings
- tcmts.core.ts.compiler