@moonbase.sh/storefront-api 3.11.0 → 3.13.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/README.md CHANGED
@@ -24,7 +24,8 @@ Configuration notes:
24
24
 
25
25
  - `endpoint`: your Moonbase storefront URL.
26
26
  - `includeManifests`: include downloadable file manifests when available.
27
- - `persistUtm`: store detected UTM values and ad click IDs in localStorage instead of sessionStorage.
27
+ - `persistUtm`: in `@moonbase.sh/vue`, keep the attribution a visitor arrived with in localStorage, across visits, instead of sessionStorage for the tab. Only with the visitor's consent (see `attributionConsent`); a refusal removes it.
28
+ - `attributionConsent`: in `@moonbase.sh/vue`, whether the visitor has agreed to marketing cookies. `false` keeps the UTM tags, referrer and the ad platforms a click came from (`adClicks`) but not the ad click IDs themselves, and records a tagged arrival on the order only with the first thing put in the cart; `true` keeps the click IDs too. Left out, it follows the store's own setting in Moonbase, which the catalog reports for this visitor as `cookieConsentRequired`. Change it later with `setAttributionConsent()`.
28
29
 
29
30
  ## Common usage
30
31
 
@@ -65,6 +66,22 @@ const user = await client.identity.get()
65
66
  console.log(user.email)
66
67
  ```
67
68
 
69
+ ### Save a customer's address
70
+
71
+ The signed-in customer's next checkout starts from the address saved here. A
72
+ checkout they have already entered billing details in keeps those.
73
+
74
+ ```ts
75
+ const user = await client.identity.updateAddress({
76
+ countryCode: 'AU',
77
+ streetAddress1: '1 George Street',
78
+ streetAddress2: null,
79
+ locality: 'Sydney',
80
+ region: 'NSW',
81
+ postCode: '2000',
82
+ })
83
+ ```
84
+
68
85
  ### Redeem a voucher
69
86
 
70
87
  ```ts
@@ -211,6 +228,11 @@ from TikTok) go to the API under those names, and the rest as `utm_*`.
211
228
  in from the tags and click IDs it has already picked up, unless you pass your own
212
229
  `utm`.
213
230
 
231
+ A click ID identifies the visitor's click, so only send one once the visitor has
232
+ agreed to marketing cookies, where the law asks for that. `withoutClickIds(utm)`
233
+ drops their values and keeps the platforms they came from in `adClicks` (sent as
234
+ `utm_ad_click`), which still counts the visit as an ad click.
235
+
214
236
  ## Inventory flow
215
237
 
216
238
  Most inventory endpoints require an authenticated user:
