@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.cjs CHANGED
@@ -71,6 +71,7 @@ __export(schemas_exports2, {
71
71
  offerConditionSchema: () => offerConditionSchema,
72
72
  storefrontBundleSchema: () => storefrontBundleSchema,
73
73
  storefrontOfferSchema: () => storefrontOfferSchema,
74
+ storefrontOfferTargetSchema: () => storefrontOfferTargetSchema,
74
75
  storefrontProductSchema: () => storefrontProductSchema,
75
76
  storefrontSchema: () => storefrontSchema,
76
77
  taxEstimateSchema: () => taxEstimateSchema
@@ -230,7 +231,7 @@ var downloadSchema = import_zod2.z.object({
230
231
  var productSummarySchema = import_zod2.z.object({
231
232
  id: import_zod2.z.string(),
232
233
  name: import_zod2.z.string(),
233
- tagline: import_zod2.z.string(),
234
+ tagline: import_zod2.z.string().nullish(),
234
235
  description: import_zod2.z.string().nullish(),
235
236
  website: import_zod2.z.string().optional(),
236
237
  iconUrl: import_zod2.z.string().optional(),
@@ -253,8 +254,8 @@ var productSummarySchema = import_zod2.z.object({
253
254
  var storefrontProductSchema = import_zod3.z.object({
254
255
  id: import_zod3.z.string(),
255
256
  name: import_zod3.z.string(),
256
- tagline: import_zod3.z.string(),
257
- description: import_zod3.z.string(),
257
+ tagline: import_zod3.z.string().nullish(),
258
+ description: import_zod3.z.string().nullish(),
258
259
  iconUrl: import_zod3.z.string().nullable(),
259
260
  website: import_zod3.z.string().nullish(),
260
261
  owned: import_zod3.z.boolean(),
@@ -268,8 +269,8 @@ var storefrontProductSchema = import_zod3.z.object({
268
269
  var storefrontBundleSchema = import_zod3.z.object({
269
270
  id: import_zod3.z.string(),
270
271
  name: import_zod3.z.string(),
271
- tagline: import_zod3.z.string(),
272
- description: import_zod3.z.string(),
272
+ tagline: import_zod3.z.string().nullish(),
273
+ description: import_zod3.z.string().nullish(),
273
274
  iconUrl: import_zod3.z.string().nullable(),
274
275
  owned: import_zod3.z.boolean(),
275
276
  partial: import_zod3.z.boolean(),
@@ -287,13 +288,36 @@ var cartContainsItemsConditionSchema = import_zod3.z.object({
287
288
  relevantItemVariations: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.string().array())
288
289
  });
289
290
  var offerConditionSchema = import_zod3.z.discriminatedUnion("type", [cartContainsItemsConditionSchema]);
291
+ var offerTargetItemSchema = import_zod3.z.union([storefrontProductSchema, storefrontBundleSchema]);
292
+ var storefrontOfferTargetSchema = import_zod3.z.object({
293
+ // The product or bundle the offer applies to.
294
+ item: offerTargetItemSchema,
295
+ // The pricing variation IDs the offer is restricted to; an empty list means all variations.
296
+ variations: import_zod3.z.string().array()
297
+ });
298
+ function legacyOfferTargets(target, targetVariations) {
299
+ if (!target)
300
+ return [];
301
+ const items = Array.isArray(target) ? target : [target];
302
+ return items.map((item) => ({ item, variations: items.length === 1 ? targetVariations != null ? targetVariations : [] : [] }));
303
+ }
290
304
  var storefrontOfferSchema = import_zod3.z.object({
291
305
  id: import_zod3.z.string(),
292
- target: singleOrMultiple(import_zod3.z.union([storefrontProductSchema, storefrontBundleSchema])),
293
- targetVariations: import_zod3.z.string().array(),
306
+ // Each target pairs a product/bundle with the pricing variations the offer applies to (an empty
307
+ // list means all variations). This is the model to consume.
308
+ targets: import_zod3.z.array(storefrontOfferTargetSchema).optional(),
309
+ // Legacy fields, kept optional only so old cached storefront responses still parse. The API now
310
+ // exposes the unified `targets` model; we derive `targets` from these when a response predates it.
311
+ // `.catch` guards against the deprecated shape drifting: a malformed legacy field is ignored
312
+ // rather than failing the whole response (newer responses carry `targets` anyway).
313
+ target: singleOrMultiple(offerTargetItemSchema).optional().catch(void 0),
314
+ targetVariations: import_zod3.z.string().array().optional().catch(void 0),
294
315
  condition: offerConditionSchema,
295
316
  discount: discountSchema
296
- });
317
+ }).transform(({ target, targetVariations, targets, ...rest }) => ({
318
+ ...rest,
319
+ targets: targets != null ? targets : legacyOfferTargets(target, targetVariations)
320
+ }));
297
321
  var taxEstimateSchema = import_zod3.z.object({
298
322
  rate: import_zod3.z.number(),
299
323
  mode: import_zod3.z.enum(["Exclusive", "Inclusive"]),
@@ -1081,7 +1105,7 @@ var couponSchema = import_zod12.z.object({
1081
1105
  var lineItemProductSchema = import_zod12.z.object({
1082
1106
  id: import_zod12.z.string(),
1083
1107
  name: import_zod12.z.string(),
1084
- tagline: import_zod12.z.string(),
1108
+ tagline: import_zod12.z.string().nullish(),
1085
1109
  iconUrl: import_zod12.z.string().nullable()
1086
1110
  });
1087
1111
  var lineItemTotalSchema = import_zod12.z.object({
@@ -1108,7 +1132,7 @@ var openProductLineItem = import_zod12.z.object({
1108
1132
  var lineItemBundleSchema = import_zod12.z.object({
1109
1133
  id: import_zod12.z.string(),
1110
1134
  name: import_zod12.z.string(),
1111
- tagline: import_zod12.z.string(),
1135
+ tagline: import_zod12.z.string().nullish(),
1112
1136
  iconUrl: import_zod12.z.string().nullable(),
1113
1137
  products: lineItemProductSchema.and(import_zod12.z.object({
1114
1138
  included: import_zod12.z.boolean().optional()
@@ -1693,11 +1717,27 @@ var OfferUtils = class _OfferUtils {
1693
1717
  // a. Not be owned, or all targets need to be owned
1694
1718
  // b. Not already in the cart
1695
1719
  static relevantTargets(offer, cartItems) {
1696
- if (Array.isArray(offer.target)) {
1697
- const allOwned = offer.target.every((i) => i.owned);
1698
- return offer.target.filter((i) => (allOwned || !i.owned) && !cartItems.some((l) => l.type === i.type && i.id === (l.type === "Product" ? l.productId : l.bundleId)));
1720
+ if (offer.targets.length > 1) {
1721
+ const allOwned = offer.targets.every((t) => t.item.owned);
1722
+ 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)));
1699
1723
  }
1700
- return [offer.target];
1724
+ return offer.targets;
1725
+ }
1726
+ // The pricing variations a target restricts the offer to. An empty (or missing) variation list
1727
+ // means the offer is not narrowed to specific variations, in which case we keep the established
1728
+ // single default-variation upsell.
1729
+ static targetedVariations(target) {
1730
+ var _a;
1731
+ const { item, variations } = target;
1732
+ if (variations.length === 0)
1733
+ return item.defaultVariation ? [item.defaultVariation] : [];
1734
+ const itemVariations = (_a = item.variations) != null ? _a : item.defaultVariation ? [item.defaultVariation] : [];
1735
+ return itemVariations.filter((v) => variations.includes(v.id));
1736
+ }
1737
+ // Expands the relevant targets into one `{ target, variation }` entry per targeted variation, so
1738
+ // an offer targeting several variations (or several products) surfaces each as its own upsell row.
1739
+ static relevantTargetVariations(offer, cartItems) {
1740
+ return _OfferUtils.relevantTargets(offer, cartItems).flatMap((target) => _OfferUtils.targetedVariations(target).map((variation) => ({ target: target.item, variation })));
1701
1741
  }
1702
1742
  static applyToVariation(offer, variation) {
1703
1743
  const discount = DiscountUtils.apply(offer.discount, variation.price);
@@ -1708,8 +1748,7 @@ var OfferUtils = class _OfferUtils {
1708
1748
  };
1709
1749
  }
1710
1750
  static targetContainsBundle(offer, bundleId) {
1711
- if (Array.isArray(offer.target))
1712
- return offer.target.some((i) => i.type === "Bundle" && i.id === bundleId);
1751
+ return offer.targets.some((t) => t.item.type === "Bundle" && t.item.id === bundleId);
1713
1752
  }
1714
1753
  };
1715
1754