mirror of https://github.com/grpc/grpc-node.git
Separate out packages. Upgrade new protobufjs package to Protobuf.js 6.8
This commit is contained in:
parent
6376422345
commit
81acd929b7
|
|
@ -6,6 +6,9 @@ npm-debug.log
|
||||||
yarn-error.log
|
yarn-error.log
|
||||||
yarn.lock
|
yarn.lock
|
||||||
|
|
||||||
|
# Emacs temp files
|
||||||
*~
|
*~
|
||||||
|
\#*\#
|
||||||
|
.\#*
|
||||||
|
|
||||||
packages/grpc-native-core/src/node/
|
packages/grpc-native-core/src/node/
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright 2017 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = require('grpc-surface')(require('grpc-js-core'));
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"name": "grpc-js",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/grpc/grpc-node.git"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/grpc/grpc-node/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://grpc.io",
|
||||||
|
"dependencies": {
|
||||||
|
"grpc-js-core": "^0.1.0",
|
||||||
|
"grpc-surface": "^1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright 2017 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// TODO(mlumish): This should eventually be grpc-native-core instead of grpc
|
||||||
|
module.exports = require('grpc-surface')(require('grpc'));
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"name": "grpc-native",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/grpc/grpc-node.git"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/grpc/grpc-node/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://grpc.io",
|
||||||
|
"dependencies": {
|
||||||
|
"grpc": "^1.6.0",
|
||||||
|
"grpc-surface": "^1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,139 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright 2017 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
|
var _ = require('lodash');
|
||||||
|
var ProtoBuf = require('protobufjs');
|
||||||
|
|
||||||
|
module.exports = function(grpc) {
|
||||||
|
|
||||||
|
let exports = {};
|
||||||
|
|
||||||
|
const protobuf_js_5_common = require('protobuf_js_5_common')(grpc);
|
||||||
|
const protobuf_js_6_common = require('protobuf_js_6_common')(grpc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default options for loading proto files into gRPC
|
||||||
|
* @alias grpc~defaultLoadOptions
|
||||||
|
*/
|
||||||
|
const defaultGrpcOptions = {
|
||||||
|
convertFieldsToCamelCase: false,
|
||||||
|
binaryAsBase64: false,
|
||||||
|
longsAsStrings: true,
|
||||||
|
enumsAsStrings: true
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a ProtoBuf.js object as a gRPC object. The options object can provide
|
||||||
|
* the following options:
|
||||||
|
* - binaryAsBase64: deserialize bytes values as base64 strings instead of
|
||||||
|
* Buffers. Defaults to false
|
||||||
|
* - longsAsStrings: deserialize long values as strings instead of objects.
|
||||||
|
* Defaults to true
|
||||||
|
* - enumsAsStrings: deserialize enum values as strings instead of numbers.
|
||||||
|
* Defaults to true
|
||||||
|
* - protobufjsVersion: Available values are 5, 6, and 'detect'. 5 and 6
|
||||||
|
* respectively indicate that an object from the corresponding version of
|
||||||
|
* ProtoBuf.js is provided in the value argument. If the option is 'detect',
|
||||||
|
* gRPC will guess what the version is based on the structure of the value.
|
||||||
|
* Defaults to 'detect'.
|
||||||
|
* @param {Object} value The ProtoBuf.js reflection object to load
|
||||||
|
* @param {Object=} options Options to apply to the loaded file
|
||||||
|
* @return {Object<string, *>} The resulting gRPC object
|
||||||
|
*/
|
||||||
|
exports.loadObject = function loadObject(value, options) {
|
||||||
|
options = _.defaults(options, defaultGrpcOptions);
|
||||||
|
options = _.defaults(options, {'protobufjsVersion': 'detect'});
|
||||||
|
var protobufjsVersion;
|
||||||
|
if (options.protobufjsVersion === 'detect') {
|
||||||
|
if (protobuf_js_6_common.isProbablyProtobufJs6(value)) {
|
||||||
|
protobufjsVersion = 6;
|
||||||
|
} else if (protobuf_js_5_common.isProbablyProtobufJs5(value)) {
|
||||||
|
protobufjsVersion = 5;
|
||||||
|
} else {
|
||||||
|
var error_message = 'Could not detect ProtoBuf.js version. Please ' +
|
||||||
|
'specify the version number with the "protobufjs_version" option';
|
||||||
|
throw new Error(error_message);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
protobufjsVersion = options.protobufjsVersion;
|
||||||
|
}
|
||||||
|
switch (protobufjsVersion) {
|
||||||
|
case 6: return protobuf_js_6_common.loadObject(value, options);
|
||||||
|
case 5: return protobuf_js_5_common.loadObject(value, options);
|
||||||
|
default:
|
||||||
|
throw new Error('Unrecognized protobufjsVersion', protobufjsVersion);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var loadObject = exports.loadObject;
|
||||||
|
|
||||||
|
function applyProtoRoot(filename, root) {
|
||||||
|
if (_.isString(filename)) {
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
filename.root = path.resolve(filename.root) + '/';
|
||||||
|
root.resolvePath = function(originPath, importPath, alreadyNormalized) {
|
||||||
|
return ProtoBuf.util.path.resolve(filename.root,
|
||||||
|
importPath,
|
||||||
|
alreadyNormalized);
|
||||||
|
};
|
||||||
|
return filename.file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a gRPC object from a .proto file. The options object can provide the
|
||||||
|
* following options:
|
||||||
|
* - convertFieldsToCamelCase: Load this file with field names in camel case
|
||||||
|
* instead of their original case
|
||||||
|
* - binaryAsBase64: deserialize bytes values as base64 strings instead of
|
||||||
|
* Buffers. Defaults to false
|
||||||
|
* - longsAsStrings: deserialize long values as strings instead of objects.
|
||||||
|
* Defaults to true
|
||||||
|
* - enumsAsStrings: deserialize enum values as strings instead of numbers.
|
||||||
|
* Defaults to true
|
||||||
|
* - deprecatedArgumentOrder: Use the beta method argument order for client
|
||||||
|
* methods, with optional arguments after the callback. Defaults to false.
|
||||||
|
* This option is only a temporary stopgap measure to smooth an API breakage.
|
||||||
|
* It is deprecated, and new code should not use it.
|
||||||
|
* @param {string|{root: string, file: string}} filename The file to load
|
||||||
|
* @param {string=} format The file format to expect. Must be either 'proto' or
|
||||||
|
* 'json'. Defaults to 'proto'
|
||||||
|
* @param {Object=} options Options to apply to the loaded file
|
||||||
|
* @return {Object<string, *>} The resulting gRPC object
|
||||||
|
*/
|
||||||
|
exports.load = function load(filename, format, options) {
|
||||||
|
/* Note: format is currently unused, because the API for loading a proto
|
||||||
|
file or a JSON file is identical in Protobuf.js 6. In the future, there is
|
||||||
|
still the possibility of adding other formats that would be loaded
|
||||||
|
differently */
|
||||||
|
options = _.defaults(options, defaultGrpcOptions);
|
||||||
|
options.protobufjs_version = 6;
|
||||||
|
var root = new ProtoBuf.Root();
|
||||||
|
var parse_options = {keepCase: !options.convertFieldsToCamelCase};
|
||||||
|
return loadObject(root.loadSync(applyProtoRoot(filename, root),
|
||||||
|
parse_options),
|
||||||
|
options);
|
||||||
|
};
|
||||||
|
|
||||||
|
return exports;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"name": "grpc-protobufjs",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/grpc/grpc-node.git"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/grpc/grpc-node/issues"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"lodash": "^4.17.4",
|
||||||
|
"protobufjs": "~6.8.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,177 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright 2017 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @module
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
|
module.exports = function(grpc) {
|
||||||
|
|
||||||
|
let exports = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a function that deserializes a specific type of protobuf.
|
||||||
|
* @param {function()} cls The constructor of the message type to deserialize
|
||||||
|
* @param {bool=} binaryAsBase64 Deserialize bytes fields as base64 strings
|
||||||
|
* instead of Buffers. Defaults to false
|
||||||
|
* @param {bool=} longsAsStrings Deserialize long values as strings instead of
|
||||||
|
* objects. Defaults to true
|
||||||
|
* @return {function(Buffer):cls} The deserialization function
|
||||||
|
*/
|
||||||
|
exports.deserializeCls = function deserializeCls(cls, options) {
|
||||||
|
/**
|
||||||
|
* Deserialize a buffer to a message object
|
||||||
|
* @param {Buffer} arg_buf The buffer to deserialize
|
||||||
|
* @return {cls} The resulting object
|
||||||
|
*/
|
||||||
|
return function deserialize(arg_buf) {
|
||||||
|
// Convert to a native object with binary fields as Buffers (first argument)
|
||||||
|
// and longs as strings (second argument)
|
||||||
|
return cls.decode(arg_buf).toRaw(options.binaryAsBase64,
|
||||||
|
options.longsAsStrings);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
var deserializeCls = exports.deserializeCls;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a function that serializes objects to a buffer by protobuf class.
|
||||||
|
* @param {function()} Cls The constructor of the message type to serialize
|
||||||
|
* @return {function(Cls):Buffer} The serialization function
|
||||||
|
*/
|
||||||
|
exports.serializeCls = function serializeCls(Cls) {
|
||||||
|
/**
|
||||||
|
* Serialize an object to a Buffer
|
||||||
|
* @param {Object} arg The object to serialize
|
||||||
|
* @return {Buffer} The serialized object
|
||||||
|
*/
|
||||||
|
return function serialize(arg) {
|
||||||
|
return new Buffer(new Cls(arg).encode().toBuffer());
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
var serializeCls = exports.serializeCls;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the fully qualified (dotted) name of a ProtoBuf.Reflect value.
|
||||||
|
* @param {ProtoBuf.Reflect.Namespace} value The value to get the name of
|
||||||
|
* @return {string} The fully qualified name of the value
|
||||||
|
*/
|
||||||
|
exports.fullyQualifiedName = function fullyQualifiedName(value) {
|
||||||
|
if (value === null || value === undefined) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
var name = value.name;
|
||||||
|
var parent_name = fullyQualifiedName(value.parent);
|
||||||
|
if (parent_name !== '') {
|
||||||
|
name = parent_name + '.' + name;
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
};
|
||||||
|
|
||||||
|
var fullyQualifiedName = exports.fullyQualifiedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a map from method names to method attributes for the service.
|
||||||
|
* @param {ProtoBuf.Reflect.Service} service The service to get attributes for
|
||||||
|
* @param {Object=} options Options to apply to these attributes
|
||||||
|
* @return {Object} The attributes map
|
||||||
|
*/
|
||||||
|
exports.getProtobufServiceAttrs = function getProtobufServiceAttrs(service,
|
||||||
|
options) {
|
||||||
|
var prefix = '/' + fullyQualifiedName(service) + '/';
|
||||||
|
var binaryAsBase64, longsAsStrings;
|
||||||
|
if (options) {
|
||||||
|
binaryAsBase64 = options.binaryAsBase64;
|
||||||
|
longsAsStrings = options.longsAsStrings;
|
||||||
|
}
|
||||||
|
/* This slightly awkward construction is used to make sure we only use
|
||||||
|
lodash@3.10.1-compatible functions. A previous version used
|
||||||
|
_.fromPairs, which would be cleaner, but was introduced in lodash
|
||||||
|
version 4 */
|
||||||
|
return _.zipObject(_.map(service.children, function(method) {
|
||||||
|
return _.camelCase(method.name);
|
||||||
|
}), _.map(service.children, function(method) {
|
||||||
|
return {
|
||||||
|
originalName: method.name,
|
||||||
|
path: prefix + method.name,
|
||||||
|
requestStream: method.requestStream,
|
||||||
|
responseStream: method.responseStream,
|
||||||
|
requestType: method.resolvedRequestType,
|
||||||
|
responseType: method.resolvedResponseType,
|
||||||
|
requestSerialize: serializeCls(method.resolvedRequestType.build()),
|
||||||
|
requestDeserialize: deserializeCls(method.resolvedRequestType.build(),
|
||||||
|
options),
|
||||||
|
responseSerialize: serializeCls(method.resolvedResponseType.build()),
|
||||||
|
responseDeserialize: deserializeCls(method.resolvedResponseType.build(),
|
||||||
|
options)
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
var getProtobufServiceAttrs = exports.getProtobufServiceAttrs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a gRPC object from an existing ProtoBuf.Reflect object.
|
||||||
|
* @param {ProtoBuf.Reflect.Namespace} value The ProtoBuf object to load.
|
||||||
|
* @param {Object=} options Options to apply to the loaded object
|
||||||
|
* @return {Object<string, *>} The resulting gRPC object
|
||||||
|
*/
|
||||||
|
exports.loadObject = function loadObject(value, options) {
|
||||||
|
var result = {};
|
||||||
|
if (!value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
if (value.hasOwnProperty('ns')) {
|
||||||
|
return loadObject(value.ns, options);
|
||||||
|
}
|
||||||
|
if (value.className === 'Namespace') {
|
||||||
|
_.each(value.children, function(child) {
|
||||||
|
result[child.name] = loadObject(child, options);
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
} else if (value.className === 'Service') {
|
||||||
|
return grpc.makeGenericClientConstructor(getProtobufServiceAttrs(value, options),
|
||||||
|
options);
|
||||||
|
} else if (value.className === 'Message' || value.className === 'Enum') {
|
||||||
|
return value.build();
|
||||||
|
} else {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The primary purpose of this method is to distinguish between reflection
|
||||||
|
* objects from different versions of ProtoBuf.js. This is just a heuristic,
|
||||||
|
* checking for properties that are (currently) specific to this version of
|
||||||
|
* ProtoBuf.js
|
||||||
|
* @param {Object} obj The object to check
|
||||||
|
* @return {boolean} Whether the object appears to be a Protobuf.js 5
|
||||||
|
* ReflectionObject
|
||||||
|
*/
|
||||||
|
exports.isProbablyProtobufJs5 = function isProbablyProtobufJs5(obj) {
|
||||||
|
return _.isArray(obj.children) && (typeof obj.build === 'function');
|
||||||
|
};
|
||||||
|
|
||||||
|
return exports;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,166 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright 2017 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @module
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
|
module.exports = function(grpc) {
|
||||||
|
|
||||||
|
let exports = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a function that deserializes a specific type of protobuf.
|
||||||
|
* @param {function()} cls The constructor of the message type to deserialize
|
||||||
|
* @param {bool=} binaryAsBase64 Deserialize bytes fields as base64 strings
|
||||||
|
* instead of Buffers. Defaults to false
|
||||||
|
* @param {bool=} longsAsStrings Deserialize long values as strings instead of
|
||||||
|
* objects. Defaults to true
|
||||||
|
* @return {function(Buffer):cls} The deserialization function
|
||||||
|
*/
|
||||||
|
exports.deserializeCls = function deserializeCls(cls, options) {
|
||||||
|
var conversion_options = {
|
||||||
|
defaults: true,
|
||||||
|
bytes: options.binaryAsBase64 ? String : Buffer,
|
||||||
|
longs: options.longsAsStrings ? String : null,
|
||||||
|
enums: options.enumsAsStrings ? String : null,
|
||||||
|
oneofs: true
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Deserialize a buffer to a message object
|
||||||
|
* @param {Buffer} arg_buf The buffer to deserialize
|
||||||
|
* @return {cls} The resulting object
|
||||||
|
*/
|
||||||
|
return function deserialize(arg_buf) {
|
||||||
|
return cls.toObject(cls.decode(arg_buf), conversion_options);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
var deserializeCls = exports.deserializeCls;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a function that serializes objects to a buffer by protobuf class.
|
||||||
|
* @param {function()} Cls The constructor of the message type to serialize
|
||||||
|
* @return {function(Cls):Buffer} The serialization function
|
||||||
|
*/
|
||||||
|
exports.serializeCls = function serializeCls(cls) {
|
||||||
|
/**
|
||||||
|
* Serialize an object to a Buffer
|
||||||
|
* @param {Object} arg The object to serialize
|
||||||
|
* @return {Buffer} The serialized object
|
||||||
|
*/
|
||||||
|
return function serialize(arg) {
|
||||||
|
var message = cls.fromObject(arg);
|
||||||
|
return cls.encode(message).finish();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
var serializeCls = exports.serializeCls;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the fully qualified (dotted) name of a ProtoBuf.Reflect value.
|
||||||
|
* @param {ProtoBuf.ReflectionObject} value The value to get the name of
|
||||||
|
* @return {string} The fully qualified name of the value
|
||||||
|
*/
|
||||||
|
exports.fullyQualifiedName = function fullyQualifiedName(value) {
|
||||||
|
if (value === null || value === undefined) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
var name = value.name;
|
||||||
|
var parent_fqn = fullyQualifiedName(value.parent);
|
||||||
|
if (parent_fqn !== '') {
|
||||||
|
name = parent_fqn + '.' + name;
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
};
|
||||||
|
|
||||||
|
var fullyQualifiedName = exports.fullyQualifiedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a map from method names to method attributes for the service.
|
||||||
|
* @param {ProtoBuf.Service} service The service to get attributes for
|
||||||
|
* @param {Object=} options Options to apply to these attributes
|
||||||
|
* @return {Object} The attributes map
|
||||||
|
*/
|
||||||
|
exports.getProtobufServiceAttrs = function getProtobufServiceAttrs(service,
|
||||||
|
options) {
|
||||||
|
var prefix = '/' + fullyQualifiedName(service) + '/';
|
||||||
|
service.resolveAll();
|
||||||
|
return _.zipObject(_.map(service.methods, function(method) {
|
||||||
|
return _.camelCase(method.name);
|
||||||
|
}), _.map(service.methods, function(method) {
|
||||||
|
return {
|
||||||
|
originalName: method.name,
|
||||||
|
path: prefix + method.name,
|
||||||
|
requestStream: !!method.requestStream,
|
||||||
|
responseStream: !!method.responseStream,
|
||||||
|
requestType: method.resolvedRequestType,
|
||||||
|
responseType: method.resolvedResponseType,
|
||||||
|
requestSerialize: serializeCls(method.resolvedRequestType),
|
||||||
|
requestDeserialize: deserializeCls(method.resolvedRequestType, options),
|
||||||
|
responseSerialize: serializeCls(method.resolvedResponseType),
|
||||||
|
responseDeserialize: deserializeCls(method.resolvedResponseType, options)
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
var getProtobufServiceAttrs = exports.getProtobufServiceAttrs;
|
||||||
|
|
||||||
|
exports.loadObject = function loadObject(value, options) {
|
||||||
|
var result = {};
|
||||||
|
if (!value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
if (value.hasOwnProperty('methods')) {
|
||||||
|
// It's a service object
|
||||||
|
var service_attrs = getProtobufServiceAttrs(value, options);
|
||||||
|
return grpc..makeGenericClientConstructor(service_attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.hasOwnProperty('nested')) {
|
||||||
|
// It's a namespace or root object
|
||||||
|
_.each(value.nested, function(nested, name) {
|
||||||
|
result[name] = loadObject(nested, options);
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, it's not something we need to change
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The primary purpose of this method is to distinguish between reflection
|
||||||
|
* objects from different versions of ProtoBuf.js. This is just a heuristic,
|
||||||
|
* checking for properties that are (currently) specific to this version of
|
||||||
|
* ProtoBuf.js
|
||||||
|
* @param {Object} obj The object to check
|
||||||
|
* @return {boolean} Whether the object appears to be a Protobuf.js 6
|
||||||
|
* ReflectionObject
|
||||||
|
*/
|
||||||
|
exports.isProbablyProtobufJs6 = function isProbablyProtobufJs6(obj) {
|
||||||
|
return (typeof obj.root === 'object') && (typeof obj.resolve === 'function');
|
||||||
|
};
|
||||||
|
|
||||||
|
return exports;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,147 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright 2017 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const util = require(util);
|
||||||
|
|
||||||
|
const _ = require('lodash');
|
||||||
|
|
||||||
|
module.exports = function(grpc) {
|
||||||
|
|
||||||
|
let exports = {};
|
||||||
|
|
||||||
|
const Client = grpc.Client;
|
||||||
|
|
||||||
|
function getDefaultValues(metadata, options) {
|
||||||
|
var res = {};
|
||||||
|
res.metadata = metadata || new grpc.Metadata();
|
||||||
|
res.options = options || {};
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map with wrappers for each type of requester function to make it use the old
|
||||||
|
* argument order with optional arguments after the callback.
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var deprecated_request_wrap = {
|
||||||
|
unary: function(makeUnaryRequest) {
|
||||||
|
return function makeWrappedUnaryRequest(argument, callback,
|
||||||
|
metadata, options) {
|
||||||
|
/* jshint validthis: true */
|
||||||
|
var opt_args = getDefaultValues(metadata, metadata);
|
||||||
|
return makeUnaryRequest.call(this, argument, opt_args.metadata,
|
||||||
|
opt_args.options, callback);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
client_stream: function(makeServerStreamRequest) {
|
||||||
|
return function makeWrappedClientStreamRequest(callback, metadata,
|
||||||
|
options) {
|
||||||
|
/* jshint validthis: true */
|
||||||
|
var opt_args = getDefaultValues(metadata, options);
|
||||||
|
return makeServerStreamRequest.call(this, opt_args.metadata,
|
||||||
|
opt_args.options, callback);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
server_stream: _.identity,
|
||||||
|
bidi: _.identity
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map with short names for each of the requester maker functions. Used in
|
||||||
|
* makeClientConstructor
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
const requester_funcs = {
|
||||||
|
unary: Client.prototype.makeUnaryRequest,
|
||||||
|
server_stream: Client.prototype.makeServerStreamRequest,
|
||||||
|
client_stream: Client.prototype.makeClientStreamRequest,
|
||||||
|
bidi: Client.prototype.makeBidiStreamRequest
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a constructor for a client with the given methods, as specified in
|
||||||
|
* the methods argument. The resulting class will have an instance method for
|
||||||
|
* each method in the service, which is a partial application of one of the
|
||||||
|
* [Client]{@link grpc.Client} request methods, depending on `requestSerialize`
|
||||||
|
* and `responseSerialize`, with the `method`, `serialize`, and `deserialize`
|
||||||
|
* arguments predefined.
|
||||||
|
* @memberof grpc
|
||||||
|
* @alias grpc~makeGenericClientConstructor
|
||||||
|
* @param {grpc~ServiceDefinition} methods An object mapping method names to
|
||||||
|
* method attributes
|
||||||
|
* @param {string} serviceName The fully qualified name of the service
|
||||||
|
* @param {Object} class_options An options object.
|
||||||
|
* @return {function} New client constructor, which is a subclass of
|
||||||
|
* {@link grpc.Client}, and has the same arguments as that constructor.
|
||||||
|
*/
|
||||||
|
exports.makeClientConstructor = function(methods, serviceName,
|
||||||
|
class_options) {
|
||||||
|
if (!class_options) {
|
||||||
|
class_options = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
function ServiceClient(address, credentials, options) {
|
||||||
|
Client.call(this, address, credentials, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
util.inherits(ServiceClient, Client);
|
||||||
|
|
||||||
|
_.each(methods, function(attrs, name) {
|
||||||
|
var method_type;
|
||||||
|
// TODO(murgatroid99): Verify that we don't need this anymore
|
||||||
|
if (_.startsWith(name, '$')) {
|
||||||
|
throw new Error('Method names cannot start with $');
|
||||||
|
}
|
||||||
|
if (attrs.requestStream) {
|
||||||
|
if (attrs.responseStream) {
|
||||||
|
method_type = 'bidi';
|
||||||
|
} else {
|
||||||
|
method_type = 'client_stream';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (attrs.responseStream) {
|
||||||
|
method_type = 'server_stream';
|
||||||
|
} else {
|
||||||
|
method_type = 'unary';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var serialize = attrs.requestSerialize;
|
||||||
|
var deserialize = attrs.responseDeserialize;
|
||||||
|
var method_func = _.partial(requester_funcs[method_type], attrs.path,
|
||||||
|
serialize, deserialize);
|
||||||
|
if (class_options.deprecatedArgumentOrder) {
|
||||||
|
ServiceClient.prototype[name] = deprecated_request_wrap(method_func);
|
||||||
|
} else {
|
||||||
|
ServiceClient.prototype[name] = method_func;
|
||||||
|
}
|
||||||
|
// Associate all provided attributes with the method
|
||||||
|
_.assign(ServiceClient.prototype[name], attrs);
|
||||||
|
if (attrs.originalName) {
|
||||||
|
ServiceClient.prototype[attrs.originalName] = ServiceClient.prototype[name];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ServiceClient.service = methods;
|
||||||
|
|
||||||
|
return ServiceClient;
|
||||||
|
};
|
||||||
|
|
||||||
|
return Object.assign(exports, grpc);
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"name": "grpc-surface",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/grpc/grpc-node.git"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/grpc/grpc-node/issues"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"lodash": "^4.17.4"
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue