| "use strict"; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| Object.defineProperty(exports, "__esModule", { value: true }); |
| exports.Client = void 0; |
| const call_1 = require("./call"); |
| const channel_1 = require("./channel"); |
| const connectivity_state_1 = require("./connectivity-state"); |
| const constants_1 = require("./constants"); |
| const metadata_1 = require("./metadata"); |
| const client_interceptors_1 = require("./client-interceptors"); |
| const CHANNEL_SYMBOL = Symbol(); |
| const INTERCEPTOR_SYMBOL = Symbol(); |
| const INTERCEPTOR_PROVIDER_SYMBOL = Symbol(); |
| const CALL_INVOCATION_TRANSFORMER_SYMBOL = Symbol(); |
| function isFunction(arg) { |
| return typeof arg === 'function'; |
| } |
| function getErrorStackString(error) { |
| var _a; |
| return ((_a = error.stack) === null || _a === void 0 ? void 0 : _a.split('\n').slice(1).join('\n')) || 'no stack trace available'; |
| } |
| |
| |
| |
| |
| class Client { |
| constructor(address, credentials, options = {}) { |
| var _a, _b; |
| options = Object.assign({}, options); |
| this[INTERCEPTOR_SYMBOL] = (_a = options.interceptors) !== null && _a !== void 0 ? _a : []; |
| delete options.interceptors; |
| this[INTERCEPTOR_PROVIDER_SYMBOL] = (_b = options.interceptor_providers) !== null && _b !== void 0 ? _b : []; |
| delete options.interceptor_providers; |
| if (this[INTERCEPTOR_SYMBOL].length > 0 && |
| this[INTERCEPTOR_PROVIDER_SYMBOL].length > 0) { |
| throw new Error('Both interceptors and interceptor_providers were passed as options ' + |
| 'to the client constructor. Only one of these is allowed.'); |
| } |
| this[CALL_INVOCATION_TRANSFORMER_SYMBOL] = |
| options.callInvocationTransformer; |
| delete options.callInvocationTransformer; |
| if (options.channelOverride) { |
| this[CHANNEL_SYMBOL] = options.channelOverride; |
| } |
| else if (options.channelFactoryOverride) { |
| const channelFactoryOverride = options.channelFactoryOverride; |
| delete options.channelFactoryOverride; |
| this[CHANNEL_SYMBOL] = channelFactoryOverride(address, credentials, options); |
| } |
| else { |
| this[CHANNEL_SYMBOL] = new channel_1.ChannelImplementation(address, credentials, options); |
| } |
| } |
| close() { |
| this[CHANNEL_SYMBOL].close(); |
| } |
| getChannel() { |
| return this[CHANNEL_SYMBOL]; |
| } |
| waitForReady(deadline, callback) { |
| const checkState = (err) => { |
| if (err) { |
| callback(new Error('Failed to connect before the deadline')); |
| return; |
| } |
| let newState; |
| try { |
| newState = this[CHANNEL_SYMBOL].getConnectivityState(true); |
| } |
| catch (e) { |
| callback(new Error('The channel has been closed')); |
| return; |
| } |
| if (newState === connectivity_state_1.ConnectivityState.READY) { |
| callback(); |
| } |
| else { |
| try { |
| this[CHANNEL_SYMBOL].watchConnectivityState(newState, deadline, checkState); |
| } |
| catch (e) { |
| callback(new Error('The channel has been closed')); |
| } |
| } |
| }; |
| setImmediate(checkState); |
| } |
| checkOptionalUnaryResponseArguments(arg1, arg2, arg3) { |
| if (isFunction(arg1)) { |
| return { metadata: new metadata_1.Metadata(), options: {}, callback: arg1 }; |
| } |
| else if (isFunction(arg2)) { |
| if (arg1 instanceof metadata_1.Metadata) { |
| return { metadata: arg1, options: {}, callback: arg2 }; |
| } |
| else { |
| return { metadata: new metadata_1.Metadata(), options: arg1, callback: arg2 }; |
| } |
| } |
| else { |
| if (!(arg1 instanceof metadata_1.Metadata && |
| arg2 instanceof Object && |
| isFunction(arg3))) { |
| throw new Error('Incorrect arguments passed'); |
| } |
| return { metadata: arg1, options: arg2, callback: arg3 }; |
| } |
| } |
| makeUnaryRequest(method, serialize, deserialize, argument, metadata, options, callback) { |
| var _a, _b; |
| const checkedArguments = this.checkOptionalUnaryResponseArguments(metadata, options, callback); |
| const methodDefinition = { |
| path: method, |
| requestStream: false, |
| responseStream: false, |
| requestSerialize: serialize, |
| responseDeserialize: deserialize, |
| }; |
| let callProperties = { |
| argument: argument, |
| metadata: checkedArguments.metadata, |
| call: new call_1.ClientUnaryCallImpl(), |
| channel: this[CHANNEL_SYMBOL], |
| methodDefinition: methodDefinition, |
| callOptions: checkedArguments.options, |
| callback: checkedArguments.callback, |
| }; |
| if (this[CALL_INVOCATION_TRANSFORMER_SYMBOL]) { |
| callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL](callProperties); |
| } |
| const emitter = callProperties.call; |
| const interceptorArgs = { |
| clientInterceptors: this[INTERCEPTOR_SYMBOL], |
| clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL], |
| callInterceptors: (_a = callProperties.callOptions.interceptors) !== null && _a !== void 0 ? _a : [], |
| callInterceptorProviders: (_b = callProperties.callOptions.interceptor_providers) !== null && _b !== void 0 ? _b : [], |
| }; |
| const call = (0, client_interceptors_1.getInterceptingCall)(interceptorArgs, callProperties.methodDefinition, callProperties.callOptions, callProperties.channel); |
| |
| |
| |
| |
| emitter.call = call; |
| let responseMessage = null; |
| let receivedStatus = false; |
| let callerStackError = new Error(); |
| call.start(callProperties.metadata, { |
| onReceiveMetadata: metadata => { |
| emitter.emit('metadata', metadata); |
| }, |
| |
| onReceiveMessage(message) { |
| if (responseMessage !== null) { |
| call.cancelWithStatus(constants_1.Status.UNIMPLEMENTED, 'Too many responses received'); |
| } |
| responseMessage = message; |
| }, |
| onReceiveStatus(status) { |
| if (receivedStatus) { |
| return; |
| } |
| receivedStatus = true; |
| if (status.code === constants_1.Status.OK) { |
| if (responseMessage === null) { |
| const callerStack = getErrorStackString(callerStackError); |
| callProperties.callback((0, call_1.callErrorFromStatus)({ |
| code: constants_1.Status.UNIMPLEMENTED, |
| details: 'No message received', |
| metadata: status.metadata, |
| }, callerStack)); |
| } |
| else { |
| callProperties.callback(null, responseMessage); |
| } |
| } |
| else { |
| const callerStack = getErrorStackString(callerStackError); |
| callProperties.callback((0, call_1.callErrorFromStatus)(status, callerStack)); |
| } |
| |
| |
| callerStackError = null; |
| emitter.emit('status', status); |
| }, |
| }); |
| call.sendMessage(argument); |
| call.halfClose(); |
| return emitter; |
| } |
| makeClientStreamRequest(method, serialize, deserialize, metadata, options, callback) { |
| var _a, _b; |
| const checkedArguments = this.checkOptionalUnaryResponseArguments(metadata, options, callback); |
| const methodDefinition = { |
| path: method, |
| requestStream: true, |
| responseStream: false, |
| requestSerialize: serialize, |
| responseDeserialize: deserialize, |
| }; |
| let callProperties = { |
| metadata: checkedArguments.metadata, |
| call: new call_1.ClientWritableStreamImpl(serialize), |
| channel: this[CHANNEL_SYMBOL], |
| methodDefinition: methodDefinition, |
| callOptions: checkedArguments.options, |
| callback: checkedArguments.callback, |
| }; |
| if (this[CALL_INVOCATION_TRANSFORMER_SYMBOL]) { |
| callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL](callProperties); |
| } |
| const emitter = callProperties.call; |
| const interceptorArgs = { |
| clientInterceptors: this[INTERCEPTOR_SYMBOL], |
| clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL], |
| callInterceptors: (_a = callProperties.callOptions.interceptors) !== null && _a !== void 0 ? _a : [], |
| callInterceptorProviders: (_b = callProperties.callOptions.interceptor_providers) !== null && _b !== void 0 ? _b : [], |
| }; |
| const call = (0, client_interceptors_1.getInterceptingCall)(interceptorArgs, callProperties.methodDefinition, callProperties.callOptions, callProperties.channel); |
| |
| |
| |
| |
| emitter.call = call; |
| let responseMessage = null; |
| let receivedStatus = false; |
| let callerStackError = new Error(); |
| call.start(callProperties.metadata, { |
| onReceiveMetadata: metadata => { |
| emitter.emit('metadata', metadata); |
| }, |
| |
| onReceiveMessage(message) { |
| if (responseMessage !== null) { |
| call.cancelWithStatus(constants_1.Status.UNIMPLEMENTED, 'Too many responses received'); |
| } |
| responseMessage = message; |
| call.startRead(); |
| }, |
| onReceiveStatus(status) { |
| if (receivedStatus) { |
| return; |
| } |
| receivedStatus = true; |
| if (status.code === constants_1.Status.OK) { |
| if (responseMessage === null) { |
| const callerStack = getErrorStackString(callerStackError); |
| callProperties.callback((0, call_1.callErrorFromStatus)({ |
| code: constants_1.Status.UNIMPLEMENTED, |
| details: 'No message received', |
| metadata: status.metadata, |
| }, callerStack)); |
| } |
| else { |
| callProperties.callback(null, responseMessage); |
| } |
| } |
| else { |
| const callerStack = getErrorStackString(callerStackError); |
| callProperties.callback((0, call_1.callErrorFromStatus)(status, callerStack)); |
| } |
| |
| |
| callerStackError = null; |
| emitter.emit('status', status); |
| }, |
| }); |
| return emitter; |
| } |
| checkMetadataAndOptions(arg1, arg2) { |
| let metadata; |
| let options; |
| if (arg1 instanceof metadata_1.Metadata) { |
| metadata = arg1; |
| if (arg2) { |
| options = arg2; |
| } |
| else { |
| options = {}; |
| } |
| } |
| else { |
| if (arg1) { |
| options = arg1; |
| } |
| else { |
| options = {}; |
| } |
| metadata = new metadata_1.Metadata(); |
| } |
| return { metadata, options }; |
| } |
| makeServerStreamRequest(method, serialize, deserialize, argument, metadata, options) { |
| var _a, _b; |
| const checkedArguments = this.checkMetadataAndOptions(metadata, options); |
| const methodDefinition = { |
| path: method, |
| requestStream: false, |
| responseStream: true, |
| requestSerialize: serialize, |
| responseDeserialize: deserialize, |
| }; |
| let callProperties = { |
| argument: argument, |
| metadata: checkedArguments.metadata, |
| call: new call_1.ClientReadableStreamImpl(deserialize), |
| channel: this[CHANNEL_SYMBOL], |
| methodDefinition: methodDefinition, |
| callOptions: checkedArguments.options, |
| }; |
| if (this[CALL_INVOCATION_TRANSFORMER_SYMBOL]) { |
| callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL](callProperties); |
| } |
| const stream = callProperties.call; |
| const interceptorArgs = { |
| clientInterceptors: this[INTERCEPTOR_SYMBOL], |
| clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL], |
| callInterceptors: (_a = callProperties.callOptions.interceptors) !== null && _a !== void 0 ? _a : [], |
| callInterceptorProviders: (_b = callProperties.callOptions.interceptor_providers) !== null && _b !== void 0 ? _b : [], |
| }; |
| const call = (0, client_interceptors_1.getInterceptingCall)(interceptorArgs, callProperties.methodDefinition, callProperties.callOptions, callProperties.channel); |
| |
| |
| |
| |
| stream.call = call; |
| let receivedStatus = false; |
| let callerStackError = new Error(); |
| call.start(callProperties.metadata, { |
| onReceiveMetadata(metadata) { |
| stream.emit('metadata', metadata); |
| }, |
| |
| onReceiveMessage(message) { |
| stream.push(message); |
| }, |
| onReceiveStatus(status) { |
| if (receivedStatus) { |
| return; |
| } |
| receivedStatus = true; |
| stream.push(null); |
| if (status.code !== constants_1.Status.OK) { |
| const callerStack = getErrorStackString(callerStackError); |
| stream.emit('error', (0, call_1.callErrorFromStatus)(status, callerStack)); |
| } |
| |
| |
| callerStackError = null; |
| stream.emit('status', status); |
| }, |
| }); |
| call.sendMessage(argument); |
| call.halfClose(); |
| return stream; |
| } |
| makeBidiStreamRequest(method, serialize, deserialize, metadata, options) { |
| var _a, _b; |
| const checkedArguments = this.checkMetadataAndOptions(metadata, options); |
| const methodDefinition = { |
| path: method, |
| requestStream: true, |
| responseStream: true, |
| requestSerialize: serialize, |
| responseDeserialize: deserialize, |
| }; |
| let callProperties = { |
| metadata: checkedArguments.metadata, |
| call: new call_1.ClientDuplexStreamImpl(serialize, deserialize), |
| channel: this[CHANNEL_SYMBOL], |
| methodDefinition: methodDefinition, |
| callOptions: checkedArguments.options, |
| }; |
| if (this[CALL_INVOCATION_TRANSFORMER_SYMBOL]) { |
| callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL](callProperties); |
| } |
| const stream = callProperties.call; |
| const interceptorArgs = { |
| clientInterceptors: this[INTERCEPTOR_SYMBOL], |
| clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL], |
| callInterceptors: (_a = callProperties.callOptions.interceptors) !== null && _a !== void 0 ? _a : [], |
| callInterceptorProviders: (_b = callProperties.callOptions.interceptor_providers) !== null && _b !== void 0 ? _b : [], |
| }; |
| const call = (0, client_interceptors_1.getInterceptingCall)(interceptorArgs, callProperties.methodDefinition, callProperties.callOptions, callProperties.channel); |
| |
| |
| |
| |
| stream.call = call; |
| let receivedStatus = false; |
| let callerStackError = new Error(); |
| call.start(callProperties.metadata, { |
| onReceiveMetadata(metadata) { |
| stream.emit('metadata', metadata); |
| }, |
| onReceiveMessage(message) { |
| stream.push(message); |
| }, |
| onReceiveStatus(status) { |
| if (receivedStatus) { |
| return; |
| } |
| receivedStatus = true; |
| stream.push(null); |
| if (status.code !== constants_1.Status.OK) { |
| const callerStack = getErrorStackString(callerStackError); |
| stream.emit('error', (0, call_1.callErrorFromStatus)(status, callerStack)); |
| } |
| |
| |
| callerStackError = null; |
| stream.emit('status', status); |
| }, |
| }); |
| return stream; |
| } |
| } |
| exports.Client = Client; |
| |