@magek/core 0.0.1

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 (195) hide show
  1. package/dist/authorizer.d.ts +7 -0
  2. package/dist/authorizer.js +35 -0
  3. package/dist/command-dispatcher.d.ts +8 -0
  4. package/dist/command-dispatcher.js +55 -0
  5. package/dist/core-concepts/data-migration/entities/data-migration-entity.d.ts +12 -0
  6. package/dist/core-concepts/data-migration/entities/data-migration-entity.js +37 -0
  7. package/dist/core-concepts/data-migration/events/data-migration-finished.d.ts +7 -0
  8. package/dist/core-concepts/data-migration/events/data-migration-finished.js +13 -0
  9. package/dist/core-concepts/data-migration/events/data-migration-started.d.ts +7 -0
  10. package/dist/core-concepts/data-migration/events/data-migration-started.js +13 -0
  11. package/dist/core-concepts/data-migration/events/entity-migrated.d.ts +9 -0
  12. package/dist/core-concepts/data-migration/events/entity-migrated.js +15 -0
  13. package/dist/core-concepts/touch-entity/events/entity-touched.d.ts +7 -0
  14. package/dist/core-concepts/touch-entity/events/entity-touched.js +13 -0
  15. package/dist/data-migrations.d.ts +8 -0
  16. package/dist/data-migrations.js +73 -0
  17. package/dist/decorators/command.d.ts +19 -0
  18. package/dist/decorators/command.js +47 -0
  19. package/dist/decorators/data-migration.d.ts +9 -0
  20. package/dist/decorators/data-migration.js +25 -0
  21. package/dist/decorators/entity.d.ts +32 -0
  22. package/dist/decorators/entity.js +100 -0
  23. package/dist/decorators/event-handler.d.ts +3 -0
  24. package/dist/decorators/event-handler.js +18 -0
  25. package/dist/decorators/event.d.ts +8 -0
  26. package/dist/decorators/event.js +22 -0
  27. package/dist/decorators/field-metadata-reader.d.ts +6 -0
  28. package/dist/decorators/field-metadata-reader.js +221 -0
  29. package/dist/decorators/global-error-handler.d.ts +2 -0
  30. package/dist/decorators/global-error-handler.js +15 -0
  31. package/dist/decorators/global-event-handler.d.ts +3 -0
  32. package/dist/decorators/global-event-handler.js +9 -0
  33. package/dist/decorators/health-sensor.d.ts +14 -0
  34. package/dist/decorators/health-sensor.js +38 -0
  35. package/dist/decorators/index.d.ts +16 -0
  36. package/dist/decorators/index.js +19 -0
  37. package/dist/decorators/metadata.d.ts +13 -0
  38. package/dist/decorators/metadata.js +55 -0
  39. package/dist/decorators/non-exposed.d.ts +2 -0
  40. package/dist/decorators/non-exposed.js +24 -0
  41. package/dist/decorators/notification.d.ts +35 -0
  42. package/dist/decorators/notification.js +94 -0
  43. package/dist/decorators/projects.d.ts +32 -0
  44. package/dist/decorators/projects.js +87 -0
  45. package/dist/decorators/query.d.ts +2 -0
  46. package/dist/decorators/query.js +25 -0
  47. package/dist/decorators/read-model.d.ts +39 -0
  48. package/dist/decorators/read-model.js +129 -0
  49. package/dist/decorators/role.d.ts +6 -0
  50. package/dist/decorators/role.js +15 -0
  51. package/dist/decorators/scheduled-command.d.ts +9 -0
  52. package/dist/decorators/scheduled-command.js +25 -0
  53. package/dist/decorators/schema-migration.d.ts +36 -0
  54. package/dist/decorators/schema-migration.js +146 -0
  55. package/dist/decorators/sequenced-by.d.ts +28 -0
  56. package/dist/decorators/sequenced-by.js +79 -0
  57. package/dist/decorators/stage3-utils.d.ts +6 -0
  58. package/dist/decorators/stage3-utils.js +25 -0
  59. package/dist/delete-event-dispatcher.d.ts +4 -0
  60. package/dist/delete-event-dispatcher.js +23 -0
  61. package/dist/event-dispatcher.d.ts +9 -0
  62. package/dist/event-dispatcher.js +37 -0
  63. package/dist/event-processor.d.ts +15 -0
  64. package/dist/event-processor.js +125 -0
  65. package/dist/event-search.d.ts +2 -0
  66. package/dist/event-search.js +26 -0
  67. package/dist/event-stream-consumer.d.ts +7 -0
  68. package/dist/event-stream-consumer.js +36 -0
  69. package/dist/event-stream-producer.d.ts +7 -0
  70. package/dist/event-stream-producer.js +30 -0
  71. package/dist/events-reader.d.ts +11 -0
  72. package/dist/events-reader.js +63 -0
  73. package/dist/global-error-dispatcher.d.ts +16 -0
  74. package/dist/global-error-dispatcher.js +109 -0
  75. package/dist/graphql-dispatcher.d.ts +16 -0
  76. package/dist/graphql-dispatcher.js +195 -0
  77. package/dist/importer.d.ts +14 -0
  78. package/dist/importer.js +49 -0
  79. package/dist/index.d.ts +60 -0
  80. package/dist/index.js +100 -0
  81. package/dist/injectable/index.d.ts +21 -0
  82. package/dist/injectable/index.js +2 -0
  83. package/dist/instrumentation/decorator/trace.d.ts +13 -0
  84. package/dist/instrumentation/decorator/trace.js +116 -0
  85. package/dist/instrumentation/index.d.ts +2 -0
  86. package/dist/instrumentation/index.js +5 -0
  87. package/dist/instrumentation/trace-notifier.d.ts +3 -0
  88. package/dist/instrumentation/trace-notifier.js +26 -0
  89. package/dist/magek.d.ts +42 -0
  90. package/dist/magek.js +158 -0
  91. package/dist/query-dispatcher.d.ts +8 -0
  92. package/dist/query-dispatcher.js +47 -0
  93. package/dist/read-model-schema-migrator.d.ts +14 -0
  94. package/dist/read-model-schema-migrator.js +80 -0
  95. package/dist/read-models-reader.d.ts +31 -0
  96. package/dist/read-models-reader.js +196 -0
  97. package/dist/register-handler.d.ts +11 -0
  98. package/dist/register-handler.js +95 -0
  99. package/dist/rocket-dispatcher.d.ts +6 -0
  100. package/dist/rocket-dispatcher.js +21 -0
  101. package/dist/scheduled-command-dispatcher.d.ts +12 -0
  102. package/dist/scheduled-command-dispatcher.js +54 -0
  103. package/dist/schema-migrator.d.ts +12 -0
  104. package/dist/schema-migrator.js +71 -0
  105. package/dist/sensor/health/health-indicators/database-events-health-indicator.d.ts +5 -0
  106. package/dist/sensor/health/health-indicators/database-events-health-indicator.js +26 -0
  107. package/dist/sensor/health/health-indicators/database-health-indicator.d.ts +5 -0
  108. package/dist/sensor/health/health-indicators/database-health-indicator.js +29 -0
  109. package/dist/sensor/health/health-indicators/database-read-models-health-indicator.d.ts +5 -0
  110. package/dist/sensor/health/health-indicators/database-read-models-health-indicator.js +26 -0
  111. package/dist/sensor/health/health-indicators/default-health-indicators.d.ts +5 -0
  112. package/dist/sensor/health/health-indicators/default-health-indicators.js +39 -0
  113. package/dist/sensor/health/health-indicators/function-health-indicator.d.ts +5 -0
  114. package/dist/sensor/health/health-indicators/function-health-indicator.js +30 -0
  115. package/dist/sensor/health/health-indicators/health-indicator.d.ts +5 -0
  116. package/dist/sensor/health/health-indicators/health-indicator.js +30 -0
  117. package/dist/sensor/health/health-indicators/index.d.ts +3 -0
  118. package/dist/sensor/health/health-indicators/index.js +6 -0
  119. package/dist/sensor/health/health-indicators/os-info.d.ts +14 -0
  120. package/dist/sensor/health/health-indicators/os-info.js +38 -0
  121. package/dist/sensor/health/health-indicators/rockets-health-indicator.d.ts +5 -0
  122. package/dist/sensor/health/health-indicators/rockets-health-indicator.js +57 -0
  123. package/dist/sensor/health/health-indicators/version.d.ts +2 -0
  124. package/dist/sensor/health/health-indicators/version.js +24 -0
  125. package/dist/sensor/health/health-service.d.ts +22 -0
  126. package/dist/sensor/health/health-service.js +117 -0
  127. package/dist/sensor/health/health-utils.d.ts +7 -0
  128. package/dist/sensor/health/health-utils.js +53 -0
  129. package/dist/sensor/health/index.d.ts +3 -0
  130. package/dist/sensor/health/index.js +6 -0
  131. package/dist/sensor/index.d.ts +1 -0
  132. package/dist/sensor/index.js +4 -0
  133. package/dist/services/event-store.d.ts +27 -0
  134. package/dist/services/event-store.js +260 -0
  135. package/dist/services/filter-helpers.d.ts +3 -0
  136. package/dist/services/filter-helpers.js +19 -0
  137. package/dist/services/graphql/common.d.ts +26 -0
  138. package/dist/services/graphql/common.js +53 -0
  139. package/dist/services/graphql/graphql-generator.d.ts +46 -0
  140. package/dist/services/graphql/graphql-generator.js +269 -0
  141. package/dist/services/graphql/graphql-mutation-generator.d.ts +12 -0
  142. package/dist/services/graphql/graphql-mutation-generator.js +25 -0
  143. package/dist/services/graphql/graphql-query-generator.d.ts +22 -0
  144. package/dist/services/graphql/graphql-query-generator.js +39 -0
  145. package/dist/services/graphql/graphql-subcriptions-generator.d.ts +17 -0
  146. package/dist/services/graphql/graphql-subcriptions-generator.js +60 -0
  147. package/dist/services/graphql/graphql-type-informer.d.ts +23 -0
  148. package/dist/services/graphql/graphql-type-informer.js +160 -0
  149. package/dist/services/graphql/query-generators/graphql-query-by-keys-generator.d.ts +14 -0
  150. package/dist/services/graphql/query-generators/graphql-query-by-keys-generator.js +48 -0
  151. package/dist/services/graphql/query-generators/graphql-query-events-generator.d.ts +11 -0
  152. package/dist/services/graphql/query-generators/graphql-query-events-generator.js +68 -0
  153. package/dist/services/graphql/query-generators/graphql-query-filters-generator.d.ts +14 -0
  154. package/dist/services/graphql/query-generators/graphql-query-filters-generator.js +31 -0
  155. package/dist/services/graphql/query-generators/graphql-query-generator.d.ts +12 -0
  156. package/dist/services/graphql/query-generators/graphql-query-generator.js +17 -0
  157. package/dist/services/graphql/query-generators/graphql-query-listed-generator.d.ts +16 -0
  158. package/dist/services/graphql/query-generators/graphql-query-listed-generator.js +65 -0
  159. package/dist/services/graphql/query-helpers/graphql-handled-fields-generator.d.ts +15 -0
  160. package/dist/services/graphql/query-helpers/graphql-handled-fields-generator.js +65 -0
  161. package/dist/services/graphql/query-helpers/graphql-query-filter-arguments-builder.d.ts +13 -0
  162. package/dist/services/graphql/query-helpers/graphql-query-filter-arguments-builder.js +169 -0
  163. package/dist/services/graphql/query-helpers/graphql-query-filter-fields-builder.d.ts +11 -0
  164. package/dist/services/graphql/query-helpers/graphql-query-filter-fields-builder.js +28 -0
  165. package/dist/services/graphql/query-helpers/graphql-query-sort-builder.d.ts +12 -0
  166. package/dist/services/graphql/query-helpers/graphql-query-sort-builder.js +61 -0
  167. package/dist/services/graphql/websocket-protocol/graphql-websocket-protocol.d.ts +20 -0
  168. package/dist/services/graphql/websocket-protocol/graphql-websocket-protocol.js +127 -0
  169. package/dist/services/pub-sub/noop-read-model-pub-sub.d.ts +5 -0
  170. package/dist/services/pub-sub/noop-read-model-pub-sub.js +10 -0
  171. package/dist/services/pub-sub/read-model-pub-sub.d.ts +9 -0
  172. package/dist/services/pub-sub/read-model-pub-sub.js +112 -0
  173. package/dist/services/raw-events-parser.d.ts +5 -0
  174. package/dist/services/raw-events-parser.js +44 -0
  175. package/dist/services/read-model-searcher.d.ts +2 -0
  176. package/dist/services/read-model-searcher.js +11 -0
  177. package/dist/services/read-model-store.d.ts +41 -0
  178. package/dist/services/read-model-store.js +295 -0
  179. package/dist/services/token-verifiers/index.d.ts +4 -0
  180. package/dist/services/token-verifiers/index.js +7 -0
  181. package/dist/services/token-verifiers/jwks-uri-token-verifier.d.ts +21 -0
  182. package/dist/services/token-verifiers/jwks-uri-token-verifier.js +23 -0
  183. package/dist/services/token-verifiers/public-key-token-verifier.d.ts +13 -0
  184. package/dist/services/token-verifiers/public-key-token-verifier.js +19 -0
  185. package/dist/services/token-verifiers/role-based-token-verifier.d.ts +8 -0
  186. package/dist/services/token-verifiers/role-based-token-verifier.js +35 -0
  187. package/dist/services/token-verifiers/utilities.d.ts +31 -0
  188. package/dist/services/token-verifiers/utilities.js +70 -0
  189. package/dist/subscribers-notifier.d.ts +14 -0
  190. package/dist/subscribers-notifier.js +109 -0
  191. package/dist/token-verifier.d.ts +11 -0
  192. package/dist/token-verifier.js +46 -0
  193. package/dist/touch-entity-handler.d.ts +4 -0
  194. package/dist/touch-entity-handler.js +16 -0
  195. package/package.json +71 -0
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GraphqlQuerySortBuilder = void 0;
4
+ const graphql_1 = require("graphql");
5
+ const metadata_1 = require("../../../decorators/metadata");
6
+ const common_1 = require("../common");
7
+ class GraphqlQuerySortBuilder {
8
+ constructor(typeInformer, config) {
9
+ this.typeInformer = typeInformer;
10
+ this.config = config;
11
+ this.generatedSortByByTypeName = {};
12
+ this.orderType = (0, common_1.buildGraphqlSimpleEnumFor)('orderProperty', ['ASC', 'DESC']);
13
+ }
14
+ generateSortArguments(type, excludeProps) {
15
+ const metadata = (0, metadata_1.getClassMetadata)(type);
16
+ const args = {};
17
+ const finalFields = (0, common_1.nonExcludedFields)(metadata.fields, excludeProps);
18
+ finalFields
19
+ .filter((field) => !field.typeInfo.isGetAccessor)
20
+ .forEach((prop) => {
21
+ args[prop.name] = {
22
+ type: this.generateSortFor(prop),
23
+ };
24
+ });
25
+ return args;
26
+ }
27
+ generateSortFor(prop) {
28
+ let sortByName = `${prop.typeInfo.name}PropertySortBy`;
29
+ sortByName = sortByName.charAt(0).toUpperCase() + sortByName.substring(1).replace(/\[]/g, '');
30
+ if (this.generatedSortByByTypeName[sortByName])
31
+ return this.generatedSortByByTypeName[sortByName];
32
+ if (!prop.typeInfo.type || typeof prop.typeInfo.type === 'object')
33
+ return this.orderType;
34
+ if (prop.typeInfo.typeGroup === 'Array')
35
+ return this.orderType;
36
+ if (prop.typeInfo.name === 'UUID' || prop.typeInfo.name === 'Date')
37
+ return this.orderType;
38
+ let fields = {};
39
+ if (prop.typeInfo.type && prop.typeInfo.typeGroup === 'Class') {
40
+ if ((0, common_1.isExternalType)(prop.typeInfo))
41
+ return this.orderType;
42
+ let nestedProperties = {};
43
+ const metadata = (0, metadata_1.getClassMetadata)(prop.typeInfo.type);
44
+ if (metadata.fields.length === 0)
45
+ return this.orderType;
46
+ const excludeProps = this.config.nonExposedGraphQLMetadataKey[prop.name];
47
+ this.typeInformer.generateGraphQLTypeForClass(prop.typeInfo.type, excludeProps, true);
48
+ for (const prop of metadata.fields) {
49
+ const property = { [prop.name]: { type: this.generateSortFor(prop) } };
50
+ nestedProperties = { ...nestedProperties, ...property };
51
+ }
52
+ fields = () => ({
53
+ ...nestedProperties,
54
+ });
55
+ this.generatedSortByByTypeName[sortByName] = new graphql_1.GraphQLInputObjectType({ name: sortByName, fields });
56
+ return this.generatedSortByByTypeName[sortByName];
57
+ }
58
+ return this.orderType;
59
+ }
60
+ }
61
+ exports.GraphqlQuerySortBuilder = GraphqlQuerySortBuilder;
@@ -0,0 +1,20 @@
1
+ import { ExecutionResult } from 'graphql';
2
+ import { MagekConfig, GraphQLRequestEnvelope, GraphQLRequestEnvelopeError } from '@magek/common';
3
+ import { MagekTokenVerifier } from '../../../token-verifier';
4
+ export interface GraphQLWebsocketHandlerCallbacks {
5
+ onStartOperation: (envelope: GraphQLRequestEnvelope) => Promise<AsyncIterableIterator<ExecutionResult> | ExecutionResult>;
6
+ onStopOperation: (connectionID: string, messageID: string) => Promise<void>;
7
+ onTerminate: (connectionID: string) => Promise<void>;
8
+ }
9
+ export declare class GraphQLWebsocketHandler {
10
+ private readonly config;
11
+ private readonly callbacks;
12
+ private readonly tokenVerifier;
13
+ constructor(config: MagekConfig, callbacks: GraphQLWebsocketHandlerCallbacks, tokenVerifier: MagekTokenVerifier);
14
+ handle(envelope: GraphQLRequestEnvelope | GraphQLRequestEnvelopeError): Promise<void>;
15
+ private handleInit;
16
+ private handleStart;
17
+ private augmentEnvelope;
18
+ private handleStop;
19
+ private handleTerminate;
20
+ }
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GraphQLWebsocketHandler = void 0;
4
+ const common_1 = require("@magek/common");
5
+ class GraphQLWebsocketHandler {
6
+ constructor(config, callbacks, tokenVerifier) {
7
+ this.config = config;
8
+ this.callbacks = callbacks;
9
+ this.tokenVerifier = tokenVerifier;
10
+ }
11
+ async handle(envelope) {
12
+ const logger = (0, common_1.getLogger)(this.config, 'GraphQLWebsocketHandler#handle');
13
+ if (!envelope.connectionID) {
14
+ // Impossible case, but just to be sure. The only thing we can do here is to log, as we don't have the connection
15
+ // to send the message to
16
+ logger.error('Missing websocket connectionID');
17
+ return;
18
+ }
19
+ try {
20
+ logger.debug('Handling websocket message');
21
+ if ('error' in envelope) {
22
+ throw envelope.error;
23
+ }
24
+ if (!envelope.value) {
25
+ throw new Error('Received an empty GraphQL body');
26
+ }
27
+ const clientMessage = envelope.value;
28
+ logger.debug('Received client message: ', clientMessage);
29
+ switch (clientMessage.type) {
30
+ case common_1.MessageTypes.GQL_CONNECTION_INIT:
31
+ return await this.handleInit(envelope.connectionID, clientMessage);
32
+ case common_1.MessageTypes.GQL_START:
33
+ return await this.handleStart(envelope.connectionID, envelope, clientMessage);
34
+ case common_1.MessageTypes.GQL_STOP:
35
+ return await this.handleStop(envelope.connectionID, clientMessage);
36
+ case common_1.MessageTypes.GQL_CONNECTION_TERMINATE:
37
+ return await this.handleTerminate(envelope.connectionID);
38
+ default:
39
+ // This branch should be impossible, but just in case
40
+ throw new Error(`Unknown message type. Message=${clientMessage}`);
41
+ }
42
+ }
43
+ catch (e) {
44
+ const error = e;
45
+ logger.error(e);
46
+ await this.config.provider.messaging.sendMessage(this.config, envelope.connectionID, new common_1.GraphQLInitError(error.message));
47
+ }
48
+ }
49
+ async handleInit(connectionID, clientMessage) {
50
+ var _a;
51
+ const logger = (0, common_1.getLogger)(this.config, 'GraphQLWebsocketHandler#handleInit');
52
+ let userEnvelope;
53
+ if ((_a = clientMessage.payload) === null || _a === void 0 ? void 0 : _a.Authorization) {
54
+ userEnvelope = await this.tokenVerifier.verify(clientMessage.payload.Authorization);
55
+ }
56
+ const nowEpoch = Math.floor(new Date().getTime() / 1000);
57
+ const connectionData = {
58
+ expirationTime: nowEpoch + this.config.subscriptions.maxConnectionDurationInSeconds,
59
+ user: userEnvelope,
60
+ };
61
+ logger.debug('Storing connection data: ', connectionData);
62
+ await this.config.sessionStore.storeConnection(this.config, connectionID, connectionData);
63
+ logger.debug('Sending ACK');
64
+ await this.config.provider.messaging.sendMessage(this.config, connectionID, new common_1.GraphQLInitAck());
65
+ }
66
+ async handleStart(connectionID, envelope, message) {
67
+ const logger = (0, common_1.getLogger)(this.config, 'GraphQLWebsocketHandler#handleStart');
68
+ if (!message.id) {
69
+ throw new Error(`Missing "id" in ${message.type} message`);
70
+ }
71
+ if (!message.payload || !message.payload.query) {
72
+ await this.config.provider.messaging.sendMessage(this.config, connectionID, new common_1.GraphQLError(message.id, {
73
+ errors: [new Error('Message payload is invalid it must contain at least the "query" property')],
74
+ }));
75
+ return;
76
+ }
77
+ const augmentedEnvelope = await this.augmentEnvelope(connectionID, envelope, message);
78
+ logger.debug('Executing operation. Envelope: ', augmentedEnvelope);
79
+ const result = await this.callbacks.onStartOperation(augmentedEnvelope);
80
+ if ('next' in result) {
81
+ logger.debug('Subscription finished.');
82
+ return; // It was a subscription. We don't need to send any data
83
+ }
84
+ logger.debug('Operation finished. Sending DATA:', result);
85
+ // It was a query or mutation. We send data and complete the operation
86
+ await this.config.provider.messaging.sendMessage(this.config, connectionID, new common_1.GraphQLData(message.id, result));
87
+ await this.config.provider.messaging.sendMessage(this.config, connectionID, new common_1.GraphQLComplete(message.id));
88
+ }
89
+ async augmentEnvelope(connectionID, envelope, message) {
90
+ const logger = (0, common_1.getLogger)(this.config, 'GraphQLWebsocketHandler#augmentEnvelope');
91
+ const connectionData = await this.config.sessionStore.fetchConnection(this.config, connectionID);
92
+ logger.debug('Found connection data: ', connectionData);
93
+ return {
94
+ ...envelope,
95
+ currentUser: connectionData === null || connectionData === void 0 ? void 0 : connectionData.user,
96
+ value: {
97
+ ...message.payload,
98
+ id: message.id,
99
+ },
100
+ };
101
+ }
102
+ async handleStop(connectionID, message) {
103
+ const logger = (0, common_1.getLogger)(this.config, 'GraphQLWebsocketHandler#handleStop');
104
+ if (!message.id) {
105
+ throw new Error(`Missing "id" in ${message.type} message`);
106
+ }
107
+ logger.debug('Executing stop operation');
108
+ await this.callbacks.onStopOperation(connectionID, message.id);
109
+ logger.debug('Stop operation finished');
110
+ try {
111
+ await this.config.provider.messaging.sendMessage(this.config, connectionID, new common_1.GraphQLComplete(message.id));
112
+ }
113
+ catch (e) {
114
+ // It could be the case that the client already closed the connection without waiting for stop operation to finish
115
+ // Log this but ignore it
116
+ logger.info(`Received an exception while sending the "complete" message after stopping the GraphQL operation with id ${message.id}.` +
117
+ 'The client probably closed the connection. Ignoring. ', e);
118
+ }
119
+ }
120
+ async handleTerminate(connectionID) {
121
+ const logger = (0, common_1.getLogger)(this.config, 'GraphQLWebsocketHandler#handleTerminate');
122
+ logger.debug('Executing terminate operation');
123
+ await this.callbacks.onTerminate(connectionID);
124
+ logger.debug('Terminate operation finished');
125
+ }
126
+ }
127
+ exports.GraphQLWebsocketHandler = GraphQLWebsocketHandler;
@@ -0,0 +1,5 @@
1
+ import { ReadModelRequestEnvelope, ReadModelInterface } from '@magek/common';
2
+ import { ReadModelPubSub } from './read-model-pub-sub';
3
+ export declare class NoopReadModelPubSub implements ReadModelPubSub<ReadModelInterface> {
4
+ asyncIterator(_: ReadModelRequestEnvelope<ReadModelInterface>): Promise<AsyncIterator<ReadModelInterface>>;
5
+ }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NoopReadModelPubSub = void 0;
4
+ const iterall_1 = require("iterall");
5
+ class NoopReadModelPubSub {
6
+ async asyncIterator(_) {
7
+ return (0, iterall_1.createAsyncIterator)([]);
8
+ }
9
+ }
10
+ exports.NoopReadModelPubSub = NoopReadModelPubSub;
@@ -0,0 +1,9 @@
1
+ import { ReadModelRequestEnvelope, ReadModelInterface, Instance, MagekConfig } from '@magek/common';
2
+ export interface ReadModelPubSub<TReadModel extends ReadModelInterface> {
3
+ asyncIterator(readModelRequestEnvelope: ReadModelRequestEnvelope<TReadModel>, config: MagekConfig): Promise<AsyncIterator<ReadModelInterface>>;
4
+ }
5
+ export declare class FilteredReadModelPubSub<TReadModel extends ReadModelInterface> implements ReadModelPubSub<TReadModel> {
6
+ private readModels;
7
+ constructor(readModels: Array<ReadModelInterface & Instance>);
8
+ asyncIterator(readModelRequestEnvelope: ReadModelRequestEnvelope<TReadModel>, config: MagekConfig): Promise<AsyncIterator<ReadModelInterface>>;
9
+ }
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FilteredReadModelPubSub = void 0;
4
+ const iterall_1 = require("iterall");
5
+ const filter_helpers_1 = require("../filter-helpers");
6
+ class FilteredReadModelPubSub {
7
+ constructor(readModels) {
8
+ this.readModels = readModels;
9
+ }
10
+ async asyncIterator(readModelRequestEnvelope, config) {
11
+ const readModelMetadata = config.readModels[readModelRequestEnvelope.class.name];
12
+ const newReadModelRequestEnvelope = await (0, filter_helpers_1.applyReadModelRequestBeforeFunctions)(readModelRequestEnvelope, readModelMetadata.before, readModelRequestEnvelope.currentUser);
13
+ return (0, iterall_1.createAsyncIterator)(this.readModels
14
+ .filter((readModel) => newReadModelRequestEnvelope.class.name == readModel.constructor.name)
15
+ .filter((readModel) => filterReadModel(readModel, newReadModelRequestEnvelope.filters)));
16
+ }
17
+ }
18
+ exports.FilteredReadModelPubSub = FilteredReadModelPubSub;
19
+ function filterReadModel(readModel, filters) {
20
+ for (const filteredProp in filters) {
21
+ const readModelPropValue = readModel[filteredProp];
22
+ return filterByOperation(filters[filteredProp], readModelPropValue);
23
+ }
24
+ return true;
25
+ }
26
+ function filterByOperation(filter, readModelPropValue) {
27
+ for (const [operation, value] of Object.entries(filter)) {
28
+ switch (operation) {
29
+ case 'eq':
30
+ if (readModelPropValue !== value)
31
+ return false;
32
+ break;
33
+ case 'ne':
34
+ if (readModelPropValue === value)
35
+ return false;
36
+ break;
37
+ case 'lt':
38
+ if (readModelPropValue >= value)
39
+ return false;
40
+ break;
41
+ case 'gt':
42
+ if (readModelPropValue <= value)
43
+ return false;
44
+ break;
45
+ case 'gte':
46
+ if (readModelPropValue < value)
47
+ return false;
48
+ break;
49
+ case 'lte':
50
+ if (readModelPropValue > value)
51
+ return false;
52
+ break;
53
+ case 'in':
54
+ if (!value.includes(readModelPropValue))
55
+ return false;
56
+ break;
57
+ case 'contains':
58
+ if (!contains(readModelPropValue, value))
59
+ return false;
60
+ break;
61
+ case 'beginsWith':
62
+ if (!beginWith(readModelPropValue, value))
63
+ return false;
64
+ break;
65
+ case 'includes':
66
+ return includes(readModelPropValue, value);
67
+ case 'regex':
68
+ if (!regex(readModelPropValue, value))
69
+ return false;
70
+ break;
71
+ case 'iRegex':
72
+ if (!regex(readModelPropValue, value, 'i'))
73
+ return false;
74
+ break;
75
+ default:
76
+ if (typeof value === 'object') {
77
+ return filterByOperation(value, readModelPropValue[operation]);
78
+ }
79
+ }
80
+ }
81
+ return true;
82
+ }
83
+ function regex(readModelPropValue, element, flags) {
84
+ if (!Array.isArray(readModelPropValue) && typeof readModelPropValue === 'string') {
85
+ const expression = new RegExp(element, flags);
86
+ return expression.test(readModelPropValue);
87
+ }
88
+ return false;
89
+ }
90
+ function contains(readModelPropValue, element) {
91
+ if (Array.isArray(readModelPropValue) || typeof readModelPropValue === 'string') {
92
+ return readModelPropValue.includes(element);
93
+ }
94
+ return false;
95
+ }
96
+ function beginWith(readModelPropValue, element) {
97
+ if (typeof readModelPropValue === 'string') {
98
+ return readModelPropValue.startsWith(element);
99
+ }
100
+ return false;
101
+ }
102
+ function includes(readModelPropValue, element) {
103
+ if (Array.isArray(readModelPropValue)) {
104
+ // Check that array includes an object
105
+ if (typeof element === 'object') {
106
+ return readModelPropValue.some((item) => Object.keys(element).every((key) => item[key] === element[key]));
107
+ }
108
+ // If not, do a regular includes
109
+ return readModelPropValue.includes(element);
110
+ }
111
+ return false;
112
+ }
@@ -0,0 +1,5 @@
1
+ import { MagekConfig, EventEnvelope, UUID } from '@magek/common';
2
+ export type EventsStreamingCallback = (entityName: string, entityID: UUID, eventEnvelopes: Array<EventEnvelope>, config: MagekConfig) => Promise<void>;
3
+ export declare class RawEventsParser {
4
+ static streamPerEntityEvents(config: MagekConfig, eventEnvelopes: Array<EventEnvelope>, callbackFn: EventsStreamingCallback): Promise<void>;
5
+ }
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RawEventsParser = void 0;
4
+ const common_1 = require("@magek/common");
5
+ class RawEventsParser {
6
+ static async streamPerEntityEvents(config, eventEnvelopes, callbackFn) {
7
+ const logger = (0, common_1.getLogger)(config, 'RawEventsParser#streamPerEntityEvents');
8
+ const eventEnvelopesPerEntity = eventEnvelopes
9
+ .filter(isEventKind)
10
+ .filter(isNotDeleted)
11
+ .reduce(groupByEntity, {});
12
+ const processes = Object.values(eventEnvelopesPerEntity).map(async (entityEnvelopes) => {
13
+ // All envelopes are for the same entity type/ID, so we get the first one to get those values
14
+ if (!entityEnvelopes[0]) {
15
+ throw new Error('The impossible happened: Attempted to process a non existent event');
16
+ }
17
+ const { entityTypeName, entityID } = entityEnvelopes[0];
18
+ logger.debug(`Streaming the following events for entity '${entityTypeName}' and ID '${entityID}':`, entityEnvelopes);
19
+ try {
20
+ await callbackFn(entityTypeName, entityID, entityEnvelopes, config);
21
+ }
22
+ catch (e) {
23
+ logger.error(`An error occurred while processing events for entity ${entityTypeName} with ID ${entityID}`, e);
24
+ }
25
+ });
26
+ // We use allSettled because we don't care if some of the processes fail
27
+ await Promise.allSettled(processes);
28
+ }
29
+ }
30
+ exports.RawEventsParser = RawEventsParser;
31
+ function isEventKind(envelope) {
32
+ return envelope.kind == 'event';
33
+ }
34
+ function isNotDeleted(envelope) {
35
+ return !(envelope === null || envelope === void 0 ? void 0 : envelope.deletedAt);
36
+ }
37
+ function groupByEntity(envelopesPerEntity, envelope) {
38
+ const entityKey = `${envelope.entityTypeName}-${envelope.entityID}`;
39
+ if (!envelopesPerEntity[entityKey]) {
40
+ envelopesPerEntity[entityKey] = [];
41
+ }
42
+ envelopesPerEntity[entityKey].push(envelope);
43
+ return envelopesPerEntity;
44
+ }
@@ -0,0 +1,2 @@
1
+ import { MagekConfig, Class, ReadModelInterface, Searcher } from '@magek/common';
2
+ export declare function readModelSearcher<TReadModel extends ReadModelInterface>(config: MagekConfig, readModelClass: Class<TReadModel>): Searcher<TReadModel>;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readModelSearcher = readModelSearcher;
4
+ const common_1 = require("@magek/common");
5
+ const read_models_reader_1 = require("../read-models-reader");
6
+ function readModelSearcher(config, readModelClass) {
7
+ const readModelsReader = new read_models_reader_1.MagekReadModelsReader(config);
8
+ const searcherFunction = readModelsReader.readModelSearch.bind(readModelsReader);
9
+ const finderByIdFunction = readModelsReader.finderByIdFunction.bind(readModelsReader);
10
+ return new common_1.Searcher(readModelClass, searcherFunction, finderByIdFunction);
11
+ }
@@ -0,0 +1,41 @@
1
+ import { MagekConfig, EntityInterface, EntityMetadata, EntitySnapshotEnvelope, ProjectionMetadata, ReadModelInterface, SequenceKey, UUID } from '@magek/common';
2
+ export declare class ReadModelStore {
3
+ readonly config: MagekConfig;
4
+ constructor(config: MagekConfig);
5
+ project(entitySnapshotEnvelope: EntitySnapshotEnvelope, deleteEvent?: boolean): Promise<void>;
6
+ /**
7
+ * Gets the read models for a given entity instance using the projection metadata
8
+ * @param {EntityInterface} entityInstance The entity instance to get the read models for
9
+ * @param {ProjectionMetadata<EntityInterface, ReadModelInterface>} projectionMetadata The projection metadata to use to get the read models
10
+ * @param {EntityMetadata} entityMetadata The entity metadata for the entity instance
11
+ * @returns {Promise<Array<ReadModelInterface>>} The read models for the entity instance
12
+ */
13
+ getReadModels(entityInstance: EntityInterface, projectionMetadata: ProjectionMetadata<EntityInterface, ReadModelInterface>, entityMetadata: EntityMetadata): Promise<Array<ReadModelInterface>>;
14
+ /**
15
+ * Gets a specific read model instance referencing it by ID when it's a regular read model
16
+ * or by ID + sequenceKey when it's a sequenced read model
17
+ * @param {string} readModelName The name of the read model class
18
+ * @param {UUID | undefined} readModelID The ID of the read model instance
19
+ * @param {SequenceKey} sequenceKey The sequence key of the read model instance
20
+ * @returns {Promise<ReadModelInterface | undefined>} The read model instance or undefined if it doesn't exist
21
+ */
22
+ fetchReadModel(readModelName: string, readModelID: UUID | undefined, sequenceKey?: SequenceKey): Promise<ReadModelInterface | undefined>;
23
+ getProjectionFunction(projectionMetadata: ProjectionMetadata<EntityInterface, ReadModelInterface>): Function;
24
+ private getUnProjections;
25
+ private entityProjections;
26
+ private entityUnProjections;
27
+ private findFirstMissingProjection;
28
+ private someProjection;
29
+ private sequenceKeyForProjection;
30
+ private projectEntity;
31
+ private projectionsForReadModels;
32
+ private projectAndStoreReadModelWithRetry;
33
+ private instanceReadModels;
34
+ private applyProjectionToReadModel;
35
+ private store;
36
+ private callProjectionFunction;
37
+ private filterForProjection;
38
+ private filterForEntityProjection;
39
+ private filterForReadModelProjection;
40
+ private isJoinKeyByEntity;
41
+ }