diff --git a/README.md b/README.md index b0cb06854..f6d23918e 100644 --- a/README.md +++ b/README.md @@ -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 -------- diff --git a/bin/pbts b/bin/pbts new file mode 100644 index 000000000..0e4855d4f --- /dev/null +++ b/bin/pbts @@ -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); diff --git a/cli/pbjs.js b/cli/pbjs.js index 3382954f8..9c92e1369 100644 --- a/cli/pbjs.js +++ b/cli/pbjs.js @@ -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), { diff --git a/cli/pbts.js b/cli/pbts.js new file mode 100644 index 000000000..36f1c8f5c --- /dev/null +++ b/cli/pbts.js @@ -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; +}; diff --git a/cli/util.js b/cli/util.js index 2cff4d5cb..f3729ab0f 100644 --- a/cli/util.js +++ b/cli/util.js @@ -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 { @@ -81,7 +87,7 @@ exports.require = function(name, version) { cwd: cwd }); } - return require(name); + return require(name + sub); }; exports.wrap = function(name, OUTPUT, ROOT) { diff --git a/dist/protobuf.js b/dist/protobuf.js index ee102cbb1..c46b6604f 100644 --- a/dist/protobuf.js +++ b/dist/protobuf.js @@ -1,6 +1,6 @@ /*! * protobuf.js v6.1.0 (c) 2016 Daniel Wirtz - * Compiled Tue, 13 Dec 2016 02:56:23 UTC + * Compiled Tue, 13 Dec 2016 12:42:17 UTC * Licensed under the Apache License, Version 2.0 * see: https://github.com/dcodeIO/protobuf.js for details */ diff --git a/dist/protobuf.min.js b/dist/protobuf.min.js index 5bd952f28..473aaaf6f 100644 --- a/dist/protobuf.min.js +++ b/dist/protobuf.min.js @@ -1,6 +1,6 @@ /*! * protobuf.js v6.1.0 (c) 2016 Daniel Wirtz - * Compiled Tue, 13 Dec 2016 02:56:23 UTC + * Compiled Tue, 13 Dec 2016 12:42:17 UTC * Licensed under the Apache License, Version 2.0 * see: https://github.com/dcodeIO/protobuf.js for details */ diff --git a/dist/protobuf.min.js.gz b/dist/protobuf.min.js.gz index 490769dda..000a7c1f2 100644 Binary files a/dist/protobuf.min.js.gz and b/dist/protobuf.min.js.gz differ diff --git a/jsdoc.types.json b/jsdoc.types.json index aa21352a1..69bb41ac4 100644 --- a/jsdoc.types.json +++ b/jsdoc.types.json @@ -3,9 +3,6 @@ "allowUnknownTags": false }, "source": { - "include": [ - "./src/" - ], "exclude": [], "includePattern": ".+\\.js(doc)?$", "excludePattern": "(^|\\/|\\\\)_" diff --git a/package.json b/package.json index e16da31fe..6709ecc09 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,8 @@ ], "main": "src/index", "bin": { - "pbjs": "bin/pbjs" + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" }, "types": "types/protobuf.js.d.ts", "scripts": { @@ -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" }, diff --git a/scripts/prepublish.js b/scripts/prepublish.js index e65ebe643..977bc66d8 100644 --- a/scripts/prepublish.js +++ b/scripts/prepublish.js @@ -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"); }); diff --git a/scripts/types.js b/scripts/types.js deleted file mode 100644 index 965622196..000000000 --- a/scripts/types.js +++ /dev/null @@ -1,23 +0,0 @@ -var fs = require("fs"), - path = require("path"), - pkg = require("../package.json"); -var dir = path.join(__dirname, "..", "types"); - -var header = [ - // '/// ', - // "", - "/*", - " * protobuf.js v" + pkg.version + " TypeScript definitions", - " * Generated " + (new Date()).toUTCString().replace(/GMT/, "UTC"), - " */" -]; - -var dts = fs.readFileSync(path.join(dir, "types.d.ts"), "utf8"); -fs.unlinkSync(path.join(dir, "types.d.ts")); - -// 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 \"protobufjs\" {\n\n" + dts + "\n}\n"; - -fs.writeFileSync(path.join(dir, "protobuf.js.d.ts"), dts); diff --git a/tests/map.js b/tests/map.js index 559ef28f9..d7037b678 100644 --- a/tests/map.js +++ b/tests/map.js @@ -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(); diff --git a/types/protobuf.js.d.ts b/types/protobuf.js.d.ts index 5f0e7f67c..3bec9bdb8 100644 --- a/types/protobuf.js.d.ts +++ b/types/protobuf.js.d.ts @@ -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" { /**