mirror of
https://github.com/protobufjs/protobuf.js.git
synced 2025-12-08 20:58:55 +00:00
CLI: More progress on decoupling the CLI; Docs: Explained the JSON structure in README and moved CLI specific information to the CLI package
This commit is contained in:
parent
8a60174932
commit
4bfe0c239b
175
README.md
175
README.md
@ -252,9 +252,7 @@ protobuf.load("awesome.proto")
|
||||
|
||||
### Using JSON descriptors
|
||||
|
||||
The library utilizes a JSON format that is equivalent to a .proto definition (see also: [Command line usage](#command-line)).
|
||||
|
||||
The following is identical to the .proto definition seen above, but it can also be used with just the light library because it doesn't require the parser:
|
||||
The library utilizes a JSON format that is equivalent to a .proto definition. For example, the following is identical to the .proto definition seen above:
|
||||
|
||||
```json
|
||||
// awesome.json
|
||||
@ -272,6 +270,25 @@ The following is identical to the .proto definition seen above, but it can also
|
||||
}
|
||||
```
|
||||
|
||||
The JSON format closely resembles the internal reflection structure:
|
||||
|
||||
| Type (T) | Extends | Type-specific properties
|
||||
|--------------------|--------------------|-------------------------
|
||||
| *ReflectionObject* | | options
|
||||
| *Namespace* | *ReflectionObject* | nested
|
||||
| Type | *Namespace* | **fields**
|
||||
| Enum | *ReflectionObject* | **values**
|
||||
| Field | *ReflectionObject* | rule, **type**, **id**
|
||||
| MapField | Field | **keyType**
|
||||
| Service | *Namespace* | **methods**
|
||||
| Method | *ReflectionObject* | *type*, **requestType**, **responseType**, requestStream, responseStream
|
||||
|
||||
* **Bold** properties are required. *Italic* types are abstract.
|
||||
* `T.fromJSON(name, json)` creates the respective reflection object from a JSON descriptor
|
||||
* `T#toJSON()` creates a JSON descriptor from the respective reflection object (`name` is used as the key within the parent)
|
||||
|
||||
Exclusively using JSON instead of .proto files enables the use of just the light library (the parser isn't required in this case).
|
||||
|
||||
A JSON descriptor can either be loaded the usual way:
|
||||
|
||||
```js
|
||||
@ -438,9 +455,7 @@ protobuf.load("awesome.proto", function(err, root) {
|
||||
});
|
||||
```
|
||||
|
||||
To achieve the same with static code generated by [pbjs](#command-line), there is the [pbts](#generating-typescript-definitions-from-static-modules) command line utility to generate type definitions from static code as well.
|
||||
|
||||
Let's say you generated your static code to `bundle.js` and its type definitions to `bundle.d.ts`, then you can do:
|
||||
If you generated static code using the CLI to `bundle.js` and its type definitions to `bundle.d.ts`, then you can do:
|
||||
|
||||
```ts
|
||||
import * as root from "./bundle.js";
|
||||
@ -470,6 +485,7 @@ Documentation
|
||||
|
||||
#### protobuf.js
|
||||
* [API Documentation](http://dcode.io/protobuf.js)
|
||||
* [CLI Documentation](./cli/README.md)
|
||||
* [CHANGELOG](https://github.com/dcodeIO/protobuf.js/blob/master/CHANGELOG.md)
|
||||
* [Frequently asked questions](https://github.com/dcodeIO/protobuf.js/wiki) on our wiki
|
||||
|
||||
@ -478,152 +494,7 @@ Documentation
|
||||
|
||||
Command line
|
||||
------------
|
||||
|
||||
The `pbjs` command line utility can be used to bundle and translate between .proto and .json files. It also generates static code.
|
||||
|
||||
```
|
||||
Consolidates imports and converts between file formats.
|
||||
|
||||
-t, --target Specifies the target format. Also accepts a path to require a custom target.
|
||||
|
||||
json JSON representation
|
||||
json-module JSON representation as a module
|
||||
proto2 Protocol Buffers, Version 2
|
||||
proto3 Protocol Buffers, Version 3
|
||||
static Static code without reflection
|
||||
static-module Static code without reflection as a module
|
||||
|
||||
-p, --path Adds a directory to the include path.
|
||||
|
||||
-o, --out Saves to a file instead of writing to stdout.
|
||||
|
||||
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 (implies --es6)
|
||||
|
||||
-r, --root Specifies an alternative protobuf.roots name.
|
||||
|
||||
-l, --lint Linter configuration. Defaults to protobuf.js-compatible rules:
|
||||
|
||||
eslint-disable block-scoped-var, no-redeclare, no-control-regex, no-prototype-builtins
|
||||
|
||||
--es6 Enables ES6 syntax (const/let instead of var)
|
||||
|
||||
Proto sources only:
|
||||
|
||||
--keep-case Keeps field casing instead of converting to camel case.
|
||||
|
||||
Static targets only:
|
||||
|
||||
--no-create Does not generate create functions used for reflection 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 from/toObject
|
||||
--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: pbjs [options] file1.proto file2.json ... (or) other | pbjs [options] -
|
||||
```
|
||||
|
||||
For production environments it is recommended to bundle all your .proto files to a single .json file, which minimizes the number of network requests and avoids any parser overhead (hint: works with just the [light library](#distributions)):
|
||||
|
||||
```
|
||||
$> pbjs -t json file1.proto file2.proto > bundle.json
|
||||
```
|
||||
|
||||
Now, either include this file in your final bundle:
|
||||
|
||||
```js
|
||||
var root = protobuf.Root.fromJSON(require("./bundle.json"));
|
||||
```
|
||||
|
||||
or load it the usual way:
|
||||
|
||||
```js
|
||||
protobuf.load("bundle.json", function(err, root) {
|
||||
...
|
||||
});
|
||||
```
|
||||
|
||||
The `pbjs` utility is also capable of generating static code (hint: works with just the [minimal library](#distributions)). For example
|
||||
|
||||
```
|
||||
$> pbjs -t static-module -w commonjs -o compiled.js file1.proto file2.proto
|
||||
```
|
||||
|
||||
will generate static code for definitions within `file1.proto` and `file2.proto` to a CommonJS module `compiled.js`.
|
||||
|
||||
**ProTip!** Documenting your .proto files with `/** ... */`-blocks or (trailing) `/// ...` lines translates to generated static code.
|
||||
|
||||
### Generating TypeScript definitions from 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.
|
||||
|
||||
-o, --out Saves to a file instead of writing to stdout.
|
||||
|
||||
-g, --global Name of the global object in browser environments, if any.
|
||||
|
||||
--no-comments Does not output any JSDoc comments.
|
||||
|
||||
Internal flags:
|
||||
|
||||
-n, --name Wraps everything in a module of the specified name.
|
||||
|
||||
-m, --main Whether building the main library without any imports.
|
||||
|
||||
usage: pbts [options] file1.js file2.js ... (or) other | pbts [options] -
|
||||
```
|
||||
|
||||
Picking up on the example above, the following not just generates static code to a CommonJS module `compiled.js` but also its respective TypeScript definitions to `compiled.d.ts`:
|
||||
|
||||
```
|
||||
$> pbjs -t static-module -w commonjs -o compiled.js file1.proto file2.proto
|
||||
$> pbts -o compiled.d.ts compiled.js
|
||||
```
|
||||
|
||||
Additionally, TypeScript definitions of static modules are compatible with their reflection-based counterparts (i.e. as exported by JSON modules), as long as the following conditions are met:
|
||||
|
||||
1. Instead of using `new SomeMessage(...)`, always use `SomeMessage.create(...)` because reflection objects do not provide a constructor.
|
||||
2. Types, services and enums must start with an uppercase letter to become available as properties of the reflected types as well (i.e. to be able to use `MyMessage.MyEnum` instead of `root.lookup("MyMessage.MyEnum")`).
|
||||
|
||||
For example, the following generates a JSON module `bundle.js` and a `bundle.d.ts`, but no static code:
|
||||
|
||||
```
|
||||
$> pbjs -t json-module -w commonjs -o bundle.js file1.proto file2.proto
|
||||
$> pbjs -t static-module file1.proto file2.proto | pbts -o bundle.d.ts -
|
||||
```
|
||||
|
||||
### On reflection vs. static code
|
||||
|
||||
While using .proto files directly requires the full library respectively pure reflection/JSON the light library, pretty much all code but the relatively short descriptors is shared.
|
||||
|
||||
Static code, on the other hand, requires just the minimal library, but generates additional, albeit editable, source code without any reflection features.
|
||||
|
||||
There is no significant difference performance-wise as the code generated statically is pretty much the same as generated at runtime and both are largely interchangeable as seen in the previous section.
|
||||
|
||||
### Using pbjs and pbts programmatically
|
||||
|
||||
Both utilities can be used programmatically by providing command line arguments and a callback to their respective `main` functions:
|
||||
|
||||
```js
|
||||
var pbjs = require("protobufjs/cli/pbjs");
|
||||
|
||||
pbjs.main([ "--target", "json-module", "path/to/myproto.proto" ], function(err, output) {
|
||||
if (err)
|
||||
throw err;
|
||||
// do something with output
|
||||
});
|
||||
```
|
||||
Command line usage has moved to the (soon to be decoupled) [CLI package]((./cli/README.md))
|
||||
|
||||
Performance
|
||||
-----------
|
||||
|
||||
185
cli/README.md
Normal file
185
cli/README.md
Normal file
@ -0,0 +1,185 @@
|
||||
protobufjs-cli
|
||||
==============
|
||||
[](https://www.npmjs.com/package/protobufjs-cli)
|
||||
|
||||
Command line interface (CLI) for [protobuf.js](https://github.com/dcodeIO/protobuf.js). Translates between file formats and generates static code as well as TypeScript definitions.
|
||||
|
||||
Contents
|
||||
--------
|
||||
|
||||
<!--
|
||||
|
||||
* [Installation](#installation)<br />
|
||||
How to get started using the CLI.
|
||||
|
||||
-->
|
||||
|
||||
* [Usage](#usage)<br />
|
||||
An introduction to the toolset.
|
||||
|
||||
* [API](#api)<br />
|
||||
Details on using pbjs and pbts programmatically.
|
||||
|
||||
<!--
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
```
|
||||
$> npm install protobufjs protobufjs-cli [--save --save-prefix=~]
|
||||
```
|
||||
|
||||
Note that the CLI package is tightly coupled to the main package, so don't forget to update it as well.
|
||||
|
||||
-->
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
### pbjs
|
||||
|
||||
```
|
||||
Translates between file formats and generates static code.
|
||||
|
||||
-t, --target Specifies the target format. Also accepts a path to require a custom target.
|
||||
|
||||
json JSON representation
|
||||
json-module JSON representation as a module
|
||||
proto2 Protocol Buffers, Version 2
|
||||
proto3 Protocol Buffers, Version 3
|
||||
static Static code without reflection
|
||||
static-module Static code without reflection as a module
|
||||
|
||||
-p, --path Adds a directory to the include path.
|
||||
|
||||
-o, --out Saves to a file instead of writing to stdout.
|
||||
|
||||
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 (implies --es6)
|
||||
|
||||
-r, --root Specifies an alternative protobuf.roots name.
|
||||
|
||||
-l, --lint Linter configuration. Defaults to protobuf.js-compatible rules:
|
||||
|
||||
eslint-disable block-scoped-var, no-redeclare, no-control-regex, no-prototype-builtins
|
||||
|
||||
--es6 Enables ES6 syntax (const/let instead of var)
|
||||
|
||||
Proto sources only:
|
||||
|
||||
--keep-case Keeps field casing instead of converting to camel case.
|
||||
|
||||
Static targets only:
|
||||
|
||||
--no-create Does not generate create functions used for reflection 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 from/toObject
|
||||
--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: pbjs [options] file1.proto file2.json ... (or) other | pbjs [options] -
|
||||
```
|
||||
|
||||
For production environments it is recommended to bundle all your .proto files to a single .json file, which minimizes the number of network requests and avoids any parser overhead (hint: works with just the **light** library):
|
||||
|
||||
```
|
||||
$> pbjs -t json file1.proto file2.proto > bundle.json
|
||||
```
|
||||
|
||||
Now, either include this file in your final bundle:
|
||||
|
||||
```js
|
||||
var root = protobuf.Root.fromJSON(require("./bundle.json"));
|
||||
```
|
||||
|
||||
or load it the usual way:
|
||||
|
||||
```js
|
||||
protobuf.load("bundle.json", function(err, root) {
|
||||
...
|
||||
});
|
||||
```
|
||||
|
||||
Generated static code, on the other hand, works with just the **minimal** library. For example
|
||||
|
||||
```
|
||||
$> pbjs -t static-module -w commonjs -o compiled.js file1.proto file2.proto
|
||||
```
|
||||
|
||||
will generate static code for definitions within `file1.proto` and `file2.proto` to a CommonJS module `compiled.js`.
|
||||
|
||||
**ProTip!** Documenting your .proto files with `/** ... */`-blocks or (trailing) `/// ...` lines translates to generated static code.
|
||||
|
||||
|
||||
### pbts
|
||||
|
||||
```
|
||||
Generates TypeScript definitions from annotated JavaScript files.
|
||||
|
||||
-o, --out Saves to a file instead of writing to stdout.
|
||||
|
||||
-g, --global Name of the global object in browser environments, if any.
|
||||
|
||||
--no-comments Does not output any JSDoc comments.
|
||||
|
||||
Internal flags:
|
||||
|
||||
-n, --name Wraps everything in a module of the specified name.
|
||||
|
||||
-m, --main Whether building the main library without any imports.
|
||||
|
||||
usage: pbts [options] file1.js file2.js ... (or) other | pbts [options] -
|
||||
```
|
||||
|
||||
Picking up on the example above, the following not just generates static code to a CommonJS module `compiled.js` but also its respective TypeScript definitions to `compiled.d.ts`:
|
||||
|
||||
```
|
||||
$> pbjs -t static-module -w commonjs -o compiled.js file1.proto file2.proto
|
||||
$> pbts -o compiled.d.ts compiled.js
|
||||
```
|
||||
|
||||
Additionally, TypeScript definitions of static modules are compatible with their reflection-based counterparts (i.e. as exported by JSON modules), as long as the following conditions are met:
|
||||
|
||||
1. Instead of using `new SomeMessage(...)`, always use `SomeMessage.create(...)` because reflection objects do not provide a constructor.
|
||||
2. Types, services and enums must start with an uppercase letter to become available as properties of the reflected types as well (i.e. to be able to use `MyMessage.MyEnum` instead of `root.lookup("MyMessage.MyEnum")`).
|
||||
|
||||
For example, the following generates a JSON module `bundle.js` and a `bundle.d.ts`, but no static code:
|
||||
|
||||
```
|
||||
$> pbjs -t json-module -w commonjs -o bundle.js file1.proto file2.proto
|
||||
$> pbjs -t static-module file1.proto file2.proto | pbts -o bundle.d.ts -
|
||||
```
|
||||
|
||||
### Reflection vs. static code
|
||||
|
||||
While using .proto files directly requires the full library respectively pure reflection/JSON the light library, pretty much all code but the relatively short descriptors is shared.
|
||||
|
||||
Static code, on the other hand, requires just the minimal library, but generates additional, albeit editable, source code without any reflection features.
|
||||
|
||||
There is no significant difference performance-wise as the code generated statically is pretty much the same as generated at runtime and both are largely interchangeable as seen in the previous section.
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
Both utilities can be used programmatically by providing command line arguments and a callback to their respective `main` functions:
|
||||
|
||||
```js
|
||||
var pbjs = require("protobufjs-cli/pbjs"); // or require("protobufjs-cli").pbjs / .pbts
|
||||
|
||||
pbjs.main([ "--target", "json-module", "path/to/myproto.proto" ], function(err, output) {
|
||||
if (err)
|
||||
throw err;
|
||||
// do something with output
|
||||
});
|
||||
```
|
||||
|
||||
**License:** [BSD 3-Clause License](https://opensource.org/licenses/BSD-3-Clause)
|
||||
@ -1,32 +1 @@
|
||||
{
|
||||
"name": "protobufjs-cli",
|
||||
"description": "protobuf.js command line interface (CLI).",
|
||||
"version": "6.7.0",
|
||||
"author": "Daniel Wirtz <dcode+protobufjs@dcode.io>",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dcodeIO/protobuf.js.git"
|
||||
},
|
||||
"license": "BSD-3-Clause",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"bin": {
|
||||
"pbjs": "bin/pbjs",
|
||||
"pbts": "bin/pbts"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"protobufjs": "6.7.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": "^1.1.3",
|
||||
"escodegen": "^1.8.1",
|
||||
"espree": "^3.1.3",
|
||||
"estraverse": "^4.2.0",
|
||||
"glob": "^7.1.1",
|
||||
"jsdoc": "^3.4.2",
|
||||
"minimist": "^1.2.0",
|
||||
"semver": "^5.3.0",
|
||||
"tmp": "0.0.31",
|
||||
"uglify-js": "^2.8.15"
|
||||
}
|
||||
}
|
||||
{}
|
||||
32
cli/package.standalone.json
Normal file
32
cli/package.standalone.json
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "protobufjs-cli",
|
||||
"description": "Translates between file formats and generates static code as well as TypeScript definitions.",
|
||||
"version": "6.7.0",
|
||||
"author": "Daniel Wirtz <dcode+protobufjs@dcode.io>",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dcodeIO/protobuf.js.git"
|
||||
},
|
||||
"license": "BSD-3-Clause",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"bin": {
|
||||
"pbjs": "bin/pbjs",
|
||||
"pbts": "bin/pbts"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"protobufjs": "~6.7.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": "^1.1.3",
|
||||
"escodegen": "^1.8.1",
|
||||
"espree": "^3.1.3",
|
||||
"estraverse": "^4.2.0",
|
||||
"glob": "^7.1.1",
|
||||
"jsdoc": "^3.4.2",
|
||||
"minimist": "^1.2.0",
|
||||
"semver": "^5.3.0",
|
||||
"tmp": "0.0.31",
|
||||
"uglify-js": "^2.8.15"
|
||||
}
|
||||
}
|
||||
@ -1,12 +1,12 @@
|
||||
"use strict";
|
||||
var path = require("path"),
|
||||
fs = require("fs"),
|
||||
pkg = require(path.join(__dirname, "package.json")),
|
||||
pkg = require("./package.json"),
|
||||
util = require("./util");
|
||||
|
||||
util.setup();
|
||||
|
||||
var protobuf = require(".."),
|
||||
var protobuf = require(util.pathToProtobufJs),
|
||||
minimist = require("minimist"),
|
||||
chalk = require("chalk"),
|
||||
glob = require("glob");
|
||||
@ -66,7 +66,7 @@ exports.main = function main(args, callback) {
|
||||
process.stderr.write([
|
||||
"protobuf.js v" + pkg.version + " CLI for JavaScript",
|
||||
"",
|
||||
chalk.bold.white("Consolidates imports and converts between file formats."),
|
||||
chalk.bold.white("Translates between file formats and generates static code."),
|
||||
"",
|
||||
" -t, --target Specifies the target format. Also accepts a path to require a custom target.",
|
||||
"",
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
var child_process = require("child_process"),
|
||||
path = require("path"),
|
||||
fs = require("fs"),
|
||||
pkg = require(path.join(__dirname, "./package.json")),
|
||||
pkg = require("./package.json"),
|
||||
util = require("./util");
|
||||
|
||||
util.setup();
|
||||
|
||||
11
cli/util.js
11
cli/util.js
@ -5,7 +5,16 @@ var fs = require("fs"),
|
||||
|
||||
var semver;
|
||||
|
||||
var protobuf = require("..");
|
||||
try {
|
||||
// installed as a peer dependency
|
||||
require.resolve("protobufjs");
|
||||
exports.pathToProtobufJs = "protobufjs";
|
||||
} catch (e) {
|
||||
// local development, i.e. forked from github
|
||||
exports.pathToProtobufJs = "..";
|
||||
}
|
||||
|
||||
var protobuf = require(exports.pathToProtobufJs);
|
||||
|
||||
function basenameCompare(a, b) {
|
||||
var aa = String(a).replace(/\.\w+$/, "").split(/(-?\d*\.?\d+)/g),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user