@my-devkit/firebase 1.0.76 → 1.0.77
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{dist/aggregate.d.ts → aggregate.d.ts} +0 -0
- package/{dist/aggregate.js → aggregate.js} +0 -0
- package/{dist/aggregate.js.map → aggregate.js.map} +0 -0
- package/{dist/app-factory.d.ts → app-factory.d.ts} +0 -0
- package/{dist/app-factory.js → app-factory.js} +0 -0
- package/{dist/app-factory.js.map → app-factory.js.map} +0 -0
- package/{dist/bus.d.ts → bus.d.ts} +0 -0
- package/{dist/bus.js → bus.js} +0 -0
- package/{dist/bus.js.map → bus.js.map} +0 -0
- package/{dist/constants.d.ts → constants.d.ts} +0 -0
- package/{dist/constants.js → constants.js} +0 -0
- package/{dist/constants.js.map → constants.js.map} +0 -0
- package/{dist/context.d.ts → context.d.ts} +0 -0
- package/{dist/context.js → context.js} +0 -0
- package/{dist/context.js.map → context.js.map} +0 -0
- package/{dist/decorators → decorators}/controller/body.d.ts +0 -0
- package/{dist/decorators → decorators}/controller/body.js +0 -0
- package/{dist/decorators → decorators}/controller/body.js.map +0 -0
- package/{dist/decorators → decorators}/controller/body.spec.d.ts +0 -0
- package/{dist/decorators → decorators}/controller/body.spec.js +0 -0
- package/{dist/decorators → decorators}/controller/body.spec.js.map +0 -0
- package/{dist/decorators → decorators}/controller/controller.d.ts +0 -0
- package/{dist/decorators → decorators}/controller/controller.js +0 -0
- package/{dist/decorators → decorators}/controller/controller.js.map +0 -0
- package/{dist/decorators → decorators}/controller/controller.spec.d.ts +0 -0
- package/{dist/decorators → decorators}/controller/controller.spec.js +0 -0
- package/{dist/decorators → decorators}/controller/controller.spec.js.map +0 -0
- package/{dist/decorators → decorators}/controller/get.d.ts +0 -0
- package/{dist/decorators → decorators}/controller/get.js +0 -0
- package/{dist/decorators → decorators}/controller/get.js.map +0 -0
- package/{dist/decorators → decorators}/controller/get.spec.d.ts +0 -0
- package/{dist/decorators → decorators}/controller/get.spec.js +0 -0
- package/{dist/decorators → decorators}/controller/get.spec.js.map +0 -0
- package/{dist/decorators → decorators}/controller/index.d.ts +0 -0
- package/{dist/decorators → decorators}/controller/index.js +0 -0
- package/{dist/decorators → decorators}/controller/index.js.map +0 -0
- package/{dist/decorators → decorators}/controller/param.d.ts +0 -0
- package/{dist/decorators → decorators}/controller/param.js +0 -0
- package/{dist/decorators → decorators}/controller/param.js.map +0 -0
- package/{dist/decorators → decorators}/controller/param.spec.d.ts +0 -0
- package/{dist/decorators → decorators}/controller/param.spec.js +0 -0
- package/{dist/decorators → decorators}/controller/param.spec.js.map +0 -0
- package/{dist/decorators → decorators}/controller/post.d.ts +0 -0
- package/{dist/decorators → decorators}/controller/post.js +0 -0
- package/{dist/decorators → decorators}/controller/post.js.map +0 -0
- package/{dist/decorators → decorators}/controller/post.spec.d.ts +0 -0
- package/{dist/decorators → decorators}/controller/post.spec.js +0 -0
- package/{dist/decorators → decorators}/controller/post.spec.js.map +0 -0
- package/{dist/decorators → decorators}/controller/query.d.ts +0 -0
- package/{dist/decorators → decorators}/controller/query.js +0 -0
- package/{dist/decorators → decorators}/controller/query.js.map +0 -0
- package/{dist/decorators → decorators}/controller/query.spec.d.ts +0 -0
- package/{dist/decorators → decorators}/controller/query.spec.js +0 -0
- package/{dist/decorators → decorators}/controller/query.spec.js.map +0 -0
- package/{dist/decorators → decorators}/handler/command-handler.d.ts +0 -0
- package/{dist/decorators → decorators}/handler/command-handler.js +0 -0
- package/{dist/decorators → decorators}/handler/command-handler.js.map +0 -0
- package/{dist/decorators → decorators}/handler/command-handler.spec.d.ts +0 -0
- package/{dist/decorators → decorators}/handler/command-handler.spec.js +0 -0
- package/{dist/decorators → decorators}/handler/command-handler.spec.js.map +0 -0
- package/{dist/decorators → decorators}/handler/event-handler.d.ts +0 -0
- package/{dist/decorators → decorators}/handler/event-handler.js +0 -0
- package/{dist/decorators → decorators}/handler/event-handler.js.map +0 -0
- package/{dist/decorators → decorators}/handler/event-handler.spec.d.ts +0 -0
- package/{dist/decorators → decorators}/handler/event-handler.spec.js +0 -0
- package/{dist/decorators → decorators}/handler/event-handler.spec.js.map +0 -0
- package/{dist/decorators → decorators}/handler/index.d.ts +0 -0
- package/{dist/decorators → decorators}/handler/index.js +0 -0
- package/{dist/decorators → decorators}/handler/index.js.map +0 -0
- package/{dist/decorators → decorators}/index.d.ts +0 -0
- package/{dist/decorators → decorators}/index.js +0 -0
- package/{dist/decorators → decorators}/index.js.map +0 -0
- package/{dist/decorators → decorators}/injectable.d.ts +0 -0
- package/{dist/decorators → decorators}/injectable.js +0 -0
- package/{dist/decorators → decorators}/injectable.js.map +0 -0
- package/{dist/decorators → decorators}/module.d.ts +0 -0
- package/{dist/decorators → decorators}/module.js +0 -0
- package/{dist/decorators → decorators}/module.js.map +0 -0
- package/{dist/decorators → decorators}/transactional-client.d.ts +0 -0
- package/{dist/decorators → decorators}/transactional-client.js +0 -0
- package/{dist/decorators → decorators}/transactional-client.js.map +0 -0
- package/{dist/execution-mode-enum.d.ts → execution-mode-enum.d.ts} +0 -0
- package/{dist/execution-mode-enum.js → execution-mode-enum.js} +0 -0
- package/{dist/execution-mode-enum.js.map → execution-mode-enum.js.map} +0 -0
- package/{dist/firestore-client.d.ts → firestore-client.d.ts} +0 -0
- package/{dist/firestore-client.js → firestore-client.js} +0 -0
- package/{dist/firestore-client.js.map → firestore-client.js.map} +0 -0
- package/{dist/handler-helper.d.ts → handler-helper.d.ts} +0 -0
- package/{dist/handler-helper.js → handler-helper.js} +0 -0
- package/{dist/handler-helper.js.map → handler-helper.js.map} +0 -0
- package/{dist/index.d.ts → index.d.ts} +0 -0
- package/{dist/index.js → index.js} +0 -0
- package/{dist/index.js.map → index.js.map} +0 -0
- package/{dist/injector.d.ts → injector.d.ts} +0 -0
- package/{dist/injector.js → injector.js} +0 -0
- package/{dist/injector.js.map → injector.js.map} +0 -0
- package/{dist/interfaces → interfaces}/app-config.d.ts +0 -0
- package/{dist/interfaces → interfaces}/app-config.js +0 -0
- package/{dist/interfaces → interfaces}/app-config.js.map +0 -0
- package/{dist/interfaces → interfaces}/from-array.d.ts +0 -0
- package/{dist/interfaces → interfaces}/from-array.js +0 -0
- package/{dist/interfaces → interfaces}/from-array.js.map +0 -0
- package/{dist/interfaces → interfaces}/index.d.ts +0 -0
- package/{dist/interfaces → interfaces}/index.js +0 -0
- package/{dist/interfaces → interfaces}/index.js.map +0 -0
- package/{dist/interfaces → interfaces}/newable.d.ts +0 -0
- package/{dist/interfaces → interfaces}/newable.js +0 -0
- package/{dist/interfaces → interfaces}/newable.js.map +0 -0
- package/{dist/interfaces → interfaces}/transactional-client.d.ts +0 -0
- package/{dist/interfaces → interfaces}/transactional-client.js +0 -0
- package/{dist/interfaces → interfaces}/transactional-client.js.map +0 -0
- package/{dist/interfaces → interfaces}/type.d.ts +0 -0
- package/{dist/interfaces → interfaces}/type.js +0 -0
- package/{dist/interfaces → interfaces}/type.js.map +0 -0
- package/my-devkit-firebase-1.0.77.tgz +0 -0
- package/package.json +6 -6
- package/{dist/reflect.d.ts → reflect.d.ts} +0 -0
- package/{dist/reflect.js → reflect.js} +0 -0
- package/{dist/reflect.js.map → reflect.js.map} +0 -0
- package/{dist/request-method.enum.d.ts → request-method.enum.d.ts} +0 -0
- package/{dist/request-method.enum.js → request-method.enum.js} +0 -0
- package/{dist/request-method.enum.js.map → request-method.enum.js.map} +0 -0
- package/{dist/server → server}/index.d.ts +0 -0
- package/{dist/server → server}/index.js +0 -0
- package/{dist/server → server}/index.js.map +0 -0
- package/{dist/server → server}/middlewares/authentication-middleware.d.ts +0 -0
- package/{dist/server → server}/middlewares/authentication-middleware.js +0 -0
- package/{dist/server → server}/middlewares/authentication-middleware.js.map +0 -0
- package/{dist/server → server}/middlewares/create-context-middleware.d.ts +0 -0
- package/{dist/server → server}/middlewares/create-context-middleware.js +0 -0
- package/{dist/server → server}/middlewares/create-context-middleware.js.map +0 -0
- package/{dist/server → server}/middlewares/error-middleware.d.ts +0 -0
- package/{dist/server → server}/middlewares/error-middleware.js +0 -0
- package/{dist/server → server}/middlewares/error-middleware.js.map +0 -0
- package/{dist/server → server}/middlewares/headers-middleware.d.ts +0 -0
- package/{dist/server → server}/middlewares/headers-middleware.js +0 -0
- package/{dist/server → server}/middlewares/headers-middleware.js.map +0 -0
- package/{dist/server → server}/middlewares/index.d.ts +0 -0
- package/{dist/server → server}/middlewares/index.js +0 -0
- package/{dist/server → server}/middlewares/index.js.map +0 -0
- package/{dist/server → server}/middlewares/not-found-middleware.d.ts +0 -0
- package/{dist/server → server}/middlewares/not-found-middleware.js +0 -0
- package/{dist/server → server}/middlewares/not-found-middleware.js.map +0 -0
- package/{dist/server → server}/server.d.ts +0 -0
- package/{dist/server → server}/server.js +0 -0
- package/{dist/server → server}/server.js.map +0 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/.eslintrc.js +0 -15
- package/.vscode/settings.json +0 -7
- package/dist/package.json +0 -54
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/my-devkit-firebase-1.0.76.tgz +0 -0
- package/src/aggregate.ts +0 -54
- package/src/app-factory.ts +0 -252
- package/src/bus.ts +0 -70
- package/src/constants.ts +0 -5
- package/src/context.ts +0 -108
- package/src/decorators/controller/body.spec.ts +0 -52
- package/src/decorators/controller/body.ts +0 -17
- package/src/decorators/controller/controller.spec.ts +0 -19
- package/src/decorators/controller/controller.ts +0 -10
- package/src/decorators/controller/get.spec.ts +0 -32
- package/src/decorators/controller/get.ts +0 -8
- package/src/decorators/controller/index.ts +0 -8
- package/src/decorators/controller/param.spec.ts +0 -51
- package/src/decorators/controller/param.ts +0 -21
- package/src/decorators/controller/post.spec.ts +0 -60
- package/src/decorators/controller/post.ts +0 -8
- package/src/decorators/controller/query.spec.ts +0 -51
- package/src/decorators/controller/query.ts +0 -21
- package/src/decorators/handler/command-handler.spec.ts +0 -101
- package/src/decorators/handler/command-handler.ts +0 -21
- package/src/decorators/handler/event-handler.spec.ts +0 -104
- package/src/decorators/handler/event-handler.ts +0 -22
- package/src/decorators/handler/index.ts +0 -2
- package/src/decorators/index.ts +0 -5
- package/src/decorators/injectable.ts +0 -7
- package/src/decorators/module.ts +0 -29
- package/src/decorators/transactional-client.ts +0 -7
- package/src/execution-mode-enum.ts +0 -4
- package/src/firestore-client.ts +0 -125
- package/src/handler-helper.ts +0 -68
- package/src/index.ts +0 -7
- package/src/injector.ts +0 -31
- package/src/interfaces/app-config.ts +0 -1
- package/src/interfaces/from-array.ts +0 -1
- package/src/interfaces/index.ts +0 -4
- package/src/interfaces/newable.ts +0 -1
- package/src/interfaces/transactional-client.ts +0 -3
- package/src/interfaces/type.ts +0 -3
- package/src/reflect.ts +0 -164
- package/src/request-method.enum.ts +0 -4
- package/src/server/index.ts +0 -1
- package/src/server/middlewares/authentication-middleware.ts +0 -47
- package/src/server/middlewares/create-context-middleware.ts +0 -16
- package/src/server/middlewares/error-middleware.ts +0 -33
- package/src/server/middlewares/headers-middleware.ts +0 -16
- package/src/server/middlewares/index.ts +0 -5
- package/src/server/middlewares/not-found-middleware.ts +0 -9
- package/src/server/server.ts +0 -96
- package/tsconfig.json +0 -24
package/src/aggregate.ts
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { autoserializeAs, Document, DomainError, Event, guid, serialize } from '@my-devkit/core';
|
|
2
|
-
|
|
3
|
-
import { Context } from './context';
|
|
4
|
-
|
|
5
|
-
export abstract class Aggregate implements Document {
|
|
6
|
-
@autoserializeAs(String) public id: string = null;
|
|
7
|
-
@autoserializeAs(String) public _type: string = null;
|
|
8
|
-
private _events: Event[] = [];
|
|
9
|
-
|
|
10
|
-
public constructor() {
|
|
11
|
-
this.id = guid();
|
|
12
|
-
this._type = this.constructor.name;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
public get _path(): string {
|
|
16
|
-
return `/aggregates/${this.id}`;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
public get hash(): string {
|
|
20
|
-
return JSON.stringify(serialize(this));
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
protected assert(value: boolean, errorMessage: string): void {
|
|
24
|
-
if (!value) {
|
|
25
|
-
throw new DomainError(errorMessage);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
protected apply<E extends Event>(event: E): void {
|
|
30
|
-
const methodName = `apply${event._type}`;
|
|
31
|
-
if (!(methodName in this)) {
|
|
32
|
-
throw new Error(`${this._type}.${methodName} method is missing!`);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
event._aggregateId = this.id;
|
|
36
|
-
event._aggregateType = this._type;
|
|
37
|
-
|
|
38
|
-
event._correlationId = Context.correlationId;
|
|
39
|
-
event._publishedBy = Context.user ? Context.user.uid : null;
|
|
40
|
-
event.publishedAt = new Date();
|
|
41
|
-
|
|
42
|
-
this[methodName](event);
|
|
43
|
-
|
|
44
|
-
this._events.push(event);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
public get events(): Event[] {
|
|
48
|
-
return [...this._events];
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
public clearEvents(): void {
|
|
52
|
-
this._events = [];
|
|
53
|
-
}
|
|
54
|
-
}
|
package/src/app-factory.ts
DELETED
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
import { deserialize, Event, guid, Logger, retry } from '@my-devkit/core';
|
|
2
|
-
import { initializeApp } from 'firebase-admin/app';
|
|
3
|
-
import { Auth, getAuth } from 'firebase-admin/auth';
|
|
4
|
-
import { DocumentSnapshot, Firestore, getFirestore } from 'firebase-admin/firestore';
|
|
5
|
-
import { CloudFunction, config, FunctionBuilder, HttpsFunction, logger, region, RuntimeOptions, SUPPORTED_REGIONS, VALID_MEMORY_OPTIONS } from 'firebase-functions';
|
|
6
|
-
|
|
7
|
-
import { Bus } from './bus';
|
|
8
|
-
import { MODULE_METADATA } from './constants';
|
|
9
|
-
import { Context } from './context';
|
|
10
|
-
import { ExecutionMode } from './execution-mode-enum';
|
|
11
|
-
import { FirestoreClient } from './firestore-client';
|
|
12
|
-
import { Type } from './interfaces';
|
|
13
|
-
import { reflect } from './reflect';
|
|
14
|
-
import { Server } from './server';
|
|
15
|
-
|
|
16
|
-
export class AppFactory {
|
|
17
|
-
private static functionInRegion: FunctionBuilder;
|
|
18
|
-
private static firestore: Firestore;
|
|
19
|
-
private static auth: Auth;
|
|
20
|
-
private static publicPaths: string[];
|
|
21
|
-
private static instanceId: string;
|
|
22
|
-
|
|
23
|
-
public static isActive(name: string): boolean {
|
|
24
|
-
const functionName = process.env.FUNCTION_NAME || process.env.K_SERVICE;
|
|
25
|
-
return !functionName || functionName === name;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
public static initializeApp(options: AppFactory.Options): void {
|
|
29
|
-
this.instanceId = guid();
|
|
30
|
-
|
|
31
|
-
Context.init();
|
|
32
|
-
this.registerLogger();
|
|
33
|
-
|
|
34
|
-
this.publicPaths = options.publicPaths || [];
|
|
35
|
-
|
|
36
|
-
const app = initializeApp(config().firebase);
|
|
37
|
-
this.firestore = getFirestore(app);
|
|
38
|
-
this.firestore.settings({});
|
|
39
|
-
|
|
40
|
-
this.auth = getAuth(app);
|
|
41
|
-
|
|
42
|
-
const runtimeOptions: RuntimeOptions = {
|
|
43
|
-
timeoutSeconds: options.timeoutSeconds,
|
|
44
|
-
memory: options.memory
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
this.functionInRegion = region(this.isEmulator ? 'functions' : options.region).runWith(runtimeOptions);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
public static createHttpFunction(name: string, module: Type): HttpsFunction {
|
|
51
|
-
if (!this.isActive(name)) {
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
Logger.info(`Cold Start Http function ${name}`);
|
|
56
|
-
|
|
57
|
-
const bus = new Bus();
|
|
58
|
-
|
|
59
|
-
const server = new Server({
|
|
60
|
-
bus,
|
|
61
|
-
firebaseAuth: this.auth,
|
|
62
|
-
firestore: this.firestore,
|
|
63
|
-
publicPaths: this.publicPaths
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
this.registerControllers(server, module);
|
|
67
|
-
|
|
68
|
-
this.registerEventPersisterHandler(bus);
|
|
69
|
-
|
|
70
|
-
this.registerHandlers(bus, module);
|
|
71
|
-
|
|
72
|
-
return this.functionInRegion.https.onRequest(server.app);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
public static createEventListener(name: string, module: Type, mode: ExecutionMode = ExecutionMode.Asynchronous): CloudFunction<DocumentSnapshot> {
|
|
76
|
-
if (!this.isActive(name)) {
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
Logger.info(`Cold Start Event Listener ${mode}`);
|
|
81
|
-
|
|
82
|
-
const bus = new Bus();
|
|
83
|
-
|
|
84
|
-
this.registerEventPersisterHandler(bus);
|
|
85
|
-
|
|
86
|
-
this.registerHandlers(bus, module);
|
|
87
|
-
|
|
88
|
-
return this.functionInRegion
|
|
89
|
-
.firestore
|
|
90
|
-
.document('events/{eventId}')
|
|
91
|
-
.onCreate(this.getFunctionEventHandler(bus, ExecutionMode.Asynchronous));
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
private static registerEventPersisterHandler(bus: Bus): void {
|
|
95
|
-
bus.onEachEvent(async (event: Event): Promise<void> => {
|
|
96
|
-
Context.resolve(FirestoreClient).createDocument(event);
|
|
97
|
-
}, ExecutionMode.Synchronous);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
private static registerControllers(server: Server, module: Type): void {
|
|
101
|
-
const controllers = Reflect.getMetadata(MODULE_METADATA.CONTROLLERS, module) || [];
|
|
102
|
-
for (const controller of controllers) {
|
|
103
|
-
this.registerController(server, controller);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const imports: any[] = Reflect.getMetadata(MODULE_METADATA.IMPORTS, module) || [];
|
|
107
|
-
for (const importedModule of imports) {
|
|
108
|
-
this.registerControllers(server, importedModule);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
private static registerController(server: Server, controller: Type): void {
|
|
113
|
-
const router = new Server.Router();
|
|
114
|
-
|
|
115
|
-
const config = reflect(controller).getControllerConfiguration();
|
|
116
|
-
|
|
117
|
-
for (const route of config.routes) {
|
|
118
|
-
router.registerRoute(route.requestMethod, `/${route.path}`, async (request: Server.Request, response: Server.Response): Promise<void> => {
|
|
119
|
-
Logger.info(`${route.requestMethod}/${route.path}: executing handler method ${controller.name}.${route.methodName}`);
|
|
120
|
-
const controllerInstance = Context.resolve(controller);
|
|
121
|
-
const args = route.argumentInjectors.map(injector => injector(request));
|
|
122
|
-
const result = await controllerInstance[route.methodName](...args);
|
|
123
|
-
|
|
124
|
-
for (const client of Context.getTransactionalClients()) {
|
|
125
|
-
Logger.info(`Saving transactions...`);
|
|
126
|
-
await client.save();
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
Context.destroy();
|
|
130
|
-
response.status(Server.statusCodes.OK).send({ result });
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
router.registerOnServer(`/${config.basePath}`, server);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
private static registerHandlers(bus: Bus, module: Type): void {
|
|
138
|
-
const handlers = Reflect.getMetadata(MODULE_METADATA.HANDLERS, module) || [];
|
|
139
|
-
for (const handler of handlers) {
|
|
140
|
-
const handlerConfiguration = reflect(handler).getHandlerConfiguration();
|
|
141
|
-
|
|
142
|
-
const instance = new handler();
|
|
143
|
-
for (const commandHandler of Array.from(handlerConfiguration.commandHandlers.values())) {
|
|
144
|
-
Logger.debug(`onCommand ${commandHandler.command.constructor.name} => ${handler.name}.${commandHandler.methodName}`);
|
|
145
|
-
bus.onCommand(commandHandler.command, (command) => {
|
|
146
|
-
const startDate = new Date();
|
|
147
|
-
Logger.info(`${handler.name}.${commandHandler.methodName} handle ${command._type}`);
|
|
148
|
-
const result = instance[commandHandler.methodName](command);
|
|
149
|
-
Logger.infoWithElapesedTime(`${command._type} handled by ${handler.name}.${commandHandler.methodName}`, startDate);
|
|
150
|
-
return result;
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
for (const eventHandler of Array.from(handlerConfiguration.eventHandlers.values())) {
|
|
155
|
-
Logger.debug(`onEvent ${eventHandler.event.constructor.name} => ${handler.name}.${eventHandler.methodName} (mode: ${eventHandler.executionMode})`);
|
|
156
|
-
bus.onEvent(eventHandler.event, async (event) => {
|
|
157
|
-
const startDate = new Date();
|
|
158
|
-
Logger.info(`${handler.name}.${eventHandler.methodName} handle ${event._type}`);
|
|
159
|
-
await instance[eventHandler.methodName](event);
|
|
160
|
-
Logger.infoWithElapesedTime(`${event._type} handled by ${handler.name}.${eventHandler.methodName}`, startDate);
|
|
161
|
-
}, eventHandler.executionMode);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const imports: any[] = Reflect.getMetadata(MODULE_METADATA.IMPORTS, module) || [];
|
|
166
|
-
for (const importedModule of imports) {
|
|
167
|
-
this.registerHandlers(bus, importedModule);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
private static registerLogger(): void {
|
|
172
|
-
if (this.isEmulator) {
|
|
173
|
-
Logger.registerLogger(new Logger.ConsoleImplementation());
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const completeMetaData = (data: Logger.LogMetaData): Logger.LogMetaData => {
|
|
178
|
-
return {
|
|
179
|
-
instanceId: this.instanceId,
|
|
180
|
-
correlationId: Context.correlationId,
|
|
181
|
-
eventId: Context.eventId,
|
|
182
|
-
userId: Context.user?.uid,
|
|
183
|
-
userEmail: Context.user?.email,
|
|
184
|
-
...data
|
|
185
|
-
};
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
Logger.registerLogger({
|
|
189
|
-
debug: (message: string, data: Logger.LogMetaData): void => {
|
|
190
|
-
logger.debug(message, completeMetaData(data));
|
|
191
|
-
},
|
|
192
|
-
info: (message: string, data: Logger.LogMetaData): void => {
|
|
193
|
-
logger.info(message, completeMetaData(data));
|
|
194
|
-
},
|
|
195
|
-
warn: (message: string, data: Logger.LogMetaData): void => {
|
|
196
|
-
logger.warn(message, completeMetaData(data));
|
|
197
|
-
},
|
|
198
|
-
error: (message: string, data: Logger.LogMetaData): void => {
|
|
199
|
-
logger.error(message, completeMetaData(data));
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
public static getFunctionEventHandler(bus: Bus, mode: ExecutionMode): (snapshot: DocumentSnapshot) => any {
|
|
205
|
-
return async (snapshot: DocumentSnapshot): Promise<void> => {
|
|
206
|
-
const startDate = new Date();
|
|
207
|
-
const unserializedEvent = snapshot.data();
|
|
208
|
-
|
|
209
|
-
const event = deserialize<Event>(unserializedEvent);
|
|
210
|
-
|
|
211
|
-
Context.create(bus);
|
|
212
|
-
Context.correlationId = event._correlationId;
|
|
213
|
-
Context.eventId = event.id;
|
|
214
|
-
|
|
215
|
-
if (unserializedEvent['_restored'] === true) {
|
|
216
|
-
Logger.debug(`Event ${event._type} is ignored as it is restored from backup.`);
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
try {
|
|
221
|
-
await retry(async (): Promise<void> => {
|
|
222
|
-
Logger.info(`${'-'.repeat(5)} handling ${event._type} ${'-'.repeat(5)}`);
|
|
223
|
-
|
|
224
|
-
await bus.publish(event, mode);
|
|
225
|
-
|
|
226
|
-
for (const client of Context.getTransactionalClients()) {
|
|
227
|
-
await client.save();
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
Logger.infoWithElapesedTime(`${'-'.repeat(5)} ${event._type} handled successfully ${'-'.repeat(5)}`, startDate);
|
|
231
|
-
});
|
|
232
|
-
} catch (error) {
|
|
233
|
-
Logger.error(`${'-'.repeat(5)} ${event._type} couldn't be handled correctly ${'-'.repeat(5)}`, { error });
|
|
234
|
-
} finally {
|
|
235
|
-
Context.destroy();
|
|
236
|
-
}
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
private static get isEmulator(): boolean {
|
|
241
|
-
return !!process.env.FUNCTIONS_EMULATOR;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
export namespace AppFactory {
|
|
246
|
-
export interface Options {
|
|
247
|
-
region: typeof SUPPORTED_REGIONS[number];
|
|
248
|
-
timeoutSeconds: number;
|
|
249
|
-
memory: typeof VALID_MEMORY_OPTIONS[number];
|
|
250
|
-
publicPaths?: string[]
|
|
251
|
-
}
|
|
252
|
-
}
|
package/src/bus.ts
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { Command, DomainError, Event, Logger, serialize, Validators } from '@my-devkit/core';
|
|
2
|
-
|
|
3
|
-
import { ExecutionMode } from './execution-mode-enum';
|
|
4
|
-
|
|
5
|
-
export class Bus {
|
|
6
|
-
private commandHandlers = new Map<string, Bus.Handler<Command, any>>();
|
|
7
|
-
private eventHandlers = new Map<string, Bus.Handler<Event, void>[]>();
|
|
8
|
-
|
|
9
|
-
public async send<T, C extends Command>(command: C): Promise<T> {
|
|
10
|
-
Logger.info(`Bus.send ${command._type}`, { command: serialize(command) });
|
|
11
|
-
|
|
12
|
-
const validationErrors = Validators.validate(command);
|
|
13
|
-
if (validationErrors.length > 0) {
|
|
14
|
-
throw new DomainError(validationErrors[0].getErrorMessage());
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const handler: Bus.Handler<C, T> = this.commandHandlers.get(command._type);
|
|
18
|
-
if (!handler) {
|
|
19
|
-
throw new Error(`No command handler for ${command._type}`);
|
|
20
|
-
}
|
|
21
|
-
Logger.info(`Run command handler ${handler.name}`);
|
|
22
|
-
|
|
23
|
-
return handler(command);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
public async publish<E extends Event>(event: E, mode: ExecutionMode = ExecutionMode.Synchronous): Promise<void> {
|
|
27
|
-
Logger.info(`Bus.publish ${event._type} `, { event: serialize(event) });
|
|
28
|
-
|
|
29
|
-
const handlers = [...this.getEventHandlers(event._type, mode), ...this.getEventHandlers('**', mode)];
|
|
30
|
-
for (const handler of handlers) {
|
|
31
|
-
Logger.info(`Run event handler ${handler.name}`);
|
|
32
|
-
await handler(event);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
public onCommand<C extends Command, R>(commandType: new () => C, handler: Bus.Handler<C, R>): void {
|
|
37
|
-
const commandName = commandType.constructor.name;
|
|
38
|
-
this.commandHandlers.set(commandName, handler);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
public onEvent<E extends Event>(eventType: new () => E, handler: Bus.Handler<E, void>, mode: ExecutionMode): void {
|
|
42
|
-
this.registerEventHandler(eventType.constructor.name, mode, handler);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
public onEachEvent<E extends Event>(handler: Bus.Handler<E, void>, mode: ExecutionMode): void {
|
|
46
|
-
this.registerEventHandler('**', mode, handler);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
private getDictionaryKey(eventType: string, mode: ExecutionMode): string {
|
|
50
|
-
return `${eventType}_${mode.toString()}`;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
private registerEventHandler<E extends Event>(type: string, mode: ExecutionMode, handler: Bus.Handler<E, void>): void {
|
|
54
|
-
const key = this.getDictionaryKey(type, mode);
|
|
55
|
-
|
|
56
|
-
if (!this.eventHandlers.has(key)) {
|
|
57
|
-
this.eventHandlers.set(key, []);
|
|
58
|
-
}
|
|
59
|
-
this.eventHandlers.get(key).push(handler);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
private getEventHandlers(type: string, mode: ExecutionMode) {
|
|
63
|
-
const key = this.getDictionaryKey(type, mode);
|
|
64
|
-
return this.eventHandlers.get(key) || [];
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export namespace Bus {
|
|
69
|
-
export type Handler<T, R> = (arg: T) => Promise<R>;
|
|
70
|
-
}
|
package/src/constants.ts
DELETED
package/src/context.ts
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { Logger } from '@my-devkit/core';
|
|
2
|
-
import { AsyncHook, createHook, executionAsyncId } from 'async_hooks';
|
|
3
|
-
|
|
4
|
-
import { Bus } from './bus';
|
|
5
|
-
import { Injector } from './injector';
|
|
6
|
-
import { ITransactionalClient, Type } from './interfaces';
|
|
7
|
-
|
|
8
|
-
interface ContextStore {
|
|
9
|
-
injector: Injector;
|
|
10
|
-
bus: Bus;
|
|
11
|
-
correlationId?: string;
|
|
12
|
-
eventId?: string;
|
|
13
|
-
user?: UserRecord;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
interface UserRecord {
|
|
17
|
-
uid: string;
|
|
18
|
-
email?: string;
|
|
19
|
-
displayName?: string;
|
|
20
|
-
photoURL?: string;
|
|
21
|
-
disabled: boolean;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export class Context {
|
|
25
|
-
private static store = new Map<number, ContextStore>();
|
|
26
|
-
private static asyncHook: AsyncHook;
|
|
27
|
-
|
|
28
|
-
public static init(): void {
|
|
29
|
-
this.asyncHook = createHook({
|
|
30
|
-
init: (asyncId: number, _type: string, triggerAsyncId: number) => {
|
|
31
|
-
if (this.store.has(triggerAsyncId)) {
|
|
32
|
-
this.store.set(asyncId, this.store.get(triggerAsyncId))
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
destroy: (asyncId: number) => {
|
|
36
|
-
this.store.delete(asyncId);
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
this.asyncHook.enable();
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
public static create(bus: Bus): void {
|
|
43
|
-
this.store.set(executionAsyncId(), { injector: new Injector(), bus });
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
public static resolve<T>(type: Type<T>): T {
|
|
47
|
-
if (!this.store.has(executionAsyncId())) {
|
|
48
|
-
throw new Error(`Create context before resolving an injection!`);
|
|
49
|
-
}
|
|
50
|
-
return this.store.get(executionAsyncId()).injector.resolve(type);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
public static getTransactionalClients(): ITransactionalClient[] {
|
|
54
|
-
if (!this.store.has(executionAsyncId())) {
|
|
55
|
-
throw new Error(`Create context before getting transactional clients!`);
|
|
56
|
-
}
|
|
57
|
-
return this.store.get(executionAsyncId()).injector.getTransactionalClients();
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
public static get bus(): Bus {
|
|
61
|
-
return this.store.get(executionAsyncId())?.bus;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
public static set correlationId(correlationId: string) {
|
|
65
|
-
if (!this.store.has(executionAsyncId())) {
|
|
66
|
-
throw new Error(`Create context before setting correlationId!`);
|
|
67
|
-
}
|
|
68
|
-
this.store.get(executionAsyncId()).correlationId = correlationId;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
public static get correlationId(): string {
|
|
72
|
-
return this.store.get(executionAsyncId())?.correlationId;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
public static set eventId(eventId: string) {
|
|
76
|
-
if (!this.store.has(executionAsyncId())) {
|
|
77
|
-
throw new Error(`Create context before setting eventId!`);
|
|
78
|
-
}
|
|
79
|
-
this.store.get(executionAsyncId()).eventId = eventId;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
public static get eventId(): string {
|
|
83
|
-
return this.store.get(executionAsyncId())?.eventId;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
public static set user(user: UserRecord) {
|
|
87
|
-
if (!this.store.has(executionAsyncId())) {
|
|
88
|
-
throw new Error(`Create context before setting user!`);
|
|
89
|
-
}
|
|
90
|
-
this.store.get(executionAsyncId()).user = user;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
public static get user(): UserRecord {
|
|
94
|
-
return this.store.get(executionAsyncId())?.user;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
public static destroy(): void {
|
|
98
|
-
this.store.delete(executionAsyncId());
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
public static size(): number {
|
|
102
|
-
return this.store.size;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
public static logRemainingKeys(): void {
|
|
106
|
-
Logger.info(Array.from(this.store.keys()).join(' '));
|
|
107
|
-
}
|
|
108
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { autoserializeAs } from '@my-devkit/core';
|
|
2
|
-
import { expect } from 'chai';
|
|
3
|
-
|
|
4
|
-
import { reflect } from '../../reflect';
|
|
5
|
-
import { Body } from './body';
|
|
6
|
-
import { Controller } from './controller';
|
|
7
|
-
|
|
8
|
-
describe('Given a Body decorator', () => {
|
|
9
|
-
|
|
10
|
-
class Command {
|
|
11
|
-
@autoserializeAs(String)
|
|
12
|
-
public testString: string = null;
|
|
13
|
-
|
|
14
|
-
@autoserializeAs(Date)
|
|
15
|
-
public testDate: Date = null;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
@Controller('test')
|
|
20
|
-
class TestClass {
|
|
21
|
-
public testDate(@Body() param1: Date): string {
|
|
22
|
-
return `testDate: ${param1}`;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
public testCommand(@Body() param1: Command): string {
|
|
26
|
-
return `testCommand: ${param1}`;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
describe('When decorator is called', () => {
|
|
31
|
-
it('Then we should retrieve information via reflect', async () => {
|
|
32
|
-
const config = reflect(TestClass).getControllerConfiguration();
|
|
33
|
-
expect(config.routes.length).equal(2, 'Wrong route count detected');
|
|
34
|
-
|
|
35
|
-
const request1 = <any>{ body: '2021-02-08T11:14:23.318Z' };
|
|
36
|
-
|
|
37
|
-
expect(config.routes[0].argumentInjectors.length).equal(1, 'Wrong argumentInjectors length');
|
|
38
|
-
expect(config.routes[0].argumentInjectors[0](request1)).to.be.a('Date');
|
|
39
|
-
expect(config.routes[0].argumentInjectors[0](request1).toISOString()).equals((new Date('2021-02-08T11:14:23.318Z')).toISOString());
|
|
40
|
-
|
|
41
|
-
const request2 = <any>{ body: { testString: 'test' } };
|
|
42
|
-
|
|
43
|
-
const expectedBody2 = new Command();
|
|
44
|
-
expectedBody2.testString = 'test';
|
|
45
|
-
expectedBody2.testDate = null;
|
|
46
|
-
|
|
47
|
-
expect(config.routes[1].argumentInjectors.length).equal(1, 'Wrong argumentInjectors length');
|
|
48
|
-
expect(config.routes[1].argumentInjectors[0](request2)).to.be.instanceOf(Command);
|
|
49
|
-
expect(config.routes[1].argumentInjectors[0](request2)).deep.equal(expectedBody2);
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
});
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { deserialize } from '@my-devkit/core';
|
|
2
|
-
|
|
3
|
-
import { reflect, RequestArgumentInjector } from '../../reflect';
|
|
4
|
-
import { Server } from '../../server';
|
|
5
|
-
|
|
6
|
-
export function Body(): ParameterDecorator {
|
|
7
|
-
return (target, propertyKey, parameterIndex) => {
|
|
8
|
-
const methodArguments = reflect(target, propertyKey).getParameters();
|
|
9
|
-
if (!methodArguments.hasOwnProperty(parameterIndex)) {
|
|
10
|
-
throw new Error(`Body: can't find argument ${parameterIndex} on ${target.constructor.name}.${propertyKey.toString()}`);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const injector: RequestArgumentInjector = (req: Server.Request) => deserialize(req.body, methodArguments[parameterIndex]);
|
|
14
|
-
|
|
15
|
-
reflect(target, propertyKey).registerControllerRouteArgumentInjector(injector, parameterIndex);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { expect } from 'chai';
|
|
2
|
-
|
|
3
|
-
import { reflect } from '../../reflect';
|
|
4
|
-
import { Controller } from './controller';
|
|
5
|
-
|
|
6
|
-
describe('Given a Controller decorator', () => {
|
|
7
|
-
|
|
8
|
-
@Controller('test')
|
|
9
|
-
class TestClass {
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
describe('When decorator is called', () => {
|
|
13
|
-
it('Then we should retrieve information via reflect', async () => {
|
|
14
|
-
const config = reflect(TestClass).getControllerConfiguration();
|
|
15
|
-
|
|
16
|
-
expect(config.basePath).equals('test');
|
|
17
|
-
});
|
|
18
|
-
});
|
|
19
|
-
});
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { reflect } from '../../reflect';
|
|
2
|
-
import { Injectable } from './../injectable';
|
|
3
|
-
|
|
4
|
-
export function Controller(basePath: string): ClassDecorator {
|
|
5
|
-
return target => {
|
|
6
|
-
reflect(target).registerController(basePath);
|
|
7
|
-
// Register controller as injectable ressource
|
|
8
|
-
Injectable()(target);
|
|
9
|
-
};
|
|
10
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { guid } from '@my-devkit/core';
|
|
2
|
-
import { expect } from 'chai';
|
|
3
|
-
|
|
4
|
-
import { Get } from '.';
|
|
5
|
-
import { reflect } from '../../reflect';
|
|
6
|
-
import { RequestMethod } from '../../request-method.enum';
|
|
7
|
-
import { Controller } from './controller';
|
|
8
|
-
|
|
9
|
-
describe('Given a Get decorator', () => {
|
|
10
|
-
|
|
11
|
-
@Controller('test')
|
|
12
|
-
class TestClass {
|
|
13
|
-
public test = guid();
|
|
14
|
-
|
|
15
|
-
@Get('create')
|
|
16
|
-
public get(): string {
|
|
17
|
-
return `create`;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
describe('When decorator is called', () => {
|
|
22
|
-
it('Then we should retrieve information via reflect', async () => {
|
|
23
|
-
const config = reflect(TestClass).getControllerConfiguration();
|
|
24
|
-
|
|
25
|
-
expect(config.routes.length).equal(1, 'Wrong route count detected');
|
|
26
|
-
|
|
27
|
-
expect(config.routes[0].path).equal('create');
|
|
28
|
-
expect(config.routes[0].methodName).equal('get');
|
|
29
|
-
expect(config.routes[0].requestMethod).equal(RequestMethod.GET);
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
});
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { reflect } from '../../reflect';
|
|
2
|
-
import { RequestMethod } from '../../request-method.enum';
|
|
3
|
-
|
|
4
|
-
export function Get(path: string): MethodDecorator {
|
|
5
|
-
return (target, propertyKey) => {
|
|
6
|
-
reflect(target.constructor, propertyKey).registerControllerRoute({ path, requestMethod: RequestMethod.GET });
|
|
7
|
-
}
|
|
8
|
-
}
|