@labdigital/commercetools-mock 2.54.0 → 2.56.0

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 (53) hide show
  1. package/dist/index.d.ts +107 -77
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +455 -8
  4. package/dist/index.js.map +1 -1
  5. package/package.json +4 -3
  6. package/src/lib/predicateParser.test.ts +13 -37
  7. package/src/lib/predicateParser.ts +12 -1
  8. package/src/lib/productSearchFilter.test.ts +1 -0
  9. package/src/lib/projectionSearchFilter.test.ts +1 -0
  10. package/src/priceSelector.test.ts +1 -0
  11. package/src/product-projection-search.ts +2 -0
  12. package/src/product-search.ts +1 -0
  13. package/src/repositories/cart/actions.ts +178 -0
  14. package/src/repositories/cart/helpers.ts +170 -3
  15. package/src/repositories/cart/index.test.ts +86 -2
  16. package/src/repositories/cart/index.ts +19 -2
  17. package/src/repositories/cart-discount/index.ts +1 -1
  18. package/src/repositories/customer/index.ts +2 -0
  19. package/src/repositories/discount-group/actions.ts +50 -0
  20. package/src/repositories/discount-group/index.ts +29 -0
  21. package/src/repositories/index.ts +6 -0
  22. package/src/repositories/order/index.test.ts +126 -125
  23. package/src/repositories/payment/actions.ts +87 -0
  24. package/src/repositories/payment/index.ts +1 -1
  25. package/src/repositories/product/index.ts +1 -0
  26. package/src/repositories/product-type.ts +1 -0
  27. package/src/repositories/quote/index.ts +1 -0
  28. package/src/repositories/quote-request/index.test.ts +1 -0
  29. package/src/repositories/quote-request/index.ts +1 -0
  30. package/src/repositories/recurrence-policy/actions.ts +53 -0
  31. package/src/repositories/recurrence-policy/index.ts +36 -0
  32. package/src/repositories/recurring-order/actions.ts +157 -0
  33. package/src/repositories/recurring-order/index.ts +52 -0
  34. package/src/repositories/review.test.ts +2 -0
  35. package/src/repositories/shopping-list/actions.ts +1 -0
  36. package/src/repositories/shopping-list/index.ts +1 -0
  37. package/src/services/cart.test.ts +282 -0
  38. package/src/services/discount-group.test.ts +270 -0
  39. package/src/services/discount-group.ts +16 -0
  40. package/src/services/index.ts +12 -0
  41. package/src/services/my-cart.test.ts +1 -0
  42. package/src/services/my-payment.test.ts +1 -0
  43. package/src/services/payment.test.ts +1 -0
  44. package/src/services/product-projection.test.ts +4 -0
  45. package/src/services/product-type.test.ts +1 -0
  46. package/src/services/product.test.ts +1 -0
  47. package/src/services/recurrence-policy.test.ts +316 -0
  48. package/src/services/recurrence-policy.ts +16 -0
  49. package/src/services/recurring-order.test.ts +424 -0
  50. package/src/services/recurring-order.ts +16 -0
  51. package/src/services/shopping-list.test.ts +3 -0
  52. package/src/storage/in-memory.ts +6 -0
  53. package/src/types.ts +6 -0
package/dist/index.js CHANGED
@@ -760,7 +760,88 @@ const selectPrice = ({ prices, currency, country }) => {
760
760
  });
761
761
  };
762
762
  const calculateLineItemTotalPrice = (lineItem) => lineItem.price?.value.centAmount * lineItem.quantity;
