diff options
Diffstat (limited to 'src/node')
-rw-r--r-- | src/node/.gitignore | 2 | ||||
-rw-r--r-- | src/node/.jshintignore | 1 | ||||
-rw-r--r-- | src/node/.jshintrc | 28 | ||||
-rw-r--r-- | src/node/ext/node_grpc.cc | 35 | ||||
-rw-r--r-- | src/node/ext/server_credentials.cc | 4 | ||||
-rw-r--r-- | src/node/index.js | 7 | ||||
-rw-r--r-- | src/node/src/client.js | 3 | ||||
-rw-r--r-- | src/node/src/server.js | 34 | ||||
-rw-r--r-- | src/node/test/math/math_grpc_pb.js | 99 | ||||
-rw-r--r-- | src/node/test/math/math_pb.js | 866 | ||||
-rw-r--r-- | src/node/test/math/math_server.js | 40 | ||||
-rw-r--r-- | src/node/test/math/node_modules/grpc.js | 37 | ||||
-rw-r--r-- | src/node/test/math_client_test.js | 45 | ||||
-rw-r--r-- | src/node/test/surface_test.js | 56 | ||||
-rwxr-xr-x | src/node/tools/bin/protoc.js | 4 | ||||
-rwxr-xr-x | src/node/tools/bin/protoc_plugin.js | 56 | ||||
-rw-r--r-- | src/node/tools/package.json | 4 |
17 files changed, 1236 insertions, 85 deletions
diff --git a/src/node/.gitignore b/src/node/.gitignore deleted file mode 100644 index e3fbd98336..0000000000 --- a/src/node/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -node_modules diff --git a/src/node/.jshintignore b/src/node/.jshintignore new file mode 100644 index 0000000000..0a73e1e2b6 --- /dev/null +++ b/src/node/.jshintignore @@ -0,0 +1 @@ +**/*_pb.js
\ No newline at end of file diff --git a/src/node/.jshintrc b/src/node/.jshintrc deleted file mode 100644 index 8237e0d2b6..0000000000 --- a/src/node/.jshintrc +++ /dev/null @@ -1,28 +0,0 @@ -{ - "bitwise": true, - "curly": true, - "eqeqeq": true, - "esnext": true, - "freeze": true, - "immed": true, - "indent": 2, - "latedef": "nofunc", - "maxlen": 80, - "newcap": true, - "node": true, - "noarg": true, - "quotmark": "single", - "strict": true, - "trailing": true, - "undef": true, - "unused": "vars", - "globals": { - /* Mocha-provided globals */ - "describe": false, - "it": false, - "before": false, - "beforeEach": false, - "after": false, - "afterEach": false - } -} diff --git a/src/node/ext/node_grpc.cc b/src/node/ext/node_grpc.cc index b988f29878..6b6e42737b 100644 --- a/src/node/ext/node_grpc.cc +++ b/src/node/ext/node_grpc.cc @@ -35,6 +35,8 @@ #include <nan.h> #include <v8.h> #include "grpc/grpc.h" +#include "grpc/grpc_security.h" +#include "grpc/support/alloc.h" #include "call.h" #include "call_credentials.h" @@ -51,6 +53,8 @@ using v8::Object; using v8::Uint32; using v8::String; +static char *pem_root_certs = NULL; + void InitStatusConstants(Local<Object> exports) { Nan::HandleScope scope; Local<Object> status = Nan::New<Object>(); @@ -268,9 +272,36 @@ NAN_METHOD(MetadataKeyIsBinary) { grpc_is_binary_header(key_str, static_cast<size_t>(key->Length())))); } +static grpc_ssl_roots_override_result get_ssl_roots_override( + char **pem_root_certs_ptr) { + *pem_root_certs_ptr = pem_root_certs; + if (pem_root_certs == NULL) { + return GRPC_SSL_ROOTS_OVERRIDE_FAIL; + } else { + return GRPC_SSL_ROOTS_OVERRIDE_OK; + } +} + +/* This should only be called once, and only before creating any + *ServerCredentials */ +NAN_METHOD(SetDefaultRootsPem) { + if (!info[0]->IsString()) { + return Nan::ThrowTypeError( + "setDefaultRootsPem's argument must be a string"); + } + Nan::Utf8String utf8_roots(info[0]); + size_t length = static_cast<size_t>(utf8_roots.length()); + if (length > 0) { + const char *data = *utf8_roots; + pem_root_certs = (char *)gpr_malloc((length + 1) * sizeof(char)); + memcpy(pem_root_certs, data, length + 1); + } +} + void init(Local<Object> exports) { Nan::HandleScope scope; grpc_init(); + grpc_set_ssl_roots_override_callback(get_ssl_roots_override); InitStatusConstants(exports); InitCallErrorConstants(exports); InitOpTypeConstants(exports); @@ -298,6 +329,10 @@ void init(Local<Object> exports) { Nan::GetFunction( Nan::New<FunctionTemplate>(MetadataKeyIsBinary) ).ToLocalChecked()); + Nan::Set(exports, Nan::New("setDefaultRootsPem").ToLocalChecked(), + Nan::GetFunction( + Nan::New<FunctionTemplate>(SetDefaultRootsPem) + ).ToLocalChecked()); } NODE_MODULE(grpc_node, init) diff --git a/src/node/ext/server_credentials.cc b/src/node/ext/server_credentials.cc index cff821aafc..a817ade518 100644 --- a/src/node/ext/server_credentials.cc +++ b/src/node/ext/server_credentials.cc @@ -146,7 +146,9 @@ NAN_METHOD(ServerCredentials::CreateSsl) { "createSsl's second argument must be a list of objects"); } - grpc_ssl_client_certificate_request_type client_certificate_request; + // Default to not requesting the client certificate + grpc_ssl_client_certificate_request_type client_certificate_request = + GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE; if (info[2]->IsBoolean()) { client_certificate_request = Nan::To<bool>(info[2]).FromJust() diff --git a/src/node/index.js b/src/node/index.js index d345a5142d..66664d94b5 100644 --- a/src/node/index.js +++ b/src/node/index.js @@ -34,13 +34,10 @@ 'use strict'; var path = require('path'); +var fs = require('fs'); var SSL_ROOTS_PATH = path.resolve(__dirname, '..', '..', 'etc', 'roots.pem'); -if (!process.env.GRPC_DEFAULT_SSL_ROOTS_FILE_PATH) { - process.env.GRPC_DEFAULT_SSL_ROOTS_FILE_PATH = SSL_ROOTS_PATH; -} - var _ = require('lodash'); var ProtoBuf = require('protobufjs'); @@ -53,6 +50,8 @@ var Metadata = require('./src/metadata.js'); var grpc = require('./src/grpc_extension'); +grpc.setDefaultRootsPem(fs.readFileSync(SSL_ROOTS_PATH, 'ascii')); + /** * Load a gRPC object from an existing ProtoBuf.Reflect object. * @param {ProtoBuf.Reflect.Namespace} value The ProtoBuf object to load. diff --git a/src/node/src/client.js b/src/node/src/client.js index 5e07046fc6..f75f951eb8 100644 --- a/src/node/src/client.js +++ b/src/node/src/client.js @@ -815,8 +815,7 @@ exports.waitForClientReady = function(client, deadline, callback) { * @return {function(string, Object)} New client constructor */ exports.makeProtobufClientConstructor = function(service, options) { - var method_attrs = common.getProtobufServiceAttrs(service, service.name, - options); + var method_attrs = common.getProtobufServiceAttrs(service, options); var deprecatedArgumentOrder = false; if (options) { deprecatedArgumentOrder = options.deprecatedArgumentOrder; diff --git a/src/node/src/server.js b/src/node/src/server.js index 22128343a9..fd5153f124 100644 --- a/src/node/src/server.js +++ b/src/node/src/server.js @@ -684,6 +684,26 @@ Server.prototype.register = function(name, handler, serialize, deserialize, return true; }; +var unimplementedStatusResponse = { + code: grpc.status.UNIMPLEMENTED, + details: 'The server does not implement this method' +}; + +var defaultHandler = { + unary: function(call, callback) { + callback(unimplementedStatusResponse); + }, + client_stream: function(call, callback) { + callback(unimplementedStatusResponse); + }, + server_stream: function(call) { + call.emit('error', unimplementedStatusResponse); + }, + bidi: function(call) { + call.emit('error', unimplementedStatusResponse); + } +}; + /** * Add a service to the server, with a corresponding implementation. If you are * generating this from a proto file, you should instead use @@ -713,16 +733,18 @@ Server.prototype.addService = function(service, implementation) { method_type = 'unary'; } } + var impl; if (implementation[name] === undefined) { - throw new Error('Method handler for ' + attrs.path + - ' not provided.'); + console.warn('Method handler for %s expected but not provided', + attrs.path); + impl = defaultHandler[method_type]; + } else { + impl = _.bind(implementation[name], implementation); } var serialize = attrs.responseSerialize; var deserialize = attrs.requestDeserialize; - var register_success = self.register(attrs.path, - _.bind(implementation[name], - implementation), - serialize, deserialize, method_type); + var register_success = self.register(attrs.path, impl, serialize, + deserialize, method_type); if (!register_success) { throw new Error('Method handler for ' + attrs.path + ' already provided.'); diff --git a/src/node/test/math/math_grpc_pb.js b/src/node/test/math/math_grpc_pb.js new file mode 100644 index 0000000000..083ed66913 --- /dev/null +++ b/src/node/test/math/math_grpc_pb.js @@ -0,0 +1,99 @@ +// GENERATED CODE -- DO NOT EDIT! + +'use strict'; +var grpc = require('grpc'); +var math_pb = require('./math_pb.js'); + +function serialize_DivArgs(arg) { + if (!(arg instanceof math_pb.DivArgs)) { + throw new Error('Expected argument of type DivArgs'); + } + return new Buffer(arg.serializeBinary()); +} + +function deserialize_DivArgs(buffer_arg) { + return math_pb.DivArgs.deserializeBinary(new Uint8Array(buffer_arg)); +} + +function serialize_DivReply(arg) { + if (!(arg instanceof math_pb.DivReply)) { + throw new Error('Expected argument of type DivReply'); + } + return new Buffer(arg.serializeBinary()); +} + +function deserialize_DivReply(buffer_arg) { + return math_pb.DivReply.deserializeBinary(new Uint8Array(buffer_arg)); +} + +function serialize_FibArgs(arg) { + if (!(arg instanceof math_pb.FibArgs)) { + throw new Error('Expected argument of type FibArgs'); + } + return new Buffer(arg.serializeBinary()); +} + +function deserialize_FibArgs(buffer_arg) { + return math_pb.FibArgs.deserializeBinary(new Uint8Array(buffer_arg)); +} + +function serialize_Num(arg) { + if (!(arg instanceof math_pb.Num)) { + throw new Error('Expected argument of type Num'); + } + return new Buffer(arg.serializeBinary()); +} + +function deserialize_Num(buffer_arg) { + return math_pb.Num.deserializeBinary(new Uint8Array(buffer_arg)); +} + + +var MathService = exports.MathService = { + div: { + path: '/math.Math/Div', + requestStream: false, + responseStream: false, + requestType: math_pb.DivArgs, + responseType: math_pb.DivReply, + requestSerialize: serialize_DivArgs, + requestDeserialize: deserialize_DivArgs, + responseSerialize: serialize_DivReply, + responseDeserialize: deserialize_DivReply, + }, + divMany: { + path: '/math.Math/DivMany', + requestStream: true, + responseStream: true, + requestType: math_pb.DivArgs, + responseType: math_pb.DivReply, + requestSerialize: serialize_DivArgs, + requestDeserialize: deserialize_DivArgs, + responseSerialize: serialize_DivReply, + responseDeserialize: deserialize_DivReply, + }, + fib: { + path: '/math.Math/Fib', + requestStream: false, + responseStream: true, + requestType: math_pb.FibArgs, + responseType: math_pb.Num, + requestSerialize: serialize_FibArgs, + requestDeserialize: deserialize_FibArgs, + responseSerialize: serialize_Num, + responseDeserialize: deserialize_Num, + }, + sum: { + path: '/math.Math/Sum', + requestStream: true, + responseStream: false, + requestType: math_pb.Num, + responseType: math_pb.Num, + requestSerialize: serialize_Num, + requestDeserialize: deserialize_Num, + responseSerialize: serialize_Num, + responseDeserialize: deserialize_Num, + }, +}; + +exports.MathClient = grpc.makeGenericClientConstructor(MathService); diff --git a/src/node/test/math/math_pb.js b/src/node/test/math/math_pb.js new file mode 100644 index 0000000000..3489143bec --- /dev/null +++ b/src/node/test/math/math_pb.js @@ -0,0 +1,866 @@ +/** + * @fileoverview + * @enhanceable + * @public + */ +// GENERATED CODE -- DO NOT EDIT! + +var jspb = require('google-protobuf'); +var goog = jspb; +var global = Function('return this')(); + +goog.exportSymbol('proto.math.DivArgs', null, global); +goog.exportSymbol('proto.math.DivReply', null, global); +goog.exportSymbol('proto.math.FibArgs', null, global); +goog.exportSymbol('proto.math.FibReply', null, global); +goog.exportSymbol('proto.math.Num', null, global); + +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.math.DivArgs = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.math.DivArgs, jspb.Message); +if (goog.DEBUG && !COMPILED) { + proto.math.DivArgs.displayName = 'proto.math.DivArgs'; +} + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto suitable for use in Soy templates. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. + * @param {boolean=} opt_includeInstance Whether to include the JSPB instance + * for transitional soy proto support: http://goto/soy-param-migration + * @return {!Object} + */ +proto.math.DivArgs.prototype.toObject = function(opt_includeInstance) { + return proto.math.DivArgs.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Whether to include the JSPB + * instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.math.DivArgs} msg The msg instance to transform. + * @return {!Object} + */ +proto.math.DivArgs.toObject = function(includeInstance, msg) { + var f, obj = { + dividend: msg.getDividend(), + divisor: msg.getDivisor() + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.math.DivArgs} + */ +proto.math.DivArgs.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.math.DivArgs; + return proto.math.DivArgs.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.math.DivArgs} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.math.DivArgs} + */ +proto.math.DivArgs.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {number} */ (reader.readInt64()); + msg.setDividend(value); + break; + case 2: + var value = /** @type {number} */ (reader.readInt64()); + msg.setDivisor(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Class method variant: serializes the given message to binary data + * (in protobuf wire format), writing to the given BinaryWriter. + * @param {!proto.math.DivArgs} message + * @param {!jspb.BinaryWriter} writer + */ +proto.math.DivArgs.serializeBinaryToWriter = function(message, writer) { + message.serializeBinaryToWriter(writer); +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.math.DivArgs.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + this.serializeBinaryToWriter(writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the message to binary data (in protobuf wire format), + * writing to the given BinaryWriter. + * @param {!jspb.BinaryWriter} writer + */ +proto.math.DivArgs.prototype.serializeBinaryToWriter = function (writer) { + var f = undefined; + f = this.getDividend(); + if (f !== 0) { + writer.writeInt64( + 1, + f + ); + } + f = this.getDivisor(); + if (f !== 0) { + writer.writeInt64( + 2, + f + ); + } +}; + + +/** + * Creates a deep clone of this proto. No data is shared with the original. + * @return {!proto.math.DivArgs} The clone. + */ +proto.math.DivArgs.prototype.cloneMessage = function() { + return /** @type {!proto.math.DivArgs} */ (jspb.Message.cloneMessage(this)); +}; + + +/** + * optional int64 dividend = 1; + * @return {number} + */ +proto.math.DivArgs.prototype.getDividend = function() { + return /** @type {number} */ (jspb.Message.getFieldProto3(this, 1, 0)); +}; + + +/** @param {number} value */ +proto.math.DivArgs.prototype.setDividend = function(value) { + jspb.Message.setField(this, 1, value); +}; + + +/** + * optional int64 divisor = 2; + * @return {number} + */ +proto.math.DivArgs.prototype.getDivisor = function() { + return /** @type {number} */ (jspb.Message.getFieldProto3(this, 2, 0)); +}; + + +/** @param {number} value */ +proto.math.DivArgs.prototype.setDivisor = function(value) { + jspb.Message.setField(this, 2, value); +}; + + + +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.math.DivReply = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.math.DivReply, jspb.Message); +if (goog.DEBUG && !COMPILED) { + proto.math.DivReply.displayName = 'proto.math.DivReply'; +} + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto suitable for use in Soy templates. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. + * @param {boolean=} opt_includeInstance Whether to include the JSPB instance + * for transitional soy proto support: http://goto/soy-param-migration + * @return {!Object} + */ +proto.math.DivReply.prototype.toObject = function(opt_includeInstance) { + return proto.math.DivReply.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Whether to include the JSPB + * instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.math.DivReply} msg The msg instance to transform. + * @return {!Object} + */ +proto.math.DivReply.toObject = function(includeInstance, msg) { + var f, obj = { + quotient: msg.getQuotient(), + remainder: msg.getRemainder() + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.math.DivReply} + */ +proto.math.DivReply.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.math.DivReply; + return proto.math.DivReply.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.math.DivReply} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.math.DivReply} + */ +proto.math.DivReply.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {number} */ (reader.readInt64()); + msg.setQuotient(value); + break; + case 2: + var value = /** @type {number} */ (reader.readInt64()); + msg.setRemainder(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Class method variant: serializes the given message to binary data + * (in protobuf wire format), writing to the given BinaryWriter. + * @param {!proto.math.DivReply} message + * @param {!jspb.BinaryWriter} writer + */ +proto.math.DivReply.serializeBinaryToWriter = function(message, writer) { + message.serializeBinaryToWriter(writer); +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.math.DivReply.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + this.serializeBinaryToWriter(writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the message to binary data (in protobuf wire format), + * writing to the given BinaryWriter. + * @param {!jspb.BinaryWriter} writer + */ +proto.math.DivReply.prototype.serializeBinaryToWriter = function (writer) { + var f = undefined; + f = this.getQuotient(); + if (f !== 0) { + writer.writeInt64( + 1, + f + ); + } + f = this.getRemainder(); + if (f !== 0) { + writer.writeInt64( + 2, + f + ); + } +}; + + +/** + * Creates a deep clone of this proto. No data is shared with the original. + * @return {!proto.math.DivReply} The clone. + */ +proto.math.DivReply.prototype.cloneMessage = function() { + return /** @type {!proto.math.DivReply} */ (jspb.Message.cloneMessage(this)); +}; + + +/** + * optional int64 quotient = 1; + * @return {number} + */ +proto.math.DivReply.prototype.getQuotient = function() { + return /** @type {number} */ (jspb.Message.getFieldProto3(this, 1, 0)); +}; + + +/** @param {number} value */ +proto.math.DivReply.prototype.setQuotient = function(value) { + jspb.Message.setField(this, 1, value); +}; + + +/** + * optional int64 remainder = 2; + * @return {number} + */ +proto.math.DivReply.prototype.getRemainder = function() { + return /** @type {number} */ (jspb.Message.getFieldProto3(this, 2, 0)); +}; + + +/** @param {number} value */ +proto.math.DivReply.prototype.setRemainder = function(value) { + jspb.Message.setField(this, 2, value); +}; + + + +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.math.FibArgs = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.math.FibArgs, jspb.Message); +if (goog.DEBUG && !COMPILED) { + proto.math.FibArgs.displayName = 'proto.math.FibArgs'; +} + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto suitable for use in Soy templates. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. + * @param {boolean=} opt_includeInstance Whether to include the JSPB instance + * for transitional soy proto support: http://goto/soy-param-migration + * @return {!Object} + */ +proto.math.FibArgs.prototype.toObject = function(opt_includeInstance) { + return proto.math.FibArgs.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Whether to include the JSPB + * instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.math.FibArgs} msg The msg instance to transform. + * @return {!Object} + */ +proto.math.FibArgs.toObject = function(includeInstance, msg) { + var f, obj = { + limit: msg.getLimit() + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.math.FibArgs} + */ +proto.math.FibArgs.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.math.FibArgs; + return proto.math.FibArgs.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.math.FibArgs} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.math.FibArgs} + */ +proto.math.FibArgs.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {number} */ (reader.readInt64()); + msg.setLimit(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Class method variant: serializes the given message to binary data + * (in protobuf wire format), writing to the given BinaryWriter. + * @param {!proto.math.FibArgs} message + * @param {!jspb.BinaryWriter} writer + */ +proto.math.FibArgs.serializeBinaryToWriter = function(message, writer) { + message.serializeBinaryToWriter(writer); +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.math.FibArgs.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + this.serializeBinaryToWriter(writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the message to binary data (in protobuf wire format), + * writing to the given BinaryWriter. + * @param {!jspb.BinaryWriter} writer + */ +proto.math.FibArgs.prototype.serializeBinaryToWriter = function (writer) { + var f = undefined; + f = this.getLimit(); + if (f !== 0) { + writer.writeInt64( + 1, + f + ); + } +}; + + +/** + * Creates a deep clone of this proto. No data is shared with the original. + * @return {!proto.math.FibArgs} The clone. + */ +proto.math.FibArgs.prototype.cloneMessage = function() { + return /** @type {!proto.math.FibArgs} */ (jspb.Message.cloneMessage(this)); +}; + + +/** + * optional int64 limit = 1; + * @return {number} + */ +proto.math.FibArgs.prototype.getLimit = function() { + return /** @type {number} */ (jspb.Message.getFieldProto3(this, 1, 0)); +}; + + +/** @param {number} value */ +proto.math.FibArgs.prototype.setLimit = function(value) { + jspb.Message.setField(this, 1, value); +}; + + + +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.math.Num = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.math.Num, jspb.Message); +if (goog.DEBUG && !COMPILED) { + proto.math.Num.displayName = 'proto.math.Num'; +} + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto suitable for use in Soy templates. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. + * @param {boolean=} opt_includeInstance Whether to include the JSPB instance + * for transitional soy proto support: http://goto/soy-param-migration + * @return {!Object} + */ +proto.math.Num.prototype.toObject = function(opt_includeInstance) { + return proto.math.Num.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Whether to include the JSPB + * instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.math.Num} msg The msg instance to transform. + * @return {!Object} + */ +proto.math.Num.toObject = function(includeInstance, msg) { + var f, obj = { + num: msg.getNum() + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.math.Num} + */ +proto.math.Num.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.math.Num; + return proto.math.Num.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.math.Num} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.math.Num} + */ +proto.math.Num.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {number} */ (reader.readInt64()); + msg.setNum(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Class method variant: serializes the given message to binary data + * (in protobuf wire format), writing to the given BinaryWriter. + * @param {!proto.math.Num} message + * @param {!jspb.BinaryWriter} writer + */ +proto.math.Num.serializeBinaryToWriter = function(message, writer) { + message.serializeBinaryToWriter(writer); +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.math.Num.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + this.serializeBinaryToWriter(writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the message to binary data (in protobuf wire format), + * writing to the given BinaryWriter. + * @param {!jspb.BinaryWriter} writer + */ +proto.math.Num.prototype.serializeBinaryToWriter = function (writer) { + var f = undefined; + f = this.getNum(); + if (f !== 0) { + writer.writeInt64( + 1, + f + ); + } +}; + + +/** + * Creates a deep clone of this proto. No data is shared with the original. + * @return {!proto.math.Num} The clone. + */ +proto.math.Num.prototype.cloneMessage = function() { + return /** @type {!proto.math.Num} */ (jspb.Message.cloneMessage(this)); +}; + + +/** + * optional int64 num = 1; + * @return {number} + */ +proto.math.Num.prototype.getNum = function() { + return /** @type {number} */ (jspb.Message.getFieldProto3(this, 1, 0)); +}; + + +/** @param {number} value */ +proto.math.Num.prototype.setNum = function(value) { + jspb.Message.setField(this, 1, value); +}; + + + +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.math.FibReply = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.math.FibReply, jspb.Message); +if (goog.DEBUG && !COMPILED) { + proto.math.FibReply.displayName = 'proto.math.FibReply'; +} + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto suitable for use in Soy templates. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. + * @param {boolean=} opt_includeInstance Whether to include the JSPB instance + * for transitional soy proto support: http://goto/soy-param-migration + * @return {!Object} + */ +proto.math.FibReply.prototype.toObject = function(opt_includeInstance) { + return proto.math.FibReply.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Whether to include the JSPB + * instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.math.FibReply} msg The msg instance to transform. + * @return {!Object} + */ +proto.math.FibReply.toObject = function(includeInstance, msg) { + var f, obj = { + count: msg.getCount() + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.math.FibReply} + */ +proto.math.FibReply.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.math.FibReply; + return proto.math.FibReply.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.math.FibReply} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.math.FibReply} + */ +proto.math.FibReply.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {number} */ (reader.readInt64()); + msg.setCount(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Class method variant: serializes the given message to binary data + * (in protobuf wire format), writing to the given BinaryWriter. + * @param {!proto.math.FibReply} message + * @param {!jspb.BinaryWriter} writer + */ +proto.math.FibReply.serializeBinaryToWriter = function(message, writer) { + message.serializeBinaryToWriter(writer); +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.math.FibReply.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + this.serializeBinaryToWriter(writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the message to binary data (in protobuf wire format), + * writing to the given BinaryWriter. + * @param {!jspb.BinaryWriter} writer + */ +proto.math.FibReply.prototype.serializeBinaryToWriter = function (writer) { + var f = undefined; + f = this.getCount(); + if (f !== 0) { + writer.writeInt64( + 1, + f + ); + } +}; + + +/** + * Creates a deep clone of this proto. No data is shared with the original. + * @return {!proto.math.FibReply} The clone. + */ +proto.math.FibReply.prototype.cloneMessage = function() { + return /** @type {!proto.math.FibReply} */ (jspb.Message.cloneMessage(this)); +}; + + +/** + * optional int64 count = 1; + * @return {number} + */ +proto.math.FibReply.prototype.getCount = function() { + return /** @type {number} */ (jspb.Message.getFieldProto3(this, 1, 0)); +}; + + +/** @param {number} value */ +proto.math.FibReply.prototype.setCount = function(value) { + jspb.Message.setField(this, 1, value); +}; + + +goog.object.extend(exports, proto.math); diff --git a/src/node/test/math/math_server.js b/src/node/test/math/math_server.js index 9f67c52ab0..fa05ed0165 100644 --- a/src/node/test/math/math_server.js +++ b/src/node/test/math/math_server.js @@ -34,8 +34,8 @@ 'use strict'; var grpc = require('../..'); -var math = grpc.load(__dirname + '/../../../proto/math/math.proto').math; - +var grpcMath = require('./math_grpc_pb'); +var math = require('./math_pb'); /** * Server function for division. Provides the /Math/DivMany and /Math/Div @@ -46,14 +46,16 @@ var math = grpc.load(__dirname + '/../../../proto/math/math.proto').math; */ function mathDiv(call, cb) { var req = call.request; + var divisor = req.getDivisor(); + var dividend = req.getDividend(); // Unary + is explicit coersion to integer - if (+req.divisor === 0) { + if (req.getDivisor() === 0) { cb(new Error('cannot divide by zero')); } else { - cb(null, { - quotient: req.dividend / req.divisor, - remainder: req.dividend % req.divisor - }); + var response = new math.DivReply(); + response.setQuotient(Math.floor(dividend / divisor)); + response.setRemainder(dividend % divisor); + cb(null, response); } } @@ -67,7 +69,9 @@ function mathFib(stream) { // Here, call is a standard writable Node object Stream var previous = 0, current = 1; for (var i = 0; i < stream.request.limit; i++) { - stream.write({num: current}); + var response = new math.Num(); + response.setNum(current); + stream.write(response); var temp = current; current += previous; previous = temp; @@ -85,22 +89,26 @@ function mathSum(call, cb) { // Here, call is a standard readable Node object Stream var sum = 0; call.on('data', function(data) { - sum += (+data.num); + sum += data.getNum(); }); call.on('end', function() { - cb(null, {num: sum}); + var response = new math.Num(); + response.setNum(sum); + cb(null, response); }); } function mathDivMany(stream) { stream.on('data', function(div_args) { - if (+div_args.divisor === 0) { + var divisor = div_args.getDivisor(); + var dividend = div_args.getDividend(); + if (divisor === 0) { stream.emit('error', new Error('cannot divide by zero')); } else { - stream.write({ - quotient: div_args.dividend / div_args.divisor, - remainder: div_args.dividend % div_args.divisor - }); + var response = new math.DivReply(); + response.setQuotient(Math.floor(dividend / divisor)); + response.setRemainder(dividend % divisor); + stream.write(response); } }); stream.on('end', function() { @@ -110,7 +118,7 @@ function mathDivMany(stream) { function getMathServer() { var server = new grpc.Server(); - server.addProtoService(math.Math.service, { + server.addService(grpcMath.MathService, { div: mathDiv, fib: mathFib, sum: mathSum, diff --git a/src/node/test/math/node_modules/grpc.js b/src/node/test/math/node_modules/grpc.js new file mode 100644 index 0000000000..17c8fd96d9 --- /dev/null +++ b/src/node/test/math/node_modules/grpc.js @@ -0,0 +1,37 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* This exists solely to allow the generated code to import the grpc module + * without using a relative path */ + +module.exports = require('../../..'); diff --git a/src/node/test/math_client_test.js b/src/node/test/math_client_test.js index 3d44610536..34c16e070b 100644 --- a/src/node/test/math_client_test.js +++ b/src/node/test/math_client_test.js @@ -36,7 +36,8 @@ var assert = require('assert'); var grpc = require('..'); -var math = grpc.load(__dirname + '/../../proto/math/math.proto').math; +var math = require('./math/math_pb'); +var MathClient = require('./math/math_grpc_pb').MathClient; /** * Client to use to make requests to a running server. @@ -55,35 +56,41 @@ describe('Math client', function() { var port_num = server.bind('0.0.0.0:0', grpc.ServerCredentials.createInsecure()); server.start(); - math_client = new math.Math('localhost:' + port_num, - grpc.credentials.createInsecure()); + math_client = new MathClient('localhost:' + port_num, + grpc.credentials.createInsecure()); done(); }); after(function() { server.forceShutdown(); }); it('should handle a single request', function(done) { - var arg = {dividend: 7, divisor: 4}; + var arg = new math.DivArgs(); + arg.setDividend(7); + arg.setDivisor(4); math_client.div(arg, function handleDivResult(err, value) { assert.ifError(err); - assert.equal(value.quotient, 1); - assert.equal(value.remainder, 3); + assert.equal(value.getQuotient(), 1); + assert.equal(value.getRemainder(), 3); done(); }); }); it('should handle an error from a unary request', function(done) { - var arg = {dividend: 7, divisor: 0}; + var arg = new math.DivArgs(); + arg.setDividend(7); + arg.setDivisor(0); math_client.div(arg, function handleDivResult(err, value) { assert(err); done(); }); }); it('should handle a server streaming request', function(done) { - var call = math_client.fib({limit: 7}); + var arg = new math.FibArgs(); + arg.setLimit(7); + var call = math_client.fib(arg); var expected_results = [1, 1, 2, 3, 5, 8, 13]; var next_expected = 0; call.on('data', function checkResponse(value) { - assert.equal(value.num, expected_results[next_expected]); + assert.equal(value.getNum(), expected_results[next_expected]); next_expected += 1; }); call.on('status', function checkStatus(status) { @@ -94,10 +101,12 @@ describe('Math client', function() { it('should handle a client streaming request', function(done) { var call = math_client.sum(function handleSumResult(err, value) { assert.ifError(err); - assert.equal(value.num, 21); + assert.equal(value.getNum(), 21); }); for (var i = 0; i < 7; i++) { - call.write({'num': i}); + var arg = new math.Num(); + arg.setNum(i); + call.write(arg); } call.end(); call.on('status', function checkStatus(status) { @@ -107,8 +116,8 @@ describe('Math client', function() { }); it('should handle a bidirectional streaming request', function(done) { function checkResponse(index, value) { - assert.equal(value.quotient, index); - assert.equal(value.remainder, 1); + assert.equal(value.getQuotient(), index); + assert.equal(value.getRemainder(), 1); } var call = math_client.divMany(); var response_index = 0; @@ -117,7 +126,10 @@ describe('Math client', function() { response_index += 1; }); for (var i = 0; i < 7; i++) { - call.write({dividend: 2 * i + 1, divisor: 2}); + var arg = new math.DivArgs(); + arg.setDividend(2 * i + 1); + arg.setDivisor(2); + call.write(arg); } call.end(); call.on('status', function checkStatus(status) { @@ -131,7 +143,10 @@ describe('Math client', function() { assert.fail(value, undefined, 'Unexpected data response on failing call', '!='); }); - call.write({dividend: 7, divisor: 0}); + var arg = new math.DivArgs(); + arg.setDividend(7); + arg.setDivisor(0); + call.write(arg); call.end(); call.on('error', function checkStatus(status) { done(); diff --git a/src/node/test/surface_test.js b/src/node/test/surface_test.js index b96e8e487c..d8b36dc55c 100644 --- a/src/node/test/surface_test.js +++ b/src/node/test/surface_test.js @@ -143,21 +143,59 @@ describe('Server.prototype.addProtoService', function() { server.addProtoService(mathService, dummyImpls); }); }); - it('Should fail with missing handlers', function() { - assert.throws(function() { - server.addProtoService(mathService, { - 'div': function() {}, - 'divMany': function() {}, - 'fib': function() {} - }); - }, /math.Math.Sum/); - }); it('Should fail if the server has been started', function() { server.start(); assert.throws(function() { server.addProtoService(mathService, dummyImpls); }); }); + describe('Default handlers', function() { + var client; + beforeEach(function() { + server.addProtoService(mathService, {}); + var port = server.bind('localhost:0', server_insecure_creds); + var Client = surface_client.makeProtobufClientConstructor(mathService); + client = new Client('localhost:' + port, + grpc.credentials.createInsecure()); + server.start(); + }); + it('should respond to a unary call with UNIMPLEMENTED', function(done) { + client.div({divisor: 4, dividend: 3}, function(error, response) { + assert(error); + assert.strictEqual(error.code, grpc.status.UNIMPLEMENTED); + done(); + }); + }); + it('should respond to a client stream with UNIMPLEMENTED', function(done) { + var call = client.sum(function(error, respones) { + assert(error); + assert.strictEqual(error.code, grpc.status.UNIMPLEMENTED); + done(); + }); + call.end(); + }); + it('should respond to a server stream with UNIMPLEMENTED', function(done) { + var call = client.fib({limit: 5}); + call.on('data', function(value) { + assert.fail('No messages expected'); + }); + call.on('status', function(status) { + assert.strictEqual(status.code, grpc.status.UNIMPLEMENTED); + done(); + }); + }); + it('should respond to a bidi call with UNIMPLEMENTED', function(done) { + var call = client.divMany(); + call.on('data', function(value) { + assert.fail('No messages expected'); + }); + call.on('status', function(status) { + assert.strictEqual(status.code, grpc.status.UNIMPLEMENTED); + done(); + }); + call.end(); + }); + }); }); describe('Client constructor building', function() { var illegal_service_attrs = { diff --git a/src/node/tools/bin/protoc.js b/src/node/tools/bin/protoc.js index 0c6d7ce017..4d50c94b0f 100755 --- a/src/node/tools/bin/protoc.js +++ b/src/node/tools/bin/protoc.js @@ -43,7 +43,9 @@ var path = require('path'); var execFile = require('child_process').execFile; -var protoc = path.resolve(__dirname, 'protoc'); +var exe_ext = process.platform === 'win32' ? '.exe' : ''; + +var protoc = path.resolve(__dirname, 'protoc' + exe_ext); execFile(protoc, process.argv.slice(2), function(error, stdout, stderr) { if (error) { diff --git a/src/node/tools/bin/protoc_plugin.js b/src/node/tools/bin/protoc_plugin.js new file mode 100755 index 0000000000..281ec0d85e --- /dev/null +++ b/src/node/tools/bin/protoc_plugin.js @@ -0,0 +1,56 @@ +#!/usr/bin/env node +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/** + * This file is required because package.json cannot reference a file that + * is not distributed with the package, and we use node-pre-gyp to distribute + * the plugin binary + */ + +'use strict'; + +var path = require('path'); +var execFile = require('child_process').execFile; + +var exe_ext = process.platform === 'win32' ? '.exe' : ''; + +var plugin = path.resolve(__dirname, 'grpc_node_plugin' + exe_ext); + +execFile(plugin, process.argv.slice(2), function(error, stdout, stderr) { + if (error) { + throw error; + } + console.log(stdout); + console.log(stderr); +}); diff --git a/src/node/tools/package.json b/src/node/tools/package.json index 4b3499f2f9..d98ed0b1fc 100644 --- a/src/node/tools/package.json +++ b/src/node/tools/package.json @@ -16,7 +16,8 @@ } ], "bin": { - "grpc-tools-protoc": "./bin/protoc.js" + "grpc-tools-protoc": "./bin/protoc.js", + "grpc-tools-plugin": "./bin/protoc_plugin.js" }, "scripts": { "install": "./node_modules/.bin/node-pre-gyp install" @@ -32,6 +33,7 @@ "files": [ "index.js", "bin/protoc.js", + "bin/protoc_plugin.js", "LICENSE" ], "main": "index.js" |