mirror of
https://github.com/grpc/grpc-node.git
synced 2025-12-08 18:23:54 +00:00
Add json option and google.protobuf.Any wrapper type
This commit is contained in:
parent
c6e17f2758
commit
c7bbf045b6
@ -38,6 +38,7 @@ The options parameter is an object that can have the following optional properti
|
||||
| `arrays` | `true` or `false` | Set empty arrays for missing array values even if `defaults` is `false` Defaults to `false`.
|
||||
| `objects` | `true` or `false` | Set empty objects for missing object values even if `defaults` is `false` Defaults to `false`.
|
||||
| `oneofs` | `true` or `false` | Set virtual oneof properties to the present field's name. Defaults to `false`.
|
||||
| `json` | `true` or `false` | Represent `Infinity` and `NaN` as strings in `float` fields, and automatically decode `google.protobuf.Any` values. Defaults to `false`
|
||||
| `includeDirs` | An array of strings | A list of search paths for imported `.proto` files.
|
||||
|
||||
The following options object closely approximates the existing behavior of `grpc.load`:
|
||||
|
||||
@ -96,6 +96,15 @@ function getImportLine(dependency: Protobuf.Type | Protobuf.Enum, from?: Protobu
|
||||
}
|
||||
|
||||
function generatePermissiveMessageInterface(formatter: TextFormatter, messageType: Protobuf.Type) {
|
||||
if (messageType.fullName === '.google.protobuf.Any') {
|
||||
/* This describes the behavior of the Protobuf.js Any wrapper fromObject
|
||||
* replacement function */
|
||||
formatter.writeLine('export type Any__Output = AnyExtension | {');
|
||||
formatter.writeLine(' type_url: string;');
|
||||
formatter.writeLine(' value: Buffer | Uint8Array | string;');
|
||||
formatter.writeLine('}');
|
||||
return;
|
||||
}
|
||||
formatter.writeLine(`export interface ${messageType.name} {`);
|
||||
formatter.indent();
|
||||
for (const field of messageType.fieldsArray) {
|
||||
@ -104,6 +113,8 @@ function generatePermissiveMessageInterface(formatter: TextFormatter, messageTyp
|
||||
switch (field.type) {
|
||||
case 'double':
|
||||
case 'float':
|
||||
type = 'number | string';
|
||||
break;
|
||||
case 'int32':
|
||||
case 'uint32':
|
||||
case 'sint32':
|
||||
@ -149,6 +160,23 @@ function generatePermissiveMessageInterface(formatter: TextFormatter, messageTyp
|
||||
}
|
||||
|
||||
function generateRestrictedMessageInterface(formatter: TextFormatter, messageType: Protobuf.Type, options: Protobuf.IConversionOptions) {
|
||||
if (messageType.fullName === '.google.protobuf.Any' && options.json) {
|
||||
/* This describes the behavior of the Protobuf.js Any wrapper toObject
|
||||
* replacement function */
|
||||
formatter.writeLine('export type Any__Output = AnyExtension | {');
|
||||
formatter.writeLine(' type_url: string;');
|
||||
let type: string;
|
||||
if (options.bytes === Array) {
|
||||
type = 'Uint8Array';
|
||||
} else if (options.bytes === String) {
|
||||
type = 'string';
|
||||
} else {
|
||||
type = 'Buffer';
|
||||
}
|
||||
formatter.writeLine(` value: ${type};`);
|
||||
formatter.writeLine('}');
|
||||
return;
|
||||
}
|
||||
formatter.writeLine(`export interface ${messageType.name}__Output {`);
|
||||
formatter.indent();
|
||||
for (const field of messageType.fieldsArray) {
|
||||
@ -158,6 +186,12 @@ function generateRestrictedMessageInterface(formatter: TextFormatter, messageTyp
|
||||
switch (field.type) {
|
||||
case 'double':
|
||||
case 'float':
|
||||
if (options.json) {
|
||||
type = 'number | string';
|
||||
} else {
|
||||
type = 'number';
|
||||
}
|
||||
break;
|
||||
case 'int32':
|
||||
case 'uint32':
|
||||
case 'sint32':
|
||||
@ -244,6 +278,9 @@ function generateMessageInterfaces(formatter: TextFormatter, messageType: Protob
|
||||
if (usesLong) {
|
||||
formatter.writeLine("import { Long } from '@grpc/proto-loader';");
|
||||
}
|
||||
if (messageType.fullName === '.google.protobuf.Any') {
|
||||
formatter.writeLine("import { AnyExtension } from '@grpc/proto-loader';")
|
||||
}
|
||||
formatter.writeLine('');
|
||||
|
||||
generatePermissiveMessageInterface(formatter, messageType);
|
||||
@ -524,7 +561,7 @@ function runScript() {
|
||||
.string(['includeDirs', 'grpcLib'])
|
||||
.normalize(['includeDirs', 'outDir'])
|
||||
.array('includeDirs')
|
||||
.boolean(['keepCase', 'defaults', 'arrays', 'objects', 'oneofs'])
|
||||
.boolean(['keepCase', 'defaults', 'arrays', 'objects', 'oneofs', 'json'])
|
||||
// .choices('longs', ['String', 'Number'])
|
||||
// .choices('enums', ['String'])
|
||||
// .choices('bytes', ['Array', 'String'])
|
||||
@ -559,13 +596,14 @@ function runScript() {
|
||||
outDir: 'O'
|
||||
}).describe({
|
||||
keepCase: 'Preserve the case of field names',
|
||||
longs: 'The type that should be used to output 64 bit integer values',
|
||||
enums: 'The type that should be used to output enum fields',
|
||||
bytes: 'The type that should be used to output bytes fields',
|
||||
longs: 'The type that should be used to output 64 bit integer values. Can be String, Number',
|
||||
enums: 'The type that should be used to output enum fields. Can be String',
|
||||
bytes: 'The type that should be used to output bytes fields. Can be String, Array',
|
||||
defaults: 'Output default values for omitted fields',
|
||||
arrays: 'Output default values for omitted repeated fields even if --defaults is not set',
|
||||
objects: 'Output default values for omitted message fields even if --defaults is not set',
|
||||
oneofs: 'Output virtual oneof fields set to the present field\'s name',
|
||||
json: 'Represent Infinity and NaN as strings in float fields. Also decode google.protobuf.Any automatically',
|
||||
includeDirs: 'Directories to search for included files',
|
||||
outDir: 'Directory in which to output files',
|
||||
grpcLib: 'The gRPC implementation library that these types will be used with'
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@grpc/proto-loader",
|
||||
"version": "0.6.0-pre2",
|
||||
"version": "0.6.0-pre3",
|
||||
"author": "Google Inc.",
|
||||
"contributors": [
|
||||
{
|
||||
|
||||
@ -22,6 +22,39 @@ import * as descriptor from 'protobufjs/ext/descriptor';
|
||||
|
||||
export { Long } from 'long';
|
||||
|
||||
/**
|
||||
* This type exists for use with code generated by the proto-loader-gen-types
|
||||
* tool. This type should be used with another interface, e.g.
|
||||
* MessageType & AnyExtension for an object that is converted to or from a
|
||||
* google.protobuf.Any message.
|
||||
* For example, when processing an Any message:
|
||||
*
|
||||
* ```ts
|
||||
* if (isAnyExtension(message)) {
|
||||
* switch (message['@type']) {
|
||||
* case TYPE1_URL:
|
||||
* handleType1(message as AnyExtension & Type1);
|
||||
* break;
|
||||
* case TYPE2_URL:
|
||||
* handleType2(message as AnyExtension & Type2);
|
||||
* break;
|
||||
* // ...
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export interface AnyExtension {
|
||||
/**
|
||||
* The fully qualified name of the message type that this object represents,
|
||||
* possibly including a URL prefix.
|
||||
*/
|
||||
'@type': string;
|
||||
}
|
||||
|
||||
export function isAnyExtension(obj: object): obj is AnyExtension {
|
||||
return ('@type' in obj) && (typeof (obj as AnyExtension)['@type'] === 'string');
|
||||
}
|
||||
|
||||
import camelCase = require('lodash.camelcase');
|
||||
|
||||
declare module 'protobufjs' {
|
||||
@ -331,6 +364,8 @@ function addIncludePathResolver(root: Protobuf.Root, includePaths: string[]) {
|
||||
* `defaults` is `false`. Defaults to `false`.
|
||||
* @param options.oneofs Set virtual oneof properties to the present field's
|
||||
* name
|
||||
* @param options.json Represent Infinity and NaN as strings in float fields,
|
||||
* and automatically decode google.protobuf.Any values.
|
||||
* @param options.includeDirs Paths to search for imported `.proto` files.
|
||||
*/
|
||||
export function load(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user