Skip to content

Commit

Permalink
Initial pbts CLI for generating TypeScript definitions, see #550
Browse files Browse the repository at this point in the history
  • Loading branch information
dcodeIO committed Dec 13, 2016
1 parent baea920 commit 3783af7
Show file tree
Hide file tree
Showing 14 changed files with 135 additions and 47 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,20 @@ protobuf.load("bundle.json", function(err, root) {
});
```

#### Generating TypeScript definitions for static modules

Likewise, the `pbts` command line utility can be used to generate TypeScript definitions from `pbjs`-generated static modules.

```
Generates TypeScript definitions from annotated JavaScript files.
-n, --name Specifies the module name.
-o, --out Saves to a file instead of writing to stdout.
usage: pbts [options] file1.js file2.js ...
```

Building
--------

Expand Down
6 changes: 6 additions & 0 deletions bin/pbts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env node
var path = require("path"),
cli = require(path.join(__dirname, "..", "cli", "pbts.js"));
var ret = cli.main(process.argv);
if (typeof ret === 'number')
process.exit(ret);
3 changes: 1 addition & 2 deletions cli/pbjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ var minimist = util.require("minimist", pkg.devDependencies.minimist),
glob = util.require("glob", pkg.devDependencies.glob);

var protobuf = require(".."),
targets = util.requireAll("./targets"),
pkg = require("../package.json");
targets = util.requireAll("./targets");

exports.main = function(args) {
var argv = minimist(args.slice(2), {
Expand Down
85 changes: 85 additions & 0 deletions cli/pbts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
var path = require("path"),
fs = require("fs"),
pkg = require(path.join(__dirname, "..", "package.json")),
util = require("./util");
var child_process = require("child_process");

var minimist = util.require("minimist", pkg.devDependencies.minimist),
chalk = util.require("chalk", pkg.devDependencies.chalk),
glob = util.require("glob", pkg.devDependencies.glob);

var jsdoc = util.require("jsdoc/package.json", pkg.devDependencies.jsdoc),
tsdjsdoc = util.require("tsd-jsdoc/package.json", pkg.devDependencies['tsd-jsdoc']);

var protobuf = require("..");

exports.main = function(args) {
var argv = minimist(args.slice(2), {
alias: {
out : "o"
},
string: [ "out" ]
});

var files = argv._;

if (!files.length) {
console.log([
"protobuf.js v" + pkg.version + " cli for TypeScript",
"",
"Generates TypeScript definitions from annotated JavaScript files.",
"",
" -n, --name Specifies the module name.",
"",
" -o, --out Saves to a file instead of writing to stdout.",
"",
"usage: " + chalk.bold.green(path.basename(process.argv[1])) + " [options] file1.js file2.js ..."
].join("\n"));
return 1;
}

// Resolve glob expressions
for (var i = 0; i < files.length;) {
if (glob.hasMagic(files[i])) {
var matches = glob.sync(files[i]);
Array.prototype.splice.apply(files, [i, 1].concat(matches));
i += matches.length;
} else
++i;
}

// There is no proper API for jsdoc, so this executes the CLI and writes to types/types.d.ts
var child = child_process.exec("node node_modules/jsdoc/jsdoc.js -c jsdoc.types.json " + files.join(' '), {
cwd: path.join(__dirname, ".."),
argv0: "node",
stdio: "pipe"
});
child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stderr);
child.on("close", function(code) {
if (code)
throw Error("exited with " + code);

var dir = path.join(__dirname, "..", "types");
var dts = fs.readFileSync(path.join(dir, "types.d.ts"), "utf8");
fs.unlinkSync(path.join(dir, "types.d.ts"));

var header = [
"// pbts " + process.argv.slice(2).join(' '),
"// Generated " + (new Date()).toUTCString().replace(/GMT/, "UTC"),
""
];

// Remove declare statements and wrap everything in a module
dts = dts.replace(/\bdeclare\s/g, "");
dts = dts.replace(/^/mg, " ");
dts = header.join('\n')+"\ndeclare module " + JSON.stringify(argv.name || "mymodule") + " {\n\n" + dts + "\n}\n";

if (argv.out)
fs.writeFileSync(argv.out, dts);
else
process.stdout.write(dts, "utf8");
});

return undefined;
};
8 changes: 7 additions & 1 deletion cli/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ exports.inspect = function inspect(object, indent) {
};

exports.require = function(name, version) {
var sub = "";
var p = name.indexOf("/");
if (p > -1) {
sub = name.substring(p);
name = name.substring(0, p);
}
var cwd = path.join(__dirname, "..");
var dir = path.join(cwd, "node_modules", name);
try {
Expand All @@ -81,7 +87,7 @@ exports.require = function(name, version) {
cwd: cwd
});
}
return require(name);
return require(name + sub);
};

exports.wrap = function(name, OUTPUT, ROOT) {
Expand Down
2 changes: 1 addition & 1 deletion dist/protobuf.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/protobuf.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified dist/protobuf.min.js.gz
Binary file not shown.
3 changes: 0 additions & 3 deletions jsdoc.types.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
"allowUnknownTags": false
},
"source": {
"include": [
"./src/"
],
"exclude": [],
"includePattern": ".+\\.js(doc)?$",
"excludePattern": "(^|\\/|\\\\)_"
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
],
"main": "src/index",
"bin": {
"pbjs": "bin/pbjs"
"pbjs": "bin/pbjs",
"pbts": "bin/pbts"
},
"types": "types/protobuf.js.d.ts",
"scripts": {
Expand All @@ -32,7 +33,7 @@
"prepublish": "node scripts/prepublish",
"prof": "node bench/prof",
"test": "tape tests/*.js | tap-spec",
"types": "jsdoc -c jsdoc.types.json && node scripts/types.js && tsc types/test.ts --lib es2015 --noEmit",
"types": "node bin/pbts --name protobufjs --out types/protobuf.js.d.ts ./src && tsc types/test.ts --lib es2015 --noEmit",
"zuul": "zuul --ui tape --no-coverage --concurrency 4 -- tests/*.js",
"zuul-local": "zuul --ui tape --no-coverage --concurrency 1 --local 8080 --disable-tunnel -- tests/*.js"
},
Expand Down
6 changes: 5 additions & 1 deletion scripts/prepublish.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ var path = require("path"),
fs = require("fs");

// ensure LF on bin files
[ path.join(__dirname, "..", "bin", "pbjs") ].forEach(function(file) {
[
path.join(__dirname, "..", "bin", "pbjs"),
path.join(__dirname, "..", "bin", "pbts")
]
.forEach(function(file) {
fs.writeFileSync(file, fs.readFileSync(file).toString("utf8").replace(/\r?\n/g, "\n"), "utf8");
});
23 changes: 0 additions & 23 deletions scripts/types.js

This file was deleted.

18 changes: 9 additions & 9 deletions tests/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,25 +118,25 @@ function verifyEncode(test, buf) {
values: ["c", "d"]
},
*/
test.equal(buf[ 0], 10, "id 1, wireType 2");
test.equal(buf[ 0], 10, "id 1, wireType 2"); // Outer.value
test.equal(buf[ 1], 14, "a length of 14");
test.equal(buf[ 2], 10, "id 1, wireType 2");
test.equal(buf[ 2], 10, "id 1, wireType 2"); // Outer.value $key
test.equal(buf[ 3], 1, "a length of 1");
test.equal(buf[ 4], 98, "'b'");
test.equal(buf[ 5], 18, "id 2, wireType 2");
test.equal(buf[ 5], 18, "id 2, wireType 2"); // Outer.value $value
test.equal(buf[ 6], 9, "a length of 9");
test.equal(buf[ 7], 10, "id 1, wireType 2");
test.equal(buf[ 8], 1 , "a length of 9");
test.equal(buf[ 7], 10, "id 1, wireType 2"); // Inner.key
test.equal(buf[ 8], 1 , "a length of 1");
test.equal(buf[ 9], 49, "'1'");
test.equal(buf[10], 18, "id 2, wireType 2");
test.equal(buf[10], 18, "id 2, wireType 2"); // Inner.values (1)
test.equal(buf[11], 1, "a length of 1");
test.equal(buf[12], 99, "'c'");
test.equal(buf[13], 18, "id 2, wireType 2");
test.equal(buf[14], 1, "a lenfth of 1");
test.equal(buf[13], 18, "id 2, wireType 2"); // Inner.values (2)
test.equal(buf[14], 1, "a length of 1");
test.equal(buf[15],100, "'d'");

// second
test.equal(buf[16], 10, "id 1, wireType 2");
test.equal(buf[16], 10, "id 1, wireType 2"); // Outer.value
// ...

test.end();
Expand Down
7 changes: 3 additions & 4 deletions types/protobuf.js.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/*
* protobuf.js v6.1.0 TypeScript definitions
* Generated Tue, 13 Dec 2016 02:56:17 UTC
*/
// pbts --name protobufjs --out types/protobuf.js.d.ts ./src
// Generated Tue, 13 Dec 2016 12:42:40 UTC

declare module "protobufjs" {

/**
Expand Down

0 comments on commit 3783af7

Please sign in to comment.