[types] Start on auth flow typings

This commit is contained in:
Chris Bianca 2017-11-17 14:22:46 +00:00
parent f1d8bee5b0
commit 746faad043
20 changed files with 296 additions and 253 deletions

View File

@ -24,15 +24,6 @@ import Utils, { statics as UtilsStatics } from './modules/utils';
const FirebaseCoreModule = NativeModules.RNFirebase;
export type FirebaseOptions = {
apiKey: string,
appId: string,
databaseURL: string,
messagingSenderId: string,
projectId: string,
storageBucket: string,
}
class FirebaseCore {
_nativeEmitters: { [string]: NativeEventEmitter };
_nativeSubscriptions: { [string]: boolean };

View File

@ -1,20 +1,39 @@
/* eslint-disable */
// declare module 'react-native' {
// // noinspection ES6ConvertVarToLetConst
// declare var exports: any;
// }
/* Core types */
declare class FirebaseError {
message: string,
name: string,
code: string,
stack: string,
path: string,
details: string,
modifiers: string
};
declare type AuthResultType = {
declare type FirebaseOptions = {
apiKey: string,
appId: string,
databaseURL: string,
messagingSenderId: string,
projectId: string,
storageBucket: string,
}
/* Auth types */
declare type AuthResult = {
authenticated: boolean,
user: Object|null
} | null;
declare type CredentialType = {
declare type AuthCredential = {
providerId: string,
token: string,
secret: string
};
/* Database types */
declare type DatabaseListener = {
listenerId: number;
eventName: string;
@ -31,6 +50,40 @@ declare type DatabaseModifier = {
valueType?: string;
};
/* Firestore types */
declare type FirestoreNativeDocumentChange = {
document: FirestoreNativeDocumentSnapshot,
newIndex: number,
oldIndex: number,
type: string,
}
declare type FirestoreNativeDocumentSnapshot = {
data: { [string]: FirestoreTypeMap },
metadata: FirestoreSnapshotMetadata,
path: string,
}
declare type FirestoreSnapshotMetadata = {
fromCache: boolean,
hasPendingWrites: boolean,
}
declare type FirestoreQueryDirection = 'DESC' | 'desc' | 'ASC' | 'asc';
declare type FirestoreQueryOperator = '<' | '<=' | '=' | '==' | '>' | '>=';
declare type FirestoreTypeMap = {
type: 'array' | 'boolean' | 'date' | 'fieldvalue' | 'geopoint' | 'null' | 'number' | 'object' | 'reference' | 'string',
value: any,
}
declare type FirestoreWriteOptions = {
merge?: boolean,
}
/* Util types */
declare type GoogleApiAvailabilityType = {
status: number,
isAvailable: boolean,
@ -38,13 +91,3 @@ declare type GoogleApiAvailabilityType = {
hasResolution?: boolean,
error?: string
};
declare class FirebaseError {
message: string,
name: string,
code: string,
stack: string,
path: string,
details: string,
modifiers: string
};

View File

@ -1,8 +1,12 @@
/**
* @url https://firebase.google.com/docs/reference/js/firebase.User
* @flow
* ConfirmationResult representation wrapper
*/
import type Auth from './';
import type User from './User';
export default class ConfirmationResult {
_auth: Object;
_auth: Auth;
_verificationId: string;
/**
@ -10,7 +14,7 @@ export default class ConfirmationResult {
* @param auth
* @param verificationId The phone number authentication operation's verification ID.
*/
constructor(auth: Object, verificationId: string) {
constructor(auth: Auth, verificationId: string) {
this._auth = auth;
this._verificationId = verificationId;
}
@ -20,13 +24,11 @@ export default class ConfirmationResult {
* @param verificationCode
* @return {*}
*/
confirm(verificationCode: string): Promise<Object> {
return this._auth._interceptUserValue(
this._auth._native._confirmVerificationCode(verificationCode)
);
confirm(verificationCode: string): Promise<?User> {
return this._auth._interceptUserValue(this._auth._native._confirmVerificationCode(verificationCode));
}
get verificationId(): String | null {
get verificationId(): string | null {
return this._verificationId;
}
}

View File

@ -2,6 +2,8 @@
import INTERNALS from './../../internals';
import { generatePushID, isFunction, isAndroid, isIOS, isString, nativeToJSError } from './../../utils';
import type Auth from './';
type PhoneAuthSnapshot = {
state: 'sent' | 'timeout' | 'verified' | 'error',
verificationId: string,
@ -17,7 +19,6 @@ type PhoneAuthError = {
};
export default class PhoneAuthListener {
_auth: Object;
_timeout: number;
_publicEvents: Object;
@ -34,7 +35,7 @@ export default class PhoneAuthListener {
* @param phoneNumber
* @param timeout
*/
constructor(auth: Object, phoneNumber: string, timeout?: number) {
constructor(auth: Auth, phoneNumber: string, timeout?: number) {
this._auth = auth;
this._reject = null;
this._resolve = null;

View File

@ -1,104 +1,144 @@
/**
* @flow
* User representation wrapper
*/
import INTERNALS from './../../internals';
/**
* @url https://firebase.google.com/docs/reference/js/firebase.User
*/
import type Auth from './';
type NativeUser = {
displayName?: string,
email?: string,
emailVerified?: boolean,
isAnonymous?: boolean,
phoneNumber?: string,
photoURL?: string,
providerData: UserInfo[],
providerId: string,
uid: string,
}
type UserInfo = {
displayName?: string,
email?: string,
phoneNumber?: string,
photoURL?: string,
providerId: string,
uid: string,
}
export default class User {
_auth: Auth;
_user: NativeUser;
/**
*
* @param authClass Instance of Authentication class
* @param auth Instance of Authentication class
* @param user user result object from native
*/
constructor(authClass, userObj) {
this._auth = authClass;
this._user = userObj;
}
/**
* INTERNALS
*/
/**
* Returns a user property or null if does not exist
* @param prop
* @returns {*}
* @private
*/
_valueOrNull(prop) {
if (!Object.hasOwnProperty.call(this._user, prop)) return null;
return this._user[prop];
}
/**
* Returns a user property or false if does not exist
* @param prop
* @returns {*}
* @private
*/
_valueOrFalse(prop) {
if (!Object.hasOwnProperty.call(this._user, prop)) return false;
return this._user[prop];
constructor(auth: Auth, user: NativeUser) {
this._auth = auth;
this._user = user;
}
/**
* PROPERTIES
*/
get displayName(): String | null {
return this._valueOrNull('displayName');
get displayName(): ?string {
return this._user.displayName || null;
}
get email(): String | null {
return this._valueOrNull('email');
get email(): ?string {
return this._user.email || null;
}
get emailVerified(): Boolean {
return this._valueOrNull('emailVerified');
get emailVerified(): boolean {
return this._user.emailVerified || false;
}
get isAnonymous(): Boolean {
return this._valueOrFalse('isAnonymous');
get isAnonymous(): boolean {
return this._user.isAnonymous || false;
}
get phoneNumber(): String | null {
return this._valueOrNull('phoneNumber');
get phoneNumber(): ?string {
return this._user.phoneNumber || null;
}
get photoURL(): String | null {
return this._valueOrNull('photoURL');
get photoURL(): ?string {
return this._user.photoURL || null;
}
get providerId() {
return this._valueOrNull('providerId');
get providerData(): Array<UserInfo> {
return this._user.providerData;
}
get uid(): String {
return this._valueOrNull('uid');
get providerId(): string {
return this._user.providerId;
}
get uid(): string {
return this._user.uid;
}
// noinspection ReservedWordAsName
/**
* METHODS
*/
toJSON() {
return Object.assign({}, this._user);
}
/**
* Delete the current user
* @return {Promise}
*/
delete(): Promise<Object> {
return this._auth._interceptUserValue(this._auth._native.delete());
delete(): Promise<void> {
return this._auth
._interceptUndefinedUserValue(this._auth._native.delete());
}
/**
* get the token of current user
* @return {Promise}
*/
getIdToken(forceRefresh: boolean = false): Promise<string> {
return this._auth._native.getToken(forceRefresh);
}
/**
*
* @param credential
*/
linkWithCredential(credential: CredentialType) {
return this._auth._interceptUserValue(this._auth._native.link(credential.providerId, credential.token, credential.secret));
linkWithCredential(credential: AuthCredential): Promise<User> {
return this._auth
._interceptUserValue(this._auth._native.link(credential.providerId, credential.token, credential.secret));
}
/**
* Re-authenticate a user with a third-party authentication provider
* @return {Promise} A promise resolved upon completion
*/
reauthenticateWithCredential(credential: AuthCredential): Promise<void> {
return this._auth
._interceptUndefinedUserValue(this._auth._native.reauthenticate(credential.providerId, credential.token, credential.secret));
}
/**
* Reload the current user
* @return {Promise}
*/
reload(): Promise<void> {
return this._auth
._interceptUndefinedUserValue(this._auth._native.reload());
}
/**
* Send verification email to current user.
*/
sendEmailVerification(): Promise<void> {
return this._auth
._interceptUndefinedUserValue(this._auth._native.sendEmailVerification());
}
toJSON(): Object {
return Object.assign({}, this._user);
}
/**
@ -106,69 +146,19 @@ export default class User {
* @param providerId
* @return {Promise.<TResult>|*}
*/
unlink(providerId: string) {
unlink(providerId: string): Promise<User> {
return this._auth._interceptUserValue(this._auth._native.unlink(providerId));
}
/**
* Re-authenticate a user with a third-party authentication provider
* @return {Promise} A promise resolved upon completion
*/
reauthenticateWithCredential(credential: CredentialType) {
return this._auth._interceptUserValue(this._auth._native.reauthenticate(credential.providerId, credential.token, credential.secret));
}
/**
* Reload the current user
* @return {Promise}
*/
reload(): Promise<Object> {
return this._auth._interceptUserValue(this._auth._native.reload());
}
/**
* get the token of current user
* @deprecated Deprecated getToken in favor of getIdToken.
* @return {Promise}
*/
getToken(forceRefresh: Boolean = false): Promise<Object> {
console.warn('Deprecated firebase.User.prototype.getToken in favor of firebase.User.prototype.getIdToken.');
return this._auth._native.getToken(forceRefresh);
}
/**
* get the token of current user
* @return {Promise}
*/
getIdToken(forceRefresh: Boolean = false): Promise<Object> {
return this._auth._native.getToken(forceRefresh);
}
/**
*
* @returns {Array}
*/
get providerData(): Array {
return this._valueOrNull('providerData') || [];
}
/**
* Update the current user's email
*
* @param {string} email The user's _new_ email
* @return {Promise} A promise resolved upon completion
*/
updateEmail(email: string): Promise<Object> {
return this._auth._interceptUserValue(this._auth._native.updateEmail(email));
}
/**
* Update the current user's profile
* @param {Object} updates An object containing the keys listed [here](https://firebase.google.com/docs/auth/ios/manage-users#update_a_users_profile)
* @return {Promise}
*/
updateProfile(updates: Object = {}): Promise<Object> {
return this._auth._interceptUserValue(this._auth._native.updateProfile(updates));
updateEmail(email: string): Promise<void> {
return this._auth
._interceptUndefinedUserValue(this._auth._native.updateEmail(email));
}
/**
@ -176,15 +166,29 @@ export default class User {
* @param {string} password the new password
* @return {Promise}
*/
updatePassword(password: string): Promise<Object> {
return this._auth._interceptUserValue(this._auth._native.updatePassword(password));
updatePassword(password: string): Promise<void> {
return this._auth
._interceptUndefinedUserValue(this._auth._native.updatePassword(password));
}
/**
* Send verification email to current user.
* Update the current user's profile
* @param {Object} updates An object containing the keys listed [here](https://firebase.google.com/docs/auth/ios/manage-users#update_a_users_profile)
* @return {Promise}
*/
sendEmailVerification(): Promise<Object> {
return this._auth._interceptUserValue(this._auth._native.sendEmailVerification());
updateProfile(updates: Object = {}): Promise<void> {
return this._auth
._interceptUndefinedUserValue(this._auth._native.updateProfile(updates));
}
/**
* get the token of current user
* @deprecated Deprecated getToken in favor of getIdToken.
* @return {Promise}
*/
getToken(forceRefresh: boolean = false): Promise<Object> {
console.warn('Deprecated firebase.User.prototype.getToken in favor of firebase.User.prototype.getIdToken.');
return this._auth._native.getToken(forceRefresh);
}
/**
@ -223,7 +227,7 @@ export default class User {
throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD('User', 'updatePhoneNumber'));
}
get refreshToken() {
get refreshToken(): string {
throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_PROPERTY('User', 'refreshToken'));
}
}

View File

@ -1,5 +1,8 @@
// @flow
import User from './user';
/**
* @flow
* Auth representation wrapper
*/
import User from './User';
import ModuleBase from './../../utils/ModuleBase';
import INTERNALS from './../../internals';
import ConfirmationResult from './ConfirmationResult';
@ -14,16 +17,16 @@ import FacebookAuthProvider from './providers/FacebookAuthProvider';
import PhoneAuthListener from './PhoneAuthListener';
import type FirebaseApp from '../../firebase-app';
export default class Auth extends ModuleBase {
static _NAMESPACE = 'auth';
static _NATIVE_MODULE = 'RNFirebaseAuth';
_authResult: AuthResult | null;
_user: User | null;
_native: Object;
_getAppEventName: Function;
_authResult: AuthResultType | null;
constructor(firebaseApp: Object, options: Object = {}) {
constructor(firebaseApp: FirebaseApp, options: Object = {}) {
super(firebaseApp, options, true);
this._user = null;
this._authResult = null;
@ -31,21 +34,21 @@ export default class Auth extends ModuleBase {
this.addListener(
// sub to internal native event - this fans out to
// public event name: onAuthStateChanged
this._getAppEventName('auth_state_changed'),
super._getAppEventName('auth_state_changed'),
this._onInternalAuthStateChanged.bind(this),
);
this.addListener(
// sub to internal native event - this fans out to
// public events based on event.type
this._getAppEventName('phone_auth_state_changed'),
super._getAppEventName('phone_auth_state_changed'),
this._onInternalPhoneAuthStateChanged.bind(this),
);
this.addListener(
// sub to internal native event - this fans out to
// public event name: onIdTokenChanged
this._getAppEventName('auth_id_token_changed'),
super._getAppEventName('auth_id_token_changed'),
this._onInternalIdTokenChanged.bind(this),
);
@ -63,7 +66,7 @@ export default class Auth extends ModuleBase {
this.emit(eventKey, event.state);
}
_setAuthState(auth: AuthResultType) {
_setAuthState(auth: AuthResult) {
this._authResult = auth;
this._user = auth && auth.user ? new User(this, auth.user) : null;
this.emit(this._getAppEventName('onUserChanged'), this._user);
@ -74,7 +77,7 @@ export default class Auth extends ModuleBase {
* @param auth
* @private
*/
_onInternalAuthStateChanged(auth: AuthResultType) {
_onInternalAuthStateChanged(auth: AuthResult) {
this._setAuthState(auth);
this.emit(this._getAppEventName('onAuthStateChanged'), this._user);
}
@ -85,7 +88,7 @@ export default class Auth extends ModuleBase {
* @param emit
* @private
*/
_onInternalIdTokenChanged(auth: AuthResultType) {
_onInternalIdTokenChanged(auth: AuthResult) {
this._setAuthState(auth);
this.emit(this._getAppEventName('onIdTokenChanged'), this._user);
}
@ -97,8 +100,8 @@ export default class Auth extends ModuleBase {
* @returns {Promise.<*>}
* @private
*/
_interceptUserValue(promise) {
return promise.then((result) => {
_interceptUserValue(promise: Promise<AuthResult>): Promise<User> {
return promise.then((result: AuthResult) => {
if (!result) this._setAuthState(null);
else if (result.user) this._setAuthState(result);
else if (result.uid) this._setAuthState({ authenticated: true, user: result });
@ -106,6 +109,11 @@ export default class Auth extends ModuleBase {
});
}
_interceptUndefinedUserValue(promise: Promise<AuthResult>): Promise<void> {
return this._interceptUserValue(promise)
.then(() => {});
}
/*
* WEB API
*/
@ -174,15 +182,15 @@ export default class Auth extends ModuleBase {
* Sign the current user out
* @return {Promise}
*/
signOut(): Promise<null> {
return this._interceptUserValue(this._native.signOut());
signOut(): Promise<void> {
return this._interceptUndefinedUserValue(this._native.signOut());
}
/**
* Sign a user in anonymously
* @return {Promise} A promise resolved upon completion
*/
signInAnonymously(): Promise<Object> {
signInAnonymously(): Promise<User> {
return this._interceptUserValue(this._native.signInAnonymously());
}
@ -192,7 +200,7 @@ 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<Object> {
createUserWithEmailAndPassword(email: string, password: string): Promise<User> {
return this._interceptUserValue(this._native.createUserWithEmailAndPassword(email, password));
}
@ -202,7 +210,7 @@ export default class Auth extends ModuleBase {
* @param {string} password The user's password
* @return {Promise} A promise that is resolved upon completion
*/
signInWithEmailAndPassword(email: string, password: string): Promise<Object> {
signInWithEmailAndPassword(email: string, password: string): Promise<User> {
return this._interceptUserValue(this._native.signInWithEmailAndPassword(email, password));
}
@ -211,7 +219,7 @@ export default class Auth extends ModuleBase {
* @param {string} customToken A self-signed custom auth token.
* @return {Promise} A promise resolved upon completion
*/
signInWithCustomToken(customToken: string): Promise<Object> {
signInWithCustomToken(customToken: string): Promise<User> {
return this._interceptUserValue(this._native.signInWithCustomToken(customToken));
}
@ -219,7 +227,7 @@ export default class Auth extends ModuleBase {
* Sign the user in with a third-party authentication provider
* @return {Promise} A promise resolved upon completion
*/
signInWithCredential(credential: CredentialType): Promise<Object> {
signInWithCredential(credential: AuthCredential): Promise<User> {
return this._interceptUserValue(
this._native.signInWithCredential(
credential.providerId, credential.token, credential.secret,
@ -231,7 +239,7 @@ export default class Auth extends ModuleBase {
* Asynchronously signs in using a phone number.
*
*/
signInWithPhoneNumber(phoneNumber: string): Promise<Object> {
signInWithPhoneNumber(phoneNumber: string): Promise<ConfirmationResult> {
return this._native.signInWithPhoneNumber(phoneNumber).then((result) => {
return new ConfirmationResult(this, result.verificationId);
});
@ -254,7 +262,7 @@ 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): Promise<Object> {
sendPasswordResetEmail(email: string): Promise<void> {
return this._native.sendPasswordResetEmail(email);
}
@ -266,7 +274,7 @@ export default class Auth extends ModuleBase {
* @param newPassword
* @return {Promise.<Null>}
*/
confirmPasswordReset(code: string, newPassword: string): Promise<null> {
confirmPasswordReset(code: string, newPassword: string): Promise<void> {
return this._native.confirmPasswordReset(code, newPassword);
}
@ -277,7 +285,7 @@ export default class Auth extends ModuleBase {
* @param code
* @return {Promise.<Null>}
*/
applyActionCode(code: string): Promise<any> {
applyActionCode(code: string): Promise<void> {
return this._native.applyActionCode(code);
}
@ -288,7 +296,7 @@ export default class Auth extends ModuleBase {
* @param code
* @return {Promise.<any>|Promise<ActionCodeInfo>}
*/
checkActionCode(code: string): Promise<any> {
checkActionCode(code: string): Promise<void> {
return this._native.checkActionCode(code);
}
@ -296,7 +304,7 @@ export default class Auth extends ModuleBase {
* Get the currently signed in user
* @return {Promise}
*/
getCurrentUser(): Promise<Object> {
getCurrentUser(): Promise<User | null> {
return this._interceptUserValue(this._native.getCurrentUser());
}

View File

@ -1,3 +1,7 @@
/**
* @flow
* EmailAuthProvider representation wrapper
*/
const providerId = 'password';
export default class EmailAuthProvider {
@ -5,11 +9,11 @@ export default class EmailAuthProvider {
throw new Error('`new EmailAuthProvider()` is not supported on the native Firebase SDKs.');
}
static get PROVIDER_ID() {
static get PROVIDER_ID(): string {
return providerId;
}
static credential(email, password) {
static credential(email: string, password: string): AuthCredential {
return {
token: email,
secret: password,

View File

@ -1,3 +1,7 @@
/**
* @flow
* FacebookAuthProvider representation wrapper
*/
const providerId = 'facebook.com';
export default class FacebookAuthProvider {
@ -5,11 +9,11 @@ export default class FacebookAuthProvider {
throw new Error('`new FacebookAuthProvider()` is not supported on the native Firebase SDKs.');
}
static get PROVIDER_ID() {
static get PROVIDER_ID(): string {
return providerId;
}
static credential(token) {
static credential(token: string): AuthCredential {
return {
token,
secret: '',

View File

@ -1,3 +1,7 @@
/**
* @flow
* GithubAuthProvider representation wrapper
*/
const providerId = 'github.com';
export default class GithubAuthProvider {
@ -5,11 +9,11 @@ export default class GithubAuthProvider {
throw new Error('`new GithubAuthProvider()` is not supported on the native Firebase SDKs.');
}
static get PROVIDER_ID() {
static get PROVIDER_ID(): string {
return providerId;
}
static credential(token) {
static credential(token: string): AuthCredential {
return {
token,
secret: '',

View File

@ -1,3 +1,7 @@
/**
* @flow
* EmailAuthProvider representation wrapper
*/
const providerId = 'google.com';
export default class GoogleAuthProvider {
@ -5,11 +9,11 @@ export default class GoogleAuthProvider {
throw new Error('`new GoogleAuthProvider()` is not supported on the native Firebase SDKs.');
}
static get PROVIDER_ID() {
static get PROVIDER_ID(): string {
return providerId;
}
static credential(token, secret) {
static credential(token: string, secret: string): AuthCredential {
return {
token,
secret,

View File

@ -1,3 +1,7 @@
/**
* @flow
* PhoneAuthProvider representation wrapper
*/
const providerId = 'phone';
export default class PhoneAuthProvider {
@ -5,11 +9,11 @@ export default class PhoneAuthProvider {
throw new Error('`new PhoneAuthProvider()` is not supported on the native Firebase SDKs.');
}
static get PROVIDER_ID() {
static get PROVIDER_ID(): string {
return providerId;
}
static credential(verificationId, code) {
static credential(verificationId: string, code: string): AuthCredential {
return {
token: verificationId,
secret: code,

View File

@ -1,3 +1,7 @@
/**
* @flow
* TwitterAuthProvider representation wrapper
*/
const providerId = 'twitter.com';
export default class TwitterAuthProvider {
@ -5,11 +9,11 @@ export default class TwitterAuthProvider {
throw new Error('`new TwitterAuthProvider()` is not supported on the native Firebase SDKs.');
}
static get PROVIDER_ID() {
static get PROVIDER_ID(): string {
return providerId;
}
static credential(token, secret) {
static credential(token: string, secret: string): AuthCredential {
return {
token,
secret,

View File

@ -3,7 +3,7 @@
* CollectionReference representation wrapper
*/
import DocumentReference from './DocumentReference';
import Query, { type Direction, type Operator } from './Query';
import Query from './Query';
import { firestoreAutoId } from '../../utils';
import type Firestore from './';
@ -75,7 +75,7 @@ export default class CollectionReference {
return this._query.onSnapshot(onNext, onError);
}
orderBy(fieldPath: string, directionStr?: Direction): Query {
orderBy(fieldPath: string, directionStr?: FirestoreQueryDirection): Query {
return this._query.orderBy(fieldPath, directionStr);
}
@ -87,7 +87,7 @@ export default class CollectionReference {
return this._query.startAt(fieldValues);
}
where(fieldPath: string, opStr: Operator, value: any): Query {
where(fieldPath: string, opStr: FirestoreQueryOperator, value: any): Query {
return this._query.where(fieldPath, opStr, value);
}
}

View File

@ -2,18 +2,10 @@
* @flow
* DocumentChange representation wrapper
*/
import DocumentSnapshot, { type DocumentSnapshotNativeData } from './DocumentSnapshot';
import DocumentSnapshot from './DocumentSnapshot';
import type Firestore from './';
export type DocumentChangeNativeData = {
document: DocumentSnapshotNativeData,
newIndex: number,
oldIndex: number,
type: string,
}
/**
* @class DocumentChange
*/
@ -23,7 +15,7 @@ export default class DocumentChange {
_oldIndex: number;
_type: string;
constructor(firestore: Firestore, nativeData: DocumentChangeNativeData) {
constructor(firestore: Firestore, nativeData: FirestoreNativeDocumentChange) {
this._document = new DocumentSnapshot(firestore, nativeData.document);
this._newIndex = nativeData.newIndex;
this._oldIndex = nativeData.oldIndex;

View File

@ -3,17 +3,13 @@
* DocumentReference representation wrapper
*/
import CollectionReference from './CollectionReference';
import DocumentSnapshot, { type DocumentSnapshotNativeData } from './DocumentSnapshot';
import DocumentSnapshot from './DocumentSnapshot';
import { buildNativeMap } from './utils/serialize';
import { firestoreAutoId, isFunction, isObject, isString } from '../../utils';
import type Firestore from './';
import type Path from './Path';
export type WriteOptions = {
merge?: boolean,
}
type DocumentListenOptions = {
includeMetadataChanges: boolean,
}
@ -133,7 +129,7 @@ export default class DocumentReference {
}
const listenerId = firestoreAutoId();
const listener = (nativeDocumentSnapshot: DocumentSnapshotNativeData) => {
const listener = (nativeDocumentSnapshot: FirestoreNativeDocumentSnapshot) => {
const documentSnapshot = new DocumentSnapshot(this.firestore, nativeDocumentSnapshot);
observer.next(documentSnapshot);
};
@ -160,7 +156,7 @@ export default class DocumentReference {
return this._offDocumentSnapshot.bind(this, listenerId, listener);
}
set(data: Object, writeOptions?: WriteOptions): Promise<void> {
set(data: Object, writeOptions?: FirestoreWriteOptions): Promise<void> {
const nativeData = buildNativeMap(data);
return this._firestore._native
.documentSet(this.path, nativeData, writeOptions);

View File

@ -4,30 +4,19 @@
*/
import DocumentReference from './DocumentReference';
import Path from './Path';
import { parseNativeMap, type TypeMap } from './utils/serialize';
import { parseNativeMap } from './utils/serialize';
import type Firestore from './';
export type SnapshotMetadata = {
fromCache: boolean,
hasPendingWrites: boolean,
}
export type DocumentSnapshotNativeData = {
data: { [string]: TypeMap },
metadata: SnapshotMetadata,
path: string,
}
/**
* @class DocumentSnapshot
*/
export default class DocumentSnapshot {
_data: Object | void;
_metadata: SnapshotMetadata;
_metadata: FirestoreSnapshotMetadata;
_ref: DocumentReference;
constructor(firestore: Firestore, nativeData: DocumentSnapshotNativeData) {
constructor(firestore: Firestore, nativeData: FirestoreNativeDocumentSnapshot) {
this._data = parseNativeMap(firestore, nativeData.data);
this._metadata = nativeData.metadata;
this._ref = new DocumentReference(firestore, Path.fromName(nativeData.path));
@ -41,7 +30,7 @@ export default class DocumentSnapshot {
return this._ref.id;
}
get metadata(): SnapshotMetadata {
get metadata(): FirestoreSnapshotMetadata {
return this._metadata;
}

View File

@ -10,14 +10,14 @@ import { firestoreAutoId, isFunction, isObject } from '../../utils';
import type Firestore from './';
import type Path from './Path';
const DIRECTIONS = {
const DIRECTIONS: { [FirestoreQueryDirection]: string } = {
ASC: 'ASCENDING',
asc: 'ASCENDING',
DESC: 'DESCENDING',
desc: 'DESCENDING',
};
const OPERATORS = {
const OPERATORS: { [FirestoreQueryOperator]: string } = {
'=': 'EQUAL',
'==': 'EQUAL',
'>': 'GREATER_THAN',
@ -26,7 +26,6 @@ const OPERATORS = {
'<=': 'LESS_THAN_OR_EQUAL',
};
export type Direction = 'DESC' | 'desc' | 'ASC' | 'asc';
type FieldFilter = {
fieldPath: string,
operator: string,
@ -45,7 +44,6 @@ type QueryOptions = {
startAfter?: any[],
startAt?: any[],
}
export type Operator = '<' | '<=' | '=' | '==' | '>' | '>=';
type QueryListenOptions = {
includeDocumentMetadataChanges: boolean,
includeQueryMetadataChanges: boolean,
@ -234,7 +232,7 @@ export default class Query {
return this._offCollectionSnapshot.bind(this, listenerId, listener);
}
orderBy(fieldPath: string, directionStr?: Direction = 'asc'): Query {
orderBy(fieldPath: string, directionStr?: FirestoreQueryDirection = 'asc'): Query {
// TODO: Validation
// validate.isFieldPath('fieldPath', fieldPath);
// validate.isOptionalFieldOrder('directionStr', directionStr);
@ -288,7 +286,7 @@ export default class Query {
);
}
where(fieldPath: string, opStr: Operator, value: any): Query {
where(fieldPath: string, opStr: FirestoreQueryOperator, value: any): Query {
// TODO: Validation
// validate.isFieldPath('fieldPath', fieldPath);
// validate.isFieldFilter('fieldFilter', opStr, value);

View File

@ -2,16 +2,16 @@
* @flow
* QuerySnapshot representation wrapper
*/
import DocumentChange, { type DocumentChangeNativeData } from './DocumentChange';
import DocumentSnapshot, { type DocumentSnapshotNativeData, type SnapshotMetadata } from './DocumentSnapshot';
import DocumentChange from './DocumentChange';
import DocumentSnapshot from './DocumentSnapshot';
import type Firestore from './';
import type Query from './Query';
type QuerySnapshotNativeData = {
changes: DocumentChangeNativeData[],
documents: DocumentSnapshotNativeData[],
metadata: SnapshotMetadata,
changes: FirestoreNativeDocumentChange[],
documents: FirestoreNativeDocumentSnapshot[],
metadata: FirestoreSnapshotMetadata,
}
/**
@ -20,7 +20,7 @@ type QuerySnapshotNativeData = {
export default class QuerySnapshot {
_changes: DocumentChange[];
_docs: DocumentSnapshot[];
_metadata: SnapshotMetadata;
_metadata: FirestoreSnapshotMetadata;
_query: Query;
constructor(firestore: Firestore, query: Query, nativeData: QuerySnapshotNativeData) {
@ -42,7 +42,7 @@ export default class QuerySnapshot {
return this._docs.length === 0;
}
get metadata(): SnapshotMetadata {
get metadata(): FirestoreSnapshotMetadata {
return this._metadata;
}

View File

@ -5,7 +5,7 @@
import { buildNativeMap } from './utils/serialize';
import { isObject, isString } from '../../utils';
import type DocumentReference, { WriteOptions } from './DocumentReference';
import type DocumentReference from './DocumentReference';
import type Firestore from './';
type DocumentWrite = {
@ -44,7 +44,7 @@ export default class WriteBatch {
return this;
}
set(docRef: DocumentReference, data: Object, writeOptions?: WriteOptions) {
set(docRef: DocumentReference, data: Object, writeOptions?: FirestoreWriteOptions) {
// TODO: Validation
// validate.isDocumentReference('docRef', docRef);
// validate.isDocument('data', data);

View File

@ -10,18 +10,13 @@ import { typeOf } from '../../../utils';
import type Firestore from '../';
export type TypeMap = {
type: 'array' | 'boolean' | 'date' | 'fieldvalue' | 'geopoint' | 'null' | 'number' | 'object' | 'reference' | 'string',
value: any,
}
/*
* Functions that build up the data needed to represent
* the different types available within Firestore
* for transmission to the native side
*/
export const buildNativeMap = (data: Object): { [string]: TypeMap } => {
export const buildNativeMap = (data: Object): { [string]: FirestoreTypeMap } => {
const nativeData = {};
if (data) {
Object.keys(data).forEach((key) => {
@ -34,7 +29,7 @@ export const buildNativeMap = (data: Object): { [string]: TypeMap } => {
return nativeData;
};
export const buildNativeArray = (array: Object[]): TypeMap[] => {
export const buildNativeArray = (array: Object[]): FirestoreTypeMap[] => {
const nativeArray = [];
if (array) {
array.forEach((value) => {
@ -47,7 +42,7 @@ export const buildNativeArray = (array: Object[]): TypeMap[] => {
return nativeArray;
};
export const buildTypeMap = (value: any): TypeMap | null => {
export const buildTypeMap = (value: any): FirestoreTypeMap | null => {
const type = typeOf(value);
if (value === null || value === undefined) {
return {
@ -108,7 +103,7 @@ export const buildTypeMap = (value: any): TypeMap | null => {
* side and converts to the correct Firestore JS types
*/
export const parseNativeMap = (firestore: Firestore, nativeData: { [string]: TypeMap }): Object | void => {
export const parseNativeMap = (firestore: Firestore, nativeData: { [string]: FirestoreTypeMap }): Object | void => {
let data;
if (nativeData) {
data = {};
@ -119,7 +114,7 @@ export const parseNativeMap = (firestore: Firestore, nativeData: { [string]: Typ
return data;
};
const parseNativeArray = (firestore: Firestore, nativeArray: TypeMap[]): any[] => {
const parseNativeArray = (firestore: Firestore, nativeArray: FirestoreTypeMap[]): any[] => {
const array = [];
if (nativeArray) {
nativeArray.forEach((typeMap) => {
@ -129,7 +124,7 @@ const parseNativeArray = (firestore: Firestore, nativeArray: TypeMap[]): any[] =
return array;
};
const parseTypeMap = (firestore: Firestore, typeMap: TypeMap): any => {
const parseTypeMap = (firestore: Firestore, typeMap: FirestoreTypeMap): any => {
const { type, value } = typeMap;
if (type === 'null') {
return null;