@solidstarters/solid-core 1.2.127 → 1.2.129

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 (35) hide show
  1. package/dist/entities/common.entity.js +2 -2
  2. package/dist/entities/common.entity.js.map +1 -1
  3. package/dist/filters/http-exception.filter.d.ts +2 -0
  4. package/dist/filters/http-exception.filter.d.ts.map +1 -1
  5. package/dist/filters/http-exception.filter.js +17 -16
  6. package/dist/filters/http-exception.filter.js.map +1 -1
  7. package/dist/helpers/schematic.service.js +1 -1
  8. package/dist/helpers/schematic.service.js.map +1 -1
  9. package/dist/helpers/solid-registry.d.ts.map +1 -1
  10. package/dist/helpers/solid-registry.js.map +1 -1
  11. package/dist/seeders/seed-data/solid-core-metadata.json +16 -3
  12. package/dist/services/authentication.service.js +1 -1
  13. package/dist/services/authentication.service.js.map +1 -1
  14. package/dist/services/model-metadata.service.d.ts +1 -0
  15. package/dist/services/model-metadata.service.d.ts.map +1 -1
  16. package/dist/services/model-metadata.service.js +15 -3
  17. package/dist/services/model-metadata.service.js.map +1 -1
  18. package/dist/solid-core.module.d.ts.map +1 -1
  19. package/dist/solid-core.module.js +5 -0
  20. package/dist/solid-core.module.js.map +1 -1
  21. package/dist/subscribers/computed-entity-field.subscriber.d.ts +6 -4
  22. package/dist/subscribers/computed-entity-field.subscriber.d.ts.map +1 -1
  23. package/dist/subscribers/computed-entity-field.subscriber.js +28 -23
  24. package/dist/subscribers/computed-entity-field.subscriber.js.map +1 -1
  25. package/dist/tsconfig.tsbuildinfo +1 -1
  26. package/package.json +1 -1
  27. package/src/entities/common.entity.ts +2 -2
  28. package/src/filters/http-exception.filter.ts +16 -15
  29. package/src/helpers/schematic.service.ts +1 -1
  30. package/src/helpers/solid-registry.ts +0 -10
  31. package/src/seeders/seed-data/solid-core-metadata.json +16 -3
  32. package/src/services/authentication.service.ts +1 -1
  33. package/src/services/model-metadata.service.ts +21 -23
  34. package/src/solid-core.module.ts +6 -0
  35. package/src/subscribers/computed-entity-field.subscriber.ts +45 -35
@@ -8,16 +8,18 @@ export declare class ComputedEntityFieldSubscriber implements EntitySubscriberIn
8
8
  private readonly dataSource;
9
9
  private readonly solidRegistry;
10
10
  private readonly computedFieldPublisher;
11
+ private readonly logger;
11
12
  constructor(dataSource: DataSource, solidRegistry: SolidRegistry, computedFieldPublisher: ComputedFieldEvaluationPublisher);
12
13
  beforeInsert(event: InsertEvent<any>): Promise<any>;
13
14
  beforeUpdate(event: UpdateEvent<any>): Promise<any>;
14
- afterInsert(event: InsertEvent<any>): Promise<void>;
15
- afterUpdate(event: UpdateEvent<any>): Promise<void>;
16
- afterRemove(event: any): Promise<void>;
15
+ afterInsert(event: InsertEvent<any>): void;
16
+ afterUpdate(event: UpdateEvent<any>): void;
17
+ afterRemove(event: any): void;
17
18
  private handleComputedFieldEvaluation;
18
19
  private handleComputedFieldEvaluationJob;
20
+ private getComputedFieldsForEvaluation;
21
+ private evaluateComputedField;
19
22
  private getComputedValue;
20
23
  private enqueueComputedFieldEvaluationJob;
21
- private getComputedFieldsToBeEvaluated;
22
24
  }
