From d06fbec40aa47ef6dc7638eba007bddd7510d8fa Mon Sep 17 00:00:00 2001 From: Salakar Date: Sun, 6 May 2018 00:50:09 +0100 Subject: [PATCH] [js][functions] finalise + cleanup --- lib/modules/functions/index.js | 72 +++++++++++++++++++++++++---- lib/modules/functions/types.flow.js | 30 ++++++++++++ 2 files changed, 93 insertions(+), 9 deletions(-) create mode 100644 lib/modules/functions/types.flow.js diff --git a/lib/modules/functions/index.js b/lib/modules/functions/index.js index a6703af0..f690d655 100644 --- a/lib/modules/functions/index.js +++ b/lib/modules/functions/index.js @@ -3,36 +3,90 @@ * Functions representation wrapper */ import ModuleBase from '../../utils/ModuleBase'; +import { isObject } from '../../utils'; import { getNativeModule } from '../../utils/native'; +import type { + HttpsCallable, + HttpsErrorCode, + FunctionsErrorCode, + HttpsCallablePromise, +} from './types.flow'; import type App from '../core/app'; -export const MODULE_NAME = 'RNFirebaseFunctions'; export const NAMESPACE = 'functions'; +export const MODULE_NAME = 'RNFirebaseFunctions'; -type HttpsCallableResult = { - data: Object, -}; - -type HttpsCallable = (data?: any) => Promise; +class HttpsError extends Error { + +details: ?any; + +code: FunctionsErrorCode; + constructor(code: string, message?: string, details?: any) { + super(message); + this.details = details; + this.code = statics.HttpsErrorCode[code] || statics.HttpsErrorCode.UNKNOWN; + } +} export default class Functions extends ModuleBase { constructor(app: App) { super(app, { - moduleName: MODULE_NAME, multiApp: false, hasShards: false, namespace: NAMESPACE, + moduleName: MODULE_NAME, }); } + /** + * ------------- + * PUBLIC API + * ------------- + */ + /** * Returns a reference to the callable https trigger with the given name. * @param name The name of the trigger. */ httpsCallable(name: string): HttpsCallable { - return (data?: any) => getNativeModule(this).httpsCallable(name, data); + return (data?: any): HttpsCallablePromise => { + const promise = getNativeModule(this).httpsCallable(name, { data }); + return promise.then(this._errorOrResult); + }; + } + + /** + * ------------- + * INTERNALS + * ------------- + */ + _errorOrResult(possibleError): HttpsCallablePromise { + if (isObject(possibleError) && possibleError.__error) { + const { code, message, details } = possibleError; + return Promise.reject(new HttpsError(code, message, details)); + } + + return Promise.resolve(possibleError); } } -export const statics = {}; +export const statics: { HttpsErrorCode: HttpsErrorCode } = { + HttpsErrorCode: { + OK: 'ok', + CANCELLED: 'cancelled', + UNKNOWN: 'unknown', + INVALID_ARGUMENT: 'invalid-argument', + DEADLINE_EXCEEDED: 'deadline-exceeded', + NOT_FOUND: 'not-found', + ALREADY_EXISTS: 'already-exists', + PERMISSION_DENIED: 'permission-denied', + UNAUTHENTICATED: 'unauthenticated', + RESOURCE_EXHAUSTED: 'resource-exhausted', + FAILED_PRECONDITION: 'failed-precondition', + ABORTED: 'aborted', + OUT_OF_RANGE: 'out-of-range', + UNIMPLEMENTED: 'unimplemented', + INTERNAL: 'internal', + UNAVAILABLE: 'unavailable', + DATA_LOSS: 'data-loss', + }, +}; diff --git a/lib/modules/functions/types.flow.js b/lib/modules/functions/types.flow.js new file mode 100644 index 00000000..86608279 --- /dev/null +++ b/lib/modules/functions/types.flow.js @@ -0,0 +1,30 @@ +export type HttpsCallableResult = { + data: Object, +}; + +export type FunctionsErrorCode = + | 'ok' + | 'cancelled' + | 'unknown' + | 'invalid-argument' + | 'deadline-exceeded' + | 'not-found' + | 'already-exists' + | 'permission-denied' + | 'resource-exhausted' + | 'failed-precondition' + | 'aborted' + | 'out-of-range' + | 'unimplemented' + | 'internal' + | 'unavailable' + | 'data-loss' + | 'unauthenticated'; + +export type HttpsCallablePromise = + | Promise + | Promise; + +export type HttpsCallable = (data?: any) => HttpsCallablePromise; + +export type HttpsErrorCode = { [name: string]: FunctionsErrorCode };