763
- const calculateCartTotalPrice = (cart) => cart.lineItems.reduce((cur, item) => cur + item.totalPrice.centAmount, 0);
763
+ const calculateCartTotalPrice = (cart) => {
764
+ const lineItemsTotal = cart.lineItems.reduce((cur, item) => cur + item.totalPrice.centAmount, 0);
765
+ const customLineItemsTotal = cart.customLineItems.reduce((cur, item) => cur + item.totalPrice.centAmount, 0);
766
+ return lineItemsTotal + customLineItemsTotal;
767
+ };
768
+ const calculateTaxedPrice = (amount, taxCategory, currency, country) => {
769
+ if (!taxCategory || !taxCategory.rates.length) return void 0;
770
+ const taxRate = taxCategory.rates.find((rate) => !rate.country || rate.country === country) || taxCategory.rates[0];
771
+ if (!taxRate) return void 0;
772
+ let netAmount;
773
+ let grossAmount;
774
+ let taxAmount;
775
+ if (taxRate.includedInPrice) {
776
+ grossAmount = amount;
777
+ taxAmount = Math.round(grossAmount * taxRate.amount / (1 + taxRate.amount));
778
+ netAmount = grossAmount - taxAmount;
779
+ } else {
780
+ netAmount = amount;
781
+ taxAmount = Math.round(netAmount * taxRate.amount);
782
+ grossAmount = netAmount + taxAmount;
783
+ }
784
+ return {
785
+ totalNet: {
786
+ type: "centPrecision",
787
+ currencyCode: currency,
788
+ centAmount: netAmount,
789
+ fractionDigits: 2
790
+ },
791
+ totalGross: {
792
+ type: "centPrecision",
793
+ currencyCode: currency,
794
+ centAmount: grossAmount,
795
+ fractionDigits: 2
796
+ },
797
+ taxPortions: taxAmount > 0 ? [{
798
+ rate: taxRate.amount,
799
+ amount: {
800
+ type: "centPrecision",
801
+ currencyCode: currency,
802
+ centAmount: taxAmount,
803
+ fractionDigits: 2
804
+ },
805
+ name: taxRate.name
806
+ }] : [],
807
+ totalTax: taxAmount > 0 ? {
808
+ type: "centPrecision",
809
+ currencyCode: currency,
810
+ centAmount: taxAmount,
811
+ fractionDigits: 2
812
+ } : void 0
813
+ };
814
+ };
815
+ const createCustomLineItemFromDraft = (projectKey, draft, storage, country) => {
816
+ const quantity = draft.quantity ?? 1;
817
+ const taxCategoryRef = draft.taxCategory ? getReferenceFromResourceIdentifier(draft.taxCategory, projectKey, storage) : void 0;
818
+ let taxCategory = void 0;
819
+ if (taxCategoryRef) try {
820
+ taxCategory = storage.get(projectKey, "tax-category", taxCategoryRef.id, {}) || void 0;
821
+ } catch (error) {}
822
+ const totalPrice = createCentPrecisionMoney({
823
+ ...draft.money,
824
+ centAmount: (draft.money.centAmount ?? 0) * quantity
825
+ });
826
+ const taxedPrice = taxCategory ? calculateTaxedPrice(totalPrice.centAmount, taxCategory, totalPrice.currencyCode, country) : void 0;
827
+ return {
828
+ id: v4(),
829
+ key: draft.key,
830
+ name: draft.name,
831
+ money: createTypedMoney(draft.money),
832
+ slug: draft.slug,
833
+ quantity: draft.quantity ?? 1,
834
+ state: [],
835
+ taxCategory: taxCategoryRef,
836
+ taxedPrice,
837
+ custom: createCustomFields(draft.custom, projectKey, storage),
838
+ discountedPricePerQuantity: [],
839
+ perMethodTaxRate: [],
840
+ priceMode: draft.priceMode ?? "Standard",
841
+ totalPrice,
842
+ taxedPricePortions: []
843
+ };
844
+ };
764
845
 
765
846
  //#endregion
766
847
  //#region src/repositories/cart/actions.ts
@@ -886,6 +967,94 @@ var CartUpdateHandler = class extends AbstractUpdateHandler {
886
967
  });
887
968
  resource.totalPrice.centAmount = calculateCartTotalPrice(resource);
888
969
  }
