@magek/core 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authorizer.js +1 -1
- package/dist/command-dispatcher.js +47 -41
- package/dist/core-concepts/data-migration/entities/data-migration-entity.js +5 -2
- package/dist/core-concepts/data-migration/events/data-migration-finished.js +3 -1
- package/dist/core-concepts/data-migration/events/data-migration-started.js +3 -1
- package/dist/core-concepts/data-migration/events/entity-migrated.js +4 -0
- package/dist/core-concepts/touch-entity/events/entity-touched.js +2 -0
- package/dist/data-migrations.js +59 -54
- package/dist/decorators/command.d.ts +4 -11
- package/dist/decorators/command.js +10 -18
- package/dist/decorators/data-migration.d.ts +4 -1
- package/dist/decorators/data-migration.js +3 -1
- package/dist/decorators/decorator-types.d.ts +50 -0
- package/dist/decorators/decorator-types.js +11 -0
- package/dist/decorators/decorator-utils.d.ts +1 -0
- package/dist/decorators/decorator-utils.js +2 -0
- package/dist/decorators/entity.d.ts +7 -15
- package/dist/decorators/entity.js +27 -37
- package/dist/decorators/event-handler.d.ts +11 -1
- package/dist/decorators/event-handler.js +13 -1
- package/dist/decorators/event.d.ts +4 -1
- package/dist/decorators/event.js +3 -2
- package/dist/decorators/field-metadata-reader.d.ts +8 -3
- package/dist/decorators/field-metadata-reader.js +61 -62
- package/dist/decorators/field.d.ts +23 -0
- package/dist/decorators/field.js +41 -0
- package/dist/decorators/global-error-handler.d.ts +10 -1
- package/dist/decorators/global-error-handler.js +9 -1
- package/dist/decorators/global-event-handler.d.ts +10 -1
- package/dist/decorators/global-event-handler.js +9 -1
- package/dist/decorators/health-sensor.d.ts +4 -1
- package/dist/decorators/health-sensor.js +3 -2
- package/dist/decorators/index.d.ts +4 -0
- package/dist/decorators/index.js +3 -0
- package/dist/decorators/metadata.d.ts +17 -1
- package/dist/decorators/metadata.js +22 -22
- package/dist/decorators/non-exposed.d.ts +13 -2
- package/dist/decorators/non-exposed.js +22 -20
- package/dist/decorators/notification.d.ts +6 -18
- package/dist/decorators/notification.js +10 -50
- package/dist/decorators/projects.d.ts +5 -18
- package/dist/decorators/projects.js +23 -54
- package/dist/decorators/query.d.ts +11 -1
- package/dist/decorators/query.js +18 -4
- package/dist/decorators/read-model.d.ts +13 -27
- package/dist/decorators/read-model.js +45 -77
- package/dist/decorators/returns.d.ts +37 -0
- package/dist/decorators/returns.js +154 -0
- package/dist/decorators/role.d.ts +9 -3
- package/dist/decorators/role.js +8 -3
- package/dist/decorators/scheduled-command.d.ts +4 -1
- package/dist/decorators/scheduled-command.js +3 -1
- package/dist/decorators/schema-migration.d.ts +11 -27
- package/dist/decorators/schema-migration.js +32 -77
- package/dist/decorators/sequenced-by.d.ts +7 -25
- package/dist/decorators/sequenced-by.js +11 -71
- package/dist/event-dispatcher.js +29 -24
- package/dist/event-processor.js +107 -103
- package/dist/event-stream-consumer.js +25 -20
- package/dist/event-stream-producer.js +22 -17
- package/dist/events-reader.js +1 -0
- package/dist/global-error-dispatcher.js +3 -2
- package/dist/graphql-dispatcher.js +161 -156
- package/dist/index.js +4 -0
- package/dist/instrumentation/decorator/trace.d.ts +11 -3
- package/dist/instrumentation/decorator/trace.js +17 -71
- package/dist/magek.js +2 -2
- package/dist/query-dispatcher.js +2 -0
- package/dist/read-model-schema-migrator.js +71 -68
- package/dist/read-models-reader.js +178 -180
- package/dist/register-handler.js +3 -3
- package/dist/scheduled-command-dispatcher.js +48 -42
- package/dist/schema-migrator.js +63 -59
- package/dist/sensor/health/health-service.js +2 -1
- package/dist/services/event-store.js +221 -224
- package/dist/services/graphql/graphql-generator.js +11 -8
- package/dist/services/graphql/graphql-mutation-generator.js +4 -0
- package/dist/services/graphql/graphql-query-generator.js +14 -0
- package/dist/services/graphql/graphql-subcriptions-generator.js +7 -0
- package/dist/services/graphql/graphql-type-informer.js +4 -3
- package/dist/services/graphql/query-generators/graphql-query-by-keys-generator.js +4 -0
- package/dist/services/graphql/query-generators/graphql-query-events-generator.js +3 -0
- package/dist/services/graphql/query-generators/graphql-query-filters-generator.js +6 -0
- package/dist/services/graphql/query-generators/graphql-query-generator.js +4 -0
- package/dist/services/graphql/query-generators/graphql-query-listed-generator.js +7 -0
- package/dist/services/graphql/query-helpers/graphql-handled-fields-generator.js +5 -2
- package/dist/services/graphql/query-helpers/graphql-query-filter-arguments-builder.js +3 -0
- package/dist/services/graphql/query-helpers/graphql-query-filter-fields-builder.js +4 -0
- package/dist/services/graphql/query-helpers/graphql-query-sort-builder.js +4 -2
- package/dist/services/graphql/websocket-protocol/graphql-websocket-protocol.js +5 -3
- package/dist/services/pub-sub/read-model-pub-sub.js +1 -0
- package/dist/services/raw-events-parser.js +1 -1
- package/dist/services/read-model-store.js +20 -20
- package/dist/services/token-verifiers/jwks-uri-token-verifier.js +8 -4
- package/dist/services/token-verifiers/public-key-token-verifier.js +4 -2
- package/dist/services/token-verifiers/role-based-token-verifier.js +2 -1
- package/dist/services/token-verifiers/utilities.js +1 -1
- package/dist/subscribers-notifier.js +99 -92
- package/dist/token-verifier.js +2 -1
- package/dist/utils/promises.d.ts +25 -0
- package/dist/utils/promises.js +43 -0
- package/package.json +4 -4
- package/dist/decorators/stage3-utils.d.ts +0 -6
- package/dist/decorators/stage3-utils.js +0 -25
package/dist/authorizer.js
CHANGED
|
@@ -31,5 +31,5 @@ class MagekAuthorizer {
|
|
|
31
31
|
}
|
|
32
32
|
exports.MagekAuthorizer = MagekAuthorizer;
|
|
33
33
|
function userHasSomeRole(user, authorizedRoles) {
|
|
34
|
-
return authorizedRoles.some((roleClass) =>
|
|
34
|
+
return authorizedRoles.some((roleClass) => user.roles?.includes(roleClass.name));
|
|
35
35
|
}
|
|
@@ -8,48 +8,54 @@ const filter_helpers_1 = require("./services/filter-helpers");
|
|
|
8
8
|
const global_error_dispatcher_1 = require("./global-error-dispatcher");
|
|
9
9
|
const schema_migrator_1 = require("./schema-migrator");
|
|
10
10
|
const instrumentation_1 = require("./instrumentation");
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
throw new common_1.InvalidParameterError('The required command "version" was not present');
|
|
11
|
+
let MagekCommandDispatcher = (() => {
|
|
12
|
+
let _instanceExtraInitializers = [];
|
|
13
|
+
let _dispatchCommand_decorators;
|
|
14
|
+
return class MagekCommandDispatcher {
|
|
15
|
+
static {
|
|
16
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
17
|
+
_dispatchCommand_decorators = [(0, instrumentation_1.trace)(common_1.TraceActionTypes.COMMAND_HANDLER)];
|
|
18
|
+
tslib_1.__esDecorate(this, null, _dispatchCommand_decorators, { kind: "method", name: "dispatchCommand", static: false, private: false, access: { has: obj => "dispatchCommand" in obj, get: obj => obj.dispatchCommand }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
19
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
21
20
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
config = tslib_1.__runInitializers(this, _instanceExtraInitializers);
|
|
22
|
+
globalErrorDispatcher;
|
|
23
|
+
constructor(config) {
|
|
24
|
+
this.config = config;
|
|
25
|
+
this.globalErrorDispatcher = new global_error_dispatcher_1.MagekGlobalErrorDispatcher(config);
|
|
25
26
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
27
|
+
async dispatchCommand(commandEnvelope, context) {
|
|
28
|
+
const logger = (0, common_1.getLogger)(this.config, 'MagekCommandDispatcher#dispatchCommand');
|
|
29
|
+
logger.debug('Dispatching the following command envelope: ', commandEnvelope);
|
|
30
|
+
if (!commandEnvelope.version) {
|
|
31
|
+
throw new common_1.InvalidParameterError('The required command "version" was not present');
|
|
32
|
+
}
|
|
33
|
+
const commandMetadata = this.config.commandHandlers[commandEnvelope.typeName];
|
|
34
|
+
if (!commandMetadata) {
|
|
35
|
+
throw new common_1.NotFoundError(`Could not find a proper handler for ${commandEnvelope.typeName}`);
|
|
36
|
+
}
|
|
37
|
+
await commandMetadata.authorizer(commandEnvelope.currentUser, commandEnvelope);
|
|
38
|
+
const commandClass = commandMetadata.class;
|
|
39
|
+
logger.debug('Found the following command:', commandClass.name);
|
|
40
|
+
const migratedCommandEnvelope = await new schema_migrator_1.SchemaMigrator(this.config).migrate(commandEnvelope);
|
|
41
|
+
let result;
|
|
42
|
+
const register = new common_1.Register(migratedCommandEnvelope.requestID, context.responseHeaders, register_handler_1.RegisterHandler.flush, migratedCommandEnvelope.currentUser, migratedCommandEnvelope.context);
|
|
43
|
+
try {
|
|
44
|
+
const commandInput = await (0, filter_helpers_1.applyBeforeFunctions)(migratedCommandEnvelope.value, commandMetadata.before, migratedCommandEnvelope.currentUser);
|
|
45
|
+
const commandInstance = (0, common_1.createInstance)(commandClass, commandInput);
|
|
46
|
+
logger.debug('Calling "handle" method on command: ', commandClass);
|
|
47
|
+
result = await commandClass.handle(commandInstance, register);
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
const e = err;
|
|
51
|
+
const error = await this.globalErrorDispatcher.dispatch(new common_1.CommandHandlerGlobalError(migratedCommandEnvelope, commandMetadata, e));
|
|
52
|
+
if (error)
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
logger.debug('Command dispatched with register: ', register);
|
|
56
|
+
await register_handler_1.RegisterHandler.handle(this.config, register);
|
|
57
|
+
return result;
|
|
37
58
|
}
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
}
|
|
59
|
+
};
|
|
60
|
+
})();
|
|
49
61
|
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);
|
|
@@ -3,6 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.MagekDataMigrationEntity = void 0;
|
|
4
4
|
const common_1 = require("@magek/common");
|
|
5
5
|
class MagekDataMigrationEntity {
|
|
6
|
+
id;
|
|
7
|
+
status;
|
|
8
|
+
lastUpdated;
|
|
9
|
+
duration;
|
|
6
10
|
constructor(id, status, lastUpdated, duration) {
|
|
7
11
|
this.id = id;
|
|
8
12
|
this.status = status;
|
|
@@ -16,9 +20,8 @@ class MagekDataMigrationEntity {
|
|
|
16
20
|
return new MagekDataMigrationEntity(event.name, common_1.DataMigrationStatus.RUNNING, event.lastUpdated, duration);
|
|
17
21
|
}
|
|
18
22
|
static finished(event, currentDataMigration) {
|
|
19
|
-
var _a;
|
|
20
23
|
const current = new Date();
|
|
21
|
-
if (
|
|
24
|
+
if (currentDataMigration.duration?.start) {
|
|
22
25
|
const start = currentDataMigration.duration.start;
|
|
23
26
|
const end = current.toISOString();
|
|
24
27
|
const startTime = Date.parse(start);
|
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MagekDataMigrationFinished = void 0;
|
|
4
4
|
class MagekDataMigrationFinished {
|
|
5
|
+
name;
|
|
6
|
+
lastUpdated;
|
|
5
7
|
constructor(name, lastUpdated) {
|
|
6
8
|
this.name = name;
|
|
7
|
-
this.lastUpdated = lastUpdated
|
|
9
|
+
this.lastUpdated = lastUpdated ?? new Date().toISOString();
|
|
8
10
|
}
|
|
9
11
|
entityID() {
|
|
10
12
|
return this.name;
|
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MagekDataMigrationStarted = void 0;
|
|
4
4
|
class MagekDataMigrationStarted {
|
|
5
|
+
name;
|
|
6
|
+
lastUpdated;
|
|
5
7
|
constructor(name, lastUpdated) {
|
|
6
8
|
this.name = name;
|
|
7
|
-
this.lastUpdated = lastUpdated
|
|
9
|
+
this.lastUpdated = lastUpdated ?? new Date().toISOString();
|
|
8
10
|
}
|
|
9
11
|
entityID() {
|
|
10
12
|
return this.name;
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MagekEntityMigrated = void 0;
|
|
4
4
|
class MagekEntityMigrated {
|
|
5
|
+
oldEntityName;
|
|
6
|
+
oldEntityId;
|
|
7
|
+
newEntityName;
|
|
8
|
+
newEntity;
|
|
5
9
|
constructor(oldEntityName, oldEntityId, newEntityName, newEntity) {
|
|
6
10
|
this.oldEntityName = oldEntityName;
|
|
7
11
|
this.oldEntityId = oldEntityId;
|
package/dist/data-migrations.js
CHANGED
|
@@ -10,64 +10,69 @@ const entity_migrated_1 = require("./core-concepts/data-migration/events/entity-
|
|
|
10
10
|
const index_1 = require("./index");
|
|
11
11
|
const data_migration_started_1 = require("./core-concepts/data-migration/events/data-migration-started");
|
|
12
12
|
const instrumentation_1 = require("./instrumentation");
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
13
|
+
let MagekDataMigrations = (() => {
|
|
14
|
+
let _staticExtraInitializers = [];
|
|
15
|
+
let _static_run_decorators;
|
|
16
|
+
return class MagekDataMigrations {
|
|
17
|
+
static {
|
|
18
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
19
|
+
_static_run_decorators = [(0, instrumentation_1.trace)(common_1.TraceActionTypes.MIGRATION_RUN)];
|
|
20
|
+
tslib_1.__esDecorate(this, null, _static_run_decorators, { kind: "method", name: "run", static: true, private: false, access: { has: obj => "run" in obj, get: obj => obj.run }, metadata: _metadata }, null, _staticExtraInitializers);
|
|
21
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
22
|
+
tslib_1.__runInitializers(this, _staticExtraInitializers);
|
|
22
23
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
static async run() {
|
|
25
|
+
const config = index_1.Magek.config;
|
|
26
|
+
const logger = (0, common_1.getLogger)(config, 'MagekDataMigrationDispatcher#dispatch');
|
|
27
|
+
let migrating = false;
|
|
28
|
+
const configuredMigrations = config.dataMigrationHandlers;
|
|
29
|
+
if (Object.keys(configuredMigrations).length === 0) {
|
|
30
|
+
logger.debug('No defined migrations found. Skipping...');
|
|
31
|
+
return false;
|
|
31
32
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
const sortedConfiguredMigrations = MagekDataMigrations.sortConfiguredMigrations(configuredMigrations);
|
|
34
|
+
const eventStore = new event_store_1.EventStore(config);
|
|
35
|
+
for (const configuredMigration of Object.values(sortedConfiguredMigrations)) {
|
|
36
|
+
const migrationEntityForConfiguredMigration = await eventStore.fetchEntitySnapshot(data_migration_entity_1.MagekDataMigrationEntity.name, configuredMigration.class.name);
|
|
37
|
+
if (!migrationEntityForConfiguredMigration) {
|
|
38
|
+
logger.debug('Not found running or finished migrations for the DataMigration', configuredMigration);
|
|
36
39
|
migrating = true;
|
|
40
|
+
await MagekDataMigrations.migrate(configuredMigration);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
const dataMigrationEntity = migrationEntityForConfiguredMigration.value;
|
|
44
|
+
if (dataMigrationEntity.status === common_1.DataMigrationStatus.RUNNING) {
|
|
45
|
+
logger.debug('Found running migrations for the DataMigration', configuredMigration);
|
|
46
|
+
migrating = true;
|
|
47
|
+
}
|
|
37
48
|
}
|
|
38
49
|
}
|
|
50
|
+
return migrating;
|
|
51
|
+
}
|
|
52
|
+
static migrateEntity(oldEntityName, oldEntityId, newEntity) {
|
|
53
|
+
const requestID = common_1.UUID.generate();
|
|
54
|
+
const register = new common_1.Register(requestID, {}, register_handler_1.RegisterHandler.flush);
|
|
55
|
+
register.events(new entity_migrated_1.MagekEntityMigrated(oldEntityName, oldEntityId, newEntity.constructor.name, newEntity));
|
|
56
|
+
return register_handler_1.RegisterHandler.handle(index_1.Magek.config, register);
|
|
57
|
+
}
|
|
58
|
+
static sortConfiguredMigrations(configuredMigrations) {
|
|
59
|
+
return Object.values(configuredMigrations).sort((a, b) => {
|
|
60
|
+
return a.migrationOptions.order - b.migrationOptions.order;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
static async migrate(migrationHandler) {
|
|
64
|
+
const startedRegister = new common_1.Register(common_1.UUID.generate(), {}, register_handler_1.RegisterHandler.flush);
|
|
65
|
+
await MagekDataMigrations.emitStarted(startedRegister, migrationHandler.class.name);
|
|
66
|
+
await register_handler_1.RegisterHandler.handle(index_1.Magek.config, startedRegister);
|
|
67
|
+
const finishedRegister = new common_1.Register(common_1.UUID.generate(), {}, register_handler_1.RegisterHandler.flush);
|
|
68
|
+
await migrationHandler.class.start(finishedRegister);
|
|
69
|
+
await register_handler_1.RegisterHandler.handle(index_1.Magek.config, finishedRegister);
|
|
70
|
+
}
|
|
71
|
+
static async emitStarted(register, configuredMigrationName) {
|
|
72
|
+
const logger = (0, common_1.getLogger)(index_1.Magek.config, 'MagekMigration#emitStarted');
|
|
73
|
+
logger.info('Migration started', configuredMigrationName);
|
|
74
|
+
register.events(new data_migration_started_1.MagekDataMigrationStarted(configuredMigrationName, new Date().toISOString()));
|
|
39
75
|
}
|
|
40
|
-
|
|
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
|
-
}
|
|
76
|
+
};
|
|
77
|
+
})();
|
|
67
78
|
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);
|
|
@@ -1,19 +1,12 @@
|
|
|
1
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
|
-
}
|
|
2
|
+
import { ClassDecoratorContext } from './decorator-utils';
|
|
11
3
|
/**
|
|
12
4
|
* Decorator to mark a class as a Magek Command.
|
|
13
5
|
* Commands represent user intentions and trigger business logic.
|
|
14
6
|
*
|
|
7
|
+
* Uses TC39 Stage 3 decorators.
|
|
8
|
+
*
|
|
15
9
|
* @param attributes - Role access control and filter hooks configuration
|
|
16
10
|
* @returns A class decorator function
|
|
17
11
|
*/
|
|
18
|
-
export declare function Command(attributes: CommandRoleAccess & CommandFilterHooks): <TCommand>(commandClass: CommandInterface<TCommand>, context
|
|
19
|
-
export {};
|
|
12
|
+
export declare function Command(attributes: CommandRoleAccess & CommandFilterHooks): <TCommand>(commandClass: CommandInterface<TCommand>, context: ClassDecoratorContext) => void;
|
|
@@ -4,44 +4,36 @@ exports.Command = Command;
|
|
|
4
4
|
const magek_1 = require("../magek");
|
|
5
5
|
const metadata_1 = require("./metadata");
|
|
6
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
7
|
/**
|
|
19
8
|
* Decorator to mark a class as a Magek Command.
|
|
20
9
|
* Commands represent user intentions and trigger business logic.
|
|
21
10
|
*
|
|
11
|
+
* Uses TC39 Stage 3 decorators.
|
|
12
|
+
*
|
|
22
13
|
* @param attributes - Role access control and filter hooks configuration
|
|
23
14
|
* @returns A class decorator function
|
|
24
15
|
*/
|
|
25
16
|
function Command(attributes) {
|
|
26
17
|
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
18
|
magek_1.Magek.configureCurrentEnv((config) => {
|
|
32
|
-
var _a;
|
|
33
19
|
if (config.commandHandlers[commandClass.name]) {
|
|
34
20
|
throw new Error(`A command called ${commandClass.name} is already registered.
|
|
35
21
|
If you think that this is an error, try performing a clean build.`);
|
|
36
22
|
}
|
|
37
|
-
|
|
23
|
+
// Pass context.metadata because Symbol.metadata isn't attached to class yet during decorator execution
|
|
24
|
+
const metadata = (0, metadata_1.getClassMetadata)(commandClass, context.metadata);
|
|
38
25
|
config.commandHandlers[commandClass.name] = {
|
|
39
26
|
class: commandClass,
|
|
40
27
|
authorizer: authorizer_1.MagekAuthorizer.build(attributes),
|
|
41
|
-
before:
|
|
28
|
+
before: attributes.before ?? [],
|
|
42
29
|
properties: metadata.fields,
|
|
43
30
|
methods: metadata.methods,
|
|
44
31
|
};
|
|
32
|
+
// Register non-exposed fields from context.metadata
|
|
33
|
+
const nonExposedFields = (0, metadata_1.getNonExposedFields)(context.metadata);
|
|
34
|
+
if (nonExposedFields.length > 0) {
|
|
35
|
+
config.nonExposedGraphQLMetadataKey[commandClass.name] = nonExposedFields;
|
|
36
|
+
}
|
|
45
37
|
});
|
|
46
38
|
};
|
|
47
39
|
}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { DataMigrationInterface, DataMigrationParameters } from '@magek/common';
|
|
2
|
+
import { ClassDecoratorContext } from './decorator-types';
|
|
2
3
|
/**
|
|
3
4
|
* Decorator to mark a class as a Magek Data Migration.
|
|
4
5
|
* Data migrations are background processes that update existing data in the database.
|
|
5
6
|
*
|
|
7
|
+
* Uses TC39 Stage 3 decorators.
|
|
8
|
+
*
|
|
6
9
|
* @param attributes - Migration configuration (e.g., execution order)
|
|
7
10
|
* @returns A class decorator function
|
|
8
11
|
*/
|
|
9
|
-
export declare function DataMigration(attributes: DataMigrationParameters): (dataMigrationClass: DataMigrationInterface) => void;
|
|
12
|
+
export declare function DataMigration(attributes: DataMigrationParameters): (dataMigrationClass: DataMigrationInterface, context: ClassDecoratorContext) => void;
|
|
@@ -6,11 +6,13 @@ const magek_1 = require("../magek");
|
|
|
6
6
|
* Decorator to mark a class as a Magek Data Migration.
|
|
7
7
|
* Data migrations are background processes that update existing data in the database.
|
|
8
8
|
*
|
|
9
|
+
* Uses TC39 Stage 3 decorators.
|
|
10
|
+
*
|
|
9
11
|
* @param attributes - Migration configuration (e.g., execution order)
|
|
10
12
|
* @returns A class decorator function
|
|
11
13
|
*/
|
|
12
14
|
function DataMigration(attributes) {
|
|
13
|
-
return (migrationClass) => {
|
|
15
|
+
return (migrationClass, _context) => {
|
|
14
16
|
magek_1.Magek.configureCurrentEnv((config) => {
|
|
15
17
|
if (config.dataMigrationHandlers[migrationClass.name]) {
|
|
16
18
|
throw new Error(`A data migration called ${migrationClass.name} is already registered.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/** Symbol used to store field metadata in decorator context.metadata */
|
|
2
|
+
export declare const FIELDS_METADATA_KEY: unique symbol;
|
|
3
|
+
/**
|
|
4
|
+
* Symbol.metadata - either the native one or TypeScript's polyfill.
|
|
5
|
+
* TypeScript uses Symbol.for('Symbol.metadata') when native isn't available.
|
|
6
|
+
*/
|
|
7
|
+
export declare const SYMBOL_METADATA: symbol;
|
|
8
|
+
export type DecoratorMetadataObject = Record<string | symbol, unknown>;
|
|
9
|
+
export interface ClassDecoratorContext {
|
|
10
|
+
kind: 'class';
|
|
11
|
+
name: string | undefined;
|
|
12
|
+
metadata?: DecoratorMetadataObject;
|
|
13
|
+
addInitializer?: (initializer: () => void) => void;
|
|
14
|
+
}
|
|
15
|
+
export interface FieldDecoratorContext {
|
|
16
|
+
kind: 'field';
|
|
17
|
+
name: string | symbol;
|
|
18
|
+
static: boolean;
|
|
19
|
+
private: boolean;
|
|
20
|
+
metadata?: DecoratorMetadataObject;
|
|
21
|
+
access?: {
|
|
22
|
+
get?: (object: any) => any;
|
|
23
|
+
set?: (object: any, value: any) => void;
|
|
24
|
+
};
|
|
25
|
+
addInitializer?: (initializer: () => void) => void;
|
|
26
|
+
}
|
|
27
|
+
export interface MethodDecoratorContext {
|
|
28
|
+
kind: 'method';
|
|
29
|
+
name: string | symbol;
|
|
30
|
+
static: boolean;
|
|
31
|
+
private: boolean;
|
|
32
|
+
metadata?: DecoratorMetadataObject;
|
|
33
|
+
access?: {
|
|
34
|
+
get?: (object: any) => any;
|
|
35
|
+
has?: (object: any) => boolean;
|
|
36
|
+
};
|
|
37
|
+
addInitializer?: (initializer: () => void) => void;
|
|
38
|
+
}
|
|
39
|
+
export interface GetterDecoratorContext {
|
|
40
|
+
kind: 'getter';
|
|
41
|
+
name: string | symbol;
|
|
42
|
+
static: boolean;
|
|
43
|
+
private: boolean;
|
|
44
|
+
metadata?: DecoratorMetadataObject;
|
|
45
|
+
access?: {
|
|
46
|
+
get?: (object: any) => any;
|
|
47
|
+
has?: (object: any) => boolean;
|
|
48
|
+
};
|
|
49
|
+
addInitializer?: (initializer: () => void) => void;
|
|
50
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============ SYMBOLS ============
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.SYMBOL_METADATA = exports.FIELDS_METADATA_KEY = void 0;
|
|
5
|
+
/** Symbol used to store field metadata in decorator context.metadata */
|
|
6
|
+
exports.FIELDS_METADATA_KEY = Symbol.for('magek:fields');
|
|
7
|
+
/**
|
|
8
|
+
* Symbol.metadata - either the native one or TypeScript's polyfill.
|
|
9
|
+
* TypeScript uses Symbol.for('Symbol.metadata') when native isn't available.
|
|
10
|
+
*/
|
|
11
|
+
exports.SYMBOL_METADATA = Symbol.metadata ?? Symbol.for('Symbol.metadata');
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { ClassDecoratorContext, FieldDecoratorContext, MethodDecoratorContext, GetterDecoratorContext, DecoratorMetadataObject, } from './decorator-types';
|
|
@@ -1,32 +1,24 @@
|
|
|
1
1
|
import { Class, EntityInterface, EventInterface, EventStreamRoleAccess, AnyClass } from '@magek/common';
|
|
2
|
+
import { ClassDecoratorContext, MethodDecoratorContext } from './decorator-utils';
|
|
2
3
|
type EntityAttributes = EventStreamRoleAccess;
|
|
3
4
|
type EntityDecoratorParam = AnyClass | EntityAttributes;
|
|
4
|
-
type EntityDecoratorResult<TEntity, TParam> = TParam extends EntityAttributes ? (entityClass: Class<TEntity
|
|
5
|
+
type EntityDecoratorResult<TEntity, TParam> = TParam extends EntityAttributes ? (entityClass: Class<TEntity>, context: ClassDecoratorContext) => void : void;
|
|
5
6
|
/**
|
|
6
7
|
* Decorator to mark a class as a Magek Entity.
|
|
7
8
|
* Entities represent the current state derived from events.
|
|
8
9
|
*
|
|
9
10
|
* @param classOrAttributes - Either the class itself or entity configuration attributes
|
|
11
|
+
* @param context - Decorator context (when used without parentheses)
|
|
10
12
|
* @returns A class decorator function or void if used without parentheses
|
|
11
13
|
*/
|
|
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
|
-
}
|
|
14
|
+
export declare function Entity<TEntity extends EntityInterface, TParam extends EntityDecoratorParam>(classOrAttributes: TParam, context?: ClassDecoratorContext): EntityDecoratorResult<TEntity, TParam>;
|
|
24
15
|
/**
|
|
25
16
|
* Decorator to register an entity class method as a reducer function
|
|
26
17
|
* for a specific event.
|
|
27
18
|
*
|
|
19
|
+
* Uses TC39 Stage 3 decorators.
|
|
20
|
+
*
|
|
28
21
|
* @param eventClass The event that this method will react to
|
|
29
22
|
*/
|
|
30
|
-
export declare function
|
|
31
|
-
type ReducerMethod<TEvent, TEntity> = TypedPropertyDescriptor<(event: TEvent, entity: TEntity) => TEntity> | TypedPropertyDescriptor<(event: TEvent, entity?: TEntity) => TEntity>;
|
|
23
|
+
export declare function reduces<TEvent extends EventInterface>(eventClass: Class<TEvent>): <TEntity>(entityClassOrMethod: Function, context: MethodDecoratorContext) => void;
|
|
32
24
|
export {};
|
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Entity = Entity;
|
|
4
|
-
exports.
|
|
4
|
+
exports.reduces = reduces;
|
|
5
5
|
const magek_1 = require("../magek");
|
|
6
6
|
const authorizer_1 = require("../authorizer");
|
|
7
|
+
const metadata_1 = require("./metadata");
|
|
7
8
|
/**
|
|
8
9
|
* Decorator to mark a class as a Magek Entity.
|
|
9
10
|
* Entities represent the current state derived from events.
|
|
10
11
|
*
|
|
11
12
|
* @param classOrAttributes - Either the class itself or entity configuration attributes
|
|
13
|
+
* @param context - Decorator context (when used without parentheses)
|
|
12
14
|
* @returns A class decorator function or void if used without parentheses
|
|
13
15
|
*/
|
|
14
|
-
function Entity(classOrAttributes) {
|
|
16
|
+
function Entity(classOrAttributes, context) {
|
|
15
17
|
let authorizeReadEvents;
|
|
16
18
|
// This function will be either returned or executed, depending on the parameters passed to the decorator
|
|
17
|
-
const mainLogicFunction = (entityClass) => {
|
|
19
|
+
const mainLogicFunction = (entityClass, ctx) => {
|
|
18
20
|
magek_1.Magek.configureCurrentEnv((config) => {
|
|
19
21
|
if (config.entities[entityClass.name]) {
|
|
20
22
|
throw new Error(`An entity called ${entityClass.name} is already registered
|
|
@@ -34,56 +36,44 @@ function Entity(classOrAttributes) {
|
|
|
34
36
|
class: entityClass,
|
|
35
37
|
eventStreamAuthorizer,
|
|
36
38
|
};
|
|
39
|
+
// Register non-exposed fields from context.metadata
|
|
40
|
+
const nonExposedFields = (0, metadata_1.getNonExposedFields)(ctx?.metadata);
|
|
41
|
+
if (nonExposedFields.length > 0) {
|
|
42
|
+
config.nonExposedGraphQLMetadataKey[entityClass.name] = nonExposedFields;
|
|
43
|
+
}
|
|
37
44
|
});
|
|
38
45
|
};
|
|
39
46
|
if (isEntityAttributes(classOrAttributes)) {
|
|
40
47
|
authorizeReadEvents = classOrAttributes.authorizeReadEvents;
|
|
41
|
-
return
|
|
48
|
+
return ((entityClass, ctx) => {
|
|
49
|
+
mainLogicFunction(entityClass, ctx);
|
|
50
|
+
});
|
|
42
51
|
}
|
|
43
|
-
return mainLogicFunction(classOrAttributes);
|
|
52
|
+
return mainLogicFunction(classOrAttributes, context);
|
|
44
53
|
}
|
|
45
54
|
function isEntityAttributes(param) {
|
|
46
55
|
return 'authorizeReadEvents' in param;
|
|
47
56
|
}
|
|
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
57
|
/**
|
|
59
58
|
* Decorator to register an entity class method as a reducer function
|
|
60
59
|
* for a specific event.
|
|
61
60
|
*
|
|
61
|
+
* Uses TC39 Stage 3 decorators.
|
|
62
|
+
*
|
|
62
63
|
* @param eventClass The event that this method will react to
|
|
63
64
|
*/
|
|
64
|
-
function
|
|
65
|
-
return (
|
|
66
|
-
//
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
context.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
registerReducer(eventClass.name, {
|
|
76
|
-
class: targetClass,
|
|
77
|
-
methodName: context.name.toString(),
|
|
78
|
-
});
|
|
65
|
+
function reduces(eventClass) {
|
|
66
|
+
return (_method, context) => {
|
|
67
|
+
// Stage 3 decorator - use addInitializer to get the class
|
|
68
|
+
if (context.addInitializer) {
|
|
69
|
+
context.addInitializer(function () {
|
|
70
|
+
// For static methods, 'this' is the class itself
|
|
71
|
+
// For instance methods, 'this' is an instance and we need this.constructor
|
|
72
|
+
const targetClass = context.static ? this : this.constructor;
|
|
73
|
+
registerReducer(eventClass.name, {
|
|
74
|
+
class: targetClass,
|
|
75
|
+
methodName: context.name.toString(),
|
|
79
76
|
});
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
// Legacy decorator
|
|
84
|
-
registerReducer(eventClass.name, {
|
|
85
|
-
class: entityClassOrMethod,
|
|
86
|
-
methodName: methodNameOrContext,
|
|
87
77
|
});
|
|
88
78
|
}
|
|
89
79
|
};
|