@bufbuild/protoc-gen-es 0.0.6 → 0.0.9

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.
@@ -0,0 +1,552 @@
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.typescript = void 0;
17
+ const protobuf_1 = require("@bufbuild/protobuf");
18
+ const ecmascript_1 = require("@bufbuild/protoplugin/ecmascript");
19
+ const match_wkt_js_1 = require("./match-wkt.js");
20
+ const javascript_js_1 = require("./javascript.js");
21
+ const ecmascript_2 = require("@bufbuild/protoplugin/ecmascript");
22
+ exports.typescript = {
23
+ target: "ts",
24
+ extension: "_pb.ts",
25
+ generateEnum,
26
+ generateMessage,
27
+ };
28
+ // prettier-ignore
29
+ function generateEnum(schema, f, enumeration) {
30
+ const protoN = schema.runtime[enumeration.file.syntax];
31
+ f.print((0, ecmascript_1.makeJsDoc)(enumeration));
32
+ f.print("export enum ", enumeration, " {");
33
+ for (const value of enumeration.values) {
34
+ if (enumeration.values.indexOf(value) > 0) {
35
+ f.print();
36
+ }
37
+ f.print((0, ecmascript_1.makeJsDoc)(value, " "));
38
+ f.print(" ", (0, ecmascript_1.localName)(value), " = ", value.number, ",");
39
+ }
40
+ f.print("}");
41
+ f.print("// Retrieve enum metadata with: ", enumeration.file.syntax, ".getEnumType(", enumeration, ")");
42
+ f.print(protoN, `.util.setEnumType(`, enumeration, `, "`, enumeration.typeName, `", [`);
43
+ for (const value of enumeration.values) {
44
+ f.print(" { no: ", value.number, ', name: "', value.name, '" },');
45
+ }
46
+ f.print("]);");
47
+ f.print();
48
+ }
49
+ // prettier-ignore
50
+ function generateMessage(schema, f, message) {
51
+ const protoN = schema.runtime[message.file.syntax];
52
+ const { PartialMessage, FieldList, Message, PlainMessage, BinaryReadOptions, JsonReadOptions, JsonValue } = schema.runtime;
53
+ f.print((0, ecmascript_1.makeJsDoc)(message));
54
+ f.print("export class ", message, " extends ", Message, "<", message, "> {");
55
+ for (const member of message.members) {
56
+ switch (member.kind) {
57
+ case "oneof":
58
+ generateOneof(schema, f, member);
59
+ break;
60
+ default:
61
+ generateField(schema, f, member);
62
+ break;
63
+ }
64
+ f.print();
65
+ }
66
+ f.print(" constructor(data?: ", PartialMessage, "<", message, ">) {");
67
+ f.print(" super();");
68
+ f.print(" ", protoN, ".util.initPartial(data, this);");
69
+ f.print(" }");
70
+ f.print();
71
+ generateWktMethods(schema, f, message);
72
+ f.print(" static readonly runtime = ", protoN, ";");
73
+ f.print(' static readonly typeName = ', (0, ecmascript_2.literalString)(message.typeName), ';');
74
+ f.print(" static readonly fields: ", FieldList, " = ", protoN, ".util.newFieldList(() => [");
75
+ for (const field of message.fields) {
76
+ (0, javascript_js_1.generateFieldInfo)(schema, f, field);
77
+ }
78
+ f.print(" ]);");
79
+ // In case we start supporting options, we have to surface them here
80
+ //f.print(" static readonly options: { readonly [extensionName: string]: ", rt.JsonValue, " } = {};")
81
+ f.print();
82
+ generateWktStaticMethods(schema, f, message);
83
+ f.print(" static fromBinary(bytes: Uint8Array, options?: Partial<", BinaryReadOptions, ">): ", message, " {");
84
+ f.print(" return new ", message, "().fromBinary(bytes, options);");
85
+ f.print(" }");
86
+ f.print();
87
+ f.print(" static fromJson(jsonValue: ", JsonValue, ", options?: Partial<", JsonReadOptions, ">): ", message, " {");
88
+ f.print(" return new ", message, "().fromJson(jsonValue, options);");
89
+ f.print(" }");
90
+ f.print();
91
+ f.print(" static fromJsonString(jsonString: string, options?: Partial<", JsonReadOptions, ">): ", message, " {");
92
+ f.print(" return new ", message, "().fromJsonString(jsonString, options);");
93
+ f.print(" }");
94
+ f.print();
95
+ f.print(" static equals(a: ", message, " | ", PlainMessage, "<", message, "> | undefined, b: ", message, " | ", PlainMessage, "<", message, "> | undefined): boolean {");
96
+ f.print(" return ", protoN, ".util.equals(", message, ", a, b);");
97
+ f.print(" }");
98
+ f.print("}");
99
+ f.print();
100
+ for (const nestedEnum of message.nestedEnums) {
101
+ generateEnum(schema, f, nestedEnum);
102
+ }
103
+ for (const nestedMessage of message.nestedMessages) {
104
+ generateMessage(schema, f, nestedMessage);
105
+ }
106
+ // We do not support extensions at this time
107
+ }
108
+ // prettier-ignore
109
+ function generateOneof(schema, f, oneof) {
110
+ f.print((0, ecmascript_1.makeJsDoc)(oneof, " "));
111
+ f.print(" ", (0, ecmascript_1.localName)(oneof), ": {");
112
+ for (const field of oneof.fields) {
113
+ if (oneof.fields.indexOf(field) > 0) {
114
+ f.print(` } | {`);
115
+ }
116
+ f.print((0, ecmascript_1.makeJsDoc)(field, " "));
117
+ const { typing } = (0, ecmascript_1.getFieldTyping)(field, f);
118
+ f.print(` value: `, typing, `;`);
119
+ f.print(` case: "`, (0, ecmascript_1.localName)(field), `";`);
120
+ }
121
+ f.print(` } | { case: undefined; value?: undefined } = { case: undefined };`);
122
+ }
123
+ function generateField(schema, f, field) {
124
+ f.print((0, ecmascript_1.makeJsDoc)(field, " "));
125
+ const e = [];
126
+ e.push(" ", (0, ecmascript_1.localName)(field));
127
+ const { defaultValue, typingInferrable } = (0, ecmascript_1.getFieldIntrinsicDefaultValue)(field);
128
+ const { typing, optional } = (0, ecmascript_1.getFieldTyping)(field, f);
129
+ if (optional || defaultValue === undefined) {
130
+ e.push("?: ", typing);
131
+ }
132
+ else if (!typingInferrable) {
133
+ e.push(": ", typing);
134
+ }
135
+ if (defaultValue !== undefined) {
136
+ e.push(" = ", defaultValue);
137
+ }
138
+ e.push(";");
139
+ f.print(e);
140
+ }
141
+ // prettier-ignore
142
+ function generateWktMethods(schema, f, message) {
143
+ var _a;
144
+ const ref = (0, match_wkt_js_1.matchWkt)(message);
145
+ if (ref === undefined) {
146
+ return;
147
+ }
148
+ const { Message, JsonValue, JsonReadOptions, JsonWriteOptions, JsonObject, MessageType, ScalarType: rtScalarType, protoInt64, } = schema.runtime;
149
+ const protoN = schema.runtime[message.file.syntax];
150
+ switch (ref.typeName) {
151
+ case "google.protobuf.Any":
152
+ f.print(" override toJson(options?: Partial<", JsonWriteOptions, ">): ", JsonValue, " {");
153
+ f.print(` if (this.`, (0, ecmascript_1.localName)(ref.typeUrl), ` === "") {`);
154
+ f.print(" return {};");
155
+ f.print(" }");
156
+ f.print(" const typeName = this.typeUrlToName(this.", (0, ecmascript_1.localName)(ref.typeUrl), ");");
157
+ f.print(" const messageType = options?.typeRegistry?.findMessage(typeName);");
158
+ f.print(" if (!messageType) {");
159
+ f.print(" throw new Error(`cannot encode message ", message.typeName, ' to JSON: "${this.', (0, ecmascript_1.localName)(ref.typeUrl), '}" is not in the type registry`);');
160
+ f.print(" }");
161
+ f.print(" const message = messageType.fromBinary(this.", (0, ecmascript_1.localName)(ref.value), ");");
162
+ f.print(" let json = message.toJson(options);");
163
+ f.print(` if (typeName.startsWith("google.protobuf.") || (json === null || Array.isArray(json) || typeof json !== "object")) {`);
164
+ f.print(" json = {value: json};");
165
+ f.print(" }");
166
+ f.print(` json["@type"] = this.`, (0, ecmascript_1.localName)(ref.typeUrl), `;`);
167
+ f.print(" return json;");
168
+ f.print(" }");
169
+ f.print();
170
+ f.print(" override fromJson(json: ", JsonValue, ", options?: Partial<", JsonReadOptions, ">): this {");
171
+ f.print(` if (json === null || Array.isArray(json) || typeof json != "object") {`);
172
+ f.print(" throw new Error(`cannot decode message ", message.typeName, ' from JSON: expected object but got ${json === null ? "null" : Array.isArray(json) ? "array" : typeof json}`);');
173
+ f.print(" }");
174
+ f.print(` const typeUrl = json["@type"];`);
175
+ f.print(` if (typeof typeUrl != "string" || typeUrl == "") {`);
176
+ f.print(" throw new Error(`cannot decode message ", message.typeName, ' from JSON: "@type" is empty`);');
177
+ f.print(" }");
178
+ f.print(" const typeName = this.typeUrlToName(typeUrl), messageType = options?.typeRegistry?.findMessage(typeName);");
179
+ f.print(" if (!messageType) {");
180
+ f.print(" throw new Error(`cannot decode message ", message.typeName, " from JSON: ${typeUrl} is not in the type registry`);");
181
+ f.print(" }");
182
+ f.print(" let message;");
183
+ f.print(` if (typeName.startsWith("google.protobuf.") && Object.prototype.hasOwnProperty.call(json, "value")) {`);
184
+ f.print(` message = messageType.fromJson(json["value"], options);`);
185
+ f.print(" } else {");
186
+ f.print(" const copy = Object.assign({}, json);");
187
+ f.print(` delete copy["@type"];`);
188
+ f.print(" message = messageType.fromJson(copy, options);");
189
+ f.print(" }");
190
+ f.print(" this.packFrom(message);");
191
+ f.print(" return this;");
192
+ f.print(" }");
193
+ f.print();
194
+ f.print(" packFrom(message: ", Message, "): void {");
195
+ f.print(" this.", (0, ecmascript_1.localName)(ref.value), " = message.toBinary();");
196
+ f.print(" this.", (0, ecmascript_1.localName)(ref.typeUrl), " = this.typeNameToUrl(message.getType().typeName);");
197
+ f.print(" }");
198
+ f.print();
199
+ f.print(" unpackTo(target: ", Message, "): boolean {");
200
+ f.print(" if (!this.is(target.getType())) {");
201
+ f.print(" return false;");
202
+ f.print(" }");
203
+ f.print(" target.fromBinary(this.", (0, ecmascript_1.localName)(ref.value), ");");
204
+ f.print(" return true;");
205
+ f.print(" }");
206
+ f.print();
207
+ f.print(" is(type: ", MessageType, "): boolean {");
208
+ f.print(" return this.", (0, ecmascript_1.localName)(ref.typeUrl), " === this.typeNameToUrl(type.typeName);");
209
+ f.print(" }");
210
+ f.print();
211
+ f.print(" private typeNameToUrl(name: string): string {");
212
+ f.print(" return `type.googleapis.com/${name}`;");
213
+ f.print(" }");
214
+ f.print();
215
+ f.print(" private typeUrlToName(url: string): string {");
216
+ f.print(" if (!url.length) {");
217
+ f.print(" throw new Error(`invalid type url: ${url}`);");
218
+ f.print(" }");
219
+ f.print(` const slash = url.lastIndexOf("/");`);
220
+ f.print(" const name = slash > 0 ? url.substring(slash + 1) : url;");
221
+ f.print(" if (!name.length) {");
222
+ f.print(" throw new Error(`invalid type url: ${url}`);");
223
+ f.print(" }");
224
+ f.print(" return name;");
225
+ f.print(" }");
226
+ f.print();
227
+ break;
228
+ case "google.protobuf.Timestamp":
229
+ f.print(" override fromJson(json: ", JsonValue, ", options?: Partial<", JsonReadOptions, ">): this {");
230
+ f.print(` if (typeof json !== "string") {`);
231
+ f.print(" throw new Error(`cannot decode ", message.typeName, " from JSON: ${", protoN, ".json.debug(json)}`);");
232
+ f.print(" }");
233
+ f.print(` const matches = json.match(/^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(?:Z|\\.([0-9]{3,9})Z|([+-][0-9][0-9]:[0-9][0-9]))$/);`);
234
+ f.print(" if (!matches) {");
235
+ f.print(" throw new Error(`cannot decode ", message.typeName, " from JSON: invalid RFC 3339 string`);");
236
+ f.print(" }");
237
+ f.print(` const ms = Date.parse(matches[1] + "-" + matches[2] + "-" + matches[3] + "T" + matches[4] + ":" + matches[5] + ":" + matches[6] + (matches[8] ? matches[8] : "Z"));`);
238
+ f.print(" if (Number.isNaN(ms)) {");
239
+ f.print(" throw new Error(`cannot decode ", message.typeName, " from JSON: invalid RFC 3339 string`);");
240
+ f.print(" }");
241
+ f.print(` if (ms < Date.parse("0001-01-01T00:00:00Z") || ms > Date.parse("9999-12-31T23:59:59Z")) {`);
242
+ f.print(" throw new Error(`cannot decode message ", message.typeName, " from JSON: must be from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z inclusive`);");
243
+ f.print(" }");
244
+ f.print(" this.", (0, ecmascript_1.localName)(ref.seconds), " = ", protoInt64, ".parse(ms / 1000);");
245
+ f.print(" this.", (0, ecmascript_1.localName)(ref.nanos), " = 0;");
246
+ f.print(" if (matches[7]) {");
247
+ f.print(` this.`, (0, ecmascript_1.localName)(ref.nanos), ` = (parseInt("1" + matches[7] + "0".repeat(9 - matches[7].length)) - 1000000000);`);
248
+ f.print(" }");
249
+ f.print(" return this;");
250
+ f.print(" }");
251
+ f.print();
252
+ f.print(" override toJson(options?: Partial<", JsonWriteOptions, ">): JsonValue {");
253
+ f.print(" const ms = Number(this.", (0, ecmascript_1.localName)(ref.seconds), ") * 1000;");
254
+ f.print(` if (ms < Date.parse("0001-01-01T00:00:00Z") || ms > Date.parse("9999-12-31T23:59:59Z")) {`);
255
+ f.print(" throw new Error(`cannot encode ", message.typeName, " to JSON: must be from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z inclusive`);");
256
+ f.print(" }");
257
+ f.print(" if (this.", (0, ecmascript_1.localName)(ref.nanos), " < 0) {");
258
+ f.print(" throw new Error(`cannot encode ", message.typeName, " to JSON: nanos must not be negative`);");
259
+ f.print(" }");
260
+ f.print(` let z = "Z";`);
261
+ f.print(" if (this.", (0, ecmascript_1.localName)(ref.nanos), " > 0) {");
262
+ f.print(" const nanosStr = (this.", (0, ecmascript_1.localName)(ref.nanos), " + 1000000000).toString().substring(1);");
263
+ f.print(` if (nanosStr.substring(3) === "000000") {`);
264
+ f.print(` z = "." + nanosStr.substring(0, 3) + "Z";`);
265
+ f.print(` } else if (nanosStr.substring(6) === "000") {`);
266
+ f.print(` z = "." + nanosStr.substring(0, 6) + "Z";`);
267
+ f.print(" } else {");
268
+ f.print(` z = "." + nanosStr + "Z";`);
269
+ f.print(" }");
270
+ f.print(" }");
271
+ f.print(` return new Date(ms).toISOString().replace(".000Z", z);`);
272
+ f.print(" }");
273
+ f.print();
274
+ f.print(" toDate(): Date {");
275
+ f.print(" return new Date(Number(this.", (0, ecmascript_1.localName)(ref.seconds), ") * 1000 + Math.ceil(this.", (0, ecmascript_1.localName)(ref.nanos), " / 1000000));");
276
+ f.print(" }");
277
+ f.print();
278
+ break;
279
+ case "google.protobuf.Duration":
280
+ f.print(" override fromJson(json: ", JsonValue, ", options?: Partial<", JsonReadOptions, ">): this {");
281
+ f.print(` if (typeof json !== "string") {`);
282
+ f.print(" throw new Error(`cannot decode ", message.typeName, " from JSON: ${proto3.json.debug(json)}`);");
283
+ f.print(" }");
284
+ f.print(` const match = json.match(/^(-?[0-9]+)(?:\\.([0-9]+))?s/);`);
285
+ f.print(" if (match === null) {");
286
+ f.print(" throw new Error(`cannot decode ", message.typeName, " from JSON: ${", protoN, ".json.debug(json)}`);");
287
+ f.print(" }");
288
+ f.print(" const longSeconds = Number(match[1]);");
289
+ f.print(" if (longSeconds > 315576000000 || longSeconds < -315576000000) {");
290
+ f.print(" throw new Error(`cannot decode ", message.typeName, " from JSON: ${", protoN, ".json.debug(json)}`);");
291
+ f.print(" }");
292
+ f.print(" this.", (0, ecmascript_1.localName)(ref.seconds), " = ", protoInt64, ".parse(longSeconds);");
293
+ f.print(` if (typeof match[2] == "string") {`);
294
+ f.print(` const nanosStr = match[2] + "0".repeat(9 - match[2].length);`);
295
+ f.print(" this.", (0, ecmascript_1.localName)(ref.nanos), " = parseInt(nanosStr);");
296
+ f.print(" if (longSeconds < ", protoInt64, ".zero) {");
297
+ f.print(" this.", (0, ecmascript_1.localName)(ref.nanos), " = -this.", (0, ecmascript_1.localName)(ref.nanos), ";");
298
+ f.print(" }");
299
+ f.print(" }");
300
+ f.print(" return this;");
301
+ f.print(" }");
302
+ f.print();
303
+ f.print(" override toJson(options?: Partial<", JsonWriteOptions, ">): JsonValue {");
304
+ f.print(" if (Number(this.", (0, ecmascript_1.localName)(ref.seconds), ") > 315576000000 || Number(this.", (0, ecmascript_1.localName)(ref.seconds), ") < -315576000000) {");
305
+ f.print(" throw new Error(`cannot encode ", message.typeName, " to JSON: value out of range`);");
306
+ f.print(" }");
307
+ f.print(" let text = this.", (0, ecmascript_1.localName)(ref.seconds), ".toString();");
308
+ f.print(" if (this.", (0, ecmascript_1.localName)(ref.nanos), " !== 0) {");
309
+ f.print(" let nanosStr = Math.abs(this.", (0, ecmascript_1.localName)(ref.nanos), ").toString();");
310
+ f.print(` nanosStr = "0".repeat(9 - nanosStr.length) + nanosStr;`);
311
+ f.print(` if (nanosStr.substring(3) === "000000") {`);
312
+ f.print(" nanosStr = nanosStr.substring(0, 3);");
313
+ f.print(` } else if (nanosStr.substring(6) === "000") {`);
314
+ f.print(" nanosStr = nanosStr.substring(0, 6);");
315
+ f.print(` }`);
316
+ f.print(` text += "." + nanosStr;`);
317
+ f.print(" }");
318
+ f.print(` return text + "s";`);
319
+ f.print(" }");
320
+ f.print();
321
+ break;
322
+ case "google.protobuf.Struct":
323
+ f.print(" override toJson(options?: Partial<", JsonWriteOptions, ">): ", JsonValue, " {");
324
+ f.print(" const json: ", JsonObject, " = {}");
325
+ f.print(" for (const [k, v] of Object.entries(this.", (0, ecmascript_1.localName)(ref.fields), ")) {");
326
+ f.print(" json[k] = v.toJson(options);");
327
+ f.print(" }");
328
+ f.print(" return json;");
329
+ f.print(" }");
330
+ f.print();
331
+ f.print(" override fromJson(json: ", JsonValue, ", options?: Partial<", JsonReadOptions, ">): this {");
332
+ f.print(` if (typeof json != "object" || json == null || Array.isArray(json)) {`);
333
+ f.print(` throw new Error("cannot decode `, message.typeName, ` from JSON " + `, protoN, `.json.debug(json));`);
334
+ f.print(" }");
335
+ f.print(" for (const [k, v] of Object.entries(json)) {");
336
+ f.print(" this.", (0, ecmascript_1.localName)(ref.fields), "[k] = ", (_a = ref.fields.mapValue.message) !== null && _a !== void 0 ? _a : "", ".fromJson(v);");
337
+ f.print(" }");
338
+ f.print(" return this;");
339
+ f.print(" }");
340
+ f.print();
341
+ break;
342
+ case "google.protobuf.Value":
343
+ f.print(" override toJson(options?: Partial<", JsonWriteOptions, ">): ", JsonValue, " {");
344
+ f.print(" switch (this.", (0, ecmascript_1.localName)(ref.kind), ".case) {");
345
+ f.print(` case "`, (0, ecmascript_1.localName)(ref.nullValue), `":`);
346
+ f.print(" return null;");
347
+ f.print(` case "`, (0, ecmascript_1.localName)(ref.boolValue), `":`);
348
+ f.print(` case "`, (0, ecmascript_1.localName)(ref.numberValue), `":`);
349
+ f.print(` case "`, (0, ecmascript_1.localName)(ref.stringValue), `":`);
350
+ f.print(" return this.", (0, ecmascript_1.localName)(ref.kind), ".value;");
351
+ f.print(` case "`, (0, ecmascript_1.localName)(ref.structValue), `":`);
352
+ f.print(` case "`, (0, ecmascript_1.localName)(ref.listValue), `":`);
353
+ f.print(` return this.`, (0, ecmascript_1.localName)(ref.kind), `.value.toJson({...options, emitDefaultValues: true});`);
354
+ f.print(" }");
355
+ f.print(` throw new Error("`, message.typeName, ` must have a value");`);
356
+ f.print(" }");
357
+ f.print();
358
+ f.print(" override fromJson(json: ", JsonValue, ", options?: Partial<", JsonReadOptions, ">): this {");
359
+ f.print(" switch (typeof json) {");
360
+ f.print(` case "number":`);
361
+ f.print(` this.kind = { case: "`, (0, ecmascript_1.localName)(ref.numberValue), `", value: json };`);
362
+ f.print(" break;");
363
+ f.print(` case "string":`);
364
+ f.print(` this.kind = { case: "`, (0, ecmascript_1.localName)(ref.stringValue), `", value: json };`);
365
+ f.print(" break;");
366
+ f.print(` case "boolean":`);
367
+ f.print(` this.kind = { case: "`, (0, ecmascript_1.localName)(ref.boolValue), `", value: json };`);
368
+ f.print(" break;");
369
+ f.print(` case "object":`);
370
+ f.print(" if (json === null) {");
371
+ f.print(` this.kind = { case: "`, (0, ecmascript_1.localName)(ref.nullValue), `", value: `, ref.nullValue.enum, `.`, (0, ecmascript_1.localName)(ref.nullValue.enum.values[0]), ` };`);
372
+ f.print(" } else if (Array.isArray(json)) {");
373
+ f.print(` this.kind = { case: "`, (0, ecmascript_1.localName)(ref.listValue), `", value: `, ref.listValue.message, `.fromJson(json) };`);
374
+ f.print(" } else {");
375
+ f.print(` this.kind = { case: "`, (0, ecmascript_1.localName)(ref.structValue), `", value: `, ref.structValue.message, `.fromJson(json) };`);
376
+ f.print(" }");
377
+ f.print(" break;");
378
+ f.print(" default:");
379
+ f.print(` throw new Error("cannot decode `, message.typeName, ` from JSON " + `, protoN, `.json.debug(json));`);
380
+ f.print(" }");
381
+ f.print(" return this;");
382
+ f.print(" }");
383
+ f.print();
384
+ break;
385
+ case "google.protobuf.ListValue":
386
+ f.print(` override toJson(options?: Partial<`, JsonWriteOptions, `>): `, JsonValue, ` {`);
387
+ f.print(` return this.`, (0, ecmascript_1.localName)(ref.values), `.map(v => v.toJson());`);
388
+ f.print(` }`);
389
+ f.print();
390
+ f.print(` override fromJson(json: `, JsonValue, `, options?: Partial<`, JsonReadOptions, `>): this {`);
391
+ f.print(` if (!Array.isArray(json)) {`);
392
+ f.print(` throw new Error("cannot decode `, message.typeName, ` from JSON " + `, protoN, `.json.debug(json));`);
393
+ f.print(` }`);
394
+ f.print(` for (let e of json) {`);
395
+ f.print(` this.`, (0, ecmascript_1.localName)(ref.values), `.push(`, ref.values.message, `.fromJson(e));`);
396
+ f.print(` }`);
397
+ f.print(` return this;`);
398
+ f.print(` }`);
399
+ f.print();
400
+ break;
401
+ case "google.protobuf.FieldMask":
402
+ f.print(` override toJson(options?: Partial<`, JsonWriteOptions, `>): `, JsonValue, ` {`);
403
+ f.print(` // Converts snake_case to protoCamelCase according to the convention`);
404
+ f.print(` // used by protoc to convert a field name to a JSON name.`);
405
+ f.print(` function protoCamelCase(snakeCase: string): string {`);
406
+ f.print(` let capNext = false;`);
407
+ f.print(` const b = [];`);
408
+ f.print(` for (let i = 0; i < snakeCase.length; i++) {`);
409
+ f.print(` let c = snakeCase.charAt(i);`);
410
+ f.print(` switch (c) {`);
411
+ f.print(` case '_':`);
412
+ f.print(` capNext = true;`);
413
+ f.print(` break;`);
414
+ f.print(` case '0':`);
415
+ f.print(` case '1':`);
416
+ f.print(` case '2':`);
417
+ f.print(` case '3':`);
418
+ f.print(` case '4':`);
419
+ f.print(` case '5':`);
420
+ f.print(` case '6':`);
421
+ f.print(` case '7':`);
422
+ f.print(` case '8':`);
423
+ f.print(` case '9':`);
424
+ f.print(` b.push(c);`);
425
+ f.print(` capNext = false;`);
426
+ f.print(` break;`);
427
+ f.print(` default:`);
428
+ f.print(` if (capNext) {`);
429
+ f.print(` capNext = false;`);
430
+ f.print(` c = c.toUpperCase();`);
431
+ f.print(` }`);
432
+ f.print(` b.push(c);`);
433
+ f.print(` break;`);
434
+ f.print(` }`);
435
+ f.print(` }`);
436
+ f.print(` return b.join('');`);
437
+ f.print(` }`);
438
+ f.print(` return this.`, (0, ecmascript_1.localName)(ref.paths), `.map(p => {`);
439
+ f.print(` if (p.match(/_[0-9]?_/g) || p.match(/[A-Z]/g)) {`);
440
+ f.print(` throw new Error("cannot decode `, message.typeName, ` from JSON: lowerCamelCase of path name \\"" + p + "\\" is irreversible");`);
441
+ f.print(` }`);
442
+ f.print(` return protoCamelCase(p);`);
443
+ f.print(` }).join(",");`);
444
+ f.print(` }`);
445
+ f.print();
446
+ f.print(` override fromJson(json: `, JsonValue, `, options?: Partial<`, JsonReadOptions, `>): this {`);
447
+ f.print(` if (typeof json !== "string") {`);
448
+ f.print(` throw new Error("cannot decode `, message.typeName, ` from JSON: " + proto3.json.debug(json));`);
449
+ f.print(` }`);
450
+ f.print(` if (json === "") {`);
451
+ f.print(` return this;`);
452
+ f.print(` }`);
453
+ f.print(` function camelToSnake (str: string) {`);
454
+ f.print(` if (str.includes("_")) {`);
455
+ f.print(` throw new Error("cannot decode `, message.typeName, ` from JSON: path names must be lowerCamelCase");`);
456
+ f.print(` }`);
457
+ f.print(` const sc = str.replace(/[A-Z]/g, letter => "_" + letter.toLowerCase());`);
458
+ f.print(` return (sc[0] === "_") ? sc.substring(1) : sc;`);
459
+ f.print(` }`);
460
+ f.print(` this.`, (0, ecmascript_1.localName)(ref.paths), ` = json.split(",").map(camelToSnake);`);
461
+ f.print(` return this;`);
462
+ f.print(` }`);
463
+ f.print();
464
+ break;
465
+ case "google.protobuf.DoubleValue":
466
+ case "google.protobuf.FloatValue":
467
+ case "google.protobuf.Int64Value":
468
+ case "google.protobuf.UInt64Value":
469
+ case "google.protobuf.Int32Value":
470
+ case "google.protobuf.UInt32Value":
471
+ case "google.protobuf.BoolValue":
472
+ case "google.protobuf.StringValue":
473
+ case "google.protobuf.BytesValue":
474
+ f.print(" override toJson(options?: Partial<", JsonWriteOptions, ">): ", JsonValue, " {");
475
+ f.print(" return proto3.json.writeScalar(", rtScalarType, ".", protobuf_1.ScalarType[ref.value.scalar], ", this.value, true)!;");
476
+ f.print(" }");
477
+ f.print();
478
+ f.print(" override fromJson(json: ", JsonValue, ", options?: Partial<", JsonReadOptions, ">): this {");
479
+ f.print(" try {");
480
+ f.print(" this.value = ", protoN, ".json.readScalar(", rtScalarType, ".", protobuf_1.ScalarType[ref.value.scalar], ", json);");
481
+ f.print(" } catch (e) {");
482
+ f.print(" let m = `cannot decode message ", message.typeName, " from JSON\"`;");
483
+ f.print(" if (e instanceof Error && e.message.length > 0) {");
484
+ f.print(" m += `: ${e.message}`");
485
+ f.print(" }");
486
+ f.print(" throw new Error(m);");
487
+ f.print(" }");
488
+ f.print(" return this;");
489
+ f.print(" }");
490
+ f.print();
491
+ break;
492
+ }
493
+ }
494
+ // prettier-ignore
495
+ function generateWktStaticMethods(schema, f, message) {
496
+ const ref = (0, match_wkt_js_1.matchWkt)(message);
497
+ if (ref === undefined) {
498
+ return;
499
+ }
500
+ const { protoInt64, } = schema.runtime;
501
+ switch (ref.typeName) {
502
+ case "google.protobuf.Any":
503
+ f.print(" static pack(message: Message): ", message, " {");
504
+ f.print(" const any = new ", message, "();");
505
+ f.print(" any.packFrom(message);");
506
+ f.print(" return any;");
507
+ f.print(" }");
508
+ f.print();
509
+ break;
510
+ case "google.protobuf.Timestamp":
511
+ f.print(" static now(): ", message, " {");
512
+ f.print(" return ", message, ".fromDate(new Date())");
513
+ f.print(" }");
514
+ f.print();
515
+ f.print(" static fromDate(date: Date): ", message, " {");
516
+ f.print(" const ms = date.getTime();");
517
+ f.print(" return new ", message, "({");
518
+ f.print(" ", (0, ecmascript_1.localName)(ref.seconds), ": ", protoInt64, ".parse(Math.floor(ms / 1000)),");
519
+ f.print(" ", (0, ecmascript_1.localName)(ref.nanos), ": (ms % 1000) * 1000000,");
520
+ f.print(" });");
521
+ f.print(" }");
522
+ f.print();
523
+ break;
524
+ case "google.protobuf.DoubleValue":
525
+ case "google.protobuf.FloatValue":
526
+ case "google.protobuf.Int64Value":
527
+ case "google.protobuf.UInt64Value":
528
+ case "google.protobuf.Int32Value":
529
+ case "google.protobuf.UInt32Value":
530
+ case "google.protobuf.BoolValue":
531
+ case "google.protobuf.StringValue":
532
+ case "google.protobuf.BytesValue": {
533
+ const { typing } = (0, ecmascript_1.getFieldTyping)(ref.value, f);
534
+ f.print(" static readonly fieldWrapper = {");
535
+ f.print(" wrapField(value: ", typing, " | ", message, "): ", message, " {");
536
+ f.print(" return value instanceof ", message, " ? value : new ", message, "({value});");
537
+ f.print(" },");
538
+ f.print(" unwrapField(value: ", message, "): ", typing, " {");
539
+ f.print(" return value.", (0, ecmascript_1.localName)(ref.value), ";");
540
+ f.print(" }");
541
+ f.print(" };");
542
+ f.print();
543
+ break;
544
+ }
545
+ case "google.protobuf.Duration":
546
+ case "google.protobuf.Struct":
547
+ case "google.protobuf.Value":
548
+ case "google.protobuf.ListValue":
549
+ case "google.protobuf.FieldMask":
550
+ break;
551
+ }
552
+ }
package/package.json CHANGED
@@ -1,37 +1,33 @@
1
1
  {
2
2
  "name": "@bufbuild/protoc-gen-es",
3
- "version": "0.0.6",
4
- "description": "protoc-gen-es",
3
+ "version": "0.0.9",
4
+ "description": "Protocol Buffers code generator for ECMAScript",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "https://github.com/bufbuild/protobuf-es.git"
8
+ "url": "https://github.com/bufbuild/protobuf-es.git",
9
+ "directory": "packages/protoc-gen-es"
9
10
  },
