├── .gitignore ├── LICENSE ├── README.md ├── example ├── README.md ├── grpc │ ├── bash │ │ ├── build.sh │ │ └── server.sh │ ├── build │ │ ├── proto │ │ │ ├── Example_grpc_pb.d.ts │ │ │ ├── Example_grpc_pb.js │ │ │ ├── Example_pb.d.ts │ │ │ └── Example_pb.js │ │ ├── server.d.ts │ │ ├── server.js │ │ └── server.js.map │ ├── package.json │ ├── proto │ │ └── Example.proto │ ├── src │ │ ├── proto │ │ │ ├── Example_grpc_pb.d.ts │ │ │ ├── Example_grpc_pb.js │ │ │ ├── Example_pb.d.ts │ │ │ └── Example_pb.js │ │ └── server.ts │ ├── tsconfig.json │ ├── tslint.json │ └── yarn.lock ├── index.js ├── package-lock.json ├── package.json ├── schema.graphql └── yarn.lock ├── grpcgraphql.png ├── lib ├── index.d.ts ├── index.js ├── index.js.map ├── protobuf.d.ts ├── protobuf.js ├── protobuf.js.map ├── service_converter.d.ts ├── service_converter.js ├── service_converter.js.map ├── subscription.d.ts ├── subscription.js ├── subscription.js.map ├── type_converter.d.ts ├── type_converter.js ├── type_converter.js.map ├── types.d.ts ├── types.js └── types.js.map ├── package-lock.json ├── package.json ├── src ├── index.ts ├── protobuf.ts ├── service_converter.ts ├── subscription.ts ├── type_converter.ts ├── types.ts └── typings.d.ts ├── tsconfig.json ├── tslint.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | 63 | .DS_Store -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Xanthous Tech 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Grpc Graphql Schema 2 | 3 |

4 | 5 |

