@my-devkit/firebase 1.0.65 → 1.0.69

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.
Files changed (236) hide show
  1. package/.eslintrc.js +15 -0
  2. package/.vscode/settings.json +7 -0
  3. package/{aggregate.d.ts → dist/aggregate.d.ts} +0 -0
  4. package/{aggregate.js → dist/aggregate.js} +16 -12
  5. package/dist/aggregate.js.map +1 -0
  6. package/{app-factory.d.ts → dist/app-factory.d.ts} +3 -3
  7. package/{app-factory.js → dist/app-factory.js} +27 -23
  8. package/dist/app-factory.js.map +1 -0
  9. package/{bus.d.ts → dist/bus.d.ts} +0 -0
  10. package/{bus.js → dist/bus.js} +15 -11
  11. package/dist/bus.js.map +1 -0
  12. package/{constants.d.ts → dist/constants.d.ts} +0 -0
  13. package/{constants.js → dist/constants.js} +0 -0
  14. package/{constants.js.map → dist/constants.js.map} +0 -0
  15. package/{context.d.ts → dist/context.d.ts} +0 -0
  16. package/{context.js → dist/context.js} +17 -17
  17. package/dist/context.js.map +1 -0
  18. package/{decorators → dist/decorators}/controller/body.d.ts +0 -0
  19. package/dist/decorators/controller/body.js +17 -0
  20. package/dist/decorators/controller/body.js.map +1 -0
  21. package/{decorators → dist/decorators}/controller/body.spec.d.ts +0 -0
  22. package/{decorators → dist/decorators}/controller/body.spec.js +15 -15
  23. package/dist/decorators/controller/body.spec.js.map +1 -0
  24. package/{decorators → dist/decorators}/controller/controller.d.ts +0 -0
  25. package/{decorators → dist/decorators}/controller/controller.js +2 -2
  26. package/{decorators → dist/decorators}/controller/controller.js.map +1 -1
  27. package/{decorators → dist/decorators}/controller/controller.spec.d.ts +0 -0
  28. package/{decorators → dist/decorators}/controller/controller.spec.js +3 -3
  29. package/dist/decorators/controller/controller.spec.js.map +1 -0
  30. package/{decorators → dist/decorators}/controller/get.d.ts +0 -0
  31. package/{decorators → dist/decorators}/controller/get.js +1 -1
  32. package/{decorators → dist/decorators}/controller/get.js.map +1 -1
  33. package/{decorators → dist/decorators}/controller/get.spec.d.ts +0 -0
  34. package/{decorators → dist/decorators}/controller/get.spec.js +8 -8
  35. package/dist/decorators/controller/get.spec.js.map +1 -0
  36. package/{decorators → dist/decorators}/controller/index.d.ts +0 -0
  37. package/{decorators → dist/decorators}/controller/index.js +0 -0
  38. package/{decorators → dist/decorators}/controller/index.js.map +0 -0
  39. package/{decorators → dist/decorators}/controller/param.d.ts +0 -0
  40. package/dist/decorators/controller/param.js +21 -0
  41. package/dist/decorators/controller/param.js.map +1 -0
  42. package/{decorators → dist/decorators}/controller/param.spec.d.ts +0 -0
  43. package/{decorators → dist/decorators}/controller/param.spec.js +18 -17
  44. package/dist/decorators/controller/param.spec.js.map +1 -0
  45. package/{decorators → dist/decorators}/controller/post.d.ts +0 -0
  46. package/{decorators → dist/decorators}/controller/post.js +1 -1
  47. package/{decorators → dist/decorators}/controller/post.js.map +1 -1
  48. package/{decorators → dist/decorators}/controller/post.spec.d.ts +0 -0
  49. package/{decorators → dist/decorators}/controller/post.spec.js +24 -24
  50. package/dist/decorators/controller/post.spec.js.map +1 -0
  51. package/{decorators → dist/decorators}/controller/query.d.ts +0 -0
  52. package/dist/decorators/controller/query.js +21 -0
  53. package/dist/decorators/controller/query.js.map +1 -0
  54. package/{decorators → dist/decorators}/controller/query.spec.d.ts +0 -0
  55. package/{decorators → dist/decorators}/controller/query.spec.js +18 -17
  56. package/dist/decorators/controller/query.spec.js.map +1 -0
  57. package/{decorators → dist/decorators}/handler/command-handler.d.ts +0 -0
  58. package/dist/decorators/handler/command-handler.js +22 -0
  59. package/dist/decorators/handler/command-handler.js.map +1 -0
  60. package/{decorators → dist/decorators}/handler/command-handler.spec.d.ts +0 -0
  61. package/{decorators → dist/decorators}/handler/command-handler.spec.js +21 -21
  62. package/dist/decorators/handler/command-handler.spec.js.map +1 -0
  63. package/{decorators → dist/decorators}/handler/event-handler.d.ts +0 -0
  64. package/dist/decorators/handler/event-handler.js +22 -0
  65. package/dist/decorators/handler/event-handler.js.map +1 -0
  66. package/{decorators → dist/decorators}/handler/event-handler.spec.d.ts +0 -0
  67. package/{decorators → dist/decorators}/handler/event-handler.spec.js +23 -23
  68. package/dist/decorators/handler/event-handler.spec.js.map +1 -0
  69. package/{decorators → dist/decorators}/handler/index.d.ts +0 -0
  70. package/{decorators → dist/decorators}/handler/index.js +0 -0
  71. package/{decorators → dist/decorators}/handler/index.js.map +0 -0
  72. package/{decorators → dist/decorators}/index.d.ts +0 -0
  73. package/{decorators → dist/decorators}/index.js +0 -0
  74. package/{decorators → dist/decorators}/index.js.map +0 -0
  75. package/{decorators → dist/decorators}/injectable.d.ts +0 -0
  76. package/{decorators → dist/decorators}/injectable.js +1 -1
  77. package/dist/decorators/injectable.js.map +1 -0
  78. package/{decorators → dist/decorators}/module.d.ts +0 -0
  79. package/{decorators → dist/decorators}/module.js +0 -0
  80. package/{decorators → dist/decorators}/module.js.map +0 -0
  81. package/{decorators → dist/decorators}/transactional-client.d.ts +0 -0
  82. package/{decorators → dist/decorators}/transactional-client.js +1 -1
  83. package/{decorators → dist/decorators}/transactional-client.js.map +1 -1
  84. package/{event.d.ts → dist/event.d.ts} +0 -0
  85. package/{event.js → dist/event.js} +9 -9
  86. package/dist/event.js.map +1 -0
  87. package/{execution-mode-enum.d.ts → dist/execution-mode-enum.d.ts} +0 -0
  88. package/{execution-mode-enum.js → dist/execution-mode-enum.js} +0 -0
  89. package/{execution-mode-enum.js.map → dist/execution-mode-enum.js.map} +0 -0
  90. package/{firestore-client.d.ts → dist/firestore-client.d.ts} +0 -0
  91. package/{firestore-client.js → dist/firestore-client.js} +19 -19
  92. package/dist/firestore-client.js.map +1 -0
  93. package/{handler-helper.d.ts → dist/handler-helper.d.ts} +0 -0
  94. package/{handler-helper.js → dist/handler-helper.js} +3 -3
  95. package/dist/handler-helper.js.map +1 -0
  96. package/{index.d.ts → dist/index.d.ts} +0 -0
  97. package/{index.js → dist/index.js} +0 -0
  98. package/{index.js.map → dist/index.js.map} +0 -0
  99. package/{injector.d.ts → dist/injector.d.ts} +0 -0
  100. package/{injector.js → dist/injector.js} +14 -10
  101. package/dist/injector.js.map +1 -0
  102. package/{interfaces → dist/interfaces}/app-config.d.ts +0 -0
  103. package/{interfaces → dist/interfaces}/app-config.js +0 -0
  104. package/{interfaces → dist/interfaces}/app-config.js.map +0 -0
  105. package/{interfaces → dist/interfaces}/from-array.d.ts +0 -0
  106. package/{interfaces → dist/interfaces}/from-array.js +0 -0
  107. package/{interfaces → dist/interfaces}/from-array.js.map +0 -0
  108. package/{interfaces → dist/interfaces}/index.d.ts +0 -0
  109. package/{interfaces → dist/interfaces}/index.js +0 -0
  110. package/{interfaces → dist/interfaces}/index.js.map +0 -0
  111. package/{interfaces → dist/interfaces}/newable.d.ts +0 -0
  112. package/{interfaces → dist/interfaces}/newable.js +0 -0
  113. package/{interfaces → dist/interfaces}/newable.js.map +0 -0
  114. package/{interfaces → dist/interfaces}/transactional-client.d.ts +0 -0
  115. package/{interfaces → dist/interfaces}/transactional-client.js +0 -0
  116. package/{interfaces → dist/interfaces}/transactional-client.js.map +0 -0
  117. package/{interfaces → dist/interfaces}/type.d.ts +0 -0
  118. package/{interfaces → dist/interfaces}/type.js +0 -0
  119. package/{interfaces → dist/interfaces}/type.js.map +0 -0
  120. package/dist/package.json +54 -0
  121. package/{reflect.d.ts → dist/reflect.d.ts} +0 -0
  122. package/{reflect.js → dist/reflect.js} +1 -1
  123. package/dist/reflect.js.map +1 -0
  124. package/{request-method.enum.d.ts → dist/request-method.enum.d.ts} +0 -0
  125. package/{request-method.enum.js → dist/request-method.enum.js} +0 -0
  126. package/{request-method.enum.js.map → dist/request-method.enum.js.map} +0 -0
  127. package/{server → dist/server}/index.d.ts +0 -0
  128. package/{server → dist/server}/index.js +0 -0
  129. package/{server → dist/server}/index.js.map +0 -0
  130. package/dist/server/middlewares/authentication-middleware.d.ts +3 -0
  131. package/{server → dist/server}/middlewares/authentication-middleware.js +8 -9
  132. package/dist/server/middlewares/authentication-middleware.js.map +1 -0
  133. package/{server → dist/server}/middlewares/create-context-middleware.d.ts +0 -0
  134. package/{server → dist/server}/middlewares/create-context-middleware.js +2 -2
  135. package/{server → dist/server}/middlewares/create-context-middleware.js.map +1 -1
  136. package/{server → dist/server}/middlewares/error-middleware.d.ts +0 -0
  137. package/{server → dist/server}/middlewares/error-middleware.js +1 -1
  138. package/{server → dist/server}/middlewares/error-middleware.js.map +1 -1
  139. package/{server → dist/server}/middlewares/headers-middleware.d.ts +0 -0
  140. package/{server → dist/server}/middlewares/headers-middleware.js +3 -13
  141. package/dist/server/middlewares/headers-middleware.js.map +1 -0
  142. package/{server → dist/server}/middlewares/index.d.ts +0 -0
  143. package/{server → dist/server}/middlewares/index.js +0 -0
  144. package/{server → dist/server}/middlewares/index.js.map +0 -0
  145. package/{server → dist/server}/middlewares/not-found-middleware.d.ts +0 -0
  146. package/{server → dist/server}/middlewares/not-found-middleware.js +1 -1
  147. package/{server → dist/server}/middlewares/not-found-middleware.js.map +1 -1
  148. package/{server → dist/server}/server.d.ts +0 -0
  149. package/{server → dist/server}/server.js +1 -1
  150. package/{server → dist/server}/server.js.map +1 -1
  151. package/dist/tsconfig.tsbuildinfo +1 -0
  152. package/my-devkit-firebase-1.0.69.tgz +0 -0
  153. package/package.json +23 -34
  154. package/src/aggregate.ts +49 -0
  155. package/src/app-factory.ts +253 -0
  156. package/src/bus.ts +71 -0
  157. package/src/constants.ts +5 -0
  158. package/src/context.ts +108 -0
  159. package/src/decorators/controller/body.spec.ts +52 -0
  160. package/src/decorators/controller/body.ts +17 -0
  161. package/src/decorators/controller/controller.spec.ts +19 -0
  162. package/src/decorators/controller/controller.ts +10 -0
  163. package/src/decorators/controller/get.spec.ts +32 -0
  164. package/src/decorators/controller/get.ts +8 -0
  165. package/src/decorators/controller/index.ts +8 -0
  166. package/src/decorators/controller/param.spec.ts +51 -0
  167. package/src/decorators/controller/param.ts +21 -0
  168. package/src/decorators/controller/post.spec.ts +60 -0
  169. package/src/decorators/controller/post.ts +8 -0
  170. package/src/decorators/controller/query.spec.ts +51 -0
  171. package/src/decorators/controller/query.ts +21 -0
  172. package/src/decorators/handler/command-handler.spec.ts +101 -0
  173. package/src/decorators/handler/command-handler.ts +23 -0
  174. package/src/decorators/handler/event-handler.spec.ts +104 -0
  175. package/src/decorators/handler/event-handler.ts +23 -0
  176. package/src/decorators/handler/index.ts +2 -0
  177. package/src/decorators/index.ts +5 -0
  178. package/src/decorators/injectable.ts +7 -0
  179. package/src/decorators/module.ts +29 -0
  180. package/src/decorators/transactional-client.ts +7 -0
  181. package/src/event.ts +43 -0
  182. package/src/execution-mode-enum.ts +4 -0
  183. package/src/firestore-client.ts +125 -0
  184. package/src/handler-helper.ts +68 -0
  185. package/src/index.ts +8 -0
  186. package/src/injector.ts +31 -0
  187. package/src/interfaces/app-config.ts +1 -0
  188. package/src/interfaces/from-array.ts +1 -0
  189. package/src/interfaces/index.ts +4 -0
  190. package/src/interfaces/newable.ts +1 -0
  191. package/src/interfaces/transactional-client.ts +3 -0
  192. package/src/interfaces/type.ts +3 -0
  193. package/src/reflect.ts +165 -0
  194. package/src/request-method.enum.ts +4 -0
  195. package/src/server/index.ts +1 -0
  196. package/src/server/middlewares/authentication-middleware.ts +47 -0
  197. package/src/server/middlewares/create-context-middleware.ts +16 -0
  198. package/src/server/middlewares/error-middleware.ts +33 -0
  199. package/src/server/middlewares/headers-middleware.ts +16 -0
  200. package/src/server/middlewares/index.ts +5 -0
  201. package/src/server/middlewares/not-found-middleware.ts +9 -0
  202. package/src/server/server.ts +96 -0
  203. package/tsconfig.json +24 -0
  204. package/aggregate.js.map +0 -1
  205. package/app-factory.js.map +0 -1
  206. package/bus.js.map +0 -1
  207. package/context.js.map +0 -1
  208. package/decorators/controller/body.js +0 -17
  209. package/decorators/controller/body.js.map +0 -1
  210. package/decorators/controller/body.spec.js.map +0 -1
  211. package/decorators/controller/controller.spec.js.map +0 -1
  212. package/decorators/controller/get.spec.js.map +0 -1
  213. package/decorators/controller/param.js +0 -21
  214. package/decorators/controller/param.js.map +0 -1
  215. package/decorators/controller/param.spec.js.map +0 -1
  216. package/decorators/controller/post.spec.js.map +0 -1
  217. package/decorators/controller/query.js +0 -21
  218. package/decorators/controller/query.js.map +0 -1
  219. package/decorators/controller/query.spec.js.map +0 -1
  220. package/decorators/handler/command-handler.js +0 -22
  221. package/decorators/handler/command-handler.js.map +0 -1
  222. package/decorators/handler/command-handler.spec.js.map +0 -1
  223. package/decorators/handler/event-handler.js +0 -22
  224. package/decorators/handler/event-handler.js.map +0 -1
  225. package/decorators/handler/event-handler.spec.js.map +0 -1
  226. package/decorators/injectable.js.map +0 -1
  227. package/event.js.map +0 -1
  228. package/firestore-client.js.map +0 -1
  229. package/handler-helper.js.map +0 -1
  230. package/injector.js.map +0 -1
  231. package/my-devkit-firebase-1.0.65.tgz +0 -0
  232. package/reflect.js.map +0 -1
  233. package/server/middlewares/authentication-middleware.d.ts +0 -3
  234. package/server/middlewares/authentication-middleware.js.map +0 -1
  235. package/server/middlewares/headers-middleware.js.map +0 -1
  236. package/tsconfig.tsbuildinfo +0 -9698
