Skip to content

Commit da34f43

Browse files
Taylor McIntyreStacey Serngcangussualexander-fenster
authored
feat!: move command line tool to a new package named protobufjs-cli (#1234)
* Get protobufjs-cli to a publishable state * Fix eslint issues * Fix pbts path * Install cli package deps on CI 'build' job * fix: get rid of require-protobufjs.js * fix: lint * fix: versions * chore(deps): update package-lock.json Co-authored-by: Stacey Sern <stacey@dropbox.com> Co-authored-by: Gabriel Cangussu <gabrielcangussu@gmail.com> Co-authored-by: Alexander Fenster <fenster@google.com>
1 parent b4cae07 commit da34f43

File tree

21 files changed

+12976
-3434
lines changed

21 files changed

+12976
-3434
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
with:
2828
node-version: "12"
2929
- name: "Install dependencies"
30-
run: npm install
30+
run: npm install && (cd cli && npm install)
3131
- name: "Build distribution files"
3232
run: npm run build
3333
test:

README.md

Lines changed: 6 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,6 @@ Contents
2727
* [Using services](#using-services)
2828
* [Usage with TypeScript](#usage-with-typescript)<br />
2929

30-
* [Command line](#command-line)<br />
31-
How to use the command line utility.
32-
33-
* [pbjs for JavaScript](#pbjs-for-javascript)
34-
* [pbts for TypeScript](#pbts-for-typescript)
35-
* [Reflection vs. static code](#reflection-vs-static-code)
36-
* [Command line API](#command-line-api)<br />
37-
3830
* [Additional documentation](#additional-documentation)<br />
3931
A list of available documentation resources.
4032

@@ -60,6 +52,12 @@ $> npm install protobufjs [--save --save-prefix=~]
6052
var protobuf = require("protobufjs");
6153
```
6254

55+
The command line utility lives in the protobufjs-cli package and must be installed separately:
56+
57+
```
58+
$> npm install protobufjs-cli [--save --save-prefix=~]
59+
```
60+
6361
**Note** that this library's versioning scheme is not semver-compatible for historical reasons. For guaranteed backward compatibility, always depend on `~6.A.B` instead of `^6.A.B` (hence the `--save-prefix` above).
6462

6563
### Browsers
@@ -597,171 +595,6 @@ Other notes:
597595

598596
**ProTip!** Not as pretty, but you can [use decorators in plain JavaScript](https://github.com/dcodeIO/protobuf.js/blob/master/examples/js-decorators.js) as well.
599597

600-
Command line
601-
------------
602-
603-
**Note** that moving the CLI to [its own package](./cli) is a work in progress. At the moment, it's still part of the main package.
604-
605-
The command line interface (CLI) can be used to translate between file formats and to generate static code as well as TypeScript definitions.
606-
607-
### pbjs for JavaScript
608-
609-
```
610-
Translates between file formats and generates static code.
611-
612-
-t, --target Specifies the target format. Also accepts a path to require a custom target.
613-
614-
json JSON representation
615-
json-module JSON representation as a module
616-
proto2 Protocol Buffers, Version 2
617-
proto3 Protocol Buffers, Version 3
618-
static Static code without reflection (non-functional on its own)
619-
static-module Static code without reflection as a module
620-
621-
-p, --path Adds a directory to the include path.
622-
623-
-o, --out Saves to a file instead of writing to stdout.
624-
625-
--sparse Exports only those types referenced from a main file (experimental).
626-
627-
Module targets only:
628-
629-
-w, --wrap Specifies the wrapper to use. Also accepts a path to require a custom wrapper.
630-
631-
default Default wrapper supporting both CommonJS and AMD
632-
commonjs CommonJS wrapper
633-
amd AMD wrapper
634-
es6 ES6 wrapper (implies --es6)
635-
closure A closure adding to protobuf.roots where protobuf is a global
636-
637-
-r, --root Specifies an alternative protobuf.roots name.
638-
639-
-l, --lint Linter configuration. Defaults to protobuf.js-compatible rules:
640-
641-
eslint-disable block-scoped-var, no-redeclare, no-control-regex, no-prototype-builtins
642-
643-
--es6 Enables ES6 syntax (const/let instead of var)
644-
645-
Proto sources only:
646-
647-
--keep-case Keeps field casing instead of converting to camel case.
648-
649-
Static targets only:
650-
651-
--no-create Does not generate create functions used for reflection compatibility.
652-
--no-encode Does not generate encode functions.
653-
--no-decode Does not generate decode functions.
654-
--no-verify Does not generate verify functions.
655-
--no-convert Does not generate convert functions like from/toObject
656-
--no-delimited Does not generate delimited encode/decode functions.
657-
--no-beautify Does not beautify generated code.
658-
--no-comments Does not output any JSDoc comments.
659-
660-
--force-long Enforces the use of 'Long' for s-/u-/int64 and s-/fixed64 fields.
661-
--force-number Enforces the use of 'number' for s-/u-/int64 and s-/fixed64 fields.
662-
--force-message Enforces the use of message instances instead of plain objects.
663-
664-
usage: pbjs [options] file1.proto file2.json ... (or pipe) other | pbjs [options] -
665-
```
666-
667-
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):
668-
669-
```
670-
$> pbjs -t json file1.proto file2.proto > bundle.json
671-
```
672-
673-
Now, either include this file in your final bundle:
674-
675-
```js
676-
var root = protobuf.Root.fromJSON(require("./bundle.json"));
677-
```
678-
679-
or load it the usual way:
680-
681-
```js
682-
protobuf.load("bundle.json", function(err, root) {
683-
...
684-
});
685-
```
686-
687-
Generated static code, on the other hand, works with just the **minimal** library. For example
688-
689-
```
690-
$> pbjs -t static-module -w commonjs -o compiled.js file1.proto file2.proto
691-
```
692-
693-
will generate static code for definitions within `file1.proto` and `file2.proto` to a CommonJS module `compiled.js`.
694-
695-
**ProTip!** Documenting your .proto files with `/** ... */`-blocks or (trailing) `/// ...` lines translates to generated static code.
696-
697-
698-
### pbts for TypeScript
699-
700-
```
701-
Generates TypeScript definitions from annotated JavaScript files.
702-
703-
-o, --out Saves to a file instead of writing to stdout.
704-
705-
-g, --global Name of the global object in browser environments, if any.
706-
707-
--no-comments Does not output any JSDoc comments.
708-
709-
Internal flags:
710-
711-
-n, --name Wraps everything in a module of the specified name.
712-
713-
-m, --main Whether building the main library without any imports.
714-
715-
usage: pbts [options] file1.js file2.js ... (or) other | pbts [options] -
716-
```
717-
718-
Picking up on the example above, the following not only generates static code to a CommonJS module `compiled.js` but also its respective TypeScript definitions to `compiled.d.ts`:
719-
720-
```
721-
$> pbjs -t static-module -w commonjs -o compiled.js file1.proto file2.proto
722-
$> pbts -o compiled.d.ts compiled.js
723-
```
724-
725-
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:
726-
727-
1. Instead of using `new SomeMessage(...)`, always use `SomeMessage.create(...)` because reflection objects do not provide a constructor.
728-
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")`).
729-
730-
For example, the following generates a JSON module `bundle.js` and a `bundle.d.ts`, but no static code:
731-
732-
```
733-
$> pbjs -t json-module -w commonjs -o bundle.js file1.proto file2.proto
734-
$> pbjs -t static-module file1.proto file2.proto | pbts -o bundle.d.ts -
735-
```
736-
737-
### Reflection vs. static code
738-
739-
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.
740-
741-
Static code, on the other hand, requires just the minimal library, but generates additional source code without any reflection features. This also implies that there is a break-even point where statically generated code becomes larger than descriptor-based code once the amount of code generated exceeds the size of the full respectively light library.
742-
743-
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.
744-
745-
| Source | Library | Advantages | Tradeoffs
746-
|--------|---------|------------|-----------
747-
| .proto | full | Easily editable<br />Interoperability with other libraries<br />No compile step | Some parsing and possibly network overhead
748-
| JSON | light | Easily editable<br />No parsing overhead<br />Single bundle (no network overhead) | protobuf.js specific<br />Has a compile step
749-
| static | minimal | Works where `eval` access is restricted<br />Fully documented<br />Small footprint for small protos | Can be hard to edit<br />No reflection<br />Has a compile step
750-
751-
### Command line API
752-
753-
Both utilities can be used programmatically by providing command line arguments and a callback to their respective `main` functions:
754-
755-
```js
756-
var pbjs = require("protobufjs/cli/pbjs"); // or require("protobufjs/cli").pbjs / .pbts
757-
758-
pbjs.main([ "--target", "json-module", "path/to/myproto.proto" ], function(err, output) {
759-
if (err)
760-
throw err;
761-
// do something with output
762-
});
763-
```
764-
765598
Additional documentation
766599
------------------------
767600

bin/pbjs

Lines changed: 0 additions & 6 deletions
This file was deleted.

bin/pbts

Lines changed: 0 additions & 6 deletions
This file was deleted.

cli/README.md

Lines changed: 165 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,172 @@
11
protobufjs-cli
22
==============
3-
[![npm](https://img.shields.io/npm/v/protobufjscli.svg)](https://www.npmjs.com/package/protobufjs-cli)
3+
[![npm](https://img.shields.io/npm/v/protobufjs-cli.svg)](https://www.npmjs.com/package/protobufjs-cli)
44

5-
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.
5+
Command line interface (CLI) for [protobuf.js](https://github.com/dcodeIO/protobuf.js).
66

7-
* [CLI Documentation](https://github.com/dcodeIO/protobuf.js#command-line)
7+
This can be used to translate between file formats and to generate static code as well as TypeScript definitions.
88

9-
**Note** that moving the CLI to its own package is a work in progress. At the moment, it's still part of the main package.
9+
* [pbjs for JavaScript](#pbjs-for-javascript)
10+
* [pbts for TypeScript](#pbts-for-typescript)
11+
* [Reflection vs. static code](#reflection-vs-static-code)
12+
* [Command line API](#command-line-api)<br />
13+
14+
### pbjs for JavaScript
15+
16+
```
17+
Translates between file formats and generates static code.
18+
19+
-t, --target Specifies the target format. Also accepts a path to require a custom target.
20+
21+
json JSON representation
22+
json-module JSON representation as a module
23+
proto2 Protocol Buffers, Version 2
24+
proto3 Protocol Buffers, Version 3
25+
static Static code without reflection (non-functional on its own)
26+
static-module Static code without reflection as a module
27+
28+
-p, --path Adds a directory to the include path.
29+
30+
-o, --out Saves to a file instead of writing to stdout.
31+
32+
--sparse Exports only those types referenced from a main file (experimental).
33+
34+
Module targets only:
35+
36+
-w, --wrap Specifies the wrapper to use. Also accepts a path to require a custom wrapper.
37+
38+
default Default wrapper supporting both CommonJS and AMD
39+
commonjs CommonJS wrapper
40+
amd AMD wrapper
41+
es6 ES6 wrapper (implies --es6)
42+
closure A closure adding to protobuf.roots where protobuf is a global
43+
44+
-r, --root Specifies an alternative protobuf.roots name.
45+
46+
-l, --lint Linter configuration. Defaults to protobuf.js-compatible rules:
47+
48+
eslint-disable block-scoped-var, no-redeclare, no-control-regex, no-prototype-builtins
49+
50+
--es6 Enables ES6 syntax (const/let instead of var)
51+
52+
Proto sources only:
53+
54+
--keep-case Keeps field casing instead of converting to camel case.
55+
56+
Static targets only:
57+
58+
--no-create Does not generate create functions used for reflection compatibility.
59+
--no-encode Does not generate encode functions.
60+
--no-decode Does not generate decode functions.
61+
--no-verify Does not generate verify functions.
62+
--no-convert Does not generate convert functions like from/toObject
63+
--no-delimited Does not generate delimited encode/decode functions.
64+
--no-beautify Does not beautify generated code.
65+
--no-comments Does not output any JSDoc comments.
66+
67+
--force-long Enforces the use of 'Long' for s-/u-/int64 and s-/fixed64 fields.
68+
--force-number Enforces the use of 'number' for s-/u-/int64 and s-/fixed64 fields.
69+
--force-message Enforces the use of message instances instead of plain objects.
70+
71+
usage: pbjs [options] file1.proto file2.json ... (or pipe) other | pbjs [options] -
72+
```
73+
74+
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):
75+
76+
```
77+
$> pbjs -t json file1.proto file2.proto > bundle.json
78+
```
79+
80+
Now, either include this file in your final bundle:
81+
82+
```js
83+
var root = protobuf.Root.fromJSON(require("./bundle.json"));
84+
```
85+
86+
or load it the usual way:
87+
88+
```js
89+
protobuf.load("bundle.json", function(err, root) {
90+
...
91+
});
92+
```
93+
94+
Generated static code, on the other hand, works with just the **minimal** library. For example
95+
96+
```
97+
$> pbjs -t static-module -w commonjs -o compiled.js file1.proto file2.proto
98+
```
99+
100+
will generate static code for definitions within `file1.proto` and `file2.proto` to a CommonJS module `compiled.js`.
101+
102+
**ProTip!** Documenting your .proto files with `/** ... */`-blocks or (trailing) `/// ...` lines translates to generated static code.
103+
104+
105+
### pbts for TypeScript
106+
107+
```
108+
Generates TypeScript definitions from annotated JavaScript files.
109+
110+
-o, --out Saves to a file instead of writing to stdout.
111+
112+
-g, --global Name of the global object in browser environments, if any.
113+
114+
--no-comments Does not output any JSDoc comments.
115+
116+
Internal flags:
117+
118+
-n, --name Wraps everything in a module of the specified name.
119+
120+
-m, --main Whether building the main library without any imports.
121+
122+
usage: pbts [options] file1.js file2.js ... (or) other | pbts [options] -
123+
```
124+
125+
Picking up on the example above, the following not only generates static code to a CommonJS module `compiled.js` but also its respective TypeScript definitions to `compiled.d.ts`:
126+
127+
```
128+
$> pbjs -t static-module -w commonjs -o compiled.js file1.proto file2.proto
129+
$> pbts -o compiled.d.ts compiled.js
130+
```
131+
132+
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:
133+
134+
1. Instead of using `new SomeMessage(...)`, always use `SomeMessage.create(...)` because reflection objects do not provide a constructor.
135+
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")`).
136+
137+
For example, the following generates a JSON module `bundle.js` and a `bundle.d.ts`, but no static code:
138+
139+
```
140+
$> pbjs -t json-module -w commonjs -o bundle.js file1.proto file2.proto
141+
$> pbjs -t static-module file1.proto file2.proto | pbts -o bundle.d.ts -
142+
```
143+
144+
### Reflection vs. static code
145+
146+
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.
147+
148+
Static code, on the other hand, requires just the minimal library, but generates additional source code without any reflection features. This also implies that there is a break-even point where statically generated code becomes larger than descriptor-based code once the amount of code generated exceeds the size of the full respectively light library.
149+
150+
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.
151+
152+
| Source | Library | Advantages | Tradeoffs
153+
|--------|---------|------------|-----------
154+
| .proto | full | Easily editable<br />Interoperability with other libraries<br />No compile step | Some parsing and possibly network overhead
155+
| JSON | light | Easily editable<br />No parsing overhead<br />Single bundle (no network overhead) | protobuf.js specific<br />Has a compile step
156+
| static | minimal | Works where `eval` access is restricted<br />Fully documented<br />Small footprint for small protos | Can be hard to edit<br />No reflection<br />Has a compile step
157+
158+
### Command line API
159+
160+
Both utilities can be used programmatically by providing command line arguments and a callback to their respective `main` functions:
161+
162+
```js
163+
var pbjs = require("protobufjs-cli/pbjs"); // or require("protobufjs-cli").pbjs / .pbts
164+
165+
pbjs.main([ "--target", "json-module", "path/to/myproto.proto" ], function(err, output) {
166+
if (err)
167+
throw err;
168+
// do something with output
169+
});
170+
```
10171

11172
**License:** [BSD 3-Clause License](https://opensource.org/licenses/BSD-3-Clause)

0 commit comments

Comments
 (0)