970
+ addCustomLineItem(context, resource, { money, name, slug, quantity = 1, taxCategory, custom, priceMode = "Standard", key }) {
971
+ const customLineItem = createCustomLineItemFromDraft(context.projectKey, {
972
+ money,
973
+ name,
974
+ slug,
975
+ quantity,
976
+ taxCategory,
977
+ custom,
978
+ priceMode,
979
+ key
980
+ }, this._storage, resource.country);
981
+ resource.customLineItems.push(customLineItem);
982
+ resource.totalPrice.centAmount = calculateCartTotalPrice(resource);
983
+ }
984
+ removeCustomLineItem(context, resource, { customLineItemId, customLineItemKey }) {
985
+ let customLineItem;
986
+ if (!customLineItemId && !customLineItemKey) throw new CommercetoolsError({
987
+ code: "General",
988
+ message: "Either customLineItemId or customLineItemKey needs to be provided."
989
+ });
990
+ if (customLineItemId) {
991
+ customLineItem = resource.customLineItems.find((x) => x.id === customLineItemId);
992
+ if (!customLineItem) throw new CommercetoolsError({
993
+ code: "General",
994
+ message: `A custom line item with ID '${customLineItemId}' not found.`
995
+ });
996
+ resource.customLineItems = resource.customLineItems.filter((x) => x.id !== customLineItemId);
997
+ }
998
+ if (customLineItemKey) {
999
+ customLineItem = resource.customLineItems.find((x) => x.key === customLineItemKey);
1000
+ if (!customLineItem) throw new CommercetoolsError({
1001
+ code: "General",
1002
+ message: `A custom line item with key '${customLineItemKey}' not found.`
1003
+ });
1004
+ resource.customLineItems = resource.customLineItems.filter((x) => x.key !== customLineItemKey);
1005
+ }
1006
+ resource.totalPrice.centAmount = calculateCartTotalPrice(resource);
1007
+ }
1008
+ changeCustomLineItemQuantity(context, resource, { customLineItemId, customLineItemKey, quantity }) {
1009
+ let customLineItem;
1010
+ if (!customLineItemId && !customLineItemKey) throw new CommercetoolsError({
1011
+ code: "General",
1012
+ message: "Either customLineItemId or customLineItemKey needs to be provided."
1013
+ });
1014
+ const setQuantity = (customLineItem$1) => {
1015
+ if (!customLineItem$1) throw new CommercetoolsError({
1016
+ code: "General",
1017
+ message: `A custom line item with ${customLineItemId ? `ID '${customLineItemId}'` : `key '${customLineItemKey}'`} not found.`
1018
+ });
1019
+ customLineItem$1.quantity = quantity;
1020
+ customLineItem$1.totalPrice = createCentPrecisionMoney({
1021
+ ...customLineItem$1.money,
1022
+ centAmount: (customLineItem$1.money.centAmount ?? 0) * quantity
1023
+ });
1024
+ };
1025
+ if (customLineItemId) {
1026
+ customLineItem = resource.customLineItems.find((x) => x.id === customLineItemId);
1027
+ setQuantity(customLineItem);
1028
+ }
1029
+ if (customLineItemKey) {
1030
+ customLineItem = resource.customLineItems.find((x) => x.key === customLineItemKey);
1031
+ setQuantity(customLineItem);
1032
+ }
1033
+ resource.totalPrice.centAmount = calculateCartTotalPrice(resource);
1034
+ }
1035
+ changeCustomLineItemMoney(context, resource, { customLineItemId, customLineItemKey, money }) {
1036
+ let customLineItem;
1037
+ const setMoney = (customLineItem$1) => {
1038
+ if (!customLineItem$1) throw new CommercetoolsError({
1039
+ code: "General",
1040
+ message: `A custom line item with ${customLineItemId ? `ID '${customLineItemId}'` : `key '${customLineItemKey}'`} not found.`
1041
+ });
1042
+ customLineItem$1.money = createTypedMoney(money);
1043
+ customLineItem$1.totalPrice = createCentPrecisionMoney({
1044
+ ...money,
1045
+ centAmount: (money.centAmount ?? 0) * customLineItem$1.quantity
1046
+ });
1047
+ };
1048
+ if (customLineItemId) {
1049
+ customLineItem = resource.customLineItems.find((x) => x.id === customLineItemId);
1050
+ setMoney(customLineItem);
1051
+ }
1052
+ if (customLineItemKey) {
1053
+ customLineItem = resource.customLineItems.find((x) => x.key === customLineItemKey);
1054
+ setMoney(customLineItem);
1055
+ }
1056
+ resource.totalPrice.centAmount = calculateCartTotalPrice(resource);
1057
+ }
889
1058
  setAnonymousId(_context, resource, { anonymousId }) {
890
1059
  resource.anonymousId = anonymousId;
891
1060
  resource.customerId = void 0;
@@ -1110,6 +1279,7 @@ var CartRepository = class extends AbstractResourceRepository {
1110
1279
  key: draft.businessUnit.key
1111
1280
  });
1112
1281
  const lineItems = draft.lineItems?.map((draftLineItem) => this.draftLineItemtoLineItem(context.projectKey, draftLineItem, draft.currency, draft.country)) ?? [];
