mirror of
https://github.com/protobufjs/protobuf.js.git
synced 2025-12-08 20:58:55 +00:00
191 lines
6.9 KiB
JavaScript
191 lines
6.9 KiB
JavaScript
"use strict";
|
|
var path = require("path"),
|
|
fs = require("fs"),
|
|
pkg = require(path.join(__dirname, "..", "package.json")),
|
|
util = require("./util");
|
|
|
|
util.setup();
|
|
|
|
var protobuf = require(".."),
|
|
minimist = require("minimist"),
|
|
chalk = require("chalk"),
|
|
glob = require("glob");
|
|
|
|
var targets = util.requireAll("./targets");
|
|
|
|
/**
|
|
* Runs pbjs programmatically.
|
|
* @param {string[]} args Command line arguments
|
|
* @param {function(?Error)} [callback] Optional completion callback
|
|
* @returns {number|undefined} Exit code, if known
|
|
*/
|
|
exports.main = function(args, callback) {
|
|
var lintDefault = "eslint-disable block-scoped-var, no-redeclare, no-control-regex";
|
|
var argv = minimist(args, {
|
|
alias: {
|
|
target : "t",
|
|
out : "o",
|
|
path : "p",
|
|
wrap : "w",
|
|
root : "r",
|
|
lint : "l"
|
|
},
|
|
string: [ "target", "out", "path", "wrap", "root", "lint" ],
|
|
boolean: [ "keep-case", "create", "encode", "decode", "verify", "convert", "delimited", "beautify", "comments" ],
|
|
default: {
|
|
target : "json",
|
|
create : true,
|
|
encode : true,
|
|
decode : true,
|
|
verify : true,
|
|
convert : true,
|
|
delimited : true,
|
|
beautify : true,
|
|
comments : true,
|
|
lint : lintDefault
|
|
}
|
|
});
|
|
|
|
var target = targets[argv.target],
|
|
files = argv._,
|
|
paths = typeof argv.path === 'string' ? [ argv.path ] : argv.path || [];
|
|
|
|
if (!files.length) {
|
|
var descs = Object.keys(targets).filter(function(key) { return !targets[key].private; }).map(function(key) {
|
|
return " " + util.pad(key, 14, true) + targets[key].description;
|
|
});
|
|
if (callback)
|
|
callback(Error("usage"));
|
|
else
|
|
console.error([
|
|
"protobuf.js v" + pkg.version + " CLI for JavaScript",
|
|
"",
|
|
chalk.bold.white("Consolidates imports and converts between file formats."),
|
|
"",
|
|
" -t, --target Specifies the target format. Also accepts a path to require a custom target.",
|
|
"",
|
|
descs.join('\n'),
|
|
"",
|
|
" -p, --path Adds a directory to the include path.",
|
|
"",
|
|
" -o, --out Saves to a file instead of writing to stdout.",
|
|
"",
|
|
chalk.bold.gray(" Module targets only:"),
|
|
"",
|
|
" -w, --wrap Specifies the wrapper to use. Also accepts a path to require a custom wrapper.",
|
|
"",
|
|
" default Default wrapper supporting both CommonJS and AMD",
|
|
" commonjs CommonJS wrapper",
|
|
" amd AMD wrapper",
|
|
" es6 ES6 wrapper",
|
|
"",
|
|
" -r, --root Specifies an alternative protobuf.roots name.",
|
|
"",
|
|
" -l, --lint Linter configuration. Defaults to protobuf.js-compatible rules:",
|
|
"",
|
|
" " + lintDefault,
|
|
"",
|
|
chalk.bold.gray(" Proto sources only:"),
|
|
"",
|
|
" --keep-case Keeps field casing instead of converting to camel case.",
|
|
"",
|
|
chalk.bold.gray(" Static targets only:"),
|
|
"",
|
|
" --no-create Does not generate create functions used for runtime compatibility.",
|
|
" --no-encode Does not generate encode functions.",
|
|
" --no-decode Does not generate decode functions.",
|
|
" --no-verify Does not generate verify functions.",
|
|
" --no-convert Does not generate convert functions like asJSON and from.",
|
|
" --no-delimited Does not generate delimited encode/decode functions.",
|
|
" --no-beautify Does not beautify generated code.",
|
|
" --no-comments Does not output any JSDoc comments.",
|
|
"",
|
|
"usage: " + chalk.bold.green("pbjs") + " [options] file1.proto file2.json ..." + chalk.gray(" (or) ") + "other | " + chalk.bold.green("pbjs") + " [options] -"
|
|
].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;
|
|
}
|
|
|
|
// Require custom target
|
|
if (!target)
|
|
target = require(path.resolve(process.cwd(), argv.target));
|
|
|
|
var root = new protobuf.Root();
|
|
|
|
// Search include paths when resolving imports
|
|
root.resolvePath = function pbjsResolvePath(origin, target) {
|
|
var filepath = protobuf.util.path.resolve(origin, target);
|
|
if (fs.existsSync(filepath))
|
|
return filepath;
|
|
for (var i = 0; i < paths.length; ++i) {
|
|
var ifilepath = protobuf.util.path.resolve(paths[i] + "/", target);
|
|
if (fs.existsSync(ifilepath))
|
|
return ifilepath;
|
|
}
|
|
return filepath;
|
|
};
|
|
|
|
var parseOptions = {
|
|
"keepCase": argv["keep-case"] || false
|
|
};
|
|
|
|
// Read from stdin
|
|
if (files.length === 1 && files[0] === "-") {
|
|
var data = [];
|
|
process.stdin.on("data", function(chunk) {
|
|
data.push(chunk);
|
|
});
|
|
process.stdin.on("end", function() {
|
|
var source = Buffer.concat(data).toString("utf8");
|
|
if (source.charAt(0) !== "{") {
|
|
protobuf.parse(source, root, parseOptions);
|
|
} else {
|
|
var json = JSON.parse(source);
|
|
root.setOptions(json.options).addJSON(json);
|
|
}
|
|
callTarget();
|
|
});
|
|
|
|
// Load from disk
|
|
} else {
|
|
try {
|
|
root.loadSync(files, parseOptions); // sync is deterministic while async is not
|
|
callTarget();
|
|
} catch (err) {
|
|
if (callback) {
|
|
callback(err);
|
|
return undefined;
|
|
}
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
function callTarget() {
|
|
target(root, argv, function targetCallback(err, output) {
|
|
if (err) {
|
|
if (callback)
|
|
return callback(err);
|
|
throw err;
|
|
}
|
|
if (output !== "") {
|
|
if (argv.out)
|
|
fs.writeFileSync(argv.out, output, { encoding: "utf8" });
|
|
else
|
|
process.stdout.write(output, "utf8");
|
|
}
|
|
return callback
|
|
? callback(null)
|
|
: undefined;
|
|
});
|
|
}
|
|
};
|