From 3939667ef1f37b025bd7f9476015890496d50e00 Mon Sep 17 00:00:00 2001 From: dcodeIO Date: Tue, 11 Apr 2017 12:35:31 +0200 Subject: [PATCH] New: Added 'json' conversion option for proto3 JSON mapping compatibility of NaN and Infinity + additional documentation of util.toJSONOptions, see #351 --- README.md | 2 +- src/converter.js | 8 ++++++-- src/type.js | 1 + src/util/minimal.js | 17 +++++++++++++++-- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a85f0c9e1..2afa91496 100644 --- a/README.md +++ b/README.md @@ -570,7 +570,7 @@ Supported decorators are: * **OneOf.d<T extends string>(...fieldNames: `string[]`)**
annotates a property as a protobuf oneof covering the specified fields. -Decorated types reside in `protobuf.roots.decorators` using a flat structure (no duplicate names). +Decorated types reside in `protobuf.roots["decorators"]` using a flat structure (no duplicate names). Command line ------------ diff --git a/src/converter.js b/src/converter.js index a696a5543..87497d0d4 100644 --- a/src/converter.js +++ b/src/converter.js @@ -40,8 +40,8 @@ function genValuePartial_fromObject(gen, field, fieldIndex, prop) { var isUnsigned = false; switch (field.type) { case "double": - case "float":gen - ("m%s=Number(d%s)", prop, prop); + case "float": gen + ("m%s=Number(d%s)", prop, prop); // also catches "NaN", "Infinity" break; case "uint32": case "fixed32": gen @@ -162,6 +162,10 @@ function genValuePartial_toObject(gen, field, fieldIndex, prop) { } else { var isUnsigned = false; switch (field.type) { + case "double": + case "float": gen + ("d%s=o.json&&!isFinite(m%s)?String(m%s):m%s", prop, prop, prop, prop); + break; case "uint64": isUnsigned = true; // eslint-disable-line no-fallthrough diff --git a/src/type.js b/src/type.js index 1c8a26397..6cd75b66f 100644 --- a/src/type.js +++ b/src/type.js @@ -537,6 +537,7 @@ Type.prototype.fromObject = function fromObject(object) { * @property {boolean} [arrays=false] Sets empty arrays for missing repeated fields even if `defaults=false` * @property {boolean} [objects=false] Sets empty objects for missing map fields even if `defaults=false` * @property {boolean} [oneofs=false] Includes virtual oneof properties set to the present field's name, if any + * @property {boolean} [json=false] Performs additional JSON compatibility conversions, i.e. NaN and Infinity to strings */ /** diff --git a/src/util/minimal.js b/src/util/minimal.js index 0fb991cb7..43999f95a 100644 --- a/src/util/minimal.js +++ b/src/util/minimal.js @@ -375,13 +375,26 @@ util.oneOfSetter = function setOneOf(fieldNames) { }; /** - * Default conversion options used for {@link Message#toJSON} implementations. Longs, enums and bytes are converted to strings by default. + * Default conversion options used for {@link Message#toJSON} implementations. + * + * These options are close to proto3's JSON mapping with the exception that internal types like Any are handled just like messages. More precisely: + * + * - Longs become strings + * - Enums become string keys + * - Bytes become base64 encoded strings + * - (Sub-)Messages become plain objects + * - Maps become plain objects with all string keys + * - Repeated fields become arrays + * - NaN and Infinity for float and double fields become strings + * * @type {ConversionOptions} + * @see https://developers.google.com/protocol-buffers/docs/proto3?hl=en#json */ util.toJSONOptions = { longs: String, enums: String, - bytes: String + bytes: String, + json: true }; util._configure = function() {