From d0ff5fabca2fc334b1853c0e9d938646a3e0bfd4 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Mon, 10 Aug 2020 06:18:58 +0200 Subject: [PATCH] Normalize unset fields to null --- packages/proto-signing/src/adr27.spec.ts | 12 +++++++++++ packages/proto-signing/src/adr27.ts | 27 +++++++++++++++++------- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/packages/proto-signing/src/adr27.spec.ts b/packages/proto-signing/src/adr27.spec.ts index 5d7c55e5..788e535c 100644 --- a/packages/proto-signing/src/adr27.spec.ts +++ b/packages/proto-signing/src/adr27.spec.ts @@ -46,6 +46,12 @@ describe("adr27", () => { expect(omitDefault(Review.values["ACCEPTED"])).toEqual(Review.values["ACCEPTED"]); expect(omitDefault(Review.values["UNSPECIFIED"])).toEqual(null); }); + + it("works for unset", () => { + // null and undefined both represent unset in protobuf.js serialization + expect(omitDefault(undefined)).toEqual(null); + expect(omitDefault(null)).toEqual(null); + }); }); describe("omitDefaults", () => { @@ -85,6 +91,12 @@ describe("adr27", () => { expect(omitDefaults(Review.values["UNSPECIFIED"])).toEqual(null); }); + it("works for unset", () => { + // null and undefined both represent unset in protobuf.js serialization + expect(omitDefaults(undefined)).toEqual(null); + expect(omitDefaults(null)).toEqual(null); + }); + it("works for objects", () => { // empty expect(omitDefaults({})).toEqual({}); diff --git a/packages/proto-signing/src/adr27.ts b/packages/proto-signing/src/adr27.ts index 7183fdf3..6c79dc76 100644 --- a/packages/proto-signing/src/adr27.ts +++ b/packages/proto-signing/src/adr27.ts @@ -1,4 +1,4 @@ -import { isUint8Array } from "@cosmjs/utils"; +import { isNonNullObject, isUint8Array } from "@cosmjs/utils"; /** * Converts default values to null in order to tell protobuf.js @@ -7,6 +7,8 @@ import { isUint8Array } from "@cosmjs/utils"; * @see https://github.com/cosmos/cosmos-sdk/pull/6979 */ export function omitDefault(input: T): T | null { + if (input === undefined || input === null) return null; + if (typeof input === "number" || typeof input === "boolean" || typeof input === "string") { return input || null; } @@ -23,6 +25,10 @@ export function omitDefault(input: T): T | null { */ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function omitDefaults(input: any): any { + // Unset + if (input === undefined || input === null) return null; + + // Protobuf element if ( typeof input === "number" || typeof input === "boolean" || @@ -33,11 +39,16 @@ export function omitDefaults(input: any): any { return omitDefault(input); } - return Object.keys(input).reduce( - (accumulator, key) => ({ - ...accumulator, - [key]: omitDefaults(input[key]), - }), - {}, - ); + // Object + if (isNonNullObject(input)) { + return Object.keys(input).reduce( + (accumulator, key) => ({ + ...accumulator, + [key]: omitDefaults((input as any)[key]), + }), + {}, + ); + } + + throw new Error(`Input type not supported: ${typeof input}`); }