-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgc-function.class.ts
More file actions
67 lines (54 loc) · 2.55 KB
/
gc-function.class.ts
File metadata and controls
67 lines (54 loc) · 2.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import { CloudFunction } from 'firebase-functions';
import { Logger } from './util/logger/logger.interface';
import { getLogger } from './util/logger.util';
import { FunctionHandler } from './function-handler.class';
import { FunctionRegistrar } from './registrars/function-registrar.interface';
import { Guard } from './guard/guard.interface';
import { wrapGaurd } from './guard/wrap-gaurd.util';
import { Context } from './context/context.interface';
import { createContext } from './context/create-context.util';
import { Environment } from './environment.interface';
import { FunctionTools } from './function-tools.interface';
import { RepositoryFactory } from './data/repository.factory';
/**
* A conceptual representation of a Google Cloud function which contains the logic of a Firebase Function of type T (input) -> R (result).
*
* @param T: The data expected by the function
* @param R: The result returned from the function
*/
export class GCFunction<T, R> {
protected _logger: Logger;
protected _tools: FunctionTools;
constructor(private _name: string,
private _registrar: FunctionRegistrar<T, R>,
private _guards : Guard<T>[],
private _handler : FunctionHandler<T,R>,
_environment: Environment)
{
this._logger = getLogger(_environment);
this._tools = {
Logger: this._logger,
getRepository: RepositoryFactory.create
};
}
/**
* Turns the registered function into an actual cloud function.
*/
build(): CloudFunction<any>
{
// Start with the inner core function which is the handler logic or this._handler.execute
// From there, move up the chain by adding extra layers and steps.
// 1) Bind function scope.
// Handler loses scope because of wrapping. Explicitely bind it to its scope.
// Needs a cast too to ensure not breaking the types. R is lost "=> Promise<{}>"
const funcWithScope = <(data: T, context: Context, tools: FunctionTools) => Promise<R>> this._handler.execute.bind(this._handler);
// 2) Bind function context.
const funcWithContext = (data: any, context: Context) => funcWithScope(data, createContext(context), this._tools);
// 3) Wrap the guard around the handler. If the guard fails halt execution and throw an error.
const gaurdedFunc = wrapGaurd(funcWithContext, this._guards, this._name, this._logger);
// 4) Register function onto Firebase
const registeredFunc = this._registrar.wrap(gaurdedFunc);
// 5) Return built function
return registeredFunc;
}
}