@aptre/protobuf-es-lite 0.2.14 → 0.3.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/LICENSE +1 -1
- package/README.md +10 -15
- package/dist/binary.d.ts +13 -10
- package/dist/binary.js +24 -23
- package/dist/codegen-info.d.ts +8 -0
- package/dist/codegen-info.js +12 -4
- package/dist/create-descriptor-set.js +1 -1
- package/dist/descriptor-set.d.ts +8 -9
- package/dist/google/protobuf/any.pb.d.ts +55 -2
- package/dist/google/protobuf/any.pb.js +74 -4
- package/dist/google/protobuf/api.pb.js +13 -10
- package/dist/google/protobuf/descriptor.pb.js +125 -93
- package/dist/google/protobuf/duration.pb.d.ts +7 -2
- package/dist/google/protobuf/duration.pb.js +54 -4
- package/dist/google/protobuf/empty.pb.js +1 -0
- package/dist/google/protobuf/source_context.pb.js +3 -2
- package/dist/google/protobuf/struct.pb.d.ts +17 -4
- package/dist/google/protobuf/struct.pb.js +104 -8
- package/dist/google/protobuf/timestamp.pb.d.ts +8 -2
- package/dist/google/protobuf/timestamp.pb.js +54 -4
- package/dist/google/protobuf/type.pb.js +21 -16
- package/dist/google/protobuf/wrappers.pb.d.ts +47 -10
- package/dist/google/protobuf/wrappers.pb.js +190 -19
- package/dist/index.d.ts +5 -1
- package/dist/index.js +4 -1
- package/dist/json.d.ts +30 -4
- package/dist/json.js +17 -16
- package/dist/message.d.ts +8 -15
- package/dist/message.js +75 -71
- package/dist/protoc-gen-es-lite/typescript.d.ts +2 -2
- package/dist/protoc-gen-es-lite/typescript.js +323 -26
- package/dist/protoplugin/ecmascript/reify-wkt.d.ts +1 -5
- package/dist/protoplugin/ecmascript/reify-wkt.js +0 -10
- package/dist/type-registry.d.ts +43 -0
- package/dist/type-registry.js +14 -0
- package/example/example.pb.ts +6 -7
- package/package.json +3 -1
package/dist/message.js
CHANGED
|
@@ -14,8 +14,81 @@
|
|
|
14
14
|
import { newFieldList, resolveMessageType, } from "./field.js";
|
|
15
15
|
import { applyPartialMessage } from "./partial.js";
|
|
16
16
|
import { ScalarType, scalarEquals } from "./scalar.js";
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
17
|
+
import { binaryReadMessage, binaryWriteMessage, binaryMakeReadOptions, binaryMakeWriteOptions, } from "./binary.js";
|
|
18
|
+
import { jsonReadMessage, jsonWriteMessage, jsonMakeReadOptions, jsonMakeWriteOptions, } from "./json.js";
|
|
19
|
+
/**
|
|
20
|
+
* createMessageType creates a new message type.
|
|
21
|
+
*
|
|
22
|
+
* The argument `packedByDefault` specifies whether fields that do not specify
|
|
23
|
+
* `packed` should be packed (proto3) or unpacked (proto2).
|
|
24
|
+
*/
|
|
25
|
+
export function createMessageType(params, exts) {
|
|
26
|
+
const { fields: fieldsSource, typeName, packedByDefault, delimitedMessageEncoding, fieldWrapper, } = params;
|
|
27
|
+
const fields = newFieldList(fieldsSource, packedByDefault);
|
|
28
|
+
const mt = {
|
|
29
|
+
typeName,
|
|
30
|
+
fields,
|
|
31
|
+
fieldWrapper,
|
|
32
|
+
create(partial) {
|
|
33
|
+
const message = createMessage(fields);
|
|
34
|
+
applyPartialMessage(partial, message, fields);
|
|
35
|
+
return message;
|
|
36
|
+
},
|
|
37
|
+
equals(a, b) {
|
|
38
|
+
return compareMessages(fields, a, b);
|
|
39
|
+
},
|
|
40
|
+
clone(a) {
|
|
41
|
+
if (a == null) {
|
|
42
|
+
return a;
|
|
43
|
+
}
|
|
44
|
+
return cloneMessage(a, fields);
|
|
45
|
+
},
|
|
46
|
+
fromBinary(bytes, options) {
|
|
47
|
+
const message = {};
|
|
48
|
+
if (bytes && bytes.length) {
|
|
49
|
+
const opt = binaryMakeReadOptions(options);
|
|
50
|
+
binaryReadMessage(message, fields, opt.readerFactory(bytes), bytes.byteLength, opt, delimitedMessageEncoding);
|
|
51
|
+
}
|
|
52
|
+
return message;
|
|
53
|
+
},
|
|
54
|
+
fromJson(jsonValue, options) {
|
|
55
|
+
const message = {};
|
|
56
|
+
if (jsonValue != null) {
|
|
57
|
+
const opts = jsonMakeReadOptions(options);
|
|
58
|
+
jsonReadMessage(fields, typeName, jsonValue, opts, message);
|
|
59
|
+
}
|
|
60
|
+
return message;
|
|
61
|
+
},
|
|
62
|
+
fromJsonString(jsonString, options) {
|
|
63
|
+
let json = null;
|
|
64
|
+
if (jsonString) {
|
|
65
|
+
try {
|
|
66
|
+
json = JSON.parse(jsonString);
|
|
67
|
+
}
|
|
68
|
+
catch (e) {
|
|
69
|
+
throw new Error(`cannot decode ${typeName} from JSON: ${e instanceof Error ? e.message : String(e)}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return mt.fromJson(json, options);
|
|
73
|
+
},
|
|
74
|
+
toBinary(a, options) {
|
|
75
|
+
const opt = binaryMakeWriteOptions(options);
|
|
76
|
+
const writer = opt.writerFactory();
|
|
77
|
+
binaryWriteMessage(a, fields, writer, opt);
|
|
78
|
+
return writer.finish();
|
|
79
|
+
},
|
|
80
|
+
toJson(a, options) {
|
|
81
|
+
const opt = jsonMakeWriteOptions(options);
|
|
82
|
+
return jsonWriteMessage(a, fields, opt);
|
|
83
|
+
},
|
|
84
|
+
toJsonString(a, options) {
|
|
85
|
+
const value = mt.toJson(a, options);
|
|
86
|
+
return JSON.stringify(value, null, options?.prettySpaces ?? 0);
|
|
87
|
+
},
|
|
88
|
+
...(exts ?? {}),
|
|
89
|
+
};
|
|
90
|
+
return mt;
|
|
91
|
+
}
|
|
19
92
|
// compareMessages compares two messages for equality.
|
|
20
93
|
export function compareMessages(fields, a, b) {
|
|
21
94
|
if (a == null && b == null) {
|
|
@@ -144,75 +217,6 @@ export function cloneMessage(message, fields) {
|
|
|
144
217
|
}
|
|
145
218
|
return clone;
|
|
146
219
|
}
|
|
147
|
-
/**
|
|
148
|
-
* createMessageType creates a new message type.
|
|
149
|
-
*
|
|
150
|
-
* The argument `packedByDefault` specifies whether fields that do not specify
|
|
151
|
-
* `packed` should be packed (proto3) or unpacked (proto2).
|
|
152
|
-
*/
|
|
153
|
-
export function createMessageType(params) {
|
|
154
|
-
const { fields: fieldsSource, typeName, packedByDefault, delimitedMessageEncoding, fieldWrapper, } = params;
|
|
155
|
-
const fields = newFieldList(fieldsSource, packedByDefault);
|
|
156
|
-
const mt = {
|
|
157
|
-
typeName,
|
|
158
|
-
fields,
|
|
159
|
-
fieldWrapper,
|
|
160
|
-
create(partial) {
|
|
161
|
-
const message = createMessage(fields);
|
|
162
|
-
applyPartialMessage(partial, message, fields);
|
|
163
|
-
return message;
|
|
164
|
-
},
|
|
165
|
-
equals(a, b) {
|
|
166
|
-
return compareMessages(fields, a, b);
|
|
167
|
-
},
|
|
168
|
-
clone(a) {
|
|
169
|
-
if (a == null) {
|
|
170
|
-
return a;
|
|
171
|
-
}
|
|
172
|
-
return cloneMessage(a, fields);
|
|
173
|
-
},
|
|
174
|
-
fromBinary(bytes, options) {
|
|
175
|
-
const message = {};
|
|
176
|
-
const opt = makeBinaryReadOptions(options);
|
|
177
|
-
readBinaryMessage(message, fields, opt.readerFactory(bytes), bytes.byteLength, opt, delimitedMessageEncoding);
|
|
178
|
-
return message;
|
|
179
|
-
},
|
|
180
|
-
fromJson(jsonValue, options) {
|
|
181
|
-
const message = {};
|
|
182
|
-
const opts = makeJsonReadOptions(options);
|
|
183
|
-
readJsonMessage(fields, typeName, jsonValue, opts, message);
|
|
184
|
-
return message;
|
|
185
|
-
},
|
|
186
|
-
fromJsonString(jsonString, options) {
|
|
187
|
-
let json;
|
|
188
|
-
try {
|
|
189
|
-
json = JSON.parse(jsonString);
|
|
190
|
-
}
|
|
191
|
-
catch (e) {
|
|
192
|
-
throw new Error(`cannot decode ${typeName} from JSON: ${e instanceof Error ? e.message : String(e)}`);
|
|
193
|
-
}
|
|
194
|
-
return this.fromJson(json, options);
|
|
195
|
-
},
|
|
196
|
-
toBinary(a, options) {
|
|
197
|
-
const opt = makeBinaryWriteOptions(options);
|
|
198
|
-
const writer = opt.writerFactory();
|
|
199
|
-
writeBinaryMessage(a, fields, writer, opt);
|
|
200
|
-
return writer.finish();
|
|
201
|
-
},
|
|
202
|
-
toJson(a, options) {
|
|
203
|
-
const opt = makeJsonWriteOptions(options);
|
|
204
|
-
return writeJsonMessage(a, fields, opt);
|
|
205
|
-
},
|
|
206
|
-
toJsonString(a, options) {
|
|
207
|
-
const value = this.toJson(a, options);
|
|
208
|
-
return JSON.stringify(value, null, options?.prettySpaces ?? 0);
|
|
209
|
-
},
|
|
210
|
-
};
|
|
211
|
-
if (params.toJson) {
|
|
212
|
-
mt.toJson = params.toJson;
|
|
213
|
-
}
|
|
214
|
-
return mt;
|
|
215
|
-
}
|
|
216
220
|
/**
|
|
217
221
|
* createMessage recursively builds a message filled with zero values based on the given FieldList.
|
|
218
222
|
*/
|
|
@@ -3,6 +3,6 @@ import { DescEnum, DescExtension, DescField, DescFile, DescMessage } from "../de
|
|
|
3
3
|
export declare function generateTs(schema: Schema): void;
|
|
4
4
|
export declare function checkSupportedSyntax(file: DescFile): void;
|
|
5
5
|
export declare function makeImportPath(file: DescFile): string;
|
|
6
|
-
export declare function generateFieldInfo(f: GeneratedFile, field: DescField | DescExtension): void;
|
|
6
|
+
export declare function generateFieldInfo(f: GeneratedFile, schema: Schema, field: DescField | DescExtension): void;
|
|
7
7
|
export declare const createTypeImport: (desc: DescMessage | DescEnum | DescExtension) => ImportSymbol;
|
|
8
|
-
export declare function getFieldInfoLiteral(field: DescField | DescExtension): Printable;
|
|
8
|
+
export declare function getFieldInfoLiteral(schema: Schema, field: DescField | DescExtension): Printable;
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
13
|
// See the License for the specific language governing permissions and
|
|
14
14
|
// limitations under the License.
|
|
15
|
-
import { createImportSymbol } from "../protoplugin/ecmascript/index.js";
|
|
15
|
+
import { createImportSymbol, reifyWkt, } from "../protoplugin/ecmascript/index.js";
|
|
16
16
|
import { getFieldDefaultValueExpression, getFieldTypeInfo } from "../util.js";
|
|
17
17
|
import { localName } from "../names.js";
|
|
18
18
|
import { LongType, ScalarType } from "../scalar.js";
|
|
@@ -107,20 +107,9 @@ export function checkSupportedSyntax(file) {
|
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
function generateMessage(schema, f, message) {
|
|
110
|
-
// check if we support this runtime
|
|
111
110
|
checkSupportedSyntax(message.file);
|
|
111
|
+
const { MessageType: rtMessageType, createMessageType, PartialFieldInfo, } = schema.runtime;
|
|
112
112
|
f.print(f.jsDoc(message));
|
|
113
|
-
/*
|
|
114
|
-
f.print(
|
|
115
|
-
f.exportDecl("interface", message),
|
|
116
|
-
" extends ",
|
|
117
|
-
schema.runtime.Message,
|
|
118
|
-
"<",
|
|
119
|
-
message,
|
|
120
|
-
">",
|
|
121
|
-
" {",
|
|
122
|
-
);
|
|
123
|
-
*/
|
|
124
113
|
f.print(f.exportDecl("type", message), " = ", schema.runtime.Message, "<{");
|
|
125
114
|
for (const field of message.fields) {
|
|
126
115
|
generateField(f, field);
|
|
@@ -131,17 +120,34 @@ function generateMessage(schema, f, message) {
|
|
|
131
120
|
f.print();
|
|
132
121
|
f.print("}>;");
|
|
133
122
|
f.print();
|
|
134
|
-
|
|
135
|
-
|
|
123
|
+
// If we need to extend the message type, do that here.
|
|
124
|
+
const reWkt = reifyWkt(message);
|
|
125
|
+
if (reWkt != null) {
|
|
126
|
+
f.print("// ", message, "_Wkt contains the well-known-type overrides for ", message, ".");
|
|
127
|
+
f.print("const ", message, "_Wkt = {");
|
|
128
|
+
generateWktMethods(schema, f, message, reWkt);
|
|
129
|
+
f.print("};");
|
|
130
|
+
f.print();
|
|
131
|
+
f.print("// ", message, " contains the message type declaration for ", message, ".");
|
|
132
|
+
f.print(f.exportDecl("const", message), `: `, rtMessageType, `<`, message, `> & typeof `, message, `_Wkt = `, createMessageType, "<", message, ", typeof ", message, "_Wkt>({");
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
f.print("// ", message, " contains the message type declaration for ", message, ".");
|
|
136
|
+
f.print(f.exportDecl("const", message), `: `, rtMessageType, `<`, message, `> = `, createMessageType, "({");
|
|
137
|
+
}
|
|
136
138
|
f.print(" typeName: ", f.string(message.typeName), ",");
|
|
137
139
|
f.print(" fields: [");
|
|
138
140
|
for (const field of message.fields) {
|
|
139
|
-
generateFieldInfo(f, field);
|
|
141
|
+
generateFieldInfo(f, schema, field);
|
|
140
142
|
}
|
|
141
|
-
f.print(" ] as readonly ",
|
|
143
|
+
f.print(" ] as readonly ", PartialFieldInfo, "[],");
|
|
142
144
|
f.print(" packedByDefault: ", message.file.proto.syntax === "proto3", ",");
|
|
143
|
-
|
|
144
|
-
|
|
145
|
+
if (reWkt == null) {
|
|
146
|
+
f.print("});");
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
f.print("}, ", message, "_Wkt);");
|
|
150
|
+
}
|
|
145
151
|
f.print();
|
|
146
152
|
}
|
|
147
153
|
function generateField(f, field) {
|
|
@@ -175,8 +181,8 @@ function generateOneof(f, oneof) {
|
|
|
175
181
|
export function makeImportPath(file) {
|
|
176
182
|
return "./" + file.name + ".pb.js";
|
|
177
183
|
}
|
|
178
|
-
export function generateFieldInfo(f, field) {
|
|
179
|
-
f.print(" ", getFieldInfoLiteral(field), ",");
|
|
184
|
+
export function generateFieldInfo(f, schema, field) {
|
|
185
|
+
f.print(" ", getFieldInfoLiteral(schema, field), ",");
|
|
180
186
|
}
|
|
181
187
|
export const createTypeImport = (desc) => {
|
|
182
188
|
var name = localName(desc);
|
|
@@ -186,7 +192,8 @@ export const createTypeImport = (desc) => {
|
|
|
186
192
|
const from = makeImportPath(desc.file);
|
|
187
193
|
return createImportSymbol(name, from);
|
|
188
194
|
};
|
|
189
|
-
export function getFieldInfoLiteral(field) {
|
|
195
|
+
export function getFieldInfoLiteral(schema, field) {
|
|
196
|
+
const { ScalarType: rtScalarType, LongType: rtLongType } = schema.runtime;
|
|
190
197
|
const e = [];
|
|
191
198
|
e.push("{ no: ", field.number, `, `);
|
|
192
199
|
if (field.kind == "field") {
|
|
@@ -197,16 +204,16 @@ export function getFieldInfoLiteral(field) {
|
|
|
197
204
|
}
|
|
198
205
|
switch (field.fieldKind) {
|
|
199
206
|
case "scalar":
|
|
200
|
-
e.push(`kind: "scalar", T: `,
|
|
207
|
+
e.push(`kind: "scalar", T: `, rtScalarType, `.`, ScalarType[field.scalar], `, `);
|
|
201
208
|
if (field.longType != LongType.BIGINT) {
|
|
202
|
-
e.push(`L: `,
|
|
209
|
+
e.push(`L: `, rtLongType, `.`, LongType[field.longType], `, `);
|
|
203
210
|
}
|
|
204
211
|
break;
|
|
205
212
|
case "map":
|
|
206
|
-
e.push(`kind: "map", K: `,
|
|
213
|
+
e.push(`kind: "map", K: `, rtScalarType, `.`, ScalarType[field.mapKey], `, `);
|
|
207
214
|
switch (field.mapValue.kind) {
|
|
208
215
|
case "scalar":
|
|
209
|
-
e.push(`V: {kind: "scalar", T: `,
|
|
216
|
+
e.push(`V: {kind: "scalar", T: `, rtScalarType, `.`, ScalarType[field.mapValue.scalar], `}, `);
|
|
210
217
|
break;
|
|
211
218
|
case "message":
|
|
212
219
|
e.push(`V: {kind: "message", T: () => `, field.mapValue.message, `}, `);
|
|
@@ -252,3 +259,293 @@ export function getFieldInfoLiteral(field) {
|
|
|
252
259
|
e.push(" }");
|
|
253
260
|
return e;
|
|
254
261
|
}
|
|
262
|
+
function generateWktMethods(schema, f, message, ref) {
|
|
263
|
+
const { JsonValue, JsonReadOptions, JsonWriteOptions, JsonObject, jsonReadScalar, jsonWriteScalar, jsonDebugValue, Message, MessageType, IMessageTypeRegistry, ScalarType: rtScalarType, LongType: rtLongType,
|
|
264
|
+
// ScalarValue: rtScalarValue,
|
|
265
|
+
protoInt64, applyPartialMessage, } = schema.runtime;
|
|
266
|
+
switch (ref.typeName) {
|
|
267
|
+
case "google.protobuf.Any":
|
|
268
|
+
f.print(" toJson(msg: ", message, ", options?: Partial<", JsonWriteOptions, ">): ", JsonValue, " {");
|
|
269
|
+
f.print(" const typeName = msg?.", localName(ref.typeUrl), ";");
|
|
270
|
+
f.print(` if (!typeName) {`);
|
|
271
|
+
f.print(" return {};");
|
|
272
|
+
f.print(" }");
|
|
273
|
+
f.print(" const messageType = options?.typeRegistry?.findMessage(typeName);");
|
|
274
|
+
f.print(" if (!messageType) {");
|
|
275
|
+
f.print(" throw new Error(`cannot encode message ", message.typeName, ' to JSON: "${typeName}" is not in the type registry`);');
|
|
276
|
+
f.print(" }");
|
|
277
|
+
f.print(" const message = messageType.fromBinary(msg.", localName(ref.value), ");");
|
|
278
|
+
f.print(" let json = messageType.toJson(message, options);");
|
|
279
|
+
f.print(` if (typeName.startsWith("google.protobuf.") || (json === null || Array.isArray(json) || typeof json !== "object")) {`);
|
|
280
|
+
f.print(" json = {value: json};");
|
|
281
|
+
f.print(" }");
|
|
282
|
+
f.print(` json["@type"] = typeName;`);
|
|
283
|
+
f.print(" return json;");
|
|
284
|
+
f.print(" },");
|
|
285
|
+
f.print();
|
|
286
|
+
f.print(" fromJson(json: ", JsonValue, ", options?: Partial<", JsonReadOptions, ">) {");
|
|
287
|
+
f.print(` if (json === null || Array.isArray(json) || typeof json != "object") {`);
|
|
288
|
+
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}`);');
|
|
289
|
+
f.print(" }");
|
|
290
|
+
f.print(` if (Object.keys(json).length == 0) {`);
|
|
291
|
+
f.print(` return {} as `, message, `;`);
|
|
292
|
+
f.print(` }`);
|
|
293
|
+
f.print(` const typeUrl = json["@type"];`);
|
|
294
|
+
f.print(` if (typeof typeUrl != "string" || typeUrl == "") {`);
|
|
295
|
+
f.print(" throw new Error(`cannot decode message ", message.typeName, ' from JSON: "@type" is empty`);');
|
|
296
|
+
f.print(" }");
|
|
297
|
+
f.print(" const typeName = typeUrl, messageType = options?.typeRegistry?.findMessage(typeName);");
|
|
298
|
+
f.print(" if (!messageType) {");
|
|
299
|
+
f.print(" throw new Error(`cannot decode message ", message.typeName, " from JSON: ${typeUrl} is not in the type registry`);");
|
|
300
|
+
f.print(" }");
|
|
301
|
+
f.print(" let message;");
|
|
302
|
+
f.print(` if (typeName.startsWith("google.protobuf.") && Object.prototype.hasOwnProperty.call(json, "value")) {`);
|
|
303
|
+
f.print(` message = messageType.fromJson(json["value"], options);`);
|
|
304
|
+
f.print(" } else {");
|
|
305
|
+
f.print(" const copy = Object.assign({}, json);");
|
|
306
|
+
f.print(` delete copy["@type"];`);
|
|
307
|
+
f.print(" message = messageType.fromJson(copy, options);");
|
|
308
|
+
f.print(" }");
|
|
309
|
+
f.print(" const out = {} as ", message, ";");
|
|
310
|
+
f.print(" ", message, ".packFrom(out, message, messageType);");
|
|
311
|
+
f.print(" return out;");
|
|
312
|
+
f.print(" },");
|
|
313
|
+
f.print();
|
|
314
|
+
f.print(" packFrom<T extends ", Message, "<T>>(out: ", message, ", message: ", Message, "<T>, messageType: ", MessageType, "<T>): void {");
|
|
315
|
+
f.print(" out.", localName(ref.value), " = messageType.toBinary(message);");
|
|
316
|
+
f.print(" out.", localName(ref.typeUrl), " = messageType.typeName;");
|
|
317
|
+
f.print(" },");
|
|
318
|
+
f.print();
|
|
319
|
+
f.print(" unpackTo<T extends ", Message, "<T>>(msg: ", message, ", target: ", Message, "<T>, targetMessageType: ", MessageType, "<T>): boolean {");
|
|
320
|
+
f.print(" if (!", message, ".is(msg, targetMessageType)) {");
|
|
321
|
+
f.print(" return false;");
|
|
322
|
+
f.print(" }");
|
|
323
|
+
f.print(" const partial = targetMessageType.fromBinary(msg.", localName(ref.value), ");");
|
|
324
|
+
f.print(" ", applyPartialMessage, "(partial, target, targetMessageType.fields);");
|
|
325
|
+
f.print(" return true;");
|
|
326
|
+
f.print(" },");
|
|
327
|
+
f.print();
|
|
328
|
+
f.print(" unpack<T extends Message<T>>(msg: ", message, ", registry: ", IMessageTypeRegistry, "): {message: ", Message, "<T>, messageType: ", MessageType, "<T>} | undefined {");
|
|
329
|
+
f.print(" const typeUrl = msg.", localName(ref.typeUrl)), ";";
|
|
330
|
+
f.print(" const messageType = !!typeUrl && registry.findMessage<T>(typeUrl);");
|
|
331
|
+
f.print(" return messageType ? {message: messageType.fromBinary(msg.", localName(ref.value), "), messageType} : undefined;");
|
|
332
|
+
f.print(" },");
|
|
333
|
+
f.print();
|
|
334
|
+
f.print(" is(msg: ", message, ", msgType: ", MessageType, " | string): boolean {");
|
|
335
|
+
f.print(" const name = msg.", localName(ref.typeUrl)), ";";
|
|
336
|
+
f.print(" return !!name && (typeof msgType === 'string' ? name === msgType : name === msgType.typeName);");
|
|
337
|
+
f.print(" },");
|
|
338
|
+
break;
|
|
339
|
+
case "google.protobuf.Timestamp":
|
|
340
|
+
f.print(" fromJson(json: ", JsonValue, "): ", message, " {");
|
|
341
|
+
f.print(` if (typeof json !== "string") {`);
|
|
342
|
+
f.print(" throw new Error(`cannot decode ", message.typeName, "(json)}`);");
|
|
343
|
+
f.print(" }");
|
|
344
|
+
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]))$/);`);
|
|
345
|
+
f.print(" if (!matches) {");
|
|
346
|
+
f.print(" throw new Error(`cannot decode ", message.typeName, " from JSON: invalid RFC 3339 string`);");
|
|
347
|
+
f.print(" }");
|
|
348
|
+
f.print(` const ms = Date.parse(matches[1] + "-" + matches[2] + "-" + matches[3] + "T" + matches[4] + ":" + matches[5] + ":" + matches[6] + (matches[8] ? matches[8] : "Z"));`);
|
|
349
|
+
f.print(" if (Number.isNaN(ms)) {");
|
|
350
|
+
f.print(" throw new Error(`cannot decode ", message.typeName, " from JSON: invalid RFC 3339 string`);");
|
|
351
|
+
f.print(" }");
|
|
352
|
+
f.print(` if (ms < Date.parse("0001-01-01T00:00:00Z") || ms > Date.parse("9999-12-31T23:59:59Z")) {`);
|
|
353
|
+
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`);");
|
|
354
|
+
f.print(" }");
|
|
355
|
+
f.print(" return {");
|
|
356
|
+
if (ref.seconds.longType === LongType.STRING) {
|
|
357
|
+
f.print(" ", localName(ref.seconds), ": ", protoInt64, ".parse(ms / 1000).toString(),");
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
f.print(" ", localName(ref.seconds), ": ", protoInt64, ".parse(ms / 1000),");
|
|
361
|
+
}
|
|
362
|
+
f.print(" ", localName(ref.nanos), ": !matches[7] ? 0 : ", `(parseInt("1" + matches[7] + "0".repeat(9 - matches[7].length)) - 1000000000),`);
|
|
363
|
+
f.print(" }");
|
|
364
|
+
f.print(" },");
|
|
365
|
+
f.print(" toJson(msg: ", message, "): JsonValue {");
|
|
366
|
+
f.print(" const ms = Number(msg.", localName(ref.seconds), ") * 1000;");
|
|
367
|
+
f.print(` if (ms < Date.parse("0001-01-01T00:00:00Z") || ms > Date.parse("9999-12-31T23:59:59Z")) {`);
|
|
368
|
+
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`);");
|
|
369
|
+
f.print(" }");
|
|
370
|
+
f.print(" if (msg.", localName(ref.nanos), " != null && msg.", localName(ref.nanos), " < 0) {");
|
|
371
|
+
f.print(" throw new Error(`cannot encode ", message.typeName, " to JSON: nanos must not be negative`);");
|
|
372
|
+
f.print(" }");
|
|
373
|
+
f.print(` let z = "Z";`);
|
|
374
|
+
f.print(" if (msg.", localName(ref.nanos), " != null && msg.", localName(ref.nanos), " > 0) {");
|
|
375
|
+
f.print(" const nanosStr = (msg.", localName(ref.nanos), " + 1000000000).toString().substring(1);");
|
|
376
|
+
f.print(` if (nanosStr.substring(3) === "000000") {`);
|
|
377
|
+
f.print(` z = "." + nanosStr.substring(0, 3) + "Z";`);
|
|
378
|
+
f.print(` } else if (nanosStr.substring(6) === "000") {`);
|
|
379
|
+
f.print(` z = "." + nanosStr.substring(0, 6) + "Z";`);
|
|
380
|
+
f.print(" } else {");
|
|
381
|
+
f.print(` z = "." + nanosStr + "Z";`);
|
|
382
|
+
f.print(" }");
|
|
383
|
+
f.print(" }");
|
|
384
|
+
f.print(` return new Date(ms).toISOString().replace(".000Z", z);`);
|
|
385
|
+
f.print(" },");
|
|
386
|
+
f.print(" toDate(msg: ", message, "): Date {");
|
|
387
|
+
f.print(" return new Date(Number(msg.", localName(ref.seconds), " ?? 0) * 1000 + Math.ceil((msg.", localName(ref.nanos), " ?? 0) / 1000000));");
|
|
388
|
+
f.print(" },");
|
|
389
|
+
break;
|
|
390
|
+
case "google.protobuf.Duration":
|
|
391
|
+
f.print(" fromJson(json: ", JsonValue, " | null | undefined, _options?: Partial<", JsonReadOptions, ">): ", message, " {");
|
|
392
|
+
f.print(` if (typeof json !== "string") {`);
|
|
393
|
+
f.print(" throw new Error(`cannot decode ", message.typeName, " from JSON: ${", jsonDebugValue, "(json)}`);");
|
|
394
|
+
f.print(" }");
|
|
395
|
+
f.print(` const match = json.match(/^(-?[0-9]+)(?:\\.([0-9]+))?s/);`);
|
|
396
|
+
f.print(" if (match === null) {");
|
|
397
|
+
f.print(" throw new Error(`cannot decode ", message.typeName, " from JSON: ${", jsonDebugValue, "(json)}`);");
|
|
398
|
+
f.print(" }");
|
|
399
|
+
f.print(" const longSeconds = Number(match[1]);");
|
|
400
|
+
f.print(" if (longSeconds > 315576000000 || longSeconds < -315576000000) {");
|
|
401
|
+
f.print(" throw new Error(`cannot decode ", message.typeName, " from JSON: ${", jsonDebugValue, "(json)}`);");
|
|
402
|
+
f.print(" }");
|
|
403
|
+
f.print(" const msg = {} as ", message, ";");
|
|
404
|
+
if (ref.seconds.longType === LongType.STRING) {
|
|
405
|
+
f.print(" msg.", localName(ref.seconds), " = ", protoInt64, ".parse(longSeconds).toString();");
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
f.print(" msg.", localName(ref.seconds), " = ", protoInt64, ".parse(longSeconds);");
|
|
409
|
+
}
|
|
410
|
+
f.print(` if (typeof match[2] == "string") {`);
|
|
411
|
+
f.print(` const nanosStr = match[2] + "0".repeat(9 - match[2].length);`);
|
|
412
|
+
f.print(" msg.", localName(ref.nanos), " = parseInt(nanosStr);");
|
|
413
|
+
f.print(" if (longSeconds < 0 || Object.is(longSeconds, -0)) {");
|
|
414
|
+
f.print(" msg.", localName(ref.nanos), " = -msg.", localName(ref.nanos), ";");
|
|
415
|
+
f.print(" }");
|
|
416
|
+
f.print(" }");
|
|
417
|
+
f.print(" return msg;");
|
|
418
|
+
f.print(" },");
|
|
419
|
+
f.print(" toJson(msg: ", message, "): JsonValue {");
|
|
420
|
+
f.print(" const secs = Number(msg.", localName(ref.seconds), " ?? 0);");
|
|
421
|
+
f.print(" const nanos = Number(msg.", localName(ref.nanos), " ?? 0);");
|
|
422
|
+
f.print(" if (secs > 315576000000 || secs < -315576000000) {");
|
|
423
|
+
f.print(" throw new Error(`cannot encode ", message.typeName, " to JSON: value out of range`);");
|
|
424
|
+
f.print(" }");
|
|
425
|
+
f.print(" let text = secs.toString();");
|
|
426
|
+
f.print(" if (nanos !== 0) {");
|
|
427
|
+
f.print(" let nanosStr = Math.abs(nanos).toString();");
|
|
428
|
+
f.print(` nanosStr = "0".repeat(9 - nanosStr.length) + nanosStr;`);
|
|
429
|
+
f.print(` if (nanosStr.substring(3) === "000000") {`);
|
|
430
|
+
f.print(" nanosStr = nanosStr.substring(0, 3);");
|
|
431
|
+
f.print(` } else if (nanosStr.substring(6) === "000") {`);
|
|
432
|
+
f.print(" nanosStr = nanosStr.substring(0, 6);");
|
|
433
|
+
f.print(` }`);
|
|
434
|
+
f.print(` text += "." + nanosStr;`);
|
|
435
|
+
f.print(" if (nanos < 0 && secs === 0) {");
|
|
436
|
+
f.print(` text = "-" + text;`);
|
|
437
|
+
f.print(` }`);
|
|
438
|
+
f.print(" }");
|
|
439
|
+
f.print(` return text + "s";`);
|
|
440
|
+
f.print(" },");
|
|
441
|
+
break;
|
|
442
|
+
case "google.protobuf.Struct":
|
|
443
|
+
f.print(" toJson(msg: ", message, ", options?: Partial<", JsonWriteOptions, ">): ", JsonValue, " {");
|
|
444
|
+
f.print(" const json: ", JsonObject, " = {}");
|
|
445
|
+
f.print(" if (!msg.", localName(ref.fields), ") { return json; }");
|
|
446
|
+
f.print(" for (const [k, v] of Object.entries(msg.", localName(ref.fields), ")) {");
|
|
447
|
+
f.print(" json[k] = v != null ? ", ref.fields.mapValue.message, ".toJson(v, options) : null;");
|
|
448
|
+
f.print(" }");
|
|
449
|
+
f.print(" return json;");
|
|
450
|
+
f.print(" },");
|
|
451
|
+
f.print(" fromJson(json: ", JsonValue, " | null | undefined, _options?: Partial<", JsonReadOptions, ">): ", message, " {");
|
|
452
|
+
f.print(` if (typeof json != "object" || json == null || Array.isArray(json)) {`);
|
|
453
|
+
f.print(" throw new Error(`cannot decode ", message.typeName, " from JSON ${", jsonDebugValue, "(json)}`);");
|
|
454
|
+
f.print(" }");
|
|
455
|
+
f.print(" const fields = {} as { [key: string]: Value };");
|
|
456
|
+
f.print(" for (const [k, v] of Object.entries(json)) {");
|
|
457
|
+
f.print(" fields[k] = ", ref.fields.mapValue.message ?? "", ".fromJson(v);");
|
|
458
|
+
f.print(" }");
|
|
459
|
+
f.print(" return {", localName(ref.fields), ": fields} as ", message, ";");
|
|
460
|
+
f.print(" },");
|
|
461
|
+
break;
|
|
462
|
+
case "google.protobuf.Value":
|
|
463
|
+
f.print(" toJson(msg: ", message, ", options?: Partial<", JsonWriteOptions, ">): ", JsonValue, " {");
|
|
464
|
+
f.print(" switch (msg.", localName(ref.kind), "?.case) {");
|
|
465
|
+
f.print(` case "`, localName(ref.nullValue), `":`);
|
|
466
|
+
f.print(" return null;");
|
|
467
|
+
f.print(` case "`, localName(ref.numberValue), `":`);
|
|
468
|
+
f.print(` if (!Number.isFinite(msg.`, localName(ref.kind), `.value)) {`);
|
|
469
|
+
f.print(` throw new Error("google.protobuf.Value cannot be NaN or Infinity");`);
|
|
470
|
+
f.print(` }`);
|
|
471
|
+
f.print(` return msg.`, localName(ref.kind), `.value;`);
|
|
472
|
+
f.print(` case "`, localName(ref.boolValue), `":`);
|
|
473
|
+
f.print(` return msg.`, localName(ref.kind), `.value;`);
|
|
474
|
+
f.print(` case "`, localName(ref.stringValue), `":`);
|
|
475
|
+
f.print(" return msg.", localName(ref.kind), ".value;");
|
|
476
|
+
f.print(` case "`, localName(ref.structValue), `":`);
|
|
477
|
+
f.print(` return `, ref.structValue.message, `.toJson(msg.`, localName(ref.kind), `.value, {...options, emitDefaultValues: true});`);
|
|
478
|
+
f.print(` case "`, localName(ref.listValue), `":`);
|
|
479
|
+
f.print(` return `, ref.listValue.message, `.toJson(msg.`, localName(ref.kind), `.value, {...options, emitDefaultValues: true});`);
|
|
480
|
+
f.print(` case null:`);
|
|
481
|
+
f.print(` case undefined:`);
|
|
482
|
+
f.print(` default:`);
|
|
483
|
+
f.print(` return null;`);
|
|
484
|
+
f.print(" }");
|
|
485
|
+
f.print(" },");
|
|
486
|
+
f.print(" fromJson(json: ", JsonValue, " | null | undefined, _options?: Partial<", JsonReadOptions, ">): ", message, " {");
|
|
487
|
+
f.print(" const msg = {} as ", message, ";");
|
|
488
|
+
f.print(" switch (typeof json) {");
|
|
489
|
+
f.print(` case "number":`);
|
|
490
|
+
f.print(` msg.kind = { case: "`, localName(ref.numberValue), `", value: json };`);
|
|
491
|
+
f.print(" break;");
|
|
492
|
+
f.print(` case "string":`);
|
|
493
|
+
f.print(` msg.kind = { case: "`, localName(ref.stringValue), `", value: json };`);
|
|
494
|
+
f.print(" break;");
|
|
495
|
+
f.print(` case "boolean":`);
|
|
496
|
+
f.print(` msg.kind = { case: "`, localName(ref.boolValue), `", value: json };`);
|
|
497
|
+
f.print(" break;");
|
|
498
|
+
f.print(` case "object":`);
|
|
499
|
+
f.print(" if (json == null) {");
|
|
500
|
+
f.print(` msg.kind = { case: "`, localName(ref.nullValue), `", value: `, ref.nullValue.enum, `.`, localName(ref.nullValue.enum.values[0]), ` };`);
|
|
501
|
+
f.print(" } else if (Array.isArray(json)) {");
|
|
502
|
+
f.print(` msg.kind = { case: "`, localName(ref.listValue), `", value: `, ref.listValue.message, `.fromJson(json) };`);
|
|
503
|
+
f.print(" } else {");
|
|
504
|
+
f.print(` msg.kind = { case: "`, localName(ref.structValue), `", value: `, ref.structValue.message, `.fromJson(json) };`);
|
|
505
|
+
f.print(" }");
|
|
506
|
+
f.print(" break;");
|
|
507
|
+
f.print(" default:");
|
|
508
|
+
f.print(" throw new Error(`cannot decode ", message.typeName, " from JSON ${", jsonDebugValue, "(json)}`);");
|
|
509
|
+
f.print(" }");
|
|
510
|
+
f.print(" return msg;");
|
|
511
|
+
f.print(" },");
|
|
512
|
+
break;
|
|
513
|
+
case "google.protobuf.ListValue":
|
|
514
|
+
f.print(` toJson(msg: `, message, `, options?: Partial<`, JsonWriteOptions, `>): `, JsonValue, ` {`);
|
|
515
|
+
f.print(` return msg.`, localName(ref.values), `?.map(v => `, ref.values.message, `.toJson(v, options)) ?? [];`);
|
|
516
|
+
f.print(` },`);
|
|
517
|
+
f.print(` fromJson(json: `, JsonValue, ` | null | undefined, options?: Partial<`, JsonReadOptions, `>): `, message, ` {`);
|
|
518
|
+
f.print(` if (json == null) { return {}; }`);
|
|
519
|
+
f.print(` if (!Array.isArray(json)) {`);
|
|
520
|
+
f.print(" throw new Error(`cannot decode ", message.typeName, " from JSON ${", jsonDebugValue, "(json)}`);");
|
|
521
|
+
f.print(` }`);
|
|
522
|
+
f.print(` const values: `, ref.values.message, `[] = json.map(v => `, ref.values.message, `.fromJson(v, options));`);
|
|
523
|
+
f.print(` return {`, localName(ref.values), `: values} as `, message, `;`);
|
|
524
|
+
f.print(` },`);
|
|
525
|
+
break;
|
|
526
|
+
case "google.protobuf.DoubleValue":
|
|
527
|
+
case "google.protobuf.FloatValue":
|
|
528
|
+
case "google.protobuf.Int64Value":
|
|
529
|
+
case "google.protobuf.UInt64Value":
|
|
530
|
+
case "google.protobuf.Int32Value":
|
|
531
|
+
case "google.protobuf.UInt32Value":
|
|
532
|
+
case "google.protobuf.BoolValue":
|
|
533
|
+
case "google.protobuf.StringValue":
|
|
534
|
+
case "google.protobuf.BytesValue":
|
|
535
|
+
f.print(" toJson(msg: ", message, ", _options?: Partial<", JsonWriteOptions, ">): ", JsonValue, " {");
|
|
536
|
+
f.print(" return ", jsonWriteScalar, "(", rtScalarType, ".", ScalarType[ref.value.scalar], ", msg.value)!;");
|
|
537
|
+
f.print(" },");
|
|
538
|
+
f.print(" fromJson(json: ", JsonValue, " | null | undefined, _options?: Partial<", JsonReadOptions, ">): ", message, " {");
|
|
539
|
+
f.print(" try {");
|
|
540
|
+
f.print(" return {", localName(ref.value), ": ", jsonReadScalar, "(", rtScalarType, ".", ScalarType[ref.value.scalar], ", json, ", rtLongType, ".", LongType[ref.value.longType], ")} as ", message, ";");
|
|
541
|
+
f.print(" } catch (e) {");
|
|
542
|
+
f.print(" let m = `cannot decode message ", message.typeName, ' from JSON"`;');
|
|
543
|
+
f.print(" if (e instanceof Error && e.message.length > 0) {");
|
|
544
|
+
f.print(" m += `: ${e.message}`");
|
|
545
|
+
f.print(" }");
|
|
546
|
+
f.print(" throw new Error(m);");
|
|
547
|
+
f.print(" }");
|
|
548
|
+
f.print(" },");
|
|
549
|
+
break;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DescField, DescMessage, DescOneof } from "../../descriptor-set.js";
|
|
2
|
-
type DescWkt = {
|
|
2
|
+
export type DescWkt = {
|
|
3
3
|
typeName: "google.protobuf.Any";
|
|
4
4
|
typeUrl: DescField;
|
|
5
5
|
value: DescField;
|
|
@@ -36,9 +36,6 @@ type DescWkt = {
|
|
|
36
36
|
values: DescField & {
|
|
37
37
|
fieldKind: "message";
|
|
38
38
|
};
|
|
39
|
-
} | {
|
|
40
|
-
typeName: "google.protobuf.FieldMask";
|
|
41
|
-
paths: DescField;
|
|
42
39
|
} | {
|
|
43
40
|
typeName: "google.protobuf.DoubleValue";
|
|
44
41
|
value: DescField & {
|
|
@@ -97,4 +94,3 @@ type DescWkt = {
|
|
|
97
94
|
* DescMessage.
|
|
98
95
|
*/
|
|
99
96
|
export declare function reifyWkt(message: DescMessage): DescWkt | undefined;
|
|
100
|
-
export {};
|
|
@@ -133,16 +133,6 @@ export function reifyWkt(message) {
|
|
|
133
133
|
}
|
|
134
134
|
return { typeName: message.typeName, values };
|
|
135
135
|
}
|
|
136
|
-
case "google.protobuf.FieldMask": {
|
|
137
|
-
const paths = message.fields.find((f) => f.number == 1 &&
|
|
138
|
-
f.fieldKind == "scalar" &&
|
|
139
|
-
f.scalar === ScalarType.STRING &&
|
|
140
|
-
f.repeated);
|
|
141
|
-
if (paths) {
|
|
142
|
-
return { typeName: message.typeName, paths };
|
|
143
|
-
}
|
|
144
|
-
break;
|
|
145
|
-
}
|
|
146
136
|
case "google.protobuf.DoubleValue":
|
|
147
137
|
case "google.protobuf.FloatValue":
|
|
148
138
|
case "google.protobuf.Int64Value":
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { EnumType } from "./enum.js";
|
|
2
|
+
import type { Message, MessageType } from "./message.js";
|
|
3
|
+
import type { ServiceType } from "./service-type.js";
|
|
4
|
+
/**
|
|
5
|
+
* IMessageTypeRegistry provides look-up for message types.
|
|
6
|
+
*
|
|
7
|
+
* You can conveniently create a registry using the createRegistry()
|
|
8
|
+
* function:
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { createTypeRegistry, IMessageTypeRegistry } from "@aptre/protobuf-es-lite";
|
|
12
|
+
* import { MyMessage, MyOtherMessage } from "./gen/my_message.pb.js";
|
|
13
|
+
*
|
|
14
|
+
* const reg: IMessageTypeRegistry = createRegistry(
|
|
15
|
+
* MyMessage,
|
|
16
|
+
* MyOtherMessage,
|
|
17
|
+
* );
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export interface IMessageTypeRegistry {
|
|
21
|
+
/**
|
|
22
|
+
* Find a message type by its protobuf type name.
|
|
23
|
+
*/
|
|
24
|
+
findMessage<T extends Message<T>>(typeName: string): MessageType<T> | undefined;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* IEnumTypeRegistry provides look-up for enum types.
|
|
28
|
+
*/
|
|
29
|
+
export interface IEnumTypeRegistry {
|
|
30
|
+
/**
|
|
31
|
+
* Find an enum type by its protobuf type name.
|
|
32
|
+
*/
|
|
33
|
+
findEnum(typeName: string): EnumType | undefined;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* IServiceTypeRegistry provides look-up for service types.
|
|
37
|
+
*/
|
|
38
|
+
export interface IServiceTypeRegistry {
|
|
39
|
+
/**
|
|
40
|
+
* Find a service type by its protobuf type name.
|
|
41
|
+
*/
|
|
42
|
+
findService(typeName: string): ServiceType | undefined;
|
|
43
|
+
}
|