@nmshd/consumption 2.0.0-beta.21 → 2.0.0-beta.23

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 (30) hide show
  1. package/dist/buildInformation.js +4 -4
  2. package/dist/consumption/ConsumptionErrors.d.ts +2 -1
  3. package/dist/consumption/ConsumptionErrors.js +3 -0
  4. package/dist/consumption/ConsumptionErrors.js.map +1 -1
  5. package/dist/modules/attributes/AttributesController.d.ts +1 -0
  6. package/dist/modules/attributes/AttributesController.js +34 -6
  7. package/dist/modules/attributes/AttributesController.js.map +1 -1
  8. package/dist/modules/attributes/local/CreateLocalAttributeParams.d.ts +3 -0
  9. package/dist/modules/attributes/local/CreateLocalAttributeParams.js +6 -0
  10. package/dist/modules/attributes/local/CreateLocalAttributeParams.js.map +1 -1
  11. package/dist/modules/attributes/local/LocalAttribute.d.ts +15 -2
  12. package/dist/modules/attributes/local/LocalAttribute.js +25 -4
  13. package/dist/modules/attributes/local/LocalAttribute.js.map +1 -1
  14. package/dist/modules/requests/incoming/IncomingRequestsController.d.ts +1 -0
  15. package/dist/modules/requests/incoming/IncomingRequestsController.js +16 -7
  16. package/dist/modules/requests/incoming/IncomingRequestsController.js.map +1 -1
  17. package/dist/modules/requests/local/LocalRequest.d.ts +2 -0
  18. package/dist/modules/requests/local/LocalRequest.js +16 -0
  19. package/dist/modules/requests/local/LocalRequest.js.map +1 -1
  20. package/dist/modules/requests/local/LocalRequestStatus.d.ts +2 -1
  21. package/dist/modules/requests/local/LocalRequestStatus.js +1 -0
  22. package/dist/modules/requests/local/LocalRequestStatus.js.map +1 -1
  23. package/dist/modules/requests/outgoing/OutgoingRequestsController.d.ts +1 -0
  24. package/dist/modules/requests/outgoing/OutgoingRequestsController.js +23 -8
  25. package/dist/modules/requests/outgoing/OutgoingRequestsController.js.map +1 -1
  26. package/lib-web/nmshd.consumption.js +128 -29
  27. package/lib-web/nmshd.consumption.js.map +1 -1
  28. package/lib-web/nmshd.consumption.min.js +1 -1
  29. package/lib-web/nmshd.consumption.min.js.map +1 -1
  30. package/package.json +2 -2
@@ -17,10 +17,10 @@ const content_1 = __webpack_require__(/*! @nmshd/content */ "@nmshd/content");
17
17
  const crypto_1 = __webpack_require__(/*! @nmshd/crypto */ "@nmshd/crypto");
18
18
  const transport_1 = __webpack_require__(/*! @nmshd/transport */ "@nmshd/transport");
