@bufbuild/protoc-gen-es 0.0.8 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,12 +1,37 @@
1
1
  # @bufbuild/protoc-gen-es
2
2
 
3
- [![npm](https://img.shields.io/npm/v/@bufbuild/protoc-gen-es?style=flat-square)](https://www.npmjs.com/package/@bufbuild/protoc-gen-es)
3
+ This package provides the code generator plugin `protoc-gen-es`. The code it
4
+ generates depends on [@bufbuild/protobuf](https://www.npmjs.com/package/@bufbuild/protobuf).
4
5
 
5
- A complete implementation of protocol buffers in TypeScript,
6
- suitable for web browsers and Node.js.
7
- Learn more at [github.com/bufbuild/protobuf-es](https://github.com/bufbuild/protobuf-es).
6
+ ## Protocol Buffers for ECMAScript
7
+
8
+ A complete implementation of [Protocol Buffers](https://developers.google.com/protocol-buffers)
9
+ in TypeScript, suitable for web browsers and Node.js.
10
+
11
+ For example, the following definition:
8
12
 
9
- This is a code generator plugin for `protoc` and [`buf`](https://github.com/bufbuild/buf).
13
+ ```protobuf
14
+ message Person {
15
+ string name = 1;
16
+ int32 id = 2; // Unique ID number for this person.
17
+ string email = 3;
18
+ }
19
+ ```
20
+
21
+ Is compiled to an ECMAScript class that can be used like this:
22
+
23
+ ```typescript
24
+ let pete = new Person({
25
+ name: "pete",
26
+ id: 123
27
+ });
28
+
29
+ let bytes = pete.toBinary();
30
+ pete = Person.fromBinary(bytes);
31
+ pete = Person.fromJsonString('{"name": "pete", "id": 123}');
32
+ ```
33
+
34
+ Learn more at [github.com/bufbuild/protobuf-es](https://github.com/bufbuild/protobuf-es).
10
35
 
11
36
 
12
37
  ## Installation
@@ -24,14 +49,6 @@ Note that npm does not add the executable to your `$PATH`. You can do so with:
24
49
  PATH=$PATH:$(pwd)/node_modules/.bin
25
50
  ```
26
51
 
27
- Note that `protoc-gen-es` is actually just a simple node script that selects the
28
- correct precompiled binary for your platform. For example, if you are on a 32-bit
29
- linux machine, the optional dependency `@bufbuild/protoc-gen-es-linux-32` is
30
- automatically installed by `npm`, and our node script will run it. Note that this
31
- means you cannot move your `node_modules` directory to a different platform and
32
- run it. We recommend you run `npm ci` in CI or your docker images instead.
33
-
34
-
35
52
  ### With yarn
36
53
 
37
54
  ```shell
@@ -42,29 +59,12 @@ Note that yarn v2 does not use a `node_modules` directory anymore. To find the p
42
59
  where yarn stores the executable, run `yarn bin protoc-gen-es` (it is "unplugged"
43
60
  automatically).
44
61
 
45
- Yarn supports installing dependencies for several platforms at the same time, by
46
- adding the configuration field [`supportedArchitectures`](https://yarnpkg.com/configuration/yarnrc#supportedArchitectures)
47
- in your `.yarnrc.yml`.
48
-
49
-
50
- ### With go
51
-
52
- Alternatively, you can install the plugin with `go`:
53
-
54
- ```shell
55
- go install github.com/bufbuild/protobuf-es/cmd/protoc-gen-es@latest
56
- ```
57
-
58
- If your go environment is set up correctly, the executable is now available on
59
- your `$PATH`.
60
-
61
62
  You can always confirm successful installation with:
62
63
  ```shell
63
64
  protoc-gen-es --version
64
65
  ```
65
66
 
66
67
 
67
-
68
68
  ## Plugin options
69
69
 
70
70
  ### `target`
package/bin/protoc-gen-es CHANGED
@@ -1,109 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- // Copyright 2021-2022 Buf Technologies, Inc.
4
- //
5
- // Licensed under the Apache License, Version 2.0 (the "License");
6
- // you may not use this file except in compliance with the License.
7
- // You may obtain a copy of the License at
8
- //
9
- // http://www.apache.org/licenses/LICENSE-2.0
10
- //
11
- // Unless required by applicable law or agreed to in writing, software
12
- // distributed under the License is distributed on an "AS IS" BASIS,
13
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- // See the License for the specific language governing permissions and
15
- // limitations under the License.
3
+ const {runNodeJs} = require("@bufbuild/protoplugin");
4
+ const {protocGenEs} = require("../dist/cjs/src/protoc-gen-es-plugin.js");
16
5
 
17
- const {basename, join, dirname} = require("path");
18
- const {existsSync, readFileSync} = require("fs");
19
- const {execFileSync} = require("child_process");
20
-
21
- const baseDir = dirname(__dirname);
22
- let basePkg;
23
- try {
24
- basePkg = readPackage(baseDir);
25
- } catch (e) {
26
- exitReadBasePackage(e);
27
- }
28
- const wantName = findPlatformPackageName(basePkg);
29
- if (!basePkg.optionalDependencies[wantName]) {
30
- exitUnsupportedPlatform(basePkg);
31
- }
32
- const binPath = Object.values(basePkg.bin)[0];
33
- let absBinPath;
34
- try {
35
- absBinPath = require.resolve(join(wantName, binPath));
36
- } catch (e) {
37
- exitMissingPlatformBinary(basePkg);
38
- }
39
- execFileSync(absBinPath, process.argv.slice(2), {stdio: 'inherit', cwd: process.cwd(), env: process.env});
40
-
41
- function exitReadBasePackage(error) {
42
- const message = error instanceof Error ? error.message : String(error);
43
- process.stderr.write(`${basename(__filename)}: ${message}\n`);
44
- process.exit(1);
45
- }
46
-
47
- function exitUnsupportedPlatform(basePkg) {
48
- process.stderr.write(`${basePkg.name}: unsupported platform/architecture: ${process.platform}/${process.arch}\n`);
49
- process.exit(1);
50
- }
51
-
52
- function exitMissingPlatformBinary(basePkg) {
53
- process.stderr.write(`${basePkg.name}: binary for ${process.platform}/${process.arch} is missing\n`);
54
- process.exit(1);
55
- }
56
-
57
- function readPackage(dir) {
58
- const pkgPath = join(dir, "package.json");
59
- if (!existsSync(pkgPath)) {
60
- throw new Error(`invalid npm-base: ${pkgPath} not found`);
61
- }
62
- const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
63
- if (!pkg.name) {
64
- throw new Error(`${pkgPath} is missing "name"`);
65
- }
66
- if (!pkg.bin) {
67
- throw new Error(`${pkgPath} is missing "bin"`);
68
- }
69
- if (Object.keys(pkg.bin).length !== 1) {
70
- throw new Error(`${pkgPath} is requires exactly one entry in "bin"`);
71
- }
72
- const binName = Object.keys(pkg.bin)[0];
73
- const binValue = Object.values(pkg.bin)[0];
74
- if (
75
- binName === undefined ||
76
- binValue === undefined ||
77
- binValue !== `bin/${binName}`
78
- ) {
79
- throw new Error(
80
- `${pkgPath} is missing an entry in "bin" in the form of {"foo": "bin/foo"}`
81
- );
82
- }
83
- return pkg;
84
- }
85
-
86
- function findPlatformPackageName() {
87
- // prettier-ignore
88
- const platforms = [
89
- { name: "darwin-64", npmOs: "darwin", npmCpu: "x64", },
90
- { name: "darwin-64", npmOs: "darwin", npmCpu: "x64", },
91
- { name: "darwin-arm64", npmOs: "darwin", npmCpu: "arm64", },
92
- { name: "windows-64", npmOs: "win32", npmCpu: "x64", },
93
- { name: "windows-arm64", npmOs: "win32", npmCpu: "arm64", },
94
- { name: "windows-32", npmOs: "win32", npmCpu: "ia32", },
95
- { name: "linux-64", npmOs: "linux", npmCpu: "x64", },
96
- { name: "linux-32", npmOs: "linux", npmCpu: "ia32", },
97
- { name: "linux-arm", npmOs: "linux", npmCpu: "arm", },
98
- { name: "linux-arm64", npmOs: "linux", npmCpu: "arm64", },
99
- { name: "freebsd-64", npmOs: "freebsd", npmCpu: "x64", },
100
- { name: "freebsd-arm64", npmOs: "freebsd", npmCpu: "arm64", },
101
- { name: "netbsd-64", npmOs: "netbsd", npmCpu: "x64", },
102
- { name: "openbsd-64", npmOs: "openbsd", npmCpu: "x64", },
103
- ];
104
- const platform = platforms.find(p => p.npmOs === process.platform && p.npmCpu === process.arch);
105
- if (!platform) {
106
- return undefined;
107
- }
108
- return `${basePkg.name}-${platform.name}`;
109
- }
6
+ runNodeJs(protocGenEs);
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@bufbuild/protoc-gen-es",
3
+ "version": "0.1.0",
4
+ "description": "Protocol Buffers code generator for ECMAScript",
5
+ "license": "Apache-2.0",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/bufbuild/protobuf-es.git",
9
+ "directory": "packages/protoc-gen-es"
10
+ },
11
+ "bin": {
12
+ "protoc-gen-es": "bin/protoc-gen-es"
13
+ },
14
+ "engines": {
15
+ "node": ">=14"
16
+ },
17
+ "scripts": {
18
+ "clean": "rm -rf ./dist/cjs/*",
19
+ "build": "../../node_modules/typescript/bin/tsc --project tsconfig.json --module commonjs --outDir ./dist/cjs"
20
+ },
21
+ "preferUnplugged": true,
22
+ "dependencies": {
23
+ "@bufbuild/protoplugin": "0.1.0"
24
+ },
25
+ "peerDependencies": {
26
+ "@bufbuild/protobuf": "0.1.0"
27
+ },
28
+ "peerDependenciesMeta": {
29
+ "@bufbuild/protobuf": {
30
+ "optional": true
31
+ }
32
+ }
33
+ }
@@ -0,0 +1,194 @@
1
+ "use strict";
2
+ // Copyright 2021-2022 Buf Technologies, Inc.
3
+ //
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // you may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ //
8
+ // http://www.apache.org/licenses/LICENSE-2.0
9
+ //
10
+ // Unless required by applicable law or agreed to in writing, software
11
+ // distributed under the License is distributed on an "AS IS" BASIS,
12
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ // See the License for the specific language governing permissions and
14
+ // limitations under the License.
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.declaration = void 0;
17
+ const ecmascript_1 = require("@bufbuild/protoplugin/ecmascript");
18
+ const match_wkt_js_1 = require("./match-wkt.js");
19
+ exports.declaration = {
20
+ target: "dts",
21
+ extension: "_pb.d.ts",
22
+ generateEnum,
23
+ generateMessage,
24
+ };
25
+ // prettier-ignore
26
+ function generateEnum(schema, f, enumeration) {
27
+ f.print((0, ecmascript_1.makeJsDoc)(enumeration));
28
+ f.print("export declare enum ", enumeration, " {");
29
+ for (const value of enumeration.values) {
30
+ if (enumeration.values.indexOf(value) > 0) {
31
+ f.print();
32
+ }
33
+ f.print((0, ecmascript_1.makeJsDoc)(value, " "));
34
+ f.print(" ", (0, ecmascript_1.localName)(value), " = ", value.number, ",");
35
+ }
36
+ f.print("}");
37
+ f.print();
38
+ }
39
+ // prettier-ignore
40
+ function generateMessage(schema, f, message) {
41
+ const protoN = schema.runtime[message.file.syntax];
42
+ const { PartialMessage, FieldList, Message, PlainMessage, BinaryReadOptions, JsonReadOptions, JsonValue } = schema.runtime;
43
+ f.print((0, ecmascript_1.makeJsDoc)(message));
44
+ f.print("export declare class ", message, " extends ", Message, "<", message, "> {");
45
+ for (const member of message.members) {
46
+ switch (member.kind) {
47
+ case "oneof":
48
+ generateOneof(schema, f, member);
49
+ break;
50
+ default:
51
+ generateField(schema, f, member);
52
+ break;
53
+ }
54
+ f.print();
55
+ }
56
+ f.print(" constructor(data?: ", PartialMessage, "<", message, ">);");
57
+ f.print();
58
+ generateWktMethods(schema, f, message);
59
+ f.print(" static readonly runtime: typeof ", protoN, ";");
60
+ f.print(' static readonly typeName = ', (0, ecmascript_1.literalString)(message.typeName), ';');
61
+ f.print(" static readonly fields: ", FieldList, ";");
62
+ // In case we start supporting options, we have to surface them here
63
+ //f.print(" static readonly options: { readonly [extensionName: string]: ", rt.JsonValue, " } = {};")
64
+ f.print();
65
+ generateWktStaticMethods(schema, f, message);
66
+ f.print(" static fromBinary(bytes: Uint8Array, options?: Partial<", BinaryReadOptions, ">): ", message, ";");
67
+ f.print();
68
+ f.print(" static fromJson(jsonValue: ", JsonValue, ", options?: Partial<", JsonReadOptions, ">): ", message, ";");
69
+ f.print();
70
+ f.print(" static fromJsonString(jsonString: string, options?: Partial<", JsonReadOptions, ">): ", message, ";");
71
+ f.print();
72
+ f.print(" static equals(a: ", message, " | ", PlainMessage, "<", message, "> | undefined, b: ", message, " | ", PlainMessage, "<", message, "> | undefined): boolean;");
73
+ f.print("}");
74
+ f.print();
75
+ for (const nestedEnum of message.nestedEnums) {
76
+ generateEnum(schema, f, nestedEnum);
77
+ }
78
+ for (const nestedMessage of message.nestedMessages) {
79
+ generateMessage(schema, f, nestedMessage);
80
+ }
81
+ // We do not support extensions at this time
82
+ }
83
+ // prettier-ignore
84
+ function generateOneof(schema, f, oneof) {
85
+ f.print((0, ecmascript_1.makeJsDoc)(oneof, " "));
86
+ f.print(" ", (0, ecmascript_1.localName)(oneof), ": {");
87
+ for (const field of oneof.fields) {
88
+ if (oneof.fields.indexOf(field) > 0) {
89
+ f.print(` } | {`);
90
+ }
91
+ f.print((0, ecmascript_1.makeJsDoc)(field, " "));
92
+ const { typing } = (0, ecmascript_1.getFieldTyping)(field, f);
93
+ f.print(` value: `, typing, `;`);
94
+ f.print(` case: "`, (0, ecmascript_1.localName)(field), `";`);
95
+ }
96
+ f.print(` } | { case: undefined; value?: undefined };`);
97
+ }
98
+ function generateField(schema, f, field) {
99
+ f.print((0, ecmascript_1.makeJsDoc)(field, " "));
100
+ const e = [];
101
+ e.push(" ", (0, ecmascript_1.localName)(field));
102
+ const { typing, optional } = (0, ecmascript_1.getFieldTyping)(field, f);
103
+ if (optional) {
104
+ e.push("?: ", typing);
105
+ }
106
+ else {
107
+ e.push(": ", typing);
108
+ }
109
+ e.push(";");
110
+ f.print(e);
111
+ }
112
+ // prettier-ignore
113
+ function generateWktMethods(schema, f, message) {
114
+ const ref = (0, match_wkt_js_1.matchWkt)(message);
115
+ if (ref === undefined) {
116
+ return;
117
+ }
118
+ const { Message, MessageType, } = schema.runtime;
119
+ switch (ref.typeName) {
120
+ case "google.protobuf.Any":
121
+ f.print(" packFrom(message: ", Message, "): void;");
122
+ f.print();
123
+ f.print(" unpackTo(target: ", Message, "): boolean;");
124
+ f.print();
125
+ f.print(" is(type: ", MessageType, "): boolean;");
126
+ f.print();
127
+ f.print(" private typeNameToUrl(name: string): string;");
128
+ f.print();
129
+ f.print(" private typeUrlToName(url: string): string;");
130
+ f.print();
131
+ break;
132
+ case "google.protobuf.Timestamp":
133
+ f.print(" toDate(): Date;");
134
+ f.print();
135
+ break;
136
+ case "google.protobuf.Duration":
137
+ case "google.protobuf.Struct":
138
+ case "google.protobuf.Value":
139
+ case "google.protobuf.ListValue":
140
+ case "google.protobuf.FieldMask":
141
+ case "google.protobuf.DoubleValue":
142
+ case "google.protobuf.FloatValue":
143
+ case "google.protobuf.Int64Value":
144
+ case "google.protobuf.UInt64Value":
145
+ case "google.protobuf.Int32Value":
146
+ case "google.protobuf.UInt32Value":
147
+ case "google.protobuf.BoolValue":
148
+ case "google.protobuf.StringValue":
149
+ case "google.protobuf.BytesValue":
150
+ break;
151
+ }
152
+ }
153
+ // prettier-ignore
154
+ function generateWktStaticMethods(schema, f, message) {
155
+ const ref = (0, match_wkt_js_1.matchWkt)(message);
156
+ if (ref === undefined) {
157
+ return;
158
+ }
159
+ switch (ref.typeName) {
160
+ case "google.protobuf.Any":
161
+ f.print(" static pack(message: Message): ", message, ";");
162
+ f.print();
163
+ break;
164
+ case "google.protobuf.Timestamp":
165
+ f.print(" static now(): ", message, ";");
166
+ f.print();
167
+ f.print(" static fromDate(date: Date): ", message, ";");
168
+ f.print();
169
+ break;
170
+ case "google.protobuf.DoubleValue":
171
+ case "google.protobuf.FloatValue":
172
+ case "google.protobuf.Int64Value":
173
+ case "google.protobuf.UInt64Value":
174
+ case "google.protobuf.Int32Value":
175
+ case "google.protobuf.UInt32Value":
176
+ case "google.protobuf.BoolValue":
177
+ case "google.protobuf.StringValue":
178
+ case "google.protobuf.BytesValue": {
179
+ const { typing } = (0, ecmascript_1.getFieldTyping)(ref.value, f);
180
+ f.print(" static readonly fieldWrapper: {");
181
+ f.print(" wrapField(value: ", typing, " | ", message, "): ", message, ",");
182
+ f.print(" unwrapField(value: ", message, "): ", typing, ",");
183
+ f.print(" };");
184
+ f.print();
185
+ break;
186
+ }
187
+ case "google.protobuf.Duration":
188
+ case "google.protobuf.Struct":
189
+ case "google.protobuf.Value":
190
+ case "google.protobuf.ListValue":
191
+ case "google.protobuf.FieldMask":
192
+ break;
193
+ }
194
+ }