@@ -0,0 +1,32 @@
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
+ });
@@ -0,0 +1,8 @@
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
+ }
@@ -0,0 +1,8 @@
1
+ export * from './controller';
2
+
3
+ export * from './body';
4
+ export * from './param';
5
+ export * from './query';
6
+
7
+ export * from './get';
8
+ export * from './post';
@@ -0,0 +1,51 @@
1
+ import { expect } from 'chai';
2
+
3
+ import { reflect } from '../../reflect';
4
+ import { Controller } from './controller';
5
+ import { Get } from './get';
6
+ import { Param } from './param';
7
+
8
+ describe('Given a Param decorator', () => {
9
+
10
+ enum Gender {
11
+ Male = 0,
12
+ Female = 'Female'
13
+ }
14
+
15
+ @Controller('test')
16
+ class TestClass {
17
+ @Get(':id')
18
+ public getById(@Param('id') id: string): string {
19
+ return `getById: ${id}`;
20
+ }
21
+
22
+ @Get(':gender/:minDate')
23
+ public getByGenderOlderThan(@Param('minDate') minDate: Date, @Param('gender') gender: Gender): string {
24
+ return `getByGenderOlderThan: ${gender} ${minDate.toISOString()}`;
25
+ }
26
+ }
27
+
28
+ describe('When decorator is called', () => {
29
+ it('Then we should retrieve information via reflect', async () => {
30
+ const config = reflect(TestClass).getControllerConfiguration();
31
+ expect(config.routes.length).equal(2, 'Wrong route count detected');
32
+
33
+ const request1 = <any>{ params: { id: 'guid 1' } };
34
+ expect(config.routes[0].argumentInjectors.length).equal(1, 'Wrong argumentInjectors length for getById');
35
+ expect(config.routes[0].argumentInjectors[0](request1)).to.be.a('string');
36
+ expect(config.routes[0].argumentInjectors[0](request1)).equals('guid 1');
37
+
38
+ const request2 = <any>{ params: { gender: 0, minDate: '2021-02-15T14:23:00.318Z' } };
39
+
40
+ expect(config.routes[1].argumentInjectors.length).equal(2, 'Wrong argumentInjectors length for getByGenderOlderThan');
41
+
42
+ expect(config.routes[1].argumentInjectors[0](request2)).to.be.a('Date');
43
+ expect(config.routes[1].argumentInjectors[0](request2).toISOString()).equals((new Date('2021-02-15T14:23:00.318Z')).toISOString());
44
+
45
+ expect(config.routes[1].argumentInjectors[1](request2)).equals(Gender.Male);
46
+
47
+ request2.params.gender = 'Female';
48
+ expect(config.routes[1].argumentInjectors[1](request2)).equals(Gender.Female);
49
+ });
50
+ });
51
+ });
@@ -0,0 +1,21 @@
1
+ import { deserialize } from '@my-devkit/core';
2
+
3
+ import { reflect, RequestArgumentInjector } from '../../reflect';
4
+ import { Server } from '../../server';
5
+
6
+ export function Param(key: string): ParameterDecorator {
7
+ return (target, propertyKey, parameterIndex) => {
8
+ const methodArguments = reflect(target, propertyKey).getParameters();
9
+ if (!methodArguments.hasOwnProperty(parameterIndex)) {
10
+ throw new Error(`Param: can't find argument ${parameterIndex} on ${target.constructor.name}.${propertyKey.toString()}`);
11
+ }
12
+
13
+ const injector: RequestArgumentInjector = (req: Server.Request) => {
14
+ if (req.params.hasOwnProperty(key)) {
15
+ return deserialize(req.params[key], methodArguments[parameterIndex]);
16
+ }
17
+ };
18
+
19
+ reflect(target, propertyKey).registerControllerRouteArgumentInjector(injector, parameterIndex);
20
+ }
21
+ }
@@ -0,0 +1,60 @@
1
+ import { autoserializeAs, guid } from '@my-devkit/core';
2
+ import { expect } from 'chai';
3
+
4
+ import { reflect } from '../../reflect';
5
+ import { RequestMethod } from '../../request-method.enum';
6
+ import { Body } from './body';
7
+ import { Controller } from './controller';
8
+ import { Post } from './post';
9
+
10
+ describe('Given a Post decorator', () => {
11
+
12
+ class Command {
13
+ @autoserializeAs(String)
14
+ public testString: string = null;
15
+
16
+ @autoserializeAs(Date)
17
+ public testDate: Date = null;
18
+ }
19
+
20
+
21
+ @Controller('test')
22
+ class TestClass {
23
+ public test = guid();
24
+
25
+ @Post('create')
26
+ public createMethod(@Body() param1: Date): string {
27
+ return `createMethod: ${param1}`;
28
+ }
29
+
30
+ @Post('update')
31
+ public updateMethod(@Body() param1: Command): string {
32
+ return `updateMethod: ${param1}`;
33
+ }
34
+
35
+ @Post('delete')
36
+ public deleteMethod(@Body() param1: Command): string {
37
+ return `deleteMethod: ${param1}`;
38
+ }
39
+ }
40
+
41
+ describe('When decorator is called', () => {
42
+ it('Then we should retrieve information via reflect', async () => {
43
+ const config = reflect(TestClass).getControllerConfiguration();
44
+
45
+ expect(config.routes.length).equal(3, 'Wrong route count detected');
46
+
47
+ expect(config.routes[0].path).equal('create');
48
+ expect(config.routes[0].methodName).equal('createMethod');
49
+ expect(config.routes[0].requestMethod).equal(RequestMethod.POST);
50
+
51
+ expect(config.routes[1].path).equal('update');
52
+ expect(config.routes[1].methodName).equal('updateMethod');
53
+ expect(config.routes[1].requestMethod).equal(RequestMethod.POST);
54
+
55
+ expect(config.routes[2].path).equal('delete');
56
+ expect(config.routes[2].methodName).equal('deleteMethod');
57
+ expect(config.routes[2].requestMethod).equal(RequestMethod.POST);
58
+ });
59
+ });
60
+ });
@@ -0,0 +1,8 @@
1
+ import { reflect } from '../../reflect';
2
+ import { RequestMethod } from '../../request-method.enum';
3
+
4
+ export function Post(path: string): MethodDecorator {
5
+ return (target, propertyKey) => {
6
+ reflect(target.constructor, propertyKey).registerControllerRoute({ path, requestMethod: RequestMethod.POST });
7
+ }
8
+ }
@@ -0,0 +1,51 @@
1
+ import { expect } from 'chai';
2
+
3
+ import { reflect } from '../../reflect';
4
+ import { Controller } from './controller';
5
+ import { Get } from './get';
6
+ import { Query } from './query';
7
+
8
+ describe('Given a Query decorator', () => {
9
+
10
+ enum Gender {
11
+ Male = 0,
12
+ Female = 'Female'
13
+ }
14
+
15
+ @Controller('test')
16
+ class TestClass {
17
+ @Get('by-id')
18
+ public getById(@Query('id') id: string): string {
19
+ return `getById: ${id}`;
20
+ }
21
+
22
+ @Get('all')
23
+ public all(@Query('minDate') minDate: Date, @Query('gender') gender: Gender): string {
24
+ return `getByGenderOlderThan: ${gender} ${minDate.toISOString()}`;
25
+ }
26
+ }
27
+
28
+ describe('When decorator is called', () => {
29
+ it('Then we should retrieve information via reflect', async () => {
30
+ const config = reflect(TestClass).getControllerConfiguration();
31
+ expect(config.routes.length).equal(2, 'Wrong route count detected');
32
+
33
+ const request1 = <any>{ query: { id: 'guid 1' } };
34
+ expect(config.routes[0].argumentInjectors.length).equal(1, 'Wrong argumentInjectors length for getById');
35
+ expect(config.routes[0].argumentInjectors[0](request1)).to.be.a('string');
36
+ expect(config.routes[0].argumentInjectors[0](request1)).equals('guid 1');
37
+
38
+ const request2 = <any>{ query: { gender: 0, minDate: '2021-02-15T14:23:00.318Z' } };
39
+
40
+ expect(config.routes[1].argumentInjectors.length).equal(2, 'Wrong argumentInjectors length for getByGenderOlderThan');
41
+
42
+ expect(config.routes[1].argumentInjectors[0](request2)).to.be.a('Date');
43
+ expect(config.routes[1].argumentInjectors[0](request2).toISOString()).equals((new Date('2021-02-15T14:23:00.318Z')).toISOString());
44
+
45
+ expect(config.routes[1].argumentInjectors[1](request2)).equals(Gender.Male);
46
+
47
+ request2.query.gender = 'Female';
48
+ expect(config.routes[1].argumentInjectors[1](request2)).equals(Gender.Female);
49
+ });
50
+ });
51
+ });
@@ -0,0 +1,21 @@
1
+ import { deserialize } from '@my-devkit/core';
2
+
3
+ import { reflect, RequestArgumentInjector } from '../../reflect';
4
+ import { Server } from '../../server';
5
+
6
+ export function Query(key: string): ParameterDecorator {
7
+ return (target, propertyKey, parameterIndex) => {
8
+ const methodArguments = reflect(target, propertyKey).getParameters();
9
+ if (!methodArguments.hasOwnProperty(parameterIndex)) {
10
+ throw new Error(`Query: can't find argument ${parameterIndex} on ${target.constructor.name}.${propertyKey.toString()}`);
11
+ }
12
+
13
+ const injector: RequestArgumentInjector = (req: Server.Request) => {
14
+ if (req.query.hasOwnProperty(key)) {
15
+ return deserialize(req.query[key], methodArguments[parameterIndex]);
16
+ }
17
+ };
18
+
19
+ reflect(target, propertyKey).registerControllerRouteArgumentInjector(injector, parameterIndex);
20
+ }
21
+ }
@@ -0,0 +1,101 @@
1
+ import { Command } from '@my-devkit/core';
2
+ import { expect } from 'chai';
3
+
4
+ import { reflect } from '../../reflect';
5
+ import { CommandHandler } from './command-handler';
6
+
7
+ describe('Given a CommandHandler decorator', () => {
8
+
9
+ describe('When decorator is called', () => {
10
+
11
+ describe('And decorated method has no parameter', () => {
12
+ it('Then we should retrieve information via reflect', async () => {
13
+
14
+ try {
15
+ class TestClass {
16
+ @CommandHandler()
17
+ public create(): string {
18
+ return `create`;
19
+ }
20
+ }
21
+
22
+ reflect(TestClass).getHandlerConfiguration();
23
+ } catch (error) {
24
+ expect(error.message).equal('TestClass.create should have one argument!');
25
+ }
26
+ });
27
+ });
28
+
29
+ describe('And decorated method has more than 1 parameter', () => {
30
+ it('Then we should retrieve information via reflect', async () => {
31
+
32
+ try {
33
+ class TestClass {
34
+ @CommandHandler()
35
+ public create(param1: string, param2: string): string {
36
+ return `create ${param1} / ${param2}`;
37
+ }
38
+ }
39
+
40
+ reflect(TestClass).getHandlerConfiguration();
41
+ } catch (error) {
42
+ expect(error.message).equal('TestClass.create should have only one argument!');
43
+ }
44
+ });
45
+ });
46
+
47
+ describe('And decorated method parameter is not a command', () => {
48
+ it('Then we should retrieve information via reflect', async () => {
49
+
50
+ try {
51
+ class FakeCommand {
52
+ test: string;
53
+ }
54
+
55
+ class TestClass {
56
+ @CommandHandler()
57
+ public create(fakeCommand: FakeCommand): string {
58
+ return `create ${fakeCommand}`;
59
+ }
60
+ }
61
+
62
+ reflect(TestClass).getHandlerConfiguration();
63
+ } catch (error) {
64
+ expect(error.message).equal('TestClass.create should have a command as argument!');
65
+ }
66
+ });
67
+ });
68
+
69
+ describe('And handler is correctly implemented', () => {
70
+
71
+ class CreateCommand extends Command {
72
+ }
73
+
74
+ class UpdateCommand extends Command {
75
+ }
76
+
77
+ class TestClass {
78
+ @CommandHandler()
79
+ public create(command: CreateCommand): string {
80
+ return `create: ${command}`;
81
+ }
82
+
83
+ @CommandHandler()
84
+ public update(command: UpdateCommand): string {
85
+ return `update: ${command}`;
86
+ }
87
+ }
88
+ it('Then we should retrieve information via reflect', async () => {
89
+ const config = reflect(TestClass).getHandlerConfiguration();
90
+ expect(config.commandHandlers.size).equal(2, 'Wrong route count detected');
91
+
92
+ expect(config.commandHandlers[0].methodName).equal('create');
93
+ expect(config.commandHandlers[0].command.constructor.name).equal('CreateCommand');
94
+
95
+ expect(config.commandHandlers[1].methodName).equal('update');
96
+ expect(config.commandHandlers[1].command.constructor.name).equal('UpdateCommand');
97
+
98
+ });
99
+ });
100
+ });
101
+ });
@@ -0,0 +1,23 @@
1
+ import { Command } from '@my-devkit/core';
2
+
3
+ import { reflect } from '../../reflect';
4
+
5
+ export function CommandHandler(): MethodDecorator {
6
+ return (target, propertyKey) => {
7
+ const paramTypes = reflect(target, propertyKey).getParameters();
8
+
9
+ if (paramTypes.length === 0) {
10
+ throw new Error(`${target.constructor.name}.${propertyKey.toString()} should have one argument!`);
11
+ }
12
+
13
+ if (paramTypes.length > 1) {
14
+ throw new Error(`${target.constructor.name}.${propertyKey.toString()} should have only one argument!`);
15
+ }
16
+
17
+ if (!(paramTypes[0].prototype instanceof Command)) {
18
+ throw new Error(`${target.constructor.name}.${propertyKey.toString()} should have a command as argument!`);
19
+ }
20
+
21
+ reflect(target, propertyKey).registerCommandHandler(<any>paramTypes[0].prototype);
22
+ }
23
+ }
@@ -0,0 +1,104 @@
1
+ import { expect } from 'chai';
2
+
3
+ import { Event } from '../../event';
4
+ import { ExecutionMode } from '../../execution-mode-enum';
5
+ import { reflect } from '../../reflect';
6
+ import { EventHandler } from './event-handler';
7
+
8
+ describe('Given a EventHandler decorator', () => {
9
+
10
+ describe('When decorator is called', () => {
11
+
12
+ describe('And decorated method has no parameter', () => {
13
+ it('Then we should retrieve information via reflect', async () => {
14
+
15
+ try {
16
+ class TestClass {
17
+ @EventHandler(ExecutionMode.Asynchronous)
18
+ public created(): string {
19
+ return `created`;
20
+ }
21
+ }
22
+
23
+ reflect(TestClass).getHandlerConfiguration();
24
+ } catch (error) {
25
+ expect(error.message).equal('TestClass.created should have one argument!');
26
+ }
27
+ });
28
+ });
29
+
30
+ describe('And decorated method has more than 1 parameter', () => {
31
+ it('Then we should retrieve information via reflect', async () => {
32
+
33
+ try {
34
+ class TestClass {
35
+ @EventHandler(ExecutionMode.Asynchronous)
36
+ public created(param1: string, param2: string): string {
37
+ return `created ${param1} / ${param2}`;
38
+ }
39
+ }
40
+
41
+ reflect(TestClass).getHandlerConfiguration();
42
+ } catch (error) {
43
+ expect(error.message).equal('TestClass.created should have only one argument!');
44
+ }
45
+ });
46
+ });
47
+
48
+ describe('And decorated method parameter is not a command', () => {
49
+ it('Then we should retrieve information via reflect', async () => {
50
+
51
+ try {
52
+ class FakeEvent {
53
+ test: string;
54
+ }
55
+
56
+ class TestClass {
57
+ @EventHandler(ExecutionMode.Asynchronous)
58
+ public created(fakeEvent: FakeEvent): string {
59
+ return `created ${fakeEvent}`;
60
+ }
61
+ }
62
+
63
+ reflect(TestClass).getHandlerConfiguration();
64
+ } catch (error) {
65
+ expect(error.message).equal('TestClass.created should have an event as argument!');
66
+ }
67
+ });
68
+ });
69
+
70
+ describe('And handler is correctly implemented', () => {
71
+
72
+ class CreatedEvent extends Event {
73
+ }
74
+
75
+ class UpdatedEvent extends Event {
76
+ }
77
+
78
+ class TestClass {
79
+ @EventHandler(ExecutionMode.Asynchronous)
80
+ public created(event: CreatedEvent): string {
81
+ return `created: ${event}`;
82
+ }
83
+
84
+ @EventHandler(ExecutionMode.Synchronous)
85
+ public updated(event: UpdatedEvent): string {
86
+ return `updated: ${event}`;
87
+ }
88
+ }
89
+ it('Then we should retrieve information via reflect', async () => {
90
+ const config = reflect(TestClass).getHandlerConfiguration();
91
+ expect(config.eventHandlers.size).equal(2, 'Wrong route count detected');
92
+
93
+ expect(config.eventHandlers[0].methodName).equal('created');
94
+ expect(config.eventHandlers[0].executionMode).equal(ExecutionMode.Asynchronous);
95
+ expect(config.eventHandlers[0].event.constructor.name).equal('CreatedEvent');
96
+
97
+ expect(config.eventHandlers[1].methodName).equal('updated');
98
+ expect(config.eventHandlers[1].executionMode).equal(ExecutionMode.Synchronous);
99
+ expect(config.eventHandlers[1].event.constructor.name).equal('UpdatedEvent');
100
+
101
+ });
102
+ });
103
+ });
104
+ });
@@ -0,0 +1,23 @@
1
+ import { Event } from '../../event';
2
+ import { ExecutionMode } from '../../execution-mode-enum';
3
+ import { reflect } from '../../reflect';
4
+
5
+ export function EventHandler(mode: ExecutionMode): MethodDecorator {
6
+ return (target, propertyKey) => {
7
+ const paramTypes = reflect(target, propertyKey).getParameters();
8
+
9
+ if (paramTypes.length === 0) {
10
+ throw new Error(`${target.constructor.name}.${propertyKey.toString()} should have one argument!`);
11
+ }
12
+
13
+ if (paramTypes.length > 1) {
14
+ throw new Error(`${target.constructor.name}.${propertyKey.toString()} should have only one argument!`);
15
+ }
16
+
17
+ if (!(paramTypes[0].prototype instanceof Event)) {
18
+ throw new Error(`${target.constructor.name}.${propertyKey.toString()} should have an event as argument!`);
19
+ }
20
+
21
+ reflect(target, propertyKey).registerEventHandler(<any>paramTypes[0].prototype, mode);
22
+ }
23
+ }
@@ -0,0 +1,2 @@
1
+ export * from './command-handler';
2
+ export * from './event-handler';
@@ -0,0 +1,5 @@
1
+ export * from './controller';
2
+ export * from './handler';
3
+ export * from './injectable';
4
+ export * from './module';
5
+ export * from './transactional-client';
@@ -0,0 +1,7 @@
1
+ import { reflect } from '../reflect';
2
+
3
+ export function Injectable(): ClassDecorator {
4
+ return target => {
5
+ reflect(target).registerInjectable();
6
+ };
7
+ }
@@ -0,0 +1,29 @@
1
+ import { Type } from '../interfaces';
2
+
3
+ export interface ModuleOptions {
4
+ /**
5
+ * Optional list of imported modules that export the providers which are
6
+ * required in this module.
7
+ */
8
+ imports?: Type[];
9
+ /**
10
+ * Optional list of controllers defined in this module which have to be
11
+ * instantiated.
12
+ */
13
+ controllers?: Type[];
14
+
15
+ /**
16
+ * Optional list of handlers defined in this module which have to be instantiated.
17
+ */
18
+ handlers?: Type[];
19
+ }
20
+
21
+ export function Module(options: ModuleOptions): ClassDecorator {
22
+ return target => {
23
+ for (const key in options) {
24
+ if (options.hasOwnProperty(key)) {
25
+ Reflect.defineMetadata(key, options[key], target);
26
+ }
27
+ }
28
+ };
29
+ }
@@ -0,0 +1,7 @@
1
+ import { reflect } from '../reflect';
2
+
3
+ export function TransactionalClient(): ClassDecorator {
4
+ return target => {
5
+ reflect(target).registerTransactionalClient();
6
+ };
7
+ }
package/src/event.ts ADDED
@@ -0,0 +1,43 @@
1
+ import { autoserializeAs, Document, guid } from '@my-devkit/core';
2
+
3
+ import { Aggregate } from './aggregate';
4
+ import { Context } from './context';
5
+
6
+ export abstract class Event implements Document {
7
+ public static counter = 0;
8
+ @autoserializeAs(String) public id: string = null;
9
+ @autoserializeAs(String) public _type: string = null;
10
+ @autoserializeAs(String) public _correlationId: string = null;
11
+ @autoserializeAs(String) public _aggregateType: string = null;
12
+ @autoserializeAs(String) public _aggregateId: string = null;
13
+ @autoserializeAs(String) public _publishedBy: string = null;
14
+ @autoserializeAs(String) private _publishedAt: string = null;
15
+
16
+ constructor() {
17
+ this.id = guid();
18
+ this._type = this.constructor.name;
19
+
20
+ this._correlationId = Context.correlationId;
21
+ this._publishedBy = Context.user ? Context.user.uid : null;
22
+ }
23
+
24
+ public beforePublish<A extends Aggregate>(aggregate: A): void {
25
+ this._aggregateId = aggregate.id;
26
+ this._aggregateType = aggregate._type;
27
+
28
+ this._publishedAt = this.getNow();
29
+ }
30
+
31
+ public get _path(): string {
32
+ return `/events/${this.id}`;
33
+ }
34
+
35
+ public get publishedAt(): Date {
36
+ return new Date(this._publishedAt.substr(0, 23) + 'Z');
37
+ }
38
+
39
+ private getNow(): string {
40
+ Event.counter++;
41
+ return (new Date()).toISOString().replace('Z', '.' + (('0'.repeat(9) + Event.counter).slice(-9))) + 'Z';
42
+ }
43
+ }
@@ -0,0 +1,4 @@
1
+ export enum ExecutionMode {
2
+ Synchronous = <any>'Synchronous',
3
+ Asynchronous = <any>'Asynchronous'
4
+ }