@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,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Projects = Projects;
4
+ const magek_1 = require("../magek");
5
+ /**
6
+ * Type guard for Stage 3 method context
7
+ */
8
+ function isStage3MethodContext(arg) {
9
+ return (arg !== null &&
10
+ typeof arg === 'object' &&
11
+ 'kind' in arg &&
12
+ arg.kind === 'method' &&
13
+ 'name' in arg);
14
+ }
15
+ /**
16
+ * Decorator to register a read model method as a projection
17
+ * for a specific entity
18
+ *
19
+ * @param originEntity The entity that this method will react to
20
+ * @param joinKey
21
+ * @param unProject
22
+ */
23
+ function Projects(originEntity, joinKey, unProject) {
24
+ return (readModelClassOrMethod, methodNameOrContext) => {
25
+ // Detect Stage 3 vs Legacy decorator
26
+ if (isStage3MethodContext(methodNameOrContext)) {
27
+ // Stage 3 decorator - use addInitializer to get the class
28
+ const context = methodNameOrContext;
29
+ if (context.addInitializer) {
30
+ context.addInitializer(function () {
31
+ const readModelClass = context.static ? this : this.constructor;
32
+ const projectionMetadata = {
33
+ joinKey: joinKey,
34
+ class: readModelClass,
35
+ methodName: context.name.toString(),
36
+ };
37
+ registerProjection(originEntity.name, projectionMetadata);
38
+ if (unProject) {
39
+ const unProjectionMetadata = {
40
+ joinKey,
41
+ class: readModelClass,
42
+ methodName: unProject.name,
43
+ };
44
+ registerUnProjection(originEntity.name, unProjectionMetadata);
45
+ }
46
+ });
47
+ }
48
+ }
49
+ else {
50
+ // Legacy decorator
51
+ const readModelClass = readModelClassOrMethod;
52
+ const methodName = methodNameOrContext;
53
+ const projectionMetadata = {
54
+ joinKey: joinKey,
55
+ class: readModelClass,
56
+ methodName: methodName,
57
+ };
58
+ registerProjection(originEntity.name, projectionMetadata);
59
+ if (unProject) {
60
+ const unProjectionMetadata = {
61
+ joinKey,
62
+ class: readModelClass,
63
+ methodName: unProject.name,
64
+ };
65
+ registerUnProjection(originEntity.name, unProjectionMetadata);
66
+ }
67
+ }
68
+ };
69
+ }
70
+ function registerProjection(originName, projectionMetadata) {
71
+ magek_1.Magek.configureCurrentEnv((config) => {
72
+ configure(originName, projectionMetadata, config.projections);
73
+ });
74
+ }
75
+ function registerUnProjection(originName, projectionMetadata) {
76
+ magek_1.Magek.configureCurrentEnv((config) => {
77
+ configure(originName, projectionMetadata, config.unProjections);
78
+ });
79
+ }
80
+ function configure(originName, projectionMetadata, configuration) {
81
+ const entityProjections = configuration[originName] || [];
82
+ if (entityProjections.indexOf(projectionMetadata) < 0) {
83
+ // Skip duplicate registrations
84
+ entityProjections.push(projectionMetadata);
85
+ configuration[originName] = entityProjections;
86
+ }
87
+ }
@@ -0,0 +1,2 @@
1
+ import { CommandFilterHooks, QueryInterface, QueryRoleAccess } from '@magek/common';
2
+ export declare function Query(attributes: QueryRoleAccess & CommandFilterHooks): <TCommand>(queryClass: QueryInterface<TCommand>) => void;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Query = Query;
4
+ const magek_1 = require("../magek");
5
+ const metadata_1 = require("./metadata");
6
+ const authorizer_1 = require("../authorizer");
7
+ function Query(attributes) {
8
+ return (queryClass) => {
9
+ magek_1.Magek.configureCurrentEnv((config) => {
10
+ var _a;
11
+ if (config.queryHandlers[queryClass.name]) {
12
+ throw new Error(`A query called ${queryClass.name} is already registered.
13
+ If you think that this is an error, try performing a clean build.`);
14
+ }
15
+ const metadata = (0, metadata_1.getClassMetadata)(queryClass);
16
+ config.queryHandlers[queryClass.name] = {
17
+ class: queryClass,
18
+ authorizer: authorizer_1.MagekAuthorizer.build(attributes),
19
+ properties: metadata.fields,
20
+ methods: metadata.methods,
21
+ before: (_a = attributes.before) !== null && _a !== void 0 ? _a : [],
22
+ };
23
+ });
24
+ };
25
+ }
@@ -0,0 +1,39 @@
1
+ import { Class, ReadModelFilterHooks, ReadModelInterface, ReadModelRoleAccess } 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 register a class as a ReadModel
13
+ * @param attributes
14
+ */
15
+ export declare function ReadModel(attributes: ReadModelRoleAccess & ReadModelFilterHooks): (readModelClass: Class<ReadModelInterface>, context?: Stage3ClassContext) => void;
16
+ interface CalculatedFieldOptions {
17
+ dependsOn: string[];
18
+ }
19
+ /**
20
+ * Stage 3 getter decorator context
21
+ */
22
+ interface Stage3GetterContext {
23
+ kind: 'getter';
24
+ name: string | symbol;
25
+ static: boolean;
26
+ private: boolean;
27
+ metadata: Record<string | symbol, unknown>;
28
+ access?: {
29
+ get: () => unknown;
30
+ };
31
+ addInitializer?: (initializer: () => void) => void;
32
+ }
33
+ /**
34
+ * Decorator to mark a property as a calculated field with dependencies.
35
+ * Supports both legacy and Stage 3 decorators.
36
+ * @param options - A `CalculatedFieldOptions` object indicating the dependencies.
37
+ */
38
+ export declare function CalculatedField(options: CalculatedFieldOptions): (target: object | Function, propertyKeyOrContext: string | symbol | Stage3GetterContext) => void;
39
+ export {};
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ReadModel = ReadModel;
4
+ exports.CalculatedField = CalculatedField;
5
+ const common_1 = require("@magek/common");
6
+ const magek_1 = require("../magek");
7
+ const authorizer_1 = require("../authorizer");
8
+ const metadata_1 = require("./metadata");
9
+ const stage3_utils_1 = require("./stage3-utils");
10
+ const sequenced_by_1 = require("./sequenced-by");
11
+ /**
12
+ * Type guard to detect Stage 3 class decorator context
13
+ */
14
+ function isStage3ClassContext(arg) {
15
+ return (arg !== null &&
16
+ typeof arg === 'object' &&
17
+ 'kind' in arg &&
18
+ arg.kind === 'class' &&
19
+ 'metadata' in arg);
20
+ }
21
+ /**
22
+ * Decorator to register a class as a ReadModel
23
+ * @param attributes
24
+ */
25
+ function ReadModel(attributes) {
26
+ return (readModelClass, context) => {
27
+ // Transfer Stage 3 field metadata if applicable
28
+ if (isStage3ClassContext(context)) {
29
+ (0, stage3_utils_1.transferStage3FieldMetadata)(readModelClass, context.metadata);
30
+ (0, sequenced_by_1.transferSequenceKeyMetadata)(readModelClass, context.metadata);
31
+ transferCalculatedFieldDependencies(readModelClass, context.metadata);
32
+ }
33
+ magek_1.Magek.configureCurrentEnv((config) => {
34
+ var _a;
35
+ if (config.readModels[readModelClass.name]) {
36
+ throw new Error(`A read model called ${readModelClass.name} is already registered.
37
+ If you think that this is an error, try performing a clean build.`);
38
+ }
39
+ const authorizer = authorizer_1.MagekAuthorizer.build(attributes);
40
+ const classMetadata = (0, metadata_1.getClassMetadata)(readModelClass);
41
+ const dynamicDependencies = (0, common_1.getMetadata)('dynamic:dependencies', readModelClass) || {};
42
+ // Combine fields with dynamic dependencies
43
+ const fieldProperties = classMetadata.fields.map((field) => {
44
+ return {
45
+ ...field,
46
+ dependencies: dynamicDependencies[field.name] || [],
47
+ };
48
+ });
49
+ // Include calculated fields (getters) from methods with their dependencies
50
+ const methodProperties = classMetadata.methods.map((method) => {
51
+ return {
52
+ ...method,
53
+ // Dependencies already included in method from getAllGetters
54
+ };
55
+ });
56
+ // Merge fields and methods into properties
57
+ const properties = [...fieldProperties, ...methodProperties];
58
+ config.readModels[readModelClass.name] = {
59
+ class: readModelClass,
60
+ properties,
61
+ authorizer,
62
+ before: (_a = attributes.before) !== null && _a !== void 0 ? _a : [],
63
+ };
64
+ });
65
+ };
66
+ }
67
+ /**
68
+ * Type guard for Stage 3 getter context
69
+ */
70
+ function isStage3GetterContext(arg) {
71
+ return (arg !== null &&
72
+ typeof arg === 'object' &&
73
+ 'kind' in arg &&
74
+ arg.kind === 'getter' &&
75
+ 'name' in arg &&
76
+ 'metadata' in arg);
77
+ }
78
+ // Symbol for storing calculated field dependencies in Stage 3 decorator context.metadata
79
+ const CALCULATED_FIELDS_SYMBOL = Symbol.for('magek:calculatedFields');
80
+ /**
81
+ * Transfer calculated field dependencies from Stage 3 context.metadata to class metadata.
82
+ * Called by the ReadModel class decorator.
83
+ */
84
+ function transferCalculatedFieldDependencies(classType, contextMetadata) {
85
+ const calculatedFields = contextMetadata[CALCULATED_FIELDS_SYMBOL];
86
+ if (calculatedFields) {
87
+ const existingDependencies = (0, common_1.getMetadata)('dynamic:dependencies', classType) || {};
88
+ for (const [propertyName, dependencies] of Object.entries(calculatedFields)) {
89
+ existingDependencies[propertyName] = dependencies;
90
+ }
91
+ (0, common_1.defineMetadata)('dynamic:dependencies', existingDependencies, classType);
92
+ }
93
+ }
94
+ /**
95
+ * Decorator to mark a property as a calculated field with dependencies.
96
+ * Supports both legacy and Stage 3 decorators.
97
+ * @param options - A `CalculatedFieldOptions` object indicating the dependencies.
98
+ */
99
+ function CalculatedField(options) {
100
+ return (target, propertyKeyOrContext) => {
101
+ // Detect Stage 3 getter decorator
102
+ if (isStage3GetterContext(propertyKeyOrContext)) {
103
+ const context = propertyKeyOrContext;
104
+ const propertyName = String(context.name);
105
+ // Store in context.metadata for ReadModel decorator to pick up
106
+ if (!context.metadata[CALCULATED_FIELDS_SYMBOL]) {
107
+ context.metadata[CALCULATED_FIELDS_SYMBOL] = {};
108
+ }
109
+ const calculatedFields = context.metadata[CALCULATED_FIELDS_SYMBOL];
110
+ calculatedFields[propertyName] = options.dependsOn;
111
+ // Also use addInitializer to set Reflect metadata
112
+ if (context.addInitializer) {
113
+ context.addInitializer(function () {
114
+ const klass = this.constructor;
115
+ const existingDependencies = (0, common_1.getMetadata)('dynamic:dependencies', klass) || {};
116
+ existingDependencies[propertyName] = options.dependsOn;
117
+ (0, common_1.defineMetadata)('dynamic:dependencies', existingDependencies, klass);
118
+ });
119
+ }
120
+ return;
121
+ }
122
+ // Legacy decorator
123
+ const propertyKey = propertyKeyOrContext;
124
+ const existingDependencies = (0, common_1.getMetadata)('dynamic:dependencies', target.constructor) ||
125
+ {};
126
+ existingDependencies[propertyKey] = options.dependsOn;
127
+ (0, common_1.defineMetadata)('dynamic:dependencies', existingDependencies, target.constructor);
128
+ };
129
+ }
@@ -0,0 +1,6 @@
1
+ import { Class, RoleMetadata, RoleInterface } from '@magek/common';
2
+ /**
3
+ * Annotation to tell Magek which classes represent your roles
4
+ * @param roleMetadata
5
+ */
6
+ export declare function Role(roleMetadata?: RoleMetadata): (role: Class<RoleInterface>) => void;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Role = Role;
4
+ const magek_1 = require("../magek");
5
+ /**
6
+ * Annotation to tell Magek which classes represent your roles
7
+ * @param roleMetadata
8
+ */
9
+ function Role(roleMetadata = { auth: {} }) {
10
+ return (role) => {
11
+ magek_1.Magek.configureCurrentEnv((config) => {
12
+ config.roles[role.name] = roleMetadata;
13
+ });
14
+ };
15
+ }
@@ -0,0 +1,9 @@
1
+ import { ScheduledCommandInterface, ScheduleInterface } from '@magek/common';
2
+ /**
3
+ * Decorator to mark a class as a Magek Scheduled Command.
4
+ * Scheduled commands are executed automatically based on a schedule.
5
+ *
6
+ * @param attributes - Schedule configuration (e.g., cron expression)
7
+ * @returns A class decorator function
8
+ */
9
+ export declare function ScheduledCommand(attributes: ScheduleInterface): (scheduledCommandClass: ScheduledCommandInterface) => void;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ScheduledCommand = ScheduledCommand;
4
+ const magek_1 = require("../magek");
5
+ /**
6
+ * Decorator to mark a class as a Magek Scheduled Command.
7
+ * Scheduled commands are executed automatically based on a schedule.
8
+ *
9
+ * @param attributes - Schedule configuration (e.g., cron expression)
10
+ * @returns A class decorator function
11
+ */
12
+ function ScheduledCommand(attributes) {
13
+ return (commandClass) => {
14
+ magek_1.Magek.configureCurrentEnv((config) => {
15
+ if (config.scheduledCommandHandlers[commandClass.name]) {
16
+ throw new Error(`A command called ${commandClass.name} is already registered.
17
+ If you think that this is an error, try performing a clean build.`);
18
+ }
19
+ config.scheduledCommandHandlers[commandClass.name] = {
20
+ class: commandClass,
21
+ scheduledOn: attributes,
22
+ };
23
+ });
24
+ };
25
+ }
@@ -0,0 +1,36 @@
1
+ import { Class, AnyClass, Instance } from '@magek/common';
2
+ /**
3
+ * Stage 3 method decorator context
4
+ */
5
+ interface Stage3MethodContext {
6
+ kind: 'method';
7
+ name: string | symbol;
8
+ static: boolean;
9
+ private: boolean;
10
+ metadata: Record<string | symbol, unknown>;
11
+ addInitializer?: (initializer: () => void) => void;
12
+ }
13
+ /**
14
+ * Stage 3 class decorator context
15
+ */
16
+ interface Stage3ClassContext {
17
+ kind: 'class';
18
+ name: string | undefined;
19
+ metadata: Record<string | symbol, unknown>;
20
+ addInitializer?: (initializer: () => void) => void;
21
+ }
22
+ /**
23
+ * **NOTE:** Using this decorator for read model migrations is deprecated. Prefer using `@DataMigration` instead.
24
+ */
25
+ export declare function SchemaMigration(conceptClass: AnyClass): (schemaMigrationClass: AnyClass, context?: Stage3ClassContext) => void;
26
+ /**
27
+ * Decorator to tell Magek the version you are migrating to
28
+ * @param toVersion
29
+ * @param props
30
+ */
31
+ export declare function ToVersion<TOldSchema, TNewSchema>(toVersion: number, props: {
32
+ fromSchema: Class<TOldSchema>;
33
+ toSchema: Class<TNewSchema>;
34
+ }): (migrationInstanceOrMethod: Instance | Function, propertyNameOrContext: string | Stage3MethodContext, propertyDescriptor?: MigrationMethod<TOldSchema, TNewSchema>) => void;
35
+ type MigrationMethod<TOldSchema, TNewSchema> = TypedPropertyDescriptor<(old: TOldSchema) => Promise<TNewSchema>>;
36
+ export {};
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SchemaMigration = SchemaMigration;
4
+ exports.ToVersion = ToVersion;
5
+ const magek_1 = require("../magek");
6
+ const common_1 = require("@magek/common");
7
+ const migrationMethodsMetadataKey = 'magek:migrationsMethods';
8
+ /**
9
+ * Type guard to detect Stage 3 method decorator context
10
+ */
11
+ function isStage3MethodContext(arg) {
12
+ return (arg !== null &&
13
+ typeof arg === 'object' &&
14
+ 'kind' in arg &&
15
+ arg.kind === 'method' &&
16
+ 'name' in arg);
17
+ }
18
+ /**
19
+ * Type guard to detect Stage 3 class decorator context
20
+ */
21
+ function isStage3ClassContext(arg) {
22
+ return (arg !== null &&
23
+ typeof arg === 'object' &&
24
+ 'kind' in arg &&
25
+ arg.kind === 'class' &&
26
+ 'metadata' in arg);
27
+ }
28
+ // Symbol for storing migration metadata in Stage 3 decorator context.metadata
29
+ const MIGRATIONS_METADATA_KEY = Symbol.for('magek:migrationsMethods');
30
+ /**
31
+ * **NOTE:** Using this decorator for read model migrations is deprecated. Prefer using `@DataMigration` instead.
32
+ */
33
+ function SchemaMigration(conceptClass) {
34
+ return (schemaMigrationClass, context) => {
35
+ magek_1.Magek.configureCurrentEnv((config) => {
36
+ const conceptMigrations = getConceptMigrations(config, conceptClass);
37
+ // Get migration methods - for Stage 3, read from context.metadata first
38
+ let migrationMethodsMetadata;
39
+ if (isStage3ClassContext(context)) {
40
+ // Stage 3: read from context.metadata
41
+ migrationMethodsMetadata =
42
+ context.metadata[MIGRATIONS_METADATA_KEY] || [];
43
+ // Update each metadata entry with the actual class reference
44
+ migrationMethodsMetadata = migrationMethodsMetadata.map((m) => ({
45
+ ...m,
46
+ migrationClass: schemaMigrationClass,
47
+ }));
48
+ }
49
+ else {
50
+ // Legacy: read from Reflect.getMetadata
51
+ migrationMethodsMetadata = getMigrationMethods(schemaMigrationClass);
52
+ }
53
+ if (!migrationMethodsMetadata || migrationMethodsMetadata.length === 0) {
54
+ throw new Error('No migration methods found in this class. Define at least one migration and annotate it with @ToVersion()');
55
+ }
56
+ for (const schemaMigrationMetadata of migrationMethodsMetadata) {
57
+ if (conceptMigrations.has(schemaMigrationMetadata.toVersion)) {
58
+ throw new Error(`Found duplicated migration for '${conceptClass.name}' in migration class '${schemaMigrationClass.name}': ` +
59
+ `There is an already defined migration for version ${schemaMigrationMetadata.toVersion}`);
60
+ }
61
+ conceptMigrations.set(schemaMigrationMetadata.toVersion, schemaMigrationMetadata);
62
+ }
63
+ });
64
+ };
65
+ }
66
+ function getConceptMigrations(config, conceptClass) {
67
+ if (!config.schemaMigrations[conceptClass.name]) {
68
+ config.schemaMigrations[conceptClass.name] = new Map();
69
+ }
70
+ return config.schemaMigrations[conceptClass.name];
71
+ }
72
+ function getMigrationMethods(migrationClass) {
73
+ const migrationMethods = (0, common_1.getMetadata)(migrationMethodsMetadataKey, migrationClass);
74
+ if (!migrationMethods || migrationMethods.length == 0) {
75
+ throw new Error('No migration methods found in this class. Define at least one migration and annotate it with @ToVersion()');
76
+ }
77
+ return migrationMethods;
78
+ }
79
+ /**
80
+ * Decorator to tell Magek the version you are migrating to
81
+ * @param toVersion
82
+ * @param props
83
+ */
84
+ function ToVersion(toVersion, props) {
85
+ if (toVersion <= 1) {
86
+ throw new Error('Migration versions must always be greater than 1');
87
+ }
88
+ return (migrationInstanceOrMethod, propertyNameOrContext) => {
89
+ // Detect Stage 3 vs Legacy decorator
90
+ if (isStage3MethodContext(propertyNameOrContext)) {
91
+ // Stage 3 decorator - store in context.metadata so @SchemaMigration can read it
92
+ const context = propertyNameOrContext;
93
+ // Get or initialize the migrations array in context.metadata
94
+ let migrationMethods = context.metadata[MIGRATIONS_METADATA_KEY];
95
+ if (!migrationMethods) {
96
+ migrationMethods = [];
97
+ context.metadata[MIGRATIONS_METADATA_KEY] = migrationMethods;
98
+ }
99
+ // Add this migration (migrationClass will be set by @SchemaMigration)
100
+ migrationMethods.push({
101
+ migrationClass: undefined, // Will be set by @SchemaMigration
102
+ methodName: context.name.toString(),
103
+ toVersion,
104
+ fromSchema: props.fromSchema,
105
+ toSchema: props.toSchema,
106
+ });
107
+ // Also store in Reflect metadata for the standalone test case
108
+ if (context.addInitializer) {
109
+ context.addInitializer(function () {
110
+ const migrationClass = context.static ? this : this.constructor;
111
+ let reflectMethods = (0, common_1.getMetadata)(migrationMethodsMetadataKey, migrationClass);
112
+ if (!reflectMethods) {
113
+ reflectMethods = [];
114
+ }
115
+ reflectMethods.push({
116
+ migrationClass,
117
+ methodName: context.name.toString(),
118
+ toVersion,
119
+ fromSchema: props.fromSchema,
120
+ toSchema: props.toSchema,
121
+ });
122
+ (0, common_1.defineMetadata)(migrationMethodsMetadataKey, reflectMethods, migrationClass);
123
+ });
124
+ }
125
+ }
126
+ else {
127
+ // Legacy decorator
128
+ const migrationInstance = migrationInstanceOrMethod;
129
+ const propertyName = propertyNameOrContext;
130
+ const migrationClass = migrationInstance.constructor;
131
+ let migrationMethods = (0, common_1.getMetadata)(migrationMethodsMetadataKey, migrationClass);
132
+ if (!migrationMethods) {
133
+ migrationMethods = [];
134
+ }
135
+ migrationMethods.push({
136
+ migrationClass,
137
+ methodName: propertyName,
138
+ toVersion,
139
+ fromSchema: props.fromSchema,
140
+ toSchema: props.toSchema,
141
+ });
142
+ // Here we just store the information (version and method). All the checks will be done in the @Migrates decorator
143
+ (0, common_1.defineMetadata)(migrationMethodsMetadataKey, migrationMethods, migrationClass);
144
+ }
145
+ };
146
+ }
@@ -0,0 +1,28 @@
1
+ import { Class, ReadModelInterface, AnyClass } from '@magek/common';
2
+ /**
3
+ * Stage 3 field decorator context
4
+ */
5
+ interface Stage3FieldContext {
6
+ kind: 'field';
7
+ name: string | symbol;
8
+ static: boolean;
9
+ private: boolean;
10
+ metadata: Record<string | symbol, unknown>;
11
+ access?: {
12
+ get: () => unknown;
13
+ set: (value: unknown) => void;
14
+ };
15
+ addInitializer?: (initializer: () => void) => void;
16
+ }
17
+ /**
18
+ * Decorator to specify the sequencing key for a ReadModel.
19
+ * Can be used as both a parameter decorator and property decorator.
20
+ * Supports both legacy (experimentalDecorators) and Stage 3 decorators.
21
+ */
22
+ export declare function sequencedBy(target: Class<ReadModelInterface> | Object | undefined, propertyKeyOrContext?: string | symbol | Stage3FieldContext, parameterIndex?: number): void;
23
+ /**
24
+ * Transfer sequence key metadata from Stage 3 context to class.
25
+ * Called by the ReadModel class decorator.
26
+ */
27
+ export declare function transferSequenceKeyMetadata(classType: AnyClass, contextMetadata: Record<string | symbol, unknown>): void;
28
+ export {};
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sequencedBy = sequencedBy;
4
+ exports.transferSequenceKeyMetadata = transferSequenceKeyMetadata;
5
+ const magek_1 = require("../magek");
6
+ const metadata_1 = require("./metadata");
7
+ // Symbol for storing sequence key in Stage 3 decorator context.metadata
8
+ const SEQUENCE_KEY_SYMBOL = Symbol.for('magek:sequenceKey');
9
+ /**
10
+ * Type guard to detect Stage 3 field context
11
+ */
12
+ function isStage3FieldContext(arg) {
13
+ return (arg !== null &&
14
+ typeof arg === 'object' &&
15
+ 'kind' in arg &&
16
+ arg.kind === 'field' &&
17
+ 'name' in arg &&
18
+ 'metadata' in arg);
19
+ }
20
+ /**
21
+ * Register sequence key for a class
22
+ */
23
+ function registerSequenceKey(klass, propertyName) {
24
+ magek_1.Magek.configureCurrentEnv((config) => {
25
+ if (config.readModelSequenceKeys[klass.name] && config.readModelSequenceKeys[klass.name] !== propertyName) {
26
+ throw new Error(`Error trying to register a sort key named \`${propertyName}\` for class \`${klass.name}\`. It already had the sort key \`${config.readModelSequenceKeys[klass.name]}\` defined and only one sort key is allowed for each read model.`);
27
+ }
28
+ else {
29
+ config.readModelSequenceKeys[klass.name] = propertyName;
30
+ }
31
+ });
32
+ }
33
+ /**
34
+ * Decorator to specify the sequencing key for a ReadModel.
35
+ * Can be used as both a parameter decorator and property decorator.
36
+ * Supports both legacy (experimentalDecorators) and Stage 3 decorators.
37
+ */
38
+ function sequencedBy(target, propertyKeyOrContext, parameterIndex) {
39
+ // Detect Stage 3 field decorator
40
+ if (isStage3FieldContext(propertyKeyOrContext)) {
41
+ const context = propertyKeyOrContext;
42
+ const propertyName = String(context.name);
43
+ // Store the sequence key in context.metadata for ReadModel decorator to pick up
44
+ context.metadata[SEQUENCE_KEY_SYMBOL] = propertyName;
45
+ // Also use addInitializer to register immediately when class is defined
46
+ if (context.addInitializer) {
47
+ context.addInitializer(function () {
48
+ const klass = this.constructor;
49
+ registerSequenceKey(klass, propertyName);
50
+ });
51
+ }
52
+ return;
53
+ }
54
+ // Legacy decorator handling
55
+ const propertyKey = propertyKeyOrContext;
56
+ // Property decorator usage: @sequencedBy on a class property
57
+ if (propertyKey !== undefined && parameterIndex === undefined) {
58
+ const klass = target.constructor;
59
+ const propertyName = String(propertyKey);
60
+ registerSequenceKey(klass, propertyName);
61
+ }
62
+ // Parameter decorator usage: @sequencedBy on constructor parameter
63
+ else if (parameterIndex !== undefined) {
64
+ const klass = target;
65
+ const args = (0, metadata_1.getFunctionArguments)(klass);
66
+ const propertyName = args[parameterIndex];
67
+ registerSequenceKey(klass, propertyName);
68
+ }
69
+ }
70
+ /**
71
+ * Transfer sequence key metadata from Stage 3 context to class.
72
+ * Called by the ReadModel class decorator.
73
+ */
74
+ function transferSequenceKeyMetadata(classType, contextMetadata) {
75
+ const sequenceKey = contextMetadata[SEQUENCE_KEY_SYMBOL];
76
+ if (sequenceKey) {
77
+ registerSequenceKey(classType, sequenceKey);
78
+ }
79
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Transfer field metadata from Stage 3 decorator context.metadata to the class constructor.
3
+ * This is needed because Symbol.metadata is not available in Node.js, so Stage 3 decorators
4
+ * need an explicit step to make field metadata accessible on the class.
5
+ */
6
+ export declare function transferStage3FieldMetadata(classType: Function, contextMetadata: Record<string | symbol, unknown>): void;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.transferStage3FieldMetadata = transferStage3FieldMetadata;
4
+ // Symbol used by Stage 3 decorators to store field metadata
5
+ const FIELDS_KEY = Symbol.for('magek:fields');
6
+ /**
7
+ * Transfer field metadata from Stage 3 decorator context.metadata to the class constructor.
8
+ * This is needed because Symbol.metadata is not available in Node.js, so Stage 3 decorators
9
+ * need an explicit step to make field metadata accessible on the class.
10
+ */
11
+ function transferStage3FieldMetadata(classType, contextMetadata) {
12
+ const fields = contextMetadata[FIELDS_KEY];
13
+ if (fields && fields.length > 0) {
14
+ const ctorWithFields = classType;
15
+ if (!ctorWithFields.__magek_fields__) {
16
+ ctorWithFields.__magek_fields__ = [];
17
+ }
18
+ // Add fields that aren't already present
19
+ for (const field of fields) {
20
+ if (!ctorWithFields.__magek_fields__.some((f) => f.name === field.name)) {
21
+ ctorWithFields.__magek_fields__.push(field);
22
+ }
23
+ }
24
+ }
25
+ }