6 | 7 | Convert gRPC proto Definition into GraphQL Schema 8 | 9 | [Slides @ GraphQL BKK 4.0](https://docs.google.com/presentation/d/11sw3yK7p6xYcES9Wsjco7z3lGgmYlefnNrqhZ6vaYvA/edit?usp=sharing) 10 | 11 | [Medium Article](https://medium.com/xanthous/translating-grpc-services-into-graphql-6a8e49556d96) 12 | 13 | # How to Use 14 | 15 | ```javascript 16 | const { getGraphqlSchemaFromGrpc } = require('grpc-graphql-schema'); 17 | 18 | getGraphqlSchemaFromGrpc({ 19 | endpoint: 'localhost:50051', 20 | protoFilePath: '/path/to/ServiceDefinition.proto', 21 | serviceName: 'GrpcServiceName', 22 | packageName: 'name.package', 23 | }).then(schema => { 24 | // load schema in graphql server 25 | }); 26 | ``` 27 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # How to Run this Demo 2 | 3 | ``` 4 | # start the gRPC server 5 | cd grpc 6 | npm install 7 | npm start 8 | 9 | # start the GraphQL server 10 | cd .. 11 | npm install 12 | npm start 13 | ``` -------------------------------------------------------------------------------- /example/grpc/bash/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | BASEDIR=$(dirname "$0") 4 | cd ${BASEDIR}/../ 5 | 6 | PROTO_DEST=./src/proto 7 | 8 | mkdir -p ${PROTO_DEST} 9 | 10 | # JavaScript code generating 11 | ./node_modules/.bin/grpc_tools_node_protoc \ 12 | --js_out=import_style=commonjs,binary:${PROTO_DEST} \ 13 | --grpc_out=${PROTO_DEST} \ 14 | --plugin=protoc-gen-grpc=./node_modules/.bin/grpc_tools_node_protoc_plugin \ 15 | -I ./proto \ 16 | proto/*.proto 17 | 18 | ./node_modules/.bin/grpc_tools_node_protoc \ 19 | --plugin=protoc-gen-ts=./node_modules/.bin/protoc-gen-ts \ 20 | --ts_out=${PROTO_DEST} \ 21 | -I ./proto \ 22 | proto/*.proto 23 | 24 | # TypeScript compiling 25 | mkdir -p build/proto 26 | cp -r ./src/proto/* build/proto 27 | tsc -------------------------------------------------------------------------------- /example/grpc/bash/server.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | BASEDIR=$(dirname "$0") 4 | cd ${BASEDIR}/../ 5 | 6 | DEBUG=* node ./build/server.js -------------------------------------------------------------------------------- /example/grpc/build/proto/Example_grpc_pb.d.ts: -------------------------------------------------------------------------------- 1 | // package: io.xtech.example 2 | // file: Example.proto 3 | 4 | /* tslint:disable */ 5 | 6 | import * as grpc from "grpc"; 7 | import * as Example_pb from "./Example_pb"; 8 | 9 | interface IExampleService extends grpc.ServiceDefinition { 10 | setMovies: IExampleService_ISetMovies; 11 | searchMoviesByCast: IExampleService_ISearchMoviesByCast; 12 | } 13 | 14 | interface IExampleService_ISetMovies extends grpc.MethodDefinition { 15 | path: string; // "/io.xtech.example.Example/SetMovies" 16 | requestStream: boolean; // false 17 | responseStream: boolean; // false 18 | requestSerialize: grpc.serialize; 19 | requestDeserialize: grpc.deserialize; 20 | responseSerialize: grpc.serialize; 21 | responseDeserialize: grpc.deserialize; 22 | } 23 | interface IExampleService_ISearchMoviesByCast extends grpc.MethodDefinition { 24 | path: string; // "/io.xtech.example.Example/SearchMoviesByCast" 25 | requestStream: boolean; // false 26 | responseStream: boolean; // true 27 | requestSerialize: grpc.serialize; 28 | requestDeserialize: grpc.deserialize; 29 | responseSerialize: grpc.serialize; 30 | responseDeserialize: grpc.deserialize; 31 | } 32 | 33 | export const ExampleService: IExampleService; 34 | 35 | export interface IExampleServer { 36 | setMovies: grpc.handleUnaryCall; 37 | searchMoviesByCast: grpc.handleServerStreamingCall; 38 | } 39 | 40 | export interface IExampleClient { 41 | setMovies(request: Example_pb.EmptyRequest, callback: (error: grpc.ServiceError | null, response: Example_pb.MoviesResult) => void): grpc.ClientUnaryCall; 42 | setMovies(request: Example_pb.EmptyRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: Example_pb.MoviesResult) => void): grpc.ClientUnaryCall; 43 | setMovies(request: Example_pb.EmptyRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: Example_pb.MoviesResult) => void): grpc.ClientUnaryCall; 44 | searchMoviesByCast(request: Example_pb.SearchByCastInput, options?: Partial): grpc.ClientReadableStream; 45 | searchMoviesByCast(request: Example_pb.SearchByCastInput, metadata?: grpc.Metadata, options?: Partial): grpc.ClientReadableStream; 46 | } 47 | 48 | export class ExampleClient extends grpc.Client implements IExampleClient { 49 | constructor(address: string, credentials: grpc.ChannelCredentials, options?: object); 50 | public setMovies(request: Example_pb.EmptyRequest, callback: (error: grpc.ServiceError | null, response: Example_pb.MoviesResult) => void): grpc.ClientUnaryCall; 51 | public setMovies(request: Example_pb.EmptyRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: Example_pb.MoviesResult) => void): grpc.ClientUnaryCall; 52 | public setMovies(request: Example_pb.EmptyRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: Example_pb.MoviesResult) => void): grpc.ClientUnaryCall; 53 | public searchMoviesByCast(request: Example_pb.SearchByCastInput, options?: Partial): grpc.ClientReadableStream; 54 | public searchMoviesByCast(request: Example_pb.SearchByCastInput, metadata?: grpc.Metadata, options?: Partial): grpc.ClientReadableStream; 55 | } 56 | -------------------------------------------------------------------------------- /example/grpc/build/proto/Example_grpc_pb.js: -------------------------------------------------------------------------------- 1 | // GENERATED CODE -- DO NOT EDIT! 2 | 3 | 'use strict'; 4 | var grpc = require('grpc'); 5 | var Example_pb = require('./Example_pb.js'); 6 | 7 | function serialize_io_xtech_example_EmptyRequest(arg) { 8 | if (!(arg instanceof Example_pb.EmptyRequest)) { 9 | throw new Error('Expected argument of type io.xtech.example.EmptyRequest'); 10 | } 11 | return new Buffer(arg.serializeBinary()); 12 | } 13 | 14 | function deserialize_io_xtech_example_EmptyRequest(buffer_arg) { 15 | return Example_pb.EmptyRequest.deserializeBinary(new Uint8Array(buffer_arg)); 16 | } 17 | 18 | function serialize_io_xtech_example_Movie(arg) { 19 | if (!(arg instanceof Example_pb.Movie)) { 20 | throw new Error('Expected argument of type io.xtech.example.Movie'); 21 | } 22 | return new Buffer(arg.serializeBinary()); 23 | } 24 | 25 | function deserialize_io_xtech_example_Movie(buffer_arg) { 26 | return Example_pb.Movie.deserializeBinary(new Uint8Array(buffer_arg)); 27 | } 28 | 29 | function serialize_io_xtech_example_MoviesResult(arg) { 30 | if (!(arg instanceof Example_pb.MoviesResult)) { 31 | throw new Error('Expected argument of type io.xtech.example.MoviesResult'); 32 | } 33 | return new Buffer(arg.serializeBinary()); 34 | } 35 | 36 | function deserialize_io_xtech_example_MoviesResult(buffer_arg) { 37 | return Example_pb.MoviesResult.deserializeBinary(new Uint8Array(buffer_arg)); 38 | } 39 | 40 | function serialize_io_xtech_example_SearchByCastInput(arg) { 41 | if (!(arg instanceof Example_pb.SearchByCastInput)) { 42 | throw new Error('Expected argument of type io.xtech.example.SearchByCastInput'); 43 | } 44 | return new Buffer(arg.serializeBinary()); 45 | } 46 | 47 | function deserialize_io_xtech_example_SearchByCastInput(buffer_arg) { 48 | return Example_pb.SearchByCastInput.deserializeBinary(new Uint8Array(buffer_arg)); 49 | } 50 | 51 | 52 | var ExampleService = exports.ExampleService = { 53 | setMovies: { 54 | path: '/io.xtech.example.Example/SetMovies', 55 | requestStream: false, 56 | responseStream: false, 57 | requestType: Example_pb.EmptyRequest, 58 | responseType: Example_pb.MoviesResult, 59 | requestSerialize: serialize_io_xtech_example_EmptyRequest, 60 | requestDeserialize: deserialize_io_xtech_example_EmptyRequest, 61 | responseSerialize: serialize_io_xtech_example_MoviesResult, 62 | responseDeserialize: deserialize_io_xtech_example_MoviesResult, 63 | }, 64 | searchMoviesByCast: { 65 | path: '/io.xtech.example.Example/SearchMoviesByCast', 66 | requestStream: false, 67 | responseStream: true, 68 | requestType: Example_pb.SearchByCastInput, 69 | responseType: Example_pb.Movie, 70 | requestSerialize: serialize_io_xtech_example_SearchByCastInput, 71 | requestDeserialize: deserialize_io_xtech_example_SearchByCastInput, 72 | responseSerialize: serialize_io_xtech_example_Movie, 73 | responseDeserialize: deserialize_io_xtech_example_Movie, 74 | }, 75 | }; 76 | 77 | exports.ExampleClient = grpc.makeGenericClientConstructor(ExampleService); 78 | -------------------------------------------------------------------------------- /example/grpc/build/proto/Example_pb.d.ts: -------------------------------------------------------------------------------- 1 | // package: io.xtech.example 2 | // file: Example.proto 3 | 4 | /* tslint:disable */ 5 | 6 | import * as jspb from "google-protobuf"; 7 | 8 | export class Movie extends jspb.Message { 9 | getName(): string; 10 | setName(value: string): void; 11 | 12 | getYear(): number; 13 | setYear(value: number): void; 14 | 15 | getRating(): number; 16 | setRating(value: number): void; 17 | 18 | clearCastList(): void; 19 | getCastList(): Array; 20 | setCastList(value: Array): void; 21 | addCast(value: string, index?: number): string; 22 | 23 | 24 | serializeBinary(): Uint8Array; 25 | toObject(includeInstance?: boolean): Movie.AsObject; 26 | static toObject(includeInstance: boolean, msg: Movie): Movie.AsObject; 27 | static extensions: {[key: number]: jspb.ExtensionFieldInfo}; 28 | static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; 29 | static serializeBinaryToWriter(message: Movie, writer: jspb.BinaryWriter): void; 30 | static deserializeBinary(bytes: Uint8Array): Movie; 31 | static deserializeBinaryFromReader(message: Movie, reader: jspb.BinaryReader): Movie; 32 | } 33 | 34 | export namespace Movie { 35 | export type AsObject = { 36 | name: string, 37 | year: number, 38 | rating: number, 39 | castList: Array, 40 | } 41 | } 42 | 43 | export class EmptyRequest extends jspb.Message { 44 | 45 | serializeBinary(): Uint8Array; 46 | toObject(includeInstance?: boolean): EmptyRequest.AsObject; 47 | static toObject(includeInstance: boolean, msg: EmptyRequest): EmptyRequest.AsObject; 48 | static extensions: {[key: number]: jspb.ExtensionFieldInfo}; 49 | static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; 50 | static serializeBinaryToWriter(message: EmptyRequest, writer: jspb.BinaryWriter): void; 51 | static deserializeBinary(bytes: Uint8Array): EmptyRequest; 52 | static deserializeBinaryFromReader(message: EmptyRequest, reader: jspb.BinaryReader): EmptyRequest; 53 | } 54 | 55 | export namespace EmptyRequest { 56 | export type AsObject = { 57 | } 58 | } 59 | 60 | export class SearchByCastInput extends jspb.Message { 61 | getCastname(): string; 62 | setCastname(value: string): void; 63 | 64 | 65 | serializeBinary(): Uint8Array; 66 | toObject(includeInstance?: boolean): SearchByCastInput.AsObject; 67 | static toObject(includeInstance: boolean, msg: SearchByCastInput): SearchByCastInput.AsObject; 68 | static extensions: {[key: number]: jspb.ExtensionFieldInfo}; 69 | static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; 70 | static serializeBinaryToWriter(message: SearchByCastInput, writer: jspb.BinaryWriter): void; 71 | static deserializeBinary(bytes: Uint8Array): SearchByCastInput; 72 | static deserializeBinaryFromReader(message: SearchByCastInput, reader: jspb.BinaryReader): SearchByCastInput; 73 | } 74 | 75 | export namespace SearchByCastInput { 76 | export type AsObject = { 77 | castname: string, 78 | } 79 | } 80 | 81 | export class MoviesResult extends jspb.Message { 82 | clearResultList(): void; 83 | getResultList(): Array; 84 | setResultList(value: Array): void; 85 | addResult(value?: Movie, index?: number): Movie; 86 | 87 | 88 | serializeBinary(): Uint8Array; 89 | toObject(includeInstance?: boolean): MoviesResult.AsObject; 90 | static toObject(includeInstance: boolean, msg: MoviesResult): MoviesResult.AsObject; 91 | static extensions: {[key: number]: jspb.ExtensionFieldInfo}; 92 | static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; 93 | static serializeBinaryToWriter(message: MoviesResult, writer: jspb.BinaryWriter): void; 94 | static deserializeBinary(bytes: Uint8Array): MoviesResult; 95 | static deserializeBinaryFromReader(message: MoviesResult, reader: jspb.BinaryReader): MoviesResult; 96 | } 97 | 98 | export namespace MoviesResult { 99 | export type AsObject = { 100 | resultList: Array, 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /example/grpc/build/proto/Example_pb.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview 3 | * @enhanceable 4 | * @suppress {messageConventions} JS Compiler reports an error if a variable or 5 | * field starts with 'MSG_' and isn't a translatable message. 6 | * @public 7 | */ 8 | // GENERATED CODE -- DO NOT EDIT! 9 | 10 | var jspb = require('google-protobuf'); 11 | var goog = jspb; 12 | var global = Function('return this')(); 13 | 14 | goog.exportSymbol('proto.io.xtech.example.EmptyRequest', null, global); 15 | goog.exportSymbol('proto.io.xtech.example.Movie', null, global); 16 | goog.exportSymbol('proto.io.xtech.example.MoviesResult', null, global); 17 | goog.exportSymbol('proto.io.xtech.example.SearchByCastInput', null, global); 18 | 19 | /** 20 | * Generated by JsPbCodeGenerator. 21 | * @param {Array=} opt_data Optional initial data array, typically from a 22 | * server response, or constructed directly in Javascript. The array is used 23 | * in place and becomes part of the constructed object. It is not cloned. 24 | * If no data is provided, the constructed object will be empty, but still 25 | * valid. 26 | * @extends {jspb.Message} 27 | * @constructor 28 | */ 29 | proto.io.xtech.example.Movie = function(opt_data) { 30 | jspb.Message.initialize(this, opt_data, 0, -1, proto.io.xtech.example.Movie.repeatedFields_, null); 31 | }; 32 | goog.inherits(proto.io.xtech.example.Movie, jspb.Message); 33 | if (goog.DEBUG && !COMPILED) { 34 | proto.io.xtech.example.Movie.displayName = 'proto.io.xtech.example.Movie'; 35 | } 36 | /** 37 | * List of repeated fields within this message type. 38 | * @private {!Array} 39 | * @const 40 | */ 41 | proto.io.xtech.example.Movie.repeatedFields_ = [4]; 42 | 43 | 44 | 45 | if (jspb.Message.GENERATE_TO_OBJECT) { 46 | /** 47 | * Creates an object representation of this proto suitable for use in Soy templates. 48 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 49 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 50 | * For the list of reserved names please see: 51 | * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. 52 | * @param {boolean=} opt_includeInstance Whether to include the JSPB instance 53 | * for transitional soy proto support: http://goto/soy-param-migration 54 | * @return {!Object} 55 | */ 56 | proto.io.xtech.example.Movie.prototype.toObject = function(opt_includeInstance) { 57 | return proto.io.xtech.example.Movie.toObject(opt_includeInstance, this); 58 | }; 59 | 60 | 61 | /** 62 | * Static version of the {@see toObject} method. 63 | * @param {boolean|undefined} includeInstance Whether to include the JSPB 64 | * instance for transitional soy proto support: 65 | * http://goto/soy-param-migration 66 | * @param {!proto.io.xtech.example.Movie} msg The msg instance to transform. 67 | * @return {!Object} 68 | * @suppress {unusedLocalVariables} f is only used for nested messages 69 | */ 70 | proto.io.xtech.example.Movie.toObject = function(includeInstance, msg) { 71 | var f, obj = { 72 | name: jspb.Message.getFieldWithDefault(msg, 1, ""), 73 | year: jspb.Message.getFieldWithDefault(msg, 2, 0), 74 | rating: +jspb.Message.getFieldWithDefault(msg, 3, 0.0), 75 | castList: jspb.Message.getRepeatedField(msg, 4) 76 | }; 77 | 78 | if (includeInstance) { 79 | obj.$jspbMessageInstance = msg; 80 | } 81 | return obj; 82 | }; 83 | } 84 | 85 | 86 | /** 87 | * Deserializes binary data (in protobuf wire format). 88 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 89 | * @return {!proto.io.xtech.example.Movie} 90 | */ 91 | proto.io.xtech.example.Movie.deserializeBinary = function(bytes) { 92 | var reader = new jspb.BinaryReader(bytes); 93 | var msg = new proto.io.xtech.example.Movie; 94 | return proto.io.xtech.example.Movie.deserializeBinaryFromReader(msg, reader); 95 | }; 96 | 97 | 98 | /** 99 | * Deserializes binary data (in protobuf wire format) from the 100 | * given reader into the given message object. 101 | * @param {!proto.io.xtech.example.Movie} msg The message object to deserialize into. 102 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 103 | * @return {!proto.io.xtech.example.Movie} 104 | */ 105 | proto.io.xtech.example.Movie.deserializeBinaryFromReader = function(msg, reader) { 106 | while (reader.nextField()) { 107 | if (reader.isEndGroup()) { 108 | break; 109 | } 110 | var field = reader.getFieldNumber(); 111 | switch (field) { 112 | case 1: 113 | var value = /** @type {string} */ (reader.readString()); 114 | msg.setName(value); 115 | break; 116 | case 2: 117 | var value = /** @type {number} */ (reader.readInt32()); 118 | msg.setYear(value); 119 | break; 120 | case 3: 121 | var value = /** @type {number} */ (reader.readFloat()); 122 | msg.setRating(value); 123 | break; 124 | case 4: 125 | var value = /** @type {string} */ (reader.readString()); 126 | msg.addCast(value); 127 | break; 128 | default: 129 | reader.skipField(); 130 | break; 131 | } 132 | } 133 | return msg; 134 | }; 135 | 136 | 137 | /** 138 | * Serializes the message to binary data (in protobuf wire format). 139 | * @return {!Uint8Array} 140 | */ 141 | proto.io.xtech.example.Movie.prototype.serializeBinary = function() { 142 | var writer = new jspb.BinaryWriter(); 143 | proto.io.xtech.example.Movie.serializeBinaryToWriter(this, writer); 144 | return writer.getResultBuffer(); 145 | }; 146 | 147 | 148 | /** 149 | * Serializes the given message to binary data (in protobuf wire 150 | * format), writing to the given BinaryWriter. 151 | * @param {!proto.io.xtech.example.Movie} message 152 | * @param {!jspb.BinaryWriter} writer 153 | * @suppress {unusedLocalVariables} f is only used for nested messages 154 | */ 155 | proto.io.xtech.example.Movie.serializeBinaryToWriter = function(message, writer) { 156 | var f = undefined; 157 | f = message.getName(); 158 | if (f.length > 0) { 159 | writer.writeString( 160 | 1, 161 | f 162 | ); 163 | } 164 | f = message.getYear(); 165 | if (f !== 0) { 166 | writer.writeInt32( 167 | 2, 168 | f 169 | ); 170 | } 171 | f = message.getRating(); 172 | if (f !== 0.0) { 173 | writer.writeFloat( 174 | 3, 175 | f 176 | ); 177 | } 178 | f = message.getCastList(); 179 | if (f.length > 0) { 180 | writer.writeRepeatedString( 181 | 4, 182 | f 183 | ); 184 | } 185 | }; 186 | 187 | 188 | /** 189 | * optional string name = 1; 190 | * @return {string} 191 | */ 192 | proto.io.xtech.example.Movie.prototype.getName = function() { 193 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); 194 | }; 195 | 196 | 197 | /** @param {string} value */ 198 | proto.io.xtech.example.Movie.prototype.setName = function(value) { 199 | jspb.Message.setField(this, 1, value); 200 | }; 201 | 202 | 203 | /** 204 | * optional int32 year = 2; 205 | * @return {number} 206 | */ 207 | proto.io.xtech.example.Movie.prototype.getYear = function() { 208 | return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); 209 | }; 210 | 211 | 212 | /** @param {number} value */ 213 | proto.io.xtech.example.Movie.prototype.setYear = function(value) { 214 | jspb.Message.setField(this, 2, value); 215 | }; 216 | 217 | 218 | /** 219 | * optional float rating = 3; 220 | * @return {number} 221 | */ 222 | proto.io.xtech.example.Movie.prototype.getRating = function() { 223 | return /** @type {number} */ (+jspb.Message.getFieldWithDefault(this, 3, 0.0)); 224 | }; 225 | 226 | 227 | /** @param {number} value */ 228 | proto.io.xtech.example.Movie.prototype.setRating = function(value) { 229 | jspb.Message.setField(this, 3, value); 230 | }; 231 | 232 | 233 | /** 234 | * repeated string cast = 4; 235 | * @return {!Array.} 236 | */ 237 | proto.io.xtech.example.Movie.prototype.getCastList = function() { 238 | return /** @type {!Array.} */ (jspb.Message.getRepeatedField(this, 4)); 239 | }; 240 | 241 | 242 | /** @param {!Array.} value */ 243 | proto.io.xtech.example.Movie.prototype.setCastList = function(value) { 244 | jspb.Message.setField(this, 4, value || []); 245 | }; 246 | 247 | 248 | /** 249 | * @param {!string} value 250 | * @param {number=} opt_index 251 | */ 252 | proto.io.xtech.example.Movie.prototype.addCast = function(value, opt_index) { 253 | jspb.Message.addToRepeatedField(this, 4, value, opt_index); 254 | }; 255 | 256 | 257 | proto.io.xtech.example.Movie.prototype.clearCastList = function() { 258 | this.setCastList([]); 259 | }; 260 | 261 | 262 | 263 | /** 264 | * Generated by JsPbCodeGenerator. 265 | * @param {Array=} opt_data Optional initial data array, typically from a 266 | * server response, or constructed directly in Javascript. The array is used 267 | * in place and becomes part of the constructed object. It is not cloned. 268 | * If no data is provided, the constructed object will be empty, but still 269 | * valid. 270 | * @extends {jspb.Message} 271 | * @constructor 272 | */ 273 | proto.io.xtech.example.EmptyRequest = function(opt_data) { 274 | jspb.Message.initialize(this, opt_data, 0, -1, null, null); 275 | }; 276 | goog.inherits(proto.io.xtech.example.EmptyRequest, jspb.Message); 277 | if (goog.DEBUG && !COMPILED) { 278 | proto.io.xtech.example.EmptyRequest.displayName = 'proto.io.xtech.example.EmptyRequest'; 279 | } 280 | 281 | 282 | if (jspb.Message.GENERATE_TO_OBJECT) { 283 | /** 284 | * Creates an object representation of this proto suitable for use in Soy templates. 285 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 286 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 287 | * For the list of reserved names please see: 288 | * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. 289 | * @param {boolean=} opt_includeInstance Whether to include the JSPB instance 290 | * for transitional soy proto support: http://goto/soy-param-migration 291 | * @return {!Object} 292 | */ 293 | proto.io.xtech.example.EmptyRequest.prototype.toObject = function(opt_includeInstance) { 294 | return proto.io.xtech.example.EmptyRequest.toObject(opt_includeInstance, this); 295 | }; 296 | 297 | 298 | /** 299 | * Static version of the {@see toObject} method. 300 | * @param {boolean|undefined} includeInstance Whether to include the JSPB 301 | * instance for transitional soy proto support: 302 | * http://goto/soy-param-migration 303 | * @param {!proto.io.xtech.example.EmptyRequest} msg The msg instance to transform. 304 | * @return {!Object} 305 | * @suppress {unusedLocalVariables} f is only used for nested messages 306 | */ 307 | proto.io.xtech.example.EmptyRequest.toObject = function(includeInstance, msg) { 308 | var f, obj = { 309 | 310 | }; 311 | 312 | if (includeInstance) { 313 | obj.$jspbMessageInstance = msg; 314 | } 315 | return obj; 316 | }; 317 | } 318 | 319 | 320 | /** 321 | * Deserializes binary data (in protobuf wire format). 322 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 323 | * @return {!proto.io.xtech.example.EmptyRequest} 324 | */ 325 | proto.io.xtech.example.EmptyRequest.deserializeBinary = function(bytes) { 326 | var reader = new jspb.BinaryReader(bytes); 327 | var msg = new proto.io.xtech.example.EmptyRequest; 328 | return proto.io.xtech.example.EmptyRequest.deserializeBinaryFromReader(msg, reader); 329 | }; 330 | 331 | 332 | /** 333 | * Deserializes binary data (in protobuf wire format) from the 334 | * given reader into the given message object. 335 | * @param {!proto.io.xtech.example.EmptyRequest} msg The message object to deserialize into. 336 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 337 | * @return {!proto.io.xtech.example.EmptyRequest} 338 | */ 339 | proto.io.xtech.example.EmptyRequest.deserializeBinaryFromReader = function(msg, reader) { 340 | while (reader.nextField()) { 341 | if (reader.isEndGroup()) { 342 | break; 343 | } 344 | var field = reader.getFieldNumber(); 345 | switch (field) { 346 | default: 347 | reader.skipField(); 348 | break; 349 | } 350 | } 351 | return msg; 352 | }; 353 | 354 | 355 | /** 356 | * Serializes the message to binary data (in protobuf wire format). 357 | * @return {!Uint8Array} 358 | */ 359 | proto.io.xtech.example.EmptyRequest.prototype.serializeBinary = function() { 360 | var writer = new jspb.BinaryWriter(); 361 | proto.io.xtech.example.EmptyRequest.serializeBinaryToWriter(this, writer); 362 | return writer.getResultBuffer(); 363 | }; 364 | 365 | 366 | /** 367 | * Serializes the given message to binary data (in protobuf wire 368 | * format), writing to the given BinaryWriter. 369 | * @param {!proto.io.xtech.example.EmptyRequest} message 370 | * @param {!jspb.BinaryWriter} writer 371 | * @suppress {unusedLocalVariables} f is only used for nested messages 372 | */ 373 | proto.io.xtech.example.EmptyRequest.serializeBinaryToWriter = function(message, writer) { 374 | var f = undefined; 375 | }; 376 | 377 | 378 | 379 | /** 380 | * Generated by JsPbCodeGenerator. 381 | * @param {Array=} opt_data Optional initial data array, typically from a 382 | * server response, or constructed directly in Javascript. The array is used 383 | * in place and becomes part of the constructed object. It is not cloned. 384 | * If no data is provided, the constructed object will be empty, but still 385 | * valid. 386 | * @extends {jspb.Message} 387 | * @constructor 388 | */ 389 | proto.io.xtech.example.SearchByCastInput = function(opt_data) { 390 | jspb.Message.initialize(this, opt_data, 0, -1, null, null); 391 | }; 392 | goog.inherits(proto.io.xtech.example.SearchByCastInput, jspb.Message); 393 | if (goog.DEBUG && !COMPILED) { 394 | proto.io.xtech.example.SearchByCastInput.displayName = 'proto.io.xtech.example.SearchByCastInput'; 395 | } 396 | 397 | 398 | if (jspb.Message.GENERATE_TO_OBJECT) { 399 | /** 400 | * Creates an object representation of this proto suitable for use in Soy templates. 401 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 402 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 403 | * For the list of reserved names please see: 404 | * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. 405 | * @param {boolean=} opt_includeInstance Whether to include the JSPB instance 406 | * for transitional soy proto support: http://goto/soy-param-migration 407 | * @return {!Object} 408 | */ 409 | proto.io.xtech.example.SearchByCastInput.prototype.toObject = function(opt_includeInstance) { 410 | return proto.io.xtech.example.SearchByCastInput.toObject(opt_includeInstance, this); 411 | }; 412 | 413 | 414 | /** 415 | * Static version of the {@see toObject} method. 416 | * @param {boolean|undefined} includeInstance Whether to include the JSPB 417 | * instance for transitional soy proto support: 418 | * http://goto/soy-param-migration 419 | * @param {!proto.io.xtech.example.SearchByCastInput} msg The msg instance to transform. 420 | * @return {!Object} 421 | * @suppress {unusedLocalVariables} f is only used for nested messages 422 | */ 423 | proto.io.xtech.example.SearchByCastInput.toObject = function(includeInstance, msg) { 424 | var f, obj = { 425 | castname: jspb.Message.getFieldWithDefault(msg, 1, "") 426 | }; 427 | 428 | if (includeInstance) { 429 | obj.$jspbMessageInstance = msg; 430 | } 431 | return obj; 432 | }; 433 | } 434 | 435 | 436 | /** 437 | * Deserializes binary data (in protobuf wire format). 438 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 439 | * @return {!proto.io.xtech.example.SearchByCastInput} 440 | */ 441 | proto.io.xtech.example.SearchByCastInput.deserializeBinary = function(bytes) { 442 | var reader = new jspb.BinaryReader(bytes); 443 | var msg = new proto.io.xtech.example.SearchByCastInput; 444 | return proto.io.xtech.example.SearchByCastInput.deserializeBinaryFromReader(msg, reader); 445 | }; 446 | 447 | 448 | /** 449 | * Deserializes binary data (in protobuf wire format) from the 450 | * given reader into the given message object. 451 | * @param {!proto.io.xtech.example.SearchByCastInput} msg The message object to deserialize into. 452 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 453 | * @return {!proto.io.xtech.example.SearchByCastInput} 454 | */ 455 | proto.io.xtech.example.SearchByCastInput.deserializeBinaryFromReader = function(msg, reader) { 456 | while (reader.nextField()) { 457 | if (reader.isEndGroup()) { 458 | break; 459 | } 460 | var field = reader.getFieldNumber(); 461 | switch (field) { 462 | case 1: 463 | var value = /** @type {string} */ (reader.readString()); 464 | msg.setCastname(value); 465 | break; 466 | default: 467 | reader.skipField(); 468 | break; 469 | } 470 | } 471 | return msg; 472 | }; 473 | 474 | 475 | /** 476 | * Serializes the message to binary data (in protobuf wire format). 477 | * @return {!Uint8Array} 478 | */ 479 | proto.io.xtech.example.SearchByCastInput.prototype.serializeBinary = function() { 480 | var writer = new jspb.BinaryWriter(); 481 | proto.io.xtech.example.SearchByCastInput.serializeBinaryToWriter(this, writer); 482 | return writer.getResultBuffer(); 483 | }; 484 | 485 | 486 | /** 487 | * Serializes the given message to binary data (in protobuf wire 488 | * format), writing to the given BinaryWriter. 489 | * @param {!proto.io.xtech.example.SearchByCastInput} message 490 | * @param {!jspb.BinaryWriter} writer 491 | * @suppress {unusedLocalVariables} f is only used for nested messages 492 | */ 493 | proto.io.xtech.example.SearchByCastInput.serializeBinaryToWriter = function(message, writer) { 494 | var f = undefined; 495 | f = message.getCastname(); 496 | if (f.length > 0) { 497 | writer.writeString( 498 | 1, 499 | f 500 | ); 501 | } 502 | }; 503 | 504 | 505 | /** 506 | * optional string castName = 1; 507 | * @return {string} 508 | */ 509 | proto.io.xtech.example.SearchByCastInput.prototype.getCastname = function() { 510 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); 511 | }; 512 | 513 | 514 | /** @param {string} value */ 515 | proto.io.xtech.example.SearchByCastInput.prototype.setCastname = function(value) { 516 | jspb.Message.setField(this, 1, value); 517 | }; 518 | 519 | 520 | 521 | /** 522 | * Generated by JsPbCodeGenerator. 523 | * @param {Array=} opt_data Optional initial data array, typically from a 524 | * server response, or constructed directly in Javascript. The array is used 525 | * in place and becomes part of the constructed object. It is not cloned. 526 | * If no data is provided, the constructed object will be empty, but still 527 | * valid. 528 | * @extends {jspb.Message} 529 | * @constructor 530 | */ 531 | proto.io.xtech.example.MoviesResult = function(opt_data) { 532 | jspb.Message.initialize(this, opt_data, 0, -1, proto.io.xtech.example.MoviesResult.repeatedFields_, null); 533 | }; 534 | goog.inherits(proto.io.xtech.example.MoviesResult, jspb.Message); 535 | if (goog.DEBUG && !COMPILED) { 536 | proto.io.xtech.example.MoviesResult.displayName = 'proto.io.xtech.example.MoviesResult'; 537 | } 538 | /** 539 | * List of repeated fields within this message type. 540 | * @private {!Array} 541 | * @const 542 | */ 543 | proto.io.xtech.example.MoviesResult.repeatedFields_ = [1]; 544 | 545 | 546 | 547 | if (jspb.Message.GENERATE_TO_OBJECT) { 548 | /** 549 | * Creates an object representation of this proto suitable for use in Soy templates. 550 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 551 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 552 | * For the list of reserved names please see: 553 | * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. 554 | * @param {boolean=} opt_includeInstance Whether to include the JSPB instance 555 | * for transitional soy proto support: http://goto/soy-param-migration 556 | * @return {!Object} 557 | */ 558 | proto.io.xtech.example.MoviesResult.prototype.toObject = function(opt_includeInstance) { 559 | return proto.io.xtech.example.MoviesResult.toObject(opt_includeInstance, this); 560 | }; 561 | 562 | 563 | /** 564 | * Static version of the {@see toObject} method. 565 | * @param {boolean|undefined} includeInstance Whether to include the JSPB 566 | * instance for transitional soy proto support: 567 | * http://goto/soy-param-migration 568 | * @param {!proto.io.xtech.example.MoviesResult} msg The msg instance to transform. 569 | * @return {!Object} 570 | * @suppress {unusedLocalVariables} f is only used for nested messages 571 | */ 572 | proto.io.xtech.example.MoviesResult.toObject = function(includeInstance, msg) { 573 | var f, obj = { 574 | resultList: jspb.Message.toObjectList(msg.getResultList(), 575 | proto.io.xtech.example.Movie.toObject, includeInstance) 576 | }; 577 | 578 | if (includeInstance) { 579 | obj.$jspbMessageInstance = msg; 580 | } 581 | return obj; 582 | }; 583 | } 584 | 585 | 586 | /** 587 | * Deserializes binary data (in protobuf wire format). 588 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 589 | * @return {!proto.io.xtech.example.MoviesResult} 590 | */ 591 | proto.io.xtech.example.MoviesResult.deserializeBinary = function(bytes) { 592 | var reader = new jspb.BinaryReader(bytes); 593 | var msg = new proto.io.xtech.example.MoviesResult; 594 | return proto.io.xtech.example.MoviesResult.deserializeBinaryFromReader(msg, reader); 595 | }; 596 | 597 | 598 | /** 599 | * Deserializes binary data (in protobuf wire format) from the 600 | * given reader into the given message object. 601 | * @param {!proto.io.xtech.example.MoviesResult} msg The message object to deserialize into. 602 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 603 | * @return {!proto.io.xtech.example.MoviesResult} 604 | */ 605 | proto.io.xtech.example.MoviesResult.deserializeBinaryFromReader = function(msg, reader) { 606 | while (reader.nextField()) { 607 | if (reader.isEndGroup()) { 608 | break; 609 | } 610 | var field = reader.getFieldNumber(); 611 | switch (field) { 612 | case 1: 613 | var value = new proto.io.xtech.example.Movie; 614 | reader.readMessage(value,proto.io.xtech.example.Movie.deserializeBinaryFromReader); 615 | msg.addResult(value); 616 | break; 617 | default: 618 | reader.skipField(); 619 | break; 620 | } 621 | } 622 | return msg; 623 | }; 624 | 625 | 626 | /** 627 | * Serializes the message to binary data (in protobuf wire format). 628 | * @return {!Uint8Array} 629 | */ 630 | proto.io.xtech.example.MoviesResult.prototype.serializeBinary = function() { 631 | var writer = new jspb.BinaryWriter(); 632 | proto.io.xtech.example.MoviesResult.serializeBinaryToWriter(this, writer); 633 | return writer.getResultBuffer(); 634 | }; 635 | 636 | 637 | /** 638 | * Serializes the given message to binary data (in protobuf wire 639 | * format), writing to the given BinaryWriter. 640 | * @param {!proto.io.xtech.example.MoviesResult} message 641 | * @param {!jspb.BinaryWriter} writer 642 | * @suppress {unusedLocalVariables} f is only used for nested messages 643 | */ 644 | proto.io.xtech.example.MoviesResult.serializeBinaryToWriter = function(message, writer) { 645 | var f = undefined; 646 | f = message.getResultList(); 647 | if (f.length > 0) { 648 | writer.writeRepeatedMessage( 649 | 1, 650 | f, 651 | proto.io.xtech.example.Movie.serializeBinaryToWriter 652 | ); 653 | } 654 | }; 655 | 656 | 657 | /** 658 | * repeated Movie result = 1; 659 | * @return {!Array.} 660 | */ 661 | proto.io.xtech.example.MoviesResult.prototype.getResultList = function() { 662 | return /** @type{!Array.} */ ( 663 | jspb.Message.getRepeatedWrapperField(this, proto.io.xtech.example.Movie, 1)); 664 | }; 665 | 666 | 667 | /** @param {!Array.} value */ 668 | proto.io.xtech.example.MoviesResult.prototype.setResultList = function(value) { 669 | jspb.Message.setRepeatedWrapperField(this, 1, value); 670 | }; 671 | 672 | 673 | /** 674 | * @param {!proto.io.xtech.example.Movie=} opt_value 675 | * @param {number=} opt_index 676 | * @return {!proto.io.xtech.example.Movie} 677 | */ 678 | proto.io.xtech.example.MoviesResult.prototype.addResult = function(opt_value, opt_index) { 679 | return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.io.xtech.example.Movie, opt_index); 680 | }; 681 | 682 | 683 | proto.io.xtech.example.MoviesResult.prototype.clearResultList = function() { 684 | this.setResultList([]); 685 | }; 686 | 687 | 688 | goog.object.extend(exports, proto.io.xtech.example); 689 | -------------------------------------------------------------------------------- /example/grpc/build/server.d.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | export {}; 3 | -------------------------------------------------------------------------------- /example/grpc/build/server.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | "use strict"; 3 | Object.defineProperty(exports, "__esModule", { value: true }); 4 | const debug = require("debug"); 5 | const grpc = require("grpc"); 6 | const Example_grpc_pb_1 = require("./proto/Example_grpc_pb"); 7 | const Example_pb_1 = require("./proto/Example_pb"); 8 | const log = debug("SampleServer"); 9 | const Movies = [ 10 | { 11 | cast: ["Tom Cruise", "Simon Pegg", "Jeremy Renner"], 12 | name: "Mission: Impossible Rogue Nation", 13 | rating: 0.97, 14 | year: 2015, 15 | }, 16 | { 17 | cast: ["Tom Cruise", "Simon Pegg", "Henry Cavill"], 18 | name: "Mission: Impossible - Fallout", 19 | rating: 0.93, 20 | year: 2018, 21 | }, 22 | { 23 | cast: ["Leonardo DiCaprio", "Jonah Hill", "Margot Robbie"], 24 | name: "The Wolf of Wall Street", 25 | rating: 0.78, 26 | year: 2013, 27 | }, 28 | ]; 29 | function createMovie(movie) { 30 | const result = new Example_pb_1.Movie(); 31 | result.setCastList(movie.cast); 32 | result.setName(movie.name); 33 | result.setYear(movie.year); 34 | result.setRating(movie.rating); 35 | return result; 36 | } 37 | class ServerImpl { 38 | setMovies(request, callback) { 39 | const result = new Example_pb_1.MoviesResult(); 40 | Movies.map(createMovie).forEach((movie) => result.addResult(movie)); 41 | callback(null, result); 42 | } 43 | searchMoviesByCast(call) { 44 | log("call started"); 45 | const input = call.request; 46 | let i = 1; 47 | call.on("error", (error) => { 48 | log(error); 49 | call.end(); 50 | }); 51 | Movies.map(createMovie).forEach((movie) => { 52 | if (movie.getCastList().indexOf(input.getCastname()) > -1) { 53 | setTimeout(() => { 54 | log(movie.getName()); 55 | call.write(movie); 56 | }, i * 1000); 57 | i += 1; 58 | } 59 | }); 60 | setTimeout(() => { 61 | call.end(); 62 | log("call ended"); 63 | }, 3000); 64 | } 65 | } 66 | function startServer() { 67 | const server = new grpc.Server(); 68 | server.addService(Example_grpc_pb_1.ExampleService, new ServerImpl()); 69 | server.bind("0.0.0.0:50051", grpc.ServerCredentials.createInsecure()); 70 | server.start(); 71 | log("Server started, listening: 0.0.0.0:50051"); 72 | } 73 | startServer(); 74 | process.on("uncaughtException", (err) => { 75 | log(`process on uncaughtException error: ${err}`); 76 | }); 77 | process.on("unhandledRejection", (err) => { 78 | log(`process on unhandledRejection error: ${err}`); 79 | }); 80 | //# sourceMappingURL=server.js.map -------------------------------------------------------------------------------- /example/grpc/build/server.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";;;AAEA,+BAA+B;AAC/B,6BAA6B;AAE7B,6DAAyE;AACzE,mDAA0F;AAE1F,MAAM,GAAG,GAAG,KAAK,CAAC,cAAc,CAAC,CAAC;AASlC,MAAM,MAAM,GAAG;IACb;QACE,IAAI,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,eAAe,CAAC;QACnD,IAAI,EAAE,kCAAkC;QACxC,MAAM,EAAE,IAAI;QACZ,IAAI,EAAE,IAAI;KACX;IACD;QACE,IAAI,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,cAAc,CAAC;QAClD,IAAI,EAAE,+BAA+B;QACrC,MAAM,EAAE,IAAI;QACZ,IAAI,EAAE,IAAI;KACX;IACD;QACE,IAAI,EAAE,CAAC,mBAAmB,EAAE,YAAY,EAAE,eAAe,CAAC;QAC1D,IAAI,EAAE,yBAAyB;QAC/B,MAAM,EAAE,IAAI;QACZ,IAAI,EAAE,IAAI;KACX;CACF,CAAC;AAEF,SAAS,WAAW,CAAC,KAAgB;IACnC,MAAM,MAAM,GAAG,IAAI,kBAAK,EAAE,CAAC;IAE3B,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3B,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3B,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAE/B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU;IACP,SAAS,CAAC,OAA2C,EAAE,QAA0C;QACtG,MAAM,MAAM,GAAG,IAAI,yBAAY,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,KAAY,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACzB,CAAC;IAEM,kBAAkB,CAAC,IAAmD;QAC3E,GAAG,CAAC,cAAc,CAAC,CAAC;QACpB,MAAM,KAAK,GAAsB,IAAI,CAAC,OAAO,CAAC;QAC9C,IAAI,CAAC,GAAW,CAAC,CAAC;QAClB,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACzB,GAAG,CAAC,KAAK,CAAC,CAAC;YACX,IAAI,CAAC,GAAG,EAAE,CAAC;QACb,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,KAAY,EAAE,EAAE;YAC/C,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE;gBACzD,UAAU,CAAC,GAAG,EAAE;oBACd,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;oBACrB,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBACpB,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;gBACb,CAAC,IAAI,CAAC,CAAC;aACR;QACH,CAAC,CAAC,CAAC;QACH,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,GAAG,EAAE,CAAC;YACX,GAAG,CAAC,YAAY,CAAC,CAAC;QACpB,CAAC,EAAE,IAAI,CAAC,CAAC;IACX,CAAC;CACF;AAED,SAAS,WAAW;IAClB,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;IAEjC,MAAM,CAAC,UAAU,CAAC,gCAAc,EAAE,IAAI,UAAU,EAAE,CAAC,CAAC;IACpD,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,iBAAiB,CAAC,cAAc,EAAE,CAAC,CAAC;IACtE,MAAM,CAAC,KAAK,EAAE,CAAC;IAEf,GAAG,CAAC,0CAA0C,CAAC,CAAC;AAClD,CAAC;AAED,WAAW,EAAE,CAAC;AAEd,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,GAAG,EAAE,EAAE;IACtC,GAAG,CAAC,uCAAuC,GAAG,EAAE,CAAC,CAAC;AACpD,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,GAAG,EAAE,EAAE;IACvC,GAAG,CAAC,wCAAwC,GAAG,EAAE,CAAC,CAAC;AACrD,CAAC,CAAC,CAAC"} -------------------------------------------------------------------------------- /example/grpc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "grpc-graphql-schema-example-grpc", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "directories": { 7 | "example": "example" 8 | }, 9 | "scripts": { 10 | "postinstall": "npm run build", 11 | "build": "bash bash/build.sh", 12 | "start": "bash bash/server.sh", 13 | "test": "echo \"Error: no test specified\" && exit 1" 14 | }, 15 | "author": "", 16 | "license": "ISC", 17 | "dependencies": { 18 | "debug": "^4.1.1", 19 | "google-protobuf": "^3.6.1", 20 | "grpc": "^1.17.0" 21 | }, 22 | "devDependencies": { 23 | "@types/debug": "^0.0.31", 24 | "@types/google-protobuf": "^3.2.7", 25 | "@types/node": "^10.12.18", 26 | "grpc-tools": "^1.6.6", 27 | "grpc_tools_node_protoc_ts": "^2.4.2", 28 | "typescript": "^3.2.2" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /example/grpc/proto/Example.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package io.xtech.example; 4 | 5 | /** 6 | * movie message payload 7 | */ 8 | message Movie { 9 | string name = 1; 10 | int32 year = 2; 11 | float rating = 3; 12 | 13 | /** 14 | * list of cast 15 | */ 16 | repeated string cast = 4; 17 | } 18 | 19 | message EmptyRequest {} 20 | 21 | message SearchByCastInput { 22 | string castName = 1; 23 | } 24 | 25 | /** 26 | * movie result message, contains list of movies 27 | */ 28 | message MoviesResult { 29 | /** 30 | * list of movies 31 | */ 32 | repeated Movie result = 1; 33 | } 34 | 35 | service Example { 36 | /** 37 | * get all movies 38 | */ 39 | rpc GetMovies (EmptyRequest) returns (MoviesResult) {} 40 | 41 | /** 42 | * search movies by the name of the cast 43 | */ 44 | rpc SearchMoviesByCast (SearchByCastInput) returns (stream Movie) {} 45 | } 46 | -------------------------------------------------------------------------------- /example/grpc/src/proto/Example_grpc_pb.d.ts: -------------------------------------------------------------------------------- 1 | // package: io.xtech.example 2 | // file: Example.proto 3 | 4 | /* tslint:disable */ 5 | 6 | import * as grpc from "grpc"; 7 | import * as Example_pb from "./Example_pb"; 8 | 9 | interface IExampleService extends grpc.ServiceDefinition { 10 | setMovies: IExampleService_ISetMovies; 11 | searchMoviesByCast: IExampleService_ISearchMoviesByCast; 12 | } 13 | 14 | interface IExampleService_ISetMovies extends grpc.MethodDefinition { 15 | path: string; // "/io.xtech.example.Example/SetMovies" 16 | requestStream: boolean; // false 17 | responseStream: boolean; // false 18 | requestSerialize: grpc.serialize; 19 | requestDeserialize: grpc.deserialize; 20 | responseSerialize: grpc.serialize; 21 | responseDeserialize: grpc.deserialize; 22 | } 23 | interface IExampleService_ISearchMoviesByCast extends grpc.MethodDefinition { 24 | path: string; // "/io.xtech.example.Example/SearchMoviesByCast" 25 | requestStream: boolean; // false 26 | responseStream: boolean; // true 27 | requestSerialize: grpc.serialize; 28 | requestDeserialize: grpc.deserialize; 29 | responseSerialize: grpc.serialize; 30 | responseDeserialize: grpc.deserialize; 31 | } 32 | 33 | export const ExampleService: IExampleService; 34 | 35 | export interface IExampleServer { 36 | setMovies: grpc.handleUnaryCall; 37 | searchMoviesByCast: grpc.handleServerStreamingCall; 38 | } 39 | 40 | export interface IExampleClient { 41 | setMovies(request: Example_pb.EmptyRequest, callback: (error: grpc.ServiceError | null, response: Example_pb.MoviesResult) => void): grpc.ClientUnaryCall; 42 | setMovies(request: Example_pb.EmptyRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: Example_pb.MoviesResult) => void): grpc.ClientUnaryCall; 43 | setMovies(request: Example_pb.EmptyRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: Example_pb.MoviesResult) => void): grpc.ClientUnaryCall; 44 | searchMoviesByCast(request: Example_pb.SearchByCastInput, options?: Partial): grpc.ClientReadableStream; 45 | searchMoviesByCast(request: Example_pb.SearchByCastInput, metadata?: grpc.Metadata, options?: Partial): grpc.ClientReadableStream; 46 | } 47 | 48 | export class ExampleClient extends grpc.Client implements IExampleClient { 49 | constructor(address: string, credentials: grpc.ChannelCredentials, options?: object); 50 | public setMovies(request: Example_pb.EmptyRequest, callback: (error: grpc.ServiceError | null, response: Example_pb.MoviesResult) => void): grpc.ClientUnaryCall; 51 | public setMovies(request: Example_pb.EmptyRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: Example_pb.MoviesResult) => void): grpc.ClientUnaryCall; 52 | public setMovies(request: Example_pb.EmptyRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: Example_pb.MoviesResult) => void): grpc.ClientUnaryCall; 53 | public searchMoviesByCast(request: Example_pb.SearchByCastInput, options?: Partial): grpc.ClientReadableStream; 54 | public searchMoviesByCast(request: Example_pb.SearchByCastInput, metadata?: grpc.Metadata, options?: Partial): grpc.ClientReadableStream; 55 | } 56 | -------------------------------------------------------------------------------- /example/grpc/src/proto/Example_grpc_pb.js: -------------------------------------------------------------------------------- 1 | // GENERATED CODE -- DO NOT EDIT! 2 | 3 | 'use strict'; 4 | var grpc = require('grpc'); 5 | var Example_pb = require('./Example_pb.js'); 6 | 7 | function serialize_io_xtech_example_EmptyRequest(arg) { 8 | if (!(arg instanceof Example_pb.EmptyRequest)) { 9 | throw new Error('Expected argument of type io.xtech.example.EmptyRequest'); 10 | } 11 | return new Buffer(arg.serializeBinary()); 12 | } 13 | 14 | function deserialize_io_xtech_example_EmptyRequest(buffer_arg) { 15 | return Example_pb.EmptyRequest.deserializeBinary(new Uint8Array(buffer_arg)); 16 | } 17 | 18 | function serialize_io_xtech_example_Movie(arg) { 19 | if (!(arg instanceof Example_pb.Movie)) { 20 | throw new Error('Expected argument of type io.xtech.example.Movie'); 21 | } 22 | return new Buffer(arg.serializeBinary()); 23 | } 24 | 25 | function deserialize_io_xtech_example_Movie(buffer_arg) { 26 | return Example_pb.Movie.deserializeBinary(new Uint8Array(buffer_arg)); 27 | } 28 | 29 | function serialize_io_xtech_example_MoviesResult(arg) { 30 | if (!(arg instanceof Example_pb.MoviesResult)) { 31 | throw new Error('Expected argument of type io.xtech.example.MoviesResult'); 32 | } 33 | return new Buffer(arg.serializeBinary()); 34 | } 35 | 36 | function deserialize_io_xtech_example_MoviesResult(buffer_arg) { 37 | return Example_pb.MoviesResult.deserializeBinary(new Uint8Array(buffer_arg)); 38 | } 39 | 40 | function serialize_io_xtech_example_SearchByCastInput(arg) { 41 | if (!(arg instanceof Example_pb.SearchByCastInput)) { 42 | throw new Error('Expected argument of type io.xtech.example.SearchByCastInput'); 43 | } 44 | return new Buffer(arg.serializeBinary()); 45 | } 46 | 47 | function deserialize_io_xtech_example_SearchByCastInput(buffer_arg) { 48 | return Example_pb.SearchByCastInput.deserializeBinary(new Uint8Array(buffer_arg)); 49 | } 50 | 51 | 52 | var ExampleService = exports.ExampleService = { 53 | setMovies: { 54 | path: '/io.xtech.example.Example/SetMovies', 55 | requestStream: false, 56 | responseStream: false, 57 | requestType: Example_pb.EmptyRequest, 58 | responseType: Example_pb.MoviesResult, 59 | requestSerialize: serialize_io_xtech_example_EmptyRequest, 60 | requestDeserialize: deserialize_io_xtech_example_EmptyRequest, 61 | responseSerialize: serialize_io_xtech_example_MoviesResult, 62 | responseDeserialize: deserialize_io_xtech_example_MoviesResult, 63 | }, 64 | searchMoviesByCast: { 65 | path: '/io.xtech.example.Example/SearchMoviesByCast', 66 | requestStream: false, 67 | responseStream: true, 68 | requestType: Example_pb.SearchByCastInput, 69 | responseType: Example_pb.Movie, 70 | requestSerialize: serialize_io_xtech_example_SearchByCastInput, 71 | requestDeserialize: deserialize_io_xtech_example_SearchByCastInput, 72 | responseSerialize: serialize_io_xtech_example_Movie, 73 | responseDeserialize: deserialize_io_xtech_example_Movie, 74 | }, 75 | }; 76 | 77 | exports.ExampleClient = grpc.makeGenericClientConstructor(ExampleService); 78 | -------------------------------------------------------------------------------- /example/grpc/src/proto/Example_pb.d.ts: -------------------------------------------------------------------------------- 1 | // package: io.xtech.example 2 | // file: Example.proto 3 | 4 | /* tslint:disable */ 5 | 6 | import * as jspb from "google-protobuf"; 7 | 8 | export class Movie extends jspb.Message { 9 | getName(): string; 10 | setName(value: string): void; 11 | 12 | getYear(): number; 13 | setYear(value: number): void; 14 | 15 | getRating(): number; 16 | setRating(value: number): void; 17 | 18 | clearCastList(): void; 19 | getCastList(): Array; 20 | setCastList(value: Array): void; 21 | addCast(value: string, index?: number): string; 22 | 23 | 24 | serializeBinary(): Uint8Array; 25 | toObject(includeInstance?: boolean): Movie.AsObject; 26 | static toObject(includeInstance: boolean, msg: Movie): Movie.AsObject; 27 | static extensions: {[key: number]: jspb.ExtensionFieldInfo}; 28 | static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; 29 | static serializeBinaryToWriter(message: Movie, writer: jspb.BinaryWriter): void; 30 | static deserializeBinary(bytes: Uint8Array): Movie; 31 | static deserializeBinaryFromReader(message: Movie, reader: jspb.BinaryReader): Movie; 32 | } 33 | 34 | export namespace Movie { 35 | export type AsObject = { 36 | name: string, 37 | year: number, 38 | rating: number, 39 | castList: Array, 40 | } 41 | } 42 | 43 | export class EmptyRequest extends jspb.Message { 44 | 45 | serializeBinary(): Uint8Array; 46 | toObject(includeInstance?: boolean): EmptyRequest.AsObject; 47 | static toObject(includeInstance: boolean, msg: EmptyRequest): EmptyRequest.AsObject; 48 | static extensions: {[key: number]: jspb.ExtensionFieldInfo}; 49 | static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; 50 | static serializeBinaryToWriter(message: EmptyRequest, writer: jspb.BinaryWriter): void; 51 | static deserializeBinary(bytes: Uint8Array): EmptyRequest; 52 | static deserializeBinaryFromReader(message: EmptyRequest, reader: jspb.BinaryReader): EmptyRequest; 53 | } 54 | 55 | export namespace EmptyRequest { 56 | export type AsObject = { 57 | } 58 | } 59 | 60 | export class SearchByCastInput extends jspb.Message { 61 | getCastname(): string; 62 | setCastname(value: string): void; 63 | 64 | 65 | serializeBinary(): Uint8Array; 66 | toObject(includeInstance?: boolean): SearchByCastInput.AsObject; 67 | static toObject(includeInstance: boolean, msg: SearchByCastInput): SearchByCastInput.AsObject; 68 | static extensions: {[key: number]: jspb.ExtensionFieldInfo}; 69 | static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; 70 | static serializeBinaryToWriter(message: SearchByCastInput, writer: jspb.BinaryWriter): void; 71 | static deserializeBinary(bytes: Uint8Array): SearchByCastInput; 72 | static deserializeBinaryFromReader(message: SearchByCastInput, reader: jspb.BinaryReader): SearchByCastInput; 73 | } 74 | 75 | export namespace SearchByCastInput { 76 | export type AsObject = { 77 | castname: string, 78 | } 79 | } 80 | 81 | export class MoviesResult extends jspb.Message { 82 | clearResultList(): void; 83 | getResultList(): Array; 84 | setResultList(value: Array): void; 85 | addResult(value?: Movie, index?: number): Movie; 86 | 87 | 88 | serializeBinary(): Uint8Array; 89 | toObject(includeInstance?: boolean): MoviesResult.AsObject; 90 | static toObject(includeInstance: boolean, msg: MoviesResult): MoviesResult.AsObject; 91 | static extensions: {[key: number]: jspb.ExtensionFieldInfo}; 92 | static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; 93 | static serializeBinaryToWriter(message: MoviesResult, writer: jspb.BinaryWriter): void; 94 | static deserializeBinary(bytes: Uint8Array): MoviesResult; 95 | static deserializeBinaryFromReader(message: MoviesResult, reader: jspb.BinaryReader): MoviesResult; 96 | } 97 | 98 | export namespace MoviesResult { 99 | export type AsObject = { 100 | resultList: Array, 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /example/grpc/src/proto/Example_pb.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview 3 | * @enhanceable 4 | * @suppress {messageConventions} JS Compiler reports an error if a variable or 5 | * field starts with 'MSG_' and isn't a translatable message. 6 | * @public 7 | */ 8 | // GENERATED CODE -- DO NOT EDIT! 9 | 10 | var jspb = require('google-protobuf'); 11 | var goog = jspb; 12 | var global = Function('return this')(); 13 | 14 | goog.exportSymbol('proto.io.xtech.example.EmptyRequest', null, global); 15 | goog.exportSymbol('proto.io.xtech.example.Movie', null, global); 16 | goog.exportSymbol('proto.io.xtech.example.MoviesResult', null, global); 17 | goog.exportSymbol('proto.io.xtech.example.SearchByCastInput', null, global); 18 | 19 | /** 20 | * Generated by JsPbCodeGenerator. 21 | * @param {Array=} opt_data Optional initial data array, typically from a 22 | * server response, or constructed directly in Javascript. The array is used 23 | * in place and becomes part of the constructed object. It is not cloned. 24 | * If no data is provided, the constructed object will be empty, but still 25 | * valid. 26 | * @extends {jspb.Message} 27 | * @constructor 28 | */ 29 | proto.io.xtech.example.Movie = function(opt_data) { 30 | jspb.Message.initialize(this, opt_data, 0, -1, proto.io.xtech.example.Movie.repeatedFields_, null); 31 | }; 32 | goog.inherits(proto.io.xtech.example.Movie, jspb.Message); 33 | if (goog.DEBUG && !COMPILED) { 34 | proto.io.xtech.example.Movie.displayName = 'proto.io.xtech.example.Movie'; 35 | } 36 | /** 37 | * List of repeated fields within this message type. 38 | * @private {!Array} 39 | * @const 40 | */ 41 | proto.io.xtech.example.Movie.repeatedFields_ = [4]; 42 | 43 | 44 | 45 | if (jspb.Message.GENERATE_TO_OBJECT) { 46 | /** 47 | * Creates an object representation of this proto suitable for use in Soy templates. 48 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 49 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 50 | * For the list of reserved names please see: 51 | * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. 52 | * @param {boolean=} opt_includeInstance Whether to include the JSPB instance 53 | * for transitional soy proto support: http://goto/soy-param-migration 54 | * @return {!Object} 55 | */ 56 | proto.io.xtech.example.Movie.prototype.toObject = function(opt_includeInstance) { 57 | return proto.io.xtech.example.Movie.toObject(opt_includeInstance, this); 58 | }; 59 | 60 | 61 | /** 62 | * Static version of the {@see toObject} method. 63 | * @param {boolean|undefined} includeInstance Whether to include the JSPB 64 | * instance for transitional soy proto support: 65 | * http://goto/soy-param-migration 66 | * @param {!proto.io.xtech.example.Movie} msg The msg instance to transform. 67 | * @return {!Object} 68 | * @suppress {unusedLocalVariables} f is only used for nested messages 69 | */ 70 | proto.io.xtech.example.Movie.toObject = function(includeInstance, msg) { 71 | var f, obj = { 72 | name: jspb.Message.getFieldWithDefault(msg, 1, ""), 73 | year: jspb.Message.getFieldWithDefault(msg, 2, 0), 74 | rating: +jspb.Message.getFieldWithDefault(msg, 3, 0.0), 75 | castList: jspb.Message.getRepeatedField(msg, 4) 76 | }; 77 | 78 | if (includeInstance) { 79 | obj.$jspbMessageInstance = msg; 80 | } 81 | return obj; 82 | }; 83 | } 84 | 85 | 86 | /** 87 | * Deserializes binary data (in protobuf wire format). 88 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 89 | * @return {!proto.io.xtech.example.Movie} 90 | */ 91 | proto.io.xtech.example.Movie.deserializeBinary = function(bytes) { 92 | var reader = new jspb.BinaryReader(bytes); 93 | var msg = new proto.io.xtech.example.Movie; 94 | return proto.io.xtech.example.Movie.deserializeBinaryFromReader(msg, reader); 95 | }; 96 | 97 | 98 | /** 99 | * Deserializes binary data (in protobuf wire format) from the 100 | * given reader into the given message object. 101 | * @param {!proto.io.xtech.example.Movie} msg The message object to deserialize into. 102 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 103 | * @return {!proto.io.xtech.example.Movie} 104 | */ 105 | proto.io.xtech.example.Movie.deserializeBinaryFromReader = function(msg, reader) { 106 | while (reader.nextField()) { 107 | if (reader.isEndGroup()) { 108 | break; 109 | } 110 | var field = reader.getFieldNumber(); 111 | switch (field) { 112 | case 1: 113 | var value = /** @type {string} */ (reader.readString()); 114 | msg.setName(value); 115 | break; 116 | case 2: 117 | var value = /** @type {number} */ (reader.readInt32()); 118 | msg.setYear(value); 119 | break; 120 | case 3: 121 | var value = /** @type {number} */ (reader.readFloat()); 122 | msg.setRating(value); 123 | break; 124 | case 4: 125 | var value = /** @type {string} */ (reader.readString()); 126 | msg.addCast(value); 127 | break; 128 | default: 129 | reader.skipField(); 130 | break; 131 | } 132 | } 133 | return msg; 134 | }; 135 | 136 | 137 | /** 138 | * Serializes the message to binary data (in protobuf wire format). 139 | * @return {!Uint8Array} 140 | */ 141 | proto.io.xtech.example.Movie.prototype.serializeBinary = function() { 142 | var writer = new jspb.BinaryWriter(); 143 | proto.io.xtech.example.Movie.serializeBinaryToWriter(this, writer); 144 | return writer.getResultBuffer(); 145 | }; 146 | 147 | 148 | /** 149 | * Serializes the given message to binary data (in protobuf wire 150 | * format), writing to the given BinaryWriter. 151 | * @param {!proto.io.xtech.example.Movie} message 152 | * @param {!jspb.BinaryWriter} writer 153 | * @suppress {unusedLocalVariables} f is only used for nested messages 154 | */ 155 | proto.io.xtech.example.Movie.serializeBinaryToWriter = function(message, writer) { 156 | var f = undefined; 157 | f = message.getName(); 158 | if (f.length > 0) { 159 | writer.writeString( 160 | 1, 161 | f 162 | ); 163 | } 164 | f = message.getYear(); 165 | if (f !== 0) { 166 | writer.writeInt32( 167 | 2, 168 | f 169 | ); 170 | } 171 | f = message.getRating(); 172 | if (f !== 0.0) { 173 | writer.writeFloat( 174 | 3, 175 | f 176 | ); 177 | } 178 | f = message.getCastList(); 179 | if (f.length > 0) { 180 | writer.writeRepeatedString( 181 | 4, 182 | f 183 | ); 184 | } 185 | }; 186 | 187 | 188 | /** 189 | * optional string name = 1; 190 | * @return {string} 191 | */ 192 | proto.io.xtech.example.Movie.prototype.getName = function() { 193 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); 194 | }; 195 | 196 | 197 | /** @param {string} value */ 198 | proto.io.xtech.example.Movie.prototype.setName = function(value) { 199 | jspb.Message.setField(this, 1, value); 200 | }; 201 | 202 | 203 | /** 204 | * optional int32 year = 2; 205 | * @return {number} 206 | */ 207 | proto.io.xtech.example.Movie.prototype.getYear = function() { 208 | return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); 209 | }; 210 | 211 | 212 | /** @param {number} value */ 213 | proto.io.xtech.example.Movie.prototype.setYear = function(value) { 214 | jspb.Message.setField(this, 2, value); 215 | }; 216 | 217 | 218 | /** 219 | * optional float rating = 3; 220 | * @return {number} 221 | */ 222 | proto.io.xtech.example.Movie.prototype.getRating = function() { 223 | return /** @type {number} */ (+jspb.Message.getFieldWithDefault(this, 3, 0.0)); 224 | }; 225 | 226 | 227 | /** @param {number} value */ 228 | proto.io.xtech.example.Movie.prototype.setRating = function(value) { 229 | jspb.Message.setField(this, 3, value); 230 | }; 231 | 232 | 233 | /** 234 | * repeated string cast = 4; 235 | * @return {!Array.} 236 | */ 237 | proto.io.xtech.example.Movie.prototype.getCastList = function() { 238 | return /** @type {!Array.} */ (jspb.Message.getRepeatedField(this, 4)); 239 | }; 240 | 241 | 242 | /** @param {!Array.} value */ 243 | proto.io.xtech.example.Movie.prototype.setCastList = function(value) { 244 | jspb.Message.setField(this, 4, value || []); 245 | }; 246 | 247 | 248 | /** 249 | * @param {!string} value 250 | * @param {number=} opt_index 251 | */ 252 | proto.io.xtech.example.Movie.prototype.addCast = function(value, opt_index) { 253 | jspb.Message.addToRepeatedField(this, 4, value, opt_index); 254 | }; 255 | 256 | 257 | proto.io.xtech.example.Movie.prototype.clearCastList = function() { 258 | this.setCastList([]); 259 | }; 260 | 261 | 262 | 263 | /** 264 | * Generated by JsPbCodeGenerator. 265 | * @param {Array=} opt_data Optional initial data array, typically from a 266 | * server response, or constructed directly in Javascript. The array is used 267 | * in place and becomes part of the constructed object. It is not cloned. 268 | * If no data is provided, the constructed object will be empty, but still 269 | * valid. 270 | * @extends {jspb.Message} 271 | * @constructor 272 | */ 273 | proto.io.xtech.example.EmptyRequest = function(opt_data) { 274 | jspb.Message.initialize(this, opt_data, 0, -1, null, null); 275 | }; 276 | goog.inherits(proto.io.xtech.example.EmptyRequest, jspb.Message); 277 | if (goog.DEBUG && !COMPILED) { 278 | proto.io.xtech.example.EmptyRequest.displayName = 'proto.io.xtech.example.EmptyRequest'; 279 | } 280 | 281 | 282 | if (jspb.Message.GENERATE_TO_OBJECT) { 283 | /** 284 | * Creates an object representation of this proto suitable for use in Soy templates. 285 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 286 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 287 | * For the list of reserved names please see: 288 | * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. 289 | * @param {boolean=} opt_includeInstance Whether to include the JSPB instance 290 | * for transitional soy proto support: http://goto/soy-param-migration 291 | * @return {!Object} 292 | */ 293 | proto.io.xtech.example.EmptyRequest.prototype.toObject = function(opt_includeInstance) { 294 | return proto.io.xtech.example.EmptyRequest.toObject(opt_includeInstance, this); 295 | }; 296 | 297 | 298 | /** 299 | * Static version of the {@see toObject} method. 300 | * @param {boolean|undefined} includeInstance Whether to include the JSPB 301 | * instance for transitional soy proto support: 302 | * http://goto/soy-param-migration 303 | * @param {!proto.io.xtech.example.EmptyRequest} msg The msg instance to transform. 304 | * @return {!Object} 305 | * @suppress {unusedLocalVariables} f is only used for nested messages 306 | */ 307 | proto.io.xtech.example.EmptyRequest.toObject = function(includeInstance, msg) { 308 | var f, obj = { 309 | 310 | }; 311 | 312 | if (includeInstance) { 313 | obj.$jspbMessageInstance = msg; 314 | } 315 | return obj; 316 | }; 317 | } 318 | 319 | 320 | /** 321 | * Deserializes binary data (in protobuf wire format). 322 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 323 | * @return {!proto.io.xtech.example.EmptyRequest} 324 | */ 325 | proto.io.xtech.example.EmptyRequest.deserializeBinary = function(bytes) { 326 | var reader = new jspb.BinaryReader(bytes); 327 | var msg = new proto.io.xtech.example.EmptyRequest; 328 | return proto.io.xtech.example.EmptyRequest.deserializeBinaryFromReader(msg, reader); 329 | }; 330 | 331 | 332 | /** 333 | * Deserializes binary data (in protobuf wire format) from the 334 | * given reader into the given message object. 335 | * @param {!proto.io.xtech.example.EmptyRequest} msg The message object to deserialize into. 336 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 337 | * @return {!proto.io.xtech.example.EmptyRequest} 338 | */ 339 | proto.io.xtech.example.EmptyRequest.deserializeBinaryFromReader = function(msg, reader) { 340 | while (reader.nextField()) { 341 | if (reader.isEndGroup()) { 342 | break; 343 | } 344 | var field = reader.getFieldNumber(); 345 | switch (field) { 346 | default: 347 | reader.skipField(); 348 | break; 349 | } 350 | } 351 | return msg; 352 | }; 353 | 354 | 355 | /** 356 | * Serializes the message to binary data (in protobuf wire format). 357 | * @return {!Uint8Array} 358 | */ 359 | proto.io.xtech.example.EmptyRequest.prototype.serializeBinary = function() { 360 | var writer = new jspb.BinaryWriter(); 361 | proto.io.xtech.example.EmptyRequest.serializeBinaryToWriter(this, writer); 362 | return writer.getResultBuffer(); 363 | }; 364 | 365 | 366 | /** 367 | * Serializes the given message to binary data (in protobuf wire 368 | * format), writing to the given BinaryWriter. 369 | * @param {!proto.io.xtech.example.EmptyRequest} message 370 | * @param {!jspb.BinaryWriter} writer 371 | * @suppress {unusedLocalVariables} f is only used for nested messages 372 | */ 373 | proto.io.xtech.example.EmptyRequest.serializeBinaryToWriter = function(message, writer) { 374 | var f = undefined; 375 | }; 376 | 377 | 378 | 379 | /** 380 | * Generated by JsPbCodeGenerator. 381 | * @param {Array=} opt_data Optional initial data array, typically from a 382 | * server response, or constructed directly in Javascript. The array is used 383 | * in place and becomes part of the constructed object. It is not cloned. 384 | * If no data is provided, the constructed object will be empty, but still 385 | * valid. 386 | * @extends {jspb.Message} 387 | * @constructor 388 | */ 389 | proto.io.xtech.example.SearchByCastInput = function(opt_data) { 390 | jspb.Message.initialize(this, opt_data, 0, -1, null, null); 391 | }; 392 | goog.inherits(proto.io.xtech.example.SearchByCastInput, jspb.Message); 393 | if (goog.DEBUG && !COMPILED) { 394 | proto.io.xtech.example.SearchByCastInput.displayName = 'proto.io.xtech.example.SearchByCastInput'; 395 | } 396 | 397 | 398 | if (jspb.Message.GENERATE_TO_OBJECT) { 399 | /** 400 | * Creates an object representation of this proto suitable for use in Soy templates. 401 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 402 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 403 | * For the list of reserved names please see: 404 | * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. 405 | * @param {boolean=} opt_includeInstance Whether to include the JSPB instance 406 | * for transitional soy proto support: http://goto/soy-param-migration 407 | * @return {!Object} 408 | */ 409 | proto.io.xtech.example.SearchByCastInput.prototype.toObject = function(opt_includeInstance) { 410 | return proto.io.xtech.example.SearchByCastInput.toObject(opt_includeInstance, this); 411 | }; 412 | 413 | 414 | /** 415 | * Static version of the {@see toObject} method. 416 | * @param {boolean|undefined} includeInstance Whether to include the JSPB 417 | * instance for transitional soy proto support: 418 | * http://goto/soy-param-migration 419 | * @param {!proto.io.xtech.example.SearchByCastInput} msg The msg instance to transform. 420 | * @return {!Object} 421 | * @suppress {unusedLocalVariables} f is only used for nested messages 422 | */ 423 | proto.io.xtech.example.SearchByCastInput.toObject = function(includeInstance, msg) { 424 | var f, obj = { 425 | castname: jspb.Message.getFieldWithDefault(msg, 1, "") 426 | }; 427 | 428 | if (includeInstance) { 429 | obj.$jspbMessageInstance = msg; 430 | } 431 | return obj; 432 | }; 433 | } 434 | 435 | 436 | /** 437 | * Deserializes binary data (in protobuf wire format). 438 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 439 | * @return {!proto.io.xtech.example.SearchByCastInput} 440 | */ 441 | proto.io.xtech.example.SearchByCastInput.deserializeBinary = function(bytes) { 442 | var reader = new jspb.BinaryReader(bytes); 443 | var msg = new proto.io.xtech.example.SearchByCastInput; 444 | return proto.io.xtech.example.SearchByCastInput.deserializeBinaryFromReader(msg, reader); 445 | }; 446 | 447 | 448 | /** 449 | * Deserializes binary data (in protobuf wire format) from the 450 | * given reader into the given message object. 451 | * @param {!proto.io.xtech.example.SearchByCastInput} msg The message object to deserialize into. 452 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 453 | * @return {!proto.io.xtech.example.SearchByCastInput} 454 | */ 455 | proto.io.xtech.example.SearchByCastInput.deserializeBinaryFromReader = function(msg, reader) { 456 | while (reader.nextField()) { 457 | if (reader.isEndGroup()) { 458 | break; 459 | } 460 | var field = reader.getFieldNumber(); 461 | switch (field) { 462 | case 1: 463 | var value = /** @type {string} */ (reader.readString()); 464 | msg.setCastname(value); 465 | break; 466 | default: 467 | reader.skipField(); 468 | break; 469 | } 470 | } 471 | return msg; 472 | }; 473 | 474 | 475 | /** 476 | * Serializes the message to binary data (in protobuf wire format). 477 | * @return {!Uint8Array} 478 | */ 479 | proto.io.xtech.example.SearchByCastInput.prototype.serializeBinary = function() { 480 | var writer = new jspb.BinaryWriter(); 481 | proto.io.xtech.example.SearchByCastInput.serializeBinaryToWriter(this, writer); 482 | return writer.getResultBuffer(); 483 | }; 484 | 485 | 486 | /** 487 | * Serializes the given message to binary data (in protobuf wire 488 | * format), writing to the given BinaryWriter. 489 | * @param {!proto.io.xtech.example.SearchByCastInput} message 490 | * @param {!jspb.BinaryWriter} writer 491 | * @suppress {unusedLocalVariables} f is only used for nested messages 492 | */ 493 | proto.io.xtech.example.SearchByCastInput.serializeBinaryToWriter = function(message, writer) { 494 | var f = undefined; 495 | f = message.getCastname(); 496 | if (f.length > 0) { 497 | writer.writeString( 498 | 1, 499 | f 500 | ); 501 | } 502 | }; 503 | 504 | 505 | /** 506 | * optional string castName = 1; 507 | * @return {string} 508 | */ 509 | proto.io.xtech.example.SearchByCastInput.prototype.getCastname = function() { 510 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); 511 | }; 512 | 513 | 514 | /** @param {string} value */ 515 | proto.io.xtech.example.SearchByCastInput.prototype.setCastname = function(value) { 516 | jspb.Message.setField(this, 1, value); 517 | }; 518 | 519 | 520 | 521 | /** 522 | * Generated by JsPbCodeGenerator. 523 | * @param {Array=} opt_data Optional initial data array, typically from a 524 | * server response, or constructed directly in Javascript. The array is used 525 | * in place and becomes part of the constructed object. It is not cloned. 526 | * If no data is provided, the constructed object will be empty, but still 527 | * valid. 528 | * @extends {jspb.Message} 529 | * @constructor 530 | */ 531 | proto.io.xtech.example.MoviesResult = function(opt_data) { 532 | jspb.Message.initialize(this, opt_data, 0, -1, proto.io.xtech.example.MoviesResult.repeatedFields_, null); 533 | }; 534 | goog.inherits(proto.io.xtech.example.MoviesResult, jspb.Message); 535 | if (goog.DEBUG && !COMPILED) { 536 | proto.io.xtech.example.MoviesResult.displayName = 'proto.io.xtech.example.MoviesResult'; 537 | } 538 | /** 539 | * List of repeated fields within this message type. 540 | * @private {!Array} 541 | * @const 542 | */ 543 | proto.io.xtech.example.MoviesResult.repeatedFields_ = [1]; 544 | 545 | 546 | 547 | if (jspb.Message.GENERATE_TO_OBJECT) { 548 | /** 549 | * Creates an object representation of this proto suitable for use in Soy templates. 550 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 551 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 552 | * For the list of reserved names please see: 553 | * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. 554 | * @param {boolean=} opt_includeInstance Whether to include the JSPB instance 555 | * for transitional soy proto support: http://goto/soy-param-migration 556 | * @return {!Object} 557 | */ 558 | proto.io.xtech.example.MoviesResult.prototype.toObject = function(opt_includeInstance) { 559 | return proto.io.xtech.example.MoviesResult.toObject(opt_includeInstance, this); 560 | }; 561 | 562 | 563 | /** 564 | * Static version of the {@see toObject} method. 565 | * @param {boolean|undefined} includeInstance Whether to include the JSPB 566 | * instance for transitional soy proto support: 567 | * http://goto/soy-param-migration 568 | * @param {!proto.io.xtech.example.MoviesResult} msg The msg instance to transform. 569 | * @return {!Object} 570 | * @suppress {unusedLocalVariables} f is only used for nested messages 571 | */ 572 | proto.io.xtech.example.MoviesResult.toObject = function(includeInstance, msg) { 573 | var f, obj = { 574 | resultList: jspb.Message.toObjectList(msg.getResultList(), 575 | proto.io.xtech.example.Movie.toObject, includeInstance) 576 | }; 577 | 578 | if (includeInstance) { 579 | obj.$jspbMessageInstance = msg; 580 | } 581 | return obj; 582 | }; 583 | } 584 | 585 | 586 | /** 587 | * Deserializes binary data (in protobuf wire format). 588 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 589 | * @return {!proto.io.xtech.example.MoviesResult} 590 | */ 591 | proto.io.xtech.example.MoviesResult.deserializeBinary = function(bytes) { 592 | var reader = new jspb.BinaryReader(bytes); 593 | var msg = new proto.io.xtech.example.MoviesResult; 594 | return proto.io.xtech.example.MoviesResult.deserializeBinaryFromReader(msg, reader); 595 | }; 596 | 597 | 598 | /** 599 | * Deserializes binary data (in protobuf wire format) from the 600 | * given reader into the given message object. 601 | * @param {!proto.io.xtech.example.MoviesResult} msg The message object to deserialize into. 602 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 603 | * @return {!proto.io.xtech.example.MoviesResult} 604 | */ 605 | proto.io.xtech.example.MoviesResult.deserializeBinaryFromReader = function(msg, reader) { 606 | while (reader.nextField()) { 607 | if (reader.isEndGroup()) { 608 | break; 609 | } 610 | var field = reader.getFieldNumber(); 611 | switch (field) { 612 | case 1: 613 | var value = new proto.io.xtech.example.Movie; 614 | reader.readMessage(value,proto.io.xtech.example.Movie.deserializeBinaryFromReader); 615 | msg.addResult(value); 616 | break; 617 | default: 618 | reader.skipField(); 619 | break; 620 | } 621 | } 622 | return msg; 623 | }; 624 | 625 | 626 | /** 627 | * Serializes the message to binary data (in protobuf wire format). 628 | * @return {!Uint8Array} 629 | */ 630 | proto.io.xtech.example.MoviesResult.prototype.serializeBinary = function() { 631 | var writer = new jspb.BinaryWriter(); 632 | proto.io.xtech.example.MoviesResult.serializeBinaryToWriter(this, writer); 633 | return writer.getResultBuffer(); 634 | }; 635 | 636 | 637 | /** 638 | * Serializes the given message to binary data (in protobuf wire 639 | * format), writing to the given BinaryWriter. 640 | * @param {!proto.io.xtech.example.MoviesResult} message 641 | * @param {!jspb.BinaryWriter} writer 642 | * @suppress {unusedLocalVariables} f is only used for nested messages 643 | */ 644 | proto.io.xtech.example.MoviesResult.serializeBinaryToWriter = function(message, writer) { 645 | var f = undefined; 646 | f = message.getResultList(); 647 | if (f.length > 0) { 648 | writer.writeRepeatedMessage( 649 | 1, 650 | f, 651 | proto.io.xtech.example.Movie.serializeBinaryToWriter 652 | ); 653 | } 654 | }; 655 | 656 | 657 | /** 658 | * repeated Movie result = 1; 659 | * @return {!Array.} 660 | */ 661 | proto.io.xtech.example.MoviesResult.prototype.getResultList = function() { 662 | return /** @type{!Array.} */ ( 663 | jspb.Message.getRepeatedWrapperField(this, proto.io.xtech.example.Movie, 1)); 664 | }; 665 | 666 | 667 | /** @param {!Array.} value */ 668 | proto.io.xtech.example.MoviesResult.prototype.setResultList = function(value) { 669 | jspb.Message.setRepeatedWrapperField(this, 1, value); 670 | }; 671 | 672 | 673 | /** 674 | * @param {!proto.io.xtech.example.Movie=} opt_value 675 | * @param {number=} opt_index 676 | * @return {!proto.io.xtech.example.Movie} 677 | */ 678 | proto.io.xtech.example.MoviesResult.prototype.addResult = function(opt_value, opt_index) { 679 | return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.io.xtech.example.Movie, opt_index); 680 | }; 681 | 682 | 683 | proto.io.xtech.example.MoviesResult.prototype.clearResultList = function() { 684 | this.setResultList([]); 685 | }; 686 | 687 | 688 | goog.object.extend(exports, proto.io.xtech.example); 689 | -------------------------------------------------------------------------------- /example/grpc/src/server.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import * as debug from "debug"; 4 | import * as grpc from "grpc"; 5 | 6 | import { ExampleService, IExampleServer } from "./proto/Example_grpc_pb"; 7 | import { EmptyRequest, Movie, MoviesResult, SearchByCastInput } from "./proto/Example_pb"; 8 | 9 | const log = debug("SampleServer"); 10 | 11 | interface IRawMovie { 12 | cast: string[]; 13 | name: string; 14 | rating: number; 15 | year: number; 16 | } 17 | 18 | const Movies = [ 19 | { 20 | cast: ["Tom Cruise", "Simon Pegg", "Jeremy Renner"], 21 | name: "Mission: Impossible Rogue Nation", 22 | rating: 0.97, 23 | year: 2015, 24 | }, 25 | { 26 | cast: ["Tom Cruise", "Simon Pegg", "Henry Cavill"], 27 | name: "Mission: Impossible - Fallout", 28 | rating: 0.93, 29 | year: 2018, 30 | }, 31 | { 32 | cast: ["Leonardo DiCaprio", "Jonah Hill", "Margot Robbie"], 33 | name: "The Wolf of Wall Street", 34 | rating: 0.78, 35 | year: 2013, 36 | }, 37 | ]; 38 | 39 | function createMovie(movie: IRawMovie): Movie { 40 | const result = new Movie(); 41 | 42 | result.setCastList(movie.cast); 43 | result.setName(movie.name); 44 | result.setYear(movie.year); 45 | result.setRating(movie.rating); 46 | 47 | return result; 48 | } 49 | 50 | class ServerImpl implements IExampleServer { 51 | public getMovies(request: grpc.ServerUnaryCall, callback: grpc.sendUnaryData) { 52 | const result = new MoviesResult(); 53 | Movies.map(createMovie).forEach((movie: Movie) => result.addResult(movie)); 54 | callback(null, result); 55 | } 56 | 57 | public searchMoviesByCast(call: grpc.ServerWriteableStream) { 58 | log("call started"); 59 | const input: SearchByCastInput = call.request; 60 | let i: number = 1; 61 | call.on("error", (error) => { 62 | log(error); 63 | call.end(); 64 | }); 65 | Movies.map(createMovie).forEach((movie: Movie) => { 66 | if (movie.getCastList().indexOf(input.getCastname()) > -1) { 67 | setTimeout(() => { 68 | log(movie.getName()); 69 | call.write(movie); 70 | }, i * 1000); 71 | i += 1; 72 | } 73 | }); 74 | setTimeout(() => { 75 | call.end(); 76 | log("call ended"); 77 | }, 3000); 78 | } 79 | } 80 | 81 | function startServer() { 82 | const server = new grpc.Server(); 83 | 84 | server.addService(ExampleService, new ServerImpl()); 85 | server.bind("0.0.0.0:50051", grpc.ServerCredentials.createInsecure()); 86 | server.start(); 87 | 88 | log("Server started, listening: 0.0.0.0:50051"); 89 | } 90 | 91 | startServer(); 92 | 93 | process.on("uncaughtException", (err) => { 94 | log(`process on uncaughtException error: ${err}`); 95 | }); 96 | 97 | process.on("unhandledRejection", (err) => { 98 | log(`process on unhandledRejection error: ${err}`); 99 | }); 100 | -------------------------------------------------------------------------------- /example/grpc/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": [ 4 | "es2015", 5 | "esnext.asynciterable" 6 | ], 7 | "target": "ES6", 8 | "module": "commonjs", 9 | "sourceMap": true, 10 | "declaration": true, 11 | "rootDir": "src", 12 | "outDir": "build", 13 | "experimentalDecorators": true, 14 | "emitDecoratorMetadata": true 15 | }, 16 | "include": [ 17 | "src/*" 18 | ], 19 | "exclude": [ 20 | "node_modules" 21 | ] 22 | } -------------------------------------------------------------------------------- /example/grpc/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": [ 4 | "tslint:recommended" 5 | ], 6 | "jsRules": {}, 7 | "rules": {}, 8 | "rulesDirectory": [] 9 | } -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const { GraphQLServer, PubSub } = require('graphql-yoga'); 3 | const { printSchema } = require('graphql'); 4 | const { getGraphqlSchemaFromGrpc } = require('grpc-graphql-schema'); 5 | 6 | getGraphqlSchemaFromGrpc({ 7 | endpoint: 'localhost:50051', 8 | protoFilePath: path.resolve(__dirname, 'grpc', 'proto', 'Example.proto'), 9 | serviceName: 'Example', 10 | packageName: 'io.xtech.example', 11 | }).then((schema) => { 12 | console.log(printSchema(schema)); 13 | const pubsub = new PubSub(); 14 | const server = new GraphQLServer({ 15 | schema, 16 | context: { 17 | pubsub, 18 | }, 19 | }); 20 | server.start({ 21 | port: 4000, 22 | }, () => console.log('server started on port 4000')); 23 | }); -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "grpc-graphql-schema-example", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "author": "Simon Liang", 6 | "license": "MIT", 7 | "private": false, 8 | "scripts": { 9 | "start": "node ." 10 | }, 11 | "dependencies": { 12 | "graphql": "^14.0.2", 13 | "graphql-tools": "^4.0.3", 14 | "graphql-yoga": "^1.16.9", 15 | "grpc-graphql-schema": "^0.0.7" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /example/schema.graphql: -------------------------------------------------------------------------------- 1 | type Movie { 2 | name: String 3 | year: Int 4 | rating: Float 5 | cast: [String] 6 | } 7 | 8 | type MoviesResult { 9 | result: [Movie] 10 | } 11 | 12 | type Query { 13 | ping: ServerStatus 14 | ExampleGetMovies: MoviesResult 15 | } 16 | 17 | input SearchByCastInput { 18 | castName: String 19 | } 20 | 21 | type ServerStatus { 22 | status: String 23 | } 24 | 25 | type Subscription { 26 | ExampleSearchMoviesByCast(SearchByCastInput: SearchByCastInput): Movie 27 | } -------------------------------------------------------------------------------- /grpcgraphql.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xanthous-tech/grpc-graphql-schema/06c97e7a879045ba81f499aade9409048297cf8f/grpcgraphql.png -------------------------------------------------------------------------------- /lib/index.d.ts: -------------------------------------------------------------------------------- 1 | import { GraphQLSchema } from 'graphql'; 2 | import { GrpcGraphqlSchemaConfiguration } from './types'; 3 | export { getGraphqlQueriesFromProtoService, getGraphqlMutationsFromProtoService, getGraphQlSubscriptionsFromProtoService, } from './service_converter'; 4 | export { convertGrpcTypeToGraphqlType, getGraphqlTypeFromProtoDefinition, } from './type_converter'; 5 | export { GRPC_GQL_TYPE_MAPPING, GrpcGraphqlSchemaConfiguration, typeDefinitionCache, } from './types'; 6 | export declare function getGraphqlSchemaFromGrpc({ endpoint, protoFilePath, serviceName, packageName, }: GrpcGraphqlSchemaConfiguration): Promise; 7 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | return new (P || (P = Promise))(function (resolve, reject) { 4 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 5 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 6 | function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } 7 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 8 | }); 9 | }; 10 | Object.defineProperty(exports, "__esModule", { value: true }); 11 | const grpcCaller = require("grpc-caller"); 12 | const graphql_1 = require("graphql"); 13 | const type_converter_1 = require("./type_converter"); 14 | const service_converter_1 = require("./service_converter"); 15 | const protobuf_1 = require("./protobuf"); 16 | var service_converter_2 = require("./service_converter"); 17 | exports.getGraphqlQueriesFromProtoService = service_converter_2.getGraphqlQueriesFromProtoService; 18 | exports.getGraphqlMutationsFromProtoService = service_converter_2.getGraphqlMutationsFromProtoService; 19 | exports.getGraphQlSubscriptionsFromProtoService = service_converter_2.getGraphQlSubscriptionsFromProtoService; 20 | var type_converter_2 = require("./type_converter"); 21 | exports.convertGrpcTypeToGraphqlType = type_converter_2.convertGrpcTypeToGraphqlType; 22 | exports.getGraphqlTypeFromProtoDefinition = type_converter_2.getGraphqlTypeFromProtoDefinition; 23 | var types_1 = require("./types"); 24 | exports.GRPC_GQL_TYPE_MAPPING = types_1.GRPC_GQL_TYPE_MAPPING; 25 | exports.typeDefinitionCache = types_1.typeDefinitionCache; 26 | function getGraphqlSchemaFromGrpc({ endpoint, protoFilePath, serviceName, packageName, }) { 27 | return __awaiter(this, void 0, void 0, function* () { 28 | const client = grpcCaller(endpoint, protoFilePath, serviceName, null, { 29 | 'grpc.max_send_message_length': -1, 30 | 'grpc.max_receive_message_length': -1, 31 | }); 32 | const { nested } = yield protobuf_1.getPackageProtoDefinition(protoFilePath, packageName); 33 | const types = Object.keys(nested) 34 | .filter((key) => 'fields' in nested[key]) 35 | .reduce((acc, key) => { 36 | const definition = nested[key]; 37 | // skip empty 38 | if (key.startsWith('Empty')) { 39 | return acc; 40 | } 41 | if (definition.fields) { 42 | return acc.concat([ 43 | type_converter_1.getGraphqlTypeFromProtoDefinition({ 44 | definition: definition, 45 | typeName: key, 46 | }), 47 | ]); 48 | } 49 | return acc; 50 | }, []); 51 | const query = Object.keys(nested) 52 | .filter((key) => 'methods' in nested[key] && key === serviceName) 53 | .reduce((__, key) => { 54 | const definition = nested[key]; 55 | return service_converter_1.getGraphqlQueriesFromProtoService({ 56 | client, 57 | definition, 58 | serviceName: key, 59 | }); 60 | }, null); 61 | const mutation = Object.keys(nested) 62 | .filter((key) => 'methods' in nested[key] && key === serviceName) 63 | .reduce((__, key) => { 64 | const definition = nested[key]; 65 | return service_converter_1.getGraphqlMutationsFromProtoService({ 66 | client, 67 | definition, 68 | serviceName: key, 69 | }); 70 | }, null); 71 | const subscription = Object.keys(nested) 72 | .filter(key => 'methods' in nested[key] && key === serviceName) 73 | .reduce((__, key) => { 74 | const definition = nested[key]; 75 | return service_converter_1.getGraphQlSubscriptionsFromProtoService({ 76 | client, 77 | definition, 78 | serviceName: key, 79 | }); 80 | }, null); 81 | return new graphql_1.GraphQLSchema({ 82 | types, 83 | query, 84 | mutation, 85 | subscription, 86 | }); 87 | }); 88 | } 89 | exports.getGraphqlSchemaFromGrpc = getGraphqlSchemaFromGrpc; 90 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /lib/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;AAEA,0CAA0C;AAC1C,qCAIiB;AAGjB,qDAAqE;AACrE,2DAI6B;AAC7B,yCAAuD;AAEvD,yDAI6B;AAH3B,gEAAA,iCAAiC,CAAA;AACjC,kEAAA,mCAAmC,CAAA;AACnC,sEAAA,uCAAuC,CAAA;AAGzC,mDAG0B;AAFxB,wDAAA,4BAA4B,CAAA;AAC5B,6DAAA,iCAAiC,CAAA;AAEnC,iCAIiB;AAHf,wCAAA,qBAAqB,CAAA;AAErB,sCAAA,mBAAmB,CAAA;AAKrB,SAAsB,wBAAwB,CAAC,EAC7C,QAAQ,EACR,aAAa,EACb,WAAW,EACX,WAAW,GACoB;;QAC/B,MAAM,MAAM,GAAG,UAAU,CACvB,QAAQ,EACR,aAAa,EACb,WAAW,EACX,IAAI,EACJ;YACE,8BAA8B,EAAE,CAAC,CAAC;YAClC,iCAAiC,EAAE,CAAC,CAAC;SACtC,CACF,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GACd,MAAM,oCAAyB,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;QAE9D,MAAM,KAAK,GAAwB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;aACnD,MAAM,CAAC,CAAC,GAAW,EAAE,EAAE,CAAC,QAAQ,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;aAChD,MAAM,CACL,CAAC,GAAwB,EAAE,GAAW,EAAE,EAAE;YACxC,MAAM,UAAU,GAA6B,MAAM,CAAC,GAAG,CAAC,CAAC;YAEzD,aAAa;YACb,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE;gBAC3B,OAAO,GAAG,CAAC;aACZ;YAED,IAAqB,UAAW,CAAC,MAAM,EAAE;gBACvC,OAAO,GAAG,CAAC,MAAM,CAAC;oBAChB,kDAAiC,CAAC;wBAChC,UAAU,EAAmB,UAAW;wBACxC,QAAQ,EAAE,GAAG;qBACd,CAAC;iBACH,CAAC,CAAC;aACJ;YAED,OAAO,GAAG,CAAC;QACb,CAAC,EACD,EAAE,CACH,CAAC;QAEJ,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;aAC9B,MAAM,CAAC,CAAC,GAAW,EAAE,EAAE,CAAC,SAAS,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,WAAW,CAAC;aACxE,MAAM,CACL,CAAC,EAAO,EAAE,GAAW,EAA4B,EAAE;YACjD,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YAE/B,OAAO,qDAAiC,CAAC;gBACvC,MAAM;gBACN,UAAU;gBACV,WAAW,EAAE,GAAG;aACjB,CAAC,CAAC;QACL,CAAC,EACD,IAAI,CACL,CAAC;QAEJ,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;aACjC,MAAM,CAAC,CAAC,GAAW,EAAE,EAAE,CAAC,SAAS,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,WAAW,CAAC;aACxE,MAAM,CACL,CAAC,EAAO,EAAE,GAAW,EAA4B,EAAE;YACjD,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YAE/B,OAAO,uDAAmC,CAAC;gBACzC,MAAM;gBACN,UAAU;gBACV,WAAW,EAAE,GAAG;aACjB,CAAC,CAAC;QACL,CAAC,EACD,IAAI,CACL,CAAC;QAEJ,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;aACrC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,WAAW,CAAC;aAC9D,MAAM,CACL,CAAC,EAAO,EAAE,GAAW,EAA4B,EAAE;YACjD,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YAE/B,OAAO,2DAAuC,CAAC;gBAC7C,MAAM;gBACN,UAAU;gBACV,WAAW,EAAE,GAAG;aACjB,CAAC,CAAC;QACL,CAAC,EACD,IAAI,CACL,CAAC;QAEJ,OAAO,IAAI,uBAAa,CAAC;YACvB,KAAK;YACL,KAAK;YACL,QAAQ;YACR,YAAY;SACb,CAAC,CAAC;IACL,CAAC;CAAA;AAhGD,4DAgGC"} -------------------------------------------------------------------------------- /lib/protobuf.d.ts: -------------------------------------------------------------------------------- 1 | import * as protobuf from 'protobufjs'; 2 | export declare function getPackageProtoDefinition(protoFile: string, packageName: string): Promise; 3 | -------------------------------------------------------------------------------- /lib/protobuf.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | return new (P || (P = Promise))(function (resolve, reject) { 4 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 5 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 6 | function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } 7 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 8 | }); 9 | }; 10 | Object.defineProperty(exports, "__esModule", { value: true }); 11 | const _ = require("lodash"); 12 | const protobuf = require("protobufjs"); 13 | function getPackageProtoDefinition(protoFile, packageName) { 14 | return __awaiter(this, void 0, void 0, function* () { 15 | const protoDefinition = yield protobuf.load(protoFile); 16 | const protoDefinitionObject = yield protoDefinition.toJSON({ 17 | keepComments: true, 18 | }); 19 | const packagePaths = packageName.split('.'); 20 | for (let i = 0; i < packagePaths.length; i += 2) { 21 | packagePaths.splice(i, 0, 'nested'); 22 | } 23 | return _.get(protoDefinitionObject, packagePaths.join('.')); 24 | }); 25 | } 26 | exports.getPackageProtoDefinition = getPackageProtoDefinition; 27 | //# sourceMappingURL=protobuf.js.map -------------------------------------------------------------------------------- /lib/protobuf.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"protobuf.js","sourceRoot":"","sources":["../src/protobuf.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,4BAA4B;AAC5B,uCAAuC;AAEvC,SAAsB,yBAAyB,CAC7C,SAAiB,EACjB,WAAmB;;QAEnB,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACvD,MAAM,qBAAqB,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC;YACzD,YAAY,EAAE,IAAI;SACnB,CAAC,CAAC;QACH,MAAM,YAAY,GAAa,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAEtD,KAAK,IAAI,CAAC,GAAW,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE;YACvD,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;SACrC;QAED,OAAO,CAAC,CAAC,GAAG,CAAC,qBAAqB,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9D,CAAC;CAAA;AAfD,8DAeC"} -------------------------------------------------------------------------------- /lib/service_converter.d.ts: -------------------------------------------------------------------------------- 1 | import { GraphQLObjectType } from 'graphql'; 2 | export declare function getGraphqlQueriesFromProtoService({ definition, serviceName, client, }: { 3 | definition: any; 4 | serviceName: any; 5 | client: any; 6 | }): GraphQLObjectType; 7 | export declare function getGraphqlMutationsFromProtoService({ definition, serviceName, client, }: { 8 | definition: any; 9 | serviceName: any; 10 | client: any; 11 | }): GraphQLObjectType; 12 | export declare function getGraphQlSubscriptionsFromProtoService({ definition, serviceName, client, }: { 13 | definition: any; 14 | serviceName: any; 15 | client: any; 16 | }): GraphQLObjectType; 17 | -------------------------------------------------------------------------------- /lib/service_converter.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | return new (P || (P = Promise))(function (resolve, reject) { 4 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 5 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 6 | function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } 7 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 8 | }); 9 | }; 10 | Object.defineProperty(exports, "__esModule", { value: true }); 11 | const _ = require("lodash"); 12 | const graphql_1 = require("graphql"); 13 | const subscription_1 = require("./subscription"); 14 | const type_converter_1 = require("./type_converter"); 15 | const types_1 = require("./types"); 16 | function getGraphqlMethodsFromProtoService({ definition, serviceName, client, methodType, }) { 17 | const { methods } = definition; 18 | const fields = () => Object.keys(methods).reduce((result, methodName) => { 19 | const args = {}; 20 | const { requestType: requestArgName, responseType, responseStream, comment, } = methods[methodName]; 21 | if (responseStream) { 22 | // responseStream should be in subscriptions 23 | return result; 24 | } 25 | // filter for mutations 26 | if (methodType === 'Mutation' && !methodName.startsWith('Set')) { 27 | return result; 28 | } 29 | // filter out ping for mutation 30 | if (methodType === 'Mutation' && methodName === 'ping') { 31 | return result; 32 | } 33 | if (!requestArgName.startsWith('Empty')) { 34 | args[requestArgName] = { 35 | type: types_1.typeDefinitionCache[requestArgName], 36 | }; 37 | } 38 | const queryField = { 39 | args, 40 | type: types_1.typeDefinitionCache[responseType], 41 | description: comment, 42 | resolve: (__, arg) => __awaiter(this, void 0, void 0, function* () { 43 | const response = yield client[methodName](arg[requestArgName] || {}, {}, { 44 | deadline: Date.now() + (Number(process.env.REQUEST_TIMEOUT) || 200000), 45 | }); 46 | // FIXME: there is a bug in the graphQL type conversion 47 | return response; 48 | // return convertGrpcTypeToGraphqlType( 49 | // response, 50 | // typeDefinitionCache[responseType], 51 | // ); 52 | }), 53 | }; 54 | // eslint-disable-next-line no-param-reassign 55 | result[`${serviceName}${methodName}`] = queryField; 56 | return result; 57 | }, (methodType === 'Mutation') ? {} : { 58 | // adding a default ping 59 | ping: { 60 | type: types_1.typeDefinitionCache.ServerStatus, 61 | description: 'query for getting server status', 62 | resolve: () => ({ status: 'online' }), 63 | }, 64 | }); 65 | if (_.isEmpty(fields())) { 66 | return null; 67 | } 68 | return new graphql_1.GraphQLObjectType({ 69 | fields, 70 | name: methodType, 71 | }); 72 | } 73 | function getGraphqlQueriesFromProtoService({ definition, serviceName, client, }) { 74 | return getGraphqlMethodsFromProtoService({ 75 | definition, 76 | serviceName, 77 | client, 78 | methodType: 'Query', 79 | }); 80 | } 81 | exports.getGraphqlQueriesFromProtoService = getGraphqlQueriesFromProtoService; 82 | function getGraphqlMutationsFromProtoService({ definition, serviceName, client, }) { 83 | return getGraphqlMethodsFromProtoService({ 84 | definition, 85 | serviceName, 86 | client, 87 | methodType: 'Mutation', 88 | }); 89 | } 90 | exports.getGraphqlMutationsFromProtoService = getGraphqlMutationsFromProtoService; 91 | function getGraphQlSubscriptionsFromProtoService({ definition, serviceName, client, }) { 92 | const { methods } = definition; 93 | const fields = () => Object.keys(methods).reduce((result, methodName) => { 94 | const args = {}; 95 | const { requestType: requestArgName, responseType, responseStream, comment, } = methods[methodName]; 96 | if (!responseStream) { 97 | // non-responseStream should be in queries / mutations 98 | return result; 99 | } 100 | if (!requestArgName.startsWith('Empty')) { 101 | args[requestArgName] = { 102 | type: types_1.typeDefinitionCache[requestArgName], 103 | }; 104 | } 105 | const subscribeField = { 106 | args, 107 | type: types_1.typeDefinitionCache[responseType], 108 | description: comment, 109 | subscribe: (__, arg, { pubsub }) => __awaiter(this, void 0, void 0, function* () { 110 | const response = yield client[methodName](arg[requestArgName] || {}, {}); 111 | response.on('data', (data) => { 112 | const payload = {}; 113 | payload[`${serviceName}${methodName}`] = type_converter_1.convertGrpcTypeToGraphqlType(data, types_1.typeDefinitionCache[responseType]); 114 | pubsub.publish(`${methodName}-onSubscribe`, payload); 115 | }); 116 | response.on('error', (error) => { 117 | if (error.code === 1) { 118 | // cancelled 119 | response.removeAllListeners('error'); 120 | response.removeAllListeners(); 121 | } 122 | }); 123 | response.on('end', () => { 124 | response.removeAllListeners(); 125 | }); 126 | const asyncIterator = pubsub.asyncIterator(`${methodName}-onSubscribe`); 127 | return subscription_1.withAsyncIteratorCancel(asyncIterator, () => { 128 | response.cancel(); 129 | }); 130 | }), 131 | }; 132 | // eslint-disable-next-line no-param-reassign 133 | result[`${serviceName}${methodName}`] = subscribeField; 134 | return result; 135 | }, {}); 136 | if (_.isEmpty(fields())) { 137 | return null; 138 | } 139 | return new graphql_1.GraphQLObjectType({ 140 | fields, 141 | name: 'Subscription', 142 | }); 143 | } 144 | exports.getGraphQlSubscriptionsFromProtoService = getGraphQlSubscriptionsFromProtoService; 145 | //# sourceMappingURL=service_converter.js.map -------------------------------------------------------------------------------- /lib/service_converter.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"service_converter.js","sourceRoot":"","sources":["../src/service_converter.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /lib/subscription.d.ts: -------------------------------------------------------------------------------- 1 | export declare function withAsyncIteratorCancel(asyncIterator: any, onCancel: any): any; 2 | -------------------------------------------------------------------------------- /lib/subscription.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | // https://github.com/apollographql/graphql-subscriptions/issues/99#issuecomment-400500956 4 | function withAsyncIteratorCancel(asyncIterator, onCancel) { 5 | return Object.assign({}, asyncIterator, { return() { 6 | if (typeof onCancel === 'function') { 7 | onCancel(); 8 | } 9 | return asyncIterator.return 10 | ? asyncIterator.return() 11 | : Promise.resolve({ value: undefined, done: true }); 12 | } }); 13 | } 14 | exports.withAsyncIteratorCancel = withAsyncIteratorCancel; 15 | //# sourceMappingURL=subscription.js.map -------------------------------------------------------------------------------- /lib/subscription.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"subscription.js","sourceRoot":"","sources":["../src/subscription.ts"],"names":[],"mappings":";;AAAA,0FAA0F;AAC1F,SAAgB,uBAAuB,CAAC,aAAa,EAAE,QAAQ;IAC7D,yBACK,aAAa,IAChB,MAAM;YACJ,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;gBAClC,QAAQ,EAAE,CAAC;aACZ;YACD,OAAO,aAAa,CAAC,MAAM;gBACzB,CAAC,CAAC,aAAa,CAAC,MAAM,EAAE;gBACxB,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,CAAC,IACD;AACJ,CAAC;AAZD,0DAYC"} -------------------------------------------------------------------------------- /lib/type_converter.d.ts: -------------------------------------------------------------------------------- 1 | import * as protobuf from 'protobufjs'; 2 | import { GraphQLInputObjectType, GraphQLObjectType } from 'graphql'; 3 | interface IFieldWithComment extends protobuf.IField { 4 | comment?: string | null | undefined; 5 | } 6 | interface ITypeWithComment extends protobuf.IType { 7 | fields: { 8 | [k: string]: IFieldWithComment; 9 | }; 10 | comment?: string | null | undefined; 11 | } 12 | interface ProtoDefinitionInput { 13 | definition: ITypeWithComment; 14 | typeName: string; 15 | } 16 | export declare function convertGrpcTypeToGraphqlType(payload: any, typeDef: any): any; 17 | export declare function getGraphqlTypeFromProtoDefinition({ definition, typeName }: ProtoDefinitionInput): GraphQLInputObjectType | GraphQLObjectType; 18 | export {}; 19 | -------------------------------------------------------------------------------- /lib/type_converter.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const Long = require("long"); 4 | const graphql_1 = require("graphql"); 5 | const types_1 = require("./types"); 6 | function convertToGraphqlType(value) { 7 | if (Long.isLong(value)) { 8 | // conver long 9 | return value.toNumber(); 10 | } 11 | return value; 12 | } 13 | // TODO: this convert method is not complete 14 | function convertGrpcTypeToGraphqlType(payload, typeDef) { 15 | const fields = typeDef.getFields(); 16 | Object.keys(fields).forEach((key) => { 17 | const value = payload[key]; 18 | const field = fields[key]; 19 | const fieldType = field.type; 20 | if (graphql_1.isListType(fieldType)) { 21 | // process list 22 | // eslint-disable-next-line no-param-reassign 23 | payload[key] = value.map(convertToGraphqlType); 24 | } 25 | else { 26 | // eslint-disable-next-line no-param-reassign 27 | payload[key] = convertToGraphqlType(value); 28 | } 29 | }); 30 | return payload; 31 | } 32 | exports.convertGrpcTypeToGraphqlType = convertGrpcTypeToGraphqlType; 33 | function getGraphqlTypeFromProtoDefinition({ definition, typeName }) { 34 | const { fields, comment } = definition; 35 | // TODO: need to set up for either input type or object type 36 | const fieldsFunction = () => Object.keys(fields) 37 | .reduce((result, fieldName) => { 38 | const { rule, type, comment } = fields[fieldName]; 39 | const gqlType = types_1.GRPC_GQL_TYPE_MAPPING[type] || types_1.typeDefinitionCache[type]; 40 | // eslint-disable-next-line no-param-reassign 41 | result[fieldName] = { 42 | type: rule === 'repeated' ? graphql_1.GraphQLList(gqlType) : gqlType, 43 | description: comment, 44 | }; 45 | return result; 46 | }, {}); 47 | const typeDef = { 48 | name: typeName, 49 | fields: fieldsFunction, 50 | description: comment, 51 | }; 52 | // CONVENTION - types that end with `Input` are GraphQL input types 53 | const type = typeName.endsWith('Input') 54 | ? new graphql_1.GraphQLInputObjectType(typeDef) 55 | : new graphql_1.GraphQLObjectType(typeDef); 56 | types_1.typeDefinitionCache[typeName] = type; 57 | return type; 58 | } 59 | exports.getGraphqlTypeFromProtoDefinition = getGraphqlTypeFromProtoDefinition; 60 | //# sourceMappingURL=type_converter.js.map -------------------------------------------------------------------------------- /lib/type_converter.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"type_converter.js","sourceRoot":"","sources":["../src/type_converter.ts"],"names":[],"mappings":";;AACA,6BAA6B;AAC7B,qCAMiB;AAEjB,mCAGiB;AAgBjB,SAAS,oBAAoB,CAAC,KAAU;IACtC,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;QACtB,cAAc;QACd,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;KACzB;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,4CAA4C;AAC5C,SAAgB,4BAA4B,CAAC,OAAO,EAAE,OAAO;IAC3D,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAEnC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QAClC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC3B,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC;QAE7B,IAAI,oBAAU,CAAC,SAAS,CAAC,EAAE;YACzB,eAAe;YACf,6CAA6C;YAC7C,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;SAChD;aAAM;YACL,6CAA6C;YAC7C,OAAO,CAAC,GAAG,CAAC,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;SAC5C;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC;AACjB,CAAC;AAnBD,oEAmBC;AAED,SAAgB,iCAAiC,CAC/C,EAAE,UAAU,EAAE,QAAQ,EAAwB;IAE9C,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;IAEvC,4DAA4D;IAC5D,MAAM,cAAc,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;SAC7C,MAAM,CACL,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE;QACpB,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;QAElD,MAAM,OAAO,GAAG,6BAAqB,CAAC,IAAI,CAAC,IAAI,2BAAmB,CAAC,IAAI,CAAC,CAAC;QAEzE,6CAA6C;QAC7C,MAAM,CAAC,SAAS,CAAC,GAAG;YAClB,IAAI,EAAE,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,qBAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO;YAC1D,WAAW,EAAE,OAAO;SACrB,CAAC;QAEF,OAAO,MAAM,CAAC;IAChB,CAAC,EACD,EAAE,CACH,CAAC;IAEJ,MAAM,OAAO,GAAG;QACd,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,cAAc;QACtB,WAAW,EAAE,OAAO;KACrB,CAAC;IAEF,mEAAmE;IACnE,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;QACrC,CAAC,CAAC,IAAI,gCAAsB,CAAC,OAAO,CAAC;QACrC,CAAC,CAAC,IAAI,2BAAiB,CAAC,OAAO,CAAC,CAAC;IAEnC,2BAAmB,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IACrC,OAAO,IAAI,CAAC;AACd,CAAC;AArCD,8EAqCC"} -------------------------------------------------------------------------------- /lib/types.d.ts: -------------------------------------------------------------------------------- 1 | import { GraphQLType } from 'graphql'; 2 | export interface GrpcGraphqlSchemaConfiguration { 3 | endpoint: string; 4 | protoFilePath: string; 5 | serviceName: string; 6 | packageName: string; 7 | } 8 | export interface TypeMapping { 9 | [key: string]: GraphQLType; 10 | } 11 | export declare const GRPC_GQL_TYPE_MAPPING: TypeMapping; 12 | export declare const typeDefinitionCache: TypeMapping; 13 | -------------------------------------------------------------------------------- /lib/types.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const graphql_1 = require("graphql"); 4 | // https://developers.google.com/protocol-buffers/docs/proto3#scalar 5 | // https://www.apollographql.com/docs/apollo-server/schemas/types.html 6 | exports.GRPC_GQL_TYPE_MAPPING = { 7 | int32: graphql_1.GraphQLInt, 8 | int64: graphql_1.GraphQLFloat, 9 | float: graphql_1.GraphQLFloat, 10 | double: graphql_1.GraphQLFloat, 11 | string: graphql_1.GraphQLString, 12 | bool: graphql_1.GraphQLBoolean, 13 | }; 14 | exports.typeDefinitionCache = { 15 | ServerStatus: new graphql_1.GraphQLObjectType({ 16 | name: 'ServerStatus', 17 | description: 'status of the server', 18 | fields: () => ({ 19 | status: { 20 | type: graphql_1.GraphQLString, 21 | descripton: 'status string', 22 | }, 23 | }), 24 | }), 25 | }; 26 | //# sourceMappingURL=types.js.map -------------------------------------------------------------------------------- /lib/types.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;AAAA,qCAOiB;AAajB,oEAAoE;AACpE,sEAAsE;AACzD,QAAA,qBAAqB,GAAgB;IAChD,KAAK,EAAE,oBAAU;IACjB,KAAK,EAAE,sBAAY;IACnB,KAAK,EAAE,sBAAY;IACnB,MAAM,EAAE,sBAAY;IACpB,MAAM,EAAE,uBAAa;IACrB,IAAI,EAAE,wBAAc;CACrB,CAAC;AAEW,QAAA,mBAAmB,GAAgB;IAC9C,YAAY,EAAE,IAAI,2BAAiB,CAAC;QAClC,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,sBAAsB;QACnC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YACb,MAAM,EAAE;gBACN,IAAI,EAAE,uBAAa;gBACnB,UAAU,EAAE,eAAe;aAC5B;SACF,CAAC;KACH,CAAC;CACH,CAAC"} -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "grpc-graphql-schema", 3 | "version": "0.0.9", 4 | "description": "Convert gRPC proto Definition into GraphQL Schema", 5 | "main": "lib/index.js", 6 | "repository": "https://github.com/xanthous-tech/grpc-graphql-schema", 7 | "author": "Simon Liang ", 8 | "license": "MIT", 9 | "private": false, 10 | "scripts": { 11 | "build": "tsc --project .", 12 | "start": "node ." 13 | }, 14 | "devDependencies": { 15 | "@types/graphql": "^14.0.4", 16 | "@types/node": "^10.12.18", 17 | "tslint": "^5.12.1", 18 | "tslint-config-airbnb": "^5.11.1", 19 | "typescript": "^3.2.2" 20 | }, 21 | "peerDependencies": { 22 | "graphql": "^14.0.2" 23 | }, 24 | "dependencies": { 25 | "graphql": "^14.0.2", 26 | "grpc": "^1.17.0", 27 | "grpc-caller": "^0.11.0", 28 | "lodash": "^4.17.11", 29 | "long": "^4.0.0", 30 | "protobufjs": "^6.8.8" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import * as protobuf from 'protobufjs'; 2 | import * as _ from 'lodash'; 3 | import * as grpcCaller from 'grpc-caller'; 4 | import { 5 | GraphQLSchema, 6 | GraphQLInputObjectType, 7 | GraphQLObjectType, 8 | } from 'graphql'; 9 | 10 | import { GrpcGraphqlSchemaConfiguration } from './types'; 11 | import { getGraphqlTypeFromProtoDefinition } from './type_converter'; 12 | import { 13 | getGraphqlQueriesFromProtoService, 14 | getGraphQlSubscriptionsFromProtoService, 15 | getGraphqlMutationsFromProtoService, 16 | } from './service_converter'; 17 | import { getPackageProtoDefinition } from './protobuf'; 18 | 19 | export { 20 | getGraphqlQueriesFromProtoService, 21 | getGraphqlMutationsFromProtoService, 22 | getGraphQlSubscriptionsFromProtoService, 23 | } from './service_converter'; 24 | 25 | export { 26 | convertGrpcTypeToGraphqlType, 27 | getGraphqlTypeFromProtoDefinition, 28 | } from './type_converter'; 29 | export { 30 | GRPC_GQL_TYPE_MAPPING, 31 | GrpcGraphqlSchemaConfiguration, 32 | typeDefinitionCache, 33 | } from './types'; 34 | 35 | type GraphqlInputTypes = GraphQLInputObjectType | GraphQLObjectType; 36 | 37 | export async function getGraphqlSchemaFromGrpc({ 38 | endpoint, 39 | protoFilePath, 40 | serviceName, 41 | packageName, 42 | }: GrpcGraphqlSchemaConfiguration): Promise { 43 | const client = grpcCaller( 44 | endpoint, 45 | protoFilePath, 46 | serviceName, 47 | null, 48 | { 49 | 'grpc.max_send_message_length': -1, 50 | 'grpc.max_receive_message_length': -1, 51 | }, 52 | ); 53 | 54 | const { nested }: protobuf.INamespace = 55 | await getPackageProtoDefinition(protoFilePath, packageName); 56 | 57 | const types: GraphqlInputTypes[] = Object.keys(nested) 58 | .filter((key: string) => 'fields' in nested[key]) 59 | .reduce( 60 | (acc: GraphqlInputTypes[], key: string) => { 61 | const definition: protobuf.AnyNestedObject = nested[key]; 62 | 63 | // skip empty 64 | if (key.startsWith('Empty')) { 65 | return acc; 66 | } 67 | 68 | if ((definition).fields) { 69 | return acc.concat([ 70 | getGraphqlTypeFromProtoDefinition({ 71 | definition: (definition), 72 | typeName: key, 73 | }), 74 | ]); 75 | } 76 | 77 | return acc; 78 | }, 79 | [], 80 | ); 81 | 82 | const query = Object.keys(nested) 83 | .filter((key: string) => 'methods' in nested[key] && key === serviceName) 84 | .reduce( 85 | (__: any, key: string): GraphQLObjectType | null => { 86 | const definition = nested[key]; 87 | 88 | return getGraphqlQueriesFromProtoService({ 89 | client, 90 | definition, 91 | serviceName: key, 92 | }); 93 | }, 94 | null, 95 | ); 96 | 97 | const mutation = Object.keys(nested) 98 | .filter((key: string) => 'methods' in nested[key] && key === serviceName) 99 | .reduce( 100 | (__: any, key: string): GraphQLObjectType | null => { 101 | const definition = nested[key]; 102 | 103 | return getGraphqlMutationsFromProtoService({ 104 | client, 105 | definition, 106 | serviceName: key, 107 | }); 108 | }, 109 | null, 110 | ); 111 | 112 | const subscription = Object.keys(nested) 113 | .filter(key => 'methods' in nested[key] && key === serviceName) 114 | .reduce( 115 | (__: any, key: string): GraphQLObjectType | null => { 116 | const definition = nested[key]; 117 | 118 | return getGraphQlSubscriptionsFromProtoService({ 119 | client, 120 | definition, 121 | serviceName: key, 122 | }); 123 | }, 124 | null, 125 | ); 126 | 127 | return new GraphQLSchema({ 128 | types, 129 | query, 130 | mutation, 131 | subscription, 132 | }); 133 | } 134 | -------------------------------------------------------------------------------- /src/protobuf.ts: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash'; 2 | import * as protobuf from 'protobufjs'; 3 | 4 | export async function getPackageProtoDefinition( 5 | protoFile: string, 6 | packageName: string, 7 | ): Promise { 8 | const protoDefinition = await protobuf.load(protoFile); 9 | const protoDefinitionObject = await protoDefinition.toJSON({ 10 | keepComments: true, 11 | }); 12 | const packagePaths: string[] = packageName.split('.'); 13 | 14 | for (let i: number = 0; i < packagePaths.length; i += 2) { 15 | packagePaths.splice(i, 0, 'nested'); 16 | } 17 | 18 | return _.get(protoDefinitionObject, packagePaths.join('.')); 19 | } 20 | -------------------------------------------------------------------------------- /src/service_converter.ts: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash'; 2 | 3 | import { 4 | GraphQLObjectType, GraphQLFieldConfigMap, Thunk, GraphQLFieldConfig, GraphQLOutputType, 5 | } from 'graphql'; 6 | 7 | import { withAsyncIteratorCancel } from './subscription'; 8 | 9 | import { 10 | convertGrpcTypeToGraphqlType, 11 | } from './type_converter'; 12 | 13 | import { 14 | typeDefinitionCache, 15 | } from './types'; 16 | 17 | function getGraphqlMethodsFromProtoService({ 18 | definition, 19 | serviceName, 20 | client, 21 | methodType, 22 | }) { 23 | const { methods } = definition; 24 | const fields: Thunk> = () => Object.keys(methods).reduce( 25 | (result: GraphQLFieldConfigMap, methodName): GraphQLFieldConfigMap => { 26 | const args = {}; 27 | const { 28 | requestType: requestArgName, 29 | responseType, 30 | responseStream, 31 | comment, 32 | } = methods[methodName]; 33 | 34 | if (responseStream) { 35 | // responseStream should be in subscriptions 36 | return result; 37 | } 38 | 39 | // filter for mutations 40 | if (methodType === 'Mutation' && !methodName.startsWith('Set')) { 41 | return result; 42 | } 43 | 44 | // filter out ping for mutation 45 | if (methodType === 'Mutation' && methodName === 'ping') { 46 | return result; 47 | } 48 | 49 | if (!requestArgName.startsWith('Empty')) { 50 | args[requestArgName] = { 51 | type: typeDefinitionCache[requestArgName], 52 | }; 53 | } 54 | 55 | const queryField = { 56 | args, 57 | type: typeDefinitionCache[responseType], 58 | description: comment, 59 | resolve: async (__, arg) => { 60 | const response = await client[methodName]( 61 | arg[requestArgName] || {}, 62 | {}, 63 | { 64 | deadline: 65 | Date.now() + (Number(process.env.REQUEST_TIMEOUT) || 200000), 66 | }, 67 | ); 68 | // FIXME: there is a bug in the graphQL type conversion 69 | return response; 70 | // return convertGrpcTypeToGraphqlType( 71 | // response, 72 | // typeDefinitionCache[responseType], 73 | // ); 74 | }, 75 | }; 76 | 77 | // eslint-disable-next-line no-param-reassign 78 | result[`${serviceName}${methodName}`] = >queryField; 79 | 80 | return result; 81 | }, 82 | (methodType === 'Mutation') ? {} : { 83 | // adding a default ping 84 | ping: { 85 | type: typeDefinitionCache.ServerStatus, 86 | description: 'query for getting server status', 87 | resolve: () => ({ status: 'online' }), 88 | }, 89 | }, 90 | ); 91 | 92 | if (_.isEmpty(fields())) { 93 | return null; 94 | } 95 | 96 | return new GraphQLObjectType({ 97 | fields, 98 | name: methodType, 99 | }); 100 | } 101 | 102 | export function getGraphqlQueriesFromProtoService({ 103 | definition, 104 | serviceName, 105 | client, 106 | }) { 107 | return getGraphqlMethodsFromProtoService({ 108 | definition, 109 | serviceName, 110 | client, 111 | methodType: 'Query', 112 | }); 113 | } 114 | 115 | export function getGraphqlMutationsFromProtoService({ 116 | definition, 117 | serviceName, 118 | client, 119 | }) { 120 | return getGraphqlMethodsFromProtoService({ 121 | definition, 122 | serviceName, 123 | client, 124 | methodType: 'Mutation', 125 | }); 126 | } 127 | 128 | export function getGraphQlSubscriptionsFromProtoService({ 129 | definition, 130 | serviceName, 131 | client, 132 | }) { 133 | const { methods } = definition; 134 | const fields = () => Object.keys(methods).reduce( 135 | (result, methodName) => { 136 | const args = {}; 137 | const { 138 | requestType: requestArgName, 139 | responseType, 140 | responseStream, 141 | comment, 142 | } = methods[methodName]; 143 | 144 | if (!responseStream) { 145 | // non-responseStream should be in queries / mutations 146 | return result; 147 | } 148 | 149 | if (!requestArgName.startsWith('Empty')) { 150 | args[requestArgName] = { 151 | type: typeDefinitionCache[requestArgName], 152 | }; 153 | } 154 | 155 | const subscribeField = { 156 | args, 157 | type: typeDefinitionCache[responseType], 158 | description: comment, 159 | subscribe: async (__, arg, { pubsub }) => { 160 | const response = await client[methodName]( 161 | arg[requestArgName] || {}, 162 | {}, 163 | ); 164 | 165 | response.on('data', (data) => { 166 | const payload = {}; 167 | payload[`${serviceName}${methodName}`] = convertGrpcTypeToGraphqlType( 168 | data, 169 | typeDefinitionCache[responseType], 170 | ); 171 | pubsub.publish(`${methodName}-onSubscribe`, payload); 172 | }); 173 | 174 | response.on('error', (error) => { 175 | if (error.code === 1) { 176 | // cancelled 177 | response.removeAllListeners('error'); 178 | response.removeAllListeners(); 179 | } 180 | }); 181 | 182 | response.on('end', () => { 183 | response.removeAllListeners(); 184 | }); 185 | 186 | const asyncIterator = pubsub.asyncIterator( 187 | `${methodName}-onSubscribe`, 188 | ); 189 | 190 | return withAsyncIteratorCancel(asyncIterator, () => { 191 | response.cancel(); 192 | }); 193 | }, 194 | }; 195 | 196 | // eslint-disable-next-line no-param-reassign 197 | result[`${serviceName}${methodName}`] = subscribeField; 198 | 199 | return result; 200 | }, 201 | {}, 202 | ); 203 | 204 | if (_.isEmpty(fields())) { 205 | return null; 206 | } 207 | 208 | return new GraphQLObjectType({ 209 | fields, 210 | name: 'Subscription', 211 | }); 212 | } 213 | -------------------------------------------------------------------------------- /src/subscription.ts: -------------------------------------------------------------------------------- 1 | // https://github.com/apollographql/graphql-subscriptions/issues/99#issuecomment-400500956 2 | export function withAsyncIteratorCancel(asyncIterator, onCancel) { 3 | return { 4 | ...asyncIterator, 5 | return() { 6 | if (typeof onCancel === 'function') { 7 | onCancel(); 8 | } 9 | return asyncIterator.return 10 | ? asyncIterator.return() 11 | : Promise.resolve({ value: undefined, done: true }); 12 | }, 13 | }; 14 | } -------------------------------------------------------------------------------- /src/type_converter.ts: -------------------------------------------------------------------------------- 1 | import * as protobuf from 'protobufjs'; 2 | import * as Long from 'long'; 3 | import { 4 | GraphQLList, 5 | GraphQLInputObjectType, 6 | GraphQLObjectType, 7 | isListType, 8 | Thunk, 9 | } from 'graphql'; 10 | 11 | import { 12 | GRPC_GQL_TYPE_MAPPING, 13 | typeDefinitionCache, 14 | } from './types'; 15 | 16 | interface IFieldWithComment extends protobuf.IField { 17 | comment?: string | null | undefined; 18 | } 19 | 20 | interface ITypeWithComment extends protobuf.IType { 21 | fields: { [k: string]: IFieldWithComment }; 22 | comment?: string | null | undefined; 23 | } 24 | 25 | interface ProtoDefinitionInput { 26 | definition: ITypeWithComment; 27 | typeName: string; 28 | } 29 | 30 | function convertToGraphqlType(value: any): any { 31 | if (Long.isLong(value)) { 32 | // conver long 33 | return value.toNumber(); 34 | } 35 | 36 | return value; 37 | } 38 | 39 | // TODO: this convert method is not complete 40 | export function convertGrpcTypeToGraphqlType(payload, typeDef) { 41 | const fields = typeDef.getFields(); 42 | 43 | Object.keys(fields).forEach((key) => { 44 | const value = payload[key]; 45 | const field = fields[key]; 46 | const fieldType = field.type; 47 | 48 | if (isListType(fieldType)) { 49 | // process list 50 | // eslint-disable-next-line no-param-reassign 51 | payload[key] = value.map(convertToGraphqlType); 52 | } else { 53 | // eslint-disable-next-line no-param-reassign 54 | payload[key] = convertToGraphqlType(value); 55 | } 56 | }); 57 | 58 | return payload; 59 | } 60 | 61 | export function getGraphqlTypeFromProtoDefinition( 62 | { definition, typeName }: ProtoDefinitionInput, 63 | ): GraphQLInputObjectType | GraphQLObjectType { 64 | const { fields, comment } = definition; 65 | 66 | // TODO: need to set up for either input type or object type 67 | const fieldsFunction = () => Object.keys(fields) 68 | .reduce( 69 | (result, fieldName) => { 70 | const { rule, type, comment } = fields[fieldName]; 71 | 72 | const gqlType = GRPC_GQL_TYPE_MAPPING[type] || typeDefinitionCache[type]; 73 | 74 | // eslint-disable-next-line no-param-reassign 75 | result[fieldName] = { 76 | type: rule === 'repeated' ? GraphQLList(gqlType) : gqlType, 77 | description: comment, 78 | }; 79 | 80 | return result; 81 | }, 82 | {}, 83 | ); 84 | 85 | const typeDef = { 86 | name: typeName, 87 | fields: fieldsFunction, 88 | description: comment, 89 | }; 90 | 91 | // CONVENTION - types that end with `Input` are GraphQL input types 92 | const type = typeName.endsWith('Input') 93 | ? new GraphQLInputObjectType(typeDef) 94 | : new GraphQLObjectType(typeDef); 95 | 96 | typeDefinitionCache[typeName] = type; 97 | return type; 98 | } 99 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | import { 2 | GraphQLType, 3 | GraphQLObjectType, 4 | GraphQLInt, 5 | GraphQLFloat, 6 | GraphQLString, 7 | GraphQLBoolean, 8 | } from 'graphql'; 9 | 10 | export interface GrpcGraphqlSchemaConfiguration { 11 | endpoint: string; 12 | protoFilePath: string; 13 | serviceName: string; 14 | packageName: string; 15 | } 16 | 17 | export interface TypeMapping { 18 | [key: string]: GraphQLType; 19 | } 20 | 21 | // https://developers.google.com/protocol-buffers/docs/proto3#scalar 22 | // https://www.apollographql.com/docs/apollo-server/schemas/types.html 23 | export const GRPC_GQL_TYPE_MAPPING: TypeMapping = { 24 | int32: GraphQLInt, 25 | int64: GraphQLFloat, // TODO: https://github.com/graphql/graphql-js/issues/292 26 | float: GraphQLFloat, 27 | double: GraphQLFloat, 28 | string: GraphQLString, 29 | bool: GraphQLBoolean, 30 | }; 31 | 32 | export const typeDefinitionCache: TypeMapping = { 33 | ServerStatus: new GraphQLObjectType({ 34 | name: 'ServerStatus', 35 | description: 'status of the server', 36 | fields: () => ({ 37 | status: { 38 | type: GraphQLString, 39 | descripton: 'status string', 40 | }, 41 | }), 42 | }), 43 | }; 44 | -------------------------------------------------------------------------------- /src/typings.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'grpc-caller'; 2 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": true, 3 | "compilerOptions": { 4 | "types": [ 5 | "node" 6 | ], 7 | "lib": [ 8 | "es2015", 9 | "esnext.asynciterable" 10 | ], 11 | "target": "es6", 12 | "module": "commonjs", 13 | "sourceMap": true, 14 | "declaration": true, 15 | "outDir": "lib" 16 | }, 17 | "include": [ 18 | "src/**/*" 19 | ], 20 | "exclude": [ 21 | "node_modules" 22 | ] 23 | } -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tslint-config-airbnb" 3 | } -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@fimbul/bifrost@^0.17.0": 6 | version "0.17.0" 7 | resolved "https://registry.yarnpkg.com/@fimbul/bifrost/-/bifrost-0.17.0.tgz#f0383ba7e40992e3193dc87e2ddfde2ad62a9cf4" 8 | integrity sha512-gVTkJAOef5HtN6LPmrtt5fAUmBywwlgmObsU3FBhPoNeXPLaIl2zywXkJEtvvVLQnaFmtff3x+wIj5lHRCDE3Q== 9 | dependencies: 10 | "@fimbul/ymir" "^0.17.0" 11 | get-caller-file "^2.0.0" 12 | tslib "^1.8.1" 13 | tsutils "^3.5.0" 14 | 15 | "@fimbul/ymir@^0.17.0": 16 | version "0.17.0" 17 | resolved "https://registry.yarnpkg.com/@fimbul/ymir/-/ymir-0.17.0.tgz#4f28389b9f804d1cd202e11983af1743488b7815" 18 | integrity sha512-xMXM9KTXRLHLVS6dnX1JhHNEkmWHcAVCQ/4+DA1KKwC/AFnGHzu/7QfQttEPgw3xplT+ILf9e3i64jrFwB3JtA== 19 | dependencies: 20 | inversify "^5.0.0" 21 | reflect-metadata "^0.1.12" 22 | tslib "^1.8.1" 23 | 24 | "@grpc/proto-loader@^0.3.0": 25 | version "0.3.0" 26 | resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.3.0.tgz#c127d3859bff895f220453612ba04b923af0c584" 27 | integrity sha512-9b8S/V+3W4Gv7G/JKSZ48zApgyYbfIR7mAC9XNnaSWme3zj57MIESu0ELzm9j5oxNIpFG8DgO00iJMIUZ5luqw== 28 | dependencies: 29 | "@types/lodash" "^4.14.104" 30 | "@types/node" "^9.4.6" 31 | lodash "^4.17.5" 32 | protobufjs "^6.8.6" 33 | 34 | "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": 35 | version "1.1.2" 36 | resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" 37 | integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78= 38 | 39 | "@protobufjs/base64@^1.1.2": 40 | version "1.1.2" 41 | resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" 42 | integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== 43 | 44 | "@protobufjs/codegen@^2.0.4": 45 | version "2.0.4" 46 | resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" 47 | integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== 48 | 49 | "@protobufjs/eventemitter@^1.1.0": 50 | version "1.1.0" 51 | resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" 52 | integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A= 53 | 54 | "@protobufjs/fetch@^1.1.0": 55 | version "1.1.0" 56 | resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" 57 | integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU= 58 | dependencies: 59 | "@protobufjs/aspromise" "^1.1.1" 60 | "@protobufjs/inquire" "^1.1.0" 61 | 62 | "@protobufjs/float@^1.0.2": 63 | version "1.0.2" 64 | resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" 65 | integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E= 66 | 67 | "@protobufjs/inquire@^1.1.0": 68 | version "1.1.0" 69 | resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" 70 | integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik= 71 | 72 | "@protobufjs/path@^1.1.2": 73 | version "1.1.2" 74 | resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" 75 | integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0= 76 | 77 | "@protobufjs/pool@^1.1.0": 78 | version "1.1.0" 79 | resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" 80 | integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q= 81 | 82 | "@protobufjs/utf8@^1.1.0": 83 | version "1.1.0" 84 | resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" 85 | integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= 86 | 87 | "@types/graphql@^14.0.4": 88 | version "14.0.4" 89 | resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-14.0.4.tgz#d71a75967cd93c33eaea32b626b362ce0f2b2ae9" 90 | integrity sha512-gI98ANelzzpq7lZzuYCUJg8LZDjQc7ekj7cxoWt8RezOKaVaAyK27U6AHa9LEqikP1NUhyi8blQQkHYHVRZ7Tg== 91 | 92 | "@types/lodash@^4.14.104": 93 | version "4.14.119" 94 | resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.119.tgz#be847e5f4bc3e35e46d041c394ead8b603ad8b39" 95 | integrity sha512-Z3TNyBL8Vd/M9D9Ms2S3LmFq2sSMzahodD6rCS9V2N44HUMINb75jNkSuwAx7eo2ufqTdfOdtGQpNbieUjPQmw== 96 | 97 | "@types/long@^4.0.0": 98 | version "4.0.0" 99 | resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.0.tgz#719551d2352d301ac8b81db732acb6bdc28dbdef" 100 | integrity sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q== 101 | 102 | "@types/node@^10.1.0", "@types/node@^10.12.18": 103 | version "10.12.18" 104 | resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" 105 | integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== 106 | 107 | "@types/node@^9.4.6": 108 | version "9.6.41" 109 | resolved "https://registry.yarnpkg.com/@types/node/-/node-9.6.41.tgz#e57c3152eb2e7ec748c733cebd0c095b437c5d37" 110 | integrity sha512-sPZWEbFMz6qAy9SLY7jh5cgepmsiwqUUHjvEm8lpU6kug2hmmcyuTnwhoGw/GWpI5Npue4EqvsiQQI0eWjW/ZA== 111 | 112 | abbrev@1: 113 | version "1.1.1" 114 | resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" 115 | integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== 116 | 117 | ansi-regex@^2.0.0: 118 | version "2.1.1" 119 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 120 | integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= 121 | 122 | ansi-regex@^3.0.0: 123 | version "3.0.0" 124 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" 125 | integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= 126 | 127 | ansi-styles@^2.2.1: 128 | version "2.2.1" 129 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" 130 | integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= 131 | 132 | ansi-styles@^3.2.1: 133 | version "3.2.1" 134 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 135 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 136 | dependencies: 137 | color-convert "^1.9.0" 138 | 139 | aproba@^1.0.3: 140 | version "1.2.0" 141 | resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" 142 | integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== 143 | 144 | are-we-there-yet@~1.1.2: 145 | version "1.1.5" 146 | resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" 147 | integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== 148 | dependencies: 149 | delegates "^1.0.0" 150 | readable-stream "^2.0.6" 151 | 152 | argparse@^1.0.7: 153 | version "1.0.10" 154 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" 155 | integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== 156 | dependencies: 157 | sprintf-js "~1.0.2" 158 | 159 | ascli@~1: 160 | version "1.0.1" 161 | resolved "https://registry.yarnpkg.com/ascli/-/ascli-1.0.1.tgz#bcfa5974a62f18e81cabaeb49732ab4a88f906bc" 162 | integrity sha1-vPpZdKYvGOgcq660lzKrSoj5Brw= 163 | dependencies: 164 | colour "~0.7.1" 165 | optjs "~3.2.2" 166 | 167 | async@^2.6.1: 168 | version "2.6.1" 169 | resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" 170 | integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ== 171 | dependencies: 172 | lodash "^4.17.10" 173 | 174 | babel-code-frame@^6.22.0: 175 | version "6.26.0" 176 | resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" 177 | integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= 178 | dependencies: 179 | chalk "^1.1.3" 180 | esutils "^2.0.2" 181 | js-tokens "^3.0.2" 182 | 183 | balanced-match@^1.0.0: 184 | version "1.0.0" 185 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 186 | integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= 187 | 188 | brace-expansion@^1.1.7: 189 | version "1.1.11" 190 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 191 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 192 | dependencies: 193 | balanced-match "^1.0.0" 194 | concat-map "0.0.1" 195 | 196 | builtin-modules@^1.1.1: 197 | version "1.1.1" 198 | resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" 199 | integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= 200 | 201 | bytebuffer@~5: 202 | version "5.0.1" 203 | resolved "https://registry.yarnpkg.com/bytebuffer/-/bytebuffer-5.0.1.tgz#582eea4b1a873b6d020a48d58df85f0bba6cfddd" 204 | integrity sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0= 205 | dependencies: 206 | long "~3" 207 | 208 | call-me-maybe@^1.0.1: 209 | version "1.0.1" 210 | resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" 211 | integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= 212 | 213 | camelcase@^2.0.1: 214 | version "2.1.1" 215 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" 216 | integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= 217 | 218 | chalk@^1.1.3: 219 | version "1.1.3" 220 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" 221 | integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= 222 | dependencies: 223 | ansi-styles "^2.2.1" 224 | escape-string-regexp "^1.0.2" 225 | has-ansi "^2.0.0" 226 | strip-ansi "^3.0.0" 227 | supports-color "^2.0.0" 228 | 229 | chalk@^2.3.0: 230 | version "2.4.2" 231 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" 232 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== 233 | dependencies: 234 | ansi-styles "^3.2.1" 235 | escape-string-regexp "^1.0.5" 236 | supports-color "^5.3.0" 237 | 238 | chownr@^1.1.1: 239 | version "1.1.1" 240 | resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" 241 | integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== 242 | 243 | cliui@^3.0.3: 244 | version "3.2.0" 245 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" 246 | integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= 247 | dependencies: 248 | string-width "^1.0.1" 249 | strip-ansi "^3.0.1" 250 | wrap-ansi "^2.0.0" 251 | 252 | code-point-at@^1.0.0: 253 | version "1.1.0" 254 | resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" 255 | integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= 256 | 257 | color-convert@^1.9.0: 258 | version "1.9.3" 259 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 260 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 261 | dependencies: 262 | color-name "1.1.3" 263 | 264 | color-name@1.1.3: 265 | version "1.1.3" 266 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 267 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= 268 | 269 | colour@~0.7.1: 270 | version "0.7.1" 271 | resolved "https://registry.yarnpkg.com/colour/-/colour-0.7.1.tgz#9cb169917ec5d12c0736d3e8685746df1cadf778" 272 | integrity sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g= 273 | 274 | commander@^2.12.1: 275 | version "2.19.0" 276 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" 277 | integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== 278 | 279 | concat-map@0.0.1: 280 | version "0.0.1" 281 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 282 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 283 | 284 | console-control-strings@^1.0.0, console-control-strings@~1.1.0: 285 | version "1.1.0" 286 | resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" 287 | integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= 288 | 289 | core-util-is@~1.0.0: 290 | version "1.0.2" 291 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 292 | integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= 293 | 294 | debug@^2.1.2: 295 | version "2.6.9" 296 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 297 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== 298 | dependencies: 299 | ms "2.0.0" 300 | 301 | decamelize@^1.1.1: 302 | version "1.2.0" 303 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" 304 | integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= 305 | 306 | deep-extend@^0.6.0: 307 | version "0.6.0" 308 | resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" 309 | integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== 310 | 311 | delegates@^1.0.0: 312 | version "1.0.0" 313 | resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" 314 | integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= 315 | 316 | detect-libc@^1.0.2: 317 | version "1.0.3" 318 | resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" 319 | integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= 320 | 321 | diff@^3.2.0: 322 | version "3.5.0" 323 | resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" 324 | integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== 325 | 326 | doctrine@0.7.2: 327 | version "0.7.2" 328 | resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-0.7.2.tgz#7cb860359ba3be90e040b26b729ce4bfa654c523" 329 | integrity sha1-fLhgNZujvpDgQLJrcpzkv6ZUxSM= 330 | dependencies: 331 | esutils "^1.1.6" 332 | isarray "0.0.1" 333 | 334 | escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: 335 | version "1.0.5" 336 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 337 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= 338 | 339 | esprima@^4.0.0: 340 | version "4.0.1" 341 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" 342 | integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== 343 | 344 | esutils@^1.1.6: 345 | version "1.1.6" 346 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-1.1.6.tgz#c01ccaa9ae4b897c6d0c3e210ae52f3c7a844375" 347 | integrity sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U= 348 | 349 | esutils@^2.0.2: 350 | version "2.0.2" 351 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" 352 | integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= 353 | 354 | fs-minipass@^1.2.5: 355 | version "1.2.5" 356 | resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" 357 | integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ== 358 | dependencies: 359 | minipass "^2.2.1" 360 | 361 | fs.realpath@^1.0.0: 362 | version "1.0.0" 363 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 364 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 365 | 366 | gauge@~2.7.3: 367 | version "2.7.4" 368 | resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" 369 | integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= 370 | dependencies: 371 | aproba "^1.0.3" 372 | console-control-strings "^1.0.0" 373 | has-unicode "^2.0.0" 374 | object-assign "^4.1.0" 375 | signal-exit "^3.0.0" 376 | string-width "^1.0.1" 377 | strip-ansi "^3.0.1" 378 | wide-align "^1.1.0" 379 | 380 | get-caller-file@^2.0.0: 381 | version "2.0.1" 382 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.1.tgz#25835260d3a2b9665fcdbb08cb039a7bbf7011c0" 383 | integrity sha512-SpOZHfz845AH0wJYVuZk2jWDqFmu7Xubsx+ldIpwzy5pDUpu7OJHK7QYNSA2NPlDSKQwM1GFaAkciOWjjW92Sg== 384 | 385 | glob@^7.0.5, glob@^7.1.1, glob@^7.1.3: 386 | version "7.1.3" 387 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" 388 | integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== 389 | dependencies: 390 | fs.realpath "^1.0.0" 391 | inflight "^1.0.4" 392 | inherits "2" 393 | minimatch "^3.0.4" 394 | once "^1.3.0" 395 | path-is-absolute "^1.0.0" 396 | 397 | graphql@^14.0.2: 398 | version "14.0.2" 399 | resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.0.2.tgz#7dded337a4c3fd2d075692323384034b357f5650" 400 | integrity sha512-gUC4YYsaiSJT1h40krG3J+USGlwhzNTXSb4IOZljn9ag5Tj+RkoXrWp+Kh7WyE3t1NCfab5kzCuxBIvOMERMXw== 401 | dependencies: 402 | iterall "^1.2.2" 403 | 404 | grpc-caller@^0.11.0: 405 | version "0.11.0" 406 | resolved "https://registry.yarnpkg.com/grpc-caller/-/grpc-caller-0.11.0.tgz#6974c126cdee66d80aeb9a2499f8fe2d91ca966f" 407 | integrity sha512-8/rK6+wHlPRNU2YvQtecQHDAiDr24rW36W9r+XmIpAetoxtqtC3ItOSAXO/xfV1Zt9ZiBTjn6srKvwWwBVrZWw== 408 | dependencies: 409 | "@grpc/proto-loader" "^0.3.0" 410 | async "^2.6.1" 411 | call-me-maybe "^1.0.1" 412 | grpc-create-metadata "^3.0.0" 413 | grpc-inspect "^0.6.0" 414 | lodash "^4.17.11" 415 | promisify-call "^2.0.0" 416 | 417 | grpc-create-metadata@^3.0.0: 418 | version "3.0.0" 419 | resolved "https://registry.yarnpkg.com/grpc-create-metadata/-/grpc-create-metadata-3.0.0.tgz#54ceb3351959454c59a11bf0e5e38975452193d0" 420 | integrity sha512-Gr+wYv4NdlG1fKbk7W60xI+6tgWaereF/8ga1NTo9W7IhCAH+mqMt6NDXYBwa9v4KFLWKWngNhDSdGU+HLVdIw== 421 | dependencies: 422 | lodash.forown "^4.4.0" 423 | 424 | grpc-inspect@^0.6.0: 425 | version "0.6.0" 426 | resolved "https://registry.yarnpkg.com/grpc-inspect/-/grpc-inspect-0.6.0.tgz#c10fbf920ece85f315c249ab569e0a1739e711be" 427 | integrity sha512-pKW9FvIex0oLI18ms8SkEEvuR0UB1YVEFPecIe457XsxvPMM5gJYjMfuSaCeFVJ1Hv3V6vJYUxTHCy/+HgL0Ww== 428 | dependencies: 429 | lodash "^4.17.11" 430 | traverse "^0.6.6" 431 | 432 | grpc@^1.17.0: 433 | version "1.17.0" 434 | resolved "https://registry.yarnpkg.com/grpc/-/grpc-1.17.0.tgz#d7971dd39bd4eec90c69a048f7727795ab504876" 435 | integrity sha512-5zb5ilwHlsiWfE2Abq/IN5SkHQ2zi4QF/u9Gewcw5DO3y+hGTtzZUiMK52MX3YZHAIRjqxDcO3fx0jLhPjT8Zw== 436 | dependencies: 437 | lodash.camelcase "^4.3.0" 438 | lodash.clone "^4.5.0" 439 | nan "^2.0.0" 440 | node-pre-gyp "^0.12.0" 441 | protobufjs "^5.0.3" 442 | 443 | has-ansi@^2.0.0: 444 | version "2.0.0" 445 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" 446 | integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= 447 | dependencies: 448 | ansi-regex "^2.0.0" 449 | 450 | has-flag@^3.0.0: 451 | version "3.0.0" 452 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 453 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= 454 | 455 | has-unicode@^2.0.0: 456 | version "2.0.1" 457 | resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" 458 | integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= 459 | 460 | iconv-lite@^0.4.4: 461 | version "0.4.24" 462 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" 463 | integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== 464 | dependencies: 465 | safer-buffer ">= 2.1.2 < 3" 466 | 467 | ignore-walk@^3.0.1: 468 | version "3.0.1" 469 | resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" 470 | integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== 471 | dependencies: 472 | minimatch "^3.0.4" 473 | 474 | inflight@^1.0.4: 475 | version "1.0.6" 476 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 477 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 478 | dependencies: 479 | once "^1.3.0" 480 | wrappy "1" 481 | 482 | inherits@2, inherits@~2.0.3: 483 | version "2.0.3" 484 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 485 | integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= 486 | 487 | ini@~1.3.0: 488 | version "1.3.5" 489 | resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" 490 | integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== 491 | 492 | inversify@^5.0.0: 493 | version "5.0.1" 494 | resolved "https://registry.yarnpkg.com/inversify/-/inversify-5.0.1.tgz#500d709b1434896ce5a0d58915c4a4210e34fb6e" 495 | integrity sha512-Ieh06s48WnEYGcqHepdsJUIJUXpwH5o5vodAX+DK2JA/gjy4EbEcQZxw+uFfzysmKjiLXGYwNG3qDZsKVMcINQ== 496 | 497 | invert-kv@^1.0.0: 498 | version "1.0.0" 499 | resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" 500 | integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= 501 | 502 | is-fullwidth-code-point@^1.0.0: 503 | version "1.0.0" 504 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" 505 | integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= 506 | dependencies: 507 | number-is-nan "^1.0.0" 508 | 509 | is-fullwidth-code-point@^2.0.0: 510 | version "2.0.0" 511 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" 512 | integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= 513 | 514 | isarray@0.0.1: 515 | version "0.0.1" 516 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" 517 | integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= 518 | 519 | isarray@~1.0.0: 520 | version "1.0.0" 521 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 522 | integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= 523 | 524 | iterall@^1.2.2: 525 | version "1.2.2" 526 | resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" 527 | integrity sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA== 528 | 529 | js-tokens@^3.0.2: 530 | version "3.0.2" 531 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" 532 | integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= 533 | 534 | js-yaml@^3.7.0: 535 | version "3.12.1" 536 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.1.tgz#295c8632a18a23e054cf5c9d3cecafe678167600" 537 | integrity sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA== 538 | dependencies: 539 | argparse "^1.0.7" 540 | esprima "^4.0.0" 541 | 542 | lcid@^1.0.0: 543 | version "1.0.0" 544 | resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" 545 | integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= 546 | dependencies: 547 | invert-kv "^1.0.0" 548 | 549 | lodash.camelcase@^4.3.0: 550 | version "4.3.0" 551 | resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" 552 | integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= 553 | 554 | lodash.clone@^4.5.0: 555 | version "4.5.0" 556 | resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6" 557 | integrity sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y= 558 | 559 | lodash.forown@^4.4.0: 560 | version "4.4.0" 561 | resolved "https://registry.yarnpkg.com/lodash.forown/-/lodash.forown-4.4.0.tgz#85115cf04f73ef966eced52511d3893cc46683af" 562 | integrity sha1-hRFc8E9z75ZuztUlEdOJPMRmg68= 563 | 564 | lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.5: 565 | version "4.17.11" 566 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" 567 | integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== 568 | 569 | long@^4.0.0: 570 | version "4.0.0" 571 | resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" 572 | integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== 573 | 574 | long@~3: 575 | version "3.2.0" 576 | resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" 577 | integrity sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s= 578 | 579 | minimatch@^3.0.4: 580 | version "3.0.4" 581 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 582 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 583 | dependencies: 584 | brace-expansion "^1.1.7" 585 | 586 | minimist@0.0.8: 587 | version "0.0.8" 588 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 589 | integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= 590 | 591 | minimist@^1.2.0: 592 | version "1.2.0" 593 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" 594 | integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= 595 | 596 | minipass@^2.2.1, minipass@^2.3.4: 597 | version "2.3.5" 598 | resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" 599 | integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== 600 | dependencies: 601 | safe-buffer "^5.1.2" 602 | yallist "^3.0.0" 603 | 604 | minizlib@^1.1.1: 605 | version "1.2.1" 606 | resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" 607 | integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== 608 | dependencies: 609 | minipass "^2.2.1" 610 | 611 | mkdirp@^0.5.0, mkdirp@^0.5.1: 612 | version "0.5.1" 613 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 614 | integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= 615 | dependencies: 616 | minimist "0.0.8" 617 | 618 | ms@2.0.0: 619 | version "2.0.0" 620 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 621 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= 622 | 623 | nan@^2.0.0: 624 | version "2.12.1" 625 | resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552" 626 | integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw== 627 | 628 | needle@^2.2.1: 629 | version "2.2.4" 630 | resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" 631 | integrity sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA== 632 | dependencies: 633 | debug "^2.1.2" 634 | iconv-lite "^0.4.4" 635 | sax "^1.2.4" 636 | 637 | node-pre-gyp@^0.12.0: 638 | version "0.12.0" 639 | resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" 640 | integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A== 641 | dependencies: 642 | detect-libc "^1.0.2" 643 | mkdirp "^0.5.1" 644 | needle "^2.2.1" 645 | nopt "^4.0.1" 646 | npm-packlist "^1.1.6" 647 | npmlog "^4.0.2" 648 | rc "^1.2.7" 649 | rimraf "^2.6.1" 650 | semver "^5.3.0" 651 | tar "^4" 652 | 653 | nopt@^4.0.1: 654 | version "4.0.1" 655 | resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" 656 | integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= 657 | dependencies: 658 | abbrev "1" 659 | osenv "^0.1.4" 660 | 661 | npm-bundled@^1.0.1: 662 | version "1.0.5" 663 | resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" 664 | integrity sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g== 665 | 666 | npm-packlist@^1.1.6: 667 | version "1.2.0" 668 | resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.2.0.tgz#55a60e793e272f00862c7089274439a4cc31fc7f" 669 | integrity sha512-7Mni4Z8Xkx0/oegoqlcao/JpPCPEMtUvsmB0q7mgvlMinykJLSRTYuFqoQLYgGY8biuxIeiHO+QNJKbCfljewQ== 670 | dependencies: 671 | ignore-walk "^3.0.1" 672 | npm-bundled "^1.0.1" 673 | 674 | npmlog@^4.0.2: 675 | version "4.1.2" 676 | resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" 677 | integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== 678 | dependencies: 679 | are-we-there-yet "~1.1.2" 680 | console-control-strings "~1.1.0" 681 | gauge "~2.7.3" 682 | set-blocking "~2.0.0" 683 | 684 | number-is-nan@^1.0.0: 685 | version "1.0.1" 686 | resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" 687 | integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= 688 | 689 | object-assign@^4.1.0: 690 | version "4.1.1" 691 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 692 | integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= 693 | 694 | once@^1.3.0: 695 | version "1.4.0" 696 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 697 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 698 | dependencies: 699 | wrappy "1" 700 | 701 | optjs@~3.2.2: 702 | version "3.2.2" 703 | resolved "https://registry.yarnpkg.com/optjs/-/optjs-3.2.2.tgz#69a6ce89c442a44403141ad2f9b370bd5bb6f4ee" 704 | integrity sha1-aabOicRCpEQDFBrS+bNwvVu29O4= 705 | 706 | os-homedir@^1.0.0: 707 | version "1.0.2" 708 | resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" 709 | integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= 710 | 711 | os-locale@^1.4.0: 712 | version "1.4.0" 713 | resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" 714 | integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= 715 | dependencies: 716 | lcid "^1.0.0" 717 | 718 | os-tmpdir@^1.0.0: 719 | version "1.0.2" 720 | resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" 721 | integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= 722 | 723 | osenv@^0.1.4: 724 | version "0.1.5" 725 | resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" 726 | integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== 727 | dependencies: 728 | os-homedir "^1.0.0" 729 | os-tmpdir "^1.0.0" 730 | 731 | path-is-absolute@^1.0.0: 732 | version "1.0.1" 733 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 734 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 735 | 736 | path-parse@^1.0.6: 737 | version "1.0.6" 738 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" 739 | integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== 740 | 741 | process-nextick-args@~2.0.0: 742 | version "2.0.0" 743 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" 744 | integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== 745 | 746 | promisify-call@^2.0.0: 747 | version "2.0.4" 748 | resolved "https://registry.yarnpkg.com/promisify-call/-/promisify-call-2.0.4.tgz#d48c2d45652ccccd52801ddecbd533a6d4bd5fba" 749 | integrity sha1-1IwtRWUszM1SgB3ey9UzptS9X7o= 750 | dependencies: 751 | with-callback "^1.0.2" 752 | 753 | protobufjs@^5.0.3: 754 | version "5.0.3" 755 | resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-5.0.3.tgz#e4dfe9fb67c90b2630d15868249bcc4961467a17" 756 | integrity sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA== 757 | dependencies: 758 | ascli "~1" 759 | bytebuffer "~5" 760 | glob "^7.0.5" 761 | yargs "^3.10.0" 762 | 763 | protobufjs@^6.8.6, protobufjs@^6.8.8: 764 | version "6.8.8" 765 | resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.8.8.tgz#c8b4f1282fd7a90e6f5b109ed11c84af82908e7c" 766 | integrity sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw== 767 | dependencies: 768 | "@protobufjs/aspromise" "^1.1.2" 769 | "@protobufjs/base64" "^1.1.2" 770 | "@protobufjs/codegen" "^2.0.4" 771 | "@protobufjs/eventemitter" "^1.1.0" 772 | "@protobufjs/fetch" "^1.1.0" 773 | "@protobufjs/float" "^1.0.2" 774 | "@protobufjs/inquire" "^1.1.0" 775 | "@protobufjs/path" "^1.1.2" 776 | "@protobufjs/pool" "^1.1.0" 777 | "@protobufjs/utf8" "^1.1.0" 778 | "@types/long" "^4.0.0" 779 | "@types/node" "^10.1.0" 780 | long "^4.0.0" 781 | 782 | rc@^1.2.7: 783 | version "1.2.8" 784 | resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" 785 | integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== 786 | dependencies: 787 | deep-extend "^0.6.0" 788 | ini "~1.3.0" 789 | minimist "^1.2.0" 790 | strip-json-comments "~2.0.1" 791 | 792 | readable-stream@^2.0.6: 793 | version "2.3.6" 794 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" 795 | integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== 796 | dependencies: 797 | core-util-is "~1.0.0" 798 | inherits "~2.0.3" 799 | isarray "~1.0.0" 800 | process-nextick-args "~2.0.0" 801 | safe-buffer "~5.1.1" 802 | string_decoder "~1.1.1" 803 | util-deprecate "~1.0.1" 804 | 805 | reflect-metadata@^0.1.12: 806 | version "0.1.12" 807 | resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.12.tgz#311bf0c6b63cd782f228a81abe146a2bfa9c56f2" 808 | integrity sha512-n+IyV+nGz3+0q3/Yf1ra12KpCyi001bi4XFxSjbiWWjfqb52iTTtpGXmCCAOWWIAn9KEuFZKGqBERHmrtScZ3A== 809 | 810 | resolve@^1.3.2: 811 | version "1.9.0" 812 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.9.0.tgz#a14c6fdfa8f92a7df1d996cb7105fa744658ea06" 813 | integrity sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ== 814 | dependencies: 815 | path-parse "^1.0.6" 816 | 817 | rimraf@^2.6.1: 818 | version "2.6.3" 819 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" 820 | integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== 821 | dependencies: 822 | glob "^7.1.3" 823 | 824 | safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: 825 | version "5.1.2" 826 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 827 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== 828 | 829 | "safer-buffer@>= 2.1.2 < 3": 830 | version "2.1.2" 831 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 832 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 833 | 834 | sax@^1.2.4: 835 | version "1.2.4" 836 | resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" 837 | integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== 838 | 839 | semver@^5.3.0: 840 | version "5.6.0" 841 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" 842 | integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== 843 | 844 | set-blocking@~2.0.0: 845 | version "2.0.0" 846 | resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" 847 | integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= 848 | 849 | signal-exit@^3.0.0: 850 | version "3.0.2" 851 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" 852 | integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= 853 | 854 | sprintf-js@~1.0.2: 855 | version "1.0.3" 856 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" 857 | integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= 858 | 859 | string-width@^1.0.1: 860 | version "1.0.2" 861 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" 862 | integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= 863 | dependencies: 864 | code-point-at "^1.0.0" 865 | is-fullwidth-code-point "^1.0.0" 866 | strip-ansi "^3.0.0" 867 | 868 | "string-width@^1.0.2 || 2": 869 | version "2.1.1" 870 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" 871 | integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== 872 | dependencies: 873 | is-fullwidth-code-point "^2.0.0" 874 | strip-ansi "^4.0.0" 875 | 876 | string_decoder@~1.1.1: 877 | version "1.1.1" 878 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" 879 | integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== 880 | dependencies: 881 | safe-buffer "~5.1.0" 882 | 883 | strip-ansi@^3.0.0, strip-ansi@^3.0.1: 884 | version "3.0.1" 885 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 886 | integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= 887 | dependencies: 888 | ansi-regex "^2.0.0" 889 | 890 | strip-ansi@^4.0.0: 891 | version "4.0.0" 892 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" 893 | integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= 894 | dependencies: 895 | ansi-regex "^3.0.0" 896 | 897 | strip-json-comments@~2.0.1: 898 | version "2.0.1" 899 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" 900 | integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= 901 | 902 | supports-color@^2.0.0: 903 | version "2.0.0" 904 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" 905 | integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= 906 | 907 | supports-color@^5.3.0: 908 | version "5.5.0" 909 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 910 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 911 | dependencies: 912 | has-flag "^3.0.0" 913 | 914 | tar@^4: 915 | version "4.4.8" 916 | resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" 917 | integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== 918 | dependencies: 919 | chownr "^1.1.1" 920 | fs-minipass "^1.2.5" 921 | minipass "^2.3.4" 922 | minizlib "^1.1.1" 923 | mkdirp "^0.5.0" 924 | safe-buffer "^5.1.2" 925 | yallist "^3.0.2" 926 | 927 | traverse@^0.6.6: 928 | version "0.6.6" 929 | resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" 930 | integrity sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc= 931 | 932 | tslib@1.9.0: 933 | version "1.9.0" 934 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8" 935 | integrity sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ== 936 | 937 | tslib@^1.7.1, tslib@^1.8.0, tslib@^1.8.1: 938 | version "1.9.3" 939 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" 940 | integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== 941 | 942 | tslint-config-airbnb@^5.11.1: 943 | version "5.11.1" 944 | resolved "https://registry.yarnpkg.com/tslint-config-airbnb/-/tslint-config-airbnb-5.11.1.tgz#51a27fbb8bf24c144d064a274a71da47e7ece617" 945 | integrity sha512-hkaittm2607vVMe8eotANGN1CimD5tor7uoY3ypg2VTtEcDB/KGWYbJOz58t8LI4cWSyWtgqYQ5F0HwKxxhlkQ== 946 | dependencies: 947 | tslint-consistent-codestyle "^1.14.1" 948 | tslint-eslint-rules "^5.4.0" 949 | tslint-microsoft-contrib "~5.2.1" 950 | 951 | tslint-consistent-codestyle@^1.14.1: 952 | version "1.15.0" 953 | resolved "https://registry.yarnpkg.com/tslint-consistent-codestyle/-/tslint-consistent-codestyle-1.15.0.tgz#a3acf8d0a3ca0dc7d1285705102ba1fe4a17c4cb" 954 | integrity sha512-6BNDBbZh2K0ibRXe70Mkl9gfVttxQ3t3hqV1BRDfpIcjrUoOgD946iH4SrXp+IggDgeMs3dJORjD5tqL5j4jXg== 955 | dependencies: 956 | "@fimbul/bifrost" "^0.17.0" 957 | tslib "^1.7.1" 958 | tsutils "^2.29.0" 959 | 960 | tslint-eslint-rules@^5.4.0: 961 | version "5.4.0" 962 | resolved "https://registry.yarnpkg.com/tslint-eslint-rules/-/tslint-eslint-rules-5.4.0.tgz#e488cc9181bf193fe5cd7bfca213a7695f1737b5" 963 | integrity sha512-WlSXE+J2vY/VPgIcqQuijMQiel+UtmXS+4nvK4ZzlDiqBfXse8FAvkNnTcYhnQyOTW5KFM+uRRGXxYhFpuBc6w== 964 | dependencies: 965 | doctrine "0.7.2" 966 | tslib "1.9.0" 967 | tsutils "^3.0.0" 968 | 969 | tslint-microsoft-contrib@~5.2.1: 970 | version "5.2.1" 971 | resolved "https://registry.yarnpkg.com/tslint-microsoft-contrib/-/tslint-microsoft-contrib-5.2.1.tgz#a6286839f800e2591d041ea2800c77487844ad81" 972 | integrity sha512-PDYjvpo0gN9IfMULwKk0KpVOPMhU6cNoT9VwCOLeDl/QS8v8W2yspRpFFuUS7/c5EIH/n8ApMi8TxJAz1tfFUA== 973 | dependencies: 974 | tsutils "^2.27.2 <2.29.0" 975 | 976 | tslint@^5.12.1: 977 | version "5.12.1" 978 | resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.12.1.tgz#8cec9d454cf8a1de9b0a26d7bdbad6de362e52c1" 979 | integrity sha512-sfodBHOucFg6egff8d1BvuofoOQ/nOeYNfbp7LDlKBcLNrL3lmS5zoiDGyOMdT7YsEXAwWpTdAHwOGOc8eRZAw== 980 | dependencies: 981 | babel-code-frame "^6.22.0" 982 | builtin-modules "^1.1.1" 983 | chalk "^2.3.0" 984 | commander "^2.12.1" 985 | diff "^3.2.0" 986 | glob "^7.1.1" 987 | js-yaml "^3.7.0" 988 | minimatch "^3.0.4" 989 | resolve "^1.3.2" 990 | semver "^5.3.0" 991 | tslib "^1.8.0" 992 | tsutils "^2.27.2" 993 | 994 | tsutils@^2.27.2, tsutils@^2.29.0: 995 | version "2.29.0" 996 | resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" 997 | integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== 998 | dependencies: 999 | tslib "^1.8.1" 1000 | 1001 | "tsutils@^2.27.2 <2.29.0": 1002 | version "2.28.0" 1003 | resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.28.0.tgz#6bd71e160828f9d019b6f4e844742228f85169a1" 1004 | integrity sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA== 1005 | dependencies: 1006 | tslib "^1.8.1" 1007 | 1008 | tsutils@^3.0.0, tsutils@^3.5.0: 1009 | version "3.7.0" 1010 | resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.7.0.tgz#f97bdd2f109070bd1865467183e015b25734b477" 1011 | integrity sha512-n+e+3q7Jx2kfZw7tjfI9axEIWBY0sFMOlC+1K70X0SeXpO/UYSB+PN+E9tIJNqViB7oiXQdqD7dNchnvoneZew== 1012 | dependencies: 1013 | tslib "^1.8.1" 1014 | 1015 | typescript@^3.2.2: 1016 | version "3.2.2" 1017 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.2.tgz#fe8101c46aa123f8353523ebdcf5730c2ae493e5" 1018 | integrity sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg== 1019 | 1020 | util-deprecate@~1.0.1: 1021 | version "1.0.2" 1022 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 1023 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= 1024 | 1025 | wide-align@^1.1.0: 1026 | version "1.1.3" 1027 | resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" 1028 | integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== 1029 | dependencies: 1030 | string-width "^1.0.2 || 2" 1031 | 1032 | window-size@^0.1.4: 1033 | version "0.1.4" 1034 | resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876" 1035 | integrity sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY= 1036 | 1037 | with-callback@^1.0.2: 1038 | version "1.0.2" 1039 | resolved "https://registry.yarnpkg.com/with-callback/-/with-callback-1.0.2.tgz#a09629b9a920028d721404fb435bdcff5c91bc21" 1040 | integrity sha1-oJYpuakgAo1yFAT7Q1vc/1yRvCE= 1041 | 1042 | wrap-ansi@^2.0.0: 1043 | version "2.1.0" 1044 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" 1045 | integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= 1046 | dependencies: 1047 | string-width "^1.0.1" 1048 | strip-ansi "^3.0.1" 1049 | 1050 | wrappy@1: 1051 | version "1.0.2" 1052 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1053 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 1054 | 1055 | y18n@^3.2.0: 1056 | version "3.2.1" 1057 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" 1058 | integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= 1059 | 1060 | yallist@^3.0.0, yallist@^3.0.2: 1061 | version "3.0.3" 1062 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" 1063 | integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== 1064 | 1065 | yargs@^3.10.0: 1066 | version "3.32.0" 1067 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995" 1068 | integrity sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU= 1069 | dependencies: 1070 | camelcase "^2.0.1" 1071 | cliui "^3.0.3" 1072 | decamelize "^1.1.1" 1073 | os-locale "^1.4.0" 1074 | string-width "^1.0.1" 1075 | window-size "^0.1.4" 1076 | y18n "^3.2.0" 1077 | --------------------------------------------------------------------------------