10
11
  "bin": {
11
12
  "protoc-gen-es": "bin/protoc-gen-es"
12
13
  },
14
+ "engines": {
15
+ "node": ">=14"
16
+ },
17
+ "scripts": {
18
+ "clean": "rm -rf ./dist/cjs/*",
19
+ "build": "npx tsc --project tsconfig.json --module commonjs --outDir ./dist/cjs"
20
+ },
13
21
  "preferUnplugged": true,
22
+ "dependencies": {
23
+ "@bufbuild/protoplugin": "^0.0.9"
24
+ },
14
25
  "peerDependencies": {
15
- "@bufbuild/protobuf": "^0.0.6"
26
+ "@bufbuild/protobuf": "^0.0.9"
16
27
  },
17
28
  "peerDependenciesMeta": {
18
29
  "@bufbuild/protobuf": {
19
30
  "optional": true
20
31
  }
21
- },
22
- "optionalDependencies": {
23
- "@bufbuild/protoc-gen-es-darwin-64": "0.0.6",
24
- "@bufbuild/protoc-gen-es-darwin-arm64": "0.0.6",
25
- "@bufbuild/protoc-gen-es-windows-64": "0.0.6",
26
- "@bufbuild/protoc-gen-es-windows-arm64": "0.0.6",
27
- "@bufbuild/protoc-gen-es-windows-32": "0.0.6",
28
- "@bufbuild/protoc-gen-es-linux-64": "0.0.6",
29
- "@bufbuild/protoc-gen-es-linux-32": "0.0.6",
30
- "@bufbuild/protoc-gen-es-linux-arm": "0.0.6",
31
- "@bufbuild/protoc-gen-es-linux-arm64": "0.0.6",
32
- "@bufbuild/protoc-gen-es-freebsd-64": "0.0.6",
33
- "@bufbuild/protoc-gen-es-freebsd-arm64": "0.0.6",
34
- "@bufbuild/protoc-gen-es-netbsd-64": "0.0.6",
35
- "@bufbuild/protoc-gen-es-openbsd-64": "0.0.6"
36
32
  }
37
33
  }