package/dist/index.cjs CHANGED
@@ -54,6 +54,7 @@ __export(index_exports, {
54
54
  SubscriptionStatus: () => SubscriptionStatus,
55
55
  TokenStore: () => TokenStore,
56
56
  accessTokenLifetime: () => accessTokenLifetime,
57
+ adClicksOf: () => adClicksOf,
57
58
  imageWidths: () => imageWidths,
58
59
  isLocalStorageAvailable: () => isLocalStorageAvailable,
59
60
  isPromotionDisplay: () => isPromotionDisplay,
@@ -66,41 +67,14 @@ __export(index_exports, {
66
67
  promotionDisplays: () => promotionDisplays,
67
68
  resolveUtm: () => resolveUtm,
68
69
  schemas: () => schemas_exports12,
69
- utmToObject: () => utmToObject
70
+ utmToObject: () => utmToObject,
71
+ withoutClickIds: () => withoutClickIds
70
72
  });
71
73
  module.exports = __toCommonJS(index_exports);
72
74
 
73
75
  // src/activationRequests/endpoints.ts
74
76
  var import_zod5 = require("zod");
75
77
 
76
- // src/activationRequests/schemas.ts
77
- var schemas_exports3 = {};
78
- __export(schemas_exports3, {
79
- activationRequestSchema: () => activationRequestSchema
80
- });
81
- var import_zod4 = require("zod");
82
-
83
- // src/storefront/schemas.ts
84
- var schemas_exports2 = {};
85
- __export(schemas_exports2, {
86
- offerConditionSchema: () => offerConditionSchema,
87
- offerScopeSchema: () => offerScopeSchema,
88
- storefrontBundleSchema: () => storefrontBundleSchema,
89
- storefrontLicenseUpgradeSchema: () => storefrontLicenseUpgradeSchema,
90
- storefrontOfferSchema: () => storefrontOfferSchema,
91
- storefrontOfferTargetSchema: () => storefrontOfferTargetSchema,
92
- storefrontProductSchema: () => storefrontProductSchema,
93
- storefrontPromotionCtaSchema: () => storefrontPromotionCtaSchema,
94
- storefrontPromotionSchema: () => storefrontPromotionSchema,
95
- storefrontPromotionTargetSchema: () => storefrontPromotionTargetSchema,
96
- storefrontSchema: () => storefrontSchema,
97
- taxEstimateSchema: () => taxEstimateSchema
98
- });
99
- var import_zod3 = require("zod");
100
-
101
- // src/globalSchemas.ts
102
- var import_zod = require("zod");
103
-
104
78
  // src/globalModels.ts
105
79
  var CycleLength = /* @__PURE__ */ ((CycleLength2) => {
106
80
  CycleLength2["Daily"] = "Daily";
@@ -117,6 +91,7 @@ var MarketingConsentType = /* @__PURE__ */ ((MarketingConsentType2) => {
117
91
  return MarketingConsentType2;
118
92
  })(MarketingConsentType || {});
119
93
  function utmToObject(utm) {
94
+ var _a;
120
95
  return Object.entries({
121
96
  utm_source: utm == null ? void 0 : utm.source,
122
97
  utm_medium: utm == null ? void 0 : utm.medium,
@@ -129,14 +104,41 @@ function utmToObject(utm) {
129
104
  wbraid: utm == null ? void 0 : utm.wbraid,
130
105
  fbclid: utm == null ? void 0 : utm.fbclid,
131
106
  msclkid: utm == null ? void 0 : utm.msclkid,
132
- ttclid: utm == null ? void 0 : utm.ttclid
107
+ ttclid: utm == null ? void 0 : utm.ttclid,
108
+ utm_ad_click: ((_a = utm == null ? void 0 : utm.adClicks) == null ? void 0 : _a.length) ? utm.adClicks.join(",") : void 0
133
109
  }).filter(([_, value]) => value !== void 0).reduce((obj, [key, value]) => ({
134
110
  ...obj,
135
111
  [key]: value
136
112
  }), {});
137
113
  }
138
114
 
115
+ // src/activationRequests/schemas.ts
116
+ var schemas_exports3 = {};
117
+ __export(schemas_exports3, {
118
+ activationRequestSchema: () => activationRequestSchema
119
+ });
120
+ var import_zod4 = require("zod");
121
+
122
+ // src/storefront/schemas.ts
123
+ var schemas_exports2 = {};
124
+ __export(schemas_exports2, {
125
+ offerConditionSchema: () => offerConditionSchema,
126
+ offerScopeSchema: () => offerScopeSchema,
127
+ storefrontBundleSchema: () => storefrontBundleSchema,
128
+ storefrontLicenseUpgradeSchema: () => storefrontLicenseUpgradeSchema,
129
+ storefrontOfferSchema: () => storefrontOfferSchema,
130
+ storefrontOfferTargetSchema: () => storefrontOfferTargetSchema,
131
+ storefrontProductSchema: () => storefrontProductSchema,
132
+ storefrontPromotionCtaSchema: () => storefrontPromotionCtaSchema,
133
+ storefrontPromotionSchema: () => storefrontPromotionSchema,
134
+ storefrontPromotionTargetSchema: () => storefrontPromotionTargetSchema,
135
+ storefrontSchema: () => storefrontSchema,
136
+ taxEstimateSchema: () => taxEstimateSchema
137
+ });
138
+ var import_zod3 = require("zod");
139
+
139
140
  // src/globalSchemas.ts
141
+ var import_zod = require("zod");
140
142
  var priceCollectionSchema = import_zod.z.record(import_zod.z.number());
141
143
  var discountPromotionFields = {
142
144
  promotionId: import_zod.z.string().optional(),
@@ -500,7 +502,11 @@ var storefrontSchema = import_zod3.z.object({
500
502
  // Promotions need to be optional since we may still have old, cached representations in browsers
501
503
  promotions: storefrontPromotionsSchema.optional(),
502
504
  // Depending on circumstances, we may have a tax estimate available
503
- estimatedTax: taxEstimateSchema.optional()
505
+ estimatedTax: taxEstimateSchema.optional(),
506
+ // Whether the storefront has to wait for this visitor's cookie consent before it keeps ad click
507
+ // IDs or remembers their visit: the store's setting, for the country the visit comes from.
508
+ // Optional for older backends and cached catalogs, which count as asking.
509
+ cookieConsentRequired: import_zod3.z.boolean().optional()
504
510
  });
505
511
 
506
512
  // src/activationRequests/models.ts
@@ -566,8 +572,14 @@ var ActivationRequestEndpoints = class {
566
572
  const response = await this.api.authenticatedFetch(`/api/customer/activations/${requestId}/license`, activationRequestSchema, { method: "POST" });
567
573
  return response.data;
568
574
  }
569
- async fulfillTrial(requestId) {
570
- const response = await this.api.fetch(`/api/customer/activations/${requestId}/trial`, activationRequestSchema, { method: "POST" });
575
+ /**
576
+ * Starts the trial the request's app asked for. `utm` is the tracking the visitor arrived with, which the
577
+ * trial is put down to, as a sign-up or an order is, so trials can be told apart by the marketing that
578
+ * brought them.
579
+ */
580
+ async fulfillTrial(requestId, utm) {
581
+ const query = new URLSearchParams(utmToObject(utm)).toString();
582
+ const response = await this.api.fetch(`/api/customer/activations/${requestId}/trial${query ? `?${query}` : ""}`, activationRequestSchema, { method: "POST" });
571
583
  return response.data;
572
584
  }
573
585
  async cancel(requestId) {
@@ -1050,6 +1062,20 @@ var IdentityEndpoints = class {
1050
1062
  user: response.data
1051
1063
  };
1052
1064
  }
1065
+ /**
1066
+ * Saves the signed-in customer's address, which their next checkout starts from. A checkout
1067
+ * they have already entered billing details in keeps those. Rejects with a `MoonbaseError` for
1068
+ * an address the store can't use: it needs a known country, a street address, a city or a
1069
+ * region, and in the US a postal code.
1070
+ */
1071
+ async updateAddress(address) {
1072
+ const response = await this.api.authenticatedFetch("/api/customer/identity", userSchema, {
1073
+ method: "PATCH",
1074
+ body: { address }
1075
+ });
1076
+ this.tokenStore.setUser(response.data);
1077
+ return response.data;
1078
+ }
1053
1079
  async setPassword(currentPassword, newPassword) {
1054
1080
  await this.api.authenticatedFetch(`/api/customer/identity/set-password`, null, {
1055
1081
  method: "POST",
@@ -1295,7 +1321,7 @@ var ProductEndpoints = class {
1295
1321
  var import_zod15 = require("zod");
1296
1322
 
1297
1323
  // package.json
1298
- var version = "3.11.0";
1324
+ var version = "3.13.0";
1299
1325
 
1300
1326
  // src/utils/client.ts
1301
1327
  function buildClientHeader(sdk) {
@@ -3056,6 +3082,31 @@ var ImageUtils = class _ImageUtils {
3056
3082
  };
3057
3083
 
3058
3084
  // src/utils/utm.ts
3085
+ var clickIdPlatforms = [
3086
+ ["gclid", "google"],
3087
+ ["gbraid", "google"],
3088
+ ["wbraid", "google"],
3089
+ ["msclkid", "microsoft"],
3090
+ ["fbclid", "meta"],
3091
+ ["ttclid", "tiktok"]
3092
+ ];
3093
+ var adPlatformOrder = ["google", "microsoft", "meta", "tiktok"];
3094
+ function adClicksOf(utm) {
3095
+ var _a;
3096
+ if (!utm)
3097
+ return void 0;
3098
+ const platforms = new Set((_a = utm.adClicks) != null ? _a : []);
3099
+ for (const [key, platform] of clickIdPlatforms) {
3100
+ if (utm[key])
3101
+ platforms.add(platform);
3102
+ }
3103
+ const ordered = adPlatformOrder.filter((platform) => platforms.has(platform));
3104
+ return ordered.length > 0 ? ordered : void 0;
3105
+ }
3106
+ function withoutClickIds(utm) {
3107
+ const { gclid: _gclid, gbraid: _gbraid, wbraid: _wbraid, msclkid: _msclkid, fbclid: _fbclid, ttclid: _ttclid, ...rest } = utm;
3108
+ return { ...rest, adClicks: adClicksOf(utm) };
3109
+ }
3059
3110
  function parseOffSiteReferrer(rawReferrer, currentOrigin) {
3060
3111
  if (!rawReferrer)
3061
3112
  return void 0;
@@ -3070,7 +3121,7 @@ function parseOffSiteReferrer(rawReferrer, currentOrigin) {
3070
3121
  }
3071
3122
  function resolveUtm(cached, fresh) {
3072
3123
  const freshHasUtm = !!(fresh.source || fresh.medium || fresh.campaign || fresh.term || fresh.content);
3073
- const freshHasClickId = !!(fresh.gclid || fresh.gbraid || fresh.wbraid || fresh.fbclid || fresh.msclkid || fresh.ttclid);
3124
+ const freshHasClickId = !!adClicksOf(fresh);
3074
3125
  const freshIsExternalArrival = freshHasUtm || freshHasClickId || !!fresh.referrer;
3075
3126
  if (freshIsExternalArrival)
3076
3127
  return fresh;
@@ -3133,6 +3184,7 @@ var MoonbaseClient = class {
3133
3184
  SubscriptionStatus,
3134
3185
  TokenStore,
3135
3186
  accessTokenLifetime,
3187
+ adClicksOf,
3136
3188
  imageWidths,
3137
3189
  isLocalStorageAvailable,
3138
3190
  isPromotionDisplay,
@@ -3145,5 +3197,6 @@ var MoonbaseClient = class {
3145
3197
  promotionDisplays,
3146
3198
  resolveUtm,
3147
3199
  schemas,
3148
- utmToObject
3200
+ utmToObject,
3201
+ withoutClickIds
3149
3202
  });