1282
+ const customLineItems = draft.customLineItems?.map((draftCustomLineItem) => createCustomLineItemFromDraft(context.projectKey, draftCustomLineItem, this._storage, draft.country)) ?? [];
1113
1283
  const resource = {
1114
1284
  ...getBaseResourceProperties(),
1115
1285
  anonymousId: draft.anonymousId,
@@ -1122,13 +1292,14 @@ var CartRepository = class extends AbstractResourceRepository {
1122
1292
  country: draft.country,
1123
1293
  customerId: draft.customerId,
1124
1294
  customerEmail: draft.customerEmail,
1125
- customLineItems: [],
1295
+ customLineItems,
1126
1296
  directDiscounts: [],
1127
1297
  discountCodes: [],
1128
1298
  inventoryMode: "None",
1129
1299
  itemShippingAddresses: [],
1130
1300
  lineItems,
1131
1301
  locale: draft.locale,
1302
+ priceRoundingMode: draft.priceRoundingMode ?? "HalfEven",
1132
1303
  taxCalculationMode: draft.taxCalculationMode ?? "LineItemLevel",
1133
1304
  taxMode: draft.taxMode ?? "Platform",
1134
1305
  taxRoundingMode: draft.taxRoundingMode ?? "HalfEven",
@@ -1565,6 +1736,7 @@ var QuoteRequestRepository = class extends AbstractResourceRepository {
1565
1736
  directDiscounts: cart.directDiscounts,
1566
1737
  lineItems: cart.lineItems,
1567
1738
  paymentInfo: cart.paymentInfo,
1739
+ priceRoundingMode: cart.priceRoundingMode,
1568
1740
  quoteRequestState: "Submitted",
1569
1741
  shippingAddress: cart.shippingAddress,
1570
1742
  taxCalculationMode: cart.taxCalculationMode,
@@ -1922,7 +2094,7 @@ var CartDiscountRepository = class extends AbstractResourceRepository {
1922
2094
  references: [],
1923
2095
  target: draft.target,
1924
2096
  requiresDiscountCode: draft.requiresDiscountCode || false,
1925
- sortOrder: draft.sortOrder,
2097
+ sortOrder: draft.sortOrder ?? "0.1",
1926
2098
  stackingMode: draft.stackingMode || "Stacking",
1927
2099
  validFrom: draft.validFrom,
1928
2100
  validUntil: draft.validUntil,
@@ -2487,7 +2659,8 @@ var CustomerRepository = class extends AbstractResourceRepository {
2487
2659
  lastModifiedAt: rest.lastModifiedAt,
2488
2660
  customerId: customer.id,
2489
2661
  expiresAt: expiresAt.toISOString(),
2490
- value: token
2662
+ value: token,
2663
+ invalidateOlderTokens: request.invalidateOlderTokens || false
2491
2664
  };
2492
2665
  }
2493
2666
  passwordReset(context, resetPassword) {
@@ -2523,7 +2696,8 @@ var CustomerRepository = class extends AbstractResourceRepository {
2523
2696
  lastModifiedAt: rest.lastModifiedAt,
2524
2697
  customerId: customer.id,
2525
2698
  expiresAt: expiresAt.toISOString(),
2526
- value: token
2699
+ value: token,
2700
+ invalidateOlderTokens: false
2527
2701
  };
2528
2702
  }
2529
2703
  storeReferenceToStoreKeyReference(draftStores, projectKey) {
@@ -2664,6 +2838,42 @@ var DiscountCodeRepository = class extends AbstractResourceRepository {
2664
2838
  }
2665
2839
  };
2666
2840
 
2841
+ //#endregion
2842
+ //#region src/repositories/discount-group/actions.ts
2843
+ var DiscountGroupUpdateHandler = class extends AbstractUpdateHandler {
2844
+ setDescription(context, resource, { description }) {
2845
+ resource.description = description;
2846
+ }
2847
+ setKey(context, resource, { key }) {
2848
+ resource.key = key;
2849
+ }
2850
+ setName(context, resource, { name }) {
2851
+ resource.name = name;
2852
+ }
2853
+ setSortOrder(context, resource, { sortOrder }) {
2854
+ resource.sortOrder = sortOrder;
2855
+ }
2856
+ };
2857
+
2858
+ //#endregion
2859
+ //#region src/repositories/discount-group/index.ts
2860
+ var DiscountGroupRepository = class extends AbstractResourceRepository {
2861
+ constructor(config) {
2862
+ super("discount-group", config);
2863
+ this.actions = new DiscountGroupUpdateHandler(config.storage);
2864
+ }
2865
+ create(context, draft) {
2866
+ const resource = {
2867
+ ...getBaseResourceProperties(),
2868
+ description: draft.description,
2869
+ name: draft.name,
2870
+ key: draft.key,
2871
+ sortOrder: draft.sortOrder
2872
+ };
2873
+ return this.saveNew(context, resource);
2874
+ }
2875
+ };
2876
+
2667
2877
  //#endregion
2668
2878
  //#region src/lib/masking.ts
2669
2879
  const maskSecretValue = (resource, path) => {
@@ -2982,6 +3192,37 @@ var PaymentUpdateHandler = class extends AbstractUpdateHandler {
2982
3192
  obj: stateObj
2983
3193
  };
2984
3194
  }
3195
+ setMethodInfo(context, resource, { paymentInterface, method, name, interfaceAccount, token }) {
3196
+ if (paymentInterface !== void 0) resource.paymentMethodInfo.paymentInterface = paymentInterface;
3197
+ if (method !== void 0) resource.paymentMethodInfo.method = method;
3198
+ if (name !== void 0) resource.paymentMethodInfo.name = name;
3199
+ if (interfaceAccount !== void 0) resource.paymentMethodInfo.interfaceAccount = interfaceAccount;
3200
+ if (token !== void 0) resource.paymentMethodInfo.token = token;
3201
+ }
3202
+ setMethodInfoCustomField(context, resource, { name, value }) {
3203
+ if (!resource.paymentMethodInfo.custom) throw new Error("PaymentMethodInfo has no custom field");
3204
+ resource.paymentMethodInfo.custom.fields[name] = value;
3205
+ }
3206
+ setMethodInfoCustomType(context, resource, { type, fields }) {
3207
+ if (!type) resource.paymentMethodInfo.custom = void 0;
3208
+ else {
3209
+ const resolvedType = this._storage.getByResourceIdentifier(context.projectKey, type);
3210
+ if (!resolvedType) throw new Error(`Type ${type} not found`);
3211
+ resource.paymentMethodInfo.custom = {
3212
+ type: {
3213
+ typeId: "type",
3214
+ id: resolvedType.id
3215
+ },
3216
+ fields: fields ?? {}
3217
+ };
3218
+ }
3219
+ }
3220
+ setMethodInfoInterfaceAccount(_context, resource, { interfaceAccount }) {
3221
+ resource.paymentMethodInfo.interfaceAccount = interfaceAccount;
3222
+ }
3223
+ setMethodInfoToken(_context, resource, { token }) {
3224
+ resource.paymentMethodInfo.token = token;
3225
+ }
2985
3226
  };
2986
3227
 
2987
3228
  //#endregion
@@ -2996,7 +3237,10 @@ var PaymentRepository = class extends AbstractResourceRepository {
2996
3237
  ...getBaseResourceProperties(),
2997
3238
  key: draft.key,
2998
3239
  amountPlanned: createCentPrecisionMoney(draft.amountPlanned),
2999
- paymentMethodInfo: draft.paymentMethodInfo,
3240
+ paymentMethodInfo: {
3241
+ ...draft.paymentMethodInfo,
3242
+ custom: void 0
3243
+ },
3000
3244
  paymentStatus: draft.paymentStatus ? {
3001
3245
  ...draft.paymentStatus,
3002
3246
  state: draft.paymentStatus.state ? getReferenceFromResourceIdentifier(draft.paymentStatus.state, context.projectKey, this._storage) : void 0
@@ -4032,6 +4276,7 @@ var ProductSearch = class {
4032
4276
  metaDescription: obj.metaDescription,
4033
4277
  slug: obj.slug,
4034
4278
  categories: obj.categories,
4279
+ attributes: obj.attributes,
4035
4280
  masterVariant: {
4036
4281
  ...obj.masterVariant,
4037
4282
  availability: getVariantAvailability(obj.masterVariant.sku)
@@ -4496,6 +4741,7 @@ var ProductRepository = class extends AbstractResourceRepository {
4496
4741
  name: draft.name,
4497
4742
  slug: draft.slug,
4498
4743
  description: draft.description,
4744
+ attributes: draft.attributes ?? [],
4499
4745
  categories: categoryReferences,
4500
4746
  masterVariant: variantFromDraft(context, this._storage, 1, draft.masterVariant),
4501
4747
  variants: draft.variants?.map((variant, index) => variantFromDraft(context, this._storage, index + 2, variant)) ?? [],
@@ -4788,13 +5034,15 @@ const generateMatchFunc = (predicate) => {
4788
5034
  default: throw new Error("Unexpected");
4789
5035
  }
4790
5036
  }).led("IN", 20, ({ left, bp }) => {
5037
+ const firstToken = lexer.peek();
4791
5038
  const expr = parser.parse({ terminals: [bp - 1] });
4792
- lexer.expect(")");
5039
+ if (firstToken.match === "(") lexer.expect(")");
4793
5040
  return (obj, vars) => {
4794
5041
  let symbols = expr;
4795
5042
  if (!Array.isArray(symbols)) symbols = [expr];
4796
5043
  const inValues = symbols.flatMap((item) => resolveSymbol(item, vars));
4797
5044
  const value = resolveValue(obj, left);
5045
+ if (Array.isArray(value)) return inValues.some((inValue) => value.includes(inValue));
4798
5046
  return inValues.includes(value);
4799
5047
  };
4800
5048
  }).led("MATCHES_IGNORE_CASE", 20, ({ left, bp }) => {
@@ -4907,6 +5155,7 @@ var ProductProjectionSearch = class {
4907
5155
  return {
4908
5156
  id: product.id,
4909
5157
  createdAt: product.createdAt,
5158
+ attributes: obj.attributes,
4910
5159
  lastModifiedAt: product.lastModifiedAt,
4911
5160
  version: product.version,
4912
5161
  name: obj.name,
@@ -5139,6 +5388,7 @@ var ProductTypeRepository = class extends AbstractResourceRepository {
5139
5388
  };
5140
5389
  const attributeDefinitionFromAttributeDefinitionDraft = (_context, draft) => ({
5141
5390
  ...draft,
5391
+ level: draft.level ?? "Variant",
5142
5392
  attributeConstraint: draft.attributeConstraint ?? "None",
5143
5393
  inputHint: draft.inputHint ?? "SingleLine",
5144
5394
  inputTip: draft.inputTip && Object.keys(draft.inputTip).length > 0 ? draft.inputTip : void 0,
@@ -5347,6 +5597,7 @@ var QuoteRepository = class extends AbstractResourceRepository {
5347
5597
  typeId: "staged-quote",
5348
5598
  id: staged.id
5349
5599
  },
5600
+ priceRoundingMode: cart.priceRoundingMode,
5350
5601
  totalPrice: cart.totalPrice,
5351
5602
  taxedPrice: cart.taxedPrice,
5352
5603
  taxMode: cart.taxMode,
@@ -5421,6 +5672,152 @@ var StagedQuoteRepository = class extends AbstractResourceRepository {
5421
5672
  }
5422
5673
  };
5423
5674
 
5675
+ //#endregion
5676
+ //#region src/repositories/recurrence-policy/actions.ts
5677
+ var RecurrencePolicyUpdateHandler = class extends AbstractUpdateHandler {
5678
+ setKey(context, resource, { key }) {
5679
+ if (key) resource.key = key;
5680
+ }
5681
+ setDescription(context, resource, { description }) {
5682
+ resource.description = description;
5683
+ }
5684
+ setName(context, resource, { name }) {
5685
+ resource.name = name;
5686
+ }
5687
+ setSchedule(context, resource, { schedule }) {
5688
+ resource.schedule = schedule;
5689
+ }
5690
+ };
5691
+
5692
+ //#endregion
5693
+ //#region src/repositories/recurrence-policy/index.ts
5694
+ var RecurrencePolicyRepository = class extends AbstractResourceRepository {
5695
+ constructor(config) {
5696
+ super("recurrence-policy", config);
5697
+ this.actions = new RecurrencePolicyUpdateHandler(config.storage);
5698
+ }
5699
+ create(context, draft) {
5700
+ const resource = {
5701
+ ...getBaseResourceProperties(),
5702
+ key: draft.key,
5703
+ name: draft.name,
5704
+ description: draft.description,
5705
+ schedule: draft.schedule
5706
+ };
5707
+ return this.saveNew(context, resource);
5708
+ }
5709
+ };
5710
+
5711
+ //#endregion
5712
+ //#region src/repositories/recurring-order/actions.ts
5713
+ var RecurringOrderUpdateHandler = class extends AbstractUpdateHandler {
5714
+ setCustomField(context, resource, { name, value }) {
5715
+ if (!resource.custom) throw new Error("Resource has no custom field");
5716
+ if (value === null) delete resource.custom.fields[name];
5717
+ else resource.custom.fields[name] = value;
5718
+ }
5719
+ setCustomType(context, resource, { type, fields }) {
5720
+ if (!type) resource.custom = void 0;
5721
+ else {
5722
+ const resolvedType = this._storage.getByResourceIdentifier(context.projectKey, type);
5723
+ if (!resolvedType) throw new Error(`Type ${type} not found`);
5724
+ resource.custom = {
5725
+ type: {
5726
+ typeId: "type",
5727
+ id: resolvedType.id
5728
+ },
5729
+ fields: fields || {}
5730
+ };
5731
+ }
5732
+ }
5733
+ setExpiresAt(context, resource, { expiresAt }) {
5734
+ resource.expiresAt = expiresAt;
5735
+ }
5736
+ setKey(context, resource, { key }) {
5737
+ resource.key = key;
5738
+ }
5739
+ setOrderSkipConfiguration(context, resource, { skipConfiguration, updatedExpiresAt }) {
5740
+ if (skipConfiguration) resource.skipConfiguration = {
5741
+ type: skipConfiguration.type,
5742
+ totalToSkip: skipConfiguration.totalToSkip,
5743
+ skipped: 0,
5744
+ lastSkippedAt: void 0
5745
+ };
5746
+ else resource.skipConfiguration = void 0;
5747
+ if (updatedExpiresAt !== void 0) resource.expiresAt = updatedExpiresAt;
5748
+ }
5749
+ setSchedule(context, resource, { recurrencePolicy }) {
5750
+ resource.schedule = {
5751
+ ...resource.schedule,
5752
+ ...recurrencePolicy
5753
+ };
5754
+ }
5755
+ setStartsAt(context, resource, { startsAt }) {
5756
+ resource.startsAt = startsAt;
5757
+ }
5758
+ setRecurringOrderState(context, resource, { recurringOrderState }) {
5759
+ switch (recurringOrderState.type) {
5760
+ case "active":
5761
+ resource.recurringOrderState = "Active";
5762
+ if (recurringOrderState.resumesAt) resource.resumesAt = recurringOrderState.resumesAt;
5763
+ break;
5764
+ case "canceled":
5765
+ resource.recurringOrderState = "Canceled";
5766
+ break;
5767
+ case "expired":
5768
+ resource.recurringOrderState = "Expired";
5769
+ break;
5770
+ case "paused":
5771
+ resource.recurringOrderState = "Paused";
5772
+ break;
5773
+ }
5774
+ }
5775
+ transitionState(context, resource, { state, force }) {
5776
+ resource.state = {
5777
+ typeId: "state",
5778
+ id: state.id
5779
+ };
5780
+ }
5781
+ };
5782
+
5783
+ //#endregion
5784
+ //#region src/repositories/recurring-order/index.ts
5785
+ var RecurringOrderRepository = class extends AbstractResourceRepository {
5786
+ constructor(config) {
5787
+ super("recurring-order", config);
5788
+ this.actions = new RecurringOrderUpdateHandler(config.storage);
5789
+ }
5790
+ create(context, draft) {
5791
+ assert(draft.cart, "draft.cart is missing");
5792
+ const orderRepo = new OrderRepository(this.config);
5793
+ const initialOrder = orderRepo.createFromCart(context, {
5794
+ id: draft.cart.id,
5795
+ typeId: "cart"
5796
+ });
5797
+ const resource = {
5798
+ ...getBaseResourceProperties(),
5799
+ key: draft.key,
5800
+ cart: {
5801
+ typeId: "cart",
5802
+ id: draft.cart.id
5803
+ },
5804
+ originOrder: {
5805
+ typeId: "order",
5806
+ id: initialOrder.id
5807
+ },
5808
+ startsAt: draft.startsAt,
5809
+ expiresAt: draft.expiresAt,
5810
+ recurringOrderState: "Active",
5811
+ schedule: {
5812
+ type: "standard",
5813
+ intervalUnit: "month",
5814
+ value: 1
5815
+ }
5816
+ };
5817
+ return this.saveNew(context, resource);
5818
+ }
5819
+ };
5820
+
5424
5821
  //#endregion
5425
5822
  //#region src/repositories/review.ts
5426
5823
  var ReviewRepository = class extends AbstractResourceRepository {
@@ -5640,7 +6037,8 @@ var ShoppingListUpdateHandler = class extends AbstractUpdateHandler {
5640
6037
  productType: product.productType,
5641
6038
  name: product.masterData.current.name,
5642
6039
  variantId: varId,
5643
- quantity
6040
+ quantity,
6041
+ published: Boolean(product.masterData.current)
5644
6042
  });
5645
6043
  }
5646
6044
  changeLineItemQuantity(context, resource, { lineItemId, lineItemKey, quantity }) {
@@ -5760,6 +6158,7 @@ var ShoppingListRepository = class extends AbstractResourceRepository {
5760
6158
  productId: draftLineItem.productId ?? "",
5761
6159
  name: {},
5762
6160
  variantId,
6161
+ published: true,
5763
6162
  quantity: draftLineItem.quantity ?? 1,
5764
6163
  productType: {
5765
6164
  typeId: "product-type",
@@ -6161,6 +6560,7 @@ const createRepositories = (config) => ({
6161
6560
  channel: new ChannelRepository(config),
6162
6561
  "customer-group": new CustomerGroupRepository(config),
6163
6562
  "discount-code": new DiscountCodeRepository(config),
6563
+ "discount-group": new DiscountGroupRepository(config),
6164
6564
  extension: new ExtensionRepository(config),
6165
6565
  "inventory-entry": new InventoryEntryRepository(config),
6166
6566
  "key-value-document": new CustomObjectRepository(config),
@@ -6179,6 +6579,8 @@ const createRepositories = (config) => ({
6179
6579
  "product-selection": new ProductSelectionRepository(config),
6180
6580
  "product-tailoring": new ProductTailoringRepository(config),
6181
6581
  project: new ProjectRepository(config),
6582
+ "recurring-order": new RecurringOrderRepository(config),
6583
+ "recurrence-policy": new RecurrencePolicyRepository(config),
6182
6584
  review: new ReviewRepository(config),
6183
6585
  quote: new QuoteRepository(config),
6184
6586
  "quote-request": new QuoteRequestRepository(config),
@@ -6670,6 +7072,19 @@ var DiscountCodeService = class extends AbstractService {
6670
7072
  }
6671
7073
  };
6672
7074
 
7075
+ //#endregion
7076
+ //#region src/services/discount-group.ts
7077
+ var DiscountGroupService = class extends AbstractService {
7078
+ repository;
7079
+ constructor(parent, repository) {
7080
+ super(parent);
7081
+ this.repository = repository;
7082
+ }
7083
+ getBasePath() {
7084
+ return "discount-groups";
7085
+ }
7086
+ };
7087
+
6673
7088
  //#endregion
6674
7089
  //#region src/services/extension.ts
6675
7090
  var ExtensionServices = class extends AbstractService {
@@ -7101,6 +7516,32 @@ var StagedQuoteService = class extends AbstractService {
7101
7516
  }
7102
7517
  };
7103
7518
 
7519
+ //#endregion
7520
+ //#region src/services/recurrence-policy.ts
7521
+ var RecurrencePolicyService = class extends AbstractService {
7522
+ repository;
7523
+ constructor(parent, repository) {
7524
+ super(parent);
7525
+ this.repository = repository;
7526
+ }
7527
+ getBasePath() {
7528
+ return "recurrence-policies";
7529
+ }
7530
+ };
7531
+
7532
+ //#endregion
7533
+ //#region src/services/recurring-order.ts
7534
+ var RecurringOrderService = class extends AbstractService {
7535
+ repository;
7536
+ constructor(parent, repository) {
7537
+ super(parent);
7538
+ this.repository = repository;
7539
+ }
7540
+ getBasePath() {
7541
+ return "recurring-orders";
7542
+ }
7543
+ };
7544
+
7104
7545
  //#endregion
7105
7546
  //#region src/services/reviews.ts
7106
7547
  var ReviewService = class extends AbstractService {
@@ -7258,6 +7699,7 @@ const createServices = (router, repos) => ({
7258
7699
  channel: new ChannelService(router, repos.channel),
7259
7700
  "customer-group": new CustomerGroupService(router, repos["customer-group"]),
7260
7701
  "discount-code": new DiscountCodeService(router, repos["discount-code"]),
7702
+ "discount-group": new DiscountGroupService(router, repos["discount-group"]),
7261
7703
  extension: new ExtensionServices(router, repos.extension),
7262
7704
  "inventory-entry": new InventoryEntryService(router, repos["inventory-entry"]),
7263
7705
  "key-value-document": new CustomObjectService(router, repos["key-value-document"]),
@@ -7278,6 +7720,8 @@ const createServices = (router, repos) => ({
7278
7720
  "product-selection": new ProductSelectionService(router, repos["product-selection"]),
7279
7721
  quotes: new QuoteService(router, repos.quote),
7280
7722
  "quote-request": new QuoteRequestService(router, repos["quote-request"]),
7723
+ "recurrence-policy": new RecurrencePolicyService(router, repos["recurrence-policy"]),
7724
+ "recurring-order": new RecurringOrderService(router, repos["recurring-order"]),
7281
7725
  reviews: new ReviewService(router, repos.review),
7282
7726
  "shopping-list": new ShoppingListService(router, repos["shopping-list"]),
7283
7727
  "staged-quote": new StagedQuoteService(router, repos["staged-quote"]),
@@ -7402,6 +7846,7 @@ var InMemoryStorage = class extends AbstractStorage {
7402
7846
  customer: new Map(),
7403
7847
  "customer-group": new Map(),
7404
7848
  "discount-code": new Map(),
7849
+ "discount-group": new Map(),
7405
7850
  extension: new Map(),
7406
7851
  "inventory-entry": new Map(),
7407
7852
  "key-value-document": new Map(),
@@ -7416,6 +7861,8 @@ var InMemoryStorage = class extends AbstractStorage {
7416
7861
  "product-type": new Map(),
7417
7862
  "product-projection": new Map(),
7418
7863
  "product-tailoring": new Map(),
7864
+ "recurrence-policy": new Map(),
7865
+ "recurring-order": new Map(),
7419
7866
  review: new Map(),
7420
7867
  "shipping-method": new Map(),
7421
7868
  "staged-quote": new Map(),