diff --git a/packages/firestore/.eslintrc.json b/packages/firestore/.eslintrc.json index 2b39e9f6f85..f8a5c337134 100644 --- a/packages/firestore/.eslintrc.json +++ b/packages/firestore/.eslintrc.json @@ -2,5 +2,30 @@ "extends": "../../config/.eslintrc.json", "parserOptions": { "project": "tsconfig.json" - } + }, + "plugins": [ + "import" + ], + "rules": { + "no-console":[ "error", { "allow": ["warn", "error"] }], + "import/no-default-export": "error", + "@typescript-eslint/no-unused-vars": [ + "error", + { + "varsIgnorePattern": "^_", + "args": "none" + } + ] + }, + "overrides": [ + { + "files": [ + "**/*.test.ts", + "**/test/**/*.ts" + ], + "rules": { + "@typescript-eslint/no-explicit-any": "error" + } + } + ] } \ No newline at end of file diff --git a/packages/firestore/index.node.ts b/packages/firestore/index.node.ts index 1393181e72d..a4fba26f35a 100644 --- a/packages/firestore/index.node.ts +++ b/packages/firestore/index.node.ts @@ -18,7 +18,6 @@ import firebase from '@firebase/app'; import { FirebaseNamespace } from '@firebase/app-types'; import * as types from '@firebase/firestore-types'; -import { Firestore } from './src/api/database'; import { configureForFirebase } from './src/platform/config'; import './src/platform_node/node_init'; diff --git a/packages/firestore/package.json b/packages/firestore/package.json index 5d4a1bb1782..99f60066502 100644 --- a/packages/firestore/package.json +++ b/packages/firestore/package.json @@ -7,9 +7,8 @@ "build": "rollup -c", "build:console": "node tools/console.build.js", "dev": "rollup -c -w", - "lint": "tslint -p tsconfig.json -c tslint.json 'src/**/*.ts' 'test/**/*.ts'", - "lint:fix": "tslint --fix -p tsconfig.json -c tslint.json 'src/**/*.ts' 'test/**/*.ts'", - "lint:eslint": "eslint -c .eslintrc.json '**/*.ts' --ignore-path '../../.gitignore'", + "lint": "eslint -c .eslintrc.json '**/*.ts' --ignore-path '../../.gitignore'", + "lint:fix": "eslint --fix -c .eslintrc.json '**/*.ts' --ignore-path '../../.gitignore'", "prettier": "prettier --write 'src/**/*.js' 'test/**/*.js' 'src/**/*.ts' 'test/**/*.ts'", "test": "run-s lint test:all", "test:all": "run-p test:browser test:emulator", @@ -33,6 +32,7 @@ "@firebase/logger": "0.1.17", "@firebase/webchannel-wrapper": "0.2.21", "@grpc/proto-loader": "^0.5.0", + "@firebase/util": "0.2.20", "grpc": "1.20.3", "tslib": "1.9.3" }, @@ -82,7 +82,8 @@ "eslint": "5.16.0", "@typescript-eslint/parser": "1.10.2", "@typescript-eslint/eslint-plugin": "1.10.2", - "@typescript-eslint/eslint-plugin-tslint": "1.10.2" + "@typescript-eslint/eslint-plugin-tslint": "1.10.2", + "eslint-plugin-import": "2.17.3" }, "repository": { "directory": "packages/firestore", @@ -99,4 +100,4 @@ ], "reportDir": "./coverage/node" } -} +} \ No newline at end of file diff --git a/packages/firestore/src/api/blob.ts b/packages/firestore/src/api/blob.ts index ac95930ca89..e469e4c0ad6 100644 --- a/packages/firestore/src/api/blob.ts +++ b/packages/firestore/src/api/blob.ts @@ -136,8 +136,7 @@ export class Blob { // instanceof checks. // For our internal TypeScript code PublicBlob doesn't exist as a type, and so // we need to use Blob as type and export it too. -// tslint:disable-next-line:variable-name We're treating this as a class name. -export let PublicBlob = makeConstructorPrivate( +export const PublicBlob = makeConstructorPrivate( Blob, 'Use Blob.fromUint8Array() or Blob.fromBase64String() instead.' ); diff --git a/packages/firestore/src/api/credentials.ts b/packages/firestore/src/api/credentials.ts index 8346f4b577b..49385291736 100644 --- a/packages/firestore/src/api/credentials.ts +++ b/packages/firestore/src/api/credentials.ts @@ -104,8 +104,6 @@ export class EmptyCredentialsProvider implements CredentialsProvider { */ private changeListener: CredentialChangeListener | null = null; - constructor() {} - getToken(): Promise { return Promise.resolve(null); } diff --git a/packages/firestore/src/api/database.ts b/packages/firestore/src/api/database.ts index 8b2e4410050..b03cf3dfb06 100644 --- a/packages/firestore/src/api/database.ts +++ b/packages/firestore/src/api/database.ts @@ -74,7 +74,9 @@ import { validateStringEnum, valueDescription } from '../util/input_validation'; +// eslint-disable-next-line import/no-duplicates import * as log from '../util/log'; +// eslint-disable-next-line import/no-duplicates import { LogLevel } from '../util/log'; import { AutoId } from '../util/misc'; import * as objUtils from '../util/obj'; @@ -103,11 +105,6 @@ import { UserDataConverter } from './user_data_converter'; -// The objects that are a part of this API are exposed to third-parties as -// compiled javascript so we want to flag our private members with a leading -// underscore to discourage their use. -// tslint:disable:strip-private-property-underscore - // settings() defaults: const DEFAULT_HOST = 'firestore.googleapis.com'; const DEFAULT_SSL = true; @@ -158,7 +155,7 @@ class FirestoreSettings { readonly forceLongPolling: boolean; // Can be a google-auth-library or gapi client. - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any credentials?: any; constructor(settings: PrivateSettings) { @@ -298,6 +295,9 @@ class FirestoreConfig { * The root reference to the database. */ export class Firestore implements firestore.FirebaseFirestore, FirebaseService { + // The objects that are a part of this API are exposed to third-parties as + // compiled javascript so we want to flag our private members with a leading + // underscore to discourage their use. private readonly _config: FirestoreConfig; readonly _databaseId: DatabaseId; @@ -480,7 +480,7 @@ export class Firestore implements firestore.FirebaseFirestore, FirebaseService { const databaseInfo = this.makeDatabaseInfo(); - const preConverter = (value: unknown) => { + const preConverter = (value: unknown): unknown => { if (value instanceof DocumentReference) { const thisDb = this._config.databaseId; const otherDb = value.firestore._config.databaseId; @@ -1116,7 +1116,7 @@ export class DocumentReference implements firestore.DocumentReference { options: ListenOptions, observer: PartialObserver ): Unsubscribe { - let errHandler = (err: Error) => { + let errHandler = (err: Error): void => { console.error('Uncaught Error in onSnapshot:', err); }; if (observer.error) { @@ -1387,16 +1387,6 @@ export class DocumentSnapshot implements firestore.DocumentSnapshot { export class QueryDocumentSnapshot extends DocumentSnapshot implements firestore.QueryDocumentSnapshot { - constructor( - firestore: Firestore, - key: DocumentKey, - document: Document, - fromCache: boolean, - hasPendingWrites: boolean - ) { - super(firestore, key, document, fromCache, hasPendingWrites); - } - data(options?: SnapshotOptions): firestore.DocumentData { const data = super.data(options); assert( @@ -1860,7 +1850,7 @@ export class Query implements firestore.Query { options: ListenOptions, observer: PartialObserver ): Unsubscribe { - let errHandler = (err: Error) => { + let errHandler = (err: Error): void => { console.error('Uncaught Error in onSnapshot:', err); }; if (observer.error) { @@ -1882,7 +1872,7 @@ export class Query implements firestore.Query { asyncObserver, options ); - return () => { + return (): void => { asyncObserver.mute(); firestoreClient.unlisten(internalListener); }; @@ -2417,7 +2407,6 @@ function resultChangeType(type: ChangeType): firestore.DocumentChangeType { // We're treating the variables as class names, so disable checking for lower // case variable names. -// tslint:disable:variable-name export const PublicFirestore = makeConstructorPrivate( Firestore, 'Use firebase.firestore() instead.' @@ -2444,4 +2433,3 @@ export const PublicCollectionReference = makeConstructorPrivate( CollectionReference, 'Use firebase.firestore().collection() instead.' ); -// tslint:enable:variable-name diff --git a/packages/firestore/src/api/field_path.ts b/packages/firestore/src/api/field_path.ts index b74c42eb842..d5cb3c1fb34 100644 --- a/packages/firestore/src/api/field_path.ts +++ b/packages/firestore/src/api/field_path.ts @@ -28,7 +28,6 @@ import { // The objects that are a part of this API are exposed to third-parties as // compiled javascript so we want to flag our private members with a leading // underscore to discourage their use. -// tslint:disable:strip-private-property-underscore /** * A FieldPath refers to a field in a document. The path may consist of a single diff --git a/packages/firestore/src/api/field_value.ts b/packages/firestore/src/api/field_value.ts index 70f783f28b1..576ea915869 100644 --- a/packages/firestore/src/api/field_value.ts +++ b/packages/firestore/src/api/field_value.ts @@ -29,7 +29,6 @@ import { * An opaque base class for FieldValue sentinel objects in our public API, * with public static methods for creating said sentinel objects. */ -// tslint:disable-next-line:class-as-namespace We use this as a base class. export abstract class FieldValueImpl implements firestore.FieldValue { protected constructor(readonly _methodName: string) {} @@ -109,7 +108,6 @@ export class NumericIncrementFieldValueImpl extends FieldValueImpl { // PublicFieldValue can be used interchangeably in instanceof checks. // For our internal TypeScript code PublicFieldValue doesn't exist as a type, // and so we need to use FieldValueImpl as type and export it too. -// tslint:disable-next-line:variable-name We treat this as a class name. export const PublicFieldValue = makeConstructorPrivate( FieldValueImpl, 'Use FieldValue.() instead.' diff --git a/packages/firestore/src/api/user_data_converter.ts b/packages/firestore/src/api/user_data_converter.ts index 79729bf6a31..f4f539ffe17 100644 --- a/packages/firestore/src/api/user_data_converter.ts +++ b/packages/firestore/src/api/user_data_converter.ts @@ -20,8 +20,10 @@ import * as firestore from '@firebase/firestore-types'; import { Timestamp } from '../api/timestamp'; import { DatabaseId } from '../core/database_info'; import { DocumentKey } from '../model/document_key'; -import { FieldValue, NumberValue, ObjectValue } from '../model/field_value'; import { + FieldValue, + NumberValue, + ObjectValue, ArrayValue, BlobValue, BooleanValue, @@ -33,6 +35,7 @@ import { StringValue, TimestampValue } from '../model/field_value'; + import { FieldMask, FieldTransform, @@ -47,8 +50,7 @@ import { assert, fail } from '../util/assert'; import { Code, FirestoreError } from '../util/error'; import { isPlainObject, valueDescription } from '../util/input_validation'; import { primitiveComparator } from '../util/misc'; -import * as objUtils from '../util/obj'; -import { Dict } from '../util/obj'; +import { Dict, forEach, isEmpty } from '../util/obj'; import { SortedMap } from '../util/sorted_map'; import * as typeUtils from '../util/types'; @@ -394,7 +396,7 @@ export class UserDataConverter { let fieldMaskPaths = new SortedSet(FieldPath.comparator); let updateData = ObjectValue.EMPTY; - objUtils.forEach(input as Dict, (key, value) => { + forEach(input as Dict, (key, value) => { const path = fieldPathFromDotSeparatedString(methodName, key); const childContext = context.childContextForFieldPath(path); @@ -544,14 +546,14 @@ export class UserDataConverter { private parseObject(obj: Dict, context: ParseContext): FieldValue { let result = new SortedMap(primitiveComparator); - if (objUtils.isEmpty(obj)) { + if (isEmpty(obj)) { // If we encounter an empty object, we explicitly add it to the update // mask to ensure that the server creates a map entry. if (context.path && context.path.length > 0) { context.fieldMask.push(context.path); } } else { - objUtils.forEach(obj, (key: string, val: unknown) => { + forEach(obj, (key: string, val: unknown) => { const parsedValue = this.parseData( val, context.childContextForField(key) diff --git a/packages/firestore/src/core/event_manager.ts b/packages/firestore/src/core/event_manager.ts index 0e055c6e165..c2851d21805 100644 --- a/packages/firestore/src/core/event_manager.ts +++ b/packages/firestore/src/core/event_manager.ts @@ -21,8 +21,7 @@ import { ObjectMap } from '../util/obj_map'; import { Query } from './query'; import { SyncEngine, SyncEngineListener } from './sync_engine'; import { OnlineState, TargetId } from './types'; -import { DocumentViewChange } from './view_snapshot'; -import { ChangeType, ViewSnapshot } from './view_snapshot'; +import { DocumentViewChange, ChangeType, ViewSnapshot } from './view_snapshot'; /** * Holds the listeners and the last received ViewSnapshot for a query being @@ -72,7 +71,9 @@ export class EventManager implements SyncEngineListener { listener.applyOnlineStateChange(this.onlineState); - if (queryInfo.viewSnap) listener.onViewSnapshot(queryInfo.viewSnap); + if (queryInfo.viewSnap) { + listener.onViewSnapshot(queryInfo.viewSnap); + } if (firstListen) { return this.syncEngine.listen(query).then(targetId => { diff --git a/packages/firestore/src/core/firestore_client.ts b/packages/firestore/src/core/firestore_client.ts index db7ca678107..89a818535ce 100644 --- a/packages/firestore/src/core/firestore_client.ts +++ b/packages/firestore/src/core/firestore_client.ts @@ -252,7 +252,6 @@ export class FirestoreClient { if (!this.canFallback(error)) { throw error; } - console.warn( 'Error enabling offline persistence. Falling back to' + ' persistence disabled: ' + @@ -431,14 +430,14 @@ export class FirestoreClient { const remoteStoreOnlineStateChangedHandler = ( onlineState: OnlineState - ) => + ): void => this.syncEngine.applyOnlineStateChange( onlineState, OnlineStateSource.RemoteStore ); const sharedClientStateOnlineStateChangedHandler = ( onlineState: OnlineState - ) => + ): void => this.syncEngine.applyOnlineStateChange( onlineState, OnlineStateSource.SharedClientState diff --git a/packages/firestore/src/core/query.ts b/packages/firestore/src/core/query.ts index 221803bb95f..83a63cfec75 100644 --- a/packages/firestore/src/core/query.ts +++ b/packages/firestore/src/core/query.ts @@ -310,7 +310,9 @@ export class Query { let comparedOnKeyField = false; for (const orderBy of this.orderBy) { const comp = orderBy.compare(d1, d2); - if (comp !== 0) return comp; + if (comp !== 0) { + return comp; + } comparedOnKeyField = comparedOnKeyField || orderBy.field.isKeyField(); } // Assert that we actually compared by key @@ -620,10 +622,6 @@ export class FieldFilter extends Filter { /** Filter that matches on key fields (i.e. '__name__'). */ export class KeyFieldFilter extends FieldFilter { - constructor(field: FieldPath, op: Operator, value: RefValue) { - super(field, op, value); - } - matches(doc: Document): boolean { const refValue = this.value as RefValue; const comparison = DocumentKey.comparator(doc.key, refValue.key); diff --git a/packages/firestore/src/core/sync_engine.ts b/packages/firestore/src/core/sync_engine.ts index a00161ee1ae..1ff09c54be7 100644 --- a/packages/firestore/src/core/sync_engine.ts +++ b/packages/firestore/src/core/sync_engine.ts @@ -248,7 +248,6 @@ export class SyncEngine implements RemoteSyncer, SharedClientStateSyncer { .then(remoteKeys => { const view = new View(query, remoteKeys); const viewDocChanges = view.computeDocChanges(docs); - // tslint:disable-next-line:max-line-length Prettier formats this exceed 100 characters. const synthesizedTargetChange = TargetChange.createSynthesizedTargetChangeForCurrentChange( queryData.targetId, current && this.onlineState !== OnlineState.Offline @@ -388,7 +387,7 @@ export class SyncEngine implements RemoteSyncer, SharedClientStateSyncer { ): Promise { assert(retries >= 0, 'Got negative number of retries for transaction.'); const transaction = this.remoteStore.createTransaction(); - const wrappedUpdateFunction = () => { + const wrappedUpdateFunction = (): Promise => { try { const userPromise = updateFunction(transaction); if ( @@ -976,8 +975,6 @@ export class SyncEngine implements RemoteSyncer, SharedClientStateSyncer { case 'not-current': { return this.localStore.getNewDocumentChanges().then( async changes => { - // tslint and prettier disagree about their preferred line length. - // tslint:disable-next-line:max-line-length const synthesizedRemoteEvent = RemoteEvent.createSynthesizedRemoteEventForCurrentChange( targetId, state === 'current' diff --git a/packages/firestore/src/core/transaction.ts b/packages/firestore/src/core/transaction.ts index 229f498b2a7..69d4d57c44d 100644 --- a/packages/firestore/src/core/transaction.ts +++ b/packages/firestore/src/core/transaction.ts @@ -17,8 +17,8 @@ import { ParsedSetData, ParsedUpdateData } from '../api/user_data_converter'; import { documentVersionMap } from '../model/collections'; -import { Document, NoDocument } from '../model/document'; -import { MaybeDocument } from '../model/document'; +import { Document, NoDocument, MaybeDocument } from '../model/document'; + import { DocumentKey } from '../model/document_key'; import { DeleteMutation, Mutation, Precondition } from '../model/mutation'; import { Datastore } from '../remote/datastore'; diff --git a/packages/firestore/src/core/view.ts b/packages/firestore/src/core/view.ts index 9d519fc6ece..c57b2231341 100644 --- a/packages/firestore/src/core/view.ts +++ b/packages/firestore/src/core/view.ts @@ -468,7 +468,7 @@ export class View { } function compareChangeType(c1: ChangeType, c2: ChangeType): number { - const order = (change: ChangeType) => { + const order = (change: ChangeType): 0 | 1 | 2 => { switch (change) { case ChangeType.Added: return 1; diff --git a/packages/firestore/src/core/view_snapshot.ts b/packages/firestore/src/core/view_snapshot.ts index 9e5f3a39eaa..c1c06cab8dc 100644 --- a/packages/firestore/src/core/view_snapshot.ts +++ b/packages/firestore/src/core/view_snapshot.ts @@ -50,8 +50,6 @@ export class DocumentChangeSet { DocumentKey.comparator ); - constructor() {} - track(change: DocumentViewChange): void { const key = change.doc.key; const oldChange = this.changeMap.get(key); diff --git a/packages/firestore/src/local/indexeddb_mutation_queue.ts b/packages/firestore/src/local/indexeddb_mutation_queue.ts index 2ddfaff34a4..af3b585786c 100644 --- a/packages/firestore/src/local/indexeddb_mutation_queue.ts +++ b/packages/firestore/src/local/indexeddb_mutation_queue.ts @@ -165,7 +165,7 @@ export class IndexedDbMutationQueue implements MutationQueue { // mutation batch. // See: https://bugs.chromium.org/p/chromium/issues/detail?id=701972 - // tslint:disable-next-line:no-any We write an empty object to obtain key + // eslint-disable-next-line @typescript-eslint/no-explicit-any, We write an empty object to obtain key return mutationStore.add({} as any).next(batchId => { assert(typeof batchId === 'number', 'Auto-generated key is not a number'); diff --git a/packages/firestore/src/local/indexeddb_persistence.ts b/packages/firestore/src/local/indexeddb_persistence.ts index aaa87e78059..2e37d98afa7 100644 --- a/packages/firestore/src/local/indexeddb_persistence.ts +++ b/packages/firestore/src/local/indexeddb_persistence.ts @@ -168,9 +168,9 @@ export class IndexedDbTransaction extends PersistenceTransaction { * TODO(b/114226234): Remove `synchronizeTabs` section when multi-tab is no * longer optional. */ -export type MultiClientParams = { +export interface MultiClientParams { sequenceNumberSyncer: SequenceNumberSyncer; -}; +} export class IndexedDbPersistence implements Persistence { static getStore( txn: PersistenceTransaction, diff --git a/packages/firestore/src/local/indexeddb_schema.ts b/packages/firestore/src/local/indexeddb_schema.ts index a6c72de035e..eee5ba8acbc 100644 --- a/packages/firestore/src/local/indexeddb_schema.ts +++ b/packages/firestore/src/local/indexeddb_schema.ts @@ -249,7 +249,9 @@ export class SchemaConverter implements SimpleDbSchemaConverter { // Helper to add an index entry iff we haven't already written it. const cache = new MemoryCollectionParentIndex(); - const addEntry = (collectionPath: ResourcePath) => { + const addEntry = ( + collectionPath: ResourcePath + ): PersistencePromise | undefined => { if (cache.add(collectionPath)) { const collectionId = collectionPath.lastSegment(); const parentPath = collectionPath.popLast(); @@ -784,7 +786,6 @@ export class DbTargetDocument { ) { assert( (targetId === 0) === (sequenceNumber !== undefined), - // tslint:disable-next-line:max-line-length 'A target-document row must either have targetId == 0 and a defined sequence number, or a non-zero targetId and no sequence number' ); } diff --git a/packages/firestore/src/local/local_store.ts b/packages/firestore/src/local/local_store.ts index dc9b8c2a55b..b1453dde1f5 100644 --- a/packages/firestore/src/local/local_store.ts +++ b/packages/firestore/src/local/local_store.ts @@ -458,7 +458,9 @@ export class LocalStore { (targetId: TargetId, change: TargetChange) => { // Do not ref/unref unassigned targetIds - it may lead to leaks. let queryData = this.queryDataByTarget[targetId]; - if (!queryData) return; + if (!queryData) { + return; + } // When a global snapshot contains updates (either add or modify) we // can completely trust these updates as authoritative and blindly @@ -616,10 +618,14 @@ export class LocalStore { change: TargetChange ): boolean { // Avoid clearing any existing value - if (newQueryData.resumeToken.length === 0) return false; + if (newQueryData.resumeToken.length === 0) { + return false; + } // Any resume token is interesting if there isn't one already. - if (oldQueryData.resumeToken.length === 0) return true; + if (oldQueryData.resumeToken.length === 0) { + return true; + } // Don't allow resume token changes to be buffered indefinitely. This // allows us to be reasonably up-to-date after a crash and avoids needing @@ -629,7 +635,9 @@ export class LocalStore { const timeDelta = newQueryData.snapshotVersion.toMicroseconds() - oldQueryData.snapshotVersion.toMicroseconds(); - if (timeDelta >= this.RESUME_TOKEN_MAX_AGE_MICROS) return true; + if (timeDelta >= this.RESUME_TOKEN_MAX_AGE_MICROS) { + return true; + } // Otherwise if the only thing that has changed about a target is its resume // token it's not worth persisting. Note that the RemoteStore keeps an diff --git a/packages/firestore/src/local/lru_garbage_collector.ts b/packages/firestore/src/local/lru_garbage_collector.ts index 1fd748aa77e..4b4e4e820a6 100644 --- a/packages/firestore/src/local/lru_garbage_collector.ts +++ b/packages/firestore/src/local/lru_garbage_collector.ts @@ -86,9 +86,9 @@ export interface LruDelegate { * Describes an object whose keys are active target ids. We do not care about the type of the * values. */ -export type ActiveTargets = { +export interface ActiveTargets { [id: number]: unknown; -}; +} // The type and comparator for the items contained in the SortedSet used in // place of a priority queue for the RollingSequenceNumberBuffer. @@ -154,12 +154,12 @@ class RollingSequenceNumberBuffer { * has not hit the threshold). If collection ran, the other fields will be * filled in with the details of the results. */ -export type LruResults = { +export interface LruResults { readonly didRun: boolean; readonly sequenceNumbersCollected: number; readonly targetsRemoved: number; readonly documentsRemoved: number; -}; +} const GC_DID_NOT_RUN: LruResults = { didRun: false, @@ -373,12 +373,11 @@ export class LruGarbageCollector { let upperBoundSequenceNumber: number; let sequenceNumbersToCollect: number, targetsRemoved: number; // Timestamps for various pieces of the process - let startTs: number, - countedTargetsTs: number, + let countedTargetsTs: number, foundUpperBoundTs: number, removedTargetsTs: number, removedDocumentsTs: number; - startTs = Date.now(); + const startTs = Date.now(); return this.calculateTargetCount(txn, this.params.percentileToCollect) .next(sequenceNumbers => { // Cap at the configured max diff --git a/packages/firestore/src/local/memory_persistence.ts b/packages/firestore/src/local/memory_persistence.ts index cc8e1f7a86e..c88e7d856f0 100644 --- a/packages/firestore/src/local/memory_persistence.ts +++ b/packages/firestore/src/local/memory_persistence.ts @@ -105,7 +105,7 @@ export class MemoryPersistence implements Persistence { this._started = true; this.referenceDelegate = referenceDelegateFactory(this); this.queryCache = new MemoryQueryCache(this); - const sizer = (doc: MaybeDocument) => + const sizer = (doc: MaybeDocument): number => this.referenceDelegate.documentSize(doc); this.indexManager = new MemoryIndexManager(); this.remoteDocumentCache = new MemoryRemoteDocumentCache( diff --git a/packages/firestore/src/local/persistence_promise.ts b/packages/firestore/src/local/persistence_promise.ts index 3ac59d4c928..eb799021584 100644 --- a/packages/firestore/src/local/persistence_promise.ts +++ b/packages/firestore/src/local/persistence_promise.ts @@ -42,10 +42,8 @@ export type Rejector = (error: Error) => void; export class PersistencePromise { // NOTE: next/catchCallback will always point to our own wrapper functions, // not the user's raw next() or catch() callbacks. - // tslint:disable-next-line:no-any Accept any result type for the next call in the Promise chain. - private nextCallback: FulfilledHandler = null; - // tslint:disable-next-line:no-any Accept any result type for the error handler. - private catchCallback: RejectedHandler = null; + private nextCallback: FulfilledHandler = null; + private catchCallback: RejectedHandler = null; // When the operation resolves, we'll set result or error and mark isDone. private result: T | undefined = undefined; @@ -137,10 +135,8 @@ export class PersistencePromise { if (nextFn) { return this.wrapUserFunction(() => nextFn(value)); } else { - // If there's no nextFn, then R must be the same as T but we - // can't express that in the type system. - // tslint:disable-next-line:no-any - return PersistencePromise.resolve(value as any); + // If there's no nextFn, then R must be the same as T + return PersistencePromise.resolve((value as unknown) as R); } } @@ -170,7 +166,7 @@ export class PersistencePromise { } static waitFor( - // tslint:disable-next-line:no-any Accept all Promise types in waitFor(). + // eslint-disable-next-line @typescript-eslint/no-explicit-any, Accept all Promise types in waitFor(). all: { forEach: (cb: (el: PersistencePromise) => void) => void } ): PersistencePromise { return new PersistencePromise((resolve, reject) => { diff --git a/packages/firestore/src/local/simple_db.ts b/packages/firestore/src/local/simple_db.ts index 3145fe6e7f2..73311426126 100644 --- a/packages/firestore/src/local/simple_db.ts +++ b/packages/firestore/src/local/simple_db.ts @@ -485,7 +485,7 @@ export class SimpleDbStore< */ get(key: KeyType): PersistencePromise { const request = this.store.get(key); - // tslint:disable-next-line:no-any We're doing an unsafe cast to ValueType. + // eslint-disable-next-line @typescript-eslint/no-explicit-any, We're doing an unsafe cast to ValueType. return wrapRequest(request).next(result => { // Normalize nonexistence to null. if (result === undefined) { diff --git a/packages/firestore/src/model/collections.ts b/packages/firestore/src/model/collections.ts index 0f7862a3a2a..72f9a4e5b27 100644 --- a/packages/firestore/src/model/collections.ts +++ b/packages/firestore/src/model/collections.ts @@ -25,10 +25,10 @@ import { Document, MaybeDocument } from './document'; import { DocumentKey } from './document_key'; /** Miscellaneous collection types / constants. */ -export type DocumentSizeEntry = { +export interface DocumentSizeEntry { maybeDocument: MaybeDocument; size: number; -}; +} export type MaybeDocumentMap = SortedMap; const EMPTY_MAYBE_DOCUMENT_MAP = new SortedMap( @@ -47,10 +47,10 @@ export function nullableMaybeDocumentMap(): NullableMaybeDocumentMap { return maybeDocumentMap(); } -export type DocumentSizeEntries = { +export interface DocumentSizeEntries { maybeDocuments: NullableMaybeDocumentMap; sizeMap: SortedMap; -}; +} export type DocumentMap = SortedMap; const EMPTY_DOCUMENT_MAP = new SortedMap( diff --git a/packages/firestore/src/model/document.ts b/packages/firestore/src/model/document.ts index f70bd66191d..7c9311c1692 100644 --- a/packages/firestore/src/model/document.ts +++ b/packages/firestore/src/model/document.ts @@ -162,10 +162,6 @@ export class NoDocument extends MaybeDocument { * document that was updated without a known base document). */ export class UnknownDocument extends MaybeDocument { - constructor(key: DocumentKey, version: SnapshotVersion) { - super(key, version); - } - toString(): string { return `UnknownDocument(${this.key}, ${this.version})`; } diff --git a/packages/firestore/src/model/document_set.ts b/packages/firestore/src/model/document_set.ts index b8a657250f7..1abd3b05a6d 100644 --- a/packages/firestore/src/model/document_set.ts +++ b/packages/firestore/src/model/document_set.ts @@ -120,15 +120,21 @@ export class DocumentSet { } isEqual(other: DocumentSet | null | undefined): boolean { - if (!(other instanceof DocumentSet)) return false; - if (this.size !== other.size) return false; + if (!(other instanceof DocumentSet)) { + return false; + } + if (this.size !== other.size) { + return false; + } const thisIt = this.sortedSet.getIterator(); const otherIt = other.sortedSet.getIterator(); while (thisIt.hasNext()) { const thisDoc = thisIt.getNext().key; const otherDoc = otherIt.getNext().key; - if (!thisDoc.isEqual(otherDoc)) return false; + if (!thisDoc.isEqual(otherDoc)) { + return false; + } } return true; } diff --git a/packages/firestore/src/model/field_value.ts b/packages/firestore/src/model/field_value.ts index ef41f2a545e..18d5e2e1ab6 100644 --- a/packages/firestore/src/model/field_value.ts +++ b/packages/firestore/src/model/field_value.ts @@ -257,10 +257,6 @@ function numericEquals(left: number, right: number): boolean { } export class IntegerValue extends NumberValue { - constructor(internalValue: number) { - super(internalValue); - } - isEqual(other: FieldValue): boolean { // NOTE: DoubleValue and IntegerValue instances may compareTo() the same, // but that doesn't make them equal via isEqual(). @@ -275,10 +271,6 @@ export class IntegerValue extends NumberValue { } export class DoubleValue extends NumberValue { - constructor(readonly internalValue: number) { - super(internalValue); - } - static NAN = new DoubleValue(NaN); static POSITIVE_INFINITY = new DoubleValue(Infinity); static NEGATIVE_INFINITY = new DoubleValue(-Infinity); diff --git a/packages/firestore/src/model/path.ts b/packages/firestore/src/model/path.ts index 6131fd7233a..b351f16d187 100644 --- a/packages/firestore/src/model/path.ts +++ b/packages/firestore/src/model/path.ts @@ -180,11 +180,19 @@ abstract class Path { for (let i = 0; i < len; i++) { const left = p1.get(i); const right = p2.get(i); - if (left < right) return -1; - if (left > right) return 1; + if (left < right) { + return -1; + } + if (left > right) { + return 1; + } + } + if (p1.length < p2.length) { + return -1; + } + if (p1.length > p2.length) { + return 1; } - if (p1.length < p2.length) return -1; - if (p1.length > p2.length) return 1; return 0; } } @@ -288,7 +296,7 @@ export class FieldPath extends Path { let current = ''; let i = 0; - const addCurrentSegment = () => { + const addCurrentSegment = (): void => { if (current.length === 0) { throw new FirestoreError( Code.INVALID_ARGUMENT, diff --git a/packages/firestore/src/platform/config/goog_module_config.ts b/packages/firestore/src/platform/config/goog_module_config.ts index 99fa8dbd1c2..c201da8b074 100644 --- a/packages/firestore/src/platform/config/goog_module_config.ts +++ b/packages/firestore/src/platform/config/goog_module_config.ts @@ -28,8 +28,9 @@ import { configureForStandalone } from '../config'; * Note that name was chosen arbitrarily but was intended to not conflict with * any other variable in scope. */ +// eslint-disable-next-line camelcase declare let __firestore_exports__: { [key: string]: {} }; - +// eslint-disable-next-line camelcase if (typeof __firestore_exports__ !== 'undefined') { configureForStandalone(__firestore_exports__); } else { diff --git a/packages/firestore/src/platform_browser/webchannel_connection.ts b/packages/firestore/src/platform_browser/webchannel_connection.ts index f264d0a4588..aae4f1c27e4 100644 --- a/packages/firestore/src/platform_browser/webchannel_connection.ts +++ b/packages/firestore/src/platform_browser/webchannel_connection.ts @@ -97,7 +97,7 @@ export class WebChannelConnection implements Connection { const url = this.makeUrl(rpcName); return new Promise((resolve: Resolver, reject: Rejecter) => { - // tslint:disable-next-line:no-any XhrIo doesn't have TS typings. + // eslint-disable-next-line @typescript-eslint/no-explicit-any, XhrIo doesn't have TS typings. const xhr: any = new XhrIo(); xhr.listenOnce(EventType.COMPLETE, () => { try { @@ -249,7 +249,7 @@ export class WebChannelConnection implements Connection { const url = urlParts.join(''); log.debug(LOG_TAG, 'Creating WebChannel: ' + url + ' ' + request); - // tslint:disable-next-line:no-any Because listen isn't defined on it. + // eslint-disable-next-line @typescript-eslint/no-explicit-any, Because listen isn't defined on it. const channel = webchannelTransport.createWebChannel(url, request) as any; // WebChannel supports sending the first message with the handshake - saving @@ -288,7 +288,7 @@ export class WebChannelConnection implements Connection { const unguardedEventListen = ( type: WebChannel.EventType, fn: (param?: T) => void - ) => { + ): void => { // TODO(dimond): closure typing seems broken because WebChannel does // not implement goog.events.Listenable channel.listen(type, (param?: T) => { @@ -332,7 +332,9 @@ export class WebChannelConnection implements Connection { // WebChannel delivers message events as array. If batching is not enabled // (it's off by default) each message will be delivered alone, resulting in // a single element array. - type WebChannelResponse = { data: Resp[] }; + interface WebChannelResponse { + data: Resp[]; + } unguardedEventListen( WebChannel.EventType.MESSAGE, @@ -344,7 +346,7 @@ 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. + // eslint-disable-next-line @typescript-eslint/no-explicit-any, msgData.error is not typed. const msgDataAsAny: any = msgData; const error = msgDataAsAny.error || (msgDataAsAny[0] && msgDataAsAny[0].error); diff --git a/packages/firestore/src/platform_node/grpc_connection.ts b/packages/firestore/src/platform_node/grpc_connection.ts index da6b1a7f262..655fd6d1d44 100644 --- a/packages/firestore/src/platform_node/grpc_connection.ts +++ b/packages/firestore/src/platform_node/grpc_connection.ts @@ -20,6 +20,7 @@ import * as grpc from 'grpc'; import firebase from '@firebase/app'; const SDK_VERSION = firebase.SDK_VERSION; +// eslint-disable-next-line @typescript-eslint/no-require-imports const grpcVersion = require('grpc/package.json').version; import { Token } from '../api/credentials'; @@ -72,21 +73,21 @@ function createMetadata( // The type of these stubs is dynamically generated by the GRPC runtime // from the protocol buffer. -// tslint:disable-next-line:no-any +// eslint-disable-next-line @typescript-eslint/no-explicit-any type GeneratedGrpcStub = any; /** * A Connection implemented by GRPC-Node. */ export class GrpcConnection implements Connection { - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any private firestore: any; // We cache stubs for the most-recently-used token. private cachedStub: GeneratedGrpcStub | null = null; constructor(protos: grpc.GrpcObject, private databaseInfo: DatabaseInfo) { - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any this.firestore = (protos as any)['google']['firestore']['v1']; } @@ -186,7 +187,13 @@ export class GrpcConnection implements Connection { const grpcStream = stub[rpcName](metadata); let closed = false; - let close: (err?: FirestoreError) => void; + const close = (err?: FirestoreError): void => { + if (!closed) { + closed = true; + stream.callOnClose(err); + grpcStream.end(); + } + }; const stream = new StreamBridge({ sendFn: (msg: Req) => { @@ -211,14 +218,6 @@ export class GrpcConnection implements Connection { } }); - close = (err?: FirestoreError) => { - if (!closed) { - closed = true; - stream.callOnClose(err); - grpcStream.end(); - } - }; - grpcStream.on('data', (msg: Resp) => { if (!closed) { log.debug(LOG_TAG, 'GRPC stream received:', msg); diff --git a/packages/firestore/src/platform_node/load_protos.ts b/packages/firestore/src/platform_node/load_protos.ts index a3cdfe45ff2..43e28b73605 100644 --- a/packages/firestore/src/platform_node/load_protos.ts +++ b/packages/firestore/src/platform_node/load_protos.ts @@ -18,6 +18,7 @@ import * as protoLoader from '@grpc/proto-loader'; import * as grpc from 'grpc'; import * as path from 'path'; +// eslint-disable-next-line import/no-extraneous-dependencies, only used in tests import * as ProtobufJS from 'protobufjs'; /** Used by tests so we can match @grpc/proto-loader behavior. */ diff --git a/packages/firestore/src/protos/firestore_proto_api.d.ts b/packages/firestore/src/protos/firestore_proto_api.d.ts index e2b6e57084f..d7255a6e4a4 100644 --- a/packages/firestore/src/protos/firestore_proto_api.d.ts +++ b/packages/firestore/src/protos/firestore_proto_api.d.ts @@ -16,7 +16,11 @@ */ // Rather than pull these in from other protos, we just alias them to any. -// tslint:disable:no-any +/* + eslint-disable + camelcase, @typescript-eslint/no-explicit-any, + @typescript-eslint/interface-name-prefix, @typescript-eslint/class-name-casing +*/ export declare type ApiClientHookFactory = any; export declare type ApiClientObjectMap = any; export declare type PromiseRequestService = any; @@ -25,7 +29,7 @@ export declare type CompositeFilterOp = 'OPERATOR_UNSPECIFIED' | 'AND'; export interface ICompositeFilterOpEnum { OPERATOR_UNSPECIFIED: CompositeFilterOp; AND: CompositeFilterOp; - values(): Array; + values(): CompositeFilterOp[]; } export declare const CompositeFilterOpEnum: ICompositeFilterOpEnum; export declare type FieldFilterOp = @@ -48,7 +52,7 @@ export interface IFieldFilterOpEnum { ARRAY_CONTAINS: FieldFilterOp; IN: FieldFilterOp; ARRAY_CONTAINS_ANY: FieldFilterOp; - values(): Array; + values(): FieldFilterOp[]; } export declare const FieldFilterOpEnum: IFieldFilterOpEnum; export declare type FieldTransformSetToServerValue = @@ -57,7 +61,7 @@ export declare type FieldTransformSetToServerValue = export interface IFieldTransformSetToServerValueEnum { SERVER_VALUE_UNSPECIFIED: FieldTransformSetToServerValue; REQUEST_TIME: FieldTransformSetToServerValue; - values(): Array; + values(): FieldTransformSetToServerValue[]; } export declare const FieldTransformSetToServerValueEnum: IFieldTransformSetToServerValueEnum; export declare type IndexFieldMode = @@ -68,7 +72,7 @@ export interface IIndexFieldModeEnum { MODE_UNSPECIFIED: IndexFieldMode; ASCENDING: IndexFieldMode; DESCENDING: IndexFieldMode; - values(): Array; + values(): IndexFieldMode[]; } export declare const IndexFieldModeEnum: IIndexFieldModeEnum; export declare type IndexState = @@ -81,7 +85,7 @@ export interface IIndexStateEnum { CREATING: IndexState; READY: IndexState; ERROR: IndexState; - values(): Array; + values(): IndexState[]; } export declare const IndexStateEnum: IIndexStateEnum; export declare type OrderDirection = @@ -92,7 +96,7 @@ export interface IOrderDirectionEnum { DIRECTION_UNSPECIFIED: OrderDirection; ASCENDING: OrderDirection; DESCENDING: OrderDirection; - values(): Array; + values(): OrderDirection[]; } export declare const OrderDirectionEnum: IOrderDirectionEnum; export declare type TargetChangeTargetChangeType = @@ -107,7 +111,7 @@ export interface ITargetChangeTargetChangeTypeEnum { REMOVE: TargetChangeTargetChangeType; CURRENT: TargetChangeTargetChangeType; RESET: TargetChangeTargetChangeType; - values(): Array; + values(): TargetChangeTargetChangeType[]; } export declare const TargetChangeTargetChangeTypeEnum: ITargetChangeTargetChangeTypeEnum; export declare type UnaryFilterOp = @@ -118,21 +122,21 @@ export interface IUnaryFilterOpEnum { OPERATOR_UNSPECIFIED: UnaryFilterOp; IS_NAN: UnaryFilterOp; IS_NULL: UnaryFilterOp; - values(): Array; + values(): UnaryFilterOp[]; } export declare const UnaryFilterOpEnum: IUnaryFilterOpEnum; export declare type ValueNullValue = 'NULL_VALUE'; export interface IValueNullValueEnum { NULL_VALUE: ValueNullValue; - values(): Array; + values(): ValueNullValue[]; } export declare const ValueNullValueEnum: IValueNullValueEnum; export declare namespace firestoreV1ApiClientInterfaces { interface ArrayValue { - values?: Array; + values?: Value[]; } interface BatchGetDocumentsRequest { - documents?: Array; + documents?: string[]; mask?: DocumentMask; transaction?: string; newTransaction?: TransactionOptions; @@ -155,19 +159,19 @@ export declare namespace firestoreV1ApiClientInterfaces { allDescendants?: boolean; } interface CommitRequest { - writes?: Array; + writes?: Write[]; transaction?: string; } interface CommitResponse { - writeResults?: Array; + writeResults?: WriteResult[]; commitTime?: string; } interface CompositeFilter { op?: CompositeFilterOp; - filters?: Array; + filters?: Filter[]; } interface Cursor { - values?: Array; + values?: Value[]; before?: boolean; } interface Document { @@ -178,28 +182,28 @@ export declare namespace firestoreV1ApiClientInterfaces { } interface DocumentChange { document?: Document; - targetIds?: Array; - removedTargetIds?: Array; + targetIds?: number[]; + removedTargetIds?: number[]; } interface DocumentDelete { document?: string; - removedTargetIds?: Array; + removedTargetIds?: number[]; readTime?: string; } interface DocumentMask { - fieldPaths?: Array; + fieldPaths?: string[]; } interface DocumentRemove { document?: string; - removedTargetIds?: Array; + removedTargetIds?: number[]; readTime?: string; } interface DocumentTransform { document?: string; - fieldTransforms?: Array; + fieldTransforms?: FieldTransform[]; } interface DocumentsTarget { - documents?: Array; + documents?: string[]; } interface Empty {} interface ExistenceFilter { @@ -229,7 +233,7 @@ export declare namespace firestoreV1ApiClientInterfaces { interface Index { name?: string; collectionId?: string; - fields?: Array; + fields?: IndexField[]; state?: IndexState; } interface IndexField { @@ -245,15 +249,15 @@ export declare namespace firestoreV1ApiClientInterfaces { pageToken?: string; } interface ListCollectionIdsResponse { - collectionIds?: Array; + collectionIds?: string[]; nextPageToken?: string; } interface ListDocumentsResponse { - documents?: Array; + documents?: Document[]; nextPageToken?: string; } interface ListIndexesResponse { - indexes?: Array; + indexes?: Index[]; nextPageToken?: string; } interface ListenRequest { @@ -287,7 +291,7 @@ export declare namespace firestoreV1ApiClientInterfaces { updateTime?: string; } interface Projection { - fields?: Array; + fields?: FieldReference[]; } interface QueryTarget { parent?: string; @@ -321,9 +325,9 @@ export declare namespace firestoreV1ApiClientInterfaces { } interface StructuredQuery { select?: Projection; - from?: Array; + from?: CollectionSelector[]; where?: Filter; - orderBy?: Array; + orderBy?: Order[]; startAt?: Cursor; endAt?: Cursor; offset?: number; @@ -339,7 +343,7 @@ export declare namespace firestoreV1ApiClientInterfaces { } interface TargetChange { targetChangeType?: TargetChangeTargetChangeType; - targetIds?: Array; + targetIds?: number[]; cause?: Status; resumeToken?: string; readTime?: string; @@ -374,19 +378,19 @@ export declare namespace firestoreV1ApiClientInterfaces { } interface WriteRequest { streamId?: string; - writes?: Array; + writes?: Write[]; streamToken?: string; labels?: ApiClientObjectMap; } interface WriteResponse { streamId?: string; streamToken?: string; - writeResults?: Array; + writeResults?: WriteResult[]; commitTime?: string; } interface WriteResult { updateTime?: string; - transformResults?: Array; + transformResults?: Value[]; } } export declare type ArrayValue = firestoreV1ApiClientInterfaces.ArrayValue; @@ -447,7 +451,7 @@ export declare type ProjectsDatabasesDocumentsApiClient$Xgafv = '1' | '2'; export interface IProjectsDatabasesDocumentsApiClient$XgafvEnum { 1: ProjectsDatabasesDocumentsApiClient$Xgafv; 2: ProjectsDatabasesDocumentsApiClient$Xgafv; - values(): Array; + values(): ProjectsDatabasesDocumentsApiClient$Xgafv[]; } export declare const ProjectsDatabasesDocumentsApiClient$XgafvEnum: IProjectsDatabasesDocumentsApiClient$XgafvEnum; export declare type ProjectsDatabasesDocumentsApiClientAlt = @@ -458,7 +462,7 @@ export interface IProjectsDatabasesDocumentsApiClientAltEnum { JSON: ProjectsDatabasesDocumentsApiClientAlt; MEDIA: ProjectsDatabasesDocumentsApiClientAlt; PROTO: ProjectsDatabasesDocumentsApiClientAlt; - values(): Array; + values(): ProjectsDatabasesDocumentsApiClientAlt[]; } export declare const ProjectsDatabasesDocumentsApiClientAltEnum: IProjectsDatabasesDocumentsApiClientAltEnum; export interface ProjectsDatabasesDocumentsBatchGetNamedParameters { @@ -521,7 +525,7 @@ export interface ProjectsDatabasesDocumentsCreateDocumentNamedParameters { uploadType?: string; $Xgafv?: ProjectsDatabasesDocumentsApiClient$Xgafv; documentId?: string; - maskFieldPaths?: Array; + maskFieldPaths?: string[]; } export interface ProjectsDatabasesDocumentsDeleteNamedParameters { access_token?: string; @@ -554,7 +558,7 @@ export interface ProjectsDatabasesDocumentsGetNamedParameters { upload_protocol?: string; uploadType?: string; $Xgafv?: ProjectsDatabasesDocumentsApiClient$Xgafv; - maskFieldPaths?: Array; + maskFieldPaths?: string[]; transaction?: string; readTime?: string; } @@ -590,7 +594,7 @@ export interface ProjectsDatabasesDocumentsListNamedParameters { pageSize?: number; pageToken?: string; orderBy?: string; - maskFieldPaths?: Array; + maskFieldPaths?: string[]; transaction?: string; readTime?: string; showMissing?: boolean; @@ -624,8 +628,8 @@ export interface ProjectsDatabasesDocumentsPatchNamedParameters { upload_protocol?: string; uploadType?: string; $Xgafv?: ProjectsDatabasesDocumentsApiClient$Xgafv; - updateMaskFieldPaths?: Array; - maskFieldPaths?: Array; + updateMaskFieldPaths?: string[]; + maskFieldPaths?: string[]; currentDocumentExists?: boolean; currentDocumentUpdateTime?: string; } @@ -1022,7 +1026,7 @@ export declare type ProjectsDatabasesIndexesApiClient$Xgafv = '1' | '2'; export interface IProjectsDatabasesIndexesApiClient$XgafvEnum { 1: ProjectsDatabasesIndexesApiClient$Xgafv; 2: ProjectsDatabasesIndexesApiClient$Xgafv; - values(): Array; + values(): ProjectsDatabasesIndexesApiClient$Xgafv[]; } export declare const ProjectsDatabasesIndexesApiClient$XgafvEnum: IProjectsDatabasesIndexesApiClient$XgafvEnum; export declare type ProjectsDatabasesIndexesApiClientAlt = @@ -1033,7 +1037,7 @@ export interface IProjectsDatabasesIndexesApiClientAltEnum { JSON: ProjectsDatabasesIndexesApiClientAlt; MEDIA: ProjectsDatabasesIndexesApiClientAlt; PROTO: ProjectsDatabasesIndexesApiClientAlt; - values(): Array; + values(): ProjectsDatabasesIndexesApiClientAlt[]; } export declare const ProjectsDatabasesIndexesApiClientAltEnum: IProjectsDatabasesIndexesApiClientAltEnum; export interface ProjectsDatabasesIndexesCreateNamedParameters { diff --git a/packages/firestore/src/remote/datastore.ts b/packages/firestore/src/remote/datastore.ts index 30bdc9db165..d5623b71dd1 100644 --- a/packages/firestore/src/remote/datastore.ts +++ b/packages/firestore/src/remote/datastore.ts @@ -25,11 +25,13 @@ import { assert } from '../util/assert'; import { AsyncQueue } from '../util/async_queue'; import { Code, FirestoreError } from '../util/error'; import { Connection } from './connection'; -import { WatchStreamListener, WriteStreamListener } from './persistent_stream'; import { + WatchStreamListener, + WriteStreamListener, PersistentListenStream, PersistentWriteStream } from './persistent_stream'; + import { JsonProtoSerializer } from './serializer'; // The generated proto interfaces for these class are missing the database diff --git a/packages/firestore/src/remote/persistent_stream.ts b/packages/firestore/src/remote/persistent_stream.ts index 24738f0c027..d8cf760d0fd 100644 --- a/packages/firestore/src/remote/persistent_stream.ts +++ b/packages/firestore/src/remote/persistent_stream.ts @@ -770,7 +770,7 @@ export class PersistentWriteStream extends PersistentStream< const request: WriteRequest = { // Protos are typed with string, but we support UInt8Array on Node - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any streamToken: this.lastStreamToken as any, writes: mutations.map(mutation => this.serializer.toMutation(mutation)) }; diff --git a/packages/firestore/src/remote/rpc_error.ts b/packages/firestore/src/remote/rpc_error.ts index 66a1beaf7f9..e28cd66de69 100644 --- a/packages/firestore/src/remote/rpc_error.ts +++ b/packages/firestore/src/remote/rpc_error.ts @@ -110,7 +110,7 @@ export function isPermanentWriteError(code: Code): boolean { * there is no match. */ export function mapCodeFromRpcStatus(status: string): Code | undefined { - // tslint:disable-next-line:no-any lookup by string + // eslint-disable-next-line @typescript-eslint/no-explicit-any, lookup by string const code: RpcCode = RpcCode[status as any] as any; if (code === undefined) { return undefined; @@ -286,9 +286,15 @@ export function mapCodeFromHttpStatus(status: number): Code { return Code.DEADLINE_EXCEEDED; default: - if (status >= 200 && status < 300) return Code.OK; - if (status >= 400 && status < 500) return Code.FAILED_PRECONDITION; - if (status >= 500 && status < 600) return Code.INTERNAL; + if (status >= 200 && status < 300) { + return Code.OK; + } + if (status >= 400 && status < 500) { + return Code.FAILED_PRECONDITION; + } + if (status >= 500 && status < 600) { + return Code.INTERNAL; + } return Code.UNKNOWN; } } diff --git a/packages/firestore/src/remote/serializer.ts b/packages/firestore/src/remote/serializer.ts index 307b84bab9e..0d5aa0e89b7 100644 --- a/packages/firestore/src/remote/serializer.ts +++ b/packages/firestore/src/remote/serializer.ts @@ -52,7 +52,6 @@ import { Code, FirestoreError } from '../util/error'; import * as obj from '../util/obj'; import * as typeUtils from '../util/types'; -import { DoubleValue, NullValue, NumberValue } from '../model/field_value'; import { ArrayRemoveTransformOperation, ArrayUnionTransformOperation, @@ -60,7 +59,6 @@ import { ServerTimestampTransform, TransformOperation } from '../model/transform_operation'; -import { ApiClientObjectMap } from '../protos/firestore_proto_api'; import { ExistenceFilter } from './existence_filter'; import { mapCodeFromRpcCode, mapRpcCodeFromCode } from './rpc_error'; import { @@ -171,7 +169,7 @@ export class JsonProtoSerializer { */ private toInt32Value(val: number | null): number | undefined { if (!typeUtils.isNullOrUndefined(val)) { - // tslint:disable-next-line:no-any We need to match generated Proto types. + // eslint-disable-next-line @typescript-eslint/no-explicit-any, We need to match generated Proto types. return { value: val } as any; } else { return undefined; @@ -188,7 +186,7 @@ export class JsonProtoSerializer { private fromInt32Value(val: number | undefined): number | null { let result; if (typeof val === 'object') { - // tslint:disable-next-line:no-any We need to match generated Proto types. + // eslint-disable-next-line @typescript-eslint/no-explicit-any, We need to match generated Proto types. result = (val as any).value; } else { // We accept raw numbers (without the {value: ... } wrapper) for @@ -209,7 +207,7 @@ export class JsonProtoSerializer { return { seconds: '' + timestamp.seconds, nanos: timestamp.nanoseconds - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any; } @@ -979,11 +977,11 @@ export class JsonProtoSerializer { } else if ('increment' in proto) { const operand = this.fromValue(proto.increment!); assert( - operand instanceof NumberValue, + operand instanceof fieldValue.NumberValue, 'NUMERIC_ADD transform requires a NumberValue' ); transform = new NumericIncrementTransformOperation( - operand as NumberValue + operand as fieldValue.NumberValue ); } else { fail('Unknown transform proto: ' + JSON.stringify(proto)); @@ -1113,7 +1111,7 @@ export class JsonProtoSerializer { toListenRequestLabels( queryData: QueryData - ): ApiClientObjectMap | null { + ): api.ApiClientObjectMap | null { const value = this.toLabel(queryData.purpose); if (value == null) { return null; @@ -1159,7 +1157,9 @@ export class JsonProtoSerializer { } private toFilter(filters: Filter[]): api.Filter | undefined { - if (filters.length === 0) return; + if (filters.length === 0) { + return; + } const protos = filters.map(filter => { if (filter instanceof FieldFilter) { return this.toUnaryOrFieldFilter(filter); @@ -1190,7 +1190,9 @@ export class JsonProtoSerializer { } private toOrder(orderBys: OrderBy[]): api.Order[] | undefined { - if (orderBys.length === 0) return; + if (orderBys.length === 0) { + return; + } return orderBys.map(order => this.toPropertyOrder(order)); } @@ -1292,14 +1294,14 @@ export class JsonProtoSerializer { // visible for testing toUnaryOrFieldFilter(filter: FieldFilter): api.Filter { if (filter.op === Operator.EQUAL) { - if (filter.value.isEqual(DoubleValue.NAN)) { + if (filter.value.isEqual(fieldValue.DoubleValue.NAN)) { return { unaryFilter: { field: this.toFieldPathReference(filter.field), op: 'IS_NAN' } }; - } else if (filter.value.isEqual(NullValue.INSTANCE)) { + } else if (filter.value.isEqual(fieldValue.NullValue.INSTANCE)) { return { unaryFilter: { field: this.toFieldPathReference(filter.field), @@ -1323,7 +1325,11 @@ export class JsonProtoSerializer { const nanField = this.fromFieldPathReference( filter.unaryFilter!.field! ); - return FieldFilter.create(nanField, Operator.EQUAL, DoubleValue.NAN); + return FieldFilter.create( + nanField, + Operator.EQUAL, + fieldValue.DoubleValue.NAN + ); case 'IS_NULL': const nullField = this.fromFieldPathReference( filter.unaryFilter!.field! @@ -1331,7 +1337,7 @@ export class JsonProtoSerializer { return FieldFilter.create( nullField, Operator.EQUAL, - NullValue.INSTANCE + fieldValue.NullValue.INSTANCE ); case 'OPERATOR_UNSPECIFIED': return fail('Unspecified filter'); diff --git a/packages/firestore/src/util/api.ts b/packages/firestore/src/util/api.ts index ea409fe1e4e..f1f61e5a7b2 100644 --- a/packages/firestore/src/util/api.ts +++ b/packages/firestore/src/util/api.ts @@ -15,9 +15,6 @@ * limitations under the License. */ -// We are doing some heavy reflective stuff, lots of any casting necessary -/* tslint:disable:no-any */ - import { Code, FirestoreError } from './error'; /** @@ -31,7 +28,10 @@ import { Code, FirestoreError } from './error'; * To also make all the static methods available, all properties of the * original constructor are copied to the new constructor. */ -export function makeConstructorPrivate(cls: T, optionalMessage?: string): T { +export function makeConstructorPrivate( + cls: T, + optionalMessage?: string +): T { function PublicConstructor(): never { let error = 'This constructor is private.'; if (optionalMessage) { @@ -43,14 +43,15 @@ export function makeConstructorPrivate(cls: T, optionalMessage?: string): T { // Make sure instanceof checks work and all methods are exposed on the public // constructor - PublicConstructor.prototype = (cls as any).prototype; + PublicConstructor.prototype = cls.prototype; // Copy any static methods/members for (const staticProperty in cls) { if (cls.hasOwnProperty(staticProperty)) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any (PublicConstructor as any)[staticProperty] = (cls as any)[staticProperty]; } } - + // eslint-disable-next-line @typescript-eslint/no-explicit-any return PublicConstructor as any; } diff --git a/packages/firestore/src/util/array.ts b/packages/firestore/src/util/array.ts index 151b727416d..125de6834da 100644 --- a/packages/firestore/src/util/array.ts +++ b/packages/firestore/src/util/array.ts @@ -20,7 +20,9 @@ */ export function includes(array: T[], value: T): boolean { for (let i = 0; i < array.length; i++) { - if (array[i] === value) return true; + if (array[i] === value) { + return true; + } } return false; } @@ -30,7 +32,9 @@ export function includes(array: T[], value: T): boolean { */ export function some(array: T[], predicate: (t: T) => boolean): boolean { for (let i = 0; i < array.length; i++) { - if (predicate(array[i])) return true; + if (predicate(array[i])) { + return true; + } } return false; } diff --git a/packages/firestore/src/util/async_queue.ts b/packages/firestore/src/util/async_queue.ts index 6b4b4bb3970..5483100b893 100644 --- a/packages/firestore/src/util/async_queue.ts +++ b/packages/firestore/src/util/async_queue.ts @@ -20,7 +20,7 @@ import { Code, FirestoreError } from './error'; import * as log from './log'; import { CancelablePromise, Deferred } from './promise'; -// tslint:disable-next-line:no-any Accept any return type from setTimeout(). +// eslint-disable-next-line @typescript-eslint/no-explicit-any, Accept any return type from setTimeout(). type TimerHandle = any; /** diff --git a/packages/firestore/src/util/error.ts b/packages/firestore/src/util/error.ts index aa9914c108f..384b1322108 100644 --- a/packages/firestore/src/util/error.ts +++ b/packages/firestore/src/util/error.ts @@ -24,7 +24,6 @@ import * as firestore from '@firebase/firestore-types'; export type Code = firestore.FirestoreErrorCode; // TODO(mcg): Change to a string enum once we've upgraded to typescript 2.4. -// tslint:disable-next-line:variable-name Intended to look like a TS 2.4 enum export const Code = { // Causes are copied from: // https://github.com/grpc/grpc/blob/bceec94ea4fc5f0085d81235d8e1c06798dc341a/include/grpc%2B%2B/impl/codegen/status_code_enum.h diff --git a/packages/firestore/src/util/log.ts b/packages/firestore/src/util/log.ts index 066b1f4853b..124a9a73735 100644 --- a/packages/firestore/src/util/log.ts +++ b/packages/firestore/src/util/log.ts @@ -15,8 +15,6 @@ * limitations under the License. */ -/* tslint:disable:no-console */ - import { Logger, LogLevel as FirebaseLogLevel } from '@firebase/logger'; import { SDK_VERSION } from '../core/version'; import { PlatformSupport } from '../platform/platform'; diff --git a/packages/firestore/src/util/misc.ts b/packages/firestore/src/util/misc.ts index ca2750757bb..6e9cf71da78 100644 --- a/packages/firestore/src/util/misc.ts +++ b/packages/firestore/src/util/misc.ts @@ -18,9 +18,10 @@ import { assert } from './assert'; export type EventHandler = (value: E) => void; -export type Indexable = { [k: string]: unknown }; +export interface Indexable { + [k: string]: unknown; +} -// tslint:disable-next-line:class-as-namespace export class AutoId { static newId(): string { // Alphanumeric characters @@ -36,8 +37,12 @@ export class AutoId { } export function primitiveComparator(left: T, right: T): number { - if (left < right) return -1; - if (left > right) return 1; + if (left < right) { + return -1; + } + if (left > right) { + return 1; + } return 0; } diff --git a/packages/firestore/src/util/sorted_map.ts b/packages/firestore/src/util/sorted_map.ts index 98ad92b1f69..93f9a05e655 100644 --- a/packages/firestore/src/util/sorted_map.ts +++ b/packages/firestore/src/util/sorted_map.ts @@ -197,7 +197,9 @@ export class SortedMapIterator { while (!node.isEmpty()) { cmp = startKey ? comparator(node.key, startKey) : 1; // flip the comparison if we're going in reverse - if (isReverse) cmp *= -1; + if (isReverse) { + cmp *= -1; + } if (cmp < 0) { // This node is less than our start key. ignore it @@ -255,7 +257,9 @@ export class SortedMapIterator { } peek(): Entry | null { - if (this.nodeStack.length === 0) return null; + if (this.nodeStack.length === 0) { + return null; + } const node = this.nodeStack[this.nodeStack.length - 1]; return { key: node.key, value: node.value }; @@ -269,7 +273,7 @@ export class LLRBNode { readonly right: LLRBNode | LLRBEmptyNode; readonly size: number; - // tslint:disable-next-line:no-any Empty node is shared between all LLRB trees. + // eslint-disable-next-line @typescript-eslint/no-explicit-any, Empty node is shared between all LLRB trees. static EMPTY: LLRBEmptyNode = null as any; static RED = true; @@ -381,7 +385,9 @@ export class LLRBNode { return LLRBNode.EMPTY; } let n: LLRBNode = this; - if (!n.left.isRed() && !n.left.left.isRed()) n = n.moveRedLeft(); + if (!n.left.isRed() && !n.left.left.isRed()) { + n = n.moveRedLeft(); + } n = n.copy(null, null, null, (n.left as LLRBNode).removeMin(), null); return n.fixUp(); } @@ -399,7 +405,9 @@ export class LLRBNode { } n = n.copy(null, null, null, n.left.remove(key, comparator), null); } else { - if (n.left.isRed()) n = n.rotateRight(); + if (n.left.isRed()) { + n = n.rotateRight(); + } if (!n.right.isEmpty() && !n.right.isRed() && !n.right.left.isRed()) { n = n.moveRedRight(); } @@ -429,9 +437,15 @@ export class LLRBNode { // Returns new tree after performing any needed rotations. private fixUp(): LLRBNode { let n: LLRBNode = this; - if (n.right.isRed() && !n.left.isRed()) n = n.rotateLeft(); - if (n.left.isRed() && n.left.left.isRed()) n = n.rotateRight(); - if (n.left.isRed() && n.right.isRed()) n = n.colorFlip(); + if (n.right.isRed() && !n.left.isRed()) { + n = n.rotateLeft(); + } + if (n.left.isRed() && n.left.left.isRed()) { + n = n.rotateRight(); + } + if (n.left.isRed() && n.right.isRed()) { + n = n.colorFlip(); + } return n; } @@ -519,8 +533,6 @@ export class LLRBEmptyNode { right: LLRBNode; size = 0; - constructor() {} - // Returns a copy of the current node. copy( key: K | null, diff --git a/packages/firestore/src/util/sorted_set.ts b/packages/firestore/src/util/sorted_set.ts index d49cf56f473..dc788079b55 100644 --- a/packages/firestore/src/util/sorted_set.ts +++ b/packages/firestore/src/util/sorted_set.ts @@ -76,7 +76,9 @@ export class SortedSet { const iter = this.data.getIteratorFrom(range[0]); while (iter.hasNext()) { const elem = iter.getNext(); - if (this.comparator(elem.key, range[1]) >= 0) return; + if (this.comparator(elem.key, range[1]) >= 0) { + return; + } cb(elem.key); } } @@ -94,7 +96,9 @@ export class SortedSet { while (iter.hasNext()) { const elem = iter.getNext(); const result = cb(elem.key); - if (!result) return; + if (!result) { + return; + } } } @@ -119,7 +123,9 @@ export class SortedSet { /** Deletes an element */ delete(elem: T): SortedSet { - if (!this.has(elem)) return this; + if (!this.has(elem)) { + return this; + } return this.copy(this.data.remove(elem)); } @@ -136,15 +142,21 @@ export class SortedSet { } isEqual(other: SortedSet): boolean { - if (!(other instanceof SortedSet)) return false; - if (this.size !== other.size) return false; + if (!(other instanceof SortedSet)) { + return false; + } + if (this.size !== other.size) { + return false; + } const thisIt = this.data.getIterator(); const otherIt = other.data.getIterator(); while (thisIt.hasNext()) { const thisElem = thisIt.getNext().key; const otherElem = otherIt.getNext().key; - if (this.comparator(thisElem, otherElem) !== 0) return false; + if (this.comparator(thisElem, otherElem) !== 0) { + return false; + } } return true; } diff --git a/packages/firestore/src/util/types.ts b/packages/firestore/src/util/types.ts index 84640733340..13f6b1ebd67 100644 --- a/packages/firestore/src/util/types.ts +++ b/packages/firestore/src/util/types.ts @@ -16,24 +16,26 @@ */ // Untyped Number alias we can use to check for ES6 methods / properties. -// tslint:disable-next-line:no-any variable-name +// eslint-disable-next-line @typescript-eslint/no-explicit-any const NumberAsAny = Number as any; // An Object whose keys and values are strings. -export type StringMap = { [key: string]: string }; +export interface StringMap { + [key: string]: string; +} /** * Minimum safe integer in Javascript because of floating point precision. * Added to not rely on ES6 features. */ -export let MIN_SAFE_INTEGER: number = +export const MIN_SAFE_INTEGER: number = NumberAsAny.MIN_SAFE_INTEGER || -(Math.pow(2, 53) - 1); /** * Maximum safe integer in Javascript because of floating point precision. * Added to not rely on ES6 features. */ -export let MAX_SAFE_INTEGER: number = +export const MAX_SAFE_INTEGER: number = NumberAsAny.MAX_SAFE_INTEGER || Math.pow(2, 53) - 1; /** @@ -42,7 +44,7 @@ export let MAX_SAFE_INTEGER: number = * Added to not rely on ES6 features. * @param value The value to test for being an integer */ -export let isInteger: (value: unknown) => boolean = +export const isInteger: (value: unknown) => boolean = NumberAsAny.isInteger || (value => typeof value === 'number' && diff --git a/packages/firestore/test/integration/api/batch_writes.test.ts b/packages/firestore/test/integration/api/batch_writes.test.ts index 88e21abff5e..438ad60cbf1 100644 --- a/packages/firestore/test/integration/api/batch_writes.test.ts +++ b/packages/firestore/test/integration/api/batch_writes.test.ts @@ -22,6 +22,8 @@ import { EventsAccumulator } from '../util/events_accumulator'; import firebase from '../util/firebase_export'; import * as integrationHelpers from '../util/helpers'; +// tslint:disable:no-floating-promises + const apiDescribe = integrationHelpers.apiDescribe; const Timestamp = firebase.firestore!.Timestamp; const FieldValue = firebase.firestore!.FieldValue; diff --git a/packages/firestore/test/integration/api/cursor.test.ts b/packages/firestore/test/integration/api/cursor.test.ts index bdc975997ba..2706c2894c7 100644 --- a/packages/firestore/test/integration/api/cursor.test.ts +++ b/packages/firestore/test/integration/api/cursor.test.ts @@ -26,6 +26,7 @@ import { withTestDb, withTestDbs } from '../util/helpers'; +import { Timestamp as TimestampInstance } from '@firebase/firestore-types'; const Timestamp = firebase.firestore!.Timestamp; const FieldPath = firebase.firestore!.FieldPath; @@ -242,7 +243,7 @@ apiDescribe('Cursors', (persistence: boolean) => { // Currently, timestamps are truncated to microseconds on the backend, so // don't create timestamps with more precision than that. - const makeTimestamp = (seconds: number, micros: number) => + const makeTimestamp = (seconds: number, micros: number): TimestampInstance => new Timestamp(seconds, micros * 1000); it('can accept Timestamps as bounds', () => { diff --git a/packages/firestore/test/integration/api/database.test.ts b/packages/firestore/test/integration/api/database.test.ts index a33b1af0120..dd1b8d276a9 100644 --- a/packages/firestore/test/integration/api/database.test.ts +++ b/packages/firestore/test/integration/api/database.test.ts @@ -15,11 +15,10 @@ * limitations under the License. */ -import * as chai from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; import * as firestore from '@firebase/firestore-types'; -import { expect } from 'chai'; +import { expect, use } from 'chai'; import { SimpleDb } from '../../../src/local/simple_db'; import { fail } from '../../../src/util/assert'; @@ -39,7 +38,9 @@ import { withTestDocAndInitialData } from '../util/helpers'; -chai.use(chaiAsPromised); +// tslint:disable:no-floating-promises + +use(chaiAsPromised); const Timestamp = firebase.firestore!.Timestamp; const FieldValue = firebase.firestore!.FieldValue; @@ -516,9 +517,9 @@ apiDescribe('Database', (persistence: boolean) => { for (const val of invalidDocValues) { it('set/update should reject: ' + val, () => { return withTestDoc(persistence, async doc => { - // tslint:disable-next-line:no-any Intentionally passing bad types. + // eslint-disable-next-line @typescript-eslint/no-explicit-any, Intentionally passing bad types. expect(() => doc.set(val as any)).to.throw(); - // tslint:disable-next-line:no-any Intentionally passing bad types. + // eslint-disable-next-line @typescript-eslint/no-explicit-any, Intentionally passing bad types. expect(() => doc.update(val as any)).to.throw(); }); }); diff --git a/packages/firestore/test/integration/api/fields.test.ts b/packages/firestore/test/integration/api/fields.test.ts index e489761e0ba..d249a21a06f 100644 --- a/packages/firestore/test/integration/api/fields.test.ts +++ b/packages/firestore/test/integration/api/fields.test.ts @@ -16,8 +16,7 @@ */ import { expect } from 'chai'; -import * as log from '../../../src/util/log'; -import { LogLevel } from '../../../src/util/log'; +import { LogLevel, getLogLevel, setLogLevel } from '../../../src/util/log'; import firebase from '../util/firebase_export'; import { apiDescribe, @@ -32,7 +31,7 @@ const FieldPath = firebase.firestore!.FieldPath; const FieldValue = firebase.firestore!.FieldValue; const Timestamp = firebase.firestore!.Timestamp; -// tslint:disable-next-line:no-any Allow custom types for testing. +// eslint-disable-next-line @typescript-eslint/no-explicit-any, Allow custom types for testing. type AnyTestData = any; apiDescribe('Nested Fields', (persistence: boolean) => { @@ -347,7 +346,7 @@ apiDescribe('Fields with special characters', (persistence: boolean) => { }); apiDescribe('Timestamp Fields in snapshots', (persistence: boolean) => { - // tslint:disable-next-line:no-any Figure out how to pass in the Timestamp type + // eslint-disable-next-line @typescript-eslint/no-explicit-any, Figure out how to pass in the Timestamp type const testDataWithTimestamps = (ts: any): AnyTestData => { return { timestamp: ts, nested: { timestamp2: ts } }; }; @@ -355,8 +354,8 @@ apiDescribe('Timestamp Fields in snapshots', (persistence: boolean) => { it('are returned as native dates if timestampsInSnapshots set to false', () => { // Avoid the verbose log message triggered by timestampsInSnapshots == // false. - const logLevel = log.getLogLevel(); - log.setLogLevel(LogLevel.SILENT); + const logLevel = getLogLevel(); + setLogLevel(LogLevel.SILENT); const settings = { ...DEFAULT_SETTINGS }; settings['timestampsInSnapshots'] = false; @@ -364,7 +363,7 @@ apiDescribe('Timestamp Fields in snapshots', (persistence: boolean) => { const timestamp = new Timestamp(100, 123456789); const testDocs = { a: testDataWithTimestamps(timestamp) }; return withTestCollectionSettings(persistence, settings, testDocs, coll => { - log.setLogLevel(logLevel); + setLogLevel(logLevel); return coll .doc('a') .get() @@ -419,8 +418,8 @@ apiDescribe('Timestamp Fields in snapshots', (persistence: boolean) => { }); it('timestampsInSnapshots affects server timestamps', () => { - const logLevel = log.getLogLevel(); - log.setLogLevel(LogLevel.SILENT); + const logLevel = getLogLevel(); + setLogLevel(LogLevel.SILENT); const settings = { ...DEFAULT_SETTINGS }; settings['timestampsInSnapshots'] = false; @@ -429,7 +428,7 @@ apiDescribe('Timestamp Fields in snapshots', (persistence: boolean) => { }; return withTestCollectionSettings(persistence, settings, testDocs, coll => { - log.setLogLevel(logLevel); + setLogLevel(logLevel); return coll .doc('a') .get() diff --git a/packages/firestore/test/integration/api/get_options.test.ts b/packages/firestore/test/integration/api/get_options.test.ts index 78b349a4f8e..e5624826fbd 100644 --- a/packages/firestore/test/integration/api/get_options.test.ts +++ b/packages/firestore/test/integration/api/get_options.test.ts @@ -23,6 +23,8 @@ import { withTestDocAndInitialData } from '../util/helpers'; +// tslint:disable:no-floating-promises + apiDescribe('GetOptions', (persistence: boolean) => { it('get document while online with default get options', () => { const initialData = { key: 'value' }; diff --git a/packages/firestore/test/integration/api/numeric_transforms.test.ts b/packages/firestore/test/integration/api/numeric_transforms.test.ts index dc522ac8287..d85f677d1ac 100644 --- a/packages/firestore/test/integration/api/numeric_transforms.test.ts +++ b/packages/firestore/test/integration/api/numeric_transforms.test.ts @@ -22,6 +22,8 @@ import { EventsAccumulator } from '../util/events_accumulator'; import firebase from '../util/firebase_export'; import { apiDescribe, withTestDoc } from '../util/helpers'; +// tslint:disable:no-floating-promises + // tslint:disable-next-line:variable-name Type alias can be capitalized. const FieldValue = firebase.firestore!.FieldValue; diff --git a/packages/firestore/test/integration/api/query.test.ts b/packages/firestore/test/integration/api/query.test.ts index fc107288f74..5040b6188df 100644 --- a/packages/firestore/test/integration/api/query.test.ts +++ b/packages/firestore/test/integration/api/query.test.ts @@ -35,6 +35,8 @@ import { withTestDb } from '../util/helpers'; +// tslint:disable:no-floating-promises + const Blob = firebase.firestore!.Blob; const FieldPath = firebase.firestore!.FieldPath; const GeoPoint = firebase.firestore!.GeoPoint; @@ -625,7 +627,7 @@ apiDescribe('Queries', (persistence: boolean) => { const expectedError = 'QuerySnapshot.docChanges has been changed from a property into a method'; - // tslint:disable-next-line:no-any We are testing invalid API usage. + // eslint-disable-next-line @typescript-eslint/no-explicit-any, We are testing invalid API usage. const docChange = querySnap.docChanges as any; expect(() => docChange.length).to.throw(expectedError); expect(() => { diff --git a/packages/firestore/test/integration/api/server_timestamp.test.ts b/packages/firestore/test/integration/api/server_timestamp.test.ts index 76f44a1a89d..110e180f1fb 100644 --- a/packages/firestore/test/integration/api/server_timestamp.test.ts +++ b/packages/firestore/test/integration/api/server_timestamp.test.ts @@ -22,7 +22,9 @@ import { EventsAccumulator } from '../util/events_accumulator'; import firebase from '../util/firebase_export'; import { apiDescribe, withTestDoc } from '../util/helpers'; -// tslint:disable-next-line:no-any Allow custom types for testing. +// tslint:disable:no-floating-promises + +// eslint-disable-next-line @typescript-eslint/no-explicit-any, Allow custom types for testing. type AnyTestData = any; const Timestamp = firebase.firestore!.Timestamp; diff --git a/packages/firestore/test/integration/api/transactions.test.ts b/packages/firestore/test/integration/api/transactions.test.ts index 074d1e84cfc..5da389a3236 100644 --- a/packages/firestore/test/integration/api/transactions.test.ts +++ b/packages/firestore/test/integration/api/transactions.test.ts @@ -473,7 +473,7 @@ apiDescribe('Database transactions', (persistence: boolean) => { }); describe('must return a promise:', () => { - const noop = () => { + const noop = (): void => { /* -_- */ }; const badReturns = [ @@ -487,7 +487,7 @@ apiDescribe('Database transactions', (persistence: boolean) => { for (const badReturn of badReturns) { it(badReturn + ' is rejected', () => { - // tslint:disable-next-line:no-any Intentionally returning bad type. + // eslint-disable-next-line @typescript-eslint/no-explicit-any, Intentionally returning bad type. const fn = ((txn: firestore.Transaction) => badReturn) as any; return integrationHelpers.withTestDb(persistence, db => { return db diff --git a/packages/firestore/test/integration/api/validation.test.ts b/packages/firestore/test/integration/api/validation.test.ts index c1e10645f87..1382847bbea 100644 --- a/packages/firestore/test/integration/api/validation.test.ts +++ b/packages/firestore/test/integration/api/validation.test.ts @@ -32,11 +32,13 @@ import { withTestDb } from '../util/helpers'; +// tslint:disable:no-floating-promises + const FieldPath = firebase.firestore!.FieldPath; const FieldValue = firebase.firestore!.FieldValue; // We're using 'as any' to pass invalid values to APIs for testing purposes. -// tslint:disable:no-any +/* eslint-disable @typescript-eslint/no-explicit-any */ interface ValidationIt { ( @@ -115,7 +117,9 @@ apiDescribe('Validation:', (persistence: boolean) => { // that it will be impossible to verify that a set of settings don't throw, // and additionally that some exceptions happen for specific reasons, rather // than persistence having already been enabled. - if (persistence) return; + if (persistence) { + return; + } validationIt(persistence, 'validates options', db => { // NOTE: 'credentials' is an undocumented API so ideally we wouldn't @@ -318,7 +322,7 @@ apiDescribe('Validation:', (persistence: boolean) => { validationIt(persistence, 'Listen options are validated', db => { const collection = db.collection('test'); - const fn = () => {}; + const fn = (): void => {}; const doc = collection.doc(); expect(() => doc.onSnapshot({ bad: true } as any, fn)).to.throw( @@ -336,7 +340,7 @@ apiDescribe('Validation:', (persistence: boolean) => { validationIt(persistence, 'get options are validated', db => { const collection = db.collection('test'); const doc = collection.doc(); - const fn = () => {}; + const fn = (): void => {}; expect(() => doc.get(fn as any)).to.throw( 'Function DocumentReference.get() requires its first argument to be of type object, ' + @@ -880,7 +884,9 @@ apiDescribe('Validation:', (persistence: boolean) => { const unsubscribe = collection.onSnapshot(snapshot => { // Skip the initial empty snapshot. - if (snapshot.empty) return; + if (snapshot.empty) { + return; + } expect(snapshot.docs).to.have.lengthOf(1); const docSnap: firestore.DocumentSnapshot = snapshot.docs[0]; @@ -1347,7 +1353,7 @@ function expectWriteToFail( } const docRef = db.doc('foo/bar'); - const error = (fnName: string) => + const error = (fnName: string): string => `Function ${fnName}() called with invalid data. ${reason}`; if (includeSets) { diff --git a/packages/firestore/test/integration/api_internal/idle_timeout.test.ts b/packages/firestore/test/integration/api_internal/idle_timeout.test.ts index f13df17db04..49326f0b0a3 100644 --- a/packages/firestore/test/integration/api_internal/idle_timeout.test.ts +++ b/packages/firestore/test/integration/api_internal/idle_timeout.test.ts @@ -37,7 +37,7 @@ apiDescribe('Idle Timeout', (persistence: boolean) => { it('can watch documents after idle timeout', () => { return withTestDb(persistence, db => { - const awaitOnlineSnapshot = () => { + const awaitOnlineSnapshot = (): Promise => { const docRef = db.collection('test-collection').doc(); const deferred = new Deferred(); const unregister = docRef.onSnapshot( diff --git a/packages/firestore/test/integration/bootstrap.ts b/packages/firestore/test/integration/bootstrap.ts index 0f12ec993ff..bf10a51b4a1 100644 --- a/packages/firestore/test/integration/bootstrap.ts +++ b/packages/firestore/test/integration/bootstrap.ts @@ -25,7 +25,7 @@ import '../../index'; */ // 'context()' definition requires additional dependency on webpack-env package. -// tslint:disable-next-line:no-any +// eslint-disable-next-line @typescript-eslint/no-explicit-any const testsContext = (require as any).context('.', true, /.test$/); const browserTests = testsContext .keys() diff --git a/packages/firestore/test/integration/util/events_accumulator.ts b/packages/firestore/test/integration/util/events_accumulator.ts index c5957d9c864..c17bae6db95 100644 --- a/packages/firestore/test/integration/util/events_accumulator.ts +++ b/packages/firestore/test/integration/util/events_accumulator.ts @@ -61,7 +61,7 @@ export class EventsAccumulator< if (snapshot.metadata.hasPendingWrites) { return snapshot; } else { - return await this.awaitLocalEvent(); + return this.awaitLocalEvent(); } } @@ -80,7 +80,7 @@ export class EventsAccumulator< if (!snapshot.metadata.hasPendingWrites) { return snapshot; } else { - return await this.awaitRemoteEvent(); + return this.awaitRemoteEvent(); } } diff --git a/packages/firestore/test/integration/util/firebase_export.ts b/packages/firestore/test/integration/util/firebase_export.ts index 84e37bafb0c..0aacdf9cc63 100644 --- a/packages/firestore/test/integration/util/firebase_export.ts +++ b/packages/firestore/test/integration/util/firebase_export.ts @@ -22,5 +22,5 @@ import firebase from '@firebase/app'; -// tslint:disable-next-line:no-default-export +// eslint-disable-next-line import/no-default-export export default firebase; diff --git a/packages/firestore/test/integration/util/helpers.ts b/packages/firestore/test/integration/util/helpers.ts index 429abcffb0b..dab836d6b28 100644 --- a/packages/firestore/test/integration/util/helpers.ts +++ b/packages/firestore/test/integration/util/helpers.ts @@ -24,9 +24,10 @@ import firebase from './firebase_export'; * dependencies on src/ files. */ -// tslint:disable-next-line:no-any __karma__ is an untyped global +// eslint-disable-next-line @typescript-eslint/no-explicit-any, __karma__ is an untyped global declare const __karma__: any; +// eslint-disable-next-line @typescript-eslint/no-require-imports const PROJECT_CONFIG = require('../../../../../config/project.json'); const EMULATOR_PORT = process.env.FIRESTORE_EMULATOR_PORT; @@ -45,7 +46,7 @@ const PROD_FIRESTORE_SETTING = { export const DEFAULT_SETTINGS = getDefaultSettings(); -// tslint:disable-next-line:no-console +// eslint-disable-next-line no-console console.log(`Default Settings: ${JSON.stringify(DEFAULT_SETTINGS)}`); function getDefaultSettings(): firestore.Settings { diff --git a/packages/firestore/test/unit/api/blob.test.ts b/packages/firestore/test/unit/api/blob.test.ts index 94bc21128c0..c98570f0736 100644 --- a/packages/firestore/test/unit/api/blob.test.ts +++ b/packages/firestore/test/unit/api/blob.test.ts @@ -58,7 +58,7 @@ describe('Blob', () => { }); it('Blob throws on using the public constructor', () => { - // tslint:disable-next-line:no-any allow using constructor with any + // eslint-disable-next-line @typescript-eslint/no-explicit-any, allow using constructor with any expect(() => new (PublicBlob as any)('')).to.throw( 'This constructor is private. Use Blob.fromUint8Array() or ' + 'Blob.fromBase64String() instead.' diff --git a/packages/firestore/test/unit/bootstrap.ts b/packages/firestore/test/unit/bootstrap.ts index e8e14400828..f6bb54236d9 100644 --- a/packages/firestore/test/unit/bootstrap.ts +++ b/packages/firestore/test/unit/bootstrap.ts @@ -25,7 +25,7 @@ import '../../src/platform_browser/browser_init'; */ // 'context()' definition requires additional dependency on webpack-env package. -// tslint:disable-next-line:no-any +// eslint-disable-next-line @typescript-eslint/no-explicit-any const testsContext = (require as any).context('.', true, /.test$/); const browserTests = testsContext .keys() diff --git a/packages/firestore/test/unit/core/event_manager.test.ts b/packages/firestore/test/unit/core/event_manager.test.ts index 41c2ca0dc5d..2feaf9c2617 100644 --- a/packages/firestore/test/unit/core/event_manager.test.ts +++ b/packages/firestore/test/unit/core/event_manager.test.ts @@ -39,7 +39,7 @@ import { } from '../../util/helpers'; describe('EventManager', () => { - // tslint:disable-next-line:no-any mock object. + // eslint-disable-next-line @typescript-eslint/no-explicit-any, mock object. function fakeQueryListener(query: Query): any { return { query, @@ -49,7 +49,7 @@ describe('EventManager', () => { }; } - // tslint:disable-next-line:no-any mock object. + // eslint-disable-next-line @typescript-eslint/no-explicit-any, mock object. function makeSyncEngineSpy(): any { const stub = { listen: sinon.stub().returns(Promise.resolve(0)), @@ -115,9 +115,9 @@ describe('EventManager', () => { await eventManager.listen(fakeListener3); expect(syncEngineSpy.listen.callCount).to.equal(2); - // tslint:disable-next-line:no-any mock ViewSnapshot. + // eslint-disable-next-line @typescript-eslint/no-explicit-any, mock ViewSnapshot. const viewSnap1: any = { query: query1 }; - // tslint:disable-next-line:no-any mock ViewSnapshot. + // eslint-disable-next-line @typescript-eslint/no-explicit-any, mock ViewSnapshot. const viewSnap2: any = { query: query2 }; eventManager.onWatchChange([viewSnap1, viewSnap2]); diff --git a/packages/firestore/test/unit/local/indexeddb_persistence.test.ts b/packages/firestore/test/unit/local/indexeddb_persistence.test.ts index 2e5a73edbc7..38f1d694da7 100644 --- a/packages/firestore/test/unit/local/indexeddb_persistence.test.ts +++ b/packages/firestore/test/unit/local/indexeddb_persistence.test.ts @@ -228,7 +228,7 @@ describe('IndexedDbSchema: createOrUpgradeDb', () => { return ( targets - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any .put({ targetId, canonicalId: 'foo' } as any) .next(() => targetGlobal.put(DbTargetGlobal.key, dummyTargetGlobal) @@ -335,7 +335,7 @@ describe('IndexedDbSchema: createOrUpgradeDb', () => { ); p = p.next(() => { store - .add({} as any) // tslint:disable-line:no-any + .add({} as any) // eslint-disable-line @typescript-eslint/no-explicit-any .next(batchId => { expect(batchId).to.equal(43); }); diff --git a/packages/firestore/test/unit/local/local_store.test.ts b/packages/firestore/test/unit/local/local_store.test.ts index 97a0009fed1..df48fc0cbdb 100644 --- a/packages/firestore/test/unit/local/local_store.test.ts +++ b/packages/firestore/test/unit/local/local_store.test.ts @@ -1132,12 +1132,12 @@ function genericLocalStoreTests( expectLocalStore() .afterAllocatingQuery(query) .toReturnTargetId(2) - .after(setMutation('foo/bar', { sum: 0, array_union: [] })) + .after(setMutation('foo/bar', { sum: 0, arrayUnion: [] })) .toReturnChanged( doc( 'foo/bar', 0, - { sum: 0, array_union: [] }, + { sum: 0, arrayUnion: [] }, { hasLocalMutations: true } ) ) @@ -1146,27 +1146,27 @@ function genericLocalStoreTests( doc( 'foo/bar', 1, - { sum: 0, array_union: [] }, + { sum: 0, arrayUnion: [] }, { hasCommittedMutations: true } ) ) .afterRemoteEvent( - docAddedRemoteEvent(doc('foo/bar', 1, { sum: 0, array_union: [] }), [ + docAddedRemoteEvent(doc('foo/bar', 1, { sum: 0, arrayUnion: [] }), [ 2 ]) ) - .toReturnChanged(doc('foo/bar', 1, { sum: 0, array_union: [] })) + .toReturnChanged(doc('foo/bar', 1, { sum: 0, arrayUnion: [] })) .afterMutations([ transformMutation('foo/bar', { sum: PublicFieldValue.increment(1) }), transformMutation('foo/bar', { - array_union: PublicFieldValue.arrayUnion('foo') + arrayUnion: PublicFieldValue.arrayUnion('foo') }) ]) .toReturnChanged( doc( 'foo/bar', 1, - { sum: 1, array_union: ['foo'] }, + { sum: 1, arrayUnion: ['foo'] }, { hasLocalMutations: true } ) ) @@ -1175,7 +1175,7 @@ function genericLocalStoreTests( // backend value. .afterRemoteEvent( docUpdateRemoteEvent( - doc('foo/bar', 2, { sum: 1337, array_union: ['bar'] }), + doc('foo/bar', 2, { sum: 1337, arrayUnion: ['bar'] }), [2] ) ) @@ -1183,7 +1183,7 @@ function genericLocalStoreTests( doc( 'foo/bar', 2, - { sum: 1, array_union: ['bar', 'foo'] }, + { sum: 1, arrayUnion: ['bar', 'foo'] }, { hasLocalMutations: true } ) ) diff --git a/packages/firestore/test/unit/local/lru_garbage_collector.test.ts b/packages/firestore/test/unit/local/lru_garbage_collector.test.ts index fcdc56785df..7c154b9cd81 100644 --- a/packages/firestore/test/unit/local/lru_garbage_collector.test.ts +++ b/packages/firestore/test/unit/local/lru_garbage_collector.test.ts @@ -122,7 +122,7 @@ function genericLruGarbageCollectorTests( ); const referenceDelegate = persistence.referenceDelegate; referenceDelegate.setInMemoryPins(new ReferenceSet()); - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any garbageCollector = ((referenceDelegate as any) as LruDelegate) .garbageCollector; } diff --git a/packages/firestore/test/unit/local/persistence_promise.test.ts b/packages/firestore/test/unit/local/persistence_promise.test.ts index abb55b84af7..9a1ce9fd0f2 100644 --- a/packages/firestore/test/unit/local/persistence_promise.test.ts +++ b/packages/firestore/test/unit/local/persistence_promise.test.ts @@ -15,13 +15,12 @@ * limitations under the License. */ -import { expect } from 'chai'; +import { expect, use } from 'chai'; import { PersistencePromise } from '../../../src/local/persistence_promise'; -import * as chai from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; -chai.use(chaiAsPromised); +use(chaiAsPromised); describe('PersistencePromise', () => { function async(value: R): PersistencePromise { diff --git a/packages/firestore/test/unit/local/persistence_test_helpers.ts b/packages/firestore/test/unit/local/persistence_test_helpers.ts index e229fcb0265..6063459bc2b 100644 --- a/packages/firestore/test/unit/local/persistence_test_helpers.ts +++ b/packages/firestore/test/unit/local/persistence_test_helpers.ts @@ -22,9 +22,10 @@ import { BatchId, MutationBatchState, OnlineState, - TargetId + TargetId, + ListenSequenceNumber } from '../../../src/core/types'; -import { ListenSequenceNumber } from '../../../src/core/types'; + import { IndexedDbPersistence } from '../../../src/local/indexeddb_persistence'; import { LocalSerializer } from '../../../src/local/local_serializer'; import { LruParams } from '../../../src/local/lru_garbage_collector'; diff --git a/packages/firestore/test/unit/local/remote_document_cache.test.ts b/packages/firestore/test/unit/local/remote_document_cache.test.ts index 134a016d21b..93f4b1b16f0 100644 --- a/packages/firestore/test/unit/local/remote_document_cache.test.ts +++ b/packages/firestore/test/unit/local/remote_document_cache.test.ts @@ -31,10 +31,7 @@ import { removedDoc } from '../../util/helpers'; -import { - IndexedDbRemoteDocumentCache, - isDocumentChangeMissingError -} from '../../../src/local/indexeddb_remote_document_cache'; +import { isDocumentChangeMissingError } from '../../../src/local/indexeddb_remote_document_cache'; import { DbRemoteDocumentChanges, DbRemoteDocumentChangesKey diff --git a/packages/firestore/test/unit/local/simple_db.test.ts b/packages/firestore/test/unit/local/simple_db.test.ts index b6b296d5e7f..9a3c8d162e7 100644 --- a/packages/firestore/test/unit/local/simple_db.test.ts +++ b/packages/firestore/test/unit/local/simple_db.test.ts @@ -15,23 +15,21 @@ * limitations under the License. */ -import * as chai from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; -import { expect } from 'chai'; +import { expect, use } from 'chai'; import { SimpleDb, - SimpleDbSchemaConverter -} from '../../../src/local/simple_db'; - -import { PersistencePromise } from '../../../src/local/persistence_promise'; -import { + SimpleDbSchemaConverter, SimpleDbStore, SimpleDbTransaction } from '../../../src/local/simple_db'; + +import { PersistencePromise } from '../../../src/local/persistence_promise'; + import { fail } from '../../../src/util/assert'; -chai.use(chaiAsPromised); +use(chaiAsPromised); interface User { id: number; @@ -511,7 +509,7 @@ describe('SimpleDb', () => { } return PersistencePromise.waitFor(promises).next(() => { const end = new Date().getTime(); - // tslint:disable-next-line:no-console + // eslint-disable-next-line no-console console.log(`Writing: ${end - start} ms`); }); }).then(() => { @@ -523,7 +521,7 @@ describe('SimpleDb', () => { } return PersistencePromise.waitFor(promises).next(() => { const end = new Date().getTime(); - // tslint:disable-next-line:no-console + // eslint-disable-next-line no-console console.log(`Reading: ${end - start} ms`); }); }); 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 e4a15d8f9d4..d93bad32afc 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 @@ -45,9 +45,9 @@ import * as objUtils from '../../../src/util/obj'; import { SortedSet } from '../../../src/util/sorted_set'; import { clearWebStorage, - TEST_PERSISTENCE_PREFIX + TEST_PERSISTENCE_PREFIX, + populateWebStorage } from './persistence_test_helpers'; -import * as persistenceHelpers from './persistence_test_helpers'; const AUTHENTICATED_USER = new User('test'); const UNAUTHENTICATED_USER = User.UNAUTHENTICATED; @@ -55,24 +55,20 @@ const TEST_ERROR = new FirestoreError('internal', 'Test Error'); function mutationKey(user: User, batchId: BatchId): string { if (user.isAuthenticated()) { - return `firestore_mutations_${ - persistenceHelpers.TEST_PERSISTENCE_PREFIX - }_${batchId}_${user.uid}`; + return `firestore_mutations_${TEST_PERSISTENCE_PREFIX}_${batchId}_${ + user.uid + }`; } else { - return `firestore_mutations_${ - persistenceHelpers.TEST_PERSISTENCE_PREFIX - }_${batchId}`; + return `firestore_mutations_${TEST_PERSISTENCE_PREFIX}_${batchId}`; } } function targetKey(targetId: TargetId): string { - return `firestore_targets_${ - persistenceHelpers.TEST_PERSISTENCE_PREFIX - }_${targetId}`; + return `firestore_targets_${TEST_PERSISTENCE_PREFIX}_${targetId}`; } function onlineStateKey(): string { - return `firestore_online_state_${persistenceHelpers.TEST_PERSISTENCE_PREFIX}`; + return `firestore_online_state_${TEST_PERSISTENCE_PREFIX}`; } function sequenceNumberKey(): string { @@ -237,9 +233,7 @@ describe('WebStorageSharedClientState', () => { function assertClientState(activeTargetIds: TargetId[]): void { const actual = JSON.parse( webStorage.getItem( - `firestore_clients_${ - persistenceHelpers.TEST_PERSISTENCE_PREFIX - }_${primaryClientId}` + `firestore_clients_${TEST_PERSISTENCE_PREFIX}_${primaryClientId}` )! ); @@ -390,24 +384,20 @@ describe('WebStorageSharedClientState', () => { describe('combines client state', () => { const secondaryClientId = AutoId.newId(); - const secondaryClientStateKey = `firestore_clients_${ - persistenceHelpers.TEST_PERSISTENCE_PREFIX - }_${secondaryClientId}`; + const secondaryClientStateKey = `firestore_clients_${TEST_PERSISTENCE_PREFIX}_${secondaryClientId}`; beforeEach(() => { const existingClientId = AutoId.newId(); - return persistenceHelpers - .populateWebStorage( - AUTHENTICATED_USER, - existingClientId, - [1, 2], - [3, 4] - ) - .then(() => { - clientSyncer.activeClients = [primaryClientId, existingClientId]; - return sharedClientState.start(); - }); + return populateWebStorage( + AUTHENTICATED_USER, + existingClientId, + [1, 2], + [3, 4] + ).then(() => { + clientSyncer.activeClients = [primaryClientId, existingClientId]; + return sharedClientState.start(); + }); }); async function verifyState( @@ -527,9 +517,7 @@ describe('WebStorageSharedClientState', () => { }); it('ignores invalid data', async () => { - const secondaryClientStateKey = `firestore_clients_${ - persistenceHelpers.TEST_PERSISTENCE_PREFIX - }_${AutoId.newId()}`; + const secondaryClientStateKey = `firestore_clients_${TEST_PERSISTENCE_PREFIX}_${AutoId.newId()}`; const invalidState = { activeTargetIds: [5, 'invalid'] @@ -657,7 +645,7 @@ describe('WebStorageSharedClientState', () => { new MutationMetadata( AUTHENTICATED_USER, 1, - 'invalid' as any // tslint:disable-line:no-any + 'invalid' as any // eslint-disable-line @typescript-eslint/no-explicit-any ).toWebStorageJSON() ); }).then(clientState => { @@ -670,12 +658,8 @@ describe('WebStorageSharedClientState', () => { const firstClientTargetId: TargetId = 1; const secondClientTargetId: TargetId = 2; - const firstClientStorageKey = `firestore_clients_${ - persistenceHelpers.TEST_PERSISTENCE_PREFIX - }_${AutoId.newId()}`; - const secondClientStorageKey = `firestore_clients_${ - persistenceHelpers.TEST_PERSISTENCE_PREFIX - }_${AutoId.newId()}`; + const firstClientStorageKey = `firestore_clients_${TEST_PERSISTENCE_PREFIX}_${AutoId.newId()}`; + const secondClientStorageKey = `firestore_clients_${TEST_PERSISTENCE_PREFIX}_${AutoId.newId()}`; let firstClient: LocalClientState; let secondClientState: LocalClientState; @@ -818,7 +802,7 @@ describe('WebStorageSharedClientState', () => { targetKey(firstClientTargetId), new QueryTargetMetadata( firstClientTargetId, - 'invalid' as any // tslint:disable-line:no-any + 'invalid' as any // eslint-disable-line @typescript-eslint/no-explicit-any ).toWebStorageJSON() ); }).then(clientState => { diff --git a/packages/firestore/test/unit/model/document.test.ts b/packages/firestore/test/unit/model/document.test.ts index e1825c3e0f9..967925d6202 100644 --- a/packages/firestore/test/unit/model/document.test.ts +++ b/packages/firestore/test/unit/model/document.test.ts @@ -16,8 +16,7 @@ */ import { expect } from 'chai'; -import * as make from '../../util/helpers'; -import { expectEqual, expectNotEqual } from '../../util/helpers'; +import { expectEqual, expectNotEqual, doc, field } from '../../util/helpers'; describe('Document', () => { it('can be constructed', () => { @@ -25,15 +24,15 @@ describe('Document', () => { desc: 'Discuss all the project related stuff', owner: 'Jonny' }; - const doc = make.doc('rooms/Eros', 1, data); + const document = doc('rooms/Eros', 1, data); - const value = doc.value(); + const value = document.value(); expect(value).to.deep.equal({ desc: 'Discuss all the project related stuff', owner: 'Jonny' }); expect(value).not.to.equal(data); - expect(doc.hasLocalMutations).to.equal(false); + expect(document.hasLocalMutations).to.equal(false); }); it('returns fields correctly', () => { @@ -41,44 +40,35 @@ describe('Document', () => { desc: 'Discuss all the project related stuff', owner: { name: 'Jonny', title: 'scallywag' } }; - const doc = make.doc('rooms/Eros', 1, data, { hasLocalMutations: true }); + const document = doc('rooms/Eros', 1, data, { hasLocalMutations: true }); - expect(doc.fieldValue(make.field('desc'))).to.deep.equal( + expect(document.fieldValue(field('desc'))).to.deep.equal( 'Discuss all the project related stuff' ); - expect(doc.fieldValue(make.field('owner.title'))).to.deep.equal( + expect(document.fieldValue(field('owner.title'))).to.deep.equal( 'scallywag' ); - expect(doc.hasLocalMutations).to.equal(true); + expect(document.hasLocalMutations).to.equal(true); }); it('equals to other same documents', () => { - expect(make.doc('a/b', 0, {}).isEqual(null)).to.equal(false); + expect(doc('a/b', 0, {}).isEqual(null)).to.equal(false); - expectEqual( - make.doc('a/b', 3, { foo: 'bar' }), - make.doc('a/b', 3, { foo: 'bar' }) - ); - expectEqual( - make.doc('a/b', 1, { foo: NaN }), - make.doc('a/b', 1, { foo: NaN }) - ); + expectEqual(doc('a/b', 3, { foo: 'bar' }), doc('a/b', 3, { foo: 'bar' })); + expectEqual(doc('a/b', 1, { foo: NaN }), doc('a/b', 1, { foo: NaN })); expectNotEqual( - make.doc('a/b', 1, { foo: 'bar' }), - make.doc('a/0', 1, { foo: 'bar' }) - ); - expectNotEqual( - make.doc('a/b', 1, { foo: 'bar' }), - make.doc('a/b', 2, { foo: 'bar' }) + doc('a/b', 1, { foo: 'bar' }), + doc('a/0', 1, { foo: 'bar' }) ); expectNotEqual( - make.doc('a/b', 1, { foo: 'bar' }), - make.doc('a/b', 1, { foo: 100 }) + doc('a/b', 1, { foo: 'bar' }), + doc('a/b', 2, { foo: 'bar' }) ); + expectNotEqual(doc('a/b', 1, { foo: 'bar' }), doc('a/b', 1, { foo: 100 })); expectNotEqual( - make.doc('a/b', 1, { foo: 'bar' }, { hasLocalMutations: true }), - make.doc('a/b', 1, { foo: 'bar' }, { hasLocalMutations: false }) + doc('a/b', 1, { foo: 'bar' }, { hasLocalMutations: true }), + doc('a/b', 1, { foo: 'bar' }, { hasLocalMutations: false }) ); }); }); diff --git a/packages/firestore/test/unit/model/mutation.test.ts b/packages/firestore/test/unit/model/mutation.test.ts index e8b94cdadc3..5ea3519f3d7 100644 --- a/packages/firestore/test/unit/model/mutation.test.ts +++ b/packages/firestore/test/unit/model/mutation.test.ts @@ -459,9 +459,9 @@ describe('Mutation', () => { }); it('can apply numeric add transform to unexpected type', () => { - const baseDoc = { string: 'zero' }; - const transform = { string: FieldValue.increment(1) }; - const expected = { string: 1 }; + const baseDoc = { stringVal: 'zero' }; + const transform = { stringVal: FieldValue.increment(1) }; + const expected = { stringVal: 1 }; verifyTransform(baseDoc, transform, expected); }); @@ -473,11 +473,11 @@ describe('Mutation', () => { }); it('can apply numeric add transforms consecutively', () => { - const baseDoc = { number: 1 }; - const transform1 = { number: FieldValue.increment(2) }; - const transform2 = { number: FieldValue.increment(3) }; - const transform3 = { number: FieldValue.increment(4) }; - const expected = { number: 10 }; + const baseDoc = { numberVal: 1 }; + const transform1 = { numberVal: FieldValue.increment(2) }; + const transform2 = { numberVal: FieldValue.increment(3) }; + const transform3 = { numberVal: FieldValue.increment(4) }; + const expected = { numberVal: 10 }; verifyTransform(baseDoc, [transform1, transform2, transform3], expected); }); diff --git a/packages/firestore/test/unit/remote/node/serializer.test.ts b/packages/firestore/test/unit/remote/node/serializer.test.ts index 17917b9200d..c91f1e44769 100644 --- a/packages/firestore/test/unit/remote/node/serializer.test.ts +++ b/packages/firestore/test/unit/remote/node/serializer.test.ts @@ -1223,7 +1223,7 @@ describe('Serializer', () => { addEqualityMatcher(); it('contains all Operators', () => { - // tslint:disable-next-line:no-any giant hack + // eslint-disable-next-line @typescript-eslint/no-explicit-any, giant hack obj.forEach(Operator as any, (name, op) => { if (op instanceof Operator) { expect(s.toOperatorName(op), 'for name').to.exist; @@ -1237,7 +1237,7 @@ describe('Serializer', () => { addEqualityMatcher(); it('contains all Directions', () => { - // tslint:disable-next-line:no-any giant hack + // eslint-disable-next-line @typescript-eslint/no-explicit-any, giant hack obj.forEach(Direction as any, (name, dir) => { if (dir instanceof Direction) { expect(s.toDirection(dir), 'for ' + name).to.exist; diff --git a/packages/firestore/test/unit/remote/remote_event.test.ts b/packages/firestore/test/unit/remote/remote_event.test.ts index c541ac306f8..96fe15be427 100644 --- a/packages/firestore/test/unit/remote/remote_event.test.ts +++ b/packages/firestore/test/unit/remote/remote_event.test.ts @@ -44,18 +44,19 @@ import { version } from '../../util/helpers'; -type TargetMap = { - [targetId: number]: QueryData; -}; -type PendingTargetResponses = { - [targetId: number]: number; -}; +interface TargetMap { + [targetId: string]: QueryData; +} +interface PendingTargetResponses { + [targetId: string]: number; +} function listens(...targetIds: TargetId[]): TargetMap { const targets: TargetMap = {}; for (const target of targetIds) { targets[target] = queryData(target, QueryPurpose.Listen, 'coll'); } + return targets; } diff --git a/packages/firestore/test/unit/specs/describe_spec.ts b/packages/firestore/test/unit/specs/describe_spec.ts index 1953ed73d48..0b6378f0195 100644 --- a/packages/firestore/test/unit/specs/describe_spec.ts +++ b/packages/firestore/test/unit/specs/describe_spec.ts @@ -176,7 +176,7 @@ export function specTest( await spec.runAsTest(fullName, usePersistence); const end = Date.now(); if (tags.indexOf(BENCHMARK_TAG) >= 0) { - // tslint:disable-next-line:no-console + // eslint-disable-next-line no-console console.log(`Runtime: ${end - start} ms.`); } }); diff --git a/packages/firestore/test/unit/specs/listen_spec.test.ts b/packages/firestore/test/unit/specs/listen_spec.test.ts index 0efcd02d095..ab188bba9f2 100644 --- a/packages/firestore/test/unit/specs/listen_spec.test.ts +++ b/packages/firestore/test/unit/specs/listen_spec.test.ts @@ -448,8 +448,9 @@ describeSpec('Listens:', [], () => { }); specTest('Listens are reestablished after network disconnect', [], () => { - const expectRequestCount = (requestCounts: { [type: string]: number }) => - requestCounts.addTarget + requestCounts.removeTarget; + const expectRequestCount = (requestCounts: { + [type: string]: number; + }): number => requestCounts.addTarget + requestCounts.removeTarget; const query = Query.atPath(path('collection')); const docA = doc('collection/a', 1000, { key: 'a' }); diff --git a/packages/firestore/test/unit/specs/spec_builder.ts b/packages/firestore/test/unit/specs/spec_builder.ts index 1262176b35d..2960ef74844 100644 --- a/packages/firestore/test/unit/specs/spec_builder.ts +++ b/packages/firestore/test/unit/specs/spec_builder.ts @@ -30,8 +30,8 @@ import { mapCodeFromRpcCode, mapRpcCodeFromCode } from '../../../src/remote/rpc_error'; -import { assert } from '../../../src/util/assert'; -import { fail } from '../../../src/util/assert'; +import { assert, fail } from '../../../src/util/assert'; + import { Code } from '../../../src/util/error'; import * as objUtils from '../../../src/util/obj'; import { isNullOrUndefined } from '../../../src/util/types'; @@ -54,11 +54,16 @@ import { // These types are used in a protected API by SpecBuilder and need to be // exported. -export type QueryMap = { [query: string]: TargetId }; -export type LimboMap = { [key: string]: TargetId }; -export type ActiveTargetMap = { - [targetId: number]: { query: SpecQuery; resumeToken: string }; -}; +export interface QueryMap { + [query: string]: TargetId; +} +export interface LimboMap { + [key: string]: TargetId; +} + +export interface ActiveTargetMap { + [targetId: string]: { query: SpecQuery; resumeToken: string }; +} /** * Tracks the expected memory state of a client (e.g. the expected active watch diff --git a/packages/firestore/test/unit/specs/spec_test_runner.ts b/packages/firestore/test/unit/specs/spec_test_runner.ts index 6deeb3acb71..af8d7822469 100644 --- a/packages/firestore/test/unit/specs/spec_test_runner.ts +++ b/packages/firestore/test/unit/specs/spec_test_runner.ts @@ -258,7 +258,7 @@ class MockConnection implements Connection { } }); this.writeStream = writeStream; - // tslint:disable-next-line:no-any Replace 'any' with conditional types. + // eslint-disable-next-line @typescript-eslint/no-explicit-any, Replace 'any' with conditional types. return writeStream as any; } else { assert(rpcName === 'Listen', 'Unexpected rpc name: ' + rpcName); @@ -292,7 +292,7 @@ class MockConnection implements Connection { } }); this.watchStream = watchStream; - // tslint:disable-next-line:no-any Replace 'any' with conditional types. + // eslint-disable-next-line @typescript-eslint/no-explicit-any, Replace 'any' with conditional types. return this.watchStream as any; } } @@ -439,7 +439,9 @@ abstract class TestRunner { new EmptyCredentialsProvider(), this.serializer ); - const remoteStoreOnlineStateChangedHandler = (onlineState: OnlineState) => { + const remoteStoreOnlineStateChangedHandler = ( + onlineState: OnlineState + ): void => { this.syncEngine.applyOnlineStateChange( onlineState, OnlineStateSource.RemoteStore @@ -447,7 +449,7 @@ abstract class TestRunner { }; const sharedClientStateOnlineStateChangedHandler = ( onlineState: OnlineState - ) => { + ): void => { this.syncEngine.applyOnlineStateChange( onlineState, OnlineStateSource.SharedClientState @@ -1238,7 +1240,7 @@ export async function runSpec( config: SpecConfig, steps: SpecStep[] ): Promise { - // tslint:disable-next-line:no-console + // eslint-disable-next-line no-console console.log('Running spec: ' + name); const sharedMockStorage = new SharedFakeWebStorage(); @@ -1247,7 +1249,7 @@ export async function runSpec( const runners: TestRunner[] = []; const outstandingMutations = new SharedWriteTracker(); - const ensureRunner = async (clientIndex: number) => { + const ensureRunner = async (clientIndex: number): Promise => { if (!runners[clientIndex]) { const platform = new TestPlatform( PlatformSupport.getPlatform(), @@ -1419,28 +1421,28 @@ export type SpecWatchCurrent = [TargetId[], string]; /** [, ...] */ export type SpecWatchReset = TargetId[]; -export type SpecError = { +export interface SpecError { code: number; message: string; -}; +} -export type SpecWatchRemove = { +export interface SpecWatchRemove { targetIds: TargetId[]; cause?: SpecError; -}; +} -export type SpecWatchSnapshot = { +export interface SpecWatchSnapshot { version: TestSnapshotVersion; targetIds: TargetId[]; resumeToken?: string; -}; +} -export type SpecWatchStreamClose = { +export interface SpecWatchStreamClose { error: SpecError; runBackoffTimer: boolean; -}; +} -export type SpecWriteAck = { +export interface SpecWriteAck { /** The version the backend uses to ack the write. */ version: TestSnapshotVersion; /** @@ -1452,9 +1454,9 @@ export type SpecWriteAck = { */ // PORTING NOTE: Multi-Tab only. keepInQueue?: boolean; -}; +} -export type SpecWriteFailure = { +export interface SpecWriteFailure { /** The error the backend uses to fail the write. */ error: SpecError; /** @@ -1465,7 +1467,7 @@ export type SpecWriteFailure = { * Defaults to false. */ keepInQueue?: boolean; -}; +} export interface SpecWatchEntity { // exactly one of key, doc or docs is set @@ -1481,12 +1483,12 @@ export interface SpecWatchEntity { } // PORTING NOTE: Only used by web multi-tab tests. -export type SpecClientState = { +export interface SpecClientState { /** The visibility state of the browser tab running the client. */ visibility?: VisibilityState; /** Whether this tab should try to forcefully become primary. */ primary?: true; -}; +} /** * [[, ...], , ...] diff --git a/packages/firestore/test/unit/specs/write_spec.test.ts b/packages/firestore/test/unit/specs/write_spec.test.ts index 25b795dfd07..e5c7d8007b0 100644 --- a/packages/firestore/test/unit/specs/write_spec.test.ts +++ b/packages/firestore/test/unit/specs/write_spec.test.ts @@ -772,7 +772,9 @@ describeSpec('Writes:', [], () => { ); specTest('Writes are resent after network disconnect', [], () => { - const expectRequestCount = (requestCounts: { [type: string]: number }) => + const expectRequestCount = (requestCounts: { + [type: string]: number; + }): number => requestCounts.handshakes + requestCounts.writes + requestCounts.closes; return spec() diff --git a/packages/firestore/test/unit/util/async_queue.test.ts b/packages/firestore/test/unit/util/async_queue.test.ts index a48f816e04e..281ff463447 100644 --- a/packages/firestore/test/unit/util/async_queue.test.ts +++ b/packages/firestore/test/unit/util/async_queue.test.ts @@ -120,7 +120,8 @@ describe('AsyncQueue', () => { return Promise.all([op1Promise, op2Promise]).then(() => { // Once the queue is failed, trying to queue new operations will // synchronously throw with "already failed" error. - const dummyOp = () => Promise.reject('dummyOp should not be run'); + const dummyOp = (): Promise => + Promise.reject('dummyOp should not be run'); expect(() => { queue.enqueueAndForget(dummyOp); }).to.throw(/already failed:.*Simulated Error/); @@ -133,7 +134,8 @@ describe('AsyncQueue', () => { it('can schedule ops in the future', async () => { const queue = new AsyncQueue(); const completedSteps: number[] = []; - const doStep = (n: number) => defer(() => completedSteps.push(n)); + const doStep = (n: number): Promise => + defer(() => completedSteps.push(n)); queue.enqueueAndForget(() => doStep(1)); const last = queue.enqueueAfterDelay(timerId1, 5, () => doStep(4)); queue.enqueueAfterDelay(timerId2, 1, () => doStep(3)); @@ -146,7 +148,8 @@ describe('AsyncQueue', () => { it('Can cancel delayed operations', async () => { const queue = new AsyncQueue(); const completedSteps: number[] = []; - const doStep = (n: number) => defer(() => completedSteps.push(n)); + const doStep = (n: number): Promise => + defer(() => completedSteps.push(n)); queue.enqueueAndForget(() => doStep(1)); const delayedPromise = queue.enqueueAfterDelay(timerId1, 1, () => doStep(2) @@ -168,7 +171,8 @@ describe('AsyncQueue', () => { it('Can run all delayed operations early', async () => { const queue = new AsyncQueue(); const completedSteps: number[] = []; - const doStep = (n: number) => defer(() => completedSteps.push(n)); + const doStep = (n: number): Promise => + defer(() => completedSteps.push(n)); queue.enqueueAndForget(() => doStep(1)); queue.enqueueAfterDelay(timerId1, 20000, () => doStep(4)); queue.enqueueAfterDelay(timerId2, 10000, () => doStep(3)); @@ -181,7 +185,8 @@ describe('AsyncQueue', () => { it('Can run some delayed operations early', async () => { const queue = new AsyncQueue(); const completedSteps: number[] = []; - const doStep = (n: number) => defer(() => completedSteps.push(n)); + const doStep = (n: number): Promise => + defer(() => completedSteps.push(n)); queue.enqueueAndForget(() => doStep(1)); queue.enqueueAfterDelay(timerId1, 20000, () => doStep(5)); queue.enqueueAfterDelay(timerId2, 10000, () => doStep(3)); @@ -195,7 +200,8 @@ describe('AsyncQueue', () => { it('Can drain (non-delayed) operations', async () => { const queue = new AsyncQueue(); const completedSteps: number[] = []; - const doStep = (n: number) => defer(() => completedSteps.push(n)); + const doStep = (n: number): Promise => + defer(() => completedSteps.push(n)); queue.enqueueAndForget(() => doStep(1)); queue.enqueueAfterDelay(timerId1, 10000, () => doStep(5)); queue.enqueueAndForget(() => doStep(2)); diff --git a/packages/firestore/test/unit/util/sorted_map.test.ts b/packages/firestore/test/unit/util/sorted_map.test.ts index 32f6023a432..9842b82dc9a 100644 --- a/packages/firestore/test/unit/util/sorted_map.test.ts +++ b/packages/firestore/test/unit/util/sorted_map.test.ts @@ -301,14 +301,17 @@ describe('SortedMap Tests', () => { map = map.remove(i); } const end = new Date().getTime(); - // tslint:disable-next-line:no-console + // eslint-disable-next-line no-console console.log(end - start); } }); // tslint:disable-next-line:ban A little perf test for convenient benchmarking it.skip('Perf: Insertion and removal with various # of items.', () => { - const verifyTraversal = (map: SortedMap, max: number) => { + const verifyTraversal = ( + map: SortedMap, + max: number + ): void => { let next = 0; map.inorderTraversal((key: number, value: number) => { expect(key).to.equal(next); @@ -345,20 +348,25 @@ describe('SortedMap Tests', () => { } const elapsed = new Date().getTime() - start.getTime(); - // tslint:disable-next-line:no-console + // eslint-disable-next-line no-console console.log(N + ': ' + elapsed); } }); // tslint:disable-next-line:ban A little perf test for convenient benchmarking it.skip('Perf: Comparison with {}: Insertion and removal with various # of items.', () => { - const verifyTraversal = (tree: { [key: number]: number }, max: number) => { + const verifyTraversal = ( + tree: { [key: number]: number }, + max: number + ): void => { const keys: number[] = []; obj.forEach(tree, k => keys.push(Number(k))); keys.sort(); expect(keys.length).to.equal(max); - for (let i = 0; i < max; i++) expect(tree[i]).to.equal(i); + for (let i = 0; i < max; i++) { + expect(tree[i]).to.equal(i); + } }; for (let N = 10; N <= 100000; N *= 10) { @@ -387,7 +395,7 @@ describe('SortedMap Tests', () => { } const elapsed = new Date().getTime() - start.getTime(); - // tslint:disable-next-line:no-console + // eslint-disable-next-line no-console console.log(N + ': ' + elapsed); } }); @@ -401,11 +409,15 @@ describe('SortedMap Tests', () => { it('SortedMapIterator test with 10 items.', () => { const items: number[] = []; - for (let i = 0; i < 10; i++) items.push(i); + for (let i = 0; i < 10; i++) { + items.push(i); + } shuffle(items); let map = new SortedMap(primitiveComparator); - for (let i = 0; i < 10; i++) map = map.insert(items[i], items[i]); + for (let i = 0; i < 10; i++) { + map = map.insert(items[i], items[i]); + } const iterator = map.getIterator(); let expected = 0; diff --git a/packages/firestore/test/util/equality_matcher.ts b/packages/firestore/test/util/equality_matcher.ts index d59f4ae175e..6a5fadee53b 100644 --- a/packages/firestore/test/util/equality_matcher.ts +++ b/packages/firestore/test/util/equality_matcher.ts @@ -38,7 +38,9 @@ function customDeepEqual(left: unknown, right: unknown): boolean { /** * END: Custom compare logic */ - if (left === right) return true; + if (left === right) { + return true; + } if ( typeof left === 'number' && typeof right === 'number' && @@ -47,17 +49,27 @@ function customDeepEqual(left: unknown, right: unknown): boolean { ) { return true; } - if (typeof left !== typeof right) return false; // needed for structurally different objects - if (Object(left) !== left) return false; // primitive values - // @ts-ignore - const keys = Object.keys(left); - // @ts-ignore - if (keys.length !== Object.keys(right).length) return false; + if (typeof left !== typeof right) { + return false; + } // needed for structurally different objects + if (Object(left) !== left) { + return false; + } // primitive values + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const keys = Object.keys(left as any); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if (keys.length !== Object.keys(right as any).length) { + return false; + } for (let i = 0; i < keys.length; i++) { const key = keys[i]; - if (!Object.prototype.hasOwnProperty.call(right, key)) return false; - // @ts-ignore - if (!customDeepEqual(left[key], right[key])) return false; + if (!Object.prototype.hasOwnProperty.call(right, key)) { + return false; + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if (!customDeepEqual((left as any)[key], (right as any)[key])) { + return false; + } } return true; } @@ -72,6 +84,7 @@ export function addEqualityMatcher(): void { use((chai, utils) => { const Assertion = chai.Assertion; + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type const assertEql = (_super: (r: unknown, l: unknown) => boolean) => { originalFunction = originalFunction || _super; return function(...args: unknown[]): void { diff --git a/packages/firestore/test/util/helpers.ts b/packages/firestore/test/util/helpers.ts index 1deb75bb1f5..ddc5026afe8 100644 --- a/packages/firestore/test/util/helpers.ts +++ b/packages/firestore/test/util/helpers.ts @@ -95,7 +95,7 @@ export type TestSnapshotVersion = number; */ export const DELETE_SENTINEL = ''; -const preConverter = (input: unknown) => { +const preConverter = (input: unknown): unknown => { return input === DELETE_SENTINEL ? FieldValueImpl.delete() : input; }; @@ -411,8 +411,12 @@ export function localViewChanges( targetId: TargetId, changes: { added?: string[]; removed?: string[] } ): LocalViewChanges { - if (!changes.added) changes.added = []; - if (!changes.removed) changes.removed = []; + if (!changes.added) { + changes.added = []; + } + if (!changes.removed) { + changes.removed = []; + } let addedKeys = documentKeySet(); let removedKeys = documentKeySet(); @@ -551,7 +555,7 @@ export class DocComparator { /** * Two helper functions to simplify testing isEqual() method. */ -// tslint:disable-next-line:no-any so we can dynamically call .isEqual(). +// eslint-disable-next-line @typescript-eslint/no-explicit-any, so we can dynamically call .isEqual(). export function expectEqual(left: any, right: any, message?: string): void { message = message || ''; if (typeof left.isEqual !== 'function') { @@ -568,7 +572,7 @@ export function expectEqual(left: any, right: any, message?: string): void { expect(right.isEqual(left)).to.equal(true, message); } -// tslint:disable-next-line:no-any so we can dynamically call .isEqual(). +// eslint-disable-next-line @typescript-eslint/no-explicit-any, so we can dynamically call .isEqual(). export function expectNotEqual(left: any, right: any, message?: string): void { expect(left.isEqual(right)).to.equal(false, message || ''); expect(right.isEqual(left)).to.equal(false, message || ''); diff --git a/packages/firestore/test/util/node_persistence.ts b/packages/firestore/test/util/node_persistence.ts index e2793645816..6324221872e 100644 --- a/packages/firestore/test/util/node_persistence.ts +++ b/packages/firestore/test/util/node_persistence.ts @@ -29,7 +29,8 @@ import { FakeWindow, SharedFakeWebStorage } from './test_platform'; // To use this code to run persistence-based tests in Node, include this module // and set the environment variable `USE_MOCK_PERSISTENCE` to `YES`. -const globalAny = global as any; // tslint:disable-line:no-any +// eslint-disable-next-line @typescript-eslint/no-explicit-any, +const globalAny = global as any; const dbDir = fs.mkdtempSync(os.tmpdir() + '/firestore_tests'); @@ -50,6 +51,7 @@ if (process.env.USE_MOCK_PERSISTENCE === 'YES') { // We need to define the `Event` type as it is used in Node to send events to // WebStorage when using both the IndexedDB mock and the WebStorage mock. class Event { + // eslint-disable-next-line @typescript-eslint/no-useless-constructor constructor(typeArg: string, eventInitDict?: EventInit) {} } diff --git a/packages/firestore/test/util/test_platform.ts b/packages/firestore/test/util/test_platform.ts index fd4b475e59b..b20130b8f23 100644 --- a/packages/firestore/test/util/test_platform.ts +++ b/packages/firestore/test/util/test_platform.ts @@ -199,7 +199,7 @@ export class SharedFakeWebStorage { oldValue, newValue, storageArea: client.storageArea - } as any); // tslint:disable-line:no-any Not mocking entire Event type. + } as any); // eslint-disable-line @typescript-eslint/no-explicit-any, Not mocking entire Event type. }); } } @@ -220,12 +220,12 @@ export class TestPlatform implements Platform { } get document(): Document | null { - // tslint:disable-next-line:no-any FakeWindow doesn't support full Document interface. + // eslint-disable-next-line @typescript-eslint/no-explicit-any, FakeWindow doesn't support full Document interface. return this.mockDocument as any; } get window(): Window | null { - // tslint:disable-next-line:no-any FakeWindow doesn't support full Window interface. + // eslint-disable-next-line @typescript-eslint/no-explicit-any, FakeWindow doesn't support full Window interface. return this.mockWindow as any; } diff --git a/packages/firestore/tslint.json b/packages/firestore/tslint.json deleted file mode 100644 index c27f046465d..00000000000 --- a/packages/firestore/tslint.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "rules": { - "array-type": [true, "array-simple"], - "arrow-return-shorthand": true, - "ban": [true, - {"name": ["it", "skip"]}, - {"name": ["it", "only"]}, - {"name": ["describe", "skip"]}, - {"name": ["describe", "only"]}, - {"name": ["xit"]}, - {"name": ["xdescribe"]}, - {"name": "parseInt", "message": "tsstyle#type-coercion"}, - {"name": "parseFloat", "message": "tsstyle#type-coercion"}, - {"name": "Array", "message": "tsstyle#array-constructor"} - ], - "ban-types": [true, - ["Object", "Use object instead."], - ["String", "Use 'string' instead."], - ["Number", "Use 'number' instead."], - ["Boolean", "Use 'boolean' instead."] - ], - "class-name": true, - "curly": [true, "ignore-same-line"], - "forin": true, - "interface-name": [true, "never-prefix"], - "jsdoc-format": true, - "label-position": true, - "max-line-length": [true, {"limit": 100, "ignore-pattern": "^import|https?://"}], - "member-access": [true, "no-public"], - "new-parens": true, - "no-angle-bracket-type-assertion": true, - "no-any": true, - "no-arg": true, - "no-conditional-assignment": true, - "no-console": [true, "log"], - "no-construct": true, - "no-debugger": true, - "no-default-export": true, - "no-duplicate-variable": true, - "no-floating-promises": true, - "no-inferrable-types": true, - "no-namespace": [true, "allow-declarations"], - "no-reference": true, - "no-string-throw": true, - "no-unused-expression": false, - "no-unused-variable": [true, {"ignore-pattern": "^_$"}], - "no-var-keyword": true, - "object-literal-shorthand": true, - "only-arrow-functions": [true, "allow-declarations", "allow-named-functions"], - "ordered-imports": true, - "prefer-const": true, - "radix": true, - "semicolon": [true, "always", "ignore-bound-class-methods"], - "switch-default": true, - "triple-equals": [true, "allow-null-check"], - "typedef": [true, "call-signature", "property-declaration"], - "use-isnan": true, - "variable-name": [ - true, - "check-format", - "ban-keywords", - "allow-leading-underscore", - "allow-trailing-underscore" - ] - }, - "linterOptions": { - "exclude": [ - "src/protos/firestore_proto_api.d.ts" - ] - } -}