23
25
  //# sourceMappingURL=computed-entity-field.subscriber.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"computed-entity-field.subscriber.d.ts","sourceRoot":"","sources":["../../src/subscribers/computed-entity-field.subscriber.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAElF,OAAO,EAAE,gCAAgC,EAAE,MAAM,+DAA+D,CAAC;AACjH,OAAO,EAAE,UAAU,EAAE,yBAAyB,EAAmB,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAG3G,MAAM,WAAW,8BAA+B,SAAQ,qBAAqB;IACzE,cAAc,EAAE,GAAG,CAAC;CACvB;AAED,qBAEa,6BAA8B,YAAW,yBAAyB;IAGvE,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,sBAAsB;gBAFtB,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,aAAa,EAC5B,sBAAsB,EAAE,gCAAgC;IAKvE,YAAY,CAAC,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAInD,YAAY,CAAC,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAInD,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC;IAInC,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC;IAInC,WAAW,CAAC,KAAK,EAAE,GAAG;YAMd,6BAA6B;YAgB7B,gCAAgC;YAehC,gBAAgB;IAQ9B,OAAO,CAAC,iCAAiC;IAYzC,OAAO,CAAC,8BAA8B;CAQzC"}
1
+ {"version":3,"file":"computed-entity-field.subscriber.d.ts","sourceRoot":"","sources":["../../src/subscribers/computed-entity-field.subscriber.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAElF,OAAO,EAAE,gCAAgC,EAAE,MAAM,+DAA+D,CAAC;AACjH,OAAO,EAAE,UAAU,EAAE,yBAAyB,EAAmB,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAG3G,MAAM,WAAW,8BAA+B,SAAQ,qBAAqB;IACzE,cAAc,EAAE,GAAG,CAAC;CACvB;AAED,qBAEa,6BAA8B,YAAW,yBAAyB;IAIvE,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IAL3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqC;gBAGvC,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,aAAa,EAC5B,sBAAsB,EAAE,gCAAgC;IAKvE,YAAY,CAAC,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAInD,YAAY,CAAC,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAIzD,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC;IAInC,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC;IAInC,WAAW,CAAC,KAAK,EAAE,GAAG;YAMR,6BAA6B;IAe3C,OAAO,CAAC,gCAAgC;IAiBxC,OAAO,CAAC,8BAA8B;YASxB,qBAAqB;YAKrB,gBAAgB;IAY9B,OAAO,CAAC,iCAAiC;CAU5C"}
@@ -25,6 +25,7 @@ let ComputedEntityFieldSubscriber = class ComputedEntityFieldSubscriber {
25
25
  this.dataSource = dataSource;
26
26
  this.solidRegistry = solidRegistry;
27
27
  this.computedFieldPublisher = computedFieldPublisher;
28
+ this.logger = new common_1.Logger(this.constructor.name);
28
29
  this.dataSource.subscribers.push(this);
29
30
  }
30
31
  async beforeInsert(event) {
@@ -33,41 +34,49 @@ let ComputedEntityFieldSubscriber = class ComputedEntityFieldSubscriber {
33
34
  async beforeUpdate(event) {
34
35
  await this.handleComputedFieldEvaluation(event.databaseEntity, create_field_metadata_dto_1.ComputedFieldTriggerOperation.beforeUpdate);
35
36
  }
36
- async afterInsert(event) {
37
- await this.handleComputedFieldEvaluationJob(event.entity, create_field_metadata_dto_1.ComputedFieldTriggerOperation.afterInsert);
37
+ afterInsert(event) {
38
+ this.handleComputedFieldEvaluationJob(event.entity, create_field_metadata_dto_1.ComputedFieldTriggerOperation.afterInsert);
38
39
  }
39
- async afterUpdate(event) {
40
- await this.handleComputedFieldEvaluationJob(event.databaseEntity, create_field_metadata_dto_1.ComputedFieldTriggerOperation.afterUpdate);
40
+ afterUpdate(event) {
41
+ this.handleComputedFieldEvaluationJob(event.databaseEntity, create_field_metadata_dto_1.ComputedFieldTriggerOperation.afterUpdate);
41
42
  }
42
- async afterRemove(event) {
43
- await this.handleComputedFieldEvaluationJob(event.databaseEntity, create_field_metadata_dto_1.ComputedFieldTriggerOperation.afterRemove);
43
+ afterRemove(event) {
44
+ this.handleComputedFieldEvaluationJob(event.databaseEntity, create_field_metadata_dto_1.ComputedFieldTriggerOperation.afterRemove);
44
45
  }
45
46
  async handleComputedFieldEvaluation(entity, currentOperation) {
46
47
  if (!entity) {
47
48
  return;
48
49
  }
49
- const currentModelName = (0, strings_1.camelize)(entity.constructor.name);
50
- const computedFieldsTobeEvaluated = this.getComputedFieldsToBeEvaluated(this.solidRegistry.getComputedFieldMetadata(), currentOperation, currentModelName);
51
- for (const computedFieldMetadata of computedFieldsTobeEvaluated) {
52
- const computedValue = await this.getComputedValue(computedFieldMetadata, entity);
53
- entity[computedFieldMetadata.fieldName] = computedValue;
54
- }
50
+ const computedFieldsTobeEvaluated = this.getComputedFieldsForEvaluation(this.solidRegistry.getComputedFieldMetadata(), currentOperation, (0, strings_1.camelize)(entity.constructor.name));
51
+ await Promise.all(computedFieldsTobeEvaluated.map(c => this.evaluateComputedField(c, entity)));
55
52
  }
56
- async handleComputedFieldEvaluationJob(entity, currentOperation) {
53
+ handleComputedFieldEvaluationJob(entity, currentOperation) {
57
54
  if (!entity) {
58
55
  return;
59
56
  }
60
- const currentModelName = (0, strings_1.camelize)(entity.constructor.name);
61
- const computedFieldsTobeEvaluated = this.getComputedFieldsToBeEvaluated(this.solidRegistry.getComputedFieldMetadata(), currentOperation, currentModelName);
57
+ const computedFieldsTobeEvaluated = this.getComputedFieldsForEvaluation(this.solidRegistry.getComputedFieldMetadata(), currentOperation, (0, strings_1.camelize)(entity.constructor.name));
62
58
  for (const computedField of computedFieldsTobeEvaluated) {
63
59
  this.enqueueComputedFieldEvaluationJob(computedField, entity);
64
60
  }
65
61
  }
62
+ getComputedFieldsForEvaluation(computedFieldMetadata = [], currentOperation, currentModelName) {
63
+ return computedFieldMetadata.filter((computedField) => computedField.computedFieldTriggerConfig.some((trigger) => trigger.operations.includes(currentOperation) &&
64
+ trigger.modelName === currentModelName));
65
+ }
66
+ async evaluateComputedField(computedFieldMetadata, entity) {
67
+ const computedValue = await this.getComputedValue(computedFieldMetadata, entity);
68
+ entity[computedFieldMetadata.fieldName] = computedValue;
69
+ }
66
70
  async getComputedValue(computedFieldMetadata, entity) {
67
- const provider = this.solidRegistry.getComputedFieldProvider(computedFieldMetadata.computedFieldValueProviderName);
68
- const providerInstance = provider.instance;
69
- const computedValue = await providerInstance.preComputeValue(entity, computedFieldMetadata);
70
- return computedValue;
71
+ try {
72
+ const provider = this.solidRegistry.getComputedFieldProvider(computedFieldMetadata.computedFieldValueProviderName);
73
+ const providerInstance = provider.instance;
74
+ const computedValue = await providerInstance.preComputeValue(entity, computedFieldMetadata);
75
+ return computedValue;
76
+ }
77
+ catch (error) {
78
+ throw new common_1.InternalServerErrorException(`Error evaluating computed field ${computedFieldMetadata.fieldName} for model ${computedFieldMetadata.modelName} for triggered entity ${entity.constructor.name}: ${error.message}`);
79
+ }
71
80
  }
72
81
  enqueueComputedFieldEvaluationJob(computedField, databaseEntity) {
73
82
  const payload = {
@@ -78,10 +87,6 @@ let ComputedEntityFieldSubscriber = class ComputedEntityFieldSubscriber {
78
87
  payload
79
88
  });
80
89
  }
81
- getComputedFieldsToBeEvaluated(computedFieldMetadata, currentOperation, currentModelName) {
82
- return computedFieldMetadata.filter((computedField) => computedField.computedFieldTriggerConfig.some((trigger) => trigger.operations.includes(currentOperation) &&
83
- trigger.modelName === currentModelName));
84
- }
85
90
  };
86
91
  exports.ComputedEntityFieldSubscriber = ComputedEntityFieldSubscriber;
87
92
  exports.ComputedEntityFieldSubscriber = ComputedEntityFieldSubscriber = __decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"computed-entity-field.subscriber.js","sourceRoot":"","sources":["../../src/subscribers/computed-entity-field.subscriber.ts"],"names":[],"mappings":"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","sourcesContent":["import { camelize } from \"@angular-devkit/core/src/utils/strings\";\nimport { Injectable } from \"@nestjs/common\";\nimport { InjectDataSource } from \"@nestjs/typeorm\";\nimport { ComputedFieldTriggerOperation } from \"src/dtos/create-field-metadata.dto\";\nimport { ComputedFieldMetadata, SolidRegistry } from \"src/helpers/solid-registry\";\nimport { IEntityPreComputeFieldProvider } from \"src/interfaces\";\nimport { ComputedFieldEvaluationPublisher } from \"src/jobs/database/computed-field-evaluation-publisher.service\";\nimport { DataSource, EntitySubscriberInterface, EventSubscriber, InsertEvent, UpdateEvent } from \"typeorm\";\n\n// Create an interface i.e ComputedFieldEvaluationPayload which has same fields as the ComputedFieldMetadata and an additional field for the database entity\nexport interface ComputedFieldEvaluationPayload extends ComputedFieldMetadata {\n databaseEntity: any;\n}\n\n@Injectable()\n@EventSubscriber()\nexport class ComputedEntityFieldSubscriber implements EntitySubscriberInterface {\n constructor(\n @InjectDataSource()\n private readonly dataSource: DataSource,\n private readonly solidRegistry: SolidRegistry,\n private readonly computedFieldPublisher: ComputedFieldEvaluationPublisher,\n ) {\n this.dataSource.subscribers.push(this);\n }\n\n async beforeInsert(event: InsertEvent<any>): Promise<any> {\n await this.handleComputedFieldEvaluation(event.entity, ComputedFieldTriggerOperation.beforeInsert);\n }\n\n async beforeUpdate(event: UpdateEvent<any>): Promise<any>{\n await this.handleComputedFieldEvaluation(event.databaseEntity, ComputedFieldTriggerOperation.beforeUpdate);\n }\n\n async afterInsert(event: InsertEvent<any>) {\n await this.handleComputedFieldEvaluationJob(event.entity, ComputedFieldTriggerOperation.afterInsert);\n }\n\n async afterUpdate(event: UpdateEvent<any>) {\n await this.handleComputedFieldEvaluationJob(event.databaseEntity, ComputedFieldTriggerOperation.afterUpdate);\n }\n\n async afterRemove(event: any) {\n await this.handleComputedFieldEvaluationJob(event.databaseEntity, ComputedFieldTriggerOperation.afterRemove);\n }\n\n //FIXME: Need to add support for beforeRemmove, beforeSoftRemove, afterSoftRemove, beforeRecover, afterRecover\n\n private async handleComputedFieldEvaluation(entity: any, currentOperation: ComputedFieldTriggerOperation): Promise<void> {\n if (!entity) {\n return;\n }\n const currentModelName = camelize(entity.constructor.name); // Resolve the model name from the entity class name\n const computedFieldsTobeEvaluated = this.getComputedFieldsToBeEvaluated(\n this.solidRegistry.getComputedFieldMetadata(),\n currentOperation,\n currentModelName\n );\n for (const computedFieldMetadata of computedFieldsTobeEvaluated) {\n const computedValue = await this.getComputedValue(computedFieldMetadata, entity); //FIXME: There should some way to check/assert if the provider actually has a postComputeAndSaveValue\n entity[computedFieldMetadata.fieldName] = computedValue; // Set the computed value on the entity\n }\n }\n\n private async handleComputedFieldEvaluationJob(entity: any, currentOperation: ComputedFieldTriggerOperation): Promise<void> {\n if (!entity) {\n return;\n }\n const currentModelName = camelize(entity.constructor.name); //Resolve the model name from the entity class name\n const computedFieldsTobeEvaluated = this.getComputedFieldsToBeEvaluated(\n this.solidRegistry.getComputedFieldMetadata(),\n currentOperation,\n currentModelName\n );\n for (const computedField of computedFieldsTobeEvaluated) {\n this.enqueueComputedFieldEvaluationJob(computedField, entity);\n }\n }\n\n private async getComputedValue(computedFieldMetadata: ComputedFieldMetadata<any>, entity: any) {\n const provider = this.solidRegistry.getComputedFieldProvider(computedFieldMetadata.computedFieldValueProviderName);\n // Get the instance of the provider and assert it is of type IEntityComputedFieldProvider\n const providerInstance = provider.instance as IEntityPreComputeFieldProvider<any, any, any>; // IEntityComputedFieldProvider\n const computedValue = await providerInstance.preComputeValue(entity, computedFieldMetadata); //FIXME There should some way to check/assert if the provider actually has a postComputeAndSaveValue\n return computedValue;\n }\n\n private enqueueComputedFieldEvaluationJob(computedField: ComputedFieldMetadata<any>, databaseEntity: any) {\n const payload = {\n ...computedField,\n databaseEntity,\n };\n this.computedFieldPublisher.publish({\n payload\n });\n }\n\n // Based on the current model name and current operation, identify all the computed providers that need to be evaluated\n // Pass the database entity and the context to the provider of type IEntityComputedFieldProvider\n private getComputedFieldsToBeEvaluated(computedFieldMetadata: ComputedFieldMetadata[], currentOperation: ComputedFieldTriggerOperation, currentModelName: string) {\n return computedFieldMetadata.filter(\n (computedField) => computedField.computedFieldTriggerConfig.some(\n (trigger) => trigger.operations.includes(currentOperation) &&\n trigger.modelName === currentModelName\n )\n );\n }\n}"]}
1
+ {"version":3,"file":"computed-entity-field.subscriber.js","sourceRoot":"","sources":["../../src/subscribers/computed-entity-field.subscriber.ts"],"names":[],"mappings":"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","sourcesContent":["import { camelize } from \"@angular-devkit/core/src/utils/strings\";\nimport { Injectable, InternalServerErrorException, Logger } from \"@nestjs/common\";\nimport { InjectDataSource } from \"@nestjs/typeorm\";\nimport { ComputedFieldTriggerOperation } from \"src/dtos/create-field-metadata.dto\";\nimport { ComputedFieldMetadata, SolidRegistry } from \"src/helpers/solid-registry\";\nimport { IEntityPreComputeFieldProvider } from \"src/interfaces\";\nimport { ComputedFieldEvaluationPublisher } from \"src/jobs/database/computed-field-evaluation-publisher.service\";\nimport { DataSource, EntitySubscriberInterface, EventSubscriber, InsertEvent, UpdateEvent } from \"typeorm\";\n\n// Create an interface i.e ComputedFieldEvaluationPayload which has same fields as the ComputedFieldMetadata and an additional field for the database entity\nexport interface ComputedFieldEvaluationPayload extends ComputedFieldMetadata {\n databaseEntity: any;\n}\n\n@Injectable()\n@EventSubscriber()\nexport class ComputedEntityFieldSubscriber implements EntitySubscriberInterface {\n private readonly logger = new Logger(this.constructor.name);\n constructor(\n @InjectDataSource()\n private readonly dataSource: DataSource,\n private readonly solidRegistry: SolidRegistry,\n private readonly computedFieldPublisher: ComputedFieldEvaluationPublisher,\n ) {\n this.dataSource.subscribers.push(this);\n }\n\n async beforeInsert(event: InsertEvent<any>): Promise<any> {\n await this.handleComputedFieldEvaluation(event.entity, ComputedFieldTriggerOperation.beforeInsert);\n }\n\n async beforeUpdate(event: UpdateEvent<any>): Promise<any> {\n await this.handleComputedFieldEvaluation(event.databaseEntity, ComputedFieldTriggerOperation.beforeUpdate);\n }\n\n afterInsert(event: InsertEvent<any>) {\n this.handleComputedFieldEvaluationJob(event.entity, ComputedFieldTriggerOperation.afterInsert);\n }\n\n afterUpdate(event: UpdateEvent<any>) {\n this.handleComputedFieldEvaluationJob(event.databaseEntity, ComputedFieldTriggerOperation.afterUpdate);\n }\n\n afterRemove(event: any) {\n this.handleComputedFieldEvaluationJob(event.databaseEntity, ComputedFieldTriggerOperation.afterRemove);\n }\n\n //FIXME: Need to add support for beforeRemove, beforeSoftRemove, afterSoftRemove, beforeRecover, afterRecover\n\n private async handleComputedFieldEvaluation(entity: any, currentOperation: ComputedFieldTriggerOperation): Promise<void> {\n if (!entity) {\n return;\n }\n const computedFieldsTobeEvaluated = this.getComputedFieldsForEvaluation(\n this.solidRegistry.getComputedFieldMetadata(),\n currentOperation,\n camelize(entity.constructor.name)\n );\n //TODO: We can add a feature i.e dependsOn, where we can check if the computed field depends on other computed fields and evaluate them first\n await Promise.all(\n computedFieldsTobeEvaluated.map(c => this.evaluateComputedField(c, entity))\n )\n }\n\n private handleComputedFieldEvaluationJob(entity: any, currentOperation: ComputedFieldTriggerOperation) {\n if (!entity) {\n return;\n }\n const computedFieldsTobeEvaluated = this.getComputedFieldsForEvaluation(\n this.solidRegistry.getComputedFieldMetadata(),\n currentOperation,\n camelize(entity.constructor.name)\n );\n //TODO: We can add a feature i.e dependsOn, where we can check if the computed field depends on other computed fields and evaluate them first\n for (const computedField of computedFieldsTobeEvaluated) {\n this.enqueueComputedFieldEvaluationJob(computedField, entity);\n }\n }\n\n // Based on the current model name and current operation, identify all the computed providers that need to be evaluated\n // Pass the database entity and the context to the provider of type IEntityComputedFieldProvider\n private getComputedFieldsForEvaluation(computedFieldMetadata: ComputedFieldMetadata[] = [], currentOperation: ComputedFieldTriggerOperation, currentModelName: string) {\n return computedFieldMetadata.filter(\n (computedField) => computedField.computedFieldTriggerConfig.some(\n (trigger) => trigger.operations.includes(currentOperation) &&\n trigger.modelName === currentModelName\n )\n );\n }\n\n private async evaluateComputedField(computedFieldMetadata: ComputedFieldMetadata<any>, entity: any) {\n const computedValue = await this.getComputedValue(computedFieldMetadata, entity);\n entity[computedFieldMetadata.fieldName] = computedValue; // Set the computed value on the entity\n }\n\n private async getComputedValue(computedFieldMetadata: ComputedFieldMetadata<any>, entity: any) {\n try {\n const provider = this.solidRegistry.getComputedFieldProvider(computedFieldMetadata.computedFieldValueProviderName);\n // Get the instance of the provider and assert it is of type IEntityComputedFieldProvider\n const providerInstance = provider.instance as IEntityPreComputeFieldProvider<any, any, any>; // IEntityComputedFieldProvider\n const computedValue = await providerInstance.preComputeValue(entity, computedFieldMetadata); //FIXME There should some way to check/assert if the provider actually has a postComputeAndSaveValue\n return computedValue;\n } catch (error) {\n throw new InternalServerErrorException(`Error evaluating computed field ${computedFieldMetadata.fieldName} for model ${computedFieldMetadata.modelName} for triggered entity ${entity.constructor.name}: ${error.message}`);\n }\n }\n\n private enqueueComputedFieldEvaluationJob(computedField: ComputedFieldMetadata<any>, databaseEntity: any) {\n const payload = {\n ...computedField,\n databaseEntity,\n };\n this.computedFieldPublisher.publish({\n payload\n });\n }\n\n}"]}