-
Notifications
You must be signed in to change notification settings - Fork 349
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
feat: add support for Struct in NestJS #762
Merged
Merged
Changes from 5 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
5249801
feat: add support for Struct in NestJS
301ebb0
Add another codegen update.
stephenh 13d1ce9
Fix tests
0253e48
Format.
stephenh 9956fed
Make const/base output more conditional.
stephenh 6c76cf6
Use isStructType.
stephenh 6aa03cc
Consistently wrap & unwrap.
stephenh 1bfd10d
Use conditional shallow/deep wrapping.
stephenh ffb21dc
Fix oneofs.
stephenh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
/* eslint-disable */ | ||
import { wrappers } from "protobufjs"; | ||
|
||
export const protobufPackage = "google.protobuf"; | ||
|
||
/** | ||
* `NullValue` is a singleton enumeration to represent the null value for the | ||
* `Value` type union. | ||
* | ||
* The JSON representation for `NullValue` is JSON `null`. | ||
*/ | ||
export enum NullValue { | ||
/** NULL_VALUE - Null value. */ | ||
NULL_VALUE = 0, | ||
UNRECOGNIZED = -1, | ||
} | ||
|
||
/** | ||
* `Struct` represents a structured data value, consisting of fields | ||
* which map to dynamically typed values. In some languages, `Struct` | ||
* might be supported by a native representation. For example, in | ||
* scripting languages like JS a struct is represented as an | ||
* object. The details of that representation are described together | ||
* with the proto support for the language. | ||
* | ||
* The JSON representation for `Struct` is JSON object. | ||
*/ | ||
export interface Struct { | ||
/** Unordered map of dynamically typed values. */ | ||
fields: { [key: string]: any | undefined }; | ||
} | ||
|
||
export interface Struct_FieldsEntry { | ||
key: string; | ||
value: any | undefined; | ||
} | ||
|
||
/** | ||
* `Value` represents a dynamically typed value which can be either | ||
* null, a number, a string, a boolean, a recursive struct value, or a | ||
* list of values. A producer of value is expected to set one of these | ||
* variants. Absence of any variant indicates an error. | ||
* | ||
* The JSON representation for `Value` is JSON value. | ||
*/ | ||
export interface Value { | ||
/** Represents a null value. */ | ||
nullValue?: | ||
| NullValue | ||
| undefined; | ||
/** Represents a double value. */ | ||
numberValue?: | ||
| number | ||
| undefined; | ||
/** Represents a string value. */ | ||
stringValue?: | ||
| string | ||
| undefined; | ||
/** Represents a boolean value. */ | ||
boolValue?: | ||
| boolean | ||
| undefined; | ||
/** Represents a structured value. */ | ||
structValue?: | ||
| { [key: string]: any } | ||
| undefined; | ||
/** Represents a repeated `Value`. */ | ||
listValue?: Array<any> | undefined; | ||
} | ||
|
||
/** | ||
* `ListValue` is a wrapper around a repeated field of values. | ||
* | ||
* The JSON representation for `ListValue` is JSON array. | ||
*/ | ||
export interface ListValue { | ||
/** Repeated field of dynamically typed values. */ | ||
values: any[]; | ||
} | ||
|
||
export const GOOGLE_PROTOBUF_PACKAGE_NAME = "google.protobuf"; | ||
|
||
const wrapStruct = (value: any, nested = false): any => { | ||
const valueType = typeof value; | ||
const primitiveValueTypes = { number: "numberValue", string: "stringValue", boolean: "boolValue" }; | ||
if (Object.keys(primitiveValueTypes).includes(valueType)) { | ||
return Value.wrap(value); | ||
} | ||
if (Array.isArray(value)) { | ||
return { listValue: { values: value.map((item) => wrapStruct(item)) } }; | ||
} | ||
if (valueType === "object") { | ||
const res = nested ? { structValue: { fields: {} as any } } : { fields: {} as any }; | ||
Object.keys(value).forEach((field) => { | ||
if (nested) { | ||
res.structValue!.fields[field] = wrapStruct(value[field], true); | ||
} else { | ||
res.fields![field] = wrapStruct(value[field], true); | ||
} | ||
}); | ||
return res; | ||
} | ||
}; | ||
wrappers[".google.protobuf.Struct"] = { | ||
fromObject: wrapStruct, | ||
toObject(message: Struct) { | ||
return message ? Struct.unwrap(message) : message; | ||
}, | ||
} as any; | ||
|
||
function createBaseStruct(): Struct { | ||
return { fields: {} }; | ||
} | ||
|
||
export const Struct = { | ||
wrap(object: { [key: string]: any } | undefined): Struct { | ||
const struct = createBaseStruct(); | ||
if (object !== undefined) { | ||
Object.keys(object).forEach((key) => { | ||
struct.fields[key] = object[key]; | ||
}); | ||
} | ||
return struct; | ||
}, | ||
|
||
unwrap(message: Struct): { [key: string]: any } { | ||
if (!message.fields) { | ||
return message; | ||
} | ||
const object: { [key: string]: any } = {}; | ||
Object.keys(message.fields).forEach((key) => { | ||
const unwrappedValue = Value.unwrap(message.fields[key]); | ||
object[key] = unwrappedValue !== undefined ? unwrappedValue : message.fields[key]; | ||
}); | ||
return object; | ||
}, | ||
}; | ||
|
||
function createBaseValue(): Value { | ||
return {}; | ||
} | ||
|
||
export const Value = { | ||
wrap(value: any): Value { | ||
const result = createBaseValue(); | ||
|
||
if (value === null) { | ||
result.nullValue = NullValue.NULL_VALUE; | ||
} else if (typeof value === "boolean") { | ||
result.boolValue = value; | ||
} else if (typeof value === "number") { | ||
result.numberValue = value; | ||
} else if (typeof value === "string") { | ||
result.stringValue = value; | ||
} else if (Array.isArray(value)) { | ||
result.listValue = value; | ||
} else if (typeof value === "object") { | ||
result.structValue = value; | ||
} else if (typeof value !== "undefined") { | ||
throw new Error("Unsupported any value type: " + typeof value); | ||
} | ||
|
||
return result; | ||
}, | ||
|
||
unwrap(message: any): string | number | boolean | Object | null | Array<any> | undefined { | ||
if (message?.hasOwnProperty("stringValue") && message?.stringValue !== undefined) { | ||
return message.stringValue; | ||
} else if (message?.hasOwnProperty("numberValue") && message?.numberValue !== undefined) { | ||
return message.numberValue; | ||
} else if (message?.hasOwnProperty("boolValue") && message?.boolValue !== undefined) { | ||
return message.boolValue; | ||
} else if (message?.hasOwnProperty("structValue") && message?.structValue !== undefined) { | ||
return Struct.unwrap(message.structValue as any); | ||
} else if (message?.hasOwnProperty("listValue") && message?.listValue !== undefined) { | ||
return ListValue.unwrap(message.listValue); | ||
} else if (message?.hasOwnProperty("nullValue") && message?.nullValue !== undefined) { | ||
return null; | ||
} | ||
return undefined; | ||
}, | ||
}; | ||
|
||
function createBaseListValue(): ListValue { | ||
return { values: [] }; | ||
} | ||
|
||
export const ListValue = { | ||
wrap(value: Array<any> | undefined): ListValue { | ||
const result = createBaseListValue(); | ||
|
||
result.values = value ?? []; | ||
|
||
return result; | ||
}, | ||
|
||
unwrap(message: ListValue): Array<any> { | ||
if (message?.hasOwnProperty("values") && Array.isArray(message.values)) { | ||
return message.values.map((value: any) => Value.unwrap(value) || value); | ||
} else { | ||
return message as any; | ||
} | ||
}, | ||
}; |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Question: Should this
true
be a false? Just thinking that we are in thenested = false
branch of theit
, so should we pass alongfalse
as well?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 only case we actually need for
nested
to befalse
is the base object, we should only get here initially and from here it should be alwaystrue
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.
Gotcha, thanks!