@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,7 @@
1
+ import { Class, UserEnvelope, RoleInterface, QueryAuthorizer, CommandRoleAccess, QueryRoleAccess, ReadModelRoleAccess, CommandAuthorizer, ReadModelAuthorizer, HealthRoleAccess, HealthAuthorizer } from '@magek/common';
2
+ export declare class MagekAuthorizer {
3
+ static allowAccess(): Promise<void>;
4
+ static denyAccess(): Promise<void>;
5
+ static authorizeRoles(authorizedRoles: Array<Class<RoleInterface>>, user?: UserEnvelope): Promise<void>;
6
+ static build(attributes: CommandRoleAccess | QueryRoleAccess | ReadModelRoleAccess | HealthRoleAccess): CommandAuthorizer | QueryAuthorizer | ReadModelAuthorizer | HealthAuthorizer;
7
+ }
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MagekAuthorizer = void 0;
4
+ const common_1 = require("@magek/common");
5
+ class MagekAuthorizer {
6
+ static allowAccess() {
7
+ return Promise.resolve();
8
+ }
9
+ static denyAccess() {
10
+ return Promise.reject(new common_1.NotAuthorizedError('Access denied for this resource'));
11
+ }
12
+ static authorizeRoles(authorizedRoles, user) {
13
+ if (user && userHasSomeRole(user, authorizedRoles)) {
14
+ return MagekAuthorizer.allowAccess();
15
+ }
16
+ return MagekAuthorizer.denyAccess();
17
+ }
18
+ static build(attributes) {
19
+ let authorizer = MagekAuthorizer.denyAccess;
20
+ if (attributes.authorize === 'all') {
21
+ authorizer = MagekAuthorizer.allowAccess;
22
+ }
23
+ else if (Array.isArray(attributes.authorize)) {
24
+ authorizer = MagekAuthorizer.authorizeRoles.bind(null, attributes.authorize);
25
+ }
26
+ else if (typeof attributes.authorize === 'function') {
27
+ authorizer = attributes.authorize;
28
+ }
29
+ return authorizer;
30
+ }
31
+ }
32
+ exports.MagekAuthorizer = MagekAuthorizer;
33
+ function userHasSomeRole(user, authorizedRoles) {
34
+ return authorizedRoles.some((roleClass) => { var _a; return (_a = user.roles) === null || _a === void 0 ? void 0 : _a.includes(roleClass.name); });
35
+ }
@@ -0,0 +1,8 @@
1
+ import { MagekConfig, CommandEnvelope } from '@magek/common';
2
+ import { GraphQLResolverContext } from './services/graphql/common';
3
+ export declare class MagekCommandDispatcher {
4
+ readonly config: MagekConfig;
5
+ private readonly globalErrorDispatcher;
6
+ constructor(config: MagekConfig);
7
+ dispatchCommand(commandEnvelope: CommandEnvelope, context: GraphQLResolverContext): Promise<unknown>;
8
+ }
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MagekCommandDispatcher = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const common_1 = require("@magek/common");
6
+ const register_handler_1 = require("./register-handler");
7
+ const filter_helpers_1 = require("./services/filter-helpers");
8
+ const global_error_dispatcher_1 = require("./global-error-dispatcher");
9
+ const schema_migrator_1 = require("./schema-migrator");
10
+ const instrumentation_1 = require("./instrumentation");
11
+ class MagekCommandDispatcher {
12
+ constructor(config) {
13
+ this.config = config;
14
+ this.globalErrorDispatcher = new global_error_dispatcher_1.MagekGlobalErrorDispatcher(config);
15
+ }
16
+ async dispatchCommand(commandEnvelope, context) {
17
+ const logger = (0, common_1.getLogger)(this.config, 'MagekCommandDispatcher#dispatchCommand');
18
+ logger.debug('Dispatching the following command envelope: ', commandEnvelope);
19
+ if (!commandEnvelope.version) {
20
+ throw new common_1.InvalidParameterError('The required command "version" was not present');
21
+ }
22
+ const commandMetadata = this.config.commandHandlers[commandEnvelope.typeName];
23
+ if (!commandMetadata) {
24
+ throw new common_1.NotFoundError(`Could not find a proper handler for ${commandEnvelope.typeName}`);
25
+ }
26
+ await commandMetadata.authorizer(commandEnvelope.currentUser, commandEnvelope);
27
+ const commandClass = commandMetadata.class;
28
+ logger.debug('Found the following command:', commandClass.name);
29
+ const migratedCommandEnvelope = await new schema_migrator_1.SchemaMigrator(this.config).migrate(commandEnvelope);
30
+ let result;
31
+ const register = new common_1.Register(migratedCommandEnvelope.requestID, context.responseHeaders, register_handler_1.RegisterHandler.flush, migratedCommandEnvelope.currentUser, migratedCommandEnvelope.context);
32
+ try {
33
+ const commandInput = await (0, filter_helpers_1.applyBeforeFunctions)(migratedCommandEnvelope.value, commandMetadata.before, migratedCommandEnvelope.currentUser);
34
+ const commandInstance = (0, common_1.createInstance)(commandClass, commandInput);
35
+ logger.debug('Calling "handle" method on command: ', commandClass);
36
+ result = await commandClass.handle(commandInstance, register);
37
+ }
38
+ catch (err) {
39
+ const e = err;
40
+ const error = await this.globalErrorDispatcher.dispatch(new common_1.CommandHandlerGlobalError(migratedCommandEnvelope, commandMetadata, e));
41
+ if (error)
42
+ throw error;
43
+ }
44
+ logger.debug('Command dispatched with register: ', register);
45
+ await register_handler_1.RegisterHandler.handle(this.config, register);
46
+ return result;
47
+ }
48
+ }
49
+ exports.MagekCommandDispatcher = MagekCommandDispatcher;
50
+ tslib_1.__decorate([
51
+ (0, instrumentation_1.Trace)(common_1.TraceActionTypes.COMMAND_HANDLER),
52
+ tslib_1.__metadata("design:type", Function),
53
+ tslib_1.__metadata("design:paramtypes", [Object, Object]),
54
+ tslib_1.__metadata("design:returntype", Promise)
55
+ ], MagekCommandDispatcher.prototype, "dispatchCommand", null);
@@ -0,0 +1,12 @@
1
+ import { MagekDataMigrationEntityDuration, DataMigrationStatus } from '@magek/common';
2
+ import { MagekDataMigrationStarted } from '../events/data-migration-started';
3
+ import { MagekDataMigrationFinished } from '../events/data-migration-finished';
4
+ export declare class MagekDataMigrationEntity {
5
+ id: string;
6
+ status: DataMigrationStatus;
7
+ lastUpdated: string;
8
+ duration?: MagekDataMigrationEntityDuration | undefined;
9
+ constructor(id: string, status: DataMigrationStatus, lastUpdated: string, duration?: MagekDataMigrationEntityDuration | undefined);
10
+ static started(event: MagekDataMigrationStarted, currentDataMigration: MagekDataMigrationEntity): MagekDataMigrationEntity;
11
+ static finished(event: MagekDataMigrationFinished, currentDataMigration: MagekDataMigrationEntity): MagekDataMigrationEntity;
12
+ }
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MagekDataMigrationEntity = void 0;
4
+ const common_1 = require("@magek/common");
5
+ class MagekDataMigrationEntity {
6
+ constructor(id, status, lastUpdated, duration) {
7
+ this.id = id;
8
+ this.status = status;
9
+ this.lastUpdated = lastUpdated;
10
+ this.duration = duration;
11
+ }
12
+ static started(event, currentDataMigration) {
13
+ const duration = {
14
+ start: new Date().toISOString(),
15
+ };
16
+ return new MagekDataMigrationEntity(event.name, common_1.DataMigrationStatus.RUNNING, event.lastUpdated, duration);
17
+ }
18
+ static finished(event, currentDataMigration) {
19
+ var _a;
20
+ const current = new Date();
21
+ if ((_a = currentDataMigration.duration) === null || _a === void 0 ? void 0 : _a.start) {
22
+ const start = currentDataMigration.duration.start;
23
+ const end = current.toISOString();
24
+ const startTime = Date.parse(start);
25
+ const endTime = current.getTime();
26
+ const elapsedTime = endTime - startTime;
27
+ const duration = {
28
+ start: start,
29
+ end: end,
30
+ elapsedMilliseconds: elapsedTime,
31
+ };
32
+ return new MagekDataMigrationEntity(event.name, common_1.DataMigrationStatus.FINISHED, event.lastUpdated, duration);
33
+ }
34
+ return new MagekDataMigrationEntity(event.name, common_1.DataMigrationStatus.FINISHED, event.lastUpdated);
35
+ }
36
+ }
37
+ exports.MagekDataMigrationEntity = MagekDataMigrationEntity;
@@ -0,0 +1,7 @@
1
+ import { UUID } from '@magek/common';
2
+ export declare class MagekDataMigrationFinished {
3
+ readonly name: string;
4
+ readonly lastUpdated: string;
5
+ constructor(name: string, lastUpdated?: string);
6
+ entityID(): UUID;
7
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MagekDataMigrationFinished = void 0;
4
+ class MagekDataMigrationFinished {
5
+ constructor(name, lastUpdated) {
6
+ this.name = name;
7
+ this.lastUpdated = lastUpdated !== null && lastUpdated !== void 0 ? lastUpdated : new Date().toISOString();
8
+ }
9
+ entityID() {
10
+ return this.name;
11
+ }
12
+ }
13
+ exports.MagekDataMigrationFinished = MagekDataMigrationFinished;
@@ -0,0 +1,7 @@
1
+ import { UUID } from '@magek/common';
2
+ export declare class MagekDataMigrationStarted {
3
+ readonly name: string;
4
+ readonly lastUpdated: string;
5
+ constructor(name: string, lastUpdated?: string);
6
+ entityID(): UUID;
7
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MagekDataMigrationStarted = void 0;
4
+ class MagekDataMigrationStarted {
5
+ constructor(name, lastUpdated) {
6
+ this.name = name;
7
+ this.lastUpdated = lastUpdated !== null && lastUpdated !== void 0 ? lastUpdated : new Date().toISOString();
8
+ }
9
+ entityID() {
10
+ return this.name;
11
+ }
12
+ }
13
+ exports.MagekDataMigrationStarted = MagekDataMigrationStarted;
@@ -0,0 +1,9 @@
1
+ import { EntityInterface, Instance, UUID } from '@magek/common';
2
+ export declare class MagekEntityMigrated {
3
+ readonly oldEntityName: string;
4
+ readonly oldEntityId: UUID;
5
+ readonly newEntityName: string;
6
+ readonly newEntity: Instance & EntityInterface;
7
+ constructor(oldEntityName: string, oldEntityId: UUID, newEntityName: string, newEntity: Instance & EntityInterface);
8
+ entityID(): UUID;
9
+ }
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MagekEntityMigrated = void 0;
4
+ class MagekEntityMigrated {
5
+ constructor(oldEntityName, oldEntityId, newEntityName, newEntity) {
6
+ this.oldEntityName = oldEntityName;
7
+ this.oldEntityId = oldEntityId;
8
+ this.newEntityName = newEntityName;
9
+ this.newEntity = newEntity;
10
+ }
11
+ entityID() {
12
+ return this.oldEntityId;
13
+ }
14
+ }
15
+ exports.MagekEntityMigrated = MagekEntityMigrated;
@@ -0,0 +1,7 @@
1
+ import { UUID } from '@magek/common';
2
+ export declare class MagekEntityTouched {
3
+ readonly entityName: string;
4
+ readonly entityId: UUID;
5
+ constructor(entityName: string, entityId: UUID);
6
+ entityID(): UUID;
7
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MagekEntityTouched = void 0;
4
+ class MagekEntityTouched {
5
+ constructor(entityName, entityId) {
6
+ this.entityName = entityName;
7
+ this.entityId = entityId;
8
+ }
9
+ entityID() {
10
+ return this.entityId;
11
+ }
12
+ }
13
+ exports.MagekEntityTouched = MagekEntityTouched;
@@ -0,0 +1,8 @@
1
+ import { EntityInterface, Instance, UUID } from '@magek/common';
2
+ export declare class MagekDataMigrations {
3
+ static run(): Promise<boolean>;
4
+ static migrateEntity(oldEntityName: string, oldEntityId: UUID, newEntity: Instance & EntityInterface): Promise<void>;
5
+ private static sortConfiguredMigrations;
6
+ private static migrate;
7
+ private static emitStarted;
8
+ }
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MagekDataMigrations = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const common_1 = require("@magek/common");
6
+ const register_handler_1 = require("./register-handler");
7
+ const event_store_1 = require("./services/event-store");
8
+ const data_migration_entity_1 = require("./core-concepts/data-migration/entities/data-migration-entity");
9
+ const entity_migrated_1 = require("./core-concepts/data-migration/events/entity-migrated");
10
+ const index_1 = require("./index");
11
+ const data_migration_started_1 = require("./core-concepts/data-migration/events/data-migration-started");
12
+ const instrumentation_1 = require("./instrumentation");
13
+ class MagekDataMigrations {
14
+ static async run() {
15
+ const config = index_1.Magek.config;
16
+ const logger = (0, common_1.getLogger)(config, 'MagekDataMigrationDispatcher#dispatch');
17
+ let migrating = false;
18
+ const configuredMigrations = config.dataMigrationHandlers;
19
+ if (Object.keys(configuredMigrations).length === 0) {
20
+ logger.debug('No defined migrations found. Skipping...');
21
+ return false;
22
+ }
23
+ const sortedConfiguredMigrations = MagekDataMigrations.sortConfiguredMigrations(configuredMigrations);
24
+ const eventStore = new event_store_1.EventStore(config);
25
+ for (const configuredMigration of Object.values(sortedConfiguredMigrations)) {
26
+ const migrationEntityForConfiguredMigration = await eventStore.fetchEntitySnapshot(data_migration_entity_1.MagekDataMigrationEntity.name, configuredMigration.class.name);
27
+ if (!migrationEntityForConfiguredMigration) {
28
+ logger.debug('Not found running or finished migrations for the DataMigration', configuredMigration);
29
+ migrating = true;
30
+ await MagekDataMigrations.migrate(configuredMigration);
31
+ }
32
+ else {
33
+ const dataMigrationEntity = migrationEntityForConfiguredMigration.value;
34
+ if (dataMigrationEntity.status === common_1.DataMigrationStatus.RUNNING) {
35
+ logger.debug('Found running migrations for the DataMigration', configuredMigration);
36
+ migrating = true;
37
+ }
38
+ }
39
+ }
40
+ return migrating;
41
+ }
42
+ static migrateEntity(oldEntityName, oldEntityId, newEntity) {
43
+ const requestID = common_1.UUID.generate();
44
+ const register = new common_1.Register(requestID, {}, register_handler_1.RegisterHandler.flush);
45
+ register.events(new entity_migrated_1.MagekEntityMigrated(oldEntityName, oldEntityId, newEntity.constructor.name, newEntity));
46
+ return register_handler_1.RegisterHandler.handle(index_1.Magek.config, register);
47
+ }
48
+ static sortConfiguredMigrations(configuredMigrations) {
49
+ return Object.values(configuredMigrations).sort((a, b) => {
50
+ return a.migrationOptions.order - b.migrationOptions.order;
51
+ });
52
+ }
53
+ static async migrate(migrationHandler) {
54
+ const startedRegister = new common_1.Register(common_1.UUID.generate(), {}, register_handler_1.RegisterHandler.flush);
55
+ await MagekDataMigrations.emitStarted(startedRegister, migrationHandler.class.name);
56
+ await register_handler_1.RegisterHandler.handle(index_1.Magek.config, startedRegister);
57
+ const finishedRegister = new common_1.Register(common_1.UUID.generate(), {}, register_handler_1.RegisterHandler.flush);
58
+ await migrationHandler.class.start(finishedRegister);
59
+ await register_handler_1.RegisterHandler.handle(index_1.Magek.config, finishedRegister);
60
+ }
61
+ static async emitStarted(register, configuredMigrationName) {
62
+ const logger = (0, common_1.getLogger)(index_1.Magek.config, 'MagekMigration#emitStarted');
63
+ logger.info('Migration started', configuredMigrationName);
64
+ register.events(new data_migration_started_1.MagekDataMigrationStarted(configuredMigrationName, new Date().toISOString()));
65
+ }
66
+ }
67
+ exports.MagekDataMigrations = MagekDataMigrations;
68
+ tslib_1.__decorate([
69
+ (0, instrumentation_1.Trace)(common_1.TraceActionTypes.MIGRATION_RUN),
70
+ tslib_1.__metadata("design:type", Function),
71
+ tslib_1.__metadata("design:paramtypes", []),
72
+ tslib_1.__metadata("design:returntype", Promise)
73
+ ], MagekDataMigrations, "run", null);
@@ -0,0 +1,19 @@
1
+ import { CommandFilterHooks, CommandInterface, CommandRoleAccess } from '@magek/common';
2
+ /**
3
+ * Stage 3 class decorator context
4
+ */
5
+ interface Stage3ClassContext {
6
+ kind: 'class';
7
+ name: string | undefined;
8
+ metadata: Record<string | symbol, unknown>;
9
+ addInitializer?: (initializer: () => void) => void;
10
+ }
11
+ /**
12
+ * Decorator to mark a class as a Magek Command.
13
+ * Commands represent user intentions and trigger business logic.
14
+ *
15
+ * @param attributes - Role access control and filter hooks configuration
16
+ * @returns A class decorator function
17
+ */
18
+ export declare function Command(attributes: CommandRoleAccess & CommandFilterHooks): <TCommand>(commandClass: CommandInterface<TCommand>, context?: Stage3ClassContext) => void;
19
+ export {};
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Command = Command;
4
+ const magek_1 = require("../magek");
5
+ const metadata_1 = require("./metadata");
6
+ const authorizer_1 = require("../authorizer");
7
+ const stage3_utils_1 = require("./stage3-utils");
8
+ /**
9
+ * Type guard to detect Stage 3 class decorator context
10
+ */
11
+ function isStage3ClassContext(arg) {
12
+ return (arg !== null &&
13
+ typeof arg === 'object' &&
14
+ 'kind' in arg &&
15
+ arg.kind === 'class' &&
16
+ 'metadata' in arg);
17
+ }
18
+ /**
19
+ * Decorator to mark a class as a Magek Command.
20
+ * Commands represent user intentions and trigger business logic.
21
+ *
22
+ * @param attributes - Role access control and filter hooks configuration
23
+ * @returns A class decorator function
24
+ */
25
+ function Command(attributes) {
26
+ return (commandClass, context) => {
27
+ // Transfer Stage 3 field metadata if applicable
28
+ if (isStage3ClassContext(context)) {
29
+ (0, stage3_utils_1.transferStage3FieldMetadata)(commandClass, context.metadata);
30
+ }
31
+ magek_1.Magek.configureCurrentEnv((config) => {
32
+ var _a;
33
+ if (config.commandHandlers[commandClass.name]) {
34
+ throw new Error(`A command called ${commandClass.name} is already registered.
35
+ If you think that this is an error, try performing a clean build.`);
36
+ }
37
+ const metadata = (0, metadata_1.getClassMetadata)(commandClass);
38
+ config.commandHandlers[commandClass.name] = {
39
+ class: commandClass,
40
+ authorizer: authorizer_1.MagekAuthorizer.build(attributes),
41
+ before: (_a = attributes.before) !== null && _a !== void 0 ? _a : [],
42
+ properties: metadata.fields,
43
+ methods: metadata.methods,
44
+ };
45
+ });
46
+ };
47
+ }
@@ -0,0 +1,9 @@
1
+ import { DataMigrationInterface, DataMigrationParameters } from '@magek/common';
2
+ /**
3
+ * Decorator to mark a class as a Magek Data Migration.
4
+ * Data migrations are background processes that update existing data in the database.
5
+ *
6
+ * @param attributes - Migration configuration (e.g., execution order)
7
+ * @returns A class decorator function
8
+ */
9
+ export declare function DataMigration(attributes: DataMigrationParameters): (dataMigrationClass: DataMigrationInterface) => void;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DataMigration = DataMigration;
4
+ const magek_1 = require("../magek");
5
+ /**
6
+ * Decorator to mark a class as a Magek Data Migration.
7
+ * Data migrations are background processes that update existing data in the database.
8
+ *
9
+ * @param attributes - Migration configuration (e.g., execution order)
10
+ * @returns A class decorator function
11
+ */
12
+ function DataMigration(attributes) {
13
+ return (migrationClass) => {
14
+ magek_1.Magek.configureCurrentEnv((config) => {
15
+ if (config.dataMigrationHandlers[migrationClass.name]) {
16
+ throw new Error(`A data migration called ${migrationClass.name} is already registered.
17
+ If you think that this is an error, try performing a clean build.`);
18
+ }
19
+ config.dataMigrationHandlers[migrationClass.name] = {
20
+ class: migrationClass,
21
+ migrationOptions: attributes,
22
+ };
23
+ });
24
+ };
25
+ }
@@ -0,0 +1,32 @@
1
+ import { Class, EntityInterface, EventInterface, EventStreamRoleAccess, AnyClass } from '@magek/common';
2
+ type EntityAttributes = EventStreamRoleAccess;
3
+ type EntityDecoratorParam = AnyClass | EntityAttributes;
4
+ type EntityDecoratorResult<TEntity, TParam> = TParam extends EntityAttributes ? (entityClass: Class<TEntity>) => void : void;
5
+ /**
6
+ * Decorator to mark a class as a Magek Entity.
7
+ * Entities represent the current state derived from events.
8
+ *
9
+ * @param classOrAttributes - Either the class itself or entity configuration attributes
10
+ * @returns A class decorator function or void if used without parentheses
11
+ */
12
+ export declare function Entity<TEntity extends EntityInterface, TParam extends EntityDecoratorParam>(classOrAttributes: TParam): EntityDecoratorResult<TEntity, TParam>;
13
+ /**
14
+ * Stage 3 method decorator context
15
+ */
16
+ interface Stage3MethodContext {
17
+ kind: 'method';
18
+ name: string | symbol;
19
+ static: boolean;
20
+ private: boolean;
21
+ metadata: Record<string | symbol, unknown>;
22
+ addInitializer?: (initializer: () => void) => void;
23
+ }
24
+ /**
25
+ * Decorator to register an entity class method as a reducer function
26
+ * for a specific event.
27
+ *
28
+ * @param eventClass The event that this method will react to
29
+ */
30
+ export declare function Reduces<TEvent extends EventInterface>(eventClass: Class<TEvent>): <TEntity>(entityClassOrMethod: Class<TEntity> | Function, methodNameOrContext: string | Stage3MethodContext, methodDescriptor?: ReducerMethod<TEvent, TEntity>) => void;
31
+ type ReducerMethod<TEvent, TEntity> = TypedPropertyDescriptor<(event: TEvent, entity: TEntity) => TEntity> | TypedPropertyDescriptor<(event: TEvent, entity?: TEntity) => TEntity>;
32
+ export {};
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Entity = Entity;
4
+ exports.Reduces = Reduces;
5
+ const magek_1 = require("../magek");
6
+ const authorizer_1 = require("../authorizer");
7
+ /**
8
+ * Decorator to mark a class as a Magek Entity.
9
+ * Entities represent the current state derived from events.
10
+ *
11
+ * @param classOrAttributes - Either the class itself or entity configuration attributes
12
+ * @returns A class decorator function or void if used without parentheses
13
+ */
14
+ function Entity(classOrAttributes) {
15
+ let authorizeReadEvents;
16
+ // This function will be either returned or executed, depending on the parameters passed to the decorator
17
+ const mainLogicFunction = (entityClass) => {
18
+ magek_1.Magek.configureCurrentEnv((config) => {
19
+ if (config.entities[entityClass.name]) {
20
+ throw new Error(`An entity called ${entityClass.name} is already registered
21
+ If you think that this is an error, try performing a clean build..`);
22
+ }
23
+ let eventStreamAuthorizer = authorizer_1.MagekAuthorizer.denyAccess;
24
+ if (authorizeReadEvents === 'all') {
25
+ eventStreamAuthorizer = authorizer_1.MagekAuthorizer.allowAccess;
26
+ }
27
+ else if (Array.isArray(authorizeReadEvents)) {
28
+ eventStreamAuthorizer = authorizer_1.MagekAuthorizer.authorizeRoles.bind(null, authorizeReadEvents);
29
+ }
30
+ else if (typeof authorizeReadEvents === 'function') {
31
+ eventStreamAuthorizer = authorizeReadEvents;
32
+ }
33
+ config.entities[entityClass.name] = {
34
+ class: entityClass,
35
+ eventStreamAuthorizer,
36
+ };
37
+ });
38
+ };
39
+ if (isEntityAttributes(classOrAttributes)) {
40
+ authorizeReadEvents = classOrAttributes.authorizeReadEvents;
41
+ return mainLogicFunction;
42
+ }
43
+ return mainLogicFunction(classOrAttributes);
44
+ }
45
+ function isEntityAttributes(param) {
46
+ return 'authorizeReadEvents' in param;
47
+ }
48
+ /**
49
+ * Type guard to detect Stage 3 method decorator context
50
+ */
51
+ function isStage3MethodContext(arg) {
52
+ return (arg !== null &&
53
+ typeof arg === 'object' &&
54
+ 'kind' in arg &&
55
+ arg.kind === 'method' &&
56
+ 'name' in arg);
57
+ }
58
+ /**
59
+ * Decorator to register an entity class method as a reducer function
60
+ * for a specific event.
61
+ *
62
+ * @param eventClass The event that this method will react to
63
+ */
64
+ function Reduces(eventClass) {
65
+ return (entityClassOrMethod, methodNameOrContext, _methodDescriptor) => {
66
+ // Detect Stage 3 vs Legacy decorator
67
+ if (isStage3MethodContext(methodNameOrContext)) {
68
+ // Stage 3 decorator - use addInitializer to get the class
69
+ const context = methodNameOrContext;
70
+ if (context.addInitializer) {
71
+ context.addInitializer(function () {
72
+ // For static methods, 'this' is the class itself
73
+ // For instance methods, 'this' is an instance and we need this.constructor
74
+ const targetClass = context.static ? this : this.constructor;
75
+ registerReducer(eventClass.name, {
76
+ class: targetClass,
77
+ methodName: context.name.toString(),
78
+ });
79
+ });
80
+ }
81
+ }
82
+ else {
83
+ // Legacy decorator
84
+ registerReducer(eventClass.name, {
85
+ class: entityClassOrMethod,
86
+ methodName: methodNameOrContext,
87
+ });
88
+ }
89
+ };
90
+ }
91
+ function registerReducer(eventName, reducerMetadata) {
92
+ magek_1.Magek.configureCurrentEnv((config) => {
93
+ const reducerPath = config.reducers[eventName];
94
+ if (reducerPath) {
95
+ throw new Error(`Error registering reducer: The event ${eventName} was already registered to be reduced by method ${reducerPath.methodName} in the entity ${reducerPath.class.name}.
96
+ If you think that this is an error, try performing a clean build.`);
97
+ }
98
+ config.reducers[eventName] = reducerMetadata;
99
+ });
100
+ }
@@ -0,0 +1,3 @@
1
+ import { EventInterface, EventHandlerInterface, Class, NotificationInterface } from '@magek/common';
2
+ export declare function EventHandler<TEvent extends EventInterface | NotificationInterface>(event: Class<TEvent>): <TEventHandler extends EventHandlerInterface>(eventHandlerClass: TEventHandler) => void;
3
+ export declare function registerEventHandler<TEventHandler extends EventHandlerInterface>(eventName: string, eventHandlerClass: TEventHandler): void;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EventHandler = EventHandler;
4
+ exports.registerEventHandler = registerEventHandler;
5
+ const magek_1 = require("../magek");
6
+ function EventHandler(event) {
7
+ return (eventHandlerClass) => registerEventHandler(event.name, eventHandlerClass);
8
+ }
9
+ function registerEventHandler(eventName, eventHandlerClass) {
10
+ magek_1.Magek.configureCurrentEnv((config) => {
11
+ const registeredEventHandlers = config.eventHandlers[eventName] || [];
12
+ if (registeredEventHandlers.some((klass) => klass == eventHandlerClass)) {
13
+ return;
14
+ }
15
+ registeredEventHandlers.push(eventHandlerClass);
16
+ config.eventHandlers[eventName] = registeredEventHandlers;
17
+ });
18
+ }
@@ -0,0 +1,8 @@
1
+ import { Class, EventInterface } from '@magek/common';
2
+ /**
3
+ * Decorator to mark a class as a Magek Event.
4
+ * Events are immutable records of facts that occurred in your system.
5
+ *
6
+ * @param eventClass - The event class to register
7
+ */
8
+ export declare function Event<TEvent extends EventInterface>(eventClass: Class<TEvent>): void;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Event = Event;
4
+ const magek_1 = require("../magek");
5
+ /**
6
+ * Decorator to mark a class as a Magek Event.
7
+ * Events are immutable records of facts that occurred in your system.
8
+ *
9
+ * @param eventClass - The event class to register
10
+ */
11
+ // Disabling unused vars here, because it won't allow us to call the decorator without parens
12
+ function Event(eventClass) {
13
+ magek_1.Magek.configureCurrentEnv((config) => {
14
+ if (config.events[eventClass.name]) {
15
+ throw new Error(`A event called ${eventClass.name} is already registered.
16
+ If you think that this is an error, try performing a clean build.`);
17
+ }
18
+ config.events[eventClass.name] = {
19
+ class: eventClass,
20
+ };
21
+ });
22
+ }
@@ -0,0 +1,6 @@
1
+ import 'reflect-metadata';
2
+ import { AnyClass, ClassMetadata } from '@magek/common';
3
+ /**
4
+ * Build ClassMetadata from @Field() decorators
5
+ */
6
+ export declare function buildClassMetadataFromFields(classType: AnyClass): ClassMetadata;