@bufbuild/protoc-gen-es 2.0.0-alpha.1 → 2.0.0-alpha.3

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
@@ -91,19 +91,18 @@ By default, we generate JavaScript and TypeScript declaration files, which
91
91
  produces the smallest code size and is the most compatible with various
92
92
  bundler configurations. If you prefer to generate TypeScript, use `target=ts`.
93
93
 
94
- ### `import_extension=.js`
94
+ ### `import_extension`
95
95
 
96
96
  By default, [protoc-gen-es](https://www.npmjs.com/package/@bufbuild/protoc-gen-es)
97
97
  (and all other plugins based on [@bufbuild/protoplugin](https://www.npmjs.com/package/@bufbuild/protoplugin))
98
- uses a `.js` file extensions in import paths, even in TypeScript files.
98
+ does not add a file extensions to import paths.
99
99
 
100
- This is unintuitive, but necessary for [ECMAScript modules in Node.js](https://www.typescriptlang.org/docs/handbook/esm-node.html).
101
- Unfortunately, not all bundlers and tools have caught up yet, and Deno
102
- requires `.ts`. With this plugin option, you can replace `.js` extensions
100
+ Some environments require an import extension. For example, using [ECMAScript modules in Node.js](https://www.typescriptlang.org/docs/handbook/esm-node.html) requires the `.js` extension, and Deno requires `.ts`. With this plugin option, you can add `.js`/`.ts` extensions
103
101
  in import paths with the given value. For example, set
104
102
 
105
- - `import_extension=none` to remove the `.js` extension.
106
- - `import_extension=.ts` to replace the `.js` extension with `.ts`.
103
+ - `import_extension=.js` to add the `.js` extension.
104
+ - `import_extension=.ts` to add the `.ts` extension.
105
+ - `import_extension=none` to not add an extension. (Default)
107
106
 
108
107
  ### `js_import_style`
109
108
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bufbuild/protoc-gen-es",
3
- "version": "2.0.0-alpha.1",
3
+ "version": "2.0.0-alpha.3",
4
4
  "description": "Protocol Buffers code generator for ECMAScript",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -20,15 +20,19 @@
20
20
  },
21
21
  "preferUnplugged": true,
22
22
  "dependencies": {
23
- "@bufbuild/protobuf": "^2.0.0-alpha.1",
24
- "@bufbuild/protoplugin": "2.0.0-alpha.1"
23
+ "@bufbuild/protobuf": "^2.0.0-alpha.3",
24
+ "@bufbuild/protoplugin": "2.0.0-alpha.3"
25
25
  },
26
26
  "peerDependencies": {
27
- "@bufbuild/protobuf": "2.0.0-alpha.1"
27
+ "@bufbuild/protobuf": "2.0.0-alpha.3"
28
28
  },
29
29
  "peerDependenciesMeta": {
30
30
  "@bufbuild/protobuf": {
31
31
  "optional": true
32
32
  }
33
- }
33
+ },
34
+ "files": [
35
+ "dist/**",
36
+ "bin/**"
37
+ ]
34
38
  }
@@ -38,8 +38,9 @@ function generateTs(schema) {
38
38
  f.preamble(file);
39
39
  const { GenDescFile } = f.runtime.codegen;
40
40
  const fileDesc = f.importDesc(file);
41
- f.print(f.exportDecl("const", fileDesc.name), ": ", GenDescFile, " = ", pure);
42
- f.print(" ", getFileDescCall(f, file), ";");
41
+ generateDescDoc(f, file);
42
+ f.print(f.export("const", fileDesc.name), ": ", GenDescFile, " = ", pure);
43
+ f.print(" ", getFileDescCall(f, file, schema), ";");
43
44
  f.print();
44
45
  for (const desc of schema.typesInFile(file)) {
45
46
  switch (desc.kind) {
@@ -47,12 +48,10 @@ function generateTs(schema) {
47
48
  generateMessageShape(f, desc, "ts");
48
49
  const { GenDescMessage, messageDesc } = f.runtime.codegen;
49
50
  const MessageShape = f.importShape(desc);
50
- const fileDesc = f.importDesc(file);
51
51
  const name = f.importDesc(desc).name;
52
- f.print("// Describes the ", desc.toString(), ".");
53
- f.print("// Use `create(", name, ")` to create a new ", MessageShape.name, ".");
52
+ generateDescDoc(f, desc);
54
53
  const call = (0, util_1.functionCall)(messageDesc, [fileDesc, ...(0, codegenv1_1.pathInFileDesc)(desc)]);
55
- f.print(f.exportDecl("const", name), ": ", GenDescMessage, "<", MessageShape, ">", " = ", pure);
54
+ f.print(f.export("const", name), ": ", GenDescMessage, "<", MessageShape, ">", " = ", pure);
56
55
  f.print(" ", call, ";");
57
56
  f.print();
58
57
  break;
@@ -61,11 +60,10 @@ function generateTs(schema) {
61
60
  generateEnumShape(f, desc);
62
61
  const { GenDescEnum, enumDesc } = f.runtime.codegen;
63
62
  const EnumShape = f.importShape(desc);
64
- const fileDesc = f.importDesc(file);
65
- f.print("// Describes the ", desc.toString(), ".");
63
+ generateDescDoc(f, desc);
66
64
  const name = f.importDesc(desc).name;
67
65
  const call = (0, util_1.functionCall)(enumDesc, [fileDesc, ...(0, codegenv1_1.pathInFileDesc)(desc)]);
68
- f.print(f.exportDecl("const", name), ": ", GenDescEnum, "<", EnumShape, ">", " = ", pure);
66
+ f.print(f.export("const", name), ": ", GenDescEnum, "<", EnumShape, ">", " = ", pure);
69
67
  f.print(" ", call, ";");
70
68
  f.print();
71
69
  break;
@@ -74,10 +72,10 @@ function generateTs(schema) {
74
72
  const { GenDescExtension, extDesc } = f.runtime.codegen;
75
73
  const name = f.importDesc(desc).name;
76
74
  const E = f.importShape(desc.extendee);
77
- const V = (0, util_1.getFieldTypeInfo)(desc).typing;
78
- const call = (0, util_1.functionCall)(extDesc, [f.importDesc(file), ...(0, codegenv1_1.pathInFileDesc)(desc)]);
75
+ const V = (0, util_1.fieldTypeScriptType)(desc).typing;
76
+ const call = (0, util_1.functionCall)(extDesc, [fileDesc, ...(0, codegenv1_1.pathInFileDesc)(desc)]);
79
77
  f.print(f.jsDoc(desc));
80
- f.print(f.exportDecl("const", name), ": ", GenDescExtension, "<", E, ", ", V, ">", " = ", pure);
78
+ f.print(f.export("const", name), ": ", GenDescExtension, "<", E, ", ", V, ">", " = ", pure);
81
79
  f.print(" ", call, ";");
82
80
  f.print();
83
81
  break;
@@ -85,9 +83,9 @@ function generateTs(schema) {
85
83
  case "service": {
86
84
  const { GenDescService, serviceDesc } = f.runtime.codegen;
87
85
  const name = f.importDesc(desc).name;
88
- const call = (0, util_1.functionCall)(serviceDesc, [f.importDesc(file), ...(0, codegenv1_1.pathInFileDesc)(desc)]);
86
+ const call = (0, util_1.functionCall)(serviceDesc, [fileDesc, ...(0, codegenv1_1.pathInFileDesc)(desc)]);
89
87
  f.print(f.jsDoc(desc));
90
- f.print(f.exportDecl("const", name), ": ", GenDescService, "<", getServiceShapeExpr(f, desc), "> = ", pure);
88
+ f.print(f.export("const", name), ": ", GenDescService, "<", getServiceShapeExpr(f, desc), "> = ", pure);
91
89
  f.print(" ", call, ";");
92
90
  f.print();
93
91
  break;
@@ -102,18 +100,18 @@ function generateJs(schema) {
102
100
  const f = schema.generateFile(file.name + "_pb.js");
103
101
  f.preamble(file);
104
102
  const fileDesc = f.importDesc(file);
105
- f.print(f.exportDecl("const", fileDesc.name), " = ", pure);
106
- f.print(" ", getFileDescCall(f, file), ";");
103
+ generateDescDoc(f, file);
104
+ f.print(f.export("const", fileDesc.name), " = ", pure);
105
+ f.print(" ", getFileDescCall(f, file, schema), ";");
107
106
  f.print();
108
107
  for (const desc of schema.typesInFile(file)) {
109
108
  switch (desc.kind) {
110
109
  case "message": {
111
110
  const { messageDesc } = f.runtime.codegen;
112
- const MessageShape = f.importShape(desc);
113
111
  const name = f.importDesc(desc).name;
114
- f.print("// Describes the ", desc.toString(), ". Use `create(", name, ")` to create a new ", MessageShape.name, ".");
112
+ generateDescDoc(f, desc);
115
113
  const call = (0, util_1.functionCall)(messageDesc, [fileDesc, ...(0, codegenv1_1.pathInFileDesc)(desc)]);
116
- f.print(f.exportDecl("const", name), " = ", pure);
114
+ f.print(f.export("const", name), " = ", pure);
117
115
  f.print(" ", call, ";");
118
116
  f.print();
119
117
  break;
@@ -122,10 +120,10 @@ function generateJs(schema) {
122
120
  // generate descriptor
123
121
  {
124
122
  const { enumDesc } = f.runtime.codegen;
125
- f.print("// Describes the ", desc.toString(), ".");
123
+ generateDescDoc(f, desc);
126
124
  const name = f.importDesc(desc).name;
127
125
  const call = (0, util_1.functionCall)(enumDesc, [fileDesc, ...(0, codegenv1_1.pathInFileDesc)(desc)]);
128
- f.print(f.exportDecl("const", name), " = ", pure);
126
+ f.print(f.export("const", name), " = ", pure);
129
127
  f.print(" ", call, ";");
130
128
  f.print();
131
129
  }
@@ -134,7 +132,7 @@ function generateJs(schema) {
134
132
  f.print(f.jsDoc(desc));
135
133
  const { tsEnum } = f.runtime.codegen;
136
134
  const call = (0, util_1.functionCall)(tsEnum, [f.importDesc(desc)]);
137
- f.print(f.exportDecl("const", f.importShape(desc).name), " = ", pure);
135
+ f.print(f.export("const", f.importShape(desc).name), " = ", pure);
138
136
  f.print(" ", call, ";");
139
137
  f.print();
140
138
  }
@@ -143,9 +141,9 @@ function generateJs(schema) {
143
141
  case "extension": {
144
142
  const { extDesc } = f.runtime.codegen;
145
143
  const name = f.importDesc(desc).name;
146
- const call = (0, util_1.functionCall)(extDesc, [f.importDesc(desc.file), ...(0, codegenv1_1.pathInFileDesc)(desc)]);
144
+ const call = (0, util_1.functionCall)(extDesc, [fileDesc, ...(0, codegenv1_1.pathInFileDesc)(desc)]);
147
145
  f.print(f.jsDoc(desc));
148
- f.print(f.exportDecl("const", name), " = ", pure);
146
+ f.print(f.export("const", name), " = ", pure);
149
147
  f.print(" ", call, ";");
150
148
  f.print();
151
149
  break;
@@ -154,8 +152,8 @@ function generateJs(schema) {
154
152
  const { serviceDesc } = f.runtime.codegen;
155
153
  const name = f.importDesc(desc).name;
156
154
  f.print(f.jsDoc(desc));
157
- const call = (0, util_1.functionCall)(serviceDesc, [f.importDesc(desc.file), ...(0, codegenv1_1.pathInFileDesc)(desc)]);
158
- f.print(f.exportDecl("const", name), " = ", pure);
155
+ const call = (0, util_1.functionCall)(serviceDesc, [fileDesc, ...(0, codegenv1_1.pathInFileDesc)(desc)]);
156
+ f.print(f.export("const", name), " = ", pure);
159
157
  f.print(" ", call, ";");
160
158
  f.print();
161
159
  break;
@@ -171,7 +169,8 @@ function generateDts(schema) {
171
169
  f.preamble(file);
172
170
  const { GenDescFile } = f.runtime.codegen;
173
171
  const fileDesc = f.importDesc(file);
174
- f.print(f.exportDecl("declare const", fileDesc.name), ": ", GenDescFile, ";");
172
+ generateDescDoc(f, file);
173
+ f.print(f.export("declare const", fileDesc.name), ": ", GenDescFile, ";");
175
174
  f.print();
176
175
  for (const desc of schema.typesInFile(file)) {
177
176
  switch (desc.kind) {
@@ -180,8 +179,8 @@ function generateDts(schema) {
180
179
  const { GenDescMessage } = f.runtime.codegen;
181
180
  const MessageShape = f.importShape(desc);
182
181
  const name = f.importDesc(desc).name;
183
- f.print("// Describes the ", desc.toString(), ". Use `create(", name, ")` to create a new ", MessageShape.name, ".");
184
- f.print(f.exportDecl("declare const", name), ": ", GenDescMessage, "<", MessageShape, ">", ";");
182
+ generateDescDoc(f, desc);
183
+ f.print(f.export("declare const", name), ": ", GenDescMessage, "<", MessageShape, ">", ";");
185
184
  f.print();
186
185
  break;
187
186
  }
@@ -189,9 +188,9 @@ function generateDts(schema) {
189
188
  generateEnumShape(f, desc);
190
189
  const { GenDescEnum } = f.runtime.codegen;
191
190
  const EnumShape = f.importShape(desc);
192
- f.print("// Describes the ", desc.toString(), ".");
191
+ generateDescDoc(f, desc);
193
192
  const name = f.importDesc(desc).name;
194
- f.print(f.exportDecl("declare const", name), ": ", GenDescEnum, "<", EnumShape, ">;");
193
+ f.print(f.export("declare const", name), ": ", GenDescEnum, "<", EnumShape, ">;");
195
194
  f.print();
196
195
  break;
197
196
  }
@@ -199,9 +198,9 @@ function generateDts(schema) {
199
198
  const { GenDescExtension } = f.runtime.codegen;
200
199
  const name = f.importDesc(desc).name;
201
200
  const E = f.importShape(desc.extendee);
202
- const V = (0, util_1.getFieldTypeInfo)(desc).typing;
201
+ const V = (0, util_1.fieldTypeScriptType)(desc).typing;
203
202
  f.print(f.jsDoc(desc));
204
- f.print(f.exportDecl("declare const", name), ": ", GenDescExtension, "<", E, ", ", V, ">;");
203
+ f.print(f.export("declare const", name), ": ", GenDescExtension, "<", E, ", ", V, ">;");
205
204
  f.print();
206
205
  break;
207
206
  }
@@ -209,7 +208,7 @@ function generateDts(schema) {
209
208
  const { GenDescService } = f.runtime.codegen;
210
209
  const name = f.importDesc(desc).name;
211
210
  f.print(f.jsDoc(desc));
212
- f.print(f.exportDecl("declare const", name), ": ", GenDescService, "<", getServiceShapeExpr(f, desc), ">;");
211
+ f.print(f.export("declare const", name), ": ", GenDescService, "<", getServiceShapeExpr(f, desc), ">;");
213
212
  f.print();
214
213
  break;
215
214
  }
@@ -217,9 +216,39 @@ function generateDts(schema) {
217
216
  }
218
217
  }
219
218
  }
219
+ function generateDescDoc(f, desc) {
220
+ let lines;
221
+ switch (desc.kind) {
222
+ case "file":
223
+ lines = [`Describes the ${desc.toString()}.`];
224
+ break;
225
+ case "message":
226
+ lines = [
227
+ `Describes the ${desc.toString()}.`,
228
+ `Use \`create(${f.importDesc(desc).name})\` to create a new message.`,
229
+ ];
230
+ break;
231
+ case "enum":
232
+ lines = [`Describes the ${desc.toString()}.`];
233
+ break;
234
+ }
235
+ const deprecated = desc.deprecated || (0, reflect_1.parentTypes)(desc).some((d) => d.deprecated);
236
+ if (deprecated) {
237
+ lines.push("@deprecated");
238
+ }
239
+ f.print({
240
+ kind: "es_jsdoc",
241
+ text: lines.join("\n"),
242
+ });
243
+ }
220
244
  // prettier-ignore
221
- function getFileDescCall(f, file) {
222
- const info = (0, codegenv1_1.embedFileDesc)(file);
245
+ function getFileDescCall(f, file, schema) {
246
+ // Schema provides files with source retention options. Since we do not want to
247
+ // embed source retention options in generated code, we use FileDescriptorProto
248
+ // messages from CodeGeneratorRequest.proto_file instead.
249
+ const sourceFile = file.proto;
250
+ const runtimeFile = schema.proto.protoFile.find(f => f.name == sourceFile.name);
251
+ const info = (0, codegenv1_1.embedFileDesc)(runtimeFile !== null && runtimeFile !== void 0 ? runtimeFile : sourceFile);
223
252
  if (info.bootable && !f.runtime.create.from.startsWith("@bufbuild/protobuf")) {
224
253
  // google/protobuf/descriptor.proto is embedded as a plain object when
225
254
  // bootstrapping to avoid recursion
@@ -247,10 +276,10 @@ function getServiceShapeExpr(f, service) {
247
276
  print("{");
248
277
  for (const method of service.methods) {
249
278
  print(f.jsDoc(method, " "));
250
- print(" ", (0, reflect_1.localName)(method), ": {");
251
- print(" kind: ", f.string(method.methodKind), ";");
252
- print(" I: ", f.importShape(method.input), ";");
253
- print(" O: ", f.importShape(method.output), ";");
279
+ print(" ", method.localName, ": {");
280
+ print(" methodKind: ", f.string(method.methodKind), ";");
281
+ print(" input: typeof ", f.importDesc(method.input, true), ";");
282
+ print(" output: typeof ", f.importDesc(method.output, true), ";");
254
283
  print(" },");
255
284
  }
256
285
  print("}");
@@ -259,13 +288,13 @@ function getServiceShapeExpr(f, service) {
259
288
  // prettier-ignore
260
289
  function generateEnumShape(f, enumeration) {
261
290
  f.print(f.jsDoc(enumeration));
262
- f.print(f.exportDecl("enum", f.importShape(enumeration).name), " {");
291
+ f.print(f.export("enum", f.importShape(enumeration).name), " {");
263
292
  for (const value of enumeration.values) {
264
293
  if (enumeration.values.indexOf(value) > 0) {
265
294
  f.print();
266
295
  }
267
296
  f.print(f.jsDoc(value, " "));
268
- f.print(" ", (0, reflect_1.localName)(value), " = ", value.number, ",");
297
+ f.print(" ", value.localName, " = ", value.number, ",");
269
298
  }
270
299
  f.print("}");
271
300
  f.print();
@@ -275,31 +304,31 @@ function generateMessageShape(f, message, target) {
275
304
  const { Message } = f.runtime;
276
305
  const declaration = target == "ts" ? "type" : "declare type";
277
306
  f.print(f.jsDoc(message));
278
- f.print(f.exportDecl(declaration, f.importShape(message).name), " = ", Message, "<", f.string(message.typeName), "> & {");
307
+ f.print(f.export(declaration, f.importShape(message).name), " = ", Message, "<", f.string(message.typeName), "> & {");
279
308
  for (const member of message.members) {
280
309
  switch (member.kind) {
281
310
  case "oneof":
282
311
  f.print(f.jsDoc(member, " "));
283
- f.print(" ", (0, reflect_1.localName)(member), ": {");
312
+ f.print(" ", member.localName, ": {");
284
313
  for (const field of member.fields) {
285
314
  if (member.fields.indexOf(field) > 0) {
286
315
  f.print(` } | {`);
287
316
  }
288
317
  f.print(f.jsDoc(field, " "));
289
- const { typing } = (0, util_1.getFieldTypeInfo)(field);
318
+ const { typing } = (0, util_1.fieldTypeScriptType)(field);
290
319
  f.print(` value: `, typing, `;`);
291
- f.print(` case: "`, (0, reflect_1.localName)(field), `";`);
320
+ f.print(` case: "`, field.localName, `";`);
292
321
  }
293
322
  f.print(` } | { case: undefined; value?: undefined };`);
294
323
  break;
295
324
  default: {
296
325
  f.print(f.jsDoc(member, " "));
297
- const { typing, optional } = (0, util_1.getFieldTypeInfo)(member);
298
- if ((0, util_1.fieldUsesPrototype)(member) || !optional) {
299
- f.print(" ", (0, reflect_1.localName)(member), ": ", typing, ";");
326
+ const { typing, optional } = (0, util_1.fieldTypeScriptType)(member);
327
+ if (optional) {
328
+ f.print(" ", member.localName, "?: ", typing, ";");
300
329
  }
301
330
  else {
302
- f.print(" ", (0, reflect_1.localName)(member), "?: ", typing, ";");
331
+ f.print(" ", member.localName, ": ", typing, ";");
303
332
  }
304
333
  break;
305
334
  }
@@ -13,41 +13,22 @@
13
13
  // See the License for the specific language governing permissions and
14
14
  // limitations under the License.
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
- exports.arrayLiteral = exports.functionCall = exports.getFieldTypeInfo = exports.fieldUsesPrototype = void 0;
17
- const reflect_1 = require("@bufbuild/protobuf/reflect");
16
+ exports.arrayLiteral = exports.functionCall = exports.fieldTypeScriptType = void 0;
17
+ const protobuf_1 = require("@bufbuild/protobuf");
18
+ const codegenv1_1 = require("@bufbuild/protobuf/codegenv1");
18
19
  const wkt_1 = require("@bufbuild/protobuf/wkt");
19
- /**
20
- * Tells whether a field uses the prototype chain for field presence.
21
- * Behavior must match with the counterpart in @bufbuild/protobuf.
22
- */
23
- function fieldUsesPrototype(field) {
24
- if (field.parent.file.edition != wkt_1.Edition.EDITION_PROTO2) {
25
- return false;
26
- }
27
- if (field.fieldKind != "scalar" && field.fieldKind != "enum") {
28
- return false;
29
- }
30
- if (field.oneof) {
31
- return false;
32
- }
33
- // proto2 singular scalar and enum fields use an initial value on the prototype chain
34
- return true;
35
- }
36
- exports.fieldUsesPrototype = fieldUsesPrototype;
37
- function getFieldTypeInfo(field) {
20
+ function fieldTypeScriptType(field) {
38
21
  const typing = [];
39
- let typingInferrableFromZeroValue;
40
22
  let optional = false;
41
23
  switch (field.fieldKind) {
42
24
  case "scalar":
43
- typing.push((0, reflect_1.scalarTypeScriptType)(field.scalar, field.longType));
44
- optional = field.optional;
45
- typingInferrableFromZeroValue = true;
25
+ typing.push((0, codegenv1_1.scalarTypeScriptType)(field.scalar, field.longAsString));
26
+ optional = field.proto.proto3Optional;
46
27
  break;
47
28
  case "message": {
48
29
  if (!field.oneof && (0, wkt_1.isWrapperDesc)(field.message)) {
49
30
  const baseType = field.message.fields[0].scalar;
50
- typing.push((0, reflect_1.scalarTypeScriptType)(baseType, reflect_1.LongType.BIGINT));
31
+ typing.push((0, codegenv1_1.scalarTypeScriptType)(baseType, false));
51
32
  }
52
33
  else {
53
34
  typing.push({
@@ -56,7 +37,6 @@ function getFieldTypeInfo(field) {
56
37
  });
57
38
  }
58
39
  optional = true;
59
- typingInferrableFromZeroValue = true;
60
40
  break;
61
41
  }
62
42
  case "enum":
@@ -64,12 +44,10 @@ function getFieldTypeInfo(field) {
64
44
  kind: "es_shape_ref",
65
45
  desc: field.enum,
66
46
  });
67
- optional = field.optional;
68
- typingInferrableFromZeroValue = true;
47
+ optional = field.proto.proto3Optional;
69
48
  break;
70
49
  case "list":
71
50
  optional = false;
72
- typingInferrableFromZeroValue = false;
73
51
  switch (field.listKind) {
74
52
  case "enum":
75
53
  typing.push({
@@ -78,7 +56,7 @@ function getFieldTypeInfo(field) {
78
56
  }, "[]");
79
57
  break;
80
58
  case "scalar":
81
- typing.push((0, reflect_1.scalarTypeScriptType)(field.scalar, field.longType), "[]");
59
+ typing.push((0, codegenv1_1.scalarTypeScriptType)(field.scalar, field.longAsString), "[]");
82
60
  break;
83
61
  case "message": {
84
62
  typing.push({
@@ -92,11 +70,11 @@ function getFieldTypeInfo(field) {
92
70
  case "map": {
93
71
  let keyType;
94
72
  switch (field.mapKey) {
95
- case reflect_1.ScalarType.INT32:
96
- case reflect_1.ScalarType.FIXED32:
97
- case reflect_1.ScalarType.UINT32:
98
- case reflect_1.ScalarType.SFIXED32:
99
- case reflect_1.ScalarType.SINT32:
73
+ case protobuf_1.ScalarType.INT32:
74
+ case protobuf_1.ScalarType.FIXED32:
75
+ case protobuf_1.ScalarType.UINT32:
76
+ case protobuf_1.ScalarType.SFIXED32:
77
+ case protobuf_1.ScalarType.SINT32:
100
78
  keyType = "number";
101
79
  break;
102
80
  default:
@@ -106,7 +84,7 @@ function getFieldTypeInfo(field) {
106
84
  let valueType;
107
85
  switch (field.mapKind) {
108
86
  case "scalar":
109
- valueType = (0, reflect_1.scalarTypeScriptType)(field.scalar, reflect_1.LongType.BIGINT);
87
+ valueType = (0, codegenv1_1.scalarTypeScriptType)(field.scalar, false);
110
88
  break;
111
89
  case "message":
112
90
  valueType = {
@@ -122,14 +100,13 @@ function getFieldTypeInfo(field) {
122
100
  break;
123
101
  }
124
102
  typing.push("{ [key: ", keyType, "]: ", valueType, " }");
125
- typingInferrableFromZeroValue = false;
126
103
  optional = false;
127
104
  break;
128
105
  }
129
106
  }
130
- return { typing, optional, typingInferrableFromZeroValue };
107
+ return { typing, optional };
131
108
  }
132
- exports.getFieldTypeInfo = getFieldTypeInfo;
109
+ exports.fieldTypeScriptType = fieldTypeScriptType;
133
110
  function functionCall(fn, args, typeParams) {
134
111
  let tp = [];
135
112
  if (typeParams !== undefined && typeParams.length > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bufbuild/protoc-gen-es",
3
- "version": "2.0.0-alpha.1",
3
+ "version": "2.0.0-alpha.3",
4
4
  "description": "Protocol Buffers code generator for ECMAScript",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -20,15 +20,19 @@
20
20
  },
21
21
  "preferUnplugged": true,
22
22
  "dependencies": {
23
- "@bufbuild/protobuf": "^2.0.0-alpha.1",
24
- "@bufbuild/protoplugin": "2.0.0-alpha.1"
23
+ "@bufbuild/protobuf": "^2.0.0-alpha.3",
24
+ "@bufbuild/protoplugin": "2.0.0-alpha.3"
25
25
  },
26
26
  "peerDependencies": {
27
- "@bufbuild/protobuf": "2.0.0-alpha.1"
27
+ "@bufbuild/protobuf": "2.0.0-alpha.3"
28
28
  },
29
29
  "peerDependenciesMeta": {
30
30
  "@bufbuild/protobuf": {
31
31
  "optional": true
32
32
  }
33
- }
33
+ },
34
+ "files": [
35
+ "dist/**",
36
+ "bin/**"
37
+ ]
34
38
  }
@@ -1,336 +0,0 @@
1
- // Copyright 2021-2024 Buf Technologies, Inc.
2
- //
3
- // Licensed under the Apache License, Version 2.0 (the "License");
4
- // you may not use this file except in compliance with the License.
5
- // You may obtain a copy of the License at
6
- //
7
- // http://www.apache.org/licenses/LICENSE-2.0
8
- //
9
- // Unless required by applicable law or agreed to in writing, software
10
- // distributed under the License is distributed on an "AS IS" BASIS,
11
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- // See the License for the specific language governing permissions and
13
- // limitations under the License.
14
-
15
- import type {
16
- DescEnum,
17
- DescFile,
18
- DescMessage,
19
- DescService,
20
- } from "@bufbuild/protobuf";
21
- import { localName } from "@bufbuild/protobuf/reflect";
22
- import { embedFileDesc, pathInFileDesc } from "@bufbuild/protobuf/codegenv1";
23
- import { createEcmaScriptPlugin } from "@bufbuild/protoplugin";
24
- import type {
25
- Schema,
26
- GeneratedFile,
27
- Printable,
28
- Target,
29
- } from "@bufbuild/protoplugin/ecmascript";
30
- import {
31
- arrayLiteral,
32
- fieldUsesPrototype,
33
- functionCall,
34
- getFieldTypeInfo,
35
- } from "./util";
36
- import { version } from "../package.json";
37
-
38
- export const protocGenEs = createEcmaScriptPlugin({
39
- name: "protoc-gen-es",
40
- version: `v${String(version)}`,
41
- generateTs,
42
- generateJs,
43
- generateDts,
44
- });
45
-
46
- // This annotation informs bundlers that the succeeding function call is free of
47
- // side effects. This means the symbol can be removed from the module during
48
- // tree-shaking if it is unused.
49
- // See https://github.com/bufbuild/protobuf-es/pull/470
50
- const pure = "/*@__PURE__*/";
51
-
52
- // prettier-ignore
53
- function generateTs(schema: Schema) {
54
- for (const file of schema.files) {
55
- const f = schema.generateFile(file.name + "_pb.ts");
56
- f.preamble(file);
57
- const { GenDescFile } = f.runtime.codegen;
58
- const fileDesc = f.importDesc(file);
59
- f.print(f.exportDecl("const", fileDesc.name), ": ", GenDescFile, " = ", pure);
60
- f.print(" ", getFileDescCall(f, file), ";");
61
- f.print();
62
- for (const desc of schema.typesInFile(file)) {
63
- switch (desc.kind) {
64
- case "message": {
65
- generateMessageShape(f, desc, "ts");
66
- const {GenDescMessage, messageDesc} = f.runtime.codegen;
67
- const MessageShape = f.importShape(desc);
68
- const fileDesc = f.importDesc(file);
69
- const name = f.importDesc(desc).name;
70
- f.print("// Describes the ", desc.toString(), ".");
71
- f.print("// Use `create(", name, ")` to create a new ", MessageShape.name, ".");
72
- const call = functionCall(messageDesc, [fileDesc, ...pathInFileDesc(desc)]);
73
- f.print(f.exportDecl("const", name), ": ", GenDescMessage, "<", MessageShape, ">", " = ", pure);
74
- f.print(" ", call, ";");
75
- f.print();
76
- break;
77
- }
78
- case "enum": {
79
- generateEnumShape(f, desc);
80
- const {GenDescEnum, enumDesc} = f.runtime.codegen;
81
- const EnumShape = f.importShape(desc);
82
- const fileDesc = f.importDesc(file);
83
- f.print("// Describes the ", desc.toString(), ".");
84
- const name = f.importDesc(desc).name;
85
- const call = functionCall(enumDesc, [fileDesc, ...pathInFileDesc(desc)]);
86
- f.print(f.exportDecl("const", name), ": ", GenDescEnum, "<", EnumShape, ">", " = ", pure);
87
- f.print(" ", call, ";");
88
- f.print();
89
- break;
90
- }
91
- case "extension": {
92
- const { GenDescExtension, extDesc } = f.runtime.codegen;
93
- const name = f.importDesc(desc).name;
94
- const E = f.importShape(desc.extendee);
95
- const V = getFieldTypeInfo(desc).typing;
96
- const call = functionCall(extDesc, [f.importDesc(file), ...pathInFileDesc(desc)]);
97
- f.print(f.jsDoc(desc));
98
- f.print(f.exportDecl("const", name), ": ", GenDescExtension, "<", E, ", ", V, ">", " = ", pure);
99
- f.print(" ", call, ";");
100
- f.print();
101
- break;
102
- }
103
- case "service": {
104
- const { GenDescService, serviceDesc} = f.runtime.codegen;
105
- const name = f.importDesc(desc).name;
106
- const call = functionCall(serviceDesc, [f.importDesc(file), ...pathInFileDesc(desc)]);
107
- f.print(f.jsDoc(desc));
108
- f.print(f.exportDecl("const", name), ": ", GenDescService, "<", getServiceShapeExpr(f, desc), "> = ", pure);
109
- f.print(" ", call, ";");
110
- f.print();
111
- break;
112
- }
113
- }
114
- }
115
- }
116
- }
117
-
118
- // prettier-ignore
119
- function generateJs(schema: Schema) {
120
- for (const file of schema.files) {
121
- const f = schema.generateFile(file.name + "_pb.js");
122
- f.preamble(file);
123
- const fileDesc = f.importDesc(file);
124
- f.print(f.exportDecl("const", fileDesc.name), " = ", pure);
125
- f.print(" ", getFileDescCall(f, file), ";");
126
- f.print();
127
- for (const desc of schema.typesInFile(file)) {
128
- switch (desc.kind) {
129
- case "message": {
130
- const { messageDesc} = f.runtime.codegen;
131
- const MessageShape = f.importShape(desc);
132
- const name = f.importDesc(desc).name;
133
- f.print("// Describes the ", desc.toString(), ". Use `create(", name, ")` to create a new ", MessageShape.name, ".");
134
- const call = functionCall(messageDesc, [fileDesc, ...pathInFileDesc(desc)]);
135
- f.print(f.exportDecl("const", name), " = ", pure);
136
- f.print(" ", call, ";");
137
- f.print();
138
- break;
139
- }
140
- case "enum": {
141
- // generate descriptor
142
- {
143
- const { enumDesc } = f.runtime.codegen;
144
- f.print("// Describes the ", desc.toString(), ".");
145
- const name = f.importDesc(desc).name;
146
- const call = functionCall(enumDesc, [fileDesc, ...pathInFileDesc(desc)]);
147
- f.print(f.exportDecl("const", name), " = ", pure);
148
- f.print(" ", call, ";");
149
- f.print();
150
- }
151
- // declare TypeScript enum
152
- {
153
- f.print(f.jsDoc(desc));
154
- const { tsEnum } = f.runtime.codegen;
155
- const call = functionCall(tsEnum, [f.importDesc(desc)]);
156
- f.print(f.exportDecl("const", f.importShape(desc).name), " = ", pure);
157
- f.print(" ", call, ";");
158
- f.print();
159
- }
160
- break;
161
- }
162
- case "extension": {
163
- const { extDesc } = f.runtime.codegen;
164
- const name = f.importDesc(desc).name;
165
- const call = functionCall(extDesc, [f.importDesc(desc.file), ...pathInFileDesc(desc)]);
166
- f.print(f.jsDoc(desc));
167
- f.print(f.exportDecl("const", name), " = ", pure);
168
- f.print(" ", call, ";");
169
- f.print();
170
- break;
171
- }
172
- case "service": {
173
- const { serviceDesc} = f.runtime.codegen;
174
- const name = f.importDesc(desc).name;
175
- f.print(f.jsDoc(desc));
176
- const call = functionCall(serviceDesc, [f.importDesc(desc.file), ...pathInFileDesc(desc)]);
177
- f.print(f.exportDecl("const", name), " = ", pure);
178
- f.print(" ", call, ";");
179
- f.print();
180
- break;
181
- }
182
- }
183
- }
184
- }
185
- }
186
-
187
- // prettier-ignore
188
- function generateDts(schema: Schema) {
189
- for (const file of schema.files) {
190
- const f = schema.generateFile(file.name + "_pb.d.ts");
191
- f.preamble(file);
192
- const { GenDescFile } = f.runtime.codegen;
193
- const fileDesc = f.importDesc(file);
194
- f.print(f.exportDecl("declare const", fileDesc.name), ": ", GenDescFile, ";");
195
- f.print();
196
- for (const desc of schema.typesInFile(file)) {
197
- switch (desc.kind) {
198
- case "message": {
199
- generateMessageShape(f, desc, "dts");
200
- const { GenDescMessage } = f.runtime.codegen;
201
- const MessageShape = f.importShape(desc);
202
- const name = f.importDesc(desc).name;
203
- f.print("// Describes the ", desc.toString(), ". Use `create(", name, ")` to create a new ", MessageShape.name, ".");
204
- f.print(f.exportDecl("declare const", name), ": ", GenDescMessage, "<", MessageShape, ">", ";");
205
- f.print();
206
- break;
207
- }
208
- case "enum": {
209
- generateEnumShape(f, desc);
210
- const { GenDescEnum } = f.runtime.codegen;
211
- const EnumShape = f.importShape(desc);
212
- f.print("// Describes the ", desc.toString(), ".");
213
- const name = f.importDesc(desc).name;
214
- f.print(f.exportDecl("declare const", name), ": ", GenDescEnum, "<", EnumShape, ">;");
215
- f.print();
216
- break;
217
- }
218
- case "extension": {
219
- const { GenDescExtension } = f.runtime.codegen;
220
- const name = f.importDesc(desc).name;
221
- const E = f.importShape(desc.extendee);
222
- const V = getFieldTypeInfo(desc).typing;
223
- f.print(f.jsDoc(desc));
224
- f.print(f.exportDecl("declare const", name), ": ", GenDescExtension, "<", E, ", ", V, ">;");
225
- f.print();
226
- break;
227
- }
228
- case "service": {
229
- const { GenDescService } = f.runtime.codegen;
230
- const name = f.importDesc(desc).name;
231
- f.print(f.jsDoc(desc));
232
- f.print(f.exportDecl("declare const", name), ": ", GenDescService, "<", getServiceShapeExpr(f, desc), ">;");
233
- f.print();
234
- break;
235
- }
236
- }
237
- }
238
- }
239
- }
240
-
241
- // prettier-ignore
242
- function getFileDescCall(f: GeneratedFile, file: DescFile) {
243
- const info = embedFileDesc(file);
244
- if (info.bootable && !f.runtime.create.from.startsWith("@bufbuild/protobuf")) {
245
- // google/protobuf/descriptor.proto is embedded as a plain object when
246
- // bootstrapping to avoid recursion
247
- return functionCall(f.runtime.codegen.boot, [JSON.stringify(info.boot())]);
248
- }
249
- const { fileDesc } = f.runtime.codegen;
250
- if (file.dependencies.length > 0) {
251
- const deps: Printable = file.dependencies.map((f) => ({
252
- kind: "es_desc_ref",
253
- desc: f,
254
- }));
255
- return functionCall(fileDesc, [
256
- f.string(info.base64()),
257
- arrayLiteral(deps),
258
- ]);
259
- }
260
- return functionCall(fileDesc, [f.string(info.base64())]);
261
- }
262
-
263
- // prettier-ignore
264
- function getServiceShapeExpr(f: GeneratedFile, service: DescService): Printable {
265
- const p: Printable[] = [];
266
- function print(...printables: Printable[]) {
267
- p.push(...printables, "\n");
268
- }
269
- print("{");
270
- for (const method of service.methods) {
271
- print(f.jsDoc(method, " "));
272
- print(" ", localName(method), ": {");
273
- print(" kind: ", f.string(method.methodKind), ";");
274
- print(" I: ", f.importShape(method.input), ";");
275
- print(" O: ", f.importShape(method.output), ";");
276
- print(" },");
277
- }
278
- print("}");
279
- return p;
280
- }
281
-
282
- // prettier-ignore
283
- function generateEnumShape(f: GeneratedFile, enumeration: DescEnum) {
284
- f.print(f.jsDoc(enumeration));
285
- f.print(f.exportDecl("enum", f.importShape(enumeration).name), " {");
286
- for (const value of enumeration.values) {
287
- if (enumeration.values.indexOf(value) > 0) {
288
- f.print();
289
- }
290
- f.print(f.jsDoc(value, " "));
291
- f.print(" ", localName(value), " = ", value.number, ",");
292
- }
293
- f.print("}");
294
- f.print();
295
- }
296
-
297
- // prettier-ignore
298
- function generateMessageShape(f: GeneratedFile, message: DescMessage, target: Extract<Target, "ts" | "dts">) {
299
- const { Message } = f.runtime;
300
- const declaration = target == "ts" ? "type" : "declare type";
301
- f.print(f.jsDoc(message));
302
- f.print(f.exportDecl(declaration, f.importShape(message).name), " = ", Message, "<", f.string(message.typeName), "> & {");
303
- for (const member of message.members) {
304
- switch (member.kind) {
305
- case "oneof":
306
- f.print(f.jsDoc(member, " "));
307
- f.print(" ", localName(member), ": {");
308
- for (const field of member.fields) {
309
- if (member.fields.indexOf(field) > 0) {
310
- f.print(` } | {`);
311
- }
312
- f.print(f.jsDoc(field, " "));
313
- const { typing } = getFieldTypeInfo(field);
314
- f.print(` value: `, typing, `;`);
315
- f.print(` case: "`, localName(field), `";`);
316
- }
317
- f.print(` } | { case: undefined; value?: undefined };`);
318
- break;
319
- default: {
320
- f.print(f.jsDoc(member, " "));
321
- const {typing, optional} = getFieldTypeInfo(member);
322
- if (fieldUsesPrototype(member) || !optional) {
323
- f.print(" ", localName(member), ": ", typing, ";");
324
- } else {
325
- f.print(" ", localName(member), "?: ", typing, ";");
326
- }
327
- break;
328
- }
329
- }
330
- if (message.members.indexOf(member) < message.members.length - 1) {
331
- f.print();
332
- }
333
- }
334
- f.print("};");
335
- f.print();
336
- }
package/src/util.ts DELETED
@@ -1,176 +0,0 @@
1
- // Copyright 2021-2024 Buf Technologies, Inc.
2
- //
3
- // Licensed under the Apache License, Version 2.0 (the "License");
4
- // you may not use this file except in compliance with the License.
5
- // You may obtain a copy of the License at
6
- //
7
- // http://www.apache.org/licenses/LICENSE-2.0
8
- //
9
- // Unless required by applicable law or agreed to in writing, software
10
- // distributed under the License is distributed on an "AS IS" BASIS,
11
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- // See the License for the specific language governing permissions and
13
- // limitations under the License.
14
-
15
- import type { DescExtension, DescField } from "@bufbuild/protobuf";
16
- import {
17
- LongType,
18
- ScalarType,
19
- scalarTypeScriptType,
20
- } from "@bufbuild/protobuf/reflect";
21
- import { Edition, isWrapperDesc } from "@bufbuild/protobuf/wkt";
22
- import type { Printable } from "@bufbuild/protoplugin/ecmascript";
23
-
24
- /**
25
- * Tells whether a field uses the prototype chain for field presence.
26
- * Behavior must match with the counterpart in @bufbuild/protobuf.
27
- */
28
- export function fieldUsesPrototype(field: DescField): field is DescField & {
29
- fieldKind: "scalar" | "enum";
30
- oneof: undefined;
31
- repeated: false;
32
- } {
33
- if (field.parent.file.edition != Edition.EDITION_PROTO2) {
34
- return false;
35
- }
36
- if (field.fieldKind != "scalar" && field.fieldKind != "enum") {
37
- return false;
38
- }
39
- if (field.oneof) {
40
- return false;
41
- }
42
- // proto2 singular scalar and enum fields use an initial value on the prototype chain
43
- return true;
44
- }
45
-
46
- export function getFieldTypeInfo(field: DescField | DescExtension): {
47
- typing: Printable;
48
- optional: boolean;
49
- typingInferrableFromZeroValue: boolean;
50
- } {
51
- const typing: Printable = [];
52
- let typingInferrableFromZeroValue: boolean;
53
- let optional = false;
54
- switch (field.fieldKind) {
55
- case "scalar":
56
- typing.push(scalarTypeScriptType(field.scalar, field.longType));
57
- optional = field.optional;
58
- typingInferrableFromZeroValue = true;
59
- break;
60
- case "message": {
61
- if (!field.oneof && isWrapperDesc(field.message)) {
62
- const baseType = field.message.fields[0].scalar;
63
- typing.push(scalarTypeScriptType(baseType, LongType.BIGINT));
64
- } else {
65
- typing.push({
66
- kind: "es_shape_ref",
67
- desc: field.message,
68
- });
69
- }
70
- optional = true;
71
- typingInferrableFromZeroValue = true;
72
- break;
73
- }
74
- case "enum":
75
- typing.push({
76
- kind: "es_shape_ref",
77
- desc: field.enum,
78
- });
79
- optional = field.optional;
80
- typingInferrableFromZeroValue = true;
81
- break;
82
- case "list":
83
- optional = false;
84
- typingInferrableFromZeroValue = false;
85
- switch (field.listKind) {
86
- case "enum":
87
- typing.push(
88
- {
89
- kind: "es_shape_ref",
90
- desc: field.enum,
91
- },
92
- "[]",
93
- );
94
- break;
95
- case "scalar":
96
- typing.push(scalarTypeScriptType(field.scalar, field.longType), "[]");
97
- break;
98
- case "message": {
99
- typing.push(
100
- {
101
- kind: "es_shape_ref",
102
- desc: field.message,
103
- },
104
- "[]",
105
- );
106
- break;
107
- }
108
- }
109
- break;
110
- case "map": {
111
- let keyType: string;
112
- switch (field.mapKey) {
113
- case ScalarType.INT32:
114
- case ScalarType.FIXED32:
115
- case ScalarType.UINT32:
116
- case ScalarType.SFIXED32:
117
- case ScalarType.SINT32:
118
- keyType = "number";
119
- break;
120
- default:
121
- keyType = "string";
122
- break;
123
- }
124
- let valueType: Printable;
125
- switch (field.mapKind) {
126
- case "scalar":
127
- valueType = scalarTypeScriptType(field.scalar, LongType.BIGINT);
128
- break;
129
- case "message":
130
- valueType = {
131
- kind: "es_shape_ref",
132
- desc: field.message,
133
- };
134
- break;
135
- case "enum":
136
- valueType = {
137
- kind: "es_shape_ref",
138
- desc: field.enum,
139
- };
140
- break;
141
- }
142
- typing.push("{ [key: ", keyType, "]: ", valueType, " }");
143
- typingInferrableFromZeroValue = false;
144
- optional = false;
145
- break;
146
- }
147
- }
148
- return { typing, optional, typingInferrableFromZeroValue };
149
- }
150
-
151
- export function functionCall(
152
- fn: Printable,
153
- args: Printable[],
154
- typeParams?: Printable[],
155
- ): Printable {
156
- let tp: Printable = [];
157
- if (typeParams !== undefined && typeParams.length > 0) {
158
- tp = ["<", commaSeparate(typeParams), ">"];
159
- }
160
- return [fn, ...tp, "(", commaSeparate(args), ")"];
161
- }
162
-
163
- export function arrayLiteral(elements: Printable[]): Printable {
164
- return ["[", commaSeparate(elements), "]"];
165
- }
166
-
167
- function commaSeparate(elements: Printable[]): Printable {
168
- const r: Printable[] = [];
169
- for (let i = 0; i < elements.length; i++) {
170
- r.push(elements[i]);
171
- if (i < elements.length - 1) {
172
- r.push(", ");
173
- }
174
- }
175
- return r;
176
- }
package/tsconfig.json DELETED
@@ -1,12 +0,0 @@
1
- {
2
- "files": ["src/protoc-gen-es-plugin.ts"],
3
- "extends": "../../tsconfig.base.json",
4
- "compilerOptions": {
5
- // We import the plugin's version number from package.json
6
- "resolveJsonModule": true,
7
- // This package is CommonJS
8
- "verbatimModuleSyntax": false,
9
- "module": "CommonJS",
10
- "moduleResolution": "Node10"
11
- }
12
- }