@moonbase.sh/storefront-api 2.3.1 → 2.5.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.
package/dist/index.js CHANGED
@@ -20,6 +20,7 @@ __export(schemas_exports2, {
20
20
  offerConditionSchema: () => offerConditionSchema,
21
21
  storefrontBundleSchema: () => storefrontBundleSchema,
22
22
  storefrontOfferSchema: () => storefrontOfferSchema,
23
+ storefrontOfferTargetSchema: () => storefrontOfferTargetSchema,
23
24
  storefrontProductSchema: () => storefrontProductSchema,
24
25
  storefrontSchema: () => storefrontSchema,
25
26
  taxEstimateSchema: () => taxEstimateSchema
@@ -179,7 +180,7 @@ var downloadSchema = z2.object({
179
180
  var productSummarySchema = z2.object({
180
181
  id: z2.string(),
181
182
  name: z2.string(),
182
- tagline: z2.string(),
183
+ tagline: z2.string().nullish(),
183
184
  description: z2.string().nullish(),
184
185
  website: z2.string().optional(),
185
186
  iconUrl: z2.string().optional(),
@@ -202,8 +203,8 @@ var productSummarySchema = z2.object({
202
203
  var storefrontProductSchema = z3.object({
203
204
  id: z3.string(),
204
205
  name: z3.string(),
205
- tagline: z3.string(),
206
- description: z3.string(),
206
+ tagline: z3.string().nullish(),
207
+ description: z3.string().nullish(),
207
208
  iconUrl: z3.string().nullable(),
208
209
  website: z3.string().nullish(),
209
210
  owned: z3.boolean(),
@@ -217,8 +218,8 @@ var storefrontProductSchema = z3.object({
217
218
  var storefrontBundleSchema = z3.object({
218
219
  id: z3.string(),
219
220
  name: z3.string(),
220
- tagline: z3.string(),
221
- description: z3.string(),
221
+ tagline: z3.string().nullish(),
222
+ description: z3.string().nullish(),
222
223
  iconUrl: z3.string().nullable(),
223
224
  owned: z3.boolean(),
224
225
  partial: z3.boolean(),
@@ -236,13 +237,36 @@ var cartContainsItemsConditionSchema = z3.object({
236
237
  relevantItemVariations: z3.record(z3.string(), z3.string().array())
237
238
  });
238
239
  var offerConditionSchema = z3.discriminatedUnion("type", [cartContainsItemsConditionSchema]);
240
+ var offerTargetItemSchema = z3.union([storefrontProductSchema, storefrontBundleSchema]);
241
+ var storefrontOfferTargetSchema = z3.object({
242
+ // The product or bundle the offer applies to.
243
+ item: offerTargetItemSchema,
244
+ // The pricing variation IDs the offer is restricted to; an empty list means all variations.
245
+ variations: z3.string().array()
246
+ });
247
+ function legacyOfferTargets(target, targetVariations) {
248
+ if (!target)
249
+ return [];
250
+ const items = Array.isArray(target) ? target : [target];
251
+ return items.map((item) => ({ item, variations: items.length === 1 ? targetVariations != null ? targetVariations : [] : [] }));
252
+ }
239
253
  var storefrontOfferSchema = z3.object({
240
254
  id: z3.string(),
241
- target: singleOrMultiple(z3.union([storefrontProductSchema, storefrontBundleSchema])),
242
- targetVariations: z3.string().array(),
255
+ // Each target pairs a product/bundle with the pricing variations the offer applies to (an empty
256
+ // list means all variations). This is the model to consume.
257
+ targets: z3.array(storefrontOfferTargetSchema).optional(),
258
+ // Legacy fields, kept optional only so old cached storefront responses still parse. The API now
259
+ // exposes the unified `targets` model; we derive `targets` from these when a response predates it.
260
+ // `.catch` guards against the deprecated shape drifting: a malformed legacy field is ignored
261
+ // rather than failing the whole response (newer responses carry `targets` anyway).
262
+ target: singleOrMultiple(offerTargetItemSchema).optional().catch(void 0),
263
+ targetVariations: z3.string().array().optional().catch(void 0),
243
264
  condition: offerConditionSchema,
244
265
  discount: discountSchema
245
- });
266
+ }).transform(({ target, targetVariations, targets, ...rest }) => ({
267
+ ...rest,
268
+ targets: targets != null ? targets : legacyOfferTargets(target, targetVariations)
269
+ }));
246
270
  var taxEstimateSchema = z3.object({
247
271
  rate: z3.number(),
248
272
  mode: z3.enum(["Exclusive", "Inclusive"]),
@@ -1030,7 +1054,7 @@ var couponSchema = z12.object({
1030
1054
  var lineItemProductSchema = z12.object({
1031
1055
  id: z12.string(),
1032
1056
  name: z12.string(),
1033
- tagline: z12.string(),
1057
+ tagline: z12.string().nullish(),
1034
1058
  iconUrl: z12.string().nullable()
1035
1059
  });
1036
1060
  var lineItemTotalSchema = z12.object({
@@ -1057,7 +1081,7 @@ var openProductLineItem = z12.object({
1057
1081
  var lineItemBundleSchema = z12.object({
1058
1082
  id: z12.string(),
1059
1083
  name: z12.string(),
1060
- tagline: z12.string(),
1084
+ tagline: z12.string().nullish(),
1061
1085
  iconUrl: z12.string().nullable(),
1062
1086
  products: lineItemProductSchema.and(z12.object({
1063
1087
  included: z12.boolean().optional()
@@ -1642,11 +1666,27 @@ var OfferUtils = class _OfferUtils {
1642
1666
  // a. Not be owned, or all targets need to be owned
1643
1667
  // b. Not already in the cart
1644
1668
  static relevantTargets(offer, cartItems) {
1645
- if (Array.isArray(offer.target)) {
1646
- const allOwned = offer.target.every((i) => i.owned);
1647
- return offer.target.filter((i) => (allOwned || !i.owned) && !cartItems.some((l) => l.type === i.type && i.id === (l.type === "Product" ? l.productId : l.bundleId)));
1669
+ if (offer.targets.length > 1) {
1670
+ const allOwned = offer.targets.every((t) => t.item.owned);
1671
+ return offer.targets.filter((t) => (allOwned || !t.item.owned) && !cartItems.some((l) => l.type === t.item.type && t.item.id === (l.type === "Product" ? l.productId : l.bundleId)));
1648
1672
  }
1649
- return [offer.target];
1673
+ return offer.targets;
1674
+ }
1675
+ // The pricing variations a target restricts the offer to. An empty (or missing) variation list
1676
+ // means the offer is not narrowed to specific variations, in which case we keep the established
1677
+ // single default-variation upsell.
1678
+ static targetedVariations(target) {
1679
+ var _a;
1680
+ const { item, variations } = target;
1681
+ if (variations.length === 0)
1682
+ return item.defaultVariation ? [item.defaultVariation] : [];
1683
+ const itemVariations = (_a = item.variations) != null ? _a : item.defaultVariation ? [item.defaultVariation] : [];
1684
+ return itemVariations.filter((v) => variations.includes(v.id));
1685
+ }
1686
+ // Expands the relevant targets into one `{ target, variation }` entry per targeted variation, so
1687
+ // an offer targeting several variations (or several products) surfaces each as its own upsell row.
1688
+ static relevantTargetVariations(offer, cartItems) {
1689
+ return _OfferUtils.relevantTargets(offer, cartItems).flatMap((target) => _OfferUtils.targetedVariations(target).map((variation) => ({ target: target.item, variation })));
1650
1690
  }
1651
1691
  static applyToVariation(offer, variation) {
1652
1692
  const discount = DiscountUtils.apply(offer.discount, variation.price);
@@ -1657,8 +1697,7 @@ var OfferUtils = class _OfferUtils {
1657
1697
  };
1658
1698
  }
1659
1699
  static targetContainsBundle(offer, bundleId) {
1660
- if (Array.isArray(offer.target))
1661
- return offer.target.some((i) => i.type === "Bundle" && i.id === bundleId);
1700
+ return offer.targets.some((t) => t.item.type === "Bundle" && t.item.id === bundleId);
1662
1701
  }
1663
1702
  };
1664
1703
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@moonbase.sh/storefront-api",
3
3
  "type": "module",
4
- "version": "2.3.1",
4
+ "version": "2.5.0",
5
5
  "description": "Package to let you build storefronts with Moonbase.sh as payment and delivery provider",
6
6
  "author": "Tobias Lønnerød Madsen <m@dsen.tv>",
7
7
  "license": "MIT",