diff --git a/packages/firestore/src/api/credentials.ts b/packages/firestore/src/api/credentials.ts index 8ce10d4c075..8346f4b577b 100644 --- a/packages/firestore/src/api/credentials.ts +++ b/packages/firestore/src/api/credentials.ts @@ -309,21 +309,19 @@ export function makeCredentialsProvider( switch (credentials.type) { case 'gapi': - const client = credentials.client; - // Make sure this is a Gapi client. + const client = credentials.client as Gapi; + // Make sure this really is a Gapi client. assert( !!( typeof client === 'object' && client !== null && - // @ts-ignore client['auth'] && - // @ts-ignore client['auth']['getAuthHeaderValueForFirstParty'] ), 'unexpected gapi interface' ); return new FirstPartyCredentialsProvider( - client as Gapi, + client, credentials.sessionIndex || '0' ); diff --git a/packages/firestore/src/local/shared_client_state.ts b/packages/firestore/src/local/shared_client_state.ts index 2f4e523b8e7..c87b01d290f 100644 --- a/packages/firestore/src/local/shared_client_state.ts +++ b/packages/firestore/src/local/shared_client_state.ts @@ -462,9 +462,7 @@ export class SharedOnlineState { const validData = typeof onlineState === 'object' && - // @ts-ignore Should allow arbitrary string index when checking to see - // if that string is a valid enum value. - OnlineState[onlineState.onlineState] !== undefined && + onlineState.onlineState in OnlineState && typeof onlineState.clientId === 'string'; if (validData) { diff --git a/packages/firestore/src/platform_browser/webchannel_connection.ts b/packages/firestore/src/platform_browser/webchannel_connection.ts index 162a036b456..f264d0a4588 100644 --- a/packages/firestore/src/platform_browser/webchannel_connection.ts +++ b/packages/firestore/src/platform_browser/webchannel_connection.ts @@ -20,8 +20,8 @@ import { ErrorCode, EventType, WebChannel, + WebChannelOptions, XhrIo - // @ts-ignore } from '@firebase/webchannel-wrapper'; import { isReactNative } from '@firebase/util'; @@ -193,7 +193,7 @@ export class WebChannelConnection implements Connection { '/channel' ]; const webchannelTransport = createWebChannelTransport(); - const request = { + const request: WebChannelOptions = { // Background channel test avoids the initial two test calls and decreases // initial cold start time. // TODO(dimond): wenboz@ mentioned this might affect use with proxies and @@ -224,7 +224,7 @@ export class WebChannelConnection implements Connection { forceLongPolling: this.forceLongPolling }; - this.modifyHeadersForRequest(request.initMessageHeaders, token); + this.modifyHeadersForRequest(request.initMessageHeaders!, token); // Sending the custom headers we just added to request.initMessageHeaders // (Authorization, etc.) will trigger the browser to make a CORS preflight @@ -244,8 +244,7 @@ export class WebChannelConnection implements Connection { // ReactNative and so we exclude it, which just means ReactNative may be // subject to the extra network roundtrip for CORS preflight. if (!isReactNative()) { - // @ts-ignore - request['httpHeadersOverwriteParam'] = '$httpHeaders'; + request.httpHeadersOverwriteParam = '$httpHeaders'; } const url = urlParts.join(''); @@ -345,11 +344,10 @@ export class WebChannelConnection implements Connection { // (and only errors) to be wrapped in an extra array. To be forward // compatible with the bug we need to check either condition. The latter // can be removed once the fix has been rolled out. + // tslint:disable-next-line:no-any msgData.error is not typed. + const msgDataAsAny: any = msgData; const error = - // tslint:disable-next-line:no-any msgData.error is not typed. - (msgData as any).error || - // @ts-ignore - (msgData[0] && msgData[0].error); + msgDataAsAny.error || (msgDataAsAny[0] && msgDataAsAny[0].error); if (error) { log.debug(LOG_TAG, 'WebChannel received error:', error); // error.status will be a string like 'OK' or 'NOT_FOUND'. diff --git a/packages/firestore/src/platform_node/grpc_connection.ts b/packages/firestore/src/platform_node/grpc_connection.ts index 8567cd87e48..da6b1a7f262 100644 --- a/packages/firestore/src/platform_node/grpc_connection.ts +++ b/packages/firestore/src/platform_node/grpc_connection.ts @@ -86,8 +86,8 @@ export class GrpcConnection implements Connection { private cachedStub: GeneratedGrpcStub | null = null; constructor(protos: grpc.GrpcObject, private databaseInfo: DatabaseInfo) { - // @ts-ignore - this.firestore = protos['google']['firestore']['v1']; + // tslint:disable-next-line:no-any + this.firestore = (protos as any)['google']['firestore']['v1']; } private ensureActiveStub(): GeneratedGrpcStub { diff --git a/packages/firestore/src/util/misc.ts b/packages/firestore/src/util/misc.ts index 026c5bc34da..ca2750757bb 100644 --- a/packages/firestore/src/util/misc.ts +++ b/packages/firestore/src/util/misc.ts @@ -18,6 +18,7 @@ import { assert } from './assert'; export type EventHandler = (value: E) => void; +export type Indexable = { [k: string]: unknown }; // tslint:disable-next-line:class-as-namespace export class AutoId { diff --git a/packages/firestore/test/unit/local/web_storage_shared_client_state.test.ts b/packages/firestore/test/unit/local/web_storage_shared_client_state.test.ts index 6b173f85cca..e4a15d8f9d4 100644 --- a/packages/firestore/test/unit/local/web_storage_shared_client_state.test.ts +++ b/packages/firestore/test/unit/local/web_storage_shared_client_state.test.ts @@ -205,10 +205,9 @@ describe('WebStorageSharedClientState', () => { // We capture the listener here so that we can invoke it from the local // client. If we directly relied on WebStorage listeners, we would not // receive events for local writes. - // @ts-ignore - window.addEventListener = (type: string, callback: WebStorageCallback) => { + window.addEventListener = (type: string, callback: unknown) => { if (type === 'storage') { - webStorageCallbacks.push(callback); + webStorageCallbacks.push(callback as WebStorageCallback); } }; window.removeEventListener = () => {}; diff --git a/packages/firestore/test/unit/remote/node/serializer.test.ts b/packages/firestore/test/unit/remote/node/serializer.test.ts index b2de0327f1a..5f8f5eea681 100644 --- a/packages/firestore/test/unit/remote/node/serializer.test.ts +++ b/packages/firestore/test/unit/remote/node/serializer.test.ts @@ -54,6 +54,7 @@ import { WatchTargetChangeState } from '../../../../src/remote/watch_change'; import { Code, FirestoreError } from '../../../../src/util/error'; +import { Indexable } from '../../../../src/util/misc'; import * as obj from '../../../../src/util/obj'; import * as types from '../../../../src/util/types'; import { addEqualityMatcher } from '../../../util/equality_matcher'; @@ -156,8 +157,9 @@ describe('Serializer', () => { const actualProtobufjsProto: ProtobufJS.Message = ValueMessage.fromObject( actualJsonProto ); - // @ts-ignore - expect(actualProtobufjsProto[valueType]).to.deep.equal(protobufJsValue); + expect((actualProtobufjsProto as Indexable)[valueType]).to.deep.equal( + protobufJsValue + ); // Convert protobufjs back to JSON. const returnJsonProto = ValueMessage.toObject( diff --git a/packages/firestore/test/util/equality_matcher.ts b/packages/firestore/test/util/equality_matcher.ts index 2ded6259fa3..d59f4ae175e 100644 --- a/packages/firestore/test/util/equality_matcher.ts +++ b/packages/firestore/test/util/equality_matcher.ts @@ -16,6 +16,7 @@ */ import { use } from 'chai'; +import { Equatable } from '../../src/util/misc'; /** * @file This file provides a helper function to add a matcher that matches @@ -28,10 +29,12 @@ function customDeepEqual(left: unknown, right: unknown): boolean { /** * START: Custom compare logic */ - // @ts-ignore - if (left && typeof left.isEqual === 'function') return left.isEqual(right); - // @ts-ignore - if (right && typeof right.isEqual === 'function') return right.isEqual(left); + if (typeof left === 'object' && left && 'isEqual' in left) { + return (left as Equatable).isEqual(right); + } + if (typeof right === 'object' && right && 'isEqual' in right) { + return (right as Equatable).isEqual(left); + } /** * END: Custom compare logic */ diff --git a/packages/webchannel-wrapper/package.json b/packages/webchannel-wrapper/package.json index c1d5e1b485b..93595bd5410 100644 --- a/packages/webchannel-wrapper/package.json +++ b/packages/webchannel-wrapper/package.json @@ -26,6 +26,7 @@ "type": "git", "url": "https://github.com/firebase/firebase-js-sdk.git" }, + "typings": "src/index.d.ts", "bugs": { "url": "https://github.com/firebase/firebase-js-sdk/issues" } diff --git a/packages/webchannel-wrapper/src/index.d.ts b/packages/webchannel-wrapper/src/index.d.ts new file mode 100644 index 00000000000..4aedb1a7c8b --- /dev/null +++ b/packages/webchannel-wrapper/src/index.d.ts @@ -0,0 +1,56 @@ +/** + * @license + * Copyright 2019 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// TODO(mikelehen): Flesh out proper types (or figure out how to generate via +// clutz or something). +export class XhrIo {} +export const ErrorCode: any; +export const EventType: any; +export namespace WebChannel { + export type EventType = any; + export const EventType: any; +} + +type StringMap = { [key: string]: string }; + +export interface WebChannelOptions { + messageHeaders?: StringMap; + initMessageHeaders?: StringMap; + messageContentType?: string; + messageUrlParams?: StringMap; + clientProtocolHeaderRequired?: boolean; + concurrentRequestLimit?: number; + supportsCrossDomainXhr?: boolean; + testUrl?: string; + sendRawJson?: boolean; + httpSessionIdParam?: string; + httpHeadersOverwriteParam?: string; + backgroundChannelTest?: boolean; + forceLongPolling?: boolean; + fastHandshake?: boolean; + disableRedac?: boolean; + clientProfile?: string; + internalChannelParams?: { [key: string]: boolean | number }; + xmlHttpFactory?: unknown; + requestRefreshThresholds?: { [key: string]: number }; +} + +export interface WebChannelTransport { + createWebChannel(url: string, options: WebChannelOptions): any; +} + +export function createWebChannelTransport(): WebChannelTransport;