Skip to content

Commit

Permalink
Add ability to generate source maps
Browse files Browse the repository at this point in the history
  • Loading branch information
L2jLiga committed Oct 29, 2020
1 parent 1e4deb7 commit 04481cc
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 8 deletions.
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,10 +246,17 @@ downlevelled, nor are there any other plans to support Typescript 2.x.
### Downlevel semantics
## Source map
Source map generation can be enabled by `--source-map` flag. Currently,
it will provide mappings only from source definition to downlevelled. In
case you need have full mapping from source file to downlevelled definition
you can use [`merge-source-maps`](https://www.npmjs.com/package/merge-source-maps) library.
## Usage
1. `$ npm install downlevel-dts`
2. `$ npx downlevel-dts . ts3.4 [--to=3.4]`
2. `$ npx downlevel-dts . ts3.4 [--to=3.4] [--source-map]`
3. To your package.json, add
```json
Expand Down
61 changes: 55 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,47 +7,80 @@ const assert = require("assert");
const semver = require("semver");

/** @typedef {import("typescript").Node} Node */

/**
* @typedef {Object} Options
* @property {import("semver").SemVer} targetVersion
* @property {boolean} sourceMaps
*/
/**
* @param {string} src
* @param {string} target
* @param {import("semver").SemVer} targetVersion
* @param {Options} options
*/
function main(src, target, targetVersion) {
function main(src, target, options) {
if (!src || !target) {
console.log("Usage: node index.js test test/ts3.4 [--to=3.4]");
process.exit(1);
}

const host = ts.createCompilerHost({});

// TODO: target path is probably wrong for absolute src (or target?)
// TODO: Probably will want to alter package.json if discovered in the right place.
const program = ts.createProgram(
sh.find(path.join(src)).filter(f => f.endsWith(".d.ts") && !/node_modules/.test(f)),
{}
{},
host
);
const checker = program.getTypeChecker(); // just used for setting parent pointers right now
const files = mapDefined(program.getRootFileNames(), program.getSourceFile);
const printer = ts.createPrinter({
newLine: ts.NewLineKind.CarriageReturnLineFeed
});
for (const t of ts.transform(files, [doTransform.bind(null, checker, targetVersion)]).transformed) {

const writer = ts.createTextWriter(host.getNewLine());

for (const t of ts.transform(files, [doTransform.bind(null, checker, options.targetVersion)]).transformed) {
const f = /** @type {import("typescript").SourceFile} */ (t);
const targetPath = path.join(target, path.resolve(f.fileName).slice(path.resolve(src).length));
const fileName = path.basename(path.resolve(f.fileName));
sh.mkdir("-p", path.dirname(targetPath));
fs.writeFileSync(targetPath, dedupeTripleSlash(printer.printFile(f)));
let sourceMapGenerator;
if (options.sourceMaps) {
sourceMapGenerator = ts.createSourceMapGenerator(
host,
fileName,
path.dirname(path.relative(targetPath, path.resolve(src))),
path.resolve(src),
{}
);
}

printer.writeFile(f, writer, sourceMapGenerator);

if (options.sourceMaps) {
fs.writeFileSync(targetPath + ".map", sourceMapGenerator.toString());
fs.writeFileSync(targetPath, dedupeTripleSlash(addSourceMapUrl(fileName, writer.getText())));
} else {
fs.writeFileSync(targetPath, dedupeTripleSlash(writer.getText()));
}
writer.clear();
}
}
module.exports.main = main;

if (!(/** @type {*} */ (module.parent))) {
const src = process.argv[2];
const target = process.argv[3];
const sourceMaps = process.argv.includes("--source-map");
const to = process.argv.find(arg => arg.startsWith("--to"));
/** @type {*} */ let targetVersion = semver.minVersion("3.4.0");
if (to) {
const userInput = semver.coerce(to.split("=")[1]);
if (userInput) targetVersion = userInput;
}
main(src, target, targetVersion);
main(src, target, { targetVersion, sourceMaps });
}

/**
Expand Down Expand Up @@ -248,6 +281,22 @@ function dedupeTripleSlash(s) {
return [...new Set(lines.slice(0, i)), ...lines.slice(i)].join("\n");
}

/**
* @param {string} fileName
* @param {string} content
*/
function addSourceMapUrl(fileName, content) {
const lines = content.split("\n");
const lastLine = lines.pop();
const sourceMapUrl = "//# sourceMappingURL=" + fileName + ".map";
if (!lastLine || lastLine.includes("# sourceMappingURL=")) {
lines.push(sourceMapUrl);
} else {
lines.push(lastLine, sourceMapUrl);
}
return lines.join("\n");
}

/**
* @template T,U
* @param {readonly T[]} l
Expand Down
2 changes: 1 addition & 1 deletion index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe("main", () => {
test(
"downlevel TS to " + tsVersion,
() => {
main("test", `baselines/local/ts${tsVersion}`, semver.coerce(tsVersion));
main("test", `baselines/local/ts${tsVersion}`, { targetVersion: semver.coerce(tsVersion), sourceMaps: false });

expect(fs.readFileSync(`baselines/local/ts${tsVersion}/test.d.ts`, "utf8")).toEqual(
fs.readFileSync(`baselines/reference/ts${tsVersion}/test.d.ts`, "utf8")
Expand Down

0 comments on commit 04481cc

Please sign in to comment.