-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Unable to use Google well known types #1042
Comments
Bump: @dcodeIO, is this a bug or is there another way of using these types? |
This might be due to protobuf.js implicitly converting field names from underscore_notation to camelCaseNotation since v6 (like google's js reference js impl does). You can try root.loadSync(protoFilePath, { keepCase: true }) to retain underscore notation or change the |
I loaded with |
What happens if you do: const struct = {
fields: {
label: {
kind: "struct_value",
struct_value: {
fields: {
another_label: {
kind: "number_value",
number_value: 10
}
}
}
}
}
}; |
Still the same result... |
Just edited this to use the string field names, can you try again? I believe it looks for the virtual oneof field there to determine which type of value is provided. |
Tried and still this |
Hmm, what happens if you also do const msg = MyType.fromObject({
struct_message: struct
}); If that also doesn't work, can you provide the |
I am using these protos: https://github.com/restorecommerce/protos. The proto definition is in |
Thanks. Seems that there is an issue with This appears to work: var root = new protobuf.Root();
root.load("google/protobuf/struct.proto", function() {
protobuf.parse(`syntax = "proto3"; message MyType { google.protobuf.Struct filter = 1; }`, root);
var MyType = root.MyType;
var myType = MyType.fromObject({
filter: {
fields: {
number: {
numberValue: 10
},
struct: {
structValue: {
fields: {
number: {
numberValue: 20
}
}
}
}
}
}
});
console.log(myType);
}); |
Oh, interesting! Then is it a bug when passing the options to |
Yes, this is a bug affecting keepCase. A proper fix could be to move field renaming out of the parser into construction of the reflection structure, in turn defining all of common.js in underscore notation. |
Btw, what is the use of those custom wrappers for Google well known types? Wouldn't they be parsed correctly in the "standard" way? |
Custom wrappes (from |
Any workaround or update here? I'm blocked not being able to load protos importing |
This is a pressing issue for us, any updates on this ? |
Bump: any updates here? |
Will this be even fixed? |
An issue for me too. |
any update? |
This is an issue for us trying to use the standard wrappers, they are not valid JSON for other JSON parsers that handle the standard wrappers according to the JSON documentation here: |
I'm still experiencing this issue
|
+1. Any updates? |
+1. Ready to PR if needed but I need a pointer. |
+1 please fix! |
Isn't this fixed with f61b4bc? If so, could you please release a new minor version? Maybe related/duplicates of this issue: |
@andrew8er That code doesn't seem to resolve the issue. |
I'm currently patching frontend code to manually parse to JSON and back. :( And to adjust type typescript typings for the message containing messages of type // This is how the generated TS type looks like
export namespace MyMessage {
export type AsObject = {
foo: string,
bar: ptypes_struct_struct_pb.Struct.AsObject, // :(
}
} // Patch the generated types by creating a new type that extends the generated type and override field(s) which require manual mapping.
export interface MyMessageAsObject extends Omit <MyMessage.AsObject, 'bar'> {
bar: /* Your custom type here */
} |
The methods below also appear to be incompatible. https://www.npmjs.com/package/google-protobuf import { ListValue, Struct, Value } from 'google-protobuf/google/protobuf/struct_pb';
ListValue.fromJavaScript(['foo', 'bar']).toObject();
Struct.fromJavaScript({ foo: 'bar' }).toObject();
Value.fromJavaScript('foobar').toObject(); |
protobufjs: 6.9.0 This issue is holding us back to use grpc\protoloader. |
bump |
Updates? |
same issue here, I read the official document about struct , then I write this func to build the struct data to protobuf: function buildGoogleStructValue (val, sub = false) {
const typeofVal = typeof val
const baseValueTypes = {
number: 'numberValue',
string: 'stringValue',
boolean: 'boolValue'
}
if (Object.keys(baseValueTypes).includes(typeofVal)) {
return {
[baseValueTypes[typeofVal]]: val
}
}
if (Array.isArray(val)) {
const out = {
listValue: {
values: []
}
}
val.forEach(valItem => {
const itemVal = buildGoogleStructValue(valItem, true)
out.listValue.values.push(itemVal)
})
return out
}
if (typeofVal === 'object') {
const out = sub ? {
structValue: {
fields: {}
}
} : {
fields: {}
}
Object.keys(val).forEach(field => {
if (sub) {
out.structValue.fields[field] = buildGoogleStructValue(val[field], true)
} else {
out.fields[field] = buildGoogleStructValue(val[field], true)
}
})
return out
}
} proto: message Message {
google.protobuf.Struct struct = 1;
} so, I can build message data like this: const message = {
struct: buildGoogleStructValue({
string: '1',
bool: true,
number: 12,
struct: {
structField1: 1000
},
list: [1, '12']
}
}) It's worked for me. |
Still an issue in 2021. Any update on this? |
This is a severe issue. Why is it even closed? |
Ping for severe issue - any idea how this might be fixed? |
I was able to fix this by making sure my Proto imports were sorted. I have no idea how or why that fixes it. |
+1 |
I had the same issue today with In a proto file I have:
"dependencies": {
"@grpc/proto-loader": "^0.6.11", I've solved the error by providing a list of all proto files: const protoLoader = require('@grpc/proto-loader');
const packageDefinition = protoLoader.loadSync(
[/* all proto files */], // <--- here we should provide test.proto and other files from (1)
{
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
}
); So in a my case it was an unclear error message. In the reality, Also, I found Hope, this will help someone. |
Thanks, @classLfz, this is working great for me. Only thing I added support for Also, if someone is interested I built deserialization function (to use in client) based on @classLfz's serialialization. Whole code: const isObject = (obj: any): boolean => typeof obj === 'object' && !Array.isArray(obj) && obj !== null;
enum FieldName {
Number = 'numberValue',
String = 'stringValue',
Boolean = 'boolValue',
Null = 'nullValue',
List = 'listValue',
Struct = 'structValue',
}
const typeofFieldNameMap = {
number: FieldName.Number,
string: FieldName.String,
boolean: FieldName.Boolean,
}
const baseFieldNameConstructorMap = {
[FieldName.Number]: Number,
[FieldName.String]: String,
[FieldName.Boolean]: Boolean,
}
const nullFieldValue = 0;
export const serializeGoogleStructValue = (val: any, sub = false) => {
if (val === null || val === undefined) {
return {
[FieldName.Null]: nullFieldValue
};
}
const typeofVal = typeof val;
if (Object.keys(typeofFieldNameMap).includes(typeofVal)) {
return {
[typeofFieldNameMap[typeofVal]]: val
};
}
if (Array.isArray(val)) {
const out = {
[FieldName.List]: {
values: []
}
};
for (const valItem of val) {
const itemVal = serializeGoogleStructValue(valItem, true);
out[FieldName.List].values.push(itemVal);
}
return out;
}
if (typeofVal === 'object') {
const out = sub ? {
[FieldName.Struct]: {
fields: {}
}
} : {
fields: {}
}
for (const field of Object.keys(val)) {
if (val[field] === undefined) {
continue;
}
if (sub) {
out[FieldName.Struct].fields[field] = serializeGoogleStructValue(val[field], true);
} else {
out.fields[field] = serializeGoogleStructValue(val[field], true);
}
}
return out;
}
}
export const deserializeGoogleStructValue = (val: any, sub = false) => {
if (sub === false && !isObject(val?.fields)) {
throw new Error(`Invalid Struct format. Object must include "fields" property`);
}
if (!isObject(val)) {
throw new Error(`Invalid Struct format. "${JSON.stringify(val)}" must be an object`);
}
const fieldName = Object.keys(val)[0];
if (fieldName === FieldName.Null) {
return null;
}
const baseValueTypeConstructor = baseFieldNameConstructorMap[fieldName];
if (baseValueTypeConstructor) {
return baseValueTypeConstructor(val[fieldName]);
}
if (fieldName === FieldName.List) {
return val[fieldName].values.map(listValue => deserializeGoogleStructValue(listValue, true));
}
if (fieldName === FieldName.Struct) {
return deserializeGoogleStructValue(val[fieldName], true);
}
if (isObject(val.fields)) {
const result = {};
Object.keys(val.fields).forEach(fieldName => {
result[fieldName] = deserializeGoogleStructValue(val.fields[fieldName], true);
});
return result;
}
} |
Summary: The underlying tooling seems to be sensitive to order. This works around their bugs. See also: protobufjs/protobuf.js#1042 (comment) Test Plan: Ran the script. Reviewers: philkuz, jamesbartlett, nlanam Reviewed By: jamesbartlett Signed-off-by: Vihang Mehta <vihang@pixielabs.ai> Differential Revision: https://phab.corp.pixielabs.ai/D11656 GitOrigin-RevId: d8d12d0
Summary: The underlying tooling seems to be sensitive to order. This works around their bugs. See also: protobufjs/protobuf.js#1042 (comment) Test Plan: Ran the script. Reviewers: philkuz, jamesbartlett, nlanam Reviewed By: jamesbartlett Signed-off-by: Vihang Mehta <vihang@pixielabs.ai> Differential Revision: https://phab.corp.pixielabs.ai/D11656 GitOrigin-RevId: 2ae7c8964b9d00e358481a6a5b4c4943603e0caa
Summary: The underlying tooling seems to be sensitive to order. This works around their bugs. See also: protobufjs/protobuf.js#1042 (comment) Test Plan: Ran the script. Reviewers: philkuz, jamesbartlett, nlanam Reviewed By: jamesbartlett Signed-off-by: Vihang Mehta <vihang@pixielabs.ai> Differential Revision: https://phab.corp.pixielabs.ai/D11656 GitOrigin-RevId: d8d12d0
Summary: The underlying tooling seems to be sensitive to order. This works around their bugs. See also: protobufjs/protobuf.js#1042 (comment) Test Plan: Ran the script. Reviewers: philkuz, jamesbartlett, nlanam Reviewed By: jamesbartlett Signed-off-by: Vihang Mehta <vihang@pixielabs.ai> Differential Revision: https://phab.corp.pixielabs.ai/D11656 GitOrigin-RevId: d8d12d0
Summary: The underlying tooling seems to be sensitive to order. This works around their bugs. See also: protobufjs/protobuf.js#1042 (comment) Test Plan: Ran the script. Reviewers: philkuz, jamesbartlett, nlanam Reviewed By: jamesbartlett Signed-off-by: Vihang Mehta <vihang@pixielabs.ai> Differential Revision: https://phab.corp.pixielabs.ai/D11656 GitOrigin-RevId: d8d12d0
any updates? |
protobuf.js version: 6.8.6
When I attempt to encode a message from a Google well known type (like
google.protobuf.Struct
) I get an empty field in the decoded message IF my path includesgoogle/protobuf
.Is this a bug or do we need to provide the path in some other way. I assume the problem starts when loading the commons wrapper here.
Note: this was working with
protobuf.js
version 5.The text was updated successfully, but these errors were encountered: