From fffdc774710fe13216fc10fef68e098abac55fb9 Mon Sep 17 00:00:00 2001 From: Chris Bianca Date: Sun, 7 Jan 2018 20:05:20 +0000 Subject: [PATCH 01/13] Add || exit 0 to open collective postinstall --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index adad4656..d05dab78 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "flow": "flow", "lint": "eslint ./src", "prepublish": "npm run clean && npm run build", - "postinstall": "postinstall-build dist && opencollective postinstall", + "postinstall": "postinstall-build dist && opencollective postinstall || exit 0", "test-cli": "node ./bin/test.js", "tests-packager": "cd tests && npm run start", "tests-npm-install": "cd tests && npm install", From 93a5c2939e88c04bcdc03c634bb589448489aa8f Mon Sep 17 00:00:00 2001 From: Chris Bianca Date: Sun, 7 Jan 2018 20:05:37 +0000 Subject: [PATCH 02/13] 3.2.1 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index eaedc9aa..35382c2d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "react-native-firebase", - "version": "3.2.0", + "version": "3.2.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index d05dab78..7bcf2ebb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-firebase", - "version": "3.2.0", + "version": "3.2.1", "author": "Invertase (http://invertase.io)", "description": "A well tested, feature rich Firebase implementation for React Native, supporting iOS & Android. Individual module support for Admob, Analytics, Auth, Crash Reporting, Cloud Firestore, Database, Dynamic Links, Messaging (FCM), Remote Config, Storage and Performance.", "main": "dist/index.js", From cfbef06776923c4785fcde709f6e52470990aa8b Mon Sep 17 00:00:00 2001 From: Chris Bianca Date: Wed, 10 Jan 2018 10:33:10 +0000 Subject: [PATCH 03/13] [ios] Tidy up header search paths --- ios/RNFirebase.xcodeproj/project.pbxproj | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/ios/RNFirebase.xcodeproj/project.pbxproj b/ios/RNFirebase.xcodeproj/project.pbxproj index da929dcf..c30d9012 100644 --- a/ios/RNFirebase.xcodeproj/project.pbxproj +++ b/ios/RNFirebase.xcodeproj/project.pbxproj @@ -475,9 +475,7 @@ "$(inherited)", "$(SRCROOT)/../../react-native/React/**", "${SRCROOT}/../../../ios/Firebase/**", - "${SRCROOT}/../../../ios/Pods/Headers/Public/Crashlytics", - "${SRCROOT}/../../../ios/Pods/Headers/Public/Fabric", - "${SRCROOT}/../../../ios/Pods/Firebase/**", + "${SRCROOT}/../../../ios/Pods/Headers/Public/**", ); IPHONEOS_DEPLOYMENT_TARGET = 8.0; LIBRARY_SEARCH_PATHS = "$(inherited)"; @@ -520,9 +518,7 @@ "$(inherited)", "$(SRCROOT)/../../react-native/React/**", "${SRCROOT}/../../../ios/Firebase/**", - "${SRCROOT}/../../../ios/Pods/Headers/Public/Crashlytics", - "${SRCROOT}/../../../ios/Pods/Headers/Public/Fabric", - "${SRCROOT}/../../../ios/Pods/Firebase/**", + "${SRCROOT}/../../../ios/Pods/Headers/Public/**", ); IPHONEOS_DEPLOYMENT_TARGET = 8.0; LIBRARY_SEARCH_PATHS = "$(inherited)"; From 01ef45d816e041c7166d5f54fadb9f2111860e38 Mon Sep 17 00:00:00 2001 From: Chris Bianca Date: Thu, 11 Jan 2018 10:36:29 +0000 Subject: [PATCH 04/13] [ios] Tidy up framework search paths --- ios/RNFirebase.xcodeproj/project.pbxproj | 36 +++--------------------- 1 file changed, 4 insertions(+), 32 deletions(-) diff --git a/ios/RNFirebase.xcodeproj/project.pbxproj b/ios/RNFirebase.xcodeproj/project.pbxproj index c30d9012..92df426e 100644 --- a/ios/RNFirebase.xcodeproj/project.pbxproj +++ b/ios/RNFirebase.xcodeproj/project.pbxproj @@ -453,22 +453,8 @@ ENABLE_BITCODE = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", - "${BUILT_PRODUCTS_DIR}", - "${SRCROOT}/../../../ios/Pods/Crashlytics/iOS", - "${SRCROOT}/../../../ios/Pods/Fabric/Frameworks", - "${SRCROOT}/../../../ios/Pods/FirebaseAnalytics/Frameworks", - "${SRCROOT}/../../../ios/Pods/FirebaseAuth/Frameworks", - "${SRCROOT}/../../../ios/Pods/FirebaseCore/Frameworks", - "${SRCROOT}/../../../ios/Pods/FirebaseCrash/Frameworks", - "${SRCROOT}/../../../ios/Pods/FirebaseDatabase/Frameworks", - "${SRCROOT}/../../../ios/Pods/FirebaseDynamicLinks/Frameworks", - "${SRCROOT}/../../../ios/Pods/FirebaseFirestore/Frameworks", - "${SRCROOT}/../../../ios/Pods/FirebaseInstanceID/Frameworks", - "${SRCROOT}/../../../ios/Pods/FirebaseMessaging/Frameworks", - "${SRCROOT}/../../../ios/Pods/FirebasePerformance/Frameworks", - "${SRCROOT}/../../../ios/Pods/FirebaseRemoteConfig/Frameworks", - "${SRCROOT}/../../../ios/Pods/FirebaseStorage/Frameworks", - "${SRCROOT}/../../../ios/Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks", + "${BUILT_PRODUCTS_DIR}/**", + "${SRCROOT}/../../../ios/Pods/**", "${SRCROOT}/../../../ios/Firebase/**", ); HEADER_SEARCH_PATHS = ( @@ -496,22 +482,8 @@ ENABLE_BITCODE = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", - "${BUILT_PRODUCTS_DIR}", - "${SRCROOT}/../../../ios/Pods/Crashlytics/iOS", - "${SRCROOT}/../../../ios/Pods/Fabric/Frameworks", - "${SRCROOT}/../../../ios/Pods/FirebaseAnalytics/Frameworks", - "${SRCROOT}/../../../ios/Pods/FirebaseAuth/Frameworks", - "${SRCROOT}/../../../ios/Pods/FirebaseCore/Frameworks", - "${SRCROOT}/../../../ios/Pods/FirebaseCrash/Frameworks", - "${SRCROOT}/../../../ios/Pods/FirebaseDatabase/Frameworks", - "${SRCROOT}/../../../ios/Pods/FirebaseDynamicLinks/Frameworks", - "${SRCROOT}/../../../ios/Pods/FirebaseFirestore/Frameworks", - "${SRCROOT}/../../../ios/Pods/FirebaseInstanceID/Frameworks", - "${SRCROOT}/../../../ios/Pods/FirebaseMessaging/Frameworks", - "${SRCROOT}/../../../ios/Pods/FirebasePerformance/Frameworks", - "${SRCROOT}/../../../ios/Pods/FirebaseRemoteConfig/Frameworks", - "${SRCROOT}/../../../ios/Pods/FirebaseStorage/Frameworks", - "${SRCROOT}/../../../ios/Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks", + "${BUILT_PRODUCTS_DIR}/**", + "${SRCROOT}/../../../ios/Pods/**", "${SRCROOT}/../../../ios/Firebase/**", ); HEADER_SEARCH_PATHS = ( From 7b821ae99757dccd48b9d12188a473f2cd36b95c Mon Sep 17 00:00:00 2001 From: Chris Bianca Date: Thu, 11 Jan 2018 10:37:29 +0000 Subject: [PATCH 05/13] 3.2.2 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 35382c2d..a25d4045 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "react-native-firebase", - "version": "3.2.1", + "version": "3.2.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 7bcf2ebb..5dcc8a1e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-firebase", - "version": "3.2.1", + "version": "3.2.2", "author": "Invertase (http://invertase.io)", "description": "A well tested, feature rich Firebase implementation for React Native, supporting iOS & Android. Individual module support for Admob, Analytics, Auth, Crash Reporting, Cloud Firestore, Database, Dynamic Links, Messaging (FCM), Remote Config, Storage and Performance.", "main": "dist/index.js", From 578198e2e6cc9449546dd7d8b4227cc10eed5e59 Mon Sep 17 00:00:00 2001 From: Paul Huynh Date: Mon, 22 Jan 2018 23:25:54 +1100 Subject: [PATCH 06/13] Add Typescript Definitions for Cloud Firestore --- lib/index.d.ts | 280 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) diff --git a/lib/index.d.ts b/lib/index.d.ts index 8d300c6f..38c0308d 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -72,6 +72,15 @@ declare module "react-native-firebase" { */ links(): RNFirebase.links.Links; + /** + * Cloud Firestore is Firebase's new flagship database solution for mobile + * development, however as at the time of this writing (22 Jan 2018) it is + * still a beta product, and may not be as stable as Firebase Realtime + * Database. Comparison of the two products hers: + * https://firebase.google.com/docs/database/rtdb-vs-firestore + */ + firestore(): RNFirebase.firestore.FirestoreModule; + static fabric: { crashlytics(): RNFirebase.crashlytics.Crashlytics; }; @@ -1067,5 +1076,276 @@ declare module "react-native-firebase" { }, } } + + namespace firestore { + type FirestoreModule = Firestore & FirestoreStatics; + + interface Firestore { + batch(): WriteBatch; + collection(collectionPath: string): CollectionReference; + doc(documentPath: string): DocumentReference; + + /** NOT SUPPORTED YET */ + enablePersistence(): Promise; + /** NOT SUPPORTED YET */ + runTransaction(): Promise; + /** NOT SUPPORTED YET */ + settings(): void; + } + + interface FirestoreStatics { + FieldPath: typeof FieldPath; + FieldValue: typeof FieldValue; + GeoPoint: typeof GeoPoint; + enableLogging(enabled: boolean): void; + }; + + class CollectionReference { + constructor(firestore: Firestore, collectionPath: Path); + get firestore(): Firestore; + get id(): string; + get parent(): DocumentReference; + add(data: object): Promise; + doc(documentPath?: string): DocumentReference; + endAt(snapshot: DocumentSnapshot): Query; + endAt(...varargs: any[]): Query; + endBefore(snapshot: DocumentSnapshot): Query; + endBefore(...varargs: any[]): Query; + get(): Promise; + limit(limit: number): Query; + onSnapshot(onNext: Query.ObserverOnNext, onError?: Query.ObserverOnError): () => void; + onSnapshot(observer: Observer): () => void; + onSnapshot(queryListenOptions: Query.QueryListenOptions, onNext: Query.ObserverOnNext, onError?: Query.ObserverOnError): () => void; + onSnapshot(queryListenOptions: Query.QueryListenOptions, observer: Query.Observer): () => void; + orderBy(fieldPath: string | FieldPath, directionStr?: Types.QueryDirection): Query; + startAfter(snapshot: DocumentSnapshot): Query; + startAfter(...varargs: any[]): Query; + startAt(snapshot: DocumentSnapshot): Query; + startAt(...varargs: any[]): Query; + where(fieldPath: string, op: Types.QueryOperator, value: any): Query; + } + + class DocumentChange { + constructor(firestore: Firestore, nativeData: Types.NativeDocumentChange); + get doc(): DocumentSnapshot; + get newIndex(): number; + get oldIndex(): number; + get type(): string; + } + + class DocumentReference { + constructor(firestore: Firestore, documentPath: Path); + get firestore(): Firestore; + get id(): string | null; + get parent(): CollectionReference; + get path(): string; + collection(collectionPath: string): CollectionReference; + delete(): Promise; + get(): Promise; + onSnapshot(onNext: DocumentReference.ObserverOnNext, onError?: DocumentReference.ObserverOnError): () => void; + onSnapshot(observer: DocumentReference.Observer): () => void; + onSnapshot(documentListenOptions: DocumentReference.DocumentListenOptions, onNext: DocumentReference.ObserverOnNext, onError?: DocumentReference.ObserverOnError): () => void; + onSnapshot(documentListenOptions: DocumentReference.DocumentListenOptions, observer: DocumentReference.Observer): () => void; + set(data: object, writeOptions?: Types.WriteOptions): Promise; + update(obj: object): Promise; + update(key1: Types.UpdateKey, val1: any): Promise; + update(key1: Types.UpdateKey, val1: any, key2: Types.UpdateKey, val2: any): Promise; + update(key1: Types.UpdateKey, val1: any, key2: Types.UpdateKey, val2: any, key3: Types.UpdateKey, val3: any): Promise; + update(key1: Types.UpdateKey, val1: any, key2: Types.UpdateKey, val2: any, key3: Types.UpdateKey, val3: any, key4: Types.UpdateKey, val4: any): Promise; + update(key1: Types.UpdateKey, val1: any, key2: Types.UpdateKey, val2: any, key3: Types.UpdateKey, val3: any, key4: Types.UpdateKey, val4: any, key5: Types.UpdateKey, val5: any): Promise; + } + namespace DocumentReference { + // JS code expects this value to be true. + interface DocumentListenOptions { + includeMetadataChanges: true; + } + + type ObserverOnNext = (documentSnapshot: DocumentSnapshot) => void; + type ObserverOnError = (err: object) => void; + interface Observer { + next: ObserverOnNext; + error?: ObserverOnError; + } + } + + class DocumentSnapshot { + constructor(firestore: Firestore, nativeData: Types.NativeDocumentSnapshot) + get exists(): boolean; + get id(): string | null; + get metadata(): Types.SnapshotMetadata; + get ref(): DocumentReference; + data(): object | void; + get(fieldPath: string | FieldPath): any | undefined; + } + + class FieldPath { + static documentId(): FieldPath; + constructor(...segments: string[]); + } + + class FieldValue { + static delete(): FieldValue; + static serverTimestamp(): FieldValue; + } + + class GeoPoint { + constructor(latitude: number, longitude: number); + get latitude(): number; + get longitude(): number; + } + + class Path { + static fromName(name: string): Path; + constructor(pathComponents: string[]); + get id(): string | null; + get isDocument(): boolean; + get isCollection(): boolean; + get relativeName(): string; + child(relativePath: string): Path; + parent(): Path | null; + } + + class Query { + constructor( + firestore: Firestore, + path: Path, + fieldFilters?: Query.FieldFilter[], + fieldOrders?: Query.FieldOrder[], + queryOptions?: Query.QueryOptions, + ); + get firestore(): Firestore; + endAt(snapshot: DocumentSnapshot): Query; + endAt(...varargs: any[]): Query; + endBefore(snapshot: DocumentSnapshot): Query; + endBefore(...varargs: any[]): Query; + get(): Promise; + limit(limit: number): Query; + onSnapshot(onNext: Query.ObserverOnNext, onError?: Query.ObserverOnError): () => void; + onSnapshot(observer: Observer): () => void; + onSnapshot(queryListenOptions: Query.QueryListenOptions, onNext: Query.ObserverOnNext, onError?: Query.ObserverOnError): () => void; + onSnapshot(queryListenOptions: Query.QueryListenOptions, observer: Query.Observer): () => void; + orderBy(fieldPath: string | FieldPath, directionStr?: Types.QueryDirection): Query; + startAfter(snapshot: DocumentSnapshot): Query; + startAfter(...varargs: any[]): Query; + startAt(snapshot: DocumentSnapshot): Query; + startAt(...varargs: any[]): Query; + where(fieldPath: string, op: Types.QueryOperator, value: any): Query; + } + namespace Query { + interface NativeFieldPath { + elements?: string[]; + string?: string; + type: 'fieldpath' | 'string'; + } + + interface FieldFilter { + fieldPath: NativeFieldPath; + operator: string; + value: any; + } + + interface FieldOrder { + direction: string; + fieldPath: NativeFieldPath; + } + + interface QueryOptions { + endAt?: any[]; + endBefore?: any[]; + limit?: number; + offset?: number; + selectFields?: string[]; + startAfter?: any[]; + startAt?: any[]; + } + + // The JS code expects at least one of 'includeDocumentMetadataChanges' + // or 'includeQueryMetadataChanges' to be true. This logic is + // encapsulated in QueryListenOptions. + interface _IncludeDocumentMetadataChanges { + includeDocumentMetadataChanges: true; + } + interface _IncludeQueryMetadataChanges { + includeQueryMetadataChanges: true + } + type QueryListenOptions = _IncludeDocumentMetadataChanges | _IncludeQueryMetadataChanges | (_IncludeDocumentMetadataChanges & _IncludeQueryMetadataChanges); + + type ObserverOnNext = (querySnapshot: QuerySnapshot) => void; + type ObserverOnError = (err: object) => void; + interface Observer { + next: ObserverOnNext; + error?: ObserverOnError; + } + } + + class QuerySnapshot { + constructor(firestore: Firestore, query: Query, nativeData: QuerySnapshot.NativeData); + get docChanges(): DocumentChange[]; + get docs(): DocumentSnapshot[]; + get empty(): boolean; + get metadata(): Types.SnapshotMetadata; + get query(): Query; + get size(): number; + forEach(callback: (snapshot: DocumentSnapshot) => any); + } + namespace QuerySnapshot { + interface NativeData { + changes: Types.NativeDocumentChange[]; + documents: Types.NativeDocumentSnapshot[]; + metadata: Types.SnapshotMetadata; + } + } + + class WriteBatch { + constructor(firestore: Firestore); + commit(): Promise; + delete(docRef: DocumentReference): WriteBatch; + set(docRef: DocumentReference, data: object, options?: Types.WriteOptions): WriteBatch; + // multiple overrides for update() to allow strong-typed var_args + update(docRef: DocumentReference, obj: object): WriteBatch; + update(docRef: DocumentReference, key1: Types.UpdateKey, val1: any): WriteBatch; + update(docRef: DocumentReference, key1: Types.UpdateKey, val1: any, key2: Types.UpdateKey, val2: any): WriteBatch; + update(docRef: DocumentReference, key1: Types.UpdateKey, val1: any, key2: Types.UpdateKey, val2: any, key3: Types.UpdateKey, val3: any): WriteBatch; + update(docRef: DocumentReference, key1: Types.UpdateKey, val1: any, key2: Types.UpdateKey, val2: any, key3: Types.UpdateKey, val3: any, key4: Types.UpdateKey, val4: any): WriteBatch; + update(docRef: DocumentReference, key1: Types.UpdateKey, val1: any, key2: Types.UpdateKey, val2: any, key3: Types.UpdateKey, val3: any, key4: Types.UpdateKey, val4: any, key5: Types.UpdateKey, val5: any): WriteBatch; + } + + namespace Types { + interface NativeDocumentChange { + document: NativeDocumentSnapshot; + newIndex: number; + oldIndex: number; + type: string; + } + + interface NativeDocumentSnapshot { + data: { + [key: string]: TypeMap; + }; + metadata: SnapshotMetadata; + path: string; + } + + interface SnapshotMetadata { + fromCache: boolean; + hasPendingWrites: boolean; + } + + type QueryDirection = 'asc' | 'ASC' | 'desc' | 'DESC'; + type QueryOperator = '=' | '==' | '>' | '>=' | '<' | '<='; + + interface TypeMap { + type: 'array' | 'boolean' | 'date' | 'documentid' | 'fieldvalue' | 'geopoint' | 'null' | 'number' | 'object' | 'reference' | 'string'; + value: any; + } + + /** The key in update() function for DocumentReference and WriteBatch. */ + type UpdateKey = string | FieldPath + + interface WriteOptions { + merge?: boolean; + } + } + } } } From 8feffd85c5f0829cdfcdc6b2b0edf6c9627bfbe0 Mon Sep 17 00:00:00 2001 From: Chris Bianca Date: Thu, 25 Jan 2018 18:11:37 +0000 Subject: [PATCH 07/13] [js] Setup prettier --- .eslintrc | 54 ++-- package-lock.json | 624 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 8 +- 3 files changed, 653 insertions(+), 33 deletions(-) diff --git a/.eslintrc b/.eslintrc index 2c8b7e3b..daf94a0b 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,46 +1,36 @@ { - "extends": "airbnb", + "extends": [ + "airbnb", + "prettier", + "prettier/flowtype", + "prettier/react" + ], "parser": "babel-eslint", - "ecmaFeatures": { - "jsx": true - }, "plugins": [ - "flowtype" + "flowtype", + "prettier" ], "env": { "es6": true, "jasmine": true }, - "parserOptions": { - "ecmaFeatures": { - "experimentalObjectRestSpread": true - } - }, "rules": { + "prettier/prettier": ["error", { + "trailingComma": "es5", + "singleQuote": true + }], + + "react/forbid-prop-types": "warn", + "react/jsx-filename-extension": [ + "off", { "extensions": [".js", ".jsx"] } + ], + "class-methods-use-this": 0, - "no-plusplus": 0, - "no-underscore-dangle": 0, - "no-return-assign": 0, - "no-undef": 0, - "no-use-before-define": 0, - "arrow-body-style": 0, - "import/prefer-default-export": 0, - "radix": 0, - "new-cap": 0, - "max-len": 0, - "no-continue": 0, "no-console": 0, - "global-require": 0, - "import/extensions": 0, - "import/no-unresolved": 0, - "import/no-extraneous-dependencies": 0, - "react/jsx-filename-extension": 0, - "no-unused-expressions": 0, - "flowtype/no-unused-expressions": ['error', { - allowShortCircuit: false, - allowTernary: false, - allowTaggedTemplates: false, - }] + "no-plusplus": 0, + "no-undef": 0, + "no-underscore-dangle": "off", + "no-use-before-define": 0 }, "globals": { "__DEV__": true, diff --git a/package-lock.json b/package-lock.json index eb812eb4..9a078a16 100644 --- a/package-lock.json +++ b/package-lock.json @@ -102,6 +102,12 @@ "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", "dev": true }, + "any-observable": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.2.0.tgz", + "integrity": "sha1-xnhwBYADV5AJCD9UrAq6+1wz0kI=", + "dev": true + }, "anymatch": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", @@ -112,6 +118,12 @@ "normalize-path": "2.1.1" } }, + "app-root-path": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.0.1.tgz", + "integrity": "sha1-zWLc+OT9WkF+/GZNLlsQZTxlG0Y=", + "dev": true + }, "are-we-there-yet": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", @@ -1423,6 +1435,12 @@ "readdirp": "2.1.0" } }, + "ci-info": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.2.tgz", + "integrity": "sha512-uTGIPNx/nSpBdsF6xnseRXLLtfr9VLqkz8ZqHXr3Y7b6SftyRxBGjwMtJj1OhNbmlc1wZzLNAlAcvyIiE8a6ZA==", + "dev": true + }, "circular-json": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", @@ -1438,6 +1456,30 @@ "restore-cursor": "1.0.1" } }, + "cli-spinners": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-0.1.2.tgz", + "integrity": "sha1-u3ZNiOGF+54eaiofGXcjGPYF4xw=", + "dev": true + }, + "cli-truncate": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", + "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", + "dev": true, + "requires": { + "slice-ansi": "0.0.4", + "string-width": "1.0.2" + }, + "dependencies": { + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + } + } + }, "cli-width": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", @@ -1723,6 +1765,30 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, + "cosmiconfig": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-4.0.0.tgz", + "integrity": "sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==", + "dev": true, + "requires": { + "is-directory": "0.3.1", + "js-yaml": "3.10.0", + "parse-json": "4.0.0", + "require-from-string": "2.0.1" + }, + "dependencies": { + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "1.3.1", + "json-parse-better-errors": "1.0.1" + } + } + } + }, "crc": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/crc/-/crc-3.3.0.tgz", @@ -1827,6 +1893,12 @@ "assert-plus": "1.0.0" } }, + "date-fns": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.29.0.tgz", + "integrity": "sha512-lbTXWZ6M20cWH8N9S6afb0SBm6tMk+uUg6z3MqHPKE9atmsY3kJkTm8vKe93izJ2B2+q5MV990sM2CHgtAZaOw==", + "dev": true + }, "dateformat": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", @@ -1848,6 +1920,12 @@ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", @@ -2034,6 +2112,12 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "dev": true }, + "elegant-spinner": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", + "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", + "dev": true + }, "emoji-regex": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.5.1.tgz", @@ -2294,6 +2378,15 @@ "eslint-restricted-globals": "0.1.1" } }, + "eslint-config-prettier": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-2.9.0.tgz", + "integrity": "sha512-ag8YEyBXsm3nmOv1Hz991VtNNDMRa+MNy8cY47Pl4bw6iuzqKbJajXdqUpiw13STdLLrznxgm1hj9NhxeOYq0A==", + "dev": true, + "requires": { + "get-stdin": "5.0.1" + } + }, "eslint-import-resolver-node": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz", @@ -2368,6 +2461,24 @@ "jsx-ast-utils": "1.4.1" } }, + "eslint-plugin-prettier": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-2.5.0.tgz", + "integrity": "sha512-L06bewYpt2Wb8Uk7os8f/0cL5DjddL38t1M/nOpjw5MqVFBn1RIIBBE6tfr37lHUH7AvAubZsvu/bDmNl4RBKQ==", + "dev": true, + "requires": { + "fast-diff": "1.1.2", + "jest-docblock": "21.2.0" + }, + "dependencies": { + "jest-docblock": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz", + "integrity": "sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw==", + "dev": true + } + } + }, "eslint-plugin-react": { "version": "7.4.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.4.0.tgz", @@ -2606,6 +2717,12 @@ "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", "dev": true }, + "fast-diff": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz", + "integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==", + "dev": true + }, "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", @@ -2747,6 +2864,12 @@ "parents": "1.0.1" } }, + "find-parent-dir": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.0.tgz", + "integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ=", + "dev": true + }, "find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", @@ -3910,6 +4033,18 @@ "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", "dev": true }, + "get-own-enumerable-property-symbols": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-2.0.1.tgz", + "integrity": "sha512-TtY/sbOemiMKPRUDDanGCSgBYe7Mf0vbRsWnBZ+9yghpZ1MvcpSpuZFjHdEeY/LZjZy0vdLjS77L6HosisFiug==", + "dev": true + }, + "get-stdin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", + "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=", + "dev": true + }, "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", @@ -4181,6 +4316,25 @@ "sshpk": "1.13.1" } }, + "husky": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-0.14.3.tgz", + "integrity": "sha512-e21wivqHpstpoiWA/Yi8eFti8E+sQDSS53cpJsPptPs295QTOQR0ZwnHo2TXy1XOpZFD9rPOd3NpmqTK6uMLJA==", + "dev": true, + "requires": { + "is-ci": "1.1.0", + "normalize-path": "1.0.0", + "strip-indent": "2.0.0" + }, + "dependencies": { + "normalize-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz", + "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=", + "dev": true + } + } + }, "iconv-lite": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", @@ -4204,6 +4358,15 @@ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "2.0.1" + } + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -4430,12 +4593,27 @@ "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", "dev": true }, + "is-ci": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.1.0.tgz", + "integrity": "sha512-c7TnwxLePuqIlxHgr7xtxzycJPegNHFuIrBkwbf8hc58//+Op1CqFkyS+xnIMkwn9UsJIwc174BIjkyBmSpjKg==", + "dev": true, + "requires": { + "ci-info": "1.1.2" + } + }, "is-date-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", "dev": true }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, "is-dotfile": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", @@ -4499,6 +4677,29 @@ "kind-of": "3.2.2" } }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-observable": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-0.2.0.tgz", + "integrity": "sha1-s2ExHYPG5dcmyr9eJQsCNxBvWuI=", + "dev": true, + "requires": { + "symbol-observable": "0.2.4" + }, + "dependencies": { + "symbol-observable": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-0.2.4.tgz", + "integrity": "sha1-lag9smGG1q9+ehjb2XYKL4bQj0A=", + "dev": true + } + } + }, "is-path-cwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", @@ -4549,6 +4750,12 @@ "has": "1.0.1" } }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "dev": true + }, "is-resolvable": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", @@ -4638,6 +4845,12 @@ "detect-newline": "2.1.0" } }, + "jest-get-type": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-21.2.0.tgz", + "integrity": "sha512-y2fFw3C+D0yjNSDp7ab1kcd6NUYfy3waPTlD8yWkAtiocJdBRQqNoRqVfMNxgj+IjT0V5cBIHJO0z9vuSSZ43Q==", + "dev": true + }, "jest-haste-map": { "version": "22.0.3", "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-22.0.3.tgz", @@ -4652,6 +4865,65 @@ "sane": "2.2.0" } }, + "jest-validate": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-21.2.1.tgz", + "integrity": "sha512-k4HLI1rZQjlU+EC682RlQ6oZvLrE5SCh3brseQc24vbZTxzT/k/3urar5QMCVgjadmSO7lECeGdc6YxnM3yEGg==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "jest-get-type": "21.2.0", + "leven": "2.1.0", + "pretty-format": "21.2.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "pretty-format": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-21.2.1.tgz", + "integrity": "sha512-ZdWPGYAnYfcVP8yKA3zFjCn8s4/17TeYH28MXuC8vTp0o21eXjbFGcOAXZEaDaOFJjc3h2qa7HQNHNshhvoh2A==", + "dev": true, + "requires": { + "ansi-regex": "3.0.0", + "ansi-styles": "3.2.0" + } + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, "jest-worker": { "version": "22.0.3", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-22.0.3.tgz", @@ -4694,6 +4966,12 @@ "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", "dev": true }, + "json-parse-better-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.1.tgz", + "integrity": "sha512-xyQpxeWWMKyJps9CuGJYeng6ssI5bpqS9ltQpdVQ90t4ql6NdnxFKh95JcRt2cun/DjMVNrdjniLPuMA69xmCw==", + "dev": true + }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -4808,6 +5086,12 @@ "integrity": "sha1-0wpzxrggHY99jnlWupYWCHpo4O4=", "dev": true }, + "leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", + "dev": true + }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -4818,6 +5102,197 @@ "type-check": "0.3.2" } }, + "lint-staged": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-6.0.1.tgz", + "integrity": "sha512-GZnFshBzIpJMHO5aSqXGVJh5G1agKTrKGQOs6cTKA6a62PvZ7l2RawbpOrFdzjzkezxm7+LpKeleNt83gd9yRA==", + "dev": true, + "requires": { + "app-root-path": "2.0.1", + "chalk": "2.3.0", + "commander": "2.11.0", + "cosmiconfig": "4.0.0", + "debug": "3.1.0", + "dedent": "0.7.0", + "execa": "0.8.0", + "find-parent-dir": "0.3.0", + "is-glob": "4.0.0", + "jest-validate": "21.2.1", + "listr": "0.13.0", + "lodash": "4.17.4", + "log-symbols": "2.2.0", + "minimatch": "3.0.4", + "npm-which": "3.0.1", + "p-map": "1.2.0", + "path-is-inside": "1.0.2", + "pify": "3.0.0", + "staged-git-files": "0.0.4", + "stringify-object": "3.2.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "execa": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz", + "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", + "dev": true, + "requires": { + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "dev": true, + "requires": { + "is-extglob": "2.1.1" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "listr": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/listr/-/listr-0.13.0.tgz", + "integrity": "sha1-ILsLowuuZg7oTMBQPfS+PVYjiH0=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "cli-truncate": "0.2.1", + "figures": "1.7.0", + "indent-string": "2.1.0", + "is-observable": "0.2.0", + "is-promise": "2.1.0", + "is-stream": "1.1.0", + "listr-silent-renderer": "1.1.1", + "listr-update-renderer": "0.4.0", + "listr-verbose-renderer": "0.4.1", + "log-symbols": "1.0.2", + "log-update": "1.0.2", + "ora": "0.2.3", + "p-map": "1.2.0", + "rxjs": "5.5.6", + "stream-to-observable": "0.2.0", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "log-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", + "dev": true, + "requires": { + "chalk": "1.1.3" + } + } + } + }, + "listr-silent-renderer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz", + "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=", + "dev": true + }, + "listr-update-renderer": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.4.0.tgz", + "integrity": "sha1-NE2YDaLKLosUW6MFkI8yrj9MyKc=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "cli-truncate": "0.2.1", + "elegant-spinner": "1.0.1", + "figures": "1.7.0", + "indent-string": "3.2.0", + "log-symbols": "1.0.2", + "log-update": "1.0.2", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true + }, + "log-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", + "dev": true, + "requires": { + "chalk": "1.1.3" + } + } + } + }, + "listr-verbose-renderer": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz", + "integrity": "sha1-ggb0z21S3cWCfl/RSYng6WWTOjU=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "cli-cursor": "1.0.2", + "date-fns": "1.29.0", + "figures": "1.7.0" + } + }, "load-json-file": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", @@ -5074,6 +5549,56 @@ "lodash.escape": "3.2.0" } }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "2.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "log-update": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-1.0.2.tgz", + "integrity": "sha1-GZKfZMQJPS0ucHWh2tivWcKWuNE=", + "dev": true, + "requires": { + "ansi-escapes": "1.4.0", + "cli-cursor": "1.0.2" + } + }, "loose-envify": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", @@ -5542,6 +6067,15 @@ "remove-trailing-separator": "1.1.0" } }, + "npm-path": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/npm-path/-/npm-path-2.0.4.tgz", + "integrity": "sha512-IFsj0R9C7ZdR5cP+ET342q77uSRdtWOlWpih5eC+lu29tIDbNEgDbzgVJ5UFvYHWhxDZ5TFkJafFioO0pPQjCw==", + "dev": true, + "requires": { + "which": "1.3.0" + } + }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -5551,6 +6085,17 @@ "path-key": "2.0.1" } }, + "npm-which": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-which/-/npm-which-3.0.1.tgz", + "integrity": "sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo=", + "dev": true, + "requires": { + "commander": "2.11.0", + "npm-path": "2.0.4", + "which": "1.3.0" + } + }, "npmlog": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-2.0.4.tgz", @@ -5879,6 +6424,18 @@ "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=", "dev": true }, + "ora": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/ora/-/ora-0.2.3.tgz", + "integrity": "sha1-N1J9Igrc1Tw5tzVx11QVbV22V6Q=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "cli-cursor": "1.0.2", + "cli-spinners": "0.1.2", + "object-assign": "4.1.1" + } + }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", @@ -5947,6 +6504,12 @@ "p-limit": "1.1.0" } }, + "p-map": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", + "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", + "dev": true + }, "parents": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", @@ -6120,6 +6683,12 @@ "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", "dev": true }, + "prettier": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.10.2.tgz", + "integrity": "sha512-TcdNoQIWFoHblurqqU6d1ysopjq7UX0oRcT/hJ8qvBAELiYWn+Ugf0AXdnzISEJ7vuhNnQ98N8jR8Sh53x4IZg==", + "dev": true + }, "pretty-format": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-4.3.1.tgz", @@ -6646,6 +7215,12 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, + "require-from-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.1.tgz", + "integrity": "sha1-xUUjPp19pmFunVmt+zn8n1iGdv8=", + "dev": true + }, "require-main-filename": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", @@ -6749,6 +7324,23 @@ "rx-lite": "3.1.2" } }, + "rxjs": { + "version": "5.5.6", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.6.tgz", + "integrity": "sha512-v4Q5HDC0FHAQ7zcBX7T2IL6O5ltl1a2GX4ENjPXg6SjDY69Cmx9v4113C99a4wGF16ClPv5Z8mghuYorVkg/kg==", + "dev": true, + "requires": { + "symbol-observable": "1.0.1" + }, + "dependencies": { + "symbol-observable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", + "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=", + "dev": true + } + } + }, "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", @@ -7129,6 +7721,12 @@ "integrity": "sha1-ATl5IuX2Ls8whFUiyVxP4dJefU4=", "dev": true }, + "staged-git-files": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/staged-git-files/-/staged-git-files-0.0.4.tgz", + "integrity": "sha1-15fhtVHKemOd7AI33G60u5vhfTU=", + "dev": true + }, "statuses": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", @@ -7176,6 +7774,15 @@ } } }, + "stream-to-observable": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/stream-to-observable/-/stream-to-observable-0.2.0.tgz", + "integrity": "sha1-WdbqOT2HwsDdrBCqDVYbxrpvDhA=", + "dev": true, + "requires": { + "any-observable": "0.2.0" + } + }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -7196,6 +7803,17 @@ "safe-buffer": "5.1.1" } }, + "stringify-object": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.2.1.tgz", + "integrity": "sha512-jPcQYw/52HUPP8uOE4kkjxl5bB9LfHkKCTptIk3qw7ozP5XMIMlHMLjt00GGSwW6DJAf/njY5EU6Vpwl4LlBKQ==", + "dev": true, + "requires": { + "get-own-enumerable-property-symbols": "2.0.1", + "is-obj": "1.0.1", + "is-regexp": "1.0.0" + } + }, "stringstream": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", @@ -7222,6 +7840,12 @@ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, + "strip-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true + }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", diff --git a/package.json b/package.json index 8f001a1b..9284e312 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "build-lib": "BABEL_ENV=publish babel lib -d dist --ignore __tests__ --copy-files", "clean": "rimraf dist/", "flow": "flow", - "lint": "eslint ./src", + "format": "eslint --fix ./lib ./tests/src ./tests/lib", + "lint": "eslint ./lib ./tests/src ./tests/lib", "prepublish": "npm run clean && npm run build", "postinstall": "postinstall-build dist && opencollective postinstall || exit 0", "test-cli": "node ./bin/test.js", @@ -82,13 +83,18 @@ "enzyme": "^2.4.1", "eslint": "^4.11.0", "eslint-config-airbnb": "^16.1.0", + "eslint-config-prettier": "^2.9.0", "eslint-plugin-flowtype": "^2.39.1", "eslint-plugin-import": "^2.8.0", "eslint-plugin-jsx-a11y": "^6.0.2", + "eslint-plugin-prettier": "^2.5.0", "eslint-plugin-react": "^7.4.0", "flow-bin": "^0.61.0", "flow-copy-source": "^1.2.1", "genversion": "^2.0.1", + "husky": "^0.14.3", + "lint-staged": "^6.0.1", + "prettier": "1.10.2", "react": "^16.2.0", "react-dom": "^16.2.0", "react-native": "^0.52.0", From fba638072927e2acdf216747894884f42dbb8e96 Mon Sep 17 00:00:00 2001 From: Chris Bianca Date: Thu, 25 Jan 2018 18:25:39 +0000 Subject: [PATCH 08/13] [js] Run prettier for the first time --- lib/modules/admob/AdMobComponent.js | 9 +- lib/modules/admob/AdRequest.js | 3 +- lib/modules/admob/Banner.js | 7 +- lib/modules/admob/EventTypes.js | 3 +- lib/modules/admob/Interstitial.js | 19 +- lib/modules/admob/NativeExpress.js | 7 +- lib/modules/admob/RewardedVideo.js | 19 +- lib/modules/admob/VideoOptions.js | 1 - lib/modules/admob/index.js | 21 +- lib/modules/analytics/index.js | 15 +- lib/modules/auth/PhoneAuthListener.js | 65 +- lib/modules/auth/User.js | 122 ++- lib/modules/auth/index.js | 169 +++- .../auth/providers/EmailAuthProvider.js | 4 +- .../auth/providers/FacebookAuthProvider.js | 4 +- .../auth/providers/GithubAuthProvider.js | 4 +- .../auth/providers/GoogleAuthProvider.js | 4 +- lib/modules/auth/providers/OAuthProvider.js | 4 +- .../auth/providers/PhoneAuthProvider.js | 4 +- .../auth/providers/TwitterAuthProvider.js | 4 +- lib/modules/auth/types.js | 18 +- lib/modules/config/index.js | 36 +- lib/modules/core/firebase-app.js | 39 +- lib/modules/core/firebase.js | 110 ++- lib/modules/database/disconnect.js | 11 +- lib/modules/database/index.js | 12 +- lib/modules/database/query.js | 8 +- lib/modules/database/reference.js | 273 ++++-- lib/modules/database/snapshot.js | 5 +- lib/modules/database/transaction.js | 37 +- lib/modules/firestore/CollectionReference.js | 32 +- lib/modules/firestore/DocumentReference.js | 153 +++- lib/modules/firestore/DocumentSnapshot.js | 15 +- lib/modules/firestore/Query.js | 200 +++-- lib/modules/firestore/QuerySnapshot.js | 24 +- lib/modules/firestore/WriteBatch.js | 21 +- lib/modules/firestore/index.js | 35 +- lib/modules/firestore/utils/index.js | 13 +- lib/modules/firestore/utils/serialize.js | 27 +- lib/modules/links/index.js | 19 +- lib/modules/messaging/RemoteMessage.js | 9 +- lib/modules/messaging/index.js | 56 +- lib/modules/storage/index.js | 51 +- lib/modules/storage/reference.js | 13 +- lib/modules/storage/task.js | 110 ++- lib/modules/utils/index.js | 20 +- lib/types/index.js | 82 +- lib/utils/ModuleBase.js | 5 +- lib/utils/ReferenceBase.js | 4 +- lib/utils/SyncTree.js | 46 +- lib/utils/apps.js | 31 +- lib/utils/events.js | 25 +- lib/utils/index.js | 110 ++- lib/utils/internals.js | 83 +- lib/utils/log.js | 7 +- lib/utils/native.js | 16 +- tests/.eslintrc | 49 +- tests/index.js | 1 - tests/lib/TestDSL.js | 9 - tests/lib/TestRun.js | 160 +++- tests/lib/TestSuite.js | 41 +- tests/lib/TestSuiteDefinition.js | 52 +- tests/src/actions/AppActions.js | 5 +- tests/src/actions/TestActions.js | 8 +- tests/src/components/Banner.js | 21 +- tests/src/components/Icon.js | 23 +- tests/src/components/OverviewControlButton.js | 23 +- tests/src/components/StatusIndicator.js | 54 +- tests/src/components/TestControlButton.js | 9 +- .../src/components/TestSuiteControlButton.js | 20 +- tests/src/containers/CoreContainer.js | 19 +- tests/src/firebase.js | 57 +- tests/src/helpers.js | 3 - tests/src/main.admob.js | 35 +- tests/src/main.js | 15 +- tests/src/phone-auth.js | 225 +++-- tests/src/reducers/device.js | 2 - tests/src/reducers/testSuitesReducers.js | 8 +- tests/src/screens/Overview.js | 93 +- tests/src/screens/Suite.js | 168 ++-- tests/src/screens/Test.js | 87 +- tests/src/store/setup.js | 14 +- tests/src/tests/admob/admob.js | 108 +-- tests/src/tests/analytics/analytics.js | 67 +- tests/src/tests/auth/authTests.js | 659 +++++++++----- tests/src/tests/config/configTests.js | 48 +- tests/src/tests/core/coreTests.js | 50 +- tests/src/tests/crash/log.js | 35 +- .../src/tests/crashlytics/crashlyticsTests.js | 53 +- tests/src/tests/crashlytics/index.js | 6 +- tests/src/tests/database/index.js | 1 - tests/src/tests/database/ref/childTests.js | 2 +- tests/src/tests/database/ref/factoryTests.js | 3 +- tests/src/tests/database/ref/index.js | 24 +- .../tests/database/ref/issueSpecificTests.js | 74 +- tests/src/tests/database/ref/keyTests.js | 5 +- tests/src/tests/database/ref/offTests.js | 55 +- .../database/ref/on/onChildAddedTests.js | 18 +- tests/src/tests/database/ref/on/onTests.js | 30 +- .../src/tests/database/ref/on/onValueTests.js | 180 ++-- tests/src/tests/database/ref/onceTests.js | 13 +- tests/src/tests/database/ref/parentTests.js | 1 - tests/src/tests/database/ref/priorityTests.js | 29 +- tests/src/tests/database/ref/pushTests.js | 91 +- tests/src/tests/database/ref/queryTests.js | 33 +- tests/src/tests/database/ref/removeTests.js | 35 +- tests/src/tests/database/ref/setTests.js | 68 +- .../tests/database/ref/transactionTests.js | 82 +- tests/src/tests/database/ref/updateTests.js | 34 +- tests/src/tests/database/snapshot.js | 126 +-- .../firestore/collectionReferenceTests.js | 815 ++++++++++-------- .../tests/firestore/documentReferenceTests.js | 242 +++--- tests/src/tests/firestore/fieldPathTests.js | 30 +- tests/src/tests/firestore/fieldValueTests.js | 27 +- tests/src/tests/firestore/firestoreTests.js | 117 ++- tests/src/tests/firestore/index.js | 14 +- tests/src/tests/index.js | 33 +- tests/src/tests/links/linksTests.js | 135 +-- tests/src/tests/messaging/messagingTests.js | 22 +- tests/src/tests/perf/index.js | 6 +- tests/src/tests/storage/index.js | 7 +- tests/src/tests/storage/storageTests.js | 117 ++- tests/src/tests/support/DatabaseContents.js | 28 +- tests/src/tests/support/databaseTypeMap.js | 8 +- 124 files changed, 4343 insertions(+), 2633 deletions(-) delete mode 100644 tests/src/helpers.js diff --git a/lib/modules/admob/AdMobComponent.js b/lib/modules/admob/AdMobComponent.js index 36ec08d0..c39b4c07 100644 --- a/lib/modules/admob/AdMobComponent.js +++ b/lib/modules/admob/AdMobComponent.js @@ -11,13 +11,15 @@ const adMobPropTypes = { ...ViewPropTypes, size: PropTypes.string.isRequired, unitId: PropTypes.string.isRequired, + /* eslint-disable react/forbid-prop-types */ request: PropTypes.object, video: PropTypes.object, + /* eslint-enable react/forbid-prop-types */ }; -Object.keys(EventTypes).forEach((eventType) => { +Object.keys(EventTypes).forEach(eventType => { adMobPropTypes[eventType] = PropTypes.func; }); -Object.keys(NativeExpressEventTypes).forEach((eventType) => { +Object.keys(NativeExpressEventTypes).forEach(eventType => { adMobPropTypes[eventType] = PropTypes.func; }); @@ -67,7 +69,8 @@ class AdMobComponent extends React.Component { } } - if (nativeEvent.type === 'onSizeChange') this.updateSize(nativeEvent.payload); + if (nativeEvent.type === 'onSizeChange') + this.updateSize(nativeEvent.payload); }; /** diff --git a/lib/modules/admob/AdRequest.js b/lib/modules/admob/AdRequest.js index 69b7236e..41d2d5d6 100644 --- a/lib/modules/admob/AdRequest.js +++ b/lib/modules/admob/AdRequest.js @@ -1,5 +1,4 @@ export default class AdRequest { - constructor() { this._props = { keywords: [], @@ -12,7 +11,7 @@ export default class AdRequest { } addTestDevice(deviceId?: string) { - this._props.testDevices.push(deviceId ? deviceId : 'DEVICE_ID_EMULATOR'); + this._props.testDevices.push(deviceId || 'DEVICE_ID_EMULATOR'); return this; } diff --git a/lib/modules/admob/Banner.js b/lib/modules/admob/Banner.js index c3554703..82eac4e8 100644 --- a/lib/modules/admob/Banner.js +++ b/lib/modules/admob/Banner.js @@ -2,12 +2,7 @@ import React from 'react'; import AdMobComponent from './AdMobComponent'; function Banner({ ...props }) { - return ( - - ); + return ; } Banner.propTypes = AdMobComponent.propTypes; diff --git a/lib/modules/admob/EventTypes.js b/lib/modules/admob/EventTypes.js index d4343633..1afdd1f0 100644 --- a/lib/modules/admob/EventTypes.js +++ b/lib/modules/admob/EventTypes.js @@ -1,4 +1,3 @@ - export default { onAdLoaded: 'onAdLoaded', onAdOpened: 'onAdOpened', @@ -18,4 +17,4 @@ export const NativeExpressEventTypes = { export const RewardedVideoEventTypes = { onRewarded: 'onRewarded', onRewardedVideoStarted: 'onRewardedVideoStarted', -}; \ No newline at end of file +}; diff --git a/lib/modules/admob/Interstitial.js b/lib/modules/admob/Interstitial.js index 06ff6eee..74fcd5d2 100644 --- a/lib/modules/admob/Interstitial.js +++ b/lib/modules/admob/Interstitial.js @@ -9,7 +9,6 @@ const FirebaseAdMob = NativeModules.RNFirebaseAdMob; let subscriptions = []; export default class Interstitial { - constructor(admob: Object, adUnit: string) { // Interstitials on iOS require a new instance each time if (Platform.OS === 'ios') { @@ -25,7 +24,10 @@ export default class Interstitial { this.adUnit = adUnit; this.loaded = false; SharedEventEmitter.removeAllListeners(`interstitial_${adUnit}`); - SharedEventEmitter.addListener(`interstitial_${adUnit}`, this._onInterstitialEvent); + SharedEventEmitter.addListener( + `interstitial_${adUnit}`, + this._onInterstitialEvent + ); } /** @@ -33,7 +35,7 @@ export default class Interstitial { * @param event * @private */ - _onInterstitialEvent = (event) => { + _onInterstitialEvent = event => { const eventType = `interstitial:${this.adUnit}:${event.type}`; let emitData = Object.assign({}, event); @@ -94,11 +96,18 @@ export default class Interstitial { */ on(eventType, listenerCb) { if (!statics.EventTypes[eventType]) { - console.warn(`Invalid event type provided, must be one of: ${Object.keys(statics.EventTypes).join(', ')}`); + console.warn( + `Invalid event type provided, must be one of: ${Object.keys( + statics.EventTypes + ).join(', ')}` + ); return null; } - const sub = SharedEventEmitter.addListener(`interstitial:${this.adUnit}:${eventType}`, listenerCb); + const sub = SharedEventEmitter.addListener( + `interstitial:${this.adUnit}:${eventType}`, + listenerCb + ); subscriptions.push(sub); return sub; } diff --git a/lib/modules/admob/NativeExpress.js b/lib/modules/admob/NativeExpress.js index 6ee7ecfa..1dd57232 100644 --- a/lib/modules/admob/NativeExpress.js +++ b/lib/modules/admob/NativeExpress.js @@ -2,12 +2,7 @@ import React from 'react'; import AdMobComponent from './AdMobComponent'; function NativeExpress({ ...props }) { - return ( - - ); + return ; } NativeExpress.propTypes = AdMobComponent.propTypes; diff --git a/lib/modules/admob/RewardedVideo.js b/lib/modules/admob/RewardedVideo.js index 84b02860..601e5a78 100644 --- a/lib/modules/admob/RewardedVideo.js +++ b/lib/modules/admob/RewardedVideo.js @@ -9,7 +9,6 @@ const FirebaseAdMob = NativeModules.RNFirebaseAdMob; let subscriptions = []; export default class RewardedVideo { - constructor(admob: Object, adUnit: string) { for (let i = 0, len = subscriptions.length; i < len; i++) { subscriptions[i].remove(); @@ -20,7 +19,10 @@ export default class RewardedVideo { this.adUnit = adUnit; this.loaded = false; SharedEventEmitter.removeAllListeners(`rewarded_video_${adUnit}`); - SharedEventEmitter.addListener(`rewarded_video_${adUnit}`, this._onRewardedVideoEvent); + SharedEventEmitter.addListener( + `rewarded_video_${adUnit}`, + this._onRewardedVideoEvent + ); } /** @@ -28,7 +30,7 @@ export default class RewardedVideo { * @param event * @private */ - _onRewardedVideoEvent = (event) => { + _onRewardedVideoEvent = event => { const eventType = `rewarded_video:${this.adUnit}:${event.type}`; let emitData = Object.assign({}, event); @@ -94,11 +96,18 @@ export default class RewardedVideo { }; if (!types[eventType]) { - console.warn(`Invalid event type provided, must be one of: ${Object.keys(types).join(', ')}`); + console.warn( + `Invalid event type provided, must be one of: ${Object.keys(types).join( + ', ' + )}` + ); return null; } - const sub = SharedEventEmitter.addListener(`rewarded_video:${this.adUnit}:${eventType}`, listenerCb); + const sub = SharedEventEmitter.addListener( + `rewarded_video:${this.adUnit}:${eventType}`, + listenerCb + ); subscriptions.push(sub); return sub; } diff --git a/lib/modules/admob/VideoOptions.js b/lib/modules/admob/VideoOptions.js index 0bee19d0..ab8a4777 100644 --- a/lib/modules/admob/VideoOptions.js +++ b/lib/modules/admob/VideoOptions.js @@ -1,5 +1,4 @@ export default class VideoOptions { - constructor() { this._props = { startMuted: true, diff --git a/lib/modules/admob/index.js b/lib/modules/admob/index.js index 6c6e357d..22c26e4b 100644 --- a/lib/modules/admob/index.js +++ b/lib/modules/admob/index.js @@ -25,12 +25,9 @@ type NativeEvent = { adUnit: string, payload: Object, type: string, -} +}; -const NATIVE_EVENTS = [ - 'interstitial_event', - 'rewarded_video_event', -]; +const NATIVE_EVENTS = ['interstitial_event', 'rewarded_video_event']; export const MODULE_NAME = 'RNFirebaseAdmob'; export const NAMESPACE = 'admob'; @@ -50,8 +47,14 @@ export default class AdMob extends ModuleBase { this._initialized = false; this._appId = null; - SharedEventEmitter.addListener('interstitial_event', this._onInterstitialEvent.bind(this)); - SharedEventEmitter.addListener('rewarded_video_event', this._onRewardedVideoEvent.bind(this)); + SharedEventEmitter.addListener( + 'interstitial_event', + this._onInterstitialEvent.bind(this) + ); + SharedEventEmitter.addListener( + 'rewarded_video_event', + this._onRewardedVideoEvent.bind(this) + ); } _onInterstitialEvent(event: NativeEvent): void { @@ -88,7 +91,9 @@ export default class AdMob extends ModuleBase { openDebugMenu(): void { if (!this._initialized) { - getLogger(this).warn('AdMob needs to be initialized before opening the dev menu!'); + getLogger(this).warn( + 'AdMob needs to be initialized before opening the dev menu!' + ); } else { getLogger(this).info('Opening debug menu'); getNativeModule(this).openDebugMenu(this._appId); diff --git a/lib/modules/analytics/index.js b/lib/modules/analytics/index.js index e45678ae..373753d3 100644 --- a/lib/modules/analytics/index.js +++ b/lib/modules/analytics/index.js @@ -46,16 +46,21 @@ export default class Analytics extends ModuleBase { logEvent(name: string, params: Object = {}): void { // check name is not a reserved event name if (ReservedEventNames.includes(name)) { - throw new Error(`event name '${name}' is a reserved event name and can not be used.`); + throw new Error( + `event name '${name}' is a reserved event name and can not be used.` + ); } // name format validation if (!AlphaNumericUnderscore.test(name)) { - throw new Error(`Event name '${name}' is invalid. Names should contain 1 to 32 alphanumeric characters or underscores.`); + throw new Error( + `Event name '${name}' is invalid. Names should contain 1 to 32 alphanumeric characters or underscores.` + ); } // maximum number of allowed params check - if (params && Object.keys(params).length > 25) throw new Error('Maximum number of parameters exceeded (25).'); + if (params && Object.keys(params).length > 25) + throw new Error('Maximum number of parameters exceeded (25).'); // Parameter names can be up to 24 characters long and must start with an alphabetic character // and contain only alphanumeric characters and underscores. Only String, long and double param @@ -121,9 +126,9 @@ export default class Analytics extends ModuleBase { * @param object */ setUserProperties(object: Object): void { - for (const property of Object.keys(object)) { + Object.keys(object).forEach(property => { getNativeModule(this).setUserProperty(property, object[property]); - } + }); } } diff --git a/lib/modules/auth/PhoneAuthListener.js b/lib/modules/auth/PhoneAuthListener.js index 648b249e..838dc86e 100644 --- a/lib/modules/auth/PhoneAuthListener.js +++ b/lib/modules/auth/PhoneAuthListener.js @@ -1,7 +1,14 @@ // @flow import INTERNALS from '../../utils/internals'; import { SharedEventEmitter } from '../../utils/events'; -import { generatePushID, isFunction, isAndroid, isIOS, isString, nativeToJSError } from '../../utils'; +import { + generatePushID, + isFunction, + isAndroid, + isIOS, + isString, + nativeToJSError, +} from '../../utils'; import { getNativeModule } from '../../utils/native'; import type Auth from './'; @@ -50,9 +57,15 @@ export default class PhoneAuthListener { // internal events this._internalEvents = { codeSent: `phone:auth:${this._phoneAuthRequestKey}:onCodeSent`, - verificationFailed: `phone:auth:${this._phoneAuthRequestKey}:onVerificationFailed`, - verificationComplete: `phone:auth:${this._phoneAuthRequestKey}:onVerificationComplete`, - codeAutoRetrievalTimeout: `phone:auth:${this._phoneAuthRequestKey}:onCodeAutoRetrievalTimeout`, + verificationFailed: `phone:auth:${ + this._phoneAuthRequestKey + }:onVerificationFailed`, + verificationComplete: `phone:auth:${ + this._phoneAuthRequestKey + }:onVerificationComplete`, + codeAutoRetrievalTimeout: `phone:auth:${ + this._phoneAuthRequestKey + }:onCodeAutoRetrievalTimeout`, }; // user observer events @@ -73,14 +86,14 @@ export default class PhoneAuthListener { getNativeModule(this._auth).verifyPhoneNumber( phoneNumber, this._phoneAuthRequestKey, - this._timeout, + this._timeout ); } if (isIOS) { getNativeModule(this._auth).verifyPhoneNumber( phoneNumber, - this._phoneAuthRequestKey, + this._phoneAuthRequestKey ); } } @@ -95,7 +108,10 @@ export default class PhoneAuthListener { for (let i = 0, len = events.length; i < len; i++) { const type = events[i]; // $FlowBug: Flow doesn't support indexable signatures on classes: https://github.com/facebook/flow/issues/1323 - SharedEventEmitter.once(this._internalEvents[type], this[`_${type}Handler`].bind(this)); + SharedEventEmitter.once( + this._internalEvents[type], + this[`_${type}Handler`].bind(this) + ); } } @@ -143,14 +159,15 @@ export default class PhoneAuthListener { * @private */ _removeAllListeners() { - setTimeout(() => { // move to next event loop - not sure if needed + setTimeout(() => { + // move to next event loop - not sure if needed // internal listeners - Object.values(this._internalEvents).forEach((event) => { + Object.values(this._internalEvents).forEach(event => { SharedEventEmitter.removeAllListeners(event); }); // user observer listeners - Object.values(this._publicEvents).forEach((publicEvent) => { + Object.values(this._publicEvents).forEach(publicEvent => { SharedEventEmitter.removeAllListeners(publicEvent); }); }, 0); @@ -163,12 +180,12 @@ export default class PhoneAuthListener { _promiseDeferred() { if (!this._promise) { this._promise = new Promise((resolve, reject) => { - this._resolve = (result) => { + this._resolve = result => { this._resolve = null; return resolve(result); }; - this._reject = (possibleError) => { + this._reject = possibleError => { this._reject = null; return reject(possibleError); }; @@ -261,22 +278,36 @@ export default class PhoneAuthListener { this._removeAllListeners(); } - /* ------------- -- PUBLIC API --------------*/ - on(event: string, observer: () => PhoneAuthSnapshot, errorCb?: () => PhoneAuthError, successCb?: () => PhoneAuthSnapshot): this { + on( + event: string, + observer: () => PhoneAuthSnapshot, + errorCb?: () => PhoneAuthError, + successCb?: () => PhoneAuthSnapshot + ): this { if (!isString(event)) { - throw new Error(INTERNALS.STRINGS.ERROR_MISSING_ARG_NAMED('event', 'string', 'on')); + throw new Error( + INTERNALS.STRINGS.ERROR_MISSING_ARG_NAMED('event', 'string', 'on') + ); } if (event !== 'state_changed') { - throw new Error(INTERNALS.STRINGS.ERROR_ARG_INVALID_VALUE('event', 'state_changed', event)); + throw new Error( + INTERNALS.STRINGS.ERROR_ARG_INVALID_VALUE( + 'event', + 'state_changed', + event + ) + ); } if (!isFunction(observer)) { - throw new Error(INTERNALS.STRINGS.ERROR_MISSING_ARG_NAMED('observer', 'function', 'on')); + throw new Error( + INTERNALS.STRINGS.ERROR_MISSING_ARG_NAMED('observer', 'function', 'on') + ); } this._addUserObserver(observer); diff --git a/lib/modules/auth/User.js b/lib/modules/auth/User.js index e4f7a2b0..cd3b3af6 100644 --- a/lib/modules/auth/User.js +++ b/lib/modules/auth/User.js @@ -6,7 +6,13 @@ import INTERNALS from '../../utils/internals'; import { getNativeModule } from '../../utils/native'; import type Auth from './'; -import type { ActionCodeSettings, AuthCredential, NativeUser, UserCredential, UserMetadata } from './types'; +import type { + ActionCodeSettings, + AuthCredential, + NativeUser, + UserCredential, + UserMetadata, +} from './types'; type UserInfo = { displayName?: string, @@ -15,12 +21,12 @@ type UserInfo = { photoURL?: string, providerId: string, uid: string, -} +}; type UpdateProfile = { displayName?: string, photoURL?: string, -} +}; export default class User { _auth: Auth; @@ -110,7 +116,9 @@ export default class User { * @return {Promise} */ getToken(forceRefresh: boolean = false): Promise { - console.warn('Deprecated firebase.User.prototype.getToken in favor of firebase.User.prototype.getIdToken.'); + console.warn( + 'Deprecated firebase.User.prototype.getToken in favor of firebase.User.prototype.getIdToken.' + ); return getNativeModule(this._auth).getToken(forceRefresh); } @@ -119,9 +127,15 @@ export default class User { * @param credential */ linkWithCredential(credential: AuthCredential): Promise { - console.warn('Deprecated firebase.User.prototype.linkWithCredential in favor of firebase.User.prototype.linkAndRetrieveDataWithCredential.'); + console.warn( + 'Deprecated firebase.User.prototype.linkWithCredential in favor of firebase.User.prototype.linkAndRetrieveDataWithCredential.' + ); return getNativeModule(this._auth) - .linkWithCredential(credential.providerId, credential.token, credential.secret) + .linkWithCredential( + credential.providerId, + credential.token, + credential.secret + ) .then(user => this._auth._setUser(user)); } @@ -129,9 +143,15 @@ export default class User { * * @param credential */ - linkAndRetrieveDataWithCredential(credential: AuthCredential): Promise { + linkAndRetrieveDataWithCredential( + credential: AuthCredential + ): Promise { return getNativeModule(this._auth) - .linkAndRetrieveDataWithCredential(credential.providerId, credential.token, credential.secret) + .linkAndRetrieveDataWithCredential( + credential.providerId, + credential.token, + credential.secret + ) .then(userCredential => this._auth._setUserCredential(userCredential)); } @@ -140,10 +160,16 @@ export default class User { * @return {Promise} A promise resolved upon completion */ reauthenticateWithCredential(credential: AuthCredential): Promise { - console.warn('Deprecated firebase.User.prototype.reauthenticateWithCredential in favor of firebase.User.prototype.reauthenticateAndRetrieveDataWithCredential.'); + console.warn( + 'Deprecated firebase.User.prototype.reauthenticateWithCredential in favor of firebase.User.prototype.reauthenticateAndRetrieveDataWithCredential.' + ); return getNativeModule(this._auth) - .reauthenticateWithCredential(credential.providerId, credential.token, credential.secret) - .then((user) => { + .reauthenticateWithCredential( + credential.providerId, + credential.token, + credential.secret + ) + .then(user => { this._auth._setUser(user); }); } @@ -152,9 +178,15 @@ export default class User { * Re-authenticate a user with a third-party authentication provider * @return {Promise} A promise resolved upon completion */ - reauthenticateAndRetrieveDataWithCredential(credential: AuthCredential): Promise { + reauthenticateAndRetrieveDataWithCredential( + credential: AuthCredential + ): Promise { return getNativeModule(this._auth) - .reauthenticateAndRetrieveDataWithCredential(credential.providerId, credential.token, credential.secret) + .reauthenticateAndRetrieveDataWithCredential( + credential.providerId, + credential.token, + credential.secret + ) .then(userCredential => this._auth._setUserCredential(userCredential)); } @@ -165,7 +197,7 @@ export default class User { reload(): Promise { return getNativeModule(this._auth) .reload() - .then((user) => { + .then(user => { this._auth._setUser(user); }); } @@ -173,10 +205,12 @@ export default class User { /** * Send verification email to current user. */ - sendEmailVerification(actionCodeSettings?: ActionCodeSettings): Promise { + sendEmailVerification( + actionCodeSettings?: ActionCodeSettings + ): Promise { return getNativeModule(this._auth) .sendEmailVerification(actionCodeSettings) - .then((user) => { + .then(user => { this._auth._setUser(user); }); } @@ -205,7 +239,7 @@ export default class User { updateEmail(email: string): Promise { return getNativeModule(this._auth) .updateEmail(email) - .then((user) => { + .then(user => { this._auth._setUser(user); }); } @@ -218,7 +252,7 @@ export default class User { updatePassword(password: string): Promise { return getNativeModule(this._auth) .updatePassword(password) - .then((user) => { + .then(user => { this._auth._setUser(user); }); } @@ -231,7 +265,7 @@ export default class User { updateProfile(updates: UpdateProfile = {}): Promise { return getNativeModule(this._auth) .updateProfile(updates) - .then((user) => { + .then(user => { this._auth._setUser(user); }); } @@ -241,34 +275,68 @@ export default class User { */ linkWithPhoneNumber() { - throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD('User', 'linkWithPhoneNumber')); + throw new Error( + INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD( + 'User', + 'linkWithPhoneNumber' + ) + ); } linkWithPopup() { - throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD('User', 'linkWithPopup')); + throw new Error( + INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD('User', 'linkWithPopup') + ); } linkWithRedirect() { - throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD('User', 'linkWithRedirect')); + throw new Error( + INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD( + 'User', + 'linkWithRedirect' + ) + ); } reauthenticateWithPhoneNumber() { - throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD('User', 'reauthenticateWithPhoneNumber')); + throw new Error( + INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD( + 'User', + 'reauthenticateWithPhoneNumber' + ) + ); } reauthenticateWithPopup() { - throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD('User', 'reauthenticateWithPopup')); + throw new Error( + INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD( + 'User', + 'reauthenticateWithPopup' + ) + ); } reauthenticateWithRedirect() { - throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD('User', 'reauthenticateWithRedirect')); + throw new Error( + INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD( + 'User', + 'reauthenticateWithRedirect' + ) + ); } updatePhoneNumber() { - throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD('User', 'updatePhoneNumber')); + throw new Error( + INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD( + 'User', + 'updatePhoneNumber' + ) + ); } get refreshToken(): string { - throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_PROPERTY('User', 'refreshToken')); + throw new Error( + INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_PROPERTY('User', 'refreshToken') + ); } } diff --git a/lib/modules/auth/index.js b/lib/modules/auth/index.js index 325ff79a..2b18b9df 100644 --- a/lib/modules/auth/index.js +++ b/lib/modules/auth/index.js @@ -21,7 +21,13 @@ import FacebookAuthProvider from './providers/FacebookAuthProvider'; import PhoneAuthListener from './PhoneAuthListener'; -import type { ActionCodeSettings, AuthCredential, NativeUser, NativeUserCredential, UserCredential } from './types'; +import type { + ActionCodeSettings, + AuthCredential, + NativeUser, + NativeUserCredential, + UserCredential, +} from './types'; import type App from '../core/firebase-app'; type AuthState = { @@ -34,7 +40,7 @@ type ActionCodeInfo = { fromEmail?: string, }, operation: 'PASSWORD_RESET' | 'VERIFY_EMAIL' | 'RECOVER_EMAIL', -} +}; const NATIVE_EVENTS = [ 'auth_state_changed', @@ -59,7 +65,9 @@ export default class Auth extends ModuleBase { }); this._user = null; this._authResult = false; - this._languageCode = getNativeModule(this).APP_LANGUAGE[app._name] || getNativeModule(this).APP_LANGUAGE['[DEFAULT]']; + this._languageCode = + getNativeModule(this).APP_LANGUAGE[app._name] || + getNativeModule(this).APP_LANGUAGE['[DEFAULT]']; SharedEventEmitter.addListener( // sub to internal native event - this fans out to @@ -67,8 +75,11 @@ export default class Auth extends ModuleBase { getAppEventName(this, 'auth_state_changed'), (state: AuthState) => { this._setUser(state.user); - SharedEventEmitter.emit(getAppEventName(this, 'onAuthStateChanged'), this._user); - }, + SharedEventEmitter.emit( + getAppEventName(this, 'onAuthStateChanged'), + this._user + ); + } ); SharedEventEmitter.addListener( @@ -78,7 +89,7 @@ export default class Auth extends ModuleBase { (event: Object) => { const eventKey = `phone:auth:${event.requestKey}:${event.type}`; SharedEventEmitter.emit(eventKey, event.state); - }, + } ); SharedEventEmitter.addListener( @@ -87,8 +98,11 @@ export default class Auth extends ModuleBase { getAppEventName(this, 'auth_id_token_changed'), (auth: AuthState) => { this._setUser(auth.user); - SharedEventEmitter.emit(getAppEventName(this, 'onIdTokenChanged'), this._user); - }, + SharedEventEmitter.emit( + getAppEventName(this, 'onIdTokenChanged'), + this._user + ); + } ); getNativeModule(this).addAuthStateListener(); @@ -123,12 +137,18 @@ export default class Auth extends ModuleBase { */ onAuthStateChanged(listener: Function) { getLogger(this).info('Creating onAuthStateChanged listener'); - SharedEventEmitter.addListener(getAppEventName(this, 'onAuthStateChanged'), listener); + SharedEventEmitter.addListener( + getAppEventName(this, 'onAuthStateChanged'), + listener + ); if (this._authResult) listener(this._user || null); return () => { getLogger(this).info('Removing onAuthStateChanged listener'); - SharedEventEmitter.removeListener(getAppEventName(this, 'onAuthStateChanged'), listener); + SharedEventEmitter.removeListener( + getAppEventName(this, 'onAuthStateChanged'), + listener + ); }; } @@ -138,12 +158,18 @@ export default class Auth extends ModuleBase { */ onIdTokenChanged(listener: Function) { getLogger(this).info('Creating onIdTokenChanged listener'); - SharedEventEmitter.addListener(getAppEventName(this, 'onIdTokenChanged'), listener); + SharedEventEmitter.addListener( + getAppEventName(this, 'onIdTokenChanged'), + listener + ); if (this._authResult) listener(this._user || null); return () => { getLogger(this).info('Removing onIdTokenChanged listener'); - SharedEventEmitter.removeListener(getAppEventName(this, 'onIdTokenChanged'), listener); + SharedEventEmitter.removeListener( + getAppEventName(this, 'onIdTokenChanged'), + listener + ); }; } @@ -153,12 +179,18 @@ export default class Auth extends ModuleBase { */ onUserChanged(listener: Function) { getLogger(this).info('Creating onUserChanged listener'); - SharedEventEmitter.addListener(getAppEventName(this, 'onUserChanged'), listener); + SharedEventEmitter.addListener( + getAppEventName(this, 'onUserChanged'), + listener + ); if (this._authResult) listener(this._user || null); return () => { getLogger(this).info('Removing onUserChanged listener'); - SharedEventEmitter.removeListener(getAppEventName(this, 'onUserChanged'), listener); + SharedEventEmitter.removeListener( + getAppEventName(this, 'onUserChanged'), + listener + ); }; } @@ -180,7 +212,9 @@ export default class Auth extends ModuleBase { * @return {Promise} A promise resolved upon completion */ signInAnonymously(): Promise { - console.warn('Deprecated firebase.User.prototype.signInAnonymously in favor of firebase.User.prototype.signInAnonymouslyAndRetrieveData.'); + console.warn( + 'Deprecated firebase.User.prototype.signInAnonymously in favor of firebase.User.prototype.signInAnonymouslyAndRetrieveData.' + ); return getNativeModule(this) .signInAnonymously() .then(user => this._setUser(user)); @@ -203,8 +237,13 @@ export default class Auth extends ModuleBase { * @param {string} password The user's password * @return {Promise} A promise indicating the completion */ - createUserWithEmailAndPassword(email: string, password: string): Promise { - console.warn('Deprecated firebase.User.prototype.createUserWithEmailAndPassword in favor of firebase.User.prototype.createUserAndRetrieveDataWithEmailAndPassword.'); + createUserWithEmailAndPassword( + email: string, + password: string + ): Promise { + console.warn( + 'Deprecated firebase.User.prototype.createUserWithEmailAndPassword in favor of firebase.User.prototype.createUserAndRetrieveDataWithEmailAndPassword.' + ); return getNativeModule(this) .createUserWithEmailAndPassword(email, password) .then(user => this._setUser(user)); @@ -216,7 +255,10 @@ export default class Auth extends ModuleBase { * @param {string} password The user's password * @return {Promise} A promise indicating the completion */ - createUserAndRetrieveDataWithEmailAndPassword(email: string, password: string): Promise { + createUserAndRetrieveDataWithEmailAndPassword( + email: string, + password: string + ): Promise { return getNativeModule(this) .createUserAndRetrieveDataWithEmailAndPassword(email, password) .then(userCredential => this._setUserCredential(userCredential)); @@ -230,7 +272,9 @@ export default class Auth extends ModuleBase { * @return {Promise} A promise that is resolved upon completion */ signInWithEmailAndPassword(email: string, password: string): Promise { - console.warn('Deprecated firebase.User.prototype.signInWithEmailAndPassword in favor of firebase.User.prototype.signInAndRetrieveDataWithEmailAndPassword.'); + console.warn( + 'Deprecated firebase.User.prototype.signInWithEmailAndPassword in favor of firebase.User.prototype.signInAndRetrieveDataWithEmailAndPassword.' + ); return getNativeModule(this) .signInWithEmailAndPassword(email, password) .then(user => this._setUser(user)); @@ -242,7 +286,10 @@ export default class Auth extends ModuleBase { * @param {string} password The user's password * @return {Promise} A promise that is resolved upon completion */ - signInAndRetrieveDataWithEmailAndPassword(email: string, password: string): Promise { + signInAndRetrieveDataWithEmailAndPassword( + email: string, + password: string + ): Promise { return getNativeModule(this) .signInAndRetrieveDataWithEmailAndPassword(email, password) .then(userCredential => this._setUserCredential(userCredential)); @@ -255,7 +302,9 @@ export default class Auth extends ModuleBase { * @return {Promise} A promise resolved upon completion */ signInWithCustomToken(customToken: string): Promise { - console.warn('Deprecated firebase.User.prototype.signInWithCustomToken in favor of firebase.User.prototype.signInAndRetrieveDataWithCustomToken.'); + console.warn( + 'Deprecated firebase.User.prototype.signInWithCustomToken in favor of firebase.User.prototype.signInAndRetrieveDataWithCustomToken.' + ); return getNativeModule(this) .signInWithCustomToken(customToken) .then(user => this._setUser(user)); @@ -266,7 +315,9 @@ export default class Auth extends ModuleBase { * @param {string} customToken A self-signed custom auth token. * @return {Promise} A promise resolved upon completion */ - signInAndRetrieveDataWithCustomToken(customToken: string): Promise { + signInAndRetrieveDataWithCustomToken( + customToken: string + ): Promise { return getNativeModule(this) .signInAndRetrieveDataWithCustomToken(customToken) .then(userCredential => this._setUserCredential(userCredential)); @@ -278,9 +329,15 @@ export default class Auth extends ModuleBase { * @return {Promise} A promise resolved upon completion */ signInWithCredential(credential: AuthCredential): Promise { - console.warn('Deprecated firebase.User.prototype.signInWithCredential in favor of firebase.User.prototype.signInAndRetrieveDataWithCredential.'); + console.warn( + 'Deprecated firebase.User.prototype.signInWithCredential in favor of firebase.User.prototype.signInAndRetrieveDataWithCredential.' + ); return getNativeModule(this) - .signInWithCredential(credential.providerId, credential.token, credential.secret) + .signInWithCredential( + credential.providerId, + credential.token, + credential.secret + ) .then(user => this._setUser(user)); } @@ -288,9 +345,15 @@ export default class Auth extends ModuleBase { * Sign the user in with a third-party authentication provider * @return {Promise} A promise resolved upon completion */ - signInAndRetrieveDataWithCredential(credential: AuthCredential): Promise { + signInAndRetrieveDataWithCredential( + credential: AuthCredential + ): Promise { return getNativeModule(this) - .signInAndRetrieveDataWithCredential(credential.providerId, credential.token, credential.secret) + .signInAndRetrieveDataWithCredential( + credential.providerId, + credential.token, + credential.secret + ) .then(userCredential => this._setUserCredential(userCredential)); } @@ -301,9 +364,7 @@ export default class Auth extends ModuleBase { signInWithPhoneNumber(phoneNumber: string): Promise { return getNativeModule(this) .signInWithPhoneNumber(phoneNumber) - .then((result) => { - return new ConfirmationResult(this, result.verificationId); - }); + .then(result => new ConfirmationResult(this, result.verificationId)); } /** @@ -315,7 +376,10 @@ export default class Auth extends ModuleBase { * @param autoVerifyTimeout Android Only * @returns {PhoneAuthListener} */ - verifyPhoneNumber(phoneNumber: string, autoVerifyTimeout?: number): PhoneAuthListener { + verifyPhoneNumber( + phoneNumber: string, + autoVerifyTimeout?: number + ): PhoneAuthListener { return new PhoneAuthListener(this, phoneNumber, autoVerifyTimeout); } @@ -323,8 +387,14 @@ export default class Auth extends ModuleBase { * Send reset password instructions via email * @param {string} email The email to send password reset instructions */ - sendPasswordResetEmail(email: string, actionCodeSettings?: ActionCodeSettings): Promise { - return getNativeModule(this).sendPasswordResetEmail(email, actionCodeSettings); + sendPasswordResetEmail( + email: string, + actionCodeSettings?: ActionCodeSettings + ): Promise { + return getNativeModule(this).sendPasswordResetEmail( + email, + actionCodeSettings + ); } /** @@ -400,24 +470,49 @@ export default class Auth extends ModuleBase { */ getRedirectResult() { - throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD('auth', 'getRedirectResult')); + throw new Error( + INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD( + 'auth', + 'getRedirectResult' + ) + ); } setPersistence() { - throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD('auth', 'setPersistence')); + throw new Error( + INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD( + 'auth', + 'setPersistence' + ) + ); } signInWithPopup() { - throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD('auth', 'signInWithPopup')); + throw new Error( + INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD( + 'auth', + 'signInWithPopup' + ) + ); } signInWithRedirect() { - throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD('auth', 'signInWithRedirect')); + throw new Error( + INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD( + 'auth', + 'signInWithRedirect' + ) + ); } // firebase issue - https://github.com/invertase/react-native-firebase/pull/655#issuecomment-349904680 useDeviceLanguage() { - throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD('auth', 'useDeviceLanguage')); + throw new Error( + INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD( + 'auth', + 'useDeviceLanguage' + ) + ); } } diff --git a/lib/modules/auth/providers/EmailAuthProvider.js b/lib/modules/auth/providers/EmailAuthProvider.js index 0cdfe5ba..0c37d661 100644 --- a/lib/modules/auth/providers/EmailAuthProvider.js +++ b/lib/modules/auth/providers/EmailAuthProvider.js @@ -8,7 +8,9 @@ const providerId = 'password'; export default class EmailAuthProvider { constructor() { - throw new Error('`new EmailAuthProvider()` is not supported on the native Firebase SDKs.'); + throw new Error( + '`new EmailAuthProvider()` is not supported on the native Firebase SDKs.' + ); } static get PROVIDER_ID(): string { diff --git a/lib/modules/auth/providers/FacebookAuthProvider.js b/lib/modules/auth/providers/FacebookAuthProvider.js index fa1dfb35..67fa957b 100644 --- a/lib/modules/auth/providers/FacebookAuthProvider.js +++ b/lib/modules/auth/providers/FacebookAuthProvider.js @@ -8,7 +8,9 @@ const providerId = 'facebook.com'; export default class FacebookAuthProvider { constructor() { - throw new Error('`new FacebookAuthProvider()` is not supported on the native Firebase SDKs.'); + throw new Error( + '`new FacebookAuthProvider()` is not supported on the native Firebase SDKs.' + ); } static get PROVIDER_ID(): string { diff --git a/lib/modules/auth/providers/GithubAuthProvider.js b/lib/modules/auth/providers/GithubAuthProvider.js index 46a5bef8..a6e8c13c 100644 --- a/lib/modules/auth/providers/GithubAuthProvider.js +++ b/lib/modules/auth/providers/GithubAuthProvider.js @@ -8,7 +8,9 @@ const providerId = 'github.com'; export default class GithubAuthProvider { constructor() { - throw new Error('`new GithubAuthProvider()` is not supported on the native Firebase SDKs.'); + throw new Error( + '`new GithubAuthProvider()` is not supported on the native Firebase SDKs.' + ); } static get PROVIDER_ID(): string { diff --git a/lib/modules/auth/providers/GoogleAuthProvider.js b/lib/modules/auth/providers/GoogleAuthProvider.js index 09bc5353..25c81a21 100644 --- a/lib/modules/auth/providers/GoogleAuthProvider.js +++ b/lib/modules/auth/providers/GoogleAuthProvider.js @@ -8,7 +8,9 @@ const providerId = 'google.com'; export default class GoogleAuthProvider { constructor() { - throw new Error('`new GoogleAuthProvider()` is not supported on the native Firebase SDKs.'); + throw new Error( + '`new GoogleAuthProvider()` is not supported on the native Firebase SDKs.' + ); } static get PROVIDER_ID(): string { diff --git a/lib/modules/auth/providers/OAuthProvider.js b/lib/modules/auth/providers/OAuthProvider.js index 475e0666..2bd28ed2 100644 --- a/lib/modules/auth/providers/OAuthProvider.js +++ b/lib/modules/auth/providers/OAuthProvider.js @@ -8,7 +8,9 @@ const providerId = 'oauth'; export default class OAuthProvider { constructor() { - throw new Error('`new OAuthProvider()` is not supported on the native Firebase SDKs.'); + throw new Error( + '`new OAuthProvider()` is not supported on the native Firebase SDKs.' + ); } static get PROVIDER_ID(): string { diff --git a/lib/modules/auth/providers/PhoneAuthProvider.js b/lib/modules/auth/providers/PhoneAuthProvider.js index e5c25d90..57ce6558 100644 --- a/lib/modules/auth/providers/PhoneAuthProvider.js +++ b/lib/modules/auth/providers/PhoneAuthProvider.js @@ -8,7 +8,9 @@ const providerId = 'phone'; export default class PhoneAuthProvider { constructor() { - throw new Error('`new PhoneAuthProvider()` is not supported on the native Firebase SDKs.'); + throw new Error( + '`new PhoneAuthProvider()` is not supported on the native Firebase SDKs.' + ); } static get PROVIDER_ID(): string { diff --git a/lib/modules/auth/providers/TwitterAuthProvider.js b/lib/modules/auth/providers/TwitterAuthProvider.js index 8582ddaa..150926bb 100644 --- a/lib/modules/auth/providers/TwitterAuthProvider.js +++ b/lib/modules/auth/providers/TwitterAuthProvider.js @@ -8,7 +8,9 @@ const providerId = 'twitter.com'; export default class TwitterAuthProvider { constructor() { - throw new Error('`new TwitterAuthProvider()` is not supported on the native Firebase SDKs.'); + throw new Error( + '`new TwitterAuthProvider()` is not supported on the native Firebase SDKs.' + ); } static get PROVIDER_ID(): string { diff --git a/lib/modules/auth/types.js b/lib/modules/auth/types.js index a5fc3d22..8f40d619 100644 --- a/lib/modules/auth/types.js +++ b/lib/modules/auth/types.js @@ -14,25 +14,25 @@ export type ActionCodeSettings = { bundleId?: string, }, url: string, -} +}; type AdditionalUserInfo = { isNewUser: boolean, profile?: Object, providerId: string, username?: string, -} +}; export type AuthCredential = { providerId: string, token: string, - secret: string -} + secret: string, +}; export type UserCredential = {| additionalUserInfo?: AdditionalUserInfo, user: User, -|} +|}; export type UserInfo = { displayName?: string, @@ -41,12 +41,12 @@ export type UserInfo = { photoURL?: string, providerId: string, uid: string, -} +}; export type UserMetadata = { creationTime?: string, lastSignInTime?: string, -} +}; export type NativeUser = { displayName?: string, @@ -59,9 +59,9 @@ export type NativeUser = { providerData: UserInfo[], providerId: string, uid: string, -} +}; export type NativeUserCredential = {| additionalUserInfo?: AdditionalUserInfo, user: NativeUser, -|} +|}; diff --git a/lib/modules/config/index.js b/lib/modules/config/index.js index bede5a48..f6535d6d 100644 --- a/lib/modules/config/index.js +++ b/lib/modules/config/index.js @@ -13,8 +13,11 @@ type NativeValue = { numberValue?: number, dataValue?: Object, boolValue?: boolean, - source: 'remoteConfigSourceRemote' | 'remoteConfigSourceDefault' | ' remoteConfigSourceStatic', -} + source: + | 'remoteConfigSourceRemote' + | 'remoteConfigSourceDefault' + | ' remoteConfigSourceStatic', +}; export const MODULE_NAME = 'RNFirebaseRemoteConfig'; export const NAMESPACE = 'config'; @@ -44,9 +47,26 @@ export default class RemoteConfig extends ModuleBase { return { source: nativeValue.source, val() { - if (nativeValue.boolValue !== null && (nativeValue.stringValue === 'true' || nativeValue.stringValue === 'false' || nativeValue.stringValue === null)) return nativeValue.boolValue; - if (nativeValue.numberValue !== null && nativeValue.numberValue !== undefined && (nativeValue.stringValue == null || nativeValue.stringValue === '' || nativeValue.numberValue.toString() === nativeValue.stringValue)) return nativeValue.numberValue; - if (nativeValue.dataValue !== nativeValue.stringValue && (nativeValue.stringValue == null || nativeValue.stringValue === '')) return nativeValue.dataValue; + if ( + nativeValue.boolValue !== null && + (nativeValue.stringValue === 'true' || + nativeValue.stringValue === 'false' || + nativeValue.stringValue === null) + ) + return nativeValue.boolValue; + if ( + nativeValue.numberValue !== null && + nativeValue.numberValue !== undefined && + (nativeValue.stringValue == null || + nativeValue.stringValue === '' || + nativeValue.numberValue.toString() === nativeValue.stringValue) + ) + return nativeValue.numberValue; + if ( + nativeValue.dataValue !== nativeValue.stringValue && + (nativeValue.stringValue == null || nativeValue.stringValue === '') + ) + return nativeValue.dataValue; return nativeValue.stringValue; }, }; @@ -70,7 +90,9 @@ export default class RemoteConfig extends ModuleBase { */ fetch(expiration?: number) { if (expiration !== undefined) { - getLogger(this).debug(`Fetching remote config data with expiration ${expiration.toString()}`); + getLogger(this).debug( + `Fetching remote config data with expiration ${expiration.toString()}` + ); return getNativeModule(this).fetchWithExpirationDuration(expiration); } getLogger(this).debug('Fetching remote config data'); @@ -124,7 +146,7 @@ export default class RemoteConfig extends ModuleBase { getValues(keys: Array) { return getNativeModule(this) .getValues(keys || []) - .then((nativeValues) => { + .then(nativeValues => { const values: { [String]: Object } = {}; for (let i = 0, len = keys.length; i < len; i++) { values[keys[i]] = this._nativeValueToJS(nativeValues[i]); diff --git a/lib/modules/core/firebase-app.js b/lib/modules/core/firebase-app.js index a10eb140..1f81e6aa 100644 --- a/lib/modules/core/firebase-app.js +++ b/lib/modules/core/firebase-app.js @@ -13,7 +13,9 @@ import Auth, { NAMESPACE as AuthNamespace } from '../auth'; import Analytics, { NAMESPACE as AnalyticsNamespace } from '../analytics'; import Config, { NAMESPACE as ConfigNamespace } from '../config'; import Crash, { NAMESPACE as CrashNamespace } from '../crash'; -import Crashlytics, { NAMESPACE as CrashlyticsNamespace } from '../fabric/crashlytics'; +import Crashlytics, { + NAMESPACE as CrashlyticsNamespace, +} from '../fabric/crashlytics'; import Database, { NAMESPACE as DatabaseNamespace } from '../database'; import Firestore, { NAMESPACE as FirestoreNamespace } from '../firestore'; import Links, { NAMESPACE as LinksNamespace } from '../links'; @@ -22,15 +24,12 @@ import Performance, { NAMESPACE as PerfNamespace } from '../perf'; import Storage, { NAMESPACE as StorageNamespace } from '../storage'; import Utils, { NAMESPACE as UtilsNamespace } from '../utils'; -import type { - FirebaseOptions, -} from '../../types'; +import type { FirebaseOptions } from '../../types'; const FirebaseCoreModule = NativeModules.RNFirebase; - export default class App { - _extendedProps: { [string] : boolean }; + _extendedProps: { [string]: boolean }; _initialized: boolean = false; _name: string; _nativeInitialized: boolean = false; @@ -51,7 +50,11 @@ export default class App { storage: () => Storage; utils: () => Utils; - constructor(name: string, options: FirebaseOptions, fromNative: boolean = false) { + constructor( + name: string, + options: FirebaseOptions, + fromNative: boolean = false + ) { this._name = name; this._options = Object.assign({}, options); @@ -59,10 +62,14 @@ export default class App { this._initialized = true; this._nativeInitialized = true; } else if (options.databaseURL && options.apiKey) { - FirebaseCoreModule.initializeApp(this._name, this._options, (error, result) => { - this._initialized = true; - SharedEventEmitter.emit(`AppReady:${this._name}`, { error, result }); - }); + FirebaseCoreModule.initializeApp( + this._name, + this._options, + (error, result) => { + this._initialized = true; + SharedEventEmitter.emit(`AppReady:${this._name}`, { error, result }); + } + ); } // modules @@ -109,7 +116,10 @@ export default class App { * @param props */ extendApp(props: Object) { - if (!isObject(props)) throw new Error(INTERNALS.STRINGS.ERROR_MISSING_ARG('Object', 'extendApp')); + if (!isObject(props)) + throw new Error( + INTERNALS.STRINGS.ERROR_MISSING_ARG('Object', 'extendApp') + ); const keys = Object.keys(props); for (let i = 0, len = keys.length; i < len; i++) { @@ -130,7 +140,9 @@ export default class App { * @return {Promise} */ delete() { - throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD('app', 'delete')); + throw new Error( + INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD('app', 'delete') + ); // TODO only the ios sdk currently supports delete, add back in when android also supports it // if (this._name === APPS.DEFAULT_APP_NAME && this._nativeInitialized) { // return Promise.reject( @@ -141,7 +153,6 @@ export default class App { // return FirebaseCoreModule.deleteApp(this._name); } - /** * * @return {*} diff --git a/lib/modules/core/firebase.js b/lib/modules/core/firebase.js index 78317e82..13aad29d 100644 --- a/lib/modules/core/firebase.js +++ b/lib/modules/core/firebase.js @@ -10,19 +10,55 @@ import App from './firebase-app'; import VERSION from '../../version'; // module imports -import { statics as AdMobStatics, MODULE_NAME as AdmobModuleName } from '../admob'; +import { + statics as AdMobStatics, + MODULE_NAME as AdmobModuleName, +} from '../admob'; import { statics as AuthStatics, MODULE_NAME as AuthModuleName } from '../auth'; -import { statics as AnalyticsStatics, MODULE_NAME as AnalyticsModuleName } from '../analytics'; -import { statics as ConfigStatics, MODULE_NAME as ConfigModuleName } from '../config'; -import { statics as CrashStatics, MODULE_NAME as CrashModuleName } from '../crash'; -import { statics as CrashlyticsStatics, MODULE_NAME as CrashlyticsModuleName } from '../fabric/crashlytics'; -import { statics as DatabaseStatics, MODULE_NAME as DatabaseModuleName } from '../database'; -import { statics as FirestoreStatics, MODULE_NAME as FirestoreModuleName } from '../firestore'; -import { statics as LinksStatics, MODULE_NAME as LinksModuleName } from '../links'; -import { statics as MessagingStatics, MODULE_NAME as MessagingModuleName } from '../messaging'; -import { statics as PerformanceStatics, MODULE_NAME as PerfModuleName } from '../perf'; -import { statics as StorageStatics, MODULE_NAME as StorageModuleName } from '../storage'; -import { statics as UtilsStatics, MODULE_NAME as UtilsModuleName } from '../utils'; +import { + statics as AnalyticsStatics, + MODULE_NAME as AnalyticsModuleName, +} from '../analytics'; +import { + statics as ConfigStatics, + MODULE_NAME as ConfigModuleName, +} from '../config'; +import { + statics as CrashStatics, + MODULE_NAME as CrashModuleName, +} from '../crash'; +import { + statics as CrashlyticsStatics, + MODULE_NAME as CrashlyticsModuleName, +} from '../fabric/crashlytics'; +import { + statics as DatabaseStatics, + MODULE_NAME as DatabaseModuleName, +} from '../database'; +import { + statics as FirestoreStatics, + MODULE_NAME as FirestoreModuleName, +} from '../firestore'; +import { + statics as LinksStatics, + MODULE_NAME as LinksModuleName, +} from '../links'; +import { + statics as MessagingStatics, + MODULE_NAME as MessagingModuleName, +} from '../messaging'; +import { + statics as PerformanceStatics, + MODULE_NAME as PerfModuleName, +} from '../perf'; +import { + statics as StorageStatics, + MODULE_NAME as StorageModuleName, +} from '../storage'; +import { + statics as UtilsStatics, + MODULE_NAME as UtilsModuleName, +} from '../utils'; import type { AdMobModule, @@ -60,25 +96,57 @@ class Firebase { constructor() { if (!FirebaseCoreModule) { - throw (new Error(INTERNALS.STRINGS.ERROR_MISSING_CORE)); + throw new Error(INTERNALS.STRINGS.ERROR_MISSING_CORE); } APPS.initializeNativeApps(); // modules this.admob = APPS.moduleAndStatics('admob', AdMobStatics, AdmobModuleName); - this.analytics = APPS.moduleAndStatics('analytics', AnalyticsStatics, AnalyticsModuleName); + this.analytics = APPS.moduleAndStatics( + 'analytics', + AnalyticsStatics, + AnalyticsModuleName + ); this.auth = APPS.moduleAndStatics('auth', AuthStatics, AuthModuleName); - this.config = APPS.moduleAndStatics('config', ConfigStatics, ConfigModuleName); + this.config = APPS.moduleAndStatics( + 'config', + ConfigStatics, + ConfigModuleName + ); this.crash = APPS.moduleAndStatics('crash', CrashStatics, CrashModuleName); - this.database = APPS.moduleAndStatics('database', DatabaseStatics, DatabaseModuleName); + this.database = APPS.moduleAndStatics( + 'database', + DatabaseStatics, + DatabaseModuleName + ); this.fabric = { - crashlytics: APPS.moduleAndStatics('crashlytics', CrashlyticsStatics, CrashlyticsModuleName), + crashlytics: APPS.moduleAndStatics( + 'crashlytics', + CrashlyticsStatics, + CrashlyticsModuleName + ), }; - this.firestore = APPS.moduleAndStatics('firestore', FirestoreStatics, FirestoreModuleName); + this.firestore = APPS.moduleAndStatics( + 'firestore', + FirestoreStatics, + FirestoreModuleName + ); this.links = APPS.moduleAndStatics('links', LinksStatics, LinksModuleName); - this.messaging = APPS.moduleAndStatics('messaging', MessagingStatics, MessagingModuleName); - this.perf = APPS.moduleAndStatics('perf', PerformanceStatics, PerfModuleName); - this.storage = APPS.moduleAndStatics('storage', StorageStatics, StorageModuleName); + this.messaging = APPS.moduleAndStatics( + 'messaging', + MessagingStatics, + MessagingModuleName + ); + this.perf = APPS.moduleAndStatics( + 'perf', + PerformanceStatics, + PerfModuleName + ); + this.storage = APPS.moduleAndStatics( + 'storage', + StorageStatics, + StorageModuleName + ); this.utils = APPS.moduleAndStatics('utils', UtilsStatics, UtilsModuleName); } diff --git a/lib/modules/database/disconnect.js b/lib/modules/database/disconnect.js index 5266bc22..3ec940b6 100644 --- a/lib/modules/database/disconnect.js +++ b/lib/modules/database/disconnect.js @@ -7,7 +7,6 @@ import { getNativeModule } from '../../utils/native'; import type Database from './'; import type Reference from './reference'; - /** * @url https://firebase.google.com/docs/reference/js/firebase.database.OnDisconnect * @class Disconnect @@ -33,7 +32,10 @@ export default class Disconnect { * @returns {*} */ set(value: string | Object): Promise { - return getNativeModule(this._database).onDisconnectSet(this.path, { type: typeOf(value), value }); + return getNativeModule(this._database).onDisconnectSet(this.path, { + type: typeOf(value), + value, + }); } /** @@ -42,7 +44,10 @@ export default class Disconnect { * @returns {*} */ update(values: Object): Promise { - return getNativeModule(this._database).onDisconnectUpdate(this.path, values); + return getNativeModule(this._database).onDisconnectUpdate( + this.path, + values + ); } /** diff --git a/lib/modules/database/index.js b/lib/modules/database/index.js index d2fa1da0..c921c565 100644 --- a/lib/modules/database/index.js +++ b/lib/modules/database/index.js @@ -47,7 +47,7 @@ export default class Database extends ModuleBase { setTimeout(() => { this._serverTimeOffset = 0; this._offsetRef = this.ref('.info/serverTimeOffset'); - this._offsetRef.on('value', (snapshot) => { + this._offsetRef.on('value', snapshot => { this._serverTimeOffset = snapshot.val() || this._serverTimeOffset; }); }, 1); @@ -86,9 +86,13 @@ export default class Database extends ModuleBase { } export const statics = { - ServerValue: NativeModules.RNFirebaseDatabase ? { - TIMESTAMP: NativeModules.RNFirebaseDatabase.serverValueTimestamp || { '.sv': 'timestamp' }, - } : {}, + ServerValue: NativeModules.RNFirebaseDatabase + ? { + TIMESTAMP: NativeModules.RNFirebaseDatabase.serverValueTimestamp || { + '.sv': 'timestamp', + }, + } + : {}, enableLogging(enabled: boolean) { if (NativeModules[MODULE_NAME]) { NativeModules[MODULE_NAME].enableLogging(enabled); diff --git a/lib/modules/database/query.js b/lib/modules/database/query.js index 47192f22..cc200e27 100644 --- a/lib/modules/database/query.js +++ b/lib/modules/database/query.js @@ -5,7 +5,7 @@ import { objectToUniqueId } from '../../utils'; import type { DatabaseModifier } from '../../types'; -import type Reference from './reference.js'; +import type Reference from './reference'; // todo doc methods @@ -16,7 +16,11 @@ export default class Query { _reference: Reference; modifiers: Array; - constructor(ref: Reference, path: string, existingModifiers?: Array) { + constructor( + ref: Reference, + path: string, + existingModifiers?: Array + ) { this.modifiers = existingModifiers ? [...existingModifiers] : []; this._reference = ref; } diff --git a/lib/modules/database/reference.js b/lib/modules/database/reference.js index 42f41a96..739f6121 100644 --- a/lib/modules/database/reference.js +++ b/lib/modules/database/reference.js @@ -2,7 +2,7 @@ * @flow * Database Reference representation wrapper */ -import Query from './query.js'; +import Query from './query'; import Snapshot from './snapshot'; import Disconnect from './disconnect'; import { getLogger } from '../../utils/log'; @@ -41,11 +41,11 @@ const ReferenceEventTypes = { }; type DatabaseListener = { - listenerId: number; - eventName: string; - successCallback: Function; - failureCallback?: Function; -} + listenerId: number, + eventName: string, + successCallback: Function, + failureCallback?: Function, +}; /** * @typedef {String} ReferenceLocation - Path to location in the database, relative @@ -80,7 +80,11 @@ export default class Reference extends ReferenceBase { _query: Query; _refListeners: { [listenerId: number]: DatabaseListener }; - constructor(database: Database, path: string, existingModifiers?: Array) { + constructor( + database: Database, + path: string, + existingModifiers?: Array + ) { super(path); this._promise = null; this._refListeners = {}; @@ -100,7 +104,12 @@ export default class Reference extends ReferenceBase { * @returns {*} */ keepSynced(bool: boolean): Promise { - return getNativeModule(this._database).keepSynced(this._getRefKey(), this.path, this._query.getModifiers(), bool); + return getNativeModule(this._database).keepSynced( + this._getRefKey(), + this.path, + this._query.getModifiers(), + bool + ); } /** @@ -113,8 +122,11 @@ export default class Reference extends ReferenceBase { */ set(value: any, onComplete?: Function): Promise { return promiseOrCallback( - getNativeModule(this._database).set(this.path, this._serializeAnyType(value)), - onComplete, + getNativeModule(this._database).set( + this.path, + this._serializeAnyType(value) + ), + onComplete ); } @@ -126,12 +138,15 @@ export default class Reference extends ReferenceBase { * @param onComplete * @returns {Promise} */ - setPriority(priority: string | number | null, onComplete?: Function): Promise { + setPriority( + priority: string | number | null, + onComplete?: Function + ): Promise { const _priority = this._serializeAnyType(priority); return promiseOrCallback( getNativeModule(this._database).setPriority(this.path, _priority), - onComplete, + onComplete ); } @@ -144,13 +159,21 @@ export default class Reference extends ReferenceBase { * @param onComplete * @returns {Promise} */ - setWithPriority(value: any, priority: string | number | null, onComplete?: Function): Promise { + setWithPriority( + value: any, + priority: string | number | null, + onComplete?: Function + ): Promise { const _value = this._serializeAnyType(value); const _priority = this._serializeAnyType(priority); return promiseOrCallback( - getNativeModule(this._database).setWithPriority(this.path, _value, _priority), - onComplete, + getNativeModule(this._database).setWithPriority( + this.path, + _value, + _priority + ), + onComplete ); } @@ -167,7 +190,7 @@ export default class Reference extends ReferenceBase { return promiseOrCallback( getNativeModule(this._database).update(this.path, value), - onComplete, + onComplete ); } @@ -181,7 +204,7 @@ export default class Reference extends ReferenceBase { remove(onComplete?: Function): Promise { return promiseOrCallback( getNativeModule(this._database).remove(this.path), - onComplete, + onComplete ); } @@ -196,10 +219,12 @@ export default class Reference extends ReferenceBase { transaction( transactionUpdate: Function, onComplete: (error: ?Error, committed: boolean, snapshot: ?Snapshot) => *, - applyLocally: boolean = false, + applyLocally: boolean = false ) { if (!isFunction(transactionUpdate)) { - return Promise.reject(new Error('Missing transactionUpdate function argument.')); + return Promise.reject( + new Error('Missing transactionUpdate function argument.') + ); } return new Promise((resolve, reject) => { @@ -213,15 +238,22 @@ export default class Reference extends ReferenceBase { } if (error) return reject(error); - return resolve({ committed, snapshot: new Snapshot(this, snapshotData) }); + return resolve({ + committed, + snapshot: new Snapshot(this, snapshotData), + }); }; // start the transaction natively - this._database._transactionHandler.add(this, transactionUpdate, onCompleteWrapper, applyLocally); + this._database._transactionHandler.add( + this, + transactionUpdate, + onCompleteWrapper, + applyLocally + ); }); } - /** * * @param eventName @@ -234,21 +266,24 @@ export default class Reference extends ReferenceBase { eventName: string = 'value', successCallback: (snapshot: Object) => void, cancelOrContext: (error: FirebaseError) => void, - context?: Object, + context?: Object ) { - return getNativeModule(this._database).once(this._getRefKey(), this.path, this._query.getModifiers(), eventName) + return getNativeModule(this._database) + .once(this._getRefKey(), this.path, this._query.getModifiers(), eventName) .then(({ snapshot }) => { const _snapshot = new Snapshot(this, snapshot); if (isFunction(successCallback)) { - if (isObject(cancelOrContext)) successCallback.bind(cancelOrContext)(_snapshot); - if (context && isObject(context)) successCallback.bind(context)(_snapshot); + if (isObject(cancelOrContext)) + successCallback.bind(cancelOrContext)(_snapshot); + if (context && isObject(context)) + successCallback.bind(context)(_snapshot); successCallback(_snapshot); } return _snapshot; }) - .catch((error) => { + .catch(error => { if (isFunction(cancelOrContext)) return cancelOrContext(error); return error; }); @@ -262,19 +297,27 @@ export default class Reference extends ReferenceBase { */ push(value: any, onComplete?: Function): Reference | Promise { if (value === null || value === undefined) { - return new Reference(this._database, `${this.path}/${generatePushID(this._database._serverTimeOffset)}`); + return new Reference( + this._database, + `${this.path}/${generatePushID(this._database._serverTimeOffset)}` + ); } - const newRef = new Reference(this._database, `${this.path}/${generatePushID(this._database._serverTimeOffset)}`); + const newRef = new Reference( + this._database, + `${this.path}/${generatePushID(this._database._serverTimeOffset)}` + ); const promise = newRef.set(value); // if callback provided then internally call the set promise with value if (isFunction(onComplete)) { - return promise - // $FlowBug: Reports that onComplete can change to null despite the null check: https://github.com/facebook/flow/issues/1655 - .then(() => onComplete(null, newRef)) - // $FlowBug: Reports that onComplete can change to null despite the null check: https://github.com/facebook/flow/issues/1655 - .catch(error => onComplete(error, null)); + return ( + promise + // $FlowBug: Reports that onComplete can change to null despite the null check: https://github.com/facebook/flow/issues/1655 + .then(() => onComplete(null, newRef)) + // $FlowBug: Reports that onComplete can change to null despite the null check: https://github.com/facebook/flow/issues/1655 + .catch(error => onComplete(error, null)) + ); } // otherwise attach promise to 'thenable' reference and return the @@ -327,7 +370,11 @@ export default class Reference extends ReferenceBase { * @returns {Reference} */ orderBy(name: string, key?: string): Reference { - const newRef = new Reference(this._database, this.path, this._query.getModifiers()); + const newRef = new Reference( + this._database, + this.path, + this._query.getModifiers() + ); newRef._query.orderBy(name, key); return newRef; } @@ -361,7 +408,11 @@ export default class Reference extends ReferenceBase { * @returns {Reference} */ limit(name: string, limit: number): Reference { - const newRef = new Reference(this._database, this.path, this._query.getModifiers()); + const newRef = new Reference( + this._database, + this.path, + this._query.getModifiers() + ); newRef._query.limit(name, limit); return newRef; } @@ -408,7 +459,11 @@ export default class Reference extends ReferenceBase { * @returns {Reference} */ filter(name: string, value: any, key?: string): Reference { - const newRef = new Reference(this._database, this.path, this._query.getModifiers()); + const newRef = new Reference( + this._database, + this.path, + this._query.getModifiers() + ); newRef._query.filter(name, value, key); return newRef; } @@ -450,10 +505,12 @@ export default class Reference extends ReferenceBase { * {@link https://firebase.google.com/docs/reference/js/firebase.database.Reference#isEqual} */ isEqual(otherRef: Reference): boolean { - return !!otherRef - && otherRef.constructor === Reference - && otherRef.key === this.key - && this._query.queryIdentifier() === otherRef._query.queryIdentifier(); + return ( + !!otherRef && + otherRef.constructor === Reference && + otherRef.key === this.key && + this._query.queryIdentifier() === otherRef._query.queryIdentifier() + ); } /** @@ -468,7 +525,10 @@ export default class Reference extends ReferenceBase { */ get parent(): Reference | null { if (this.path === '/') return null; - return new Reference(this._database, this.path.substring(0, this.path.lastIndexOf('/'))); + return new Reference( + this._database, + this.path.substring(0, this.path.lastIndexOf('/')) + ); } /** @@ -495,20 +555,23 @@ export default class Reference extends ReferenceBase { * Access then method of promise if set * @return {*} */ - then(fnResolve: (any) => any, fnReject: (any) => any) { + then(fnResolve: any => any, fnReject: any => any) { if (isFunction(fnResolve) && this._promise && this._promise.then) { - return this._promise.then.bind(this._promise)((result) => { - this._promise = null; - return fnResolve(result); - }, (possibleErr) => { - this._promise = null; + return this._promise.then.bind(this._promise)( + result => { + this._promise = null; + return fnResolve(result); + }, + possibleErr => { + this._promise = null; - if (isFunction(fnReject)) { - return fnReject(possibleErr); + if (isFunction(fnReject)) { + return fnReject(possibleErr); + } + + throw possibleErr; } - - throw possibleErr; - }); + ); } throw new Error("Cannot read property 'then' of undefined."); @@ -518,9 +581,9 @@ export default class Reference extends ReferenceBase { * Access catch method of promise if set * @return {*} */ - catch(fnReject: (any) => any) { + catch(fnReject: any => any) { if (isFunction(fnReject) && this._promise && this._promise.catch) { - return this._promise.catch.bind(this._promise)((possibleErr) => { + return this._promise.catch.bind(this._promise)(possibleErr => { this._promise = null; return fnReject(possibleErr); }); @@ -539,7 +602,9 @@ export default class Reference extends ReferenceBase { * @return {string} */ _getRegistrationKey(eventType: string): string { - return `$${this._database.app.name}$/${this.path}$${this._query.queryIdentifier()}$${listeners}$${eventType}`; + return `$${this._database.app.name}$/${ + this.path + }$${this._query.queryIdentifier()}$${listeners}$${eventType}`; } /** @@ -550,7 +615,9 @@ export default class Reference extends ReferenceBase { * @private */ _getRefKey(): string { - return `$${this._database.app.name}$/${this.path}$${this._query.queryIdentifier()}`; + return `$${this._database.app.name}$/${ + this.path + }$${this._query.queryIdentifier()}`; } /** @@ -562,7 +629,6 @@ export default class Reference extends ReferenceBase { this._promise = promise; } - /** * * @param obj @@ -623,34 +689,65 @@ export default class Reference extends ReferenceBase { * * {@link https://firebase.google.com/docs/reference/js/firebase.database.Reference#on} */ - on(eventType: string, callback: (Snapshot) => any, cancelCallbackOrContext?: (Object) => any | Object, context?: Object): Function { + on( + eventType: string, + callback: Snapshot => any, + cancelCallbackOrContext?: Object => any | Object, + context?: Object + ): Function { if (!eventType) { - throw new Error('Query.on failed: Function called with 0 arguments. Expects at least 2.'); + throw new Error( + 'Query.on failed: Function called with 0 arguments. Expects at least 2.' + ); } if (!isString(eventType) || !ReferenceEventTypes[eventType]) { - throw new Error(`Query.on failed: First argument must be a valid string event type: "${Object.keys(ReferenceEventTypes).join(', ')}"`); + throw new Error( + `Query.on failed: First argument must be a valid string event type: "${Object.keys( + ReferenceEventTypes + ).join(', ')}"` + ); } if (!callback) { - throw new Error('Query.on failed: Function called with 1 argument. Expects at least 2.'); + throw new Error( + 'Query.on failed: Function called with 1 argument. Expects at least 2.' + ); } if (!isFunction(callback)) { - throw new Error('Query.on failed: Second argument must be a valid function.'); + throw new Error( + 'Query.on failed: Second argument must be a valid function.' + ); } - if (cancelCallbackOrContext && !isFunction(cancelCallbackOrContext) && !isObject(context) && !isObject(cancelCallbackOrContext)) { - throw new Error('Query.on failed: Function called with 3 arguments, but third optional argument `cancelCallbackOrContext` was not a function.'); + if ( + cancelCallbackOrContext && + !isFunction(cancelCallbackOrContext) && + !isObject(context) && + !isObject(cancelCallbackOrContext) + ) { + throw new Error( + 'Query.on failed: Function called with 3 arguments, but third optional argument `cancelCallbackOrContext` was not a function.' + ); } - if (cancelCallbackOrContext && !isFunction(cancelCallbackOrContext) && context) { - throw new Error('Query.on failed: Function called with 4 arguments, but third optional argument `cancelCallbackOrContext` was not a function.'); + if ( + cancelCallbackOrContext && + !isFunction(cancelCallbackOrContext) && + context + ) { + throw new Error( + 'Query.on failed: Function called with 4 arguments, but third optional argument `cancelCallbackOrContext` was not a function.' + ); } const eventRegistrationKey = this._getRegistrationKey(eventType); const registrationCancellationKey = `${eventRegistrationKey}$cancelled`; - const _context = (cancelCallbackOrContext && !isFunction(cancelCallbackOrContext)) ? cancelCallbackOrContext : context; + const _context = + cancelCallbackOrContext && !isFunction(cancelCallbackOrContext) + ? cancelCallbackOrContext + : context; const registrationObj = { eventType, ref: this, @@ -677,7 +774,9 @@ export default class Reference extends ReferenceBase { appName: this._database.app.name, eventType: `${eventType}$cancelled`, eventRegistrationKey: registrationCancellationKey, - listener: _context ? cancelCallbackOrContext.bind(_context) : cancelCallbackOrContext, + listener: _context + ? cancelCallbackOrContext.bind(_context) + : cancelCallbackOrContext, }); } @@ -724,18 +823,29 @@ export default class Reference extends ReferenceBase { if (!arguments.length) { // Firebase Docs: // if no eventType or callback is specified, all callbacks for the Reference will be removed. - return SyncTree.removeListenersForRegistrations(SyncTree.getRegistrationsByPath(this.path)); + return SyncTree.removeListenersForRegistrations( + SyncTree.getRegistrationsByPath(this.path) + ); } /* * VALIDATE ARGS */ - if (eventType && (!isString(eventType) || !ReferenceEventTypes[eventType])) { - throw new Error(`Query.off failed: First argument must be a valid string event type: "${Object.keys(ReferenceEventTypes).join(', ')}"`); + if ( + eventType && + (!isString(eventType) || !ReferenceEventTypes[eventType]) + ) { + throw new Error( + `Query.off failed: First argument must be a valid string event type: "${Object.keys( + ReferenceEventTypes + ).join(', ')}"` + ); } if (originalCallback && !isFunction(originalCallback)) { - throw new Error('Query.off failed: Function called with 2 arguments, but second optional argument was not a function.'); + throw new Error( + 'Query.off failed: Function called with 2 arguments, but second optional argument was not a function.' + ); } // Firebase Docs: @@ -745,7 +855,11 @@ export default class Reference extends ReferenceBase { // remove the callback. // Remove only a single registration if (eventType && originalCallback) { - const registration = SyncTree.getOneByPathEventListener(this.path, eventType, originalCallback); + const registration = SyncTree.getOneByPathEventListener( + this.path, + eventType, + originalCallback + ); if (!registration) return []; // remove the paired cancellation registration if any exist @@ -753,15 +867,20 @@ export default class Reference extends ReferenceBase { // remove only the first registration to match firebase web sdk // call multiple times to remove multiple registrations - return SyncTree.removeListenerRegistrations(originalCallback, [registration]); + return SyncTree.removeListenerRegistrations(originalCallback, [ + registration, + ]); } // Firebase Docs: // If a callback is not specified, all callbacks for the specified eventType will be removed. - const registrations = SyncTree.getRegistrationsByPathEvent(this.path, eventType); + const registrations = SyncTree.getRegistrationsByPathEvent( + this.path, + eventType + ); SyncTree.removeListenersForRegistrations( - SyncTree.getRegistrationsByPathEvent(this.path, `${eventType}$cancelled`), + SyncTree.getRegistrationsByPathEvent(this.path, `${eventType}$cancelled`) ); return SyncTree.removeListenersForRegistrations(registrations); diff --git a/lib/modules/database/snapshot.js b/lib/modules/database/snapshot.js index fa6c6c77..572ea85b 100644 --- a/lib/modules/database/snapshot.js +++ b/lib/modules/database/snapshot.js @@ -3,7 +3,7 @@ * Snapshot representation wrapper */ import { isObject, deepGet, deepExists } from './../../utils'; -import type Reference from './reference.js'; +import type Reference from './reference'; /** * @class DataSnapshot @@ -39,7 +39,8 @@ export default class Snapshot { */ val(): any { // clone via JSON stringify/parse - prevent modification of this._value - if (isObject(this._value) || Array.isArray(this._value)) return JSON.parse(JSON.stringify(this._value)); + if (isObject(this._value) || Array.isArray(this._value)) + return JSON.parse(JSON.stringify(this._value)); return this._value; } diff --git a/lib/modules/database/transaction.js b/lib/modules/database/transaction.js index 1711d441..cbde0edc 100644 --- a/lib/modules/database/transaction.js +++ b/lib/modules/database/transaction.js @@ -14,9 +14,7 @@ let transactionId = 0; * @returns {number} * @private */ -const generateTransactionId = (): number => { - return transactionId++; -}; +const generateTransactionId = (): number => transactionId++; /** * @class TransactionHandler @@ -24,7 +22,7 @@ const generateTransactionId = (): number => { export default class TransactionHandler { _database: Database; _transactionListener: Function; - _transactions: { [number]: Object } + _transactions: { [number]: Object }; constructor(database: Database) { this._transactions = {}; @@ -32,7 +30,7 @@ export default class TransactionHandler { this._transactionListener = SharedEventEmitter.addListener( getAppEventName(this._database, 'database_transaction_event'), - this._handleTransactionEvent.bind(this), + this._handleTransactionEvent.bind(this) ); } @@ -43,7 +41,12 @@ export default class TransactionHandler { * @param onComplete * @param applyLocally */ - add(reference: Object, transactionUpdater: Function, onComplete?: Function, applyLocally?: boolean = false) { + add( + reference: Object, + transactionUpdater: Function, + onComplete?: Function, + applyLocally?: boolean = false + ) { const id = generateTransactionId(); this._transactions[id] = { @@ -56,7 +59,11 @@ export default class TransactionHandler { started: true, }; - getNativeModule(this._database).transactionStart(reference.path, id, applyLocally); + getNativeModule(this._database).transactionStart( + reference.path, + id, + applyLocally + ); } /** @@ -78,7 +85,10 @@ export default class TransactionHandler { case 'complete': return this._handleComplete(event); default: - getLogger(this._database).warn(`Unknown transaction event type: '${event.type}'`, event); + getLogger(this._database).warn( + `Unknown transaction event type: '${event.type}'`, + event + ); return undefined; } } @@ -104,7 +114,10 @@ export default class TransactionHandler { abort = true; } - getNativeModule(this._database).transactionTryCommit(id, { value: newValue, abort }); + getNativeModule(this._database).transactionTryCommit(id, { + value: newValue, + abort, + }); } } @@ -137,7 +150,11 @@ export default class TransactionHandler { if (transaction && !transaction.completed) { transaction.completed = true; try { - transaction.onComplete(null, event.committed, Object.assign({}, event.snapshot)); + transaction.onComplete( + null, + event.committed, + Object.assign({}, event.snapshot) + ); } finally { setImmediate(() => { delete this._transactions[event.id]; diff --git a/lib/modules/firestore/CollectionReference.js b/lib/modules/firestore/CollectionReference.js index 3eb96c01..19807680 100644 --- a/lib/modules/firestore/CollectionReference.js +++ b/lib/modules/firestore/CollectionReference.js @@ -7,10 +7,18 @@ import Query from './Query'; import { firestoreAutoId } from '../../utils'; import type Firestore from './'; -import type { FirestoreQueryDirection, FirestoreQueryOperator } from '../../types'; +import type { + FirestoreQueryDirection, + FirestoreQueryOperator, +} from '../../types'; import type FieldPath from './FieldPath'; import type Path from './Path'; -import type { Observer, ObserverOnError, ObserverOnNext, QueryListenOptions } from './Query'; +import type { + Observer, + ObserverOnError, + ObserverOnNext, + QueryListenOptions, +} from './Query'; import type QuerySnapshot from './QuerySnapshot'; /** @@ -37,13 +45,14 @@ export default class CollectionReference { get parent(): DocumentReference | null { const parentPath = this._collectionPath.parent(); - return parentPath ? new DocumentReference(this._firestore, parentPath) : null; + return parentPath + ? new DocumentReference(this._firestore, parentPath) + : null; } add(data: Object): Promise { const documentRef = this.doc(); - return documentRef.set(data) - .then(() => Promise.resolve(documentRef)); + return documentRef.set(data).then(() => Promise.resolve(documentRef)); } doc(documentPath?: string): DocumentReference { @@ -77,12 +86,19 @@ export default class CollectionReference { onSnapshot( optionsOrObserverOrOnNext: QueryListenOptions | Observer | ObserverOnNext, observerOrOnNextOrOnError?: Observer | ObserverOnNext | ObserverOnError, - onError?: ObserverOnError, + onError?: ObserverOnError ): () => void { - return this._query.onSnapshot(optionsOrObserverOrOnNext, observerOrOnNextOrOnError, onError); + return this._query.onSnapshot( + optionsOrObserverOrOnNext, + observerOrOnNextOrOnError, + onError + ); } - orderBy(fieldPath: string | FieldPath, directionStr?: FirestoreQueryDirection): Query { + orderBy( + fieldPath: string | FieldPath, + directionStr?: FirestoreQueryDirection + ): Query { return this._query.orderBy(fieldPath, directionStr); } diff --git a/lib/modules/firestore/DocumentReference.js b/lib/modules/firestore/DocumentReference.js index 946e6d39..9fb9ac9c 100644 --- a/lib/modules/firestore/DocumentReference.js +++ b/lib/modules/firestore/DocumentReference.js @@ -13,20 +13,23 @@ import { firestoreAutoId, isFunction, isObject, isString } from '../../utils'; import { getNativeModule } from '../../utils/native'; import type Firestore from './'; -import type { FirestoreNativeDocumentSnapshot, FirestoreWriteOptions } from '../../types'; +import type { + FirestoreNativeDocumentSnapshot, + FirestoreWriteOptions, +} from '../../types'; import type Path from './Path'; type DocumentListenOptions = { includeMetadataChanges: boolean, -} +}; -type ObserverOnError = (Object) => void; -type ObserverOnNext = (DocumentSnapshot) => void; +type ObserverOnError = Object => void; +type ObserverOnNext = DocumentSnapshot => void; type Observer = { error?: ObserverOnError, next: ObserverOnNext, -} +}; /** * @class DocumentReference @@ -70,8 +73,7 @@ export default class DocumentReference { } delete(): Promise { - return getNativeModule(this._firestore) - .documentDelete(this.path); + return getNativeModule(this._firestore).documentDelete(this.path); } get(): Promise { @@ -81,28 +83,41 @@ export default class DocumentReference { } onSnapshot( - optionsOrObserverOrOnNext: DocumentListenOptions | Observer | ObserverOnNext, + optionsOrObserverOrOnNext: + | DocumentListenOptions + | Observer + | ObserverOnNext, observerOrOnNextOrOnError?: Observer | ObserverOnNext | ObserverOnError, - onError?: ObserverOnError, + onError?: ObserverOnError ) { let observer: Observer; let docListenOptions = {}; // Called with: onNext, ?onError if (isFunction(optionsOrObserverOrOnNext)) { if (observerOrOnNextOrOnError && !isFunction(observerOrOnNextOrOnError)) { - throw new Error('DocumentReference.onSnapshot failed: Second argument must be a valid function.'); + throw new Error( + 'DocumentReference.onSnapshot failed: Second argument must be a valid function.' + ); } // $FlowBug: Not coping with the overloaded method signature observer = { next: optionsOrObserverOrOnNext, error: observerOrOnNextOrOnError, }; - } else if (optionsOrObserverOrOnNext && isObject(optionsOrObserverOrOnNext)) { + } else if ( + optionsOrObserverOrOnNext && + isObject(optionsOrObserverOrOnNext) + ) { // Called with: Observer if (optionsOrObserverOrOnNext.next) { if (isFunction(optionsOrObserverOrOnNext.next)) { - if (optionsOrObserverOrOnNext.error && !isFunction(optionsOrObserverOrOnNext.error)) { - throw new Error('DocumentReference.onSnapshot failed: Observer.error must be a valid function.'); + if ( + optionsOrObserverOrOnNext.error && + !isFunction(optionsOrObserverOrOnNext.error) + ) { + throw new Error( + 'DocumentReference.onSnapshot failed: Observer.error must be a valid function.' + ); } // $FlowBug: Not coping with the overloaded method signature observer = { @@ -110,66 +125,103 @@ export default class DocumentReference { error: optionsOrObserverOrOnNext.error, }; } else { - throw new Error('DocumentReference.onSnapshot failed: Observer.next must be a valid function.'); + throw new Error( + 'DocumentReference.onSnapshot failed: Observer.next must be a valid function.' + ); } - } else if (Object.prototype.hasOwnProperty.call(optionsOrObserverOrOnNext, 'includeMetadataChanges')) { + } else if ( + Object.prototype.hasOwnProperty.call( + optionsOrObserverOrOnNext, + 'includeMetadataChanges' + ) + ) { docListenOptions = optionsOrObserverOrOnNext; // Called with: Options, onNext, ?onError if (isFunction(observerOrOnNextOrOnError)) { if (onError && !isFunction(onError)) { - throw new Error('DocumentReference.onSnapshot failed: Third argument must be a valid function.'); + throw new Error( + 'DocumentReference.onSnapshot failed: Third argument must be a valid function.' + ); } // $FlowBug: Not coping with the overloaded method signature observer = { next: observerOrOnNextOrOnError, error: onError, }; - // Called with Options, Observer - } else if (observerOrOnNextOrOnError && isObject(observerOrOnNextOrOnError) && observerOrOnNextOrOnError.next) { + // Called with Options, Observer + } else if ( + observerOrOnNextOrOnError && + isObject(observerOrOnNextOrOnError) && + observerOrOnNextOrOnError.next + ) { if (isFunction(observerOrOnNextOrOnError.next)) { - if (observerOrOnNextOrOnError.error && !isFunction(observerOrOnNextOrOnError.error)) { - throw new Error('DocumentReference.onSnapshot failed: Observer.error must be a valid function.'); + if ( + observerOrOnNextOrOnError.error && + !isFunction(observerOrOnNextOrOnError.error) + ) { + throw new Error( + 'DocumentReference.onSnapshot failed: Observer.error must be a valid function.' + ); } observer = { next: observerOrOnNextOrOnError.next, error: observerOrOnNextOrOnError.error, }; } else { - throw new Error('DocumentReference.onSnapshot failed: Observer.next must be a valid function.'); + throw new Error( + 'DocumentReference.onSnapshot failed: Observer.next must be a valid function.' + ); } } else { - throw new Error('DocumentReference.onSnapshot failed: Second argument must be a function or observer.'); + throw new Error( + 'DocumentReference.onSnapshot failed: Second argument must be a function or observer.' + ); } } else { - throw new Error('DocumentReference.onSnapshot failed: First argument must be a function, observer or options.'); + throw new Error( + 'DocumentReference.onSnapshot failed: First argument must be a function, observer or options.' + ); } } else { - throw new Error('DocumentReference.onSnapshot failed: Called with invalid arguments.'); + throw new Error( + 'DocumentReference.onSnapshot failed: Called with invalid arguments.' + ); } const listenerId = firestoreAutoId(); - const listener = (nativeDocumentSnapshot: FirestoreNativeDocumentSnapshot) => { - const documentSnapshot = new DocumentSnapshot(this.firestore, nativeDocumentSnapshot); + const listener = ( + nativeDocumentSnapshot: FirestoreNativeDocumentSnapshot + ) => { + const documentSnapshot = new DocumentSnapshot( + this.firestore, + nativeDocumentSnapshot + ); observer.next(documentSnapshot); }; // Listen to snapshot events SharedEventEmitter.addListener( getAppEventName(this._firestore, `onDocumentSnapshot:${listenerId}`), - listener, + listener ); // Listen for snapshot error events if (observer.error) { SharedEventEmitter.addListener( - getAppEventName(this._firestore, `onDocumentSnapshotError:${listenerId}`), - observer.error, + getAppEventName( + this._firestore, + `onDocumentSnapshotError:${listenerId}` + ), + observer.error ); } // Add the native listener - getNativeModule(this._firestore) - .documentOnSnapshot(this.path, listenerId, docListenOptions); + getNativeModule(this._firestore).documentOnSnapshot( + this.path, + listenerId, + docListenOptions + ); // Return an unsubscribe method return this._offDocumentSnapshot.bind(this, listenerId, listener); @@ -177,19 +229,27 @@ export default class DocumentReference { set(data: Object, writeOptions?: FirestoreWriteOptions): Promise { const nativeData = buildNativeMap(data); - return getNativeModule(this._firestore) - .documentSet(this.path, nativeData, writeOptions); + return getNativeModule(this._firestore).documentSet( + this.path, + nativeData, + writeOptions + ); } update(...args: any[]): Promise { let data = {}; if (args.length === 1) { if (!isObject(args[0])) { - throw new Error('DocumentReference.update failed: If using a single argument, it must be an object.'); + throw new Error( + 'DocumentReference.update failed: If using a single argument, it must be an object.' + ); } + // eslint-disable-next-line prefer-destructuring data = args[0]; } else if (args.length % 2 === 1) { - throw new Error('DocumentReference.update failed: Must have either a single object argument, or equal numbers of key/value pairs.'); + throw new Error( + 'DocumentReference.update failed: Must have either a single object argument, or equal numbers of key/value pairs.' + ); } else { for (let i = 0; i < args.length; i += 2) { const key = args[i]; @@ -199,13 +259,17 @@ export default class DocumentReference { } else if (key instanceof FieldPath) { data = mergeFieldPathData(data, key._segments, value); } else { - throw new Error(`DocumentReference.update failed: Argument at index ${i} must be a string or FieldPath`); + throw new Error( + `DocumentReference.update failed: Argument at index ${i} must be a string or FieldPath` + ); } } } const nativeData = buildNativeMap(data); - return getNativeModule(this._firestore) - .documentUpdate(this.path, nativeData); + return getNativeModule(this._firestore).documentUpdate( + this.path, + nativeData + ); } /** @@ -218,9 +282,14 @@ export default class DocumentReference { */ _offDocumentSnapshot(listenerId: string, listener: Function) { getLogger(this._firestore).info('Removing onDocumentSnapshot listener'); - SharedEventEmitter.removeListener(getAppEventName(this._firestore, `onDocumentSnapshot:${listenerId}`), listener); - SharedEventEmitter.removeListener(getAppEventName(this._firestore, `onDocumentSnapshotError:${listenerId}`), listener); - getNativeModule(this._firestore) - .documentOffSnapshot(this.path, listenerId); + SharedEventEmitter.removeListener( + getAppEventName(this._firestore, `onDocumentSnapshot:${listenerId}`), + listener + ); + SharedEventEmitter.removeListener( + getAppEventName(this._firestore, `onDocumentSnapshotError:${listenerId}`), + listener + ); + getNativeModule(this._firestore).documentOffSnapshot(this.path, listenerId); } } diff --git a/lib/modules/firestore/DocumentSnapshot.js b/lib/modules/firestore/DocumentSnapshot.js index 64cce079..691c82c4 100644 --- a/lib/modules/firestore/DocumentSnapshot.js +++ b/lib/modules/firestore/DocumentSnapshot.js @@ -9,7 +9,10 @@ import { isObject } from '../../utils'; import { parseNativeMap } from './utils/serialize'; import type Firestore from './'; -import type { FirestoreNativeDocumentSnapshot, FirestoreSnapshotMetadata } from '../../types'; +import type { + FirestoreNativeDocumentSnapshot, + FirestoreSnapshotMetadata, +} from '../../types'; const extractFieldPathData = (data: Object | void, segments: string[]): any => { if (!data || !isObject(data)) { @@ -30,10 +33,16 @@ export default class DocumentSnapshot { _metadata: FirestoreSnapshotMetadata; _ref: DocumentReference; - constructor(firestore: Firestore, nativeData: FirestoreNativeDocumentSnapshot) { + constructor( + firestore: Firestore, + nativeData: FirestoreNativeDocumentSnapshot + ) { this._data = parseNativeMap(firestore, nativeData.data); this._metadata = nativeData.metadata; - this._ref = new DocumentReference(firestore, Path.fromName(nativeData.path)); + this._ref = new DocumentReference( + firestore, + Path.fromName(nativeData.path) + ); } get exists(): boolean { diff --git a/lib/modules/firestore/Query.js b/lib/modules/firestore/Query.js index 006b2c18..176a1dcc 100644 --- a/lib/modules/firestore/Query.js +++ b/lib/modules/firestore/Query.js @@ -12,7 +12,10 @@ import { firestoreAutoId, isFunction, isObject } from '../../utils'; import { getNativeModule } from '../../utils/native'; import type Firestore from './'; -import type { FirestoreQueryDirection, FirestoreQueryOperator } from '../../types'; +import type { + FirestoreQueryDirection, + FirestoreQueryOperator, +} from '../../types'; import type Path from './Path'; const DIRECTIONS: { [FirestoreQueryDirection]: string } = { @@ -35,16 +38,16 @@ type NativeFieldPath = {| elements?: string[], string?: string, type: 'fieldpath' | 'string', -|} +|}; type FieldFilter = {| fieldPath: NativeFieldPath, operator: string, value: any, -|} +|}; type FieldOrder = {| direction: string, fieldPath: NativeFieldPath, -|} +|}; type QueryOptions = { endAt?: any[], endBefore?: any[], @@ -53,22 +56,24 @@ type QueryOptions = { selectFields?: string[], startAfter?: any[], startAt?: any[], -} +}; export type QueryListenOptions = {| includeDocumentMetadataChanges: boolean, includeQueryMetadataChanges: boolean, -|} +|}; -export type ObserverOnError = (Object) => void; -export type ObserverOnNext = (QuerySnapshot) => void; +export type ObserverOnError = Object => void; +export type ObserverOnNext = QuerySnapshot => void; export type Observer = { error?: ObserverOnError, next: ObserverOnNext, -} +}; -const buildNativeFieldPath = (fieldPath: string | FieldPath): NativeFieldPath => { +const buildNativeFieldPath = ( + fieldPath: string | FieldPath +): NativeFieldPath => { if (fieldPath instanceof FieldPath) { return { elements: fieldPath._segments, @@ -95,10 +100,9 @@ export default class Query { constructor( firestore: Firestore, path: Path, - fieldFilters?: - FieldFilter[], + fieldFilters?: FieldFilter[], fieldOrders?: FieldOrder[], - queryOptions?: QueryOptions, + queryOptions?: QueryOptions ) { this._fieldFilters = fieldFilters || []; this._fieldOrders = fieldOrders || []; @@ -122,7 +126,7 @@ export default class Query { this._referencePath, this._fieldFilters, this._fieldOrders, - options, + options ); } @@ -137,7 +141,7 @@ export default class Query { this._referencePath, this._fieldFilters, this._fieldOrders, - options, + options ); } @@ -147,7 +151,7 @@ export default class Query { this._referencePath.relativeName, this._fieldFilters, this._fieldOrders, - this._queryOptions, + this._queryOptions ) .then(nativeData => new QuerySnapshot(this._firestore, this, nativeData)); } @@ -165,33 +169,43 @@ export default class Query { this._referencePath, this._fieldFilters, this._fieldOrders, - options, + options ); } onSnapshot( optionsOrObserverOrOnNext: QueryListenOptions | Observer | ObserverOnNext, observerOrOnNextOrOnError?: Observer | ObserverOnNext | ObserverOnError, - onError?: ObserverOnError, + onError?: ObserverOnError ) { let observer: Observer; let queryListenOptions = {}; // Called with: onNext, ?onError if (isFunction(optionsOrObserverOrOnNext)) { if (observerOrOnNextOrOnError && !isFunction(observerOrOnNextOrOnError)) { - throw new Error('Query.onSnapshot failed: Second argument must be a valid function.'); + throw new Error( + 'Query.onSnapshot failed: Second argument must be a valid function.' + ); } // $FlowBug: Not coping with the overloaded method signature observer = { next: optionsOrObserverOrOnNext, error: observerOrOnNextOrOnError, }; - } else if (optionsOrObserverOrOnNext && isObject(optionsOrObserverOrOnNext)) { + } else if ( + optionsOrObserverOrOnNext && + isObject(optionsOrObserverOrOnNext) + ) { // Called with: Observer if (optionsOrObserverOrOnNext.next) { if (isFunction(optionsOrObserverOrOnNext.next)) { - if (optionsOrObserverOrOnNext.error && !isFunction(optionsOrObserverOrOnNext.error)) { - throw new Error('Query.onSnapshot failed: Observer.error must be a valid function.'); + if ( + optionsOrObserverOrOnNext.error && + !isFunction(optionsOrObserverOrOnNext.error) + ) { + throw new Error( + 'Query.onSnapshot failed: Observer.error must be a valid function.' + ); } // $FlowBug: Not coping with the overloaded method signature observer = { @@ -199,87 +213,124 @@ export default class Query { error: optionsOrObserverOrOnNext.error, }; } else { - throw new Error('Query.onSnapshot failed: Observer.next must be a valid function.'); + throw new Error( + 'Query.onSnapshot failed: Observer.next must be a valid function.' + ); } - } else if (Object.prototype.hasOwnProperty.call(optionsOrObserverOrOnNext, 'includeDocumentMetadataChanges') - || Object.prototype.hasOwnProperty.call(optionsOrObserverOrOnNext, 'includeQueryMetadataChanges')) { + } else if ( + Object.prototype.hasOwnProperty.call( + optionsOrObserverOrOnNext, + 'includeDocumentMetadataChanges' + ) || + Object.prototype.hasOwnProperty.call( + optionsOrObserverOrOnNext, + 'includeQueryMetadataChanges' + ) + ) { queryListenOptions = optionsOrObserverOrOnNext; // Called with: Options, onNext, ?onError if (isFunction(observerOrOnNextOrOnError)) { if (onError && !isFunction(onError)) { - throw new Error('Query.onSnapshot failed: Third argument must be a valid function.'); + throw new Error( + 'Query.onSnapshot failed: Third argument must be a valid function.' + ); } // $FlowBug: Not coping with the overloaded method signature observer = { next: observerOrOnNextOrOnError, error: onError, }; - // Called with Options, Observer - } else if (observerOrOnNextOrOnError && isObject(observerOrOnNextOrOnError) && observerOrOnNextOrOnError.next) { + // Called with Options, Observer + } else if ( + observerOrOnNextOrOnError && + isObject(observerOrOnNextOrOnError) && + observerOrOnNextOrOnError.next + ) { if (isFunction(observerOrOnNextOrOnError.next)) { - if (observerOrOnNextOrOnError.error && !isFunction(observerOrOnNextOrOnError.error)) { - throw new Error('Query.onSnapshot failed: Observer.error must be a valid function.'); + if ( + observerOrOnNextOrOnError.error && + !isFunction(observerOrOnNextOrOnError.error) + ) { + throw new Error( + 'Query.onSnapshot failed: Observer.error must be a valid function.' + ); } observer = { next: observerOrOnNextOrOnError.next, error: observerOrOnNextOrOnError.error, }; } else { - throw new Error('Query.onSnapshot failed: Observer.next must be a valid function.'); + throw new Error( + 'Query.onSnapshot failed: Observer.next must be a valid function.' + ); } } else { - throw new Error('Query.onSnapshot failed: Second argument must be a function or observer.'); + throw new Error( + 'Query.onSnapshot failed: Second argument must be a function or observer.' + ); } } else { - throw new Error('Query.onSnapshot failed: First argument must be a function, observer or options.'); + throw new Error( + 'Query.onSnapshot failed: First argument must be a function, observer or options.' + ); } } else { - throw new Error('Query.onSnapshot failed: Called with invalid arguments.'); + throw new Error( + 'Query.onSnapshot failed: Called with invalid arguments.' + ); } const listenerId = firestoreAutoId(); - const listener = (nativeQuerySnapshot) => { - const querySnapshot = new QuerySnapshot(this._firestore, this, nativeQuerySnapshot); + const listener = nativeQuerySnapshot => { + const querySnapshot = new QuerySnapshot( + this._firestore, + this, + nativeQuerySnapshot + ); observer.next(querySnapshot); }; // Listen to snapshot events SharedEventEmitter.addListener( getAppEventName(this._firestore, `onQuerySnapshot:${listenerId}`), - listener, + listener ); // Listen for snapshot error events if (observer.error) { SharedEventEmitter.addListener( getAppEventName(this._firestore, `onQuerySnapshotError:${listenerId}`), - observer.error, + observer.error ); } // Add the native listener - getNativeModule(this._firestore) - .collectionOnSnapshot( - this._referencePath.relativeName, - this._fieldFilters, - this._fieldOrders, - this._queryOptions, - listenerId, - queryListenOptions, - ); + getNativeModule(this._firestore).collectionOnSnapshot( + this._referencePath.relativeName, + this._fieldFilters, + this._fieldOrders, + this._queryOptions, + listenerId, + queryListenOptions + ); // Return an unsubscribe method return this._offCollectionSnapshot.bind(this, listenerId, listener); } - orderBy(fieldPath: string | FieldPath, directionStr?: FirestoreQueryDirection = 'asc'): Query { + orderBy( + fieldPath: string | FieldPath, + directionStr?: FirestoreQueryDirection = 'asc' + ): Query { // TODO: Validation // validate.isFieldPath('fieldPath', fieldPath); // validate.isOptionalFieldOrder('directionStr', directionStr); if (this._queryOptions.startAt || this._queryOptions.endAt) { - throw new Error('Cannot specify an orderBy() constraint after calling ' + - 'startAt(), startAfter(), endBefore() or endAt().'); + throw new Error( + 'Cannot specify an orderBy() constraint after calling ' + + 'startAt(), startAfter(), endBefore() or endAt().' + ); } const newOrder: FieldOrder = { @@ -292,7 +343,7 @@ export default class Query { this._referencePath, this._fieldFilters, combinedOrders, - this._queryOptions, + this._queryOptions ); } @@ -307,7 +358,7 @@ export default class Query { this._referencePath, this._fieldFilters, this._fieldOrders, - options, + options ); } @@ -322,11 +373,15 @@ export default class Query { this._referencePath, this._fieldFilters, this._fieldOrders, - options, + options ); } - where(fieldPath: string | FieldPath, opStr: FirestoreQueryOperator, value: any): Query { + where( + fieldPath: string | FieldPath, + opStr: FirestoreQueryOperator, + value: any + ): Query { // TODO: Validation // validate.isFieldPath('fieldPath', fieldPath); // validate.isFieldFilter('fieldFilter', opStr, value); @@ -342,7 +397,7 @@ export default class Query { this._referencePath, combinedFilters, this._fieldOrders, - this._queryOptions, + this._queryOptions ); } @@ -353,12 +408,18 @@ export default class Query { _buildOrderByOption(snapshotOrVarArgs: any[]) { // TODO: Validation let values; - if (snapshotOrVarArgs.length === 1 && snapshotOrVarArgs[0] instanceof DocumentSnapshot) { + if ( + snapshotOrVarArgs.length === 1 && + snapshotOrVarArgs[0] instanceof DocumentSnapshot + ) { const docSnapshot: DocumentSnapshot = snapshotOrVarArgs[0]; values = []; for (let i = 0; i < this._fieldOrders.length; i++) { const fieldOrder = this._fieldOrders[i]; - if (fieldOrder.fieldPath.type === 'string' && fieldOrder.fieldPath.string) { + if ( + fieldOrder.fieldPath.type === 'string' && + fieldOrder.fieldPath.string + ) { values.push(docSnapshot.get(fieldOrder.fieldPath.string)); } else if (fieldOrder.fieldPath.fieldpath) { const fieldPath = new FieldPath(...fieldOrder.fieldPath.fieldpath); @@ -378,15 +439,20 @@ export default class Query { */ _offCollectionSnapshot(listenerId: string, listener: Function) { getLogger(this._firestore).info('Removing onQuerySnapshot listener'); - SharedEventEmitter.removeListener(getAppEventName(this._firestore, `onQuerySnapshot:${listenerId}`), listener); - SharedEventEmitter.removeListener(getAppEventName(this._firestore, `onQuerySnapshotError:${listenerId}`), listener); - getNativeModule(this._firestore) - .collectionOffSnapshot( - this._referencePath.relativeName, - this._fieldFilters, - this._fieldOrders, - this._queryOptions, - listenerId, - ); + SharedEventEmitter.removeListener( + getAppEventName(this._firestore, `onQuerySnapshot:${listenerId}`), + listener + ); + SharedEventEmitter.removeListener( + getAppEventName(this._firestore, `onQuerySnapshotError:${listenerId}`), + listener + ); + getNativeModule(this._firestore).collectionOffSnapshot( + this._referencePath.relativeName, + this._fieldFilters, + this._fieldOrders, + this._queryOptions, + listenerId + ); } } diff --git a/lib/modules/firestore/QuerySnapshot.js b/lib/modules/firestore/QuerySnapshot.js index 67d57f5e..3ff070db 100644 --- a/lib/modules/firestore/QuerySnapshot.js +++ b/lib/modules/firestore/QuerySnapshot.js @@ -6,14 +6,18 @@ import DocumentChange from './DocumentChange'; import DocumentSnapshot from './DocumentSnapshot'; import type Firestore from './'; -import type { FirestoreNativeDocumentChange, FirestoreNativeDocumentSnapshot, FirestoreSnapshotMetadata } from '../../types'; +import type { + FirestoreNativeDocumentChange, + FirestoreNativeDocumentSnapshot, + FirestoreSnapshotMetadata, +} from '../../types'; import type Query from './Query'; type QuerySnapshotNativeData = { changes: FirestoreNativeDocumentChange[], documents: FirestoreNativeDocumentSnapshot[], metadata: FirestoreSnapshotMetadata, -} +}; /** * @class QuerySnapshot @@ -24,9 +28,17 @@ export default class QuerySnapshot { _metadata: FirestoreSnapshotMetadata; _query: Query; - constructor(firestore: Firestore, query: Query, nativeData: QuerySnapshotNativeData) { - this._changes = nativeData.changes.map(change => new DocumentChange(firestore, change)); - this._docs = nativeData.documents.map(doc => new DocumentSnapshot(firestore, doc)); + constructor( + firestore: Firestore, + query: Query, + nativeData: QuerySnapshotNativeData + ) { + this._changes = nativeData.changes.map( + change => new DocumentChange(firestore, change) + ); + this._docs = nativeData.documents.map( + doc => new DocumentSnapshot(firestore, doc) + ); this._metadata = nativeData.metadata; this._query = query; } @@ -59,7 +71,7 @@ export default class QuerySnapshot { // TODO: Validation // validate.isFunction('callback', callback); - this._docs.forEach((doc) => { + this._docs.forEach(doc => { callback(doc); }); } diff --git a/lib/modules/firestore/WriteBatch.js b/lib/modules/firestore/WriteBatch.js index 75bc555a..afb3dc47 100644 --- a/lib/modules/firestore/WriteBatch.js +++ b/lib/modules/firestore/WriteBatch.js @@ -17,7 +17,7 @@ type DocumentWrite = { options?: Object, path: string, type: 'DELETE' | 'SET' | 'UPDATE', -} +}; /** * @class WriteBatch @@ -47,7 +47,11 @@ export default class WriteBatch { return this; } - set(docRef: DocumentReference, data: Object, writeOptions?: FirestoreWriteOptions) { + set( + docRef: DocumentReference, + data: Object, + writeOptions?: FirestoreWriteOptions + ) { // TODO: Validation // validate.isDocumentReference('docRef', docRef); // validate.isDocument('data', data); @@ -69,11 +73,16 @@ export default class WriteBatch { let data = {}; if (args.length === 1) { if (!isObject(args[0])) { - throw new Error('WriteBatch.update failed: If using two arguments, the second must be an object.'); + throw new Error( + 'WriteBatch.update failed: If using two arguments, the second must be an object.' + ); } + // eslint-disable-next-line prefer-destructuring data = args[0]; } else if (args.length % 2 === 1) { - throw new Error('WriteBatch.update failed: Must have a document reference, followed by either a single object argument, or equal numbers of key/value pairs.'); + throw new Error( + 'WriteBatch.update failed: Must have a document reference, followed by either a single object argument, or equal numbers of key/value pairs.' + ); } else { for (let i = 0; i < args.length; i += 2) { const key = args[i]; @@ -83,7 +92,9 @@ export default class WriteBatch { } else if (key instanceof FieldPath) { data = mergeFieldPathData(data, key._segments, value); } else { - throw new Error(`WriteBatch.update failed: Argument at index ${i} must be a string or FieldPath`); + throw new Error( + `WriteBatch.update failed: Argument at index ${i} must be a string or FieldPath` + ); } } } diff --git a/lib/modules/firestore/index.js b/lib/modules/firestore/index.js index d58c5714..7b5a185e 100644 --- a/lib/modules/firestore/index.js +++ b/lib/modules/firestore/index.js @@ -25,7 +25,7 @@ type CollectionSyncEvent = { error?: Object, listenerId: string, path: string, -} +}; type DocumentSyncEvent = { appName: string, @@ -33,7 +33,7 @@ type DocumentSyncEvent = { error?: Object, listenerId: string, path: string, -} +}; const NATIVE_EVENTS = [ 'firestore_collection_sync_event', @@ -62,14 +62,14 @@ export default class Firestore extends ModuleBase { // sub to internal native event - this fans out to // public event name: onCollectionSnapshot getAppEventName(this, 'firestore_collection_sync_event'), - this._onCollectionSyncEvent.bind(this), + this._onCollectionSyncEvent.bind(this) ); SharedEventEmitter.addListener( // sub to internal native event - this fans out to // public event name: onDocumentSnapshot getAppEventName(this, 'firestore_document_sync_event'), - this._onDocumentSyncEvent.bind(this), + this._onDocumentSyncEvent.bind(this) ); } @@ -114,7 +114,12 @@ export default class Firestore extends ModuleBase { } setLogLevel(): void { - throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD('firestore', 'setLogLevel')); + throw new Error( + INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD( + 'firestore', + 'setLogLevel' + ) + ); } settings(): void { @@ -128,9 +133,15 @@ export default class Firestore extends ModuleBase { */ _onCollectionSyncEvent(event: CollectionSyncEvent) { if (event.error) { - SharedEventEmitter.emit(getAppEventName(this, `onQuerySnapshotError:${event.listenerId}`), event.error); + SharedEventEmitter.emit( + getAppEventName(this, `onQuerySnapshotError:${event.listenerId}`), + event.error + ); } else { - SharedEventEmitter.emit(getAppEventName(this, `onQuerySnapshot:${event.listenerId}`), event.querySnapshot); + SharedEventEmitter.emit( + getAppEventName(this, `onQuerySnapshot:${event.listenerId}`), + event.querySnapshot + ); } } @@ -141,9 +152,15 @@ export default class Firestore extends ModuleBase { */ _onDocumentSyncEvent(event: DocumentSyncEvent) { if (event.error) { - SharedEventEmitter.emit(getAppEventName(this, `onDocumentSnapshotError:${event.listenerId}`), event.error); + SharedEventEmitter.emit( + getAppEventName(this, `onDocumentSnapshotError:${event.listenerId}`), + event.error + ); } else { - SharedEventEmitter.emit(getAppEventName(this, `onDocumentSnapshot:${event.listenerId}`), event.documentSnapshot); + SharedEventEmitter.emit( + getAppEventName(this, `onDocumentSnapshot:${event.listenerId}`), + event.documentSnapshot + ); } } } diff --git a/lib/modules/firestore/utils/index.js b/lib/modules/firestore/utils/index.js index e3070e53..8405183b 100644 --- a/lib/modules/firestore/utils/index.js +++ b/lib/modules/firestore/utils/index.js @@ -13,7 +13,12 @@ const buildFieldPathData = (segments: string[], value: any): Object => { }; }; -export const mergeFieldPathData = (data: Object, segments: string[], value: any): Object => { +// eslint-disable-next-line import/prefer-default-export +export const mergeFieldPathData = ( + data: Object, + segments: string[], + value: any +): Object => { if (segments.length === 1) { return { ...data, @@ -22,7 +27,11 @@ export const mergeFieldPathData = (data: Object, segments: string[], value: any) } else if (data[segments[0]]) { return { ...data, - [segments[0]]: mergeFieldPathData(data[segments[0]], segments.slice(1), value), + [segments[0]]: mergeFieldPathData( + data[segments[0]], + segments.slice(1), + value + ), }; } return { diff --git a/lib/modules/firestore/utils/serialize.js b/lib/modules/firestore/utils/serialize.js index b4c2dd1a..24b8f0a5 100644 --- a/lib/modules/firestore/utils/serialize.js +++ b/lib/modules/firestore/utils/serialize.js @@ -4,7 +4,10 @@ import DocumentReference from '../DocumentReference'; import { DOCUMENT_ID } from '../FieldPath'; -import { DELETE_FIELD_VALUE, SERVER_TIMESTAMP_FIELD_VALUE } from '../FieldValue'; +import { + DELETE_FIELD_VALUE, + SERVER_TIMESTAMP_FIELD_VALUE, +} from '../FieldValue'; import GeoPoint from '../GeoPoint'; import Path from '../Path'; import { typeOf } from '../../../utils'; @@ -18,10 +21,12 @@ import type { FirestoreTypeMap } from '../../../types'; * for transmission to the native side */ -export const buildNativeMap = (data: Object): { [string]: FirestoreTypeMap } => { +export const buildNativeMap = ( + data: Object +): { [string]: FirestoreTypeMap } => { const nativeData = {}; if (data) { - Object.keys(data).forEach((key) => { + Object.keys(data).forEach(key => { const typeMap = buildTypeMap(data[key]); if (typeMap) { nativeData[key] = typeMap; @@ -34,7 +39,7 @@ export const buildNativeMap = (data: Object): { [string]: FirestoreTypeMap } => export const buildNativeArray = (array: Object[]): FirestoreTypeMap[] => { const nativeArray = []; if (array) { - array.forEach((value) => { + array.forEach(value => { const typeMap = buildTypeMap(value); if (typeMap) { nativeArray.push(typeMap); @@ -110,21 +115,27 @@ export const buildTypeMap = (value: any): FirestoreTypeMap | null => { * side and converts to the correct Firestore JS types */ -export const parseNativeMap = (firestore: Firestore, nativeData: { [string]: FirestoreTypeMap }): Object | void => { +export const parseNativeMap = ( + firestore: Firestore, + nativeData: { [string]: FirestoreTypeMap } +): Object | void => { let data; if (nativeData) { data = {}; - Object.keys(nativeData).forEach((key) => { + Object.keys(nativeData).forEach(key => { data[key] = parseTypeMap(firestore, nativeData[key]); }); } return data; }; -const parseNativeArray = (firestore: Firestore, nativeArray: FirestoreTypeMap[]): any[] => { +const parseNativeArray = ( + firestore: Firestore, + nativeArray: FirestoreTypeMap[] +): any[] => { const array = []; if (nativeArray) { - nativeArray.forEach((typeMap) => { + nativeArray.forEach(typeMap => { array.push(parseTypeMap(firestore, typeMap)); }); } diff --git a/lib/modules/links/index.js b/lib/modules/links/index.js index a4c36211..ae475204 100644 --- a/lib/modules/links/index.js +++ b/lib/modules/links/index.js @@ -13,9 +13,7 @@ const EVENT_TYPE = { Link: 'dynamic_link_received', }; -const NATIVE_EVENTS = [ - EVENT_TYPE.Link, -]; +const NATIVE_EVENTS = [EVENT_TYPE.Link]; export const MODULE_NAME = 'RNFirebaseLinks'; export const NAMESPACE = 'links'; @@ -59,10 +57,16 @@ function checkForMandatoryParameters(parameters: Object): void { if (!isString(parameters.link)) { throw new Error('No link was specified.'); } - if (isObject(parameters.androidInfo) && !isString(parameters.androidInfo.androidPackageName)) { + if ( + isObject(parameters.androidInfo) && + !isString(parameters.androidInfo.androidPackageName) + ) { throw new Error('No androidPackageName was specified.'); } - if (isObject(parameters.iosInfo) && !isString(parameters.iosInfo.iosBundleId)) { + if ( + isObject(parameters.iosInfo) && + !isString(parameters.iosInfo.iosBundleId) + ) { throw new Error('No iosBundleId was specified.'); } } @@ -98,7 +102,10 @@ export default class Links extends ModuleBase { * @returns {Function} */ onLink(listener: Function): () => any { - const rnListener = SharedEventEmitter.addListener(EVENT_TYPE.Link, listener); + const rnListener = SharedEventEmitter.addListener( + EVENT_TYPE.Link, + listener + ); return () => rnListener.remove(); } diff --git a/lib/modules/messaging/RemoteMessage.js b/lib/modules/messaging/RemoteMessage.js index 78472967..41370ef8 100644 --- a/lib/modules/messaging/RemoteMessage.js +++ b/lib/modules/messaging/RemoteMessage.js @@ -12,7 +12,9 @@ export default class RemoteMessage { id: generatePushID(), ttl: 3600, // add the googleapis sender id part if not already added. - sender: `${sender}`.includes('@') ? sender : `${sender}@gcm.googleapis.com`, + sender: `${sender}`.includes('@') + ? sender + : `${sender}@gcm.googleapis.com`, type: 'remote', data: {}, }; @@ -57,7 +59,6 @@ export default class RemoteMessage { return this; } - /** * * @param data @@ -65,7 +66,9 @@ export default class RemoteMessage { */ setData(data: Object = {}) { if (!isObject(data)) { - throw new Error(`RemoteMessage:setData expects an object as the first parameter but got type '${typeof data}'.`); + throw new Error( + `RemoteMessage:setData expects an object as the first parameter but got type '${typeof data}'.` + ); } const props = Object.keys(data); diff --git a/lib/modules/messaging/index.js b/lib/modules/messaging/index.js index 5136cf98..4030c5ba 100644 --- a/lib/modules/messaging/index.js +++ b/lib/modules/messaging/index.js @@ -33,10 +33,7 @@ const WILL_PRESENT_RESULT = { None: 'UNNotificationPresentationOptionNone', }; -const NATIVE_EVENTS = [ - EVENT_TYPE.RefreshToken, - EVENT_TYPE.Notification, -]; +const NATIVE_EVENTS = [EVENT_TYPE.RefreshToken, EVENT_TYPE.Notification]; const FirebaseMessaging = NativeModules.RNFirebaseMessaging; @@ -49,7 +46,6 @@ function finish(data) { return; } - if (!this._finishCalled && this._completionHandlerId) { let result = data; @@ -59,21 +55,35 @@ function finish(data) { case NOTIFICATION_TYPE.Remote: result = result || REMOTE_NOTIFICATION_RESULT.NoData; if (!Object.values(REMOTE_NOTIFICATION_RESULT).includes(result)) { - throw new Error('Invalid REMOTE_NOTIFICATION_RESULT value, use messaging().REMOTE_NOTIFICATION_RESULT'); + throw new Error( + 'Invalid REMOTE_NOTIFICATION_RESULT value, use messaging().REMOTE_NOTIFICATION_RESULT' + ); } - FirebaseMessaging.finishRemoteNotification(this._completionHandlerId, result); + FirebaseMessaging.finishRemoteNotification( + this._completionHandlerId, + result + ); return; case NOTIFICATION_TYPE.NotificationResponse: FirebaseMessaging.finishNotificationResponse(this._completionHandlerId); return; case NOTIFICATION_TYPE.WillPresent: - result = result || (this.show_in_foreground ? WILL_PRESENT_RESULT.All : WILL_PRESENT_RESULT.None); + result = + result || + (this.show_in_foreground + ? WILL_PRESENT_RESULT.All + : WILL_PRESENT_RESULT.None); if (!Object.values(WILL_PRESENT_RESULT).includes(result)) { - throw new Error('Invalid WILL_PRESENT_RESULT value, use messaging().WILL_PRESENT_RESULT'); + throw new Error( + 'Invalid WILL_PRESENT_RESULT value, use messaging().WILL_PRESENT_RESULT' + ); } - FirebaseMessaging.finishWillPresentNotification(this._completionHandlerId, result); + FirebaseMessaging.finishWillPresentNotification( + this._completionHandlerId, + result + ); break; default: } @@ -155,7 +165,10 @@ export default class Messaging extends ModuleBase { */ scheduleLocalNotification(notification: Object): Promise { const _notification = Object.assign({}, notification); - if (!notification.id) return Promise.reject(new Error('An id is required to schedule a local notification.')); + if (!notification.id) + return Promise.reject( + new Error('An id is required to schedule a local notification.') + ); _notification.local_notification = true; return getNativeModule(this).scheduleLocalNotification(_notification); } @@ -188,7 +201,8 @@ export default class Messaging extends ModuleBase { */ removeDeliveredNotification(id: string): Promise { if (!id) return Promise.reject(new Error('Missing notification id')); - if (id === '*') return getNativeModule(this).removeAllDeliveredNotifications(); + if (id === '*') + return getNativeModule(this).removeAllDeliveredNotifications(); return getNativeModule(this).removeDeliveredNotification(id); } @@ -201,7 +215,6 @@ export default class Messaging extends ModuleBase { return getNativeModule(this).requestPermissions(); } - /** * Set notification count badge number * @param n @@ -223,10 +236,10 @@ export default class Messaging extends ModuleBase { * @param listener * @returns {*} */ - onMessage(listener: (Object) => any): () => any { + onMessage(listener: Object => any): () => any { const rnListener = SharedEventEmitter.addListener( EVENT_TYPE.Notification, - async (event) => { + async event => { const data = { ...event, finish, @@ -236,7 +249,7 @@ export default class Messaging extends ModuleBase { if (!data._finishCalled) { data.finish(); } - }, + } ); return () => rnListener.remove(); } @@ -246,8 +259,11 @@ export default class Messaging extends ModuleBase { * @param listener * @returns {*} */ - onTokenRefresh(listener: (string) => any): () => any { - const rnListener = SharedEventEmitter.addListener(EVENT_TYPE.RefreshToken, listener); + onTokenRefresh(listener: string => any): () => any { + const rnListener = SharedEventEmitter.addListener( + EVENT_TYPE.RefreshToken, + listener + ); return () => rnListener.remove(); } @@ -273,7 +289,9 @@ export default class Messaging extends ModuleBase { */ send(remoteMessage: RemoteMessage): Promise { if (!(remoteMessage instanceof RemoteMessage)) { - throw new Error('messaging().send requires an instance of RemoteMessage as the first argument.'); + throw new Error( + 'messaging().send requires an instance of RemoteMessage as the first argument.' + ); } return getNativeModule(this).send(remoteMessage.toJSON()); diff --git a/lib/modules/storage/index.js b/lib/modules/storage/index.js index 8e372619..f2fce5f2 100644 --- a/lib/modules/storage/index.js +++ b/lib/modules/storage/index.js @@ -14,10 +14,7 @@ import type App from '../core/firebase-app'; const FirebaseStorage = NativeModules.RNFirebaseStorage; -const NATIVE_EVENTS = [ - 'storage_event', - 'storage_error', -]; +const NATIVE_EVENTS = ['storage_event', 'storage_error']; export const MODULE_NAME = 'RNFirebaseStorage'; export const NAMESPACE = 'storage'; @@ -38,12 +35,12 @@ export default class Storage extends ModuleBase { SharedEventEmitter.addListener( getAppEventName(this, 'storage_event'), - this._handleStorageEvent.bind(this), + this._handleStorageEvent.bind(this) ); SharedEventEmitter.addListener( getAppEventName(this, 'storage_error'), - this._handleStorageEvent.bind(this), + this._handleStorageEvent.bind(this) ); } @@ -118,12 +115,23 @@ export default class Storage extends ModuleBase { SharedEventEmitter.emit(this._getSubEventName(path, eventName), body); } - _addListener(path: string, eventName: string, cb: (evt: Object) => Object): void { + _addListener( + path: string, + eventName: string, + cb: (evt: Object) => Object + ): void { SharedEventEmitter.addListener(this._getSubEventName(path, eventName), cb); } - _removeListener(path: string, eventName: string, origCB: (evt: Object) => Object): void { - SharedEventEmitter.removeListener(this._getSubEventName(path, eventName), origCB); + _removeListener( + path: string, + eventName: string, + origCB: (evt: Object) => Object + ): void { + SharedEventEmitter.removeListener( + this._getSubEventName(path, eventName), + origCB + ); } } @@ -138,15 +146,18 @@ export const statics = { CANCELLED: 'cancelled', ERROR: 'error', }, - Native: FirebaseStorage ? { - MAIN_BUNDLE_PATH: FirebaseStorage.MAIN_BUNDLE_PATH, - CACHES_DIRECTORY_PATH: FirebaseStorage.CACHES_DIRECTORY_PATH, - DOCUMENT_DIRECTORY_PATH: FirebaseStorage.DOCUMENT_DIRECTORY_PATH, - EXTERNAL_DIRECTORY_PATH: FirebaseStorage.EXTERNAL_DIRECTORY_PATH, - EXTERNAL_STORAGE_DIRECTORY_PATH: FirebaseStorage.EXTERNAL_STORAGE_DIRECTORY_PATH, - TEMP_DIRECTORY_PATH: FirebaseStorage.TEMP_DIRECTORY_PATH, - LIBRARY_DIRECTORY_PATH: FirebaseStorage.LIBRARY_DIRECTORY_PATH, - FILETYPE_REGULAR: FirebaseStorage.FILETYPE_REGULAR, - FILETYPE_DIRECTORY: FirebaseStorage.FILETYPE_DIRECTORY, - } : {}, + Native: FirebaseStorage + ? { + MAIN_BUNDLE_PATH: FirebaseStorage.MAIN_BUNDLE_PATH, + CACHES_DIRECTORY_PATH: FirebaseStorage.CACHES_DIRECTORY_PATH, + DOCUMENT_DIRECTORY_PATH: FirebaseStorage.DOCUMENT_DIRECTORY_PATH, + EXTERNAL_DIRECTORY_PATH: FirebaseStorage.EXTERNAL_DIRECTORY_PATH, + EXTERNAL_STORAGE_DIRECTORY_PATH: + FirebaseStorage.EXTERNAL_STORAGE_DIRECTORY_PATH, + TEMP_DIRECTORY_PATH: FirebaseStorage.TEMP_DIRECTORY_PATH, + LIBRARY_DIRECTORY_PATH: FirebaseStorage.LIBRARY_DIRECTORY_PATH, + FILETYPE_REGULAR: FirebaseStorage.FILETYPE_REGULAR, + FILETYPE_DIRECTORY: FirebaseStorage.FILETYPE_DIRECTORY, + } + : {}, }; diff --git a/lib/modules/storage/reference.js b/lib/modules/storage/reference.js index 8db997ad..b58a3007 100644 --- a/lib/modules/storage/reference.js +++ b/lib/modules/storage/reference.js @@ -7,7 +7,6 @@ import StorageTask, { UPLOAD_TASK, DOWNLOAD_TASK } from './task'; import { getNativeModule } from '../../utils/native'; import type Storage from './'; - /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference */ @@ -75,7 +74,11 @@ export default class StorageReference extends ReferenceBase { * @return {Promise} */ downloadFile(filePath: string): Promise { - return new StorageTask(DOWNLOAD_TASK, getNativeModule(this._storage).downloadFile(this.path, filePath), this); + return new StorageTask( + DOWNLOAD_TASK, + getNativeModule(this._storage).downloadFile(this.path, filePath), + this + ); } /** @@ -94,6 +97,10 @@ export default class StorageReference extends ReferenceBase { */ putFile(filePath: Object, metadata: Object = {}): Promise { const _filePath = filePath.replace('file://', ''); - return new StorageTask(UPLOAD_TASK, getNativeModule(this._storage).putFile(this.path, _filePath, metadata), this); + return new StorageTask( + UPLOAD_TASK, + getNativeModule(this._storage).putFile(this.path, _filePath, metadata), + this + ); } } diff --git a/lib/modules/storage/task.js b/lib/modules/storage/task.js index e3906c23..95b0605f 100644 --- a/lib/modules/storage/task.js +++ b/lib/modules/storage/task.js @@ -12,31 +12,33 @@ export const DOWNLOAD_TASK = 'download'; declare type UploadTaskSnapshotType = { bytesTransferred: number, - downloadURL: string|null, + downloadURL: string | null, metadata: Object, // TODO flow type def for https://firebase.google.com/docs/reference/js/firebase.storage.FullMetadata.html ref: StorageReference, - state: ( - typeof StorageStatics.TaskState.RUNNING + state: + | typeof StorageStatics.TaskState.RUNNING | typeof StorageStatics.TaskState.PAUSED | typeof StorageStatics.TaskState.SUCCESS | typeof StorageStatics.TaskState.CANCELLED - | typeof StorageStatics.TaskState.ERROR - ), + | typeof StorageStatics.TaskState.ERROR, task: StorageTask, totalBytes: number, }; -declare type FuncSnapshotType = null|(snapshot: UploadTaskSnapshotType) => any; +declare type FuncSnapshotType = + | null + | ((snapshot: UploadTaskSnapshotType) => any); -declare type FuncErrorType = null|(error: Error) => any; +declare type FuncErrorType = null | ((error: Error) => any); -declare type NextOrObserverType = null | - { - next?: FuncSnapshotType, - error?: FuncErrorType, - complete?:FuncSnapshotType - } | - FuncSnapshotType; +declare type NextOrObserverType = + | null + | { + next?: FuncSnapshotType, + error?: FuncErrorType, + complete?: FuncSnapshotType, + } + | FuncSnapshotType; /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.UploadTask @@ -49,7 +51,11 @@ export default class StorageTask { then: () => Promise<*>; catch: () => Promise<*>; - constructor(type: typeof UPLOAD_TASK | typeof DOWNLOAD_TASK, promise: Promise<*>, storageRef: StorageReference) { + constructor( + type: typeof UPLOAD_TASK | typeof DOWNLOAD_TASK, + promise: Promise<*>, + storageRef: StorageReference + ) { this.type = type; this.ref = storageRef; this.storage = storageRef._storage; @@ -66,9 +72,9 @@ export default class StorageTask { * @returns {Promise.} * @private */ - _interceptSnapshotEvent(f: ?Function): null | () => * { + _interceptSnapshotEvent(f: ?Function): null | (() => *) { if (!isFunction(f)) return null; - return (snapshot) => { + return snapshot => { const _snapshot = Object.assign({}, snapshot); _snapshot.task = this; _snapshot.ref = this.ref; @@ -82,9 +88,9 @@ export default class StorageTask { * @returns {*} * @private */ - _interceptErrorEvent(f: ?Function): null | (Error) => * { + _interceptErrorEvent(f: ?Function): null | (Error => *) { if (!isFunction(f)) return null; - return (error) => { + return error => { const _error = new Error(error.message); // $FlowFixMe _error.code = error.code; @@ -100,7 +106,11 @@ export default class StorageTask { * @returns {function()} * @private */ - _subscribe(nextOrObserver: NextOrObserverType, error: FuncErrorType, complete: FuncSnapshotType): Function { + _subscribe( + nextOrObserver: NextOrObserverType, + error: FuncErrorType, + complete: FuncSnapshotType + ): Function { let _error; let _next; let _complete; @@ -119,28 +129,31 @@ export default class StorageTask { this.storage._addListener( this.path, StorageStatics.TaskEvent.STATE_CHANGED, - _next, + _next ); } if (_error) { - this.storage._addListener( - this.path, - `${this.type}_failure`, - _error, - ); + this.storage._addListener(this.path, `${this.type}_failure`, _error); } if (_complete) { - this.storage._addListener( - this.path, - `${this.type}_success`, - _complete, - ); + this.storage._addListener(this.path, `${this.type}_success`, _complete); } return () => { - if (_next) this.storage._removeListener(this.path, StorageStatics.TaskEvent.STATE_CHANGED, _next); - if (_error) this.storage._removeListener(this.path, `${this.type}_failure`, _error); - if (_complete) this.storage._removeListener(this.path, `${this.type}_success`, _complete); + if (_next) + this.storage._removeListener( + this.path, + StorageStatics.TaskEvent.STATE_CHANGED, + _next + ); + if (_error) + this.storage._removeListener(this.path, `${this.type}_failure`, _error); + if (_complete) + this.storage._removeListener( + this.path, + `${this.type}_success`, + _complete + ); }; } @@ -152,13 +165,24 @@ export default class StorageTask { * @param complete * @returns {function()} */ - on(event: string = StorageStatics.TaskEvent.STATE_CHANGED, nextOrObserver: NextOrObserverType, error: FuncErrorType, complete: FuncSnapshotType): Function { + on( + event: string = StorageStatics.TaskEvent.STATE_CHANGED, + nextOrObserver: NextOrObserverType, + error: FuncErrorType, + complete: FuncSnapshotType + ): Function { if (!event) { - throw new Error('StorageTask.on listener is missing required string argument \'event\'.'); + throw new Error( + "StorageTask.on listener is missing required string argument 'event'." + ); } if (event !== StorageStatics.TaskEvent.STATE_CHANGED) { - throw new Error(`StorageTask.on event argument must be a string with a value of '${StorageStatics.TaskEvent.STATE_CHANGED}'`); + throw new Error( + `StorageTask.on event argument must be a string with a value of '${ + StorageStatics.TaskEvent.STATE_CHANGED + }'` + ); } // if only event provided return the subscriber function @@ -170,16 +194,22 @@ export default class StorageTask { } pause() { - throw new Error('.pause() is not currently supported by react-native-firebase'); + throw new Error( + '.pause() is not currently supported by react-native-firebase' + ); } resume() { // todo - throw new Error('.resume() is not currently supported by react-native-firebase'); + throw new Error( + '.resume() is not currently supported by react-native-firebase' + ); } cancel() { // todo - throw new Error('.cancel() is not currently supported by react-native-firebase'); + throw new Error( + '.cancel() is not currently supported by react-native-firebase' + ); } } diff --git a/lib/modules/utils/index.js b/lib/modules/utils/index.js index 0cfb2ed0..f42fbf94 100644 --- a/lib/modules/utils/index.js +++ b/lib/modules/utils/index.js @@ -12,8 +12,8 @@ type GoogleApiAvailabilityType = { isAvailable: boolean, isUserResolvableError?: boolean, hasResolution?: boolean, - error?: string -} + error?: string, +}; export const MODULE_NAME = 'RNFirebaseUtils'; export const NAMESPACE = 'utils'; @@ -36,12 +36,16 @@ export default class RNFirebaseUtils extends ModuleBase { const { status } = this.playServicesAvailability; if (!this.playServicesAvailability.isAvailable) { - if (INTERNALS.OPTIONS.promptOnMissingPlayServices && this.playServicesAvailability.isUserResolvableError) { + if ( + INTERNALS.OPTIONS.promptOnMissingPlayServices && + this.playServicesAvailability.isUserResolvableError + ) { this.promptForPlayServices(); } else { const error = INTERNALS.STRINGS.ERROR_PLAY_SERVICES(status); if (INTERNALS.OPTIONS.errorOnMissingPlayServices) { - if (status === 2) console.warn(error); // only warn if it exists but may need an update + if (status === 2) + console.warn(error); // only warn if it exists but may need an update else throw new Error(error); } else { console.warn(error); @@ -80,7 +84,12 @@ export default class RNFirebaseUtils extends ModuleBase { * @return {RNFirebase.GoogleApiAvailabilityType|{isAvailable: boolean, status: number}} */ get playServicesAvailability(): GoogleApiAvailabilityType { - return FirebaseCoreModule.playServicesAvailability || { isAvailable: true, status: 0 }; + return ( + FirebaseCoreModule.playServicesAvailability || { + isAvailable: true, + status: 0, + } + ); } /** @@ -102,5 +111,4 @@ export default class RNFirebaseUtils extends ModuleBase { } } - export const statics = {}; diff --git a/lib/types/index.js b/lib/types/index.js index f410f40d..0308f711 100644 --- a/lib/types/index.js +++ b/lib/types/index.js @@ -35,8 +35,8 @@ export type FirebaseError = { stack: string, path: string, details: string, - modifiers: string -} + modifiers: string, +}; export type FirebaseModule = $Subtype; @@ -45,15 +45,36 @@ export type FirebaseModuleConfig = { moduleName: FirebaseModuleName, multiApp: boolean, namespace: FirebaseNamespace, -} +}; -export type FirebaseModuleName = 'RNFirebaseAdmob' | 'RNFirebaseAnalytics' | 'RNFirebaseAuth' - | 'RNFirebaseRemoteConfig' | 'RNFirebaseCrash' | 'RNFirebaseCrashlytics' | 'RNFirebaseDatabase' - | 'RNFirebaseFirestore' | 'RNFirebaseLinks' | 'RNFirebaseMessaging' | 'RNFirebasePerformance' - | 'RNFirebaseStorage' | 'RNFirebaseUtils'; +export type FirebaseModuleName = + | 'RNFirebaseAdmob' + | 'RNFirebaseAnalytics' + | 'RNFirebaseAuth' + | 'RNFirebaseRemoteConfig' + | 'RNFirebaseCrash' + | 'RNFirebaseCrashlytics' + | 'RNFirebaseDatabase' + | 'RNFirebaseFirestore' + | 'RNFirebaseLinks' + | 'RNFirebaseMessaging' + | 'RNFirebasePerformance' + | 'RNFirebaseStorage' + | 'RNFirebaseUtils'; -export type FirebaseNamespace = 'admob' | 'analytics' | 'auth' | 'config' | 'crash' - | 'crashlytics' | 'database' | 'firestore' | 'links' | 'messaging' | 'perf' | 'storage' +export type FirebaseNamespace = + | 'admob' + | 'analytics' + | 'auth' + | 'config' + | 'crash' + | 'crashlytics' + | 'database' + | 'firestore' + | 'links' + | 'messaging' + | 'perf' + | 'storage' | 'utils'; export type FirebaseOptions = { @@ -63,7 +84,7 @@ export type FirebaseOptions = { messagingSenderId: string, projectId: string, storageBucket: string, -} +}; export type FirebaseModuleAndStatics = { (): M, @@ -115,14 +136,14 @@ export type DatabaseModule = { } & DatabaseStatics; export type DatabaseModifier = { - id: string; - type: 'orderBy' | 'limit' | 'filter'; - name?: string; - key?: string; - limit?: number; - value?: any; - valueType?: string; -} + id: string, + type: 'orderBy' | 'limit' | 'filter', + name?: string, + key?: string, + limit?: number, + value?: any, + valueType?: string, +}; /* Fabric types */ export type CrashlyticsModule = { @@ -132,7 +153,7 @@ export type CrashlyticsModule = { export type FabricModule = { crashlytics: CrashlyticsModule, -} +}; /* Firestore types */ @@ -146,30 +167,41 @@ export type FirestoreNativeDocumentChange = { newIndex: number, oldIndex: number, type: string, -} +}; export type FirestoreNativeDocumentSnapshot = { data: { [string]: FirestoreTypeMap }, metadata: FirestoreSnapshotMetadata, path: string, -} +}; export type FirestoreSnapshotMetadata = { fromCache: boolean, hasPendingWrites: boolean, -} +}; export type FirestoreQueryDirection = 'DESC' | 'desc' | 'ASC' | 'asc'; export type FirestoreQueryOperator = '<' | '<=' | '=' | '==' | '>' | '>='; export type FirestoreTypeMap = { - type: 'array' | 'boolean' | 'date' | 'documentid' | 'fieldvalue' | 'geopoint' | 'null' | 'number' | 'object' | 'reference' | 'string', + type: + | 'array' + | 'boolean' + | 'date' + | 'documentid' + | 'fieldvalue' + | 'geopoint' + | 'null' + | 'number' + | 'object' + | 'reference' + | 'string', value: any, -} +}; export type FirestoreWriteOptions = { merge?: boolean, -} +}; /* Links types */ diff --git a/lib/utils/ModuleBase.js b/lib/utils/ModuleBase.js index 6f1ac1a1..8b68c7fd 100644 --- a/lib/utils/ModuleBase.js +++ b/lib/utils/ModuleBase.js @@ -29,7 +29,10 @@ export default class ModuleBase { // check if native module exists as all native initialiseNativeModule(this, config); - initialiseLogger(this, `${app.name}:${moduleName.replace('RNFirebase', '')}`); + initialiseLogger( + this, + `${app.name}:${moduleName.replace('RNFirebase', '')}` + ); } /** diff --git a/lib/utils/ReferenceBase.js b/lib/utils/ReferenceBase.js index 80e0eede..f774e230 100644 --- a/lib/utils/ReferenceBase.js +++ b/lib/utils/ReferenceBase.js @@ -15,6 +15,8 @@ export default class ReferenceBase { * {@link https://firebase.google.com/docs/reference/js/firebase.database.Reference#key} */ get key(): string | null { - return this.path === '/' ? null : this.path.substring(this.path.lastIndexOf('/') + 1); + return this.path === '/' + ? null + : this.path.substring(this.path.lastIndexOf('/') + 1); } } diff --git a/lib/utils/SyncTree.js b/lib/utils/SyncTree.js index 36c97c21..17de49e3 100644 --- a/lib/utils/SyncTree.js +++ b/lib/utils/SyncTree.js @@ -8,7 +8,7 @@ import DatabaseSnapshot from '../modules/database/snapshot'; import DatabaseReference from '../modules/database/reference'; import { isString, nativeToJSError } from '../utils'; -type Listener = (DatabaseSnapshot) => any; +type Listener = DatabaseSnapshot => any; type Registration = { key: string, @@ -19,7 +19,7 @@ type Registration = { listener: Listener, eventRegistrationKey: string, ref: DatabaseReference, -} +}; /** * Internally used to manage firebase database realtime event @@ -28,16 +28,18 @@ type Registration = { class SyncTree { _nativeEmitter: NativeEventEmitter; _reverseLookup: { [string]: Registration }; - _tree: { [string]: { [string]: { [string]: Listener }}}; + _tree: { [string]: { [string]: { [string]: Listener } } }; constructor() { this._tree = {}; this._reverseLookup = {}; if (NativeModules.RNFirebaseDatabase) { - this._nativeEmitter = new NativeEventEmitter(NativeModules.RNFirebaseDatabase); + this._nativeEmitter = new NativeEventEmitter( + NativeModules.RNFirebaseDatabase + ); this._nativeEmitter.addListener( 'database_sync_event', - this._handleSyncEvent.bind(this), + this._handleSyncEvent.bind(this) ); } } @@ -82,11 +84,10 @@ class SyncTree { return SharedEventEmitter.emit( eventRegistrationKey, new DatabaseSnapshot(registration.ref, snapshot), - previousChildName, + previousChildName ); } - /** * Routes native database query listener cancellation events to their js counterparts. * @@ -96,7 +97,10 @@ class SyncTree { _handleErrorEvent(event) { // console.log('SyncTree.ERROR >>>', event); const { code, message } = event.error; - const { eventRegistrationKey, registrationCancellationKey } = event.registration; + const { + eventRegistrationKey, + registrationCancellationKey, + } = event.registration; const registration = this.getRegistration(registrationCancellationKey); @@ -121,7 +125,9 @@ class SyncTree { * @return {null} */ getRegistration(registration: string): Registration | null { - return this._reverseLookup[registration] ? Object.assign({}, this._reverseLookup[registration]) : null; + return this._reverseLookup[registration] + ? Object.assign({}, this._reverseLookup[registration]) + : null; } /** @@ -159,7 +165,9 @@ class SyncTree { for (let i = 0, len = registrations.length; i < len; i++) { const registration = registrations[i]; - const subscriptions = SharedEventEmitter._subscriber.getSubscriptionsForType(registration); + const subscriptions = SharedEventEmitter._subscriber.getSubscriptionsForType( + registration + ); if (subscriptions) { for (let j = 0, l = subscriptions.length; j < l; j++) { const subscription = subscriptions[j]; @@ -188,7 +196,10 @@ class SyncTree { const eventKeys = Object.keys(this._tree[path] || {}); for (let i = 0, len = eventKeys.length; i < len; i++) { - Array.prototype.push.apply(out, Object.keys(this._tree[path][eventKeys[i]])); + Array.prototype.push.apply( + out, + Object.keys(this._tree[path][eventKeys[i]]) + ); } return out; @@ -216,11 +227,17 @@ class SyncTree { * @param listener * @return {Array} */ - getOneByPathEventListener(path: string, eventType: string, listener: Function): ?string { + getOneByPathEventListener( + path: string, + eventType: string, + listener: Function + ): ?string { if (!this._tree[path]) return null; if (!this._tree[path][eventType]) return null; - const registrationsForPathEvent = Object.entries(this._tree[path][eventType]); + const registrationsForPathEvent = Object.entries( + this._tree[path][eventType] + ); for (let i = 0; i < registrationsForPathEvent.length; i++) { const registration = registrationsForPathEvent[i]; @@ -230,7 +247,6 @@ class SyncTree { return null; } - /** * Register a new listener. * @@ -256,7 +272,7 @@ class SyncTree { if (once) { SharedEventEmitter.once( eventRegistrationKey, - this._onOnceRemoveRegistration(eventRegistrationKey, listener), + this._onOnceRemoveRegistration(eventRegistrationKey, listener) ); } else { SharedEventEmitter.addListener(eventRegistrationKey, listener); diff --git a/lib/utils/apps.js b/lib/utils/apps.js index 5e3a9c7f..7ff37b34 100644 --- a/lib/utils/apps.js +++ b/lib/utils/apps.js @@ -18,7 +18,7 @@ import type { const FirebaseCoreModule = NativeModules.RNFirebase; const APPS: { [string]: App } = {}; -const APP_MODULES: { [App]: { [string]: FirebaseModule }} = {}; +const APP_MODULES: { [App]: { [string]: FirebaseModule } } = {}; const DEFAULT_APP_NAME = '[DEFAULT]'; export default { @@ -43,13 +43,21 @@ export default { * @return {function()} * @private */ - appModule(app: App, namespace: FirebaseNamespace, InstanceClass: Class): () => FirebaseModule { + appModule( + app: App, + namespace: FirebaseNamespace, + InstanceClass: Class + ): () => FirebaseModule { return (): M => { if (!APP_MODULES[app]) { APP_MODULES[app] = {}; } - if (isAndroid && namespace !== 'utils' && !INTERNALS.FLAGS.checkedPlayServices) { + if ( + isAndroid && + namespace !== 'utils' && + !INTERNALS.FLAGS.checkedPlayServices + ) { INTERNALS.FLAGS.checkedPlayServices = true; app.utils().checkPlayServicesAvailability(); } @@ -148,16 +156,21 @@ export default { * @param InstanceClass * @return {function(App=)} */ - moduleAndStatics(namespace: FirebaseNamespace, statics: S, moduleName: FirebaseModuleName): FirebaseModuleAndStatics { + moduleAndStatics( + namespace: FirebaseNamespace, + statics: S, + moduleName: FirebaseModuleName + ): FirebaseModuleAndStatics { const getModule = (app?: App): FirebaseModule => { let _app = app; // throw an error if it's not a valid app instance - if (_app && !(_app instanceof App)) throw new Error(INTERNALS.STRINGS.ERROR_NOT_APP(namespace)); - - // default to the 'DEFAULT' app if no arg provided - will throw an error - // if default app not initialized - else if (!_app) _app = this.app(DEFAULT_APP_NAME); + if (_app && !(_app instanceof App)) + throw new Error(INTERNALS.STRINGS.ERROR_NOT_APP(namespace)); + else if (!_app) + // default to the 'DEFAULT' app if no arg provided - will throw an error + // if default app not initialized + _app = this.app(DEFAULT_APP_NAME); if (namespace === 'crashlytics') { return _app.fabric[namespace](); } diff --git a/lib/utils/events.js b/lib/utils/events.js index 83152dba..1d53798e 100644 --- a/lib/utils/events.js +++ b/lib/utils/events.js @@ -12,11 +12,15 @@ const NATIVE_SUBSCRIPTIONS: { [string]: boolean } = {}; export const SharedEventEmitter = new EventEmitter(); -export const getAppEventName = (module: ModuleBase, eventName: string): string => { - return `${module.app.name}-${eventName}`; -}; +export const getAppEventName = ( + module: ModuleBase, + eventName: string +): string => `${module.app.name}-${eventName}`; -const getNativeEmitter = (moduleName: FirebaseModuleName, module: ModuleBase): NativeEventEmitter => { +const getNativeEmitter = ( + moduleName: FirebaseModuleName, + module: ModuleBase +): NativeEventEmitter => { const name = `${module.app.name}-${moduleName}`; const nativeModule = NativeModules[moduleName]; if (!NATIVE_EMITTERS[name]) { @@ -35,10 +39,14 @@ const getNativeEmitter = (moduleName: FirebaseModuleName, module: ModuleBase): N * @param eventName * @private */ -const subscribeToNativeModuleEvents = (moduleName: FirebaseModuleName, module: ModuleBase, eventName: string): void => { +const subscribeToNativeModuleEvents = ( + moduleName: FirebaseModuleName, + module: ModuleBase, + eventName: string +): void => { if (!NATIVE_SUBSCRIPTIONS[eventName]) { const nativeEmitter = getNativeEmitter(moduleName, module); - nativeEmitter.addListener(eventName, (event) => { + nativeEmitter.addListener(eventName, event => { if (event.appName) { // native event has an appName property - auto prefix and internally emit SharedEventEmitter.emit(`${event.appName}-${eventName}`, event); @@ -52,7 +60,10 @@ const subscribeToNativeModuleEvents = (moduleName: FirebaseModuleName, module: M } }; -export const initialiseNativeModuleEventEmitter = (module: ModuleBase, config: FirebaseModuleConfig): void => { +export const initialiseNativeModuleEventEmitter = ( + module: ModuleBase, + config: FirebaseModuleConfig +): void => { const { events, moduleName } = config; if (events && events.length) { for (let i = 0, len = events.length; i < len; i++) { diff --git a/lib/utils/index.js b/lib/utils/index.js index 994bab1d..5ff9ba85 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -4,8 +4,10 @@ import { Platform } from 'react-native'; // todo cleanup unused utilities from legacy code // modeled after base64 web-safe chars, but ordered by ASCII -const PUSH_CHARS = '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz'; -const AUTO_ID_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; +const PUSH_CHARS = + '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz'; +const AUTO_ID_CHARS = + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; const { hasOwnProperty } = Object; // const DEFAULT_CHUNK_SIZE = 50; @@ -18,7 +20,11 @@ const { hasOwnProperty } = Object; * @param joiner * @returns {*} */ -export function deepGet(object: Object, path: string, joiner?: string = '/'): any { +export function deepGet( + object: Object, + path: string, + joiner?: string = '/' +): any { const keys = path.split(joiner); let i = 0; @@ -42,7 +48,11 @@ export function deepGet(object: Object, path: string, joiner?: string = '/'): an * @param joiner * @returns {*} */ -export function deepExists(object: Object, path: string, joiner?: string = '/'): boolean { +export function deepExists( + object: Object, + path: string, + joiner?: string = '/' +): boolean { const keys = path.split(joiner); let i = 0; @@ -64,18 +74,23 @@ export function deepExists(object: Object, path: string, joiner?: string = '/'): * @param obj2 * @returns {boolean} */ -export function areObjectKeysContainedInOther(obj1 : Object, obj2: Object): boolean { +export function areObjectKeysContainedInOther( + obj1: Object, + obj2: Object +): boolean { if (!isObject(obj1) || !isObject(obj2)) { return false; } const keys1 = Object.keys(obj1); const keys2 = Object.keys(obj2); if (isArrayContainedInOther(keys1, keys2)) { - return keys1.filter((key) => { - return isObject(obj1[key]); - }).reduce((acc, cur) => { - return acc && areObjectKeysContainedInOther(obj1[cur], obj2[cur]); - }, true); + return keys1 + .filter(key => isObject(obj1[key])) + .reduce( + (acc, cur) => + acc && areObjectKeysContainedInOther(obj1[cur], obj2[cur]), + true + ); } return false; } @@ -86,13 +101,14 @@ export function areObjectKeysContainedInOther(obj1 : Object, obj2: Object): bool * @param arr2 * @returns {boolean} */ -export function isArrayContainedInOther(arr1: Array<*>, arr2: Array<*>): boolean { +export function isArrayContainedInOther( + arr1: Array<*>, + arr2: Array<*> +): boolean { if (!Array.isArray(arr1) || !Array.isArray(arr2)) { return false; } - return arr1.reduce((acc, cur) => { - return acc && arr2.includes(cur); - }, true); + return arr1.reduce((acc, cur) => acc && arr2.includes(cur), true); } /** @@ -101,7 +117,9 @@ export function isArrayContainedInOther(arr1: Array<*>, arr2: Array<*>): boolean * @returns {boolean} */ export function isObject(item: mixed): boolean %checks { - return item ? (typeof item === 'object' && !Array.isArray(item) && item !== null) : false; + return item + ? typeof item === 'object' && !Array.isArray(item) && item !== null + : false; } /** @@ -126,7 +144,6 @@ export function isString(value: mixed): boolean %checks { export const isIOS = Platform.OS === 'ios'; export const isAndroid = Platform.OS === 'android'; - /** * * @param string @@ -153,16 +170,16 @@ export function tryJSONStringify(data: mixed): string | null { } } - -// noinspection Eslint -export const windowOrGlobal = (typeof self === 'object' && self.self === self && self) || (typeof global === 'object' && global.global === global && global) || this; +export const windowOrGlobal = + // eslint-disable-next-line no-restricted-globals + (typeof self === 'object' && self.self === self && self) || + (typeof global === 'object' && global.global === global && global) || + this; /** * No operation func */ -export function noop(): void { -} - +export function noop(): void {} // /** // * Delays chunks based on sizes per event loop. @@ -286,7 +303,7 @@ const lastRandChars = []; export function generatePushID(serverTimeOffset?: number = 0): string { const timeStampChars = new Array(8); let now = new Date().getTime() + serverTimeOffset; - const duplicateTime = (now === lastPushTime); + const duplicateTime = now === lastPushTime; lastPushTime = now; @@ -295,7 +312,8 @@ export function generatePushID(serverTimeOffset?: number = 0): string { now = Math.floor(now / 64); } - if (now !== 0) throw new Error('We should have converted the entire timestamp.'); + if (now !== 0) + throw new Error('We should have converted the entire timestamp.'); let id = timeStampChars.join(''); @@ -330,7 +348,11 @@ export function generatePushID(serverTimeOffset?: number = 0): string { * @param additionalProps * @returns {Error} */ -export function nativeToJSError(code: string, message: string, additionalProps?: Object = {}) { +export function nativeToJSError( + code: string, + message: string, + additionalProps?: Object = {} +) { const error: Object = new Error(message); error.code = code; Object.assign(error, additionalProps); @@ -362,7 +384,6 @@ export function objectToUniqueId(object: Object): string { return key; } - /** * Return the existing promise if no callback provided or * exec the promise and callback if optionalCallback is valid. @@ -371,23 +392,28 @@ export function objectToUniqueId(object: Object): string { * @param optionalCallback * @return {Promise} */ -export function promiseOrCallback(promise: Promise<*>, optionalCallback?: Function): Promise<*> { +export function promiseOrCallback( + promise: Promise<*>, + optionalCallback?: Function +): Promise<*> { if (!isFunction(optionalCallback)) return promise; - return promise.then((result) => { - // some of firebase internal tests & methods only check/return one arg - // see https://github.com/firebase/firebase-js-sdk/blob/master/src/utils/promise.ts#L62 - if (optionalCallback && optionalCallback.length === 1) { - optionalCallback(null); - } else if (optionalCallback) { - optionalCallback(null, result); - } + return promise + .then(result => { + // some of firebase internal tests & methods only check/return one arg + // see https://github.com/firebase/firebase-js-sdk/blob/master/src/utils/promise.ts#L62 + if (optionalCallback && optionalCallback.length === 1) { + optionalCallback(null); + } else if (optionalCallback) { + optionalCallback(null, result); + } - return Promise.resolve(result); - }).catch((error) => { - if (optionalCallback) optionalCallback(error); - return Promise.reject(error); - }); + return Promise.resolve(result); + }) + .catch(error => { + if (optionalCallback) optionalCallback(error); + return Promise.reject(error); + }); } /** @@ -398,7 +424,9 @@ export function firestoreAutoId(): string { let autoId = ''; for (let i = 0; i < 20; i++) { - autoId += AUTO_ID_CHARS.charAt(Math.floor(Math.random() * AUTO_ID_CHARS.length)); + autoId += AUTO_ID_CHARS.charAt( + Math.floor(Math.random() * AUTO_ID_CHARS.length) + ); } return autoId; } diff --git a/lib/utils/internals.js b/lib/utils/internals.js index 13b7bedc..05e611f7 100644 --- a/lib/utils/internals.js +++ b/lib/utils/internals.js @@ -29,17 +29,20 @@ const PLAY_SERVICES_CODES = { // $FlowBug: Doesn't like numerical object keys: https://github.com/facebook/flow/issues/380 2: { code: 'SERVICE_VERSION_UPDATE_REQUIRED', - message: 'The installed version of Google Play services on this device is out of date.', + message: + 'The installed version of Google Play services on this device is out of date.', }, // $FlowBug: Doesn't like numerical object keys: https://github.com/facebook/flow/issues/380 3: { code: 'SERVICE_DISABLED', - message: 'The installed version of Google Play services has been disabled on this device.', + message: + 'The installed version of Google Play services has been disabled on this device.', }, // $FlowBug: Doesn't like numerical object keys: https://github.com/facebook/flow/issues/380 9: { code: 'SERVICE_INVALID', - message: 'The version of the Google Play services installed on this device is not authentic.', + message: + 'The version of the Google Play services installed on this device is not authentic.', }, // $FlowBug: Doesn't like numerical object keys: https://github.com/facebook/flow/issues/380 18: { @@ -49,7 +52,8 @@ const PLAY_SERVICES_CODES = { // $FlowBug: Doesn't like numerical object keys: https://github.com/facebook/flow/issues/380 19: { code: 'SERVICE_MISSING_PERMISSION', - message: 'Google Play service doesn\'t have one or more required permissions.', + message: + "Google Play service doesn't have one or more required permissions.", }, }; @@ -66,27 +70,33 @@ export default { }, STRINGS: { - WARN_INITIALIZE_DEPRECATION: 'Deprecation: Calling \'initializeApp()\' for apps that are already initialised natively ' + - 'is unnecessary, use \'firebase.app()\' instead to access the already initialized default app instance.', + WARN_INITIALIZE_DEPRECATION: + "Deprecation: Calling 'initializeApp()' for apps that are already initialised natively " + + "is unnecessary, use 'firebase.app()' instead to access the already initialized default app instance.", /** * @return {string} */ get ERROR_MISSING_CORE() { if (Platform.OS === 'ios') { - return 'RNFirebase core module was not found natively on iOS, ensure you have ' + + return ( + 'RNFirebase core module was not found natively on iOS, ensure you have ' + 'correctly included the RNFirebase pod in your projects `Podfile` and have run `pod install`.' + - '\r\n\r\n See http://invertase.link/ios for the ios setup guide.'; + '\r\n\r\n See http://invertase.link/ios for the ios setup guide.' + ); } - return 'RNFirebase core module was not found natively on Android, ensure you have ' + + return ( + 'RNFirebase core module was not found natively on Android, ensure you have ' + 'correctly added the RNFirebase and Firebase gradle dependencies to your `android/app/build.gradle` file.' + - '\r\n\r\n See http://invertase.link/android for the android setup guide.'; + '\r\n\r\n See http://invertase.link/android for the android setup guide.' + ); }, - - ERROR_INIT_OBJECT: 'Firebase.initializeApp(options <-- requires a valid configuration object.', - ERROR_INIT_STRING_NAME: 'Firebase.initializeApp(options, name <-- requires a valid string value.', + ERROR_INIT_OBJECT: + 'Firebase.initializeApp(options <-- requires a valid configuration object.', + ERROR_INIT_STRING_NAME: + 'Firebase.initializeApp(options, name <-- requires a valid string value.', /** * @return {string} @@ -131,20 +141,28 @@ export default { ERROR_MISSING_MODULE(namespace: string, nativeModule: string) { const snippet = `firebase.${namespace}()`; if (Platform.OS === 'ios') { - return `You attempted to use a firebase module that's not installed natively on your iOS project by calling ${snippet}.` + + return ( + `You attempted to use a firebase module that's not installed natively on your iOS project by calling ${snippet}.` + '\r\n\r\nEnsure you have the required Firebase iOS SDK pod for this module included in your Podfile, in this instance ' + - `confirm you've added "pod '${NAMESPACE_PODS[namespace]}'" to your Podfile` + - '\r\n\r\nSee http://invertase.link/ios for full setup instructions.'; + `confirm you've added "pod '${ + NAMESPACE_PODS[namespace] + }'" to your Podfile` + + '\r\n\r\nSee http://invertase.link/ios for full setup instructions.' + ); } - const fbSDKDep = `'com.google.firebase:firebase-${GRADLE_DEPS[namespace] || namespace}'`; + const fbSDKDep = `'com.google.firebase:firebase-${GRADLE_DEPS[ + namespace + ] || namespace}'`; const rnFirebasePackage = `'io.invertase.firebase.${namespace}.${nativeModule}Package'`; const newInstance = `'new ${nativeModule}Package()'`; - return `You attempted to use a firebase module that's not installed on your Android project by calling ${snippet}.` + + return ( + `You attempted to use a firebase module that's not installed on your Android project by calling ${snippet}.` + `\r\n\r\nEnsure you have:\r\n\r\n1) Installed the required Firebase Android SDK dependency ${fbSDKDep} in your 'android/app/build.gradle' ` + `file.\r\n\r\n2) Imported the ${rnFirebasePackage} module in your 'MainApplication.java' file.\r\n\r\n3) Added the ` + `${newInstance} line inside of the RN 'getPackages()' method list.` + - '\r\n\r\nSee http://invertase.link/android for full setup instructions.'; + '\r\n\r\nSee http://invertase.link/android for full setup instructions.' + ); }, /** @@ -191,29 +209,30 @@ export default { return `firebase.${namespace}().${method}() is unsupported by the native Firebase SDKs.`; }, - /** * @return {string} */ ERROR_PLAY_SERVICES(statusCode: number) { const knownError = PLAY_SERVICES_CODES[statusCode]; - let start = 'Google Play Services is required to run firebase services on android but a valid installation was not found on this device.'; + let start = + 'Google Play Services is required to run firebase services on android but a valid installation was not found on this device.'; if (statusCode === 2) { - start = 'Google Play Services is out of date and may cause some firebase services like authentication to hang when used. It is recommended that you update it.'; + start = + 'Google Play Services is out of date and may cause some firebase services like authentication to hang when used. It is recommended that you update it.'; } // eslint-disable-next-line prefer-template - return `${start}\r\n\r\n` + - '-------------------------\r\n' + - (knownError ? - `${knownError.code}: ${knownError.message} (code ${statusCode})` : - `A specific play store availability reason reason was not available (unknown code: ${statusCode})` - ) + - '\r\n-------------------------' + - '\r\n\r\n' + - 'For more information on how to resolve this issue, configure Play Services checks or for guides on how to validate Play Services on your users devices see the link below:' + - '\r\n\r\nhttp://invertase.link/play-services'; + return ( + `${`${start}\r\n\r\n-------------------------\r\n`}${ + knownError + ? `${knownError.code}: ${knownError.message} (code ${statusCode})` + : `A specific play store availability reason reason was not available (unknown code: ${statusCode})` + }\r\n-------------------------` + + `\r\n\r\n` + + `For more information on how to resolve this issue, configure Play Services checks or for guides on how to validate Play Services on your users devices see the link below:` + + `\r\n\r\nhttp://invertase.link/play-services` + ); }, }, }; diff --git a/lib/utils/log.js b/lib/utils/log.js index 68b5bc5c..44e36261 100644 --- a/lib/utils/log.js +++ b/lib/utils/log.js @@ -5,7 +5,7 @@ import { windowOrGlobal } from './'; import type ModuleBase from './ModuleBase'; -((base) => { +(base => { window = base || window; // $FlowFixMe: Why are we using localStorage at all? if (!window.localStorage) window.localStorage = {}; @@ -15,7 +15,8 @@ import type ModuleBase from './ModuleBase'; const NATIVE_LOGGERS: { [string]: Object } = {}; -const getModuleKey = (module: ModuleBase): string => `${module.app.name}:${module.namespace}`; +const getModuleKey = (module: ModuleBase): string => + `${module.app.name}:${module.namespace}`; export const getLogger = (module: ModuleBase) => { const key = getModuleKey(module); @@ -25,12 +26,14 @@ export const getLogger = (module: ModuleBase) => { export const initialiseLogger = (module: ModuleBase, logNamespace: string) => { const key = getModuleKey(module); if (!NATIVE_LOGGERS[key]) { + // eslint-disable-next-line global-require NATIVE_LOGGERS[key] = require('bows')(`🔥 ${logNamespace.toUpperCase()}`); } }; export default class Log { static createLogger(namespace: string) { + // eslint-disable-next-line global-require return require('bows')(namespace); } diff --git a/lib/utils/native.js b/lib/utils/native.js index 274862c6..248130c7 100644 --- a/lib/utils/native.js +++ b/lib/utils/native.js @@ -21,28 +21,32 @@ const nativeWithApp = (appName: string, NativeModule: Object): Object => { for (let i = 0, len = methods.length; i < len; i++) { const method = methods[i]; - native[method] = (...args) => { - return NativeModule[method](...[appName, ...args]); - }; + native[method] = (...args) => NativeModule[method](...[appName, ...args]); } return native; }; -const getModuleKey = (module: ModuleBase): string => `${module.app.name}:${module.namespace}`; +const getModuleKey = (module: ModuleBase): string => + `${module.app.name}:${module.namespace}`; export const getNativeModule = (module: ModuleBase): Object => { const key = getModuleKey(module); return NATIVE_MODULES[key]; }; -export const initialiseNativeModule = (module: ModuleBase, config: FirebaseModuleConfig): Object => { +export const initialiseNativeModule = ( + module: ModuleBase, + config: FirebaseModuleConfig +): Object => { const { moduleName, multiApp, namespace } = config; const nativeModule = NativeModules[moduleName]; const key = getModuleKey(module); if (!nativeModule && namespace !== 'utils') { - throw new Error(INTERNALS.STRINGS.ERROR_MISSING_MODULE(namespace, moduleName)); + throw new Error( + INTERNALS.STRINGS.ERROR_MISSING_MODULE(namespace, moduleName) + ); } // used by the modules that extend ModuleBase diff --git a/tests/.eslintrc b/tests/.eslintrc index 91cb3e62..daf94a0b 100644 --- a/tests/.eslintrc +++ b/tests/.eslintrc @@ -1,42 +1,39 @@ { - "extends": "airbnb", + "extends": [ + "airbnb", + "prettier", + "prettier/flowtype", + "prettier/react" + ], "parser": "babel-eslint", - "ecmaFeatures": { - "jsx": true - }, "plugins": [ - "flowtype" + "flowtype", + "prettier" ], "env": { "es6": true, "jasmine": true }, - "parserOptions": { - "ecmaFeatures": { - "experimentalObjectRestSpread": true - } - }, "rules": { - "no-plusplus": 0, + "prettier/prettier": ["error", { + "trailingComma": "es5", + "singleQuote": true + }], + + "react/forbid-prop-types": "warn", + "react/jsx-filename-extension": [ + "off", { "extensions": [".js", ".jsx"] } + ], + "class-methods-use-this": 0, - "no-underscore-dangle": 0, - "no-use-before-define": 0, - "arrow-body-style": 0, - "import/prefer-default-export": 0, - "radix": 0, - "new-cap": 0, - "max-len": 0, - "no-continue": 0, "no-console": 0, - "global-require": 0, - "import/extensions": 0, - "import/no-unresolved": 0, - "import/no-extraneous-dependencies": 0, - "react/jsx-filename-extension": 0 + "no-plusplus": 0, + "no-undef": 0, + "no-underscore-dangle": "off", + "no-use-before-define": 0 }, "globals": { "__DEV__": true, - "window": true, - "fetch": true, + "window": true } } diff --git a/tests/index.js b/tests/index.js index c094bada..597382bc 100644 --- a/tests/index.js +++ b/tests/index.js @@ -2,4 +2,3 @@ import { AppRegistry } from 'react-native'; import bootstrap from './src/main'; AppRegistry.registerComponent('ReactNativeFirebaseDemo', () => bootstrap); - diff --git a/tests/lib/TestDSL.js b/tests/lib/TestDSL.js index bbdd5502..282d6ffe 100644 --- a/tests/lib/TestDSL.js +++ b/tests/lib/TestDSL.js @@ -199,7 +199,6 @@ class TestDSL { this.it(description, _options, _testFunction); } - /** * Defines a new focused test. Focused tests are the only * ones that appear and are run when the test suite is executed. @@ -240,12 +239,4 @@ class TestDSL { } } -/** - * Log a test DSL error to the console. - * @param {String} error - Message to included in message logged to the console - */ -function testDSLError(error) { - console.error(`ReactNativeFirebaseTests.TestDSLError: ${error}`); - console.error('This test was ignored.'); -} export default TestDSL; diff --git a/tests/lib/TestRun.js b/tests/lib/TestRun.js index bcabe188..8f7b7b0f 100644 --- a/tests/lib/TestRun.js +++ b/tests/lib/TestRun.js @@ -25,7 +25,6 @@ function cleanStack(stack, maxLines = 5) { return out.join('\r\n'); } - /** * Class that encapsulates synchronously running a suite's tests. */ @@ -50,9 +49,13 @@ class TestRun { this.rootContextId = testDefinitions.rootTestContextId; this.testContexts = tests.reduce((memo, test) => { - const testContextId = test.testContextId; + const { testContextId } = test; - this._recursivelyAddContextsTo(memo, testContextId, testDefinitions.testContexts); + this._recursivelyAddContextsTo( + memo, + testContextId, + testDefinitions.testContexts + ); memo[testContextId].tests.unshift(test); @@ -101,7 +104,7 @@ class TestRun { target[id].childContextIds[childContextId] = true; } - const parentContextId = testContext.parentContextId; + const { parentContextId } = testContext; if (parentContextId) { this._recursivelyAddContextsTo(target, parentContextId, source, id); @@ -123,7 +126,11 @@ class TestRun { const store = this.testSuite.reduxStore; if (!store) { - testRuntimeError(`Failed to run ${this.testSuite.name} tests as no Redux store has been provided`); + testRuntimeError( + `Failed to run ${ + this.testSuite.name + } tests as no Redux store has been provided` + ); } this._updateStatus(EVENTS.TEST_SUITE_STATUS, { @@ -152,17 +159,19 @@ class TestRun { progress: 100, time: Date.now() - this.runStartTime, - message: `${errors.length} test${errors.length > 1 ? 's' : ''} has error(s).`, + message: `${errors.length} test${ + errors.length > 1 ? 's' : '' + } has error(s).`, }); } else { - this._updateStatus(EVENTS.TEST_SUITE_STATUS, ({ + this._updateStatus(EVENTS.TEST_SUITE_STATUS, { suiteId: this.testSuite.id, status: RunStatus.OK, progress: 100, time: Date.now() - this.runStartTime, message: '', - })); + }); } } } @@ -179,19 +188,35 @@ class TestRun { * @returns {Promise.} Resolves once all tests and their hooks have run * @private */ - async _runTestsInContext(testContext, beforeEachHooks = [], afterEachHooks = []) { + async _runTestsInContext( + testContext, + beforeEachHooks = [], + afterEachHooks = [] + ) { const beforeHookRan = await this._runContextHooks(testContext, 'before'); if (beforeHookRan) { beforeEachHooks.push(testContext.beforeEachHooks || []); afterEachHooks.unshift(testContext.afterEachHooks || []); - await this._runTests(testContext, testContext.tests, flatten(beforeEachHooks), flatten(afterEachHooks)); + await this._runTests( + testContext, + testContext.tests, + flatten(beforeEachHooks), + flatten(afterEachHooks) + ); - await Promise.each(Object.keys(testContext.childContextIds), (childContextId) => { - const childContext = this.testContexts[childContextId]; - return this._runTestsInContext(childContext, beforeEachHooks, afterEachHooks); - }); + await Promise.each( + Object.keys(testContext.childContextIds), + childContextId => { + const childContext = this.testContexts[childContextId]; + return this._runTestsInContext( + childContext, + beforeEachHooks, + afterEachHooks + ); + } + ); beforeEachHooks.pop(); afterEachHooks.shift(); @@ -215,21 +240,39 @@ class TestRun { } _runHookChain(test, testStart, testContext, hookName, hooks) { - return Promise.each(hooks, async (hook) => { - const error = await this._safelyRunFunction(hook.callback, hook.timeout, `${hookName} hook`); + return Promise.each(hooks, async hook => { + const error = await this._safelyRunFunction( + hook.callback, + hook.timeout, + `${hookName} hook` + ); if (error) { - const errorPrefix = `Error occurred in "${testContext.name}" ${hookName} Hook: `; + const errorPrefix = `Error occurred in "${ + testContext.name + }" ${hookName} Hook: `; if (test) { - this._reportTestError(test, error, Date.now() - testStart, errorPrefix); + this._reportTestError( + test, + error, + Date.now() - testStart, + errorPrefix + ); } else { - this._reportAllTestsAsFailed(testContext, error, testStart, errorPrefix); + this._reportAllTestsAsFailed( + testContext, + error, + testStart, + errorPrefix + ); } throw new Error(); } - }).then(() => true).catch(() => false); + }) + .then(() => true) + .catch(() => false); } /** @@ -241,12 +284,17 @@ class TestRun { * @private */ _reportAllTestsAsFailed(testContext, error, testStart, errorPrefix) { - testContext.tests.forEach((test) => { + testContext.tests.forEach(test => { this._reportTestError(test, error, Date.now() - testStart, errorPrefix); }); - testContext.childContextIds.forEach((contextId) => { - this._reportAllTestsAsFailed(this.testContext[contextId], error, testStart, errorPrefix); + testContext.childContextIds.forEach(contextId => { + this._reportAllTestsAsFailed( + this.testContext[contextId], + error, + testStart, + errorPrefix + ); }); } @@ -262,7 +310,7 @@ class TestRun { * @private */ async _runTests(testContext, tests, beforeEachHooks, afterEachHooks) { - return Promise.each(tests, async (test) => { + return Promise.each(tests, async test => { this._updateStatus(EVENTS.TEST_STATUS, { testId: test.id, status: RunStatus.RUNNING, @@ -272,16 +320,29 @@ class TestRun { const testStart = Date.now(); - const beforeEachRan = await this._runHookChain(test, testStart, testContext, 'beforeEach', beforeEachHooks); + const beforeEachRan = await this._runHookChain( + test, + testStart, + testContext, + 'beforeEach', + beforeEachHooks + ); if (beforeEachRan) { - const error = await this._safelyRunFunction(test.func.bind(null, [test, this.testSuite.reduxStore.getState()]), test.timeout, 'Test'); + const error = await this._safelyRunFunction( + test.func.bind(null, [test, this.testSuite.reduxStore.getState()]), + test.timeout, + 'Test' + ); // Update test status if (error) { this._reportTestError(test, error, Date.now() - testStart); - console.groupCollapsed(`%c ❌ Test Failed: ${test.description} (${this.testSuite.name})`, 'color: #f44336;'); + console.groupCollapsed( + `%c ❌ Test Failed: ${test.description} (${this.testSuite.name})`, + 'color: #f44336;' + ); console.log(`Test Description: ${test.description}`); console.log(`Test Time Taken: ${Date.now() - testStart}`); console.log(`Suite Name: ${this.testSuite.name}`); @@ -299,7 +360,10 @@ class TestRun { message: '', }); - console.groupCollapsed(`%c ✅ Test Passed: ${test.description} (${this.testSuite.name})`, 'color: #4CAF50;'); + console.groupCollapsed( + `%c ✅ Test Passed: ${test.description} (${this.testSuite.name})`, + 'color: #4CAF50;' + ); console.log(`Test Description: ${test.description}`); console.log(`Test Time Taken: ${Date.now() - testStart}`); console.log(`Suite Name: ${this.testSuite.name}`); @@ -314,14 +378,20 @@ class TestRun { this._updateStatus(EVENTS.TEST_SUITE_STATUS, { suiteId: this.testSuite.id, status: RunStatus.RUNNING, - progress: (this.completedTests / this.tests.length) * 100, + progress: this.completedTests / this.tests.length * 100, time: Date.now() - this.runStartTime, message: '', }); - await this._runHookChain(test, testStart, testContext, 'afterEach', afterEachHooks); + await this._runHookChain( + test, + testStart, + testContext, + 'afterEach', + afterEachHooks + ); } - }).catch((error) => { + }).catch(error => { this._updateStatus(EVENTS.TEST_SUITE_STATUS, { suiteId: this.testSuite.id, status: RunStatus.ERR, @@ -346,7 +416,9 @@ class TestRun { testId: test.id, status: RunStatus.ERR, time, - message: `${errorPrefix}${error.message ? `${error.name}: ${error.message}` : error}`, + message: `${errorPrefix}${ + error.message ? `${error.name}: ${error.message}` : error + }`, stackTrace: cleanStack(error.stack), }); } @@ -368,9 +440,12 @@ class TestRun { } // Asynchronous Error - return capturePromiseErrors(syncResultOrPromise.result, timeOutDuration, description); + return capturePromiseErrors( + syncResultOrPromise.result, + timeOutDuration, + description + ); } - } /** @@ -410,15 +485,10 @@ function capturePromiseErrors(target, timeoutDuration, description) { try { returnValue = Promise.resolve(target) - .then(() => { - return null; - }, (error) => { - return Promise.resolve(error); - }) - .catch((error) => { - return Promise.resolve(error); - }) - .timeout(timeoutDuration, + .then(() => null, error => Promise.resolve(error)) + .catch(error => Promise.resolve(error)) + .timeout( + timeoutDuration, `${description} took longer than ${timeoutDuration}ms. This can be extended with the timeout option.` ); } catch (error) { @@ -434,9 +504,7 @@ function capturePromiseErrors(target, timeoutDuration, description) { * @returns {*[]} One-dimensional array */ function flatten(list) { - return list.reduce((memo, contextHooks) => { - return memo.concat(contextHooks); - }, []); + return list.reduce((memo, contextHooks) => memo.concat(contextHooks), []); } /** diff --git a/tests/lib/TestSuite.js b/tests/lib/TestSuite.js index aaa6735c..65d0b19b 100644 --- a/tests/lib/TestSuite.js +++ b/tests/lib/TestSuite.js @@ -110,31 +110,41 @@ class TestSuite { * testSuite.run([1, 2]); */ async run(testIds = undefined) { - const testsToRun = (() => { - return (testIds || Object.keys(this.testDefinitions.tests)).reduce((memo, id) => { - const test = this.testDefinitions.tests[id]; + const testsToRun = (() => + (testIds || Object.keys(this.testDefinitions.tests)).reduce( + (memo, id) => { + const test = this.testDefinitions.tests[id]; - if (!test) { - throw new RangeError(`ReactNativeFirebaseTests.TestRunError: Test with id ${id} not found in test suite ${this.name}`); - } + if (!test) { + throw new RangeError( + `ReactNativeFirebaseTests.TestRunError: Test with id ${id} not found in test suite ${ + this.name + }` + ); + } - if (!this.testDefinitions.pendingTestIds[id]) { - memo.push(test); - } + if (!this.testDefinitions.pendingTestIds[id]) { + memo.push(test); + } - return memo; - }, []); - })(); + return memo; + }, + [] + ))(); - const testRun = new TestRun(this, testsToRun.reverse(), this.testDefinitions); + const testRun = new TestRun( + this, + testsToRun.reverse(), + this.testDefinitions + ); - testRun.onChange('TEST_SUITE_STATUS', (values) => { + testRun.onChange('TEST_SUITE_STATUS', values => { if (this.suiteChangHandler) { this.suiteChangHandler(values); } }); - testRun.onChange('TEST_STATUS', (values) => { + testRun.onChange('TEST_STATUS', values => { if (this.testChangHandler) { this.testChangHandler(values); } @@ -142,7 +152,6 @@ class TestSuite { await testRun.execute(); } - } export default TestSuite; diff --git a/tests/lib/TestSuiteDefinition.js b/tests/lib/TestSuiteDefinition.js index ff250a21..b51eea22 100644 --- a/tests/lib/TestSuiteDefinition.js +++ b/tests/lib/TestSuiteDefinition.js @@ -41,7 +41,7 @@ function assignContextId() { * @enum {String} ContextOperator */ const CONTEXT_OPERATORS = { - /** Perform OR of test value with context chain values **/ + /** Perform OR of test value with context chain values * */ OR: 'OR', }; @@ -132,13 +132,18 @@ class TestSuiteDefinition { const hookAttribute = `${hookName}Hooks`; if (callback && typeof callback === 'function') { - this.currentTestContext[hookAttribute] = this.currentTestContext[hookAttribute] || []; + this.currentTestContext[hookAttribute] = + this.currentTestContext[hookAttribute] || []; this.currentTestContext[hookAttribute].push({ callback, timeout: options.timeout || 15000, }); } else { - testDefinitionError(`non-function value ${callback} passed to ${hookName} for '${this.currentTestContext.name}'`); + testDefinitionError( + `non-function value ${callback} passed to ${hookName} for '${ + this.currentTestContext.name + }'` + ); } } @@ -162,7 +167,10 @@ class TestSuiteDefinition { pushTestContext(name, options = {}) { const testContextId = assignContextId(); const parentContext = this.currentTestContext; - this.currentTestContext = this._initialiseContext(testContextId, Object.assign({ name, parentContextId: parentContext.id }, options)); + this.currentTestContext = this._initialiseContext( + testContextId, + Object.assign({ name, parentContextId: parentContext.id }, options) + ); } /** @@ -170,7 +178,7 @@ class TestSuiteDefinition { * current context. */ popTestContext() { - const parentContextId = this.currentTestContext.parentContextId; + const { parentContextId } = this.currentTestContext; this.currentTestContext = this.testContexts[parentContextId]; } @@ -199,7 +207,9 @@ class TestSuiteDefinition { this._createTest(testId, { testContextId: this.currentTestContext.id, testSuiteId: this.testSuite.id, - description: this._testDescriptionContextPrefix(this.currentTestContext) + description, + description: + this._testDescriptionContextPrefix(this.currentTestContext) + + description, func: _testFunction, timeout: _options.timeout || 5000, }); @@ -237,11 +247,17 @@ class TestSuiteDefinition { * @private */ _testDescriptionContextPrefix({ id, name, parentContextId }, suffix = '') { - if (id === this.rootTestContextId || parentContextId === this.rootTestContextId) { + if ( + id === this.rootTestContextId || + parentContextId === this.rootTestContextId + ) { return suffix; } - return this._testDescriptionContextPrefix(this.testContexts[parentContextId], `${name} ${suffix}`); + return this._testDescriptionContextPrefix( + this.testContexts[parentContextId], + `${name} ${suffix}` + ); } /** @@ -278,8 +294,18 @@ class TestSuiteDefinition { const newTestContext = { id: testContextId, name, - focus: this._incorporateParentValue(parentContext, 'focus', focus, CONTEXT_OPERATORS.OR), - pending: this._incorporateParentValue(parentContext, 'pending', pending, CONTEXT_OPERATORS.OR), + focus: this._incorporateParentValue( + parentContext, + 'focus', + focus, + CONTEXT_OPERATORS.OR + ), + pending: this._incorporateParentValue( + parentContext, + 'pending', + pending, + CONTEXT_OPERATORS.OR + ), parentContextId, testIds: [], testSuiteId: this.testSuite.id, @@ -327,7 +353,10 @@ class TestSuiteDefinition { * @returns {Test} New test matching provided options * @private */ - _createTest(testId, { testContextId, description, func, testSuiteId, timeout }) { + _createTest( + testId, + { testContextId, description, func, testSuiteId, timeout } + ) { const newTest = { id: testId, testContextId, @@ -344,7 +373,6 @@ class TestSuiteDefinition { return newTest; } - } /** diff --git a/tests/src/actions/AppActions.js b/tests/src/actions/AppActions.js index 1494c85e..0e14a7c9 100644 --- a/tests/src/actions/AppActions.js +++ b/tests/src/actions/AppActions.js @@ -8,10 +8,11 @@ export function setNetworkState(isConnected: boolean): Object { }; } -export function setAppState(appState: 'active' | 'background' | 'inactive'): Object { +export function setAppState( + appState: 'active' | 'background' | 'inactive' +): Object { return { type: APP_SET_APP_STATE, appState, }; } - diff --git a/tests/src/actions/TestActions.js b/tests/src/actions/TestActions.js index 71487b0a..f8855ee5 100644 --- a/tests/src/actions/TestActions.js +++ b/tests/src/actions/TestActions.js @@ -14,7 +14,13 @@ export function setSuiteStatus({ suiteId, status, time, message, progress }) { }; } -export function setTestStatus({ testId, status, stackTrace, time = 0, message = null }) { +export function setTestStatus({ + testId, + status, + stackTrace, + time = 0, + message = null, +}) { return { type: TEST_SET_STATUS, testId, diff --git a/tests/src/components/Banner.js b/tests/src/components/Banner.js index 8f3acaaf..dced4810 100644 --- a/tests/src/components/Banner.js +++ b/tests/src/components/Banner.js @@ -5,10 +5,7 @@ import { StyleSheet, View, Text } from 'react-native'; function Banner({ type, children, style, textStyle }) { return ( - + {children} @@ -16,18 +13,14 @@ function Banner({ type, children, style, textStyle }) { } Banner.propTypes = { - type: PropTypes.oneOf([ - 'success', - 'warning', - 'error', - 'info', - ]), - children: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.array, - ]).isRequired, + /* eslint-disable react/require-default-props */ + /* eslint-disable react/no-typos */ + type: PropTypes.oneOf(['success', 'warning', 'error', 'info']), + children: PropTypes.oneOfType([PropTypes.string, PropTypes.array]).isRequired, style: View.propTypes.style, textStyle: Text.propTypes.style, + /* eslint-enable react/require-default-props */ + /* eslint-enable react/no-typos */ }; const styles = StyleSheet.create({ diff --git a/tests/src/components/Icon.js b/tests/src/components/Icon.js index 8a2ace43..e5fb5136 100644 --- a/tests/src/components/Icon.js +++ b/tests/src/components/Icon.js @@ -4,6 +4,7 @@ import VectorIcon from 'react-native-vector-icons/MaterialIcons'; type Props = { name: string, + /* eslint-disable react/require-default-props */ size?: number, color?: string, allowFontScaling?: boolean, @@ -11,11 +12,11 @@ type Props = { rotate?: number, onPress?: () => void, underlayColor?: string, + /* eslint-enable react/require-default-props */ }; // TODO Spin? class Icon extends React.Component { - constructor() { super(); this.measured = false; @@ -36,15 +37,24 @@ class Icon extends React.Component { props: Props; render() { - const { name, size = 24, color = '#757575', allowFontScaling = true, style, rotate, onPress, underlayColor } = this.props; + const { + name, + size = 24, + color = '#757575', + allowFontScaling = true, + style, + rotate, + onPress, + underlayColor, + } = this.props; const icon = ( this.setDimensions(e)} + onLayout={e => this.setDimensions(e)} style={[ - style, - rotate ? { transform: [{ rotate: `${rotate}deg` }] } : null, - ]} + style, + rotate ? { transform: [{ rotate: `${rotate}deg` }] } : null, + ]} > ); } - } export default Icon; diff --git a/tests/src/components/OverviewControlButton.js b/tests/src/components/OverviewControlButton.js index 02a972f9..76adba5b 100644 --- a/tests/src/components/OverviewControlButton.js +++ b/tests/src/components/OverviewControlButton.js @@ -20,7 +20,10 @@ class OverviewControlButton extends Component { testSuitesAreRunning() { const { testSuites } = this.props; - return some(Object.values(testSuites), ({ status }) => status === RunStatus.RUNNING); + return some( + Object.values(testSuites), + ({ status }) => status === RunStatus.RUNNING + ); } handleOnPress() { @@ -31,18 +34,12 @@ class OverviewControlButton extends Component { render() { if (this.testSuitesAreRunning()) { - return ( - - ); + return ; } return ( 0) { - return ( - - - {progress.toFixed(0)}% - - - ); - } - +const StatusIndicator = ({ status, progress }) => { + switch (status) { + case RunStatus.RUNNING: + if (progress > 0) { return ( - + + + {progress.toFixed(0)}% + + ); - case RunStatus.OK: - return ( - - ); - case RunStatus.ERR: - return ( - - ); - default: - return null; - } + } + + return ; + case RunStatus.OK: + return ; + case RunStatus.ERR: + return ; + default: + return null; } - -} +}; StatusIndicator.propTypes = { status: PropTypes.oneOf(Object.values(RunStatus)), @@ -47,7 +35,7 @@ StatusIndicator.propTypes = { StatusIndicator.defaultProps = { status: null, - progress: 0 + progress: 0, }; module.exports = StatusIndicator; diff --git a/tests/src/components/TestControlButton.js b/tests/src/components/TestControlButton.js index 4b9a18b9..f667a8b9 100644 --- a/tests/src/components/TestControlButton.js +++ b/tests/src/components/TestControlButton.js @@ -21,7 +21,7 @@ class TestControlButton extends Component { } handleOnPress() { - const { test: { id, description } } = this.props; + const { test: { id } } = this.props; runTest(id); // Toast.show(`Running ${description}.`); @@ -33,7 +33,7 @@ class TestControlButton extends Component { if (status !== RunStatus.STARTED && !this.testIsPending()) { return ( { // eslint-disable-next-line no-param-reassign @@ -51,7 +58,7 @@ class TestSuiteControlButton extends Component { } else if (status !== RunStatus.RUNNING) { return ( { + NetInfo.isConnected.fetch().then(isConnected => { this.handleAppStateChange('active'); // Force connect (react debugger issue) this.props.dispatch(setNetworkState(isConnected)); - NetInfo.isConnected.addEventListener('connectionChange', this.handleNetworkChange); + NetInfo.isConnected.addEventListener( + 'connectionChange', + this.handleNetworkChange + ); }); } @@ -40,7 +42,10 @@ class CoreContainer extends React.Component { */ componentWillUnmount() { AppState.removeEventListener('change', this.handleAppStateChange); - NetInfo.isConnected.removeEventListener('connectionChange', this.handleNetworkChange); + NetInfo.isConnected.removeEventListener( + 'connectionChange', + this.handleNetworkChange + ); } props: Props; @@ -51,7 +56,7 @@ class CoreContainer extends React.Component { * https://facebook.github.io/react-native/docs/appstate.html * @param state */ - handleAppStateChange = (state) => { + handleAppStateChange = state => { this.props.dispatch(setAppState(state)); if (state === 'active' && this._isConnected) { // firestack.database().goOnline(); @@ -65,7 +70,7 @@ class CoreContainer extends React.Component { * https://facebook.github.io/react-native/docs/netinfo.html * @param isConnected */ - handleNetworkChange = (isConnected) => { + handleNetworkChange = isConnected => { this._isConnected = isConnected; this.props.dispatch(setNetworkState(isConnected)); if (isConnected) { diff --git a/tests/src/firebase.js b/tests/src/firebase.js index 4df18e2f..c98816fd 100644 --- a/tests/src/firebase.js +++ b/tests/src/firebase.js @@ -17,7 +17,8 @@ const config = { const android = { // firebase android sdk completely ignores client id - clientId: '305229645282-j8ij0jev9ut24odmlk9i215pas808ugn.apps.googleusercontent.com', + clientId: + '305229645282-j8ij0jev9ut24odmlk9i215pas808ugn.apps.googleusercontent.com', appId: '1:305229645282:android:efe37851d57e1d05', apiKey: 'AIzaSyDnVqNhxU0Biit9nCo4RorAh5ulQQwko3E', databaseURL: 'https://rnfirebase-b9ad4.firebaseio.com', @@ -26,9 +27,9 @@ const android = { projectId: 'rnfirebase-b9ad4', }; - const ios = { - clientId: '305229645282-22imndi01abc2p6esgtu1i1m9mqrd0ib.apps.googleusercontent.com', + clientId: + '305229645282-22imndi01abc2p6esgtu1i1m9mqrd0ib.apps.googleusercontent.com', androidClientId: android.clientId, appId: '1:305229645282:ios:7b45748cb1117d2d', apiKey: 'AIzaSyDnVqNhxU0Biit9nCo4RorAh5ulQQwko3E', @@ -41,34 +42,52 @@ const ios = { const instances = { web: firebase.initializeApp(config), native: RNfirebase, - another: RNfirebase.initializeApp(Platform.OS === 'ios' ? ios : android, 'anotherApp'), + another: RNfirebase.initializeApp( + Platform.OS === 'ios' ? ios : android, + 'anotherApp' + ), }; - - console.log('RNApps -->', RNfirebase.apps); // natively initialized apps are already available at app run time, // no need for ready checks -instances.native.auth().signInAnonymously().then((user) => { - console.log('defaultApp user ->', user.toJSON()); -}); +instances.native + .auth() + .signInAnonymously() + .then(user => { + console.log('defaultApp user ->', user.toJSON()); + }); // dynamically initialized apps need a ready check -instances.another.onReady().then((app) => { - app.auth().signInAnonymously().then((user) => { - console.log('anotherApp user ->', user.toJSON()); - }); +instances.another.onReady().then(app => { + app + .auth() + .signInAnonymously() + .then(user => { + console.log('anotherApp user ->', user.toJSON()); + }); }); -instances.web.database().ref('tests/types').set(DatabaseContents.DEFAULT); +instances.web + .database() + .ref('tests/types') + .set(DatabaseContents.DEFAULT); -instances.web.database().ref('tests/priority').setWithPriority({ - foo: 'bar', -}, 666); - -instances.web.database().ref('tests/query').set(DatabaseContents.QUERY); +instances.web + .database() + .ref('tests/priority') + .setWithPriority( + { + foo: 'bar', + }, + 666 + ); +instances.web + .database() + .ref('tests/query') + .set(DatabaseContents.QUERY); // instances.native.messaging().subscribeToTopic('fcm_test'); diff --git a/tests/src/helpers.js b/tests/src/helpers.js deleted file mode 100644 index 2227bfea..00000000 --- a/tests/src/helpers.js +++ /dev/null @@ -1,3 +0,0 @@ -// import fs from 'fs'; -import path from 'path'; - diff --git a/tests/src/main.admob.js b/tests/src/main.admob.js index 60decc8f..292219b2 100644 --- a/tests/src/main.admob.js +++ b/tests/src/main.admob.js @@ -24,8 +24,7 @@ const unitId = { const firebase = fb.native; // Components -const Banner = firebase.admob.Banner; -const NativeExpress = firebase.admob.NativeExpress; +const { Banner, NativeExpress } = firebase.admob; // API const interstitial = firebase.admob().interstitial(unitId.interstitial); @@ -34,24 +33,19 @@ interstitial.loadAd(); const rewarded = firebase.admob().rewarded(unitId.rewarded); rewarded.loadAd(); - function bootstrap() { // Remove logging on production if (!__DEV__) { - console.log = () => { - }; - console.warn = () => { - }; - console.error = () => { - }; + console.log = () => {}; + console.warn = () => {}; + console.error = () => {}; console.disableYellowBox = true; } class Root extends Component { - showInterstitial() { interstitial.show(); - }; + } showRewarded() { rewarded.show(); @@ -60,22 +54,13 @@ function bootstrap() { render() { return ( - + -