@nmshd/consumption 3.6.1 → 3.6.3

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.
@@ -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: "3.6.1",
21
- build: "115",
22
- date: "2023-11-08T13:15:42+00:00",
23
- commit: "c09ab8540f49c370264cd3323c866107ade67b0c",
20
+ version: "3.6.3",
21
+ build: "117",
22
+ date: "2023-11-13T13:10:20+00:00",
23
+ commit: "e1d5acf9736ab485a497c1e276a0e333bfa05067",
24
24
  dependencies: {"@js-soft/docdb-querytranslator":"^1.1.1","@nmshd/iql":"^0.0.4","ts-simple-nameof":"^1.3.1"},
25
25
  libraries: {
26
26
  transport: transport_1.buildInformation,
@@ -228,6 +228,9 @@ exports.CoreErrors = void 0;
228
228
  const ts_utils_1 = __webpack_require__(/*! @js-soft/ts-utils */ "./node_modules/@js-soft/ts-utils/dist/index.js");
229
229
  const transport_1 = __webpack_require__(/*! @nmshd/transport */ "@nmshd/transport");
230
230
  class Attributes {
231
+ genericValidationError(error) {
232
+ return new transport_1.CoreError("error.consumption.attributes.genericValidationError", "Validation failed during creation of object.", error, undefined, error instanceof Error ? error : undefined);
233
+ }
231
234
  successionMustNotChangeKey() {
232
235
  return new transport_1.CoreError("error.consumption.attributes.successionMustNotChangeKey", "The predecessor attribute's key does not match that of the successor. The succession of a relationship attribute must not change the key.");
233
236
  }
@@ -648,6 +651,7 @@ const ConsumptionIds_1 = __webpack_require__(/*! ../../consumption/ConsumptionId
648
651
  const CoreErrors_1 = __webpack_require__(/*! ../../consumption/CoreErrors */ "./dist/consumption/CoreErrors.js");
649
652
  const common_1 = __webpack_require__(/*! ../common */ "./dist/modules/common/index.js");
650
653
  const events_1 = __webpack_require__(/*! ./events */ "./dist/modules/attributes/events/index.js");
654
+ const AttributeSuccessorParams_1 = __webpack_require__(/*! ./local/AttributeSuccessorParams */ "./dist/modules/attributes/local/AttributeSuccessorParams.js");
651
655
  const CreateLocalAttributeParams_1 = __webpack_require__(/*! ./local/CreateLocalAttributeParams */ "./dist/modules/attributes/local/CreateLocalAttributeParams.js");
652
656
  const CreateSharedLocalAttributeCopyParams_1 = __webpack_require__(/*! ./local/CreateSharedLocalAttributeCopyParams */ "./dist/modules/attributes/local/CreateSharedLocalAttributeCopyParams.js");
653
657
  const LocalAttribute_1 = __webpack_require__(/*! ./local/LocalAttribute */ "./dist/modules/attributes/local/LocalAttribute.js");
@@ -864,96 +868,101 @@ class AttributesController extends ConsumptionBaseController_1.ConsumptionBaseCo
864
868
  this.eventBus.publish(new events_1.AttributeDeletedEvent(this.identity.address.toString(), attribute));
865
869
  }
866
870
  async succeedRepositoryAttribute(predecessorId, successorParams, validate = true) {
871
+ const parsedSuccessorParams = AttributeSuccessorParams_1.AttributeSuccessorParams.from(successorParams);
867
872
  if (validate) {
868
- const validationResult = await this.validateRepositoryAttributeSuccession(predecessorId, successorParams);
873
+ const validationResult = await this.validateRepositoryAttributeSuccession(predecessorId, parsedSuccessorParams);
869
874
  if (validationResult.isError()) {
870
875
  throw validationResult.error;
871
876
  }
872
877
  }
873
878
  const { predecessor, successor } = await this._succeedAttributeUnsafe(predecessorId, {
874
- id: successorParams.id,
875
- content: successorParams.content,
879
+ id: parsedSuccessorParams.id,
880
+ content: parsedSuccessorParams.content,
876
881
  succeeds: predecessorId,
877
- shareInfo: successorParams.shareInfo,
878
- parentId: successorParams.parentId,
879
- createdAt: successorParams.createdAt,
880
- succeededBy: successorParams.succeededBy
882
+ shareInfo: parsedSuccessorParams.shareInfo,
883
+ parentId: parsedSuccessorParams.parentId,
884
+ createdAt: parsedSuccessorParams.createdAt,
885
+ succeededBy: parsedSuccessorParams.succeededBy
881
886
  });
882
887
  this.eventBus.publish(new events_1.RepositoryAttributeSucceededEvent(this.identity.address.toString(), predecessor, successor));
883
888
  return { predecessor, successor };
884
889
  }
885
890
  async succeedOwnSharedIdentityAttribute(predecessorId, successorParams, validate = true) {
891
+ const parsedSuccessorParams = AttributeSuccessorParams_1.AttributeSuccessorParams.from(successorParams);
886
892
  if (validate) {
887
- const validationResult = await this.validateOwnSharedIdentityAttributeSuccession(predecessorId, successorParams);
893
+ const validationResult = await this.validateOwnSharedIdentityAttributeSuccession(predecessorId, parsedSuccessorParams);
888
894
  if (validationResult.isError()) {
889
895
  throw validationResult.error;
890
896
  }
891
897
  }
892
898
  const { predecessor, successor } = await this._succeedAttributeUnsafe(predecessorId, {
893
- id: successorParams.id,
894
- content: successorParams.content,
899
+ id: parsedSuccessorParams.id,
900
+ content: parsedSuccessorParams.content,
895
901
  succeeds: predecessorId,
896
- shareInfo: successorParams.shareInfo,
897
- parentId: successorParams.parentId,
898
- createdAt: successorParams.createdAt,
899
- succeededBy: successorParams.succeededBy
902
+ shareInfo: parsedSuccessorParams.shareInfo,
903
+ parentId: parsedSuccessorParams.parentId,
904
+ createdAt: parsedSuccessorParams.createdAt,
905
+ succeededBy: parsedSuccessorParams.succeededBy
900
906
  });
901
907
  this.eventBus.publish(new events_1.OwnSharedAttributeSucceededEvent(this.identity.address.toString(), predecessor, successor));
902
908
  return { predecessor, successor };
903
909
  }
904
910
  async succeedOwnSharedRelationshipAttribute(predecessorId, successorParams, validate = true) {
911
+ const parsedSuccessorParams = AttributeSuccessorParams_1.AttributeSuccessorParams.from(successorParams);
905
912
  if (validate) {
906
- const validationResult = await this.validateOwnSharedRelationshipAttributeSuccession(predecessorId, successorParams);
913
+ const validationResult = await this.validateOwnSharedRelationshipAttributeSuccession(predecessorId, parsedSuccessorParams);
907
914
  if (validationResult.isError()) {
908
915
  throw validationResult.error;
909
916
  }
910
917
  }
911
918
  const { predecessor, successor } = await this._succeedAttributeUnsafe(predecessorId, {
912
- id: successorParams.id,
913
- content: successorParams.content,
919
+ id: parsedSuccessorParams.id,
920
+ content: parsedSuccessorParams.content,
914
921
  succeeds: predecessorId,
915
- shareInfo: successorParams.shareInfo,
916
- parentId: successorParams.parentId,
917
- createdAt: successorParams.createdAt,
918
- succeededBy: successorParams.succeededBy
922
+ shareInfo: parsedSuccessorParams.shareInfo,
923
+ parentId: parsedSuccessorParams.parentId,
924
+ createdAt: parsedSuccessorParams.createdAt,
925
+ succeededBy: parsedSuccessorParams.succeededBy
919
926
  });
920
927
  this.eventBus.publish(new events_1.OwnSharedAttributeSucceededEvent(this.identity.address.toString(), predecessor, successor));
921
928
  return { predecessor, successor };
922
929
  }
923
930
  async succeedPeerSharedIdentityAttribute(predecessorId, successorParams, validate = true) {
931
+ const parsedSuccessorParams = AttributeSuccessorParams_1.AttributeSuccessorParams.from(successorParams);
924
932
  if (validate) {
925
- const validationResult = await this.validatePeerSharedIdentityAttributeSuccession(predecessorId, successorParams);
933
+ const validationResult = await this.validatePeerSharedIdentityAttributeSuccession(predecessorId, parsedSuccessorParams);
926
934
  if (validationResult.isError()) {
927
935
  throw validationResult.error;
928
936
  }
929
937
  }
930
938
  const { predecessor, successor } = await this._succeedAttributeUnsafe(predecessorId, {
931
- id: successorParams.id,
932
- content: successorParams.content,
939
+ id: parsedSuccessorParams.id,
940
+ content: parsedSuccessorParams.content,
933
941
  succeeds: predecessorId,
934
- shareInfo: successorParams.shareInfo,
935
- parentId: successorParams.parentId,
936
- createdAt: successorParams.createdAt,
937
- succeededBy: successorParams.succeededBy
942
+ shareInfo: parsedSuccessorParams.shareInfo,
943
+ parentId: parsedSuccessorParams.parentId,
944
+ createdAt: parsedSuccessorParams.createdAt,
945
+ succeededBy: parsedSuccessorParams.succeededBy
938
946
  });
939
947
  /* No succeeded attribute event fired here. This is done by the notification system. */
940
948
  return { predecessor, successor };
941
949
  }
942
950
  async succeedPeerSharedRelationshipAttribute(predecessorId, successorParams, validate = true) {
951
+ const parsedSuccessorParams = AttributeSuccessorParams_1.AttributeSuccessorParams.from(successorParams);
943
952
  if (validate) {
944
- const validationResult = await this.validatePeerSharedRelationshipAttributeSuccession(predecessorId, successorParams);
953
+ const validationResult = await this.validatePeerSharedRelationshipAttributeSuccession(predecessorId, parsedSuccessorParams);
945
954
  if (validationResult.isError()) {
946
955
  throw validationResult.error;
947
956
  }
948
957
  }
949
958
  const { predecessor, successor } = await this._succeedAttributeUnsafe(predecessorId, {
950
- id: successorParams.id,
951
- content: successorParams.content,
959
+ id: parsedSuccessorParams.id,
960
+ content: parsedSuccessorParams.content,
952
961
  succeeds: predecessorId,
953
- shareInfo: successorParams.shareInfo,
954
- parentId: successorParams.parentId,
955
- createdAt: successorParams.createdAt,
956
- succeededBy: successorParams.succeededBy
962
+ shareInfo: parsedSuccessorParams.shareInfo,
963
+ parentId: parsedSuccessorParams.parentId,
964
+ createdAt: parsedSuccessorParams.createdAt,
965
+ succeededBy: parsedSuccessorParams.succeededBy
957
966
  });
958
967
  /* No succeeded attribute event fired here. This is done by the notification system. */
959
968
  return { predecessor, successor };
@@ -974,18 +983,25 @@ class AttributesController extends ConsumptionBaseController_1.ConsumptionBaseCo
974
983
  return { predecessor, successor };
975
984
  }
976
985
  async validateRepositoryAttributeSuccession(predecessorId, successorParams) {
977
- const commonValidation = await this.validateAttributeSuccessionCommon(predecessorId, successorParams);
986
+ let parsedSuccessorParams;
987
+ try {
988
+ parsedSuccessorParams = AttributeSuccessorParams_1.AttributeSuccessorParams.from(successorParams);
989
+ }
990
+ catch (e) {
991
+ return common_1.ValidationResult.error(CoreErrors_1.CoreErrors.attributes.genericValidationError(e));
992
+ }
993
+ const commonValidation = await this.validateAttributeSuccessionCommon(predecessorId, parsedSuccessorParams);
978
994
  if (commonValidation.isError())
979
995
  return commonValidation;
980
996
  const predecessor = (await this.getLocalAttribute(predecessorId));
981
997
  const successor = LocalAttribute_1.LocalAttribute.from({
982
- id: transport_1.CoreId.from(successorParams.id ?? "dummy"),
983
- content: successorParams.content,
984
- createdAt: successorParams.createdAt ?? transport_1.CoreDate.utc(),
985
- succeeds: successorParams.succeeds,
986
- succeededBy: successorParams.succeededBy,
987
- shareInfo: successorParams.shareInfo,
988
- parentId: successorParams.parentId
998
+ id: transport_1.CoreId.from(parsedSuccessorParams.id ?? "dummy"),
999
+ content: parsedSuccessorParams.content,
1000
+ createdAt: parsedSuccessorParams.createdAt ?? transport_1.CoreDate.utc(),
1001
+ succeeds: parsedSuccessorParams.succeeds,
1002
+ succeededBy: parsedSuccessorParams.succeededBy,
1003
+ shareInfo: parsedSuccessorParams.shareInfo,
1004
+ parentId: parsedSuccessorParams.parentId
989
1005
  });
990
1006
  if (!predecessor.isIdentityAttribute() || predecessor.isShared()) {
991
1007
  return common_1.ValidationResult.error(CoreErrors_1.CoreErrors.attributes.invalidPredecessor("Predecessor is not a valid repository attribute."));
@@ -996,18 +1012,25 @@ class AttributesController extends ConsumptionBaseController_1.ConsumptionBaseCo
996
1012
  return common_1.ValidationResult.success();
997
1013
  }
998
1014
  async validateOwnSharedIdentityAttributeSuccession(predecessorId, successorParams) {
999
- const commonValidation = await this.validateAttributeSuccessionCommon(predecessorId, successorParams);
1015
+ let parsedSuccessorParams;
1016
+ try {
1017
+ parsedSuccessorParams = AttributeSuccessorParams_1.AttributeSuccessorParams.from(successorParams);
1018
+ }
1019
+ catch (e) {
1020
+ return common_1.ValidationResult.error(CoreErrors_1.CoreErrors.attributes.genericValidationError(e));
1021
+ }
1022
+ const commonValidation = await this.validateAttributeSuccessionCommon(predecessorId, parsedSuccessorParams);
1000
1023
  if (commonValidation.isError())
1001
1024
  return commonValidation;
1002
1025
  const predecessor = (await this.getLocalAttribute(predecessorId));
1003
1026
  const successor = LocalAttribute_1.LocalAttribute.from({
1004
- id: transport_1.CoreId.from(successorParams.id ?? "dummy"),
1005
- content: successorParams.content,
1006
- createdAt: successorParams.createdAt ?? transport_1.CoreDate.utc(),
1007
- succeeds: successorParams.succeeds,
1008
- succeededBy: successorParams.succeededBy,
1009
- shareInfo: successorParams.shareInfo,
1010
- parentId: successorParams.parentId
1027
+ id: transport_1.CoreId.from(parsedSuccessorParams.id ?? "dummy"),
1028
+ content: parsedSuccessorParams.content,
1029
+ createdAt: parsedSuccessorParams.createdAt ?? transport_1.CoreDate.utc(),
1030
+ succeeds: parsedSuccessorParams.succeeds,
1031
+ succeededBy: parsedSuccessorParams.succeededBy,
1032
+ shareInfo: parsedSuccessorParams.shareInfo,
1033
+ parentId: parsedSuccessorParams.parentId
1011
1034
  });
1012
1035
  if (!predecessor.isOwnSharedIdentityAttribute(this.identity.address)) {
1013
1036
  return common_1.ValidationResult.error(CoreErrors_1.CoreErrors.attributes.invalidPredecessor("Predecessor is not a valid own shared identity attribute."));
@@ -1042,18 +1065,25 @@ class AttributesController extends ConsumptionBaseController_1.ConsumptionBaseCo
1042
1065
  return common_1.ValidationResult.success();
1043
1066
  }
1044
1067
  async validateOwnSharedRelationshipAttributeSuccession(predecessorId, successorParams) {
1045
- const commonValidation = await this.validateAttributeSuccessionCommon(predecessorId, successorParams);
1068
+ let parsedSuccessorParams;
1069
+ try {
1070
+ parsedSuccessorParams = AttributeSuccessorParams_1.AttributeSuccessorParams.from(successorParams);
1071
+ }
1072
+ catch (e) {
1073
+ return common_1.ValidationResult.error(CoreErrors_1.CoreErrors.attributes.genericValidationError(e));
1074
+ }
1075
+ const commonValidation = await this.validateAttributeSuccessionCommon(predecessorId, parsedSuccessorParams);
1046
1076
  if (commonValidation.isError())
1047
1077
  return commonValidation;
1048
1078
  const predecessor = (await this.getLocalAttribute(predecessorId));
1049
1079
  const successor = LocalAttribute_1.LocalAttribute.from({
1050
- id: transport_1.CoreId.from(successorParams.id ?? "dummy"),
1051
- content: successorParams.content,
1052
- createdAt: successorParams.createdAt ?? transport_1.CoreDate.utc(),
1053
- succeeds: successorParams.succeeds,
1054
- succeededBy: successorParams.succeededBy,
1055
- shareInfo: successorParams.shareInfo,
1056
- parentId: successorParams.parentId
1080
+ id: transport_1.CoreId.from(parsedSuccessorParams.id ?? "dummy"),
1081
+ content: parsedSuccessorParams.content,
1082
+ createdAt: parsedSuccessorParams.createdAt ?? transport_1.CoreDate.utc(),
1083
+ succeeds: parsedSuccessorParams.succeeds,
1084
+ succeededBy: parsedSuccessorParams.succeededBy,
1085
+ shareInfo: parsedSuccessorParams.shareInfo,
1086
+ parentId: parsedSuccessorParams.parentId
1057
1087
  });
1058
1088
  if (!predecessor.isOwnSharedRelationshipAttribute(this.identity.address)) {
1059
1089
  return common_1.ValidationResult.error(CoreErrors_1.CoreErrors.attributes.invalidPredecessor("Predecessor is not a valid own shared relationship attribute."));
@@ -1070,18 +1100,25 @@ class AttributesController extends ConsumptionBaseController_1.ConsumptionBaseCo
1070
1100
  return common_1.ValidationResult.success();
1071
1101
  }
1072
1102
  async validatePeerSharedIdentityAttributeSuccession(predecessorId, successorParams) {
1073
- const commonValidation = await this.validateAttributeSuccessionCommon(predecessorId, successorParams);
1103
+ let parsedSuccessorParams;
1104
+ try {
1105
+ parsedSuccessorParams = AttributeSuccessorParams_1.AttributeSuccessorParams.from(successorParams);
1106
+ }
1107
+ catch (e) {
1108
+ return common_1.ValidationResult.error(CoreErrors_1.CoreErrors.attributes.genericValidationError(e));
1109
+ }
1110
+ const commonValidation = await this.validateAttributeSuccessionCommon(predecessorId, parsedSuccessorParams);
1074
1111
  if (commonValidation.isError())
1075
1112
  return commonValidation;
1076
1113
  const predecessor = (await this.getLocalAttribute(predecessorId));
1077
1114
  const successor = LocalAttribute_1.LocalAttribute.from({
1078
- id: transport_1.CoreId.from(successorParams.id ?? "dummy"),
1079
- content: successorParams.content,
1080
- createdAt: successorParams.createdAt ?? transport_1.CoreDate.utc(),
1081
- succeeds: successorParams.succeeds,
1082
- succeededBy: successorParams.succeededBy,
1083
- shareInfo: successorParams.shareInfo,
1084
- parentId: successorParams.parentId
1115
+ id: transport_1.CoreId.from(parsedSuccessorParams.id ?? "dummy"),
1116
+ content: parsedSuccessorParams.content,
1117
+ createdAt: parsedSuccessorParams.createdAt ?? transport_1.CoreDate.utc(),
1118
+ succeeds: parsedSuccessorParams.succeeds,
1119
+ succeededBy: parsedSuccessorParams.succeededBy,
1120
+ shareInfo: parsedSuccessorParams.shareInfo,
1121
+ parentId: parsedSuccessorParams.parentId
1085
1122
  });
1086
1123
  if (!predecessor.isPeerSharedIdentityAttribute()) {
1087
1124
  return common_1.ValidationResult.error(CoreErrors_1.CoreErrors.attributes.invalidPredecessor("Predecessor is not a valid peer shared identity attribute."));
@@ -1095,18 +1132,25 @@ class AttributesController extends ConsumptionBaseController_1.ConsumptionBaseCo
1095
1132
  return common_1.ValidationResult.success();
1096
1133
  }
1097
1134
  async validatePeerSharedRelationshipAttributeSuccession(predecessorId, successorParams) {
1098
- const commonValidation = await this.validateAttributeSuccessionCommon(predecessorId, successorParams);
1135
+ let parsedSuccessorParams;
1136
+ try {
1137
+ parsedSuccessorParams = AttributeSuccessorParams_1.AttributeSuccessorParams.from(successorParams);
1138
+ }
1139
+ catch (e) {
1140
+ return common_1.ValidationResult.error(CoreErrors_1.CoreErrors.attributes.genericValidationError(e));
1141
+ }
1142
+ const commonValidation = await this.validateAttributeSuccessionCommon(predecessorId, parsedSuccessorParams);
1099
1143
  if (commonValidation.isError())
1100
1144
  return commonValidation;
1101
1145
  const predecessor = (await this.getLocalAttribute(predecessorId));
1102
1146
  const successor = LocalAttribute_1.LocalAttribute.from({
1103
- id: transport_1.CoreId.from(successorParams.id ?? "dummy"),
1104
- content: successorParams.content,
1105
- createdAt: successorParams.createdAt ?? transport_1.CoreDate.utc(),
1106
- succeeds: successorParams.succeeds,
1107
- succeededBy: successorParams.succeededBy,
1108
- shareInfo: successorParams.shareInfo,
1109
- parentId: successorParams.parentId
1147
+ id: transport_1.CoreId.from(parsedSuccessorParams.id ?? "dummy"),
1148
+ content: parsedSuccessorParams.content,
1149
+ createdAt: parsedSuccessorParams.createdAt ?? transport_1.CoreDate.utc(),
1150
+ succeeds: parsedSuccessorParams.succeeds,
1151
+ succeededBy: parsedSuccessorParams.succeededBy,
1152
+ shareInfo: parsedSuccessorParams.shareInfo,
1153
+ parentId: parsedSuccessorParams.parentId
1110
1154
  });
1111
1155
  if (!predecessor.isPeerSharedRelationshipAttribute()) {
1112
1156
  return common_1.ValidationResult.error(CoreErrors_1.CoreErrors.attributes.invalidPredecessor("Predecessor is not a valid peer shared relationship attribute."));
@@ -1123,17 +1167,24 @@ class AttributesController extends ConsumptionBaseController_1.ConsumptionBaseCo
1123
1167
  return common_1.ValidationResult.success();
1124
1168
  }
1125
1169
  async validateAttributeSuccessionCommon(predecessorId, successorParams) {
1170
+ let parsedSuccessorParams;
1171
+ try {
1172
+ parsedSuccessorParams = AttributeSuccessorParams_1.AttributeSuccessorParams.from(successorParams);
1173
+ }
1174
+ catch (e) {
1175
+ return common_1.ValidationResult.error(CoreErrors_1.CoreErrors.attributes.genericValidationError(e));
1176
+ }
1126
1177
  const successor = LocalAttribute_1.LocalAttribute.from({
1127
- id: transport_1.CoreId.from(successorParams.id ?? "dummy"),
1128
- content: successorParams.content,
1129
- createdAt: successorParams.createdAt ?? transport_1.CoreDate.utc(),
1130
- succeeds: successorParams.succeeds,
1131
- succeededBy: successorParams.succeededBy,
1132
- shareInfo: successorParams.shareInfo,
1133
- parentId: successorParams.parentId
1178
+ id: transport_1.CoreId.from(parsedSuccessorParams.id ?? "dummy"),
1179
+ content: parsedSuccessorParams.content,
1180
+ createdAt: parsedSuccessorParams.createdAt ?? transport_1.CoreDate.utc(),
1181
+ succeeds: parsedSuccessorParams.succeeds,
1182
+ succeededBy: parsedSuccessorParams.succeededBy,
1183
+ shareInfo: parsedSuccessorParams.shareInfo,
1184
+ parentId: parsedSuccessorParams.parentId
1134
1185
  });
1135
- if (typeof successorParams.id !== "undefined") {
1136
- const successor = await this.getLocalAttribute(transport_1.CoreId.from(successorParams.id));
1186
+ if (typeof parsedSuccessorParams.id !== "undefined") {
1187
+ const successor = await this.getLocalAttribute(transport_1.CoreId.from(parsedSuccessorParams.id));
1137
1188
  if (typeof successor !== "undefined") {
1138
1189
  return common_1.ValidationResult.error(CoreErrors_1.CoreErrors.attributes.successorMustNotYetExist());
1139
1190
  }
@@ -1154,7 +1205,7 @@ class AttributesController extends ConsumptionBaseController_1.ConsumptionBaseCo
1154
1205
  if (typeof predecessor.succeededBy !== "undefined") {
1155
1206
  return common_1.ValidationResult.error(CoreErrors_1.CoreErrors.attributes.cannotSucceedAttributesWithASuccessor(predecessor.succeededBy.toString()));
1156
1207
  }
1157
- if (predecessor.parentId) {
1208
+ if (typeof predecessor.parentId !== "undefined") {
1158
1209
  return common_1.ValidationResult.error(CoreErrors_1.CoreErrors.attributes.cannotSucceedPartOfComplexAttribute(predecessorId.toString()));
1159
1210
  }
1160
1211
  if (!predecessor.content.owner.equals(transport_1.CoreAddress.from(successor.content.owner))) {
@@ -1437,16 +1488,85 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
1437
1488
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1438
1489
  __exportStar(__webpack_require__(/*! ./AttributesController */ "./dist/modules/attributes/AttributesController.js"), exports);
1439
1490
  __exportStar(__webpack_require__(/*! ./events */ "./dist/modules/attributes/events/index.js"), exports);
1491
+ __exportStar(__webpack_require__(/*! ./local/AttributeSuccessorParams */ "./dist/modules/attributes/local/AttributeSuccessorParams.js"), exports);
1440
1492
  __exportStar(__webpack_require__(/*! ./local/CreateLocalAttributeParams */ "./dist/modules/attributes/local/CreateLocalAttributeParams.js"), exports);
1441
1493
  __exportStar(__webpack_require__(/*! ./local/CreatePeerLocalAttributeParams */ "./dist/modules/attributes/local/CreatePeerLocalAttributeParams.js"), exports);
1442
1494
  __exportStar(__webpack_require__(/*! ./local/CreateSharedLocalAttributeCopyParams */ "./dist/modules/attributes/local/CreateSharedLocalAttributeCopyParams.js"), exports);
1443
- __exportStar(__webpack_require__(/*! ./local/IAttributeSuccessorParams */ "./dist/modules/attributes/local/IAttributeSuccessorParams.js"), exports);
1444
1495
  __exportStar(__webpack_require__(/*! ./local/LocalAttribute */ "./dist/modules/attributes/local/LocalAttribute.js"), exports);
1445
1496
  __exportStar(__webpack_require__(/*! ./local/LocalAttributeShareInfo */ "./dist/modules/attributes/local/LocalAttributeShareInfo.js"), exports);
1446
1497
  //# sourceMappingURL=index.js.map
1447
1498
 
1448
1499
  /***/ }),
1449
1500
 
1501
+ /***/ "./dist/modules/attributes/local/AttributeSuccessorParams.js":
1502
+ /*!*******************************************************************!*\
1503
+ !*** ./dist/modules/attributes/local/AttributeSuccessorParams.js ***!
1504
+ \*******************************************************************/
1505
+ /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1506
+
1507
+ "use strict";
1508
+
1509
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
1510
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1511
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1512
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1513
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1514
+ };
1515
+ var __metadata = (this && this.__metadata) || function (k, v) {
1516
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1517
+ };
1518
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
1519
+ exports.AttributeSuccessorParams = void 0;
1520
+ const ts_serval_1 = __webpack_require__(/*! @js-soft/ts-serval */ "@js-soft/ts-serval");
1521
+ const content_1 = __webpack_require__(/*! @nmshd/content */ "@nmshd/content");
1522
+ let AttributeSuccessorParams = class AttributeSuccessorParams extends ts_serval_1.Serializable {
1523
+ static from(value) {
1524
+ return this.fromAny(value);
1525
+ }
1526
+ };
1527
+ exports.AttributeSuccessorParams = AttributeSuccessorParams;
1528
+ __decorate([
1529
+ (0, ts_serval_1.validate)({ nullable: true }),
1530
+ (0, ts_serval_1.serialize)(),
1531
+ __metadata("design:type", Object)
1532
+ ], AttributeSuccessorParams.prototype, "id", void 0);
1533
+ __decorate([
1534
+ (0, ts_serval_1.validate)(),
1535
+ (0, ts_serval_1.serialize)({ unionTypes: [content_1.IdentityAttribute, content_1.RelationshipAttribute] }),
1536
+ __metadata("design:type", Object)
1537
+ ], AttributeSuccessorParams.prototype, "content", void 0);
1538
+ __decorate([
1539
+ (0, ts_serval_1.validate)({ nullable: true }),
1540
+ (0, ts_serval_1.serialize)(),
1541
+ __metadata("design:type", Object)
1542
+ ], AttributeSuccessorParams.prototype, "createdAt", void 0);
1543
+ __decorate([
1544
+ (0, ts_serval_1.validate)({ nullable: true }),
1545
+ (0, ts_serval_1.serialize)(),
1546
+ __metadata("design:type", Object)
1547
+ ], AttributeSuccessorParams.prototype, "succeeds", void 0);
1548
+ __decorate([
1549
+ (0, ts_serval_1.validate)({ nullable: true }),
1550
+ (0, ts_serval_1.serialize)(),
1551
+ __metadata("design:type", Object)
1552
+ ], AttributeSuccessorParams.prototype, "succeededBy", void 0);
1553
+ __decorate([
1554
+ (0, ts_serval_1.validate)({ nullable: true }),
1555
+ (0, ts_serval_1.serialize)(),
1556
+ __metadata("design:type", Object)
1557
+ ], AttributeSuccessorParams.prototype, "shareInfo", void 0);
1558
+ __decorate([
1559
+ (0, ts_serval_1.validate)({ nullable: true }),
1560
+ (0, ts_serval_1.serialize)(),
1561
+ __metadata("design:type", Object)
1562
+ ], AttributeSuccessorParams.prototype, "parentId", void 0);
1563
+ exports.AttributeSuccessorParams = AttributeSuccessorParams = __decorate([
1564
+ (0, ts_serval_1.type)("AttributeSuccessorParams")
1565
+ ], AttributeSuccessorParams);
1566
+ //# sourceMappingURL=AttributeSuccessorParams.js.map
1567
+
1568
+ /***/ }),
1569
+
1450
1570
  /***/ "./dist/modules/attributes/local/CreateLocalAttributeParams.js":
1451
1571
  /*!*********************************************************************!*\
1452
1572
  !*** ./dist/modules/attributes/local/CreateLocalAttributeParams.js ***!
@@ -1608,19 +1728,6 @@ __decorate([
1608
1728
 
1609
1729
  /***/ }),
1610
1730
 
1611
- /***/ "./dist/modules/attributes/local/IAttributeSuccessorParams.js":
1612
- /*!********************************************************************!*\
1613
- !*** ./dist/modules/attributes/local/IAttributeSuccessorParams.js ***!
1614
- \********************************************************************/
1615
- /***/ ((__unused_webpack_module, exports) => {
1616
-
1617
- "use strict";
1618
-
1619
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1620
- //# sourceMappingURL=IAttributeSuccessorParams.js.map
1621
-
1622
- /***/ }),
1623
-
1624
1731
  /***/ "./dist/modules/attributes/local/LocalAttribute.js":
1625
1732
  /*!*********************************************************!*\
1626
1733
  !*** ./dist/modules/attributes/local/LocalAttribute.js ***!
@@ -27436,6 +27543,17 @@ function systemLocale() {
27436
27543
  return sysLocaleCache;
27437
27544
  }
27438
27545
  }
27546
+ let weekInfoCache = {};
27547
+ function getCachedWeekInfo(locString) {
27548
+ let data = weekInfoCache[locString];
27549
+ if (!data) {
27550
+ const locale = new Intl.Locale(locString);
27551
+ // browsers currently implement this as a property, but spec says it should be a getter function
27552
+ data = "getWeekInfo" in locale ? locale.getWeekInfo() : locale.weekInfo;
27553
+ weekInfoCache[locString] = data;
27554
+ }
27555
+ return data;
27556
+ }
27439
27557
  function parseLocaleString(localeStr) {
27440
27558
  // I really want to avoid writing a BCP 47 parser
27441
27559
  // see, e.g. https://github.com/wooorm/bcp-47
@@ -27673,6 +27791,11 @@ class PolyRelFormatter {
27673
27791
  }
27674
27792
  }
27675
27793
  }
27794
+ const fallbackWeekSettings = {
27795
+ firstDay: 1,
27796
+ minimalDays: 4,
27797
+ weekend: [6, 7]
27798
+ };
27676
27799
 
27677
27800
  /**
27678
27801
  * @private
@@ -27680,15 +27803,16 @@ class PolyRelFormatter {
27680
27803
 
27681
27804
  class Locale {
27682
27805
  static fromOpts(opts) {
27683
- return Locale.create(opts.locale, opts.numberingSystem, opts.outputCalendar, opts.defaultToEN);
27806
+ return Locale.create(opts.locale, opts.numberingSystem, opts.outputCalendar, opts.weekSettings, opts.defaultToEN);
27684
27807
  }
27685
- static create(locale, numberingSystem, outputCalendar, defaultToEN = false) {
27808
+ static create(locale, numberingSystem, outputCalendar, weekSettings, defaultToEN = false) {
27686
27809
  const specifiedLocale = locale || Settings.defaultLocale;
27687
27810
  // the system locale is useful for human readable strings but annoying for parsing/formatting known formats
27688
27811
  const localeR = specifiedLocale || (defaultToEN ? "en-US" : systemLocale());
27689
27812
  const numberingSystemR = numberingSystem || Settings.defaultNumberingSystem;
27690
27813
  const outputCalendarR = outputCalendar || Settings.defaultOutputCalendar;
27691
- return new Locale(localeR, numberingSystemR, outputCalendarR, specifiedLocale);
27814
+ const weekSettingsR = validateWeekSettings(weekSettings) || Settings.defaultWeekSettings;
27815
+ return new Locale(localeR, numberingSystemR, outputCalendarR, weekSettingsR, specifiedLocale);
27692
27816
  }
27693
27817
  static resetCache() {
27694
27818
  sysLocaleCache = null;
@@ -27699,15 +27823,17 @@ class Locale {
27699
27823
  static fromObject({
27700
27824
  locale,
27701
27825
  numberingSystem,
27702
- outputCalendar
27826
+ outputCalendar,
27827
+ weekSettings
27703
27828
  } = {}) {
27704
- return Locale.create(locale, numberingSystem, outputCalendar);
27829
+ return Locale.create(locale, numberingSystem, outputCalendar, weekSettings);
27705
27830
  }
27706
- constructor(locale, numbering, outputCalendar, specifiedLocale) {
27831
+ constructor(locale, numbering, outputCalendar, weekSettings, specifiedLocale) {
27707
27832
  const [parsedLocale, parsedNumberingSystem, parsedOutputCalendar] = parseLocaleString(locale);
27708
27833
  this.locale = parsedLocale;
27709
27834
  this.numberingSystem = numbering || parsedNumberingSystem || null;
27710
27835
  this.outputCalendar = outputCalendar || parsedOutputCalendar || null;
27836
+ this.weekSettings = weekSettings;
27711
27837
  this.intl = intlConfigString(this.locale, this.numberingSystem, this.outputCalendar);
27712
27838
  this.weekdaysCache = {
27713
27839
  format: {},
@@ -27737,7 +27863,7 @@ class Locale {
27737
27863
  if (!alts || Object.getOwnPropertyNames(alts).length === 0) {
27738
27864
  return this;
27739
27865
  } else {
27740
- return Locale.create(alts.locale || this.specifiedLocale, alts.numberingSystem || this.numberingSystem, alts.outputCalendar || this.outputCalendar, alts.defaultToEN || false);
27866
+ return Locale.create(alts.locale || this.specifiedLocale, alts.numberingSystem || this.numberingSystem, alts.outputCalendar || this.outputCalendar, validateWeekSettings(alts.weekSettings) || this.weekSettings, alts.defaultToEN || false);
27741
27867
  }
27742
27868
  }
27743
27869
  redefaultToEN(alts = {}) {
@@ -27835,6 +27961,24 @@ class Locale {
27835
27961
  isEnglish() {
27836
27962
  return this.locale === "en" || this.locale.toLowerCase() === "en-us" || new Intl.DateTimeFormat(this.intl).resolvedOptions().locale.startsWith("en-us");
27837
27963
  }
27964
+ getWeekSettings() {
27965
+ if (this.weekSettings) {
27966
+ return this.weekSettings;
27967
+ } else if (!hasLocaleWeekInfo()) {
27968
+ return fallbackWeekSettings;
27969
+ } else {
27970
+ return getCachedWeekInfo(this.locale);
27971
+ }
27972
+ }
27973
+ getStartOfWeek() {
27974
+ return this.getWeekSettings().firstDay;
27975
+ }
27976
+ getMinDaysInFirstWeek() {
27977
+ return this.getWeekSettings().minimalDays;
27978
+ }
27979
+ getWeekendDays() {
27980
+ return this.getWeekSettings().weekend;
27981
+ }
27838
27982
  equals(other) {
27839
27983
  return this.locale === other.locale && this.numberingSystem === other.numberingSystem && this.outputCalendar === other.outputCalendar;
27840
27984
  }
@@ -28018,7 +28162,8 @@ let now = () => Date.now(),
28018
28162
  defaultNumberingSystem = null,
28019
28163
  defaultOutputCalendar = null,
28020
28164
  twoDigitCutoffYear = 60,
28021
- throwOnInvalid;
28165
+ throwOnInvalid,
28166
+ defaultWeekSettings = null;
28022
28167
 
28023
28168
  /**
28024
28169
  * Settings contains static getters and setters that control Luxon's overall behavior. Luxon is a simple library with few options, but the ones it does have live here.
@@ -28109,6 +28254,31 @@ class Settings {
28109
28254
  defaultOutputCalendar = outputCalendar;
28110
28255
  }
28111
28256
 
28257
+ /**
28258
+ * @typedef {Object} WeekSettings
28259
+ * @property {number} firstDay
28260
+ * @property {number} minimalDays
28261
+ * @property {number[]} weekend
28262
+ */
28263
+
28264
+ /**
28265
+ * @return {WeekSettings|null}
28266
+ */
28267
+ static get defaultWeekSettings() {
28268
+ return defaultWeekSettings;
28269
+ }
28270
+
28271
+ /**
28272
+ * Allows overriding the default locale week settings, i.e. the start of the week, the weekend and
28273
+ * how many days are required in the first week of a year.
28274
+ * Does not affect existing instances.
28275
+ *
28276
+ * @param {WeekSettings|null} weekSettings
28277
+ */
28278
+ static set defaultWeekSettings(weekSettings) {
28279
+ defaultWeekSettings = validateWeekSettings(weekSettings);
28280
+ }
28281
+
28112
28282
  /**
28113
28283
  * Get the cutoff year after which a string encoding a year as two digits is interpreted to occur in the current century.
28114
28284
  * @type {number}
@@ -28155,6 +28325,224 @@ class Settings {
28155
28325
  }
28156
28326
  }
28157
28327
 
28328
+ class Invalid {
28329
+ constructor(reason, explanation) {
28330
+ this.reason = reason;
28331
+ this.explanation = explanation;
28332
+ }
28333
+ toMessage() {
28334
+ if (this.explanation) {
28335
+ return `${this.reason}: ${this.explanation}`;
28336
+ } else {
28337
+ return this.reason;
28338
+ }
28339
+ }
28340
+ }
28341
+
28342
+ const nonLeapLadder = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
28343
+ leapLadder = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335];
28344
+ function unitOutOfRange(unit, value) {
28345
+ return new Invalid("unit out of range", `you specified ${value} (of type ${typeof value}) as a ${unit}, which is invalid`);
28346
+ }
28347
+ function dayOfWeek(year, month, day) {
28348
+ const d = new Date(Date.UTC(year, month - 1, day));
28349
+ if (year < 100 && year >= 0) {
28350
+ d.setUTCFullYear(d.getUTCFullYear() - 1900);
28351
+ }
28352
+ const js = d.getUTCDay();
28353
+ return js === 0 ? 7 : js;
28354
+ }
28355
+ function computeOrdinal(year, month, day) {
28356
+ return day + (isLeapYear(year) ? leapLadder : nonLeapLadder)[month - 1];
28357
+ }
28358
+ function uncomputeOrdinal(year, ordinal) {
28359
+ const table = isLeapYear(year) ? leapLadder : nonLeapLadder,
28360
+ month0 = table.findIndex(i => i < ordinal),
28361
+ day = ordinal - table[month0];
28362
+ return {
28363
+ month: month0 + 1,
28364
+ day
28365
+ };
28366
+ }
28367
+ function isoWeekdayToLocal(isoWeekday, startOfWeek) {
28368
+ return (isoWeekday - startOfWeek + 7) % 7 + 1;
28369
+ }
28370
+
28371
+ /**
28372
+ * @private
28373
+ */
28374
+
28375
+ function gregorianToWeek(gregObj, minDaysInFirstWeek = 4, startOfWeek = 1) {
28376
+ const {
28377
+ year,
28378
+ month,
28379
+ day
28380
+ } = gregObj,
28381
+ ordinal = computeOrdinal(year, month, day),
28382
+ weekday = isoWeekdayToLocal(dayOfWeek(year, month, day), startOfWeek);
28383
+ let weekNumber = Math.floor((ordinal - weekday + 14 - minDaysInFirstWeek) / 7),
28384
+ weekYear;
28385
+ if (weekNumber < 1) {
28386
+ weekYear = year - 1;
28387
+ weekNumber = weeksInWeekYear(weekYear, minDaysInFirstWeek, startOfWeek);
28388
+ } else if (weekNumber > weeksInWeekYear(year, minDaysInFirstWeek, startOfWeek)) {
28389
+ weekYear = year + 1;
28390
+ weekNumber = 1;
28391
+ } else {
28392
+ weekYear = year;
28393
+ }
28394
+ return {
28395
+ weekYear,
28396
+ weekNumber,
28397
+ weekday,
28398
+ ...timeObject(gregObj)
28399
+ };
28400
+ }
28401
+ function weekToGregorian(weekData, minDaysInFirstWeek = 4, startOfWeek = 1) {
28402
+ const {
28403
+ weekYear,
28404
+ weekNumber,
28405
+ weekday
28406
+ } = weekData,
28407
+ weekdayOfJan4 = isoWeekdayToLocal(dayOfWeek(weekYear, 1, minDaysInFirstWeek), startOfWeek),
28408
+ yearInDays = daysInYear(weekYear);
28409
+ let ordinal = weekNumber * 7 + weekday - weekdayOfJan4 - 7 + minDaysInFirstWeek,
28410
+ year;
28411
+ if (ordinal < 1) {
28412
+ year = weekYear - 1;
28413
+ ordinal += daysInYear(year);
28414
+ } else if (ordinal > yearInDays) {
28415
+ year = weekYear + 1;
28416
+ ordinal -= daysInYear(weekYear);
28417
+ } else {
28418
+ year = weekYear;
28419
+ }
28420
+ const {
28421
+ month,
28422
+ day
28423
+ } = uncomputeOrdinal(year, ordinal);
28424
+ return {
28425
+ year,
28426
+ month,
28427
+ day,
28428
+ ...timeObject(weekData)
28429
+ };
28430
+ }
28431
+ function gregorianToOrdinal(gregData) {
28432
+ const {
28433
+ year,
28434
+ month,
28435
+ day
28436
+ } = gregData;
28437
+ const ordinal = computeOrdinal(year, month, day);
28438
+ return {
28439
+ year,
28440
+ ordinal,
28441
+ ...timeObject(gregData)
28442
+ };
28443
+ }
28444
+ function ordinalToGregorian(ordinalData) {
28445
+ const {
28446
+ year,
28447
+ ordinal
28448
+ } = ordinalData;
28449
+ const {
28450
+ month,
28451
+ day
28452
+ } = uncomputeOrdinal(year, ordinal);
28453
+ return {
28454
+ year,
28455
+ month,
28456
+ day,
28457
+ ...timeObject(ordinalData)
28458
+ };
28459
+ }
28460
+
28461
+ /**
28462
+ * Check if local week units like localWeekday are used in obj.
28463
+ * If so, validates that they are not mixed with ISO week units and then copies them to the normal week unit properties.
28464
+ * Modifies obj in-place!
28465
+ * @param obj the object values
28466
+ */
28467
+ function usesLocalWeekValues(obj, loc) {
28468
+ const hasLocaleWeekData = !isUndefined(obj.localWeekday) || !isUndefined(obj.localWeekNumber) || !isUndefined(obj.localWeekYear);
28469
+ if (hasLocaleWeekData) {
28470
+ const hasIsoWeekData = !isUndefined(obj.weekday) || !isUndefined(obj.weekNumber) || !isUndefined(obj.weekYear);
28471
+ if (hasIsoWeekData) {
28472
+ throw new ConflictingSpecificationError("Cannot mix locale-based week fields with ISO-based week fields");
28473
+ }
28474
+ if (!isUndefined(obj.localWeekday)) obj.weekday = obj.localWeekday;
28475
+ if (!isUndefined(obj.localWeekNumber)) obj.weekNumber = obj.localWeekNumber;
28476
+ if (!isUndefined(obj.localWeekYear)) obj.weekYear = obj.localWeekYear;
28477
+ delete obj.localWeekday;
28478
+ delete obj.localWeekNumber;
28479
+ delete obj.localWeekYear;
28480
+ return {
28481
+ minDaysInFirstWeek: loc.getMinDaysInFirstWeek(),
28482
+ startOfWeek: loc.getStartOfWeek()
28483
+ };
28484
+ } else {
28485
+ return {
28486
+ minDaysInFirstWeek: 4,
28487
+ startOfWeek: 1
28488
+ };
28489
+ }
28490
+ }
28491
+ function hasInvalidWeekData(obj, minDaysInFirstWeek = 4, startOfWeek = 1) {
28492
+ const validYear = isInteger(obj.weekYear),
28493
+ validWeek = integerBetween(obj.weekNumber, 1, weeksInWeekYear(obj.weekYear, minDaysInFirstWeek, startOfWeek)),
28494
+ validWeekday = integerBetween(obj.weekday, 1, 7);
28495
+ if (!validYear) {
28496
+ return unitOutOfRange("weekYear", obj.weekYear);
28497
+ } else if (!validWeek) {
28498
+ return unitOutOfRange("week", obj.weekNumber);
28499
+ } else if (!validWeekday) {
28500
+ return unitOutOfRange("weekday", obj.weekday);
28501
+ } else return false;
28502
+ }
28503
+ function hasInvalidOrdinalData(obj) {
28504
+ const validYear = isInteger(obj.year),
28505
+ validOrdinal = integerBetween(obj.ordinal, 1, daysInYear(obj.year));
28506
+ if (!validYear) {
28507
+ return unitOutOfRange("year", obj.year);
28508
+ } else if (!validOrdinal) {
28509
+ return unitOutOfRange("ordinal", obj.ordinal);
28510
+ } else return false;
28511
+ }
28512
+ function hasInvalidGregorianData(obj) {
28513
+ const validYear = isInteger(obj.year),
28514
+ validMonth = integerBetween(obj.month, 1, 12),
28515
+ validDay = integerBetween(obj.day, 1, daysInMonth(obj.year, obj.month));
28516
+ if (!validYear) {
28517
+ return unitOutOfRange("year", obj.year);
28518
+ } else if (!validMonth) {
28519
+ return unitOutOfRange("month", obj.month);
28520
+ } else if (!validDay) {
28521
+ return unitOutOfRange("day", obj.day);
28522
+ } else return false;
28523
+ }
28524
+ function hasInvalidTimeData(obj) {
28525
+ const {
28526
+ hour,
28527
+ minute,
28528
+ second,
28529
+ millisecond
28530
+ } = obj;
28531
+ const validHour = integerBetween(hour, 0, 23) || hour === 24 && minute === 0 && second === 0 && millisecond === 0,
28532
+ validMinute = integerBetween(minute, 0, 59),
28533
+ validSecond = integerBetween(second, 0, 59),
28534
+ validMillisecond = integerBetween(millisecond, 0, 999);
28535
+ if (!validHour) {
28536
+ return unitOutOfRange("hour", hour);
28537
+ } else if (!validMinute) {
28538
+ return unitOutOfRange("minute", minute);
28539
+ } else if (!validSecond) {
28540
+ return unitOutOfRange("second", second);
28541
+ } else if (!validMillisecond) {
28542
+ return unitOutOfRange("millisecond", millisecond);
28543
+ } else return false;
28544
+ }
28545
+
28158
28546
  /*
28159
28547
  This is just a junk drawer, containing anything used across multiple classes.
28160
28548
  Because Luxon is small(ish), this should stay small and we won't worry about splitting
@@ -28192,6 +28580,13 @@ function hasRelative() {
28192
28580
  return false;
28193
28581
  }
28194
28582
  }
28583
+ function hasLocaleWeekInfo() {
28584
+ try {
28585
+ return typeof Intl !== "undefined" && !!Intl.Locale && ("weekInfo" in Intl.Locale.prototype || "getWeekInfo" in Intl.Locale.prototype);
28586
+ } catch (e) {
28587
+ return false;
28588
+ }
28589
+ }
28195
28590
 
28196
28591
  // OBJECTS AND ARRAYS
28197
28592
 
@@ -28222,6 +28617,22 @@ function pick(obj, keys) {
28222
28617
  function hasOwnProperty(obj, prop) {
28223
28618
  return Object.prototype.hasOwnProperty.call(obj, prop);
28224
28619
  }
28620
+ function validateWeekSettings(settings) {
28621
+ if (settings == null) {
28622
+ return null;
28623
+ } else if (typeof settings !== "object") {
28624
+ throw new InvalidArgumentError("Week settings must be an object");
28625
+ } else {
28626
+ if (!integerBetween(settings.firstDay, 1, 7) || !integerBetween(settings.minimalDays, 1, 7) || !Array.isArray(settings.weekend) || settings.weekend.some(v => !integerBetween(v, 1, 7))) {
28627
+ throw new InvalidArgumentError("Invalid week settings");
28628
+ }
28629
+ return {
28630
+ firstDay: settings.firstDay,
28631
+ minimalDays: settings.minimalDays,
28632
+ weekend: Array.from(settings.weekend)
28633
+ };
28634
+ }
28635
+ }
28225
28636
 
28226
28637
  // NUMBERS AND STRINGS
28227
28638
 
@@ -28304,11 +28715,16 @@ function objToLocalTS(obj) {
28304
28715
  }
28305
28716
  return +d;
28306
28717
  }
28307
- function weeksInWeekYear(weekYear) {
28308
- const p1 = (weekYear + Math.floor(weekYear / 4) - Math.floor(weekYear / 100) + Math.floor(weekYear / 400)) % 7,
28309
- last = weekYear - 1,
28310
- p2 = (last + Math.floor(last / 4) - Math.floor(last / 100) + Math.floor(last / 400)) % 7;
28311
- return p1 === 4 || p2 === 3 ? 53 : 52;
28718
+
28719
+ // adapted from moment.js: https://github.com/moment/moment/blob/000ac1800e620f770f4eb31b5ae908f6167b0ab2/src/lib/units/week-calendar-utils.js
28720
+ function firstWeekOffset(year, minDaysInFirstWeek, startOfWeek) {
28721
+ const fwdlw = isoWeekdayToLocal(dayOfWeek(year, 1, minDaysInFirstWeek), startOfWeek);
28722
+ return -fwdlw + minDaysInFirstWeek - 1;
28723
+ }
28724
+ function weeksInWeekYear(weekYear, minDaysInFirstWeek = 4, startOfWeek = 1) {
28725
+ const weekOffset = firstWeekOffset(weekYear, minDaysInFirstWeek, startOfWeek);
28726
+ const weekOffsetNext = firstWeekOffset(weekYear + 1, minDaysInFirstWeek, startOfWeek);
28727
+ return (daysInYear(weekYear) - weekOffset + weekOffsetNext) / 7;
28312
28728
  }
28313
28729
  function untruncateYear(year) {
28314
28730
  if (year > 99) {
@@ -28849,6 +29265,14 @@ class Formatter {
28849
29265
  return this.num(dt.weekNumber);
28850
29266
  case "WW":
28851
29267
  return this.num(dt.weekNumber, 2);
29268
+ case "n":
29269
+ return this.num(dt.localWeekNumber);
29270
+ case "nn":
29271
+ return this.num(dt.localWeekNumber, 2);
29272
+ case "ii":
29273
+ return this.num(dt.localWeekYear.toString().slice(-2), 2);
29274
+ case "iiii":
29275
+ return this.num(dt.localWeekYear, 4);
28852
29276
  case "o":
28853
29277
  return this.num(dt.ordinal);
28854
29278
  case "ooo":
@@ -28910,20 +29334,6 @@ class Formatter {
28910
29334
  }
28911
29335
  }
28912
29336
 
28913
- class Invalid {
28914
- constructor(reason, explanation) {
28915
- this.reason = reason;
28916
- this.explanation = explanation;
28917
- }
28918
- toMessage() {
28919
- if (this.explanation) {
28920
- return `${this.reason}: ${this.explanation}`;
28921
- } else {
28922
- return this.reason;
28923
- }
28924
- }
28925
- }
28926
-
28927
29337
  /*
28928
29338
  * This file handles parsing for well-specified formats. Here's how it works:
28929
29339
  * Two things go into parsing: a regex to match with and an extractor to take apart the groups in the match.
@@ -29600,9 +30010,10 @@ class Duration {
29600
30010
 
29601
30011
  /**
29602
30012
  * Returns a string representation of a Duration with all units included.
29603
- * To modify its behavior use the `listStyle` and any Intl.NumberFormat option, though `unitDisplay` is especially relevant.
29604
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat
29605
- * @param opts - On option object to override the formatting. Accepts the same keys as the options parameter of the native `Int.NumberFormat` constructor, as well as `listStyle`.
30013
+ * To modify its behavior, use `listStyle` and any Intl.NumberFormat option, though `unitDisplay` is especially relevant.
30014
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#options
30015
+ * @param {Object} opts - Formatting options. Accepts the same keys as the options parameter of the native `Intl.NumberFormat` constructor, as well as `listStyle`.
30016
+ * @param {string} [opts.listStyle='narrow'] - How to format the merged list. Corresponds to the `style` property of the options parameter of the native `Intl.ListFormat` constructor.
29606
30017
  * @example
29607
30018
  * ```js
29608
30019
  * var dur = Duration.fromObject({ days: 1, hours: 5, minutes: 6 })
@@ -29723,6 +30134,18 @@ class Duration {
29723
30134
  return this.toISO();
29724
30135
  }
29725
30136
 
30137
+ /**
30138
+ * Returns a string representation of this Duration appropriate for the REPL.
30139
+ * @return {string}
30140
+ */
30141
+ [Symbol.for("nodejs.util.inspect.custom")]() {
30142
+ if (this.isValid) {
30143
+ return `Duration { values: ${JSON.stringify(this.values)} }`;
30144
+ } else {
30145
+ return `Duration { Invalid, reason: ${this.invalidReason} }`;
30146
+ }
30147
+ }
30148
+
29726
30149
  /**
29727
30150
  * Returns an milliseconds value of this Duration.
29728
30151
  * @return {number}
@@ -29858,7 +30281,7 @@ class Duration {
29858
30281
  * Assuming the overall value of the Duration is positive, this means:
29859
30282
  * - excessive values for lower-order units are converted to higher-order units (if possible, see first and second example)
29860
30283
  * - negative lower-order units are converted to higher order units (there must be such a higher order unit, otherwise
29861
- * the overall value would be negative, see second example)
30284
+ * the overall value would be negative, see third example)
29862
30285
  * - fractional values for higher-order units are converted to lower-order units (if possible, see fourth example)
29863
30286
  *
29864
30287
  * If the overall value is negative, the result of this method is equivalent to `this.negate().normalize().negate()`.
@@ -30316,12 +30739,22 @@ class Interval {
30316
30739
  * Unlike {@link Interval#length} this counts sections of the calendar, not periods of time, e.g. specifying 'day'
30317
30740
  * asks 'what dates are included in this interval?', not 'how many days long is this interval?'
30318
30741
  * @param {string} [unit='milliseconds'] - the unit of time to count.
30742
+ * @param {Object} opts - options
30743
+ * @param {boolean} [opts.useLocaleWeeks=false] - If true, use weeks based on the locale, i.e. use the locale-dependent start of the week; this operation will always use the locale of the start DateTime
30319
30744
  * @return {number}
30320
30745
  */
30321
- count(unit = "milliseconds") {
30746
+ count(unit = "milliseconds", opts) {
30322
30747
  if (!this.isValid) return NaN;
30323
- const start = this.start.startOf(unit),
30324
- end = this.end.startOf(unit);
30748
+ const start = this.start.startOf(unit, opts);
30749
+ let end;
30750
+ if (opts != null && opts.useLocaleWeeks) {
30751
+ end = this.end.reconfigure({
30752
+ locale: start.locale
30753
+ });
30754
+ } else {
30755
+ end = this.end;
30756
+ }
30757
+ end = end.startOf(unit, opts);
30325
30758
  return Math.floor(end.diff(start, unit).get(unit)) + (end.valueOf() !== this.end.valueOf());
30326
30759
  }
30327
30760
 
@@ -30394,7 +30827,7 @@ class Interval {
30394
30827
  */
30395
30828
  splitAt(...dateTimes) {
30396
30829
  if (!this.isValid) return [];
30397
- const sorted = dateTimes.map(friendlyDateTime).filter(d => this.contains(d)).sort(),
30830
+ const sorted = dateTimes.map(friendlyDateTime).filter(d => this.contains(d)).sort((a, b) => a.toMillis() - b.toMillis()),
30398
30831
  results = [];
30399
30832
  let {
30400
30833
  s
@@ -30601,6 +31034,18 @@ class Interval {
30601
31034
  return `[${this.s.toISO()} – ${this.e.toISO()})`;
30602
31035
  }
30603
31036
 
31037
+ /**
31038
+ * Returns a string representation of this Interval appropriate for the REPL.
31039
+ * @return {string}
31040
+ */
31041
+ [Symbol.for("nodejs.util.inspect.custom")]() {
31042
+ if (this.isValid) {
31043
+ return `Interval { start: ${this.s.toISO()}, end: ${this.e.toISO()} }`;
31044
+ } else {
31045
+ return `Interval { Invalid, reason: ${this.invalidReason} }`;
31046
+ }
31047
+ }
31048
+
30604
31049
  /**
30605
31050
  * Returns a localized string representing this Interval. Accepts the same options as the
30606
31051
  * Intl.DateTimeFormat constructor and any presets defined by Luxon, such as
@@ -30751,6 +31196,50 @@ class Info {
30751
31196
  return normalizeZone(input, Settings.defaultZone);
30752
31197
  }
30753
31198
 
31199
+ /**
31200
+ * Get the weekday on which the week starts according to the given locale.
31201
+ * @param {Object} opts - options
31202
+ * @param {string} [opts.locale] - the locale code
31203
+ * @param {string} [opts.locObj=null] - an existing locale object to use
31204
+ * @returns {number} the start of the week, 1 for Monday through 7 for Sunday
31205
+ */
31206
+ static getStartOfWeek({
31207
+ locale = null,
31208
+ locObj = null
31209
+ } = {}) {
31210
+ return (locObj || Locale.create(locale)).getStartOfWeek();
31211
+ }
31212
+
31213
+ /**
31214
+ * Get the minimum number of days necessary in a week before it is considered part of the next year according
31215
+ * to the given locale.
31216
+ * @param {Object} opts - options
31217
+ * @param {string} [opts.locale] - the locale code
31218
+ * @param {string} [opts.locObj=null] - an existing locale object to use
31219
+ * @returns {number}
31220
+ */
31221
+ static getMinimumDaysInFirstWeek({
31222
+ locale = null,
31223
+ locObj = null
31224
+ } = {}) {
31225
+ return (locObj || Locale.create(locale)).getMinDaysInFirstWeek();
31226
+ }
31227
+
31228
+ /**
31229
+ * Get the weekdays, which are considered the weekend according to the given locale
31230
+ * @param {Object} opts - options
31231
+ * @param {string} [opts.locale] - the locale code
31232
+ * @param {string} [opts.locObj=null] - an existing locale object to use
31233
+ * @returns {number[]} an array of weekdays, 1 for Monday through 7 for Sunday
31234
+ */
31235
+ static getWeekendWeekdays({
31236
+ locale = null,
31237
+ locObj = null
31238
+ } = {}) {
31239
+ // copy the array, because we cache it internally
31240
+ return (locObj || Locale.create(locale)).getWeekendDays().slice();
31241
+ }
31242
+
30754
31243
  /**
30755
31244
  * Return an array of standalone month names.
30756
31245
  * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat
@@ -30876,12 +31365,14 @@ class Info {
30876
31365
  * Some features of Luxon are not available in all environments. For example, on older browsers, relative time formatting support is not available. Use this function to figure out if that's the case.
30877
31366
  * Keys:
30878
31367
  * * `relative`: whether this environment supports relative time formatting
30879
- * @example Info.features() //=> { relative: false }
31368
+ * * `localeWeek`: whether this environment supports different weekdays for the start of the week based on the locale
31369
+ * @example Info.features() //=> { relative: false, localeWeek: true }
30880
31370
  * @return {Object}
30881
31371
  */
30882
31372
  static features() {
30883
31373
  return {
30884
- relative: hasRelative()
31374
+ relative: hasRelative(),
31375
+ localeWeek: hasLocaleWeekInfo()
30885
31376
  };
30886
31377
  }
30887
31378
  }
@@ -31485,176 +31976,6 @@ function formatOptsToTokens(formatOpts, locale) {
31485
31976
  return parts.map(p => tokenForPart(p, formatOpts, resolvedOpts));
31486
31977
  }
31487
31978
 
31488
- const nonLeapLadder = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
31489
- leapLadder = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335];
31490
- function unitOutOfRange(unit, value) {
31491
- return new Invalid("unit out of range", `you specified ${value} (of type ${typeof value}) as a ${unit}, which is invalid`);
31492
- }
31493
- function dayOfWeek(year, month, day) {
31494
- const d = new Date(Date.UTC(year, month - 1, day));
31495
- if (year < 100 && year >= 0) {
31496
- d.setUTCFullYear(d.getUTCFullYear() - 1900);
31497
- }
31498
- const js = d.getUTCDay();
31499
- return js === 0 ? 7 : js;
31500
- }
31501
- function computeOrdinal(year, month, day) {
31502
- return day + (isLeapYear(year) ? leapLadder : nonLeapLadder)[month - 1];
31503
- }
31504
- function uncomputeOrdinal(year, ordinal) {
31505
- const table = isLeapYear(year) ? leapLadder : nonLeapLadder,
31506
- month0 = table.findIndex(i => i < ordinal),
31507
- day = ordinal - table[month0];
31508
- return {
31509
- month: month0 + 1,
31510
- day
31511
- };
31512
- }
31513
-
31514
- /**
31515
- * @private
31516
- */
31517
-
31518
- function gregorianToWeek(gregObj) {
31519
- const {
31520
- year,
31521
- month,
31522
- day
31523
- } = gregObj,
31524
- ordinal = computeOrdinal(year, month, day),
31525
- weekday = dayOfWeek(year, month, day);
31526
- let weekNumber = Math.floor((ordinal - weekday + 10) / 7),
31527
- weekYear;
31528
- if (weekNumber < 1) {
31529
- weekYear = year - 1;
31530
- weekNumber = weeksInWeekYear(weekYear);
31531
- } else if (weekNumber > weeksInWeekYear(year)) {
31532
- weekYear = year + 1;
31533
- weekNumber = 1;
31534
- } else {
31535
- weekYear = year;
31536
- }
31537
- return {
31538
- weekYear,
31539
- weekNumber,
31540
- weekday,
31541
- ...timeObject(gregObj)
31542
- };
31543
- }
31544
- function weekToGregorian(weekData) {
31545
- const {
31546
- weekYear,
31547
- weekNumber,
31548
- weekday
31549
- } = weekData,
31550
- weekdayOfJan4 = dayOfWeek(weekYear, 1, 4),
31551
- yearInDays = daysInYear(weekYear);
31552
- let ordinal = weekNumber * 7 + weekday - weekdayOfJan4 - 3,
31553
- year;
31554
- if (ordinal < 1) {
31555
- year = weekYear - 1;
31556
- ordinal += daysInYear(year);
31557
- } else if (ordinal > yearInDays) {
31558
- year = weekYear + 1;
31559
- ordinal -= daysInYear(weekYear);
31560
- } else {
31561
- year = weekYear;
31562
- }
31563
- const {
31564
- month,
31565
- day
31566
- } = uncomputeOrdinal(year, ordinal);
31567
- return {
31568
- year,
31569
- month,
31570
- day,
31571
- ...timeObject(weekData)
31572
- };
31573
- }
31574
- function gregorianToOrdinal(gregData) {
31575
- const {
31576
- year,
31577
- month,
31578
- day
31579
- } = gregData;
31580
- const ordinal = computeOrdinal(year, month, day);
31581
- return {
31582
- year,
31583
- ordinal,
31584
- ...timeObject(gregData)
31585
- };
31586
- }
31587
- function ordinalToGregorian(ordinalData) {
31588
- const {
31589
- year,
31590
- ordinal
31591
- } = ordinalData;
31592
- const {
31593
- month,
31594
- day
31595
- } = uncomputeOrdinal(year, ordinal);
31596
- return {
31597
- year,
31598
- month,
31599
- day,
31600
- ...timeObject(ordinalData)
31601
- };
31602
- }
31603
- function hasInvalidWeekData(obj) {
31604
- const validYear = isInteger(obj.weekYear),
31605
- validWeek = integerBetween(obj.weekNumber, 1, weeksInWeekYear(obj.weekYear)),
31606
- validWeekday = integerBetween(obj.weekday, 1, 7);
31607
- if (!validYear) {
31608
- return unitOutOfRange("weekYear", obj.weekYear);
31609
- } else if (!validWeek) {
31610
- return unitOutOfRange("week", obj.week);
31611
- } else if (!validWeekday) {
31612
- return unitOutOfRange("weekday", obj.weekday);
31613
- } else return false;
31614
- }
31615
- function hasInvalidOrdinalData(obj) {
31616
- const validYear = isInteger(obj.year),
31617
- validOrdinal = integerBetween(obj.ordinal, 1, daysInYear(obj.year));
31618
- if (!validYear) {
31619
- return unitOutOfRange("year", obj.year);
31620
- } else if (!validOrdinal) {
31621
- return unitOutOfRange("ordinal", obj.ordinal);
31622
- } else return false;
31623
- }
31624
- function hasInvalidGregorianData(obj) {
31625
- const validYear = isInteger(obj.year),
31626
- validMonth = integerBetween(obj.month, 1, 12),
31627
- validDay = integerBetween(obj.day, 1, daysInMonth(obj.year, obj.month));
31628
- if (!validYear) {
31629
- return unitOutOfRange("year", obj.year);
31630
- } else if (!validMonth) {
31631
- return unitOutOfRange("month", obj.month);
31632
- } else if (!validDay) {
31633
- return unitOutOfRange("day", obj.day);
31634
- } else return false;
31635
- }
31636
- function hasInvalidTimeData(obj) {
31637
- const {
31638
- hour,
31639
- minute,
31640
- second,
31641
- millisecond
31642
- } = obj;
31643
- const validHour = integerBetween(hour, 0, 23) || hour === 24 && minute === 0 && second === 0 && millisecond === 0,
31644
- validMinute = integerBetween(minute, 0, 59),
31645
- validSecond = integerBetween(second, 0, 59),
31646
- validMillisecond = integerBetween(millisecond, 0, 999);
31647
- if (!validHour) {
31648
- return unitOutOfRange("hour", hour);
31649
- } else if (!validMinute) {
31650
- return unitOutOfRange("minute", minute);
31651
- } else if (!validSecond) {
31652
- return unitOutOfRange("second", second);
31653
- } else if (!validMillisecond) {
31654
- return unitOutOfRange("millisecond", millisecond);
31655
- } else return false;
31656
- }
31657
-
31658
31979
  const INVALID = "Invalid DateTime";
31659
31980
  const MAX_DATE = 8.64e15;
31660
31981
  function unsupportedZone(zone) {
@@ -31662,6 +31983,9 @@ function unsupportedZone(zone) {
31662
31983
  }
31663
31984
 
31664
31985
  // we cache week data on the DT object and this intermediates the cache
31986
+ /**
31987
+ * @param {DateTime} dt
31988
+ */
31665
31989
  function possiblyCachedWeekData(dt) {
31666
31990
  if (dt.weekData === null) {
31667
31991
  dt.weekData = gregorianToWeek(dt.c);
@@ -31669,6 +31993,16 @@ function possiblyCachedWeekData(dt) {
31669
31993
  return dt.weekData;
31670
31994
  }
31671
31995
 
31996
+ /**
31997
+ * @param {DateTime} dt
31998
+ */
31999
+ function possiblyCachedLocalWeekData(dt) {
32000
+ if (dt.localWeekData === null) {
32001
+ dt.localWeekData = gregorianToWeek(dt.c, dt.loc.getMinDaysInFirstWeek(), dt.loc.getStartOfWeek());
32002
+ }
32003
+ return dt.localWeekData;
32004
+ }
32005
+
31672
32006
  // clone really means, "make a new object with these modifications". all "setters" really use this
31673
32007
  // to create a new object while only changing some of the properties
31674
32008
  function clone(inst, alts) {
@@ -31913,6 +32247,21 @@ function normalizeUnit(unit) {
31913
32247
  if (!normalized) throw new InvalidUnitError(unit);
31914
32248
  return normalized;
31915
32249
  }
32250
+ function normalizeUnitWithLocalWeeks(unit) {
32251
+ switch (unit.toLowerCase()) {
32252
+ case "localweekday":
32253
+ case "localweekdays":
32254
+ return "localWeekday";
32255
+ case "localweeknumber":
32256
+ case "localweeknumbers":
32257
+ return "localWeekNumber";
32258
+ case "localweekyear":
32259
+ case "localweekyears":
32260
+ return "localWeekYear";
32261
+ default:
32262
+ return normalizeUnit(unit);
32263
+ }
32264
+ }
31916
32265
 
31917
32266
  // this is a dumbed down version of fromObject() that runs about 60% faster
31918
32267
  // but doesn't do any validation, makes a bunch of assumptions about what units
@@ -32047,6 +32396,10 @@ class DateTime {
32047
32396
  * @access private
32048
32397
  */
32049
32398
  this.weekData = null;
32399
+ /**
32400
+ * @access private
32401
+ */
32402
+ this.localWeekData = null;
32050
32403
  /**
32051
32404
  * @access private
32052
32405
  */
@@ -32228,13 +32581,16 @@ class DateTime {
32228
32581
  * @param {number} obj.weekYear - an ISO week year
32229
32582
  * @param {number} obj.weekNumber - an ISO week number, between 1 and 52 or 53, depending on the year
32230
32583
  * @param {number} obj.weekday - an ISO weekday, 1-7, where 1 is Monday and 7 is Sunday
32584
+ * @param {number} obj.localWeekYear - a week year, according to the locale
32585
+ * @param {number} obj.localWeekNumber - a week number, between 1 and 52 or 53, depending on the year, according to the locale
32586
+ * @param {number} obj.localWeekday - a weekday, 1-7, where 1 is the first and 7 is the last day of the week, according to the locale
32231
32587
  * @param {number} obj.hour - hour of the day, 0-23
32232
32588
  * @param {number} obj.minute - minute of the hour, 0-59
32233
32589
  * @param {number} obj.second - second of the minute, 0-59
32234
32590
  * @param {number} obj.millisecond - millisecond of the second, 0-999
32235
32591
  * @param {Object} opts - options for creating this DateTime
32236
32592
  * @param {string|Zone} [opts.zone='local'] - interpret the numbers in the context of a particular zone. Can take any value taken as the first argument to setZone()
32237
- * @param {string} [opts.locale='system's locale'] - a locale to set on the resulting DateTime instance
32593
+ * @param {string} [opts.locale='system\'s locale'] - a locale to set on the resulting DateTime instance
32238
32594
  * @param {string} opts.outputCalendar - the output calendar to set on the resulting DateTime instance
32239
32595
  * @param {string} opts.numberingSystem - the numbering system to set on the resulting DateTime instance
32240
32596
  * @example DateTime.fromObject({ year: 1982, month: 5, day: 25}).toISODate() //=> '1982-05-25'
@@ -32244,6 +32600,7 @@ class DateTime {
32244
32600
  * @example DateTime.fromObject({ hour: 10, minute: 26, second: 6 }, { zone: 'local' })
32245
32601
  * @example DateTime.fromObject({ hour: 10, minute: 26, second: 6 }, { zone: 'America/New_York' })
32246
32602
  * @example DateTime.fromObject({ weekYear: 2016, weekNumber: 2, weekday: 3 }).toISODate() //=> '2016-01-13'
32603
+ * @example DateTime.fromObject({ localWeekYear: 2022, localWeekNumber: 1, localWeekday: 1 }, { locale: "en-US" }).toISODate() //=> '2021-12-26'
32247
32604
  * @return {DateTime}
32248
32605
  */
32249
32606
  static fromObject(obj, opts = {}) {
@@ -32252,15 +32609,19 @@ class DateTime {
32252
32609
  if (!zoneToUse.isValid) {
32253
32610
  return DateTime.invalid(unsupportedZone(zoneToUse));
32254
32611
  }
32612
+ const loc = Locale.fromObject(opts);
32613
+ const normalized = normalizeObject(obj, normalizeUnitWithLocalWeeks);
32614
+ const {
32615
+ minDaysInFirstWeek,
32616
+ startOfWeek
32617
+ } = usesLocalWeekValues(normalized, loc);
32255
32618
  const tsNow = Settings.now(),
32256
32619
  offsetProvis = !isUndefined(opts.specificOffset) ? opts.specificOffset : zoneToUse.offset(tsNow),
32257
- normalized = normalizeObject(obj, normalizeUnit),
32258
32620
  containsOrdinal = !isUndefined(normalized.ordinal),
32259
32621
  containsGregorYear = !isUndefined(normalized.year),
32260
32622
  containsGregorMD = !isUndefined(normalized.month) || !isUndefined(normalized.day),
32261
32623
  containsGregor = containsGregorYear || containsGregorMD,
32262
- definiteWeekDef = normalized.weekYear || normalized.weekNumber,
32263
- loc = Locale.fromObject(opts);
32624
+ definiteWeekDef = normalized.weekYear || normalized.weekNumber;
32264
32625
 
32265
32626
  // cases:
32266
32627
  // just a weekday -> this week's instance of that weekday, no worries
@@ -32283,7 +32644,7 @@ class DateTime {
32283
32644
  if (useWeekData) {
32284
32645
  units = orderedWeekUnits;
32285
32646
  defaultValues = defaultWeekUnitValues;
32286
- objNow = gregorianToWeek(objNow);
32647
+ objNow = gregorianToWeek(objNow, minDaysInFirstWeek, startOfWeek);
32287
32648
  } else if (containsOrdinal) {
32288
32649
  units = orderedOrdinalUnits;
32289
32650
  defaultValues = defaultOrdinalUnitValues;
@@ -32307,14 +32668,14 @@ class DateTime {
32307
32668
  }
32308
32669
 
32309
32670
  // make sure the values we have are in range
32310
- const higherOrderInvalid = useWeekData ? hasInvalidWeekData(normalized) : containsOrdinal ? hasInvalidOrdinalData(normalized) : hasInvalidGregorianData(normalized),
32671
+ const higherOrderInvalid = useWeekData ? hasInvalidWeekData(normalized, minDaysInFirstWeek, startOfWeek) : containsOrdinal ? hasInvalidOrdinalData(normalized) : hasInvalidGregorianData(normalized),
32311
32672
  invalid = higherOrderInvalid || hasInvalidTimeData(normalized);
32312
32673
  if (invalid) {
32313
32674
  return DateTime.invalid(invalid);
32314
32675
  }
32315
32676
 
32316
32677
  // compute the actual time
32317
- const gregorian = useWeekData ? weekToGregorian(normalized) : containsOrdinal ? ordinalToGregorian(normalized) : normalized,
32678
+ const gregorian = useWeekData ? weekToGregorian(normalized, minDaysInFirstWeek, startOfWeek) : containsOrdinal ? ordinalToGregorian(normalized) : normalized,
32318
32679
  [tsFinal, offsetFinal] = objToTS(gregorian, offsetProvis, zoneToUse),
32319
32680
  inst = new DateTime({
32320
32681
  ts: tsFinal,
@@ -32693,6 +33054,43 @@ class DateTime {
32693
33054
  return this.isValid ? possiblyCachedWeekData(this).weekday : NaN;
32694
33055
  }
32695
33056
 
33057
+ /**
33058
+ * Returns true if this date is on a weekend according to the locale, false otherwise
33059
+ * @returns {boolean}
33060
+ */
33061
+ get isWeekend() {
33062
+ return this.isValid && this.loc.getWeekendDays().includes(this.weekday);
33063
+ }
33064
+
33065
+ /**
33066
+ * Get the day of the week according to the locale.
33067
+ * 1 is the first day of the week and 7 is the last day of the week.
33068
+ * If the locale assigns Sunday as the first day of the week, then a date which is a Sunday will return 1,
33069
+ * @returns {number}
33070
+ */
33071
+ get localWeekday() {
33072
+ return this.isValid ? possiblyCachedLocalWeekData(this).weekday : NaN;
33073
+ }
33074
+
33075
+ /**
33076
+ * Get the week number of the week year according to the locale. Different locales assign week numbers differently,
33077
+ * because the week can start on different days of the week (see localWeekday) and because a different number of days
33078
+ * is required for a week to count as the first week of a year.
33079
+ * @returns {number}
33080
+ */
33081
+ get localWeekNumber() {
33082
+ return this.isValid ? possiblyCachedLocalWeekData(this).weekNumber : NaN;
33083
+ }
33084
+
33085
+ /**
33086
+ * Get the week year according to the locale. Different locales assign week numbers (and therefor week years)
33087
+ * differently, see localWeekNumber.
33088
+ * @returns {number}
33089
+ */
33090
+ get localWeekYear() {
33091
+ return this.isValid ? possiblyCachedLocalWeekData(this).weekYear : NaN;
33092
+ }
33093
+
32696
33094
  /**
32697
33095
  * Get the ordinal (meaning the day of the year)
32698
33096
  * @example DateTime.local(2017, 5, 25).ordinal //=> 145
@@ -32893,6 +33291,16 @@ class DateTime {
32893
33291
  return this.isValid ? weeksInWeekYear(this.weekYear) : NaN;
32894
33292
  }
32895
33293
 
33294
+ /**
33295
+ * Returns the number of weeks in this DateTime's local week year
33296
+ * @example DateTime.local(2020, 6, {locale: 'en-US'}).weeksInLocalWeekYear //=> 52
33297
+ * @example DateTime.local(2020, 6, {locale: 'de-DE'}).weeksInLocalWeekYear //=> 53
33298
+ * @type {number}
33299
+ */
33300
+ get weeksInLocalWeekYear() {
33301
+ return this.isValid ? weeksInWeekYear(this.localWeekYear, this.loc.getMinDaysInFirstWeek(), this.loc.getStartOfWeek()) : NaN;
33302
+ }
33303
+
32896
33304
  /**
32897
33305
  * Returns the resolved Intl options for this DateTime.
32898
33306
  * This is useful in understanding the behavior of formatting methods
@@ -33004,6 +33412,9 @@ class DateTime {
33004
33412
  /**
33005
33413
  * "Set" the values of specified units. Returns a newly-constructed DateTime.
33006
33414
  * You can only set units with this method; for "setting" metadata, see {@link DateTime#reconfigure} and {@link DateTime#setZone}.
33415
+ *
33416
+ * This method also supports setting locale-based week units, i.e. `localWeekday`, `localWeekNumber` and `localWeekYear`.
33417
+ * They cannot be mixed with ISO-week units like `weekday`.
33007
33418
  * @param {Object} values - a mapping of units to numbers
33008
33419
  * @example dt.set({ year: 2017 })
33009
33420
  * @example dt.set({ hour: 8, minute: 30 })
@@ -33013,8 +33424,12 @@ class DateTime {
33013
33424
  */
33014
33425
  set(values) {
33015
33426
  if (!this.isValid) return this;
33016
- const normalized = normalizeObject(values, normalizeUnit),
33017
- settingWeekStuff = !isUndefined(normalized.weekYear) || !isUndefined(normalized.weekNumber) || !isUndefined(normalized.weekday),
33427
+ const normalized = normalizeObject(values, normalizeUnitWithLocalWeeks);
33428
+ const {
33429
+ minDaysInFirstWeek,
33430
+ startOfWeek
33431
+ } = usesLocalWeekValues(normalized, this.loc);
33432
+ const settingWeekStuff = !isUndefined(normalized.weekYear) || !isUndefined(normalized.weekNumber) || !isUndefined(normalized.weekday),
33018
33433
  containsOrdinal = !isUndefined(normalized.ordinal),
33019
33434
  containsGregorYear = !isUndefined(normalized.year),
33020
33435
  containsGregorMD = !isUndefined(normalized.month) || !isUndefined(normalized.day),
@@ -33029,9 +33444,9 @@ class DateTime {
33029
33444
  let mixed;
33030
33445
  if (settingWeekStuff) {
33031
33446
  mixed = weekToGregorian({
33032
- ...gregorianToWeek(this.c),
33447
+ ...gregorianToWeek(this.c, minDaysInFirstWeek, startOfWeek),
33033
33448
  ...normalized
33034
- });
33449
+ }, minDaysInFirstWeek, startOfWeek);
33035
33450
  } else if (!isUndefined(normalized.ordinal)) {
33036
33451
  mixed = ordinalToGregorian({
33037
33452
  ...gregorianToOrdinal(this.c),
@@ -33090,6 +33505,8 @@ class DateTime {
33090
33505
  /**
33091
33506
  * "Set" this DateTime to the beginning of a unit of time.
33092
33507
  * @param {string} unit - The unit to go to the beginning of. Can be 'year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', or 'millisecond'.
33508
+ * @param {Object} opts - options
33509
+ * @param {boolean} [opts.useLocaleWeeks=false] - If true, use weeks based on the locale, i.e. use the locale-dependent start of the week
33093
33510
  * @example DateTime.local(2014, 3, 3).startOf('month').toISODate(); //=> '2014-03-01'
33094
33511
  * @example DateTime.local(2014, 3, 3).startOf('year').toISODate(); //=> '2014-01-01'
33095
33512
  * @example DateTime.local(2014, 3, 3).startOf('week').toISODate(); //=> '2014-03-03', weeks always start on Mondays
@@ -33097,7 +33514,9 @@ class DateTime {
33097
33514
  * @example DateTime.local(2014, 3, 3, 5, 30).startOf('hour').toISOTime(); //=> '05:00:00.000-05:00'
33098
33515
  * @return {DateTime}
33099
33516
  */
33100
- startOf(unit) {
33517
+ startOf(unit, {
33518
+ useLocaleWeeks = false
33519
+ } = {}) {
33101
33520
  if (!this.isValid) return this;
33102
33521
  const o = {},
33103
33522
  normalizedUnit = Duration.normalizeUnit(unit);
@@ -33126,7 +33545,18 @@ class DateTime {
33126
33545
  }
33127
33546
 
33128
33547
  if (normalizedUnit === "weeks") {
33129
- o.weekday = 1;
33548
+ if (useLocaleWeeks) {
33549
+ const startOfWeek = this.loc.getStartOfWeek();
33550
+ const {
33551
+ weekday
33552
+ } = this;
33553
+ if (weekday < startOfWeek) {
33554
+ o.weekNumber = this.weekNumber - 1;
33555
+ }
33556
+ o.weekday = startOfWeek;
33557
+ } else {
33558
+ o.weekday = 1;
33559
+ }
33130
33560
  }
33131
33561
  if (normalizedUnit === "quarters") {
33132
33562
  const q = Math.ceil(this.month / 3);
@@ -33138,6 +33568,8 @@ class DateTime {
33138
33568
  /**
33139
33569
  * "Set" this DateTime to the end (meaning the last millisecond) of a unit of time
33140
33570
  * @param {string} unit - The unit to go to the end of. Can be 'year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', or 'millisecond'.
33571
+ * @param {Object} opts - options
33572
+ * @param {boolean} [opts.useLocaleWeeks=false] - If true, use weeks based on the locale, i.e. use the locale-dependent start of the week
33141
33573
  * @example DateTime.local(2014, 3, 3).endOf('month').toISO(); //=> '2014-03-31T23:59:59.999-05:00'
33142
33574
  * @example DateTime.local(2014, 3, 3).endOf('year').toISO(); //=> '2014-12-31T23:59:59.999-05:00'
33143
33575
  * @example DateTime.local(2014, 3, 3).endOf('week').toISO(); // => '2014-03-09T23:59:59.999-05:00', weeks start on Mondays
@@ -33145,10 +33577,10 @@ class DateTime {
33145
33577
  * @example DateTime.local(2014, 3, 3, 5, 30).endOf('hour').toISO(); //=> '2014-03-03T05:59:59.999-05:00'
33146
33578
  * @return {DateTime}
33147
33579
  */
33148
- endOf(unit) {
33580
+ endOf(unit, opts) {
33149
33581
  return this.isValid ? this.plus({
33150
33582
  [unit]: 1
33151
- }).startOf(unit).minus(1) : this;
33583
+ }).startOf(unit, opts).minus(1) : this;
33152
33584
  }
33153
33585
 
33154
33586
  // OUTPUT
@@ -33388,6 +33820,18 @@ class DateTime {
33388
33820
  return this.isValid ? this.toISO() : INVALID;
33389
33821
  }
33390
33822
 
33823
+ /**
33824
+ * Returns a string representation of this DateTime appropriate for the REPL.
33825
+ * @return {string}
33826
+ */
33827
+ [Symbol.for("nodejs.util.inspect.custom")]() {
33828
+ if (this.isValid) {
33829
+ return `DateTime { ts: ${this.toISO()}, zone: ${this.zone.name}, locale: ${this.locale} }`;
33830
+ } else {
33831
+ return `DateTime { Invalid, reason: ${this.invalidReason} }`;
33832
+ }
33833
+ }
33834
+
33391
33835
  /**
33392
33836
  * Returns the epoch milliseconds of this DateTime. Alias of {@link DateTime#toMillis}
33393
33837
  * @return {number}
@@ -33525,16 +33969,18 @@ class DateTime {
33525
33969
  * Note that time zones are **ignored** in this comparison, which compares the **local** calendar time. Use {@link DateTime#setZone} to convert one of the dates if needed.
33526
33970
  * @param {DateTime} otherDateTime - the other DateTime
33527
33971
  * @param {string} unit - the unit of time to check sameness on
33972
+ * @param {Object} opts - options
33973
+ * @param {boolean} [opts.useLocaleWeeks=false] - If true, use weeks based on the locale, i.e. use the locale-dependent start of the week; only the locale of this DateTime is used
33528
33974
  * @example DateTime.now().hasSame(otherDT, 'day'); //~> true if otherDT is in the same current calendar day
33529
33975
  * @return {boolean}
33530
33976
  */
33531
- hasSame(otherDateTime, unit) {
33977
+ hasSame(otherDateTime, unit, opts) {
33532
33978
  if (!this.isValid) return false;
33533
33979
  const inputMs = otherDateTime.valueOf();
33534
33980
  const adjustedToZone = this.setZone(otherDateTime.zone, {
33535
33981
  keepLocalTime: true
33536
33982
  });
33537
- return adjustedToZone.startOf(unit) <= inputMs && inputMs <= adjustedToZone.endOf(unit);
33983
+ return adjustedToZone.startOf(unit, opts) <= inputMs && inputMs <= adjustedToZone.endOf(unit, opts);
33538
33984
  }
33539
33985
 
33540
33986
  /**
@@ -33858,7 +34304,7 @@ function friendlyDateTime(dateTimeish) {
33858
34304
  }
33859
34305
  }
33860
34306
 
33861
- const VERSION = "3.4.3";
34307
+ const VERSION = "3.4.4";
33862
34308
 
33863
34309
  exports.DateTime = DateTime;
33864
34310
  exports.Duration = Duration;