From c62203900ef7f9864b052a63ba0c13ada160c1f9 Mon Sep 17 00:00:00 2001 From: Patrick Remy Date: Thu, 9 Apr 2020 10:12:47 +0200 Subject: [PATCH 01/18] grpc-js: adjust ts definitions to equal native-core Export MethodDefinition in index.ts and add generic ImplementationType to ServiceDefinition --- packages/grpc-js/src/index.ts | 2 ++ packages/grpc-js/src/make-client.ts | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/src/index.ts b/packages/grpc-js/src/index.ts index 941174c0..5e7b8671 100644 --- a/packages/grpc-js/src/index.ts +++ b/packages/grpc-js/src/index.ts @@ -35,6 +35,7 @@ import { Deserialize, loadPackageDefinition, makeClientConstructor, + MethodDefinition, Serialize, ServiceDefinition, } from './make-client'; @@ -230,6 +231,7 @@ export { ClientWritableStream, ClientDuplexStream, CallOptions, + MethodDefinition, StatusObject, ServiceError, ServerUnaryCall, diff --git a/packages/grpc-js/src/make-client.ts b/packages/grpc-js/src/make-client.ts index 99d40a64..e9e5ead9 100644 --- a/packages/grpc-js/src/make-client.ts +++ b/packages/grpc-js/src/make-client.ts @@ -18,6 +18,7 @@ import { ChannelCredentials } from './channel-credentials'; import { ChannelOptions } from './channel-options'; import { Client } from './client'; +import { UntypedServiceImplementation } from './server'; export interface Serialize { (value: T): Buffer; @@ -49,9 +50,9 @@ export interface MethodDefinition extends ClientMethodDefinition, ServerMethodDefinition {} -export interface ServiceDefinition { +export type ServiceDefinition = { // tslint:disable-next-line no-any - [index: string]: MethodDefinition; + readonly [index in keyof ImplementationType]: MethodDefinition; } export interface ProtobufTypeDefinition { From 75b486b345446993ac6967e7c0572f455adb6935 Mon Sep 17 00:00:00 2001 From: Patrick Remy Date: Thu, 9 Apr 2020 11:37:17 +0200 Subject: [PATCH 02/18] gprc-js: remove deprecated tslint Upgrade to gts v2, replace npm lint with check, and specify src path --- packages/grpc-js/package.json | 9 +++++---- packages/grpc-js/tslint.json | 8 -------- 2 files changed, 5 insertions(+), 12 deletions(-) delete mode 100644 packages/grpc-js/tslint.json diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 7276e8c4..3128066c 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -26,7 +26,8 @@ "@types/semver": "^6.0.1", "clang-format": "^1.0.55", "execa": "^2.0.3", - "gts": "^1.1.0", + "google-ts-style": "^0.2.0", + "gts": "^2.0.0-alpha.9", "gulp": "^4.0.2", "gulp-mocha": "^6.0.0", "lodash": "^4.17.4", @@ -46,11 +47,11 @@ "clean": "gts clean", "compile": "tsc -p .", "format": "clang-format -i -style=\"{Language: JavaScript, BasedOnStyle: Google, ColumnLimit: 80}\" src/*.ts test/*.ts", - "lint": "tslint -c node_modules/google-ts-style/tslint.json -p . -t codeFrame --type-check", + "lint": "npm run check", "prepare": "npm run compile", "test": "gulp test", - "check": "gts check", - "fix": "gts fix", + "check": "gts check src/**/*.ts", + "fix": "gts fix src/**/*.ts", "pretest": "npm run compile", "posttest": "npm run check" }, diff --git a/packages/grpc-js/tslint.json b/packages/grpc-js/tslint.json deleted file mode 100644 index 27872a13..00000000 --- a/packages/grpc-js/tslint.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "gts/tslint.json", - "linterOptions": { - "exclude": [ - "**/*.json" - ] - } -} From 16ec0f0f6414687a53e9f05d4621b88162a9f1d7 Mon Sep 17 00:00:00 2001 From: Patrick Remy Date: Thu, 9 Apr 2020 11:52:24 +0200 Subject: [PATCH 03/18] grpc-js: allow any for linting globally The any type is purposely used. All functions validate their input at runtime. --- packages/grpc-js/.eslintrc | 7 +++++++ packages/grpc-js/src/call-stream.ts | 3 --- packages/grpc-js/src/channel-credentials.ts | 1 - packages/grpc-js/src/client-interceptors.ts | 17 ----------------- packages/grpc-js/src/client.ts | 3 --- packages/grpc-js/src/index.ts | 10 +++------- packages/grpc-js/src/load-balancing-config.ts | 4 ---- packages/grpc-js/src/logging.ts | 2 -- packages/grpc-js/src/make-client.ts | 2 -- packages/grpc-js/src/object-stream.ts | 2 -- packages/grpc-js/src/server-call.ts | 3 --- packages/grpc-js/src/server.ts | 6 ++---- packages/grpc-js/src/service-config.ts | 4 ---- packages/grpc-js/src/subchannel-pool.ts | 1 - packages/grpc-js/test/common.ts | 1 - .../grpc-js/test/test-channel-credentials.ts | 1 - packages/grpc-js/test/test-resolver.ts | 2 -- .../grpc-js/test/test-server-credentials.ts | 1 - packages/grpc-js/test/test-server-deadlines.ts | 1 - packages/grpc-js/test/test-server-errors.ts | 1 - packages/grpc-js/test/test-server.ts | 5 ++--- 21 files changed, 14 insertions(+), 63 deletions(-) create mode 100644 packages/grpc-js/.eslintrc diff --git a/packages/grpc-js/.eslintrc b/packages/grpc-js/.eslintrc new file mode 100644 index 00000000..46b51a24 --- /dev/null +++ b/packages/grpc-js/.eslintrc @@ -0,0 +1,7 @@ +{ + "root": true, + "extends": "./node_modules/gts", + "rules": { + "@typescript-eslint/no-explicit-any": "off" + } +} diff --git a/packages/grpc-js/src/call-stream.ts b/packages/grpc-js/src/call-stream.ts index 443d5ebf..ee7024c2 100644 --- a/packages/grpc-js/src/call-stream.ts +++ b/packages/grpc-js/src/call-stream.ts @@ -69,7 +69,6 @@ export interface MetadataListener { } export interface MessageListener { - // tslint:disable-next-line no-any (message: any, next: (message: any) => void): void; } @@ -90,7 +89,6 @@ export type Listener = Partial; */ export interface InterceptingListener { onReceiveMetadata(metadata: Metadata): void; - // tslint:disable-next-line no-any onReceiveMessage(message: any): void; onReceiveStatus(status: StatusObject): void; } @@ -117,7 +115,6 @@ export class InterceptingListenerImpl implements InterceptingListener { this.nextListener.onReceiveMetadata(metadata); }); } - // tslint:disable-next-line no-any onReceiveMessage(message: any): void { /* If this listener processes messages asynchronously, the last message may * be reordered with respect to the status */ diff --git a/packages/grpc-js/src/channel-credentials.ts b/packages/grpc-js/src/channel-credentials.ts index 5d5b87d5..7eb76a38 100644 --- a/packages/grpc-js/src/channel-credentials.ts +++ b/packages/grpc-js/src/channel-credentials.ts @@ -20,7 +20,6 @@ import { ConnectionOptions, createSecureContext, PeerCertificate } from 'tls'; import { CallCredentials } from './call-credentials'; import { CIPHER_SUITES, getDefaultRootsData } from './tls-helpers'; -// tslint:disable-next-line:no-any function verifyIsBufferOrNull(obj: any, friendlyName: string): void { if (obj && !(obj instanceof Buffer)) { throw new TypeError(`${friendlyName}, if provided, must be a Buffer.`); diff --git a/packages/grpc-js/src/client-interceptors.ts b/packages/grpc-js/src/client-interceptors.ts index 9892959e..c20db534 100644 --- a/packages/grpc-js/src/client-interceptors.ts +++ b/packages/grpc-js/src/client-interceptors.ts @@ -64,7 +64,6 @@ export interface MetadataRequester { } export interface MessageRequester { - // tslint:disable-next-line no-any (message: any, next: (message: any) => void): void; } @@ -189,7 +188,6 @@ const defaultRequester: FullRequester = { }; export interface InterceptorOptions extends CallOptions { - // tslint:disable-next-line no-any method_definition: ClientMethodDefinition; } @@ -197,9 +195,7 @@ export interface InterceptingCallInterface { cancelWithStatus(status: Status, details: string): void; getPeer(): string; start(metadata: Metadata, listener?: Partial): void; - // tslint:disable-next-line no-any sendMessageWithContext(context: MessageContext, message: any): void; - // tslint:disable-next-line no-any sendMessage(message: any): void; startRead(): void; halfClose(): void; @@ -283,7 +279,6 @@ export class InterceptingCall implements InterceptingCallInterface { this.nextCall.start(md, finalInterceptingListener); }); } - // tslint:disable-next-line no-any sendMessageWithContext(context: MessageContext, message: any): void { this.processingMessage = true; this.requester.sendMessage(message, finalMessage => { @@ -294,7 +289,6 @@ export class InterceptingCall implements InterceptingCallInterface { } }); } - // tslint:disable-next-line no-any sendMessage(message: any): void { this.sendMessageWithContext({}, message); } @@ -343,7 +337,6 @@ function getCall(channel: Channel, path: string, options: CallOptions): Call { * object and handles serialization and deseraizliation. */ class BaseInterceptingCall implements InterceptingCallInterface { - // tslint:disable-next-line no-any constructor( protected call: Call, protected methodDefinition: ClientMethodDefinition @@ -357,7 +350,6 @@ class BaseInterceptingCall implements InterceptingCallInterface { setCredentials(credentials: CallCredentials): void { this.call.setCredentials(credentials); } - // tslint:disable-next-line no-any sendMessageWithContext(context: MessageContext, message: any): void { let serialized: Buffer; try { @@ -367,7 +359,6 @@ class BaseInterceptingCall implements InterceptingCallInterface { this.call.cancelWithStatus(Status.INTERNAL, 'Serialization failure'); } } - // tslint:disable-next-line no-any sendMessage(message: any) { this.sendMessageWithContext({}, message); } @@ -381,7 +372,6 @@ class BaseInterceptingCall implements InterceptingCallInterface { interceptingListener?.onReceiveMetadata?.(metadata); }, onReceiveMessage: message => { - // tslint:disable-next-line no-any let deserialized: any; try { deserialized = this.methodDefinition.responseDeserialize(message); @@ -418,7 +408,6 @@ class BaseInterceptingCall implements InterceptingCallInterface { */ class BaseUnaryInterceptingCall extends BaseInterceptingCall implements InterceptingCallInterface { - // tslint:disable-next-line no-any constructor(call: Call, methodDefinition: ClientMethodDefinition) { super(call, methodDefinition); } @@ -427,7 +416,6 @@ class BaseUnaryInterceptingCall extends BaseInterceptingCall const wrapperListener: InterceptingListener = { onReceiveMetadata: listener?.onReceiveMetadata?.bind(listener) ?? (metadata => {}), - // tslint:disable-next-line no-any onReceiveMessage: (message: any) => { receivedMessage = true; listener?.onReceiveMessage?.(message); @@ -450,8 +438,6 @@ class BaseUnaryInterceptingCall extends BaseInterceptingCall */ class BaseStreamingInterceptingCall extends BaseInterceptingCall implements InterceptingCallInterface {} - -// tslint:disable-next-line no-any function getBottomInterceptingCall( channel: Channel, options: InterceptorOptions, @@ -474,7 +460,6 @@ export interface Interceptor { } export interface InterceptorProvider { - // tslint:disable-next-line no-any (methodDefinition: ClientMethodDefinition): Interceptor; } @@ -484,8 +469,6 @@ export interface InterceptorArguments { callInterceptors: Interceptor[]; callInterceptorProviders: InterceptorProvider[]; } - -// tslint:disable-next-line no-any export function getInterceptingCall( interceptorArgs: InterceptorArguments, methodDefinition: ClientMethodDefinition, diff --git a/packages/grpc-js/src/client.ts b/packages/grpc-js/src/client.ts index 8b4b7eea..118375b2 100644 --- a/packages/grpc-js/src/client.ts +++ b/packages/grpc-js/src/client.ts @@ -306,7 +306,6 @@ export class Client { onReceiveMetadata: metadata => { emitter.emit('metadata', metadata); }, - // tslint:disable-next-line no-any onReceiveMessage(message: any) { if (responseMessage != null) { call.cancelWithStatus(Status.INTERNAL, 'Too many responses received'); @@ -418,7 +417,6 @@ export class Client { onReceiveMetadata: metadata => { emitter.emit('metadata', metadata); }, - // tslint:disable-next-line no-any onReceiveMessage(message: any) { if (responseMessage != null) { call.cancelWithStatus(Status.INTERNAL, 'Too many responses received'); @@ -536,7 +534,6 @@ export class Client { onReceiveMetadata(metadata: Metadata) { stream.emit('metadata', metadata); }, - // tslint:disable-next-line no-any onReceiveMessage(message: any) { if (stream.push(message)) { call.startRead(); diff --git a/packages/grpc-js/src/index.ts b/packages/grpc-js/src/index.ts index 941174c0..5c77a3ff 100644 --- a/packages/grpc-js/src/index.ts +++ b/packages/grpc-js/src/index.ts @@ -62,15 +62,15 @@ if (!semver.satisfies(process.version, supportedNodeVersions)) { } interface IndexedObject { - [key: string]: any; // tslint:disable-line no-any - [key: number]: any; // tslint:disable-line no-any + [key: string]: any; + [key: number]: any; } function mixin(...sources: IndexedObject[]) { const result: { [key: string]: Function } = {}; for (const source of sources) { for (const propName of Object.getOwnPropertyNames(source)) { - const property: any = source[propName]; // tslint:disable-line no-any + const property: any = source[propName]; if (typeof property === 'function') { result[propName] = property; } @@ -245,18 +245,14 @@ export { export { handleBidiStreamingCall, handleServerStreamingCall, handleUnaryCall }; -/* tslint:disable:no-any */ export type Call = | ClientUnaryCall | ClientReadableStream | ClientWritableStream | ClientDuplexStream; -/* tslint:enable:no-any */ /**** Unimplemented function stubs ****/ -/* tslint:disable:no-any variable-name */ - export const loadObject = (value: any, options: any) => { throw new Error( 'Not available in this library. Use @grpc/proto-loader and loadPackageDefinition instead' diff --git a/packages/grpc-js/src/load-balancing-config.ts b/packages/grpc-js/src/load-balancing-config.ts index 8607f1fc..4a895903 100644 --- a/packages/grpc-js/src/load-balancing-config.ts +++ b/packages/grpc-js/src/load-balancing-config.ts @@ -21,10 +21,6 @@ * specific object type if the input has the right structure, and throws an * error otherwise. */ -/* The any type is purposely used here. All functions validate their input at - * runtime */ -/* tslint:disable:no-any */ - export interface RoundRobinConfig {} export interface XdsConfig { diff --git a/packages/grpc-js/src/logging.ts b/packages/grpc-js/src/logging.ts index 13ed2b7e..c7a63a47 100644 --- a/packages/grpc-js/src/logging.ts +++ b/packages/grpc-js/src/logging.ts @@ -47,8 +47,6 @@ export const setLogger = (logger: Partial): void => { export const setLoggerVerbosity = (verbosity: LogVerbosity): void => { _logVerbosity = verbosity; }; - -// tslint:disable-next-line no-any export const log = (severity: LogVerbosity, ...args: any[]): void => { if (severity >= _logVerbosity && typeof _logger.error === 'function') { _logger.error(...args); diff --git a/packages/grpc-js/src/make-client.ts b/packages/grpc-js/src/make-client.ts index 99d40a64..f55f4917 100644 --- a/packages/grpc-js/src/make-client.ts +++ b/packages/grpc-js/src/make-client.ts @@ -50,7 +50,6 @@ export interface MethodDefinition ServerMethodDefinition {} export interface ServiceDefinition { - // tslint:disable-next-line no-any [index: string]: MethodDefinition; } @@ -165,7 +164,6 @@ function partial( serialize: Function, deserialize: Function ): Function { - // tslint:disable-next-line:no-any return function(this: any, ...args: any[]) { return fn.call(this, path, serialize, deserialize, ...args); }; diff --git a/packages/grpc-js/src/object-stream.ts b/packages/grpc-js/src/object-stream.ts index 624e547c..8d29b786 100644 --- a/packages/grpc-js/src/object-stream.ts +++ b/packages/grpc-js/src/object-stream.ts @@ -18,8 +18,6 @@ import { Duplex, Readable, Writable } from 'stream'; import { EmitterAugmentation1 } from './events'; -// tslint:disable:no-any - export type WriteCallback = (error: Error | null | undefined) => void; export interface IntermediateObjectReadable extends Readable { diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index efdf1bcc..d6b55ae8 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -174,7 +174,6 @@ export class ServerWritableStreamImpl async _write( chunk: ResponseType, encoding: string, - // tslint:disable-next-line:no-any callback: (...args: any[]) => void ) { try { @@ -201,7 +200,6 @@ export class ServerWritableStreamImpl callback(null); } - // tslint:disable-next-line:no-any end(metadata?: any) { if (metadata) { this.trailingMetadata = metadata; @@ -671,7 +669,6 @@ export class Http2ServerCallStream< } } -// tslint:disable:no-any type UntypedServerCall = Http2ServerCallStream; function handleExpiredDeadline(call: UntypedServerCall) { diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index fc48f3cf..c37f69f7 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -67,7 +67,6 @@ function getUnimplementedStatusResponse( }; } -// tslint:disable:no-any type UntypedUnaryHandler = UnaryHandler; type UntypedClientStreamingHandler = ClientStreamingHandler; type UntypedServerStreamingHandler = ServerStreamingHandler; @@ -113,7 +112,7 @@ function getDefaultHandler(handlerType: HandlerType, methodName: string) { export class Server { private http2ServerList: (http2.Http2Server | http2.Http2SecureServer)[] = []; - + private handlers: Map = new Map< string, UntypedHandler @@ -261,7 +260,7 @@ export class Server { } else { addr = address } - + const http2Server = setupServer(); return new Promise((resolve, reject) => { function onError(err: Error): void { @@ -380,7 +379,6 @@ export class Server { this.sessions.forEach(session => { // Cast NGHTTP2_CANCEL to any because TypeScript doesn't seem to // recognize destroy(code) as a valid signature. - // tslint:disable-next-line:no-any session.destroy(http2.constants.NGHTTP2_CANCEL as any); }); this.sessions.clear(); diff --git a/packages/grpc-js/src/service-config.ts b/packages/grpc-js/src/service-config.ts index e4631507..b1b0fdd4 100644 --- a/packages/grpc-js/src/service-config.ts +++ b/packages/grpc-js/src/service-config.ts @@ -22,10 +22,6 @@ * specific object type if the input has the right structure, and throws an * error otherwise. */ -/* The any type is purposely used here. All functions validate their input at - * runtime */ -/* tslint:disable:no-any */ - import * as lbconfig from './load-balancing-config'; import * as os from 'os'; diff --git a/packages/grpc-js/src/subchannel-pool.ts b/packages/grpc-js/src/subchannel-pool.ts index 0f198afe..634d2575 100644 --- a/packages/grpc-js/src/subchannel-pool.ts +++ b/packages/grpc-js/src/subchannel-pool.ts @@ -63,7 +63,6 @@ export class SubchannelPool { /* These objects are created with Object.create(null), so they do not * have a prototype, which means that for (... in ...) loops over them * do not need to be filtered */ - // tslint:disable-next-line:forin for (const channelTarget in this.pool) { const subchannelObjArray = this.pool[channelTarget]; diff --git a/packages/grpc-js/test/common.ts b/packages/grpc-js/test/common.ts index 19d8d275..4f8c5ff8 100644 --- a/packages/grpc-js/test/common.ts +++ b/packages/grpc-js/test/common.ts @@ -73,7 +73,6 @@ export namespace assert2 { * Wraps a function to keep track of whether it was called or not. * @param fn The function to wrap. */ - // tslint:disable:no-any export function mustCall( fn: (...args: any[]) => T ): (...args: any[]) => T { diff --git a/packages/grpc-js/test/test-channel-credentials.ts b/packages/grpc-js/test/test-channel-credentials.ts index d6028f46..99966941 100644 --- a/packages/grpc-js/test/test-channel-credentials.ts +++ b/packages/grpc-js/test/test-channel-credentials.ts @@ -49,7 +49,6 @@ class CallCredentialsMock implements CallCredentials { } } -// tslint:disable-next-line:no-any const readFile: (...args: any[]) => Promise = promisify(fs.readFile); // A promise which resolves to loaded files in the form { ca, key, cert } const pFixtures = Promise.all( diff --git a/packages/grpc-js/test/test-resolver.ts b/packages/grpc-js/test/test-resolver.ts index 7f4900aa..57997c17 100644 --- a/packages/grpc-js/test/test-resolver.ts +++ b/packages/grpc-js/test/test-resolver.ts @@ -15,8 +15,6 @@ * */ -// Allow `any` data type for testing runtime type checking. -// tslint:disable no-any import * as assert from 'assert'; import * as resolverManager from '../src/resolver'; import { ServiceConfig } from '../src/service-config'; diff --git a/packages/grpc-js/test/test-server-credentials.ts b/packages/grpc-js/test/test-server-credentials.ts index ec1740f7..9cc08b10 100644 --- a/packages/grpc-js/test/test-server-credentials.ts +++ b/packages/grpc-js/test/test-server-credentials.ts @@ -16,7 +16,6 @@ */ // Allow `any` data type for testing runtime type checking. -// tslint:disable no-any import * as assert from 'assert'; import { readFileSync } from 'fs'; import { join } from 'path'; diff --git a/packages/grpc-js/test/test-server-deadlines.ts b/packages/grpc-js/test/test-server-deadlines.ts index c1152309..107994ba 100644 --- a/packages/grpc-js/test/test-server-deadlines.ts +++ b/packages/grpc-js/test/test-server-deadlines.ts @@ -16,7 +16,6 @@ */ // Allow `any` data type for testing runtime type checking. -// tslint:disable no-any import * as assert from 'assert'; import * as path from 'path'; diff --git a/packages/grpc-js/test/test-server-errors.ts b/packages/grpc-js/test/test-server-errors.ts index 7c611b9b..8e9f4520 100644 --- a/packages/grpc-js/test/test-server-errors.ts +++ b/packages/grpc-js/test/test-server-errors.ts @@ -16,7 +16,6 @@ */ // Allow `any` data type for testing runtime type checking. -// tslint:disable no-any import * as assert from 'assert'; import { join } from 'path'; diff --git a/packages/grpc-js/test/test-server.ts b/packages/grpc-js/test/test-server.ts index 434efbbc..c8d2e64a 100644 --- a/packages/grpc-js/test/test-server.ts +++ b/packages/grpc-js/test/test-server.ts @@ -16,7 +16,6 @@ */ // Allow `any` data type for testing runtime type checking. -// tslint:disable no-any import * as assert from 'assert'; import * as fs from 'fs'; import * as http2 from 'http2'; @@ -39,13 +38,13 @@ describe('Server', () => { describe('constructor', () => { it('should work with no arguments', () => { assert.doesNotThrow(() => { - new Server(); // tslint:disable-line:no-unused-expression + new Server(); }); }); it('should work with an empty object argument', () => { assert.doesNotThrow(() => { - new Server({}); // tslint:disable-line:no-unused-expression + new Server({}); }); }); From f4e295cdce2805928afbf4298f8ae35ed972ed3b Mon Sep 17 00:00:00 2001 From: Patrick Remy Date: Thu, 9 Apr 2020 11:53:13 +0200 Subject: [PATCH 04/18] grpc-js: linting fix no-unpublished-import for ts --- packages/grpc-js/.eslintrc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/.eslintrc b/packages/grpc-js/.eslintrc index 46b51a24..6b0cac4a 100644 --- a/packages/grpc-js/.eslintrc +++ b/packages/grpc-js/.eslintrc @@ -2,6 +2,9 @@ "root": true, "extends": "./node_modules/gts", "rules": { - "@typescript-eslint/no-explicit-any": "off" + "@typescript-eslint/no-explicit-any": "off", + "node/no-unpublished-import": ["error", { + "tryExtensions": [".ts", ".js", ".json", ".node"] + }] } } From b84d2f3b39eb2e51457e372fd5972df77281fbb6 Mon Sep 17 00:00:00 2001 From: Patrick Remy Date: Thu, 9 Apr 2020 11:54:09 +0200 Subject: [PATCH 05/18] grpc-js: run gts fix for src --- packages/grpc-js/src/call-credentials.ts | 2 +- packages/grpc-js/src/call-stream.ts | 29 ++- packages/grpc-js/src/call.ts | 12 +- packages/grpc-js/src/channel.ts | 76 +++++--- packages/grpc-js/src/client-interceptors.ts | 36 ++-- packages/grpc-js/src/client.ts | 78 +++++--- packages/grpc-js/src/filter-stack.ts | 2 +- packages/grpc-js/src/http_proxy.ts | 74 ++++++-- packages/grpc-js/src/index.ts | 13 +- .../grpc-js/src/load-balancer-pick-first.ts | 4 +- .../grpc-js/src/load-balancer-round-robin.ts | 6 +- packages/grpc-js/src/make-client.ts | 4 +- packages/grpc-js/src/metadata.ts | 14 +- packages/grpc-js/src/resolver-dns.ts | 171 ++++++++++-------- packages/grpc-js/src/server-call.ts | 6 +- packages/grpc-js/src/server.ts | 161 +++++++++++------ packages/grpc-js/src/subchannel-pool.ts | 2 +- packages/grpc-js/src/subchannel.ts | 26 ++- 18 files changed, 435 insertions(+), 281 deletions(-) diff --git a/packages/grpc-js/src/call-credentials.ts b/packages/grpc-js/src/call-credentials.ts index e38672ae..e5d22bf7 100644 --- a/packages/grpc-js/src/call-credentials.ts +++ b/packages/grpc-js/src/call-credentials.ts @@ -79,7 +79,7 @@ class ComposedCallCredentials extends CallCredentials { async generateMetadata(options: CallMetadataOptions): Promise { const base: Metadata = new Metadata(); const generated: Metadata[] = await Promise.all( - this.creds.map(cred => cred.generateMetadata(options)) + this.creds.map((cred) => cred.generateMetadata(options)) ); for (const gen of generated) { base.merge(gen); diff --git a/packages/grpc-js/src/call-stream.ts b/packages/grpc-js/src/call-stream.ts index ee7024c2..f40366ca 100644 --- a/packages/grpc-js/src/call-stream.ts +++ b/packages/grpc-js/src/call-stream.ts @@ -111,7 +111,7 @@ export class InterceptingListenerImpl implements InterceptingListener { ) {} onReceiveMetadata(metadata: Metadata): void { - this.listener.onReceiveMetadata(metadata, metadata => { + this.listener.onReceiveMetadata(metadata, (metadata) => { this.nextListener.onReceiveMetadata(metadata); }); } @@ -119,7 +119,7 @@ export class InterceptingListenerImpl implements InterceptingListener { /* If this listener processes messages asynchronously, the last message may * be reordered with respect to the status */ this.processingMessage = true; - this.listener.onReceiveMessage(message, msg => { + this.listener.onReceiveMessage(message, (msg) => { this.processingMessage = false; this.nextListener.onReceiveMessage(msg); if (this.pendingStatus) { @@ -128,7 +128,7 @@ export class InterceptingListenerImpl implements InterceptingListener { }); } onReceiveStatus(status: StatusObject): void { - this.listener.onReceiveStatus(status, processedStatus => { + this.listener.onReceiveStatus(status, (processedStatus) => { if (this.processingMessage) { this.pendingStatus = processedStatus; } else { @@ -221,7 +221,9 @@ export class Http2CallStream implements Call { /* Precondition: this.finalStatus !== null */ if (!this.statusOutput) { this.statusOutput = true; - const filteredStatus = this.filterStack.receiveTrailers(this.finalStatus!); + const filteredStatus = this.filterStack.receiveTrailers( + this.finalStatus! + ); this.listener!.onReceiveStatus(filteredStatus); if (this.subchannel) { this.subchannel.callUnref(); @@ -352,7 +354,7 @@ export class Http2CallStream implements Call { private handleTrailers(headers: http2.IncomingHttpHeaders) { let headersString = ''; for (const header of Object.keys(headers)) { - headersString += '\t\t' + header + ': ' + headers[header] + '\n' + headersString += '\t\t' + header + ': ' + headers[header] + '\n'; } this.trace('Received server trailers:\n' + headersString); let metadata: Metadata; @@ -363,7 +365,10 @@ export class Http2CallStream implements Call { } const metadataMap = metadata.getMap(); let code: Status = this.mappedStatusCode; - if (code === Status.UNKNOWN && typeof metadataMap['grpc-status'] === 'string') { + if ( + code === Status.UNKNOWN && + typeof metadataMap['grpc-status'] === 'string' + ) { const receivedStatus = Number(metadataMap['grpc-status']); if (receivedStatus in Status) { code = receivedStatus; @@ -375,7 +380,9 @@ export class Http2CallStream implements Call { if (typeof metadataMap['grpc-message'] === 'string') { details = decodeURI(metadataMap['grpc-message']); metadata.remove('grpc-message'); - this.trace('received status details string "' + details + '" from server'); + this.trace( + 'received status details string "' + details + '" from server' + ); } const status: StatusObject = { code, details, metadata }; let finalStatus; @@ -412,7 +419,7 @@ export class Http2CallStream implements Call { stream.on('response', (headers, flags) => { let headersString = ''; for (const header of Object.keys(headers)) { - headersString += '\t\t' + header + ': ' + headers[header] + '\n' + headersString += '\t\t' + header + ': ' + headers[header] + '\n'; } this.trace('Received server headers:\n' + headersString); switch (headers[':status']) { @@ -575,7 +582,9 @@ export class Http2CallStream implements Call { } cancelWithStatus(status: Status, details: string): void { - this.trace('cancelWithStatus code: ' + status + ' details: "' + details + '"'); + this.trace( + 'cancelWithStatus code: ' + status + ' details: "' + details + '"' + ); this.destroyHttp2Stream(); this.endCall({ code: status, details, metadata: new Metadata() }); } @@ -650,7 +659,7 @@ export class Http2CallStream implements Call { }; const cb: WriteCallback = context.callback ?? (() => {}); this.isWriteFilterPending = true; - this.filterStack.sendMessage(Promise.resolve(writeObj)).then(message => { + this.filterStack.sendMessage(Promise.resolve(writeObj)).then((message) => { this.isWriteFilterPending = false; if (this.http2Stream === null) { this.trace( diff --git a/packages/grpc-js/src/call.ts b/packages/grpc-js/src/call.ts index 61885cd6..0d88ef15 100644 --- a/packages/grpc-js/src/call.ts +++ b/packages/grpc-js/src/call.ts @@ -100,9 +100,7 @@ export class ClientUnaryCallImpl extends EventEmitter export class ClientReadableStreamImpl extends Readable implements ClientReadableStream { public call?: InterceptingCallInterface; - constructor( - readonly deserialize: (chunk: Buffer) => ResponseType - ) { + constructor(readonly deserialize: (chunk: Buffer) => ResponseType) { super({ objectMode: true }); } @@ -122,9 +120,7 @@ export class ClientReadableStreamImpl extends Readable export class ClientWritableStreamImpl extends Writable implements ClientWritableStream { public call?: InterceptingCallInterface; - constructor( - readonly serialize: (value: RequestType) => Buffer - ) { + constructor(readonly serialize: (value: RequestType) => Buffer) { super({ objectMode: true }); } @@ -140,7 +136,7 @@ export class ClientWritableStreamImpl extends Writable const context: MessageContext = { callback: cb, }; - const flags: number = Number(encoding); + const flags = Number(encoding); if (!Number.isNaN(flags)) { context.flags = flags; } @@ -179,7 +175,7 @@ export class ClientDuplexStreamImpl extends Duplex const context: MessageContext = { callback: cb, }; - const flags: number = Number(encoding); + const flags = Number(encoding); if (!Number.isNaN(flags)) { context.flags = flags; } diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index 4d07dde0..a8b9f4ec 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -144,11 +144,23 @@ export class ChannelImplementation implements Channel { throw new TypeError('Channel target must be a string'); } if (!(credentials instanceof ChannelCredentials)) { - throw new TypeError('Channel credentials must be a ChannelCredentials object'); + throw new TypeError( + 'Channel credentials must be a ChannelCredentials object' + ); } if (options) { - if ((typeof options !== 'object') || !Object.values(options).every(value => typeof value === 'string' || typeof value === 'number' || typeof value === 'undefined')) { - throw new TypeError('Channel options must be an object with string or number values'); + if ( + typeof options !== 'object' || + !Object.values(options).every( + (value) => + typeof value === 'string' || + typeof value === 'number' || + typeof value === 'undefined' + ) + ) { + throw new TypeError( + 'Channel options must be an object with string or number values' + ); } } /* The global boolean parameter to getSubchannelPool has the inverse meaning to what @@ -265,7 +277,7 @@ export class ChannelImplementation implements Channel { callStream.filterStack .sendMetadata(Promise.resolve(callMetadata.clone())) .then( - finalMetadata => { + (finalMetadata) => { const subchannelState: ConnectivityState = pickResult.subchannel!.getConnectivityState(); if (subchannelState === ConnectivityState.READY) { try { @@ -274,28 +286,31 @@ export class ChannelImplementation implements Channel { callStream ); } catch (error) { - if ((error as NodeJS.ErrnoException).code === 'ERR_HTTP2_GOAWAY_SESSION') { + if ( + (error as NodeJS.ErrnoException).code === + 'ERR_HTTP2_GOAWAY_SESSION' + ) { /* An error here indicates that something went wrong with - * the picked subchannel's http2 stream right before we - * tried to start the stream. We are handling a promise - * result here, so this is asynchronous with respect to the - * original tryPick call, so calling it again is not - * recursive. We call tryPick immediately instead of - * queueing this pick again because handling the queue is - * triggered by state changes, and we want to immediately - * check if the state has already changed since the - * previous tryPick call. We do this instead of cancelling - * the stream because the correct behavior may be - * re-queueing instead, based on the logic in the rest of - * tryPick */ + * the picked subchannel's http2 stream right before we + * tried to start the stream. We are handling a promise + * result here, so this is asynchronous with respect to the + * original tryPick call, so calling it again is not + * recursive. We call tryPick immediately instead of + * queueing this pick again because handling the queue is + * triggered by state changes, and we want to immediately + * check if the state has already changed since the + * previous tryPick call. We do this instead of cancelling + * the stream because the correct behavior may be + * re-queueing instead, based on the logic in the rest of + * tryPick */ trace( LogVerbosity.INFO, 'channel', 'Failed to start call on picked subchannel ' + - pickResult.subchannel!.getAddress() + - ' with error ' + - (error as Error).message + - '. Retrying pick' + pickResult.subchannel!.getAddress() + + ' with error ' + + (error as Error).message + + '. Retrying pick' ); this.tryPick(callStream, callMetadata); } else { @@ -303,12 +318,15 @@ export class ChannelImplementation implements Channel { LogVerbosity.INFO, 'channel', 'Failed to start call on picked subchanel ' + - pickResult.subchannel!.getAddress() + - ' with error ' + - (error as Error).message + - '. Ending call' + pickResult.subchannel!.getAddress() + + ' with error ' + + (error as Error).message + + '. Ending call' + ); + callStream.cancelWithStatus( + Status.INTERNAL, + 'Failed to start HTTP/2 stream' ); - callStream.cancelWithStatus(Status.INTERNAL, 'Failed to start HTTP/2 stream'); } } } else { @@ -360,7 +378,7 @@ export class ChannelImplementation implements Channel { watcherObject: ConnectivityStateWatcher ) { const watcherIndex = this.connectivityStateWatchers.findIndex( - value => value === watcherObject + (value) => value === watcherObject ); if (watcherIndex >= 0) { this.connectivityStateWatchers.splice(watcherIndex, 1); @@ -450,7 +468,9 @@ export class ChannelImplementation implements Channel { throw new TypeError('Channel#createCall: method must be a string'); } if (!(typeof deadline === 'number' || deadline instanceof Date)) { - throw new TypeError('Channel#createCall: deadline must be a number or Date'); + throw new TypeError( + 'Channel#createCall: deadline must be a number or Date' + ); } if (this.connectivityState === ConnectivityState.SHUTDOWN) { throw new Error('Channel has been shut down'); diff --git a/packages/grpc-js/src/client-interceptors.ts b/packages/grpc-js/src/client-interceptors.ts index c20db534..72bbdab9 100644 --- a/packages/grpc-js/src/client-interceptors.ts +++ b/packages/grpc-js/src/client-interceptors.ts @@ -179,10 +179,10 @@ const defaultRequester: FullRequester = { sendMessage: (message, next) => { next(message); }, - halfClose: next => { + halfClose: (next) => { next(); }, - cancel: next => { + cancel: (next) => { next(); }, }; @@ -250,13 +250,13 @@ export class InterceptingCall implements InterceptingCallInterface { const fullInterceptingListener: InterceptingListener = { onReceiveMetadata: interceptingListener?.onReceiveMetadata?.bind(interceptingListener) ?? - (metadata => {}), + ((metadata) => {}), onReceiveMessage: interceptingListener?.onReceiveMessage?.bind(interceptingListener) ?? - (message => {}), + ((message) => {}), onReceiveStatus: interceptingListener?.onReceiveStatus?.bind(interceptingListener) ?? - (status => {}), + ((status) => {}), }; this.requester.start(metadata, fullInterceptingListener, (md, listener) => { let finalInterceptingListener: InterceptingListener; @@ -281,7 +281,7 @@ export class InterceptingCall implements InterceptingCallInterface { } sendMessageWithContext(context: MessageContext, message: any): void { this.processingMessage = true; - this.requester.sendMessage(message, finalMessage => { + this.requester.sendMessage(message, (finalMessage) => { this.processingMessage = false; this.nextCall.sendMessageWithContext(context, finalMessage); if (this.pendingHalfClose) { @@ -368,10 +368,10 @@ class BaseInterceptingCall implements InterceptingCallInterface { ): void { let readError: StatusObject | null = null; this.call.start(metadata, { - onReceiveMetadata: metadata => { + onReceiveMetadata: (metadata) => { interceptingListener?.onReceiveMetadata?.(metadata); }, - onReceiveMessage: message => { + onReceiveMessage: (message) => { let deserialized: any; try { deserialized = this.methodDefinition.responseDeserialize(message); @@ -385,7 +385,7 @@ class BaseInterceptingCall implements InterceptingCallInterface { this.call.cancelWithStatus(readError.code, readError.details); } }, - onReceiveStatus: status => { + onReceiveStatus: (status) => { if (readError) { interceptingListener?.onReceiveStatus?.(readError); } else { @@ -415,7 +415,7 @@ class BaseUnaryInterceptingCall extends BaseInterceptingCall let receivedMessage = false; const wrapperListener: InterceptingListener = { onReceiveMetadata: - listener?.onReceiveMetadata?.bind(listener) ?? (metadata => {}), + listener?.onReceiveMetadata?.bind(listener) ?? ((metadata) => {}), onReceiveMessage: (message: any) => { receivedMessage = true; listener?.onReceiveMessage?.(message); @@ -502,21 +502,21 @@ export function getInterceptingCall( interceptors = ([] as Interceptor[]) .concat( interceptorArgs.callInterceptors, - interceptorArgs.callInterceptorProviders.map(provider => + interceptorArgs.callInterceptorProviders.map((provider) => provider(methodDefinition) ) ) - .filter(interceptor => interceptor); + .filter((interceptor) => interceptor); // Filter out falsy values when providers return nothing } else { interceptors = ([] as Interceptor[]) .concat( interceptorArgs.clientInterceptors, - interceptorArgs.clientInterceptorProviders.map(provider => + interceptorArgs.clientInterceptorProviders.map((provider) => provider(methodDefinition) ) ) - .filter(interceptor => interceptor); + .filter((interceptor) => interceptor); // Filter out falsy values when providers return nothing } const interceptorOptions = Object.assign({}, options, { @@ -531,14 +531,10 @@ export function getInterceptingCall( * channel. */ const getCall: NextCall = interceptors.reduceRight( (nextCall: NextCall, nextInterceptor: Interceptor) => { - return currentOptions => nextInterceptor(currentOptions, nextCall); + return (currentOptions) => nextInterceptor(currentOptions, nextCall); }, (finalOptions: InterceptorOptions) => - getBottomInterceptingCall( - channel, - finalOptions, - methodDefinition - ) + getBottomInterceptingCall(channel, finalOptions, methodDefinition) ); return getCall(interceptorOptions); } diff --git a/packages/grpc-js/src/client.ts b/packages/grpc-js/src/client.ts index 118375b2..f33de1f7 100644 --- a/packages/grpc-js/src/client.ts +++ b/packages/grpc-js/src/client.ts @@ -48,7 +48,12 @@ import { InterceptorArguments, InterceptingCallInterface, } from './client-interceptors'; -import { ServerUnaryCall, ServerReadableStream, ServerWritableStream, ServerDuplexStream } from './server-call'; +import { + ServerUnaryCall, + ServerReadableStream, + ServerWritableStream, + ServerDuplexStream, +} from './server-call'; const CHANNEL_SYMBOL = Symbol(); const INTERCEPTOR_SYMBOL = Symbol(); @@ -62,7 +67,11 @@ export interface UnaryCallback { export interface CallOptions { deadline?: Deadline; host?: string; - parent?: ServerUnaryCall | ServerReadableStream | ServerWritableStream | ServerDuplexStream + parent?: + | ServerUnaryCall + | ServerReadableStream + | ServerWritableStream + | ServerDuplexStream; propagate_flags?: number; credentials?: CallCredentials; interceptors?: Interceptor[]; @@ -76,11 +85,11 @@ export interface CallProperties { channel: Channel; methodDefinition: ClientMethodDefinition; callOptions: CallOptions; - callback?: UnaryCallback + callback?: UnaryCallback; } export interface CallInvocationTransformer { - (callProperties: CallProperties): CallProperties + (callProperties: CallProperties): CallProperties; } export type ClientOptions = Partial & { @@ -123,7 +132,8 @@ export class Client { 'to the client constructor. Only one of these is allowed.' ); } - this[CALL_INVOCATION_TRANSFORMER_SYMBOL] = options.callInvocationTransformer; + this[CALL_INVOCATION_TRANSFORMER_SYMBOL] = + options.callInvocationTransformer; delete options.callInvocationTransformer; if (options.channelOverride) { this[CHANNEL_SYMBOL] = options.channelOverride; @@ -274,17 +284,20 @@ export class Client { channel: this[CHANNEL_SYMBOL], methodDefinition: methodDefinition, callOptions: checkedArguments.options, - callback: checkedArguments.callback + callback: checkedArguments.callback, }; if (this[CALL_INVOCATION_TRANSFORMER_SYMBOL]) { - callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL]!(callProperties) as CallProperties; + callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL]!( + callProperties + ) as CallProperties; } const emitter: ClientUnaryCall = callProperties.call; const interceptorArgs: InterceptorArguments = { clientInterceptors: this[INTERCEPTOR_SYMBOL], clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL], callInterceptors: callProperties.callOptions.interceptors ?? [], - callInterceptorProviders: callProperties.callOptions.interceptor_providers ?? [], + callInterceptorProviders: + callProperties.callOptions.interceptor_providers ?? [], }; const call: InterceptingCallInterface = getInterceptingCall( interceptorArgs, @@ -303,7 +316,7 @@ export class Client { let responseMessage: ResponseType | null = null; let receivedStatus = false; call.start(callProperties.metadata, { - onReceiveMetadata: metadata => { + onReceiveMetadata: (metadata) => { emitter.emit('metadata', metadata); }, onReceiveMessage(message: any) { @@ -385,17 +398,22 @@ export class Client { channel: this[CHANNEL_SYMBOL], methodDefinition: methodDefinition, callOptions: checkedArguments.options, - callback: checkedArguments.callback + callback: checkedArguments.callback, }; if (this[CALL_INVOCATION_TRANSFORMER_SYMBOL]) { - callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL]!(callProperties) as CallProperties; + callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL]!( + callProperties + ) as CallProperties; } - const emitter: ClientWritableStream = callProperties.call as ClientWritableStream; + const emitter: ClientWritableStream = callProperties.call as ClientWritableStream< + RequestType + >; const interceptorArgs: InterceptorArguments = { clientInterceptors: this[INTERCEPTOR_SYMBOL], clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL], callInterceptors: callProperties.callOptions.interceptors ?? [], - callInterceptorProviders: callProperties.callOptions.interceptor_providers ?? [], + callInterceptorProviders: + callProperties.callOptions.interceptor_providers ?? [], }; const call: InterceptingCallInterface = getInterceptingCall( interceptorArgs, @@ -414,7 +432,7 @@ export class Client { let responseMessage: ResponseType | null = null; let receivedStatus = false; call.start(callProperties.metadata, { - onReceiveMetadata: metadata => { + onReceiveMetadata: (metadata) => { emitter.emit('metadata', metadata); }, onReceiveMessage(message: any) { @@ -503,17 +521,22 @@ export class Client { call: new ClientReadableStreamImpl(deserialize), channel: this[CHANNEL_SYMBOL], methodDefinition: methodDefinition, - callOptions: checkedArguments.options + callOptions: checkedArguments.options, }; if (this[CALL_INVOCATION_TRANSFORMER_SYMBOL]) { - callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL]!(callProperties) as CallProperties; + callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL]!( + callProperties + ) as CallProperties; } - const stream: ClientReadableStream = callProperties.call as ClientReadableStream; + const stream: ClientReadableStream = callProperties.call as ClientReadableStream< + ResponseType + >; const interceptorArgs: InterceptorArguments = { clientInterceptors: this[INTERCEPTOR_SYMBOL], clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL], callInterceptors: callProperties.callOptions.interceptors ?? [], - callInterceptorProviders: callProperties.callOptions.interceptor_providers ?? [], + callInterceptorProviders: + callProperties.callOptions.interceptor_providers ?? [], }; const call: InterceptingCallInterface = getInterceptingCall( interceptorArgs, @@ -589,20 +612,29 @@ export class Client { }; let callProperties: CallProperties = { metadata: checkedArguments.metadata, - call: new ClientDuplexStreamImpl(serialize, deserialize), + call: new ClientDuplexStreamImpl( + serialize, + deserialize + ), channel: this[CHANNEL_SYMBOL], methodDefinition: methodDefinition, - callOptions: checkedArguments.options + callOptions: checkedArguments.options, }; if (this[CALL_INVOCATION_TRANSFORMER_SYMBOL]) { - callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL]!(callProperties) as CallProperties; + callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL]!( + callProperties + ) as CallProperties; } - const stream: ClientDuplexStream = callProperties.call as ClientDuplexStream; + const stream: ClientDuplexStream< + RequestType, + ResponseType + > = callProperties.call as ClientDuplexStream; const interceptorArgs: InterceptorArguments = { clientInterceptors: this[INTERCEPTOR_SYMBOL], clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL], callInterceptors: callProperties.callOptions.interceptors ?? [], - callInterceptorProviders: callProperties.callOptions.interceptor_providers ?? [], + callInterceptorProviders: + callProperties.callOptions.interceptor_providers ?? [], }; const call: InterceptingCallInterface = getInterceptingCall( interceptorArgs, diff --git a/packages/grpc-js/src/filter-stack.ts b/packages/grpc-js/src/filter-stack.ts index 3b6f16ba..a656a409 100644 --- a/packages/grpc-js/src/filter-stack.ts +++ b/packages/grpc-js/src/filter-stack.ts @@ -78,7 +78,7 @@ export class FilterStackFactory implements FilterFactory { createFilter(callStream: Call): FilterStack { return new FilterStack( - this.factories.map(factory => factory.createFilter(callStream)) + this.factories.map((factory) => factory.createFilter(callStream)) ); } } diff --git a/packages/grpc-js/src/http_proxy.ts b/packages/grpc-js/src/http_proxy.ts index ecff1bb5..ef52deda 100644 --- a/packages/grpc-js/src/http_proxy.ts +++ b/packages/grpc-js/src/http_proxy.ts @@ -15,14 +15,18 @@ * */ -import { URL, parse } from "url"; -import { log } from "./logging"; -import { LogVerbosity } from "./constants"; -import { parseTarget } from "./resolver-dns"; -import { Socket } from "net"; +import { URL, parse } from 'url'; +import { log } from './logging'; +import { LogVerbosity } from './constants'; +import { parseTarget } from './resolver-dns'; +import { Socket } from 'net'; import * as http from 'http'; import * as logging from './logging'; -import { SubchannelAddress, TcpSubchannelAddress, isTcpSubchannelAddress } from "./subchannel"; +import { + SubchannelAddress, + TcpSubchannelAddress, + isTcpSubchannelAddress, +} from './subchannel'; const TRACER_NAME = 'proxy'; @@ -36,8 +40,8 @@ interface ProxyInfo { } function getProxyInfo(): ProxyInfo { - let proxyEnv: string = ''; - let envVar: string = ''; + let proxyEnv = ''; + let envVar = ''; /* Prefer using 'grpc_proxy'. Fallback on 'http_proxy' if it is not set. * Also prefer using 'https_proxy' with fallback on 'http_proxy'. The * fallback behavior can be removed if there's a demand for it. @@ -62,7 +66,10 @@ function getProxyInfo(): ProxyInfo { return {}; } if (proxyUrl.protocol !== 'http:') { - log(LogVerbosity.ERROR, `"${proxyUrl.protocol}" scheme not supported in proxy URI`); + log( + LogVerbosity.ERROR, + `"${proxyUrl.protocol}" scheme not supported in proxy URI` + ); return {}; } let userCred: string | null = null; @@ -75,12 +82,14 @@ function getProxyInfo(): ProxyInfo { } } const result: ProxyInfo = { - address: proxyUrl.host + address: proxyUrl.host, }; if (userCred) { result.creds = userCred; } - trace('Proxy server ' + result.address + ' set by environment variable ' + envVar); + trace( + 'Proxy server ' + result.address + ' set by environment variable ' + envVar + ); return result; } @@ -89,7 +98,7 @@ const PROXY_INFO = getProxyInfo(); function getNoProxyHostList(): string[] { /* Prefer using 'no_grpc_proxy'. Fallback on 'no_proxy' if it is not set. */ let noProxyStr: string | undefined = process.env.no_grpc_proxy; - let envVar: string = 'no_grpc_proxy'; + let envVar = 'no_grpc_proxy'; if (!noProxyStr) { noProxyStr = process.env.no_proxy; envVar = 'no_proxy'; @@ -124,20 +133,37 @@ export function shouldUseProxy(target: string): boolean { return true; } -export function getProxiedConnection(target: string, subchannelAddress: SubchannelAddress): Promise { - if (!(PROXY_INFO.address && shouldUseProxy(target) && isTcpSubchannelAddress(subchannelAddress))) { +export function getProxiedConnection( + target: string, + subchannelAddress: SubchannelAddress +): Promise { + if ( + !( + PROXY_INFO.address && + shouldUseProxy(target) && + isTcpSubchannelAddress(subchannelAddress) + ) + ) { return Promise.reject(); } const subchannelAddressPathString = `${subchannelAddress.host}:${subchannelAddress.port}`; - trace('Using proxy ' + PROXY_INFO.address + ' to connect to ' + target + ' at ' + subchannelAddress); + trace( + 'Using proxy ' + + PROXY_INFO.address + + ' to connect to ' + + target + + ' at ' + + subchannelAddress + ); const options: http.RequestOptions = { method: 'CONNECT', host: PROXY_INFO.address, - path: subchannelAddressPathString + path: subchannelAddressPathString, }; if (PROXY_INFO.creds) { options.headers = { - 'Proxy-Authorization': 'Basic ' + Buffer.from(PROXY_INFO.creds).toString('base64') + 'Proxy-Authorization': + 'Basic ' + Buffer.from(PROXY_INFO.creds).toString('base64'), }; } return new Promise((resolve, reject) => { @@ -146,10 +172,20 @@ export function getProxiedConnection(target: string, subchannelAddress: Subchann request.removeAllListeners(); socket.removeAllListeners(); if (res.statusCode === http.STATUS_CODES.OK) { - trace('Successfully connected to ' + subchannelAddress + ' through proxy ' + PROXY_INFO.address); + trace( + 'Successfully connected to ' + + subchannelAddress + + ' through proxy ' + + PROXY_INFO.address + ); resolve(socket); } else { - trace('Failed to connect to ' + subchannelAddress + ' through proxy ' + PROXY_INFO.address); + trace( + 'Failed to connect to ' + + subchannelAddress + + ' through proxy ' + + PROXY_INFO.address + ); reject(); } }); diff --git a/packages/grpc-js/src/index.ts b/packages/grpc-js/src/index.ts index 5c77a3ff..8324ff4c 100644 --- a/packages/grpc-js/src/index.ts +++ b/packages/grpc-js/src/index.ts @@ -28,7 +28,12 @@ import { CallCredentials } from './call-credentials'; import { Deadline, StatusObject } from './call-stream'; import { Channel, ConnectivityState, ChannelImplementation } from './channel'; import { ChannelCredentials } from './channel-credentials'; -import { CallOptions, Client, CallInvocationTransformer, CallProperties } from './client'; +import { + CallOptions, + Client, + CallInvocationTransformer, + CallProperties, +} from './client'; import { LogVerbosity, Status } from './constants'; import * as logging from './logging'; import { @@ -129,14 +134,14 @@ export const credentials = mixin( }); } getHeaders.then( - headers => { + (headers) => { const metadata = new Metadata(); for (const key of Object.keys(headers)) { metadata.add(key, headers[key]); } callback(null, metadata); }, - err => { + (err) => { callback(err); } ); @@ -202,7 +207,7 @@ export { CallProperties, CallInvocationTransformer, ChannelImplementation as Channel, - Channel as ChannelInterface + Channel as ChannelInterface, }; /** diff --git a/packages/grpc-js/src/load-balancer-pick-first.ts b/packages/grpc-js/src/load-balancer-pick-first.ts index e0e1768c..6b9756ff 100644 --- a/packages/grpc-js/src/load-balancer-pick-first.ts +++ b/packages/grpc-js/src/load-balancer-pick-first.ts @@ -338,11 +338,11 @@ export class PickFirstLoadBalancer implements LoadBalancer { this.resetSubchannelList(); trace( 'Connect to address list ' + - this.latestAddressList.map(address => + this.latestAddressList.map((address) => subchannelAddressToString(address) ) ); - this.subchannels = this.latestAddressList.map(address => + this.subchannels = this.latestAddressList.map((address) => this.channelControlHelper.createSubchannel(address, {}) ); for (const subchannel of this.subchannels) { diff --git a/packages/grpc-js/src/load-balancer-round-robin.ts b/packages/grpc-js/src/load-balancer-round-robin.ts index 863fec77..93c64610 100644 --- a/packages/grpc-js/src/load-balancer-round-robin.ts +++ b/packages/grpc-js/src/load-balancer-round-robin.ts @@ -125,7 +125,7 @@ export class RoundRobinLoadBalancer implements LoadBalancer { private calculateAndUpdateState() { if (this.subchannelStateCounts[ConnectivityState.READY] > 0) { const readySubchannels = this.subchannels.filter( - subchannel => + (subchannel) => subchannel.getConnectivityState() === ConnectivityState.READY ); let index = 0; @@ -192,9 +192,9 @@ export class RoundRobinLoadBalancer implements LoadBalancer { this.resetSubchannelList(); trace( 'Connect to address list ' + - addressList.map(address => subchannelAddressToString(address)) + addressList.map((address) => subchannelAddressToString(address)) ); - this.subchannels = addressList.map(address => + this.subchannels = addressList.map((address) => this.channelControlHelper.createSubchannel(address, {}) ); for (const subchannel of this.subchannels) { diff --git a/packages/grpc-js/src/make-client.ts b/packages/grpc-js/src/make-client.ts index f55f4917..99daef15 100644 --- a/packages/grpc-js/src/make-client.ts +++ b/packages/grpc-js/src/make-client.ts @@ -116,7 +116,7 @@ export function makeClientConstructor( [methodName: string]: Function; } - Object.keys(methods).forEach(name => { + Object.keys(methods).forEach((name) => { const attrs = methods[name]; let methodType: keyof typeof requesterFuncs; // TODO(murgatroid99): Verify that we don't need this anymore @@ -164,7 +164,7 @@ function partial( serialize: Function, deserialize: Function ): Function { - return function(this: any, ...args: any[]) { + return function (this: any, ...args: any[]) { return fn.call(this, path, serialize, deserialize, ...args); }; } diff --git a/packages/grpc-js/src/metadata.ts b/packages/grpc-js/src/metadata.ts index 630fb99a..0ffe0af2 100644 --- a/packages/grpc-js/src/metadata.ts +++ b/packages/grpc-js/src/metadata.ts @@ -178,7 +178,7 @@ export class Metadata { const newInternalRepr = newMetadata.internalRepr; this.internalRepr.forEach((value, key) => { - const clonedValue: MetadataValue[] = value.map(v => { + const clonedValue: MetadataValue[] = value.map((v) => { if (v instanceof Buffer) { return Buffer.from(v); } else { @@ -226,7 +226,7 @@ export class Metadata { this.internalRepr.forEach((values, key) => { // We assume that the user's interaction with this object is limited to // through its public API (i.e. keys and values are already validated). - result[key] = values.map(value => { + result[key] = values.map((value) => { if (value instanceof Buffer) { return value.toString('base64'); } else { @@ -249,7 +249,7 @@ export class Metadata { */ static fromHttp2Headers(headers: http2.IncomingHttpHeaders): Metadata { const result = new Metadata(); - Object.keys(headers).forEach(key => { + Object.keys(headers).forEach((key) => { // Reserved headers (beginning with `:`) are not valid keys. if (key.charAt(0) === ':') { return; @@ -260,12 +260,12 @@ export class Metadata { try { if (isBinaryKey(key)) { if (Array.isArray(values)) { - values.forEach(value => { + values.forEach((value) => { result.add(key, Buffer.from(value, 'base64')); }); } else if (values !== undefined) { if (isCustomMetadata(key)) { - values.split(',').forEach(v => { + values.split(',').forEach((v) => { result.add(key, Buffer.from(v.trim(), 'base64')); }); } else { @@ -274,12 +274,12 @@ export class Metadata { } } else { if (Array.isArray(values)) { - values.forEach(value => { + values.forEach((value) => { result.add(key, value); }); } else if (values !== undefined) { if (isCustomMetadata(key)) { - values.split(',').forEach(v => result.add(key, v.trim())); + values.split(',').forEach((v) => result.add(key, v.trim())); } else { result.add(key, values); } diff --git a/packages/grpc-js/src/resolver-dns.ts b/packages/grpc-js/src/resolver-dns.ts index 82727a42..a42a898f 100644 --- a/packages/grpc-js/src/resolver-dns.ts +++ b/packages/grpc-js/src/resolver-dns.ts @@ -109,7 +109,7 @@ function mergeArrays(...arrays: T[][]): T[] { i < Math.max.apply( null, - arrays.map(array => array.length) + arrays.map((array) => array.length) ); i++ ) { @@ -186,50 +186,56 @@ class DnsResolver implements Resolver { * if the name exists but there are no records for that family, and that * error is indistinguishable from other kinds of errors */ this.pendingLookupPromise = dnsLookupPromise(hostname, { all: true }); - this.pendingLookupPromise.then(addressList => { - this.pendingLookupPromise = null; - const ip4Addresses: dns.LookupAddress[] = addressList.filter( - addr => addr.family === 4 - ); - const ip6Addresses: dns.LookupAddress[] = addressList.filter(addr => addr.family === 6); - this.latestLookupResult = mergeArrays( - ip6Addresses, - ip4Addresses - ).map(addr => ({ host: addr.address, port: +this.port! })); - const allAddressesString: string = - '[' + - this.latestLookupResult.map(addr => addr.host + ':' + addr.port).join(',') + - ']'; - trace( - 'Resolved addresses for target ' + - this.target + - ': ' + - allAddressesString - ); - if (this.latestLookupResult.length === 0) { + this.pendingLookupPromise.then( + (addressList) => { + this.pendingLookupPromise = null; + const ip4Addresses: dns.LookupAddress[] = addressList.filter( + (addr) => addr.family === 4 + ); + const ip6Addresses: dns.LookupAddress[] = addressList.filter( + (addr) => addr.family === 6 + ); + this.latestLookupResult = mergeArrays( + ip6Addresses, + ip4Addresses + ).map((addr) => ({ host: addr.address, port: +this.port! })); + const allAddressesString: string = + '[' + + this.latestLookupResult + .map((addr) => addr.host + ':' + addr.port) + .join(',') + + ']'; + trace( + 'Resolved addresses for target ' + + this.target + + ': ' + + allAddressesString + ); + if (this.latestLookupResult.length === 0) { + this.listener.onError(this.defaultResolutionError); + return; + } + /* If the TXT lookup has not yet finished, both of the last two + * arguments will be null, which is the equivalent of getting an + * empty TXT response. When the TXT lookup does finish, its handler + * can update the service config by using the same address list */ + this.listener.onSuccessfulResolution( + this.latestLookupResult, + this.latestServiceConfig, + this.latestServiceConfigError + ); + }, + (err) => { + trace( + 'Resolution error for target ' + + this.target + + ': ' + + (err as Error).message + ); + this.pendingLookupPromise = null; this.listener.onError(this.defaultResolutionError); - return; } - /* If the TXT lookup has not yet finished, both of the last two - * arguments will be null, which is the equivalent of getting an - * empty TXT response. When the TXT lookup does finish, its handler - * can update the service config by using the same address list */ - this.listener.onSuccessfulResolution( - this.latestLookupResult, - this.latestServiceConfig, - this.latestServiceConfigError - ); - }, - err => { - trace( - 'Resolution error for target ' + - this.target + - ': ' + - (err as Error).message - ); - this.pendingLookupPromise = null; - this.listener.onError(this.defaultResolutionError); - }); + ); /* If there already is a still-pending TXT resolution, we can just use * that result when it comes in */ if (this.pendingTxtPromise === null) { @@ -237,45 +243,48 @@ class DnsResolver implements Resolver { * the name resolution attempt as a whole is a success even if the TXT * lookup fails */ this.pendingTxtPromise = resolveTxtPromise(hostname); - this.pendingTxtPromise.then(txtRecord => { - this.pendingTxtPromise = null; - try { - this.latestServiceConfig = extractAndSelectServiceConfig( - txtRecord, - this.percentage - ); - } catch (err) { + this.pendingTxtPromise.then( + (txtRecord) => { + this.pendingTxtPromise = null; + try { + this.latestServiceConfig = extractAndSelectServiceConfig( + txtRecord, + this.percentage + ); + } catch (err) { + this.latestServiceConfigError = { + code: Status.UNAVAILABLE, + details: 'Parsing service config failed', + metadata: new Metadata(), + }; + } + if (this.latestLookupResult !== null) { + /* We rely here on the assumption that calling this function with + * identical parameters will be essentialy idempotent, and calling + * it with the same address list and a different service config + * should result in a fast and seamless switchover. */ + this.listener.onSuccessfulResolution( + this.latestLookupResult, + this.latestServiceConfig, + this.latestServiceConfigError + ); + } + }, + (err) => { this.latestServiceConfigError = { code: Status.UNAVAILABLE, - details: 'Parsing service config failed', + details: 'TXT query failed', metadata: new Metadata(), }; + if (this.latestLookupResult !== null) { + this.listener.onSuccessfulResolution( + this.latestLookupResult, + this.latestServiceConfig, + this.latestServiceConfigError + ); + } } - if (this.latestLookupResult !== null) { - /* We rely here on the assumption that calling this function with - * identical parameters will be essentialy idempotent, and calling - * it with the same address list and a different service config - * should result in a fast and seamless switchover. */ - this.listener.onSuccessfulResolution( - this.latestLookupResult, - this.latestServiceConfig, - this.latestServiceConfigError - ) - } - }, err => { - this.latestServiceConfigError = { - code: Status.UNAVAILABLE, - details: 'TXT query failed', - metadata: new Metadata(), - }; - if (this.latestLookupResult !== null) { - this.listener.onSuccessfulResolution( - this.latestLookupResult, - this.latestServiceConfig, - this.latestServiceConfigError - ) - } - }); + ); } } } @@ -329,11 +338,15 @@ export interface dnsUrl { } export function parseTarget(target: string): dnsUrl | null { - const match = IPV4_REGEX.exec(target) ?? IPV6_REGEX.exec(target) ?? IPV6_BRACKET_REGEX.exec(target) ?? DNS_REGEX.exec(target) + const match = + IPV4_REGEX.exec(target) ?? + IPV6_REGEX.exec(target) ?? + IPV6_BRACKET_REGEX.exec(target) ?? + DNS_REGEX.exec(target); if (match) { return { host: match[1], - port: match[2] ?? undefined + port: match[2] ?? undefined, }; } else { return null; diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index d6b55ae8..240d8b53 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -157,7 +157,7 @@ export class ServerWritableStreamImpl this.trailingMetadata = new Metadata(); this.call.setupSurfaceCall(this); - this.on('error', err => { + this.on('error', (err) => { this.call.sendError(err); this.end(); }); @@ -226,7 +226,7 @@ export class ServerDuplexStreamImpl extends Duplex this.call.setupSurfaceCall(this); this.call.setupReadable(this); - this.on('error', err => { + this.on('error', (err) => { this.call.sendError(err); this.end(); }); @@ -562,7 +562,7 @@ export class Http2ServerCallStream< } setupSurfaceCall(call: ServerSurfaceCall) { - this.once('cancelled', reason => { + this.once('cancelled', (reason) => { call.cancelled = true; call.emit('cancelled', reason); }); diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index c37f69f7..1d851f1c 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -48,7 +48,11 @@ import { ServerCredentials } from './server-credentials'; import { ChannelOptions } from './channel-options'; import { createResolver, ResolverListener } from './resolver'; import { log } from './logging'; -import { SubchannelAddress, TcpSubchannelAddress, isTcpSubchannelAddress } from './subchannel'; +import { + SubchannelAddress, + TcpSubchannelAddress, + isTcpSubchannelAddress, +} from './subchannel'; interface BindResult { port: number; @@ -152,7 +156,7 @@ export class Server { throw new Error('Cannot add an empty service to a server'); } - serviceKeys.forEach(name => { + serviceKeys.forEach((name) => { const attrs = service[name]; let methodType: HandlerType; @@ -244,62 +248,72 @@ export class Server { http2Server.setTimeout(0, noop); this._setupHandlers(http2Server); return http2Server; - } + }; - const bindSpecificPort = (addressList: SubchannelAddress[], portNum: number, previousCount: number): Promise => { + const bindSpecificPort = ( + addressList: SubchannelAddress[], + portNum: number, + previousCount: number + ): Promise => { if (addressList.length === 0) { - return Promise.resolve({port: portNum, count: previousCount}); + return Promise.resolve({ port: portNum, count: previousCount }); } - return Promise.all(addressList.map(address => { - let addr: SubchannelAddress; - if (isTcpSubchannelAddress(address)) { - addr = { - host: (address as TcpSubchannelAddress).host, - port: portNum - }; - } else { - addr = address - } - - const http2Server = setupServer(); - return new Promise((resolve, reject) => { - function onError(err: Error): void { - resolve(err); + return Promise.all( + addressList.map((address) => { + let addr: SubchannelAddress; + if (isTcpSubchannelAddress(address)) { + addr = { + host: (address as TcpSubchannelAddress).host, + port: portNum, + }; + } else { + addr = address; } - http2Server.once('error', onError); - - http2Server.listen(addr, () => { - this.http2ServerList.push(http2Server); - const boundAddress = http2Server.address()!; - if (typeof boundAddress === 'string') { - resolve(portNum); - } else { - resolve(boundAddress.port); + const http2Server = setupServer(); + return new Promise((resolve, reject) => { + function onError(err: Error): void { + resolve(err); } - http2Server.removeListener('error', onError); + + http2Server.once('error', onError); + + http2Server.listen(addr, () => { + this.http2ServerList.push(http2Server); + const boundAddress = http2Server.address()!; + if (typeof boundAddress === 'string') { + resolve(portNum); + } else { + resolve(boundAddress.port); + } + http2Server.removeListener('error', onError); + }); }); }) - })).then(results => { + ).then((results) => { let count = 0; for (const result of results) { if (typeof result === 'number') { count += 1; if (result !== portNum) { - throw new Error('Invalid state: multiple port numbers added from single address'); + throw new Error( + 'Invalid state: multiple port numbers added from single address' + ); } } } return { port: portNum, - count: count + previousCount + count: count + previousCount, }; }); - } + }; - const bindWildcardPort = (addressList: SubchannelAddress[]): Promise => { + const bindWildcardPort = ( + addressList: SubchannelAddress[] + ): Promise => { if (addressList.length === 0) { - return Promise.resolve({port: 0, count: 0}); + return Promise.resolve({ port: 0, count: 0 }); } const address = addressList[0]; const http2Server = setupServer(); @@ -312,16 +326,26 @@ export class Server { http2Server.listen(address, () => { this.http2ServerList.push(http2Server); - resolve(bindSpecificPort(addressList.slice(1), (http2Server.address() as AddressInfo).port, 1)); + resolve( + bindSpecificPort( + addressList.slice(1), + (http2Server.address() as AddressInfo).port, + 1 + ) + ); http2Server.removeListener('error', onError); }); }); - } + }; const resolverListener: ResolverListener = { - onSuccessfulResolution: (addressList, serviceConfig, serviceConfigError) => { + onSuccessfulResolution: ( + addressList, + serviceConfig, + serviceConfigError + ) => { // We only want one resolution result. Discard all future results - resolverListener.onSuccessfulResolution = () => {} + resolverListener.onSuccessfulResolution = () => {}; if (addressList.length === 0) { callback(new Error(`No addresses resolved for port ${port}`), 0); return; @@ -331,32 +355,42 @@ export class Server { if (addressList[0].port === 0) { bindResultPromise = bindWildcardPort(addressList); } else { - bindResultPromise = bindSpecificPort(addressList, addressList[0].port, 0); + bindResultPromise = bindSpecificPort( + addressList, + addressList[0].port, + 0 + ); } - } else{ + } else { // Use an arbitrary non-zero port for non-TCP addresses bindResultPromise = bindSpecificPort(addressList, 1, 0); } - bindResultPromise.then(bindResult => { - if (bindResult.count === 0) { + bindResultPromise.then( + (bindResult) => { + if (bindResult.count === 0) { + const errorString = `No address added out of total ${addressList.length} resolved`; + log(LogVerbosity.ERROR, errorString); + callback(new Error(errorString), 0); + } else { + if (bindResult.count < addressList.length) { + log( + LogVerbosity.INFO, + `WARNING Only ${bindResult.count} addresses added out of total ${addressList.length} resolved` + ); + } + callback(null, bindResult.port); + } + }, + (error) => { const errorString = `No address added out of total ${addressList.length} resolved`; log(LogVerbosity.ERROR, errorString); callback(new Error(errorString), 0); - } else { - if (bindResult.count < addressList.length) { - log(LogVerbosity.INFO, `WARNING Only ${bindResult.count} addresses added out of total ${addressList.length} resolved`); - } - callback(null, bindResult.port); } - }, (error) => { - const errorString = `No address added out of total ${addressList.length} resolved`; - log(LogVerbosity.ERROR, errorString); - callback(new Error(errorString), 0); - }); + ); }, onError: (error) => { callback(new Error(error.details), 0); - } + }, }; const resolver = createResolver(port, resolverListener); @@ -376,7 +410,7 @@ export class Server { // Always destroy any available sessions. It's possible that one or more // tryShutdown() calls are in progress. Don't wait on them to finish. - this.sessions.forEach(session => { + this.sessions.forEach((session) => { // Cast NGHTTP2_CANCEL to any because TypeScript doesn't seem to // recognize destroy(code) as a valid signature. session.destroy(http2.constants.NGHTTP2_CANCEL as any); @@ -405,7 +439,12 @@ export class Server { } start(): void { - if (this.http2ServerList.length === 0 || this.http2ServerList.every(http2Server => http2Server.listening !== true)) { + if ( + this.http2ServerList.length === 0 || + this.http2ServerList.every( + (http2Server) => http2Server.listening !== true + ) + ) { throw new Error('server must be bound in order to start'); } @@ -439,7 +478,7 @@ export class Server { // If any sessions are active, close them gracefully. pendingChecks += this.sessions.size; - this.sessions.forEach(session => { + this.sessions.forEach((session) => { session.close(maybeCallback); }); if (pendingChecks === 0) { @@ -451,7 +490,9 @@ export class Server { throw new Error('Not yet implemented'); } - private _setupHandlers(http2Server: http2.Http2Server | http2.Http2SecureServer): void { + private _setupHandlers( + http2Server: http2.Http2Server | http2.Http2SecureServer + ): void { if (http2Server === null) { return; } @@ -525,7 +566,7 @@ export class Server { } ); - http2Server.on('session', session => { + http2Server.on('session', (session) => { if (!this.started) { session.destroy(); return; diff --git a/packages/grpc-js/src/subchannel-pool.ts b/packages/grpc-js/src/subchannel-pool.ts index 634d2575..9f143729 100644 --- a/packages/grpc-js/src/subchannel-pool.ts +++ b/packages/grpc-js/src/subchannel-pool.ts @@ -67,7 +67,7 @@ export class SubchannelPool { const subchannelObjArray = this.pool[channelTarget]; const refedSubchannels = subchannelObjArray.filter( - value => !value.subchannel.unrefIfOneRef() + (value) => !value.subchannel.unrefIfOneRef() ); if (refedSubchannels.length > 0) { diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index 64799a49..c21e3305 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -210,7 +210,7 @@ export class Subchannel { `grpc-node-js/${clientVersion}`, options['grpc.secondary_user_agent'], ] - .filter(e => e) + .filter((e) => e) .join(' '); // remove falsey values first if ('grpc.keepalive_time_ms' in options) { @@ -311,8 +311,8 @@ export class Subchannel { return socket; } else { /* net.NetConnectOpts is declared in a way that is more restrictive - * than what net.connect will actually accept, so we use the type - * assertion to work around that. */ + * than what net.connect will actually accept, so we use the type + * assertion to work around that. */ return net.connect(this.subchannelAddress); } }; @@ -397,7 +397,7 @@ export class Subchannel { } } ); - session.once('error', error => { + session.once('error', (error) => { /* Do nothing here. Any error should also trigger a close event, which is * where we want to handle that. */ trace( @@ -410,11 +410,17 @@ export class Subchannel { private startConnectingInternal() { if (shouldUseProxy(this.channelTarget)) { - getProxiedConnection(this.channelTarget, this.subchannelAddress).then((socket) => { - this.createSession(socket); - }, (reason) => { - this.transitionToState([ConnectivityState.CONNECTING], ConnectivityState.TRANSIENT_FAILURE); - }); + getProxiedConnection(this.channelTarget, this.subchannelAddress).then( + (socket) => { + this.createSession(socket); + }, + (reason) => { + this.transitionToState( + [ConnectivityState.CONNECTING], + ConnectivityState.TRANSIENT_FAILURE + ); + } + ); } else { this.createSession(); } @@ -589,7 +595,7 @@ export class Subchannel { const http2Stream = this.session!.request(headers); let headersString = ''; for (const header of Object.keys(headers)) { - headersString += '\t\t' + header + ': ' + headers[header] + '\n' + headersString += '\t\t' + header + ': ' + headers[header] + '\n'; } trace('Starting stream with headers\n' + headersString); callStream.attachHttp2Stream(http2Stream, this); From c4b92d91a1059ccb7294ab148e44b66d50035a9a Mon Sep 17 00:00:00 2001 From: Patrick Remy Date: Thu, 9 Apr 2020 12:03:48 +0200 Subject: [PATCH 06/18] grpc-js: fix more linting issues --- packages/grpc-js/src/load-balancing-config.ts | 2 +- packages/grpc-js/src/resolver-dns.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/src/load-balancing-config.ts b/packages/grpc-js/src/load-balancing-config.ts index 4a895903..f2b9f3a7 100644 --- a/packages/grpc-js/src/load-balancing-config.ts +++ b/packages/grpc-js/src/load-balancing-config.ts @@ -21,7 +21,7 @@ * specific object type if the input has the right structure, and throws an * error otherwise. */ -export interface RoundRobinConfig {} +export type RoundRobinConfig = {}; export interface XdsConfig { balancerName: string; diff --git a/packages/grpc-js/src/resolver-dns.ts b/packages/grpc-js/src/resolver-dns.ts index a42a898f..a40d5f98 100644 --- a/packages/grpc-js/src/resolver-dns.ts +++ b/packages/grpc-js/src/resolver-dns.ts @@ -332,6 +332,8 @@ export function setup(): void { registerDefaultResolver(DnsResolver); } +// camelCase needed for compatibility to grpc-native-js package +// eslint-disable-next-line @typescript-eslint/class-name-casing export interface dnsUrl { host: string; port?: string; From f4bacba9c77ef5341d1bb666e0f1b409a0e56d7d Mon Sep 17 00:00:00 2001 From: Patrick Remy Date: Thu, 9 Apr 2020 12:09:00 +0200 Subject: [PATCH 07/18] grpc-js: remove unused imports --- packages/grpc-js/src/call-credentials-filter.ts | 1 - packages/grpc-js/src/call-credentials.ts | 1 - packages/grpc-js/src/channel.ts | 1 - packages/grpc-js/src/client-interceptors.ts | 7 +------ packages/grpc-js/src/client.ts | 9 ++------- packages/grpc-js/src/deadline-filter.ts | 2 +- packages/grpc-js/src/resolver-dns.ts | 1 - packages/grpc-js/src/resolver.ts | 1 - packages/grpc-js/src/server.ts | 3 +-- packages/grpc-js/src/subchannel.ts | 2 +- 10 files changed, 6 insertions(+), 22 deletions(-) diff --git a/packages/grpc-js/src/call-credentials-filter.ts b/packages/grpc-js/src/call-credentials-filter.ts index f3fe2f4d..d39af832 100644 --- a/packages/grpc-js/src/call-credentials-filter.ts +++ b/packages/grpc-js/src/call-credentials-filter.ts @@ -15,7 +15,6 @@ * */ -import { CallCredentials } from './call-credentials'; import { Call } from './call-stream'; import { Channel } from './channel'; import { BaseFilter, Filter, FilterFactory } from './filter'; diff --git a/packages/grpc-js/src/call-credentials.ts b/packages/grpc-js/src/call-credentials.ts index e5d22bf7..40a26fec 100644 --- a/packages/grpc-js/src/call-credentials.ts +++ b/packages/grpc-js/src/call-credentials.ts @@ -16,7 +16,6 @@ */ import { Metadata } from './metadata'; -import { Call } from '.'; export interface CallMetadataOptions { service_url: string; diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index a8b9f4ec..abf14926 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -34,7 +34,6 @@ import { CallCredentialsFilterFactory } from './call-credentials-filter'; import { DeadlineFilterFactory } from './deadline-filter'; import { CompressionFilterFactory } from './compression-filter'; import { getDefaultAuthority } from './resolver'; -import { LoadBalancingConfig } from './load-balancing-config'; import { ServiceConfig, validateServiceConfig } from './service-config'; import { trace, log } from './logging'; import { SubchannelAddress } from './subchannel'; diff --git a/packages/grpc-js/src/client-interceptors.ts b/packages/grpc-js/src/client-interceptors.ts index 72bbdab9..95ea5deb 100644 --- a/packages/grpc-js/src/client-interceptors.ts +++ b/packages/grpc-js/src/client-interceptors.ts @@ -18,27 +18,22 @@ import { Metadata } from './metadata'; import { StatusObject, - CallStreamOptions, Listener, MetadataListener, MessageListener, StatusListener, FullListener, InterceptingListener, - WriteObject, - WriteCallback, InterceptingListenerImpl, isInterceptingListener, MessageContext, - Http2CallStream, - Deadline, Call, } from './call-stream'; import { Status } from './constants'; import { Channel } from './channel'; import { CallOptions } from './client'; import { CallCredentials } from './call-credentials'; -import { ClientMethodDefinition, Serialize } from './make-client'; +import { ClientMethodDefinition } from './make-client'; /** * Error class associated with passing both interceptors and interceptor diff --git a/packages/grpc-js/src/client.ts b/packages/grpc-js/src/client.ts index f33de1f7..511c1f4e 100644 --- a/packages/grpc-js/src/client.ts +++ b/packages/grpc-js/src/client.ts @@ -29,18 +29,13 @@ import { SurfaceCall, } from './call'; import { CallCredentials } from './call-credentials'; -import { - Deadline, - StatusObject, - WriteObject, - InterceptingListener, -} from './call-stream'; +import { Deadline, StatusObject } from './call-stream'; import { Channel, ConnectivityState, ChannelImplementation } from './channel'; import { ChannelCredentials } from './channel-credentials'; import { ChannelOptions } from './channel-options'; import { Status } from './constants'; import { Metadata } from './metadata'; -import { ClientMethodDefinition, MethodDefinition } from './make-client'; +import { ClientMethodDefinition } from './make-client'; import { getInterceptingCall, Interceptor, diff --git a/packages/grpc-js/src/deadline-filter.ts b/packages/grpc-js/src/deadline-filter.ts index 190d815e..2306bb8f 100644 --- a/packages/grpc-js/src/deadline-filter.ts +++ b/packages/grpc-js/src/deadline-filter.ts @@ -16,7 +16,7 @@ */ import { Call, StatusObject } from './call-stream'; -import { ConnectivityState, Channel } from './channel'; +import { Channel } from './channel'; import { Status } from './constants'; import { BaseFilter, Filter, FilterFactory } from './filter'; import { Metadata } from './metadata'; diff --git a/packages/grpc-js/src/resolver-dns.ts b/packages/grpc-js/src/resolver-dns.ts index a40d5f98..5fef4595 100644 --- a/packages/grpc-js/src/resolver-dns.ts +++ b/packages/grpc-js/src/resolver-dns.ts @@ -23,7 +23,6 @@ import { import * as dns from 'dns'; import * as util from 'util'; import { extractAndSelectServiceConfig, ServiceConfig } from './service-config'; -import { ServiceError } from './call'; import { Status } from './constants'; import { StatusObject } from './call-stream'; import { Metadata } from './metadata'; diff --git a/packages/grpc-js/src/resolver.ts b/packages/grpc-js/src/resolver.ts index b2be310f..4c091752 100644 --- a/packages/grpc-js/src/resolver.ts +++ b/packages/grpc-js/src/resolver.ts @@ -15,7 +15,6 @@ * */ -import { ServiceError } from './call'; import { ServiceConfig } from './service-config'; import * as resolver_dns from './resolver-dns'; import * as resolver_uds from './resolver-uds'; diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 1d851f1c..bcb50637 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -16,8 +16,7 @@ */ import * as http2 from 'http2'; -import { AddressInfo, ListenOptions } from 'net'; -import { URL } from 'url'; +import { AddressInfo } from 'net'; import { ServiceError } from './call'; import { Status, LogVerbosity } from './constants'; diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index c21e3305..3f6cfd52 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -20,7 +20,7 @@ import { ChannelCredentials } from './channel-credentials'; import { Metadata } from './metadata'; import { Http2CallStream } from './call-stream'; import { ChannelOptions } from './channel-options'; -import { PeerCertificate, checkServerIdentity, TLSSocket } from 'tls'; +import { PeerCertificate, checkServerIdentity } from 'tls'; import { ConnectivityState } from './channel'; import { BackoffTimeout, BackoffOptions } from './backoff-timeout'; import { getDefaultAuthority } from './resolver'; From 0d927e68723f50627ef9a045b3ce2f13a5796132 Mon Sep 17 00:00:00 2001 From: Patrick Remy Date: Thu, 9 Apr 2020 12:10:39 +0200 Subject: [PATCH 08/18] grpc-js: remove tslint disable statements --- packages/grpc-js/src/server.ts | 1 - packages/grpc-js/test/common.ts | 2 -- 2 files changed, 3 deletions(-) diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index bcb50637..af0deefc 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -111,7 +111,6 @@ function getDefaultHandler(handlerType: HandlerType, methodName: string) { throw new Error(`Invalid handlerType ${handlerType}`); } } -// tslint:enable:no-any export class Server { private http2ServerList: (http2.Http2Server | http2.Http2SecureServer)[] = []; diff --git a/packages/grpc-js/test/common.ts b/packages/grpc-js/test/common.ts index 4f8c5ff8..a3d8b9ba 100644 --- a/packages/grpc-js/test/common.ts +++ b/packages/grpc-js/test/common.ts @@ -32,7 +32,6 @@ export function mockFunction(): never { throw new Error('Not implemented'); } -// tslint:disable-next-line:no-namespace export namespace assert2 { const toCall = new Map<() => void, number>(); const afterCallsQueue: Array<() => void> = []; @@ -95,7 +94,6 @@ export namespace assert2 { return result; }; } - // tslint:enable:no-any /** * Calls the given function when every function that was wrapped with From 226016c7dca96cc56ee5211160b54a5820e1808b Mon Sep 17 00:00:00 2001 From: Patrick Remy Date: Thu, 9 Apr 2020 21:44:09 +0200 Subject: [PATCH 09/18] grpc-js: make dnsUrl type PascalCase --- packages/grpc-js/src/resolver-dns.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/grpc-js/src/resolver-dns.ts b/packages/grpc-js/src/resolver-dns.ts index 5fef4595..f359b507 100644 --- a/packages/grpc-js/src/resolver-dns.ts +++ b/packages/grpc-js/src/resolver-dns.ts @@ -331,14 +331,12 @@ export function setup(): void { registerDefaultResolver(DnsResolver); } -// camelCase needed for compatibility to grpc-native-js package -// eslint-disable-next-line @typescript-eslint/class-name-casing -export interface dnsUrl { +export interface DnsUrl { host: string; port?: string; } -export function parseTarget(target: string): dnsUrl | null { +export function parseTarget(target: string): DnsUrl | null { const match = IPV4_REGEX.exec(target) ?? IPV6_REGEX.exec(target) ?? From 53f3daa685dc2af6e64bdb00ebfdfed1233d7482 Mon Sep 17 00:00:00 2001 From: Patrick Remy Date: Fri, 10 Apr 2020 11:03:53 +0200 Subject: [PATCH 10/18] Revert "grpc-js: allow any for linting globally" This reverts commit 16ec0f0f6414687a53e9f05d4621b88162a9f1d7 and replaces tslint-disable statements by eslint-disable. --- packages/grpc-js/.eslintrc | 1 - packages/grpc-js/src/call-stream.ts | 3 +++ packages/grpc-js/src/channel-credentials.ts | 1 + packages/grpc-js/src/channel.ts | 4 ++-- packages/grpc-js/src/client-interceptors.ts | 17 +++++++++++++++++ packages/grpc-js/src/client.ts | 7 ++++++- packages/grpc-js/src/index.ts | 10 +++++++--- packages/grpc-js/src/load-balancing-config.ts | 4 ++++ packages/grpc-js/src/logging.ts | 2 ++ packages/grpc-js/src/make-client.ts | 2 ++ packages/grpc-js/src/object-stream.ts | 2 ++ packages/grpc-js/src/server-call.ts | 3 +++ packages/grpc-js/src/server.ts | 2 ++ packages/grpc-js/src/service-config.ts | 4 ++++ packages/grpc-js/src/subchannel-pool.ts | 1 + packages/grpc-js/test/common.ts | 1 + .../grpc-js/test/test-channel-credentials.ts | 1 + packages/grpc-js/test/test-resolver.ts | 2 ++ .../grpc-js/test/test-server-credentials.ts | 1 + packages/grpc-js/test/test-server-deadlines.ts | 1 + packages/grpc-js/test/test-server-errors.ts | 1 + packages/grpc-js/test/test-server.ts | 5 +++-- 22 files changed, 66 insertions(+), 9 deletions(-) diff --git a/packages/grpc-js/.eslintrc b/packages/grpc-js/.eslintrc index 6b0cac4a..7e3583cc 100644 --- a/packages/grpc-js/.eslintrc +++ b/packages/grpc-js/.eslintrc @@ -2,7 +2,6 @@ "root": true, "extends": "./node_modules/gts", "rules": { - "@typescript-eslint/no-explicit-any": "off", "node/no-unpublished-import": ["error", { "tryExtensions": [".ts", ".js", ".json", ".node"] }] diff --git a/packages/grpc-js/src/call-stream.ts b/packages/grpc-js/src/call-stream.ts index f40366ca..9ceebdbf 100644 --- a/packages/grpc-js/src/call-stream.ts +++ b/packages/grpc-js/src/call-stream.ts @@ -69,6 +69,7 @@ export interface MetadataListener { } export interface MessageListener { + // eslint-disable-next-line @typescript-eslint/no-explicit-any (message: any, next: (message: any) => void): void; } @@ -89,6 +90,7 @@ export type Listener = Partial; */ export interface InterceptingListener { onReceiveMetadata(metadata: Metadata): void; + // eslint-disable-next-line @typescript-eslint/no-explicit-any onReceiveMessage(message: any): void; onReceiveStatus(status: StatusObject): void; } @@ -115,6 +117,7 @@ export class InterceptingListenerImpl implements InterceptingListener { this.nextListener.onReceiveMetadata(metadata); }); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any onReceiveMessage(message: any): void { /* If this listener processes messages asynchronously, the last message may * be reordered with respect to the status */ diff --git a/packages/grpc-js/src/channel-credentials.ts b/packages/grpc-js/src/channel-credentials.ts index 7eb76a38..e5c9bfda 100644 --- a/packages/grpc-js/src/channel-credentials.ts +++ b/packages/grpc-js/src/channel-credentials.ts @@ -20,6 +20,7 @@ import { ConnectionOptions, createSecureContext, PeerCertificate } from 'tls'; import { CallCredentials } from './call-credentials'; import { CIPHER_SUITES, getDefaultRootsData } from './tls-helpers'; +// eslint-disable-next-line @typescript-eslint/no-explicit-any function verifyIsBufferOrNull(obj: any, friendlyName: string): void { if (obj && !(obj instanceof Buffer)) { throw new TypeError(`${friendlyName}, if provided, must be a Buffer.`); diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index abf14926..ca6254c4 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -111,7 +111,7 @@ export interface Channel { method: string, deadline: Deadline, host: string | null | undefined, - parentCall: any, + parentCall: any, // eslint-disable-line @typescript-eslint/no-explicit-any propagateFlags: number | null | undefined ): Call; } @@ -460,7 +460,7 @@ export class ChannelImplementation implements Channel { method: string, deadline: Deadline, host: string | null | undefined, - parentCall: any, + parentCall: any, // eslint-disable-line @typescript-eslint/no-explicit-any propagateFlags: number | null | undefined ): Call { if (typeof method !== 'string') { diff --git a/packages/grpc-js/src/client-interceptors.ts b/packages/grpc-js/src/client-interceptors.ts index 95ea5deb..9b503c52 100644 --- a/packages/grpc-js/src/client-interceptors.ts +++ b/packages/grpc-js/src/client-interceptors.ts @@ -59,6 +59,7 @@ export interface MetadataRequester { } export interface MessageRequester { + // eslint-disable-next-line @typescript-eslint/no-explicit-any (message: any, next: (message: any) => void): void; } @@ -183,6 +184,7 @@ const defaultRequester: FullRequester = { }; export interface InterceptorOptions extends CallOptions { + // eslint-disable-next-line @typescript-eslint/no-explicit-any method_definition: ClientMethodDefinition; } @@ -190,7 +192,9 @@ export interface InterceptingCallInterface { cancelWithStatus(status: Status, details: string): void; getPeer(): string; start(metadata: Metadata, listener?: Partial): void; + // eslint-disable-next-line @typescript-eslint/no-explicit-any sendMessageWithContext(context: MessageContext, message: any): void; + // eslint-disable-next-line @typescript-eslint/no-explicit-any sendMessage(message: any): void; startRead(): void; halfClose(): void; @@ -274,6 +278,7 @@ export class InterceptingCall implements InterceptingCallInterface { this.nextCall.start(md, finalInterceptingListener); }); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any sendMessageWithContext(context: MessageContext, message: any): void { this.processingMessage = true; this.requester.sendMessage(message, (finalMessage) => { @@ -284,6 +289,7 @@ export class InterceptingCall implements InterceptingCallInterface { } }); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any sendMessage(message: any): void { this.sendMessageWithContext({}, message); } @@ -334,6 +340,7 @@ function getCall(channel: Channel, path: string, options: CallOptions): Call { class BaseInterceptingCall implements InterceptingCallInterface { constructor( protected call: Call, + // eslint-disable-next-line @typescript-eslint/no-explicit-any protected methodDefinition: ClientMethodDefinition ) {} cancelWithStatus(status: Status, details: string): void { @@ -345,6 +352,7 @@ class BaseInterceptingCall implements InterceptingCallInterface { setCredentials(credentials: CallCredentials): void { this.call.setCredentials(credentials); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any sendMessageWithContext(context: MessageContext, message: any): void { let serialized: Buffer; try { @@ -354,6 +362,7 @@ class BaseInterceptingCall implements InterceptingCallInterface { this.call.cancelWithStatus(Status.INTERNAL, 'Serialization failure'); } } + // eslint-disable-next-line @typescript-eslint/no-explicit-any sendMessage(message: any) { this.sendMessageWithContext({}, message); } @@ -367,6 +376,7 @@ class BaseInterceptingCall implements InterceptingCallInterface { interceptingListener?.onReceiveMetadata?.(metadata); }, onReceiveMessage: (message) => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any let deserialized: any; try { deserialized = this.methodDefinition.responseDeserialize(message); @@ -403,6 +413,7 @@ class BaseInterceptingCall implements InterceptingCallInterface { */ class BaseUnaryInterceptingCall extends BaseInterceptingCall implements InterceptingCallInterface { + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(call: Call, methodDefinition: ClientMethodDefinition) { super(call, methodDefinition); } @@ -411,6 +422,7 @@ class BaseUnaryInterceptingCall extends BaseInterceptingCall const wrapperListener: InterceptingListener = { onReceiveMetadata: listener?.onReceiveMetadata?.bind(listener) ?? ((metadata) => {}), + // eslint-disable-next-line @typescript-eslint/no-explicit-any onReceiveMessage: (message: any) => { receivedMessage = true; listener?.onReceiveMessage?.(message); @@ -433,9 +445,11 @@ class BaseUnaryInterceptingCall extends BaseInterceptingCall */ class BaseStreamingInterceptingCall extends BaseInterceptingCall implements InterceptingCallInterface {} + function getBottomInterceptingCall( channel: Channel, options: InterceptorOptions, + // eslint-disable-next-line @typescript-eslint/no-explicit-any methodDefinition: ClientMethodDefinition ) { const call = getCall(channel, methodDefinition.path, options); @@ -455,6 +469,7 @@ export interface Interceptor { } export interface InterceptorProvider { + // eslint-disable-next-line @typescript-eslint/no-explicit-any (methodDefinition: ClientMethodDefinition): Interceptor; } @@ -464,8 +479,10 @@ export interface InterceptorArguments { callInterceptors: Interceptor[]; callInterceptorProviders: InterceptorProvider[]; } + export function getInterceptingCall( interceptorArgs: InterceptorArguments, + // eslint-disable-next-line @typescript-eslint/no-explicit-any methodDefinition: ClientMethodDefinition, options: CallOptions, channel: Channel diff --git a/packages/grpc-js/src/client.ts b/packages/grpc-js/src/client.ts index 511c1f4e..23930474 100644 --- a/packages/grpc-js/src/client.ts +++ b/packages/grpc-js/src/client.ts @@ -59,6 +59,7 @@ export interface UnaryCallback { (err: ServiceError | null, value?: ResponseType): void; } +/* eslint-disable @typescript-eslint/no-explicit-any */ export interface CallOptions { deadline?: Deadline; host?: string; @@ -72,6 +73,7 @@ export interface CallOptions { interceptors?: Interceptor[]; interceptor_providers?: InterceptorProvider[]; } +/* eslint-enable @typescript-eslint/no-explicit-any */ export interface CallProperties { argument?: RequestType; @@ -84,7 +86,7 @@ export interface CallProperties { } export interface CallInvocationTransformer { - (callProperties: CallProperties): CallProperties; + (callProperties: CallProperties): CallProperties; // eslint-disable-line @typescript-eslint/no-explicit-any } export type ClientOptions = Partial & { @@ -314,6 +316,7 @@ export class Client { onReceiveMetadata: (metadata) => { emitter.emit('metadata', metadata); }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any onReceiveMessage(message: any) { if (responseMessage != null) { call.cancelWithStatus(Status.INTERNAL, 'Too many responses received'); @@ -430,6 +433,7 @@ export class Client { onReceiveMetadata: (metadata) => { emitter.emit('metadata', metadata); }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any onReceiveMessage(message: any) { if (responseMessage != null) { call.cancelWithStatus(Status.INTERNAL, 'Too many responses received'); @@ -552,6 +556,7 @@ export class Client { onReceiveMetadata(metadata: Metadata) { stream.emit('metadata', metadata); }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any onReceiveMessage(message: any) { if (stream.push(message)) { call.startRead(); diff --git a/packages/grpc-js/src/index.ts b/packages/grpc-js/src/index.ts index 8324ff4c..d8f4b1cf 100644 --- a/packages/grpc-js/src/index.ts +++ b/packages/grpc-js/src/index.ts @@ -67,15 +67,15 @@ if (!semver.satisfies(process.version, supportedNodeVersions)) { } interface IndexedObject { - [key: string]: any; - [key: number]: any; + [key: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any + [key: number]: any; // eslint-disable-line @typescript-eslint/no-explicit-any } function mixin(...sources: IndexedObject[]) { const result: { [key: string]: Function } = {}; for (const source of sources) { for (const propName of Object.getOwnPropertyNames(source)) { - const property: any = source[propName]; + const property: any = source[propName]; // eslint-disable-line @typescript-eslint/no-explicit-any if (typeof property === 'function') { result[propName] = property; } @@ -250,14 +250,18 @@ export { export { handleBidiStreamingCall, handleServerStreamingCall, handleUnaryCall }; +/* eslint-disable @typescript-eslint/no-explicit-any */ export type Call = | ClientUnaryCall | ClientReadableStream | ClientWritableStream | ClientDuplexStream; +/* eslint-enable @typescript-eslint/no-explicit-any */ /**** Unimplemented function stubs ****/ +/* eslint-disable @typescript-eslint/no-explicit-any */ + export const loadObject = (value: any, options: any) => { throw new Error( 'Not available in this library. Use @grpc/proto-loader and loadPackageDefinition instead' diff --git a/packages/grpc-js/src/load-balancing-config.ts b/packages/grpc-js/src/load-balancing-config.ts index f2b9f3a7..eef025e6 100644 --- a/packages/grpc-js/src/load-balancing-config.ts +++ b/packages/grpc-js/src/load-balancing-config.ts @@ -21,6 +21,10 @@ * specific object type if the input has the right structure, and throws an * error otherwise. */ +/* The any type is purposely used here. All functions validate their input at + * runtime */ +/* eslint-disable @typescript-eslint/no-explicit-any */ + export type RoundRobinConfig = {}; export interface XdsConfig { diff --git a/packages/grpc-js/src/logging.ts b/packages/grpc-js/src/logging.ts index c7a63a47..91b4e8f0 100644 --- a/packages/grpc-js/src/logging.ts +++ b/packages/grpc-js/src/logging.ts @@ -47,6 +47,8 @@ export const setLogger = (logger: Partial): void => { export const setLoggerVerbosity = (verbosity: LogVerbosity): void => { _logVerbosity = verbosity; }; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any export const log = (severity: LogVerbosity, ...args: any[]): void => { if (severity >= _logVerbosity && typeof _logger.error === 'function') { _logger.error(...args); diff --git a/packages/grpc-js/src/make-client.ts b/packages/grpc-js/src/make-client.ts index 99daef15..f7e2dacc 100644 --- a/packages/grpc-js/src/make-client.ts +++ b/packages/grpc-js/src/make-client.ts @@ -50,6 +50,7 @@ export interface MethodDefinition ServerMethodDefinition {} export interface ServiceDefinition { + // eslint-disable-next-line @typescript-eslint/no-explicit-any [index: string]: MethodDefinition; } @@ -164,6 +165,7 @@ function partial( serialize: Function, deserialize: Function ): Function { + // eslint-disable-next-line @typescript-eslint/no-explicit-any return function (this: any, ...args: any[]) { return fn.call(this, path, serialize, deserialize, ...args); }; diff --git a/packages/grpc-js/src/object-stream.ts b/packages/grpc-js/src/object-stream.ts index 8d29b786..b17058a7 100644 --- a/packages/grpc-js/src/object-stream.ts +++ b/packages/grpc-js/src/object-stream.ts @@ -18,6 +18,8 @@ import { Duplex, Readable, Writable } from 'stream'; import { EmitterAugmentation1 } from './events'; +/* eslint-disable @typescript-eslint/no-explicit-any */ + export type WriteCallback = (error: Error | null | undefined) => void; export interface IntermediateObjectReadable extends Readable { diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index 240d8b53..abc37645 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -174,6 +174,7 @@ export class ServerWritableStreamImpl async _write( chunk: ResponseType, encoding: string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any callback: (...args: any[]) => void ) { try { @@ -200,6 +201,7 @@ export class ServerWritableStreamImpl callback(null); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any end(metadata?: any) { if (metadata) { this.trailingMetadata = metadata; @@ -669,6 +671,7 @@ export class Http2ServerCallStream< } } +/* eslint-disable @typescript-eslint/no-explicit-any */ type UntypedServerCall = Http2ServerCallStream; function handleExpiredDeadline(call: UntypedServerCall) { diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index af0deefc..5a8bfb55 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -70,6 +70,7 @@ function getUnimplementedStatusResponse( }; } +/* eslint-disable @typescript-eslint/no-explicit-any */ type UntypedUnaryHandler = UnaryHandler; type UntypedClientStreamingHandler = ClientStreamingHandler; type UntypedServerStreamingHandler = ServerStreamingHandler; @@ -411,6 +412,7 @@ export class Server { this.sessions.forEach((session) => { // Cast NGHTTP2_CANCEL to any because TypeScript doesn't seem to // recognize destroy(code) as a valid signature. + // eslint-disable-next-line @typescript-eslint/no-explicit-any session.destroy(http2.constants.NGHTTP2_CANCEL as any); }); this.sessions.clear(); diff --git a/packages/grpc-js/src/service-config.ts b/packages/grpc-js/src/service-config.ts index b1b0fdd4..ea5c449a 100644 --- a/packages/grpc-js/src/service-config.ts +++ b/packages/grpc-js/src/service-config.ts @@ -22,6 +22,10 @@ * specific object type if the input has the right structure, and throws an * error otherwise. */ +/* The any type is purposely used here. All functions validate their input at + * runtime */ +/* eslint-disable @typescript-eslint/no-explicit-any */ + import * as lbconfig from './load-balancing-config'; import * as os from 'os'; diff --git a/packages/grpc-js/src/subchannel-pool.ts b/packages/grpc-js/src/subchannel-pool.ts index 9f143729..0d42163d 100644 --- a/packages/grpc-js/src/subchannel-pool.ts +++ b/packages/grpc-js/src/subchannel-pool.ts @@ -63,6 +63,7 @@ export class SubchannelPool { /* These objects are created with Object.create(null), so they do not * have a prototype, which means that for (... in ...) loops over them * do not need to be filtered */ + // eslint-disable-disable-next-line:forin for (const channelTarget in this.pool) { const subchannelObjArray = this.pool[channelTarget]; diff --git a/packages/grpc-js/test/common.ts b/packages/grpc-js/test/common.ts index a3d8b9ba..24cb7165 100644 --- a/packages/grpc-js/test/common.ts +++ b/packages/grpc-js/test/common.ts @@ -72,6 +72,7 @@ export namespace assert2 { * Wraps a function to keep track of whether it was called or not. * @param fn The function to wrap. */ + // tslint:disable:no-any export function mustCall( fn: (...args: any[]) => T ): (...args: any[]) => T { diff --git a/packages/grpc-js/test/test-channel-credentials.ts b/packages/grpc-js/test/test-channel-credentials.ts index 99966941..d6028f46 100644 --- a/packages/grpc-js/test/test-channel-credentials.ts +++ b/packages/grpc-js/test/test-channel-credentials.ts @@ -49,6 +49,7 @@ class CallCredentialsMock implements CallCredentials { } } +// tslint:disable-next-line:no-any const readFile: (...args: any[]) => Promise = promisify(fs.readFile); // A promise which resolves to loaded files in the form { ca, key, cert } const pFixtures = Promise.all( diff --git a/packages/grpc-js/test/test-resolver.ts b/packages/grpc-js/test/test-resolver.ts index 57997c17..7f4900aa 100644 --- a/packages/grpc-js/test/test-resolver.ts +++ b/packages/grpc-js/test/test-resolver.ts @@ -15,6 +15,8 @@ * */ +// Allow `any` data type for testing runtime type checking. +// tslint:disable no-any import * as assert from 'assert'; import * as resolverManager from '../src/resolver'; import { ServiceConfig } from '../src/service-config'; diff --git a/packages/grpc-js/test/test-server-credentials.ts b/packages/grpc-js/test/test-server-credentials.ts index 9cc08b10..ec1740f7 100644 --- a/packages/grpc-js/test/test-server-credentials.ts +++ b/packages/grpc-js/test/test-server-credentials.ts @@ -16,6 +16,7 @@ */ // Allow `any` data type for testing runtime type checking. +// tslint:disable no-any import * as assert from 'assert'; import { readFileSync } from 'fs'; import { join } from 'path'; diff --git a/packages/grpc-js/test/test-server-deadlines.ts b/packages/grpc-js/test/test-server-deadlines.ts index 107994ba..c1152309 100644 --- a/packages/grpc-js/test/test-server-deadlines.ts +++ b/packages/grpc-js/test/test-server-deadlines.ts @@ -16,6 +16,7 @@ */ // Allow `any` data type for testing runtime type checking. +// tslint:disable no-any import * as assert from 'assert'; import * as path from 'path'; diff --git a/packages/grpc-js/test/test-server-errors.ts b/packages/grpc-js/test/test-server-errors.ts index 8e9f4520..7c611b9b 100644 --- a/packages/grpc-js/test/test-server-errors.ts +++ b/packages/grpc-js/test/test-server-errors.ts @@ -16,6 +16,7 @@ */ // Allow `any` data type for testing runtime type checking. +// tslint:disable no-any import * as assert from 'assert'; import { join } from 'path'; diff --git a/packages/grpc-js/test/test-server.ts b/packages/grpc-js/test/test-server.ts index c8d2e64a..434efbbc 100644 --- a/packages/grpc-js/test/test-server.ts +++ b/packages/grpc-js/test/test-server.ts @@ -16,6 +16,7 @@ */ // Allow `any` data type for testing runtime type checking. +// tslint:disable no-any import * as assert from 'assert'; import * as fs from 'fs'; import * as http2 from 'http2'; @@ -38,13 +39,13 @@ describe('Server', () => { describe('constructor', () => { it('should work with no arguments', () => { assert.doesNotThrow(() => { - new Server(); + new Server(); // tslint:disable-line:no-unused-expression }); }); it('should work with an empty object argument', () => { assert.doesNotThrow(() => { - new Server({}); + new Server({}); // tslint:disable-line:no-unused-expression }); }); From 490217c0592f0e494bde4253e3fdeb065f5c0dda Mon Sep 17 00:00:00 2001 From: Patrick Remy Date: Fri, 10 Apr 2020 11:09:42 +0200 Subject: [PATCH 11/18] grpc-js: resolve eslint no-prototype-builtins --- packages/grpc-js/src/make-client.ts | 2 +- packages/grpc-js/src/server-call.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/src/make-client.ts b/packages/grpc-js/src/make-client.ts index f7e2dacc..d23eeae0 100644 --- a/packages/grpc-js/src/make-client.ts +++ b/packages/grpc-js/src/make-client.ts @@ -194,7 +194,7 @@ export function loadPackageDefinition( ): GrpcObject { const result: GrpcObject = {}; for (const serviceFqn in packageDef) { - if (packageDef.hasOwnProperty(serviceFqn)) { + if (Object.prototype.hasOwnProperty.call(packageDef, serviceFqn)) { const service = packageDef[serviceFqn]; const nameComponents = serviceFqn.split('.'); const serviceName = nameComponents[nameComponents.length - 1]; diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index abc37645..f06f0783 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -479,7 +479,7 @@ export class Http2ServerCallStream< } if (err) { - if (!err.hasOwnProperty('metadata')) { + if (!Object.prototype.hasOwnProperty.call(err, 'metadata')) { err.metadata = metadata; } this.sendError(err); From e9172f043aecb48d226ec11c67efce79d8d0a74e Mon Sep 17 00:00:00 2001 From: Patrick Remy Date: Fri, 10 Apr 2020 11:12:00 +0200 Subject: [PATCH 12/18] grpc-js: resolve eslint error eqeqeq --- packages/grpc-js/src/client.ts | 4 ++-- packages/grpc-js/src/metadata.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/grpc-js/src/client.ts b/packages/grpc-js/src/client.ts index 23930474..8ebb2537 100644 --- a/packages/grpc-js/src/client.ts +++ b/packages/grpc-js/src/client.ts @@ -318,7 +318,7 @@ export class Client { }, // eslint-disable-next-line @typescript-eslint/no-explicit-any onReceiveMessage(message: any) { - if (responseMessage != null) { + if (responseMessage !== null) { call.cancelWithStatus(Status.INTERNAL, 'Too many responses received'); } responseMessage = message; @@ -435,7 +435,7 @@ export class Client { }, // eslint-disable-next-line @typescript-eslint/no-explicit-any onReceiveMessage(message: any) { - if (responseMessage != null) { + if (responseMessage !== null) { call.cancelWithStatus(Status.INTERNAL, 'Too many responses received'); } responseMessage = message; diff --git a/packages/grpc-js/src/metadata.ts b/packages/grpc-js/src/metadata.ts index 0ffe0af2..2da9d531 100644 --- a/packages/grpc-js/src/metadata.ts +++ b/packages/grpc-js/src/metadata.ts @@ -48,7 +48,7 @@ function validate(key: string, value?: MetadataValue): void { if (!isLegalKey(key)) { throw new Error('Metadata key "' + key + '" contains illegal characters'); } - if (value != null) { + if (value !== null && value !== undefined) { if (isBinaryKey(key)) { if (!(value instanceof Buffer)) { throw new Error("keys that end with '-bin' must have Buffer values"); From ac14e1ac544f19bb96bb7ef3b50a8174a7b6b1c6 Mon Sep 17 00:00:00 2001 From: Patrick Remy Date: Fri, 10 Apr 2020 11:15:10 +0200 Subject: [PATCH 13/18] grpc-js: Resolve eslint node/no-deprecated-api Remove unused imports --- packages/grpc-js/src/http_proxy.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/grpc-js/src/http_proxy.ts b/packages/grpc-js/src/http_proxy.ts index ef52deda..eb34a120 100644 --- a/packages/grpc-js/src/http_proxy.ts +++ b/packages/grpc-js/src/http_proxy.ts @@ -15,18 +15,14 @@ * */ -import { URL, parse } from 'url'; +import { URL } from 'url'; import { log } from './logging'; import { LogVerbosity } from './constants'; import { parseTarget } from './resolver-dns'; import { Socket } from 'net'; import * as http from 'http'; import * as logging from './logging'; -import { - SubchannelAddress, - TcpSubchannelAddress, - isTcpSubchannelAddress, -} from './subchannel'; +import { SubchannelAddress, isTcpSubchannelAddress } from './subchannel'; const TRACER_NAME = 'proxy'; From 19d960074b1223f918de4f63d1a9e3dc140c5a80 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 10 Apr 2020 10:09:54 -0700 Subject: [PATCH 14/18] grpc-js: Add more information to proxy errors --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/http_proxy.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 12f06052..9e888eb5 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "0.7.8", + "version": "0.7.9", "description": "gRPC Library for Node - pure JS implementation", "homepage": "https://grpc.io/", "repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js", diff --git a/packages/grpc-js/src/http_proxy.ts b/packages/grpc-js/src/http_proxy.ts index ab1083fc..00891bad 100644 --- a/packages/grpc-js/src/http_proxy.ts +++ b/packages/grpc-js/src/http_proxy.ts @@ -149,13 +149,13 @@ export function getProxiedConnection(target: string, subchannelAddress: Subchann trace('Successfully connected to ' + subchannelAddress + ' through proxy ' + PROXY_INFO.address); resolve(socket); } else { - log(LogVerbosity.ERROR, 'Failed to connect to ' + subchannelAddress + ' through proxy ' + PROXY_INFO.address); + log(LogVerbosity.ERROR, 'Failed to connect to ' + subchannelAddress + ' through proxy ' + PROXY_INFO.address + ' with status ' + res.statusCode); reject(); } }); request.once('error', (err) => { request.removeAllListeners(); - log(LogVerbosity.ERROR, 'Failed to connect to proxy ' + PROXY_INFO.address); + log(LogVerbosity.ERROR, 'Failed to connect to proxy ' + PROXY_INFO.address + ' with error ' + err.message); reject(); }); }); From f1c1dafae4318096ddd7fc9cc8c097d753dddc32 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 10 Apr 2020 10:15:29 -0700 Subject: [PATCH 15/18] grpc-js: Don't include the port in :authority --- packages/grpc-js/src/resolver-dns.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/grpc-js/src/resolver-dns.ts b/packages/grpc-js/src/resolver-dns.ts index 82727a42..4da295e1 100644 --- a/packages/grpc-js/src/resolver-dns.ts +++ b/packages/grpc-js/src/resolver-dns.ts @@ -298,16 +298,10 @@ class DnsResolver implements Resolver { IPV6_REGEX.exec(target) || IPV6_BRACKET_REGEX.exec(target); if (ipMatch) { - if (ipMatch[2]) { - return ipMatch[1] + ':' + ipMatch[2]; - } return ipMatch[1]; } const dnsMatch = DNS_REGEX.exec(target); if (dnsMatch) { - if (dnsMatch[2]) { - return dnsMatch[1] + ':' + dnsMatch[2]; - } return dnsMatch[1]; } throw new Error(`Failed to parse target ${target}`); From a4d3f290ebe0baf4a9a9fbd4e0f36607e30d1b9c Mon Sep 17 00:00:00 2001 From: Patrick Remy Date: Sat, 11 Apr 2020 16:11:13 +0200 Subject: [PATCH 16/18] grpc-js: linter disable no-unused-vars Make prettier happy and move eslint-disable comment --- packages/grpc-js/.eslintrc | 3 ++- packages/grpc-js/src/make-client.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/.eslintrc b/packages/grpc-js/.eslintrc index 7e3583cc..b18ad0ed 100644 --- a/packages/grpc-js/.eslintrc +++ b/packages/grpc-js/.eslintrc @@ -4,6 +4,7 @@ "rules": { "node/no-unpublished-import": ["error", { "tryExtensions": [".ts", ".js", ".json", ".node"] - }] + }], + "@typescript-eslint/no-unused-vars": "off" } } diff --git a/packages/grpc-js/src/make-client.ts b/packages/grpc-js/src/make-client.ts index b6725a71..02ef91af 100644 --- a/packages/grpc-js/src/make-client.ts +++ b/packages/grpc-js/src/make-client.ts @@ -50,12 +50,13 @@ export interface MethodDefinition extends ClientMethodDefinition, ServerMethodDefinition {} +/* eslint-disable @typescript-eslint/no-explicit-any */ export type ServiceDefinition< ImplementationType = UntypedServiceImplementation > = { - // eslint-disable-next-line @typescript-eslint/no-explicit-any readonly [index in keyof ImplementationType]: MethodDefinition; }; +/* eslint-enable @typescript-eslint/no-explicit-any */ export interface ProtobufTypeDefinition { format: string; From 70a92d2fc3cff9715399d00158f047588ab78218 Mon Sep 17 00:00:00 2001 From: Patrick Remy Date: Sun, 12 Apr 2020 17:20:28 +0200 Subject: [PATCH 17/18] grpc-js: resolve node/no-unpublished-require --- packages/grpc-js/src/index.ts | 3 ++- packages/grpc-js/src/subchannel.ts | 2 +- packages/grpc-js/tsconfig.json | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/src/index.ts b/packages/grpc-js/src/index.ts index 661e0efd..e4bb3658 100644 --- a/packages/grpc-js/src/index.ts +++ b/packages/grpc-js/src/index.ts @@ -62,7 +62,8 @@ import { ServerDuplexStream, } from './server-call'; -const supportedNodeVersions = require('../../package.json').engines.node; +import { engines as supportedEngines } from '../package.json'; +const supportedNodeVersions = supportedEngines.node; if (!semver.satisfies(process.version, supportedNodeVersions)) { throw new Error(`@grpc/grpc-js only works on Node ${supportedNodeVersions}`); } diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index 3f6cfd52..3f71720e 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -29,7 +29,7 @@ import { LogVerbosity } from './constants'; import { shouldUseProxy, getProxiedConnection } from './http_proxy'; import * as net from 'net'; -const { version: clientVersion } = require('../../package.json'); +import { version as clientVersion } from '../package.json'; const TRACER_NAME = 'subchannel'; diff --git a/packages/grpc-js/tsconfig.json b/packages/grpc-js/tsconfig.json index f60cbdc0..ba675db7 100644 --- a/packages/grpc-js/tsconfig.json +++ b/packages/grpc-js/tsconfig.json @@ -5,6 +5,7 @@ "outDir": "build", "target": "es2017", "module": "commonjs", + "resolveJsonModule": true, "incremental": true }, "include": [ From e7b25e307074ec39e80620e21a2b859987908ef0 Mon Sep 17 00:00:00 2001 From: Patrick Remy Date: Sun, 12 Apr 2020 18:04:45 +0200 Subject: [PATCH 18/18] gprc-js: upgrade to gts v2.0.0 Remove deprecated google-ts-style --- packages/grpc-js/package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 80de1316..4bd15ef5 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -26,8 +26,7 @@ "@types/semver": "^6.0.1", "clang-format": "^1.0.55", "execa": "^2.0.3", - "google-ts-style": "^0.2.0", - "gts": "^2.0.0-alpha.9", + "gts": "^2.0.0", "gulp": "^4.0.2", "gulp-mocha": "^6.0.0", "lodash": "^4.17.4",