19
19
  exports.buildInformation = {
20
- version: "2.0.0-beta.21",
21
- build: "73",
22
- date: "2022-09-20T13:25:15+00:00",
23
- commit: "79868cf6eb51c013e5c41ecd77b3d12d8cfd1b0c",
20
+ version: "2.0.0-beta.23",
21
+ build: "75",
22
+ date: "2022-09-22T07:26:01+00:00",
23
+ commit: "d236f8080e45bc388cbf4bb982d662e47bfe96e7",
24
24
  dependencies: {"@js-soft/docdb-querytranslator":"^1.1.0","ts-simple-nameof":"^1.3.1"},
25
25
  libraries: {
26
26
  transport: transport_1.buildInformation,
@@ -178,6 +178,9 @@ class Attributes {
178
178
  predecessorNotFound(id) {
179
179
  return new transport_1.CoreError("error.consumption.attributes.predecessorNotFound", `Attribute with id '${id}' does not exist. Please use create instead.`);
180
180
  }
181
+ cannotSucceedAttributesWithAParent(parentId) {
182
+ return new transport_1.CoreError("error.consumption.attributes.cannotSucceedAttributesWithAParent", `The Attribute you want to succeed has a parent (id: ${parentId.toString()}). You cannot succeed Attributes with a parent. Instead, succeed the parent, which will implicitly succeed all its children.`);
183
+ }
181
184
  }
182
185
  class Requests {
183
186
  constructor() {
@@ -681,26 +684,54 @@ class AttributesController extends consumption_1.ConsumptionBaseController {
681
684
  return this.parseArray(attributes, LocalAttribute_1.LocalAttribute);
682
685
  }
683
686
  async createLocalAttribute(params) {
684
- const localAttribute = await LocalAttribute_1.LocalAttribute.fromAttribute(params.content);
687
+ const localAttribute = LocalAttribute_1.LocalAttribute.from({
688
+ id: await consumption_1.ConsumptionIds.attribute.generate(),
689
+ createdAt: transport_1.CoreDate.utc(),
690
+ content: params.content,
691
+ parentId: params.parentId
692
+ });
685
693
  await this.attributes.create(localAttribute);
694
+ if (localAttribute.content instanceof content_1.IdentityAttribute && // nested Local Attributes should only be created for Identity Attributes
695
+ localAttribute.content.value instanceof content_1.AbstractComplexValue) {
696
+ await this.createLocalAttributesForNestedAttributeValues(localAttribute);
697
+ }
686
698
  this.eventBus.publish(new events_1.AttributeCreatedEvent(this.identity.address.toString(), localAttribute));
687
699
  return localAttribute;
688
700
  }
701
+ async createLocalAttributesForNestedAttributeValues(localAttribute) {
702
+ if (!(localAttribute.content instanceof content_1.IdentityAttribute)) {
703
+ throw new Error("Only Identity Attributes are allowed here");
704
+ }
705
+ const attributeValueAsAny = localAttribute.content.value;
706
+ const nestedAttributeValues = Object.keys(localAttribute.content.value)
707
+ .map((k) => attributeValueAsAny[k])
708
+ .filter((p) => p instanceof content_1.AbstractAttributeValue);
709
+ for (const propertyValue of nestedAttributeValues) {
710
+ const nestedAttribute = content_1.IdentityAttribute.from({
711
+ ...localAttribute.content.toJSON(),
712
+ value: propertyValue.toJSON()
713
+ });
714
+ await this.createLocalAttribute({ content: nestedAttribute, parentId: localAttribute.id });
715
+ }
716
+ }
689
717
  async succeedLocalAttribute(params) {
690
718
  const parsedParams = SucceedLocalAttributeParams_1.SucceedLocalAttributeParams.from(params);
691
- const current = await this.attributes.findOne({
719
+ const currentAttributeDoc = await this.attributes.findOne({
692
720
  [(0, ts_simple_nameof_1.nameof)((c) => c.id)]: params.succeeds.toString()
693
721
  });
694
- if (!current) {
722
+ const currentAttribute = LocalAttribute_1.LocalAttribute.from(currentAttributeDoc);
723
+ if (currentAttribute.parentId) {
724
+ throw consumption_1.ConsumptionErrors.attributes.cannotSucceedAttributesWithAParent(parsedParams.succeeds.toString());
725
+ }
726
+ if (!currentAttributeDoc) {
695
727
  throw consumption_1.ConsumptionErrors.attributes.predecessorNotFound(parsedParams.succeeds.toString());
696
728
  }
697
729
  if (!parsedParams.successorContent.validFrom) {
698
730
  parsedParams.successorContent.validFrom = transport_1.CoreDate.utc();
699
731
  }
700
732
  const validFrom = parsedParams.successorContent.validFrom;
701
- const currentUpdated = LocalAttribute_1.LocalAttribute.from(current);
702
- currentUpdated.content.validTo = validFrom.subtract(1);
703
- await this.attributes.update(current, currentUpdated);
733
+ currentAttribute.content.validTo = validFrom.subtract(1);
734
+ await this.attributes.update(currentAttributeDoc, currentAttribute);
704
735
  const successor = await LocalAttribute_1.LocalAttribute.fromAttribute(parsedParams.successorContent, parsedParams.succeeds);
705
736
  await this.attributes.create(successor);
706
737
  this.eventBus.publish(new events_1.AttributeSucceededEvent(this.identity.address.toString(), successor));
@@ -965,6 +996,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
965
996
  exports.CreateLocalAttributeParams = void 0;
966
997
  const ts_serval_1 = __webpack_require__(/*! @js-soft/ts-serval */ "@js-soft/ts-serval");
967
998
  const content_1 = __webpack_require__(/*! @nmshd/content */ "@nmshd/content");
999
+ const transport_1 = __webpack_require__(/*! @nmshd/transport */ "@nmshd/transport");
968
1000
  class CreateLocalAttributeParams extends ts_serval_1.Serializable {
969
1001
  static from(value) {
970
1002
  return this.fromAny(value);
@@ -975,6 +1007,11 @@ __decorate([
975
1007
  (0, ts_serval_1.validate)(),
976
1008
  __metadata("design:type", Object)
977
1009
  ], CreateLocalAttributeParams.prototype, "content", void 0);
1010
+ __decorate([
1011
+ (0, ts_serval_1.serialize)({ optional: true }),
1012
+ (0, ts_serval_1.validate)(),
1013
+ __metadata("design:type", transport_1.CoreId)
1014
+ ], CreateLocalAttributeParams.prototype, "parentId", void 0);
978
1015
  exports.CreateLocalAttributeParams = CreateLocalAttributeParams;
979
1016
  //# sourceMappingURL=CreateLocalAttributeParams.js.map
980
1017
 
@@ -1123,19 +1160,35 @@ let LocalAttribute = class LocalAttribute extends transport_1.CoreSynchronizable
1123
1160
  isIdentityAttribute() {
1124
1161
  return this.content instanceof content_1.IdentityAttribute;
1125
1162
  }
1163
+ isRelationshipAttribute() {
1164
+ return this.content instanceof content_1.RelationshipAttribute;
1165
+ }
1126
1166
  isOwnedBy(identity) {
1127
1167
  return this.content.owner.equals(identity);
1128
1168
  }
1169
+ isRepositoryAttribute() {
1170
+ return this.isIdentityAttribute() && !this.isShared();
1171
+ }
1172
+ isShared() {
1173
+ return this.shareInfo !== undefined;
1174
+ }
1175
+ isSharedWith(address) {
1176
+ if (!this.isShared()) {
1177
+ return false;
1178
+ }
1179
+ return this.shareInfo.peer === address;
1180
+ }
1129
1181
  static from(value) {
1130
1182
  return this.fromAny(value);
1131
1183
  }
1132
- static async fromAttribute(attribute, succeeds, shareInfo, id) {
1184
+ static async fromAttribute(content, succeeds, shareInfo, id, parentId) {
1133
1185
  return this.from({
1134
1186
  id: id ?? (await consumption_1.ConsumptionIds.attribute.generate()),
1135
- content: attribute,
1136
1187
  createdAt: transport_1.CoreDate.utc(),
1137
- succeeds: succeeds,
1138
- shareInfo: shareInfo
1188
+ content,
1189
+ succeeds,
1190
+ shareInfo,
1191
+ parentId
1139
1192
  });
1140
1193
  }
1141
1194
  };
@@ -1164,6 +1217,11 @@ __decorate([
1164
1217
  (0, ts_serval_1.serialize)(),
1165
1218
  __metadata("design:type", LocalAttributeShareInfo_1.LocalAttributeShareInfo)
1166
1219
  ], LocalAttribute.prototype, "shareInfo", void 0);
1220
+ __decorate([
1221
+ (0, ts_serval_1.validate)({ nullable: true }),
1222
+ (0, ts_serval_1.serialize)(),
1223
+ __metadata("design:type", transport_1.CoreId)
1224
+ ], LocalAttribute.prototype, "parentId", void 0);
1167
1225
  LocalAttribute = __decorate([
1168
1226
  (0, ts_serval_1.type)("LocalAttribute")
1169
1227
  ], LocalAttribute);
@@ -2179,16 +2237,19 @@ class IncomingRequestsController extends consumption_1.ConsumptionBaseController
2179
2237
  return request;
2180
2238
  }
2181
2239
  async getIncomingRequests(query) {
2182
- query ??= {};
2183
- query.isOwn = false;
2184
- const requestDocs = await this.localRequests.find(query);
2185
- const requests = requestDocs.map((r) => LocalRequest_1.LocalRequest.from(r));
2186
- return requests;
2240
+ const requestDocs = await this.localRequests.find({
2241
+ ...query,
2242
+ isOwn: false
2243
+ });
2244
+ const requestPromises = requestDocs.map((r) => this.updateRequestExpiry(LocalRequest_1.LocalRequest.from(r)));
2245
+ return await Promise.all(requestPromises);
2187
2246
  }
2188
2247
  async getIncomingRequest(idIncomingRequest) {
2189
2248
  const requestDoc = await this.localRequests.findOne({ id: idIncomingRequest.toString(), isOwn: false });
2190
- const request = requestDoc ? LocalRequest_1.LocalRequest.from(requestDoc) : undefined;
2191
- return request;
2249
+ if (!requestDoc)
2250
+ return;
2251
+ const localRequest = LocalRequest_1.LocalRequest.from(requestDoc);
2252
+ return await this.updateRequestExpiry(localRequest);
2192
2253
  }
2193
2254
  async getOrThrow(id) {
2194
2255
  const request = await this.getIncomingRequest(transport_1.CoreId.from(id));
@@ -2209,6 +2270,12 @@ class IncomingRequestsController extends consumption_1.ConsumptionBaseController
2209
2270
  throw new Error(`Local Request has to be in status '${status.join("/")}'.`);
2210
2271
  }
2211
2272
  }
2273
+ async updateRequestExpiry(request) {
2274
+ const statusUpdated = request.updateStatusBasedOnExpiration();
2275
+ if (statusUpdated)
2276
+ await this.update(request);
2277
+ return request;
2278
+ }
2212
2279
  }
2213
2280
  exports.IncomingRequestsController = IncomingRequestsController;
2214
2281
  //# sourceMappingURL=IncomingRequestsController.js.map
@@ -3410,6 +3477,8 @@ LocalRequestSource = __decorate([
3410
3477
  exports.LocalRequestSource = LocalRequestSource;
3411
3478
  let LocalRequest = class LocalRequest extends transport_1.CoreSynchronizable {
3412
3479
  changeStatus(newStatus) {
3480
+ if (this.status === newStatus)
3481
+ throw new Error("cannot change status to the same status");
3413
3482
  const logEntry = LocalRequestStatusLogEntry_1.LocalRequestStatusLogEntry.from({
3414
3483
  createdAt: transport_1.CoreDate.utc(),
3415
3484
  oldStatus: this.status,
@@ -3428,6 +3497,20 @@ let LocalRequest = class LocalRequest extends transport_1.CoreSynchronizable {
3428
3497
  static from(value) {
3429
3498
  return this.fromAny(value);
3430
3499
  }
3500
+ isExpired(comparisonDate = transport_1.CoreDate.utc()) {
3501
+ if (!this.content.expiresAt)
3502
+ return false;
3503
+ return comparisonDate.isAfter(this.content.expiresAt.add({ seconds: 10 }));
3504
+ }
3505
+ updateStatusBasedOnExpiration(comparisonDate = transport_1.CoreDate.utc()) {
3506
+ if (this.status === LocalRequestStatus_1.LocalRequestStatus.Completed || this.status === LocalRequestStatus_1.LocalRequestStatus.Expired)
3507
+ return false;
3508
+ if (this.isExpired(comparisonDate)) {
3509
+ this.changeStatus(LocalRequestStatus_1.LocalRequestStatus.Expired);
3510
+ return true;
3511
+ }
3512
+ return false;
3513
+ }
3431
3514
  };
3432
3515
  __decorate([
3433
3516
  (0, ts_serval_1.serialize)(),
@@ -3495,6 +3578,7 @@ var LocalRequestStatus;
3495
3578
  LocalRequestStatus["ManualDecisionRequired"] = "ManualDecisionRequired";
3496
3579
  LocalRequestStatus["Decided"] = "Decided";
3497
3580
  LocalRequestStatus["Completed"] = "Completed";
3581
+ LocalRequestStatus["Expired"] = "Expired";
3498
3582
  })(LocalRequestStatus = exports.LocalRequestStatus || (exports.LocalRequestStatus = {}));
3499
3583
  //# sourceMappingURL=LocalRequestStatus.js.map
3500
3584
 
@@ -3789,7 +3873,13 @@ class OutgoingRequestsController extends consumption_1.ConsumptionBaseController
3789
3873
  }
3790
3874
  async _complete(requestId, responseSourceObject, receivedResponse) {
3791
3875
  const request = await this.getOrThrow(requestId);
3792
- this.assertRequestStatus(request, LocalRequestStatus_1.LocalRequestStatus.Open);
3876
+ this.assertRequestStatus(request, LocalRequestStatus_1.LocalRequestStatus.Open, LocalRequestStatus_1.LocalRequestStatus.Expired);
3877
+ const responseSourceObjectCreationDate = responseSourceObject instanceof transport_1.Message
3878
+ ? responseSourceObject.cache.createdAt
3879
+ : responseSourceObject.request.createdAt;
3880
+ if (request.status === LocalRequestStatus_1.LocalRequestStatus.Expired && request.isExpired(responseSourceObjectCreationDate)) {
3881
+ throw new Error("Cannot complete an expired request with a response that was created before the expiration date");
3882
+ }
3793
3883
  const canComplete = await this.canComplete(request, receivedResponse);
3794
3884
  if (canComplete.isError()) {
3795
3885
  throw canComplete.error;
@@ -3859,11 +3949,12 @@ class OutgoingRequestsController extends consumption_1.ConsumptionBaseController
3859
3949
  await processor.applyIncomingResponseItem(responseItem, requestItem, request);
3860
3950
  }
3861
3951
  async getOutgoingRequests(query) {
3862
- query ??= {};
3863
- query.isOwn = true;
3864
- const requestDocs = await this.localRequests.find(query);
3865
- const requests = requestDocs.map((r) => LocalRequest_1.LocalRequest.from(r));
3866
- return requests;
3952
+ const requestDocs = await this.localRequests.find({
3953
+ ...query,
3954
+ isOwn: true
3955
+ });
3956
+ const requestPromises = requestDocs.map((r) => this.updateRequestExpiry(LocalRequest_1.LocalRequest.from(r)));
3957
+ return await Promise.all(requestPromises);
3867
3958
  }
3868
3959
  async discardOutgoingRequest(id) {
3869
3960
  const request = await this.getOrThrow(id);
@@ -3872,8 +3963,10 @@ class OutgoingRequestsController extends consumption_1.ConsumptionBaseController
3872
3963
  }
3873
3964
  async getOutgoingRequest(id) {
3874
3965
  const requestDoc = await this.localRequests.findOne({ id: id.toString(), isOwn: true });
3875
- const request = requestDoc ? LocalRequest_1.LocalRequest.from(requestDoc) : undefined;
3876
- return request;
3966
+ if (!requestDoc)
3967
+ return;
3968
+ const localRequest = LocalRequest_1.LocalRequest.from(requestDoc);
3969
+ return await this.updateRequestExpiry(localRequest);
3877
3970
  }
3878
3971
  async getOrThrow(id) {
3879
3972
  const request = await this.getOutgoingRequest(id);
@@ -3894,6 +3987,12 @@ class OutgoingRequestsController extends consumption_1.ConsumptionBaseController
3894
3987
  throw new Error(`Local Request has to be in status '${status.join("/")}'.`);
3895
3988
  }
3896
3989
  }
3990
+ async updateRequestExpiry(request) {
3991
+ const statusUpdated = request.updateStatusBasedOnExpiration();
3992
+ if (statusUpdated)
3993
+ await this.update(request);
3994
+ return request;
3995
+ }
3897
3996
  }
3898
3997
  exports.OutgoingRequestsController = OutgoingRequestsController;
3899
3998
  //# sourceMappingURL=OutgoingRequestsController.js.map