diff --git a/src/converter.js b/src/converter.js index fe72caf28..b8dd30c81 100644 --- a/src/converter.js +++ b/src/converter.js @@ -41,7 +41,9 @@ function genValuePartial_fromObject(gen, field, fieldIndex, prop) { } gen ("}"); } else - if (field.resolvedType.fullName === ".google.protobuf.Duration" || field.resolvedType.fullName === ".google.protobuf.Timestamp") { gen + if (field.resolvedType.fullName === ".google.protobuf.Duration" || field.resolvedType.fullName === ".google.protobuf.Timestamp" + || field.resolvedType.fullName === ".google.protobuf.Value" + ) { gen ("m%s=types[%i].fromObject(d%s)", prop, fieldIndex, prop); } else gen ("if(typeof d%s!==\"object\")", prop) diff --git a/src/util/is-legacy-struct.js b/src/util/is-legacy.js similarity index 65% rename from src/util/is-legacy-struct.js rename to src/util/is-legacy.js index 78b1bc7d9..a5c9dc6a5 100644 --- a/src/util/is-legacy-struct.js +++ b/src/util/is-legacy.js @@ -1,5 +1,20 @@ "use strict"; -module.exports = isLegacyStruct; +module.exports = { + isLegacyStruct, + isLegacyValue +}; + +const valueKeysSet = new Set(["string_value", "number_value", "bool_value", "struct_value", "list_value", "null_value"]); + +/** + * Checks if the given payload is in the legacy value format. + * + * @param {object} payload The payload to check for legacy value format + * @returns {boolean} True if the value is in legacy format, false otherwise + */ +function isLegacyValue(payload) { + return payload && typeof payload === "object" && Object.keys(payload).length === 1 && valueKeysSet.has(Object.keys(payload)[0]); +} /** * Identifies where the payload for a struct is in the form of a legacy struct. @@ -25,15 +40,11 @@ module.exports = isLegacyStruct; * @returns {boolean} True if the payload is in legacy struct format, false otherwise */ function isLegacyStruct(payload) { - // Value types in a struct - const valueKeysSet = new Set(["string_value", "number_value", "bool_value", "struct_value", "list_value", "null_value"]); - // If object has only one key and that key is "fields" which is an object if (payload && Object.keys(payload).length === 1 && payload.fields && typeof payload.fields === "object") { if (Array.isArray(payload.fields)) { return payload.fields.every(field => Object.keys(field).length === 2 && - field.key && field.value && Object.keys(field.value).length === 1 - && valueKeysSet.has(Object.keys(field.value)[0])); + field.key && isLegacyValue(field.value)); } // Get all the values of the fields object @@ -42,10 +53,7 @@ function isLegacyStruct(payload) { const fieldValues = Object.values(payload.fields); // Check if all the fieldValues have only one key and that key is a valid value type - if (fieldValues.every(fieldValue => { - const fieldValueKeys = fieldValue ? Object.keys(fieldValue) : []; - return fieldValueKeys.length === 1 && valueKeysSet.has(fieldValueKeys[0]); - })) { + if (fieldValues.every(fieldValue => isLegacyValue(fieldValue))) { return true; } } diff --git a/src/wrappers.js b/src/wrappers.js index 910065319..117e72bb4 100644 --- a/src/wrappers.js +++ b/src/wrappers.js @@ -8,7 +8,7 @@ var wrappers = exports; var Message = require("./message"); -var isLegacyStruct = require("./util/is-legacy-struct"); +var { isLegacyValue, isLegacyStruct } = require("./util/is-legacy"); var util = require("./util"); /** @@ -157,6 +157,10 @@ wrappers[".google.protobuf.Value"] = { // If already a Value instance, return as is if (object instanceof this.ctor) return object; + if (isLegacyValue(object)) { + return this.create(object); + } + // Handle different types and convert to appropriate Value field if (object === null || object === undefined) { return this.create({ null_value: 0 });