-
Notifications
You must be signed in to change notification settings - Fork 206
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
improve proto3 JSON types and utils #9219
Conversation
/** @typedef {{ typeUrl: string; valueBase64: string }} Proto3MsgBase64 */ | ||
/** | ||
* base64 encode `value` (possibly binary ) for cross-vat communication | ||
* | ||
* @param {Any} msg | ||
* @returns {Proto3MsgBase64} | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this change requires more explicit understanding of why Base64 is required:
- If you declare a Golang struct to have a
[]byte
member, then when youjson.Marshal
orjson.Unmarshal
it, theencoding/json
Golang module converts[]byte
to and from base64. AnyKindOfProtoCodec.toJSON(object)
, includingAny.toJSON(object)
returns a "message" with byte arrays converted to Base64AnyKindOfProtoCodec.fromJSON(message)
, includingAny.fromJSON(message)
returns an object with Base64 converted to byte arrays- That, to me, suggests that the type should be named something like
AnyJson
and defined as{ typeUrl: string, value: string }
, since that is just the Jsonable version oftype Any = { typeUrl: string, value: Uint8Array }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cf cosmic-proto/dist/codegen/google/protobuf/any.js
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The names Any
and AnyJson
make sense to me. I was hoping to distinguish between them structurely by their keys, but I forgot about this precedence that should be maintained:
agoric-sdk/packages/cosmic-proto/src/codegen/google/protobuf/any.ts
Lines 260 to 269 in 2973951
toJSON(message: Any): unknown { | |
const obj: any = {}; | |
message.typeUrl !== undefined && (obj.typeUrl = message.typeUrl); | |
message.value !== undefined && | |
(obj.value = base64FromBytes( | |
message.value !== undefined ? message.value : new Uint8Array(), | |
)); | |
return obj; | |
}, | |
fromPartial(object: Partial<Any>): Any { |
Fortunately TS can still distinguish between them.
I wonder why that method returns unknown
instead of { typeUrl: string, value: string }
.
The two codecs in this file, we don't need them, right? It's just Any.fromJSON and Any.toJSON. I'll give that a whirl
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder why that method returns
unknown
Maybe because just because the transpiler is being slothful. A proper toJSON
return type would need to be prepared to either introduce a new type, or inline the type for an object that could potentially have many properties.
The two codecs in this file, we don't need them, right? It's just Any.fromJSON and Any.toJSON.
That's correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Meanwhile I've added a helper:
// TODO make codegen toJSON() return these instead of unknown
/**
* Proto Any with arrays encoded as base64
*/
export type Base64Any<T> = {
[Prop in keyof T]: T[Prop] extends Uint8Array ? string : T[Prop];
};
Deploying agoric-sdk with Cloudflare Pages
|
@@ -34,3 +41,11 @@ export const typedJson = <T extends keyof Proto3Shape>( | |||
...obj, | |||
} as TypedJson<T>; | |||
}; | |||
|
|||
// TODO make codegen toJSON() return these instead of unknown |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will also need this for RequestQuery.toJSON()
(/tendermint/abci/types.js
). Any chance it can fit in this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that would require patching the codegen. out of scope, thus the TODO
seat: ZCFSeat, | ||
offerArgs?: OA, | ||
) => OR; | ||
type HandleOffer<OR extends unknown, OA> = (seat: ZCFSeat, offerArgs: OA) => OR; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure how this is related to the rest of the changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
type bug discovered in the course of the work: d68596cb8d1d84db4c4eb9af754b132af1ce1649
Description
Spurred by some recent reviews.
Security Considerations
none
Scaling Considerations
none
Documentation Considerations
Less to document
Testing Considerations
CI
Upgrade Considerations
not yet in production